diff --git a/win32ss/user/user32/controls/edit.c b/win32ss/user/user32/controls/edit.c index 1eccfbf168..43e99f345f 100644 --- a/win32ss/user/user32/controls/edit.c +++ b/win32ss/user/user32/controls/edit.c @@ -2907,6 +2907,40 @@ static void EDIT_EM_SetLimitText(EDITSTATE *es, UINT limit) es->buffer_limit = limit; } +static BOOL is_cjk_charset(HDC dc) +{ + switch (GdiGetCodePage(dc)) { + case 932: case 936: case 949: case 950: case 1361: + return TRUE; + default: + return FALSE; + } +} + +static BOOL is_cjk_font(HDC dc) +{ + const DWORD FS_DBCS_MASK = FS_JISJAPAN|FS_CHINESESIMP|FS_WANSUNG|FS_CHINESETRAD|FS_JOHAB; + FONTSIGNATURE fs; + 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 *); /********************************************************************* * @@ -2921,20 +2955,6 @@ static void EDIT_EM_SetLimitText(EDITSTATE *es, UINT limit) * size. Though there is an exception for the empty client rect case * with small font sizes. */ -static BOOL is_cjk(UINT charset) -{ - switch(charset) - { - case SHIFTJIS_CHARSET: - case HANGUL_CHARSET: - case GB2312_CHARSET: - case CHINESEBIG5_CHARSET: - return TRUE; - } - /* HANGUL_CHARSET is strange, though treated as CJK by Win 8, it is - * not by other versions including Win 10. */ - return FALSE; -} static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, WORD left, WORD right, BOOL repaint) @@ -2947,26 +2967,31 @@ static void EDIT_EM_SetMargins(EDITSTATE *es, INT action, if (es->font && (left == EC_USEFONTINFO || right == EC_USEFONTINFO)) { HDC dc = GetDC(es->hwndSelf); HFONT old_font = SelectObject(dc, es->font); - LONG width = GdiGetCharDimensions(dc, &tm, NULL); + LONG width = GdiGetCharDimensions(dc, &tm, NULL), rc_width; RECT rc; /* The default margins are only non zero for TrueType or Vector fonts */ if (tm.tmPitchAndFamily & ( TMPF_VECTOR | TMPF_TRUETYPE )) { - if (!is_cjk(tm.tmCharSet)) { - default_left_margin = width / 2; - default_right_margin = width / 2; + struct char_width_info width_info; - GetClientRect(es->hwndSelf, &rc); - if (rc.right - rc.left < (width / 2 + width) * 2 && - (width >= 28 || !IsRectEmpty(&rc)) ) { - default_left_margin = es->left_margin; - default_right_margin = es->right_margin; - } - } else { - /* FIXME: figure out the CJK values. They are not affected by the client rect. */ + if ((is_cjk_charset(dc) || is_cjk_font(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; + if (rc_width < default_left_margin + default_right_margin + width * 2) { + default_left_margin = es->left_margin; + default_right_margin = es->right_margin; + } } SelectObject(dc, old_font); ReleaseDC(es->hwndSelf, dc);