|
49 | 49 | #include <windows.h> |
50 | 50 | #include <imm.h> |
51 | 51 | #include <windowsx.h> |
| 52 | +#include <winnls.h> |
52 | 53 | #endif |
53 | 54 |
|
54 | 55 | #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) |
@@ -419,6 +420,8 @@ soluna_macos_install_ime(void) { |
419 | 420 | #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) |
420 | 421 | static WNDPROC g_soluna_prev_wndproc = NULL; |
421 | 422 | static bool g_soluna_wndproc_installed = false; |
| 423 | +static LOGFONTW g_soluna_ime_font; |
| 424 | +static bool g_soluna_ime_font_valid = false; |
422 | 425 |
|
423 | 426 | static void |
424 | 427 | soluna_win32_apply_ime_rect(void) { |
@@ -472,7 +475,15 @@ soluna_win32_apply_ime_rect(void) { |
472 | 475 | cand.ptCurrentPos.x = exclude_rect.left; |
473 | 476 | cand.ptCurrentPos.y = exclude_rect.bottom; |
474 | 477 | ImmSetCandidateWindow(imc, &cand); |
475 | | - } |
| 478 | + |
| 479 | + if (g_soluna_ime_font_valid) { |
| 480 | + LOGFONTW lf = g_soluna_ime_font; |
| 481 | + if (lf.lfHeight == 0) { |
| 482 | + lf.lfHeight = -(LONG)caret_h; |
| 483 | + } |
| 484 | + ImmSetCompositionFontW(imc, &lf); |
| 485 | + } |
| 486 | + } |
476 | 487 | ImmReleaseContext(hwnd, imc); |
477 | 488 | } |
478 | 489 |
|
@@ -516,6 +527,29 @@ soluna_win32_install_wndproc(void) { |
516 | 527 | g_soluna_wndproc_installed = true; |
517 | 528 | } |
518 | 529 | } |
| 530 | + |
| 531 | +static void |
| 532 | +soluna_win32_set_ime_font(const char *font_name, float height_px) { |
| 533 | + float scale = sapp_dpi_scale(); |
| 534 | + if (scale <= 0.0f) { |
| 535 | + scale = 1.0f; |
| 536 | + } |
| 537 | + LOGFONTW lf; |
| 538 | + memset(&lf, 0, sizeof(lf)); |
| 539 | + lf.lfCharSet = DEFAULT_CHARSET; |
| 540 | + lf.lfQuality = CLEARTYPE_QUALITY; |
| 541 | + if (height_px > 0.0f) { |
| 542 | + lf.lfHeight = -(LONG)(height_px * scale + 0.5f); |
| 543 | + } |
| 544 | + if (font_name && font_name[0]) { |
| 545 | + int wlen = MultiByteToWideChar(CP_UTF8, 0, font_name, -1, NULL, 0); |
| 546 | + if (wlen > 0 && wlen <= (int)(sizeof(lf.lfFaceName) / sizeof(wchar_t))) { |
| 547 | + MultiByteToWideChar(CP_UTF8, 0, font_name, -1, lf.lfFaceName, wlen); |
| 548 | + } |
| 549 | + } |
| 550 | + g_soluna_ime_font = lf; |
| 551 | + g_soluna_ime_font_valid = true; |
| 552 | +} |
519 | 553 | #endif |
520 | 554 |
|
521 | 555 | static int |
@@ -606,6 +640,35 @@ lset_ime_rect(lua_State *L) { |
606 | 640 | return 0; |
607 | 641 | } |
608 | 642 |
|
| 643 | +static int |
| 644 | +lset_ime_font(lua_State *L) { |
| 645 | + const char *name = NULL; |
| 646 | + float size = 0.0f; |
| 647 | + int top = lua_gettop(L); |
| 648 | + if (top == 0) { |
| 649 | + g_soluna_ime_font_valid = false; |
| 650 | + return 0; |
| 651 | + } |
| 652 | + if (top == 1) { |
| 653 | + size = (float)luaL_checknumber(L, 1); |
| 654 | + } else { |
| 655 | + if (!lua_isnoneornil(L, 1)) { |
| 656 | + if (lua_type(L, 1) != LUA_TSTRING) { |
| 657 | + return luaL_error(L, "set_ime_font expects string font name"); |
| 658 | + } |
| 659 | + name = lua_tostring(L, 1); |
| 660 | + } |
| 661 | + size = (float)luaL_checknumber(L, 2); |
| 662 | + } |
| 663 | + if (size < 0.0f) { |
| 664 | + size = 0.0f; |
| 665 | + } |
| 666 | +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) |
| 667 | + soluna_win32_set_ime_font(name, size); |
| 668 | +#endif |
| 669 | + return 0; |
| 670 | +} |
| 671 | + |
609 | 672 | static int |
610 | 673 | lclose_window(lua_State *L) { |
611 | 674 | sapp_quit(); |
@@ -656,6 +719,7 @@ luaopen_soluna_app(lua_State *L) { |
656 | 719 | { "unpackevent", levent_unpack }, |
657 | 720 | { "set_window_title", lset_window_title }, |
658 | 721 | { "set_ime_rect", lset_ime_rect }, |
| 722 | + { "set_ime_font", lset_ime_font }, |
659 | 723 | { "quit", lquit_signal }, |
660 | 724 | { "close_window", lclose_window }, |
661 | 725 | { "platform", NULL }, |
|
0 commit comments