https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4d0d22aee22a56b89990c…
commit 4d0d22aee22a56b89990c9e18b2a4cb3cf8d8af5
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Nov 29 19:41:09 2022 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Tue Nov 29 19:41:09 2022 +0900
[NTGDI][FREETYPE] Add special structure for hashing (#4916)
Add FONT_CACHE_HASHED structure and use it.
CORE-11848
---
win32ss/gdi/ntgdi/font.h | 34 ++++++-------
win32ss/gdi/ntgdi/freetype.c | 114 +++++++++++++++++++++----------------------
2 files changed, 73 insertions(+), 75 deletions(-)
diff --git a/win32ss/gdi/ntgdi/font.h b/win32ss/gdi/ntgdi/font.h
index e8526d8d91d..674406281a0 100644
--- a/win32ss/gdi/ntgdi/font.h
+++ b/win32ss/gdi/ntgdi/font.h
@@ -25,42 +25,42 @@ typedef struct _FONT_ENTRY_COLL_MEM
#include <pshpack1.h> /* We don't like padding for these structures for hashing
*/
-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;
+ struct {
+ BYTE Bold;
+ BYTE Italic;
+ } Emu;
} DUMMYUNIONNAME;
WORD RenderMode;
} FONT_ASPECT, *PFONT_ASPECT;
-typedef struct _FONT_CACHE_ENTRY
+typedef struct _FONT_CACHE_HASHED
{
- LIST_ENTRY ListEntry;
- FT_BitmapGlyph BitmapGlyph;
- DWORD dwHash;
-
- /* The following members are hashed */
INT GlyphIndex;
FT_Face Face;
LONG lfHeight;
_ANONYMOUS_UNION union {
- FONT_ASPECT Aspect;
DWORD AspectValue;
+ FONT_ASPECT Aspect;
} DUMMYUNIONNAME;
FT_Matrix matTransform;
-} FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY;
+} FONT_CACHE_HASHED, *PFONT_CACHE_HASHED;
#include <poppack.h>
-C_ASSERT(FIELD_OFFSET(FONT_CACHE_ENTRY, GlyphIndex) % sizeof(DWORD) == 0); /* for hashing
*/
-C_ASSERT(sizeof(FONT_CACHE_ENTRY) % sizeof(DWORD) == 0); /* for hashing */
+typedef struct _FONT_CACHE_ENTRY
+{
+ LIST_ENTRY ListEntry;
+ FT_BitmapGlyph BitmapGlyph;
+ DWORD dwHash;
+ FONT_CACHE_HASHED Hashed;
+} FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY;
+
+C_ASSERT(FIELD_OFFSET(FONT_CACHE_ENTRY, Hashed) % sizeof(DWORD) == 0); /* for hashing */
+C_ASSERT(sizeof(FONT_CACHE_HASHED) % sizeof(DWORD) == 0); /* for hashing */
/*
* FONTSUBST_... --- constants for font substitutes
diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c
index 1156684c40f..ea4a854bfad 100644
--- a/win32ss/gdi/ntgdi/freetype.c
+++ b/win32ss/gdi/ntgdi/freetype.c
@@ -280,7 +280,7 @@ RemoveCacheEntries(FT_Face Face)
FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry);
NextEntry = CurrentEntry->Flink;
- if (FontEntry->Face == Face)
+ if (FontEntry->Hashed.Face == Face)
{
RemoveCachedEntry(FontEntry);
}
@@ -3142,11 +3142,12 @@ ftGdiGlyphCacheGet(IN const FONT_CACHE_ENTRY *pCache)
{
FontEntry = CONTAINING_RECORD(CurrentEntry, FONT_CACHE_ENTRY, ListEntry);
if (FontEntry->dwHash == dwHash &&
- FontEntry->GlyphIndex == pCache->GlyphIndex &&
- FontEntry->Face == pCache->Face &&
- FontEntry->lfHeight == pCache->lfHeight &&
- FontEntry->AspectValue == pCache->AspectValue &&
- memcmp(&FontEntry->matTransform, &pCache->matTransform,
sizeof(FT_Matrix)) == 0)
+ FontEntry->Hashed.GlyphIndex == pCache->Hashed.GlyphIndex &&
+ FontEntry->Hashed.Face == pCache->Hashed.Face &&
+ FontEntry->Hashed.lfHeight == pCache->Hashed.lfHeight &&
+ FontEntry->Hashed.AspectValue == pCache->Hashed.AspectValue &&
+ memcmp(&FontEntry->Hashed.matTransform,
&pCache->Hashed.matTransform,
+ sizeof(FT_Matrix)) == 0)
{
break;
}
@@ -3226,7 +3227,7 @@ ftGdiGlyphCacheSet(
return NULL;
};
- error = FT_Glyph_To_Bitmap(&GlyphCopy, Cache->Aspect.RenderMode, 0, 1);
+ error = FT_Glyph_To_Bitmap(&GlyphCopy, Cache->Hashed.Aspect.RenderMode, 0,
1);
if (error)
{
FT_Done_Glyph(GlyphCopy);
@@ -3257,8 +3258,8 @@ ftGdiGlyphCacheSet(
BitmapGlyph->bitmap = AlignedBitmap;
NewEntry->BitmapGlyph = BitmapGlyph;
- RtlCopyMemory(&NewEntry->dwHash, &Cache->dwHash,
- sizeof(FONT_CACHE_ENTRY) - offsetof(FONT_CACHE_ENTRY, dwHash));
+ NewEntry->dwHash = Cache->dwHash;
+ NewEntry->Hashed = Cache->Hashed;
InsertHeadList(&g_FontCacheListHead, &NewEntry->ListEntry);
if (++g_FontCacheNumEntries > MAX_FONT_CACHE)
@@ -4213,49 +4214,48 @@ ftGdiGetRealGlyph(
INT error;
FT_GlyphSlot glyph;
FT_BitmapGlyph realglyph;
- DWORD cdw;
ASSERT_FREETYPE_LOCK_HELD();
- if (Cache->Aspect.EmuBoldItalic)
+ if (Cache->Hashed.Aspect.EmuBoldItalic)
{
- error = FT_Load_Glyph(Cache->Face, Cache->GlyphIndex, FT_LOAD_NO_BITMAP);
+ error = FT_Load_Glyph(Cache->Hashed.Face, Cache->Hashed.GlyphIndex,
FT_LOAD_NO_BITMAP);
if (error)
{
- DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n",
Cache->GlyphIndex);
+ DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n",
+ Cache->Hashed.GlyphIndex);
return NULL;
}
- glyph = Cache->Face->glyph;
+ glyph = Cache->Hashed.Face->glyph;
- if (Cache->Aspect.Emu.Bold)
+ if (Cache->Hashed.Aspect.Emu.Bold)
FT_GlyphSlot_Embolden(glyph);
- if (Cache->Aspect.Emu.Italic)
+ if (Cache->Hashed.Aspect.Emu.Italic)
FT_GlyphSlot_Oblique(glyph);
- realglyph = ftGdiGlyphSet(Cache->Face, glyph, Cache->Aspect.RenderMode);
+ realglyph = ftGdiGlyphSet(Cache->Hashed.Face, glyph,
Cache->Hashed.Aspect.RenderMode);
}
else
{
- cdw = (sizeof(FONT_CACHE_ENTRY) - offsetof(FONT_CACHE_ENTRY, GlyphIndex)) /
sizeof(DWORD);
- Cache->dwHash = IntGetHash(&Cache->GlyphIndex, cdw);
+ Cache->dwHash = IntGetHash(&Cache->Hashed, sizeof(Cache->Hashed) /
sizeof(DWORD));
realglyph = ftGdiGlyphCacheGet(Cache);
if (realglyph)
return realglyph;
- error = FT_Load_Glyph(Cache->Face, Cache->GlyphIndex, FT_LOAD_DEFAULT);
+ error = FT_Load_Glyph(Cache->Hashed.Face, Cache->Hashed.GlyphIndex,
FT_LOAD_DEFAULT);
if (error)
{
- DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n",
Cache->GlyphIndex);
+ DPRINT1("WARNING: Failed to load and render glyph! [index: %d]\n",
Cache->Hashed.GlyphIndex);
return NULL;
}
- glyph = Cache->Face->glyph;
+ glyph = Cache->Hashed.Face->glyph;
realglyph = ftGdiGlyphCacheSet(Cache, glyph);
}
if (!realglyph)
- DPRINT1("Failed to render glyph! [index: %d]\n",
Cache->GlyphIndex);
+ DPRINT1("Failed to render glyph! [index: %d]\n",
Cache->Hashed.GlyphIndex);
return realglyph;
}
@@ -4283,7 +4283,7 @@ TextIntGetTextExtentPoint(PDC dc,
FontGDI = ObjToGDI(TextObj->Font, FONT);
- Cache.Face = FontGDI->SharedFace->Face;
+ Cache.Hashed.Face = FontGDI->SharedFace->Face;
if (NULL != Fit)
{
*Fit = 0;
@@ -4294,30 +4294,30 @@ TextIntGetTextExtentPoint(PDC dc,
TextIntUpdateSize(dc, TextObj, FontGDI, FALSE);
plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
- Cache.lfHeight = plf->lfHeight;
- Cache.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight,
plf->lfWeight);
- Cache.Aspect.Emu.Italic = (plf->lfItalic && !FontGDI->OriginalItalic);
+ Cache.Hashed.lfHeight = plf->lfHeight;
+ Cache.Hashed.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight,
plf->lfWeight);
+ Cache.Hashed.Aspect.Emu.Italic = (plf->lfItalic &&
!FontGDI->OriginalItalic);
if (IntIsFontRenderingEnabled())
- Cache.Aspect.RenderMode = (BYTE)IntGetFontRenderMode(plf);
+ Cache.Hashed.Aspect.RenderMode = (BYTE)IntGetFontRenderMode(plf);
else
- Cache.Aspect.RenderMode = (BYTE)FT_RENDER_MODE_MONO;
+ Cache.Hashed.Aspect.RenderMode = (BYTE)FT_RENDER_MODE_MONO;
// NOTE: GetTextExtentPoint32 simply ignores lfEscapement and XFORM.
- if (FT_IS_SCALABLE(Cache.Face) && plf->lfWidth != 0)
- IntWidthMatrix(Cache.Face, &Cache.matTransform, plf->lfWidth);
+ if (FT_IS_SCALABLE(Cache.Hashed.Face) && plf->lfWidth != 0)
+ IntWidthMatrix(Cache.Hashed.Face, &Cache.Hashed.matTransform,
plf->lfWidth);
else
- Cache.matTransform = identityMat;
+ Cache.Hashed.matTransform = identityMat;
- FT_Set_Transform(Cache.Face, &Cache.matTransform, 0);
+ FT_Set_Transform(Cache.Hashed.Face, &Cache.Hashed.matTransform, 0);
- use_kerning = FT_HAS_KERNING(Cache.Face);
+ use_kerning = FT_HAS_KERNING(Cache.Hashed.Face);
previous = 0;
for (i = 0; i < Count; i++)
{
- glyph_index = get_glyph_index_flagged(Cache.Face, *String, GTEF_INDICES, fl);
- Cache.GlyphIndex = glyph_index;
+ glyph_index = get_glyph_index_flagged(Cache.Hashed.Face, *String, GTEF_INDICES,
fl);
+ Cache.Hashed.GlyphIndex = glyph_index;
realglyph = ftGdiGetRealGlyph(&Cache);
if (!realglyph)
@@ -4327,7 +4327,7 @@ TextIntGetTextExtentPoint(PDC dc,
if (use_kerning && previous && glyph_index)
{
FT_Vector delta;
- FT_Get_Kerning(Cache.Face, previous, glyph_index, 0, &delta);
+ FT_Get_Kerning(Cache.Hashed.Face, previous, glyph_index, 0, &delta);
TotalWidth64 += delta.x;
}
@@ -4337,14 +4337,13 @@ TextIntGetTextExtentPoint(PDC dc,
{
*Fit = i + 1;
}
-
if (NULL != Dx)
{
Dx[i] = (TotalWidth64 + 32) >> 6;
}
/* Bold and italic do not use the cache */
- if (Cache.Aspect.EmuBoldItalic)
+ if (Cache.Hashed.Aspect.EmuBoldItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
}
@@ -5874,7 +5873,7 @@ ftGdiGetTextWidth(
LONGLONG TextLeft64 = 0;
INT glyph_index;
FT_BitmapGlyph realglyph;
- FT_Face face = Cache->Face;
+ FT_Face face = Cache->Hashed.Face;
BOOL use_kerning = FT_HAS_KERNING(face);
ULONG previous = 0;
FT_Vector delta;
@@ -5884,7 +5883,7 @@ ftGdiGetTextWidth(
while (Count-- > 0)
{
glyph_index = get_glyph_index_flagged(face, *String, ETO_GLYPH_INDEX,
fuOptions);
- Cache->GlyphIndex = glyph_index;
+ Cache->Hashed.GlyphIndex = glyph_index;
realglyph = ftGdiGetRealGlyph(Cache);
if (!realglyph)
@@ -5899,7 +5898,7 @@ ftGdiGetTextWidth(
TextLeft64 += realglyph->root.advance.x >> 10;
- if (Cache->Aspect.EmuBoldItalic)
+ if (Cache->Hashed.Aspect.EmuBoldItalic)
FT_Done_Glyph((FT_Glyph)realglyph);
previous = glyph_index;
@@ -6070,18 +6069,17 @@ IntExtTextOutW(
ASSERT(FontGDI);
IntLockFreeType();
- Cache.Face = face = FontGDI->SharedFace->Face;
+ Cache.Hashed.Face = face = FontGDI->SharedFace->Face;
plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
- Cache.lfHeight = plf->lfHeight;
-
- Cache.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight,
plf->lfWeight);
- Cache.Aspect.Emu.Italic = (plf->lfItalic && !FontGDI->OriginalItalic);
+ Cache.Hashed.lfHeight = plf->lfHeight;
+ Cache.Hashed.Aspect.Emu.Bold = EMUBOLD_NEEDED(FontGDI->OriginalWeight,
plf->lfWeight);
+ Cache.Hashed.Aspect.Emu.Italic = (plf->lfItalic &&
!FontGDI->OriginalItalic);
if (IntIsFontRenderingEnabled())
- Cache.Aspect.RenderMode = (BYTE)IntGetFontRenderMode(plf);
+ Cache.Hashed.Aspect.RenderMode = (BYTE)IntGetFontRenderMode(plf);
else
- Cache.Aspect.RenderMode = (BYTE)FT_RENDER_MODE_MONO;
+ Cache.Hashed.Aspect.RenderMode = (BYTE)FT_RENDER_MODE_MONO;
if (!TextIntUpdateSize(dc, TextObj, FontGDI, FALSE))
{
@@ -6094,8 +6092,8 @@ IntExtTextOutW(
if (pdcattr->iGraphicsMode == GM_ADVANCED)
{
pmxWorldToDevice = DC_pmxWorldToDevice(dc);
- FtMatrixFromMx(&Cache.matTransform, pmxWorldToDevice);
- FT_Set_Transform(face, &Cache.matTransform, 0);
+ FtMatrixFromMx(&Cache.Hashed.matTransform, pmxWorldToDevice);
+ FT_Set_Transform(face, &Cache.Hashed.matTransform, 0);
fixAscender = ScaleLong(FontGDI->tmAscent, &pmxWorldToDevice->efM22)
<< 6;
fixDescender = ScaleLong(FontGDI->tmDescent, &pmxWorldToDevice->efM22)
<< 6;
@@ -6103,8 +6101,8 @@ IntExtTextOutW(
else
{
pmxWorldToDevice = (PMATRIX)&gmxWorldToDeviceDefault;
- FtMatrixFromMx(&Cache.matTransform, pmxWorldToDevice);
- FT_Set_Transform(face, &Cache.matTransform, 0);
+ FtMatrixFromMx(&Cache.Hashed.matTransform, pmxWorldToDevice);
+ FT_Set_Transform(face, &Cache.Hashed.matTransform, 0);
fixAscender = FontGDI->tmAscent << 6;
fixDescender = FontGDI->tmDescent << 6;
@@ -6197,7 +6195,7 @@ IntExtTextOutW(
for (i = 0; i < Count; ++i)
{
glyph_index = get_glyph_index_flagged(face, *String++, ETO_GLYPH_INDEX,
fuOptions);
- Cache.GlyphIndex = glyph_index;
+ Cache.Hashed.GlyphIndex = glyph_index;
realglyph = ftGdiGetRealGlyph(&Cache);
if (!realglyph)
@@ -6243,7 +6241,7 @@ IntExtTextOutW(
{
DPRINT1("WARNING: EngCreateBitmap() failed!\n");
bResult = FALSE;
- if (Cache.Aspect.EmuBoldItalic)
+ if (Cache.Hashed.Aspect.EmuBoldItalic)
FT_Done_Glyph((FT_Glyph)realglyph);
break;
}
@@ -6254,7 +6252,7 @@ IntExtTextOutW(
EngDeleteSurface((HSURF)HSourceGlyph);
DPRINT1("WARNING: EngLockSurface() failed!\n");
bResult = FALSE;
- if (Cache.Aspect.EmuBoldItalic)
+ if (Cache.Hashed.Aspect.EmuBoldItalic)
FT_Done_Glyph((FT_Glyph)realglyph);
break;
}
@@ -6305,7 +6303,7 @@ IntExtTextOutW(
if (DoBreak)
{
- if (Cache.Aspect.EmuBoldItalic)
+ if (Cache.Hashed.Aspect.EmuBoldItalic)
FT_Done_Glyph((FT_Glyph)realglyph);
break;
}
@@ -6335,7 +6333,7 @@ IntExtTextOutW(
previous = glyph_index;
- if (Cache.Aspect.EmuBoldItalic)
+ if (Cache.Hashed.Aspect.EmuBoldItalic)
{
FT_Done_Glyph((FT_Glyph)realglyph);
}