Commit b9f05239 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

dwrite: Return advances using freetype cache system.

parent 75c9da68
...@@ -204,6 +204,7 @@ extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2*,UINT16,UINT1 ...@@ -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_bbox(IDWriteFontFace2*,FLOAT,UINT16,BOOL,RECT*) DECLSPEC_HIDDEN;
extern void freetype_get_glyph_bitmap(IDWriteFontFace2*,FLOAT,UINT16,const RECT*,BYTE*) 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 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 */ /* Glyph shaping */
enum SCRIPT_JUSTIFY enum SCRIPT_JUSTIFY
......
...@@ -751,7 +751,8 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac ...@@ -751,7 +751,8 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac
DWRITE_GLYPH_METRICS *metrics, BOOL is_sideways) DWRITE_GLYPH_METRICS *metrics, BOOL is_sideways)
{ {
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface); struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
FLOAT scale; DWRITE_MEASURING_MODE mode;
FLOAT scale, size;
HRESULT hr; HRESULT hr;
UINT32 i; UINT32 i;
...@@ -761,7 +762,9 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac ...@@ -761,7 +762,9 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac
if (m && memcmp(m, &identity, sizeof(*m))) if (m && memcmp(m, &identity, sizeof(*m)))
FIXME("transform is not supported, %s\n", debugstr_matrix(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++) { for (i = 0; i < glyph_count; i++) {
DWRITE_GLYPH_METRICS *ret = metrics + i; DWRITE_GLYPH_METRICS *ret = metrics + i;
...@@ -771,9 +774,11 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac ...@@ -771,9 +774,11 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac
if (FAILED(hr)) if (FAILED(hr))
return 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) #define SCALE_METRIC(x) ret->x = round_metric(round_metric((design.x) * scale) / scale)
SCALE_METRIC(leftSideBearing); SCALE_METRIC(leftSideBearing);
SCALE_METRIC(advanceWidth);
SCALE_METRIC(rightSideBearing); SCALE_METRIC(rightSideBearing);
SCALE_METRIC(topSideBearing); SCALE_METRIC(topSideBearing);
SCALE_METRIC(advanceHeight); SCALE_METRIC(advanceHeight);
...@@ -884,16 +889,11 @@ static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace2 *i ...@@ -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); TRACE("(%p)->(%u %p %p %d)\n", This, glyph_count, glyphs, advances, is_sideways);
for (i = 0; i < glyph_count; i++) { if (is_sideways)
DWRITE_GLYPH_METRICS metrics = { 0 }; FIXME("sideways mode not supported\n");
HRESULT hr;
hr = IDWriteFontFace2_GetDesignGlyphMetrics(iface, glyphs + i, 1, &metrics, is_sideways);
if (FAILED(hr))
return hr;
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; return S_OK;
} }
...@@ -903,8 +903,7 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF ...@@ -903,8 +903,7 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF
BOOL is_sideways, UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances) BOOL is_sideways, UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances)
{ {
struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface); struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
FLOAT scale; DWRITE_MEASURING_MODE mode;
HRESULT hr;
UINT32 i; UINT32 i;
TRACE("(%p)->(%.2f %.2f %p %d %d %u %p %p)\n", This, em_size, ppdip, m, 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 ...@@ -915,8 +914,8 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF
return E_INVALIDARG; return E_INVALIDARG;
} }
scale = em_size * ppdip / This->metrics.designUnitsPerEm; em_size *= ppdip;
if (scale == 0.0) { if (em_size == 0.0) {
memset(advances, 0, sizeof(*advances) * glyph_count); memset(advances, 0, sizeof(*advances) * glyph_count);
return S_OK; return S_OK;
} }
...@@ -924,14 +923,10 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF ...@@ -924,14 +923,10 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF
if (m && memcmp(m, &identity, sizeof(*m))) if (m && memcmp(m, &identity, sizeof(*m)))
FIXME("transform is not supported, %s\n", debugstr_matrix(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++) { for (i = 0; i < glyph_count; i++) {
hr = IDWriteFontFace2_GetDesignGlyphAdvances(iface, 1, glyphs + i, advances + i, is_sideways); advances[i] = freetype_get_glyph_advance(iface, em_size, glyphs[i], mode);
if (FAILED(hr)) advances[i] = round_metric(advances[i] * This->metrics.designUnitsPerEm / em_size);
return hr;
#define SCALE_METRIC(x) x = round_metric(round_metric((x) * scale) / scale)
SCALE_METRIC(advances[i]);
#undef SCALE_METRIC
} }
return S_OK; return S_OK;
......
...@@ -599,6 +599,29 @@ INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol) ...@@ -599,6 +599,29 @@ INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol)
return charmap_index; 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 */ #else /* HAVE_FREETYPE */
BOOL init_freetype(void) BOOL init_freetype(void)
...@@ -667,4 +690,9 @@ INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol) ...@@ -667,4 +690,9 @@ INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol)
return -1; return -1;
} }
INT32 freetype_get_glyph_advance(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode)
{
return 0;
}
#endif /* HAVE_FREETYPE */ #endif /* HAVE_FREETYPE */
...@@ -3094,6 +3094,7 @@ static void test_GetDesignGlyphAdvances(void) ...@@ -3094,6 +3094,7 @@ static void test_GetDesignGlyphAdvances(void)
advance = 0; advance = 0;
hr = IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, &index, &advance, TRUE); hr = IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, &index, &advance, TRUE);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
todo_wine
ok(advance == 2048, "got %i\n", advance); ok(advance == 2048, "got %i\n", advance);
IDWriteFontFace1_Release(fontface1); IDWriteFontFace1_Release(fontface1);
...@@ -4215,12 +4216,7 @@ static void test_GetGdiCompatibleGlyphAdvances(void) ...@@ -4215,12 +4216,7 @@ static void test_GetGdiCompatibleGlyphAdvances(void)
/* advance is in design units */ /* advance is in design units */
advance = (int)floorf(emsize * advance / fm.designUnitsPerEm + 0.5f); advance = (int)floorf(emsize * advance / fm.designUnitsPerEm + 0.5f);
ok((advance - gdi_advance) <= 2, "%.0f: got advance %d, expected %d\n", emsize, advance, gdi_advance);
/* 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);
} }
DeleteObject(hdc); DeleteObject(hdc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment