diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index e94534b2b5..65bda36862 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 : "", + Face->style_name ? Face->style_name : ""); + 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);