Chromium Code Reviews| Index: Source/core/rendering/InlineIterator.h |
| diff --git a/Source/core/rendering/InlineIterator.h b/Source/core/rendering/InlineIterator.h |
| index 1885f8e521cc745ac587b5990ee6eba530d3d431..349d6ac83c4f950d750c6bda71b945287b22995e 100644 |
| --- a/Source/core/rendering/InlineIterator.h |
| +++ b/Source/core/rendering/InlineIterator.h |
| @@ -474,6 +474,8 @@ static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolv |
| // FIXME: isolatedRuns() could be a hash of object->run and then we could cheaply |
| // ASSERT here that we didn't create multiple objects for the same inline. |
| resolver.isolatedRuns().append(isolatedRun); |
| + LineMidpointState& lineMidpointState = resolver.midpointState(); |
| + resolver.setMidpointStateForIsolatedRun(isolatedRun, lineMidpointState); |
| } |
| class IsolateTracker { |
| @@ -498,26 +500,49 @@ public: |
| void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } |
| void commitExplicitEmbedding() { } |
| - void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, InlineBidiResolver& resolver) |
| + void adjustMidpointForIsolatedRun(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver) |
|
leviw_travelin_and_unemployed
2013/10/07 21:58:42
This seems really similar to RenderBlock::appendRu
|
| + { |
| + if (start > end) |
| + return; |
| + |
| + LineMidpointState& lineMidpointState = resolver.midpointState(); |
| + bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints); |
| + InlineIterator nextMidpoint; |
| + if (haveNextMidpoint) |
| + nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint]; |
| + if (lineMidpointState.betweenMidpoints) { |
| + if (!(haveNextMidpoint && nextMidpoint.m_obj == obj)) |
| + return; |
| + lineMidpointState.betweenMidpoints = false; |
| + lineMidpointState.currentMidpoint++; |
| + if (start < end) |
| + return adjustMidpointForIsolatedRun(obj, start, end, resolver); |
| + } else { |
| + if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) |
| + return; |
| + if (static_cast<int>(nextMidpoint.m_pos + 1) <= end) { |
| + lineMidpointState.betweenMidpoints = true; |
| + lineMidpointState.currentMidpoint++; |
| + if (nextMidpoint.m_pos != UINT_MAX) |
| + return adjustMidpointForIsolatedRun(obj, nextMidpoint.m_pos + 1, end, resolver); |
| + } |
| + } |
| + } |
| + |
| + void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, unsigned end, InlineBidiResolver& resolver) |
| { |
| // We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine. |
| // We'll be called for every span inside the isolated span so we just ignore subsequent calls. |
| // We also avoid creating a fake run until we hit a child that warrants one, e.g. we skip floats. |
| - if (m_haveAddedFakeRunForRootIsolate || RenderBlock::shouldSkipCreatingRunsForObject(obj)) |
| - return; |
| - m_haveAddedFakeRunForRootIsolate = true; |
| + if (!(m_haveAddedFakeRunForRootIsolate || RenderBlock::shouldSkipCreatingRunsForObject(obj))) { |
| + addPlaceholderRunForIsolatedInline(resolver, obj, pos); |
| + m_haveAddedFakeRunForRootIsolate = true; |
| + } |
| + adjustMidpointForIsolatedRun(obj, pos, end, resolver); |
| + |
| // obj and pos together denote a single position in the inline, from which the parsing of the isolate will start. |
| // We don't need to mark the end of the run because this is implicit: it is either endOfLine or the end of the |
| // isolate, when we call createBidiRunsForLine it will stop at whichever comes first. |
| - addPlaceholderRunForIsolatedInline(resolver, obj, pos); |
| - // FIXME: Inline isolates don't work properly with collapsing whitespace, see webkit.org/b/109624 |
| - // For now, if we enter an isolate between midpoints, we increment our current midpoint or else |
| - // we'll leave the isolate and ignore the content that follows. |
| - MidpointState<InlineIterator>& midpointState = resolver.midpointState(); |
| - if (midpointState.betweenMidpoints && midpointState.midpoints[midpointState.currentMidpoint].object() == obj) { |
| - midpointState.betweenMidpoints = false; |
| - ++midpointState.currentMidpoint; |
| - } |
| } |
| private: |
| @@ -537,7 +562,7 @@ inline void InlineBidiResolver::appendRun() |
| RenderObject* obj = m_sor.m_obj; |
| while (obj && obj != m_eor.m_obj && obj != endOfLine.m_obj) { |
| if (isolateTracker.inIsolate()) |
| - isolateTracker.addFakeRunIfNecessary(obj, start, *this); |
| + isolateTracker.addFakeRunIfNecessary(obj, start, obj->length(), *this); |
| else |
| RenderBlock::appendRunsForObject(m_runs, start, obj->length(), obj, *this); |
| // FIXME: start/obj should be an InlineIterator instead of two separate variables. |
| @@ -553,7 +578,7 @@ inline void InlineBidiResolver::appendRun() |
| // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be |
| int end = obj->length() ? pos + 1 : 0; |
| if (isolateTracker.inIsolate()) |
| - isolateTracker.addFakeRunIfNecessary(obj, start, *this); |
| + isolateTracker.addFakeRunIfNecessary(obj, start, end, *this); |
| else |
| RenderBlock::appendRunsForObject(m_runs, start, end, obj, *this); |
| } |