[WIN32K] -Simplify the parameters passed to GetFontPenalty and FindBestFontFromList...
[reactos.git] / reactos / win32ss / gdi / ntgdi / freetype.c
index a51e982..bab1ca2 100644 (file)
@@ -522,7 +522,6 @@ SubstituteFontByList(PLIST_ENTRY        pHead,
                      BYTE               RequestedCharSet,
                      BYTE               CharSetMap[FONTSUBST_FROM_AND_TO])
 {
-    NTSTATUS            Status;
     PLIST_ENTRY         pListEntry;
     PFONTSUBST_ENTRY    pSubstEntry;
     BYTE                CharSets[FONTSUBST_FROM_AND_TO];
@@ -564,14 +563,7 @@ SubstituteFontByList(PLIST_ENTRY        pHead,
         }
 
         /* update *pOutputName */
-        RtlFreeUnicodeString(pOutputName);
-        Status = RtlCreateUnicodeString(pOutputName,
-                                        pSubstEntry->FontNames[FONTSUBST_TO].Buffer);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT("RtlCreateUnicodeString failed: 0x%08X\n", Status);
-            continue;   /* cannot create string */
-        }
+        *pOutputName = pSubstEntry->FontNames[FONTSUBST_TO];
 
         if (CharSetMap[FONTSUBST_FROM] == DEFAULT_CHARSET)
         {
@@ -586,32 +578,33 @@ SubstituteFontByList(PLIST_ENTRY        pHead,
 }
 
 static BOOL
-SubstituteFontRecurse(PUNICODE_STRING pInOutName, BYTE *pRequestedCharSet)
+SubstituteFontRecurse(LOGFONTW* pLogFont)
 {
     UINT            RecurseCount = 5;
     UNICODE_STRING  OutputNameW = { 0 };
     BYTE            CharSetMap[FONTSUBST_FROM_AND_TO];
     BOOL            Found;
+    UNICODE_STRING  InputNameW;
 
-    if (pInOutName->Buffer[0] == UNICODE_NULL)
+    if (pLogFont->lfFaceName[0] == UNICODE_NULL)
         return FALSE;
 
+    RtlInitUnicodeString(&InputNameW, pLogFont->lfFaceName);
+
     while (RecurseCount-- > 0)
     {
-        RtlInitUnicodeString(&OutputNameW, NULL);
         Found = SubstituteFontByList(&FontSubstListHead,
-                                     &OutputNameW, pInOutName,
-                                     *pRequestedCharSet, CharSetMap);
+                                     &OutputNameW, &InputNameW,
+                                     pLogFont->lfCharSet, CharSetMap);
         if (!Found)
             break;
 
-        /* update *pInOutName and *pRequestedCharSet */
-        RtlFreeUnicodeString(pInOutName);
-        *pInOutName = OutputNameW;
+        RtlStringCbCopyW(pLogFont->lfFaceName, LF_FACESIZE, OutputNameW.Buffer);
+
         if (CharSetMap[FONTSUBST_FROM] == DEFAULT_CHARSET ||
-            CharSetMap[FONTSUBST_FROM] == *pRequestedCharSet)
+            CharSetMap[FONTSUBST_FROM] == pLogFont->lfCharSet)
         {
-            *pRequestedCharSet = CharSetMap[FONTSUBST_TO];
+            pLogFont->lfCharSet = CharSetMap[FONTSUBST_TO];
         }
     }
 
@@ -1783,7 +1776,7 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
     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,44 +2089,60 @@ IntGetFontLocalizedName(PUNICODE_STRING pNameW, PSHARED_FACE SharedFace,
                         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;
-
-        if (Name.platform_id != TT_PLATFORM_MICROSOFT ||
-            Name.encoding_id != TT_MS_ID_UNICODE_CS)
         {
-            continue;   /* not Microsoft Unicode name */
+            continue;   /* failure */
         }
 
-        if (Name.name_id != NameID || Name.language_id != LangID)
+        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_SYMBOL_CS))
+        {
+            continue;   /* not Microsoft Unicode name */
+        }
+
         if (Name.string == NULL || Name.string_len == 0 ||
             (Name.string[0] == 0 && Name.string[1] == 0))
         {
@@ -2145,26 +2154,53 @@ IntGetFontLocalizedName(PUNICODE_STRING pNameW, PSHARED_FACE SharedFace,
             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);
+        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;
+        }
 
-        RtlCreateUnicodeString(pNameW, Buf);
-        Status = STATUS_SUCCESS;
-        break;
+        if (Score > BestScore)
+        {
+            BestScore = Score;
+            BestIndex = i;
+        }
     }
 
-    if (Status == STATUS_NOT_FOUND)
+    if (BestIndex >= 0)
     {
-        if (LangID != gusEnglishUS)
+        /* store the best name */
+        Error = (Score == 30) ? 0 : FT_Get_Sfnt_Name(Face, BestIndex, &Name);
+        if (!Error)
         {
-            /* Retry with English US */
-            Status = IntGetFontLocalizedName(pNameW, SharedFace, NameID, gusEnglishUS);
+            /* 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);
         }
-        else if (NameID == TT_NAME_ID_FONT_SUBFAMILY)
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* defaulted */
+        if (NameID == TT_NAME_ID_FONT_SUBFAMILY)
         {
             RtlInitAnsiString(&AnsiName, Face->style_name);
             Status = RtlAnsiStringToUnicodeString(pNameW, &AnsiName, TRUE);
@@ -2176,21 +2212,25 @@ IntGetFontLocalizedName(PUNICODE_STRING pNameW, PSHARED_FACE SharedFace,
         }
     }
 
-    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)
+    if (NT_SUCCESS(Status))
     {
-        ASSERT_FREETYPE_LOCK_NOT_HELD();
-        IntLockFreeType;
-        if (!Cache->FullName.Buffer)
-            DuplicateUnicodeString(pNameW, &Cache->FullName);
-        IntUnLockFreeType;
+        /* 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;
@@ -2276,46 +2316,22 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName,
     if (0 == (TM->tmPitchAndFamily & TMPF_VECTOR))
         Info->FontType |= RASTER_FONTTYPE;
 
-    ExFreePoolWithTag(Otm, GDITAG_TEXT);
 
     /* face name */
-    if (FaceName)
-    {
-        RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName), FaceName);
-    }
-    else
-    {
-        status = IntGetFontLocalizedName(&NameW, SharedFace, TT_NAME_ID_FONT_FAMILY,
-                                         gusLanguageID);
-        if (NT_SUCCESS(status))
-        {
-            /* store it */
-            RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName),
-                             NameW.Buffer);
-            RtlFreeUnicodeString(&NameW);
-        }
-    }
+    if (!FaceName)
+        FaceName = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFamilyName);
+
+    RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName), FaceName);
 
     /* full name */
-    if (FullName)
-    {
-        RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
-                         sizeof(Info->EnumLogFontEx.elfFullName),
-                         FullName);
-    }
-    else
-    {
-        status = IntGetFontLocalizedName(&NameW, SharedFace, TT_NAME_ID_FULL_NAME,
-                                         gusLanguageID);
-        if (NT_SUCCESS(status))
-        {
-            /* store it */
-            RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
-                             sizeof(Info->EnumLogFontEx.elfFullName),
-                             NameW.Buffer);
-            RtlFreeUnicodeString(&NameW);
-        }
-    }
+    if (!FullName)
+        FullName = (WCHAR*)((ULONG_PTR) Otm + (ULONG_PTR)Otm->otmpFaceName);
+    
+    RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
+                     sizeof(Info->EnumLogFontEx.elfFullName),
+                     FullName);
+
+    ExFreePoolWithTag(Otm, GDITAG_TEXT);
 
     RtlInitAnsiString(&StyleA, Face->style_name);
     StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
@@ -4009,15 +4025,9 @@ ftGdiGetFontData(
 }
 
 // NOTE: See Table 1. of https://msdn.microsoft.com/en-us/library/ms969909.aspx
-static UINT FASTCALL
-GetFontPenalty(LOGFONTW *               LogFont,
-               PUNICODE_STRING          RequestedNameW,
-               PUNICODE_STRING          ActualNameW,
-               PUNICODE_STRING          FullFaceNameW,
-               BYTE                     RequestedCharSet,
-               PFONTGDI                 FontGDI,
-               OUTLINETEXTMETRICW *     Otm,
-               TEXTMETRICW *            TM,
+static UINT
+GetFontPenalty(const LOGFONTW *               LogFont,
+               const OUTLINETEXTMETRICW *     Otm,
                const char *             style_name)
 {
     ULONG   Penalty = 0;
@@ -4025,14 +4035,19 @@ GetFontPenalty(LOGFONTW *               LogFont,
     LONG    Long;
     BOOL    fFixedSys = FALSE, fNeedScaling = FALSE;
     const BYTE UserCharSet = CharSetFromLangID(gusLanguageID);
-    NTSTATUS Status;
+    const TEXTMETRICW * TM = &Otm->otmTextMetrics;
+    WCHAR* ActualNameW;
+
+    ASSERT(Otm);
+    ASSERT(LogFont);
+    ASSERT(style_name);
 
     /* FIXME: Aspect Penalty 30 */
     /* FIXME: IntSizeSynth Penalty 20 */
     /* FIXME: SmallPenalty Penalty 1 */
     /* FIXME: FaceNameSubst Penalty 500 */
 
-    if (RtlEqualUnicodeString(RequestedNameW, &SystemW, TRUE))
+    if (_wcsicmp(LogFont->lfFaceName, L"System") == 0)
     {
         /* "System" font */
         if (TM->tmCharSet != UserCharSet)
@@ -4042,7 +4057,7 @@ GetFontPenalty(LOGFONTW *               LogFont,
             Penalty += 65000;
         }
     }
-    else if (RtlEqualUnicodeString(RequestedNameW, &FixedSysW, TRUE))
+    else if (_wcsicmp(LogFont->lfFaceName, L"FixedSys") == 0)
     {
         /* "FixedSys" font */
         if (TM->tmCharSet != UserCharSet)
@@ -4055,10 +4070,10 @@ GetFontPenalty(LOGFONTW *               LogFont,
     }
     else    /* Request is non-"System" font */
     {
-        Byte = RequestedCharSet;
+        Byte = LogFont->lfCharSet;
         if (Byte == DEFAULT_CHARSET)
         {
-            if (RtlEqualUnicodeString(RequestedNameW, &MarlettW, TRUE))
+            if (_wcsicmp(LogFont->lfFaceName, L"Marlett") == 0)
             {
                 if (Byte == ANSI_CHARSET)
                 {
@@ -4159,53 +4174,22 @@ GetFontPenalty(LOGFONTW *               LogFont,
         }
     }
 
-    if (RequestedNameW->Buffer[0])
+    ActualNameW = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFamilyName);
+
+    if (LogFont->lfFaceName[0])
     {
         BOOL Found = FALSE;
-        PSHARED_FACE SharedFace = FontGDI->SharedFace;
 
         /* localized family name */
         if (!Found)
         {
-            Status = IntGetFontLocalizedName(ActualNameW, SharedFace, TT_NAME_ID_FONT_FAMILY,
-                                             gusLanguageID);
-            if (NT_SUCCESS(Status))
-            {
-                Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
-            }
+            Found = (_wcsicmp(LogFont->lfFaceName, ActualNameW) == 0);
         }
         /* localized full name */
         if (!Found)
         {
-            Status = IntGetFontLocalizedName(ActualNameW, SharedFace, TT_NAME_ID_FULL_NAME,
-                                             gusLanguageID);
-            if (NT_SUCCESS(Status))
-            {
-                Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
-            }
-        }
-        if (gusLanguageID != gusEnglishUS)
-        {
-            /* English family name */
-            if (!Found)
-            {
-                Status = IntGetFontLocalizedName(ActualNameW, SharedFace, TT_NAME_ID_FONT_FAMILY,
-                                                 gusEnglishUS);
-                if (NT_SUCCESS(Status))
-                {
-                    Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
-                }
-            }
-            /* English full name */
-            if (!Found)
-            {
-                Status = IntGetFontLocalizedName(ActualNameW, SharedFace, TT_NAME_ID_FULL_NAME,
-                                                 gusEnglishUS);
-                if (NT_SUCCESS(Status))
-                {
-                    Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
-                }
-            }
+            ActualNameW = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFaceName);
+            Found = (_wcsicmp(LogFont->lfFaceName, ActualNameW) == 0);
         }
         if (!Found)
         {
@@ -4404,7 +4388,7 @@ GetFontPenalty(LOGFONTW *               LogFont,
         DPRINT("WARNING: Penalty:%ld < 200: RequestedNameW:%ls, "
             "ActualNameW:%ls, lfCharSet:%d, lfWeight:%ld, "
             "tmCharSet:%d, tmWeight:%ld\n",
-            Penalty, RequestedNameW->Buffer, ActualNameW->Buffer,
+            Penalty, LogFont->lfFaceName, ActualNameW,
             LogFont->lfCharSet, LogFont->lfWeight,
             TM->tmCharSet, TM->tmWeight);
     }
@@ -4413,30 +4397,27 @@ GetFontPenalty(LOGFONTW *               LogFont,
 }
 
 static __inline VOID
-FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
-                     PUNICODE_STRING pRequestedNameW,
-                     PUNICODE_STRING pActualNameW, BYTE RequestedCharSet,
-                     PLIST_ENTRY Head)
+FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty,
+                     const LOGFONTW *LogFont,
+                     const PLIST_ENTRY Head)
 {
     ULONG Penalty;
-    NTSTATUS Status;
     PLIST_ENTRY Entry;
     PFONT_ENTRY CurrentEntry;
     FONTGDI *FontGDI;
-    ANSI_STRING ActualNameA;
-    UNICODE_STRING ActualNameW, FullFaceNameW;
     OUTLINETEXTMETRICW *Otm = NULL;
     UINT OtmSize, OldOtmSize = 0;
-    TEXTMETRICW *TM;
     FT_Face Face;
-    LPBYTE pb;
 
     ASSERT(FontObj);
     ASSERT(MatchPenalty);
     ASSERT(LogFont);
-    ASSERT(pRequestedNameW);
     ASSERT(Head);
 
+    /* Start with a pretty big buffer */
+    OldOtmSize = 0x200;
+    Otm = ExAllocatePoolWithTag(PagedPool, OldOtmSize, GDITAG_TEXT);
+
     /* get the FontObj of lowest penalty */
     Entry = Head->Flink;
     while (Entry != Head)
@@ -4448,14 +4429,6 @@ FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
         ASSERT(FontGDI);
         Face = FontGDI->SharedFace->Face;
 
-        /* create actual name */
-        RtlInitAnsiString(&ActualNameA, Face->family_name);
-        Status = RtlAnsiStringToUnicodeString(&ActualNameW, &ActualNameA, TRUE);
-        if (!NT_SUCCESS(Status))
-        {
-            continue;
-        }
-
         /* get text metrics */
         OtmSize = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
         if (OtmSize > OldOtmSize)
@@ -4469,37 +4442,15 @@ FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
         if (Otm)
         {
             IntGetOutlineTextMetrics(FontGDI, OtmSize, Otm);
-            TM = &Otm->otmTextMetrics;
             OldOtmSize = OtmSize;
 
-            /* create full name */
-            pb = (LPBYTE)Otm + (WORD)(DWORD_PTR)Otm->otmpFullName;
-            Status = RtlCreateUnicodeString(&FullFaceNameW, (LPWSTR)pb);
-            if (!NT_SUCCESS(Status))
-            {
-                RtlFreeUnicodeString(&ActualNameW);
-                RtlFreeUnicodeString(&FullFaceNameW);
-                continue;
-            }
-
-            Penalty = GetFontPenalty(LogFont, pRequestedNameW, &ActualNameW,
-                                     &FullFaceNameW, RequestedCharSet,
-                                     FontGDI, Otm, TM, Face->style_name);
+            Penalty = GetFontPenalty(LogFont, Otm, Face->style_name);
             if (*MatchPenalty == 0xFFFFFFFF || Penalty < *MatchPenalty)
             {
-                DPRINT("%ls Penalty: %lu\n", FullFaceNameW.Buffer, Penalty);
-                RtlFreeUnicodeString(pActualNameW);
-                RtlCreateUnicodeString(pActualNameW, ActualNameW.Buffer);
-
                 *FontObj = GDIToObj(FontGDI, FONT);
                 *MatchPenalty = Penalty;
             }
-
-            RtlFreeUnicodeString(&FullFaceNameW);
         }
-
-        /* free strings */
-        RtlFreeUnicodeString(&ActualNameW);
     }
 
     if (Otm)
@@ -4544,12 +4495,11 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
 {
     NTSTATUS Status = STATUS_SUCCESS;
     PTEXTOBJ TextObj;
-    UNICODE_STRING ActualNameW, RequestedNameW;
     PPROCESSINFO Win32Process;
     ULONG MatchPenalty;
     LOGFONTW *pLogFont;
+    LOGFONTW SubstitutedLogFont;
     FT_Face Face;
-    BYTE RequestedCharSet;
 
     if (!pTextObj)
     {
@@ -4570,21 +4520,13 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
         TextObj = pTextObj;
     }
 
-    RtlInitUnicodeString(&ActualNameW, NULL);
-
     pLogFont = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
-    if (!RtlCreateUnicodeString(&RequestedNameW, pLogFont->lfFaceName))
-    {
-        if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
-        return STATUS_NO_MEMORY;
-    }
 
     /* substitute */
-    RequestedCharSet = pLogFont->lfCharSet;
-    DPRINT("Font '%ls,%u' is substituted by: ",
-           RequestedNameW.Buffer, RequestedCharSet);
-    SubstituteFontRecurse(&RequestedNameW, &RequestedCharSet);
-    DPRINT("'%ls,%u'.\n", RequestedNameW.Buffer, RequestedCharSet);
+    SubstitutedLogFont = *pLogFont;
+    DPRINT("Font '%S,%u' is substituted by: ", pLogFont->lfFaceName, pLogFont->lfCharSet);
+    SubstituteFontRecurse(&SubstitutedLogFont);
+    DPRINT("'%S,%u'.\n", SubstitutedLogFont.lfFaceName, SubstitutedLogFont.lfCharSet);
 
     MatchPenalty = 0xFFFFFFFF;
     TextObj->Font = NULL;
@@ -4593,15 +4535,13 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
 
     /* Search private fonts */
     IntLockProcessPrivateFonts(Win32Process);
-    FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont,
-                         &RequestedNameW, &ActualNameW, RequestedCharSet,
+    FindBestFontFromList(&TextObj->Font, &MatchPenalty, &SubstitutedLogFont,
                          &Win32Process->PrivateFontListHead);
     IntUnLockProcessPrivateFonts(Win32Process);
 
     /* Search system fonts */
     IntLockGlobalFonts;
-    FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont,
-                         &RequestedNameW, &ActualNameW, RequestedCharSet,
+    FindBestFontFromList(&TextObj->Font, &MatchPenalty, &SubstitutedLogFont,
                          &FontListHead);
     IntUnLockGlobalFonts;
 
@@ -4636,14 +4576,8 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
 
         TextObj->fl |= TEXTOBJECT_INIT;
         Status = STATUS_SUCCESS;
-
-        DPRINT("RequestedNameW: %ls (CharSet: %d) -> ActualNameW: %ls (CharSet: %d)\n",
-            RequestedNameW.Buffer, pLogFont->lfCharSet,
-            ActualNameW.Buffer, FontGdi->CharSet);
     }
 
-    RtlFreeUnicodeString(&RequestedNameW);
-    RtlFreeUnicodeString(&ActualNameW);
     if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
 
     ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->Font)) != 0);