From: Akihiro Sagawa Subject: [PATCH 5/5] comctl32/edit: Implement EC_USEFONTINFO margins in the CJK case. Message-Id: <20190424214112.59AE.375B48EC@gmail.com> Date: Wed, 24 Apr 2019 21:42:19 +0900 Signed-off-by: Akihiro Sagawa --- dlls/comctl32/edit.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- dlls/comctl32/tests/edit.c | 2 -- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/dlls/comctl32/edit.c b/dlls/comctl32/edit.c index 38a0d97..fc3742d 100644 --- a/dlls/comctl32/edit.c +++ b/dlls/comctl32/edit.c @@ -2685,6 +2685,36 @@ static void EDIT_EM_SetLimitText(EDITSTATE *es, UINT limit) es->buffer_limit = limit; } +static BOOL is_cjk(HDC dc) +{ + const DWORD FS_DBCS_MASK = FS_JISJAPAN|FS_CHINESESIMP|FS_WANSUNG|FS_CHINESETRAD|FS_JOHAB; + FONTSIGNATURE fs; + + switch (GdiGetCodePage(dc)) { + case 932: case 936: case 949: case 950: case 1361: + return TRUE; + default: + return (GetTextCharsetInfo(dc, &fs, 0) != DEFAULT_CHARSET && + (fs.fsCsb[0] & FS_DBCS_MASK)); + } +} + +static int get_cjk_fontinfo_margin(int width, int side_bearing) +{ + int margin; + if (side_bearing < 0) + margin = min(-side_bearing, width/2); + else + margin = 0; + return margin; +} + +struct char_width_info { + INT min_lsb, min_rsb, unknown; +}; + +/* Undocumented gdi32 export */ +extern BOOL WINAPI GetCharWidthInfo(HDC, struct char_width_info *); /********************************************************************* * @@ -2714,9 +2744,18 @@ static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, /* The default margins are only non zero for TrueType or Vector fonts */ if (tm.tmPitchAndFamily & ( TMPF_VECTOR | TMPF_TRUETYPE )) { - /* FIXME: figure out the CJK values. */ - default_left_margin = width / 2; - default_right_margin = width / 2; + struct char_width_info width_info; + + if (is_cjk(dc) && GetCharWidthInfo(dc, &width_info)) + { + default_left_margin = get_cjk_fontinfo_margin(width, width_info.min_lsb); + default_right_margin = get_cjk_fontinfo_margin(width, width_info.min_rsb); + } + else + { + default_left_margin = width / 2; + default_right_margin = width / 2; + } GetClientRect(es->hwndSelf, &rc); rc_width = !IsRectEmpty(&rc) ? rc.right - rc.left : 80; diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c index b76a419..fa273a4 100644 --- a/dlls/comctl32/tests/edit.c +++ b/dlls/comctl32/tests/edit.c @@ -1686,7 +1686,6 @@ static void test_margins_default(const char* facename, UINT charset) SendMessageA(hwnd, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, small_margins); SendMessageA(hwnd, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO, EC_USEFONTINFO)); margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0); - todo_wine_if(cjk && expect != MAKELONG(size.cx / 2, size.cx / 2)) ok(margins == expect, "%s:%d: expected %d, %d, got %d, %d\n", facename, charset, HIWORD(expect), LOWORD(expect), HIWORD(margins), LOWORD(margins)); DestroyWindow(hwnd); @@ -1706,7 +1705,6 @@ static void test_margins_default(const char* facename, UINT charset) SendMessageA(hwnd, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, small_margins); SendMessageA(hwnd, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO, EC_USEFONTINFO)); margins = SendMessageA(hwnd, EM_GETMARGINS, 0, 0); - todo_wine_if(cjk && expect != MAKELONG(size.cx / 2, size.cx / 2)) ok(margins == expect, "%s:%d: expected %d, %d, got %d, %d\n", facename, charset, HIWORD(expect), LOWORD(expect), HIWORD(margins), LOWORD(margins)); DestroyWindow(hwnd);