Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: Source/core/rendering/RenderBlockLineLayout.cpp

Issue 26315003: Bidi-Isolate inlines break layout with collapsed whitespace (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Proposed patch fixing crash Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698