| 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, 2009, 2010, 2011 Apple Inc. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. |
| 4 * All right reserved. | 4 * All right reserved. |
| 5 * Copyright (C) 2010 Google Inc. All rights reserved. | 5 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 6 * | 6 * |
| 7 * This library is free software; you can redistribute it and/or | 7 * This library is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Library General Public | 8 * modify it under the terms of the GNU Library General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2 of the License, or (at your option) any later version. | 10 * version 2 of the License, or (at your option) any later version. |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver, | 107 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver, |
| 108 LayoutObject* root, LayoutObject* startObject) | 108 LayoutObject* root, LayoutObject* startObject) |
| 109 { | 109 { |
| 110 if (root != startObject) { | 110 if (root != startObject) { |
| 111 LayoutObject* parent = startObject->parent(); | 111 LayoutObject* parent = startObject->parent(); |
| 112 setupResolverToResumeInIsolate(resolver, root, parent); | 112 setupResolverToResumeInIsolate(resolver, root, parent); |
| 113 notifyObserverEnteredObject(&resolver, LineLayoutItem(startObject)); | 113 notifyObserverEnteredObject(&resolver, LineLayoutItem(startObject)); |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 | 116 |
| 117 static void restoreIsolatedMidpointStates(InlineBidiResolver& topResolver, | |
| 118 InlineBidiResolver& isolatedResolver) | |
| 119 { | |
| 120 while (!isolatedResolver.isolatedRuns().isEmpty()) { | |
| 121 BidiRun* run = isolatedResolver.isolatedRuns().last(); | |
| 122 isolatedResolver.isolatedRuns().removeLast(); | |
| 123 topResolver.setMidpointStateForIsolatedRun(run, | |
| 124 isolatedResolver.midpointStateForIsolatedRun(run)); | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 void constructBidiRunsForLine(InlineBidiResolver& topResolver, | 117 void constructBidiRunsForLine(InlineBidiResolver& topResolver, |
| 129 BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, | 118 BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, |
| 130 VisualDirectionOverride override, bool previousLineBrokeCleanly, | 119 VisualDirectionOverride override, bool previousLineBrokeCleanly, |
| 131 bool isNewUBAParagraph) | 120 bool isNewUBAParagraph) |
| 132 { | 121 { |
| 133 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead | 122 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead |
| 134 // of the resolver owning the runs. | 123 // of the resolver owning the runs. |
| 135 ASSERT(&topResolver.runs() == &bidiRuns); | 124 ASSERT(&topResolver.runs() == &bidiRuns); |
| 136 ASSERT(topResolver.position() != endOfLine); | 125 ASSERT(topResolver.position() != endOfLine); |
| 137 const LayoutObject* currentRoot = topResolver.position().root(); | 126 const LayoutObject* currentRoot = topResolver.position().root(); |
| 138 topResolver.createBidiRunsForLine(endOfLine, override, | 127 topResolver.createBidiRunsForLine(endOfLine, override, |
| 139 previousLineBrokeCleanly); | 128 previousLineBrokeCleanly); |
| 140 struct BidiRunsWithRoot { | |
| 141 const LayoutObject* root; | |
| 142 Vector<BidiRun*> isolatedRuns; | |
| 143 }; | |
| 144 Vector<BidiRunsWithRoot> isolatedRunsStack; | |
| 145 | 129 |
| 146 while (true) { | 130 while (!topResolver.isolatedRuns().isEmpty()) { |
| 147 if (topResolver.isolatedRuns().isEmpty()) { | |
| 148 if (isolatedRunsStack.isEmpty()) | |
| 149 break; | |
| 150 topResolver.isolatedRuns().appendVector(isolatedRunsStack.last().iso
latedRuns); | |
| 151 ASSERT(!topResolver.isolatedRuns().isEmpty()); | |
| 152 currentRoot = isolatedRunsStack.last().root; | |
| 153 isolatedRunsStack.removeLast(); | |
| 154 } | |
| 155 | |
| 156 // It does not matter which order we resolve the runs as long as we | 131 // It does not matter which order we resolve the runs as long as we |
| 157 // resolve them all. | 132 // resolve them all. |
| 158 BidiRun* isolatedRun = topResolver.isolatedRuns().last(); | 133 BidiIsolatedRun isolatedRun = topResolver.isolatedRuns().last(); |
| 159 topResolver.isolatedRuns().removeLast(); | 134 topResolver.isolatedRuns().removeLast(); |
| 135 currentRoot = &isolatedRun.root; |
| 160 | 136 |
| 161 LayoutObject* startObj = isolatedRun->object(); | 137 LayoutObject* startObj = &isolatedRun.object; |
| 162 | 138 |
| 163 // Only inlines make sense with unicode-bidi: isolate (blocks are | 139 // Only inlines make sense with unicode-bidi: isolate (blocks are |
| 164 // already isolated). | 140 // already isolated). |
| 165 // FIXME: Because enterIsolate is not passed a LayoutObject, we have to | 141 // FIXME: Because enterIsolate is not passed a LayoutObject, we have to |
| 166 // crawl up the tree to see which parent inline is the isolate. We could | 142 // crawl up the tree to see which parent inline is the isolate. We could |
| 167 // change enterIsolate to take a LayoutObject and do this logic there, | 143 // change enterIsolate to take a LayoutObject and do this logic there, |
| 168 // but that would be a layering violation for BidiResolver (which knows | 144 // but that would be a layering violation for BidiResolver (which knows |
| 169 // nothing about LayoutObject). | 145 // nothing about LayoutObject). |
| 170 LayoutInline* isolatedInline = toLayoutInline( | 146 LayoutInline* isolatedInline = toLayoutInline( |
| 171 highestContainingIsolateWithinRoot(LineLayoutItem(startObj), | 147 highestContainingIsolateWithinRoot(LineLayoutItem(startObj), |
| 172 LineLayoutItem(const_cast<LayoutObject*>(currentRoot)))); | 148 LineLayoutItem(const_cast<LayoutObject*>(currentRoot)))); |
| 173 ASSERT(isolatedInline); | 149 ASSERT(isolatedInline); |
| 174 | 150 |
| 175 InlineBidiResolver isolatedResolver; | 151 InlineBidiResolver isolatedResolver; |
| 176 LineMidpointState& isolatedLineMidpointState = | 152 LineMidpointState& isolatedLineMidpointState = |
| 177 isolatedResolver.midpointState(); | 153 isolatedResolver.midpointState(); |
| 178 isolatedLineMidpointState = topResolver.midpointStateForIsolatedRun( | 154 isolatedLineMidpointState = topResolver.midpointStateForIsolatedRun( |
| 179 isolatedRun); | 155 isolatedRun.runToReplace); |
| 180 EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi(); | 156 EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi(); |
| 181 TextDirection direction; | 157 TextDirection direction; |
| 182 if (unicodeBidi == Plaintext) { | 158 if (unicodeBidi == Plaintext) { |
| 183 direction = determinePlaintextDirectionality(isolatedInline, | 159 direction = determinePlaintextDirectionality(isolatedInline, |
| 184 isNewUBAParagraph ? startObj : 0); | 160 isNewUBAParagraph ? startObj : 0); |
| 185 } else { | 161 } else { |
| 186 ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride); | 162 ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride); |
| 187 direction = isolatedInline->style()->direction(); | 163 direction = isolatedInline->style()->direction(); |
| 188 } | 164 } |
| 189 isolatedResolver.setStatus(statusWithDirection(direction, | 165 isolatedResolver.setStatus(statusWithDirection(direction, |
| 190 isOverride(unicodeBidi))); | 166 isOverride(unicodeBidi))); |
| 191 | 167 |
| 192 setupResolverToResumeInIsolate(isolatedResolver, isolatedInline, | 168 setupResolverToResumeInIsolate(isolatedResolver, isolatedInline, |
| 193 startObj); | 169 startObj); |
| 194 | 170 |
| 195 // The starting position is the beginning of the first run within the | 171 // The starting position is the beginning of the first run within the |
| 196 // isolate that was identified during the earlier call to | 172 // isolate that was identified during the earlier call to |
| 197 // createBidiRunsForLine. This can be but is not necessarily the first | 173 // createBidiRunsForLine. This can be but is not necessarily the first |
| 198 // run within the isolate. | 174 // run within the isolate. |
| 199 InlineIterator iter = InlineIterator(LineLayoutItem(isolatedInline), Lin
eLayoutItem(startObj), | 175 InlineIterator iter = InlineIterator(LineLayoutItem(isolatedInline), Lin
eLayoutItem(startObj), |
| 200 isolatedRun->m_start); | 176 isolatedRun.position); |
| 201 isolatedResolver.setPositionIgnoringNestedIsolates(iter); | 177 isolatedResolver.setPositionIgnoringNestedIsolates(iter); |
| 202 // We stop at the next end of line; we may re-enter this isolate in the | 178 // We stop at the next end of line; we may re-enter this isolate in the |
| 203 // next call to constructBidiRuns(). | 179 // next call to constructBidiRuns(). |
| 204 // FIXME: What should end and previousLineBrokeCleanly be? | 180 // FIXME: What should end and previousLineBrokeCleanly be? |
| 205 // rniwa says previousLineBrokeCleanly is just a WinIE hack and could | 181 // rniwa says previousLineBrokeCleanly is just a WinIE hack and could |
| 206 // always be false here? | 182 // always be false here? |
| 207 isolatedResolver.createBidiRunsForLine(endOfLine, NoVisualOverride, | 183 isolatedResolver.createBidiRunsForLine(endOfLine, NoVisualOverride, |
| 208 previousLineBrokeCleanly); | 184 previousLineBrokeCleanly); |
| 209 | 185 |
| 210 ASSERT(isolatedResolver.runs().runCount()); | 186 ASSERT(isolatedResolver.runs().runCount()); |
| 211 if (isolatedResolver.runs().runCount()) | 187 if (isolatedResolver.runs().runCount()) |
| 212 bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs()); | 188 bidiRuns.replaceRunWithRuns(&isolatedRun.runToReplace, isolatedResol
ver.runs()); |
| 213 | 189 |
| 214 // If we encountered any nested isolate runs, save them for later | 190 // If we encountered any nested isolate runs, save them for later |
| 215 // processing. | 191 // processing. |
| 216 if (!isolatedResolver.isolatedRuns().isEmpty()) { | 192 while (!isolatedResolver.isolatedRuns().isEmpty()) { |
| 217 isolatedRunsStack.resize(isolatedRunsStack.size() + 1); | 193 BidiIsolatedRun runWithContext = isolatedResolver.isolatedRuns().las
t(); |
| 218 isolatedRunsStack.last().isolatedRuns.appendVector( | 194 isolatedResolver.isolatedRuns().removeLast(); |
| 219 isolatedResolver.isolatedRuns()); | 195 topResolver.setMidpointStateForIsolatedRun(runWithContext.runToRepla
ce, |
| 220 isolatedRunsStack.last().root = isolatedInline; | 196 isolatedResolver.midpointStateForIsolatedRun(runWithContext.runT
oReplace)); |
| 221 restoreIsolatedMidpointStates(topResolver, isolatedResolver); | 197 topResolver.isolatedRuns().append(runWithContext); |
| 222 } | 198 } |
| 223 } | 199 } |
| 224 } | 200 } |
| 225 | 201 |
| 226 } // namespace blink | 202 } // namespace blink |
| OLD | NEW |