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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 } | 64 } |
65 | 65 |
66 void moveTo(RenderObject* object, unsigned offset, int nextBreak = -1) | 66 void moveTo(RenderObject* object, unsigned offset, int nextBreak = -1) |
67 { | 67 { |
68 m_obj = object; | 68 m_obj = object; |
69 m_pos = offset; | 69 m_pos = offset; |
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; } |
| 75 |
74 unsigned offset() const { return m_pos; } | 76 unsigned offset() const { return m_pos; } |
75 RenderObject* root() const { return m_root; } | 77 RenderObject* root() const { return m_root; } |
76 | 78 |
77 void fastIncrementInTextNode(); | 79 void fastIncrementInTextNode(); |
78 void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextN
ode); | 80 void increment(InlineBidiResolver* = 0, IncrementRule = FastIncrementInTextN
ode); |
79 bool atEnd() const; | 81 bool atEnd() const; |
80 | 82 |
81 inline bool atTextParagraphSeparator() const | 83 inline bool atTextParagraphSeparator() const |
82 { | 84 { |
83 return m_obj && m_obj->preservesNewline() && m_obj->isText() && toRender
Text(m_obj)->textLength() | 85 return m_obj && m_obj->preservesNewline() && m_obj->isText() && toRender
Text(m_obj)->textLength() |
84 && !toRenderText(m_obj)->isWordBreak() && toRenderText(m_obj)->chara
cterAt(m_pos) == '\n'; | 86 && !toRenderText(m_obj)->isWordBreak() && toRenderText(m_obj)->chara
cterAt(m_pos) == '\n'; |
85 } | 87 } |
86 | 88 |
87 inline bool atParagraphSeparator() const | 89 inline bool atParagraphSeparator() const |
88 { | 90 { |
89 return (m_obj && m_obj->isBR()) || atTextParagraphSeparator(); | 91 return (m_obj && m_obj->isBR()) || atTextParagraphSeparator(); |
90 } | 92 } |
91 | 93 |
92 UChar characterAt(unsigned) const; | 94 UChar characterAt(unsigned) const; |
93 UChar current() const; | 95 UChar current() const; |
94 UChar previousInSameNode() const; | 96 UChar previousInSameNode() const; |
95 ALWAYS_INLINE WTF::Unicode::Direction direction() const; | 97 ALWAYS_INLINE WTF::Unicode::Direction direction() const; |
96 | 98 |
97 private: | 99 private: |
98 RenderObject* m_root; | 100 RenderObject* m_root; |
| 101 RenderObject* m_obj; |
99 | 102 |
100 // FIXME: These should be private. | 103 // FIXME: These should be private. |
101 public: | 104 public: |
102 RenderObject* m_obj; | |
103 unsigned m_pos; | 105 unsigned m_pos; |
104 int m_nextBreakablePosition; | 106 int m_nextBreakablePosition; |
105 }; | 107 }; |
106 | 108 |
107 inline bool operator==(const InlineIterator& it1, const InlineIterator& it2) | 109 inline bool operator==(const InlineIterator& it1, const InlineIterator& it2) |
108 { | 110 { |
109 return it1.m_pos == it2.m_pos && it1.m_obj == it2.m_obj; | 111 return it1.m_pos == it2.m_pos && it1.object() == it2.object(); |
110 } | 112 } |
111 | 113 |
112 inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2) | 114 inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2) |
113 { | 115 { |
114 return it1.m_pos != it2.m_pos || it1.m_obj != it2.m_obj; | 116 return it1.m_pos != it2.m_pos || it1.object() != it2.object(); |
115 } | 117 } |
116 | 118 |
117 static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir,
EUnicodeBidi unicodeBidi) | 119 static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir,
EUnicodeBidi unicodeBidi) |
118 { | 120 { |
119 using namespace WTF::Unicode; | 121 using namespace WTF::Unicode; |
120 if (unicodeBidi == Embed) | 122 if (unicodeBidi == Embed) |
121 return dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding; | 123 return dir == RTL ? RightToLeftEmbedding : LeftToRightEmbedding; |
122 return dir == RTL ? RightToLeftOverride : LeftToRightOverride; | 124 return dir == RTL ? RightToLeftOverride : LeftToRightOverride; |
123 } | 125 } |
124 | 126 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 | 417 |
416 template<> | 418 template<> |
417 inline void InlineBidiResolver::increment() | 419 inline void InlineBidiResolver::increment() |
418 { | 420 { |
419 m_current.increment(this, InlineIterator::FastIncrementInIsolatedRenderer); | 421 m_current.increment(this, InlineIterator::FastIncrementInIsolatedRenderer); |
420 } | 422 } |
421 | 423 |
422 template <> | 424 template <> |
423 inline bool InlineBidiResolver::isEndOfLine(const InlineIterator& end) | 425 inline bool InlineBidiResolver::isEndOfLine(const InlineIterator& end) |
424 { | 426 { |
425 bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() &&
m_current.m_obj == end.m_obj); | 427 bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() &&
m_current.object() == end.object()); |
426 if (inIsolate() && inEndOfLine) { | 428 if (inIsolate() && inEndOfLine) { |
427 m_current.moveTo(m_current.m_obj, end.m_pos, m_current.m_nextBreakablePo
sition); | 429 m_current.moveTo(m_current.object(), end.m_pos, m_current.m_nextBreakabl
ePosition); |
428 m_last = m_current; | 430 m_last = m_current; |
429 updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); | 431 updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral); |
430 } | 432 } |
431 return inEndOfLine; | 433 return inEndOfLine; |
432 } | 434 } |
433 | 435 |
434 static inline bool isIsolatedInline(RenderObject* object) | 436 static inline bool isIsolatedInline(RenderObject* object) |
435 { | 437 { |
436 ASSERT(object); | 438 ASSERT(object); |
437 return object->isRenderInline() && isIsolated(object->style()->unicodeBidi()
); | 439 return object->isRenderInline() && isIsolated(object->style()->unicodeBidi()
); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 { | 551 { |
550 if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) | 552 if (start > end || RenderBlockFlow::shouldSkipCreatingRunsForObject(obj)) |
551 return; | 553 return; |
552 | 554 |
553 LineMidpointState& lineMidpointState = resolver.midpointState(); | 555 LineMidpointState& lineMidpointState = resolver.midpointState(); |
554 bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointSta
te.numMidpoints); | 556 bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointSta
te.numMidpoints); |
555 InlineIterator nextMidpoint; | 557 InlineIterator nextMidpoint; |
556 if (haveNextMidpoint) | 558 if (haveNextMidpoint) |
557 nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidp
oint]; | 559 nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidp
oint]; |
558 if (lineMidpointState.betweenMidpoints) { | 560 if (lineMidpointState.betweenMidpoints) { |
559 if (!(haveNextMidpoint && nextMidpoint.m_obj == obj)) | 561 if (!(haveNextMidpoint && nextMidpoint.object() == obj)) |
560 return; | 562 return; |
561 // This is a new start point. Stop ignoring objects and | 563 // This is a new start point. Stop ignoring objects and |
562 // adjust our start. | 564 // adjust our start. |
563 lineMidpointState.betweenMidpoints = false; | 565 lineMidpointState.betweenMidpoints = false; |
564 start = nextMidpoint.m_pos; | 566 start = nextMidpoint.m_pos; |
565 lineMidpointState.currentMidpoint++; | 567 lineMidpointState.currentMidpoint++; |
566 if (start < end) | 568 if (start < end) |
567 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end
, resolver, behavior, tracker); | 569 return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end
, resolver, behavior, tracker); |
568 } else { | 570 } else { |
569 if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) { | 571 if (!haveNextMidpoint || (obj != nextMidpoint.object())) { |
570 appendRunObjectIfNecessary(obj, start, end, resolver, behavior, trac
ker); | 572 appendRunObjectIfNecessary(obj, start, end, resolver, behavior, trac
ker); |
571 return; | 573 return; |
572 } | 574 } |
573 | 575 |
574 // An end midpoint has been encountered within our object. We | 576 // An end midpoint has been encountered within our object. We |
575 // need to go ahead and append a run with our endpoint. | 577 // need to go ahead and append a run with our endpoint. |
576 if (nextMidpoint.m_pos + 1 <= end) { | 578 if (nextMidpoint.m_pos + 1 <= end) { |
577 lineMidpointState.betweenMidpoints = true; | 579 lineMidpointState.betweenMidpoints = true; |
578 lineMidpointState.currentMidpoint++; | 580 lineMidpointState.currentMidpoint++; |
579 if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the
object and don't nclude any of it. | 581 if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the
object and don't nclude any of it. |
(...skipping 15 matching lines...) Expand all Loading... |
595 | 597 |
596 template <> | 598 template <> |
597 inline void InlineBidiResolver::appendRun() | 599 inline void InlineBidiResolver::appendRun() |
598 { | 600 { |
599 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { | 601 if (!m_emptyRun && !m_eor.atEnd() && !m_reachedEndOfLine) { |
600 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. | 602 // Keep track of when we enter/leave "unicode-bidi: isolate" inlines. |
601 // Initialize our state depending on if we're starting in the middle of
such an inline. | 603 // Initialize our state depending on if we're starting in the middle of
such an inline. |
602 // FIXME: Could this initialize from this->inIsolate() instead of walkin
g up the render tree? | 604 // FIXME: Could this initialize from this->inIsolate() instead of walkin
g up the render tree? |
603 IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); | 605 IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor)); |
604 int start = m_sor.m_pos; | 606 int start = m_sor.m_pos; |
605 RenderObject* obj = m_sor.m_obj; | 607 RenderObject* obj = m_sor.object(); |
606 while (obj && obj != m_eor.m_obj && obj != m_endOfRunAtEndOfLine.m_obj)
{ | 608 while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.obje
ct()) { |
607 if (isolateTracker.inIsolate()) | 609 if (isolateTracker.inIsolate()) |
608 addFakeRunIfNecessary(obj, start, obj->length(), *this, isolateT
racker); | 610 addFakeRunIfNecessary(obj, start, obj->length(), *this, isolateT
racker); |
609 else | 611 else |
610 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->l
ength(), *this, AppendingRunsForObject, isolateTracker); | 612 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, obj->l
ength(), *this, AppendingRunsForObject, isolateTracker); |
611 // FIXME: start/obj should be an InlineIterator instead of two separ
ate variables. | 613 // FIXME: start/obj should be an InlineIterator instead of two separ
ate variables. |
612 start = 0; | 614 start = 0; |
613 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke
r); | 615 obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracke
r); |
614 } | 616 } |
615 bool isEndOfLine = obj == m_endOfLine.m_obj && !m_endOfLine.m_pos; | 617 bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.m_pos; |
616 if (obj && !isEndOfLine) { | 618 if (obj && !isEndOfLine) { |
617 unsigned pos = obj == m_eor.m_obj ? m_eor.m_pos : INT_MAX; | 619 unsigned pos = obj == m_eor.object() ? m_eor.m_pos : INT_MAX; |
618 if (obj == m_endOfRunAtEndOfLine.m_obj && m_endOfRunAtEndOfLine.m_po
s <= pos) { | 620 if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.m
_pos <= pos) { |
619 m_reachedEndOfLine = true; | 621 m_reachedEndOfLine = true; |
620 pos = m_endOfRunAtEndOfLine.m_pos; | 622 pos = m_endOfRunAtEndOfLine.m_pos; |
621 } | 623 } |
622 // It's OK to add runs for zero-length RenderObjects, just don't mak
e the run larger than it should be | 624 // It's OK to add runs for zero-length RenderObjects, just don't mak
e the run larger than it should be |
623 int end = obj->length() ? pos + 1 : 0; | 625 int end = obj->length() ? pos + 1 : 0; |
624 if (isolateTracker.inIsolate()) | 626 if (isolateTracker.inIsolate()) |
625 addFakeRunIfNecessary(obj, start, end, *this, isolateTracker); | 627 addFakeRunIfNecessary(obj, start, end, *this, isolateTracker); |
626 else | 628 else |
627 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, *
this, AppendingRunsForObject, isolateTracker); | 629 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, *
this, AppendingRunsForObject, isolateTracker); |
628 } | 630 } |
629 | 631 |
630 if (isEndOfLine) | 632 if (isEndOfLine) |
631 m_reachedEndOfLine = true; | 633 m_reachedEndOfLine = true; |
632 m_eor.increment(); | 634 m_eor.increment(); |
633 m_sor = m_eor; | 635 m_sor = m_eor; |
634 } | 636 } |
635 | 637 |
636 m_direction = WTF::Unicode::OtherNeutral; | 638 m_direction = WTF::Unicode::OtherNeutral; |
637 m_status.eor = WTF::Unicode::OtherNeutral; | 639 m_status.eor = WTF::Unicode::OtherNeutral; |
638 } | 640 } |
639 | 641 |
640 } | 642 } |
641 | 643 |
642 #endif // InlineIterator_h | 644 #endif // InlineIterator_h |
OLD | NEW |