[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.
This commit is contained in:
Katayama Hirofumi MZ 2019-07-20 23:47:29 +09:00 committed by Hermès BÉLUSCA - MAÏTO
parent eb532bc641
commit ae99df1675
2 changed files with 306 additions and 283 deletions

View file

@ -907,6 +907,11 @@ NtGdiGetOutlineTextMetricsInternalW (HDC hDC,
return 0; return 0;
} }
FontGDI = ObjToGDI(TextObj->Font, FONT); FontGDI = ObjToGDI(TextObj->Font, FONT);
if (!(FontGDI->flType & FO_TYPE_TRUETYPE))
{
TEXTOBJ_UnlockText(TextObj);
return 0;
}
TextIntUpdateSize(dc, TextObj, FontGDI, TRUE); TextIntUpdateSize(dc, TextObj, FontGDI, TRUE);
TEXTOBJ_UnlockText(TextObj); TEXTOBJ_UnlockText(TextObj);
Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL); Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);

View file

@ -1048,62 +1048,127 @@ WeightFromStyle(const char *style_name)
static FT_Error static FT_Error
IntRequestFontSize(PDC dc, PFONTGDI FontGDI, LONG lfWidth, LONG lfHeight); 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 static INT FASTCALL
IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont, IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont)
PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex)
{ {
FT_Error Error; FT_Error Error;
PFONT_ENTRY Entry; PFONT_ENTRY Entry;
FONT_ENTRY_MEM* PrivateEntry = NULL; FONT_ENTRY_MEM* PrivateEntry;
FONTGDI * FontGDI; FONTGDI * FontGDI;
NTSTATUS Status;
FT_Face Face; FT_Face Face;
ANSI_STRING AnsiString; ANSI_STRING AnsiString;
FT_WinFNT_HeaderRec WinFNT; FT_WinFNT_HeaderRec WinFNT;
INT FaceCount = 0, CharSetCount = 0;
PUNICODE_STRING pFileName = pLoadFont->pFileName; PUNICODE_STRING pFileName = pLoadFont->pFileName;
DWORD Characteristics = pLoadFont->Characteristics; DWORD Characteristics = pLoadFont->Characteristics;
PUNICODE_STRING pValueName = &pLoadFont->RegValueName; PUNICODE_STRING pValueName = &pLoadFont->RegValueName;
TT_OS2 * pOS2; TT_OS2 * pOS2;
INT BitIndex;
FT_UShort os2_version;
FT_ULong os2_ulCodePageRange1; FT_ULong os2_ulCodePageRange1;
FT_UShort os2_usWeightClass; PSHARED_FACE SharedFace;
INT iCharSet, CharSetCount;
FT_Long iFace, FaceCount;
USHORT NameLength;
WCHAR szSize[32];
UNICODE_STRING NewString;
USHORT Length;
if (SharedFace == NULL && CharSetIndex == -1) /* get num_faces */
{
/* load a face from memory */
IntLockFreeType(); IntLockFreeType();
Error = FT_New_Memory_Face( Error = FT_New_Memory_Face(g_FreeTypeLibrary,
g_FreeTypeLibrary,
pLoadFont->Memory->Buffer, pLoadFont->Memory->Buffer,
pLoadFont->Memory->BufferSize, pLoadFont->Memory->BufferSize,
((FontIndex != -1) ? FontIndex : 0), -1,
&Face); &Face);
FaceCount = Face->num_faces;
if (!Error) FT_Done_Face(Face);
SharedFace = SharedFace_Create(Face, pLoadFont->Memory);
IntUnLockFreeType(); IntUnLockFreeType();
if (!Error && FT_IS_SFNT(Face)) if (Error)
pLoadFont->IsTrueType = TRUE;
if (Error || SharedFace == NULL)
{ {
if (SharedFace)
SharedFace_Release(SharedFace);
if (Error == FT_Err_Unknown_File_Format) if (Error == FT_Err_Unknown_File_Format)
DPRINT1("Unknown font file format\n"); DPRINT1("Unknown font file format\n");
else else
DPRINT1("Error reading font (error code: %d)\n", Error); DPRINT1("Error reading font (FT_Error: %d)\n", Error);
return 0; /* failure */ return 0; /* failure */
} }
for (iFace = 0; iFace < FaceCount; ++iFace)
{
Face = NULL;
SharedFace = NULL;
IntLockFreeType();
Error = FT_New_Memory_Face(g_FreeTypeLibrary,
pLoadFont->Memory->Buffer,
pLoadFont->Memory->BufferSize,
iFace,
&Face);
if (!Error)
{
SharedFace = SharedFace_Create(Face, pLoadFont->Memory);
}
IntUnLockFreeType();
if (Error || !SharedFace)
{
DPRINT1("Error reading font (FT_Error: %d)\n", Error);
return 0;
}
/* os2_ulCodePageRange1 and CharSetCount and IsTrueType */
os2_ulCodePageRange1 = 0;
if (FT_IS_SFNT(Face))
{
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;
} }
else else
{ {
Face = SharedFace->Face; CharSetCount = 1;
pLoadFont->IsTrueType = FALSE;
}
for (iCharSet = 0; iCharSet < CharSetCount; ++iCharSet)
{
if (iCharSet > 0)
{
IntLockFreeType(); IntLockFreeType();
SharedFace_AddRef(SharedFace); SharedFace_AddRef(SharedFace);
IntUnLockFreeType(); IntUnLockFreeType();
@ -1115,6 +1180,7 @@ IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
{ {
SharedFace_Release(SharedFace); SharedFace_Release(SharedFace);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
return 0; /* failure */ return 0; /* failure */
} }
@ -1125,9 +1191,56 @@ IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
SharedFace_Release(SharedFace); SharedFace_Release(SharedFace);
ExFreePoolWithTag(Entry, TAG_FONT); ExFreePoolWithTag(Entry, TAG_FONT);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
return 0; /* failure */ return 0; /* failure */
} }
/* 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);
}
/* FontGDI->CharSet */
if (FT_IS_SFNT(Face))
{
FontGDI->CharSet = IntGetCharSet(iCharSet, os2_ulCodePageRange1);
/* FIXME: CharSet is invalid on our Marlett */
if (RtlEqualUnicodeString(&Entry->FaceName, &g_MarlettW, TRUE))
{
FontGDI->CharSet = SYMBOL_CHARSET;
}
}
else
{
IntLockFreeType();
Error = FT_Get_WinFNT_Header(Face, &WinFNT);
if (!Error)
{
FontGDI->CharSet = WinFNT.charset;
}
IntUnLockFreeType();
}
/* set file name */ /* set file name */
if (pFileName) if (pFileName)
{ {
@ -1140,6 +1253,7 @@ IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
SharedFace_Release(SharedFace); SharedFace_Release(SharedFace);
ExFreePoolWithTag(Entry, TAG_FONT); ExFreePoolWithTag(Entry, TAG_FONT);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
return 0; /* failure */ return 0; /* failure */
} }
@ -1158,6 +1272,8 @@ IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
EngFreeMem(FontGDI); EngFreeMem(FontGDI);
SharedFace_Release(SharedFace); SharedFace_Release(SharedFace);
ExFreePoolWithTag(Entry, TAG_FONT); ExFreePoolWithTag(Entry, TAG_FONT);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
DPRINT1("ERROR_NOT_ENOUGH_MEMORY\n");
return 0; return 0;
} }
@ -1173,122 +1289,6 @@ IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
} }
} }
/* 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)
{
RtlInitAnsiString(&AnsiString, Face->style_name);
Status = RtlAnsiStringToUnicodeString(&Entry->StyleName, &AnsiString, TRUE);
if (!NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&Entry->FaceName);
}
}
else
{
RtlInitUnicodeString(&Entry->StyleName, NULL);
}
}
if (!NT_SUCCESS(Status))
{
if (PrivateEntry)
{
if (pLoadFont->PrivateEntry == PrivateEntry)
{
pLoadFont->PrivateEntry = NULL;
}
else
{
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;
}
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 */
/* Make sure we do not use this pointer anymore */
pOS2 = NULL;
for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex)
{
if (os2_ulCodePageRange1 & (1 << BitIndex))
{
if (g_FontTci[BitIndex].ciCharset == DEFAULT_CHARSET)
continue;
if ((CharSetIndex == -1 && CharSetCount == 0) ||
CharSetIndex == CharSetCount)
{
FontGDI->CharSet = g_FontTci[BitIndex].ciCharset;
}
++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();
}
/* FIXME: CharSet is invalid on Marlett */
if (RtlEqualUnicodeString(&Entry->FaceName, &g_MarlettW, TRUE))
{
FontGDI->CharSet = SYMBOL_CHARSET;
}
++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);
IntLockFreeType();
IntRequestFontSize(NULL, FontGDI, 0, 0);
IntUnLockFreeType();
/* Add this font resource to the font table */ /* Add this font resource to the font table */
Entry->Font = FontGDI; Entry->Font = FontGDI;
Entry->NotEnum = (Characteristics & FR_NOT_ENUM); Entry->NotEnum = (Characteristics & FR_NOT_ENUM);
@ -1309,70 +1309,75 @@ IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont,
IntUnLockGlobalFonts(); IntUnLockGlobalFonts();
} }
if (FontIndex == -1) 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);
}
IntLockFreeType();
IntRequestFontSize(NULL, FontGDI, 0, 0);
IntUnLockFreeType();
NameLength = Entry->FaceName.Length;
if (pLoadFont->RegValueName.Length == 0)
{ {
if (FT_IS_SFNT(Face)) if (FT_IS_SFNT(Face))
{ {
TT_Face TrueType = (TT_Face)Face; RtlCreateUnicodeString(pValueName, Entry->FaceName.Buffer);
if (TrueType->ttc_header.count > 1) }
else
{ {
FT_Long i; szSize[0] = L' ';
for (i = 1; i < TrueType->ttc_header.count; ++i) _itow(PX2PT(FontGDI->EmHeight), &szSize[1], 10);
{
FaceCount += IntGdiLoadFontsFromMemory(pLoadFont, NULL, i, -1);
}
}
}
FontIndex = 0;
}
if (CharSetIndex == -1) Length = NameLength + wcslen(szSize) * sizeof(WCHAR);
{
INT i;
USHORT NameLength = Entry->FaceName.Length;
if (Entry->StyleName.Length)
NameLength += Entry->StyleName.Length + sizeof(WCHAR);
if (pLoadFont->RegValueName.Length == 0)
{
pValueName->Length = 0; pValueName->Length = 0;
pValueName->MaximumLength = NameLength + sizeof(WCHAR); pValueName->MaximumLength = Length + sizeof(WCHAR);
pValueName->Buffer = ExAllocatePoolWithTag(PagedPool, pValueName->Buffer = ExAllocatePoolWithTag(PagedPool,
pValueName->MaximumLength, pValueName->MaximumLength,
TAG_USTR); TAG_USTR);
pValueName->Buffer[0] = UNICODE_NULL; pValueName->Buffer[0] = UNICODE_NULL;
RtlAppendUnicodeStringToString(pValueName, &Entry->FaceName); RtlAppendUnicodeStringToString(pValueName, &Entry->FaceName);
RtlAppendUnicodeToString(pValueName, szSize);
}
} }
else else
{ {
UNICODE_STRING NewString; if (FT_IS_SFNT(Face))
USHORT Length = pValueName->Length + 3 * sizeof(WCHAR) + NameLength; {
Length = pValueName->Length + 3 * sizeof(WCHAR) + NameLength;
NewString.Length = 0; NewString.Length = 0;
NewString.MaximumLength = Length + sizeof(WCHAR); NewString.MaximumLength = Length + sizeof(WCHAR);
NewString.Buffer = ExAllocatePoolWithTag(PagedPool, NewString.Buffer = ExAllocatePoolWithTag(PagedPool,
NewString.MaximumLength, NewString.MaximumLength,
TAG_USTR); TAG_USTR);
NewString.Buffer[0] = UNICODE_NULL; NewString.Buffer[0] = UNICODE_NULL;
RtlAppendUnicodeStringToString(&NewString, pValueName); RtlAppendUnicodeStringToString(&NewString, pValueName);
RtlAppendUnicodeToString(&NewString, L" & "); RtlAppendUnicodeToString(&NewString, L" & ");
RtlAppendUnicodeStringToString(&NewString, &Entry->FaceName); 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); RtlFreeUnicodeString(pValueName);
*pValueName = NewString; *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 */ return FaceCount; /* number of loaded faces */
@ -1441,7 +1446,7 @@ IntGdiAddFontResource(PUNICODE_STRING FileName, DWORD Characteristics)
RtlInitUnicodeString(&LoadFont.RegValueName, NULL); RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
LoadFont.IsTrueType = FALSE; LoadFont.IsTrueType = FALSE;
LoadFont.PrivateEntry = NULL; LoadFont.PrivateEntry = NULL;
FontCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1); FontCount = IntGdiLoadFontsFromMemory(&LoadFont);
ObDereferenceObject(SectionObject); ObDereferenceObject(SectionObject);
@ -1519,7 +1524,7 @@ IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded)
RtlInitUnicodeString(&LoadFont.RegValueName, NULL); RtlInitUnicodeString(&LoadFont.RegValueName, NULL);
LoadFont.IsTrueType = FALSE; LoadFont.IsTrueType = FALSE;
LoadFont.PrivateEntry = NULL; LoadFont.PrivateEntry = NULL;
FaceCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1); FaceCount = IntGdiLoadFontsFromMemory(&LoadFont);
RtlFreeUnicodeString(&LoadFont.RegValueName); RtlFreeUnicodeString(&LoadFont.RegValueName);
@ -2200,7 +2205,11 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
IntLockFreeType(); IntLockFreeType();
pOS2 = FT_Get_Sfnt_Table(Face, FT_SFNT_OS2); 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(); IntUnLockFreeType();
DPRINT1("Can't find OS/2 table - not TT font?\n"); DPRINT1("Can't find OS/2 table - not TT font?\n");
@ -2208,8 +2217,7 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
return 0; return 0;
} }
pHori = FT_Get_Sfnt_Table(Face, FT_SFNT_HHEA); if (pHori == NULL && Error)
if (NULL == pHori)
{ {
IntUnLockFreeType(); IntUnLockFreeType();
DPRINT1("Can't find HHEA table - not TT font?\n"); DPRINT1("Can't find HHEA table - not TT font?\n");
@ -2217,14 +2225,13 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
return 0; 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; Otm->otmSize = Cache->OutlineRequiredSize;
FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, !Error ? &WinFNT : 0); FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, !Error ? &WinFNT : 0);
if (!pOS2)
goto skip_os2;
Otm->otmFiller = 0; Otm->otmFiller = 0;
RtlCopyMemory(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT); RtlCopyMemory(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT);
Otm->otmfsSelection = pOS2->fsSelection; Otm->otmfsSelection = pOS2->fsSelection;
@ -2275,6 +2282,7 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI,
#undef SCALE_X #undef SCALE_X
#undef SCALE_Y #undef SCALE_Y
skip_os2:
IntUnLockFreeType(); IntUnLockFreeType();
pb = IntStoreFontNames(&FontNames, Otm); 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 = max(FontGDI->EmHeight, 1);
FontGDI->EmHeight = min(FontGDI->EmHeight, USHORT_MAX); FontGDI->EmHeight = min(FontGDI->EmHeight, USHORT_MAX);
FontGDI->Magic = FONTGDI_MAGIC; FontGDI->Magic = FONTGDI_MAGIC;
return 0;
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);
} }
/* /*
@ -3365,6 +3367,18 @@ TextIntUpdateSize(PDC dc,
} }
} }
if (!found) 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++) 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) if (!found)
{ {
DPRINT1("WARNING: Could not find desired charmap!\n"); DPRINT1("WARNING: Could not find desired charmap!\n");
@ -4321,7 +4339,7 @@ ftGdiGetTextMetricsW(
Error = FT_Get_WinFNT_Header(Face, &Win); 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); FillTM(&ptmwi->TextMetric, FontGDI, pOS2, pHori, !Error ? &Win : 0);