mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[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:
parent
430674022a
commit
57702ed401
2 changed files with 146 additions and 118 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue