15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Google Inc. All rights reserved.
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef InlineIterator_h
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define InlineIterator_h
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/BidiRun.h"
27f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)#include "core/rendering/RenderBlockFlow.h"
28d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/rendering/RenderInline.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderText.h"
3002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "wtf/StdLibExtras.h"
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This class is used to RenderInline subtrees, stepping by character within the
355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// text children. InlineIterator will use bidiNext to find the next RenderText
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// optionally notifying a BidiResolver every time it steps into/out of a RenderInline.
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class InlineIterator {
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
398abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    enum IncrementRule {
409bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        FastIncrementInIsolatedRenderer,
418abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        FastIncrementInTextNode
428abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    };
438abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineIterator()
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_root(0)
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_obj(0)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_nextBreakablePosition(-1)
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        , m_pos(0)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineIterator(RenderObject* root, RenderObject* o, unsigned p)
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_root(root)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_obj(o)
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_nextBreakablePosition(-1)
5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        , m_pos(p)
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void clear() { moveTo(0, 0); }
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void moveToStartOf(RenderObject* object)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        moveTo(object, 0);
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void moveTo(RenderObject* object, unsigned offset, int nextBreak = -1)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_obj = object;
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_pos = offset;
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_nextBreakablePosition = nextBreak;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* object() const { return m_obj; }
7551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void setObject(RenderObject* object) { m_obj = object; }
7651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    int nextBreakablePosition() const { return m_nextBreakablePosition; }
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void setNextBreakablePosition(int position) { m_nextBreakablePosition = position; }
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned offset() const { return m_pos; }
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    void setOffset(unsigned position) { m_pos = position; }
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* root() const { return m_root; }
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void fastIncrementInTextNode();
858abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextNode);
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool atEnd() const;
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
8806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    inline bool atTextParagraphSeparator() const
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_obj && m_obj->preservesNewline() && m_obj->isText() && toRenderText(m_obj)->textLength()
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            && !toRenderText(m_obj)->isWordBreak() && toRenderText(m_obj)->characterAt(m_pos) == '\n';
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
9302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
9406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    inline bool atParagraphSeparator() const
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return (m_obj && m_obj->isBR()) || atTextParagraphSeparator();
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    UChar characterAt(unsigned) const;
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar current() const;
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    UChar previousInSameNode() const;
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ALWAYS_INLINE WTF::Unicode::Direction direction() const;
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* m_root;
10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    RenderObject* m_obj;
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    int m_nextBreakablePosition;
10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    unsigned m_pos;
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return it1.offset() == it2.offset() && it1.object() == it2.object();
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return it1.offset() != it2.offset() || it1.object() != it2.object();
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir, EUnicodeBidi unicodeBidi)
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    using namespace WTF::Unicode;
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (unicodeBidi == Embed)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding;
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return dir == RTL ? RightToLeftOverride : LeftToRightOverride;
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Observer>
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void notifyObserverEnteredObject(Observer* observer, RenderObject* object)
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!observer || !object || !object->isRenderInline())
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderStyle* style = object->style();
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    EUnicodeBidi unicodeBidi = style->unicodeBidi();
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (unicodeBidi == UBNormal) {
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // "The element does not open an additional level of embedding with respect to the bidirectional algorithm."
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Thus we ignore any possible dir= attribute on the span.
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isIsolated(unicodeBidi)) {
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Make sure that explicit embeddings are committed before we enter the isolated content.
146c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        observer->commitExplicitEmbedding(observer->runs());
1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        observer->enterIsolate();
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Embedding/Override characters implied by dir= will be handled when
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // we process the isolated span, not when laying out the "parent" run.
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!observer->inIsolate())
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        observer->embed(embedCharFromDirection(style->direction(), unicodeBidi), FromStyleOrDOM);
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Observer>
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void notifyObserverWillExitObject(Observer* observer, RenderObject* object)
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!observer || !object || !object->isRenderInline())
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    EUnicodeBidi unicodeBidi = object->style()->unicodeBidi();
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (unicodeBidi == UBNormal)
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return; // Nothing to do for unicode-bidi: normal
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isIsolated(unicodeBidi)) {
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        observer->exitIsolate();
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Otherwise we pop any embed/override character we added when we opened this tag.
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!observer->inIsolate())
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        observer->embed(WTF::Unicode::PopDirectionalFormat, FromStyleOrDOM);
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isIteratorTarget(RenderObject* object)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(object); // The iterator will of course return 0, but its not an expected argument to this function.
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return object->isText() || object->isFloating() || object->isOutOfFlowPositioned() || object->isReplaced();
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This enum is only used for bidiNextShared()
1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)enum EmptyInlineBehavior {
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SkipEmptyInlines,
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    IncludeEmptyInlines,
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)static bool isEmptyInline(RenderObject* object)
189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!object->isRenderInline())
191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
192926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
193d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    for (RenderObject* curr = toRenderInline(object)->firstChild(); curr; curr = curr->nextSibling()) {
194926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (curr->isFloatingOrOutOfFlowPositioned())
195926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            continue;
196926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace())
197926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            continue;
198926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
199926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!isEmptyInline(curr))
200926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return false;
201926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
202926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return true;
203926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
204926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: This function is misleadingly named. It has little to do with bidi.
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This function will iterate over inlines within a block, optionally notifying
2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// a bidi resolver as it enters/exits inlines (so it can push/pop embedding levels).
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Observer>
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderObject* bidiNextShared(RenderObject* root, RenderObject* current, Observer* observer = 0, EmptyInlineBehavior emptyInlineBehavior = SkipEmptyInlines, bool* endOfInlinePtr = 0)
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* next = 0;
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // oldEndOfInline denotes if when we last stopped iterating if we were at the end of an inline.
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool endOfInline = false;
2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (current) {
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        next = 0;
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!oldEndOfInline && !isIteratorTarget(current)) {
219d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            next = current->slowFirstChild();
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            notifyObserverEnteredObject(observer, next);
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We hit this when either current has no children, or when current is not a renderer we care about.
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!next) {
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If it is a renderer we care about, and we're doing our inline-walk, return it.
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (emptyInlineBehavior == IncludeEmptyInlines && !oldEndOfInline && current->isRenderInline()) {
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                next = current;
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                endOfInline = true;
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (current && current != root) {
2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                notifyObserverWillExitObject(observer, current);
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                next = current->nextSibling();
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (next) {
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    notifyObserverEnteredObject(observer, next);
2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                current = current->parent();
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (emptyInlineBehavior == IncludeEmptyInlines && current && current != root && current->isRenderInline()) {
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    next = current;
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    endOfInline = true;
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!next)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isIteratorTarget(next)
254926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            || ((emptyInlineBehavior == IncludeEmptyInlines || isEmptyInline(next)) // Always return EMPTY inlines.
2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                && next->isRenderInline()))
2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        current = next;
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (endOfInlinePtr)
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        *endOfInlinePtr = endOfInline;
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return next;
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <class Observer>
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderObject* bidiNextSkippingEmptyInlines(RenderObject* root, RenderObject* current, Observer* observer)
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The SkipEmptyInlines callers never care about endOfInlinePtr.
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return bidiNextShared(root, current, observer, SkipEmptyInlines);
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This makes callers cleaner as they don't have to specify a type for the observer when not providing one.
2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderObject* bidiNextSkippingEmptyInlines(RenderObject* root, RenderObject* current)
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineBidiResolver* observer = 0;
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return bidiNextSkippingEmptyInlines(root, current, observer);
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, RenderObject* current, bool* endOfInlinePtr = 0)
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    InlineBidiResolver* observer = 0; // Callers who include empty inlines, never use an observer.
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInlinePtr);
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
286c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root, BidiRunList<BidiRun>& runs, InlineBidiResolver* resolver = 0)
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* o = root->firstChild();
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!o)
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (o->isRenderInline()) {
2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        notifyObserverEnteredObject(resolver, o);
294926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (!isEmptyInline(o))
2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            o = bidiNextSkippingEmptyInlines(root, o, resolver);
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else {
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Never skip empty inlines.
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (resolver)
299c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                resolver->commitExplicitEmbedding(runs);
30002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch            return o;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: Unify this with the bidiNext call above.
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (o && !isIteratorTarget(o))
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        o = bidiNextSkippingEmptyInlines(root, o, resolver);
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (resolver)
309c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        resolver->commitExplicitEmbedding(runs);
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return o;
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: This method needs to be renamed when bidiNext finds a good name.
314d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderBlock* root)
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* o = root->firstChild();
3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If either there are no children to walk, or the first one is correct
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // then just return it.
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!o || o->isRenderInline() || isIteratorTarget(o))
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return o;
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return bidiNextIncludingEmptyInlines(root, o);
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void InlineIterator::fastIncrementInTextNode()
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_obj);
3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_obj->isText());
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_pos <= toRenderText(m_obj)->textLength());
330e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    if (m_pos < INT_MAX)
331e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)        m_pos++;
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
33419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)// FIXME: This is used by RenderBlockFlow for simplified layout, and has nothing to do with bidi
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// it shouldn't use functions called bidiFirst and bidiNext.
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class InlineWalker {
3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
338d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    InlineWalker(RenderBlock* root)
3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_root(root)
3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_current(0)
3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_atEndOfInline(false)
3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: This class should be taught how to do the SkipEmptyInlines codepath as well.
3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_current = bidiFirstIncludingEmptyInlines(m_root);
3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
347d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RenderBlock* root() { return m_root; }
3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* current() { return m_current; }
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool atEndOfInline() { return m_atEndOfInline; }
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool atEnd() const { return !m_current; }
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* advance()
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Support SkipEmptyInlines and observer parameters.
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_current = bidiNextIncludingEmptyInlines(m_root, m_current, &m_atEndOfInline);
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_current;
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
360d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    RenderBlock* m_root;
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* m_current;
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_atEndOfInline;
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
36509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static inline bool endOfLineHasIsolatedObjectAncestor(const InlineIterator& isolatedIterator, const InlineIterator& ancestorItertor)
36609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
36709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!isolatedIterator.object() || !isIsolated(isolatedIterator.object()->style()->unicodeBidi()))
36809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
36909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
37009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RenderObject* innerIsolatedObject = isolatedIterator.object();
37109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    while (innerIsolatedObject && innerIsolatedObject != isolatedIterator.root()) {
37209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (innerIsolatedObject == ancestorItertor.object())
37309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return true;
37409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        innerIsolatedObject = innerIsolatedObject->parent();
37509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
37609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return false;
37709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
37809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
3798abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)inline void InlineIterator::increment(InlineBidiResolver* resolver, IncrementRule rule)
3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_obj)
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3839bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
38409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (rule == FastIncrementInIsolatedRenderer
38509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        && resolver && resolver->inIsolate()
38609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        && !endOfLineHasIsolatedObjectAncestor(resolver->endOfLine(), resolver->position())) {
3879bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0);
3889bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        return;
3899bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
3909bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
3919bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    if (m_obj->isText()) {
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        fastIncrementInTextNode();
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (m_pos < toRenderText(m_obj)->textLength())
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // bidiNext can return 0, so use moveTo instead of moveToStartOf
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0);
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline bool InlineIterator::atEnd() const
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return !m_obj;
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
405926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline UChar InlineIterator::characterAt(unsigned index) const
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_obj || !m_obj->isText())
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
41093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return toRenderText(m_obj)->characterAt(index);
411926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
412926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
413926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)inline UChar InlineIterator::current() const
414926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
415926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return characterAt(m_pos);
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline UChar InlineIterator::previousInSameNode() const
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
420926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    if (!m_pos)
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
423926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    return characterAt(m_pos - 1);
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ALWAYS_INLINE WTF::Unicode::Direction InlineIterator::direction() const
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (UChar c = current())
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return WTF::Unicode::direction(c);
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_obj && m_obj->isListMarker())
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return m_obj->style()->isLeftToRightDirection() ? WTF::Unicode::LeftToRight : WTF::Unicode::RightToLeft;
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return WTF::Unicode::OtherNeutral;
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<>
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void InlineBidiResolver::increment()
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
4409bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    m_current.increment(this, InlineIterator::FastIncrementInIsolatedRenderer);
4419bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)}
4429bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)
4439bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)template <>
44451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)inline bool InlineBidiResolver::isEndOfLine(const InlineIterator& end)
4459bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles){
44651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() && m_current.object() == end.object());
44751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (inIsolate() && inEndOfLine) {
44809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakablePosition());
4499bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        m_last = m_current;
4509bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)        updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral);
4519bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)    }
45251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return inEndOfLine;
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
45509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static inline bool isCollapsibleSpace(UChar character, RenderText* renderer)
45609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
45709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (character == ' ' || character == '\t' || character == softHyphen)
45809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return true;
45909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (character == '\n')
46009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return !renderer->style()->preserveNewline();
46109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return false;
46209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
46309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
46409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template <typename CharacterType>
46509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static inline int findFirstTrailingSpace(RenderText* lastText, const CharacterType* characters, int start, int stop)
46609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
46709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    int firstSpace = stop;
46809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    while (firstSpace > start) {
46909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        UChar current = characters[firstSpace - 1];
47009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (!isCollapsibleSpace(current, lastText))
47109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            break;
47209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        firstSpace--;
47309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
47409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
47509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return firstSpace;
47609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
47709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
47809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template <>
47909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)inline int InlineBidiResolver::findFirstTrailingSpaceAtRun(BidiRun* run)
48009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
48109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(run);
48209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RenderObject* lastObject = run->m_object;
48309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!lastObject->isText())
48409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return run->m_stop;
48509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
48609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    RenderText* lastText = toRenderText(lastObject);
48709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    int firstSpace;
48809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (lastText->is8Bit())
48909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), run->start(), run->stop());
49009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    else
49109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(), run->start(), run->stop());
49209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return firstSpace;
49309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
49409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
49509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template <>
496c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline BidiRun* InlineBidiResolver::addTrailingRun(BidiRunList<BidiRun>& runs, int start, int stop, BidiRun* run, BidiContext* context, TextDirection direction) const
49709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
49809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    BidiRun* newTrailingRun = new BidiRun(start, stop, run->m_object, context, WTF::Unicode::OtherNeutral);
49909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (direction == LTR)
500c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        runs.addRun(newTrailingRun);
50109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    else
502c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        runs.prependRun(newTrailingRun);
50309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
50409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return newTrailingRun;
50509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
50609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
50709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)template <>
508c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline bool InlineBidiResolver::needsToApplyL1Rule(BidiRunList<BidiRun>& runs)
50909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
510c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (!runs.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace()
511c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        || !runs.logicallyLastRun()->m_object->style()->autoWrap())
51209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return false;
51309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return true;
51409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
51509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool isIsolatedInline(RenderObject* object)
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(object);
5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return object->isRenderInline() && isIsolated(object->style()->unicodeBidi());
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5228abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)static inline RenderObject* highestContainingIsolateWithinRoot(RenderObject* object, RenderObject* root)
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(object);
525e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    RenderObject* containingIsolateObj = 0;
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (object && object != root) {
5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isIsolatedInline(object))
528e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            containingIsolateObj = object;
529e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        object = object->parent();
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
532e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    return containingIsolateObj;
5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline unsigned numberOfIsolateAncestors(const InlineIterator& iter)
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RenderObject* object = iter.object();
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!object)
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned count = 0;
5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    while (object && object != iter.root()) {
5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (isIsolatedInline(object))
5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            count++;
5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        object = object->parent();
5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return count;
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// FIXME: This belongs on InlineBidiResolver, except it's a template specialization
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// of BidiResolver which knows nothing about RenderObjects.
55151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline BidiRun* addPlaceholderRunForIsolatedInline(InlineBidiResolver& resolver, RenderObject* obj, unsigned pos)
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(obj);
554f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    BidiRun* isolatedRun = new BidiRun(pos, pos, obj, resolver.context(), resolver.dir());
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    resolver.runs().addRun(isolatedRun);
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: isolatedRuns() could be a hash of object->run and then we could cheaply
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // ASSERT here that we didn't create multiple objects for the same inline.
5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    resolver.isolatedRuns().append(isolatedRun);
55951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    return isolatedRun;
560f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
561f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
562f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)static inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
563f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles){
564f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    return new BidiRun(start, end, obj, resolver.context(), resolver.dir());
565f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)}
566f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
567f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)enum AppendRunBehavior {
568f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    AppendingFakeRun,
569f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    AppendingRunsForObject
570f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)};
571f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class IsolateTracker {
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
574c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    explicit IsolateTracker(BidiRunList<BidiRun>& runs, unsigned nestedIsolateCount)
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_nestedIsolateCount(nestedIsolateCount)
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_haveAddedFakeRunForRootIsolate(false)
577c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        , m_runs(runs)
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
5795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
58151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    void setMidpointStateForRootIsolate(const LineMidpointState& midpointState)
58251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    {
58351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_midpointStateForRootIsolate = midpointState;
58451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
58551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void enterIsolate() { m_nestedIsolateCount++; }
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void exitIsolate()
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
5895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(m_nestedIsolateCount >= 1);
5905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_nestedIsolateCount--;
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!inIsolate())
5925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            m_haveAddedFakeRunForRootIsolate = false;
5935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool inIsolate() const { return m_nestedIsolateCount; }
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We don't care if we encounter bidi directional overrides.
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { }
598c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    void commitExplicitEmbedding(BidiRunList<BidiRun>&) { }
599c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    BidiRunList<BidiRun>& runs() { return m_runs; }
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
601f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, unsigned end, InlineBidiResolver& resolver)
6025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
6035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine.
6045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We'll be called for every span inside the isolated span so we just ignore subsequent calls.
6055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We also avoid creating a fake run until we hit a child that warrants one, e.g. we skip floats.
60619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)        if (RenderBlockFlow::shouldSkipCreatingRunsForObject(obj))
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
608f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        if (!m_haveAddedFakeRunForRootIsolate) {
60951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            BidiRun* run = addPlaceholderRunForIsolatedInline(resolver, obj, pos);
61051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            resolver.setMidpointStateForIsolatedRun(run, m_midpointStateForRootIsolate);
611f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            m_haveAddedFakeRunForRootIsolate = true;
612f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        }
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // obj and pos together denote a single position in the inline, from which the parsing of the isolate will start.
6145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // We don't need to mark the end of the run because this is implicit: it is either endOfLine or the end of the
6155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // isolate, when we call createBidiRunsForLine it will stop at whichever comes first.
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned m_nestedIsolateCount;
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool m_haveAddedFakeRunForRootIsolate;
62151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    LineMidpointState m_midpointStateForRootIsolate;
622c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    BidiRunList<BidiRun>& m_runs;
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
6245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
62551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static void inline appendRunObjectIfNecessary(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, IsolateTracker& tracker)
62651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
62751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (behavior == AppendingFakeRun)
62851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        tracker.addFakeRunIfNecessary(obj, start, end, resolver);
62951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    else
63051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        resolver.runs().addRun(createRun(start, end, obj, resolver));
63151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
63251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
63351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, IsolateTracker& tracker)
63451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
63551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj))
63651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        return;
63751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
63851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    LineMidpointState& lineMidpointState = resolver.midpointState();
63909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointState.numMidpoints());
64051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    InlineIterator nextMidpoint;
64151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (haveNextMidpoint)
64209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMidpoint()];
64309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (lineMidpointState.betweenMidpoints()) {
64451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (!(haveNextMidpoint && nextMidpoint.object() == obj))
64551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return;
64651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // This is a new start point. Stop ignoring objects and
64751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // adjust our start.
64809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        lineMidpointState.setBetweenMidpoints(false);
64909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        start = nextMidpoint.offset();
65009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        lineMidpointState.incrementCurrentMidpoint();
65151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (start < end)
65251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, resolver, behavior, tracker);
65351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    } else {
65451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (!haveNextMidpoint || (obj != nextMidpoint.object())) {
65551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            appendRunObjectIfNecessary(obj, start, end, resolver, behavior, tracker);
65651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return;
65751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
65851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
65951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // An end midpoint has been encountered within our object. We
66051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        // need to go ahead and append a run with our endpoint.
66109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (nextMidpoint.offset() + 1 <= end) {
66209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            lineMidpointState.setBetweenMidpoints(true);
66309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            lineMidpointState.incrementCurrentMidpoint();
66409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (nextMidpoint.offset() != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it.
66509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (nextMidpoint.offset() + 1 > start)
66609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    appendRunObjectIfNecessary(obj, start, nextMidpoint.offset() + 1, resolver, behavior, tracker);
66709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMidpoint.offset() + 1, end, resolver, behavior, tracker);
66851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
66951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        } else {
67051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            appendRunObjectIfNecessary(obj, start, end, resolver, behavior, tracker);
67151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        }
67251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    }
67351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
67451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
67551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static inline void addFakeRunIfNecessary(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, IsolateTracker& tracker)
67651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles){
67751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    tracker.setMidpointStateForRootIsolate(resolver.midpointState());
67851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->length(), resolver, AppendingFakeRun, tracker);
67951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)}
68051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
6815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <>
682c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)inline void InlineBidiResolver::appendRun(BidiRunList<BidiRun>& runs)
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
6845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) {
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Keep track of when we enter/leave "unicode-bidi: isolate" inlines.
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Initialize our state depending on if we're starting in the middle of such an inline.
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: Could this initialize from this->inIsolate() instead of walking up the render tree?
688c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        IsolateTracker isolateTracker(runs, numberOfIsolateAncestors(m_sor));
68909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        int start = m_sor.offset();
69051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        RenderObject* obj = m_sor.object();
69151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.object()) {
6925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isolateTracker.inIsolate())
69351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                addFakeRunIfNecessary(obj, start, obj->length(), *this, isolateTracker);
6945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
69551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->length(), *this, AppendingRunsForObject, isolateTracker);
6965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: start/obj should be an InlineIterator instead of two separate variables.
6975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            start = 0;
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracker);
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
70009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.offset();
70151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (obj && !isEndOfLine) {
70209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            unsigned pos = obj == m_eor.object() ? m_eor.offset() : INT_MAX;
70309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.offset() <= pos) {
7045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                m_reachedEndOfLine = true;
70509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                pos = m_endOfRunAtEndOfLine.offset();
7065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            int end = obj->length() ? pos + 1 : 0;
7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isolateTracker.inIsolate())
71051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                addFakeRunIfNecessary(obj, start, end, *this, isolateTracker);
7115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            else
71251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, *this, AppendingRunsForObject, isolateTracker);
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
71551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (isEndOfLine)
71651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            m_reachedEndOfLine = true;
71709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // If isolateTrack is inIsolate, the next |start of run| can not be the current isolated renderer.
71809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (isolateTracker.inIsolate())
71909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            m_eor.moveTo(bidiNextSkippingEmptyInlines(m_eor.root(), m_eor.object()), 0);
72009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        else
72109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            m_eor.increment();
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_sor = m_eor;
7235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
7245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_direction = WTF::Unicode::OtherNeutral;
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_status.eor = WTF::Unicode::OtherNeutral;
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // InlineIterator_h
732