Nikolay Sivov : dwrite: Introduce cache to be used by shaping engines.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Oct 7 14:49:56 CDT 2014


Module: wine
Branch: master
Commit: cb8556c1716c27b2252d25651c55f8c1625a87bf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cb8556c1716c27b2252d25651c55f8c1625a87bf

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sun Oct  5 17:43:47 2014 +0400

dwrite: Introduce cache to be used by shaping engines.

---

 dlls/dwrite/analyzer.c       | 12 +++++++++---
 dlls/dwrite/dwrite_private.h |  8 ++++++--
 dlls/dwrite/shape.c          | 35 ++++++++++++++++++++++++++++++++---
 dlls/dwrite/tests/analyzer.c |  6 ++++++
 4 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index 20a84c3..e2fac55 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -846,6 +846,7 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
     DWRITE_SHAPING_GLYPH_PROPERTIES* glyph_props, UINT32* actual_glyph_count)
 {
     const struct dwritescript_properties *scriptprops;
+    struct scriptshaping_cache *cache;
     WCHAR *string;
     BOOL update_cluster;
     UINT32 i, g;
@@ -925,9 +926,13 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
     }
     *actual_glyph_count = g;
 
+    hr = create_scriptshaping_cache(fontface, &cache);
+    if (FAILED(hr))
+        goto done;
+
     scriptprops = &dwritescripts_properties[script];
     if (scriptprops->ops && scriptprops->ops->contextual_shaping) {
-        hr = scriptprops->ops->contextual_shaping(fontface, is_rtl, string, length, max_glyph_count, clustermap, glyph_indices, actual_glyph_count);
+        hr = scriptprops->ops->contextual_shaping(cache, is_rtl, string, length, max_glyph_count, clustermap, glyph_indices, actual_glyph_count);
         if (FAILED(hr))
             goto done;
     }
@@ -935,11 +940,12 @@ static HRESULT WINAPI dwritetextanalyzer_GetGlyphs(IDWriteTextAnalyzer2 *iface,
     /* FIXME: apply default features */
 
     if (scriptprops->ops && scriptprops->ops->set_text_glyphs_props)
-        hr = scriptprops->ops->set_text_glyphs_props(fontface, string, length, clustermap, glyph_indices, *actual_glyph_count, text_props, glyph_props);
+        hr = scriptprops->ops->set_text_glyphs_props(cache, string, length, clustermap, glyph_indices, *actual_glyph_count, text_props, glyph_props);
     else
-        hr = default_shaping_ops.set_text_glyphs_props(fontface, string, length, clustermap, glyph_indices, *actual_glyph_count, text_props, glyph_props);
+        hr = default_shaping_ops.set_text_glyphs_props(cache, string, length, clustermap, glyph_indices, *actual_glyph_count, text_props, glyph_props);
 
 done:
+    release_scriptshaping_cache(cache);
     heap_free(string);
 
     return hr;
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 1624c6b..3eb7957 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -135,11 +135,15 @@ enum SCRIPT_JUSTIFY
     SCRIPT_JUSTIFY_ARABIC_SEEN_M
 };
 
+struct scriptshaping_cache;
+extern HRESULT create_scriptshaping_cache(IDWriteFontFace*,struct scriptshaping_cache**) DECLSPEC_HIDDEN;
+extern void release_scriptshaping_cache(struct scriptshaping_cache*) DECLSPEC_HIDDEN;
+
 struct scriptshaping_ops
 {
-    HRESULT (*contextual_shaping)(IDWriteFontFace *fontface, BOOL is_rtl, const WCHAR *text, UINT32 len, UINT32 max_glyph_count,
+    HRESULT (*contextual_shaping)(struct scriptshaping_cache *cache, BOOL is_rtl, const WCHAR *text, UINT32 len, UINT32 max_glyph_count,
                                   UINT16 *clustermap, UINT16 *glyph_indices, UINT32* actual_glyph_count);
-    HRESULT (*set_text_glyphs_props)(IDWriteFontFace *fontface, const WCHAR *text, UINT32 len, UINT16 *clustermap, UINT16 *glyph_indices,
+    HRESULT (*set_text_glyphs_props)(struct scriptshaping_cache *cache, const WCHAR *text, UINT32 len, UINT16 *clustermap, UINT16 *glyph_indices,
                                      UINT32 glyphcount, DWRITE_SHAPING_TEXT_PROPERTIES *text_props, DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props);
 };
 
diff --git a/dlls/dwrite/shape.c b/dlls/dwrite/shape.c
index fdedb2b..bf09861 100644
--- a/dlls/dwrite/shape.c
+++ b/dlls/dwrite/shape.c
@@ -26,6 +26,35 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
 
+struct scriptshaping_cache
+{
+    IDWriteFontFace *fontface;
+};
+
+HRESULT create_scriptshaping_cache(IDWriteFontFace *fontface, struct scriptshaping_cache **cache)
+{
+    struct scriptshaping_cache *ret;
+
+    ret = heap_alloc(sizeof(*ret));
+    if (!ret)
+        return E_OUTOFMEMORY;
+
+    ret->fontface = fontface;
+    IDWriteFontFace_AddRef(fontface);
+
+    *cache = ret;
+
+    return S_OK;
+}
+
+void release_scriptshaping_cache(struct scriptshaping_cache *cache)
+{
+    if (!cache)
+        return;
+    IDWriteFontFace_Release(cache->fontface);
+    heap_free(cache);
+}
+
 static void shape_update_clusters_from_glyphprop(UINT32 glyphcount, UINT32 text_len, UINT16 *clustermap, DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props)
 {
     UINT32 i;
@@ -86,7 +115,7 @@ static INT32 map_glyph_to_text_pos(const UINT16 *clustermap, UINT32 len, UINT16
     return k;
 }
 
-static HRESULT default_set_text_glyphs_props(IDWriteFontFace *fontface, const WCHAR *text, UINT32 len, UINT16 *clustermap, UINT16 *glyph_indices,
+static HRESULT default_set_text_glyphs_props(struct scriptshaping_cache *cache, const WCHAR *text, UINT32 len, UINT16 *clustermap, UINT16 *glyph_indices,
                                      UINT32 glyphcount, DWRITE_SHAPING_TEXT_PROPERTIES *text_props, DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props)
 {
     UINT32 i;
@@ -119,13 +148,13 @@ static HRESULT default_set_text_glyphs_props(IDWriteFontFace *fontface, const WC
     return S_OK;
 }
 
-static HRESULT latn_set_text_glyphs_props(IDWriteFontFace *fontface, const WCHAR *text, UINT32 len, UINT16 *clustermap, UINT16 *glyph_indices,
+static HRESULT latn_set_text_glyphs_props(struct scriptshaping_cache *cache, const WCHAR *text, UINT32 len, UINT16 *clustermap, UINT16 *glyph_indices,
                                      UINT32 glyphcount, DWRITE_SHAPING_TEXT_PROPERTIES *text_props, DWRITE_SHAPING_GLYPH_PROPERTIES *glyph_props)
 {
     HRESULT hr;
     UINT32 i;
 
-    hr = default_set_text_glyphs_props(fontface, text, len, clustermap, glyph_indices, glyphcount, text_props, glyph_props);
+    hr = default_set_text_glyphs_props(cache, text, len, clustermap, glyph_indices, glyphcount, text_props, glyph_props);
 
     for (i = 0; i < glyphcount; i++)
         if (glyph_props[i].isZeroWidthSpace)
diff --git a/dlls/dwrite/tests/analyzer.c b/dlls/dwrite/tests/analyzer.c
index 15f5ab0..1add761 100644
--- a/dlls/dwrite/tests/analyzer.c
+++ b/dlls/dwrite/tests/analyzer.c
@@ -1123,6 +1123,12 @@ static void test_GetGlyphs(void)
         NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
     ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "got 0x%08x\n", hr);
 
+if (0) {
+    /* NULL fontface - crashes on Windows */
+    hr = IDWriteTextAnalyzer_GetGlyphs(analyzer, test1W, lstrlenW(test1W), NULL, FALSE, FALSE, &sa, NULL,
+        NULL, NULL, NULL, 0, maxglyphcount, clustermap, props, glyphs1, shapingprops, &actual_count);
+}
+
     /* invalid script id */
     maxglyphcount = 10;
     actual_count = 0;




More information about the wine-cvs mailing list