From: Zhiyi Zhang zzhang@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57309 --- dlls/win32u/font.c | 52 +++++++++++++++++++++---------------- dlls/win32u/ntgdi_private.h | 4 +-- include/wingdi.h | 11 ++++---- 3 files changed, 38 insertions(+), 29 deletions(-)
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 3d70710e059..02f4045f6d9 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -2413,7 +2413,7 @@ static struct gdi_font *alloc_gdi_font( const WCHAR *file, void *data_ptr, SIZE_
static void free_gdi_font( struct gdi_font *font ) { - DWORD i; + DWORD i, j; struct gdi_font *child, *child_next;
if (font->private) font_funcs->destroy_font( font ); @@ -2423,12 +2423,16 @@ static void free_gdi_font( struct gdi_font *font ) list_remove( &child->entry ); free_gdi_font( child ); } - for (i = 0; i < font->gm_size; i++) free( font->gm[i] ); + for (i = 0; i < ARRAY_SIZE(font->gm_size); i++) + { + for (j = 0; j < font->gm_size[i]; i++) + free( font->gm[i][j] ); + free( font->gm[i] ); + } free( font->otm.otmpFamilyName ); free( font->otm.otmpStyleName ); free( font->otm.otmpFaceName ); free( font->otm.otmpFullName ); - free( font->gm ); free( font->kern_pairs ); free( font->gsub_table ); free( font ); @@ -2469,16 +2473,17 @@ struct glyph_metrics
#define GM_BLOCK_SIZE 128
-/* TODO: GGO format support */ -static BOOL get_gdi_font_glyph_metrics( struct gdi_font *font, UINT index, GLYPHMETRICS *gm, ABC *abc ) +static BOOL get_gdi_font_glyph_metrics( struct gdi_font *font, UINT format, UINT index, + GLYPHMETRICS *gm, ABC *abc ) { UINT block = index / GM_BLOCK_SIZE; UINT entry = index % GM_BLOCK_SIZE;
- if (block < font->gm_size && font->gm[block] && font->gm[block][entry].init) + if (format < WINE_GGO_FORMAT_COUNT && block < font->gm_size[format] && font->gm[format][block] + && font->gm[format][block][entry].init) { - *gm = font->gm[block][entry].gm; - *abc = font->gm[block][entry].abc; + *gm = font->gm[format][block][entry].gm; + *abc = font->gm[format][block][entry].abc;
TRACE( "cached gm: %u, %u, %s, %d, %d abc: %d, %u, %d\n", gm->gmBlackBoxX, gm->gmBlackBoxY, wine_dbgstr_point( &gm->gmptGlyphOrigin ), @@ -2489,29 +2494,32 @@ static BOOL get_gdi_font_glyph_metrics( struct gdi_font *font, UINT index, GLYPH return FALSE; }
-static void set_gdi_font_glyph_metrics( struct gdi_font *font, UINT index, +static void set_gdi_font_glyph_metrics( struct gdi_font *font, UINT format, UINT index, const GLYPHMETRICS *gm, const ABC *abc ) { UINT block = index / GM_BLOCK_SIZE; UINT entry = index % GM_BLOCK_SIZE;
- if (block >= font->gm_size) + if (format >= WINE_GGO_FORMAT_COUNT) + return; + + if (block >= font->gm_size[format]) { struct glyph_metrics **ptr;
- if (!(ptr = realloc( font->gm, (block + 1) * sizeof(*ptr) ))) return; - memset( ptr + font->gm_size, 0, (block + 1 - font->gm_size) * sizeof(*ptr) ); - font->gm_size = block + 1; - font->gm = ptr; + if (!(ptr = realloc( font->gm[format], (block + 1) * sizeof(*ptr) ))) return; + memset( ptr + font->gm_size[format], 0, (block + 1 - font->gm_size[format]) * sizeof(*ptr) ); + font->gm_size[format] = block + 1; + font->gm[format] = ptr; } - if (!font->gm[block]) + if (!font->gm[format][block]) { - font->gm[block] = calloc( sizeof(**font->gm), GM_BLOCK_SIZE ); - if (!font->gm[block]) return; + font->gm[format][block] = calloc( sizeof(***font->gm), GM_BLOCK_SIZE ); + if (!font->gm[format][block]) return; } - font->gm[block][entry].gm = *gm; - font->gm[block][entry].abc = *abc; - font->gm[block][entry].init = TRUE; + font->gm[format][block][entry].gm = *gm; + font->gm[format][block][entry].abc = *abc; + font->gm[format][block][entry].init = TRUE; }
@@ -3771,14 +3779,14 @@ static DWORD get_glyph_outline( struct gdi_font *font, UINT glyph, UINT format,
if (mat && !memcmp( mat, &identity, sizeof(*mat) )) mat = NULL;
- if (format == GGO_METRICS && !mat && get_gdi_font_glyph_metrics( font, index, &gm, &abc )) + if (format == GGO_METRICS && !mat && get_gdi_font_glyph_metrics( font, format, index, &gm, &abc )) goto done;
ret = font_funcs->get_glyph_outline( font, index, format, &gm, &abc, buflen, buf, mat, tategaki ); if (ret == GDI_ERROR) return ret;
if (format == GGO_METRICS && !mat) - set_gdi_font_glyph_metrics( font, index, &gm, &abc ); + set_gdi_font_glyph_metrics( font, format, index, &gm, &abc );
done: if (gm_ret) *gm_ret = gm; diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index 78b3ad89796..58eea19e6c1 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -255,8 +255,8 @@ struct gdi_font struct list entry; struct list unused_entry; DWORD refcount; - DWORD gm_size; - struct glyph_metrics **gm; + DWORD gm_size[WINE_GGO_FORMAT_COUNT]; + struct glyph_metrics **gm[WINE_GGO_FORMAT_COUNT]; OUTLINETEXTMETRICW otm; KERNINGPAIR *kern_pairs; int kern_count; diff --git a/include/wingdi.h b/include/wingdi.h index ed0e59462e9..31ef01b075c 100644 --- a/include/wingdi.h +++ b/include/wingdi.h @@ -1342,11 +1342,12 @@ typedef struct #define GGO_UNHINTED 0x100
#ifdef __WINESRC__ -#define WINE_GGO_GRAY16_BITMAP 0x10 -#define WINE_GGO_HRGB_BITMAP 0x11 -#define WINE_GGO_HBGR_BITMAP 0x12 -#define WINE_GGO_VRGB_BITMAP 0x13 -#define WINE_GGO_VBGR_BITMAP 0x14 +#define WINE_GGO_GRAY16_BITMAP 7 +#define WINE_GGO_HRGB_BITMAP 8 +#define WINE_GGO_HBGR_BITMAP 9 +#define WINE_GGO_VRGB_BITMAP 10 +#define WINE_GGO_VBGR_BITMAP 11 +#define WINE_GGO_FORMAT_COUNT (WINE_GGO_VBGR_BITMAP + 1) #endif
typedef struct