Nikolay Sivov : dwrite: Fix splitting by bidi levels.

Alexandre Julliard julliard at wine.codeweavers.com
Fri May 22 04:48:25 CDT 2015


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri May 22 11:27:51 2015 +0300

dwrite: Fix splitting by bidi levels.

---

 dlls/dwrite/layout.c         | 38 ++++++++++++++------------------------
 dlls/dwrite/tests/analyzer.c |  7 +++++++
 2 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index 11d69d8..0a95c4e 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -2750,15 +2750,17 @@ static HRESULT WINAPI dwritetextlayout_sink_SetBidiLevel(IDWriteTextAnalysisSink
     struct dwrite_textlayout *layout = impl_from_IDWriteTextAnalysisSink(iface);
     struct layout_run *cur_run;
 
+    TRACE("%u %u %u %u\n", position, length, explicitLevel, resolvedLevel);
+
     LIST_FOR_EACH_ENTRY(cur_run, &layout->runs, struct layout_run, entry) {
         struct regular_layout_run *cur = &cur_run->u.regular;
-        struct layout_run *run, *run2;
+        struct layout_run *run;
 
         if (cur_run->kind == LAYOUT_RUN_INLINE)
             continue;
 
         /* FIXME: levels are reported in a natural forward direction, so start loop from a run we ended on */
-        if (position < cur->descr.textPosition || position > cur->descr.textPosition + cur->descr.stringLength)
+        if (position < cur->descr.textPosition || position >= cur->descr.textPosition + cur->descr.stringLength)
             continue;
 
         /* full hit - just set run level */
@@ -2775,35 +2777,23 @@ static HRESULT WINAPI dwritetextlayout_sink_SetBidiLevel(IDWriteTextAnalysisSink
             continue;
         }
 
-        /* now starting point is in a run, so it splits it */
+        /* all fully covered runs are processed at this point, reuse existing run for remaining
+           reported bidi range and add another run for the rest of original one */
+
         run = alloc_layout_run(LAYOUT_RUN_REGULAR);
         if (!run)
             return E_OUTOFMEMORY;
 
         *run = *cur_run;
-        run->u.regular.descr.textPosition = position;
-        run->u.regular.descr.stringLength = cur->descr.stringLength - position + cur->descr.textPosition;
-        run->u.regular.descr.string = &layout->str[position];
-        run->u.regular.run.bidiLevel = resolvedLevel;
-        cur->descr.stringLength -= position - cur->descr.textPosition;
+        run->u.regular.descr.textPosition = position + length;
+        run->u.regular.descr.stringLength = cur->descr.stringLength - length;
+        run->u.regular.descr.string = &layout->str[position + length];
 
-        list_add_after(&cur_run->entry, &run->entry);
-
-        if (position + length == run->u.regular.descr.textPosition + run->u.regular.descr.stringLength)
-            break;
+        /* reduce existing run */
+        cur->run.bidiLevel = resolvedLevel;
+        cur->descr.stringLength -= length;
 
-        /* split second time */
-        run2 = alloc_layout_run(LAYOUT_RUN_REGULAR);
-        if (!run2)
-            return E_OUTOFMEMORY;
-
-        *run2 = *cur_run;
-        run2->u.regular.descr.textPosition = run->u.regular.descr.textPosition + run->u.regular.descr.stringLength;
-        run2->u.regular.descr.stringLength = cur->descr.textPosition + cur->descr.stringLength - position - length;
-        run2->u.regular.descr.string = &layout->str[run2->u.regular.descr.textPosition];
-        run->u.regular.descr.stringLength -= run2->u.regular.descr.stringLength;
-
-        list_add_after(&run->entry, &run2->entry);
+        list_add_after(&cur_run->entry, &run->entry);
         break;
     }
 
diff --git a/dlls/dwrite/tests/analyzer.c b/dlls/dwrite/tests/analyzer.c
index 0043526..43c2a66 100644
--- a/dlls/dwrite/tests/analyzer.c
+++ b/dlls/dwrite/tests/analyzer.c
@@ -878,6 +878,13 @@ static struct sa_test sa_tests[] = {
       {0x2d30,0x2d4a,0}, 1,
           { { 0, 2, DWRITE_SCRIPT_SHAPES_DEFAULT }}
     },
+    {
+      /* LRE/PDF */
+      {0x202a,0x202c,'a','b','c','\r',0}, 3,
+          { { 0, 2, DWRITE_SCRIPT_SHAPES_NO_VISUAL },
+            { 2, 3, DWRITE_SCRIPT_SHAPES_DEFAULT   },
+            { 5, 1, DWRITE_SCRIPT_SHAPES_NO_VISUAL } }
+    },
     /* keep this as end marker */
     { {0} }
 };




More information about the wine-cvs mailing list