mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[0.4.11] Revert "[FONT][GDI32] Fix font enumeration functions (#1221)"
This reverts commit 0.4.11-RC-25-gd332edcb50
. #1221 == 0.4.12-dev-320-g6e4e5a004c
== 0.4.11-RC-25-gd332edcb50
aimed to fix historic regression CORE-15558 (Abisoft Font-listbox showing too many fonts) Unfortunately, it would introduce a new regression CORE-15755. (wrong font chosen in NLite 1.4.9.3) Beside that #1221 introduced a retrospective and potentially time-expensive qsort()-call on the enumerated font-list. Due to this uncertainty / open issues I decided to keep it out of releases/0.4.11 and stick with the better evaluated state before that patch.
This commit is contained in:
parent
a9be77c640
commit
c5204e3ff1
2 changed files with 158 additions and 136 deletions
|
@ -204,88 +204,9 @@ NewTextMetricExW2A(NEWTEXTMETRICEXA *tma, NEWTEXTMETRICEXW *tmw)
|
|||
tma->ntmFontSig = tmw->ntmFontSig;
|
||||
}
|
||||
|
||||
// IntFontFamilyCompareEx's flags
|
||||
#define IFFCX_CHARSET 1
|
||||
#define IFFCX_STYLE 2
|
||||
|
||||
FORCEINLINE int FASTCALL
|
||||
IntFontFamilyCompareEx(const FONTFAMILYINFO *ffi1,
|
||||
const FONTFAMILYINFO *ffi2, DWORD dwCompareFlags)
|
||||
{
|
||||
const LOGFONTW *plf1 = &ffi1->EnumLogFontEx.elfLogFont;
|
||||
const LOGFONTW *plf2 = &ffi2->EnumLogFontEx.elfLogFont;
|
||||
ULONG WeightDiff1, WeightDiff2;
|
||||
int cmp = _wcsicmp(plf1->lfFaceName, plf2->lfFaceName);
|
||||
if (cmp)
|
||||
return cmp;
|
||||
if (dwCompareFlags & IFFCX_STYLE)
|
||||
{
|
||||
WeightDiff1 = labs(plf1->lfWeight - FW_NORMAL);
|
||||
WeightDiff2 = labs(plf2->lfWeight - FW_NORMAL);
|
||||
if (WeightDiff1 < WeightDiff2)
|
||||
return -1;
|
||||
if (WeightDiff1 > WeightDiff2)
|
||||
return 1;
|
||||
if (plf1->lfItalic < plf2->lfItalic)
|
||||
return -1;
|
||||
if (plf1->lfItalic > plf2->lfItalic)
|
||||
return 1;
|
||||
}
|
||||
if (dwCompareFlags & IFFCX_CHARSET)
|
||||
{
|
||||
if (plf1->lfCharSet < plf2->lfCharSet)
|
||||
return -1;
|
||||
if (plf1->lfCharSet > plf2->lfCharSet)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __cdecl
|
||||
IntFontFamilyCompare(const void *ffi1, const void *ffi2)
|
||||
{
|
||||
return IntFontFamilyCompareEx(ffi1, ffi2, IFFCX_STYLE | IFFCX_CHARSET);
|
||||
}
|
||||
|
||||
// IntEnumFontFamilies' flags:
|
||||
#define IEFF_UNICODE 1
|
||||
#define IEFF_EXTENDED 2
|
||||
|
||||
int FASTCALL
|
||||
IntFontFamilyListUnique(FONTFAMILYINFO *InfoList, INT nCount,
|
||||
const LOGFONTW *plf, DWORD dwFlags)
|
||||
{
|
||||
FONTFAMILYINFO *first, *last, *result;
|
||||
DWORD dwCompareFlags = 0;
|
||||
|
||||
if (plf->lfFaceName[0])
|
||||
dwCompareFlags |= IFFCX_STYLE;
|
||||
|
||||
if ((dwFlags & IEFF_EXTENDED) && plf->lfCharSet == DEFAULT_CHARSET)
|
||||
dwCompareFlags |= IFFCX_CHARSET;
|
||||
|
||||
// std::unique(first, last, IntFontFamilyCompareEx);
|
||||
if (nCount == 0)
|
||||
return 0;
|
||||
|
||||
result = first = InfoList;
|
||||
last = &InfoList[nCount];
|
||||
while (++first != last)
|
||||
{
|
||||
if (IntFontFamilyCompareEx(result, first, dwCompareFlags) != 0 &&
|
||||
++result != first)
|
||||
{
|
||||
*result = *first;
|
||||
}
|
||||
}
|
||||
nCount = (int)(++result - InfoList);
|
||||
|
||||
return nCount;
|
||||
}
|
||||
|
||||
static int FASTCALL
|
||||
IntEnumFontFamilies(HDC Dc, LPLOGFONTW LogFont, PVOID EnumProc, LPARAM lParam,
|
||||
DWORD dwFlags)
|
||||
BOOL Unicode)
|
||||
{
|
||||
int FontFamilyCount;
|
||||
int FontFamilySize;
|
||||
|
@ -335,15 +256,9 @@ IntEnumFontFamilies(HDC Dc, LPLOGFONTW LogFont, PVOID EnumProc, LPARAM lParam,
|
|||
}
|
||||
}
|
||||
|
||||
DPRINT("qsort\n");
|
||||
qsort(Info, FontFamilyCount, sizeof(*Info), IntFontFamilyCompare);
|
||||
DPRINT("qsort done\n");
|
||||
FontFamilyCount = IntFontFamilyListUnique(Info, FontFamilyCount, LogFont, dwFlags);
|
||||
DPRINT("unique done\n");
|
||||
|
||||
for (i = 0; i < FontFamilyCount; i++)
|
||||
{
|
||||
if (dwFlags & IEFF_UNICODE)
|
||||
if (Unicode)
|
||||
{
|
||||
Ret = ((FONTENUMPROCW) EnumProc)(
|
||||
(VOID*)&Info[i].EnumLogFontEx,
|
||||
|
@ -384,8 +299,7 @@ int WINAPI
|
|||
EnumFontFamiliesExW(HDC hdc, LPLOGFONTW lpLogfont, FONTENUMPROCW lpEnumFontFamExProc,
|
||||
LPARAM lParam, DWORD dwFlags)
|
||||
{
|
||||
return IntEnumFontFamilies(hdc, lpLogfont, lpEnumFontFamExProc, lParam,
|
||||
IEFF_UNICODE | IEFF_EXTENDED);
|
||||
return IntEnumFontFamilies(hdc, lpLogfont, lpEnumFontFamExProc, lParam, TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -406,7 +320,7 @@ EnumFontFamiliesW(HDC hdc, LPCWSTR lpszFamily, FONTENUMPROCW lpEnumFontFamProc,
|
|||
lstrcpynW(LogFont.lfFaceName, lpszFamily, LF_FACESIZE);
|
||||
}
|
||||
|
||||
return IntEnumFontFamilies(hdc, &LogFont, lpEnumFontFamProc, lParam, IEFF_UNICODE);
|
||||
return IntEnumFontFamilies(hdc, &LogFont, lpEnumFontFamProc, lParam, TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -427,7 +341,7 @@ EnumFontFamiliesExA (HDC hdc, LPLOGFONTA lpLogfont, FONTENUMPROCA lpEnumFontFamE
|
|||
else pLogFontW = NULL;
|
||||
|
||||
/* no need to convert LogFontW back to lpLogFont b/c it's an [in] parameter only */
|
||||
return IntEnumFontFamilies(hdc, pLogFontW, lpEnumFontFamExProc, lParam, IEFF_EXTENDED);
|
||||
return IntEnumFontFamilies(hdc, pLogFontW, lpEnumFontFamExProc, lParam, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -448,7 +362,7 @@ EnumFontFamiliesA(HDC hdc, LPCSTR lpszFamily, FONTENUMPROCA lpEnumFontFamProc,
|
|||
MultiByteToWideChar(CP_THREAD_ACP, 0, lpszFamily, -1, LogFont.lfFaceName, LF_FACESIZE);
|
||||
}
|
||||
|
||||
return IntEnumFontFamilies(hdc, &LogFont, lpEnumFontFamProc, lParam, 0);
|
||||
return IntEnumFontFamilies(hdc, &LogFont, lpEnumFontFamProc, lParam, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2202,6 +2202,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)
|
||||
|
@ -2628,10 +2695,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)
|
||||
|
@ -2658,38 +2782,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;
|
||||
|
@ -2705,9 +2819,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)
|
||||
{
|
||||
|
@ -2716,32 +2831,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;
|
||||
|
@ -5394,7 +5502,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);
|
||||
|
@ -5405,7 +5513,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);
|
||||
|
|
Loading…
Reference in a new issue