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