diff options
Diffstat (limited to 'Source/WebCore/rendering/InlineIterator.h')
-rw-r--r-- | Source/WebCore/rendering/InlineIterator.h | 173 |
1 files changed, 93 insertions, 80 deletions
diff --git a/Source/WebCore/rendering/InlineIterator.h b/Source/WebCore/rendering/InlineIterator.h index 270364f..75d9763 100644 --- a/Source/WebCore/rendering/InlineIterator.h +++ b/Source/WebCore/rendering/InlineIterator.h @@ -34,43 +34,89 @@ namespace WebCore { class InlineIterator { public: InlineIterator() - : block(0) - , obj(0) - , pos(0) - , nextBreakablePosition(-1) + : m_block(0) + , m_obj(0) + , m_pos(0) + , m_nextBreakablePosition(-1) { } InlineIterator(RenderBlock* b, RenderObject* o, unsigned p) - : block(b) - , obj(o) - , pos(p) - , nextBreakablePosition(-1) + : m_block(b) + , m_obj(o) + , m_pos(p) + , m_nextBreakablePosition(-1) { } + void clear() { moveTo(0, 0); } + + void moveToStartOf(RenderObject* object) + { + moveTo(object, 0); + } + + void moveTo(RenderObject* object, unsigned offset, int nextBreak = -1) + { + m_obj = object; + m_pos = offset; + m_nextBreakablePosition = nextBreak; + } + void increment(InlineBidiResolver* resolver = 0); bool atEnd() const; UChar current() const; ALWAYS_INLINE WTF::Unicode::Direction direction() const; - RenderBlock* block; - RenderObject* obj; - unsigned pos; - int nextBreakablePosition; + RenderBlock* m_block; + RenderObject* m_obj; + unsigned m_pos; + int m_nextBreakablePosition; }; inline bool operator==(const InlineIterator& it1, const InlineIterator& it2) { - return it1.pos == it2.pos && it1.obj == it2.obj; + return it1.m_pos == it2.m_pos && it1.m_obj == it2.m_obj; } inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2) { - return it1.pos != it2.pos || it1.obj != it2.obj; + return it1.m_pos != it2.m_pos || it1.m_obj != it2.m_obj; +} + +static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir, EUnicodeBidi unicodeBidi) +{ + using namespace WTF::Unicode; + if (unicodeBidi == Embed) + return dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding; + return dir == RTL ? RightToLeftOverride : LeftToRightOverride; +} + +static inline void notifyResolverEnteredObject(InlineBidiResolver* resolver, RenderObject* object) +{ + if (!resolver || !object || !object->isRenderInline()) + return; + + RenderStyle* style = object->style(); + EUnicodeBidi unicodeBidi = style->unicodeBidi(); + if (unicodeBidi == UBNormal) + return; + resolver->embed(embedCharFromDirection(style->direction(), unicodeBidi), FromStyleOrDOM); +} + +static inline void notifyResolverWillExitObject(InlineBidiResolver* resolver, RenderObject* object) +{ + if (!resolver || !object || !object->isRenderInline()) + return; + if (object->style()->unicodeBidi() == UBNormal) + return; + resolver->embed(WTF::Unicode::PopDirectionalFormat, FromStyleOrDOM); } +// FIXME: This function is misleadingly named. It has little to do with bidi. +// This function will iterate over inlines within a block, optionally notifying +// a bidi resolver as it enters/exits inlines (so it can push/pop embedding levels). static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, InlineBidiResolver* resolver = 0, bool skipInlines = true, bool* endOfInlinePtr = 0) { RenderObject* next = 0; @@ -81,16 +127,7 @@ static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, next = 0; if (!oldEndOfInline && !current->isFloating() && !current->isReplaced() && !current->isPositioned() && !current->isText()) { next = current->firstChild(); - if (next && resolver && next->isRenderInline()) { - EUnicodeBidi ub = next->style()->unicodeBidi(); - if (ub != UBNormal) { - TextDirection dir = next->style()->direction(); - WTF::Unicode::Direction d = (ub == Embed - ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding : WTF::Unicode::LeftToRightEmbedding) - : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride)); - resolver->embed(d); - } - } + notifyResolverEnteredObject(resolver, next); } if (!next) { @@ -101,24 +138,14 @@ static inline RenderObject* bidiNext(RenderBlock* block, RenderObject* current, } while (current && current != block) { - if (resolver && current->isRenderInline() && current->style()->unicodeBidi() != UBNormal) - resolver->embed(WTF::Unicode::PopDirectionalFormat); + notifyResolverWillExitObject(resolver, current); next = current->nextSibling(); if (next) { - if (resolver && next->isRenderInline()) { - EUnicodeBidi ub = next->style()->unicodeBidi(); - if (ub != UBNormal) { - TextDirection dir = next->style()->direction(); - WTF::Unicode::Direction d = (ub == Embed - ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding: WTF::Unicode::LeftToRightEmbedding) - : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride)); - resolver->embed(d); - } - } + notifyResolverEnteredObject(resolver, next); break; } - + current = current->parent(); if (!skipInlines && current && current != block && current->isRenderInline()) { next = current; @@ -148,19 +175,10 @@ static inline RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* re { if (!block->firstChild()) return 0; - + RenderObject* o = block->firstChild(); if (o->isRenderInline()) { - if (resolver) { - EUnicodeBidi ub = o->style()->unicodeBidi(); - if (ub != UBNormal) { - TextDirection dir = o->style()->direction(); - WTF::Unicode::Direction d = (ub == Embed - ? (dir == RTL ? WTF::Unicode::RightToLeftEmbedding : WTF::Unicode::LeftToRightEmbedding) - : (dir == RTL ? WTF::Unicode::RightToLeftOverride : WTF::Unicode::LeftToRightOverride)); - resolver->embed(d); - } - } + notifyResolverEnteredObject(resolver, o); if (skipInlines && o->firstChild()) o = bidiNext(block, o, resolver, skipInlines); else { @@ -181,37 +199,32 @@ static inline RenderObject* bidiFirst(RenderBlock* block, InlineBidiResolver* re inline void InlineIterator::increment(InlineBidiResolver* resolver) { - if (!obj) + if (!m_obj) return; - if (obj->isText()) { - pos++; - if (pos >= toRenderText(obj)->textLength()) { - obj = bidiNext(block, obj, resolver); - pos = 0; - nextBreakablePosition = -1; - } - } else { - obj = bidiNext(block, obj, resolver); - pos = 0; - nextBreakablePosition = -1; + if (m_obj->isText()) { + m_pos++; + if (m_pos < toRenderText(m_obj)->textLength()) + return; } + // bidiNext can return 0, so use moveTo instead of moveToStartOf + moveTo(bidiNext(m_block, m_obj, resolver), 0); } inline bool InlineIterator::atEnd() const { - return !obj; + return !m_obj; } inline UChar InlineIterator::current() const { - if (!obj || !obj->isText()) + if (!m_obj || !m_obj->isText()) return 0; - RenderText* text = toRenderText(obj); - if (pos >= text->textLength()) + RenderText* text = toRenderText(m_obj); + if (m_pos >= text->textLength()) return 0; - return text->characters()[pos]; + return text->characters()[m_pos]; } ALWAYS_INLINE WTF::Unicode::Direction InlineIterator::direction() const @@ -219,8 +232,8 @@ ALWAYS_INLINE WTF::Unicode::Direction InlineIterator::direction() const if (UChar c = current()) return WTF::Unicode::direction(c); - if (obj && obj->isListMarker()) - return obj->style()->isLeftToRightDirection() ? WTF::Unicode::LeftToRight : WTF::Unicode::RightToLeft; + if (m_obj && m_obj->isListMarker()) + return m_obj->style()->isLeftToRightDirection() ? WTF::Unicode::LeftToRight : WTF::Unicode::RightToLeft; return WTF::Unicode::OtherNeutral; } @@ -228,33 +241,33 @@ ALWAYS_INLINE WTF::Unicode::Direction InlineIterator::direction() const template<> inline void InlineBidiResolver::increment() { - current.increment(this); + m_current.increment(this); } template <> inline void InlineBidiResolver::appendRun() { - if (!emptyRun && !eor.atEnd()) { - int start = sor.pos; - RenderObject *obj = sor.obj; - while (obj && obj != eor.obj && obj != endOfLine.obj) { + if (!emptyRun && !m_eor.atEnd()) { + int start = m_sor.m_pos; + RenderObject* obj = m_sor.m_obj; + while (obj && obj != m_eor.m_obj && obj != endOfLine.m_obj) { RenderBlock::appendRunsForObject(start, obj->length(), obj, *this); start = 0; - obj = bidiNext(sor.block, obj); + obj = bidiNext(m_sor.m_block, obj); } if (obj) { - unsigned pos = obj == eor.obj ? eor.pos : UINT_MAX; - if (obj == endOfLine.obj && endOfLine.pos <= pos) { - reachedEndOfLine = true; - pos = endOfLine.pos; + unsigned pos = obj == m_eor.m_obj ? m_eor.m_pos : UINT_MAX; + if (obj == endOfLine.m_obj && endOfLine.m_pos <= pos) { + m_reachedEndOfLine = true; + pos = endOfLine.m_pos; } // 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; + int end = obj->length() ? pos + 1 : 0; RenderBlock::appendRunsForObject(start, end, obj, *this); } - eor.increment(); - sor = eor; + m_eor.increment(); + m_sor = m_eor; } m_direction = WTF::Unicode::OtherNeutral; |