mirror of
https://github.com/reactos/reactos.git
synced 2025-05-07 02:41:22 +00:00
[WIN32SS][NTGDI] Registry-based font management (#1816)
CORE-16269 - Add IntGdiAddFontResourceEx function that is extended from IntGdiAddFontResource, in order to add dwFlags parameter. - Add IntLoadFontsInRegistry function that will load the fonts from registry info. - If loading from registry failed, IntLoadSystemFonts will be called. - Use IntLoadFontsInRegistry rather than IntLoadSystemFonts in the OS startup. - Add NameFromCharSet function. - Append " (CharSetName)" to registry value name if not TrueType.
This commit is contained in:
parent
0749a868fc
commit
2b526bceac
3 changed files with 264 additions and 10 deletions
|
@ -62,6 +62,7 @@ typedef struct GDI_LOAD_FONT
|
||||||
DWORD Characteristics;
|
DWORD Characteristics;
|
||||||
UNICODE_STRING RegValueName;
|
UNICODE_STRING RegValueName;
|
||||||
BOOL IsTrueType;
|
BOOL IsTrueType;
|
||||||
|
BYTE CharSet;
|
||||||
PFONT_ENTRY_MEM PrivateEntry;
|
PFONT_ENTRY_MEM PrivateEntry;
|
||||||
} GDI_LOAD_FONT, *PGDI_LOAD_FONT;
|
} GDI_LOAD_FONT, *PGDI_LOAD_FONT;
|
||||||
|
|
||||||
|
|
|
@ -686,7 +686,14 @@ InitFontSupport(VOID)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntLoadSystemFonts();
|
if (!IntLoadFontsInRegistry())
|
||||||
|
{
|
||||||
|
DPRINT1("Fonts registry is empty.\n");
|
||||||
|
|
||||||
|
/* Load font(s) with writing registry */
|
||||||
|
IntLoadSystemFonts();
|
||||||
|
}
|
||||||
|
|
||||||
IntLoadFontSubstList(&g_FontSubstListHead);
|
IntLoadFontSubstList(&g_FontSubstListHead);
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
|
@ -1020,7 +1027,7 @@ IntLoadSystemFonts(VOID)
|
||||||
TempString.MaximumLength = DirInfo->FileNameLength;
|
TempString.MaximumLength = DirInfo->FileNameLength;
|
||||||
RtlCopyUnicodeString(&FileName, &Directory);
|
RtlCopyUnicodeString(&FileName, &Directory);
|
||||||
RtlAppendUnicodeStringToString(&FileName, &TempString);
|
RtlAppendUnicodeStringToString(&FileName, &TempString);
|
||||||
IntGdiAddFontResource(&FileName, 0);
|
IntGdiAddFontResourceEx(&FileName, 0, AFRX_WRITE_REGISTRY);
|
||||||
if (DirInfo->NextEntryOffset == 0)
|
if (DirInfo->NextEntryOffset == 0)
|
||||||
break;
|
break;
|
||||||
DirInfo = (PFILE_DIRECTORY_INFORMATION)((ULONG_PTR)DirInfo + DirInfo->NextEntryOffset);
|
DirInfo = (PFILE_DIRECTORY_INFORMATION)((ULONG_PTR)DirInfo + DirInfo->NextEntryOffset);
|
||||||
|
@ -1316,6 +1323,7 @@ IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont)
|
||||||
if (!Error)
|
if (!Error)
|
||||||
{
|
{
|
||||||
FontGDI->CharSet = WinFNT.charset;
|
FontGDI->CharSet = WinFNT.charset;
|
||||||
|
pLoadFont->CharSet = WinFNT.charset;
|
||||||
}
|
}
|
||||||
IntUnLockFreeType();
|
IntUnLockFreeType();
|
||||||
}
|
}
|
||||||
|
@ -1526,6 +1534,34 @@ Finish:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LPCWSTR FASTCALL
|
||||||
|
NameFromCharSet(BYTE CharSet)
|
||||||
|
{
|
||||||
|
switch (CharSet)
|
||||||
|
{
|
||||||
|
case ANSI_CHARSET: return L"ANSI";
|
||||||
|
case DEFAULT_CHARSET: return L"Default";
|
||||||
|
case SYMBOL_CHARSET: return L"Symbol";
|
||||||
|
case SHIFTJIS_CHARSET: return L"Shift_JIS";
|
||||||
|
case HANGUL_CHARSET: return L"Hangul";
|
||||||
|
case GB2312_CHARSET: return L"GB 2312";
|
||||||
|
case CHINESEBIG5_CHARSET: return L"Chinese Big5";
|
||||||
|
case OEM_CHARSET: return L"OEM";
|
||||||
|
case JOHAB_CHARSET: return L"Johab";
|
||||||
|
case HEBREW_CHARSET: return L"Hebrew";
|
||||||
|
case ARABIC_CHARSET: return L"Arabic";
|
||||||
|
case GREEK_CHARSET: return L"Greek";
|
||||||
|
case TURKISH_CHARSET: return L"Turkish";
|
||||||
|
case VIETNAMESE_CHARSET: return L"Vietnamese";
|
||||||
|
case THAI_CHARSET: return L"Thai";
|
||||||
|
case EASTEUROPE_CHARSET: return L"Eastern European";
|
||||||
|
case RUSSIAN_CHARSET: return L"Russian";
|
||||||
|
case MAC_CHARSET: return L"Mac";
|
||||||
|
case BALTIC_CHARSET: return L"Baltic";
|
||||||
|
default: return L"Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IntGdiAddFontResource
|
* IntGdiAddFontResource
|
||||||
*
|
*
|
||||||
|
@ -1533,7 +1569,8 @@ Finish:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
INT FASTCALL
|
INT FASTCALL
|
||||||
IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
|
IntGdiAddFontResourceEx(PUNICODE_STRING FileName, DWORD Characteristics,
|
||||||
|
DWORD dwFlags)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE FileHandle;
|
HANDLE FileHandle;
|
||||||
|
@ -1588,6 +1625,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
|
||||||
LoadFont.Characteristics = Characteristics;
|
LoadFont.Characteristics = Characteristics;
|
||||||
RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
|
RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
|
||||||
LoadFont.IsTrueType = FALSE;
|
LoadFont.IsTrueType = FALSE;
|
||||||
|
LoadFont.CharSet = DEFAULT_CHARSET;
|
||||||
LoadFont.PrivateEntry = NULL;
|
LoadFont.PrivateEntry = NULL;
|
||||||
FontCount = IntGdiLoadFontsFromMemory(&LoadFont);
|
FontCount = IntGdiLoadFontsFromMemory(&LoadFont);
|
||||||
|
|
||||||
|
@ -1599,15 +1637,15 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
|
||||||
ObDereferenceObject(SectionObject);
|
ObDereferenceObject(SectionObject);
|
||||||
|
|
||||||
/* Save the loaded font name into the registry */
|
/* Save the loaded font name into the registry */
|
||||||
if (FontCount > 0)
|
if (FontCount > 0 && (dwFlags & AFRX_WRITE_REGISTRY))
|
||||||
{
|
{
|
||||||
|
UNICODE_STRING NewString;
|
||||||
|
SIZE_T Length;
|
||||||
|
PWCHAR pszBuffer;
|
||||||
|
LPCWSTR CharSetName;
|
||||||
if (LoadFont.IsTrueType)
|
if (LoadFont.IsTrueType)
|
||||||
{
|
{
|
||||||
/* Append " (TrueType)" */
|
/* Append " (TrueType)" */
|
||||||
UNICODE_STRING NewString;
|
|
||||||
SIZE_T Length;
|
|
||||||
PWCHAR pszBuffer;
|
|
||||||
|
|
||||||
Length = LoadFont.RegValueName.Length + TrueTypePostfix.Length + sizeof(UNICODE_NULL);
|
Length = LoadFont.RegValueName.Length + TrueTypePostfix.Length + sizeof(UNICODE_NULL);
|
||||||
pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR);
|
pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR);
|
||||||
if (pszBuffer)
|
if (pszBuffer)
|
||||||
|
@ -1624,6 +1662,31 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
|
||||||
// FIXME!
|
// FIXME!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (LoadFont.CharSet != DEFAULT_CHARSET)
|
||||||
|
{
|
||||||
|
/* Append " (CharSetName)" */
|
||||||
|
CharSetName = NameFromCharSet(LoadFont.CharSet);
|
||||||
|
Length = LoadFont.RegValueName.Length +
|
||||||
|
(wcslen(CharSetName) + 3) * sizeof(WCHAR) +
|
||||||
|
sizeof(UNICODE_NULL);
|
||||||
|
|
||||||
|
pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR);
|
||||||
|
if (pszBuffer)
|
||||||
|
{
|
||||||
|
RtlInitEmptyUnicodeString(&NewString, pszBuffer, (USHORT)Length);
|
||||||
|
NewString.Buffer[0] = UNICODE_NULL;
|
||||||
|
RtlAppendUnicodeStringToString(&NewString, &LoadFont.RegValueName);
|
||||||
|
RtlAppendUnicodeToString(&NewString, L" (");
|
||||||
|
RtlAppendUnicodeToString(&NewString, CharSetName);
|
||||||
|
RtlAppendUnicodeToString(&NewString, L")");
|
||||||
|
RtlFreeUnicodeString(&LoadFont.RegValueName);
|
||||||
|
LoadFont.RegValueName = NewString;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// FIXME!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &g_FontRegPath,
|
InitializeObjectAttributes(&ObjectAttributes, &g_FontRegPath,
|
||||||
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
|
||||||
|
@ -1632,10 +1695,23 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
SIZE_T DataSize;
|
SIZE_T DataSize;
|
||||||
LPWSTR pFileName = wcsrchr(FileName->Buffer, L'\\');
|
LPWSTR pFileName;
|
||||||
|
|
||||||
|
if (dwFlags & AFRX_ALTERNATIVE_PATH)
|
||||||
|
{
|
||||||
|
pFileName = FileName->Buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pFileName = wcsrchr(FileName->Buffer, L'\\');
|
||||||
|
}
|
||||||
|
|
||||||
if (pFileName)
|
if (pFileName)
|
||||||
{
|
{
|
||||||
pFileName++;
|
if (!(dwFlags & AFRX_ALTERNATIVE_PATH))
|
||||||
|
{
|
||||||
|
pFileName++;
|
||||||
|
}
|
||||||
DataSize = (wcslen(pFileName) + 1) * sizeof(WCHAR);
|
DataSize = (wcslen(pFileName) + 1) * sizeof(WCHAR);
|
||||||
ZwSetValueKey(KeyHandle, &LoadFont.RegValueName, 0, REG_SZ,
|
ZwSetValueKey(KeyHandle, &LoadFont.RegValueName, 0, REG_SZ,
|
||||||
pFileName, DataSize);
|
pFileName, DataSize);
|
||||||
|
@ -1648,6 +1724,177 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
|
||||||
return FontCount;
|
return FontCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INT FASTCALL
|
||||||
|
IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
|
||||||
|
{
|
||||||
|
return IntGdiAddFontResourceEx(FileName, Characteristics, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Borrowed from shlwapi!PathIsRelativeW */
|
||||||
|
BOOL WINAPI PathIsRelativeW(LPCWSTR lpszPath)
|
||||||
|
{
|
||||||
|
if (!lpszPath || !*lpszPath)
|
||||||
|
return TRUE;
|
||||||
|
if (*lpszPath == L'\\' || (*lpszPath && lpszPath[1] == L':'))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL FASTCALL
|
||||||
|
IntLoadFontsInRegistry(VOID)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE KeyHandle;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
KEY_FULL_INFORMATION KeyFullInfo;
|
||||||
|
ULONG i, Length;
|
||||||
|
UNICODE_STRING FontTitleW, FileNameW;
|
||||||
|
SIZE_T InfoSize;
|
||||||
|
LPBYTE InfoBuffer;
|
||||||
|
PKEY_VALUE_FULL_INFORMATION pInfo;
|
||||||
|
LPWSTR pchPath;
|
||||||
|
BOOLEAN Success;
|
||||||
|
WCHAR szPath[MAX_PATH];
|
||||||
|
INT nFontCount = 0;
|
||||||
|
DWORD dwFlags;
|
||||||
|
|
||||||
|
/* open registry key */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &g_FontRegPath,
|
||||||
|
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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate buffer */
|
||||||
|
InfoSize = (MAX_PATH + 256) * sizeof(WCHAR);
|
||||||
|
InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
|
||||||
|
if (!InfoBuffer)
|
||||||
|
{
|
||||||
|
DPRINT1("ExAllocatePoolWithTag failed\n");
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for each value */
|
||||||
|
for (i = 0; i < KeyFullInfo.Values; ++i)
|
||||||
|
{
|
||||||
|
/* get value name */
|
||||||
|
Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
|
||||||
|
InfoBuffer, InfoSize, &Length);
|
||||||
|
if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
|
||||||
|
{
|
||||||
|
/* too short buffer */
|
||||||
|
ExFreePoolWithTag(InfoBuffer, TAG_FONT);
|
||||||
|
InfoSize *= 2;
|
||||||
|
InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
|
||||||
|
if (!InfoBuffer)
|
||||||
|
{
|
||||||
|
DPRINT1("ExAllocatePoolWithTag failed\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* try again */
|
||||||
|
Status = ZwEnumerateValueKey(KeyHandle, i, KeyValueFullInformation,
|
||||||
|
InfoBuffer, InfoSize, &Length);
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT("ZwEnumerateValueKey failed: 0x%08X\n", Status);
|
||||||
|
break; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create FontTitleW string */
|
||||||
|
pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
|
||||||
|
Length = pInfo->NameLength / sizeof(WCHAR);
|
||||||
|
pInfo->Name[Length] = UNICODE_NULL; /* truncate */
|
||||||
|
Success = RtlCreateUnicodeString(&FontTitleW, pInfo->Name);
|
||||||
|
if (!Success)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
DPRINT("RtlCreateUnicodeString failed\n");
|
||||||
|
break; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* query value */
|
||||||
|
Status = ZwQueryValueKey(KeyHandle, &FontTitleW, KeyValueFullInformation,
|
||||||
|
InfoBuffer, InfoSize, &Length);
|
||||||
|
if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
|
||||||
|
{
|
||||||
|
/* too short buffer */
|
||||||
|
ExFreePoolWithTag(InfoBuffer, TAG_FONT);
|
||||||
|
InfoSize *= 2;
|
||||||
|
InfoBuffer = ExAllocatePoolWithTag(PagedPool, InfoSize, TAG_FONT);
|
||||||
|
if (!InfoBuffer)
|
||||||
|
{
|
||||||
|
DPRINT1("ExAllocatePoolWithTag failed\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* try again */
|
||||||
|
Status = ZwQueryValueKey(KeyHandle, &FontTitleW, KeyValueFullInformation,
|
||||||
|
InfoBuffer, InfoSize, &Length);
|
||||||
|
}
|
||||||
|
pInfo = (PKEY_VALUE_FULL_INFORMATION)InfoBuffer;
|
||||||
|
if (!NT_SUCCESS(Status) || !pInfo->DataLength)
|
||||||
|
{
|
||||||
|
DPRINT("ZwQueryValueKey failed: 0x%08X\n", Status);
|
||||||
|
RtlFreeUnicodeString(&FontTitleW);
|
||||||
|
break; /* failure */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build pchPath */
|
||||||
|
pchPath = (LPWSTR)((PUCHAR)pInfo + pInfo->DataOffset);
|
||||||
|
Length = pInfo->DataLength / sizeof(WCHAR);
|
||||||
|
pchPath[Length] = UNICODE_NULL; /* truncate */
|
||||||
|
|
||||||
|
/* Load font(s) without writing registry */
|
||||||
|
dwFlags = 0;
|
||||||
|
if (PathIsRelativeW(pchPath))
|
||||||
|
{
|
||||||
|
Status = RtlStringCbPrintfW(szPath, sizeof(szPath),
|
||||||
|
L"%s\\Fonts\\%s",
|
||||||
|
SharedUserData->NtSystemRoot, pchPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dwFlags |= AFRX_ALTERNATIVE_PATH;
|
||||||
|
Status = RtlStringCbCopyW(szPath, sizeof(szPath), pchPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
RtlCreateUnicodeString(&FileNameW, szPath);
|
||||||
|
nFontCount += IntGdiAddFontResourceEx(&FileNameW, 0, dwFlags);
|
||||||
|
RtlFreeUnicodeString(&FileNameW);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlFreeUnicodeString(&FontTitleW);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close now */
|
||||||
|
ZwClose(KeyHandle);
|
||||||
|
|
||||||
|
/* free memory block */
|
||||||
|
if (InfoBuffer)
|
||||||
|
{
|
||||||
|
ExFreePoolWithTag(InfoBuffer, TAG_FONT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (KeyFullInfo.Values != 0 && nFontCount != 0);
|
||||||
|
}
|
||||||
|
|
||||||
HANDLE FASTCALL
|
HANDLE FASTCALL
|
||||||
IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded)
|
IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded)
|
||||||
{
|
{
|
||||||
|
|
|
@ -100,6 +100,9 @@ TEXTOBJ_UnlockText(PLFONT plfnt)
|
||||||
LFONT_ShareUnlockFont(plfnt);
|
LFONT_ShareUnlockFont(plfnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* dwFlags for IntGdiAddFontResourceEx */
|
||||||
|
#define AFRX_WRITE_REGISTRY 0x1
|
||||||
|
#define AFRX_ALTERNATIVE_PATH 0x2
|
||||||
|
|
||||||
PTEXTOBJ FASTCALL RealizeFontInit(HFONT);
|
PTEXTOBJ FASTCALL RealizeFontInit(HFONT);
|
||||||
NTSTATUS FASTCALL TextIntRealizeFont(HFONT,PTEXTOBJ);
|
NTSTATUS FASTCALL TextIntRealizeFont(HFONT,PTEXTOBJ);
|
||||||
|
@ -111,8 +114,11 @@ BOOL FASTCALL IntIsFontRenderingEnabled(VOID);
|
||||||
VOID FASTCALL IntEnableFontRendering(BOOL Enable);
|
VOID FASTCALL IntEnableFontRendering(BOOL Enable);
|
||||||
ULONG FASTCALL FontGetObject(PTEXTOBJ TextObj, ULONG Count, PVOID Buffer);
|
ULONG FASTCALL FontGetObject(PTEXTOBJ TextObj, ULONG Count, PVOID Buffer);
|
||||||
VOID FASTCALL IntLoadSystemFonts(VOID);
|
VOID FASTCALL IntLoadSystemFonts(VOID);
|
||||||
|
BOOL FASTCALL IntLoadFontsInRegistry(VOID);
|
||||||
VOID FASTCALL IntGdiCleanupPrivateFontsForProcess(VOID);
|
VOID FASTCALL IntGdiCleanupPrivateFontsForProcess(VOID);
|
||||||
INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics);
|
INT FASTCALL IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics);
|
||||||
|
INT FASTCALL IntGdiAddFontResourceEx(PUNICODE_STRING FileName, DWORD Characteristics,
|
||||||
|
DWORD dwFlags);
|
||||||
HANDLE FASTCALL IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded);
|
HANDLE FASTCALL IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded);
|
||||||
BOOL FASTCALL IntGdiRemoveFontMemResource(HANDLE hMMFont);
|
BOOL FASTCALL IntGdiRemoveFontMemResource(HANDLE hMMFont);
|
||||||
ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL);
|
ULONG FASTCALL ftGdiGetGlyphOutline(PDC,WCHAR,UINT,LPGLYPHMETRICS,ULONG,PVOID,LPMAT2,BOOL);
|
||||||
|
|
Loading…
Reference in a new issue