[FONT][WIN32SS] Fix the storage processing of IntGetOutlineTextMetrics (#942)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Wed, 24 Oct 2018 11:23:24 +0000 (20:23 +0900)
committerGitHub <noreply@github.com>
Wed, 24 Oct 2018 11:23:24 +0000 (20:23 +0900)
* 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

index aca18cc..31a4b49 100644 (file)
@@ -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;
 }