Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: Source/core/layout/line/InlineIterator.h

Issue 899163003: Move rendering/RenderObject to layout/LayoutObject. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/layout/line/InlineFlowBox.cpp ('k') | Source/core/layout/line/InlineTextBox.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right r eserved. 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010 Apple Inc. All right r eserved.
4 * Copyright (C) 2010 Google Inc. All rights reserved. 4 * Copyright (C) 2010 Google Inc. All rights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 }; 42 };
43 43
44 InlineIterator() 44 InlineIterator()
45 : m_root(0) 45 : m_root(0)
46 , m_obj(0) 46 , m_obj(0)
47 , m_nextBreakablePosition(-1) 47 , m_nextBreakablePosition(-1)
48 , m_pos(0) 48 , m_pos(0)
49 { 49 {
50 } 50 }
51 51
52 InlineIterator(RenderObject* root, RenderObject* o, unsigned p) 52 InlineIterator(LayoutObject* root, LayoutObject* o, unsigned p)
53 : m_root(root) 53 : m_root(root)
54 , m_obj(o) 54 , m_obj(o)
55 , m_nextBreakablePosition(-1) 55 , m_nextBreakablePosition(-1)
56 , m_pos(p) 56 , m_pos(p)
57 { 57 {
58 } 58 }
59 59
60 void clear() { moveTo(0, 0); } 60 void clear() { moveTo(0, 0); }
61 61
62 void moveToStartOf(RenderObject* object) 62 void moveToStartOf(LayoutObject* object)
63 { 63 {
64 moveTo(object, 0); 64 moveTo(object, 0);
65 } 65 }
66 66
67 void moveTo(RenderObject* object, unsigned offset, int nextBreak = -1) 67 void moveTo(LayoutObject* object, unsigned offset, int nextBreak = -1)
68 { 68 {
69 m_obj = object; 69 m_obj = object;
70 m_pos = offset; 70 m_pos = offset;
71 m_nextBreakablePosition = nextBreak; 71 m_nextBreakablePosition = nextBreak;
72 } 72 }
73 73
74 RenderObject* object() const { return m_obj; } 74 LayoutObject* object() const { return m_obj; }
75 void setObject(RenderObject* object) { m_obj = object; } 75 void setObject(LayoutObject* object) { m_obj = object; }
76 76
77 int nextBreakablePosition() const { return m_nextBreakablePosition; } 77 int nextBreakablePosition() const { return m_nextBreakablePosition; }
78 void setNextBreakablePosition(int position) { m_nextBreakablePosition = posi tion; } 78 void setNextBreakablePosition(int position) { m_nextBreakablePosition = posi tion; }
79 79
80 unsigned offset() const { return m_pos; } 80 unsigned offset() const { return m_pos; }
81 void setOffset(unsigned position) { m_pos = position; } 81 void setOffset(unsigned position) { m_pos = position; }
82 RenderObject* root() const { return m_root; } 82 LayoutObject* root() const { return m_root; }
83 83
84 void fastIncrementInTextNode(); 84 void fastIncrementInTextNode();
85 void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextN ode); 85 void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextN ode);
86 bool atEnd() const; 86 bool atEnd() const;
87 87
88 inline bool atTextParagraphSeparator() const 88 inline bool atTextParagraphSeparator() const
89 { 89 {
90 return m_obj && m_obj->preservesNewline() && m_obj->isText() && toRender Text(m_obj)->textLength() 90 return m_obj && m_obj->preservesNewline() && m_obj->isText() && toRender Text(m_obj)->textLength()
91 && !toRenderText(m_obj)->isWordBreak() && toRenderText(m_obj)->chara cterAt(m_pos) == '\n'; 91 && !toRenderText(m_obj)->isWordBreak() && toRenderText(m_obj)->chara cterAt(m_pos) == '\n';
92 } 92 }
93 93
94 inline bool atParagraphSeparator() const 94 inline bool atParagraphSeparator() const
95 { 95 {
96 return (m_obj && m_obj->isBR()) || atTextParagraphSeparator(); 96 return (m_obj && m_obj->isBR()) || atTextParagraphSeparator();
97 } 97 }
98 98
99 UChar characterAt(unsigned) const; 99 UChar characterAt(unsigned) const;
100 UChar current() const; 100 UChar current() const;
101 UChar previousInSameNode() const; 101 UChar previousInSameNode() const;
102 ALWAYS_INLINE WTF::Unicode::Direction direction() const; 102 ALWAYS_INLINE WTF::Unicode::Direction direction() const;
103 103
104 private: 104 private:
105 RenderObject* m_root; 105 LayoutObject* m_root;
106 RenderObject* m_obj; 106 LayoutObject* m_obj;
107 107
108 int m_nextBreakablePosition; 108 int m_nextBreakablePosition;
109 unsigned m_pos; 109 unsigned m_pos;
110 }; 110 };
111 111
112 inline bool operator==(const InlineIterator& it1, const InlineIterator& it2) 112 inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
113 { 113 {
114 return it1.offset() == it2.offset() && it1.object() == it2.object(); 114 return it1.offset() == it2.offset() && it1.object() == it2.object();
115 } 115 }
116 116
117 inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2) 117 inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
118 { 118 {
119 return it1.offset() != it2.offset() || it1.object() != it2.object(); 119 return it1.offset() != it2.offset() || it1.object() != it2.object();
120 } 120 }
121 121
122 static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir, EUnicodeBidi unicodeBidi) 122 static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir, EUnicodeBidi unicodeBidi)
123 { 123 {
124 using namespace WTF::Unicode; 124 using namespace WTF::Unicode;
125 if (unicodeBidi == Embed) 125 if (unicodeBidi == Embed)
126 return dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding; 126 return dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding;
127 return dir == RTL ? RightToLeftOverride : LeftToRightOverride; 127 return dir == RTL ? RightToLeftOverride : LeftToRightOverride;
128 } 128 }
129 129
130 template <class Observer> 130 template <class Observer>
131 static inline void notifyObserverEnteredObject(Observer* observer, RenderObject* object) 131 static inline void notifyObserverEnteredObject(Observer* observer, LayoutObject* object)
132 { 132 {
133 if (!observer || !object || !object->isRenderInline()) 133 if (!observer || !object || !object->isRenderInline())
134 return; 134 return;
135 135
136 RenderStyle* style = object->style(); 136 RenderStyle* style = object->style();
137 EUnicodeBidi unicodeBidi = style->unicodeBidi(); 137 EUnicodeBidi unicodeBidi = style->unicodeBidi();
138 if (unicodeBidi == UBNormal) { 138 if (unicodeBidi == UBNormal) {
139 // http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi 139 // http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi
140 // "The element does not open an additional level of embedding with resp ect to the bidirectional algorithm." 140 // "The element does not open an additional level of embedding with resp ect to the bidirectional algorithm."
141 // Thus we ignore any possible dir= attribute on the span. 141 // Thus we ignore any possible dir= attribute on the span.
142 return; 142 return;
143 } 143 }
144 if (isIsolated(unicodeBidi)) { 144 if (isIsolated(unicodeBidi)) {
145 // Make sure that explicit embeddings are committed before we enter the isolated content. 145 // Make sure that explicit embeddings are committed before we enter the isolated content.
146 observer->commitExplicitEmbedding(observer->runs()); 146 observer->commitExplicitEmbedding(observer->runs());
147 observer->enterIsolate(); 147 observer->enterIsolate();
148 // Embedding/Override characters implied by dir= will be handled when 148 // Embedding/Override characters implied by dir= will be handled when
149 // we process the isolated span, not when laying out the "parent" run. 149 // we process the isolated span, not when laying out the "parent" run.
150 return; 150 return;
151 } 151 }
152 152
153 if (!observer->inIsolate()) 153 if (!observer->inIsolate())
154 observer->embed(embedCharFromDirection(style->direction(), unicodeBidi), FromStyleOrDOM); 154 observer->embed(embedCharFromDirection(style->direction(), unicodeBidi), FromStyleOrDOM);
155 } 155 }
156 156
157 template <class Observer> 157 template <class Observer>
158 static inline void notifyObserverWillExitObject(Observer* observer, RenderObject * object) 158 static inline void notifyObserverWillExitObject(Observer* observer, LayoutObject * object)
159 { 159 {
160 if (!observer || !object || !object->isRenderInline()) 160 if (!observer || !object || !object->isRenderInline())
161 return; 161 return;
162 162
163 EUnicodeBidi unicodeBidi = object->style()->unicodeBidi(); 163 EUnicodeBidi unicodeBidi = object->style()->unicodeBidi();
164 if (unicodeBidi == UBNormal) 164 if (unicodeBidi == UBNormal)
165 return; // Nothing to do for unicode-bidi: normal 165 return; // Nothing to do for unicode-bidi: normal
166 if (isIsolated(unicodeBidi)) { 166 if (isIsolated(unicodeBidi)) {
167 observer->exitIsolate(); 167 observer->exitIsolate();
168 return; 168 return;
169 } 169 }
170 170
171 // Otherwise we pop any embed/override character we added when we opened thi s tag. 171 // Otherwise we pop any embed/override character we added when we opened thi s tag.
172 if (!observer->inIsolate()) 172 if (!observer->inIsolate())
173 observer->embed(WTF::Unicode::PopDirectionalFormat, FromStyleOrDOM); 173 observer->embed(WTF::Unicode::PopDirectionalFormat, FromStyleOrDOM);
174 } 174 }
175 175
176 static inline bool isIteratorTarget(RenderObject* object) 176 static inline bool isIteratorTarget(LayoutObject* object)
177 { 177 {
178 ASSERT(object); // The iterator will of course return 0, but its not an expe cted argument to this function. 178 ASSERT(object); // The iterator will of course return 0, but its not an expe cted argument to this function.
179 return object->isText() || object->isFloating() || object->isOutOfFlowPositi oned() || object->isReplaced(); 179 return object->isText() || object->isFloating() || object->isOutOfFlowPositi oned() || object->isReplaced();
180 } 180 }
181 181
182 // This enum is only used for bidiNextShared() 182 // This enum is only used for bidiNextShared()
183 enum EmptyInlineBehavior { 183 enum EmptyInlineBehavior {
184 SkipEmptyInlines, 184 SkipEmptyInlines,
185 IncludeEmptyInlines, 185 IncludeEmptyInlines,
186 }; 186 };
187 187
188 static bool isEmptyInline(RenderObject* object) 188 static bool isEmptyInline(LayoutObject* object)
189 { 189 {
190 if (!object->isRenderInline()) 190 if (!object->isRenderInline())
191 return false; 191 return false;
192 192
193 for (RenderObject* curr = toRenderInline(object)->firstChild(); curr; curr = curr->nextSibling()) { 193 for (LayoutObject* curr = toRenderInline(object)->firstChild(); curr; curr = curr->nextSibling()) {
194 if (curr->isFloatingOrOutOfFlowPositioned()) 194 if (curr->isFloatingOrOutOfFlowPositioned())
195 continue; 195 continue;
196 if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace()) 196 if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace())
197 continue; 197 continue;
198 198
199 if (!isEmptyInline(curr)) 199 if (!isEmptyInline(curr))
200 return false; 200 return false;
201 } 201 }
202 return true; 202 return true;
203 } 203 }
204 204
205 // FIXME: This function is misleadingly named. It has little to do with bidi. 205 // FIXME: This function is misleadingly named. It has little to do with bidi.
206 // This function will iterate over inlines within a block, optionally notifying 206 // This function will iterate over inlines within a block, optionally notifying
207 // a bidi resolver as it enters/exits inlines (so it can push/pop embedding leve ls). 207 // a bidi resolver as it enters/exits inlines (so it can push/pop embedding leve ls).
208 template <class Observer> 208 template <class Observer>
209 static inline RenderObject* bidiNextShared(RenderObject* root, RenderObject* cur rent, Observer* observer = 0, EmptyInlineBehavior emptyInlineBehavior = SkipEmpt yInlines, bool* endOfInlinePtr = 0) 209 static inline LayoutObject* bidiNextShared(LayoutObject* root, LayoutObject* cur rent, Observer* observer = 0, EmptyInlineBehavior emptyInlineBehavior = SkipEmpt yInlines, bool* endOfInlinePtr = 0)
210 { 210 {
211 RenderObject* next = 0; 211 LayoutObject* next = 0;
212 // oldEndOfInline denotes if when we last stopped iterating if we were at th e end of an inline. 212 // oldEndOfInline denotes if when we last stopped iterating if we were at th e end of an inline.
213 bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false; 213 bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
214 bool endOfInline = false; 214 bool endOfInline = false;
215 215
216 while (current) { 216 while (current) {
217 next = 0; 217 next = 0;
218 if (!oldEndOfInline && !isIteratorTarget(current)) { 218 if (!oldEndOfInline && !isIteratorTarget(current)) {
219 next = current->slowFirstChild(); 219 next = current->slowFirstChild();
220 notifyObserverEnteredObject(observer, next); 220 notifyObserverEnteredObject(observer, next);
221 } 221 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 current = next; 257 current = next;
258 } 258 }
259 259
260 if (endOfInlinePtr) 260 if (endOfInlinePtr)
261 *endOfInlinePtr = endOfInline; 261 *endOfInlinePtr = endOfInline;
262 262
263 return next; 263 return next;
264 } 264 }
265 265
266 template <class Observer> 266 template <class Observer>
267 static inline RenderObject* bidiNextSkippingEmptyInlines(RenderObject* root, Ren derObject* current, Observer* observer) 267 static inline LayoutObject* bidiNextSkippingEmptyInlines(LayoutObject* root, Lay outObject* current, Observer* observer)
268 { 268 {
269 // The SkipEmptyInlines callers never care about endOfInlinePtr. 269 // The SkipEmptyInlines callers never care about endOfInlinePtr.
270 return bidiNextShared(root, current, observer, SkipEmptyInlines); 270 return bidiNextShared(root, current, observer, SkipEmptyInlines);
271 } 271 }
272 272
273 // This makes callers cleaner as they don't have to specify a type for the obser ver when not providing one. 273 // This makes callers cleaner as they don't have to specify a type for the obser ver when not providing one.
274 static inline RenderObject* bidiNextSkippingEmptyInlines(RenderObject* root, Ren derObject* current) 274 static inline LayoutObject* bidiNextSkippingEmptyInlines(LayoutObject* root, Lay outObject* current)
275 { 275 {
276 InlineBidiResolver* observer = 0; 276 InlineBidiResolver* observer = 0;
277 return bidiNextSkippingEmptyInlines(root, current, observer); 277 return bidiNextSkippingEmptyInlines(root, current, observer);
278 } 278 }
279 279
280 static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re nderObject* current, bool* endOfInlinePtr = 0) 280 static inline LayoutObject* bidiNextIncludingEmptyInlines(LayoutObject* root, La youtObject* current, bool* endOfInlinePtr = 0)
281 { 281 {
282 InlineBidiResolver* observer = 0; // Callers who include empty inlines, neve r use an observer. 282 InlineBidiResolver* observer = 0; // Callers who include empty inlines, neve r use an observer.
283 return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInl inePtr); 283 return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInl inePtr);
284 } 284 }
285 285
286 static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root, BidiRunList<BidiRun>& runs, InlineBidiResolver* resolver = 0) 286 static inline LayoutObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root, BidiRunList<BidiRun>& runs, InlineBidiResolver* resolver = 0)
287 { 287 {
288 RenderObject* o = root->firstChild(); 288 LayoutObject* o = root->firstChild();
289 if (!o) 289 if (!o)
290 return 0; 290 return 0;
291 291
292 if (o->isRenderInline()) { 292 if (o->isRenderInline()) {
293 notifyObserverEnteredObject(resolver, o); 293 notifyObserverEnteredObject(resolver, o);
294 if (!isEmptyInline(o)) { 294 if (!isEmptyInline(o)) {
295 o = bidiNextSkippingEmptyInlines(root, o, resolver); 295 o = bidiNextSkippingEmptyInlines(root, o, resolver);
296 } else { 296 } else {
297 // Never skip empty inlines. 297 // Never skip empty inlines.
298 if (resolver) 298 if (resolver)
299 resolver->commitExplicitEmbedding(runs); 299 resolver->commitExplicitEmbedding(runs);
300 return o; 300 return o;
301 } 301 }
302 } 302 }
303 303
304 // FIXME: Unify this with the bidiNext call above. 304 // FIXME: Unify this with the bidiNext call above.
305 if (o && !isIteratorTarget(o)) 305 if (o && !isIteratorTarget(o))
306 o = bidiNextSkippingEmptyInlines(root, o, resolver); 306 o = bidiNextSkippingEmptyInlines(root, o, resolver);
307 307
308 if (resolver) 308 if (resolver)
309 resolver->commitExplicitEmbedding(runs); 309 resolver->commitExplicitEmbedding(runs);
310 return o; 310 return o;
311 } 311 }
312 312
313 // FIXME: This method needs to be renamed when bidiNext finds a good name. 313 // FIXME: This method needs to be renamed when bidiNext finds a good name.
314 static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderBlock* root) 314 static inline LayoutObject* bidiFirstIncludingEmptyInlines(RenderBlock* root)
315 { 315 {
316 RenderObject* o = root->firstChild(); 316 LayoutObject* o = root->firstChild();
317 // If either there are no children to walk, or the first one is correct 317 // If either there are no children to walk, or the first one is correct
318 // then just return it. 318 // then just return it.
319 if (!o || o->isRenderInline() || isIteratorTarget(o)) 319 if (!o || o->isRenderInline() || isIteratorTarget(o))
320 return o; 320 return o;
321 321
322 return bidiNextIncludingEmptyInlines(root, o); 322 return bidiNextIncludingEmptyInlines(root, o);
323 } 323 }
324 324
325 inline void InlineIterator::fastIncrementInTextNode() 325 inline void InlineIterator::fastIncrementInTextNode()
326 { 326 {
(...skipping 11 matching lines...) Expand all
338 InlineWalker(RenderBlock* root) 338 InlineWalker(RenderBlock* root)
339 : m_root(root) 339 : m_root(root)
340 , m_current(0) 340 , m_current(0)
341 , m_atEndOfInline(false) 341 , m_atEndOfInline(false)
342 { 342 {
343 // FIXME: This class should be taught how to do the SkipEmptyInlines cod epath as well. 343 // FIXME: This class should be taught how to do the SkipEmptyInlines cod epath as well.
344 m_current = bidiFirstIncludingEmptyInlines(m_root); 344 m_current = bidiFirstIncludingEmptyInlines(m_root);
345 } 345 }
346 346
347 RenderBlock* root() { return m_root; } 347 RenderBlock* root() { return m_root; }
348 RenderObject* current() { return m_current; } 348 LayoutObject* current() { return m_current; }
349 349
350 bool atEndOfInline() { return m_atEndOfInline; } 350 bool atEndOfInline() { return m_atEndOfInline; }
351 bool atEnd() const { return !m_current; } 351 bool atEnd() const { return !m_current; }
352 352
353 RenderObject* advance() 353 LayoutObject* advance()
354 { 354 {
355 // FIXME: Support SkipEmptyInlines and observer parameters. 355 // FIXME: Support SkipEmptyInlines and observer parameters.
356 m_current = bidiNextIncludingEmptyInlines(m_root, m_current, &m_atEndOfI nline); 356 m_current = bidiNextIncludingEmptyInlines(m_root, m_current, &m_atEndOfI nline);
357 return m_current; 357 return m_current;
358 } 358 }
359 private: 359 private:
360 RenderBlock* m_root; 360 RenderBlock* m_root;
361 RenderObject* m_current; 361 LayoutObject* m_current;
362 bool m_atEndOfInline; 362 bool m_atEndOfInline;
363 }; 363 };
364 364
365 static inline bool endOfLineHasIsolatedObjectAncestor(const InlineIterator& isol atedIterator, const InlineIterator& ancestorItertor) 365 static inline bool endOfLineHasIsolatedObjectAncestor(const InlineIterator& isol atedIterator, const InlineIterator& ancestorItertor)
366 { 366 {
367 if (!isolatedIterator.object() || !isIsolated(isolatedIterator.object()->sty le()->unicodeBidi())) 367 if (!isolatedIterator.object() || !isIsolated(isolatedIterator.object()->sty le()->unicodeBidi()))
368 return false; 368 return false;
369 369
370 RenderObject* innerIsolatedObject = isolatedIterator.object(); 370 LayoutObject* innerIsolatedObject = isolatedIterator.object();
371 while (innerIsolatedObject && innerIsolatedObject != isolatedIterator.root() ) { 371 while (innerIsolatedObject && innerIsolatedObject != isolatedIterator.root() ) {
372 if (innerIsolatedObject == ancestorItertor.object()) 372 if (innerIsolatedObject == ancestorItertor.object())
373 return true; 373 return true;
374 innerIsolatedObject = innerIsolatedObject->parent(); 374 innerIsolatedObject = innerIsolatedObject->parent();
375 } 375 }
376 return false; 376 return false;
377 } 377 }
378 378
379 inline void InlineIterator::increment(InlineBidiResolver* resolver, IncrementRul e rule) 379 inline void InlineIterator::increment(InlineBidiResolver* resolver, IncrementRul e rule)
380 { 380 {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 firstSpace--; 472 firstSpace--;
473 } 473 }
474 474
475 return firstSpace; 475 return firstSpace;
476 } 476 }
477 477
478 template <> 478 template <>
479 inline int InlineBidiResolver::findFirstTrailingSpaceAtRun(BidiRun* run) 479 inline int InlineBidiResolver::findFirstTrailingSpaceAtRun(BidiRun* run)
480 { 480 {
481 ASSERT(run); 481 ASSERT(run);
482 RenderObject* lastObject = run->m_object; 482 LayoutObject* lastObject = run->m_object;
483 if (!lastObject->isText()) 483 if (!lastObject->isText())
484 return run->m_stop; 484 return run->m_stop;
485 485
486 RenderText* lastText = toRenderText(lastObject); 486 RenderText* lastText = toRenderText(lastObject);
487 int firstSpace; 487 int firstSpace;
488 if (lastText->is8Bit()) 488 if (lastText->is8Bit())
489 firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), r un->start(), run->stop()); 489 firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), r un->start(), run->stop());
490 else 490 else
491 firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(), run->start(), run->stop()); 491 firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(), run->start(), run->stop());
492 return firstSpace; 492 return firstSpace;
(...skipping 13 matching lines...) Expand all
506 506
507 template <> 507 template <>
508 inline bool InlineBidiResolver::needsToApplyL1Rule(BidiRunList<BidiRun>& runs) 508 inline bool InlineBidiResolver::needsToApplyL1Rule(BidiRunList<BidiRun>& runs)
509 { 509 {
510 if (!runs.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace() 510 if (!runs.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace()
511 || !runs.logicallyLastRun()->m_object->style()->autoWrap()) 511 || !runs.logicallyLastRun()->m_object->style()->autoWrap())
512 return false; 512 return false;
513 return true; 513 return true;
514 } 514 }
515 515
516 static inline bool isIsolatedInline(RenderObject* object) 516 static inline bool isIsolatedInline(LayoutObject* object)
517 { 517 {
518 ASSERT(object); 518 ASSERT(object);
519 return object->isRenderInline() && isIsolated(object->style()->unicodeBidi() ); 519 return object->isRenderInline() && isIsolated(object->style()->unicodeBidi() );
520 } 520 }
521 521
522 static inline RenderObject* highestContainingIsolateWithinRoot(RenderObject* obj ect, RenderObject* root) 522 static inline LayoutObject* highestContainingIsolateWithinRoot(LayoutObject* obj ect, LayoutObject* root)
523 { 523 {
524 ASSERT(object); 524 ASSERT(object);
525 RenderObject* containingIsolateObj = 0; 525 LayoutObject* containingIsolateObj = 0;
526 while (object && object != root) { 526 while (object && object != root) {
527 if (isIsolatedInline(object)) 527 if (isIsolatedInline(object))
528 containingIsolateObj = object; 528 containingIsolateObj = object;
529 529
530 object = object->parent(); 530 object = object->parent();
531 } 531 }
532 return containingIsolateObj; 532 return containingIsolateObj;
533 } 533 }
534 534
535 static inline unsigned numberOfIsolateAncestors(const InlineIterator& iter) 535 static inline unsigned numberOfIsolateAncestors(const InlineIterator& iter)
536 { 536 {
537 RenderObject* object = iter.object(); 537 LayoutObject* object = iter.object();
538 if (!object) 538 if (!object)
539 return 0; 539 return 0;
540 unsigned count = 0; 540 unsigned count = 0;
541 while (object && object != iter.root()) { 541 while (object && object != iter.root()) {
542 if (isIsolatedInline(object)) 542 if (isIsolatedInline(object))
543 count++; 543 count++;
544 object = object->parent(); 544 object = object->parent();
545 } 545 }
546 return count; 546 return count;
547 } 547 }
548 548
549 // FIXME: This belongs on InlineBidiResolver, except it's a template specializat ion 549 // FIXME: This belongs on InlineBidiResolver, except it's a template specializat ion
550 // of BidiResolver which knows nothing about RenderObjects. 550 // of BidiResolver which knows nothing about LayoutObjects.
551 static inline BidiRun* addPlaceholderRunForIsolatedInline(InlineBidiResolver& re solver, RenderObject* obj, unsigned pos) 551 static inline BidiRun* addPlaceholderRunForIsolatedInline(InlineBidiResolver& re solver, LayoutObject* obj, unsigned pos)
552 { 552 {
553 ASSERT(obj); 553 ASSERT(obj);
554 BidiRun* isolatedRun = new BidiRun(pos, pos, obj, resolver.context(), resolv er.dir()); 554 BidiRun* isolatedRun = new BidiRun(pos, pos, obj, resolver.context(), resolv er.dir());
555 resolver.runs().addRun(isolatedRun); 555 resolver.runs().addRun(isolatedRun);
556 // FIXME: isolatedRuns() could be a hash of object->run and then we could ch eaply 556 // FIXME: isolatedRuns() could be a hash of object->run and then we could ch eaply
557 // ASSERT here that we didn't create multiple objects for the same inline. 557 // ASSERT here that we didn't create multiple objects for the same inline.
558 resolver.isolatedRuns().append(isolatedRun); 558 resolver.isolatedRuns().append(isolatedRun);
559 return isolatedRun; 559 return isolatedRun;
560 } 560 }
561 561
562 static inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBi diResolver& resolver) 562 static inline BidiRun* createRun(int start, int end, LayoutObject* obj, InlineBi diResolver& resolver)
563 { 563 {
564 return new BidiRun(start, end, obj, resolver.context(), resolver.dir()); 564 return new BidiRun(start, end, obj, resolver.context(), resolver.dir());
565 } 565 }
566 566
567 enum AppendRunBehavior { 567 enum AppendRunBehavior {
568 AppendingFakeRun, 568 AppendingFakeRun,
569 AppendingRunsForObject 569 AppendingRunsForObject
570 }; 570 };
571 571
572 class IsolateTracker { 572 class IsolateTracker {
(...skipping 18 matching lines...) Expand all
591 if (!inIsolate()) 591 if (!inIsolate())
592 m_haveAddedFakeRunForRootIsolate = false; 592 m_haveAddedFakeRunForRootIsolate = false;
593 } 593 }
594 bool inIsolate() const { return m_nestedIsolateCount; } 594 bool inIsolate() const { return m_nestedIsolateCount; }
595 595
596 // We don't care if we encounter bidi directional overrides. 596 // We don't care if we encounter bidi directional overrides.
597 void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { } 597 void embed(WTF::Unicode::Direction, BidiEmbeddingSource) { }
598 void commitExplicitEmbedding(BidiRunList<BidiRun>&) { } 598 void commitExplicitEmbedding(BidiRunList<BidiRun>&) { }
599 BidiRunList<BidiRun>& runs() { return m_runs; } 599 BidiRunList<BidiRun>& runs() { return m_runs; }
600 600
601 void addFakeRunIfNecessary(RenderObject* obj, unsigned pos, unsigned end, In lineBidiResolver& resolver) 601 void addFakeRunIfNecessary(LayoutObject* obj, unsigned pos, unsigned end, In lineBidiResolver& resolver)
602 { 602 {
603 // We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine. 603 // We only need to add a fake run for a given isolated span once during each call to createBidiRunsForLine.
604 // We'll be called for every span inside the isolated span so we just ig nore subsequent calls. 604 // We'll be called for every span inside the isolated span so we just ig nore subsequent calls.
605 // We also avoid creating a fake run until we hit a child that warrants one, e.g. we skip floats. 605 // We also avoid creating a fake run until we hit a child that warrants one, e.g. we skip floats.
606 if (RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) 606 if (RenderBlockFlow::shouldSkipCreatingRunsForObject(obj))
607 return; 607 return;
608 if (!m_haveAddedFakeRunForRootIsolate) { 608 if (!m_haveAddedFakeRunForRootIsolate) {
609 BidiRun* run = addPlaceholderRunForIsolatedInline(resolver, obj, pos ); 609 BidiRun* run = addPlaceholderRunForIsolatedInline(resolver, obj, pos );
610 resolver.setMidpointStateForIsolatedRun(run, m_midpointStateForRootI solate); 610 resolver.setMidpointStateForIsolatedRun(run, m_midpointStateForRootI solate);
611 m_haveAddedFakeRunForRootIsolate = true; 611 m_haveAddedFakeRunForRootIsolate = true;
612 } 612 }
613 // obj and pos together denote a single position in the inline, from whi ch the parsing of the isolate will start. 613 // obj and pos together denote a single position in the inline, from whi ch the parsing of the isolate will start.
614 // We don't need to mark the end of the run because this is implicit: it is either endOfLine or the end of the 614 // We don't need to mark the end of the run because this is implicit: it is either endOfLine or the end of the
615 // isolate, when we call createBidiRunsForLine it will stop at whichever comes first. 615 // isolate, when we call createBidiRunsForLine it will stop at whichever comes first.
616 } 616 }
617 617
618 private: 618 private:
619 unsigned m_nestedIsolateCount; 619 unsigned m_nestedIsolateCount;
620 bool m_haveAddedFakeRunForRootIsolate; 620 bool m_haveAddedFakeRunForRootIsolate;
621 LineMidpointState m_midpointStateForRootIsolate; 621 LineMidpointState m_midpointStateForRootIsolate;
622 BidiRunList<BidiRun>& m_runs; 622 BidiRunList<BidiRun>& m_runs;
623 }; 623 };
624 624
625 static void inline appendRunObjectIfNecessary(RenderObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, Isolate Tracker& tracker) 625 static void inline appendRunObjectIfNecessary(LayoutObject* obj, unsigned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behavior, Isolate Tracker& tracker)
626 { 626 {
627 // Trailing space code creates empty BidiRun objects, start == end, so 627 // Trailing space code creates empty BidiRun objects, start == end, so
628 // that case needs to be handled specifically. 628 // that case needs to be handled specifically.
629 bool addEmptyRun = (end == start); 629 bool addEmptyRun = (end == start);
630 630
631 // Append BidiRun objects, at most 64K chars at a time, until all 631 // Append BidiRun objects, at most 64K chars at a time, until all
632 // text between |start| and |end| is represented. 632 // text between |start| and |end| is represented.
633 while (end > start || addEmptyRun) { 633 while (end > start || addEmptyRun) {
634 addEmptyRun = false; 634 addEmptyRun = false;
635 const int limit = USHRT_MAX; // InlineTextBox stores text length as unsi gned short. 635 const int limit = USHRT_MAX; // InlineTextBox stores text length as unsi gned short.
636 unsigned limitedEnd = end; 636 unsigned limitedEnd = end;
637 if (end - start > limit) 637 if (end - start > limit)
638 limitedEnd = start + limit; 638 limitedEnd = start + limit;
639 if (behavior == AppendingFakeRun) 639 if (behavior == AppendingFakeRun)
640 tracker.addFakeRunIfNecessary(obj, start, limitedEnd, resolver); 640 tracker.addFakeRunIfNecessary(obj, start, limitedEnd, resolver);
641 else 641 else
642 resolver.runs().addRun(createRun(start, limitedEnd, obj, resolver)); 642 resolver.runs().addRun(createRun(start, limitedEnd, obj, resolver));
643 start = limitedEnd; 643 start = limitedEnd;
644 } 644 }
645 } 645 }
646 646
647 static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns igned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behav ior, IsolateTracker& tracker) 647 static void adjustMidpointsAndAppendRunsForObjectIfNeeded(LayoutObject* obj, uns igned start, unsigned end, InlineBidiResolver& resolver, AppendRunBehavior behav ior, IsolateTracker& tracker)
648 { 648 {
649 if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) 649 if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj))
650 return; 650 return;
651 651
652 LineMidpointState& lineMidpointState = resolver.midpointState(); 652 LineMidpointState& lineMidpointState = resolver.midpointState();
653 bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointS tate.numMidpoints()); 653 bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointS tate.numMidpoints());
654 InlineIterator nextMidpoint; 654 InlineIterator nextMidpoint;
655 if (haveNextMidpoint) 655 if (haveNextMidpoint)
656 nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMi dpoint()]; 656 nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMi dpoint()];
657 if (lineMidpointState.betweenMidpoints()) { 657 if (lineMidpointState.betweenMidpoints()) {
(...skipping 21 matching lines...) Expand all
679 if (nextMidpoint.offset() + 1 > start) 679 if (nextMidpoint.offset() + 1 > start)
680 appendRunObjectIfNecessary(obj, start, nextMidpoint.offset() + 1, resolver, behavior, tracker); 680 appendRunObjectIfNecessary(obj, start, nextMidpoint.offset() + 1, resolver, behavior, tracker);
681 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMi dpoint.offset() + 1, end, resolver, behavior, tracker); 681 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMi dpoint.offset() + 1, end, resolver, behavior, tracker);
682 } 682 }
683 } else { 683 } else {
684 appendRunObjectIfNecessary(obj, start, end, resolver, behavior, trac ker); 684 appendRunObjectIfNecessary(obj, start, end, resolver, behavior, trac ker);
685 } 685 }
686 } 686 }
687 } 687 }
688 688
689 static inline void addFakeRunIfNecessary(RenderObject* obj, unsigned start, unsi gned end, InlineBidiResolver& resolver, IsolateTracker& tracker) 689 static inline void addFakeRunIfNecessary(LayoutObject* obj, unsigned start, unsi gned end, InlineBidiResolver& resolver, IsolateTracker& tracker)
690 { 690 {
691 tracker.setMidpointStateForRootIsolate(resolver.midpointState()); 691 tracker.setMidpointStateForRootIsolate(resolver.midpointState());
692 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->length(), res olver, AppendingFakeRun, tracker); 692 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->length(), res olver, AppendingFakeRun, tracker);
693 } 693 }
694 694
695 template <> 695 template <>
696 inline void InlineBidiResolver::appendRun(BidiRunList<BidiRun>& runs) 696 inline void InlineBidiResolver::appendRun(BidiRunList<BidiRun>& runs)
697 { 697 {
698 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { 698 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) {
699 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. 699 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines.
700 // Initialize our state depending on if we're starting in the middle of such an inline. 700 // Initialize our state depending on if we're starting in the middle of such an inline.
701 // FIXME: Could this initialize from this->inIsolate() instead of walkin g up the render tree? 701 // FIXME: Could this initialize from this->inIsolate() instead of walkin g up the render tree?
702 IsolateTracker isolateTracker(runs, numberOfIsolateAncestors(m_sor)); 702 IsolateTracker isolateTracker(runs, numberOfIsolateAncestors(m_sor));
703 int start = m_sor.offset(); 703 int start = m_sor.offset();
704 RenderObject* obj = m_sor.object(); 704 LayoutObject* obj = m_sor.object();
705 while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.obje ct()) { 705 while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.obje ct()) {
706 if (isolateTracker.inIsolate()) 706 if (isolateTracker.inIsolate())
707 addFakeRunIfNecessary(obj, start, obj->length(), *this, isolateT racker); 707 addFakeRunIfNecessary(obj, start, obj->length(), *this, isolateT racker);
708 else 708 else
709 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->l ength(), *this, AppendingRunsForObject, isolateTracker); 709 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->l ength(), *this, AppendingRunsForObject, isolateTracker);
710 // FIXME: start/obj should be an InlineIterator instead of two separ ate variables. 710 // FIXME: start/obj should be an InlineIterator instead of two separ ate variables.
711 start = 0; 711 start = 0;
712 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke r); 712 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke r);
713 } 713 }
714 bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.offset(); 714 bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.offset();
715 if (obj && !isEndOfLine) { 715 if (obj && !isEndOfLine) {
716 unsigned pos = obj == m_eor.object() ? m_eor.offset() : INT_MAX; 716 unsigned pos = obj == m_eor.object() ? m_eor.offset() : INT_MAX;
717 if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.o ffset() <= pos) { 717 if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.o ffset() <= pos) {
718 m_reachedEndOfLine = true; 718 m_reachedEndOfLine = true;
719 pos = m_endOfRunAtEndOfLine.offset(); 719 pos = m_endOfRunAtEndOfLine.offset();
720 } 720 }
721 // It's OK to add runs for zero-length RenderObjects, just don't mak e the run larger than it should be 721 // It's OK to add runs for zero-length LayoutObjects, just don't mak e the run larger than it should be
722 int end = obj->length() ? pos + 1 : 0; 722 int end = obj->length() ? pos + 1 : 0;
723 if (isolateTracker.inIsolate()) 723 if (isolateTracker.inIsolate())
724 addFakeRunIfNecessary(obj, start, end, *this, isolateTracker); 724 addFakeRunIfNecessary(obj, start, end, *this, isolateTracker);
725 else 725 else
726 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, * this, AppendingRunsForObject, isolateTracker); 726 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, * this, AppendingRunsForObject, isolateTracker);
727 } 727 }
728 728
729 if (isEndOfLine) 729 if (isEndOfLine)
730 m_reachedEndOfLine = true; 730 m_reachedEndOfLine = true;
731 // If isolateTrack is inIsolate, the next |start of run| can not be the current isolated renderer. 731 // If isolateTrack is inIsolate, the next |start of run| can not be the current isolated renderer.
732 if (isolateTracker.inIsolate()) 732 if (isolateTracker.inIsolate())
733 m_eor.moveTo(bidiNextSkippingEmptyInlines(m_eor.root(), m_eor.object ()), 0); 733 m_eor.moveTo(bidiNextSkippingEmptyInlines(m_eor.root(), m_eor.object ()), 0);
734 else 734 else
735 m_eor.increment(); 735 m_eor.increment();
736 m_sor = m_eor; 736 m_sor = m_eor;
737 } 737 }
738 738
739 m_direction = WTF::Unicode::OtherNeutral; 739 m_direction = WTF::Unicode::OtherNeutral;
740 m_status.eor = WTF::Unicode::OtherNeutral; 740 m_status.eor = WTF::Unicode::OtherNeutral;
741 } 741 }
742 742
743 } 743 }
744 744
745 #endif // InlineIterator_h 745 #endif // InlineIterator_h
OLDNEW
« no previous file with comments | « Source/core/layout/line/InlineFlowBox.cpp ('k') | Source/core/layout/line/InlineTextBox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698