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 Apple Inc. All right reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008 Apple Inc. All right reserved. |
4 * | 4 * |
5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
9 * | 9 * |
10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 void startIgnoringSpaces(const Iterator& midpoint) { | 52 void startIgnoringSpaces(const Iterator& midpoint) { |
53 ASSERT(!(m_numMidpoints % 2)); | 53 ASSERT(!(m_numMidpoints % 2)); |
54 addMidpoint(midpoint); | 54 addMidpoint(midpoint); |
55 } | 55 } |
56 | 56 |
57 void stopIgnoringSpaces(const Iterator& midpoint) { | 57 void stopIgnoringSpaces(const Iterator& midpoint) { |
58 ASSERT(m_numMidpoints % 2); | 58 ASSERT(m_numMidpoints % 2); |
59 addMidpoint(midpoint); | 59 addMidpoint(midpoint); |
60 } | 60 } |
61 | 61 |
62 // Adding a pair of midpoints before a character will split it out into a new
line box. | 62 // Adding a pair of midpoints before a character will split it out into a new |
| 63 // line box. |
63 void ensureCharacterGetsLineBox(Iterator& textParagraphSeparator) { | 64 void ensureCharacterGetsLineBox(Iterator& textParagraphSeparator) { |
64 startIgnoringSpaces(Iterator(0, textParagraphSeparator.getLineLayoutItem(), | 65 startIgnoringSpaces(Iterator(0, textParagraphSeparator.getLineLayoutItem(), |
65 textParagraphSeparator.offset() - 1)); | 66 textParagraphSeparator.offset() - 1)); |
66 stopIgnoringSpaces(Iterator(0, textParagraphSeparator.getLineLayoutItem(), | 67 stopIgnoringSpaces(Iterator(0, textParagraphSeparator.getLineLayoutItem(), |
67 textParagraphSeparator.offset())); | 68 textParagraphSeparator.offset())); |
68 } | 69 } |
69 | 70 |
70 void checkMidpoints(Iterator& lBreak) { | 71 void checkMidpoints(Iterator& lBreak) { |
71 // Check to see if our last midpoint is a start point beyond the line break.
If so, | 72 // Check to see if our last midpoint is a start point beyond the line break. |
72 // shave it off the list, and shave off a trailing space if the previous end
point doesn't | 73 // If so, shave it off the list, and shave off a trailing space if the |
73 // preserve whitespace. | 74 // previous end point doesn't preserve whitespace. |
74 if (lBreak.getLineLayoutItem() && m_numMidpoints && !(m_numMidpoints % 2)) { | 75 if (lBreak.getLineLayoutItem() && m_numMidpoints && !(m_numMidpoints % 2)) { |
75 Iterator* midpointsIterator = m_midpoints.data(); | 76 Iterator* midpointsIterator = m_midpoints.data(); |
76 Iterator& endpoint = midpointsIterator[m_numMidpoints - 2]; | 77 Iterator& endpoint = midpointsIterator[m_numMidpoints - 2]; |
77 const Iterator& startpoint = midpointsIterator[m_numMidpoints - 1]; | 78 const Iterator& startpoint = midpointsIterator[m_numMidpoints - 1]; |
78 Iterator currpoint = endpoint; | 79 Iterator currpoint = endpoint; |
79 while (!currpoint.atEnd() && currpoint != startpoint && | 80 while (!currpoint.atEnd() && currpoint != startpoint && |
80 currpoint != lBreak) | 81 currpoint != lBreak) |
81 currpoint.increment(); | 82 currpoint.increment(); |
82 if (currpoint == lBreak) { | 83 if (currpoint == lBreak) { |
83 // We hit the line break before the start point. Shave off the start poi
nt. | 84 // We hit the line break before the start point. Shave off the start |
| 85 // point. |
84 m_numMidpoints--; | 86 m_numMidpoints--; |
85 if (endpoint.getLineLayoutItem().style()->collapseWhiteSpace() && | 87 if (endpoint.getLineLayoutItem().style()->collapseWhiteSpace() && |
86 endpoint.getLineLayoutItem().isText()) | 88 endpoint.getLineLayoutItem().isText()) |
87 endpoint.setOffset(endpoint.offset() - 1); | 89 endpoint.setOffset(endpoint.offset() - 1); |
88 } | 90 } |
89 } | 91 } |
90 } | 92 } |
91 | 93 |
92 Vector<Iterator>& midpoints() { return m_midpoints; } | 94 Vector<Iterator>& midpoints() { return m_midpoints; } |
93 const unsigned& numMidpoints() const { return m_numMidpoints; } | 95 const unsigned& numMidpoints() const { return m_numMidpoints; } |
94 const unsigned& currentMidpoint() const { return m_currentMidpoint; } | 96 const unsigned& currentMidpoint() const { return m_currentMidpoint; } |
95 void incrementCurrentMidpoint() { m_currentMidpoint++; } | 97 void incrementCurrentMidpoint() { m_currentMidpoint++; } |
96 const bool& betweenMidpoints() const { return m_betweenMidpoints; } | 98 const bool& betweenMidpoints() const { return m_betweenMidpoints; } |
97 void setBetweenMidpoints(bool betweenMidpoint) { | 99 void setBetweenMidpoints(bool betweenMidpoint) { |
98 m_betweenMidpoints = betweenMidpoint; | 100 m_betweenMidpoints = betweenMidpoint; |
99 } | 101 } |
100 | 102 |
101 private: | 103 private: |
102 // The goal is to reuse the line state across multiple | 104 // The goal is to reuse the line state across multiple |
103 // lines so we just keep an array around for midpoints and never clear it acro
ss multiple | 105 // lines so we just keep an array around for midpoints and never clear it |
104 // lines. We track the number of items and position using the two other variab
les. | 106 // across multiple lines. We track the number of items and position using the |
| 107 // two other variables. |
105 Vector<Iterator> m_midpoints; | 108 Vector<Iterator> m_midpoints; |
106 unsigned m_numMidpoints; | 109 unsigned m_numMidpoints; |
107 unsigned m_currentMidpoint; | 110 unsigned m_currentMidpoint; |
108 bool m_betweenMidpoints; | 111 bool m_betweenMidpoints; |
109 | 112 |
110 void addMidpoint(const Iterator& midpoint) { | 113 void addMidpoint(const Iterator& midpoint) { |
111 if (m_midpoints.size() <= m_numMidpoints) | 114 if (m_midpoints.size() <= m_numMidpoints) |
112 m_midpoints.grow(m_numMidpoints + 10); | 115 m_midpoints.grow(m_numMidpoints + 10); |
113 | 116 |
114 Iterator* midpointsIterator = m_midpoints.data(); | 117 Iterator* midpointsIterator = m_midpoints.data(); |
115 midpointsIterator[m_numMidpoints++] = midpoint; | 118 midpointsIterator[m_numMidpoints++] = midpoint; |
116 } | 119 } |
117 }; | 120 }; |
118 | 121 |
119 // The BidiStatus at a given position (typically the end of a line) can | 122 // The BidiStatus at a given position (typically the end of a line) can |
120 // be cached and then used to restart bidi resolution at that position. | 123 // be cached and then used to restart bidi resolution at that position. |
121 struct BidiStatus final { | 124 struct BidiStatus final { |
122 DISALLOW_NEW(); | 125 DISALLOW_NEW(); |
123 BidiStatus() | 126 BidiStatus() |
124 : eor(WTF::Unicode::OtherNeutral), | 127 : eor(WTF::Unicode::OtherNeutral), |
125 lastStrong(WTF::Unicode::OtherNeutral), | 128 lastStrong(WTF::Unicode::OtherNeutral), |
126 last(WTF::Unicode::OtherNeutral) {} | 129 last(WTF::Unicode::OtherNeutral) {} |
127 | 130 |
128 // Creates a BidiStatus representing a new paragraph root with a default direc
tion. | 131 // Creates a BidiStatus representing a new paragraph root with a default |
129 // Uses TextDirection as it only has two possibilities instead of WTF::Unicode
::Direction which has 19. | 132 // direction. Uses TextDirection as it only has two possibilities instead of |
| 133 // WTF::Unicode::Direction which has 19. |
130 BidiStatus(TextDirection textDirection, bool isOverride) { | 134 BidiStatus(TextDirection textDirection, bool isOverride) { |
131 WTF::Unicode::CharDirection direction = textDirection == LTR | 135 WTF::Unicode::CharDirection direction = textDirection == LTR |
132 ? WTF::Unicode::LeftToRight | 136 ? WTF::Unicode::LeftToRight |
133 : WTF::Unicode::RightToLeft; | 137 : WTF::Unicode::RightToLeft; |
134 eor = lastStrong = last = direction; | 138 eor = lastStrong = last = direction; |
135 context = BidiContext::create(textDirection == LTR ? 0 : 1, direction, | 139 context = BidiContext::create(textDirection == LTR ? 0 : 1, direction, |
136 isOverride); | 140 isOverride); |
137 } | 141 } |
138 | 142 |
139 BidiStatus(WTF::Unicode::CharDirection eorDir, | 143 BidiStatus(WTF::Unicode::CharDirection eorDir, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 const BidiStatus& status() const { return m_status; } | 256 const BidiStatus& status() const { return m_status; } |
253 void setStatus(const BidiStatus s) { | 257 void setStatus(const BidiStatus s) { |
254 ASSERT(s.context); | 258 ASSERT(s.context); |
255 m_status = s; | 259 m_status = s; |
256 m_paragraphDirectionality = | 260 m_paragraphDirectionality = |
257 s.context->dir() == WTF::Unicode::LeftToRight ? LTR : RTL; | 261 s.context->dir() == WTF::Unicode::LeftToRight ? LTR : RTL; |
258 } | 262 } |
259 | 263 |
260 MidpointState<Iterator>& midpointState() { return m_midpointState; } | 264 MidpointState<Iterator>& midpointState() { return m_midpointState; } |
261 | 265 |
262 // The current algorithm handles nested isolates one layer of nesting at a tim
e. | 266 // The current algorithm handles nested isolates one layer of nesting at a |
263 // But when we layout each isolated span, we will walk into (and ignore) all | 267 // time. But when we layout each isolated span, we will walk into (and |
264 // child isolated spans. | 268 // ignore) all child isolated spans. |
265 void enterIsolate() { m_nestedIsolateCount++; } | 269 void enterIsolate() { m_nestedIsolateCount++; } |
266 void exitIsolate() { | 270 void exitIsolate() { |
267 ASSERT(m_nestedIsolateCount >= 1); | 271 ASSERT(m_nestedIsolateCount >= 1); |
268 m_nestedIsolateCount--; | 272 m_nestedIsolateCount--; |
269 } | 273 } |
270 bool inIsolate() const { return m_nestedIsolateCount; } | 274 bool inIsolate() const { return m_nestedIsolateCount; } |
271 | 275 |
272 void embed(WTF::Unicode::CharDirection, BidiEmbeddingSource); | 276 void embed(WTF::Unicode::CharDirection, BidiEmbeddingSource); |
273 bool commitExplicitEmbedding(BidiRunList<Run>&); | 277 bool commitExplicitEmbedding(BidiRunList<Run>&); |
274 | 278 |
(...skipping 29 matching lines...) Expand all Loading... |
304 void setMidpointStateForIsolatedRun(Run&, const MidpointState<Iterator>&); | 308 void setMidpointStateForIsolatedRun(Run&, const MidpointState<Iterator>&); |
305 MidpointState<Iterator> midpointStateForIsolatedRun(Run&); | 309 MidpointState<Iterator> midpointStateForIsolatedRun(Run&); |
306 | 310 |
307 Iterator endOfLine() const { return m_endOfLine; } | 311 Iterator endOfLine() const { return m_endOfLine; } |
308 | 312 |
309 Run* trailingSpaceRun() const { return m_trailingSpaceRun; } | 313 Run* trailingSpaceRun() const { return m_trailingSpaceRun; } |
310 | 314 |
311 protected: | 315 protected: |
312 void increment() { m_current.increment(); } | 316 void increment() { m_current.increment(); } |
313 // FIXME: Instead of InlineBidiResolvers subclassing this method, we should | 317 // FIXME: Instead of InlineBidiResolvers subclassing this method, we should |
314 // pass in some sort of Traits object which knows how to create runs for appen
ding. | 318 // pass in some sort of Traits object which knows how to create runs for |
| 319 // appending. |
315 void appendRun(BidiRunList<Run>&); | 320 void appendRun(BidiRunList<Run>&); |
316 | 321 |
317 Run* addTrailingRun(BidiRunList<Run>&, | 322 Run* addTrailingRun(BidiRunList<Run>&, |
318 int, | 323 int, |
319 int, | 324 int, |
320 Run*, | 325 Run*, |
321 BidiContext*, | 326 BidiContext*, |
322 TextDirection) const { | 327 TextDirection) const { |
323 return 0; | 328 return 0; |
324 } | 329 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 } | 455 } |
451 | 456 |
452 template <class Iterator, class Run, class IsolatedRun> | 457 template <class Iterator, class Run, class IsolatedRun> |
453 void BidiResolver<Iterator, Run, IsolatedRun>::lowerExplicitEmbeddingLevel( | 458 void BidiResolver<Iterator, Run, IsolatedRun>::lowerExplicitEmbeddingLevel( |
454 BidiRunList<Run>& runs, | 459 BidiRunList<Run>& runs, |
455 WTF::Unicode::CharDirection from) { | 460 WTF::Unicode::CharDirection from) { |
456 using namespace WTF::Unicode; | 461 using namespace WTF::Unicode; |
457 | 462 |
458 if (!m_emptyRun && m_eor != m_last) { | 463 if (!m_emptyRun && m_eor != m_last) { |
459 checkDirectionInLowerRaiseEmbeddingLevel(); | 464 checkDirectionInLowerRaiseEmbeddingLevel(); |
460 // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi
.eor run or extend it through bidi.last | 465 // bidi.sor ... bidi.eor ... bidi.last eor; need to append the |
| 466 // bidi.sor-bidi.eor run or extend it through bidi.last |
461 if (from == LeftToRight) { | 467 if (from == LeftToRight) { |
462 // bidi.sor ... bidi.eor ... bidi.last L | 468 // bidi.sor ... bidi.eor ... bidi.last L |
463 if (m_status.eor == EuropeanNumber) { | 469 if (m_status.eor == EuropeanNumber) { |
464 if (m_status.lastStrong != LeftToRight) { | 470 if (m_status.lastStrong != LeftToRight) { |
465 m_direction = EuropeanNumber; | 471 m_direction = EuropeanNumber; |
466 appendRun(runs); | 472 appendRun(runs); |
467 } | 473 } |
468 } else if (m_status.eor == ArabicNumber) { | 474 } else if (m_status.eor == ArabicNumber) { |
469 m_direction = ArabicNumber; | 475 m_direction = ArabicNumber; |
470 appendRun(runs); | 476 appendRun(runs); |
(...skipping 20 matching lines...) Expand all Loading... |
491 | 497 |
492 template <class Iterator, class Run, class IsolatedRun> | 498 template <class Iterator, class Run, class IsolatedRun> |
493 void BidiResolver<Iterator, Run, IsolatedRun>::raiseExplicitEmbeddingLevel( | 499 void BidiResolver<Iterator, Run, IsolatedRun>::raiseExplicitEmbeddingLevel( |
494 BidiRunList<Run>& runs, | 500 BidiRunList<Run>& runs, |
495 WTF::Unicode::CharDirection from, | 501 WTF::Unicode::CharDirection from, |
496 WTF::Unicode::CharDirection to) { | 502 WTF::Unicode::CharDirection to) { |
497 using namespace WTF::Unicode; | 503 using namespace WTF::Unicode; |
498 | 504 |
499 if (!m_emptyRun && m_eor != m_last) { | 505 if (!m_emptyRun && m_eor != m_last) { |
500 checkDirectionInLowerRaiseEmbeddingLevel(); | 506 checkDirectionInLowerRaiseEmbeddingLevel(); |
501 // bidi.sor ... bidi.eor ... bidi.last eor; need to append the bidi.sor-bidi
.eor run or extend it through bidi.last | 507 // bidi.sor ... bidi.eor ... bidi.last eor; need to append the |
| 508 // bidi.sor-bidi.eor run or extend it through bidi.last |
502 if (to == LeftToRight) { | 509 if (to == LeftToRight) { |
503 // bidi.sor ... bidi.eor ... bidi.last L | 510 // bidi.sor ... bidi.eor ... bidi.last L |
504 if (m_status.eor == EuropeanNumber) { | 511 if (m_status.eor == EuropeanNumber) { |
505 if (m_status.lastStrong != LeftToRight) { | 512 if (m_status.lastStrong != LeftToRight) { |
506 m_direction = EuropeanNumber; | 513 m_direction = EuropeanNumber; |
507 appendRun(runs); | 514 appendRun(runs); |
508 } | 515 } |
509 } else if (m_status.eor == ArabicNumber) { | 516 } else if (m_status.eor == ArabicNumber) { |
510 m_direction = ArabicNumber; | 517 m_direction = ArabicNumber; |
511 appendRun(runs); | 518 appendRun(runs); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 trailingSpaceRun->m_level = 1; | 580 trailingSpaceRun->m_level = 1; |
574 } | 581 } |
575 m_trailingSpaceRun = trailingSpaceRun; | 582 m_trailingSpaceRun = trailingSpaceRun; |
576 } | 583 } |
577 | 584 |
578 template <class Iterator, class Run, class IsolatedRun> | 585 template <class Iterator, class Run, class IsolatedRun> |
579 bool BidiResolver<Iterator, Run, IsolatedRun>::commitExplicitEmbedding( | 586 bool BidiResolver<Iterator, Run, IsolatedRun>::commitExplicitEmbedding( |
580 BidiRunList<Run>& runs) { | 587 BidiRunList<Run>& runs) { |
581 // When we're "inIsolate()" we're resolving the parent context which | 588 // When we're "inIsolate()" we're resolving the parent context which |
582 // ignores (skips over) the isolated content, including embedding levels. | 589 // ignores (skips over) the isolated content, including embedding levels. |
583 // We should never accrue embedding levels while skipping over isolated conten
t. | 590 // We should never accrue embedding levels while skipping over isolated |
| 591 // content. |
584 ASSERT(!inIsolate() || m_currentExplicitEmbeddingSequence.isEmpty()); | 592 ASSERT(!inIsolate() || m_currentExplicitEmbeddingSequence.isEmpty()); |
585 | 593 |
586 using namespace WTF::Unicode; | 594 using namespace WTF::Unicode; |
587 | 595 |
588 unsigned char fromLevel = context()->level(); | 596 unsigned char fromLevel = context()->level(); |
589 RefPtr<BidiContext> toContext = context(); | 597 RefPtr<BidiContext> toContext = context(); |
590 | 598 |
591 for (size_t i = 0; i < m_currentExplicitEmbeddingSequence.size(); ++i) { | 599 for (size_t i = 0; i < m_currentExplicitEmbeddingSequence.size(); ++i) { |
592 BidiEmbedding embedding = m_currentExplicitEmbeddingSequence[i]; | 600 BidiEmbedding embedding = m_currentExplicitEmbeddingSequence[i]; |
593 if (embedding.direction() == PopDirectionalFormat) { | 601 if (embedding.direction() == PopDirectionalFormat) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 BidiRunList<Run>& runs) const { | 684 BidiRunList<Run>& runs) const { |
677 unsigned char levelLow = BidiContext::kMaxLevel; | 685 unsigned char levelLow = BidiContext::kMaxLevel; |
678 unsigned char levelHigh = 0; | 686 unsigned char levelHigh = 0; |
679 for (Run* run = runs.firstRun(); run; run = run->next()) { | 687 for (Run* run = runs.firstRun(); run; run = run->next()) { |
680 levelHigh = std::max(run->level(), levelHigh); | 688 levelHigh = std::max(run->level(), levelHigh); |
681 levelLow = std::min(run->level(), levelLow); | 689 levelLow = std::min(run->level(), levelLow); |
682 } | 690 } |
683 | 691 |
684 // This implements reordering of the line (L2 according to Bidi spec): | 692 // This implements reordering of the line (L2 according to Bidi spec): |
685 // http://unicode.org/reports/tr9/#L2 | 693 // http://unicode.org/reports/tr9/#L2 |
686 // L2. From the highest level found in the text to the lowest odd level on eac
h line, | 694 // L2. From the highest level found in the text to the lowest odd level on |
687 // reverse any contiguous sequence of characters that are at that level or hig
her. | 695 // each line, reverse any contiguous sequence of characters that are at that |
| 696 // level or higher. |
688 | 697 |
689 // Reversing is only done up to the lowest odd level. | 698 // Reversing is only done up to the lowest odd level. |
690 if (!(levelLow % 2)) | 699 if (!(levelLow % 2)) |
691 levelLow++; | 700 levelLow++; |
692 | 701 |
693 unsigned count = runs.runCount() - 1; | 702 unsigned count = runs.runCount() - 1; |
694 | 703 |
695 while (levelHigh >= levelLow) { | 704 while (levelHigh >= levelLow) { |
696 unsigned i = 0; | 705 unsigned i = 0; |
697 Run* run = runs.firstRun(); | 706 Run* run = runs.firstRun(); |
(...skipping 18 matching lines...) Expand all Loading... |
716 while (!m_current.atEnd()) { | 725 while (!m_current.atEnd()) { |
717 if (inIsolate()) { | 726 if (inIsolate()) { |
718 increment(); | 727 increment(); |
719 continue; | 728 continue; |
720 } | 729 } |
721 if (breakOnParagraph && m_current.atParagraphSeparator()) | 730 if (breakOnParagraph && m_current.atParagraphSeparator()) |
722 break; | 731 break; |
723 UChar32 current = m_current.current(); | 732 UChar32 current = m_current.current(); |
724 if (UNLIKELY(U16_IS_SURROGATE(current))) { | 733 if (UNLIKELY(U16_IS_SURROGATE(current))) { |
725 increment(); | 734 increment(); |
726 // If this not the high part of the surrogate pair, then drop it and move
to the next. | 735 // If this not the high part of the surrogate pair, then drop it and move |
| 736 // to the next. |
727 if (!U16_IS_SURROGATE_LEAD(current)) | 737 if (!U16_IS_SURROGATE_LEAD(current)) |
728 continue; | 738 continue; |
729 UChar high = static_cast<UChar>(current); | 739 UChar high = static_cast<UChar>(current); |
730 if (m_current.atEnd()) | 740 if (m_current.atEnd()) |
731 continue; | 741 continue; |
732 UChar low = m_current.current(); | 742 UChar low = m_current.current(); |
733 // Verify the low part. If invalid, then assume an invalid surrogate pair
and retry. | 743 // Verify the low part. If invalid, then assume an invalid surrogate pair |
| 744 // and retry. |
734 if (!U16_IS_TRAIL(low)) | 745 if (!U16_IS_TRAIL(low)) |
735 continue; | 746 continue; |
736 current = U16_GET_SUPPLEMENTARY(high, low); | 747 current = U16_GET_SUPPLEMENTARY(high, low); |
737 } | 748 } |
738 WTF::Unicode::CharDirection charDirection = | 749 WTF::Unicode::CharDirection charDirection = |
739 WTF::Unicode::direction(current); | 750 WTF::Unicode::direction(current); |
740 if (charDirection == WTF::Unicode::LeftToRight) { | 751 if (charDirection == WTF::Unicode::LeftToRight) { |
741 if (hasStrongDirectionality) | 752 if (hasStrongDirectionality) |
742 *hasStrongDirectionality = true; | 753 *hasStrongDirectionality = true; |
743 return LTR; | 754 return LTR; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
846 if (context()->override() && dirCurrent != RightToLeftEmbedding && | 857 if (context()->override() && dirCurrent != RightToLeftEmbedding && |
847 dirCurrent != LeftToRightEmbedding && | 858 dirCurrent != LeftToRightEmbedding && |
848 dirCurrent != RightToLeftOverride && | 859 dirCurrent != RightToLeftOverride && |
849 dirCurrent != LeftToRightOverride && | 860 dirCurrent != LeftToRightOverride && |
850 dirCurrent != PopDirectionalFormat) | 861 dirCurrent != PopDirectionalFormat) |
851 dirCurrent = context()->dir(); | 862 dirCurrent = context()->dir(); |
852 else if (dirCurrent == NonSpacingMark) | 863 else if (dirCurrent == NonSpacingMark) |
853 dirCurrent = m_status.last; | 864 dirCurrent = m_status.last; |
854 } | 865 } |
855 | 866 |
856 // We ignore all character directionality while in unicode-bidi: isolate spa
ns. | 867 // We ignore all character directionality while in unicode-bidi: isolate |
857 // We'll handle ordering the isolated characters in a second pass. | 868 // spans. We'll handle ordering the isolated characters in a second pass. |
858 if (inIsolate()) | 869 if (inIsolate()) |
859 dirCurrent = OtherNeutral; | 870 dirCurrent = OtherNeutral; |
860 | 871 |
861 ASSERT(m_status.eor != OtherNeutral || m_eor.atEnd()); | 872 ASSERT(m_status.eor != OtherNeutral || m_eor.atEnd()); |
862 switch (dirCurrent) { | 873 switch (dirCurrent) { |
863 // embedding and overrides (X1-X9 in the Bidi specs) | 874 // embedding and overrides (X1-X9 in the Bidi specs) |
864 case RightToLeftEmbedding: | 875 case RightToLeftEmbedding: |
865 case LeftToRightEmbedding: | 876 case LeftToRightEmbedding: |
866 case RightToLeftOverride: | 877 case RightToLeftOverride: |
867 case LeftToRightOverride: | 878 case LeftToRightOverride: |
(...skipping 18 matching lines...) Expand all Loading... |
886 case EuropeanNumberSeparator: | 897 case EuropeanNumberSeparator: |
887 case EuropeanNumberTerminator: | 898 case EuropeanNumberTerminator: |
888 case CommonNumberSeparator: | 899 case CommonNumberSeparator: |
889 case BoundaryNeutral: | 900 case BoundaryNeutral: |
890 case BlockSeparator: | 901 case BlockSeparator: |
891 case SegmentSeparator: | 902 case SegmentSeparator: |
892 case WhiteSpaceNeutral: | 903 case WhiteSpaceNeutral: |
893 case OtherNeutral: | 904 case OtherNeutral: |
894 if (m_status.eor == EuropeanNumber) { | 905 if (m_status.eor == EuropeanNumber) { |
895 if (m_status.lastStrong != LeftToRight) { | 906 if (m_status.lastStrong != LeftToRight) { |
896 // the numbers need to be on a higher embedding level, so let's
close that run | 907 // the numbers need to be on a higher embedding level, so let's |
| 908 // close that run |
897 m_direction = EuropeanNumber; | 909 m_direction = EuropeanNumber; |
898 appendRun(m_runs); | 910 appendRun(m_runs); |
899 if (context()->dir() != LeftToRight) { | 911 if (context()->dir() != LeftToRight) { |
900 // the neutrals take the embedding direction, which is R | 912 // the neutrals take the embedding direction, which is R |
901 m_eor = m_last; | 913 m_eor = m_last; |
902 m_direction = RightToLeft; | 914 m_direction = RightToLeft; |
903 appendRun(m_runs); | 915 appendRun(m_runs); |
904 } | 916 } |
905 } | 917 } |
906 } else if (m_status.eor == ArabicNumber) { | 918 } else if (m_status.eor == ArabicNumber) { |
907 // Arabic numbers are always on a higher embedding level, so let's
close that run | 919 // Arabic numbers are always on a higher embedding level, so let's |
| 920 // close that run |
908 m_direction = ArabicNumber; | 921 m_direction = ArabicNumber; |
909 appendRun(m_runs); | 922 appendRun(m_runs); |
910 if (context()->dir() != LeftToRight) { | 923 if (context()->dir() != LeftToRight) { |
911 // the neutrals take the embedding direction, which is R | 924 // the neutrals take the embedding direction, which is R |
912 m_eor = m_last; | 925 m_eor = m_last; |
913 m_direction = RightToLeft; | 926 m_direction = RightToLeft; |
914 appendRun(m_runs); | 927 appendRun(m_runs); |
915 } | 928 } |
916 } else if (m_status.lastStrong != LeftToRight) { | 929 } else if (m_status.lastStrong != LeftToRight) { |
917 // last stuff takes embedding dir | 930 // last stuff takes embedding dir |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 if (m_status.eor == EuropeanNumber) | 1002 if (m_status.eor == EuropeanNumber) |
990 break; | 1003 break; |
991 case EuropeanNumberTerminator: | 1004 case EuropeanNumberTerminator: |
992 case BoundaryNeutral: | 1005 case BoundaryNeutral: |
993 case BlockSeparator: | 1006 case BlockSeparator: |
994 case SegmentSeparator: | 1007 case SegmentSeparator: |
995 case WhiteSpaceNeutral: | 1008 case WhiteSpaceNeutral: |
996 case OtherNeutral: | 1009 case OtherNeutral: |
997 if (m_status.eor == EuropeanNumber) { | 1010 if (m_status.eor == EuropeanNumber) { |
998 if (m_status.lastStrong == RightToLeft) { | 1011 if (m_status.lastStrong == RightToLeft) { |
999 // ENs on both sides behave like Rs, so the neutrals should be
R. | 1012 // ENs on both sides behave like Rs, so the neutrals should be |
1000 // Terminate the EN run. | 1013 // R. Terminate the EN run. |
1001 appendRun(m_runs); | 1014 appendRun(m_runs); |
1002 // Make an R run. | 1015 // Make an R run. |
1003 m_eor = m_status.last == EuropeanNumberTerminator | 1016 m_eor = m_status.last == EuropeanNumberTerminator |
1004 ? m_lastBeforeET | 1017 ? m_lastBeforeET |
1005 : m_last; | 1018 : m_last; |
1006 m_direction = RightToLeft; | 1019 m_direction = RightToLeft; |
1007 appendRun(m_runs); | 1020 appendRun(m_runs); |
1008 // Begin a new EN run. | 1021 // Begin a new EN run. |
1009 m_direction = EuropeanNumber; | 1022 m_direction = EuropeanNumber; |
1010 } | 1023 } |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 } | 1117 } |
1105 break; | 1118 break; |
1106 | 1119 |
1107 // boundary neutrals should be ignored | 1120 // boundary neutrals should be ignored |
1108 case BoundaryNeutral: | 1121 case BoundaryNeutral: |
1109 if (m_eor == m_last) | 1122 if (m_eor == m_last) |
1110 m_eor = m_current; | 1123 m_eor = m_current; |
1111 break; | 1124 break; |
1112 // neutrals | 1125 // neutrals |
1113 case BlockSeparator: | 1126 case BlockSeparator: |
1114 // ### what do we do with newline and paragraph seperators that come to
here? | 1127 // ### what do we do with newline and paragraph seperators that come to |
| 1128 // here? |
1115 break; | 1129 break; |
1116 case SegmentSeparator: | 1130 case SegmentSeparator: |
1117 // ### implement rule L1 | 1131 // ### implement rule L1 |
1118 break; | 1132 break; |
1119 case WhiteSpaceNeutral: | 1133 case WhiteSpaceNeutral: |
1120 break; | 1134 break; |
1121 case OtherNeutral: | 1135 case OtherNeutral: |
1122 break; | 1136 break; |
1123 default: | 1137 default: |
1124 break; | 1138 break; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 template <class Iterator, class Run, class IsolatedRun> | 1215 template <class Iterator, class Run, class IsolatedRun> |
1202 MidpointState<Iterator> | 1216 MidpointState<Iterator> |
1203 BidiResolver<Iterator, Run, IsolatedRun>::midpointStateForIsolatedRun( | 1217 BidiResolver<Iterator, Run, IsolatedRun>::midpointStateForIsolatedRun( |
1204 Run& run) { | 1218 Run& run) { |
1205 return m_midpointStateForIsolatedRun.take(&run); | 1219 return m_midpointStateForIsolatedRun.take(&run); |
1206 } | 1220 } |
1207 | 1221 |
1208 } // namespace blink | 1222 } // namespace blink |
1209 | 1223 |
1210 #endif // BidiResolver_h | 1224 #endif // BidiResolver_h |
OLD | NEW |