diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 52e7a187080..9f8c9414281 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -254,7 +254,7 @@ enum gasp_flags { GASP_SYMMETRIC_SMOOTHING = 0x0008, }; -extern WORD opentype_get_gasp_flags(const WORD*,UINT32,INT) DECLSPEC_HIDDEN; +extern unsigned int opentype_get_gasp_flags(const struct dwrite_fonttable *gasp, float emsize) DECLSPEC_HIDDEN; /* BiDi helpers */ extern HRESULT bidi_computelevels(const WCHAR*,UINT32,UINT8,UINT8*,UINT8*) DECLSPEC_HIDDEN; diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 5c287ea6539..5c0b2a43103 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -379,11 +379,10 @@ static const void* get_fontface_vdmx(struct dwrite_fontface *fontface) return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_VDMX_TAG, &fontface->vdmx); } -static const void* get_fontface_gasp(struct dwrite_fontface *fontface, UINT32 *size) +static const struct dwrite_fonttable *get_fontface_gasp(struct dwrite_fontface *fontface) { - const void *ptr = get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_GASP_TAG, &fontface->gasp); - *size = fontface->gasp.size; - return ptr; + get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_GASP_TAG, &fontface->gasp); + return &fontface->gasp; } static const void* get_fontface_cpal(struct dwrite_fontface *fontface) @@ -687,7 +686,7 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace4 *iface, } static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_MEASURING_MODE measuring, - FLOAT ppem, WORD gasp) + float ppem, unsigned int gasp) { DWRITE_RENDERING_MODE mode = DWRITE_RENDERING_MODE_DEFAULT; @@ -718,10 +717,8 @@ static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace FLOAT ppdip, DWRITE_MEASURING_MODE measuring, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE *mode) { struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); - const WORD *ptr; - UINT32 size; + unsigned int flags; FLOAT ppem; - WORD gasp; TRACE("(%p)->(%.2f %.2f %d %p %p)\n", This, emSize, ppdip, measuring, params, mode); @@ -741,9 +738,8 @@ static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace return S_OK; } - ptr = get_fontface_gasp(This, &size); - gasp = opentype_get_gasp_flags(ptr, size, ppem); - *mode = fontface_renderingmode_from_measuringmode(measuring, ppem, gasp); + flags = opentype_get_gasp_flags(get_fontface_gasp(This), ppem); + *mode = fontface_renderingmode_from_measuringmode(measuring, ppem, flags); return S_OK; } @@ -1097,10 +1093,8 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac DWRITE_GRID_FIT_MODE *gridfitmode) { struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); + unsigned int flags; FLOAT emthreshold; - const WORD *ptr; - UINT32 size; - WORD gasp; TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold, measuringmode, params, renderingmode, gridfitmode); @@ -1131,14 +1125,13 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD; - ptr = get_fontface_gasp(This, &size); - gasp = opentype_get_gasp_flags(ptr, size, emSize); + flags = opentype_get_gasp_flags(get_fontface_gasp(This), emSize); if (*renderingmode == DWRITE_RENDERING_MODE_DEFAULT) { if (emSize >= emthreshold) *renderingmode = DWRITE_RENDERING_MODE_OUTLINE; else - *renderingmode = fontface_renderingmode_from_measuringmode(measuringmode, emSize, gasp); + *renderingmode = fontface_renderingmode_from_measuringmode(measuringmode, emSize, flags); } if (*gridfitmode == DWRITE_GRID_FIT_MODE_DEFAULT) { @@ -1147,7 +1140,8 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac else if (measuringmode == DWRITE_MEASURING_MODE_GDI_CLASSIC || measuringmode == DWRITE_MEASURING_MODE_GDI_NATURAL) *gridfitmode = DWRITE_GRID_FIT_MODE_ENABLED; else - *gridfitmode = (gasp & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT)) ? DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED; + *gridfitmode = flags & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT) ? + DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED; } return S_OK; @@ -1229,10 +1223,8 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac IDWriteRenderingParams *params, DWRITE_RENDERING_MODE1 *rendering_mode, DWRITE_GRID_FIT_MODE *gridfit_mode) { struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface); + unsigned int flags; FLOAT emthreshold; - const WORD *ptr; - UINT32 size; - WORD gasp; TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold, measuring_mode, params, rendering_mode, gridfit_mode); @@ -1263,14 +1255,13 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD; - ptr = get_fontface_gasp(This, &size); - gasp = opentype_get_gasp_flags(ptr, size, emSize); + flags = opentype_get_gasp_flags(get_fontface_gasp(This), emSize); if (*rendering_mode == DWRITE_RENDERING_MODE1_DEFAULT) { if (emSize >= emthreshold) *rendering_mode = DWRITE_RENDERING_MODE1_OUTLINE; else - *rendering_mode = fontface_renderingmode_from_measuringmode(measuring_mode, emSize, gasp); + *rendering_mode = fontface_renderingmode_from_measuringmode(measuring_mode, emSize, flags); } if (*gridfit_mode == DWRITE_GRID_FIT_MODE_DEFAULT) { @@ -1279,7 +1270,8 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac else if (measuring_mode == DWRITE_MEASURING_MODE_GDI_CLASSIC || measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL) *gridfit_mode = DWRITE_GRID_FIT_MODE_ENABLED; else - *gridfit_mode = (gasp & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT)) ? DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED; + *gridfit_mode = flags & (GASP_GRIDFIT|GASP_SYMMETRIC_GRIDFIT) ? + DWRITE_GRID_FIT_MODE_ENABLED : DWRITE_GRID_FIT_MODE_DISABLED; } return S_OK; diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c index 0e0de8730e1..291b41b131e 100644 --- a/dlls/dwrite/opentype.c +++ b/dlls/dwrite/opentype.c @@ -292,6 +292,20 @@ typedef struct { BYTE bitDepth; BYTE flags; } CBLCBitmapSizeTable; + +struct gasp_range +{ + WORD max_ppem; + WORD flags; +}; + +struct gasp_header +{ + WORD version; + WORD num_ranges; + struct gasp_range ranges[1]; +}; + #include "poppack.h" enum OS2_FSSELECTION { @@ -1959,25 +1973,32 @@ BOOL opentype_get_vdmx_size(const void *data, INT emsize, UINT16 *ascent, UINT16 return FALSE; } -WORD opentype_get_gasp_flags(const WORD *ptr, UINT32 size, INT emsize) +unsigned int opentype_get_gasp_flags(const struct dwrite_fonttable *gasp, float emsize) { - WORD num_recs, version; + unsigned int version, num_ranges, i; + const struct gasp_header *table; WORD flags = 0; - if (!ptr) + if (!gasp->exists) return 0; - version = GET_BE_WORD( *ptr++ ); - num_recs = GET_BE_WORD( *ptr++ ); - if (version > 1 || size < (num_recs * 2 + 2) * sizeof(WORD)) { - ERR("unsupported gasp table: ver %d size %d recs %d\n", version, size, num_recs); + num_ranges = table_read_be_word(gasp, FIELD_OFFSET(struct gasp_header, num_ranges)); + + table = table_read_ensure(gasp, 0, FIELD_OFFSET(struct gasp_header, ranges[num_ranges])); + if (!table) + return 0; + + version = GET_BE_WORD(table->version); + if (version > 1) + { + ERR("Unsupported gasp table format version %u.\n", version); goto done; } - while (num_recs--) { - flags = GET_BE_WORD( *(ptr + 1) ); - if (emsize <= GET_BE_WORD( *ptr )) break; - ptr += 2; + for (i = 0; i < num_ranges; ++i) + { + flags = GET_BE_WORD(table->ranges[i].flags); + if (emsize <= GET_BE_WORD(table->ranges[i].max_ppem)) break; } done: