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 * |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 m_nextBreakablePosition = nextBreak; | 70 m_nextBreakablePosition = nextBreak; |
71 } | 71 } |
72 | 72 |
73 RenderObject* object() const { return m_obj; } | 73 RenderObject* object() const { return m_obj; } |
74 void setObject(RenderObject* object) { m_obj = object; } | 74 void setObject(RenderObject* object) { m_obj = object; } |
75 | 75 |
76 int nextBreakablePosition() const { return m_nextBreakablePosition; } | 76 int nextBreakablePosition() const { return m_nextBreakablePosition; } |
77 void setNextBreakablePosition(int position) { m_nextBreakablePosition = posi
tion; } | 77 void setNextBreakablePosition(int position) { m_nextBreakablePosition = posi
tion; } |
78 | 78 |
79 unsigned offset() const { return m_pos; } | 79 unsigned offset() const { return m_pos; } |
| 80 void setOffset(unsigned position) { m_pos = position; } |
80 RenderObject* root() const { return m_root; } | 81 RenderObject* root() const { return m_root; } |
81 | 82 |
82 void fastIncrementInTextNode(); | 83 void fastIncrementInTextNode(); |
83 void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextN
ode); | 84 void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextN
ode); |
84 bool atEnd() const; | 85 bool atEnd() const; |
85 | 86 |
86 inline bool atTextParagraphSeparator() const | 87 inline bool atTextParagraphSeparator() const |
87 { | 88 { |
88 return m_obj && m_obj->preservesNewline() && m_obj->isText() && toRender
Text(m_obj)->textLength() | 89 return m_obj && m_obj->preservesNewline() && m_obj->isText() && toRender
Text(m_obj)->textLength() |
89 && !toRenderText(m_obj)->isWordBreak() && toRenderText(m_obj)->chara
cterAt(m_pos) == '\n'; | 90 && !toRenderText(m_obj)->isWordBreak() && toRenderText(m_obj)->chara
cterAt(m_pos) == '\n'; |
90 } | 91 } |
91 | 92 |
92 inline bool atParagraphSeparator() const | 93 inline bool atParagraphSeparator() const |
93 { | 94 { |
94 return (m_obj && m_obj->isBR()) || atTextParagraphSeparator(); | 95 return (m_obj && m_obj->isBR()) || atTextParagraphSeparator(); |
95 } | 96 } |
96 | 97 |
97 UChar characterAt(unsigned) const; | 98 UChar characterAt(unsigned) const; |
98 UChar current() const; | 99 UChar current() const; |
99 UChar previousInSameNode() const; | 100 UChar previousInSameNode() const; |
100 ALWAYS_INLINE WTF::Unicode::Direction direction() const; | 101 ALWAYS_INLINE WTF::Unicode::Direction direction() const; |
101 | 102 |
102 private: | 103 private: |
103 RenderObject* m_root; | 104 RenderObject* m_root; |
104 RenderObject* m_obj; | 105 RenderObject* m_obj; |
105 | 106 |
106 int m_nextBreakablePosition; | 107 int m_nextBreakablePosition; |
107 | |
108 // FIXME: These should be private. | |
109 public: | |
110 unsigned m_pos; | 108 unsigned m_pos; |
111 }; | 109 }; |
112 | 110 |
113 inline bool operator==(const InlineIterator& it1, const InlineIterator& it2) | 111 inline bool operator==(const InlineIterator& it1, const InlineIterator& it2) |
114 { | 112 { |
115 return it1.m_pos == it2.m_pos && it1.object() == it2.object(); | 113 return it1.offset() == it2.offset() && it1.object() == it2.object(); |
116 } | 114 } |
117 | 115 |
118 inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2) | 116 inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2) |
119 { | 117 { |
120 return it1.m_pos != it2.m_pos || it1.object() != it2.object(); | 118 return it1.offset() != it2.offset() || it1.object() != it2.object(); |
121 } | 119 } |
122 | 120 |
123 static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir,
EUnicodeBidi unicodeBidi) | 121 static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir,
EUnicodeBidi unicodeBidi) |
124 { | 122 { |
125 using namespace WTF::Unicode; | 123 using namespace WTF::Unicode; |
126 if (unicodeBidi == Embed) | 124 if (unicodeBidi == Embed) |
127 return dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding; | 125 return dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding; |
128 return dir == RTL ? RightToLeftOverride : LeftToRightOverride; | 126 return dir == RTL ? RightToLeftOverride : LeftToRightOverride; |
129 } | 127 } |
130 | 128 |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 inline void InlineBidiResolver::increment() | 437 inline void InlineBidiResolver::increment() |
440 { | 438 { |
441 m_current.increment(this, InlineIterator::FastIncrementInIsolatedRenderer); | 439 m_current.increment(this, InlineIterator::FastIncrementInIsolatedRenderer); |
442 } | 440 } |
443 | 441 |
444 template <> | 442 template <> |
445 inline bool InlineBidiResolver::isEndOfLine(const InlineIterator& end) | 443 inline bool InlineBidiResolver::isEndOfLine(const InlineIterator& end) |
446 { | 444 { |
447 bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() &&
m_current.object() == end.object()); | 445 bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() &&
m_current.object() == end.object()); |
448 if (inIsolate() && inEndOfLine) { | 446 if (inIsolate() && inEndOfLine) { |
449 m_current.moveTo(m_current.object(), end.m_pos, m_current.nextBreakableP
osition()); | 447 m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakab
lePosition()); |
450 m_last = m_current; | 448 m_last = m_current; |
451 updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); | 449 updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); |
452 } | 450 } |
453 return inEndOfLine; | 451 return inEndOfLine; |
454 } | 452 } |
455 | 453 |
456 static inline bool isIsolatedInline(RenderObject* object) | 454 static inline bool isIsolatedInline(RenderObject* object) |
457 { | 455 { |
458 ASSERT(object); | 456 ASSERT(object); |
459 return object->isRenderInline() && isIsolated(object->style()->unicodeBidi()
); | 457 return object->isRenderInline() && isIsolated(object->style()->unicodeBidi()
); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointSta
te.numMidpoints); | 574 bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointSta
te.numMidpoints); |
577 InlineIterator nextMidpoint; | 575 InlineIterator nextMidpoint; |
578 if (haveNextMidpoint) | 576 if (haveNextMidpoint) |
579 nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidp
oint]; | 577 nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidp
oint]; |
580 if (lineMidpointState.betweenMidpoints) { | 578 if (lineMidpointState.betweenMidpoints) { |
581 if (!(haveNextMidpoint && nextMidpoint.object() == obj)) | 579 if (!(haveNextMidpoint && nextMidpoint.object() == obj)) |
582 return; | 580 return; |
583 // This is a new start point. Stop ignoring objects and | 581 // This is a new start point. Stop ignoring objects and |
584 // adjust our start. | 582 // adjust our start. |
585 lineMidpointState.betweenMidpoints = false; | 583 lineMidpointState.betweenMidpoints = false; |
586 start = nextMidpoint.m_pos; | 584 start = nextMidpoint.offset(); |
587 lineMidpointState.currentMidpoint++; | 585 lineMidpointState.currentMidpoint++; |
588 if (start < end) | 586 if (start < end) |
589 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end
, resolver, behavior, tracker); | 587 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end
, resolver, behavior, tracker); |
590 } else { | 588 } else { |
591 if (!haveNextMidpoint || (obj != nextMidpoint.object())) { | 589 if (!haveNextMidpoint || (obj != nextMidpoint.object())) { |
592 appendRunObjectIfNecessary(obj, start, end, resolver, behavior, trac
ker); | 590 appendRunObjectIfNecessary(obj, start, end, resolver, behavior, trac
ker); |
593 return; | 591 return; |
594 } | 592 } |
595 | 593 |
596 // An end midpoint has been encountered within our object. We | 594 // An end midpoint has been encountered within our object. We |
597 // need to go ahead and append a run with our endpoint. | 595 // need to go ahead and append a run with our endpoint. |
598 if (nextMidpoint.m_pos + 1 <= end) { | 596 if (nextMidpoint.offset() + 1 <= end) { |
599 lineMidpointState.betweenMidpoints = true; | 597 lineMidpointState.betweenMidpoints = true; |
600 lineMidpointState.currentMidpoint++; | 598 lineMidpointState.currentMidpoint++; |
601 if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the
object and don't nclude any of it. | 599 if (nextMidpoint.offset() != UINT_MAX) { // UINT_MAX means stop at t
he object and don't nclude any of it. |
602 if (nextMidpoint.m_pos + 1 > start) | 600 if (nextMidpoint.offset() + 1 > start) |
603 appendRunObjectIfNecessary(obj, start, nextMidpoint.m_pos +
1, resolver, behavior, tracker); | 601 appendRunObjectIfNecessary(obj, start, nextMidpoint.offset()
+ 1, resolver, behavior, tracker); |
604 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMi
dpoint.m_pos + 1, end, resolver, behavior, tracker); | 602 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMi
dpoint.offset() + 1, end, resolver, behavior, tracker); |
605 } | 603 } |
606 } else { | 604 } else { |
607 appendRunObjectIfNecessary(obj, start, end, resolver, behavior, trac
ker); | 605 appendRunObjectIfNecessary(obj, start, end, resolver, behavior, trac
ker); |
608 } | 606 } |
609 } | 607 } |
610 } | 608 } |
611 | 609 |
612 static inline void addFakeRunIfNecessary(RenderObject* obj, unsigned start, unsi
gned end, InlineBidiResolver& resolver, IsolateTracker& tracker) | 610 static inline void addFakeRunIfNecessary(RenderObject* obj, unsigned start, unsi
gned end, InlineBidiResolver& resolver, IsolateTracker& tracker) |
613 { | 611 { |
614 tracker.setMidpointStateForRootIsolate(resolver.midpointState()); | 612 tracker.setMidpointStateForRootIsolate(resolver.midpointState()); |
615 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->length(), res
olver, AppendingFakeRun, tracker); | 613 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->length(), res
olver, AppendingFakeRun, tracker); |
616 } | 614 } |
617 | 615 |
618 template <> | 616 template <> |
619 inline void InlineBidiResolver::appendRun() | 617 inline void InlineBidiResolver::appendRun() |
620 { | 618 { |
621 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { | 619 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { |
622 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. | 620 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. |
623 // Initialize our state depending on if we're starting in the middle of
such an inline. | 621 // Initialize our state depending on if we're starting in the middle of
such an inline. |
624 // FIXME: Could this initialize from this->inIsolate() instead of walkin
g up the render tree? | 622 // FIXME: Could this initialize from this->inIsolate() instead of walkin
g up the render tree? |
625 IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); | 623 IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); |
626 int start = m_sor.m_pos; | 624 int start = m_sor.offset(); |
627 RenderObject* obj = m_sor.object(); | 625 RenderObject* obj = m_sor.object(); |
628 while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.obje
ct()) { | 626 while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.obje
ct()) { |
629 if (isolateTracker.inIsolate()) | 627 if (isolateTracker.inIsolate()) |
630 addFakeRunIfNecessary(obj, start, obj->length(), *this, isolateT
racker); | 628 addFakeRunIfNecessary(obj, start, obj->length(), *this, isolateT
racker); |
631 else | 629 else |
632 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->l
ength(), *this, AppendingRunsForObject, isolateTracker); | 630 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->l
ength(), *this, AppendingRunsForObject, isolateTracker); |
633 // FIXME: start/obj should be an InlineIterator instead of two separ
ate variables. | 631 // FIXME: start/obj should be an InlineIterator instead of two separ
ate variables. |
634 start = 0; | 632 start = 0; |
635 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke
r); | 633 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke
r); |
636 } | 634 } |
637 bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.m_pos; | 635 bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.offset(); |
638 if (obj && !isEndOfLine) { | 636 if (obj && !isEndOfLine) { |
639 unsigned pos = obj == m_eor.object() ? m_eor.m_pos : INT_MAX; | 637 unsigned pos = obj == m_eor.object() ? m_eor.offset() : INT_MAX; |
640 if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.m
_pos <= pos) { | 638 if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.o
ffset() <= pos) { |
641 m_reachedEndOfLine = true; | 639 m_reachedEndOfLine = true; |
642 pos = m_endOfRunAtEndOfLine.m_pos; | 640 pos = m_endOfRunAtEndOfLine.offset(); |
643 } | 641 } |
644 // It's OK to add runs for zero-length RenderObjects, just don't mak
e the run larger than it should be | 642 // It's OK to add runs for zero-length RenderObjects, just don't mak
e the run larger than it should be |
645 int end = obj->length() ? pos + 1 : 0; | 643 int end = obj->length() ? pos + 1 : 0; |
646 if (isolateTracker.inIsolate()) | 644 if (isolateTracker.inIsolate()) |
647 addFakeRunIfNecessary(obj, start, end, *this, isolateTracker); | 645 addFakeRunIfNecessary(obj, start, end, *this, isolateTracker); |
648 else | 646 else |
649 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, *
this, AppendingRunsForObject, isolateTracker); | 647 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, *
this, AppendingRunsForObject, isolateTracker); |
650 } | 648 } |
651 | 649 |
652 if (isEndOfLine) | 650 if (isEndOfLine) |
653 m_reachedEndOfLine = true; | 651 m_reachedEndOfLine = true; |
654 m_eor.increment(); | 652 m_eor.increment(); |
655 m_sor = m_eor; | 653 m_sor = m_eor; |
656 } | 654 } |
657 | 655 |
658 m_direction = WTF::Unicode::OtherNeutral; | 656 m_direction = WTF::Unicode::OtherNeutral; |
659 m_status.eor = WTF::Unicode::OtherNeutral; | 657 m_status.eor = WTF::Unicode::OtherNeutral; |
660 } | 658 } |
661 | 659 |
662 } | 660 } |
663 | 661 |
664 #endif // InlineIterator_h | 662 #endif // InlineIterator_h |
OLD | NEW |