mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:33:10 +00:00
[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
6e4e5a004c
and got ack of Katayama Hirofumi MZ.
Thanks to patches author Doug Lyons.
Test-results: https://reactos.org/testman/compare.php?ids=66264,66267
This commit is contained in:
parent
c527f72f23
commit
98b7ecd280
1 changed files with 152 additions and 44 deletions
|
@ -2244,6 +2244,73 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
|
||||||
return Cache->OutlineRequiredSize;
|
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 */
|
/* See https://msdn.microsoft.com/en-us/library/bb165625(v=vs.90).aspx */
|
||||||
static BYTE
|
static BYTE
|
||||||
CharSetFromLangID(LANGID LangID)
|
CharSetFromLangID(LANGID LangID)
|
||||||
|
@ -2670,10 +2737,67 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName,
|
||||||
Info->NewTextMetricEx.ntmFontSig = fs;
|
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
|
static BOOLEAN FASTCALL
|
||||||
GetFontFamilyInfoForList(LPLOGFONTW LogFont,
|
GetFontFamilyInfoForList(LPLOGFONTW LogFont,
|
||||||
PFONTFAMILYINFO Info,
|
PFONTFAMILYINFO Info,
|
||||||
LPCWSTR NominalName,
|
|
||||||
DWORD *pCount,
|
DWORD *pCount,
|
||||||
DWORD MaxCount,
|
DWORD MaxCount,
|
||||||
PLIST_ENTRY Head)
|
PLIST_ENTRY Head)
|
||||||
|
@ -2700,38 +2824,28 @@ GetFontFamilyInfoForList(LPLOGFONTW LogFont,
|
||||||
{
|
{
|
||||||
if (Count < MaxCount)
|
if (Count < MaxCount)
|
||||||
{
|
{
|
||||||
FontFamilyFillInfo(&Info[Count], NominalName, NULL, FontGDI);
|
FontFamilyFillInfo(&Info[Count], NULL, NULL, FontGDI);
|
||||||
}
|
}
|
||||||
Count++;
|
Count++;
|
||||||
continue;
|
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,
|
continue;
|
||||||
RTL_NUMBER_OF(InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName),
|
|
||||||
NominalName);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!FontFamilyFound(&InfoEntry, Info, min(Count, MaxCount)))
|
||||||
{
|
{
|
||||||
if (_wcsnicmp(LogFont->lfFaceName,
|
if (Count < MaxCount)
|
||||||
InfoEntry.EnumLogFontEx.elfLogFont.lfFaceName,
|
|
||||||
RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0 &&
|
|
||||||
_wcsnicmp(LogFont->lfFaceName,
|
|
||||||
InfoEntry.EnumLogFontEx.elfFullName,
|
|
||||||
RTL_NUMBER_OF(LogFont->lfFaceName) - 1) != 0)
|
|
||||||
{
|
{
|
||||||
continue;
|
RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
|
||||||
}
|
}
|
||||||
|
Count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Count < MaxCount)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(&Info[Count], &InfoEntry, sizeof(InfoEntry));
|
|
||||||
}
|
|
||||||
Count++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*pCount = Count;
|
*pCount = Count;
|
||||||
|
@ -2747,9 +2861,10 @@ GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
|
||||||
{
|
{
|
||||||
PLIST_ENTRY pEntry, pHead = &g_FontSubstListHead;
|
PLIST_ENTRY pEntry, pHead = &g_FontSubstListHead;
|
||||||
PFONTSUBST_ENTRY pCurrentEntry;
|
PFONTSUBST_ENTRY pCurrentEntry;
|
||||||
PUNICODE_STRING pFromW, pToW;
|
PUNICODE_STRING pFromW;
|
||||||
|
FONTGDI *FontGDI;
|
||||||
LOGFONTW lf = *LogFont;
|
LOGFONTW lf = *LogFont;
|
||||||
PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
|
UNICODE_STRING NameW;
|
||||||
|
|
||||||
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink)
|
for (pEntry = pHead->Flink; pEntry != pHead; pEntry = pEntry->Flink)
|
||||||
{
|
{
|
||||||
|
@ -2758,32 +2873,25 @@ GetFontFamilyInfoForSubstitutes(LPLOGFONTW LogFont,
|
||||||
pFromW = &pCurrentEntry->FontNames[FONTSUBST_FROM];
|
pFromW = &pCurrentEntry->FontNames[FONTSUBST_FROM];
|
||||||
if (LogFont->lfFaceName[0] != UNICODE_NULL)
|
if (LogFont->lfFaceName[0] != UNICODE_NULL)
|
||||||
{
|
{
|
||||||
if (_wcsicmp(LogFont->lfFaceName, pFromW->Buffer) != 0)
|
if (!FontFamilyInclude(LogFont, pFromW, Info, min(*pCount, MaxCount)))
|
||||||
continue; /* mismatch */
|
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);
|
IntUnicodeStringToBuffer(lf.lfFaceName, sizeof(lf.lfFaceName), pFromW);
|
||||||
SubstituteFontRecurse(&lf);
|
SubstituteFontRecurse(&lf);
|
||||||
if (LogFont->lfCharSet != DEFAULT_CHARSET && LogFont->lfCharSet != lf.lfCharSet)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
IntLockGlobalFonts();
|
RtlInitUnicodeString(&NameW, lf.lfFaceName);
|
||||||
GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount, &g_FontListHead);
|
FontGDI = FindFaceNameInLists(&NameW);
|
||||||
IntUnLockGlobalFonts();
|
if (FontGDI == NULL)
|
||||||
|
{
|
||||||
|
continue; /* no real font */
|
||||||
|
}
|
||||||
|
|
||||||
IntLockProcessPrivateFonts(Win32Process);
|
if (*pCount < MaxCount)
|
||||||
GetFontFamilyInfoForList(&lf, Info, pFromW->Buffer, pCount, MaxCount,
|
{
|
||||||
&Win32Process->PrivateFontListHead);
|
FontFamilyFillInfo(&Info[*pCount], pFromW->Buffer, NULL, FontGDI);
|
||||||
IntUnLockProcessPrivateFonts(Win32Process);
|
}
|
||||||
break;
|
(*pCount)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -5426,7 +5534,7 @@ NtGdiGetFontFamilyInfo(HDC Dc,
|
||||||
/* Enumerate font families in the global list */
|
/* Enumerate font families in the global list */
|
||||||
IntLockGlobalFonts();
|
IntLockGlobalFonts();
|
||||||
Count = 0;
|
Count = 0;
|
||||||
if (! GetFontFamilyInfoForList(&LogFont, Info, NULL, &Count, Size, &g_FontListHead) )
|
if (! GetFontFamilyInfoForList(&LogFont, Info, &Count, Size, &g_FontListHead) )
|
||||||
{
|
{
|
||||||
IntUnLockGlobalFonts();
|
IntUnLockGlobalFonts();
|
||||||
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
ExFreePoolWithTag(Info, GDITAG_TEXT);
|
||||||
|
@ -5437,7 +5545,7 @@ NtGdiGetFontFamilyInfo(HDC Dc,
|
||||||
/* Enumerate font families in the process local list */
|
/* Enumerate font families in the process local list */
|
||||||
Win32Process = PsGetCurrentProcessWin32Process();
|
Win32Process = PsGetCurrentProcessWin32Process();
|
||||||
IntLockProcessPrivateFonts(Win32Process);
|
IntLockProcessPrivateFonts(Win32Process);
|
||||||
if (! GetFontFamilyInfoForList(&LogFont, Info, NULL, &Count, Size,
|
if (! GetFontFamilyInfoForList(&LogFont, Info, &Count, Size,
|
||||||
&Win32Process->PrivateFontListHead))
|
&Win32Process->PrivateFontListHead))
|
||||||
{
|
{
|
||||||
IntUnLockProcessPrivateFonts(Win32Process);
|
IntUnLockProcessPrivateFonts(Win32Process);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue