Skip to content
Permalink
Browse files

[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
6e4e5a0
and got ack of Katayama Hirofumi MZ.

Thanks to patches author Doug Lyons.
Test-results: https://reactos.org/testman/compare.php?ids=66264,66267
  • Loading branch information...
JoachimHenze committed Mar 11, 2019
1 parent c527f72 commit 98b7ecd280c0f641d4593c8ba792b463a5117550
Showing with 152 additions and 44 deletions.
  1. +152 −44 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);

0 comments on commit 98b7ecd

Please sign in to comment.
You can’t perform that action at this time.