| 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 |