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. All r
ight reserved. | 3 * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r
ight reserved. |
4 * Copyright (C) 2010 Google Inc. All rights reserved. | 4 * Copyright (C) 2010 Google Inc. All rights reserved. |
5 * | 5 * |
6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 } | 446 } |
447 | 447 |
448 // Adding a pair of midpoints before a character will split it out into a new li
ne box. | 448 // Adding a pair of midpoints before a character will split it out into a new li
ne box. |
449 static inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointSta
te, InlineIterator& textParagraphSeparator) | 449 static inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointSta
te, InlineIterator& textParagraphSeparator) |
450 { | 450 { |
451 InlineIterator midpoint(0, textParagraphSeparator.m_obj, textParagraphSepara
tor.m_pos); | 451 InlineIterator midpoint(0, textParagraphSeparator.m_obj, textParagraphSepara
tor.m_pos); |
452 startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSepara
tor.m_obj, textParagraphSeparator.m_pos - 1)); | 452 startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSepara
tor.m_obj, textParagraphSeparator.m_pos - 1)); |
453 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparat
or.m_obj, textParagraphSeparator.m_pos)); | 453 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparat
or.m_obj, textParagraphSeparator.m_pos)); |
454 } | 454 } |
455 | 455 |
456 static inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBi
diResolver& resolver) | |
457 { | |
458 return new BidiRun(start, end, obj, resolver.context(), resolver.dir()); | |
459 } | |
460 | |
461 void RenderBlock::appendRunsForObject(BidiRunList<BidiRun>& runs, int start, int
end, RenderObject* obj, InlineBidiResolver& resolver) | 456 void RenderBlock::appendRunsForObject(BidiRunList<BidiRun>& runs, int start, int
end, RenderObject* obj, InlineBidiResolver& resolver) |
462 { | 457 { |
463 if (start > end || shouldSkipCreatingRunsForObject(obj)) | 458 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, resolver, App
endingRunsForObject, &runs); |
464 return; | |
465 | |
466 LineMidpointState& lineMidpointState = resolver.midpointState(); | |
467 bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointSta
te.numMidpoints); | |
468 InlineIterator nextMidpoint; | |
469 if (haveNextMidpoint) | |
470 nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidp
oint]; | |
471 if (lineMidpointState.betweenMidpoints) { | |
472 if (!(haveNextMidpoint && nextMidpoint.m_obj == obj)) | |
473 return; | |
474 // This is a new start point. Stop ignoring objects and | |
475 // adjust our start. | |
476 lineMidpointState.betweenMidpoints = false; | |
477 start = nextMidpoint.m_pos; | |
478 lineMidpointState.currentMidpoint++; | |
479 if (start < end) | |
480 return appendRunsForObject(runs, start, end, obj, resolver); | |
481 } else { | |
482 if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) { | |
483 runs.addRun(createRun(start, end, obj, resolver)); | |
484 return; | |
485 } | |
486 | |
487 // An end midpoint has been encountered within our object. We | |
488 // need to go ahead and append a run with our endpoint. | |
489 if (static_cast<int>(nextMidpoint.m_pos + 1) <= end) { | |
490 lineMidpointState.betweenMidpoints = true; | |
491 lineMidpointState.currentMidpoint++; | |
492 if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the
object and don't include any of it. | |
493 if (static_cast<int>(nextMidpoint.m_pos + 1) > start) | |
494 runs.addRun(createRun(start, nextMidpoint.m_pos + 1, obj, re
solver)); | |
495 return appendRunsForObject(runs, nextMidpoint.m_pos + 1, end, ob
j, resolver); | |
496 } | |
497 } else | |
498 runs.addRun(createRun(start, end, obj, resolver)); | |
499 } | |
500 } | 459 } |
501 | 460 |
502 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRo
otLineBox, bool isOnlyRun = false) | 461 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRo
otLineBox, bool isOnlyRun = false) |
503 { | 462 { |
504 if (isRootLineBox) | 463 if (isRootLineBox) |
505 return toRenderBlock(obj)->createAndAppendRootInlineBox(); | 464 return toRenderBlock(obj)->createAndAppendRootInlineBox(); |
506 | 465 |
507 if (obj->isText()) { | 466 if (obj->isText()) { |
508 InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox(); | 467 InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox(); |
509 // We only treat a box as text for a <br> if we are on a line by ourself
or in strict mode | 468 // We only treat a box as text for a <br> if we are on a line by ourself
or in strict mode |
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 | 1213 |
1255 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver,
RenderObject* root, RenderObject* startObject) | 1214 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver,
RenderObject* root, RenderObject* startObject) |
1256 { | 1215 { |
1257 if (root != startObject) { | 1216 if (root != startObject) { |
1258 RenderObject* parent = startObject->parent(); | 1217 RenderObject* parent = startObject->parent(); |
1259 setupResolverToResumeInIsolate(resolver, root, parent); | 1218 setupResolverToResumeInIsolate(resolver, root, parent); |
1260 notifyObserverEnteredObject(&resolver, startObject); | 1219 notifyObserverEnteredObject(&resolver, startObject); |
1261 } | 1220 } |
1262 } | 1221 } |
1263 | 1222 |
| 1223 static void restoreIsolatedMidpointStates(InlineBidiResolver& topResolver, Inlin
eBidiResolver& isolatedResolver) |
| 1224 { |
| 1225 while (!isolatedResolver.isolatedRuns().isEmpty()) { |
| 1226 BidiRun* run = isolatedResolver.isolatedRuns().last(); |
| 1227 isolatedResolver.isolatedRuns().removeLast(); |
| 1228 topResolver.setMidpointStateForIsolatedRun(run, isolatedResolver.midpoin
tStateForIsolatedRun(run)); |
| 1229 } |
| 1230 } |
| 1231 |
1264 // FIXME: BidiResolver should have this logic. | 1232 // FIXME: BidiResolver should have this logic. |
1265 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver,
BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirection
Override override, bool previousLineBrokeCleanly, bool isNewUBAParagraph) | 1233 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver,
BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirection
Override override, bool previousLineBrokeCleanly, bool isNewUBAParagraph) |
1266 { | 1234 { |
1267 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead | 1235 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead |
1268 // of the resolver owning the runs. | 1236 // of the resolver owning the runs. |
1269 ASSERT(&topResolver.runs() == &bidiRuns); | 1237 ASSERT(&topResolver.runs() == &bidiRuns); |
1270 ASSERT(topResolver.position() != endOfRuns); | 1238 ASSERT(topResolver.position() != endOfRuns); |
1271 RenderObject* currentRoot = topResolver.position().root(); | 1239 RenderObject* currentRoot = topResolver.position().root(); |
1272 topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeClea
nly); | 1240 topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeClea
nly); |
1273 | 1241 |
1274 while (!topResolver.isolatedRuns().isEmpty()) { | 1242 while (!topResolver.isolatedRuns().isEmpty()) { |
1275 // It does not matter which order we resolve the runs as long as we reso
lve them all. | 1243 // It does not matter which order we resolve the runs as long as we reso
lve them all. |
1276 BidiRun* isolatedRun = topResolver.isolatedRuns().last(); | 1244 BidiRun* isolatedRun = topResolver.isolatedRuns().last(); |
1277 topResolver.isolatedRuns().removeLast(); | 1245 topResolver.isolatedRuns().removeLast(); |
1278 | 1246 |
1279 RenderObject* startObj = isolatedRun->object(); | 1247 RenderObject* startObj = isolatedRun->object(); |
1280 | 1248 |
1281 // Only inlines make sense with unicode-bidi: isolate (blocks are alread
y isolated). | 1249 // Only inlines make sense with unicode-bidi: isolate (blocks are alread
y isolated). |
1282 // FIXME: Because enterIsolate is not passed a RenderObject, we have to
crawl up the | 1250 // FIXME: Because enterIsolate is not passed a RenderObject, we have to
crawl up the |
1283 // tree to see which parent inline is the isolate. We could change enter
Isolate | 1251 // tree to see which parent inline is the isolate. We could change enter
Isolate |
1284 // to take a RenderObject and do this logic there, but that would be a l
ayering | 1252 // to take a RenderObject and do this logic there, but that would be a l
ayering |
1285 // violation for BidiResolver (which knows nothing about RenderObject). | 1253 // violation for BidiResolver (which knows nothing about RenderObject). |
1286 RenderInline* isolatedInline = toRenderInline(highestContainingIsolateWi
thinRoot(startObj, currentRoot)); | 1254 RenderInline* isolatedInline = toRenderInline(highestContainingIsolateWi
thinRoot(startObj, currentRoot)); |
1287 ASSERT(isolatedInline); | 1255 ASSERT(isolatedInline); |
1288 | 1256 |
1289 InlineBidiResolver isolatedResolver; | 1257 InlineBidiResolver isolatedResolver; |
| 1258 LineMidpointState& isolatedLineMidpointState = isolatedResolver.midpoint
State(); |
| 1259 isolatedLineMidpointState = topResolver.midpointStateForIsolatedRun(isol
atedRun); |
1290 EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi(); | 1260 EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi(); |
1291 TextDirection direction = isolatedInline->style()->direction(); | 1261 TextDirection direction = isolatedInline->style()->direction(); |
1292 if (unicodeBidi == Plaintext) { | 1262 if (unicodeBidi == Plaintext) { |
1293 if (isNewUBAParagraph) | 1263 if (isNewUBAParagraph) |
1294 direction = determinePlaintextDirectionality(isolatedInline, sta
rtObj); | 1264 direction = determinePlaintextDirectionality(isolatedInline, sta
rtObj); |
1295 else | 1265 else |
1296 direction = determinePlaintextDirectionality(isolatedInline); | 1266 direction = determinePlaintextDirectionality(isolatedInline); |
1297 } else { | 1267 } else { |
1298 ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride); | 1268 ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride); |
1299 direction = isolatedInline->style()->direction(); | 1269 direction = isolatedInline->style()->direction(); |
(...skipping 16 matching lines...) Expand all Loading... |
1316 // We're not guaranteed to get any BidiRuns in the previous step. If we
don't, we allow the placeholder | 1286 // We're not guaranteed to get any BidiRuns in the previous step. If we
don't, we allow the placeholder |
1317 // itself to be turned into an InlineBox. We can't remove it here withou
t potentially losing track of | 1287 // itself to be turned into an InlineBox. We can't remove it here withou
t potentially losing track of |
1318 // the logically last run. | 1288 // the logically last run. |
1319 if (isolatedResolver.runs().runCount()) | 1289 if (isolatedResolver.runs().runCount()) |
1320 bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs()); | 1290 bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs()); |
1321 | 1291 |
1322 // If we encountered any nested isolate runs, just move them | 1292 // If we encountered any nested isolate runs, just move them |
1323 // to the top resolver's list for later processing. | 1293 // to the top resolver's list for later processing. |
1324 if (!isolatedResolver.isolatedRuns().isEmpty()) { | 1294 if (!isolatedResolver.isolatedRuns().isEmpty()) { |
1325 topResolver.isolatedRuns().append(isolatedResolver.isolatedRuns()); | 1295 topResolver.isolatedRuns().append(isolatedResolver.isolatedRuns()); |
1326 isolatedResolver.isolatedRuns().clear(); | |
1327 currentRoot = isolatedInline; | 1296 currentRoot = isolatedInline; |
| 1297 restoreIsolatedMidpointStates(topResolver, isolatedResolver); |
1328 } | 1298 } |
1329 } | 1299 } |
1330 } | 1300 } |
1331 | 1301 |
1332 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli
neIterator& segmentEnd) | 1302 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli
neIterator& segmentEnd) |
1333 { | 1303 { |
1334 return segmentStart == segmentEnd; | 1304 return segmentStart == segmentEnd; |
1335 } | 1305 } |
1336 | 1306 |
1337 static inline void constructBidiRunsForLine(const RenderBlock* block, InlineBidi
Resolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end
OfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, bool is
NewUBAParagraph) | 1307 static inline void constructBidiRunsForLine(const RenderBlock* block, InlineBidi
Resolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end
OfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, bool is
NewUBAParagraph) |
(...skipping 2212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3550 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver
ticalPositionCache); | 3520 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver
ticalPositionCache); |
3551 | 3521 |
3552 setLineGridBox(lineGridBox); | 3522 setLineGridBox(lineGridBox); |
3553 | 3523 |
3554 // FIXME: If any of the characteristics of the box change compared to the ol
d one, then we need to do a deep dirtying | 3524 // FIXME: If any of the characteristics of the box change compared to the ol
d one, then we need to do a deep dirtying |
3555 // (similar to what happens when the page height changes). Ideally, though,
we only do this if someone is actually snapping | 3525 // (similar to what happens when the page height changes). Ideally, though,
we only do this if someone is actually snapping |
3556 // to this grid. | 3526 // to this grid. |
3557 } | 3527 } |
3558 | 3528 |
3559 } | 3529 } |
OLD | NEW |