https://git.reactos.org/?p=reactos.git;a=commitdiff;h=70e27198ae15e2c0ae237…
commit 70e27198ae15e2c0ae237368ff520fe39578e06f
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Oct 24 20:23:24 2018 +0900
Commit: GitHub <noreply(a)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;
}