diff --git a/win32ss/gdi/ntgdi/font.c b/win32ss/gdi/ntgdi/font.c index a48904cd8e..ba51f26608 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 854085d01e..63bd37708d 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -1048,331 +1048,342 @@ WeightFromStyle(const char *style_name) static FT_Error IntRequestFontSize(PDC dc, PFONTGDI FontGDI, LONG lfWidth, LONG lfHeight); +UINT FASTCALL IntGetCharSet(INT nIndex, FT_ULong CodePageRange1) +{ + UINT BitIndex, CharSet; + INT nCount = 0; + + if (CodePageRange1 == 0) + { + if (nIndex < 0) + return 1; + return DEFAULT_CHARSET; + } + + for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex) + { + if (CodePageRange1 & (1 << BitIndex)) + { + CharSet = g_FontTci[BitIndex].ciCharset; + if (nCount == nIndex) + { + return CharSet; + } + ++nCount; + } + } + + if (nIndex < 0) + return nCount; + return 0; +} + +static __inline LONG FASTCALL +px2pt(LONG pixels) +{ + return 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 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 : "", - Face->style_name ? Face->style_name : ""); - 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; + DPRINT1("Font loaded: %s (%s)\n", + Face->family_name ? Face->family_name : "", + Face->style_name ? Face->style_name : ""); + DPRINT1("Num glyphs: %d\n", Face->num_glyphs); + DPRINT1("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 +1452,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 +1530,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,16 +2211,18 @@ 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"); IntFreeFontNames(&FontNames); 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,49 +2230,48 @@ 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); - Otm->otmFiller = 0; - RtlCopyMemory(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT); - Otm->otmfsSelection = pOS2->fsSelection; - Otm->otmfsType = pOS2->fsType; - Otm->otmsCharSlopeRise = pHori->caret_Slope_Rise; - Otm->otmsCharSlopeRun = pHori->caret_Slope_Run; - Otm->otmItalicAngle = 0; /* POST table */ - Otm->otmEMSquare = Face->units_per_EM; + if (pOS2) + { + Otm->otmFiller = 0; + RtlCopyMemory(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT); + Otm->otmfsSelection = pOS2->fsSelection; + Otm->otmfsType = pOS2->fsType; + Otm->otmsCharSlopeRise = pHori->caret_Slope_Rise; + Otm->otmsCharSlopeRun = pHori->caret_Slope_Run; + Otm->otmItalicAngle = 0; /* POST table */ + Otm->otmEMSquare = Face->units_per_EM; #define SCALE_X(value) ((FT_MulFix((value), XScale) + 32) >> 6) #define SCALE_Y(value) ((FT_MulFix((value), YScale) + 32) >> 6) - Otm->otmAscent = SCALE_Y(pOS2->sTypoAscender); - Otm->otmDescent = SCALE_Y(pOS2->sTypoDescender); - Otm->otmLineGap = SCALE_Y(pOS2->sTypoLineGap); - Otm->otmsCapEmHeight = SCALE_Y(pOS2->sCapHeight); - Otm->otmsXHeight = SCALE_Y(pOS2->sxHeight); - Otm->otmrcFontBox.left = SCALE_X(Face->bbox.xMin); - Otm->otmrcFontBox.right = SCALE_X(Face->bbox.xMax); - Otm->otmrcFontBox.top = SCALE_Y(Face->bbox.yMax); - Otm->otmrcFontBox.bottom = SCALE_Y(Face->bbox.yMin); - Otm->otmMacAscent = Otm->otmTextMetrics.tmAscent; - Otm->otmMacDescent = -Otm->otmTextMetrics.tmDescent; - Otm->otmMacLineGap = Otm->otmLineGap; - Otm->otmusMinimumPPEM = 0; /* TT Header */ - Otm->otmptSubscriptSize.x = SCALE_X(pOS2->ySubscriptXSize); - Otm->otmptSubscriptSize.y = SCALE_Y(pOS2->ySubscriptYSize); - Otm->otmptSubscriptOffset.x = SCALE_X(pOS2->ySubscriptXOffset); - Otm->otmptSubscriptOffset.y = SCALE_Y(pOS2->ySubscriptYOffset); - Otm->otmptSuperscriptSize.x = SCALE_X(pOS2->ySuperscriptXSize); - Otm->otmptSuperscriptSize.y = SCALE_Y(pOS2->ySuperscriptYSize); - Otm->otmptSuperscriptOffset.x = SCALE_X(pOS2->ySuperscriptXOffset); - Otm->otmptSuperscriptOffset.y = SCALE_Y(pOS2->ySuperscriptYOffset); - Otm->otmsStrikeoutSize = SCALE_Y(pOS2->yStrikeoutSize); - Otm->otmsStrikeoutPosition = SCALE_Y(pOS2->yStrikeoutPosition); + Otm->otmAscent = SCALE_Y(pOS2->sTypoAscender); + Otm->otmDescent = SCALE_Y(pOS2->sTypoDescender); + Otm->otmLineGap = SCALE_Y(pOS2->sTypoLineGap); + Otm->otmsCapEmHeight = SCALE_Y(pOS2->sCapHeight); + Otm->otmsXHeight = SCALE_Y(pOS2->sxHeight); + Otm->otmrcFontBox.left = SCALE_X(Face->bbox.xMin); + Otm->otmrcFontBox.right = SCALE_X(Face->bbox.xMax); + Otm->otmrcFontBox.top = SCALE_Y(Face->bbox.yMax); + Otm->otmrcFontBox.bottom = SCALE_Y(Face->bbox.yMin); + Otm->otmMacAscent = Otm->otmTextMetrics.tmAscent; + Otm->otmMacDescent = -Otm->otmTextMetrics.tmDescent; + Otm->otmMacLineGap = Otm->otmLineGap; + Otm->otmusMinimumPPEM = 0; /* TT Header */ + Otm->otmptSubscriptSize.x = SCALE_X(pOS2->ySubscriptXSize); + Otm->otmptSubscriptSize.y = SCALE_Y(pOS2->ySubscriptYSize); + Otm->otmptSubscriptOffset.x = SCALE_X(pOS2->ySubscriptXOffset); + Otm->otmptSubscriptOffset.y = SCALE_Y(pOS2->ySubscriptYOffset); + Otm->otmptSuperscriptSize.x = SCALE_X(pOS2->ySuperscriptXSize); + Otm->otmptSuperscriptSize.y = SCALE_Y(pOS2->ySuperscriptYSize); + Otm->otmptSuperscriptOffset.x = SCALE_X(pOS2->ySuperscriptXOffset); + Otm->otmptSuperscriptOffset.y = SCALE_Y(pOS2->ySuperscriptYOffset); + Otm->otmsStrikeoutSize = SCALE_Y(pOS2->yStrikeoutSize); + Otm->otmsStrikeoutPosition = SCALE_Y(pOS2->yStrikeoutPosition); + } if (!pPost) { @@ -2549,6 +2561,7 @@ FontFamilyFillInfo(PFONTFAMILYINFO Info, LPCWSTR FaceName, RtlInitUnicodeString(&NameW, NULL); RtlZeroMemory(Info, sizeof(FONTFAMILYINFO)); + Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL); Otm = ExAllocatePoolWithTag(PagedPool, Size, GDITAG_TEXT); if (!Otm) @@ -3260,13 +3273,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; } /* @@ -3355,13 +3362,28 @@ TextIntUpdateSize(PDC dc, DPRINT("This font face has %d charmaps\n", face->num_charmaps); found = NULL; - for (n = 0; n < face->num_charmaps; n++) + if (!found) { - charmap = face->charmaps[n]; - if (charmap->encoding == FT_ENCODING_UNICODE) + for (n = 0; n < face->num_charmaps; n++) { - found = charmap; - break; + charmap = face->charmaps[n]; + if (charmap->encoding == FT_ENCODING_UNICODE) + { + found = charmap; + break; + } + } + } + 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) @@ -3378,7 +3400,14 @@ TextIntUpdateSize(PDC dc, } if (!found) { - DPRINT1("WARNING: Could not find desired charmap!\n"); + if (face->num_charmaps > 0) + { + found = face->charmaps[0]; + } + } + if (!found) + { + DPRINT1("WARNING: Could not find the charmap!\n"); } else { @@ -4306,28 +4335,22 @@ ftGdiGetTextMetricsW( IntLockFreeType(); pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2); - if (NULL == pOS2) - { - DPRINT1("Can't find OS/2 table - not TT font?\n"); - Status = STATUS_INTERNAL_ERROR; - } - pHori = FT_Get_Sfnt_Table(Face, ft_sfnt_hhea); - if (NULL == pHori) - { - DPRINT1("Can't find HHEA table - not TT font?\n"); - Status = STATUS_INTERNAL_ERROR; - } - 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); /* FIXME: Fill Diff member */ RtlZeroMemory(&ptmwi->Diff, sizeof(ptmwi->Diff)); } + else + { + DPRINT1("Can't find HHEA table - not TT font?\n"); + DPRINT1("Can't find OS/2 table - not TT font?\n"); + Status = STATUS_INTERNAL_ERROR; + } IntUnLockFreeType(); }