Alexandre Julliard : gdi32: Support caching glyphs by character code and not only by glyph index.
Alexandre Julliard
julliard at winehq.org
Wed Dec 5 13:43:10 CST 2012
Module: wine
Branch: master
Commit: 78626cdbaa0419e78d5bf5537e084b0e8cef9234
URL: http://source.winehq.org/git/wine.git/?a=commit;h=78626cdbaa0419e78d5bf5537e084b0e8cef9234
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Dec 5 16:41:08 2012 +0100
gdi32: Support caching glyphs by character code and not only by glyph index.
---
dlls/gdi32/dibdrv/graphics.c | 61 ++++++++++++++++++++++++++---------------
dlls/gdi32/font.c | 12 ++++----
2 files changed, 45 insertions(+), 28 deletions(-)
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index 0b843fe..d0b7a39 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -33,6 +33,13 @@ struct cached_glyph
BYTE bits[1];
};
+enum glyph_type
+{
+ GLYPH_INDEX,
+ GLYPH_WCHAR,
+ GLYPH_NBTYPES
+};
+
struct cached_font
{
struct list entry;
@@ -41,8 +48,8 @@ struct cached_font
LOGFONTW lf;
XFORM xform;
UINT aa_flags;
- UINT nb_glyphs;
- struct cached_glyph **glyphs;
+ UINT nb_glyphs[GLYPH_NBTYPES];
+ struct cached_glyph **glyphs[GLYPH_NBTYPES];
};
static struct list font_cache = LIST_INIT( font_cache );
@@ -487,7 +494,7 @@ static int font_cache_cmp( const struct cached_font *p1, const struct cached_fon
static struct cached_font *add_cached_font( HDC hdc, HFONT hfont, UINT aa_flags )
{
struct cached_font font, *ptr, *last_unused = NULL;
- UINT i = 0;
+ UINT i = 0, j;
GetObjectW( hfont, sizeof(font.lf), &font.lf );
GetTransform( hdc, 0x204, &font.xform );
@@ -517,8 +524,11 @@ static struct cached_font *add_cached_font( HDC hdc, HFONT hfont, UINT aa_flags
if (i > 5) /* keep at least 5 of the most-recently used fonts around */
{
ptr = last_unused;
- for (i = 0; i < ptr->nb_glyphs; i++) HeapFree( GetProcessHeap(), 0, ptr->glyphs[i] );
- HeapFree( GetProcessHeap(), 0, ptr->glyphs );
+ for (i = 0; i < GLYPH_NBTYPES; i++)
+ {
+ for (j = 0; j < ptr->nb_glyphs[i]; j++) HeapFree( GetProcessHeap(), 0, ptr->glyphs[i][j] );
+ HeapFree( GetProcessHeap(), 0, ptr->glyphs[i] );
+ }
list_remove( &ptr->entry );
}
else if (!(ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr) )))
@@ -529,9 +539,11 @@ static struct cached_font *add_cached_font( HDC hdc, HFONT hfont, UINT aa_flags
*ptr = font;
ptr->ref = 1;
- ptr->glyphs = NULL;
- ptr->nb_glyphs = 0;
-
+ for (i = 0; i < GLYPH_NBTYPES; i++)
+ {
+ ptr->glyphs[i] = NULL;
+ ptr->nb_glyphs[i] = 0;
+ }
done:
list_add_head( &font_cache, &ptr->entry );
LeaveCriticalSection( &font_cache_cs );
@@ -544,28 +556,32 @@ void release_cached_font( struct cached_font *font )
if (font) InterlockedDecrement( &font->ref );
}
-static void add_cached_glyph( struct cached_font *font, UINT index, struct cached_glyph *glyph )
+static void add_cached_glyph( struct cached_font *font, UINT index, UINT flags, struct cached_glyph *glyph )
{
- if (index >= font->nb_glyphs)
+ enum glyph_type type = (flags & ETO_GLYPH_INDEX) ? GLYPH_INDEX : GLYPH_WCHAR;
+
+ if (index >= font->nb_glyphs[type])
{
UINT new_count = (index + 128) & ~127;
struct cached_glyph **new;
- if (font->glyphs)
+ if (font->glyphs[type])
new = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- font->glyphs, new_count * sizeof(*new) );
+ font->glyphs[type], new_count * sizeof(*new) );
else
new = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*new) );
if (!new) return;
- font->glyphs = new;
- font->nb_glyphs = new_count;
+ font->glyphs[type] = new;
+ font->nb_glyphs[type] = new_count;
}
- font->glyphs[index] = glyph;
+ font->glyphs[type][index] = glyph;
}
-static struct cached_glyph *get_cached_glyph( struct cached_font *font, UINT index )
+static struct cached_glyph *get_cached_glyph( struct cached_font *font, UINT index, UINT flags )
{
- if (index < font->nb_glyphs) return font->glyphs[index];
+ enum glyph_type type = (flags & ETO_GLYPH_INDEX) ? GLYPH_INDEX : GLYPH_WCHAR;
+
+ if (index < font->nb_glyphs[type]) return font->glyphs[type][index];
return NULL;
}
@@ -654,9 +670,9 @@ static const int padding[4] = {0, 3, 2, 1};
* For non-antialiased bitmaps convert them to the 17-level format
* using only values 0 or 16.
*/
-static struct cached_glyph *cache_glyph_bitmap( HDC hdc, struct cached_font *font, UINT index )
+static struct cached_glyph *cache_glyph_bitmap( HDC hdc, struct cached_font *font, UINT index, UINT flags )
{
- UINT ggo_flags = font->aa_flags | GGO_GLYPH_INDEX;
+ UINT ggo_flags = font->aa_flags;
static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
UINT indices[3] = {0, 0, 0x20};
int i, x, y;
@@ -666,6 +682,7 @@ static struct cached_glyph *cache_glyph_bitmap( HDC hdc, struct cached_font *fon
GLYPHMETRICS metrics;
struct cached_glyph *glyph;
+ if (flags & ETO_GLYPH_INDEX) ggo_flags |= GGO_GLYPH_INDEX;
indices[0] = index;
for (i = 0; i < sizeof(indices) / sizeof(indices[0]); i++)
{
@@ -712,7 +729,7 @@ static struct cached_glyph *cache_glyph_bitmap( HDC hdc, struct cached_font *fon
done:
glyph->metrics = metrics;
- add_cached_glyph( font, index, glyph );
+ add_cached_glyph( font, index, flags, glyph );
return glyph;
}
@@ -740,8 +757,8 @@ static void render_string( HDC hdc, dib_info *dib, struct cached_font *font, INT
EnterCriticalSection( &font_cache_cs );
for (i = 0; i < count; i++)
{
- if (!(glyph = get_cached_glyph( font, str[i] )) &&
- !(glyph = cache_glyph_bitmap( hdc, font, str[i] ))) continue;
+ if (!(glyph = get_cached_glyph( font, str[i], flags )) &&
+ !(glyph = cache_glyph_bitmap( hdc, font, str[i], flags ))) continue;
glyph_dib.width = glyph->metrics.gmBlackBoxX;
glyph_dib.height = glyph->metrics.gmBlackBoxY;
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 027c392..8580fcb 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -1710,10 +1710,9 @@ BOOL WINAPI GetCharWidth32A( HDC hdc, UINT firstChar, UINT lastChar,
/* helper for nulldrv_ExtTextOut */
-static DWORD get_glyph_bitmap( HDC hdc, UINT index, UINT aa_flags,
+static DWORD get_glyph_bitmap( HDC hdc, UINT index, UINT flags, UINT aa_flags,
GLYPHMETRICS *metrics, struct gdi_image_bits *image )
{
- UINT ggo_flags = aa_flags | GGO_GLYPH_INDEX;
static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
UINT indices[3] = {0, 0, 0x20};
int i;
@@ -1721,11 +1720,12 @@ static DWORD get_glyph_bitmap( HDC hdc, UINT index, UINT aa_flags,
int stride;
indices[0] = index;
+ if (flags & ETO_GLYPH_INDEX) aa_flags |= GGO_GLYPH_INDEX;
for (i = 0; i < sizeof(indices) / sizeof(indices[0]); i++)
{
index = indices[i];
- ret = GetGlyphOutlineW( hdc, index, ggo_flags, metrics, 0, NULL, &identity );
+ ret = GetGlyphOutlineW( hdc, index, aa_flags, metrics, 0, NULL, &identity );
if (ret != GDI_ERROR) break;
}
@@ -1743,7 +1743,7 @@ static DWORD get_glyph_bitmap( HDC hdc, UINT index, UINT aa_flags,
image->is_copy = TRUE;
image->free = free_heap_bits;
- ret = GetGlyphOutlineW( hdc, index, ggo_flags, metrics, size, image->ptr, &identity );
+ ret = GetGlyphOutlineW( hdc, index, aa_flags, metrics, size, image->ptr, &identity );
if (ret == GDI_ERROR)
{
HeapFree( GetProcessHeap(), 0, image->ptr );
@@ -1764,7 +1764,7 @@ static RECT get_total_extents( HDC hdc, INT x, INT y, UINT flags, UINT aa_flags,
{
GLYPHMETRICS metrics;
- if (get_glyph_bitmap( hdc, (UINT)str[i], aa_flags, &metrics, NULL )) continue;
+ if (get_glyph_bitmap( hdc, str[i], flags, aa_flags, &metrics, NULL )) continue;
rect.left = x + metrics.gmptGlyphOrigin.x;
rect.top = y - metrics.gmptGlyphOrigin.y;
@@ -1949,7 +1949,7 @@ BOOL nulldrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *rect
GLYPHMETRICS metrics;
struct gdi_image_bits image;
- err = get_glyph_bitmap( dev->hdc, (UINT)str[i], GGO_BITMAP, &metrics, &image );
+ err = get_glyph_bitmap( dev->hdc, str[i], flags, GGO_BITMAP, &metrics, &image );
if (err) continue;
if (image.ptr) draw_glyph( dev->hdc, x, y, &metrics, &image, (flags & ETO_CLIPPED) ? rect : NULL );
More information about the wine-cvs
mailing list