dwrite: Return advances using freetype cache system
Nikolay Sivov
nsivov at codeweavers.com
Mon Aug 24 02:43:19 CDT 2015
---
-------------- next part --------------
From 7de043c1672f3fb4ace2e8908f7d45813692b1b2 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon, 24 Aug 2015 09:33:47 +0300
Subject: [PATCH] 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);
--
2.1.4
More information about the wine-patches
mailing list