https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ae99df1675f87db87377c…
commit ae99df1675f87db87377ce4bf1f78181b1b4be95
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Jul 20 23:47:29 2019 +0900
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Jul 20 16:47:29 2019 +0200
[WIN32SS][NTGDI] Support raster fonts (*.fnt and *.fon) (#1739)
Add raster font (*.fnt and *.fon files) support. CORE-16165
- Add IntGetCharSet() function to get the charset by index and/or the number of
charsets.
- Make IntGdiLoadFontsFromMemory() a non-recursive function.
- IntGetOutlineTextMetrics() accepts raster fonts.
- Improve CharMap handling (especially TT_PLATFORM_APPLE_UNICODE).
- Write the raster font file info to the registry.
- Don't request font size for raster fonts in IntRequestFontSize() function.
---
win32ss/gdi/ntgdi/font.c | 5 +
win32ss/gdi/ntgdi/freetype.c | 568 ++++++++++++++++++++++---------------------
2 files changed, 298 insertions(+), 275 deletions(-)
diff --git a/win32ss/gdi/ntgdi/font.c b/win32ss/gdi/ntgdi/font.c
index a48904cd8ef..ba51f26608d 100644
--- a/win32ss/gdi/ntgdi/font.c
+++ b/win32ss/gdi/ntgdi/font.c
@@ -907,6 +907,11 @@ NtGdiGetOutlineTextMetricsInternalW (HDC hDC,
return 0;
}
FontGDI = ObjToGDI(TextObj->Font, FONT);
+ if (!(FontGDI->flType & FO_TYPE_TRUETYPE))
+ {
+ TEXTOBJ_UnlockText(TextObj);
+ return 0;
+ }
TextIntUpdateSize(dc, TextObj, FontGDI, TRUE);
TEXTOBJ_UnlockText(TextObj);
Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c
index 854085d01e0..29f87d14229 100644
--- a/win32ss/gdi/ntgdi/freetype.c
+++ b/win32ss/gdi/ntgdi/freetype.c
@@ -1048,331 +1048,336 @@ WeightFromStyle(const char *style_name)
static FT_Error
IntRequestFontSize(PDC dc, PFONTGDI FontGDI, LONG lfWidth, LONG lfHeight);
+/* NOTE: If nIndex < 0 then return the number of charsets. */
+UINT FASTCALL IntGetCharSet(INT nIndex, FT_ULong CodePageRange1)
+{
+ UINT BitIndex, CharSet;
+ UINT nCount = 0;
+
+ if (CodePageRange1 == 0)
+ {
+ return (nIndex < 0) ? 1 : DEFAULT_CHARSET;
+ }
+
+ for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
+ {
+ if (CodePageRange1 & (1 << BitIndex))
+ {
+ CharSet = g_FontTci[BitIndex].ciCharset;
+ if ((nIndex >= 0) && (nCount == (UINT)nIndex))
+ {
+ return CharSet;
+ }
+ ++nCount;
+ }
+ }
+
+ return (nIndex < 0) ? nCount : ANSI_CHARSET;
+}
+
+/* pixels to points */
+#define PX2PT(pixels) FT_MulDiv((pixels), 72, 96)
+
static INT FASTCALL
-IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
- PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex)
+IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont)
{
FT_Error Error;
PFONT_ENTRY Entry;
- FONT_ENTRY_MEM* PrivateEntry = NULL;
+ FONT_ENTRY_MEM* PrivateEntry;
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;
- FT_UShort os2_usWeightClass;
-
- if (SharedFace == NULL && CharSetIndex == -1)
- {
- /* 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();
- }
+ PSHARED_FACE SharedFace;
+ INT iCharSet, CharSetCount;
+ FT_Long iFace, FaceCount;
+ USHORT NameLength;
+ WCHAR szSize[32];
+ UNICODE_STRING NewString;
+ USHORT Length;
+
+ /* get num_faces */
+ IntLockFreeType();
+ Error = FT_New_Memory_Face(g_FreeTypeLibrary,
+ pLoadFont->Memory->Buffer,
+ pLoadFont->Memory->BufferSize,
+ -1,
+ &Face);
+ FaceCount = Face->num_faces;
+ FT_Done_Face(Face);
+ IntUnLockFreeType();
- /* allocate a FONT_ENTRY */
- Entry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY), TAG_FONT);
- if (!Entry)
+ if (Error)
{
- SharedFace_Release(SharedFace);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ if (Error == FT_Err_Unknown_File_Format)
+ DPRINT1("Unknown font file format\n");
+ else
+ DPRINT1("Error reading font (FT_Error: %d)\n", Error);
return 0; /* failure */
}
- /* allocate a FONTGDI */
- FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT);
- if (!FontGDI)
+ for (iFace = 0; iFace < FaceCount; ++iFace)
{
- SharedFace_Release(SharedFace);
- ExFreePoolWithTag(Entry, TAG_FONT);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return 0; /* failure */
- }
+ Face = NULL;
+ SharedFace = NULL;
- /* set file name */
- if (pFileName)
- {
- FontGDI->Filename = ExAllocatePoolWithTag(PagedPool,
- pFileName->Length +
sizeof(UNICODE_NULL),
- GDITAG_PFF);
- if (FontGDI->Filename == NULL)
+ IntLockFreeType();
+ Error = FT_New_Memory_Face(g_FreeTypeLibrary,
+ pLoadFont->Memory->Buffer,
+ pLoadFont->Memory->BufferSize,
+ iFace,
+ &Face);
+ if (!Error)
{
- EngFreeMem(FontGDI);
- SharedFace_Release(SharedFace);
- ExFreePoolWithTag(Entry, TAG_FONT);
- EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return 0; /* failure */
+ SharedFace = SharedFace_Create(Face, pLoadFont->Memory);
}
+ IntUnLockFreeType();
- 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)
+ if (Error || !SharedFace)
{
- if (FontGDI->Filename)
- ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
- EngFreeMem(FontGDI);
- SharedFace_Release(SharedFace);
- ExFreePoolWithTag(Entry, TAG_FONT);
+ DPRINT1("Error reading font (FT_Error: %d)\n", Error);
return 0;
}
- PrivateEntry->Entry = Entry;
- if (pLoadFont->PrivateEntry)
- {
- InsertTailList(&pLoadFont->PrivateEntry->ListEntry,
&PrivateEntry->ListEntry);
- }
- else
- {
- InitializeListHead(&PrivateEntry->ListEntry);
- pLoadFont->PrivateEntry = PrivateEntry;
- }
- }
-
- /* set face */
- FontGDI->SharedFace = SharedFace;
- FontGDI->CharSet = ANSI_CHARSET;
- FontGDI->OriginalItalic = ItalicFromStyle(Face->style_name);
- FontGDI->RequestItalic = FALSE;
- FontGDI->OriginalWeight = WeightFromStyle(Face->style_name);
- FontGDI->RequestWeight = FW_NORMAL;
-
- 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)
+ /* os2_ulCodePageRange1 and CharSetCount and IsTrueType */
+ os2_ulCodePageRange1 = 0;
+ if (FT_IS_SFNT(Face))
{
- RtlInitAnsiString(&AnsiString, Face->style_name);
- Status = RtlAnsiStringToUnicodeString(&Entry->StyleName,
&AnsiString, TRUE);
- if (!NT_SUCCESS(Status))
+ IntLockFreeType();
+ pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
+ if (pOS2)
{
- RtlFreeUnicodeString(&Entry->FaceName);
+ os2_ulCodePageRange1 = pOS2->ulCodePageRange1;
}
+ IntUnLockFreeType();
+
+ CharSetCount = IntGetCharSet(-1, os2_ulCodePageRange1);
+ pLoadFont->IsTrueType = TRUE;
}
else
{
- RtlInitUnicodeString(&Entry->StyleName, NULL);
+ CharSetCount = 1;
+ pLoadFont->IsTrueType = FALSE;
}
- }
- if (!NT_SUCCESS(Status))
- {
- if (PrivateEntry)
+
+ for (iCharSet = 0; iCharSet < CharSetCount; ++iCharSet)
{
- if (pLoadFont->PrivateEntry == PrivateEntry)
+ if (iCharSet > 0)
{
- pLoadFont->PrivateEntry = NULL;
+ IntLockFreeType();
+ SharedFace_AddRef(SharedFace);
+ IntUnLockFreeType();
}
- else
+
+ /* allocate a FONT_ENTRY */
+ Entry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY), TAG_FONT);
+ if (!Entry)
{
- RemoveEntryList(&PrivateEntry->ListEntry);
+ SharedFace_Release(SharedFace);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
+ return 0; /* failure */
}
- ExFreePoolWithTag(PrivateEntry, TAG_FONT);
- }
- if (FontGDI->Filename)
- ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
- EngFreeMem(FontGDI);
- SharedFace_Release(SharedFace);
- ExFreePoolWithTag(Entry, TAG_FONT);
- return 0;
- }
- 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();
-
- if (pOS2 && os2_version >= 1)
- {
- /* get charset and weight from OS/2 header */
+ /* allocate a FONTGDI */
+ FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT);
+ if (!FontGDI)
+ {
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
+ return 0; /* failure */
+ }
- /* Make sure we do not use this pointer anymore */
- pOS2 = NULL;
+ /* set face */
+ FontGDI->SharedFace = SharedFace;
+ FontGDI->CharSet = ANSI_CHARSET;
+ FontGDI->OriginalItalic = ItalicFromStyle(Face->style_name);
+ FontGDI->RequestItalic = FALSE;
+ FontGDI->OriginalWeight = WeightFromStyle(Face->style_name);
+ FontGDI->RequestWeight = FW_NORMAL;
+
+ /* Entry->FaceName */
+ RtlInitAnsiString(&AnsiString, Face->family_name);
+ RtlAnsiStringToUnicodeString(&Entry->FaceName, &AnsiString,
TRUE);
+
+ /* Entry->StyleName */
+ if (Face->style_name && Face->style_name[0] &&
+ strcmp(Face->style_name, "Regular") != 0)
+ {
+ RtlInitAnsiString(&AnsiString, Face->style_name);
+ RtlAnsiStringToUnicodeString(&Entry->StyleName, &AnsiString,
TRUE);
+ }
+ else
+ {
+ RtlInitUnicodeString(&Entry->StyleName, NULL);
+ }
- for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
- {
- if (os2_ulCodePageRange1 & (1 << BitIndex))
+ /* FontGDI->CharSet */
+ if (FT_IS_SFNT(Face))
{
- if (g_FontTci[BitIndex].ciCharset == DEFAULT_CHARSET)
- continue;
+ FontGDI->CharSet = IntGetCharSet(iCharSet, os2_ulCodePageRange1);
- if ((CharSetIndex == -1 && CharSetCount == 0) ||
- CharSetIndex == CharSetCount)
+ /* FIXME: CharSet is invalid on our Marlett */
+ if (RtlEqualUnicodeString(&Entry->FaceName, &g_MarlettW,
TRUE))
{
- FontGDI->CharSet = g_FontTci[BitIndex].ciCharset;
+ FontGDI->CharSet = SYMBOL_CHARSET;
}
-
- ++CharSetCount;
}
- }
-
- /* set actual weight */
- FontGDI->OriginalWeight = os2_usWeightClass;
- }
- else
- {
- /* get charset from WinFNT header */
- IntLockFreeType();
- Error = FT_Get_WinFNT_Header(Face, &WinFNT);
- if (!Error)
- {
- FontGDI->CharSet = WinFNT.charset;
- }
- IntUnLockFreeType();
- }
+ else
+ {
+ IntLockFreeType();
+ Error = FT_Get_WinFNT_Header(Face, &WinFNT);
+ if (!Error)
+ {
+ FontGDI->CharSet = WinFNT.charset;
+ }
+ IntUnLockFreeType();
+ }
- /* FIXME: CharSet is invalid on Marlett */
- if (RtlEqualUnicodeString(&Entry->FaceName, &g_MarlettW, TRUE))
- {
- FontGDI->CharSet = SYMBOL_CHARSET;
- }
+ /* set file name */
+ if (pFileName)
+ {
+ FontGDI->Filename = ExAllocatePoolWithTag(PagedPool,
+ pFileName->Length +
sizeof(UNICODE_NULL),
+ GDITAG_PFF);
+ if (FontGDI->Filename == NULL)
+ {
+ EngFreeMem(FontGDI);
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
+ return 0; /* failure */
+ }
- ++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);
+ RtlCopyMemory(FontGDI->Filename, pFileName->Buffer,
pFileName->Length);
+ FontGDI->Filename[pFileName->Length / sizeof(WCHAR)] =
UNICODE_NULL;
+ }
+ else
+ {
+ FontGDI->Filename = NULL;
- IntLockFreeType();
- IntRequestFontSize(NULL, FontGDI, 0, 0);
- IntUnLockFreeType();
+ PrivateEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_MEM),
TAG_FONT);
+ if (!PrivateEntry)
+ {
+ if (FontGDI->Filename)
+ ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF);
+ EngFreeMem(FontGDI);
+ SharedFace_Release(SharedFace);
+ ExFreePoolWithTag(Entry, TAG_FONT);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
+ return 0;
+ }
- /* Add this font resource to the font table */
- Entry->Font = FontGDI;
- Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
+ PrivateEntry->Entry = Entry;
+ if (pLoadFont->PrivateEntry)
+ {
+ InsertTailList(&pLoadFont->PrivateEntry->ListEntry,
&PrivateEntry->ListEntry);
+ }
+ else
+ {
+ InitializeListHead(&PrivateEntry->ListEntry);
+ pLoadFont->PrivateEntry = PrivateEntry;
+ }
+ }
- 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();
- }
+ /* Add this font resource to the font table */
+ Entry->Font = FontGDI;
+ Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
- if (FontIndex == -1)
- {
- if (FT_IS_SFNT(Face))
- {
- TT_Face TrueType = (TT_Face)Face;
- if (TrueType->ttc_header.count > 1)
+ if (Characteristics & FR_PRIVATE)
{
- FT_Long i;
- for (i = 1; i < TrueType->ttc_header.count; ++i)
- {
- FaceCount += IntGdiLoadFontsFromMemory(pLoadFont, NULL, i, -1);
- }
+ /* private font */
+ PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
+ IntLockProcessPrivateFonts(Win32Process);
+ InsertTailList(&Win32Process->PrivateFontListHead,
&Entry->ListEntry);
+ IntUnLockProcessPrivateFonts(Win32Process);
+ }
+ else
+ {
+ /* global font */
+ IntLockGlobalFonts();
+ InsertTailList(&g_FontListHead, &Entry->ListEntry);
+ IntUnLockGlobalFonts();
}
- }
- FontIndex = 0;
- }
- if (CharSetIndex == -1)
- {
- INT i;
- USHORT NameLength = Entry->FaceName.Length;
+ 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);
+ }
- if (Entry->StyleName.Length)
- NameLength += Entry->StyleName.Length + sizeof(WCHAR);
+ IntLockFreeType();
+ IntRequestFontSize(NULL, FontGDI, 0, 0);
+ IntUnLockFreeType();
+ NameLength = Entry->FaceName.Length;
if (pLoadFont->RegValueName.Length == 0)
{
- 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);
+ if (FT_IS_SFNT(Face))
+ {
+ RtlCreateUnicodeString(pValueName, Entry->FaceName.Buffer);
+ }
+ else
+ {
+ szSize[0] = L' ';
+ _itow(PX2PT(FontGDI->EmHeight), &szSize[1], 10);
+
+ Length = NameLength + wcslen(szSize) * sizeof(WCHAR);
+ pValueName->Length = 0;
+ pValueName->MaximumLength = Length + sizeof(WCHAR);
+ pValueName->Buffer = ExAllocatePoolWithTag(PagedPool,
+ pValueName->MaximumLength,
+ TAG_USTR);
+ pValueName->Buffer[0] = UNICODE_NULL;
+ RtlAppendUnicodeStringToString(pValueName, &Entry->FaceName);
+ RtlAppendUnicodeToString(pValueName, szSize);
+ }
}
else
{
- 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;
-
- RtlAppendUnicodeStringToString(&NewString, pValueName);
- RtlAppendUnicodeToString(&NewString, L" & ");
- RtlAppendUnicodeStringToString(&NewString, &Entry->FaceName);
+ if (FT_IS_SFNT(Face))
+ {
+ 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;
+ RtlAppendUnicodeStringToString(&NewString, pValueName);
+ RtlAppendUnicodeToString(&NewString, L" & ");
+ RtlAppendUnicodeStringToString(&NewString, &Entry->FaceName);
+ }
+ else
+ {
+ szSize[0] = L',';
+ szSize[1] = L' ';
+ _itow(PX2PT(FontGDI->EmHeight), &szSize[2], 10);
+
+ Length = pValueName->Length + wcslen(szSize) * sizeof(WCHAR);
+ NewString.Length = 0;
+ NewString.MaximumLength = Length + sizeof(WCHAR);
+ NewString.Buffer = ExAllocatePoolWithTag(PagedPool,
+ NewString.MaximumLength,
+ TAG_USTR);
+ NewString.Buffer[0] = UNICODE_NULL;
+ RtlAppendUnicodeStringToString(&NewString, pValueName);
+ RtlAppendUnicodeToString(&NewString, szSize);
+ }
RtlFreeUnicodeString(pValueName);
*pValueName = NewString;
}
- if (Entry->StyleName.Length)
- {
- RtlAppendUnicodeToString(pValueName, L" ");
- RtlAppendUnicodeStringToString(pValueName, &Entry->StyleName);
- }
-
- for (i = 1; i < CharSetCount; ++i)
- {
- /* Do not count charsets towards 'faces' loaded */
- IntGdiLoadFontsFromMemory(pLoadFont, SharedFace, FontIndex, i);
- }
}
return FaceCount; /* number of loaded faces */
@@ -1441,7 +1446,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD
Characteristics)
RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
LoadFont.IsTrueType = FALSE;
LoadFont.PrivateEntry = NULL;
- FontCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1);
+ FontCount = IntGdiLoadFontsFromMemory(&LoadFont);
ObDereferenceObject(SectionObject);
@@ -1519,7 +1524,7 @@ IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD
pNumAdded)
RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
LoadFont.IsTrueType = FALSE;
LoadFont.PrivateEntry = NULL;
- FaceCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1);
+ FaceCount = IntGdiLoadFontsFromMemory(&LoadFont);
RtlFreeUnicodeString(&LoadFont.RegValueName);
@@ -2200,7 +2205,11 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
IntLockFreeType();
pOS2 = FT_Get_Sfnt_Table(Face, FT_SFNT_OS2);
- if (NULL == pOS2)
+ pHori = FT_Get_Sfnt_Table(Face, FT_SFNT_HHEA);
+ pPost = FT_Get_Sfnt_Table(Face, FT_SFNT_POST); /* We can live with this failing */
+ Error = FT_Get_WinFNT_Header(Face, &WinFNT);
+
+ if (pOS2 == NULL && Error)
{
IntUnLockFreeType();
DPRINT1("Can't find OS/2 table - not TT font?\n");
@@ -2208,8 +2217,7 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
return 0;
}
- pHori = FT_Get_Sfnt_Table(Face, FT_SFNT_HHEA);
- if (NULL == pHori)
+ if (pHori == NULL && Error)
{
IntUnLockFreeType();
DPRINT1("Can't find HHEA table - not TT font?\n");
@@ -2217,14 +2225,13 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
return 0;
}
- pPost = FT_Get_Sfnt_Table(Face, FT_SFNT_POST); /* We can live with this failing */
-
- Error = FT_Get_WinFNT_Header(Face, &WinFNT);
-
Otm->otmSize = Cache->OutlineRequiredSize;
FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, !Error ? &WinFNT : 0);
+ if (!pOS2)
+ goto skip_os2;
+
Otm->otmFiller = 0;
RtlCopyMemory(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT);
Otm->otmfsSelection = pOS2->fsSelection;
@@ -2275,6 +2282,7 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
#undef SCALE_X
#undef SCALE_Y
+skip_os2:
IntUnLockFreeType();
pb = IntStoreFontNames(&FontNames, Otm);
@@ -3260,13 +3268,7 @@ IntRequestFontSize(PDC dc, PFONTGDI FontGDI, LONG lfWidth, LONG
lfHeight)
FontGDI->EmHeight = max(FontGDI->EmHeight, 1);
FontGDI->EmHeight = min(FontGDI->EmHeight, USHORT_MAX);
FontGDI->Magic = FONTGDI_MAGIC;
-
- req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
- req.width = 0;
- req.height = (FT_Long)(FontGDI->EmHeight << 6);
- req.horiResolution = 0;
- req.vertResolution = 0;
- return FT_Request_Size(face, &req);
+ return 0;
}
/*
@@ -3365,6 +3367,18 @@ TextIntUpdateSize(PDC dc,
}
}
if (!found)
+ {
+ for (n = 0; n < face->num_charmaps; n++)
+ {
+ charmap = face->charmaps[n];
+ if (charmap->platform_id == TT_PLATFORM_APPLE_UNICODE)
+ {
+ found = charmap;
+ break;
+ }
+ }
+ }
+ if (!found)
{
for (n = 0; n < face->num_charmaps; n++)
{
@@ -3376,6 +3390,10 @@ TextIntUpdateSize(PDC dc,
}
}
}
+ if (!found && face->num_charmaps > 0)
+ {
+ found = face->charmaps[0];
+ }
if (!found)
{
DPRINT1("WARNING: Could not find desired charmap!\n");
@@ -4321,7 +4339,7 @@ ftGdiGetTextMetricsW(
Error = FT_Get_WinFNT_Header(Face, &Win);
- if (NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status) || !Error)
{
FillTM(&ptmwi->TextMetric, FontGDI, pOS2, pHori, !Error ? &Win
: 0);