Index: Source/core/rendering/InlineIterator.h |
diff --git a/Source/core/rendering/InlineIterator.h b/Source/core/rendering/InlineIterator.h |
index 2aa0c6ff0f88ece779090239bdf0d25d46f324f1..ec5f7da798fd4411e9208b27ec4505ad35eade37 100644 |
--- a/Source/core/rendering/InlineIterator.h |
+++ b/Source/core/rendering/InlineIterator.h |
@@ -466,7 +466,7 @@ static inline unsigned numberOfIsolateAncestors(const InlineIterator& iter) |
// FIXME: This belongs on InlineBidiResolver, except it's a template specialization |
// of BidiResolver which knows nothing about RenderObjects. |
-static inline void addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolver, RenderObject* obj, unsigned pos) |
+static inline BidiRun* addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolver, RenderObject* obj, unsigned pos) |
{ |
ASSERT(obj); |
BidiRun* isolatedRun = new BidiRun(pos, pos, obj, resolver.context(), resolver.dir()); |
@@ -474,8 +474,7 @@ 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); |
+ return isolatedRun; |
} |
static inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBidiResolver& resolver) |
@@ -488,50 +487,6 @@ enum AppendRunBehavior { |
AppendingRunsForObject |
}; |
-static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior = AppendingFakeRun, BidiRunList<BidiRun>* runs = 0) |
-{ |
- if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) |
- 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; |
- // This is a new start point. Stop ignoring objects and |
- // adjust our start. |
- lineMidpointState.betweenMidpoints = false; |
- start = nextMidpoint.m_pos; |
- lineMidpointState.currentMidpoint++; |
- if (start < end) |
- return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, resolver, behavior, runs); |
- } else { |
- if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) { |
- if (behavior == AppendingFakeRun) |
- return; |
- runs->addRun(createRun(start, end, obj, resolver)); |
- return; |
- } |
- |
- // An end midpoint has been encountered within our object. We |
- // need to go ahead and append a run with our endpoint. |
- if (nextMidpoint.m_pos + 1 <= end) { |
- lineMidpointState.betweenMidpoints = true; |
- lineMidpointState.currentMidpoint++; |
- if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it. |
- if (nextMidpoint.m_pos + 1 > start && behavior == AppendingRunsForObject) |
- runs->addRun(createRun(start, nextMidpoint.m_pos + 1, obj, resolver)); |
- return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMidpoint.m_pos + 1, end, resolver, behavior, runs); |
- } |
- } else if (behavior == AppendingRunsForObject) { |
- runs->addRun(createRun(start, end, obj, resolver)); |
- } |
- } |
-} |
- |
class IsolateTracker { |
public: |
explicit IsolateTracker(unsigned nestedIsolateCount) |
@@ -540,6 +495,11 @@ public: |
{ |
} |
+ void setMidpointStateForRootIsolate(const LineMidpointState& midpointState) |
+ { |
+ m_midpointStateForRootIsolate = midpointState; |
+ } |
+ |
void enterIsolate() { m_nestedIsolateCount++; } |
void exitIsolate() |
{ |
@@ -554,7 +514,6 @@ public: |
void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } |
void commitExplicitEmbedding() { } |
- |
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. |
@@ -563,11 +522,10 @@ public: |
if (RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) |
return; |
if (!m_haveAddedFakeRunForRootIsolate) { |
- addPlaceholderRunForIsolatedInline(resolver, obj, pos); |
+ BidiRun* run = addPlaceholderRunForIsolatedInline(resolver, obj, pos); |
+ resolver.setMidpointStateForIsolatedRun(run, m_midpointStateForRootIsolate); |
m_haveAddedFakeRunForRootIsolate = true; |
} |
- adjustMidpointsAndAppendRunsForObjectIfNeeded(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. |
@@ -576,8 +534,65 @@ public: |
private: |
unsigned m_nestedIsolateCount; |
bool m_haveAddedFakeRunForRootIsolate; |
+ LineMidpointState m_midpointStateForRootIsolate; |
}; |
+static void inline appendRunObjectIfNecessary(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, IsolateTracker& tracker) |
+{ |
+ if (behavior == AppendingFakeRun) |
+ tracker.addFakeRunIfNecessary(obj, start, end, resolver); |
+ else |
+ resolver.runs().addRun(createRun(start, end, obj, resolver)); |
+} |
+ |
+static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, IsolateTracker& tracker) |
+{ |
+ if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) |
+ 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; |
+ // This is a new start point. Stop ignoring objects and |
+ // adjust our start. |
+ lineMidpointState.betweenMidpoints = false; |
+ start = nextMidpoint.m_pos; |
+ lineMidpointState.currentMidpoint++; |
+ if (start < end) |
+ return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, resolver, behavior, tracker); |
+ } else { |
+ if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) { |
+ appendRunObjectIfNecessary(obj, start, end, resolver, behavior, tracker); |
+ return; |
+ } |
+ |
+ // An end midpoint has been encountered within our object. We |
+ // need to go ahead and append a run with our endpoint. |
+ if (nextMidpoint.m_pos + 1 <= end) { |
+ lineMidpointState.betweenMidpoints = true; |
+ lineMidpointState.currentMidpoint++; |
+ if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it. |
+ if (nextMidpoint.m_pos + 1 > start) |
+ appendRunObjectIfNecessary(obj, start, nextMidpoint.m_pos + 1, resolver, behavior, tracker); |
+ return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMidpoint.m_pos + 1, end, resolver, behavior, tracker); |
+ } |
+ } else { |
+ appendRunObjectIfNecessary(obj, start, end, resolver, behavior, tracker); |
+ } |
+ } |
+} |
+ |
+static inline void addFakeRunIfNecessary(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, IsolateTracker& tracker) |
+{ |
+ tracker.setMidpointStateForRootIsolate(resolver.midpointState()); |
+ adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->length(), resolver, AppendingFakeRun, tracker); |
+} |
+ |
template <> |
inline void InlineBidiResolver::appendRun() |
{ |
@@ -590,9 +605,9 @@ 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, obj->length(), *this); |
+ addFakeRunIfNecessary(obj, start, obj->length(), *this, isolateTracker); |
else |
- RenderBlockFlow::appendRunsForObject(m_runs, start, obj->length(), obj, *this); |
+ adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->length(), *this, AppendingRunsForObject, isolateTracker); |
// FIXME: start/obj should be an InlineIterator instead of two separate variables. |
start = 0; |
obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracker); |
@@ -606,9 +621,9 @@ 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, end, *this); |
+ addFakeRunIfNecessary(obj, start, end, *this, isolateTracker); |
else |
- RenderBlockFlow::appendRunsForObject(m_runs, start, end, obj, *this); |
+ adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, *this, AppendingRunsForObject, isolateTracker); |
} |
m_eor.increment(); |