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/LayoutBlockFlow.h" | 27 #include "core/layout/LayoutBlockFlow.h" |
28 #include "core/layout/LayoutInline.h" | 28 #include "core/layout/LayoutInline.h" |
29 #include "core/rendering/RenderText.h" | 29 #include "core/layout/LayoutText.h" |
| 30 |
30 #include "wtf/StdLibExtras.h" | 31 #include "wtf/StdLibExtras.h" |
31 | 32 |
32 namespace blink { | 33 namespace blink { |
33 | 34 |
34 // This class is used to LayoutInline subtrees, stepping by character within the | 35 // This class is used to LayoutInline subtrees, stepping by character within the |
35 // text children. InlineIterator will use bidiNext to find the next RenderText | 36 // text children. InlineIterator will use bidiNext to find the next LayoutText |
36 // optionally notifying a BidiResolver every time it steps into/out of a LayoutI
nline. | 37 // optionally notifying a BidiResolver every time it steps into/out of a LayoutI
nline. |
37 class InlineIterator { | 38 class InlineIterator { |
38 public: | 39 public: |
39 enum IncrementRule { | 40 enum IncrementRule { |
40 FastIncrementInIsolatedRenderer, | 41 FastIncrementInIsolatedRenderer, |
41 FastIncrementInTextNode | 42 FastIncrementInTextNode |
42 }; | 43 }; |
43 | 44 |
44 InlineIterator() | 45 InlineIterator() |
45 : m_root(0) | 46 : m_root(0) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 unsigned offset() const { return m_pos; } | 81 unsigned offset() const { return m_pos; } |
81 void setOffset(unsigned position) { m_pos = position; } | 82 void setOffset(unsigned position) { m_pos = position; } |
82 LayoutObject* root() const { return m_root; } | 83 LayoutObject* root() const { return m_root; } |
83 | 84 |
84 void fastIncrementInTextNode(); | 85 void fastIncrementInTextNode(); |
85 void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextN
ode); | 86 void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextN
ode); |
86 bool atEnd() const; | 87 bool atEnd() const; |
87 | 88 |
88 inline bool atTextParagraphSeparator() const | 89 inline bool atTextParagraphSeparator() const |
89 { | 90 { |
90 return m_obj && m_obj->preservesNewline() && m_obj->isText() && toRender
Text(m_obj)->textLength() | 91 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'; | 92 && !toLayoutText(m_obj)->isWordBreak() && toLayoutText(m_obj)->chara
cterAt(m_pos) == '\n'; |
92 } | 93 } |
93 | 94 |
94 inline bool atParagraphSeparator() const | 95 inline bool atParagraphSeparator() const |
95 { | 96 { |
96 return (m_obj && m_obj->isBR()) || atTextParagraphSeparator(); | 97 return (m_obj && m_obj->isBR()) || atTextParagraphSeparator(); |
97 } | 98 } |
98 | 99 |
99 UChar characterAt(unsigned) const; | 100 UChar characterAt(unsigned) const; |
100 UChar current() const; | 101 UChar current() const; |
101 UChar previousInSameNode() const; | 102 UChar previousInSameNode() const; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 }; | 187 }; |
187 | 188 |
188 static bool isEmptyInline(LayoutObject* object) | 189 static bool isEmptyInline(LayoutObject* object) |
189 { | 190 { |
190 if (!object->isLayoutInline()) | 191 if (!object->isLayoutInline()) |
191 return false; | 192 return false; |
192 | 193 |
193 for (LayoutObject* curr = toLayoutInline(object)->firstChild(); curr; curr =
curr->nextSibling()) { | 194 for (LayoutObject* curr = toLayoutInline(object)->firstChild(); curr; curr =
curr->nextSibling()) { |
194 if (curr->isFloatingOrOutOfFlowPositioned()) | 195 if (curr->isFloatingOrOutOfFlowPositioned()) |
195 continue; | 196 continue; |
196 if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace()) | 197 if (curr->isText() && toLayoutText(curr)->isAllCollapsibleWhitespace()) |
197 continue; | 198 continue; |
198 | 199 |
199 if (!isEmptyInline(curr)) | 200 if (!isEmptyInline(curr)) |
200 return false; | 201 return false; |
201 } | 202 } |
202 return true; | 203 return true; |
203 } | 204 } |
204 | 205 |
205 // FIXME: This function is misleadingly named. It has little to do with bidi. | 206 // 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 | 207 // 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->isLayoutInline() || isIteratorTarget(o)) | 320 if (!o || o->isLayoutInline() || isIteratorTarget(o)) |
320 return o; | 321 return o; |
321 | 322 |
322 return bidiNextIncludingEmptyInlines(root, o); | 323 return bidiNextIncludingEmptyInlines(root, o); |
323 } | 324 } |
324 | 325 |
325 inline void InlineIterator::fastIncrementInTextNode() | 326 inline void InlineIterator::fastIncrementInTextNode() |
326 { | 327 { |
327 ASSERT(m_obj); | 328 ASSERT(m_obj); |
328 ASSERT(m_obj->isText()); | 329 ASSERT(m_obj->isText()); |
329 ASSERT(m_pos <= toRenderText(m_obj)->textLength()); | 330 ASSERT(m_pos <= toLayoutText(m_obj)->textLength()); |
330 if (m_pos < INT_MAX) | 331 if (m_pos < INT_MAX) |
331 m_pos++; | 332 m_pos++; |
332 } | 333 } |
333 | 334 |
334 // FIXME: This is used by LayoutBlockFlow for simplified layout, and has nothing
to do with bidi | 335 // FIXME: This is used by LayoutBlockFlow for simplified layout, and has nothing
to do with bidi |
335 // it shouldn't use functions called bidiFirst and bidiNext. | 336 // it shouldn't use functions called bidiFirst and bidiNext. |
336 class InlineWalker { | 337 class InlineWalker { |
337 public: | 338 public: |
338 InlineWalker(LayoutBlock* root) | 339 InlineWalker(LayoutBlock* root) |
339 : m_root(root) | 340 : m_root(root) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 | 384 |
384 if (rule == FastIncrementInIsolatedRenderer | 385 if (rule == FastIncrementInIsolatedRenderer |
385 && resolver && resolver->inIsolate() | 386 && resolver && resolver->inIsolate() |
386 && !endOfLineHasIsolatedObjectAncestor(resolver->endOfLine(), resolver->
position())) { | 387 && !endOfLineHasIsolatedObjectAncestor(resolver->endOfLine(), resolver->
position())) { |
387 moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0); | 388 moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0); |
388 return; | 389 return; |
389 } | 390 } |
390 | 391 |
391 if (m_obj->isText()) { | 392 if (m_obj->isText()) { |
392 fastIncrementInTextNode(); | 393 fastIncrementInTextNode(); |
393 if (m_pos < toRenderText(m_obj)->textLength()) | 394 if (m_pos < toLayoutText(m_obj)->textLength()) |
394 return; | 395 return; |
395 } | 396 } |
396 // bidiNext can return 0, so use moveTo instead of moveToStartOf | 397 // bidiNext can return 0, so use moveTo instead of moveToStartOf |
397 moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0); | 398 moveTo(bidiNextSkippingEmptyInlines(m_root, m_obj, resolver), 0); |
398 } | 399 } |
399 | 400 |
400 inline bool InlineIterator::atEnd() const | 401 inline bool InlineIterator::atEnd() const |
401 { | 402 { |
402 return !m_obj; | 403 return !m_obj; |
403 } | 404 } |
404 | 405 |
405 inline UChar InlineIterator::characterAt(unsigned index) const | 406 inline UChar InlineIterator::characterAt(unsigned index) const |
406 { | 407 { |
407 if (!m_obj || !m_obj->isText()) | 408 if (!m_obj || !m_obj->isText()) |
408 return 0; | 409 return 0; |
409 | 410 |
410 return toRenderText(m_obj)->characterAt(index); | 411 return toLayoutText(m_obj)->characterAt(index); |
411 } | 412 } |
412 | 413 |
413 inline UChar InlineIterator::current() const | 414 inline UChar InlineIterator::current() const |
414 { | 415 { |
415 return characterAt(m_pos); | 416 return characterAt(m_pos); |
416 } | 417 } |
417 | 418 |
418 inline UChar InlineIterator::previousInSameNode() const | 419 inline UChar InlineIterator::previousInSameNode() const |
419 { | 420 { |
420 if (!m_pos) | 421 if (!m_pos) |
(...skipping 24 matching lines...) Expand all Loading... |
445 { | 446 { |
446 bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() &&
m_current.object() == end.object()); | 447 bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() &&
m_current.object() == end.object()); |
447 if (inIsolate() && inEndOfLine) { | 448 if (inIsolate() && inEndOfLine) { |
448 m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakab
lePosition()); | 449 m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakab
lePosition()); |
449 m_last = m_current; | 450 m_last = m_current; |
450 updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); | 451 updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); |
451 } | 452 } |
452 return inEndOfLine; | 453 return inEndOfLine; |
453 } | 454 } |
454 | 455 |
455 static inline bool isCollapsibleSpace(UChar character, RenderText* renderer) | 456 static inline bool isCollapsibleSpace(UChar character, LayoutText* renderer) |
456 { | 457 { |
457 if (character == ' ' || character == '\t' || character == softHyphen) | 458 if (character == ' ' || character == '\t' || character == softHyphen) |
458 return true; | 459 return true; |
459 if (character == '\n') | 460 if (character == '\n') |
460 return !renderer->style()->preserveNewline(); | 461 return !renderer->style()->preserveNewline(); |
461 return false; | 462 return false; |
462 } | 463 } |
463 | 464 |
464 template <typename CharacterType> | 465 template <typename CharacterType> |
465 static inline int findFirstTrailingSpace(RenderText* lastText, const CharacterTy
pe* characters, int start, int stop) | 466 static inline int findFirstTrailingSpace(LayoutText* lastText, const CharacterTy
pe* characters, int start, int stop) |
466 { | 467 { |
467 int firstSpace = stop; | 468 int firstSpace = stop; |
468 while (firstSpace > start) { | 469 while (firstSpace > start) { |
469 UChar current = characters[firstSpace - 1]; | 470 UChar current = characters[firstSpace - 1]; |
470 if (!isCollapsibleSpace(current, lastText)) | 471 if (!isCollapsibleSpace(current, lastText)) |
471 break; | 472 break; |
472 firstSpace--; | 473 firstSpace--; |
473 } | 474 } |
474 | 475 |
475 return firstSpace; | 476 return firstSpace; |
476 } | 477 } |
477 | 478 |
478 template <> | 479 template <> |
479 inline int InlineBidiResolver::findFirstTrailingSpaceAtRun(BidiRun* run) | 480 inline int InlineBidiResolver::findFirstTrailingSpaceAtRun(BidiRun* run) |
480 { | 481 { |
481 ASSERT(run); | 482 ASSERT(run); |
482 LayoutObject* lastObject = run->m_object; | 483 LayoutObject* lastObject = run->m_object; |
483 if (!lastObject->isText()) | 484 if (!lastObject->isText()) |
484 return run->m_stop; | 485 return run->m_stop; |
485 | 486 |
486 RenderText* lastText = toRenderText(lastObject); | 487 LayoutText* lastText = toLayoutText(lastObject); |
487 int firstSpace; | 488 int firstSpace; |
488 if (lastText->is8Bit()) | 489 if (lastText->is8Bit()) |
489 firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), r
un->start(), run->stop()); | 490 firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), r
un->start(), run->stop()); |
490 else | 491 else |
491 firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(),
run->start(), run->stop()); | 492 firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(),
run->start(), run->stop()); |
492 return firstSpace; | 493 return firstSpace; |
493 } | 494 } |
494 | 495 |
495 template <> | 496 template <> |
496 inline BidiRun* InlineBidiResolver::addTrailingRun(BidiRunList<BidiRun>& runs, i
nt start, int stop, BidiRun* run, BidiContext* context, TextDirection direction)
const | 497 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; | 737 m_sor = m_eor; |
737 } | 738 } |
738 | 739 |
739 m_direction = WTF::Unicode::OtherNeutral; | 740 m_direction = WTF::Unicode::OtherNeutral; |
740 m_status.eor = WTF::Unicode::OtherNeutral; | 741 m_status.eor = WTF::Unicode::OtherNeutral; |
741 } | 742 } |
742 | 743 |
743 } | 744 } |
744 | 745 |
745 #endif // InlineIterator_h | 746 #endif // InlineIterator_h |
OLD | NEW |