| 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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   165 // BidiResolver is WebKit's implementation of the Unicode Bidi Algorithm |   165 // BidiResolver is WebKit's implementation of the Unicode Bidi Algorithm | 
|   166 // http://unicode.org/reports/tr9 |   166 // http://unicode.org/reports/tr9 | 
|   167 template <class Iterator, class Run> class BidiResolver { |   167 template <class Iterator, class Run> class BidiResolver { | 
|   168     WTF_MAKE_NONCOPYABLE(BidiResolver); |   168     WTF_MAKE_NONCOPYABLE(BidiResolver); | 
|   169 public: |   169 public: | 
|   170     BidiResolver() |   170     BidiResolver() | 
|   171         : m_direction(WTF::Unicode::OtherNeutral) |   171         : m_direction(WTF::Unicode::OtherNeutral) | 
|   172         , m_reachedEndOfLine(false) |   172         , m_reachedEndOfLine(false) | 
|   173         , m_emptyRun(true) |   173         , m_emptyRun(true) | 
|   174         , m_nestedIsolateCount(0) |   174         , m_nestedIsolateCount(0) | 
 |   175         , m_trailingSpaceRun(0) | 
|   175     { |   176     { | 
|   176     } |   177     } | 
|   177  |   178  | 
|   178 #ifndef NDEBUG |   179 #ifndef NDEBUG | 
|   179     ~BidiResolver(); |   180     ~BidiResolver(); | 
|   180 #endif |   181 #endif | 
|   181  |   182  | 
|   182     const Iterator& position() const { return m_current; } |   183     const Iterator& position() const { return m_current; } | 
|   183     Iterator& position() { return m_current; } |   184     Iterator& position() { return m_current; } | 
|   184     void setPositionIgnoringNestedIsolates(const Iterator& position) { m_current
       = position; } |   185     void setPositionIgnoringNestedIsolates(const Iterator& position) { m_current
       = position; } | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|   196     void setEorDir(WTF::Unicode::Direction eorDir) { m_status.eor = eorDir; } |   197     void setEorDir(WTF::Unicode::Direction eorDir) { m_status.eor = eorDir; } | 
|   197  |   198  | 
|   198     WTF::Unicode::Direction dir() const { return m_direction; } |   199     WTF::Unicode::Direction dir() const { return m_direction; } | 
|   199     void setDir(WTF::Unicode::Direction d) { m_direction = d; } |   200     void setDir(WTF::Unicode::Direction d) { m_direction = d; } | 
|   200  |   201  | 
|   201     const BidiStatus& status() const { return m_status; } |   202     const BidiStatus& status() const { return m_status; } | 
|   202     void setStatus(const BidiStatus s) |   203     void setStatus(const BidiStatus s) | 
|   203     { |   204     { | 
|   204         ASSERT(s.context); |   205         ASSERT(s.context); | 
|   205         m_status = s; |   206         m_status = s; | 
 |   207         m_paragraphDirectionality = s.context->dir() == WTF::Unicode::LeftToRigh
      t ? LTR : RTL; | 
|   206     } |   208     } | 
|   207  |   209  | 
|   208     MidpointState<Iterator>& midpointState() { return m_midpointState; } |   210     MidpointState<Iterator>& midpointState() { return m_midpointState; } | 
|   209  |   211  | 
|   210     // The current algorithm handles nested isolates one layer of nesting at a t
      ime. |   212     // The current algorithm handles nested isolates one layer of nesting at a t
      ime. | 
|   211     // But when we layout each isolated span, we will walk into (and ignore) all |   213     // But when we layout each isolated span, we will walk into (and ignore) all | 
|   212     // child isolated spans. |   214     // child isolated spans. | 
|   213     void enterIsolate() { m_nestedIsolateCount++; } |   215     void enterIsolate() { m_nestedIsolateCount++; } | 
|   214     void exitIsolate() { ASSERT(m_nestedIsolateCount >= 1); m_nestedIsolateCount
      --; } |   216     void exitIsolate() { ASSERT(m_nestedIsolateCount >= 1); m_nestedIsolateCount
      --; } | 
|   215     bool inIsolate() const { return m_nestedIsolateCount; } |   217     bool inIsolate() const { return m_nestedIsolateCount; } | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|   229  |   231  | 
|   230     bool isEndOfLine(const Iterator& end) { return m_current == end || m_current
      .atEnd(); } |   232     bool isEndOfLine(const Iterator& end) { return m_current == end || m_current
      .atEnd(); } | 
|   231  |   233  | 
|   232     TextDirection determineParagraphDirectionality(bool* hasStrongDirectionality
       = 0); |   234     TextDirection determineParagraphDirectionality(bool* hasStrongDirectionality
       = 0); | 
|   233  |   235  | 
|   234     void setMidpointStateForIsolatedRun(Run*, const MidpointState<Iterator>&); |   236     void setMidpointStateForIsolatedRun(Run*, const MidpointState<Iterator>&); | 
|   235     MidpointState<Iterator> midpointStateForIsolatedRun(Run*); |   237     MidpointState<Iterator> midpointStateForIsolatedRun(Run*); | 
|   236  |   238  | 
|   237     Iterator endOfLine() const { return m_endOfLine; } |   239     Iterator endOfLine() const { return m_endOfLine; } | 
|   238  |   240  | 
 |   241     Run* trailingSpaceRun() const { return m_trailingSpaceRun; } | 
 |   242  | 
|   239 protected: |   243 protected: | 
|   240     void increment() { m_current.increment(); } |   244     void increment() { m_current.increment(); } | 
|   241     // FIXME: Instead of InlineBidiResolvers subclassing this method, we should |   245     // FIXME: Instead of InlineBidiResolvers subclassing this method, we should | 
|   242     // pass in some sort of Traits object which knows how to create runs for app
      ending. |   246     // pass in some sort of Traits object which knows how to create runs for app
      ending. | 
|   243     void appendRun(); |   247     void appendRun(); | 
|   244  |   248  | 
 |   249     Run* addTrailingRun(int, int, Run*, BidiContext*, TextDirection) { return 0;
       } | 
|   245     Iterator m_current; |   250     Iterator m_current; | 
|   246     // sor and eor are "start of run" and "end of run" respectively and correpon
      d |   251     // sor and eor are "start of run" and "end of run" respectively and correpon
      d | 
|   247     // to abreviations used in UBA spec: http://unicode.org/reports/tr9/#BD7 |   252     // to abreviations used in UBA spec: http://unicode.org/reports/tr9/#BD7 | 
|   248     Iterator m_sor; // Points to the first character in the current run. |   253     Iterator m_sor; // Points to the first character in the current run. | 
|   249     Iterator m_eor; // Points to the last character in the current run. |   254     Iterator m_eor; // Points to the last character in the current run. | 
|   250     Iterator m_last; |   255     Iterator m_last; | 
|   251     BidiStatus m_status; |   256     BidiStatus m_status; | 
|   252     WTF::Unicode::Direction m_direction; |   257     WTF::Unicode::Direction m_direction; | 
|   253     // m_endOfRunAtEndOfLine is "the position last eor in the end of line" |   258     // m_endOfRunAtEndOfLine is "the position last eor in the end of line" | 
|   254     Iterator m_endOfRunAtEndOfLine; |   259     Iterator m_endOfRunAtEndOfLine; | 
|   255     Iterator m_endOfLine; |   260     Iterator m_endOfLine; | 
|   256     bool m_reachedEndOfLine; |   261     bool m_reachedEndOfLine; | 
|   257     Iterator m_lastBeforeET; // Before a EuropeanNumberTerminator |   262     Iterator m_lastBeforeET; // Before a EuropeanNumberTerminator | 
|   258     bool m_emptyRun; |   263     bool m_emptyRun; | 
|   259  |   264  | 
|   260     // FIXME: This should not belong to the resolver, but rather be passed |   265     // FIXME: This should not belong to the resolver, but rather be passed | 
|   261     // into createBidiRunsForLine by the caller. |   266     // into createBidiRunsForLine by the caller. | 
|   262     BidiRunList<Run> m_runs; |   267     BidiRunList<Run> m_runs; | 
|   263  |   268  | 
|   264     MidpointState<Iterator> m_midpointState; |   269     MidpointState<Iterator> m_midpointState; | 
|   265  |   270  | 
|   266     unsigned m_nestedIsolateCount; |   271     unsigned m_nestedIsolateCount; | 
|   267     Vector<Run*> m_isolatedRuns; |   272     Vector<Run*> m_isolatedRuns; | 
 |   273     Run* m_trailingSpaceRun; | 
 |   274     TextDirection m_paragraphDirectionality; | 
|   268  |   275  | 
|   269 private: |   276 private: | 
|   270     void raiseExplicitEmbeddingLevel(WTF::Unicode::Direction from, WTF::Unicode:
      :Direction to); |   277     void raiseExplicitEmbeddingLevel(WTF::Unicode::Direction from, WTF::Unicode:
      :Direction to); | 
|   271     void lowerExplicitEmbeddingLevel(WTF::Unicode::Direction from); |   278     void lowerExplicitEmbeddingLevel(WTF::Unicode::Direction from); | 
|   272     void checkDirectionInLowerRaiseEmbeddingLevel(); |   279     void checkDirectionInLowerRaiseEmbeddingLevel(); | 
|   273  |   280  | 
|   274     void updateStatusLastFromCurrentDirection(WTF::Unicode::Direction); |   281     void updateStatusLastFromCurrentDirection(WTF::Unicode::Direction); | 
|   275     void reorderRunsFromLevels(); |   282     void reorderRunsFromLevels(); | 
|   276  |   283  | 
 |   284     bool needsToApplyL1Rule() { return false; } | 
 |   285     int findFirstTrailingSpaceAtRun(Run*) { return 0; } | 
 |   286     // http://www.unicode.org/reports/tr9/#L1 | 
 |   287     void applyL1Rule(); | 
 |   288  | 
|   277     Vector<BidiEmbedding, 8> m_currentExplicitEmbeddingSequence; |   289     Vector<BidiEmbedding, 8> m_currentExplicitEmbeddingSequence; | 
|   278     HashMap<Run *, MidpointState<Iterator> > m_midpointStateForIsolatedRun; |   290     HashMap<Run *, MidpointState<Iterator> > m_midpointStateForIsolatedRun; | 
|   279 }; |   291 }; | 
|   280  |   292  | 
|   281 #ifndef NDEBUG |   293 #ifndef NDEBUG | 
|   282 template <class Iterator, class Run> |   294 template <class Iterator, class Run> | 
|   283 BidiResolver<Iterator, Run>::~BidiResolver() |   295 BidiResolver<Iterator, Run>::~BidiResolver() | 
|   284 { |   296 { | 
|   285     // The owner of this resolver should have handled the isolated runs. |   297     // The owner of this resolver should have handled the isolated runs. | 
|   286     ASSERT(m_isolatedRuns.isEmpty()); |   298     ASSERT(m_isolatedRuns.isEmpty()); | 
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   410  |   422  | 
|   411     appendRun(); |   423     appendRun(); | 
|   412     m_emptyRun = true; |   424     m_emptyRun = true; | 
|   413  |   425  | 
|   414     setLastDir(to); |   426     setLastDir(to); | 
|   415     setLastStrongDir(to); |   427     setLastStrongDir(to); | 
|   416     m_eor = Iterator(); |   428     m_eor = Iterator(); | 
|   417 } |   429 } | 
|   418  |   430  | 
|   419 template <class Iterator, class Run> |   431 template <class Iterator, class Run> | 
 |   432 void BidiResolver<Iterator, Run>::applyL1Rule() | 
 |   433 { | 
 |   434     ASSERT(m_runs.runCount()); | 
 |   435     if (!needsToApplyL1Rule()) | 
 |   436         return; | 
 |   437  | 
 |   438     Run* trailingSpaceRun = m_runs.logicallyLastRun(); | 
 |   439  | 
 |   440     int firstSpace = findFirstTrailingSpaceAtRun(trailingSpaceRun); | 
 |   441     if (firstSpace == trailingSpaceRun->stop()) | 
 |   442         return; | 
 |   443  | 
 |   444     bool shouldReorder = trailingSpaceRun != (m_paragraphDirectionality == LTR ?
       m_runs.lastRun() : m_runs.firstRun()); | 
 |   445     if (firstSpace != trailingSpaceRun->start()) { | 
 |   446         BidiContext* baseContext = context(); | 
 |   447         while (BidiContext* parent = baseContext->parent()) | 
 |   448             baseContext = parent; | 
 |   449  | 
 |   450         m_trailingSpaceRun = addTrailingRun(firstSpace, trailingSpaceRun->m_stop
      , trailingSpaceRun, baseContext, m_paragraphDirectionality); | 
 |   451         ASSERT(m_trailingSpaceRun); | 
 |   452         trailingSpaceRun->m_stop = firstSpace; | 
 |   453         return; | 
 |   454     } | 
 |   455     if (!shouldReorder) { | 
 |   456         m_trailingSpaceRun = trailingSpaceRun; | 
 |   457         return; | 
 |   458     } | 
 |   459  | 
 |   460     if (m_paragraphDirectionality == LTR) { | 
 |   461         m_runs.moveRunToEnd(trailingSpaceRun); | 
 |   462         trailingSpaceRun->m_level = 0; | 
 |   463     } else { | 
 |   464         m_runs.moveRunToBeginning(trailingSpaceRun); | 
 |   465         trailingSpaceRun->m_level = 1; | 
 |   466     } | 
 |   467     m_trailingSpaceRun = trailingSpaceRun; | 
 |   468 } | 
 |   469  | 
 |   470 template <class Iterator, class Run> | 
|   420 bool BidiResolver<Iterator, Run>::commitExplicitEmbedding() |   471 bool BidiResolver<Iterator, Run>::commitExplicitEmbedding() | 
|   421 { |   472 { | 
|   422     // When we're "inIsolate()" we're resolving the parent context which |   473     // When we're "inIsolate()" we're resolving the parent context which | 
|   423     // ignores (skips over) the isolated content, including embedding levels. |   474     // ignores (skips over) the isolated content, including embedding levels. | 
|   424     // We should never accrue embedding levels while skipping over isolated cont
      ent. |   475     // We should never accrue embedding levels while skipping over isolated cont
      ent. | 
|   425     ASSERT(!inIsolate() || m_currentExplicitEmbeddingSequence.isEmpty()); |   476     ASSERT(!inIsolate() || m_currentExplicitEmbeddingSequence.isEmpty()); | 
|   426  |   477  | 
|   427     using namespace WTF::Unicode; |   478     using namespace WTF::Unicode; | 
|   428  |   479  | 
|   429     unsigned char fromLevel = context()->level(); |   480     unsigned char fromLevel = context()->level(); | 
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   582         *hasStrongDirectionality = false; |   633         *hasStrongDirectionality = false; | 
|   583     return LTR; |   634     return LTR; | 
|   584 } |   635 } | 
|   585  |   636  | 
|   586 template <class Iterator, class Run> |   637 template <class Iterator, class Run> | 
|   587 void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
      ualDirectionOverride override, bool hardLineBreak) |   638 void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, Vis
      ualDirectionOverride override, bool hardLineBreak) | 
|   588 { |   639 { | 
|   589     using namespace WTF::Unicode; |   640     using namespace WTF::Unicode; | 
|   590  |   641  | 
|   591     ASSERT(m_direction == OtherNeutral); |   642     ASSERT(m_direction == OtherNeutral); | 
 |   643     m_trailingSpaceRun = 0; | 
|   592  |   644  | 
|   593     m_endOfLine = end; |   645     m_endOfLine = end; | 
|   594  |   646  | 
|   595     if (override != NoVisualOverride) { |   647     if (override != NoVisualOverride) { | 
|   596         m_emptyRun = false; |   648         m_emptyRun = false; | 
|   597         m_sor = m_current; |   649         m_sor = m_current; | 
|   598         m_eor = Iterator(); |   650         m_eor = Iterator(); | 
|   599         while (m_current != end && !m_current.atEnd()) { |   651         while (m_current != end && !m_current.atEnd()) { | 
|   600             m_eor = m_current; |   652             m_eor = m_current; | 
|   601             increment(); |   653             increment(); | 
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   978                 m_direction = OtherNeutral; |  1030                 m_direction = OtherNeutral; | 
|   979                 break; |  1031                 break; | 
|   980             } |  1032             } | 
|   981         } |  1033         } | 
|   982     } |  1034     } | 
|   983  |  1035  | 
|   984     m_runs.setLogicallyLastRun(m_runs.lastRun()); |  1036     m_runs.setLogicallyLastRun(m_runs.lastRun()); | 
|   985     reorderRunsFromLevels(); |  1037     reorderRunsFromLevels(); | 
|   986     m_endOfRunAtEndOfLine = Iterator(); |  1038     m_endOfRunAtEndOfLine = Iterator(); | 
|   987     m_endOfLine = Iterator(); |  1039     m_endOfLine = Iterator(); | 
 |  1040  | 
 |  1041     if (!hardLineBreak && m_runs.runCount()) | 
 |  1042         applyL1Rule(); | 
|   988 } |  1043 } | 
|   989  |  1044  | 
|   990 template <class Iterator, class Run> |  1045 template <class Iterator, class Run> | 
|   991 void BidiResolver<Iterator, Run>::setMidpointStateForIsolatedRun(Run* run, const
       MidpointState<Iterator>& midpoint) |  1046 void BidiResolver<Iterator, Run>::setMidpointStateForIsolatedRun(Run* run, const
       MidpointState<Iterator>& midpoint) | 
|   992 { |  1047 { | 
|   993     ASSERT(!m_midpointStateForIsolatedRun.contains(run)); |  1048     ASSERT(!m_midpointStateForIsolatedRun.contains(run)); | 
|   994     m_midpointStateForIsolatedRun.add(run, midpoint); |  1049     m_midpointStateForIsolatedRun.add(run, midpoint); | 
|   995 } |  1050 } | 
|   996  |  1051  | 
|   997 template<class Iterator, class Run> |  1052 template<class Iterator, class Run> | 
|   998 MidpointState<Iterator> BidiResolver<Iterator, Run>::midpointStateForIsolatedRun
      (Run* run) |  1053 MidpointState<Iterator> BidiResolver<Iterator, Run>::midpointStateForIsolatedRun
      (Run* run) | 
|   999 { |  1054 { | 
|  1000     return m_midpointStateForIsolatedRun.take(run); |  1055     return m_midpointStateForIsolatedRun.take(run); | 
|  1001 } |  1056 } | 
|  1002  |  1057  | 
|  1003  |  1058  | 
|  1004 } // namespace WebCore |  1059 } // namespace WebCore | 
|  1005  |  1060  | 
|  1006 #endif // BidiResolver_h |  1061 #endif // BidiResolver_h | 
| OLD | NEW |