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

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 v2 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 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 } 462 }
463 463
464 // Adding a pair of midpoints before a character will split it out into a new li ne box. 464 // Adding a pair of midpoints before a character will split it out into a new li ne box.
465 static inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointSta te, InlineIterator& textParagraphSeparator) 465 static inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointSta te, InlineIterator& textParagraphSeparator)
466 { 466 {
467 InlineIterator midpoint(0, textParagraphSeparator.m_obj, textParagraphSepara tor.m_pos); 467 InlineIterator midpoint(0, textParagraphSeparator.m_obj, textParagraphSepara tor.m_pos);
468 startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSepara tor.m_obj, textParagraphSeparator.m_pos - 1)); 468 startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSepara tor.m_obj, textParagraphSeparator.m_pos - 1));
469 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparat or.m_obj, textParagraphSeparator.m_pos)); 469 stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparat or.m_obj, textParagraphSeparator.m_pos));
470 } 470 }
471 471
472 static inline BidiRun* createRun(int start, int end, RenderObject* obj, InlineBi diResolver& resolver)
473 {
474 return new BidiRun(start, end, obj, resolver.context(), resolver.dir());
475 }
476
477 void RenderBlock::appendRunsForObject(BidiRunList<BidiRun>& runs, int start, int end, RenderObject* obj, InlineBidiResolver& resolver) 472 void RenderBlock::appendRunsForObject(BidiRunList<BidiRun>& runs, int start, int end, RenderObject* obj, InlineBidiResolver& resolver)
478 { 473 {
479 if (start > end || shouldSkipCreatingRunsForObject(obj)) 474 adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, resolver, fal se, &runs);
480 return;
481
482 LineMidpointState& lineMidpointState = resolver.midpointState();
483 bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointSta te.numMidpoints);
484 InlineIterator nextMidpoint;
485 if (haveNextMidpoint)
486 nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidp oint];
487 if (lineMidpointState.betweenMidpoints) {
488 if (!(haveNextMidpoint && nextMidpoint.m_obj == obj))
489 return;
490 // This is a new start point. Stop ignoring objects and
491 // adjust our start.
492 lineMidpointState.betweenMidpoints = false;
493 start = nextMidpoint.m_pos;
494 lineMidpointState.currentMidpoint++;
495 if (start < end)
496 return appendRunsForObject(runs, start, end, obj, resolver);
497 } else {
498 if (!haveNextMidpoint || (obj != nextMidpoint.m_obj)) {
499 runs.addRun(createRun(start, end, obj, resolver));
500 return;
501 }
502
503 // An end midpoint has been encountered within our object. We
504 // need to go ahead and append a run with our endpoint.
505 if (static_cast<int>(nextMidpoint.m_pos + 1) <= end) {
506 lineMidpointState.betweenMidpoints = true;
507 lineMidpointState.currentMidpoint++;
508 if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it.
509 if (static_cast<int>(nextMidpoint.m_pos + 1) > start)
510 runs.addRun(createRun(start, nextMidpoint.m_pos + 1, obj, re solver));
511 return appendRunsForObject(runs, nextMidpoint.m_pos + 1, end, ob j, resolver);
512 }
513 } else
514 runs.addRun(createRun(start, end, obj, resolver));
515 }
516 } 475 }
517 476
518 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRo otLineBox, bool isOnlyRun = false) 477 static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRo otLineBox, bool isOnlyRun = false)
519 { 478 {
520 if (isRootLineBox) 479 if (isRootLineBox)
521 return toRenderBlock(obj)->createAndAppendRootInlineBox(); 480 return toRenderBlock(obj)->createAndAppendRootInlineBox();
522 481
523 if (obj->isText()) { 482 if (obj->isText()) {
524 InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox(); 483 InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox();
525 // We only treat a box as text for a <br> if we are on a line by ourself or in strict mode 484 // 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
1270 1229
1271 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver, RenderObject* root, RenderObject* startObject) 1230 static inline void setupResolverToResumeInIsolate(InlineBidiResolver& resolver, RenderObject* root, RenderObject* startObject)
1272 { 1231 {
1273 if (root != startObject) { 1232 if (root != startObject) {
1274 RenderObject* parent = startObject->parent(); 1233 RenderObject* parent = startObject->parent();
1275 setupResolverToResumeInIsolate(resolver, root, parent); 1234 setupResolverToResumeInIsolate(resolver, root, parent);
1276 notifyObserverEnteredObject(&resolver, startObject); 1235 notifyObserverEnteredObject(&resolver, startObject);
1277 } 1236 }
1278 } 1237 }
1279 1238
1239 static void restoreIsolatedMidpointStates(InlineBidiResolver& topResolver, Inlin eBidiResolver& isolatedResolver)
1240 {
1241 while (!isolatedResolver.isolatedRuns().isEmpty()) {
1242 BidiRun* run = isolatedResolver.isolatedRuns().last();
1243 isolatedResolver.isolatedRuns().removeLast();
1244 topResolver.setMidpointStateForIsolatedRun(run, isolatedResolver.midpoin tStateForIsolatedRun(run));
1245 }
1246 }
1247
1280 // FIXME: BidiResolver should have this logic. 1248 // FIXME: BidiResolver should have this logic.
1281 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirection Override override, bool previousLineBrokeCleanly, bool isNewUBAParagraph) 1249 static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirection Override override, bool previousLineBrokeCleanly, bool isNewUBAParagraph)
1282 { 1250 {
1283 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead 1251 // FIXME: We should pass a BidiRunList into createBidiRunsForLine instead
1284 // of the resolver owning the runs. 1252 // of the resolver owning the runs.
1285 ASSERT(&topResolver.runs() == &bidiRuns); 1253 ASSERT(&topResolver.runs() == &bidiRuns);
1286 ASSERT(topResolver.position() != endOfRuns); 1254 ASSERT(topResolver.position() != endOfRuns);
1287 RenderObject* currentRoot = topResolver.position().root(); 1255 RenderObject* currentRoot = topResolver.position().root();
1288 topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeClea nly); 1256 topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeClea nly);
1289 1257
1290 while (!topResolver.isolatedRuns().isEmpty()) { 1258 while (!topResolver.isolatedRuns().isEmpty()) {
1291 // It does not matter which order we resolve the runs as long as we reso lve them all. 1259 // It does not matter which order we resolve the runs as long as we reso lve them all.
1292 BidiRun* isolatedRun = topResolver.isolatedRuns().last(); 1260 BidiRun* isolatedRun = topResolver.isolatedRuns().last();
1293 topResolver.isolatedRuns().removeLast(); 1261 topResolver.isolatedRuns().removeLast();
1294 1262
1295 RenderObject* startObj = isolatedRun->object(); 1263 RenderObject* startObj = isolatedRun->object();
1296 1264
1297 // Only inlines make sense with unicode-bidi: isolate (blocks are alread y isolated). 1265 // Only inlines make sense with unicode-bidi: isolate (blocks are alread y isolated).
1298 // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the 1266 // FIXME: Because enterIsolate is not passed a RenderObject, we have to crawl up the
1299 // tree to see which parent inline is the isolate. We could change enter Isolate 1267 // tree to see which parent inline is the isolate. We could change enter Isolate
1300 // to take a RenderObject and do this logic there, but that would be a l ayering 1268 // to take a RenderObject and do this logic there, but that would be a l ayering
1301 // violation for BidiResolver (which knows nothing about RenderObject). 1269 // violation for BidiResolver (which knows nothing about RenderObject).
1302 RenderInline* isolatedInline = toRenderInline(highestContainingIsolateWi thinRoot(startObj, currentRoot)); 1270 RenderInline* isolatedInline = toRenderInline(highestContainingIsolateWi thinRoot(startObj, currentRoot));
1303 ASSERT(isolatedInline); 1271 ASSERT(isolatedInline);
1304 1272
1305 InlineBidiResolver isolatedResolver; 1273 InlineBidiResolver isolatedResolver;
1274 LineMidpointState& isolatedLineMidpointState = isolatedResolver.midpoint State();
1275 isolatedLineMidpointState = topResolver.midpointStateForIsolatedRun(isol atedRun);
1306 EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi(); 1276 EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi();
1307 TextDirection direction = isolatedInline->style()->direction(); 1277 TextDirection direction = isolatedInline->style()->direction();
1308 if (unicodeBidi == Plaintext) { 1278 if (unicodeBidi == Plaintext) {
1309 if (isNewUBAParagraph) 1279 if (isNewUBAParagraph)
1310 direction = determinePlaintextDirectionality(isolatedInline, sta rtObj); 1280 direction = determinePlaintextDirectionality(isolatedInline, sta rtObj);
1311 else 1281 else
1312 direction = determinePlaintextDirectionality(isolatedInline); 1282 direction = determinePlaintextDirectionality(isolatedInline);
1313 } else { 1283 } else {
1314 ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride); 1284 ASSERT(unicodeBidi == Isolate || unicodeBidi == IsolateOverride);
1315 direction = isolatedInline->style()->direction(); 1285 direction = isolatedInline->style()->direction();
(...skipping 16 matching lines...) Expand all
1332 // We're not guaranteed to get any BidiRuns in the previous step. If we don't, we allow the placeholder 1302 // We're not guaranteed to get any BidiRuns in the previous step. If we don't, we allow the placeholder
1333 // itself to be turned into an InlineBox. We can't remove it here withou t potentially losing track of 1303 // itself to be turned into an InlineBox. We can't remove it here withou t potentially losing track of
1334 // the logically last run. 1304 // the logically last run.
1335 if (isolatedResolver.runs().runCount()) 1305 if (isolatedResolver.runs().runCount())
1336 bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs()); 1306 bidiRuns.replaceRunWithRuns(isolatedRun, isolatedResolver.runs());
1337 1307
1338 // If we encountered any nested isolate runs, just move them 1308 // If we encountered any nested isolate runs, just move them
1339 // to the top resolver's list for later processing. 1309 // to the top resolver's list for later processing.
1340 if (!isolatedResolver.isolatedRuns().isEmpty()) { 1310 if (!isolatedResolver.isolatedRuns().isEmpty()) {
1341 topResolver.isolatedRuns().append(isolatedResolver.isolatedRuns()); 1311 topResolver.isolatedRuns().append(isolatedResolver.isolatedRuns());
1342 isolatedResolver.isolatedRuns().clear();
1343 currentRoot = isolatedInline; 1312 currentRoot = isolatedInline;
1313 restoreIsolatedMidpointStates(topResolver, isolatedResolver);
1344 } 1314 }
1345 } 1315 }
1346 } 1316 }
1347 1317
1348 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli neIterator& segmentEnd) 1318 static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const Inli neIterator& segmentEnd)
1349 { 1319 {
1350 return segmentStart == segmentEnd; 1320 return segmentStart == segmentEnd;
1351 } 1321 }
1352 1322
1353 static inline void constructBidiRunsForLine(const RenderBlock* block, InlineBidi Resolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end OfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, bool is NewUBAParagraph) 1323 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 2154 matching lines...) Expand 10 before | Expand all | Expand 10 after
3508 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver ticalPositionCache); 3478 lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, ver ticalPositionCache);
3509 3479
3510 setLineGridBox(lineGridBox); 3480 setLineGridBox(lineGridBox);
3511 3481
3512 // FIXME: If any of the characteristics of the box change compared to the ol d one, then we need to do a deep dirtying 3482 // FIXME: If any of the characteristics of the box change compared to the ol d one, then we need to do a deep dirtying
3513 // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping 3483 // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping
3514 // to this grid. 3484 // to this grid.
3515 } 3485 }
3516 3486
3517 } 3487 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698