Author: mjansen Date: Sun May 21 12:24:57 2017 New Revision: 74612
URL: http://svn.reactos.org/svn/reactos?rev=74612&view=rev Log: [WIN32SS] Improve IntGetFontLocalizedName by less strict matching on language id's. Patch by Katayama Hirofumi MZ. CORE-13239 #comment Thanks!
Modified: trunk/reactos/win32ss/gdi/ntgdi/freetype.c
Modified: trunk/reactos/win32ss/gdi/ntgdi/freetype.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/freetype.... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/freetype.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/freetype.c [iso-8859-1] Sun May 21 12:24:57 2017 @@ -1783,7 +1783,7 @@ char *Cp; UNICODE_STRING FamilyNameW, FaceNameW, StyleNameW, FullNameW; PSHARED_FACE SharedFace = FontGDI->SharedFace; - PSHARED_FACE_CACHE Cache = (gusLanguageID == gusEnglishUS) ? &SharedFace->EnglishUS : &SharedFace->UserLanguage; + PSHARED_FACE_CACHE Cache = (PRIMARYLANGID(gusLanguageID) == LANG_ENGLISH) ? &SharedFace->EnglishUS : &SharedFace->UserLanguage; FT_Face Face = SharedFace->Face;
if (Cache->OutlineRequiredSize && Size < Cache->OutlineRequiredSize) @@ -2096,42 +2096,58 @@ FT_UShort NameID, FT_UShort LangID) { FT_SfntName Name; - INT i, Count; + INT i, Count, BestIndex, Score, BestScore; WCHAR Buf[LF_FULLFACESIZE]; FT_Error Error; NTSTATUS Status = STATUS_NOT_FOUND; ANSI_STRING AnsiName; - PSHARED_FACE_CACHE Cache = (LangID == gusEnglishUS) ? &SharedFace->EnglishUS : &SharedFace->UserLanguage; + PSHARED_FACE_CACHE Cache; FT_Face Face = SharedFace->Face;
RtlFreeUnicodeString(pNameW);
+ /* select cache */ + if (PRIMARYLANGID(LangID) == LANG_ENGLISH) + { + Cache = &SharedFace->EnglishUS; + } + else + { + Cache = &SharedFace->UserLanguage; + } + + /* use cache if available */ if (NameID == TT_NAME_ID_FONT_FAMILY && Cache->FontFamily.Buffer) { return DuplicateUnicodeString(&Cache->FontFamily, pNameW); } - if (NameID == TT_NAME_ID_FULL_NAME && Cache->FullName.Buffer) { return DuplicateUnicodeString(&Cache->FullName, pNameW); } + + BestIndex = -1; + BestScore = 0;
Count = FT_Get_Sfnt_Name_Count(Face); for (i = 0; i < Count; ++i) { Error = FT_Get_Sfnt_Name(Face, i, &Name); if (Error) - continue; + { + continue; /* failure */ + } + + if (Name.name_id != NameID) + { + continue; /* mismatched */ + }
if (Name.platform_id != TT_PLATFORM_MICROSOFT || - Name.encoding_id != TT_MS_ID_UNICODE_CS) + (Name.encoding_id != TT_MS_ID_UNICODE_CS && + Name.encoding_id != TT_MS_ID_SYMBOL_CS)) { continue; /* not Microsoft Unicode name */ - } - - if (Name.name_id != NameID || Name.language_id != LangID) - { - continue; /* mismatched */ }
if (Name.string == NULL || Name.string_len == 0 || @@ -2145,26 +2161,53 @@ continue; /* name too long */ }
- /* NOTE: Name.string is not null-terminated */ - RtlCopyMemory(Buf, Name.string, Name.string_len); - Buf[Name.string_len / sizeof(WCHAR)] = UNICODE_NULL; - - /* Convert UTF-16 big endian to little endian */ - SwapEndian(Buf, Name.string_len); - - RtlCreateUnicodeString(pNameW, Buf); - Status = STATUS_SUCCESS; - break; - } - - if (Status == STATUS_NOT_FOUND) - { - if (LangID != gusEnglishUS) - { - /* Retry with English US */ - Status = IntGetFontLocalizedName(pNameW, SharedFace, NameID, gusEnglishUS); - } - else if (NameID == TT_NAME_ID_FONT_SUBFAMILY) + if (Name.language_id == LangID) + { + Score = 30; + BestIndex = i; + break; /* best match */ + } + else if (PRIMARYLANGID(Name.language_id) == PRIMARYLANGID(LangID)) + { + Score = 20; + } + else if (PRIMARYLANGID(Name.language_id) == LANG_ENGLISH) + { + Score = 10; + } + else + { + Score = 0; + } + + if (Score > BestScore) + { + BestScore = Score; + BestIndex = i; + } + } + + if (BestIndex >= 0) + { + /* store the best name */ + Error = (Score == 30) ? 0 : FT_Get_Sfnt_Name(Face, BestIndex, &Name); + if (!Error) + { + /* NOTE: Name.string is not null-terminated */ + RtlCopyMemory(Buf, Name.string, Name.string_len); + Buf[Name.string_len / sizeof(WCHAR)] = UNICODE_NULL; + + /* Convert UTF-16 big endian to little endian */ + SwapEndian(Buf, Name.string_len); + + Status = RtlCreateUnicodeString(pNameW, Buf); + } + } + + if (!NT_SUCCESS(Status)) + { + /* defaulted */ + if (NameID == TT_NAME_ID_FONT_SUBFAMILY) { RtlInitAnsiString(&AnsiName, Face->style_name); Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE); @@ -2176,21 +2219,25 @@ } }
- if (NameID == TT_NAME_ID_FONT_FAMILY) - { - ASSERT_FREETYPE_LOCK_NOT_HELD(); - IntLockFreeType; - if (!Cache->FontFamily.Buffer) - DuplicateUnicodeString(pNameW, &Cache->FontFamily); - IntUnLockFreeType; - } - else if (NameID == TT_NAME_ID_FULL_NAME) - { - ASSERT_FREETYPE_LOCK_NOT_HELD(); - IntLockFreeType; - if (!Cache->FullName.Buffer) - DuplicateUnicodeString(pNameW, &Cache->FullName); - IntUnLockFreeType; + if (NT_SUCCESS(Status)) + { + /* make cache */ + if (NameID == TT_NAME_ID_FONT_FAMILY) + { + ASSERT_FREETYPE_LOCK_NOT_HELD(); + IntLockFreeType; + if (!Cache->FontFamily.Buffer) + DuplicateUnicodeString(pNameW, &Cache->FontFamily); + IntUnLockFreeType; + } + else if (NameID == TT_NAME_ID_FULL_NAME) + { + ASSERT_FREETYPE_LOCK_NOT_HELD(); + IntLockFreeType; + if (!Cache->FullName.Buffer) + DuplicateUnicodeString(pNameW, &Cache->FullName); + IntUnLockFreeType; + } }
return Status;