 Chromium Code Reviews
 Chromium Code Reviews Issue 46393003:
  BidiResolver should not append an isolated run if it is in a other line.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master
    
  
    Issue 46393003:
  BidiResolver should not append an isolated run if it is in a other line.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/blink.git@master| 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 |