mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
[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
This commit is contained in:
parent
62da624689
commit
70e27198ae
|
@ -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);
|
||||
}
|
||||
|
||||
#undef SCALE_X
|
||||
#undef SCALE_Y
|
||||
|
||||
IntUnLockFreeType();
|
||||
|
||||
Cp = (char*) Otm + sizeof(OUTLINETEXTMETRICW);
|
||||
pb = IntStoreFontNames(&FontNames, Otm);
|
||||
ASSERT(pb - (BYTE*)Otm == Cache->OutlineRequiredSize);
|
||||
|
||||
/* 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);
|
||||
|
||||
ASSERT(Cp - (char*)Otm == Cache->OutlineRequiredSize);
|
||||
|
||||
RtlFreeUnicodeString(&FamilyNameW);
|
||||
RtlFreeUnicodeString(&FaceNameW);
|
||||
RtlFreeUnicodeString(&StyleNameW);
|
||||
RtlFreeUnicodeString(&FullNameW);
|
||||
IntFreeFontNames(&FontNames);
|
||||
|
||||
return Cache->OutlineRequiredSize;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue