OLD | NEW |
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/layout/BidiRun.h" | 26 #include "core/layout/BidiRun.h" |
| 27 #include "core/layout/LayoutText.h" |
27 #include "core/rendering/RenderBlockFlow.h" | 28 #include "core/rendering/RenderBlockFlow.h" |
28 #include "core/rendering/RenderInline.h" | 29 #include "core/rendering/RenderInline.h" |
29 #include "core/rendering/RenderText.h" | |
30 #include "wtf/StdLibExtras.h" | 30 #include "wtf/StdLibExtras.h" |
31 | 31 |
32 namespace blink { | 32 namespace blink { |
33 | 33 |
34 // 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 |
35 // text children. InlineIterator will use bidiNext to find the next RenderText | 35 // text children. InlineIterator will use bidiNext to find the next LayoutText |
36 // 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. |
37 class InlineIterator { | 37 class InlineIterator { |
38 public: | 38 public: |
39 enum IncrementRule { | 39 enum IncrementRule { |
40 FastIncrementInIsolatedRenderer, | 40 FastIncrementInIsolatedRenderer, |
41 FastIncrementInTextNode | 41 FastIncrementInTextNode |
42 }; | 42 }; |
43 | 43 |
44 InlineIterator() | 44 InlineIterator() |
45 : m_root(0) | 45 : m_root(0) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 LayoutObject* 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() && toLayout
Text(m_obj)->textLength() |
91 && !toRenderText(m_obj)->isWordBreak() && toRenderText(m_obj)->chara
cterAt(m_pos) == '\n'; | 91 && !toLayoutText(m_obj)->isWordBreak() && toLayoutText(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; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 }; | 186 }; |
187 | 187 |
188 static bool isEmptyInline(LayoutObject* 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 (LayoutObject* 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() && toLayoutText(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 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 { |
327 ASSERT(m_obj); | 327 ASSERT(m_obj); |
328 ASSERT(m_obj->isText()); | 328 ASSERT(m_obj->isText()); |
329 ASSERT(m_pos <= toRenderText(m_obj)->textLength()); | 329 ASSERT(m_pos <= toLayoutText(m_obj)->textLength()); |
330 if (m_pos < INT_MAX) | 330 if (m_pos < INT_MAX) |
331 m_pos++; | 331 m_pos++; |
332 } | 332 } |
333 | 333 |
334 // 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 |
335 // it shouldn't use functions called bidiFirst and bidiNext. | 335 // it shouldn't use functions called bidiFirst and bidiNext. |
336 class InlineWalker { | 336 class InlineWalker { |
337 public: | 337 public: |
338 InlineWalker(RenderBlock* root) | 338 InlineWalker(RenderBlock* root) |
339 : m_root(root) | 339 : m_root(root) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 | 383 |
384 if (rule == FastIncrementInIsolatedRenderer | 384 if (rule == FastIncrementInIsolatedRenderer |
385 && resolver && resolver->inIsolate() | 385 && resolver && resolver->inIsolate() |
386 && !endOfLineHasIsolatedObjectAncestor(resolver->endOfLine(), resolver->
position())) { | 386 && !endOfLineHasIsolatedObjectAncestor(resolver->endOfLine(), resolver->
position())) { |
387 moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0); | 387 moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0); |
388 return; | 388 return; |
389 } | 389 } |
390 | 390 |
391 if (m_obj->isText()) { | 391 if (m_obj->isText()) { |
392 fastIncrementInTextNode(); | 392 fastIncrementInTextNode(); |
393 if (m_pos < toRenderText(m_obj)->textLength()) | 393 if (m_pos < toLayoutText(m_obj)->textLength()) |
394 return; | 394 return; |
395 } | 395 } |
396 // bidiNext can return 0, so use moveTo instead of moveToStartOf | 396 // bidiNext can return 0, so use moveTo instead of moveToStartOf |
397 moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0); | 397 moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0); |
398 } | 398 } |
399 | 399 |
400 inline bool InlineIterator::atEnd() const | 400 inline bool InlineIterator::atEnd() const |
401 { | 401 { |
402 return !m_obj; | 402 return !m_obj; |
403 } | 403 } |
404 | 404 |
405 inline UChar InlineIterator::characterAt(unsigned index) const | 405 inline UChar InlineIterator::characterAt(unsigned index) const |
406 { | 406 { |
407 if (!m_obj || !m_obj->isText()) | 407 if (!m_obj || !m_obj->isText()) |
408 return 0; | 408 return 0; |
409 | 409 |
410 return toRenderText(m_obj)->characterAt(index); | 410 return toLayoutText(m_obj)->characterAt(index); |
411 } | 411 } |
412 | 412 |
413 inline UChar InlineIterator::current() const | 413 inline UChar InlineIterator::current() const |
414 { | 414 { |
415 return characterAt(m_pos); | 415 return characterAt(m_pos); |
416 } | 416 } |
417 | 417 |
418 inline UChar InlineIterator::previousInSameNode() const | 418 inline UChar InlineIterator::previousInSameNode() const |
419 { | 419 { |
420 if (!m_pos) | 420 if (!m_pos) |
(...skipping 24 matching lines...) Expand all Loading... |
445 { | 445 { |
446 bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() &&
m_current.object() == end.object()); | 446 bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() &&
m_current.object() == end.object()); |
447 if (inIsolate() && inEndOfLine) { | 447 if (inIsolate() && inEndOfLine) { |
448 m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakab
lePosition()); | 448 m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakab
lePosition()); |
449 m_last = m_current; | 449 m_last = m_current; |
450 updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); | 450 updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); |
451 } | 451 } |
452 return inEndOfLine; | 452 return inEndOfLine; |
453 } | 453 } |
454 | 454 |
455 static inline bool isCollapsibleSpace(UChar character, RenderText* renderer) | 455 static inline bool isCollapsibleSpace(UChar character, LayoutText* renderer) |
456 { | 456 { |
457 if (character == ' ' || character == '\t' || character == softHyphen) | 457 if (character == ' ' || character == '\t' || character == softHyphen) |
458 return true; | 458 return true; |
459 if (character == '\n') | 459 if (character == '\n') |
460 return !renderer->style()->preserveNewline(); | 460 return !renderer->style()->preserveNewline(); |
461 return false; | 461 return false; |
462 } | 462 } |
463 | 463 |
464 template <typename CharacterType> | 464 template <typename CharacterType> |
465 static inline int findFirstTrailingSpace(RenderText* lastText, const CharacterTy
pe* characters, int start, int stop) | 465 static inline int findFirstTrailingSpace(LayoutText* lastText, const CharacterTy
pe* characters, int start, int stop) |
466 { | 466 { |
467 int firstSpace = stop; | 467 int firstSpace = stop; |
468 while (firstSpace > start) { | 468 while (firstSpace > start) { |
469 UChar current = characters[firstSpace - 1]; | 469 UChar current = characters[firstSpace - 1]; |
470 if (!isCollapsibleSpace(current, lastText)) | 470 if (!isCollapsibleSpace(current, lastText)) |
471 break; | 471 break; |
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 LayoutObject* 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 LayoutText* lastText = toLayoutText(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; |
493 } | 493 } |
494 | 494 |
495 template <> | 495 template <> |
496 inline BidiRun* InlineBidiResolver::addTrailingRun(BidiRunList<BidiRun>& runs, i
nt start, int stop, BidiRun* run, BidiContext* context, TextDirection direction)
const | 496 inline BidiRun* InlineBidiResolver::addTrailingRun(BidiRunList<BidiRun>& runs, i
nt start, int stop, BidiRun* run, BidiContext* context, TextDirection direction)
const |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 |
OLD | NEW |