[NTGDI][FREETYPE] Font cache: Use hash (#4901)

- Modify FONT_CACHE_ENTRY structure to use hash.
- Use hash in ftGdiGlyphCacheGet and ftGdiGlyphCacheSet functions.
- Reduce function call overheads by using FONT_CACHE_ENTRY, in getting glyph.
CORE-11848
This commit is contained in:
Katayama Hirofumi MZ 2022-11-27 11:26:44 +09:00 committed by GitHub
parent 430674022a
commit 57702ed401
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 146 additions and 118 deletions

View file

@ -23,19 +23,44 @@ typedef struct _FONT_ENTRY_COLL_MEM
FONT_ENTRY_MEM *Entry; FONT_ENTRY_MEM *Entry;
} FONT_ENTRY_COLL_MEM, *PFONT_ENTRY_COLL_MEM; } FONT_ENTRY_COLL_MEM, *PFONT_ENTRY_COLL_MEM;
#include <pshpack1.h> /* We don't like padding for these structures */
typedef struct _EMULATION_BOLD_ITALIC
{
BYTE Bold;
BYTE Italic;
} EMULATION_BOLD_ITALIC, *PEMULATION_BOLD_ITALIC;
typedef struct _FONT_ASPECT
{
_ANONYMOUS_UNION union {
EMULATION_BOLD_ITALIC Emu;
WORD EmuBoldItalic;
} DUMMYUNIONNAME;
WORD RenderMode;
} FONT_ASPECT, *PFONT_ASPECT;
typedef struct _FONT_CACHE_ENTRY typedef struct _FONT_CACHE_ENTRY
{ {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
int GlyphIndex;
FT_Face Face;
FT_BitmapGlyph BitmapGlyph; FT_BitmapGlyph BitmapGlyph;
int Height; DWORD dwHash;
int Width;
int Escapement; /* The following members are hashed */
FT_Render_Mode RenderMode; INT GlyphIndex;
FT_Face Face;
LONG lfHeight;
_ANONYMOUS_UNION union {
FONT_ASPECT Aspect;
DWORD AspectValue;
} DUMMYUNIONNAME;
FT_Matrix matTransform; FT_Matrix matTransform;
} FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY; } FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY;
#include <poppack.h>
C_ASSERT(offsetof(FONT_CACHE_ENTRY, GlyphIndex) % sizeof(DWORD) == 0);
C_ASSERT(sizeof(FONT_CACHE_ENTRY) % sizeof(DWORD) == 0);
/* /*
* FONTSUBST_... --- constants for font substitutes * FONTSUBST_... --- constants for font substitutes

View file

@ -43,7 +43,7 @@
/* Is bold emulation necessary? */ /* Is bold emulation necessary? */
#define EMUBOLD_NEEDED(original, request) \ #define EMUBOLD_NEEDED(original, request) \
((request) != FW_DONTCARE) && ((request) - (original) >= FW_BOLD - FW_MEDIUM) (((request) != FW_DONTCARE) && ((request) - (original) >= FW_BOLD - FW_MEDIUM))
extern const MATRIX gmxWorldToDeviceDefault; extern const MATRIX gmxWorldToDeviceDefault;
extern const MATRIX gmxWorldToPageDefault; extern const MATRIX gmxWorldToPageDefault;
@ -3112,16 +3112,27 @@ ftGdiGetRasterizerCaps(LPRASTERIZER_STATUS lprs)
return FALSE; return FALSE;
} }
static DWORD APIENTRY
IntGetHash(LPCVOID pv, DWORD cdw)
{
DWORD dwHash = cdw;
const DWORD *pdw = pv;
while (cdw-- > 0)
{
dwHash *= 3;
dwHash ^= *pdw++;
}
return dwHash;
}
FT_BitmapGlyph APIENTRY FT_BitmapGlyph APIENTRY
ftGdiGlyphCacheGet( ftGdiGlyphCacheGet(const FONT_CACHE_ENTRY *pCache)
FT_Face Face,
INT GlyphIndex,
INT Height,
FT_Render_Mode RenderMode,
const FT_Matrix *pmatTransform)
{ {
PLIST_ENTRY CurrentEntry; PLIST_ENTRY CurrentEntry;
PFONT_CACHE_ENTRY FontEntry; PFONT_CACHE_ENTRY FontEntry;
DWORD dwHash = pCache->dwHash;
ASSERT_FREETYPE_LOCK_HELD(); ASSERT_FREETYPE_LOCK_HELD();
@ -3130,12 +3141,15 @@ ftGdiGlyphCacheGet(
CurrentEntry = CurrentEntry->Flink) CurrentEntry = CurrentEntry->Flink)
{ {
FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry); FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry);
if ((FontEntry->Face == Face) && if (FontEntry->dwHash == dwHash &&
(FontEntry->GlyphIndex == GlyphIndex) && FontEntry->GlyphIndex == pCache->GlyphIndex &&
(FontEntry->Height == Height) && FontEntry->Face == pCache->Face &&
(FontEntry->RenderMode == RenderMode) && FontEntry->lfHeight == pCache->lfHeight &&
(memcmp(&FontEntry->matTransform, pmatTransform, sizeof(*pmatTransform)) == 0)) FontEntry->AspectValue == pCache->AspectValue &&
memcmp(&FontEntry->matTransform, &pCache->matTransform, sizeof(FT_Matrix)) == 0)
{
break; break;
}
} }
if (CurrentEntry == &g_FontCacheListHead) if (CurrentEntry == &g_FontCacheListHead)
@ -3160,6 +3174,8 @@ ftGdiGlyphSet(
FT_Bitmap AlignedBitmap; FT_Bitmap AlignedBitmap;
FT_BitmapGlyph BitmapGlyph; FT_BitmapGlyph BitmapGlyph;
ASSERT_FREETYPE_LOCK_HELD();
error = FT_Get_Glyph(GlyphSlot, &Glyph); error = FT_Get_Glyph(GlyphSlot, &Glyph);
if (error) if (error)
{ {
@ -3192,12 +3208,8 @@ ftGdiGlyphSet(
FT_BitmapGlyph APIENTRY FT_BitmapGlyph APIENTRY
ftGdiGlyphCacheSet( ftGdiGlyphCacheSet(
FT_Face Face, PFONT_CACHE_ENTRY Cache,
INT GlyphIndex, FT_GlyphSlot GlyphSlot)
INT Height,
const FT_Matrix *pmatTransform,
FT_GlyphSlot GlyphSlot,
FT_Render_Mode RenderMode)
{ {
FT_Glyph GlyphCopy; FT_Glyph GlyphCopy;
INT error; INT error;
@ -3214,7 +3226,7 @@ ftGdiGlyphCacheSet(
return NULL; return NULL;
}; };
error = FT_Glyph_To_Bitmap(&GlyphCopy, RenderMode, 0, 1); error = FT_Glyph_To_Bitmap(&GlyphCopy, Cache->Aspect.RenderMode, 0, 1);
if (error) if (error)
{ {
FT_Done_Glyph(GlyphCopy); FT_Done_Glyph(GlyphCopy);
@ -3244,12 +3256,9 @@ ftGdiGlyphCacheSet(
FT_Bitmap_Done(GlyphSlot->library, &BitmapGlyph->bitmap); FT_Bitmap_Done(GlyphSlot->library, &BitmapGlyph->bitmap);
BitmapGlyph->bitmap = AlignedBitmap; BitmapGlyph->bitmap = AlignedBitmap;
NewEntry->GlyphIndex = GlyphIndex;
NewEntry->Face = Face;
NewEntry->BitmapGlyph = BitmapGlyph; NewEntry->BitmapGlyph = BitmapGlyph;
NewEntry->Height = Height; RtlCopyMemory(&NewEntry->dwHash, &Cache->dwHash,
NewEntry->RenderMode = RenderMode; sizeof(FONT_CACHE_ENTRY) - offsetof(FONT_CACHE_ENTRY, dwHash));
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)
@ -4200,55 +4209,54 @@ ftGdiGetGlyphOutline(
FT_BitmapGlyph FT_BitmapGlyph
APIENTRY APIENTRY
ftGdiGetRealGlyph( ftGdiGetRealGlyph(
FT_Face face, PFONT_CACHE_ENTRY Cache)
INT glyph_index,
LONG lfHeight,
FT_Render_Mode RenderMode,
const FT_Matrix *pmat,
BOOL EmuBold,
BOOL EmuItalic)
{ {
INT error; INT error;
FT_GlyphSlot glyph; FT_GlyphSlot glyph;
FT_BitmapGlyph realglyph; FT_BitmapGlyph realglyph;
DWORD cdw;
if (EmuBold || EmuItalic) ASSERT_FREETYPE_LOCK_HELD();
if (Cache->Aspect.EmuBoldItalic)
{ {
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_BITMAP); error = FT_Load_Glyph(Cache->Face, Cache->GlyphIndex, FT_LOAD_NO_BITMAP);
if (error)
{
DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n", Cache->GlyphIndex);
return NULL;
}
glyph = Cache->Face->glyph;
if (Cache->Aspect.Emu.Bold)
FT_GlyphSlot_Embolden(glyph);
if (Cache->Aspect.Emu.Italic)
FT_GlyphSlot_Oblique(glyph);
realglyph = ftGdiGlyphSet(Cache->Face, glyph, Cache->Aspect.RenderMode);
} }
else else
{ {
realglyph = ftGdiGlyphCacheGet(face, glyph_index, lfHeight, cdw = (sizeof(FONT_CACHE_ENTRY) - offsetof(FONT_CACHE_ENTRY, GlyphIndex)) / sizeof(DWORD);
RenderMode, pmat); Cache->dwHash = IntGetHash(&Cache->GlyphIndex, cdw);
realglyph = ftGdiGlyphCacheGet(Cache);
if (realglyph) if (realglyph)
return realglyph; return realglyph;
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); error = FT_Load_Glyph(Cache->Face, Cache->GlyphIndex, FT_LOAD_DEFAULT);
} if (error)
{
DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n", Cache->GlyphIndex);
return NULL;
}
if (error) glyph = Cache->Face->glyph;
{ realglyph = ftGdiGlyphCacheSet(Cache, glyph);
DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n", glyph_index);
return NULL;
}
glyph = face->glyph;
if (EmuBold || EmuItalic)
{
if (EmuBold)
FT_GlyphSlot_Embolden(glyph);
if (EmuItalic)
FT_GlyphSlot_Oblique(glyph);
realglyph = ftGdiGlyphSet(face, glyph, RenderMode);
}
else
{
realglyph = ftGdiGlyphCacheSet(face, glyph_index, lfHeight,
pmat, glyph, RenderMode);
} }
if (!realglyph) if (!realglyph)
DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); DPRINT1("Failed to render glyph! [index: %d]\n", Cache->GlyphIndex);
return realglyph; return realglyph;
} }
@ -4266,20 +4274,18 @@ TextIntGetTextExtentPoint(PDC dc,
FLONG fl) FLONG fl)
{ {
PFONTGDI FontGDI; PFONTGDI FontGDI;
FT_Face face;
FT_BitmapGlyph realglyph; FT_BitmapGlyph realglyph;
INT glyph_index, i, previous; INT glyph_index, i, previous;
ULONGLONG TotalWidth64 = 0; ULONGLONG TotalWidth64 = 0;
FT_Render_Mode RenderMode;
FT_Matrix mat;
PMATRIX pmxWorldToDevice; PMATRIX pmxWorldToDevice;
LOGFONTW *plf; LOGFONTW *plf;
BOOL use_kerning, EmuBold, EmuItalic; BOOL use_kerning;
LONG ascender, descender; LONG ascender, descender;
FONT_CACHE_ENTRY Cache;
FontGDI = ObjToGDI(TextObj->Font, FONT); FontGDI = ObjToGDI(TextObj->Font, FONT);
face = FontGDI->SharedFace->Face; Cache.Face = FontGDI->SharedFace->Face;
if (NULL != Fit) if (NULL != Fit)
{ {
*Fit = 0; *Fit = 0;
@ -4290,28 +4296,33 @@ TextIntGetTextExtentPoint(PDC dc,
TextIntUpdateSize(dc, TextObj, FontGDI, FALSE); TextIntUpdateSize(dc, TextObj, FontGDI, FALSE);
plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
EmuBold = EMUBOLD_NEEDED(FontGDI->OriginalWeight, plf->lfWeight); Cache.lfHeight = plf->lfHeight;
EmuItalic = (plf->lfItalic && !FontGDI->OriginalItalic);
Cache.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight, plf->lfWeight);
ASSERT(Cache.Aspect.Emu.Bold <= 1);
Cache.Aspect.Emu.Italic = (plf->lfItalic && !FontGDI->OriginalItalic);
ASSERT(Cache.Aspect.Emu.Italic <= 1);
if (IntIsFontRenderingEnabled()) if (IntIsFontRenderingEnabled())
RenderMode = IntGetFontRenderMode(plf); Cache.Aspect.RenderMode = (BYTE)IntGetFontRenderMode(plf);
else else
RenderMode = FT_RENDER_MODE_MONO; Cache.Aspect.RenderMode = (BYTE)FT_RENDER_MODE_MONO;
/* 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);
FtMatrixFromMx(&mat, pmxWorldToDevice); FtMatrixFromMx(&Cache.matTransform, pmxWorldToDevice);
FT_Set_Transform(face, &mat, 0); FT_Set_Transform(Cache.Face, &Cache.matTransform, 0);
use_kerning = FT_HAS_KERNING(face); use_kerning = FT_HAS_KERNING(Cache.Face);
previous = 0; previous = 0;
for (i = 0; i < Count; i++) for (i = 0; i < Count; i++)
{ {
glyph_index = get_glyph_index_flagged(face, *String, GTEF_INDICES, fl); glyph_index = get_glyph_index_flagged(Cache.Face, *String, GTEF_INDICES, fl);
Cache.GlyphIndex = glyph_index;
realglyph = ftGdiGetRealGlyph(face, glyph_index, plf->lfHeight, RenderMode, realglyph = ftGdiGetRealGlyph(&Cache);
&mat, EmuBold, EmuItalic);
if (!realglyph) if (!realglyph)
break; break;
@ -4319,7 +4330,7 @@ TextIntGetTextExtentPoint(PDC dc,
if (use_kerning && previous && glyph_index) if (use_kerning && previous && glyph_index)
{ {
FT_Vector delta; FT_Vector delta;
FT_Get_Kerning(face, previous, glyph_index, 0, &delta); FT_Get_Kerning(Cache.Face, previous, glyph_index, 0, &delta);
TotalWidth64 += delta.x; TotalWidth64 += delta.x;
} }
@ -4335,7 +4346,7 @@ TextIntGetTextExtentPoint(PDC dc,
} }
/* Bold and italic do not use the cache */ /* Bold and italic do not use the cache */
if (EmuBold || EmuItalic) if (Cache.Aspect.EmuBoldItalic)
{ {
FT_Done_Glyph((FT_Glyph)realglyph); FT_Done_Glyph((FT_Glyph)realglyph);
} }
@ -5860,17 +5871,13 @@ ftGdiGetTextWidth(
LONGLONG *pTextWidth64, LONGLONG *pTextWidth64,
LPCWSTR String, LPCWSTR String,
INT Count, INT Count,
FT_Face face, PFONT_CACHE_ENTRY Cache,
LONG lfHeight, UINT fuOptions)
UINT fuOptions,
FT_Render_Mode RenderMode,
const FT_Matrix *pmat,
BOOL EmuBold,
BOOL EmuItalic)
{ {
LONGLONG TextLeft64 = 0; LONGLONG TextLeft64 = 0;
INT glyph_index; INT glyph_index;
FT_BitmapGlyph realglyph; FT_BitmapGlyph realglyph;
FT_Face face = Cache->Face;
BOOL use_kerning = FT_HAS_KERNING(face); BOOL use_kerning = FT_HAS_KERNING(face);
ULONG previous = 0; ULONG previous = 0;
FT_Vector delta; FT_Vector delta;
@ -5880,9 +5887,9 @@ ftGdiGetTextWidth(
while (Count-- > 0) while (Count-- > 0)
{ {
glyph_index = get_glyph_index_flagged(face, *String, ETO_GLYPH_INDEX, fuOptions); glyph_index = get_glyph_index_flagged(face, *String, ETO_GLYPH_INDEX, fuOptions);
Cache->GlyphIndex = glyph_index;
realglyph = ftGdiGetRealGlyph(face, glyph_index, lfHeight, RenderMode, realglyph = ftGdiGetRealGlyph(Cache);
pmat, EmuBold, EmuItalic);
if (!realglyph) if (!realglyph)
return FALSE; return FALSE;
@ -5895,7 +5902,7 @@ ftGdiGetTextWidth(
TextLeft64 += realglyph->root.advance.x >> 10; TextLeft64 += realglyph->root.advance.x >> 10;
if (EmuBold || EmuItalic) if (Cache->Aspect.EmuBoldItalic)
FT_Done_Glyph((FT_Glyph)realglyph); FT_Done_Glyph((FT_Glyph)realglyph);
previous = glyph_index; previous = glyph_index;
@ -5941,16 +5948,15 @@ IntExtTextOutW(
PFONTGDI FontGDI; PFONTGDI FontGDI;
PTEXTOBJ TextObj; PTEXTOBJ TextObj;
EXLATEOBJ exloRGB2Dst, exloDst2RGB; EXLATEOBJ exloRGB2Dst, exloDst2RGB;
FT_Render_Mode RenderMode;
FT_Matrix mat;
POINT Start; POINT Start;
USHORT DxShift; USHORT DxShift;
PMATRIX pmxWorldToDevice; PMATRIX pmxWorldToDevice;
LONG lfHeight, fixAscender, fixDescender; LONG fixAscender, fixDescender;
FLOATOBJ Scale; FLOATOBJ Scale;
LOGFONTW *plf; LOGFONTW *plf;
BOOL use_kerning, EmuBold, EmuItalic, bResult, DoBreak; BOOL use_kerning, bResult, DoBreak;
FT_Vector delta; FT_Vector delta;
FONT_CACHE_ENTRY Cache;
/* Check if String is valid */ /* Check if String is valid */
if (Count > 0xFFFF || (Count > 0 && String == NULL)) if (Count > 0xFFFF || (Count > 0 && String == NULL))
@ -6067,17 +6073,21 @@ IntExtTextOutW(
ASSERT(FontGDI); ASSERT(FontGDI);
IntLockFreeType(); IntLockFreeType();
face = FontGDI->SharedFace->Face; Cache.Face = face = FontGDI->SharedFace->Face;
plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont; plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
lfHeight = plf->lfHeight; Cache.lfHeight = plf->lfHeight;
EmuBold = EMUBOLD_NEEDED(FontGDI->OriginalWeight, plf->lfWeight);
EmuItalic = (plf->lfItalic && !FontGDI->OriginalItalic); Cache.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight, plf->lfWeight);
ASSERT(Cache.Aspect.Emu.Bold <= 1);
Cache.Aspect.Emu.Italic = (plf->lfItalic && !FontGDI->OriginalItalic);
ASSERT(Cache.Aspect.Emu.Italic <= 1);
if (IntIsFontRenderingEnabled()) if (IntIsFontRenderingEnabled())
RenderMode = IntGetFontRenderMode(plf); Cache.Aspect.RenderMode = (BYTE)IntGetFontRenderMode(plf);
else else
RenderMode = FT_RENDER_MODE_MONO; Cache.Aspect.RenderMode = (BYTE)FT_RENDER_MODE_MONO;
if (!TextIntUpdateSize(dc, TextObj, FontGDI, FALSE)) if (!TextIntUpdateSize(dc, TextObj, FontGDI, FALSE))
{ {
@ -6090,8 +6100,8 @@ IntExtTextOutW(
if (pdcattr->iGraphicsMode == GM_ADVANCED) if (pdcattr->iGraphicsMode == GM_ADVANCED)
{ {
pmxWorldToDevice = DC_pmxWorldToDevice(dc); pmxWorldToDevice = DC_pmxWorldToDevice(dc);
FtMatrixFromMx(&mat, pmxWorldToDevice); FtMatrixFromMx(&Cache.matTransform, pmxWorldToDevice);
FT_Set_Transform(face, &mat, 0); FT_Set_Transform(face, &Cache.matTransform, 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;
@ -6099,8 +6109,8 @@ IntExtTextOutW(
else else
{ {
pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault; pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault;
FtMatrixFromMx(&mat, pmxWorldToDevice); FtMatrixFromMx(&Cache.matTransform, pmxWorldToDevice);
FT_Set_Transform(face, &mat, 0); FT_Set_Transform(face, &Cache.matTransform, 0);
fixAscender = FontGDI->tmAscent << 6; fixAscender = FontGDI->tmAscent << 6;
fixDescender = FontGDI->tmDescent << 6; fixDescender = FontGDI->tmDescent << 6;
@ -6123,14 +6133,7 @@ IntExtTextOutW(
/* Calculate the text width if necessary */ /* Calculate the text width if necessary */
if ((fuOptions & ETO_OPAQUE) || (pdcattr->flTextAlign & (TA_CENTER | TA_RIGHT))) if ((fuOptions & ETO_OPAQUE) || (pdcattr->flTextAlign & (TA_CENTER | TA_RIGHT)))
{ {
if (!ftGdiGetTextWidth(&TextWidth64, if (!ftGdiGetTextWidth(&TextWidth64, String, Count, &Cache, fuOptions))
String, Count,
face,
lfHeight,
fuOptions,
RenderMode,
&mat,
EmuBold, EmuItalic))
{ {
IntUnLockFreeType(); IntUnLockFreeType();
bResult = FALSE; bResult = FALSE;
@ -6200,9 +6203,9 @@ IntExtTextOutW(
for (i = 0; i < Count; ++i) for (i = 0; i < Count; ++i)
{ {
glyph_index = get_glyph_index_flagged(face, *String++, ETO_GLYPH_INDEX, fuOptions); glyph_index = get_glyph_index_flagged(face, *String++, ETO_GLYPH_INDEX, fuOptions);
Cache.GlyphIndex = glyph_index;
realglyph = ftGdiGetRealGlyph(face, glyph_index, lfHeight, RenderMode, realglyph = ftGdiGetRealGlyph(&Cache);
&mat, EmuBold, EmuItalic);
if (!realglyph) if (!realglyph)
{ {
bResult = FALSE; bResult = FALSE;
@ -6246,7 +6249,7 @@ IntExtTextOutW(
{ {
DPRINT1("WARNING: EngCreateBitmap() failed!\n"); DPRINT1("WARNING: EngCreateBitmap() failed!\n");
bResult = FALSE; bResult = FALSE;
if (EmuBold || EmuItalic) if (Cache.Aspect.EmuBoldItalic)
FT_Done_Glyph((FT_Glyph)realglyph); FT_Done_Glyph((FT_Glyph)realglyph);
break; break;
} }
@ -6257,7 +6260,7 @@ IntExtTextOutW(
EngDeleteSurface((HSURF)HSourceGlyph); EngDeleteSurface((HSURF)HSourceGlyph);
DPRINT1("WARNING: EngLockSurface() failed!\n"); DPRINT1("WARNING: EngLockSurface() failed!\n");
bResult = FALSE; bResult = FALSE;
if (EmuBold || EmuItalic) if (Cache.Aspect.EmuBoldItalic)
FT_Done_Glyph((FT_Glyph)realglyph); FT_Done_Glyph((FT_Glyph)realglyph);
break; break;
} }
@ -6308,7 +6311,7 @@ IntExtTextOutW(
if (DoBreak) if (DoBreak)
{ {
if (EmuBold || EmuItalic) if (Cache.Aspect.EmuBoldItalic)
FT_Done_Glyph((FT_Glyph)realglyph); FT_Done_Glyph((FT_Glyph)realglyph);
break; break;
} }
@ -6338,7 +6341,7 @@ IntExtTextOutW(
previous = glyph_index; previous = glyph_index;
if (EmuBold || EmuItalic) if (Cache.Aspect.EmuBoldItalic)
{ {
FT_Done_Glyph((FT_Glyph)realglyph); FT_Done_Glyph((FT_Glyph)realglyph);
} }