https://git.reactos.org/?p=reactos.git;a=commitdiff;h=99ba7ea95ffd9dda07f52…
commit 99ba7ea95ffd9dda07f524b651c03edf15bd296f
Author: Joachim Henze <Joachim.Henze(a)reactos.org>
AuthorDate: Sun Feb 23 12:23:05 2020 +0100
Commit: Joachim Henze <Joachim.Henze(a)reactos.org>
CommitDate: Sun Feb 23 12:23:05 2020 +0100
[FREETYPE] Fix regression fonts in Adobe Photoshop CS2 menu CORE-16694
By Reverting beginnings of raster-fonts-works (*.fnt and *.fon)
Thanks Katayama Hirofumi MZ for helping with this revert.
The regression was introduced by 0.4.13-dev-681-g
ae99df1675f87db87377ce4bf1f78181b1b4be95
I will also port this revert back into 0.4.13-RC
---
win32ss/gdi/ntgdi/freetype.c | 627 ++++++++++++++++++-------------------------
1 file changed, 261 insertions(+), 366 deletions(-)
diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c
index e94534b2b5e..65bda368626 100644
--- a/win32ss/gdi/ntgdi/freetype.c
+++ b/win32ss/gdi/ntgdi/freetype.c
@@ -1077,450 +1077,345 @@ UINT FASTCALL IntGetCharSet(INT nIndex, FT_ULong
CodePageRange1)
#define PX2PT(pixels) FT_MulDiv((pixels), 72, 96)
static INT FASTCALL
-IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont)
+IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
+ PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex)
{
FT_Error Error;
PFONT_ENTRY Entry;
- PFONT_ENTRY_MEM PrivateEntry;
- PFONTGDI FontGDI;
- FT_Face Face;
+ FONT_ENTRY_MEM* PrivateEntry = NULL;
+ FONTGDI * FontGDI;
NTSTATUS Status;
+ FT_Face Face;
ANSI_STRING AnsiString;
FT_WinFNT_HeaderRec WinFNT;
+ INT FaceCount = 0, CharSetCount = 0;
PUNICODE_STRING pFileName = pLoadFont->pFileName;
DWORD Characteristics = pLoadFont->Characteristics;
PUNICODE_STRING pValueName = &pLoadFont->RegValueName;
TT_OS2 * pOS2;
+ INT BitIndex;
+ FT_UShort os2_version;
FT_ULong os2_ulCodePageRange1;
- PSHARED_FACE SharedFace;
- INT iCharSet, CharSetCount;
- FT_Long iFace, FaceCount;
- LIST_ENTRY LoadedFontList;
- USHORT NameLength;
- SIZE_T Length;
- PWCHAR pszBuffer;
- UNICODE_STRING NewString;
- WCHAR szSize[32];
-
- /* Retrieve the number of faces */
- IntLockFreeType();
- Error = FT_New_Memory_Face(g_FreeTypeLibrary,
- pLoadFont->Memory->Buffer,
- pLoadFont->Memory->BufferSize,
- -1,
- &Face);
- if (!Error)
+ FT_UShort os2_usWeightClass;
+
+ if (SharedFace == NULL && CharSetIndex == -1)
{
- FaceCount = Face->num_faces;
- FT_Done_Face(Face);
+ /* load a face from memory */
+ IntLockFreeType();
+ Error = FT_New_Memory_Face(
+ g_FreeTypeLibrary,
+ pLoadFont->Memory->Buffer,
+ pLoadFont->Memory->BufferSize,
+ ((FontIndex != -1) ? FontIndex : 0),
+ &Face);
+
+ if (!Error)
+ SharedFace = SharedFace_Create(Face, pLoadFont->Memory);
+
+ IntUnLockFreeType();
+
+ if (!Error && FT_IS_SFNT(Face))
+ pLoadFont->IsTrueType = TRUE;
+
+ if (Error || SharedFace == NULL)
+ {
+ if (SharedFace)
+ SharedFace_Release(SharedFace);
+
+ if (Error == FT_Err_Unknown_File_Format)
+ DPRINT1("Unknown font file format\n");
+ else
+ DPRINT1("Error reading font (error code: %d)\n", Error);
+ return 0; /* failure */
+ }
+ }
+ else
+ {
+ Face = SharedFace->Face;
+ IntLockFreeType();
+ SharedFace_AddRef(SharedFace);
+ IntUnLockFreeType();
}
- IntUnLockFreeType();
- if (Error)
+ /* allocate a FONT_ENTRY */
+ Entry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY), TAG_FONT);
+ if (!Entry)
{
- UNICODE_STRING MemoryFont = RTL_CONSTANT_STRING(L"MemoryFont");
- PUNICODE_STRING PrintFile = pFileName ? pFileName : &MemoryFont;
- if (Error == FT_Err_Unknown_File_Format)
- DPRINT1("Unknown font file format (%wZ)\n", PrintFile);
- else
- DPRINT1("Error reading font (FT_Error: %d, %wZ)\n", Error,
PrintFile);
+ SharedFace_Release(SharedFace);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0; /* failure */
}
- /*
- * Initialize the temporary font list that needs to be appended to the
- * global or per-process font table, in case font enumeration successes.
- * If an error happens while loading and enumerating the fonts, this list
- * is used to cleanup the allocated resources.
- */
- InitializeListHead(&LoadedFontList);
-
- /*
- * Enumerate each typeface in the font.
- */
- for (iFace = 0; iFace < FaceCount; ++iFace)
+ /* allocate a FONTGDI */
+ FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT);
+ if (!FontGDI)
{
- Face = NULL;
- SharedFace = NULL;
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return 0; /* failure */
+ }
- IntLockFreeType();
- Error = FT_New_Memory_Face(g_FreeTypeLibrary,
- pLoadFont->Memory->Buffer,
- pLoadFont->Memory->BufferSize,
- iFace,
- &Face);
- if (!Error)
+ /* set file name */
+ if (pFileName)
+ {
+ FontGDI->Filename = ExAllocatePoolWithTag(PagedPool,
+ pFileName->Length +
sizeof(UNICODE_NULL),
+ GDITAG_PFF);
+ if (FontGDI->Filename == NULL)
{
- SharedFace = SharedFace_Create(Face, pLoadFont->Memory);
+ EngFreeMem(FontGDI);
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return 0; /* failure */
}
- IntUnLockFreeType();
- if (Error || !SharedFace)
+ RtlCopyMemory(FontGDI->Filename, pFileName->Buffer, pFileName->Length);
+ FontGDI->Filename[pFileName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+ }
+ else
+ {
+ FontGDI->Filename = NULL;
+
+ PrivateEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_MEM),
TAG_FONT);
+ if (!PrivateEntry)
{
- DPRINT1("Error reading font (FT_Error: %d)\n", Error);
- goto Finish; /* failure */
+ if (FontGDI->Filename)
+ ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
+ EngFreeMem(FontGDI);
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ return 0;
}
- /* os2_ulCodePageRange1 and CharSetCount and IsTrueType */
- os2_ulCodePageRange1 = 0;
- if (FT_IS_SFNT(Face))
+ PrivateEntry->Entry = Entry;
+ if (pLoadFont->PrivateEntry)
{
- IntLockFreeType();
- pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
- if (pOS2)
- {
- os2_ulCodePageRange1 = pOS2->ulCodePageRange1;
- }
- IntUnLockFreeType();
-
- CharSetCount = IntGetCharSet(-1, os2_ulCodePageRange1);
- pLoadFont->IsTrueType = TRUE;
+ InsertTailList(&pLoadFont->PrivateEntry->ListEntry,
&PrivateEntry->ListEntry);
}
else
{
- CharSetCount = 1;
- pLoadFont->IsTrueType = FALSE;
+ InitializeListHead(&PrivateEntry->ListEntry);
+ pLoadFont->PrivateEntry = PrivateEntry;
}
+ }
- /*
- * Enumerate all supported character sets for the selected typeface.
- */
- for (iCharSet = 0; iCharSet < CharSetCount; ++iCharSet)
- {
- /*
- * Add a reference to SharedFace only when iCharSet is > 0,
- * since the first reference has been already done by the
- * SharedFace_Create() call above.
- */
- if (iCharSet > 0)
- {
- IntLockFreeType();
- SharedFace_AddRef(SharedFace);
- IntUnLockFreeType();
- }
-
- /* Allocate a FONT_ENTRY */
- Entry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY), TAG_FONT);
- if (!Entry)
- {
- DPRINT1("Failed to allocate FONT_ENTRY\n");
- SharedFace_Release(SharedFace);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto Finish; /* failure */
- }
-
- /* Allocate a FONTGDI */
- FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT);
- if (!FontGDI)
- {
- DPRINT1("Failed to allocate FontGDI\n");
- SharedFace_Release(SharedFace);
- ExFreePoolWithTag(Entry, TAG_FONT);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto Finish; /* failure */
- }
-
- /* Set face */
- FontGDI->SharedFace = SharedFace;
- FontGDI->CharSet = ANSI_CHARSET;
- FontGDI->OriginalItalic = FALSE;
- FontGDI->RequestItalic = FALSE;
- FontGDI->OriginalWeight = FW_NORMAL;
- FontGDI->RequestWeight = FW_NORMAL;
+ /* set face */
+ FontGDI->SharedFace = SharedFace;
+ FontGDI->CharSet = ANSI_CHARSET;
+ FontGDI->OriginalItalic = FALSE;
+ FontGDI->RequestItalic = FALSE;
+ FontGDI->OriginalWeight = FALSE;
+ FontGDI->RequestWeight = FW_NORMAL;
- IntLockFreeType();
- if (FT_IS_SFNT(Face))
- {
- pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
- if (pOS2)
- {
- FontGDI->OriginalItalic = !!(pOS2->fsSelection & 0x1);
- FontGDI->OriginalWeight = pOS2->usWeightClass;
- }
- }
- else
- {
- Error = FT_Get_WinFNT_Header(Face, &WinFNT);
- if (!Error)
- {
- FontGDI->OriginalItalic = !!WinFNT.italic;
- FontGDI->OriginalWeight = WinFNT.weight;
- }
- }
- IntUnLockFreeType();
+ IntLockFreeType();
+ pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
+ if (pOS2)
+ {
+ FontGDI->OriginalItalic = !!(pOS2->fsSelection & 0x1);
+ FontGDI->OriginalWeight = pOS2->usWeightClass;
+ }
+ else
+ {
+ Error = FT_Get_WinFNT_Header(Face, &WinFNT);
+ if (!Error)
+ {
+ FontGDI->OriginalItalic = !!WinFNT.italic;
+ FontGDI->OriginalWeight = WinFNT.weight;
+ }
+ }
+ IntUnLockFreeType();
- /* Entry->FaceName */
- RtlInitAnsiString(&AnsiString, Face->family_name);
- Status = RtlAnsiStringToUnicodeString(&Entry->FaceName,
&AnsiString, TRUE);
+ RtlInitAnsiString(&AnsiString, Face->family_name);
+ Status = RtlAnsiStringToUnicodeString(&Entry->FaceName, &AnsiString,
TRUE);
+ if (NT_SUCCESS(Status))
+ {
+ if (Face->style_name && Face->style_name[0] &&
+ strcmp(Face->style_name, "Regular") != 0)
+ {
+ RtlInitAnsiString(&AnsiString, Face->style_name);
+ Status = RtlAnsiStringToUnicodeString(&Entry->StyleName,
&AnsiString, TRUE);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Failed to allocate Entry->FaceName\n");
- CleanupFontEntryEx(Entry, FontGDI);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto Finish; /* failure */
+ RtlFreeUnicodeString(&Entry->FaceName);
}
-
- /* Entry->StyleName */
+ }
+ else
+ {
RtlInitUnicodeString(&Entry->StyleName, NULL);
- if (Face->style_name && Face->style_name[0] &&
- strcmp(Face->style_name, "Regular") != 0)
- {
- RtlInitAnsiString(&AnsiString, Face->style_name);
- Status = RtlAnsiStringToUnicodeString(&Entry->StyleName,
&AnsiString, TRUE);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to allocate Entry->StyleName\n");
- CleanupFontEntryEx(Entry, FontGDI);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto Finish; /* failure */
- }
- }
-
- /* FontGDI->CharSet */
- if (FT_IS_SFNT(Face))
+ }
+ }
+ if (!NT_SUCCESS(Status))
+ {
+ if (PrivateEntry)
+ {
+ if (pLoadFont->PrivateEntry == PrivateEntry)
{
- FontGDI->CharSet = IntGetCharSet(iCharSet, os2_ulCodePageRange1);
+ pLoadFont->PrivateEntry = NULL;
}
else
{
- IntLockFreeType();
- Error = FT_Get_WinFNT_Header(Face, &WinFNT);
- if (!Error)
- {
- FontGDI->CharSet = WinFNT.charset;
- pLoadFont->CharSet = WinFNT.charset;
- }
- IntUnLockFreeType();
+ RemoveEntryList(&PrivateEntry->ListEntry);
}
+ ExFreePoolWithTag(PrivateEntry, TAG_FONT);
+ }
+ if (FontGDI->Filename)
+ ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
+ EngFreeMem(FontGDI);
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ return 0;
+ }
- /* Set the file name */
- if (pFileName)
- {
- // TODO: Since this Filename is common to all the faces+charsets
- // inside the given font, it may be worth to somehow cache it
- // only once and share it amongst all these faces+charsets.
+ os2_version = 0;
+ IntLockFreeType();
+ pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
+ if (pOS2)
+ {
+ os2_version = pOS2->version;
+ os2_ulCodePageRange1 = pOS2->ulCodePageRange1;
+ os2_usWeightClass = pOS2->usWeightClass;
+ }
+ IntUnLockFreeType();
- Length = pFileName->Length + sizeof(UNICODE_NULL);
- FontGDI->Filename = ExAllocatePoolWithTag(PagedPool, Length,
GDITAG_PFF);
- if (FontGDI->Filename == NULL)
- {
- DPRINT1("Failed to allocate FontGDI->Filename\n");
- CleanupFontEntryEx(Entry, FontGDI);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto Finish; /* failure */
- }
- IntUnicodeStringToBuffer(FontGDI->Filename, Length, pFileName);
- }
- else
- {
- /* This is a memory font, initialize a suitable entry */
+ if (pOS2 && os2_version >= 1)
+ {
+ /* get charset and weight from OS/2 header */
- FontGDI->Filename = NULL;
+ /* Make sure we do not use this pointer anymore */
+ pOS2 = NULL;
- PrivateEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_MEM),
TAG_FONT);
- if (!PrivateEntry)
- {
- DPRINT1("Failed to allocate PrivateEntry\n");
- CleanupFontEntryEx(Entry, FontGDI);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- goto Finish; /* failure */
- }
+ for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
+ {
+ if (os2_ulCodePageRange1 & (1 << BitIndex))
+ {
+ if (g_FontTci[BitIndex].ciCharset == DEFAULT_CHARSET)
+ continue;
- PrivateEntry->Entry = Entry;
- if (pLoadFont->PrivateEntry)
- {
- InsertTailList(&pLoadFont->PrivateEntry->ListEntry,
&PrivateEntry->ListEntry);
- }
- else
+ if ((CharSetIndex == -1 && CharSetCount == 0) ||
+ CharSetIndex == CharSetCount)
{
- InitializeListHead(&PrivateEntry->ListEntry);
- pLoadFont->PrivateEntry = PrivateEntry;
+ FontGDI->CharSet = g_FontTci[BitIndex].ciCharset;
}
- }
- /* Add this font resource to the font table */
- Entry->Font = FontGDI;
- Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
- InsertTailList(&LoadedFontList, &Entry->ListEntry);
-
- DPRINT("Font loaded: %s (%s), CharSet %u, Num glyphs %d\n",
- Face->family_name, Face->style_name, FontGDI->CharSet,
Face->num_glyphs);
+ ++CharSetCount;
+ }
}
+ /* set actual weight */
+ FontGDI->OriginalWeight = os2_usWeightClass;
+ }
+ else
+ {
+ /* get charset from WinFNT header */
IntLockFreeType();
- /* Error = */ IntRequestFontSize(NULL, FontGDI, 0, 0);
+ Error = FT_Get_WinFNT_Header(Face, &WinFNT);
+ if (!Error)
+ {
+ FontGDI->CharSet = WinFNT.charset;
+ }
IntUnLockFreeType();
+ }
- /*
- * Initialize and build the registry font value entry,
- * only in the case we load fonts from a file and not from memory.
- */
- if (!pFileName)
- continue;
- NameLength = Entry->FaceName.Length;
- if (pValueName->Length == 0)
- {
- if (FT_IS_SFNT(Face))
- {
- // L"Name StyleName\0"
- Length = NameLength + sizeof(L' ') + Entry->StyleName.Length +
sizeof(UNICODE_NULL);
- pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR);
- if (pszBuffer)
- {
- RtlInitEmptyUnicodeString(pValueName, pszBuffer, Length);
- RtlCopyUnicodeString(pValueName, &Entry->FaceName);
- if (Entry->StyleName.Length > 0)
- {
- RtlAppendUnicodeToString(pValueName, L" ");
- RtlAppendUnicodeStringToString(pValueName,
&Entry->StyleName);
- }
- }
- else
- {
- break; /* failure */
- }
- }
- else
- {
- szSize[0] = L' ';
- _itow(PX2PT(FontGDI->EmHeight), szSize+1, 10);
+ ++FaceCount;
+ DPRINT("Font loaded: %s (%s)\n",
+ Face->family_name ? Face->family_name : "<NULL>",
+ Face->style_name ? Face->style_name : "<NULL>");
+ DPRINT("Num glyphs: %d\n", Face->num_glyphs);
+ DPRINT("CharSet: %d\n", FontGDI->CharSet);
- Length = NameLength + (wcslen(szSize) + 1) * sizeof(WCHAR);
- pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR);
- if (pszBuffer)
- {
- RtlInitEmptyUnicodeString(pValueName, pszBuffer, Length);
- RtlCopyUnicodeString(pValueName, &Entry->FaceName);
- RtlAppendUnicodeToString(pValueName, szSize);
- }
- else
- {
- break; /* failure */
- }
- }
- }
- else
+ IntLockFreeType();
+ IntRequestFontSize(NULL, FontGDI, 0, 0);
+ IntUnLockFreeType();
+
+ /* Add this font resource to the font table */
+ Entry->Font = FontGDI;
+ Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
+
+ if (Characteristics & FR_PRIVATE)
+ {
+ /* private font */
+ PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
+ IntLockProcessPrivateFonts(Win32Process);
+ InsertTailList(&Win32Process->PrivateFontListHead,
&Entry->ListEntry);
+ IntUnLockProcessPrivateFonts(Win32Process);
+ }
+ else
+ {
+ /* global font */
+ IntLockGlobalFonts();
+ InsertTailList(&g_FontListHead, &Entry->ListEntry);
+ IntUnLockGlobalFonts();
+ }
+
+ if (FontIndex == -1)
+ {
+ if (FT_IS_SFNT(Face))
{
- if (FT_IS_SFNT(Face))
- {
- // L"... & Name StyleName\0"
- Length = pValueName->Length + 3 * sizeof(WCHAR) +
Entry->FaceName.Length +
- sizeof(L' ') + Entry->StyleName.Length +
sizeof(UNICODE_NULL);
- pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR);
- if (pszBuffer)
- {
- RtlInitEmptyUnicodeString(&NewString, pszBuffer, Length);
- RtlCopyUnicodeString(&NewString, pValueName);
- RtlAppendUnicodeToString(&NewString, L" & ");
- RtlAppendUnicodeStringToString(&NewString,
&Entry->FaceName);
- if (Entry->StyleName.Length > 0)
- {
- RtlAppendUnicodeToString(&NewString, L" ");
- RtlAppendUnicodeStringToString(&NewString,
&Entry->StyleName);
- }
- }
- else
- {
- RtlFreeUnicodeString(pValueName);
- break; /* failure */
- }
- }
- else
+ TT_Face TrueType = (TT_Face)Face;
+ if (TrueType->ttc_header.count > 1)
{
- szSize[0] = L',';
- _itow(PX2PT(FontGDI->EmHeight), szSize+1, 10);
-
- Length = pValueName->Length + (wcslen(szSize) + 1) * sizeof(WCHAR);
- pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR);
- if (pszBuffer)
- {
- RtlInitEmptyUnicodeString(&NewString, pszBuffer, Length);
- RtlCopyUnicodeString(&NewString, pValueName);
- RtlAppendUnicodeToString(&NewString, szSize);
- }
- else
+ FT_Long i;
+ for (i = 1; i < TrueType->ttc_header.count; ++i)
{
- RtlFreeUnicodeString(pValueName);
- break; /* failure */
+ FaceCount += IntGdiLoadFontsFromMemory(pLoadFont, NULL, i, -1);
}
}
-
- RtlFreeUnicodeString(pValueName);
- *pValueName = NewString;
}
+ FontIndex = 0;
}
-Finish:
- if (iFace == FaceCount)
+ if (CharSetIndex == -1)
{
- /*
- * We succeeded, append the created font entries into the correct font table.
- */
- PLIST_ENTRY ListToAppend;
-
- /* No typefaces were present */
- if (FaceCount == 0)
- {
- ASSERT(IsListEmpty(&LoadedFontList));
- return 0;
- }
+ INT i;
+ USHORT NameLength = Entry->FaceName.Length;
- ASSERT(!IsListEmpty(&LoadedFontList));
+ if (Entry->StyleName.Length)
+ NameLength += Entry->StyleName.Length + sizeof(WCHAR);
- /*
- * Remove the temporary font list' head and reinitialize it.
- * This effectively empties the list and at the same time transforms
- * 'ListToAppend' into a headless list, ready to be appended to the
- * suitable font table.
- */
- ListToAppend = LoadedFontList.Flink;
- RemoveEntryList(&LoadedFontList);
- InitializeListHead(&LoadedFontList);
-
- if (Characteristics & FR_PRIVATE)
+ if (pLoadFont->RegValueName.Length == 0)
{
- /* Private font */
- PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
- IntLockProcessPrivateFonts(Win32Process);
- AppendTailList(&Win32Process->PrivateFontListHead, ListToAppend);
- IntUnLockProcessPrivateFonts(Win32Process);
+ pValueName->Length = 0;
+ pValueName->MaximumLength = NameLength + sizeof(WCHAR);
+ pValueName->Buffer = ExAllocatePoolWithTag(PagedPool,
+ pValueName->MaximumLength,
+ TAG_USTR);
+ pValueName->Buffer[0] = UNICODE_NULL;
+ RtlAppendUnicodeStringToString(pValueName, &Entry->FaceName);
}
else
{
- /* Global font */
- IntLockGlobalFonts();
- AppendTailList(&g_FontListHead, ListToAppend);
- IntUnLockGlobalFonts();
- }
+ UNICODE_STRING NewString;
+ USHORT Length = pValueName->Length + 3 * sizeof(WCHAR) + NameLength;
+ NewString.Length = 0;
+ NewString.MaximumLength = Length + sizeof(WCHAR);
+ NewString.Buffer = ExAllocatePoolWithTag(PagedPool,
+ NewString.MaximumLength,
+ TAG_USTR);
+ NewString.Buffer[0] = UNICODE_NULL;
- return FaceCount; /* Number of loaded faces */
- }
- else
- {
- /* We failed, cleanup the resources */
- PLIST_ENTRY ListEntry;
+ RtlAppendUnicodeStringToString(&NewString, pValueName);
+ RtlAppendUnicodeToString(&NewString, L" & ");
+ RtlAppendUnicodeStringToString(&NewString, &Entry->FaceName);
- if (pLoadFont->PrivateEntry)
+ RtlFreeUnicodeString(pValueName);
+ *pValueName = NewString;
+ }
+ if (Entry->StyleName.Length)
{
- while (!IsListEmpty(&pLoadFont->PrivateEntry->ListEntry))
- {
- ListEntry =
RemoveHeadList(&pLoadFont->PrivateEntry->ListEntry);
- PrivateEntry = CONTAINING_RECORD(ListEntry, FONT_ENTRY_MEM, ListEntry);
- ExFreePoolWithTag(PrivateEntry, TAG_FONT);
- }
- ExFreePoolWithTag(pLoadFont->PrivateEntry, TAG_FONT);
- pLoadFont->PrivateEntry = NULL;
+ RtlAppendUnicodeToString(pValueName, L" ");
+ RtlAppendUnicodeStringToString(pValueName, &Entry->StyleName);
}
- while (!IsListEmpty(&LoadedFontList))
+ for (i = 1; i < CharSetCount; ++i)
{
- ListEntry = RemoveHeadList(&LoadedFontList);
- Entry = CONTAINING_RECORD(ListEntry, FONT_ENTRY, ListEntry);
- CleanupFontEntry(Entry);
+ /* Do not count charsets towards 'faces' loaded */
+ IntGdiLoadFontsFromMemory(pLoadFont, SharedFace, FontIndex, i);
}
-
- return 0; /* No faces have been added */
}
+
+ return FaceCount; /* number of loaded faces */
}
static LPCWSTR FASTCALL
@@ -1656,7 +1551,7 @@ IntGdiAddFontResourceEx(PUNICODE_STRING FileName, DWORD
Characteristics,
LoadFont.IsTrueType = FALSE;
LoadFont.CharSet = DEFAULT_CHARSET;
LoadFont.PrivateEntry = NULL;
- FontCount = IntGdiLoadFontsFromMemory(&LoadFont);
+ FontCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1);
/* Release our copy */
IntLockFreeType();
@@ -1948,7 +1843,7 @@ IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD
pNumAdded)
RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
LoadFont.IsTrueType = FALSE;
LoadFont.PrivateEntry = NULL;
- FaceCount = IntGdiLoadFontsFromMemory(&LoadFont);
+ FaceCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1);
RtlFreeUnicodeString(&LoadFont.RegValueName);