mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:52:59 +00:00
[WIN32K] -Reduce the ridiculous number of string allocations done by FindBestFontFromList and GetFontPenalty. CORE-13274
svn path=/trunk/; revision=74613
This commit is contained in:
parent
275c4e77d8
commit
7fe1fd0766
1 changed files with 30 additions and 125 deletions
|
@ -2323,46 +2323,22 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName,
|
||||||
if (0 == (TM->tmPitchAndFamily & TMPF_VECTOR))
|
if (0 == (TM->tmPitchAndFamily & TMPF_VECTOR))
|
||||||
Info->FontType |= RASTER_FONTTYPE;
|
Info->FontType |= RASTER_FONTTYPE;
|
||||||
|
|
||||||
ExFreePoolWithTag(Otm, GDITAG_TEXT);
|
|
||||||
|
|
||||||
/* face name */
|
/* face name */
|
||||||
if (FaceName)
|
if (!FaceName)
|
||||||
{
|
FaceName = (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFamilyName);
|
||||||
RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName), FaceName);
|
|
||||||
}
|
RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName), FaceName);
|
||||||
else
|
|
||||||
{
|
|
||||||
status = IntGetFontLocalizedName(&NameW, SharedFace, TT_NAME_ID_FONT_FAMILY,
|
|
||||||
gusLanguageID);
|
|
||||||
if (NT_SUCCESS(status))
|
|
||||||
{
|
|
||||||
/* store it */
|
|
||||||
RtlStringCbCopyW(Lf->lfFaceName, sizeof(Lf->lfFaceName),
|
|
||||||
NameW.Buffer);
|
|
||||||
RtlFreeUnicodeString(&NameW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* full name */
|
/* full name */
|
||||||
if (FullName)
|
if (!FullName)
|
||||||
{
|
FullName = (WCHAR*)((ULONG_PTR) Otm + (ULONG_PTR)Otm->otmpFaceName);
|
||||||
RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
|
|
||||||
sizeof(Info->EnumLogFontEx.elfFullName),
|
RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
|
||||||
FullName);
|
sizeof(Info->EnumLogFontEx.elfFullName),
|
||||||
}
|
FullName);
|
||||||
else
|
|
||||||
{
|
ExFreePoolWithTag(Otm, GDITAG_TEXT);
|
||||||
status = IntGetFontLocalizedName(&NameW, SharedFace, TT_NAME_ID_FULL_NAME,
|
|
||||||
gusLanguageID);
|
|
||||||
if (NT_SUCCESS(status))
|
|
||||||
{
|
|
||||||
/* store it */
|
|
||||||
RtlStringCbCopyW(Info->EnumLogFontEx.elfFullName,
|
|
||||||
sizeof(Info->EnumLogFontEx.elfFullName),
|
|
||||||
NameW.Buffer);
|
|
||||||
RtlFreeUnicodeString(&NameW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlInitAnsiString(&StyleA, Face->style_name);
|
RtlInitAnsiString(&StyleA, Face->style_name);
|
||||||
StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
|
StyleW.Buffer = Info->EnumLogFontEx.elfStyle;
|
||||||
|
@ -4059,12 +4035,8 @@ ftGdiGetFontData(
|
||||||
static UINT FASTCALL
|
static UINT FASTCALL
|
||||||
GetFontPenalty(LOGFONTW * LogFont,
|
GetFontPenalty(LOGFONTW * LogFont,
|
||||||
PUNICODE_STRING RequestedNameW,
|
PUNICODE_STRING RequestedNameW,
|
||||||
PUNICODE_STRING ActualNameW,
|
|
||||||
PUNICODE_STRING FullFaceNameW,
|
|
||||||
BYTE RequestedCharSet,
|
BYTE RequestedCharSet,
|
||||||
PFONTGDI FontGDI,
|
|
||||||
OUTLINETEXTMETRICW * Otm,
|
OUTLINETEXTMETRICW * Otm,
|
||||||
TEXTMETRICW * TM,
|
|
||||||
const char * style_name)
|
const char * style_name)
|
||||||
{
|
{
|
||||||
ULONG Penalty = 0;
|
ULONG Penalty = 0;
|
||||||
|
@ -4072,7 +4044,8 @@ GetFontPenalty(LOGFONTW * LogFont,
|
||||||
LONG Long;
|
LONG Long;
|
||||||
BOOL fFixedSys = FALSE, fNeedScaling = FALSE;
|
BOOL fFixedSys = FALSE, fNeedScaling = FALSE;
|
||||||
const BYTE UserCharSet = CharSetFromLangID(gusLanguageID);
|
const BYTE UserCharSet = CharSetFromLangID(gusLanguageID);
|
||||||
NTSTATUS Status;
|
TEXTMETRICW * TM = &Otm->otmTextMetrics;
|
||||||
|
UNICODE_STRING ActualNameW;
|
||||||
|
|
||||||
/* FIXME: Aspect Penalty 30 */
|
/* FIXME: Aspect Penalty 30 */
|
||||||
/* FIXME: IntSizeSynth Penalty 20 */
|
/* FIXME: IntSizeSynth Penalty 20 */
|
||||||
|
@ -4206,53 +4179,22 @@ GetFontPenalty(LOGFONTW * LogFont,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&ActualNameW, (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFamilyName));
|
||||||
|
|
||||||
if (RequestedNameW->Buffer[0])
|
if (RequestedNameW->Buffer[0])
|
||||||
{
|
{
|
||||||
BOOL Found = FALSE;
|
BOOL Found = FALSE;
|
||||||
PSHARED_FACE SharedFace = FontGDI->SharedFace;
|
|
||||||
|
|
||||||
/* localized family name */
|
/* localized family name */
|
||||||
if (!Found)
|
if (!Found)
|
||||||
{
|
{
|
||||||
Status = IntGetFontLocalizedName(ActualNameW, SharedFace, TT_NAME_ID_FONT_FAMILY,
|
Found = RtlEqualUnicodeString(RequestedNameW, &ActualNameW, TRUE);
|
||||||
gusLanguageID);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* localized full name */
|
/* localized full name */
|
||||||
if (!Found)
|
if (!Found)
|
||||||
{
|
{
|
||||||
Status = IntGetFontLocalizedName(ActualNameW, SharedFace, TT_NAME_ID_FULL_NAME,
|
RtlInitUnicodeString(&ActualNameW, (WCHAR*)((ULONG_PTR)Otm + (ULONG_PTR)Otm->otmpFaceName));
|
||||||
gusLanguageID);
|
Found = RtlEqualUnicodeString(RequestedNameW, &ActualNameW, TRUE);
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (gusLanguageID != gusEnglishUS)
|
|
||||||
{
|
|
||||||
/* English family name */
|
|
||||||
if (!Found)
|
|
||||||
{
|
|
||||||
Status = IntGetFontLocalizedName(ActualNameW, SharedFace, TT_NAME_ID_FONT_FAMILY,
|
|
||||||
gusEnglishUS);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* English full name */
|
|
||||||
if (!Found)
|
|
||||||
{
|
|
||||||
Status = IntGetFontLocalizedName(ActualNameW, SharedFace, TT_NAME_ID_FULL_NAME,
|
|
||||||
gusEnglishUS);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Found = RtlEqualUnicodeString(RequestedNameW, ActualNameW, TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!Found)
|
if (!Found)
|
||||||
{
|
{
|
||||||
|
@ -4451,7 +4393,7 @@ GetFontPenalty(LOGFONTW * LogFont,
|
||||||
DPRINT("WARNING: Penalty:%ld < 200: RequestedNameW:%ls, "
|
DPRINT("WARNING: Penalty:%ld < 200: RequestedNameW:%ls, "
|
||||||
"ActualNameW:%ls, lfCharSet:%d, lfWeight:%ld, "
|
"ActualNameW:%ls, lfCharSet:%d, lfWeight:%ld, "
|
||||||
"tmCharSet:%d, tmWeight:%ld\n",
|
"tmCharSet:%d, tmWeight:%ld\n",
|
||||||
Penalty, RequestedNameW->Buffer, ActualNameW->Buffer,
|
Penalty, RequestedNameW->Buffer, ActualNameW.Buffer,
|
||||||
LogFont->lfCharSet, LogFont->lfWeight,
|
LogFont->lfCharSet, LogFont->lfWeight,
|
||||||
TM->tmCharSet, TM->tmWeight);
|
TM->tmCharSet, TM->tmWeight);
|
||||||
}
|
}
|
||||||
|
@ -4462,21 +4404,16 @@ GetFontPenalty(LOGFONTW * LogFont,
|
||||||
static __inline VOID
|
static __inline VOID
|
||||||
FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
|
FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
|
||||||
PUNICODE_STRING pRequestedNameW,
|
PUNICODE_STRING pRequestedNameW,
|
||||||
PUNICODE_STRING pActualNameW, BYTE RequestedCharSet,
|
BYTE RequestedCharSet,
|
||||||
PLIST_ENTRY Head)
|
PLIST_ENTRY Head)
|
||||||
{
|
{
|
||||||
ULONG Penalty;
|
ULONG Penalty;
|
||||||
NTSTATUS Status;
|
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
PFONT_ENTRY CurrentEntry;
|
PFONT_ENTRY CurrentEntry;
|
||||||
FONTGDI *FontGDI;
|
FONTGDI *FontGDI;
|
||||||
ANSI_STRING ActualNameA;
|
|
||||||
UNICODE_STRING ActualNameW, FullFaceNameW;
|
|
||||||
OUTLINETEXTMETRICW *Otm = NULL;
|
OUTLINETEXTMETRICW *Otm = NULL;
|
||||||
UINT OtmSize, OldOtmSize = 0;
|
UINT OtmSize, OldOtmSize = 0;
|
||||||
TEXTMETRICW *TM;
|
|
||||||
FT_Face Face;
|
FT_Face Face;
|
||||||
LPBYTE pb;
|
|
||||||
|
|
||||||
ASSERT(FontObj);
|
ASSERT(FontObj);
|
||||||
ASSERT(MatchPenalty);
|
ASSERT(MatchPenalty);
|
||||||
|
@ -4484,6 +4421,10 @@ FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
|
||||||
ASSERT(pRequestedNameW);
|
ASSERT(pRequestedNameW);
|
||||||
ASSERT(Head);
|
ASSERT(Head);
|
||||||
|
|
||||||
|
/* Start with a pretty big buffer */
|
||||||
|
OldOtmSize = 0x200;
|
||||||
|
Otm = ExAllocatePoolWithTag(PagedPool, OldOtmSize, GDITAG_TEXT);
|
||||||
|
|
||||||
/* get the FontObj of lowest penalty */
|
/* get the FontObj of lowest penalty */
|
||||||
Entry = Head->Flink;
|
Entry = Head->Flink;
|
||||||
while (Entry != Head)
|
while (Entry != Head)
|
||||||
|
@ -4495,14 +4436,6 @@ FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
|
||||||
ASSERT(FontGDI);
|
ASSERT(FontGDI);
|
||||||
Face = FontGDI->SharedFace->Face;
|
Face = FontGDI->SharedFace->Face;
|
||||||
|
|
||||||
/* create actual name */
|
|
||||||
RtlInitAnsiString(&ActualNameA, Face->family_name);
|
|
||||||
Status = RtlAnsiStringToUnicodeString(&ActualNameW, &ActualNameA, TRUE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get text metrics */
|
/* get text metrics */
|
||||||
OtmSize = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
|
OtmSize = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
|
||||||
if (OtmSize > OldOtmSize)
|
if (OtmSize > OldOtmSize)
|
||||||
|
@ -4516,37 +4449,16 @@ FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
|
||||||
if (Otm)
|
if (Otm)
|
||||||
{
|
{
|
||||||
IntGetOutlineTextMetrics(FontGDI, OtmSize, Otm);
|
IntGetOutlineTextMetrics(FontGDI, OtmSize, Otm);
|
||||||
TM = &Otm->otmTextMetrics;
|
|
||||||
OldOtmSize = OtmSize;
|
OldOtmSize = OtmSize;
|
||||||
|
|
||||||
/* create full name */
|
Penalty = GetFontPenalty(LogFont, pRequestedNameW, RequestedCharSet,
|
||||||
pb = (LPBYTE)Otm + (WORD)(DWORD_PTR)Otm->otmpFullName;
|
Otm, Face->style_name);
|
||||||
Status = RtlCreateUnicodeString(&FullFaceNameW, (LPWSTR)pb);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&ActualNameW);
|
|
||||||
RtlFreeUnicodeString(&FullFaceNameW);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Penalty = GetFontPenalty(LogFont, pRequestedNameW, &ActualNameW,
|
|
||||||
&FullFaceNameW, RequestedCharSet,
|
|
||||||
FontGDI, Otm, TM, Face->style_name);
|
|
||||||
if (*MatchPenalty == 0xFFFFFFFF || Penalty < *MatchPenalty)
|
if (*MatchPenalty == 0xFFFFFFFF || Penalty < *MatchPenalty)
|
||||||
{
|
{
|
||||||
DPRINT("%ls Penalty: %lu\n", FullFaceNameW.Buffer, Penalty);
|
|
||||||
RtlFreeUnicodeString(pActualNameW);
|
|
||||||
RtlCreateUnicodeString(pActualNameW, ActualNameW.Buffer);
|
|
||||||
|
|
||||||
*FontObj = GDIToObj(FontGDI, FONT);
|
*FontObj = GDIToObj(FontGDI, FONT);
|
||||||
*MatchPenalty = Penalty;
|
*MatchPenalty = Penalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString(&FullFaceNameW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free strings */
|
|
||||||
RtlFreeUnicodeString(&ActualNameW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Otm)
|
if (Otm)
|
||||||
|
@ -4591,7 +4503,7 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
|
||||||
{
|
{
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PTEXTOBJ TextObj;
|
PTEXTOBJ TextObj;
|
||||||
UNICODE_STRING ActualNameW, RequestedNameW;
|
UNICODE_STRING RequestedNameW;
|
||||||
PPROCESSINFO Win32Process;
|
PPROCESSINFO Win32Process;
|
||||||
ULONG MatchPenalty;
|
ULONG MatchPenalty;
|
||||||
LOGFONTW *pLogFont;
|
LOGFONTW *pLogFont;
|
||||||
|
@ -4617,8 +4529,6 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
|
||||||
TextObj = pTextObj;
|
TextObj = pTextObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlInitUnicodeString(&ActualNameW, NULL);
|
|
||||||
|
|
||||||
pLogFont = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
|
pLogFont = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
|
||||||
if (!RtlCreateUnicodeString(&RequestedNameW, pLogFont->lfFaceName))
|
if (!RtlCreateUnicodeString(&RequestedNameW, pLogFont->lfFaceName))
|
||||||
{
|
{
|
||||||
|
@ -4641,14 +4551,14 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
|
||||||
/* Search private fonts */
|
/* Search private fonts */
|
||||||
IntLockProcessPrivateFonts(Win32Process);
|
IntLockProcessPrivateFonts(Win32Process);
|
||||||
FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont,
|
FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont,
|
||||||
&RequestedNameW, &ActualNameW, RequestedCharSet,
|
&RequestedNameW, RequestedCharSet,
|
||||||
&Win32Process->PrivateFontListHead);
|
&Win32Process->PrivateFontListHead);
|
||||||
IntUnLockProcessPrivateFonts(Win32Process);
|
IntUnLockProcessPrivateFonts(Win32Process);
|
||||||
|
|
||||||
/* Search system fonts */
|
/* Search system fonts */
|
||||||
IntLockGlobalFonts;
|
IntLockGlobalFonts;
|
||||||
FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont,
|
FindBestFontFromList(&TextObj->Font, &MatchPenalty, pLogFont,
|
||||||
&RequestedNameW, &ActualNameW, RequestedCharSet,
|
&RequestedNameW, RequestedCharSet,
|
||||||
&FontListHead);
|
&FontListHead);
|
||||||
IntUnLockGlobalFonts;
|
IntUnLockGlobalFonts;
|
||||||
|
|
||||||
|
@ -4683,14 +4593,9 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
|
||||||
|
|
||||||
TextObj->fl |= TEXTOBJECT_INIT;
|
TextObj->fl |= TEXTOBJECT_INIT;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("RequestedNameW: %ls (CharSet: %d) -> ActualNameW: %ls (CharSet: %d)\n",
|
|
||||||
RequestedNameW.Buffer, pLogFont->lfCharSet,
|
|
||||||
ActualNameW.Buffer, FontGdi->CharSet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString(&RequestedNameW);
|
RtlFreeUnicodeString(&RequestedNameW);
|
||||||
RtlFreeUnicodeString(&ActualNameW);
|
|
||||||
if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
|
if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
|
||||||
|
|
||||||
ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->Font)) != 0);
|
ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->Font)) != 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue