summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering/InlineIterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/InlineIterator.h')
-rw-r--r--Source/WebCore/rendering/InlineIterator.h173
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;