[NTGDI][FREETYPE] Font cache: Use FT_Matrix instead of MATRIX (#4900)

- Use FT_Matrix instead of MATRIX in FONT_CACHE_ENTRY structure.
- Use FtMatrixFromMx and FT_Set_Transform instead of FtSetCoordinateTransform.
CORE-11848
This commit is contained in:
Katayama Hirofumi MZ 2022-11-25 11:23:29 +09:00 committed by GitHub
parent 9658c6a220
commit 3f3714bad4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 64 deletions

View file

@ -33,7 +33,7 @@ typedef struct _FONT_CACHE_ENTRY
int Width; int Width;
int Escapement; int Escapement;
FT_Render_Mode RenderMode; FT_Render_Mode RenderMode;
MATRIX mxWorldToDevice; FT_Matrix matTransform;
} FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY; } FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY;

View file

@ -749,7 +749,7 @@ VOID FASTCALL IntEscapeMatrix(FT_Matrix *pmat, LONG lfEscapement)
} }
VOID FASTCALL VOID FASTCALL
FtMatrixFromMx(FT_Matrix *pmat, PMATRIX pmx) FtMatrixFromMx(FT_Matrix *pmat, const MATRIX *pmx)
{ {
FLOATOBJ ef; FLOATOBJ ef;
@ -760,44 +760,21 @@ FtMatrixFromMx(FT_Matrix *pmat, PMATRIX pmx)
ef = pmx->efM21; ef = pmx->efM21;
FLOATOBJ_MulLong(&ef, 0x00010000); FLOATOBJ_MulLong(&ef, 0x00010000);
pmat->xy = FLOATOBJ_GetLong(&ef); pmat->xy = -FLOATOBJ_GetLong(&ef); /* (*1) See below */
ef = pmx->efM12; ef = pmx->efM12;
FLOATOBJ_MulLong(&ef, 0x00010000); FLOATOBJ_MulLong(&ef, 0x00010000);
pmat->yx = FLOATOBJ_GetLong(&ef); pmat->yx = -FLOATOBJ_GetLong(&ef); /* (*1) See below */
ef = pmx->efM22; ef = pmx->efM22;
FLOATOBJ_MulLong(&ef, 0x00010000); FLOATOBJ_MulLong(&ef, 0x00010000);
pmat->yy = FLOATOBJ_GetLong(&ef); pmat->yy = FLOATOBJ_GetLong(&ef);
}
VOID // (*1): Y direction is mirrored as follows:
FtSetCoordinateTransform( //
FT_Face face, // [ M11 -M12 ] [ X ] [ M11*X + M12*Y ]
PMATRIX pmx) // [ ] * [ ] == [ ]
{ // [ -M21 M22 ] [ -Y ] [ -(M21*X + M22*Y) ].
FT_Matrix ftmatrix;
FLOATOBJ efTemp;
/* Create a freetype matrix, by converting to 16.16 fixpoint format */
efTemp = pmx->efM11;
FLOATOBJ_MulLong(&efTemp, 0x00010000);
ftmatrix.xx = FLOATOBJ_GetLong(&efTemp);
efTemp = pmx->efM12;
FLOATOBJ_MulLong(&efTemp, 0x00010000);
ftmatrix.xy = FLOATOBJ_GetLong(&efTemp);
efTemp = pmx->efM21;
FLOATOBJ_MulLong(&efTemp, 0x00010000);
ftmatrix.yx = FLOATOBJ_GetLong(&efTemp);
efTemp = pmx->efM22;
FLOATOBJ_MulLong(&efTemp, 0x00010000);
ftmatrix.yy = FLOATOBJ_GetLong(&efTemp);
/* Set the transformation matrix */
FT_Set_Transform(face, &ftmatrix, 0);
} }
static BOOL static BOOL
@ -3135,25 +3112,13 @@ ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS lprs)
return FALSE; return FALSE;
} }
static
BOOL
SameScaleMatrix(
PMATRIX pmx1,
PMATRIX pmx2)
{
return (FLOATOBJ_Equal(&pmx1->efM11, &pmx2->efM11) &&
FLOATOBJ_Equal(&pmx1->efM12, &pmx2->efM12) &&
FLOATOBJ_Equal(&pmx1->efM21, &pmx2->efM21) &&
FLOATOBJ_Equal(&pmx1->efM22, &pmx2->efM22));
}
FT_BitmapGlyph APIENTRY FT_BitmapGlyph APIENTRY
ftGdiGlyphCacheGet( ftGdiGlyphCacheGet(
FT_Face Face, FT_Face Face,
INT GlyphIndex, INT GlyphIndex,
INT Height, INT Height,
FT_Render_Mode RenderMode, FT_Render_Mode RenderMode,
PMATRIX pmx) const FT_Matrix *pmatTransform)
{ {
PLIST_ENTRY CurrentEntry; PLIST_ENTRY CurrentEntry;
PFONT_CACHE_ENTRY FontEntry; PFONT_CACHE_ENTRY FontEntry;
@ -3169,7 +3134,7 @@ ftGdiGlyphCacheGet(
(FontEntry->GlyphIndex == GlyphIndex) && (FontEntry->GlyphIndex == GlyphIndex) &&
(FontEntry->Height == Height) && (FontEntry->Height == Height) &&
(FontEntry->RenderMode == RenderMode) && (FontEntry->RenderMode == RenderMode) &&
(SameScaleMatrix(&FontEntry->mxWorldToDevice, pmx))) (memcmp(&FontEntry->matTransform, pmatTransform, sizeof(*pmatTransform)) == 0))
break; break;
} }
@ -3230,7 +3195,7 @@ ftGdiGlyphCacheSet(
FT_Face Face, FT_Face Face,
INT GlyphIndex, INT GlyphIndex,
INT Height, INT Height,
PMATRIX pmx, const FT_Matrix *pmatTransform,
FT_GlyphSlot GlyphSlot, FT_GlyphSlot GlyphSlot,
FT_Render_Mode RenderMode) FT_Render_Mode RenderMode)
{ {
@ -3284,7 +3249,7 @@ ftGdiGlyphCacheSet(
NewEntry->BitmapGlyph = BitmapGlyph; NewEntry->BitmapGlyph = BitmapGlyph;
NewEntry->Height = Height; NewEntry->Height = Height;
NewEntry->RenderMode = RenderMode; NewEntry->RenderMode = RenderMode;
NewEntry->mxWorldToDevice = *pmx; NewEntry->matTransform = *pmatTransform;
InsertHeadList(&g_FontCacheListHead, &NewEntry->ListEntry); InsertHeadList(&g_FontCacheListHead, &NewEntry->ListEntry);
if (++g_FontCacheNumEntries > MAX_FONT_CACHE) if (++g_FontCacheNumEntries > MAX_FONT_CACHE)
@ -3776,7 +3741,7 @@ ftGdiGetGlyphOutline(
INT left, right, top = 0, bottom = 0; INT left, right, top = 0, bottom = 0;
FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; FT_Int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
FLOATOBJ eM11, widthRatio, eTemp; FLOATOBJ eM11, widthRatio, eTemp;
FT_Matrix transMat = identityMat; FT_Matrix mat, transMat = identityMat;
BOOL needsTransform = FALSE; BOOL needsTransform = FALSE;
INT orientation; INT orientation;
LONG aveWidth; LONG aveWidth;
@ -3829,7 +3794,8 @@ ftGdiGetGlyphOutline(
IntLockFreeType(); IntLockFreeType();
TextIntUpdateSize(dc, TextObj, FontGDI, FALSE); TextIntUpdateSize(dc, TextObj, FontGDI, FALSE);
FtSetCoordinateTransform(ft_face, DC_pmxWorldToDevice(dc)); FtMatrixFromMx(&mat, DC_pmxWorldToDevice(dc));
FT_Set_Transform(ft_face, &mat, 0);
TEXTOBJ_UnlockText(TextObj); TEXTOBJ_UnlockText(TextObj);
@ -4238,7 +4204,7 @@ ftGdiGetRealGlyph(
INT glyph_index, INT glyph_index,
LONG lfHeight, LONG lfHeight,
FT_Render_Mode RenderMode, FT_Render_Mode RenderMode,
PMATRIX pmxWorldToDevice, const FT_Matrix *pmat,
BOOL EmuBold, BOOL EmuBold,
BOOL EmuItalic) BOOL EmuItalic)
{ {
@ -4253,7 +4219,7 @@ ftGdiGetRealGlyph(
else else
{ {
realglyph = ftGdiGlyphCacheGet(face, glyph_index, lfHeight, realglyph = ftGdiGlyphCacheGet(face, glyph_index, lfHeight,
RenderMode, pmxWorldToDevice); RenderMode, pmat);
if (realglyph) if (realglyph)
return realglyph; return realglyph;
@ -4278,7 +4244,7 @@ ftGdiGetRealGlyph(
else else
{ {
realglyph = ftGdiGlyphCacheSet(face, glyph_index, lfHeight, realglyph = ftGdiGlyphCacheSet(face, glyph_index, lfHeight,
pmxWorldToDevice, glyph, RenderMode); pmat, glyph, RenderMode);
} }
if (!realglyph) if (!realglyph)
@ -4305,6 +4271,7 @@ TextIntGetTextExtentPoint(PDC dc,
INT glyph_index, i, previous; INT glyph_index, i, previous;
ULONGLONG TotalWidth64 = 0; ULONGLONG TotalWidth64 = 0;
FT_Render_Mode RenderMode; FT_Render_Mode RenderMode;
FT_Matrix mat;
PMATRIX pmxWorldToDevice; PMATRIX pmxWorldToDevice;
LOGFONTW *plf; LOGFONTW *plf;
BOOL use_kerning, EmuBold, EmuItalic; BOOL use_kerning, EmuBold, EmuItalic;
@ -4333,7 +4300,8 @@ TextIntGetTextExtentPoint(PDC dc,
/* Get the DC's world-to-device transformation matrix */ /* Get the DC's world-to-device transformation matrix */
pmxWorldToDevice = DC_pmxWorldToDevice(dc); pmxWorldToDevice = DC_pmxWorldToDevice(dc);
FtSetCoordinateTransform(face, pmxWorldToDevice); FtMatrixFromMx(&mat, pmxWorldToDevice);
FT_Set_Transform(face, &mat, 0);
use_kerning = FT_HAS_KERNING(face); use_kerning = FT_HAS_KERNING(face);
previous = 0; previous = 0;
@ -4343,7 +4311,7 @@ TextIntGetTextExtentPoint(PDC dc,
glyph_index = get_glyph_index_flagged(face, *String, GTEF_INDICES, fl); glyph_index = get_glyph_index_flagged(face, *String, GTEF_INDICES, fl);
realglyph = ftGdiGetRealGlyph(face, glyph_index, plf->lfHeight, RenderMode, realglyph = ftGdiGetRealGlyph(face, glyph_index, plf->lfHeight, RenderMode,
pmxWorldToDevice, EmuBold, EmuItalic); &mat, EmuBold, EmuItalic);
if (!realglyph) if (!realglyph)
break; break;
@ -4585,6 +4553,7 @@ ftGdiGetTextMetricsW(
ULONG Error; ULONG Error;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
LOGFONTW *plf; LOGFONTW *plf;
FT_Matrix mat;
if (!ptmwi) if (!ptmwi)
{ {
@ -4609,7 +4578,8 @@ ftGdiGetTextMetricsW(
IntLockFreeType(); IntLockFreeType();
Error = IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight); Error = IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
FtSetCoordinateTransform(Face, DC_pmxWorldToDevice(dc)); FtMatrixFromMx(&mat, DC_pmxWorldToDevice(dc));
FT_Set_Transform(Face, &mat, 0);
IntUnLockFreeType(); IntUnLockFreeType();
if (0 != Error) if (0 != Error)
@ -5894,7 +5864,7 @@ ftGdiGetTextWidth(
LONG lfHeight, LONG lfHeight,
UINT fuOptions, UINT fuOptions,
FT_Render_Mode RenderMode, FT_Render_Mode RenderMode,
PMATRIX pmxWorldToDevice, const FT_Matrix *pmat,
BOOL EmuBold, BOOL EmuBold,
BOOL EmuItalic) BOOL EmuItalic)
{ {
@ -5912,7 +5882,7 @@ ftGdiGetTextWidth(
glyph_index = get_glyph_index_flagged(face, *String, ETO_GLYPH_INDEX, fuOptions); glyph_index = get_glyph_index_flagged(face, *String, ETO_GLYPH_INDEX, fuOptions);
realglyph = ftGdiGetRealGlyph(face, glyph_index, lfHeight, RenderMode, realglyph = ftGdiGetRealGlyph(face, glyph_index, lfHeight, RenderMode,
pmxWorldToDevice, EmuBold, EmuItalic); pmat, EmuBold, EmuItalic);
if (!realglyph) if (!realglyph)
return FALSE; return FALSE;
@ -5972,6 +5942,7 @@ IntExtTextOutW(
PTEXTOBJ TextObj; PTEXTOBJ TextObj;
EXLATEOBJ exloRGB2Dst, exloDst2RGB; EXLATEOBJ exloRGB2Dst, exloDst2RGB;
FT_Render_Mode RenderMode; FT_Render_Mode RenderMode;
FT_Matrix mat;
POINT Start; POINT Start;
USHORT DxShift; USHORT DxShift;
PMATRIX pmxWorldToDevice; PMATRIX pmxWorldToDevice;
@ -6119,7 +6090,8 @@ IntExtTextOutW(
if (pdcattr->iGraphicsMode == GM_ADVANCED) if (pdcattr->iGraphicsMode == GM_ADVANCED)
{ {
pmxWorldToDevice = DC_pmxWorldToDevice(dc); pmxWorldToDevice = DC_pmxWorldToDevice(dc);
FtSetCoordinateTransform(face, pmxWorldToDevice); FtMatrixFromMx(&mat, pmxWorldToDevice);
FT_Set_Transform(face, &mat, 0);
fixAscender = ScaleLong(FontGDI->tmAscent, &pmxWorldToDevice->efM22) << 6; fixAscender = ScaleLong(FontGDI->tmAscent, &pmxWorldToDevice->efM22) << 6;
fixDescender = ScaleLong(FontGDI->tmDescent, &pmxWorldToDevice->efM22) << 6; fixDescender = ScaleLong(FontGDI->tmDescent, &pmxWorldToDevice->efM22) << 6;
@ -6127,7 +6099,8 @@ IntExtTextOutW(
else else
{ {
pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault; pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault;
FtSetCoordinateTransform(face, pmxWorldToDevice); FtMatrixFromMx(&mat, pmxWorldToDevice);
FT_Set_Transform(face, &mat, 0);
fixAscender = FontGDI->tmAscent << 6; fixAscender = FontGDI->tmAscent << 6;
fixDescender = FontGDI->tmDescent << 6; fixDescender = FontGDI->tmDescent << 6;
@ -6156,7 +6129,7 @@ IntExtTextOutW(
lfHeight, lfHeight,
fuOptions, fuOptions,
RenderMode, RenderMode,
pmxWorldToDevice, &mat,
EmuBold, EmuItalic)) EmuBold, EmuItalic))
{ {
IntUnLockFreeType(); IntUnLockFreeType();
@ -6229,7 +6202,7 @@ IntExtTextOutW(
glyph_index = get_glyph_index_flagged(face, *String++, ETO_GLYPH_INDEX, fuOptions); glyph_index = get_glyph_index_flagged(face, *String++, ETO_GLYPH_INDEX, fuOptions);
realglyph = ftGdiGetRealGlyph(face, glyph_index, lfHeight, RenderMode, realglyph = ftGdiGetRealGlyph(face, glyph_index, lfHeight, RenderMode,
pmxWorldToDevice, EmuBold, EmuItalic); &mat, EmuBold, EmuItalic);
if (!realglyph) if (!realglyph)
{ {
bResult = FALSE; bResult = FALSE;
@ -6626,6 +6599,7 @@ NtGdiGetCharABCWidthsW(
PFONTGDI FontGDI; PFONTGDI FontGDI;
FT_Face face; FT_Face face;
FT_CharMap charmap, found = NULL; FT_CharMap charmap, found = NULL;
FT_Matrix mat;
UINT i, glyph_index, BufferSize; UINT i, glyph_index, BufferSize;
HFONT hFont = 0; HFONT hFont = 0;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
@ -6749,7 +6723,8 @@ NtGdiGetCharABCWidthsW(
plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
IntLockFreeType(); IntLockFreeType();
IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight); IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
FtSetCoordinateTransform(face, pmxWorldToDevice); FtMatrixFromMx(&mat, pmxWorldToDevice);
FT_Set_Transform(face, &mat, 0);
for (i = FirstChar; i < FirstChar+Count; i++) for (i = FirstChar; i < FirstChar+Count; i++)
{ {
@ -6831,6 +6806,7 @@ NtGdiGetCharWidthW(
PFONTGDI FontGDI; PFONTGDI FontGDI;
FT_Face face; FT_Face face;
FT_CharMap charmap, found = NULL; FT_CharMap charmap, found = NULL;
FT_Matrix mat;
UINT i, glyph_index, BufferSize; UINT i, glyph_index, BufferSize;
HFONT hFont = 0; HFONT hFont = 0;
PMATRIX pmxWorldToDevice; PMATRIX pmxWorldToDevice;
@ -6939,7 +6915,8 @@ NtGdiGetCharWidthW(
plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
IntLockFreeType(); IntLockFreeType();
IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight); IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
FtSetCoordinateTransform(face, pmxWorldToDevice); FtMatrixFromMx(&mat, pmxWorldToDevice);
FT_Set_Transform(face, &mat, 0);
for (i = FirstChar; i < FirstChar+Count; i++) for (i = FirstChar; i < FirstChar+Count; i++)
{ {