mirror of
https://github.com/reactos/reactos.git
synced 2024-07-07 05:05:09 +00:00
[WIN32SS] Improve font substitutes by adding support for charset + loading the substitutes at boot. Patch by Katayama Hirofumi MZ. CORE-12902 #resolve #comment Thanks!
svn path=/trunk/; revision=74178
This commit is contained in:
parent
447c0daf7d
commit
0ad21ab1b8
|
@ -43,7 +43,7 @@
|
||||||
extern const MATRIX gmxWorldToDeviceDefault;
|
extern const MATRIX gmxWorldToDeviceDefault;
|
||||||
extern const MATRIX gmxWorldToPageDefault;
|
extern const MATRIX gmxWorldToPageDefault;
|
||||||
|
|
||||||
// HACK!! Fix XFORMOBJ then use 1:16 / 16:1
|
/* HACK!! Fix XFORMOBJ then use 1:16 / 16:1 */
|
||||||
#define gmxWorldToDeviceDefault gmxWorldToPageDefault
|
#define gmxWorldToDeviceDefault gmxWorldToPageDefault
|
||||||
|
|
||||||
FT_Library library;
|
FT_Library library;
|
||||||
|
@ -201,6 +201,167 @@ static const CHARSETINFO FontTci[MAXTCIINDEX] =
|
||||||
{ SYMBOL_CHARSET, CP_SYMBOL, {{0,0,0,0},{FS_SYMBOL,0}} }
|
{ SYMBOL_CHARSET, CP_SYMBOL, {{0,0,0,0},{FS_SYMBOL,0}} }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FONTSUBST_... --- constants for font substitutes
|
||||||
|
*/
|
||||||
|
#define FONTSUBST_FROM 0
|
||||||
|
#define FONTSUBST_TO 1
|
||||||
|
#define FONTSUBST_FROM_AND_TO 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FONTSUBST_ENTRY --- font substitute entry
|
||||||
|
*/
|
||||||
|
typedef struct FONTSUBST_ENTRY
|
||||||
|
{
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
UNICODE_STRING FontNames[FONTSUBST_FROM_AND_TO];
|
||||||
|
BYTE CharSets[FONTSUBST_FROM_AND_TO];
|
||||||
|
} FONTSUBST_ENTRY, *PFONTSUBST_ENTRY;
|
||||||
|
|
||||||
|
/* list head */
|
||||||
|
static RTL_STATIC_LIST_HEAD(FontSubstListHead);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IntLoadFontSubstList --- loads the list of font substitutes
|
||||||
|
*/
|
||||||
|
BOOL FASTCALL
|
||||||
|
IntLoadFontSubstList(PLIST_ENTRY pHead)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
KEY_FULL_INFORMATION KeyFullInfo;
|
||||||
|
ULONG i, Length;
|
||||||
|
UNICODE_STRING FromW, ToW;
|
||||||
|
BYTE InfoBuffer[128];
|
||||||
|
PKEY_VALUE_FULL_INFORMATION pInfo;
|
||||||
|
BYTE CharSets[FONTSUBST_FROM_AND_TO];
|
||||||
|
LPWSTR pch;
|
||||||
|
PFONTSUBST_ENTRY pEntry;
|
||||||
|
|
||||||
|
/* the FontSubstitutes registry key */
|
||||||
|
static UNICODE_STRING FontSubstKey =
|
||||||
|
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\Software\\"
|
||||||
|
L"Microsoft\\Windows NT\\CurrentVersion\\"
|
||||||
|
L"FontSubstitutes");
|
||||||
|
|
||||||
|
/* open registry key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &FontSubstKey,
|
||||||
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
NULL, NULL);
|
||||||
|
Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwOpenKey failed: 0x%08X\n", Status);
|
||||||
|
return FALSE; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* query count of values */
|
||||||
|
Status = ZwQueryKey(KeyHandle, KeyFullInformation,
|
||||||
|
&KeyFullInfo, sizeof(KeyFullInfo), &Length);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwQueryKey failed: 0x%08X\n", Status);
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
return FALSE; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for each value */
|
||||||
|
for (i = 0; i < KeyFullInfo.Values; ++i)
|
||||||
|
{
|
||||||
|
/* get value name */
|
||||||
|
Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
|
||||||
|
InfoBuffer, sizeof(InfoBuffer), &Length);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwEnumerateValueKey failed: 0x%08X\n", Status);
|
||||||
|
break; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create FromW string */
|
||||||
|
pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
|
||||||
|
Length = pInfo->NameLength / sizeof(WCHAR);
|
||||||
|
pInfo->Name[Length] = UNICODE_NULL; /* truncate */
|
||||||
|
Status = RtlCreateUnicodeString(&FromW, pInfo->Name);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("RtlCreateUnicodeString failed: 0x%08X\n", Status);
|
||||||
|
break; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* query value */
|
||||||
|
Status = ZwQueryValueKey(KeyHandle, &FromW, KeyValueFullInformation,
|
||||||
|
InfoBuffer, sizeof(InfoBuffer), &Length);
|
||||||
|
pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
|
||||||
|
if (!NT_SUCCESS(Status) || !pInfo->DataLength)
|
||||||
|
{
|
||||||
|
DPRINT("ZwQueryValueKey failed: 0x%08X\n", Status);
|
||||||
|
RtlFreeUnicodeString(&FromW);
|
||||||
|
break; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create ToW string */
|
||||||
|
pch = (LPWSTR)((PUCHAR)pInfo + pInfo->DataOffset);
|
||||||
|
Length = pInfo->DataLength / sizeof(WCHAR);
|
||||||
|
pch[Length] = UNICODE_NULL; /* truncate */
|
||||||
|
Status = RtlCreateUnicodeString(&ToW, pch);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("RtlCreateUnicodeString failed: 0x%08X\n", Status);
|
||||||
|
RtlFreeUnicodeString(&FromW);
|
||||||
|
break; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* does charset exist? (from) */
|
||||||
|
CharSets[FONTSUBST_FROM] = DEFAULT_CHARSET;
|
||||||
|
pch = wcsrchr(FromW.Buffer, L',');
|
||||||
|
if (pch)
|
||||||
|
{
|
||||||
|
/* truncate */
|
||||||
|
*pch = UNICODE_NULL;
|
||||||
|
FromW.Length = (pch - FromW.Buffer) * sizeof(WCHAR);
|
||||||
|
/* parse charset number */
|
||||||
|
CharSets[FONTSUBST_FROM] = (BYTE)_wtoi(pch + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* does charset exist? (to) */
|
||||||
|
CharSets[FONTSUBST_TO] = DEFAULT_CHARSET;
|
||||||
|
pch = wcsrchr(ToW.Buffer, L',');
|
||||||
|
if (pch)
|
||||||
|
{
|
||||||
|
/* truncate */
|
||||||
|
*pch = UNICODE_NULL;
|
||||||
|
ToW.Length = (pch - ToW.Buffer) * sizeof(WCHAR);
|
||||||
|
/* parse charset number */
|
||||||
|
CharSets[FONTSUBST_TO] = (BYTE)_wtoi(pch + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate an entry */
|
||||||
|
pEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONTSUBST_ENTRY), TAG_FONT);
|
||||||
|
if (pEntry == NULL)
|
||||||
|
{
|
||||||
|
DPRINT("ExAllocatePoolWithTag failed\n");
|
||||||
|
RtlFreeUnicodeString(&FromW);
|
||||||
|
RtlFreeUnicodeString(&ToW);
|
||||||
|
break; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store to *pEntry */
|
||||||
|
pEntry->FontNames[FONTSUBST_FROM] = FromW;
|
||||||
|
pEntry->FontNames[FONTSUBST_TO] = ToW;
|
||||||
|
pEntry->CharSets[FONTSUBST_FROM] = CharSets[FONTSUBST_FROM];
|
||||||
|
pEntry->CharSets[FONTSUBST_TO] = CharSets[FONTSUBST_TO];
|
||||||
|
|
||||||
|
/* insert pEntry to *pHead */
|
||||||
|
InsertTailList(pHead, &pEntry->ListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close now */
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
|
||||||
|
return NT_SUCCESS(Status);
|
||||||
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
InitFontSupport(VOID)
|
InitFontSupport(VOID)
|
||||||
{
|
{
|
||||||
|
@ -232,6 +393,7 @@ InitFontSupport(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
IntLoadSystemFonts();
|
IntLoadSystemFonts();
|
||||||
|
IntLoadFontSubstList(&FontSubstListHead);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -265,12 +427,114 @@ FtSetCoordinateTransform(
|
||||||
FT_Set_Transform(face, &ftmatrix, 0);
|
FT_Set_Transform(face, &ftmatrix, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
SubstituteFontByList(PLIST_ENTRY pHead,
|
||||||
|
PUNICODE_STRING pOutputName,
|
||||||
|
PUNICODE_STRING pInputName,
|
||||||
|
BYTE RequestedCharSet,
|
||||||
|
BYTE CharSetMap[FONTSUBST_FROM_AND_TO])
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PLIST_ENTRY pListEntry;
|
||||||
|
PFONTSUBST_ENTRY pSubstEntry;
|
||||||
|
BYTE CharSets[FONTSUBST_FROM_AND_TO];
|
||||||
|
|
||||||
|
CharSetMap[FONTSUBST_FROM] = DEFAULT_CHARSET;
|
||||||
|
CharSetMap[FONTSUBST_TO] = RequestedCharSet;
|
||||||
|
|
||||||
|
/* for each list entry */
|
||||||
|
for (pListEntry = pHead->Flink;
|
||||||
|
pListEntry != pHead;
|
||||||
|
pListEntry = pListEntry->Flink)
|
||||||
|
{
|
||||||
|
pSubstEntry =
|
||||||
|
(PFONTSUBST_ENTRY)CONTAINING_RECORD(pListEntry, FONT_ENTRY, ListEntry);
|
||||||
|
|
||||||
|
CharSets[FONTSUBST_FROM] = pSubstEntry->CharSets[FONTSUBST_FROM];
|
||||||
|
|
||||||
|
if (CharSets[FONTSUBST_FROM] != DEFAULT_CHARSET &&
|
||||||
|
CharSets[FONTSUBST_FROM] != RequestedCharSet)
|
||||||
|
{
|
||||||
|
continue; /* not matched */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* does charset number exist? (to) */
|
||||||
|
if (pSubstEntry->CharSets[FONTSUBST_TO] != DEFAULT_CHARSET)
|
||||||
|
{
|
||||||
|
CharSets[FONTSUBST_TO] = pSubstEntry->CharSets[FONTSUBST_TO];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CharSets[FONTSUBST_TO] = RequestedCharSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* does font name match? */
|
||||||
|
if (!RtlEqualUnicodeString(&pSubstEntry->FontNames[FONTSUBST_FROM],
|
||||||
|
pInputName, TRUE))
|
||||||
|
{
|
||||||
|
continue; /* not matched */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update *pOutputName */
|
||||||
|
RtlFreeUnicodeString(pOutputName);
|
||||||
|
Status = RtlCreateUnicodeString(pOutputName,
|
||||||
|
pSubstEntry->FontNames[FONTSUBST_TO].Buffer);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("RtlCreateUnicodeString failed: 0x%08X\n", Status);
|
||||||
|
continue; /* cannot create string */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CharSetMap[FONTSUBST_FROM] == DEFAULT_CHARSET)
|
||||||
|
{
|
||||||
|
/* update CharSetMap */
|
||||||
|
CharSetMap[FONTSUBST_FROM] = CharSets[FONTSUBST_FROM];
|
||||||
|
CharSetMap[FONTSUBST_TO] = CharSets[FONTSUBST_TO];
|
||||||
|
}
|
||||||
|
return TRUE; /* success */
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL
|
||||||
|
SubstituteFontRecurse(PUNICODE_STRING pInOutName, BYTE *pRequestedCharSet)
|
||||||
|
{
|
||||||
|
UINT RecurseCount = 5;
|
||||||
|
UNICODE_STRING OutputNameW = { 0 };
|
||||||
|
BYTE CharSetMap[FONTSUBST_FROM_AND_TO];
|
||||||
|
BOOL Found;
|
||||||
|
|
||||||
|
if (pInOutName->Buffer[0] == UNICODE_NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
while (RecurseCount-- > 0)
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&OutputNameW, NULL);
|
||||||
|
Found = SubstituteFontByList(&FontSubstListHead,
|
||||||
|
&OutputNameW, pInOutName,
|
||||||
|
*pRequestedCharSet, CharSetMap);
|
||||||
|
if (!Found)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* update *pInOutName and *pRequestedCharSet */
|
||||||
|
RtlFreeUnicodeString(pInOutName);
|
||||||
|
*pInOutName = OutputNameW;
|
||||||
|
if (CharSetMap[FONTSUBST_FROM] == DEFAULT_CHARSET ||
|
||||||
|
CharSetMap[FONTSUBST_FROM] == *pRequestedCharSet)
|
||||||
|
{
|
||||||
|
*pRequestedCharSet = CharSetMap[FONTSUBST_TO];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE; /* success */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IntLoadSystemFonts
|
* IntLoadSystemFonts
|
||||||
*
|
*
|
||||||
* Search the system font directory and adds each font found.
|
* Search the system font directory and adds each font found.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
IntLoadSystemFonts(VOID)
|
IntLoadSystemFonts(VOID)
|
||||||
{
|
{
|
||||||
|
@ -3296,7 +3560,6 @@ ftGdiGetTextMetricsW(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
FASTCALL
|
FASTCALL
|
||||||
ftGdiGetFontData(
|
ftGdiGetFontData(
|
||||||
|
@ -3337,73 +3600,13 @@ ftGdiGetFontData(
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline BOOLEAN
|
|
||||||
SubstituteFontNameByKey(PUNICODE_STRING FaceName,
|
|
||||||
LPCWSTR Key)
|
|
||||||
{
|
|
||||||
RTL_QUERY_REGISTRY_TABLE QueryTable[2] = {{0}};
|
|
||||||
NTSTATUS Status;
|
|
||||||
UNICODE_STRING Value;
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&Value, NULL);
|
|
||||||
|
|
||||||
QueryTable[0].QueryRoutine = NULL;
|
|
||||||
QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOEXPAND |
|
|
||||||
RTL_QUERY_REGISTRY_REQUIRED;
|
|
||||||
QueryTable[0].Name = FaceName->Buffer;
|
|
||||||
QueryTable[0].EntryContext = &Value;
|
|
||||||
QueryTable[0].DefaultType = REG_NONE;
|
|
||||||
QueryTable[0].DefaultData = NULL;
|
|
||||||
QueryTable[0].DefaultLength = 0;
|
|
||||||
|
|
||||||
QueryTable[1].QueryRoutine = NULL;
|
|
||||||
QueryTable[1].Name = NULL;
|
|
||||||
|
|
||||||
Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
|
|
||||||
Key,
|
|
||||||
QueryTable,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(FaceName);
|
|
||||||
*FaceName = Value;
|
|
||||||
|
|
||||||
/* truncate */
|
|
||||||
if ((LF_FACESIZE - 1) * sizeof(WCHAR) < FaceName->Length)
|
|
||||||
{
|
|
||||||
FaceName->Length = (LF_FACESIZE - 1) * sizeof(WCHAR);
|
|
||||||
FaceName->Buffer[LF_FACESIZE - 1] = UNICODE_NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NT_SUCCESS(Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline BOOL
|
|
||||||
SubstituteFontName(PUNICODE_STRING FaceName)
|
|
||||||
{
|
|
||||||
UINT Level;
|
|
||||||
const UINT MaxLevel = 10;
|
|
||||||
|
|
||||||
if (FaceName->Buffer[0] == 0)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
for (Level = 0; Level < MaxLevel; ++Level)
|
|
||||||
{
|
|
||||||
/* NOTE: SubstituteFontNameByKey changes FaceName. Be careful... */
|
|
||||||
if (!SubstituteFontNameByKey(FaceName, L"FontSubstitutes"))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return (Level > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: See Table 1. of https://msdn.microsoft.com/en-us/library/ms969909.aspx
|
// NOTE: See Table 1. of https://msdn.microsoft.com/en-us/library/ms969909.aspx
|
||||||
static UINT FASTCALL
|
static UINT FASTCALL
|
||||||
GetFontPenalty(LOGFONTW * LogFont,
|
GetFontPenalty(LOGFONTW * LogFont,
|
||||||
PUNICODE_STRING RequestedNameW,
|
PUNICODE_STRING RequestedNameW,
|
||||||
PUNICODE_STRING ActualNameW,
|
PUNICODE_STRING ActualNameW,
|
||||||
PUNICODE_STRING FullFaceNameW,
|
PUNICODE_STRING FullFaceNameW,
|
||||||
|
BYTE RequestedCharSet,
|
||||||
PFONTGDI FontGDI,
|
PFONTGDI FontGDI,
|
||||||
OUTLINETEXTMETRICW * Otm,
|
OUTLINETEXTMETRICW * Otm,
|
||||||
TEXTMETRICW * TM,
|
TEXTMETRICW * TM,
|
||||||
|
@ -3443,7 +3646,7 @@ GetFontPenalty(LOGFONTW * LogFont,
|
||||||
}
|
}
|
||||||
else /* Request is non-"System" font */
|
else /* Request is non-"System" font */
|
||||||
{
|
{
|
||||||
Byte = LogFont->lfCharSet;
|
Byte = RequestedCharSet;
|
||||||
if (Byte == DEFAULT_CHARSET)
|
if (Byte == DEFAULT_CHARSET)
|
||||||
{
|
{
|
||||||
if (RtlEqualUnicodeString(RequestedNameW, &MarlettW, TRUE))
|
if (RtlEqualUnicodeString(RequestedNameW, &MarlettW, TRUE))
|
||||||
|
@ -3470,12 +3673,12 @@ GetFontPenalty(LOGFONTW * LogFont,
|
||||||
if (UserCharSet != TM->tmCharSet)
|
if (UserCharSet != TM->tmCharSet)
|
||||||
{
|
{
|
||||||
/* UNDOCUMENTED */
|
/* UNDOCUMENTED */
|
||||||
Penalty += 10;
|
Penalty += 100;
|
||||||
}
|
if (ANSI_CHARSET != TM->tmCharSet)
|
||||||
if (ANSI_CHARSET != TM->tmCharSet)
|
{
|
||||||
{
|
/* UNDOCUMENTED */
|
||||||
/* UNDOCUMENTED */
|
Penalty += 100;
|
||||||
Penalty += 10;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3777,7 +3980,8 @@ 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, PLIST_ENTRY Head)
|
PUNICODE_STRING pActualNameW, BYTE RequestedCharSet,
|
||||||
|
PLIST_ENTRY Head)
|
||||||
{
|
{
|
||||||
ULONG Penalty;
|
ULONG Penalty;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -3846,8 +4050,8 @@ FindBestFontFromList(FONTOBJ **FontObj, ULONG *MatchPenalty, LOGFONTW *LogFont,
|
||||||
}
|
}
|
||||||
|
|
||||||
Penalty = GetFontPenalty(LogFont, pRequestedNameW, &ActualNameW,
|
Penalty = GetFontPenalty(LogFont, pRequestedNameW, &ActualNameW,
|
||||||
&FullFaceNameW, FontGDI, Otm, TM,
|
&FullFaceNameW, RequestedCharSet,
|
||||||
Face->style_name);
|
FontGDI, Otm, TM, Face->style_name);
|
||||||
if (*MatchPenalty == 0xFFFFFFFF || Penalty < *MatchPenalty)
|
if (*MatchPenalty == 0xFFFFFFFF || Penalty < *MatchPenalty)
|
||||||
{
|
{
|
||||||
DPRINT("%ls Penalty: %lu\n", FullFaceNameW.Buffer, Penalty);
|
DPRINT("%ls Penalty: %lu\n", FullFaceNameW.Buffer, Penalty);
|
||||||
|
@ -3915,6 +4119,7 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
|
||||||
ULONG MatchPenalty;
|
ULONG MatchPenalty;
|
||||||
LOGFONTW *pLogFont;
|
LOGFONTW *pLogFont;
|
||||||
FT_Face Face;
|
FT_Face Face;
|
||||||
|
BYTE RequestedCharSet;
|
||||||
|
|
||||||
if (!pTextObj)
|
if (!pTextObj)
|
||||||
{
|
{
|
||||||
|
@ -3938,15 +4143,18 @@ TextIntRealizeFont(HFONT FontHandle, PTEXTOBJ pTextObj)
|
||||||
RtlInitUnicodeString(&ActualNameW, NULL);
|
RtlInitUnicodeString(&ActualNameW, NULL);
|
||||||
|
|
||||||
pLogFont = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
|
pLogFont = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
|
||||||
if (! RtlCreateUnicodeString(&RequestedNameW, pLogFont->lfFaceName))
|
if (!RtlCreateUnicodeString(&RequestedNameW, pLogFont->lfFaceName))
|
||||||
{
|
{
|
||||||
if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
|
if (!pTextObj) TEXTOBJ_UnlockText(TextObj);
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Font '%ls' is substituted by: ", RequestedNameW.Buffer);
|
/* substitute */
|
||||||
SubstituteFontName(&RequestedNameW);
|
RequestedCharSet = pLogFont->lfCharSet;
|
||||||
DPRINT("'%ls'.\n", RequestedNameW.Buffer);
|
DPRINT("Font '%ls,%u' is substituted by: ",
|
||||||
|
RequestedNameW.Buffer, RequestedCharSet);
|
||||||
|
SubstituteFontRecurse(&RequestedNameW, &RequestedCharSet);
|
||||||
|
DPRINT("'%ls,%u'.\n", RequestedNameW.Buffer, RequestedCharSet);
|
||||||
|
|
||||||
MatchPenalty = 0xFFFFFFFF;
|
MatchPenalty = 0xFFFFFFFF;
|
||||||
TextObj->Font = NULL;
|
TextObj->Font = NULL;
|
||||||
|
@ -3956,14 +4164,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,
|
&RequestedNameW, &ActualNameW, 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,
|
&RequestedNameW, &ActualNameW, RequestedCharSet,
|
||||||
&FontListHead);
|
&FontListHead);
|
||||||
IntUnLockGlobalFonts;
|
IntUnLockGlobalFonts;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue