https://git.reactos.org/?p=reactos.git;a=commitdiff;h=99ba7ea95ffd9dda07f524b651c03edf15bd296f

commit 99ba7ea95ffd9dda07f524b651c03edf15bd296f
Author:     Joachim Henze <[email protected]>
AuthorDate: Sun Feb 23 12:23:05 2020 +0100
Commit:     Joachim Henze <[email protected]>
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);
 

Reply via email to