Module: wine Branch: master Commit: b9f05239d2b7b77ebad309f50fea2b0aa78ff144 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b9f05239d2b7b77ebad309f50f...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Mon Aug 24 10:43:19 2015 +0300
dwrite: Return advances using freetype cache system.
---
dlls/dwrite/dwrite_private.h | 1 + dlls/dwrite/font.c | 41 ++++++++++++++++++----------------------- dlls/dwrite/freetype.c | 28 ++++++++++++++++++++++++++++ dlls/dwrite/tests/font.c | 8 ++------ 4 files changed, 49 insertions(+), 29 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 42395ee..d1127f1 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -204,6 +204,7 @@ extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2*,UINT16,UINT1 extern void freetype_get_glyph_bbox(IDWriteFontFace2*,FLOAT,UINT16,BOOL,RECT*) DECLSPEC_HIDDEN; extern void freetype_get_glyph_bitmap(IDWriteFontFace2*,FLOAT,UINT16,const RECT*,BYTE*) DECLSPEC_HIDDEN; extern INT freetype_get_charmap_index(IDWriteFontFace2*,BOOL*) DECLSPEC_HIDDEN; +extern INT32 freetype_get_glyph_advance(IDWriteFontFace2*,FLOAT,UINT16,DWRITE_MEASURING_MODE) DECLSPEC_HIDDEN;
/* Glyph shaping */ enum SCRIPT_JUSTIFY diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index f86a908..0d5cbc0 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -751,7 +751,8 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac DWRITE_GLYPH_METRICS *metrics, BOOL is_sideways) { struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface); - FLOAT scale; + DWRITE_MEASURING_MODE mode; + FLOAT scale, size; HRESULT hr; UINT32 i;
@@ -761,7 +762,9 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac if (m && memcmp(m, &identity, sizeof(*m))) FIXME("transform is not supported, %s\n", debugstr_matrix(m));
- scale = emSize * ppdip / This->metrics.designUnitsPerEm; + size = emSize * ppdip; + scale = size / This->metrics.designUnitsPerEm; + mode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC;
for (i = 0; i < glyph_count; i++) { DWRITE_GLYPH_METRICS *ret = metrics + i; @@ -771,9 +774,11 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac if (FAILED(hr)) return hr;
+ ret->advanceWidth = freetype_get_glyph_advance(iface, size, glyphs[i], mode); + ret->advanceWidth = round_metric(ret->advanceWidth * This->metrics.designUnitsPerEm / size); + #define SCALE_METRIC(x) ret->x = round_metric(round_metric((design.x) * scale) / scale) SCALE_METRIC(leftSideBearing); - SCALE_METRIC(advanceWidth); SCALE_METRIC(rightSideBearing); SCALE_METRIC(topSideBearing); SCALE_METRIC(advanceHeight); @@ -884,16 +889,11 @@ static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2 *i
TRACE("(%p)->(%u %p %p %d)\n", This, glyph_count, glyphs, advances, is_sideways);
- for (i = 0; i < glyph_count; i++) { - DWRITE_GLYPH_METRICS metrics = { 0 }; - HRESULT hr; - - hr = IDWriteFontFace2_GetDesignGlyphMetrics(iface, glyphs + i, 1, &metrics, is_sideways); - if (FAILED(hr)) - return hr; + if (is_sideways) + FIXME("sideways mode not supported\n");
- advances[i] = is_sideways ? metrics.advanceHeight : metrics.advanceWidth; - } + for (i = 0; i < glyph_count; i++) + advances[i] = freetype_get_glyph_advance(iface, This->metrics.designUnitsPerEm, glyphs[i], DWRITE_MEASURING_MODE_NATURAL);
return S_OK; } @@ -903,8 +903,7 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF BOOL is_sideways, UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances) { struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface); - FLOAT scale; - HRESULT hr; + DWRITE_MEASURING_MODE mode; UINT32 i;
TRACE("(%p)->(%.2f %.2f %p %d %d %u %p %p)\n", This, em_size, ppdip, m, @@ -915,8 +914,8 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF return E_INVALIDARG; }
- scale = em_size * ppdip / This->metrics.designUnitsPerEm; - if (scale == 0.0) { + em_size *= ppdip; + if (em_size == 0.0) { memset(advances, 0, sizeof(*advances) * glyph_count); return S_OK; } @@ -924,14 +923,10 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF if (m && memcmp(m, &identity, sizeof(*m))) FIXME("transform is not supported, %s\n", debugstr_matrix(m));
+ mode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC; for (i = 0; i < glyph_count; i++) { - hr = IDWriteFontFace2_GetDesignGlyphAdvances(iface, 1, glyphs + i, advances + i, is_sideways); - if (FAILED(hr)) - return hr; - -#define SCALE_METRIC(x) x = round_metric(round_metric((x) * scale) / scale) - SCALE_METRIC(advances[i]); -#undef SCALE_METRIC + advances[i] = freetype_get_glyph_advance(iface, em_size, glyphs[i], mode); + advances[i] = round_metric(advances[i] * This->metrics.designUnitsPerEm / em_size); }
return S_OK; diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 3290243..ec6a13f 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -599,6 +599,29 @@ INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol) return charmap_index; }
+INT32 freetype_get_glyph_advance(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode) +{ + FTC_ImageTypeRec imagetype; + FT_Glyph glyph; + INT32 advance; + + imagetype.face_id = fontface; + imagetype.width = 0; + imagetype.height = emSize; + imagetype.flags = FT_LOAD_DEFAULT; + if (mode == DWRITE_MEASURING_MODE_NATURAL) + imagetype.flags |= FT_LOAD_NO_HINTING; + + EnterCriticalSection(&freetype_cs); + if (pFTC_ImageCache_Lookup(image_cache, &imagetype, index, &glyph, NULL) == 0) + advance = glyph->advance.x >> 16; + else + advance = 0; + LeaveCriticalSection(&freetype_cs); + + return advance; +} + #else /* HAVE_FREETYPE */
BOOL init_freetype(void) @@ -667,4 +690,9 @@ INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol) return -1; }
+INT32 freetype_get_glyph_advance(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode) +{ + return 0; +} + #endif /* HAVE_FREETYPE */ diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 9ba0d18..7617dbb 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -3094,6 +3094,7 @@ static void test_GetDesignGlyphAdvances(void) advance = 0; hr = IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, &index, &advance, TRUE); ok(hr == S_OK, "got 0x%08x\n", hr); + todo_wine ok(advance == 2048, "got %i\n", advance);
IDWriteFontFace1_Release(fontface1); @@ -4215,12 +4216,7 @@ static void test_GetGdiCompatibleGlyphAdvances(void)
/* advance is in design units */ advance = (int)floorf(emsize * advance / fm.designUnitsPerEm + 0.5f); - - /* allow 1 pixel difference for large sizes, for Tahoma this happens for 16 sizes in [1, 2048] range */ - if (emsize > 150.0) - ok((advance - gdi_advance) <= 1, "%.0f: got advance %d, expected %d\n", emsize, advance, gdi_advance); - else - ok(gdi_advance == advance, "%.0f: got advance %d, expected %d\n", emsize, advance, gdi_advance); + ok((advance - gdi_advance) <= 2, "%.0f: got advance %d, expected %d\n", emsize, advance, gdi_advance); }
DeleteObject(hdc);