| 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();
|
|
|