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

Side by Side Diff: Source/core/rendering/InlineIterator.h

Issue 295513003: add 'slow' prefix to RenderObject's firstChild() / lastChild() methods (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 7 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/rendering/InlineFlowBox.cpp ('k') | Source/core/rendering/RenderBlock.cpp » ('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 *
11 * This library is distributed in the hope that it will be useful, 11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details. 14 * Library General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Library General Public License 16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to 17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA. 19 * Boston, MA 02110-1301, USA.
20 * 20 *
21 */ 21 */
22 22
23 #ifndef InlineIterator_h 23 #ifndef InlineIterator_h
24 #define InlineIterator_h 24 #define InlineIterator_h
25 25
26 #include "core/rendering/BidiRun.h" 26 #include "core/rendering/BidiRun.h"
27 #include "core/rendering/RenderBlockFlow.h" 27 #include "core/rendering/RenderBlockFlow.h"
28 #include "core/rendering/RenderInline.h"
28 #include "core/rendering/RenderText.h" 29 #include "core/rendering/RenderText.h"
29 #include "wtf/StdLibExtras.h" 30 #include "wtf/StdLibExtras.h"
30 31
31 namespace WebCore { 32 namespace WebCore {
32 33
33 // This class is used to RenderInline subtrees, stepping by character within the 34 // This class is used to RenderInline subtrees, stepping by character within the
34 // text children. InlineIterator will use bidiNext to find the next RenderText 35 // text children. InlineIterator will use bidiNext to find the next RenderText
35 // optionally notifying a BidiResolver every time it steps into/out of a RenderI nline. 36 // optionally notifying a BidiResolver every time it steps into/out of a RenderI nline.
36 class InlineIterator { 37 class InlineIterator {
37 public: 38 public:
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 enum EmptyInlineBehavior { 183 enum EmptyInlineBehavior {
183 SkipEmptyInlines, 184 SkipEmptyInlines,
184 IncludeEmptyInlines, 185 IncludeEmptyInlines,
185 }; 186 };
186 187
187 static bool isEmptyInline(RenderObject* object) 188 static bool isEmptyInline(RenderObject* object)
188 { 189 {
189 if (!object->isRenderInline()) 190 if (!object->isRenderInline())
190 return false; 191 return false;
191 192
192 for (RenderObject* curr = object->firstChild(); curr; curr = curr->nextSibli ng()) { 193 for (RenderObject* curr = toRenderInline(object)->firstChild(); curr; curr = curr->nextSibling()) {
193 if (curr->isFloatingOrOutOfFlowPositioned()) 194 if (curr->isFloatingOrOutOfFlowPositioned())
194 continue; 195 continue;
195 if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace()) 196 if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace())
196 continue; 197 continue;
197 198
198 if (!isEmptyInline(curr)) 199 if (!isEmptyInline(curr))
199 return false; 200 return false;
200 } 201 }
201 return true; 202 return true;
202 } 203 }
203 204
204 // 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.
205 // This function will iterate over inlines within a block, optionally notifying 206 // This function will iterate over inlines within a block, optionally notifying
206 // 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).
207 template <class Observer> 208 template <class Observer>
208 static inline RenderObject* bidiNextShared(RenderObject* root, RenderObject* cur rent, Observer* observer = 0, EmptyInlineBehavior emptyInlineBehavior = SkipEmpt yInlines, bool* endOfInlinePtr = 0) 209 static inline RenderObject* bidiNextShared(RenderObject* root, RenderObject* cur rent, Observer* observer = 0, EmptyInlineBehavior emptyInlineBehavior = SkipEmpt yInlines, bool* endOfInlinePtr = 0)
209 { 210 {
210 RenderObject* next = 0; 211 RenderObject* next = 0;
211 // 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.
212 bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false; 213 bool oldEndOfInline = endOfInlinePtr ? *endOfInlinePtr : false;
213 bool endOfInline = false; 214 bool endOfInline = false;
214 215
215 while (current) { 216 while (current) {
216 next = 0; 217 next = 0;
217 if (!oldEndOfInline && !isIteratorTarget(current)) { 218 if (!oldEndOfInline && !isIteratorTarget(current)) {
218 next = current->firstChild(); 219 next = current->slowFirstChild();
219 notifyObserverEnteredObject(observer, next); 220 notifyObserverEnteredObject(observer, next);
220 } 221 }
221 222
222 // We hit this when either current has no children, or when current is n ot a renderer we care about. 223 // We hit this when either current has no children, or when current is n ot a renderer we care about.
223 if (!next) { 224 if (!next) {
224 // If it is a renderer we care about, and we're doing our inline-wal k, return it. 225 // If it is a renderer we care about, and we're doing our inline-wal k, return it.
225 if (emptyInlineBehavior == IncludeEmptyInlines && !oldEndOfInline && current->isRenderInline()) { 226 if (emptyInlineBehavior == IncludeEmptyInlines && !oldEndOfInline && current->isRenderInline()) {
226 next = current; 227 next = current;
227 endOfInline = true; 228 endOfInline = true;
228 break; 229 break;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 InlineBidiResolver* observer = 0; 276 InlineBidiResolver* observer = 0;
276 return bidiNextSkippingEmptyInlines(root, current, observer); 277 return bidiNextSkippingEmptyInlines(root, current, observer);
277 } 278 }
278 279
279 static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re nderObject* current, bool* endOfInlinePtr = 0) 280 static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re nderObject* current, bool* endOfInlinePtr = 0)
280 { 281 {
281 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.
282 return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInl inePtr); 283 return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInl inePtr);
283 } 284 }
284 285
285 static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderObject* root, In lineBidiResolver* resolver = 0) 286 static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root, InlineBidiResolver* resolver = 0)
286 { 287 {
287 RenderObject* o = root->firstChild(); 288 RenderObject* o = root->firstChild();
288 if (!o) 289 if (!o)
289 return 0; 290 return 0;
290 291
291 if (o->isRenderInline()) { 292 if (o->isRenderInline()) {
292 notifyObserverEnteredObject(resolver, o); 293 notifyObserverEnteredObject(resolver, o);
293 if (!isEmptyInline(o)) 294 if (!isEmptyInline(o))
294 o = bidiNextSkippingEmptyInlines(root, o, resolver); 295 o = bidiNextSkippingEmptyInlines(root, o, resolver);
295 else { 296 else {
296 // Never skip empty inlines. 297 // Never skip empty inlines.
297 if (resolver) 298 if (resolver)
298 resolver->commitExplicitEmbedding(); 299 resolver->commitExplicitEmbedding();
299 return o; 300 return o;
300 } 301 }
301 } 302 }
302 303
303 // FIXME: Unify this with the bidiNext call above. 304 // FIXME: Unify this with the bidiNext call above.
304 if (o && !isIteratorTarget(o)) 305 if (o && !isIteratorTarget(o))
305 o = bidiNextSkippingEmptyInlines(root, o, resolver); 306 o = bidiNextSkippingEmptyInlines(root, o, resolver);
306 307
307 if (resolver) 308 if (resolver)
308 resolver->commitExplicitEmbedding(); 309 resolver->commitExplicitEmbedding();
309 return o; 310 return o;
310 } 311 }
311 312
312 // 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.
313 static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderObject* root) 314 static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderBlock* root)
314 { 315 {
315 RenderObject* o = root->firstChild(); 316 RenderObject* o = root->firstChild();
316 // 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
317 // then just return it. 318 // then just return it.
318 if (!o || o->isRenderInline() || isIteratorTarget(o)) 319 if (!o || o->isRenderInline() || isIteratorTarget(o))
319 return o; 320 return o;
320 321
321 return bidiNextIncludingEmptyInlines(root, o); 322 return bidiNextIncludingEmptyInlines(root, o);
322 } 323 }
323 324
324 inline void InlineIterator::fastIncrementInTextNode() 325 inline void InlineIterator::fastIncrementInTextNode()
325 { 326 {
326 ASSERT(m_obj); 327 ASSERT(m_obj);
327 ASSERT(m_obj->isText()); 328 ASSERT(m_obj->isText());
328 ASSERT(m_pos <= toRenderText(m_obj)->textLength()); 329 ASSERT(m_pos <= toRenderText(m_obj)->textLength());
329 if (m_pos < INT_MAX) 330 if (m_pos < INT_MAX)
330 m_pos++; 331 m_pos++;
331 } 332 }
332 333
333 // FIXME: This is used by RenderBlockFlow for simplified layout, and has nothing to do with bidi 334 // FIXME: This is used by RenderBlockFlow for simplified layout, and has nothing to do with bidi
334 // it shouldn't use functions called bidiFirst and bidiNext. 335 // it shouldn't use functions called bidiFirst and bidiNext.
335 class InlineWalker { 336 class InlineWalker {
336 public: 337 public:
337 InlineWalker(RenderObject* root) 338 InlineWalker(RenderBlock* root)
338 : m_root(root) 339 : m_root(root)
339 , m_current(0) 340 , m_current(0)
340 , m_atEndOfInline(false) 341 , m_atEndOfInline(false)
341 { 342 {
342 // 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.
343 m_current = bidiFirstIncludingEmptyInlines(m_root); 344 m_current = bidiFirstIncludingEmptyInlines(m_root);
344 } 345 }
345 346
346 RenderObject* root() { return m_root; } 347 RenderBlock* root() { return m_root; }
347 RenderObject* current() { return m_current; } 348 RenderObject* current() { return m_current; }
348 349
349 bool atEndOfInline() { return m_atEndOfInline; } 350 bool atEndOfInline() { return m_atEndOfInline; }
350 bool atEnd() const { return !m_current; } 351 bool atEnd() const { return !m_current; }
351 352
352 RenderObject* advance() 353 RenderObject* advance()
353 { 354 {
354 // FIXME: Support SkipEmptyInlines and observer parameters. 355 // FIXME: Support SkipEmptyInlines and observer parameters.
355 m_current = bidiNextIncludingEmptyInlines(m_root, m_current, &m_atEndOfI nline); 356 m_current = bidiNextIncludingEmptyInlines(m_root, m_current, &m_atEndOfI nline);
356 return m_current; 357 return m_current;
357 } 358 }
358 private: 359 private:
359 RenderObject* m_root; 360 RenderBlock* m_root;
360 RenderObject* m_current; 361 RenderObject* m_current;
361 bool m_atEndOfInline; 362 bool m_atEndOfInline;
362 }; 363 };
363 364
364 static inline bool endOfLineHasIsolatedObjectAncestor(const InlineIterator& isol atedIterator, const InlineIterator& ancestorItertor) 365 static inline bool endOfLineHasIsolatedObjectAncestor(const InlineIterator& isol atedIterator, const InlineIterator& ancestorItertor)
365 { 366 {
366 if (!isolatedIterator.object() || !isIsolated(isolatedIterator.object()->sty le()->unicodeBidi())) 367 if (!isolatedIterator.object() || !isIsolated(isolatedIterator.object()->sty le()->unicodeBidi()))
367 return false; 368 return false;
368 369
369 RenderObject* innerIsolatedObject = isolatedIterator.object(); 370 RenderObject* innerIsolatedObject = isolatedIterator.object();
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 m_sor = m_eor; 719 m_sor = m_eor;
719 } 720 }
720 721
721 m_direction = WTF::Unicode::OtherNeutral; 722 m_direction = WTF::Unicode::OtherNeutral;
722 m_status.eor = WTF::Unicode::OtherNeutral; 723 m_status.eor = WTF::Unicode::OtherNeutral;
723 } 724 }
724 725
725 } 726 }
726 727
727 #endif // InlineIterator_h 728 #endif // InlineIterator_h
OLDNEW
« no previous file with comments | « Source/core/rendering/InlineFlowBox.cpp ('k') | Source/core/rendering/RenderBlock.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698