diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 6417012..0ae2aa4 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -608,7 +608,7 @@ SubstituteFontRecurse(LOGFONTW* pLogFont) } } - return TRUE; /* success */ + return RecurseCount != 4; /* changed */ } /* @@ -4014,9 +4014,10 @@ ftGdiGetFontData( // NOTE: See Table 1. of https://msdn.microsoft.com/en-us/library/ms969909.aspx static UINT -GetFontPenalty(const LOGFONTW * LogFont, - const OUTLINETEXTMETRICW * Otm, - const char * style_name) +GetFontPenalty(const LOGFONTW *LogFont, + const OUTLINETEXTMETRICW *Otm, + const char *style_name, + BOOL bSubstituted) { ULONG Penalty = 0; BYTE Byte; @@ -4137,25 +4138,34 @@ GetFontPenalty(const LOGFONTW * LogFont, if (LogFont->lfFaceName[0]) { - BOOL Found = FALSE; - - /* localized family name */ - if (!Found) - { - Found = (_wcsicmp(LogFont->lfFaceName, ActualNameW) == 0); - } - /* localized full name */ - if (!Found) + if (bSubstituted) { - ActualNameW = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFaceName); - Found = (_wcsicmp(LogFont->lfFaceName, ActualNameW) == 0); + /* This is a substituted font, so the name won't match. */ + /* Apply the substitution penalty */ + Penalty += 500; } - if (!Found) + else { - /* FaceName Penalty 10000 */ - /* Requested a face name, but the candidate's face name - does not match. */ - Penalty += 10000; + BOOL Found = FALSE; + + /* localized family name */ + if (!Found) + { + Found = (_wcsicmp(LogFont->lfFaceName, ActualNameW) == 0); + } + /* localized full name */ + if (!Found) + { + ActualNameW = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFaceName); + Found = (_wcsicmp(LogFont->lfFaceName, ActualNameW) == 0); + } + if (!Found) + { + /* FaceName Penalty 10000 */ + /* Requested a face name, but the candidate's face name + does not match. */ + Penalty += 10000; + } } } @@ -4358,6 +4368,7 @@ GetFontPenalty(const LOGFONTW * LogFont, static __inline VOID FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, const LOGFONTW *LogFont, + const LOGFONTW *SubstitutedLogFont, const PLIST_ENTRY Head) { ULONG Penalty; @@ -4406,12 +4417,21 @@ FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, OldOtmSize = OtmSize; - Penalty = GetFontPenalty(LogFont, Otm, Face->style_name); + Penalty = GetFontPenalty(LogFont, Otm, Face->style_name, FALSE); if (*MatchPenalty == 0xFFFFFFFF || Penalty < *MatchPenalty) { *FontObj = GDIToObj(FontGDI, FONT); *MatchPenalty = Penalty; } + if (SubstitutedLogFont) + { + Penalty = GetFontPenalty(SubstitutedLogFont, Otm, Face->style_name, TRUE); + if (*MatchPenalty == 0xFFFFFFFF || Penalty < *MatchPenalty) + { + *FontObj = GDIToObj(FontGDI, FONT); + *MatchPenalty = Penalty; + } + } } } @@ -4461,6 +4481,7 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj) ULONG MatchPenalty; LOGFONTW *pLogFont; LOGFONTW SubstitutedLogFont; + BOOL bSubstituted; FT_Face Face; if (!pTextObj) @@ -4486,9 +4507,13 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj) /* substitute */ SubstitutedLogFont = *pLogFont; - DPRINT("Font '%S,%u' is substituted by: ", pLogFont->lfFaceName, pLogFont->lfCharSet); - SubstituteFontRecurse(&SubstitutedLogFont); - DPRINT("'%S,%u'.\n", SubstitutedLogFont.lfFaceName, SubstitutedLogFont.lfCharSet); + bSubstituted = SubstituteFontRecurse(&SubstitutedLogFont); + if (bSubstituted) + { + DPRINT("Font '%S,%u' is substituted by: '%S,%u'.\n", + pLogFont->lfFaceName, pLogFont->lfCharSet, + SubstitutedLogFont.lfFaceName, SubstitutedLogFont.lfCharSet); + } MatchPenalty = 0xFFFFFFFF; TextObj->Font = NULL; @@ -4497,13 +4522,15 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj) /* Search private fonts */ IntLockProcessPrivateFonts(Win32Process); - FindBestFontFromList(&TextObj->Font, &MatchPenalty, &SubstitutedLogFont, + FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont, + bSubstituted ? &SubstitutedLogFont : NULL, &Win32Process->PrivateFontListHead); IntUnLockProcessPrivateFonts(Win32Process); /* Search system fonts */ IntLockGlobalFonts; - FindBestFontFromList(&TextObj->Font, &MatchPenalty, &SubstitutedLogFont, + FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont, + bSubstituted ? &SubstitutedLogFont : NULL, &FontListHead); IntUnLockGlobalFonts;