diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h')
-rw-r--r-- | chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h | 130 |
1 files changed, 97 insertions, 33 deletions
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h b/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h index c0c30d9ad8a..e0ecc103241 100644 --- a/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h +++ b/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h @@ -25,6 +25,7 @@ #include "core/rendering/BidiRun.h" #include "core/rendering/RenderBlockFlow.h" +#include "core/rendering/RenderInline.h" #include "core/rendering/RenderText.h" #include "wtf/StdLibExtras.h" @@ -43,16 +44,16 @@ public: InlineIterator() : m_root(0) , m_obj(0) - , m_pos(0) , m_nextBreakablePosition(-1) + , m_pos(0) { } InlineIterator(RenderObject* root, RenderObject* o, unsigned p) : m_root(root) , m_obj(o) - , m_pos(p) , m_nextBreakablePosition(-1) + , m_pos(p) { } @@ -73,7 +74,11 @@ public: RenderObject* object() const { return m_obj; } void setObject(RenderObject* object) { m_obj = object; } + int nextBreakablePosition() const { return m_nextBreakablePosition; } + void setNextBreakablePosition(int position) { m_nextBreakablePosition = position; } + unsigned offset() const { return m_pos; } + void setOffset(unsigned position) { m_pos = position; } RenderObject* root() const { return m_root; } void fastIncrementInTextNode(); @@ -100,20 +105,18 @@ private: RenderObject* m_root; RenderObject* m_obj; -// FIXME: These should be private. -public: - unsigned m_pos; int m_nextBreakablePosition; + unsigned m_pos; }; inline bool operator==(const InlineIterator& it1, const InlineIterator& it2) { - return it1.m_pos == it2.m_pos && it1.object() == it2.object(); + return it1.offset() == it2.offset() && it1.object() == it2.object(); } inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2) { - return it1.m_pos != it2.m_pos || it1.object() != it2.object(); + return it1.offset() != it2.offset() || it1.object() != it2.object(); } static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir, EUnicodeBidi unicodeBidi) @@ -187,7 +190,7 @@ static bool isEmptyInline(RenderObject* object) if (!object->isRenderInline()) return false; - for (RenderObject* curr = object->firstChild(); curr; curr = curr->nextSibling()) { + for (RenderObject* curr = toRenderInline(object)->firstChild(); curr; curr = curr->nextSibling()) { if (curr->isFloatingOrOutOfFlowPositioned()) continue; if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace()) @@ -213,7 +216,7 @@ static inline RenderObject* bidiNextShared(RenderObject* root, RenderObject* cur while (current) { next = 0; if (!oldEndOfInline && !isIteratorTarget(current)) { - next = current->firstChild(); + next = current->slowFirstChild(); notifyObserverEnteredObject(observer, next); } @@ -280,7 +283,7 @@ static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInlinePtr); } -static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderObject* root, InlineBidiResolver* resolver = 0) +static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root, InlineBidiResolver* resolver = 0) { RenderObject* o = root->firstChild(); if (!o) @@ -308,7 +311,7 @@ static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderObject* root, In } // FIXME: This method needs to be renamed when bidiNext finds a good name. -static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderObject* root) +static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderBlock* root) { RenderObject* o = root->firstChild(); // If either there are no children to walk, or the first one is correct @@ -332,7 +335,7 @@ inline void InlineIterator::fastIncrementInTextNode() // it shouldn't use functions called bidiFirst and bidiNext. class InlineWalker { public: - InlineWalker(RenderObject* root) + InlineWalker(RenderBlock* root) : m_root(root) , m_current(0) , m_atEndOfInline(false) @@ -341,7 +344,7 @@ public: m_current = bidiFirstIncludingEmptyInlines(m_root); } - RenderObject* root() { return m_root; } + RenderBlock* root() { return m_root; } RenderObject* current() { return m_current; } bool atEndOfInline() { return m_atEndOfInline; } @@ -354,7 +357,7 @@ public: return m_current; } private: - RenderObject* m_root; + RenderBlock* m_root; RenderObject* m_current; bool m_atEndOfInline; }; @@ -442,13 +445,74 @@ inline bool InlineBidiResolver::isEndOfLine(const InlineIterator& end) { bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() && m_current.object() == end.object()); if (inIsolate() && inEndOfLine) { - m_current.moveTo(m_current.object(), end.m_pos, m_current.m_nextBreakablePosition); + m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakablePosition()); m_last = m_current; updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); } return inEndOfLine; } +static inline bool isCollapsibleSpace(UChar character, RenderText* renderer) +{ + if (character == ' ' || character == '\t' || character == softHyphen) + return true; + if (character == '\n') + return !renderer->style()->preserveNewline(); + return false; +} + +template <typename CharacterType> +static inline int findFirstTrailingSpace(RenderText* lastText, const CharacterType* characters, int start, int stop) +{ + int firstSpace = stop; + while (firstSpace > start) { + UChar current = characters[firstSpace - 1]; + if (!isCollapsibleSpace(current, lastText)) + break; + firstSpace--; + } + + return firstSpace; +} + +template <> +inline int InlineBidiResolver::findFirstTrailingSpaceAtRun(BidiRun* run) +{ + ASSERT(run); + RenderObject* lastObject = run->m_object; + if (!lastObject->isText()) + return run->m_stop; + + RenderText* lastText = toRenderText(lastObject); + int firstSpace; + if (lastText->is8Bit()) + firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), run->start(), run->stop()); + else + firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(), run->start(), run->stop()); + return firstSpace; +} + +template <> +inline BidiRun* InlineBidiResolver::addTrailingRun(int start, int stop, BidiRun* run, BidiContext* context, TextDirection direction) +{ + BidiRun* newTrailingRun = new BidiRun(start, stop, run->m_object, context, WTF::Unicode::OtherNeutral); + if (direction == LTR) + m_runs.addRun(newTrailingRun); + else + m_runs.prependRun(newTrailingRun); + + return newTrailingRun; +} + +template <> +inline bool InlineBidiResolver::needsToApplyL1Rule() +{ + if (!m_runs.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace() + || !m_runs.logicallyLastRun()->m_object->style()->autoWrap()) + return false; + return true; +} + static inline bool isIsolatedInline(RenderObject* object) { ASSERT(object); @@ -569,18 +633,18 @@ static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns return; LineMidpointState& lineMidpointState = resolver.midpointState(); - bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints); + bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointState.numMidpoints()); InlineIterator nextMidpoint; if (haveNextMidpoint) - nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint]; - if (lineMidpointState.betweenMidpoints) { + nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMidpoint()]; + if (lineMidpointState.betweenMidpoints()) { if (!(haveNextMidpoint && nextMidpoint.object() == obj)) return; // This is a new start point. Stop ignoring objects and // adjust our start. - lineMidpointState.betweenMidpoints = false; - start = nextMidpoint.m_pos; - lineMidpointState.currentMidpoint++; + lineMidpointState.setBetweenMidpoints(false); + start = nextMidpoint.offset(); + lineMidpointState.incrementCurrentMidpoint(); if (start < end) return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, resolver, behavior, tracker); } else { @@ -591,13 +655,13 @@ static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns // 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); + if (nextMidpoint.offset() + 1 <= end) { + lineMidpointState.setBetweenMidpoints(true); + lineMidpointState.incrementCurrentMidpoint(); + if (nextMidpoint.offset() != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it. + if (nextMidpoint.offset() + 1 > start) + appendRunObjectIfNecessary(obj, start, nextMidpoint.offset() + 1, resolver, behavior, tracker); + return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMidpoint.offset() + 1, end, resolver, behavior, tracker); } } else { appendRunObjectIfNecessary(obj, start, end, resolver, behavior, tracker); @@ -619,7 +683,7 @@ inline void InlineBidiResolver::appendRun() // Initialize our state depending on if we're starting in the middle of such an inline. // FIXME: Could this initialize from this->inIsolate() instead of walking up the render tree? IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); - int start = m_sor.m_pos; + int start = m_sor.offset(); RenderObject* obj = m_sor.object(); while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.object()) { if (isolateTracker.inIsolate()) @@ -630,12 +694,12 @@ inline void InlineBidiResolver::appendRun() start = 0; obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracker); } - bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.m_pos; + bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.offset(); if (obj && !isEndOfLine) { - unsigned pos = obj == m_eor.object() ? m_eor.m_pos : INT_MAX; - if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.m_pos <= pos) { + unsigned pos = obj == m_eor.object() ? m_eor.offset() : INT_MAX; + if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.offset() <= pos) { m_reachedEndOfLine = true; - pos = m_endOfRunAtEndOfLine.m_pos; + pos = m_endOfRunAtEndOfLine.offset(); } // 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; |