There are 2 ways to output Ansi text: 1. Call DrawTextA/ExtTextOutA, it uses font codepage for unicode translation. 2. hfont = CreateFont("Wingdings", SYMBOL_CHARSET); SendMessageA(hwnd, WM_SETFONT, hfont); SendMessageA(hwnd, WM_SETTEXT, textA); It uses current ANSI codepage for unicode translation.
Currently #1 works correctly for Symbol fonts but #2 does not. This patch makes #2 work as well. Since this is a text drawing bug I don't see a way of adding a test case for this behaviour.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/gdi32/freetype.c | 48 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c index 1293e08a73..ba1839af82 100644 --- a/dlls/gdi32/freetype.c +++ b/dlls/gdi32/freetype.c @@ -6303,24 +6303,44 @@ static FT_UInt get_GSUB_vert_glyph(const GdiFont *font, UINT glyph) return GSUB_apply_feature(header, feature, glyph); }
+static FT_UInt get_glyph_index_symbol(const GdiFont *font, UINT glyph) +{ + FT_UInt ret; + + if (glyph < 0x100) glyph += 0xf000; + /* there is a number of old pre-Unicode "broken" TTFs, which + do have symbols at U+00XX instead of U+f0XX */ + if (!(ret = pFT_Get_Char_Index(font->ft_face, glyph))) + ret = pFT_Get_Char_Index(font->ft_face, glyph - 0xf000); + + return ret; +} + static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph) { - FT_UInt glyphId; + FT_UInt ret; + WCHAR wc; + char buf;
if(font->ft_face->charmap->encoding == FT_ENCODING_NONE) { - WCHAR wc = (WCHAR)glyph; BOOL default_used; BOOL *default_used_pointer; - FT_UInt ret; - char buf; default_used_pointer = NULL; default_used = FALSE; if (codepage_sets_default_used(font->codepage)) default_used_pointer = &default_used; + wc = (WCHAR)glyph; if(!WideCharToMultiByte(font->codepage, 0, &wc, 1, &buf, sizeof(buf), NULL, default_used_pointer) || default_used) { - if (font->codepage == CP_SYMBOL && wc < 0x100) - ret = pFT_Get_Char_Index(font->ft_face, (unsigned char)wc); + if (font->codepage == CP_SYMBOL) + { + ret = get_glyph_index_symbol(font, glyph); + if (!ret) + { + if (WideCharToMultiByte(CP_ACP, 0, &wc, 1, &buf, 1, NULL, NULL)) + ret = get_glyph_index_symbol(font, buf); + } + } else ret = 0; } @@ -6332,15 +6352,17 @@ static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph)
if(font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL) { - if (glyph < 0x100) glyph += 0xf000; - /* there is a number of old pre-Unicode "broken" TTFs, which - do have symbols at U+00XX instead of U+f0XX */ - if (!(glyphId = pFT_Get_Char_Index(font->ft_face, glyph))) - glyphId = pFT_Get_Char_Index(font->ft_face, glyph-0xf000); + ret = get_glyph_index_symbol(font, glyph); + if (!ret) + { + wc = (WCHAR)glyph; + if (WideCharToMultiByte(CP_ACP, 0, &wc, 1, &buf, 1, NULL, NULL)) + ret = get_glyph_index_symbol(font, (unsigned char)buf); + } + return ret; } - else glyphId = pFT_Get_Char_Index(font->ft_face, glyph);
- return glyphId; + return pFT_Get_Char_Index(font->ft_face, glyph); }
/* helper for freetype_GetGlyphIndices */
On Fri, Jun 22, 2018 at 12:55:06PM +0800, Dmitry Timoshkov wrote:
There are 2 ways to output Ansi text:
- Call DrawTextA/ExtTextOutA, it uses font codepage for unicode translation.
- hfont = CreateFont("Wingdings", SYMBOL_CHARSET); SendMessageA(hwnd, WM_SETFONT, hfont); SendMessageA(hwnd, WM_SETTEXT, textA);
It uses current ANSI codepage for unicode translation.
Currently #1 works correctly for Symbol fonts but #2 does not. This patch makes #2 work as well. Since this is a text drawing bug I don't see a way of adding a test case for this behaviour.
Looks good. I've sent in a new version with a re-worded commit message that hopefully makes it clear that this isn't a work-around in Wine, but a work-around in Windows. I also fixed a grammar issue in an existing comment and took the opportunity to make the formatting more consistent.
Huw.
Huw Davies huw@codeweavers.com wrote:
Looks good. I've sent in a new version with a re-worded commit message that hopefully makes it clear that this isn't a work-around in Wine, but a work-around in Windows. I also fixed a grammar issue in an existing comment and took the opportunity to make the formatting more consistent.
Thanks Huw!