dwrite: Fix splitting by bidi levels.
This commit is contained in:
parent
1f55764dfc
commit
90ed96a766
|
@ -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];
|
||||
|
||||
/* reduce existing run */
|
||||
cur->run.bidiLevel = resolvedLevel;
|
||||
cur->descr.stringLength -= length;
|
||||
|
||||
list_add_after(&cur_run->entry, &run->entry);
|
||||
|
||||
if (position + length == run->u.regular.descr.textPosition + run->u.regular.descr.stringLength)
|
||||
break;
|
||||
|
||||
/* 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);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -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} }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue