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