Chromium Code Reviews| 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 215 void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = No VisualOverride, bool hardLineBreak = false); | 215 void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = No VisualOverride, bool hardLineBreak = false); |
| 216 | 216 |
| 217 BidiRunList<Run>& runs() { return m_runs; } | 217 BidiRunList<Run>& runs() { return m_runs; } |
| 218 | 218 |
| 219 // FIXME: This used to be part of deleteRuns() but was a layering violation. | 219 // FIXME: This used to be part of deleteRuns() but was a layering violation. |
| 220 // It's unclear if this is still needed. | 220 // It's unclear if this is still needed. |
| 221 void markCurrentRunEmpty() { m_emptyRun = true; } | 221 void markCurrentRunEmpty() { m_emptyRun = true; } |
| 222 | 222 |
| 223 Vector<Run*>& isolatedRuns() { return m_isolatedRuns; } | 223 Vector<Run*>& isolatedRuns() { return m_isolatedRuns; } |
| 224 | 224 |
| 225 bool isEndOfParagraph(const Iterator& end) { return m_current == end || m_cu rrent.atEnd(); } | 225 bool isEndOfLine(const Iterator& end) { return m_current == end || m_current .atEnd(); } |
| 226 | 226 |
| 227 TextDirection determineParagraphDirectionality(bool* hasStrongDirectionality = 0); | 227 TextDirection determineParagraphDirectionality(bool* hasStrongDirectionality = 0); |
| 228 | 228 |
| 229 void setMidpointStateForIsolatedRun(Run*, const MidpointState<Iterator>&); | 229 void setMidpointStateForIsolatedRun(Run*, const MidpointState<Iterator>&); |
| 230 MidpointState<Iterator> midpointStateForIsolatedRun(Run*); | 230 MidpointState<Iterator> midpointStateForIsolatedRun(Run*); |
| 231 | 231 |
| 232 protected: | 232 protected: |
| 233 void increment() { m_current.increment(); } | 233 void increment() { m_current.increment(); } |
| 234 // FIXME: Instead of InlineBidiResolvers subclassing this method, we should | 234 // FIXME: Instead of InlineBidiResolvers subclassing this method, we should |
| 235 // pass in some sort of Traits object which knows how to create runs for app ending. | 235 // pass in some sort of Traits object which knows how to create runs for app ending. |
| 236 void appendRun(); | 236 void appendRun(); |
| 237 | 237 |
| 238 Iterator m_current; | 238 Iterator m_current; |
| 239 // sor and eor are "start of run" and "end of run" respectively and correpon d | 239 // sor and eor are "start of run" and "end of run" respectively and correpon d |
| 240 // to abreviations used in UBA spec: http://unicode.org/reports/tr9/#BD7 | 240 // to abreviations used in UBA spec: http://unicode.org/reports/tr9/#BD7 |
| 241 Iterator m_sor; // Points to the first character in the current run. | 241 Iterator m_sor; // Points to the first character in the current run. |
| 242 Iterator m_eor; // Points to the last character in the current run. | 242 Iterator m_eor; // Points to the last character in the current run. |
| 243 Iterator m_last; | 243 Iterator m_last; |
| 244 BidiStatus m_status; | 244 BidiStatus m_status; |
| 245 WTF::Unicode::Direction m_direction; | 245 WTF::Unicode::Direction m_direction; |
| 246 Iterator endOfLine; | 246 Iterator m_endOfRunAtEndOfLine; |
| 247 Iterator m_endOfLine; | |
|
leviw_travelin_and_unemployed
2013/11/01 20:46:02
It may be good to put a comment explaining what th
| |
| 247 bool m_reachedEndOfLine; | 248 bool m_reachedEndOfLine; |
| 248 Iterator m_lastBeforeET; // Before a EuropeanNumberTerminator | 249 Iterator m_lastBeforeET; // Before a EuropeanNumberTerminator |
| 249 bool m_emptyRun; | 250 bool m_emptyRun; |
| 250 | 251 |
| 251 // FIXME: This should not belong to the resolver, but rather be passed | 252 // FIXME: This should not belong to the resolver, but rather be passed |
| 252 // into createBidiRunsForLine by the caller. | 253 // into createBidiRunsForLine by the caller. |
| 253 BidiRunList<Run> m_runs; | 254 BidiRunList<Run> m_runs; |
| 254 | 255 |
| 255 MidpointState<Iterator> m_midpointState; | 256 MidpointState<Iterator> m_midpointState; |
| 256 | 257 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 278 } | 279 } |
| 279 #endif | 280 #endif |
| 280 | 281 |
| 281 template <class Iterator, class Run> | 282 template <class Iterator, class Run> |
| 282 void BidiResolver<Iterator, Run>::appendRun() | 283 void BidiResolver<Iterator, Run>::appendRun() |
| 283 { | 284 { |
| 284 if (!m_emptyRun && !m_eor.atEnd()) { | 285 if (!m_emptyRun && !m_eor.atEnd()) { |
| 285 unsigned startOffset = m_sor.offset(); | 286 unsigned startOffset = m_sor.offset(); |
| 286 unsigned endOffset = m_eor.offset(); | 287 unsigned endOffset = m_eor.offset(); |
| 287 | 288 |
| 288 if (!endOfLine.atEnd() && endOffset >= endOfLine.offset()) { | 289 if (!m_endOfRunAtEndOfLine.atEnd() && endOffset >= m_endOfRunAtEndOfLine .offset()) { |
| 289 m_reachedEndOfLine = true; | 290 m_reachedEndOfLine = true; |
| 290 endOffset = endOfLine.offset(); | 291 endOffset = m_endOfRunAtEndOfLine.offset(); |
| 291 } | 292 } |
| 292 | 293 |
| 293 if (endOffset >= startOffset) | 294 if (endOffset >= startOffset) |
| 294 m_runs.addRun(new Run(startOffset, endOffset + 1, context(), m_direc tion)); | 295 m_runs.addRun(new Run(startOffset, endOffset + 1, context(), m_direc tion)); |
| 295 | 296 |
| 296 m_eor.increment(); | 297 m_eor.increment(); |
| 297 m_sor = m_eor; | 298 m_sor = m_eor; |
| 298 } | 299 } |
| 299 | 300 |
| 300 m_direction = WTF::Unicode::OtherNeutral; | 301 m_direction = WTF::Unicode::OtherNeutral; |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 appendRun(); | 581 appendRun(); |
| 581 m_runs.setLogicallyLastRun(m_runs.lastRun()); | 582 m_runs.setLogicallyLastRun(m_runs.lastRun()); |
| 582 if (override == VisualRightToLeftOverride && m_runs.runCount()) | 583 if (override == VisualRightToLeftOverride && m_runs.runCount()) |
| 583 m_runs.reverseRuns(0, m_runs.runCount() - 1); | 584 m_runs.reverseRuns(0, m_runs.runCount() - 1); |
| 584 return; | 585 return; |
| 585 } | 586 } |
| 586 | 587 |
| 587 m_emptyRun = true; | 588 m_emptyRun = true; |
| 588 | 589 |
| 589 m_eor = Iterator(); | 590 m_eor = Iterator(); |
| 591 m_endOfLine = end; | |
| 590 | 592 |
| 591 m_last = m_current; | 593 m_last = m_current; |
| 592 bool lastParagraphEnded = false; | 594 bool lastLineEnded = false; |
| 593 BidiResolver<Iterator, Run> stateAtEnd; | 595 BidiResolver<Iterator, Run> stateAtEnd; |
| 594 | 596 |
| 595 while (true) { | 597 while (true) { |
| 596 if (inIsolate() && m_emptyRun) { | 598 if (inIsolate() && m_emptyRun) { |
| 597 m_sor = m_current; | 599 m_sor = m_current; |
| 598 m_emptyRun = false; | 600 m_emptyRun = false; |
| 599 } | 601 } |
| 600 | 602 |
| 601 if (!lastParagraphEnded && isEndOfParagraph(end)) { | 603 if (!lastLineEnded && isEndOfLine(end)) { |
| 602 if (m_emptyRun) | 604 if (m_emptyRun) |
| 603 break; | 605 break; |
| 604 | 606 |
| 605 stateAtEnd.m_status = m_status; | 607 stateAtEnd.m_status = m_status; |
| 606 stateAtEnd.m_sor = m_sor; | 608 stateAtEnd.m_sor = m_sor; |
| 607 stateAtEnd.m_eor = m_eor; | 609 stateAtEnd.m_eor = m_eor; |
| 608 stateAtEnd.m_last = m_last; | 610 stateAtEnd.m_last = m_last; |
| 609 stateAtEnd.m_reachedEndOfLine = m_reachedEndOfLine; | 611 stateAtEnd.m_reachedEndOfLine = m_reachedEndOfLine; |
| 610 stateAtEnd.m_lastBeforeET = m_lastBeforeET; | 612 stateAtEnd.m_lastBeforeET = m_lastBeforeET; |
| 611 stateAtEnd.m_emptyRun = m_emptyRun; | 613 stateAtEnd.m_emptyRun = m_emptyRun; |
| 612 endOfLine = m_last; | 614 m_endOfRunAtEndOfLine = m_last; |
| 613 lastParagraphEnded = true; | 615 lastLineEnded = true; |
| 614 } | 616 } |
| 615 Direction dirCurrent; | 617 Direction dirCurrent; |
| 616 if (lastParagraphEnded && (hardLineBreak || m_current.atEnd())) { | 618 if (lastLineEnded && (hardLineBreak || m_current.atEnd())) { |
| 617 BidiContext* c = context(); | 619 BidiContext* c = context(); |
| 618 if (hardLineBreak) { | 620 if (hardLineBreak) { |
| 619 // A deviation from the Unicode Bidi Algorithm in order to match | 621 // A deviation from the Unicode Bidi Algorithm in order to match |
| 620 // WinIE and user expectations: hard line breaks reset bidi stat e | 622 // WinIE and user expectations: hard line breaks reset bidi stat e |
| 621 // coming from unicode bidi control characters, but not those fr om | 623 // coming from unicode bidi control characters, but not those fr om |
| 622 // DOM nodes with specified directionality | 624 // DOM nodes with specified directionality |
| 623 stateAtEnd.setContext(c->copyStackRemovingUnicodeEmbeddingContex ts()); | 625 stateAtEnd.setContext(c->copyStackRemovingUnicodeEmbeddingContex ts()); |
| 624 | 626 |
| 625 dirCurrent = stateAtEnd.context()->dir(); | 627 dirCurrent = stateAtEnd.context()->dir(); |
| 626 stateAtEnd.setEorDir(dirCurrent); | 628 stateAtEnd.setEorDir(dirCurrent); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 895 // ### implement rule L1 | 897 // ### implement rule L1 |
| 896 break; | 898 break; |
| 897 case WhiteSpaceNeutral: | 899 case WhiteSpaceNeutral: |
| 898 break; | 900 break; |
| 899 case OtherNeutral: | 901 case OtherNeutral: |
| 900 break; | 902 break; |
| 901 default: | 903 default: |
| 902 break; | 904 break; |
| 903 } | 905 } |
| 904 | 906 |
| 905 if (lastParagraphEnded && m_eor == m_current) { | 907 if (lastLineEnded && m_eor == m_current) { |
| 906 if (!m_reachedEndOfLine) { | 908 if (!m_reachedEndOfLine) { |
| 907 m_eor = endOfLine; | 909 m_eor = m_endOfRunAtEndOfLine; |
| 908 switch (m_status.eor) { | 910 switch (m_status.eor) { |
| 909 case LeftToRight: | 911 case LeftToRight: |
| 910 case RightToLeft: | 912 case RightToLeft: |
| 911 case ArabicNumber: | 913 case ArabicNumber: |
| 912 m_direction = m_status.eor; | 914 m_direction = m_status.eor; |
| 913 break; | 915 break; |
| 914 case EuropeanNumber: | 916 case EuropeanNumber: |
| 915 m_direction = m_status.lastStrong == LeftToRight ? LeftToRig ht : EuropeanNumber; | 917 m_direction = m_status.lastStrong == LeftToRight ? LeftToRig ht : EuropeanNumber; |
| 916 break; | 918 break; |
| 917 default: | 919 default: |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 935 m_last = m_current; | 937 m_last = m_current; |
| 936 | 938 |
| 937 if (m_emptyRun) { | 939 if (m_emptyRun) { |
| 938 m_sor = m_current; | 940 m_sor = m_current; |
| 939 m_emptyRun = false; | 941 m_emptyRun = false; |
| 940 } | 942 } |
| 941 | 943 |
| 942 increment(); | 944 increment(); |
| 943 if (!m_currentExplicitEmbeddingSequence.isEmpty()) { | 945 if (!m_currentExplicitEmbeddingSequence.isEmpty()) { |
| 944 bool committed = commitExplicitEmbedding(); | 946 bool committed = commitExplicitEmbedding(); |
| 945 if (committed && lastParagraphEnded) { | 947 if (committed && lastLineEnded) { |
| 946 m_current = end; | 948 m_current = end; |
| 947 m_status = stateAtEnd.m_status; | 949 m_status = stateAtEnd.m_status; |
| 948 m_sor = stateAtEnd.m_sor; | 950 m_sor = stateAtEnd.m_sor; |
| 949 m_eor = stateAtEnd.m_eor; | 951 m_eor = stateAtEnd.m_eor; |
| 950 m_last = stateAtEnd.m_last; | 952 m_last = stateAtEnd.m_last; |
| 951 m_reachedEndOfLine = stateAtEnd.m_reachedEndOfLine; | 953 m_reachedEndOfLine = stateAtEnd.m_reachedEndOfLine; |
| 952 m_lastBeforeET = stateAtEnd.m_lastBeforeET; | 954 m_lastBeforeET = stateAtEnd.m_lastBeforeET; |
| 953 m_emptyRun = stateAtEnd.m_emptyRun; | 955 m_emptyRun = stateAtEnd.m_emptyRun; |
| 954 m_direction = OtherNeutral; | 956 m_direction = OtherNeutral; |
| 955 break; | 957 break; |
| 956 } | 958 } |
| 957 } | 959 } |
| 958 } | 960 } |
| 959 | 961 |
| 960 m_runs.setLogicallyLastRun(m_runs.lastRun()); | 962 m_runs.setLogicallyLastRun(m_runs.lastRun()); |
| 961 reorderRunsFromLevels(); | 963 reorderRunsFromLevels(); |
| 962 endOfLine = Iterator(); | 964 m_endOfRunAtEndOfLine = Iterator(); |
| 965 m_endOfLine = Iterator(); | |
| 963 } | 966 } |
| 964 | 967 |
| 965 template <class Iterator, class Run> | 968 template <class Iterator, class Run> |
| 966 void BidiResolver<Iterator, Run>::setMidpointStateForIsolatedRun(Run* run, const MidpointState<Iterator>& midpoint) | 969 void BidiResolver<Iterator, Run>::setMidpointStateForIsolatedRun(Run* run, const MidpointState<Iterator>& midpoint) |
| 967 { | 970 { |
| 968 ASSERT(!m_midpointStateForIsolatedRun.contains(run)); | 971 ASSERT(!m_midpointStateForIsolatedRun.contains(run)); |
| 969 m_midpointStateForIsolatedRun.add(run, midpoint); | 972 m_midpointStateForIsolatedRun.add(run, midpoint); |
| 970 } | 973 } |
| 971 | 974 |
| 972 template<class Iterator, class Run> | 975 template<class Iterator, class Run> |
| 973 MidpointState<Iterator> BidiResolver<Iterator, Run>::midpointStateForIsolatedRun (Run* run) | 976 MidpointState<Iterator> BidiResolver<Iterator, Run>::midpointStateForIsolatedRun (Run* run) |
| 974 { | 977 { |
| 975 return m_midpointStateForIsolatedRun.take(run); | 978 return m_midpointStateForIsolatedRun.take(run); |
| 976 } | 979 } |
| 977 | 980 |
| 978 | 981 |
| 979 } // namespace WebCore | 982 } // namespace WebCore |
| 980 | 983 |
| 981 #endif // BidiResolver_h | 984 #endif // BidiResolver_h |
| OLD | NEW |