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 |