Nikolay Sivov : dwrite: Share same cluster for bases and following diacritics in initial map.

Alexandre Julliard julliard at winehq.org
Wed Jun 10 16:09:43 CDT 2020


Module: wine
Branch: master
Commit: 796f34e81f62124ffb5b03c64ef63f9d4bae90d7
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=796f34e81f62124ffb5b03c64ef63f9d4bae90d7

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Jun 10 17:21:33 2020 +0300

dwrite: Share same cluster for bases and following diacritics in initial map.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dwrite/opentype.c     | 26 ++++++++++++++++++++++----
 dlls/dwrite/tests/layout.c | 16 ++++++----------
 2 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index 1f0174ad72..72cc6f4c93 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -5834,13 +5834,23 @@ static unsigned int opentype_is_default_ignorable(unsigned int codepoint)
             (codepoint >= 0x180b && codepoint <= 0x180e) || (codepoint >= 0x200b && codepoint <= 0x200f);
 }
 
+static unsigned int opentype_is_diacritic(unsigned int codepoint)
+{
+    WCHAR ch = codepoint;
+    WORD type = 0;
+    /* Ignore higher planes for now. */
+    if (codepoint > 0xffff) return 0;
+    GetStringTypeW(CT_CTYPE3, &ch, 1, &type);
+    return !!(type & C3_DIACRITIC);
+}
+
 static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, const struct shaping_features *features)
 {
     unsigned int rtlm_mask = shaping_features_get_mask(features, DWRITE_MAKE_OPENTYPE_TAG('r','t','l','m'), NULL);
     const struct shaping_font_ops *font = context->cache->font;
+    unsigned int i, g, c, codepoint, cluster_start_idx = 0;
     UINT16 *clustermap = context->u.subst.clustermap;
     const WCHAR *text = context->text;
-    unsigned int i, g, c, codepoint;
     BOOL bmp;
 
     memset(context->u.subst.glyph_props, 0, context->u.subst.max_glyph_count * sizeof(*context->u.subst.glyph_props));
@@ -5873,17 +5883,25 @@ static void opentype_get_nominal_glyphs(struct scriptshaping_context *context, c
 
         context->u.buffer.glyphs[g] = font->get_glyph(context->cache->context, codepoint);
         context->u.buffer.glyph_props[g].justification = SCRIPT_JUSTIFY_CHARACTER;
-        context->u.buffer.glyph_props[g].isClusterStart = 1;
         opentype_set_subst_glyph_props(context, g);
+
+        /* Group diacritics with preceding base. Glyph class is ignored here. */
+        if (!g || !opentype_is_diacritic(codepoint))
+        {
+            context->u.buffer.glyph_props[g].isClusterStart = 1;
+            cluster_start_idx = g;
+        }
+
         if (opentype_is_default_ignorable(codepoint))
             context->u.buffer.glyph_props[g].isZeroWidthSpace = 1;
         context->u.buffer.glyph_props[g].components = 1;
         context->glyph_count++;
 
-        clustermap[i] = i;
+        /* Set initial cluster map here, it's used for setting user features masks. */
+        clustermap[i] = cluster_start_idx;
         if (!bmp)
         {
-            clustermap[i + 1] = i;
+            clustermap[i + 1] = cluster_start_idx;
             ++i;
         }
     }
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index d19f91311d..2e309f14b7 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -2630,13 +2630,11 @@ if (0) { /* crashes on native */
     count = 0;
     hr = IDWriteTextLayout1_GetClusterMetrics(layout1, clusters, 4, &count);
     ok(hr == S_OK, "got 0x%08x\n", hr);
-todo_wine
-    ok(count == 3, "got %u\n", count);
-if (count == 3) {
+    ok(count == 3, "Unexpected cluster count %u.\n", count);
     ok(clusters[0].length == 1, "got %u\n", clusters[0].length);
     ok(clusters[1].length == 2, "got %u\n", clusters[1].length);
     ok(clusters[2].length == 1, "got %u\n", clusters[2].length);
-}
+
     /* pair kerning flag participates in itemization - combining characters
        breaks */
     range.startPosition = 0;
@@ -5235,9 +5233,8 @@ static void test_SetUnderline(void)
 
     count = 0;
     hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, ARRAY_SIZE(clusters), &count);
-    ok(hr == S_OK, "got 0x%08x\n", hr);
-todo_wine
-    ok(count == 3, "got %u\n", count);
+    ok(hr == S_OK, "Failed to get cluster metrics, hr %#x.\n", hr);
+    ok(count == 3, "Unexpected cluster count %u.\n", count);
 
     range.startPosition = 0;
     range.length = 2;
@@ -5246,9 +5243,8 @@ todo_wine
 
     count = 0;
     hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, ARRAY_SIZE(clusters), &count);
-    ok(hr == S_OK, "got 0x%08x\n", hr);
-todo_wine
-    ok(count == 3, "got %u\n", count);
+    ok(hr == S_OK, "Failed to get cluster metrics, hr %#x.\n", hr);
+    ok(count == 3, "Unexpected cluster count %u.\n", count);
 
     flush_sequence(sequences, RENDERER_ID);
     hr = IDWriteTextLayout_Draw(layout, NULL, &testrenderer, 0.0, 0.0);




More information about the wine-cvs mailing list