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;