https://git.reactos.org/?p=reactos.git;a=commitdiff;h=98b7ecd280c0f641d4593…
commit 98b7ecd280c0f641d4593c8ba792b463a5117550
Author: Joachim Henze <Joachim.Henze(a)reactos.org>
AuthorDate: Mon Mar 11 20:10:14 2019 +0100
Commit: Joachim Henze <Joachim.Henze(a)reactos.org>
CommitDate: Mon Mar 11 20:10:14 2019 +0100
[FREETYPE] Fix 3 regressions in one patch
Fixes regression CORE-15785 (Zim Desktop Wiki 0.67 crashed) and
Fixes regression CORE-15755 (NLite 1.4.9.3 used wrong font)
without reintroducing regression CORE-15558 (AbiWord 2.6.8 font enumeration)
This is achieved by partial revert of
0.4.12-dev-320-g
6e4e5a004c9da6276695d90187fb577812e8892f
and got ack of Katayama Hirofumi MZ.
Thanks to patches author Doug Lyons.
Test-results:
https://reactos.org/testman/compare.php?ids=66264,66267
---
win32ss/gdi/ntgdi/freetype.c | 196 +++++++++++++++++++++++++++++++++----------
1 file changed, 152 insertions(+), 44 deletions(-)
diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c
index 7005057a077..4f58f030f27 100644
--- a/win32ss/gdi/ntgdi/freetype.c
+++ b/win32ss/gdi/ntgdi/freetype.c
@@ -2244,6 +2244,73 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
return Cache->OutlineRequiredSize;
}
+static PFONTGDI FASTCALL
+FindFaceNameInList(PUNICODE_STRING FaceName, PLIST_ENTRY Head)
+{
+ PLIST_ENTRY Entry;
+ PFONT_ENTRY CurrentEntry;
+ ANSI_STRING EntryFaceNameA;
+ UNICODE_STRING EntryFaceNameW;
+ FONTGDI *FontGDI;
+ NTSTATUS status;
+
+ for (Entry = Head->Flink; Entry != Head; Entry = Entry->Flink)
+ {
+ CurrentEntry = CONTAINING_RECORD(Entry, FONT_ENTRY, ListEntry);
+
+ FontGDI = CurrentEntry->Font;
+ ASSERT(FontGDI);
+
+ RtlInitAnsiString(&EntryFaceNameA,
FontGDI->SharedFace->Face->family_name);
+ status = RtlAnsiStringToUnicodeString(&EntryFaceNameW, &EntryFaceNameA,
TRUE);
+ if (!NT_SUCCESS(status))
+ {
+ break;
+ }
+
+ if ((LF_FACESIZE - 1) * sizeof(WCHAR) < EntryFaceNameW.Length)
+ {
+ EntryFaceNameW.Length = (LF_FACESIZE - 1) * sizeof(WCHAR);
+ EntryFaceNameW.Buffer[LF_FACESIZE - 1] = L'\0';
+ }
+
+ if (RtlEqualUnicodeString(FaceName, &EntryFaceNameW, TRUE))
+ {
+ RtlFreeUnicodeString(&EntryFaceNameW);
+ return FontGDI;
+ }
+
+ RtlFreeUnicodeString(&EntryFaceNameW);
+ }
+
+ return NULL;
+}
+
+static PFONTGDI FASTCALL
+FindFaceNameInLists(PUNICODE_STRING FaceName)
+{
+ PPROCESSINFO Win32Process;
+ PFONTGDI Font;
+
+ /* Search the process local list.
+ We do not have to search the 'Mem' list, since those fonts are linked in
the PrivateFontListHead */
+ Win32Process = PsGetCurrentProcessWin32Process();
+ IntLockProcessPrivateFonts(Win32Process);
+ Font = FindFaceNameInList(FaceName, &Win32Process->PrivateFontListHead);
+ IntUnLockProcessPrivateFonts(Win32Process);
+ if (NULL != Font)
+ {
+ return Font;
+ }
+
+ /* Search the global list */
+ IntLockGlobalFonts();
+ Font = FindFaceNameInList(FaceName, &g_FontListHead);
+ IntUnLockGlobalFonts();
+
+ return Font;
+}
+
/* See
https://msdn.microsoft.com/en-us/library/bb165625(v=vs.90).aspx */
static BYTE
CharSetFromLangID(LANGID LangID)
@@ -2670,10 +2737,67 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName,
Info->NewTextMetricEx.ntmFontSig = fs;
}
+static int FASTCALL
+FindFaceNameInInfo(PUNICODE_STRING FaceName, PFONTFAMILYINFO Info, DWORD InfoEntries)
+{
+ DWORD i;
+ UNICODE_STRING InfoFaceName;
+
+ for (i = 0; i < InfoEntries; i++)
+ {
+ RtlInitUnicodeString(&InfoFaceName,
Info[i].EnumLogFontEx.elfLogFont.lfFaceName);
+ if (RtlEqualUnicodeString(&InfoFaceName, FaceName, TRUE))
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static BOOLEAN FASTCALL
+FontFamilyInclude(LPLOGFONTW LogFont, PUNICODE_STRING FaceName,
+ PFONTFAMILYINFO Info, DWORD InfoEntries)
+{
+ UNICODE_STRING LogFontFaceName;
+
+ RtlInitUnicodeString(&LogFontFaceName, LogFont->lfFaceName);
+ if (0 != LogFontFaceName.Length &&
+ !RtlEqualUnicodeString(&LogFontFaceName, FaceName, TRUE))
+ {
+ return FALSE;
+ }
+
+ return FindFaceNameInInfo(FaceName, Info, InfoEntries) < 0;
+}
+
+static BOOL FASTCALL
+FontFamilyFound(PFONTFAMILYINFO InfoEntry,
+ PFONTFAMILYINFO Info, DWORD InfoCount)
+{
+ LPLOGFONTW plf1 = &InfoEntry->EnumLogFontEx.elfLogFont;
+ LPWSTR pFullName1 = InfoEntry->EnumLogFontEx.elfFullName;
+ LPWSTR pFullName2;
+ DWORD i;
+
+ for (i = 0; i < InfoCount; ++i)
+ {
+ LPLOGFONTW plf2 = &Info[i].EnumLogFontEx.elfLogFont;
+ if (plf1->lfCharSet != plf2->lfCharSet)
+ continue;
+
+ pFullName2 = Info[i].EnumLogFontEx.elfFullName;
+ if (_wcsicmp(pFullName1, pFullName2) != 0)
+ continue;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
static BOOLEAN FASTCALL
GetFontFamilyInfoForList(LPLOGFONTW LogFont,
PFONTFAMILYINFO Info,
- LPCWSTR NominalName,
DWORD *pCount,
DWORD MaxCount,
PLIST_ENTRY Head)
@@ -2700,38 +2824,28 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
{
if (Count < MaxCount)
{
- FontFamilyFillInfo(&Info[Count], NominalName, NULL, FontGDI);
+ FontFamilyFillInfo(&Info[Count], NULL, NULL, FontGDI);
}
Count++;
continue;
}
- FontFamilyFillInfo(&InfoEntry, NominalName, NULL, FontGDI);
+ FontFamilyFillInfo(&InfoEntry, NULL, NULL, FontGDI);
- if (NominalName)
+ if (_wcsnicmp(LogFont->lfFaceName,
InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName, RTL_NUMBER_OF(LogFont->lfFaceName)-1) !=
0 &&
+ _wcsnicmp(LogFont->lfFaceName, InfoEntry.EnumLogFontEx.elfFullName,
RTL_NUMBER_OF(LogFont->lfFaceName)-1) != 0)
{
- RtlStringCchCopyW(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
-
RTL_NUMBER_OF(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName),
- NominalName);
+ continue;
}
- else
+
+ if (!FontFamilyFound(&InfoEntry, Info, min(Count, MaxCount)))
{
- if (_wcsnicmp(LogFont->lfFaceName,
- InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
- RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0 &&
- _wcsnicmp(LogFont->lfFaceName,
- InfoEntry.EnumLogFontEx.elfFullName,
- RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0)
+ if (Count < MaxCount)
{
- continue;
+ RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
}
+ Count++;
}
-
- if (Count < MaxCount)
- {
- RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
- }
- Count++;
}
*pCount = Count;
@@ -2747,9 +2861,10 @@ GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
{
PLIST_ENTRY pEntry, pHead = &g_FontSubstListHead;
PFONTSUBST_ENTRY pCurrentEntry;
- PUNICODE_STRING pFromW, pToW;
+ PUNICODE_STRING pFromW;
+ FONTGDI *FontGDI;
LOGFONTW lf = *LogFont;
- PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
+ UNICODE_STRING NameW;
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink)
{
@@ -2758,32 +2873,25 @@ GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
pFromW = &pCurrentEntry->FontNames[FONTSUBST_FROM];
if (LogFont->lfFaceName[0] != UNICODE_NULL)
{
- if (_wcsicmp(LogFont->lfFaceName, pFromW->Buffer) != 0)
+ if (!FontFamilyInclude(LogFont, pFromW, Info, min(*pCount, MaxCount)))
continue; /* mismatch */
}
- pToW = &pCurrentEntry->FontNames[FONTSUBST_TO];
- if (RtlEqualUnicodeString(pFromW, pToW, TRUE) &&
- pCurrentEntry->CharSets[FONTSUBST_FROM] ==
- pCurrentEntry->CharSets[FONTSUBST_TO])
- {
- continue;
- }
-
IntUnicodeStringToBuffer(lf.lfFaceName, sizeof(lf.lfFaceName), pFromW);
SubstituteFontRecurse(&lf);
- if (LogFont->lfCharSet != DEFAULT_CHARSET && LogFont->lfCharSet !=
lf.lfCharSet)
- continue;
- IntLockGlobalFonts();
- GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
&g_FontListHead);
- IntUnLockGlobalFonts();
+ RtlInitUnicodeString(&NameW, lf.lfFaceName);
+ FontGDI = FindFaceNameInLists(&NameW);
+ if (FontGDI == NULL)
+ {
+ continue; /* no real font */
+ }
- IntLockProcessPrivateFonts(Win32Process);
- GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
- &Win32Process->PrivateFontListHead);
- IntUnLockProcessPrivateFonts(Win32Process);
- break;
+ if (*pCount < MaxCount)
+ {
+ FontFamilyFillInfo(&Info[*pCount], pFromW->Buffer, NULL, FontGDI);
+ }
+ (*pCount)++;
}
return TRUE;
@@ -5426,7 +5534,7 @@ NtGdiGetFontFamilyInfo(HDC Dc,
/* Enumerate font families in the global list */
IntLockGlobalFonts();
Count = 0;
- if (! GetFontFamilyInfoForList(&LogFont, Info, NULL, &Count, Size,
&g_FontListHead) )
+ if (! GetFontFamilyInfoForList(&LogFont, Info, &Count, Size,
&g_FontListHead) )
{
IntUnLockGlobalFonts();
ExFreePoolWithTag(Info, GDITAG_TEXT);
@@ -5437,7 +5545,7 @@ NtGdiGetFontFamilyInfo(HDC Dc,
/* Enumerate font families in the process local list */
Win32Process = PsGetCurrentProcessWin32Process();
IntLockProcessPrivateFonts(Win32Process);
- if (! GetFontFamilyInfoForList(&LogFont, Info, NULL, &Count, Size,
+ if (! GetFontFamilyInfoForList(&LogFont, Info, &Count, Size,
&Win32Process->PrivateFontListHead))
{
IntUnLockProcessPrivateFonts(Win32Process);