Module: wine Branch: master Commit: 90ed96a766b4b627a5dd18d601b41257c4f8e390 URL: http://source.winehq.org/git/wine.git/?a=commit;h=90ed96a766b4b627a5dd18d601...
Author: Nikolay Sivov nsivov@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} } };