From b8f0343bc390ce73201804a3f26183ed521ac3f9 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Thu, 9 Nov 2017 12:03:31 +0900 Subject: [PATCH] add pick_charmap function --- win32ss/gdi/ntgdi/freetype.c | 182 ++++++++++++++++++++++++++++--------------- 1 file changed, 121 insertions(+), 61 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 5fb58cf3e4..7dcdb6ee87 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -3018,6 +3018,116 @@ IntRequestFontSize(PDC dc, FT_Face face, LONG Width, LONG Height) return FT_Request_Size(face, &req); } +static BOOL select_charmap(FT_Face ft_face, FT_Encoding encoding, BOOL bDoLock) +{ + FT_Error ft_err = FT_Err_Invalid_CharMap_Handle; + FT_CharMap cmap0, cmap1, cmap2, cmap3, cmap_def; + FT_Int i; + + cmap0 = cmap1 = cmap2 = cmap3 = cmap_def = NULL; + + for (i = 0; i < ft_face->num_charmaps; i++) + { + if (ft_face->charmaps[i]->encoding == encoding) + { + DPRINT("found cmap with platform_id %u, encoding_id %u\n", + ft_face->charmaps[i]->platform_id, ft_face->charmaps[i]->encoding_id); + + switch (ft_face->charmaps[i]->platform_id) + { + case TT_PLATFORM_APPLE_UNICODE: + cmap0 = ft_face->charmaps[i]; + break; + case TT_PLATFORM_MACINTOSH: + cmap1 = ft_face->charmaps[i]; + break; + case TT_PLATFORM_ISO: + cmap2 = ft_face->charmaps[i]; + break; + case TT_PLATFORM_MICROSOFT: + cmap3 = ft_face->charmaps[i]; + break; + default: + cmap_def = ft_face->charmaps[i]; + break; + } + } + + if (bDoLock) + { + IntLockFreeType; + } + + if (cmap3) /* prefer Microsoft cmap table */ + ft_err = FT_Set_Charmap(ft_face, cmap3); + else if (cmap1) + ft_err = FT_Set_Charmap(ft_face, cmap1); + else if (cmap2) + ft_err = FT_Set_Charmap(ft_face, cmap2); + else if (cmap0) + ft_err = FT_Set_Charmap(ft_face, cmap0); + else if (cmap_def) + ft_err = FT_Set_Charmap(ft_face, cmap_def); + + if (bDoLock) + { + IntUnLockFreeType; + } + } + + return ft_err == FT_Err_Ok; +} + +static FT_Encoding pick_charmap(FT_Face face, int charset, BOOL bDoLock) +{ + static const FT_Encoding regular_order[] = + { + FT_ENCODING_UNICODE, FT_ENCODING_APPLE_ROMAN, FT_ENCODING_MS_SYMBOL, 0 + }; + static const FT_Encoding symbol_order[] = + { + FT_ENCODING_MS_SYMBOL, FT_ENCODING_UNICODE, FT_ENCODING_APPLE_ROMAN, 0 + }; + FT_Encoding encoding; + const FT_Encoding *encs = regular_order; + + if (charset == SYMBOL_CHARSET) + encs = symbol_order; + + while (*encs != 0) + { + if (select_charmap(face, *encs, bDoLock)) + break; + encs++; + } + encoding = *encs; + + if (encoding == 0) + { + DPRINT1("WARNING: Could not find desired charmap!\n"); + } + + if (!face->charmap && face->num_charmaps) + { + if (bDoLock) + { + IntLockFreeType; + } + + if (FT_Err_Ok == FT_Set_Charmap(face, face->charmaps[0])) + encoding = face->charmap->encoding; + else + DPRINT1("WARNING: Could not set the charmap!\n"); + + if (bDoLock) + { + IntUnLockFreeType; + } + } + + return encoding; +} + BOOL FASTCALL TextIntUpdateSize(PDC dc, @@ -3026,46 +3136,22 @@ TextIntUpdateSize(PDC dc, BOOL bDoLock) { FT_Face face; - INT error, n; - FT_CharMap charmap, found; + INT error; LOGFONTW *plf; if (bDoLock) IntLockFreeType; face = FontGDI->SharedFace->Face; + plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; if (face->charmap == NULL) { DPRINT("WARNING: No charmap selected!\n"); DPRINT("This font face has %d charmaps\n", face->num_charmaps); - found = NULL; - for (n = 0; n < face->num_charmaps; n++) - { - charmap = face->charmaps[n]; - DPRINT("Found charmap encoding: %i\n", charmap->encoding); - if (charmap->encoding != 0) - { - found = charmap; - break; - } - } - if (!found) - { - DPRINT1("WARNING: Could not find desired charmap!\n"); - } - else - { - error = FT_Set_Charmap(face, found); - if (error) - { - DPRINT1("WARNING: Could not set the charmap!\n"); - } - } + pick_charmap(face, plf->lfCharSet, FALSE); } - plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; - error = IntRequestFontSize(dc, face, plf->lfWidth, plf->lfHeight); if (bDoLock) @@ -5950,7 +6036,6 @@ NtGdiGetCharABCWidthsW( PTEXTOBJ TextObj; PFONTGDI FontGDI; FT_Face face; - FT_CharMap charmap, found = NULL; UINT i, glyph_index, BufferSize; HFONT hFont = 0; NTSTATUS Status = STATUS_SUCCESS; @@ -6042,36 +6127,26 @@ NtGdiGetCharABCWidthsW( FontGDI = ObjToGDI(TextObj->Font, FONT); face = FontGDI->SharedFace->Face; + plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; if (face->charmap == NULL) { - for (i = 0; i < (UINT)face->num_charmaps; i++) - { - charmap = face->charmaps[i]; - if (charmap->encoding != 0) - { - found = charmap; - break; - } - } + DPRINT("WARNING: No charmap selected!\n"); + DPRINT("This font face has %d charmaps\n", face->num_charmaps); - if (!found) + if (pick_charmap(face, plf->lfCharSet, TRUE) == 0) { DPRINT1("WARNING: Could not find desired charmap!\n"); + ExFreePoolWithTag(SafeBuff, GDITAG_TEXT); - if(Safepwch) + if (Safepwch) ExFreePoolWithTag(Safepwch , GDITAG_TEXT); EngSetLastError(ERROR_INVALID_HANDLE); return FALSE; } - - IntLockFreeType; - FT_Set_Charmap(face, found); - IntUnLockFreeType; } - plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; IntLockFreeType; IntRequestFontSize(dc, face, plf->lfWidth, plf->lfHeight); FtSetCoordinateTransform(face, pmxWorldToDevice); @@ -6161,7 +6236,6 @@ NtGdiGetCharWidthW( PTEXTOBJ TextObj; PFONTGDI FontGDI; FT_Face face; - FT_CharMap charmap, found = NULL; UINT i, glyph_index, BufferSize; HFONT hFont = 0; PMATRIX pmxWorldToDevice; @@ -6236,21 +6310,12 @@ NtGdiGetCharWidthW( } FontGDI = ObjToGDI(TextObj->Font, FONT); + plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; face = FontGDI->SharedFace->Face; if (face->charmap == NULL) { - for (i = 0; i < (UINT)face->num_charmaps; i++) - { - charmap = face->charmaps[i]; - if (charmap->encoding != 0) - { - found = charmap; - break; - } - } - - if (!found) + if (pick_charmap(face, plf->lfCharSet, TRUE) == 0) { DPRINT1("WARNING: Could not find desired charmap!\n"); @@ -6261,13 +6326,8 @@ NtGdiGetCharWidthW( EngSetLastError(ERROR_INVALID_HANDLE); return FALSE; } - - IntLockFreeType; - FT_Set_Charmap(face, found); - IntUnLockFreeType; } - plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; IntLockFreeType; IntRequestFontSize(dc, face, plf->lfWidth, plf->lfHeight); FtSetCoordinateTransform(face, pmxWorldToDevice); -- 2.14.2