https://git.reactos.org/?p=reactos.git;a=commitdiff;h=70e27198ae15e2c0ae2373...
commit 70e27198ae15e2c0ae237368ff520fe39578e06f Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Wed Oct 24 20:23:24 2018 +0900 Commit: GitHub noreply@github.com CommitDate: Wed Oct 24 20:23:24 2018 +0900
[FONT][WIN32SS] Fix the storage processing of IntGetOutlineTextMetrics (#942)
* Add IntStoreFontNames and IntStoreName functions and use them. * SCALE_X and SCALE_Y macros * Fix too long line * Reduce type casts --- win32ss/gdi/ntgdi/freetype.c | 226 +++++++++++++++++++++++++------------------ 1 file changed, 134 insertions(+), 92 deletions(-)
diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index aca18ccd6c..31a4b4920e 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -1965,6 +1965,84 @@ static NTSTATUS IntGetFontLocalizedName(PUNICODE_STRING pNameW, PSHARED_FACE SharedFace, FT_UShort NameID, FT_UShort LangID);
+typedef struct FONT_NAMES +{ + UNICODE_STRING FamilyNameW; /* family name (TT_NAME_ID_FONT_FAMILY) */ + UNICODE_STRING FaceNameW; /* face name (TT_NAME_ID_FULL_NAME) */ + UNICODE_STRING StyleNameW; /* style name (TT_NAME_ID_FONT_SUBFAMILY) */ + UNICODE_STRING FullNameW; /* unique name (TT_NAME_ID_UNIQUE_ID) */ + ULONG OtmSize; /* size of OUTLINETEXTMETRICW with extra data */ +} FONT_NAMES, *LPFONT_NAMES; + +static __inline void FASTCALL +IntInitFontNames(FONT_NAMES *Names, PSHARED_FACE SharedFace) +{ + ULONG OtmSize; + + RtlInitUnicodeString(&Names->FamilyNameW, NULL); + RtlInitUnicodeString(&Names->FaceNameW, NULL); + RtlInitUnicodeString(&Names->StyleNameW, NULL); + RtlInitUnicodeString(&Names->FullNameW, NULL); + + /* family name */ + IntGetFontLocalizedName(&Names->FamilyNameW, SharedFace, TT_NAME_ID_FONT_FAMILY, gusLanguageID); + /* face name */ + IntGetFontLocalizedName(&Names->FaceNameW, SharedFace, TT_NAME_ID_FULL_NAME, gusLanguageID); + /* style name */ + IntGetFontLocalizedName(&Names->StyleNameW, SharedFace, TT_NAME_ID_FONT_SUBFAMILY, gusLanguageID); + /* unique name (full name) */ + IntGetFontLocalizedName(&Names->FullNameW, SharedFace, TT_NAME_ID_UNIQUE_ID, gusLanguageID); + + /* Calculate the size of OUTLINETEXTMETRICW with extra data */ + OtmSize = sizeof(OUTLINETEXTMETRICW) + + Names->FamilyNameW.Length + sizeof(UNICODE_NULL) + + Names->FaceNameW.Length + sizeof(UNICODE_NULL) + + Names->StyleNameW.Length + sizeof(UNICODE_NULL) + + Names->FullNameW.Length + sizeof(UNICODE_NULL); + Names->OtmSize = OtmSize; +} + +static __inline SIZE_T FASTCALL +IntStoreName(const UNICODE_STRING *pName, BYTE *pb) +{ + RtlCopyMemory(pb, pName->Buffer, pName->Length); + *(WCHAR *)&pb[pName->Length] = UNICODE_NULL; + return pName->Length + sizeof(UNICODE_NULL); +} + +static __inline BYTE *FASTCALL +IntStoreFontNames(const FONT_NAMES *Names, OUTLINETEXTMETRICW *Otm) +{ + BYTE *pb = (BYTE *)Otm + sizeof(OUTLINETEXTMETRICW); + + /* family name */ + Otm->otmpFamilyName = (LPSTR)(pb - (BYTE*) Otm); + pb += IntStoreName(&Names->FamilyNameW, pb); + + /* face name */ + Otm->otmpFaceName = (LPSTR)(pb - (BYTE*) Otm); + pb += IntStoreName(&Names->FaceNameW, pb); + + /* style name */ + Otm->otmpStyleName = (LPSTR)(pb - (BYTE*) Otm); + pb += IntStoreName(&Names->StyleNameW, pb); + + /* unique name (full name) */ + Otm->otmpFullName = (LPSTR)(pb - (BYTE*) Otm); + pb += IntStoreName(&Names->FullNameW, pb); + + return pb; +} + +static __inline void FASTCALL +IntFreeFontNames(FONT_NAMES *Names) +{ + RtlFreeUnicodeString(&Names->FamilyNameW); + RtlFreeUnicodeString(&Names->FaceNameW); + RtlFreeUnicodeString(&Names->StyleNameW); + RtlFreeUnicodeString(&Names->FullNameW); +} + /************************************************************* * IntGetOutlineTextMetrics * @@ -1978,53 +2056,38 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI, TT_HoriHeader *pHori; TT_Postscript *pPost; FT_Fixed XScale, YScale; - FT_WinFNT_HeaderRec Win; + FT_WinFNT_HeaderRec WinFNT; FT_Error Error; - char *Cp; - UNICODE_STRING FamilyNameW, FaceNameW, StyleNameW, FullNameW; + BYTE *pb; + FONT_NAMES FontNames; PSHARED_FACE SharedFace = FontGDI->SharedFace; - PSHARED_FACE_CACHE Cache = (PRIMARYLANGID(gusLanguageID) == LANG_ENGLISH) ? &SharedFace->EnglishUS : &SharedFace->UserLanguage; + PSHARED_FACE_CACHE Cache; FT_Face Face = SharedFace->Face;
+ if (PRIMARYLANGID(gusLanguageID) == LANG_ENGLISH) + { + Cache = &SharedFace->EnglishUS; + } + else + { + Cache = &SharedFace->UserLanguage; + } + if (Cache->OutlineRequiredSize && Size < Cache->OutlineRequiredSize) { return Cache->OutlineRequiredSize; }
- /* family name */ - RtlInitUnicodeString(&FamilyNameW, NULL); - IntGetFontLocalizedName(&FamilyNameW, SharedFace, TT_NAME_ID_FONT_FAMILY, gusLanguageID); - - /* face name */ - RtlInitUnicodeString(&FaceNameW, NULL); - IntGetFontLocalizedName(&FaceNameW, SharedFace, TT_NAME_ID_FULL_NAME, gusLanguageID); - - /* style name */ - RtlInitUnicodeString(&StyleNameW, NULL); - IntGetFontLocalizedName(&StyleNameW, SharedFace, TT_NAME_ID_FONT_SUBFAMILY, gusLanguageID); - - /* unique name (full name) */ - RtlInitUnicodeString(&FullNameW, NULL); - IntGetFontLocalizedName(&FullNameW, SharedFace, TT_NAME_ID_UNIQUE_ID, gusLanguageID); + IntInitFontNames(&FontNames, SharedFace);
if (!Cache->OutlineRequiredSize) { - UINT Needed; - Needed = sizeof(OUTLINETEXTMETRICW); - Needed += FamilyNameW.Length + sizeof(WCHAR); - Needed += FaceNameW.Length + sizeof(WCHAR); - Needed += StyleNameW.Length + sizeof(WCHAR); - Needed += FullNameW.Length + sizeof(WCHAR); - - Cache->OutlineRequiredSize = Needed; + Cache->OutlineRequiredSize = FontNames.OtmSize; }
if (Size < Cache->OutlineRequiredSize) { - RtlFreeUnicodeString(&FamilyNameW); - RtlFreeUnicodeString(&FaceNameW); - RtlFreeUnicodeString(&StyleNameW); - RtlFreeUnicodeString(&FullNameW); + IntFreeFontNames(&FontNames); return Cache->OutlineRequiredSize; }
@@ -2032,37 +2095,32 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI, YScale = Face->size->metrics.y_scale;
IntLockFreeType(); - pOS2 = FT_Get_Sfnt_Table(Face, ft_sfnt_os2); + + pOS2 = FT_Get_Sfnt_Table(Face, FT_SFNT_OS2); if (NULL == pOS2) { IntUnLockFreeType(); DPRINT1("Can't find OS/2 table - not TT font?\n"); - RtlFreeUnicodeString(&FamilyNameW); - RtlFreeUnicodeString(&FaceNameW); - RtlFreeUnicodeString(&StyleNameW); - RtlFreeUnicodeString(&FullNameW); + IntFreeFontNames(&FontNames); return 0; }
- pHori = FT_Get_Sfnt_Table(Face, ft_sfnt_hhea); + pHori = FT_Get_Sfnt_Table(Face, FT_SFNT_HHEA); if (NULL == pHori) { IntUnLockFreeType(); DPRINT1("Can't find HHEA table - not TT font?\n"); - RtlFreeUnicodeString(&FamilyNameW); - RtlFreeUnicodeString(&FaceNameW); - RtlFreeUnicodeString(&StyleNameW); - RtlFreeUnicodeString(&FullNameW); + IntFreeFontNames(&FontNames); return 0; }
- pPost = FT_Get_Sfnt_Table(Face, ft_sfnt_post); /* We can live with this failing */ + pPost = FT_Get_Sfnt_Table(Face, FT_SFNT_POST); /* We can live with this failing */
- Error = FT_Get_WinFNT_Header(Face , &Win); + Error = FT_Get_WinFNT_Header(Face, &WinFNT);
Otm->otmSize = Cache->OutlineRequiredSize;
- FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, !Error ? &Win : 0); + FillTM(&Otm->otmTextMetrics, FontGDI, pOS2, pHori, !Error ? &WinFNT : 0);
Otm->otmFiller = 0; RtlCopyMemory(&Otm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT); @@ -2072,29 +2130,34 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI, Otm->otmsCharSlopeRun = pHori->caret_Slope_Run; Otm->otmItalicAngle = 0; /* POST table */ Otm->otmEMSquare = Face->units_per_EM; - Otm->otmAscent = (FT_MulFix(pOS2->sTypoAscender, YScale) + 32) >> 6; - Otm->otmDescent = (FT_MulFix(pOS2->sTypoDescender, YScale) + 32) >> 6; - Otm->otmLineGap = (FT_MulFix(pOS2->sTypoLineGap, YScale) + 32) >> 6; - Otm->otmsCapEmHeight = (FT_MulFix(pOS2->sCapHeight, YScale) + 32) >> 6; - Otm->otmsXHeight = (FT_MulFix(pOS2->sxHeight, YScale) + 32) >> 6; - Otm->otmrcFontBox.left = (FT_MulFix(Face->bbox.xMin, XScale) + 32) >> 6; - Otm->otmrcFontBox.right = (FT_MulFix(Face->bbox.xMax, XScale) + 32) >> 6; - Otm->otmrcFontBox.top = (FT_MulFix(Face->bbox.yMax, YScale) + 32) >> 6; - Otm->otmrcFontBox.bottom = (FT_MulFix(Face->bbox.yMin, YScale) + 32) >> 6; + +#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 = (FT_MulFix(pOS2->ySubscriptXSize, XScale) + 32) >> 6; - Otm->otmptSubscriptSize.y = (FT_MulFix(pOS2->ySubscriptYSize, YScale) + 32) >> 6; - Otm->otmptSubscriptOffset.x = (FT_MulFix(pOS2->ySubscriptXOffset, XScale) + 32) >> 6; - Otm->otmptSubscriptOffset.y = (FT_MulFix(pOS2->ySubscriptYOffset, YScale) + 32) >> 6; - Otm->otmptSuperscriptSize.x = (FT_MulFix(pOS2->ySuperscriptXSize, XScale) + 32) >> 6; - Otm->otmptSuperscriptSize.y = (FT_MulFix(pOS2->ySuperscriptYSize, YScale) + 32) >> 6; - Otm->otmptSuperscriptOffset.x = (FT_MulFix(pOS2->ySuperscriptXOffset, XScale) + 32) >> 6; - Otm->otmptSuperscriptOffset.y = (FT_MulFix(pOS2->ySuperscriptYOffset, YScale) + 32) >> 6; - Otm->otmsStrikeoutSize = (FT_MulFix(pOS2->yStrikeoutSize, YScale) + 32) >> 6; - Otm->otmsStrikeoutPosition = (FT_MulFix(pOS2->yStrikeoutPosition, YScale) + 32) >> 6; + 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) { Otm->otmsUnderscoreSize = 0; @@ -2102,40 +2165,19 @@ IntGetOutlineTextMetrics(PFONTGDI FontGDI, } else { - Otm->otmsUnderscoreSize = (FT_MulFix(pPost->underlineThickness, YScale) + 32) >> 6; - Otm->otmsUnderscorePosition = (FT_MulFix(pPost->underlinePosition, YScale) + 32) >> 6; + Otm->otmsUnderscoreSize = SCALE_Y(pPost->underlineThickness); + Otm->otmsUnderscorePosition = SCALE_Y(pPost->underlinePosition); }
- IntUnLockFreeType(); - - Cp = (char*) Otm + sizeof(OUTLINETEXTMETRICW); +#undef SCALE_X +#undef SCALE_Y
- /* family name */ - Otm->otmpFamilyName = (LPSTR)(Cp - (char*) Otm); - wcscpy((WCHAR*) Cp, FamilyNameW.Buffer); - Cp += FamilyNameW.Length + sizeof(WCHAR); - - /* face name */ - Otm->otmpFaceName = (LPSTR)(Cp - (char*) Otm); - wcscpy((WCHAR*) Cp, FaceNameW.Buffer); - Cp += FaceNameW.Length + sizeof(WCHAR); - - /* style name */ - Otm->otmpStyleName = (LPSTR)(Cp - (char*) Otm); - wcscpy((WCHAR*) Cp, StyleNameW.Buffer); - Cp += StyleNameW.Length + sizeof(WCHAR); - - /* unique name (full name) */ - Otm->otmpFullName = (LPSTR)(Cp - (char*) Otm); - wcscpy((WCHAR*) Cp, FullNameW.Buffer); - Cp += FullNameW.Length + sizeof(WCHAR); + IntUnLockFreeType();
- ASSERT(Cp - (char*)Otm == Cache->OutlineRequiredSize); + pb = IntStoreFontNames(&FontNames, Otm); + ASSERT(pb - (BYTE*)Otm == Cache->OutlineRequiredSize);
- RtlFreeUnicodeString(&FamilyNameW); - RtlFreeUnicodeString(&FaceNameW); - RtlFreeUnicodeString(&StyleNameW); - RtlFreeUnicodeString(&FullNameW); + IntFreeFontNames(&FontNames);
return Cache->OutlineRequiredSize; }