| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 // invalidate our paint (and the child) anyway. | 478 // invalidate our paint (and the child) anyway. |
| 479 bool didNotDoFullLayoutAndMoved = childHadLayout && !selfNeedsLayout() && (c
hildOffset.width() || childOffset.height()); | 479 bool didNotDoFullLayoutAndMoved = childHadLayout && !selfNeedsLayout() && (c
hildOffset.width() || childOffset.height()); |
| 480 bool didNotLayoutAndNeedsPaintInvalidation = !childHadLayout && child->check
ForPaintInvalidation(); | 480 bool didNotLayoutAndNeedsPaintInvalidation = !childHadLayout && child->check
ForPaintInvalidation(); |
| 481 | 481 |
| 482 if (didNotDoFullLayoutAndMoved || didNotLayoutAndNeedsPaintInvalidation) | 482 if (didNotDoFullLayoutAndMoved || didNotLayoutAndNeedsPaintInvalidation) |
| 483 child->invalidatePaintForOverhangingFloats(true); | 483 child->invalidatePaintForOverhangingFloats(true); |
| 484 } | 484 } |
| 485 | 485 |
| 486 void RenderBlockFlow::rebuildFloatsFromIntruding() | 486 void RenderBlockFlow::rebuildFloatsFromIntruding() |
| 487 { | 487 { |
| 488 if (m_floatingObjects) | 488 // FIXME(sky): Remove this. |
| 489 m_floatingObjects->setHorizontalWritingMode(isHorizontalWritingMode()); | |
| 490 | |
| 491 HashSet<RenderBox*> oldIntrudingFloatSet; | |
| 492 if (!childrenInline() && m_floatingObjects) { | |
| 493 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 494 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 495 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end
; ++it) { | |
| 496 FloatingObject* floatingObject = it->get(); | |
| 497 if (!floatingObject->isDescendant()) | |
| 498 oldIntrudingFloatSet.add(floatingObject->renderer()); | |
| 499 } | |
| 500 } | |
| 501 | |
| 502 // Inline blocks are covered by the isReplaced() check in the avoidFloats me
thod. | |
| 503 if (avoidsFloats() || isDocumentElement() || isRenderView() || isFloatingOrO
utOfFlowPositioned()) { | |
| 504 if (m_floatingObjects) { | |
| 505 m_floatingObjects->clear(); | |
| 506 } | |
| 507 if (!oldIntrudingFloatSet.isEmpty()) | |
| 508 markAllDescendantsWithFloatsForLayout(); | |
| 509 return; | |
| 510 } | |
| 511 | |
| 512 RendererToFloatInfoMap floatMap; | |
| 513 | |
| 514 if (m_floatingObjects) { | |
| 515 if (childrenInline()) | |
| 516 m_floatingObjects->moveAllToFloatInfoMap(floatMap); | |
| 517 else | |
| 518 m_floatingObjects->clear(); | |
| 519 } | |
| 520 | |
| 521 // We should not process floats if the parent node is not a RenderBlockFlow.
Otherwise, we will add | |
| 522 // floats in an invalid context. This will cause a crash arising from a bad
cast on the parent. | |
| 523 // See <rdar://problem/8049753>, where float property is applied on a text n
ode in a SVG. | |
| 524 if (!parent() || !parent()->isRenderBlockFlow()) | |
| 525 return; | |
| 526 | |
| 527 // Attempt to locate a previous sibling with overhanging floats. We skip any
elements that | |
| 528 // may have shifted to avoid floats, and any objects whose floats cannot int
eract with objects | |
| 529 // outside it (i.e. objects that create a new block formatting context). | |
| 530 RenderBlockFlow* parentBlockFlow = toRenderBlockFlow(parent()); | |
| 531 bool parentHasFloats = false; | |
| 532 RenderObject* prev = previousSibling(); | |
| 533 while (prev && (!prev->isBox() || !prev->isRenderBlock() || toRenderBlock(pr
ev)->avoidsFloats() || toRenderBlock(prev)->createsBlockFormattingContext())) { | |
| 534 if (prev->isFloating()) | |
| 535 parentHasFloats = true; | |
| 536 prev = prev->previousSibling(); | |
| 537 } | |
| 538 | |
| 539 // First add in floats from the parent. Self-collapsing blocks let their par
ent track any floats that intrude into | |
| 540 // them (as opposed to floats they contain themselves) so check for those he
re too. | |
| 541 LayoutUnit logicalTopOffset = logicalTop(); | |
| 542 bool parentHasIntrudingFloats = !parentHasFloats && (!prev || toRenderBlockF
low(prev)->isSelfCollapsingBlock()) && parentBlockFlow->lowestFloatLogicalBottom
() > logicalTopOffset; | |
| 543 if (parentHasFloats || parentHasIntrudingFloats) | |
| 544 addIntrudingFloats(parentBlockFlow, parentBlockFlow->logicalLeftOffsetFo
rContent(), logicalTopOffset); | |
| 545 | |
| 546 // Add overhanging floats from the previous RenderBlockFlow, but only if it
has a float that intrudes into our space. | |
| 547 if (prev) { | |
| 548 RenderBlockFlow* blockFlow = toRenderBlockFlow(prev); | |
| 549 logicalTopOffset -= blockFlow->logicalTop(); | |
| 550 if (blockFlow->lowestFloatLogicalBottom() > logicalTopOffset) | |
| 551 addIntrudingFloats(blockFlow, 0, logicalTopOffset); | |
| 552 } | |
| 553 | |
| 554 if (childrenInline()) { | |
| 555 LayoutUnit changeLogicalTop = LayoutUnit::max(); | |
| 556 LayoutUnit changeLogicalBottom = LayoutUnit::min(); | |
| 557 if (m_floatingObjects) { | |
| 558 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(
); | |
| 559 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 560 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it !=
end; ++it) { | |
| 561 FloatingObject* floatingObject = it->get(); | |
| 562 FloatingObject* oldFloatingObject = floatMap.get(floatingObject-
>renderer()); | |
| 563 LayoutUnit logicalBottom = logicalBottomForFloat(floatingObject)
; | |
| 564 if (oldFloatingObject) { | |
| 565 LayoutUnit oldLogicalBottom = logicalBottomForFloat(oldFloat
ingObject); | |
| 566 if (logicalWidthForFloat(floatingObject) != logicalWidthForF
loat(oldFloatingObject) || logicalLeftForFloat(floatingObject) != logicalLeftFor
Float(oldFloatingObject)) { | |
| 567 changeLogicalTop = 0; | |
| 568 changeLogicalBottom = std::max(changeLogicalBottom, std:
:max(logicalBottom, oldLogicalBottom)); | |
| 569 } else { | |
| 570 if (logicalBottom != oldLogicalBottom) { | |
| 571 changeLogicalTop = std::min(changeLogicalTop, std::m
in(logicalBottom, oldLogicalBottom)); | |
| 572 changeLogicalBottom = std::max(changeLogicalBottom,
std::max(logicalBottom, oldLogicalBottom)); | |
| 573 } | |
| 574 LayoutUnit logicalTop = logicalTopForFloat(floatingObjec
t); | |
| 575 LayoutUnit oldLogicalTop = logicalTopForFloat(oldFloatin
gObject); | |
| 576 if (logicalTop != oldLogicalTop) { | |
| 577 changeLogicalTop = std::min(changeLogicalTop, std::m
in(logicalTop, oldLogicalTop)); | |
| 578 changeLogicalBottom = std::max(changeLogicalBottom,
std::max(logicalTop, oldLogicalTop)); | |
| 579 } | |
| 580 } | |
| 581 | |
| 582 if (oldFloatingObject->originatingLine() && !selfNeedsLayout
()) { | |
| 583 ASSERT(oldFloatingObject->originatingLine()->renderer()
== this); | |
| 584 oldFloatingObject->originatingLine()->markDirty(); | |
| 585 } | |
| 586 | |
| 587 floatMap.remove(floatingObject->renderer()); | |
| 588 } else { | |
| 589 changeLogicalTop = 0; | |
| 590 changeLogicalBottom = std::max(changeLogicalBottom, logicalB
ottom); | |
| 591 } | |
| 592 } | |
| 593 } | |
| 594 | |
| 595 RendererToFloatInfoMap::iterator end = floatMap.end(); | |
| 596 for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end;
++it) { | |
| 597 OwnPtr<FloatingObject>& floatingObject = it->value; | |
| 598 if (!floatingObject->isDescendant()) { | |
| 599 changeLogicalTop = 0; | |
| 600 changeLogicalBottom = std::max(changeLogicalBottom, logicalBotto
mForFloat(floatingObject.get())); | |
| 601 } | |
| 602 } | |
| 603 | |
| 604 markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom); | |
| 605 } else if (!oldIntrudingFloatSet.isEmpty()) { | |
| 606 // If there are previously intruding floats that no longer intrude, then
children with floats | |
| 607 // should also get layout because they might need their floating object
lists cleared. | |
| 608 if (m_floatingObjects->set().size() < oldIntrudingFloatSet.size()) { | |
| 609 markAllDescendantsWithFloatsForLayout(); | |
| 610 } else { | |
| 611 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(
); | |
| 612 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 613 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it !=
end && !oldIntrudingFloatSet.isEmpty(); ++it) | |
| 614 oldIntrudingFloatSet.remove((*it)->renderer()); | |
| 615 if (!oldIntrudingFloatSet.isEmpty()) | |
| 616 markAllDescendantsWithFloatsForLayout(); | |
| 617 } | |
| 618 } | |
| 619 } | 489 } |
| 620 | 490 |
| 621 void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, SubtreeLayoutSc
ope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge) | 491 void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, SubtreeLayoutSc
ope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge) |
| 622 { | 492 { |
| 623 dirtyForLayoutFromPercentageHeightDescendants(layoutScope); | 493 dirtyForLayoutFromPercentageHeightDescendants(layoutScope); |
| 624 | 494 |
| 625 // The margin struct caches all our current margin collapsing state. The com
pact struct caches state when we encounter compacts, | 495 // The margin struct caches all our current margin collapsing state. The com
pact struct caches state when we encounter compacts, |
| 626 MarginInfo marginInfo(this, beforeEdge, afterEdge); | 496 MarginInfo marginInfo(this, beforeEdge, afterEdge); |
| 627 | 497 |
| 628 LayoutUnit previousFloatLogicalBottom = 0; | 498 LayoutUnit previousFloatLogicalBottom = 0; |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 return childStyle->marginAfterCollapse() == MSEPARATE; | 1128 return childStyle->marginAfterCollapse() == MSEPARATE; |
| 1259 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) | 1129 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) |
| 1260 return childStyle->marginBeforeCollapse() == MSEPARATE; | 1130 return childStyle->marginBeforeCollapse() == MSEPARATE; |
| 1261 | 1131 |
| 1262 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 1132 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
| 1263 return false; | 1133 return false; |
| 1264 } | 1134 } |
| 1265 | 1135 |
| 1266 void RenderBlockFlow::addOverflowFromFloats() | 1136 void RenderBlockFlow::addOverflowFromFloats() |
| 1267 { | 1137 { |
| 1268 if (!m_floatingObjects) | 1138 // FIXME(sky): Remove this. |
| 1269 return; | |
| 1270 | |
| 1271 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1272 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 1273 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { | |
| 1274 FloatingObject* floatingObject = it->get(); | |
| 1275 if (floatingObject->isDescendant()) | |
| 1276 addOverflowFromChild(floatingObject->renderer(), IntSize(xPositionFo
rFloatIncludingMargin(floatingObject), yPositionForFloatIncludingMargin(floating
Object))); | |
| 1277 } | |
| 1278 } | 1139 } |
| 1279 | 1140 |
| 1280 void RenderBlockFlow::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomp
uteFloats) | 1141 void RenderBlockFlow::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomp
uteFloats) |
| 1281 { | 1142 { |
| 1282 RenderBlock::computeOverflow(oldClientAfterEdge, recomputeFloats); | 1143 RenderBlock::computeOverflow(oldClientAfterEdge, recomputeFloats); |
| 1283 if (recomputeFloats || createsBlockFormattingContext() || hasSelfPaintingLay
er()) | 1144 if (recomputeFloats || createsBlockFormattingContext() || hasSelfPaintingLay
er()) |
| 1284 addOverflowFromFloats(); | 1145 addOverflowFromFloats(); |
| 1285 } | 1146 } |
| 1286 | 1147 |
| 1287 RootInlineBox* RenderBlockFlow::createAndAppendRootInlineBox() | 1148 RootInlineBox* RenderBlockFlow::createAndAppendRootInlineBox() |
| 1288 { | 1149 { |
| 1289 RootInlineBox* rootBox = createRootInlineBox(); | 1150 RootInlineBox* rootBox = createRootInlineBox(); |
| 1290 m_lineBoxes.appendLineBox(rootBox); | 1151 m_lineBoxes.appendLineBox(rootBox); |
| 1291 | 1152 |
| 1292 return rootBox; | 1153 return rootBox; |
| 1293 } | 1154 } |
| 1294 | 1155 |
| 1295 void RenderBlockFlow::deleteLineBoxTree() | 1156 void RenderBlockFlow::deleteLineBoxTree() |
| 1296 { | 1157 { |
| 1297 if (containsFloats()) | 1158 if (containsFloats()) |
| 1298 m_floatingObjects->clearLineBoxTreePointers(); | 1159 m_floatingObjects->clearLineBoxTreePointers(); |
| 1299 | 1160 |
| 1300 m_lineBoxes.deleteLineBoxTree(); | 1161 m_lineBoxes.deleteLineBoxTree(); |
| 1301 } | 1162 } |
| 1302 | 1163 |
| 1303 void RenderBlockFlow::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRe
move, bool inLayout) | 1164 void RenderBlockFlow::markAllDescendantsWithFloatsForLayout(RenderBox* floatToRe
move, bool inLayout) |
| 1304 { | 1165 { |
| 1305 if (!everHadLayout() && !containsFloats()) | 1166 // FIXME(sky): Remove this. |
| 1306 return; | |
| 1307 | |
| 1308 if (m_descendantsWithFloatsMarkedForLayout && !floatToRemove) | |
| 1309 return; | |
| 1310 m_descendantsWithFloatsMarkedForLayout |= !floatToRemove; | |
| 1311 | |
| 1312 MarkingBehavior markParents = inLayout ? MarkOnlyThis : MarkContainingBlockC
hain; | |
| 1313 setChildNeedsLayout(markParents); | |
| 1314 | |
| 1315 if (floatToRemove) | |
| 1316 removeFloatingObject(floatToRemove); | |
| 1317 | |
| 1318 // Iterate over our children and mark them as needed. | |
| 1319 if (!childrenInline()) { | |
| 1320 for (RenderObject* child = firstChild(); child; child = child->nextSibli
ng()) { | |
| 1321 if ((!floatToRemove && child->isFloatingOrOutOfFlowPositioned()) ||
!child->isRenderBlock()) | |
| 1322 continue; | |
| 1323 if (!child->isRenderBlockFlow()) { | |
| 1324 RenderBlock* childBlock = toRenderBlock(child); | |
| 1325 if (childBlock->shrinkToAvoidFloats() && childBlock->everHadLayo
ut()) | |
| 1326 childBlock->setChildNeedsLayout(markParents); | |
| 1327 continue; | |
| 1328 } | |
| 1329 RenderBlockFlow* childBlockFlow = toRenderBlockFlow(child); | |
| 1330 if ((floatToRemove ? childBlockFlow->containsFloat(floatToRemove) :
childBlockFlow->containsFloats()) || childBlockFlow->shrinkToAvoidFloats()) | |
| 1331 childBlockFlow->markAllDescendantsWithFloatsForLayout(floatToRem
ove, inLayout); | |
| 1332 } | |
| 1333 } | |
| 1334 } | 1167 } |
| 1335 | 1168 |
| 1336 void RenderBlockFlow::markSiblingsWithFloatsForLayout(RenderBox* floatToRemove) | 1169 void RenderBlockFlow::markSiblingsWithFloatsForLayout(RenderBox* floatToRemove) |
| 1337 { | 1170 { |
| 1338 if (!m_floatingObjects) | 1171 // FIXME(sky): Remove this. |
| 1339 return; | |
| 1340 | |
| 1341 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1342 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 1343 | |
| 1344 for (RenderObject* next = nextSibling(); next; next = next->nextSibling()) { | |
| 1345 if (!next->isRenderBlockFlow() || next->isFloatingOrOutOfFlowPositioned(
) || toRenderBlockFlow(next)->avoidsFloats()) | |
| 1346 continue; | |
| 1347 | |
| 1348 RenderBlockFlow* nextBlock = toRenderBlockFlow(next); | |
| 1349 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end
; ++it) { | |
| 1350 RenderBox* floatingBox = (*it)->renderer(); | |
| 1351 if (floatToRemove && floatingBox != floatToRemove) | |
| 1352 continue; | |
| 1353 if (nextBlock->containsFloat(floatingBox)) | |
| 1354 nextBlock->markAllDescendantsWithFloatsForLayout(floatingBox); | |
| 1355 } | |
| 1356 } | |
| 1357 } | 1172 } |
| 1358 | 1173 |
| 1359 LayoutUnit RenderBlockFlow::getClearDelta(RenderBox* child, LayoutUnit logicalTo
p) | 1174 LayoutUnit RenderBlockFlow::getClearDelta(RenderBox* child, LayoutUnit logicalTo
p) |
| 1360 { | 1175 { |
| 1361 // There is no need to compute clearance if we have no floats. | 1176 // FIXME(sky): Remove this. |
| 1362 if (!containsFloats()) | 1177 return 0; |
| 1363 return 0; | |
| 1364 | |
| 1365 // At least one float is present. We need to perform the clearance computati
on. | |
| 1366 bool clearSet = child->style()->clear() != CNONE; | |
| 1367 LayoutUnit logicalBottom = 0; | |
| 1368 switch (child->style()->clear()) { | |
| 1369 case CNONE: | |
| 1370 break; | |
| 1371 case CLEFT: | |
| 1372 logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatLeft); | |
| 1373 break; | |
| 1374 case CRIGHT: | |
| 1375 logicalBottom = lowestFloatLogicalBottom(FloatingObject::FloatRight); | |
| 1376 break; | |
| 1377 case CBOTH: | |
| 1378 logicalBottom = lowestFloatLogicalBottom(); | |
| 1379 break; | |
| 1380 } | |
| 1381 | |
| 1382 // We also clear floats if we are too big to sit on the same line as a float
(and wish to avoid floats by default). | |
| 1383 LayoutUnit result = clearSet ? std::max<LayoutUnit>(0, logicalBottom - logic
alTop) : LayoutUnit(); | |
| 1384 if (!result && child->avoidsFloats()) { | |
| 1385 LayoutUnit newLogicalTop = logicalTop; | |
| 1386 while (true) { | |
| 1387 LayoutUnit availableLogicalWidthAtNewLogicalTopOffset = availableLog
icalWidthForLine(newLogicalTop, false, logicalHeightForChild(child)); | |
| 1388 if (availableLogicalWidthAtNewLogicalTopOffset == availableLogicalWi
dthForContent()) | |
| 1389 return newLogicalTop - logicalTop; | |
| 1390 | |
| 1391 LayoutRect borderBox = child->borderBoxRect(); | |
| 1392 LayoutUnit childLogicalWidthAtOldLogicalTopOffset = isHorizontalWrit
ingMode() ? borderBox.width() : borderBox.height(); | |
| 1393 | |
| 1394 // FIXME: None of this is right for perpendicular writing-mode child
ren. | |
| 1395 LayoutUnit childOldLogicalWidth = child->logicalWidth(); | |
| 1396 LayoutUnit childOldMarginLeft = child->marginLeft(); | |
| 1397 LayoutUnit childOldMarginRight = child->marginRight(); | |
| 1398 LayoutUnit childOldLogicalTop = child->logicalTop(); | |
| 1399 | |
| 1400 child->setLogicalTop(newLogicalTop); | |
| 1401 child->updateLogicalWidth(); | |
| 1402 borderBox = child->borderBoxRect(); | |
| 1403 LayoutUnit childLogicalWidthAtNewLogicalTopOffset = isHorizontalWrit
ingMode() ? borderBox.width() : borderBox.height(); | |
| 1404 | |
| 1405 child->setLogicalTop(childOldLogicalTop); | |
| 1406 child->setLogicalWidth(childOldLogicalWidth); | |
| 1407 child->setMarginLeft(childOldMarginLeft); | |
| 1408 child->setMarginRight(childOldMarginRight); | |
| 1409 | |
| 1410 if (childLogicalWidthAtNewLogicalTopOffset <= availableLogicalWidthA
tNewLogicalTopOffset) { | |
| 1411 // Even though we may not be moving, if the logical width did sh
rink because of the presence of new floats, then | |
| 1412 // we need to force a relayout as though we shifted. This happen
s because of the dynamic addition of overhanging floats | |
| 1413 // from previous siblings when negative margins exist on a child
(see the addOverhangingFloats call at the end of collapseMargins). | |
| 1414 if (childLogicalWidthAtOldLogicalTopOffset != childLogicalWidthA
tNewLogicalTopOffset) | |
| 1415 child->setChildNeedsLayout(MarkOnlyThis); | |
| 1416 return newLogicalTop - logicalTop; | |
| 1417 } | |
| 1418 | |
| 1419 newLogicalTop = nextFloatLogicalBottomBelow(newLogicalTop); | |
| 1420 ASSERT(newLogicalTop >= logicalTop); | |
| 1421 if (newLogicalTop < logicalTop) | |
| 1422 break; | |
| 1423 } | |
| 1424 ASSERT_NOT_REACHED(); | |
| 1425 } | |
| 1426 return result; | |
| 1427 } | 1178 } |
| 1428 | 1179 |
| 1429 void RenderBlockFlow::createFloatingObjects() | 1180 void RenderBlockFlow::createFloatingObjects() |
| 1430 { | 1181 { |
| 1431 m_floatingObjects = adoptPtr(new FloatingObjects(this, isHorizontalWritingMo
de())); | 1182 // FIXME(sky): Remove this. |
| 1432 } | 1183 } |
| 1433 | 1184 |
| 1434 void RenderBlockFlow::styleWillChange(StyleDifference diff, const RenderStyle& n
ewStyle) | 1185 void RenderBlockFlow::styleWillChange(StyleDifference diff, const RenderStyle& n
ewStyle) |
| 1435 { | 1186 { |
| 1436 RenderStyle* oldStyle = style(); | 1187 RenderStyle* oldStyle = style(); |
| 1437 s_canPropagateFloatIntoSibling = oldStyle ? !isFloatingOrOutOfFlowPositioned
() && !avoidsFloats() : false; | 1188 s_canPropagateFloatIntoSibling = oldStyle ? !isFloatingOrOutOfFlowPositioned
() && !avoidsFloats() : false; |
| 1438 if (oldStyle && parent() && diff.needsFullLayout() && oldStyle->position() !
= newStyle.position() | 1189 if (oldStyle && parent() && diff.needsFullLayout() && oldStyle->position() !
= newStyle.position() |
| 1439 && containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newS
tyle.hasOutOfFlowPosition()) | 1190 && containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newS
tyle.hasOutOfFlowPosition()) |
| 1440 markAllDescendantsWithFloatsForLayout(); | 1191 markAllDescendantsWithFloatsForLayout(); |
| 1441 | 1192 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1490 child->layer()->setStaticInlinePosition(inlinePosition); | 1241 child->layer()->setStaticInlinePosition(inlinePosition); |
| 1491 } | 1242 } |
| 1492 | 1243 |
| 1493 void RenderBlockFlow::addChild(RenderObject* newChild, RenderObject* beforeChild
) | 1244 void RenderBlockFlow::addChild(RenderObject* newChild, RenderObject* beforeChild
) |
| 1494 { | 1245 { |
| 1495 RenderBlock::addChild(newChild, beforeChild); | 1246 RenderBlock::addChild(newChild, beforeChild); |
| 1496 } | 1247 } |
| 1497 | 1248 |
| 1498 void RenderBlockFlow::moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, boo
l fullRemoveInsert) | 1249 void RenderBlockFlow::moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, boo
l fullRemoveInsert) |
| 1499 { | 1250 { |
| 1251 // FIXME(sky): Merge this into callers. |
| 1500 RenderBlockFlow* toBlockFlow = toRenderBlockFlow(toBlock); | 1252 RenderBlockFlow* toBlockFlow = toRenderBlockFlow(toBlock); |
| 1501 moveAllChildrenTo(toBlockFlow, fullRemoveInsert); | 1253 moveAllChildrenTo(toBlockFlow, fullRemoveInsert); |
| 1502 | |
| 1503 // When a portion of the render tree is being detached, anonymous blocks | |
| 1504 // will be combined as their children are deleted. In this process, the | |
| 1505 // anonymous block later in the tree is merged into the one preceeding it. | |
| 1506 // It can happen that the later block (this) contains floats that the | |
| 1507 // previous block (toBlockFlow) did not contain, and thus are not in the | |
| 1508 // floating objects list for toBlockFlow. This can result in toBlockFlow con
taining | |
| 1509 // floats that are not in it's floating objects list, but are in the | |
| 1510 // floating objects lists of siblings and parents. This can cause problems | |
| 1511 // when the float itself is deleted, since the deletion code assumes that | |
| 1512 // if a float is not in it's containing block's floating objects list, it | |
| 1513 // isn't in any floating objects list. In order to preserve this condition | |
| 1514 // (removing it has serious performance implications), we need to copy the | |
| 1515 // floating objects from the old block (this) to the new block (toBlockFlow)
. | |
| 1516 // The float's metrics will likely all be wrong, but since toBlockFlow is | |
| 1517 // already marked for layout, this will get fixed before anything gets | |
| 1518 // displayed. | |
| 1519 // See bug https://code.google.com/p/chromium/issues/detail?id=230907 | |
| 1520 if (m_floatingObjects) { | |
| 1521 if (!toBlockFlow->m_floatingObjects) | |
| 1522 toBlockFlow->createFloatingObjects(); | |
| 1523 | |
| 1524 const FloatingObjectSet& fromFloatingObjectSet = m_floatingObjects->set(
); | |
| 1525 FloatingObjectSetIterator end = fromFloatingObjectSet.end(); | |
| 1526 | |
| 1527 for (FloatingObjectSetIterator it = fromFloatingObjectSet.begin(); it !=
end; ++it) { | |
| 1528 FloatingObject* floatingObject = it->get(); | |
| 1529 | |
| 1530 // Don't insert the object again if it's already in the list | |
| 1531 if (toBlockFlow->containsFloat(floatingObject->renderer())) | |
| 1532 continue; | |
| 1533 | |
| 1534 toBlockFlow->m_floatingObjects->add(floatingObject->unsafeClone()); | |
| 1535 } | |
| 1536 } | |
| 1537 | |
| 1538 } | 1254 } |
| 1539 | 1255 |
| 1540 void RenderBlockFlow::invalidatePaintForOverhangingFloats(bool paintAllDescendan
ts) | 1256 void RenderBlockFlow::invalidatePaintForOverhangingFloats(bool paintAllDescendan
ts) |
| 1541 { | 1257 { |
| 1542 // Invalidate paint of any overhanging floats (if we know we're the one to p
aint them). | 1258 // FIXME(sky): Remove this. |
| 1543 // Otherwise, bail out. | |
| 1544 if (!hasOverhangingFloats()) | |
| 1545 return; | |
| 1546 | |
| 1547 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1548 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 1549 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { | |
| 1550 FloatingObject* floatingObject = it->get(); | |
| 1551 // Only issue paint invaldiations for the object if it is overhanging, i
s not in its own layer, and | |
| 1552 // is our responsibility to paint (m_shouldPaint is set). When paintAllD
escendants is true, the latter | |
| 1553 // condition is replaced with being a descendant of us. | |
| 1554 if (logicalBottomForFloat(floatingObject) > logicalHeight() | |
| 1555 && !floatingObject->renderer()->hasSelfPaintingLayer() | |
| 1556 && (floatingObject->shouldPaint() || (paintAllDescendants && floatin
gObject->renderer()->isDescendantOf(this)))) { | |
| 1557 | |
| 1558 RenderBox* floatingRenderer = floatingObject->renderer(); | |
| 1559 floatingRenderer->setShouldDoFullPaintInvalidation(true); | |
| 1560 floatingRenderer->invalidatePaintForOverhangingFloats(false); | |
| 1561 } | |
| 1562 } | |
| 1563 } | 1259 } |
| 1564 | 1260 |
| 1565 void RenderBlockFlow::invalidatePaintForOverflow() | 1261 void RenderBlockFlow::invalidatePaintForOverflow() |
| 1566 { | 1262 { |
| 1567 // FIXME: We could tighten up the left and right invalidation points if we l
et layoutInlineChildren fill them in based off the particular lines | 1263 // FIXME: We could tighten up the left and right invalidation points if we l
et layoutInlineChildren fill them in based off the particular lines |
| 1568 // it had to lay out. We wouldn't need the hasOverflowClip() hack in that ca
se either. | 1264 // it had to lay out. We wouldn't need the hasOverflowClip() hack in that ca
se either. |
| 1569 LayoutUnit paintInvalidationLogicalLeft = logicalLeftVisualOverflow(); | 1265 LayoutUnit paintInvalidationLogicalLeft = logicalLeftVisualOverflow(); |
| 1570 LayoutUnit paintInvalidationLogicalRight = logicalRightVisualOverflow(); | 1266 LayoutUnit paintInvalidationLogicalRight = logicalRightVisualOverflow(); |
| 1571 if (hasOverflowClip()) { | 1267 if (hasOverflowClip()) { |
| 1572 // If we have clipped overflow, we should use layout overflow as well, s
ince visual overflow from lines didn't propagate to our block's overflow. | 1268 // If we have clipped overflow, we should use layout overflow as well, s
ince visual overflow from lines didn't propagate to our block's overflow. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1597 | 1293 |
| 1598 invalidatePaintRectangle(paintInvalidationRect); // We need to do a part
ial paint invalidation of our content. | 1294 invalidatePaintRectangle(paintInvalidationRect); // We need to do a part
ial paint invalidation of our content. |
| 1599 } | 1295 } |
| 1600 | 1296 |
| 1601 m_paintInvalidationLogicalTop = 0; | 1297 m_paintInvalidationLogicalTop = 0; |
| 1602 m_paintInvalidationLogicalBottom = 0; | 1298 m_paintInvalidationLogicalBottom = 0; |
| 1603 } | 1299 } |
| 1604 | 1300 |
| 1605 void RenderBlockFlow::paintFloats(PaintInfo& paintInfo, const LayoutPoint& paint
Offset, bool preservePhase) | 1301 void RenderBlockFlow::paintFloats(PaintInfo& paintInfo, const LayoutPoint& paint
Offset, bool preservePhase) |
| 1606 { | 1302 { |
| 1607 if (!m_floatingObjects) | 1303 // FIXME(sky): Remove this. |
| 1608 return; | |
| 1609 | |
| 1610 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1611 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 1612 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { | |
| 1613 FloatingObject* floatingObject = it->get(); | |
| 1614 // Only paint the object if our m_shouldPaint flag is set. | |
| 1615 if (floatingObject->shouldPaint() && !floatingObject->renderer()->hasSel
fPaintingLayer()) { | |
| 1616 PaintInfo currentPaintInfo(paintInfo); | |
| 1617 currentPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhas
eBlockBackground; | |
| 1618 // FIXME: LayoutPoint version of xPositionForFloatIncludingMargin wo
uld make this much cleaner. | |
| 1619 LayoutPoint childPoint = flipFloatForWritingModeForChild(floatingObj
ect, LayoutPoint(paintOffset.x() + xPositionForFloatIncludingMargin(floatingObje
ct) - floatingObject->renderer()->x(), paintOffset.y() + yPositionForFloatInclud
ingMargin(floatingObject) - floatingObject->renderer()->y())); | |
| 1620 floatingObject->renderer()->paint(currentPaintInfo, childPoint); | |
| 1621 if (!preservePhase) { | |
| 1622 currentPaintInfo.phase = PaintPhaseChildBlockBackgrounds; | |
| 1623 floatingObject->renderer()->paint(currentPaintInfo, childPoint); | |
| 1624 currentPaintInfo.phase = PaintPhaseFloat; | |
| 1625 floatingObject->renderer()->paint(currentPaintInfo, childPoint); | |
| 1626 currentPaintInfo.phase = PaintPhaseForeground; | |
| 1627 floatingObject->renderer()->paint(currentPaintInfo, childPoint); | |
| 1628 currentPaintInfo.phase = PaintPhaseOutline; | |
| 1629 floatingObject->renderer()->paint(currentPaintInfo, childPoint); | |
| 1630 } | |
| 1631 } | |
| 1632 } | |
| 1633 } | 1304 } |
| 1634 | 1305 |
| 1635 void RenderBlockFlow::clipOutFloatingObjects(RenderBlock* rootBlock, const Paint
Info* paintInfo, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize&
offsetFromRootBlock) | 1306 void RenderBlockFlow::clipOutFloatingObjects(RenderBlock* rootBlock, const Paint
Info* paintInfo, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize&
offsetFromRootBlock) |
| 1636 { | 1307 { |
| 1637 if (m_floatingObjects) { | 1308 // FIXME(sky): Remove this. |
| 1638 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1639 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 1640 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end
; ++it) { | |
| 1641 FloatingObject* floatingObject = it->get(); | |
| 1642 LayoutRect floatBox(offsetFromRootBlock.width() + xPositionForFloatI
ncludingMargin(floatingObject), | |
| 1643 offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(
floatingObject), | |
| 1644 floatingObject->renderer()->width(), floatingObject->renderer()-
>height()); | |
| 1645 rootBlock->flipForWritingMode(floatBox); | |
| 1646 floatBox.move(rootBlockPhysicalPosition.x(), rootBlockPhysicalPositi
on.y()); | |
| 1647 paintInfo->context->clipOut(pixelSnappedIntRect(floatBox)); | |
| 1648 } | |
| 1649 } | |
| 1650 } | 1309 } |
| 1651 | 1310 |
| 1652 void RenderBlockFlow::clearFloats(EClear clear) | 1311 void RenderBlockFlow::clearFloats(EClear clear) |
| 1653 { | 1312 { |
| 1654 positionNewFloats(); | 1313 // FIXME(sky): Remove this. |
| 1655 // set y position | |
| 1656 LayoutUnit newY = 0; | |
| 1657 switch (clear) { | |
| 1658 case CLEFT: | |
| 1659 newY = lowestFloatLogicalBottom(FloatingObject::FloatLeft); | |
| 1660 break; | |
| 1661 case CRIGHT: | |
| 1662 newY = lowestFloatLogicalBottom(FloatingObject::FloatRight); | |
| 1663 break; | |
| 1664 case CBOTH: | |
| 1665 newY = lowestFloatLogicalBottom(); | |
| 1666 default: | |
| 1667 break; | |
| 1668 } | |
| 1669 if (height() < newY) | |
| 1670 setLogicalHeight(newY); | |
| 1671 } | 1314 } |
| 1672 | 1315 |
| 1673 bool RenderBlockFlow::containsFloat(RenderBox* renderer) const | 1316 bool RenderBlockFlow::containsFloat(RenderBox* renderer) const |
| 1674 { | 1317 { |
| 1675 return m_floatingObjects && m_floatingObjects->set().contains<FloatingObject
HashTranslator>(renderer); | 1318 // FIXME(sky): Remove this. |
| 1319 return false; |
| 1676 } | 1320 } |
| 1677 | 1321 |
| 1678 void RenderBlockFlow::removeFloatingObjects() | 1322 void RenderBlockFlow::removeFloatingObjects() |
| 1679 { | 1323 { |
| 1680 if (!m_floatingObjects) | 1324 // FIXME(sky): Remove this. |
| 1681 return; | |
| 1682 | |
| 1683 markSiblingsWithFloatsForLayout(); | |
| 1684 | |
| 1685 m_floatingObjects->clear(); | |
| 1686 } | 1325 } |
| 1687 | 1326 |
| 1688 LayoutPoint RenderBlockFlow::flipFloatForWritingModeForChild(const FloatingObjec
t* child, const LayoutPoint& point) const | 1327 LayoutPoint RenderBlockFlow::flipFloatForWritingModeForChild(const FloatingObjec
t* child, const LayoutPoint& point) const |
| 1689 { | 1328 { |
| 1690 if (!style()->isFlippedBlocksWritingMode()) | 1329 // FIXME(sky): Remove this. |
| 1691 return point; | 1330 return LayoutPoint(); |
| 1692 | |
| 1693 // This is similar to RenderBox::flipForWritingModeForChild. We have to subt
ract out our left/top offsets twice, since | |
| 1694 // it's going to get added back in. We hide this complication here so that t
he calling code looks normal for the unflipped | |
| 1695 // case. | |
| 1696 if (isHorizontalWritingMode()) | |
| 1697 return LayoutPoint(point.x(), point.y() + height() - child->renderer()->
height() - 2 * yPositionForFloatIncludingMargin(child)); | |
| 1698 return LayoutPoint(point.x() + width() - child->renderer()->width() - 2 * xP
ositionForFloatIncludingMargin(child), point.y()); | |
| 1699 } | 1331 } |
| 1700 | 1332 |
| 1701 LayoutUnit RenderBlockFlow::logicalLeftOffsetForPositioningFloat(LayoutUnit logi
calTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemainin
g) const | 1333 LayoutUnit RenderBlockFlow::logicalLeftOffsetForPositioningFloat(LayoutUnit logi
calTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemainin
g) const |
| 1702 { | 1334 { |
| 1335 // FIXME(sky): Remove this. |
| 1703 LayoutUnit offset = fixedOffset; | 1336 LayoutUnit offset = fixedOffset; |
| 1704 if (m_floatingObjects && m_floatingObjects->hasLeftObjects()) | |
| 1705 offset = m_floatingObjects->logicalLeftOffsetForPositioningFloat(fixedOf
fset, logicalTop, heightRemaining); | |
| 1706 return adjustLogicalLeftOffsetForLine(offset, applyTextIndent); | 1337 return adjustLogicalLeftOffsetForLine(offset, applyTextIndent); |
| 1707 } | 1338 } |
| 1708 | 1339 |
| 1709 LayoutUnit RenderBlockFlow::logicalRightOffsetForPositioningFloat(LayoutUnit log
icalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaini
ng) const | 1340 LayoutUnit RenderBlockFlow::logicalRightOffsetForPositioningFloat(LayoutUnit log
icalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaini
ng) const |
| 1710 { | 1341 { |
| 1342 // FIXME(sky): Remove this. |
| 1711 LayoutUnit offset = fixedOffset; | 1343 LayoutUnit offset = fixedOffset; |
| 1712 if (m_floatingObjects && m_floatingObjects->hasRightObjects()) | |
| 1713 offset = m_floatingObjects->logicalRightOffsetForPositioningFloat(fixedO
ffset, logicalTop, heightRemaining); | |
| 1714 return adjustLogicalRightOffsetForLine(offset, applyTextIndent); | 1344 return adjustLogicalRightOffsetForLine(offset, applyTextIndent); |
| 1715 } | 1345 } |
| 1716 | 1346 |
| 1717 LayoutUnit RenderBlockFlow::adjustLogicalLeftOffsetForLine(LayoutUnit offsetFrom
Floats, bool applyTextIndent) const | 1347 LayoutUnit RenderBlockFlow::adjustLogicalLeftOffsetForLine(LayoutUnit offsetFrom
Floats, bool applyTextIndent) const |
| 1718 { | 1348 { |
| 1719 LayoutUnit left = offsetFromFloats; | 1349 LayoutUnit left = offsetFromFloats; |
| 1720 | 1350 |
| 1721 if (applyTextIndent && style()->isLeftToRightDirection()) | 1351 if (applyTextIndent && style()->isLeftToRightDirection()) |
| 1722 left += textIndentOffset(); | 1352 left += textIndentOffset(); |
| 1723 | 1353 |
| 1724 return left; | 1354 return left; |
| 1725 } | 1355 } |
| 1726 | 1356 |
| 1727 LayoutUnit RenderBlockFlow::adjustLogicalRightOffsetForLine(LayoutUnit offsetFro
mFloats, bool applyTextIndent) const | 1357 LayoutUnit RenderBlockFlow::adjustLogicalRightOffsetForLine(LayoutUnit offsetFro
mFloats, bool applyTextIndent) const |
| 1728 { | 1358 { |
| 1729 LayoutUnit right = offsetFromFloats; | 1359 LayoutUnit right = offsetFromFloats; |
| 1730 | 1360 |
| 1731 if (applyTextIndent && !style()->isLeftToRightDirection()) | 1361 if (applyTextIndent && !style()->isLeftToRightDirection()) |
| 1732 right -= textIndentOffset(); | 1362 right -= textIndentOffset(); |
| 1733 | 1363 |
| 1734 return right; | 1364 return right; |
| 1735 } | 1365 } |
| 1736 | 1366 |
| 1737 LayoutPoint RenderBlockFlow::computeLogicalLocationForFloat(const FloatingObject
* floatingObject, LayoutUnit logicalTopOffset) const | 1367 LayoutPoint RenderBlockFlow::computeLogicalLocationForFloat(const FloatingObject
* floatingObject, LayoutUnit logicalTopOffset) const |
| 1738 { | 1368 { |
| 1739 RenderBox* childBox = floatingObject->renderer(); | 1369 // FIXME(sky): Remove this. |
| 1740 LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent(); // Constant pa
rt of left offset. | 1370 return LayoutPoint(); |
| 1741 LayoutUnit logicalRightOffset; // Constant part of right offset. | |
| 1742 logicalRightOffset = logicalRightOffsetForContent(); | |
| 1743 | |
| 1744 LayoutUnit floatLogicalWidth = std::min(logicalWidthForFloat(floatingObject)
, logicalRightOffset - logicalLeftOffset); // The width we look for. | |
| 1745 | |
| 1746 LayoutUnit floatLogicalLeft; | |
| 1747 | |
| 1748 if (childBox->style()->floating() == LeftFloat) { | |
| 1749 LayoutUnit heightRemainingLeft = 1; | |
| 1750 LayoutUnit heightRemainingRight = 1; | |
| 1751 floatLogicalLeft = logicalLeftOffsetForPositioningFloat(logicalTopOffset
, logicalLeftOffset, false, &heightRemainingLeft); | |
| 1752 while (logicalRightOffsetForPositioningFloat(logicalTopOffset, logicalRi
ghtOffset, false, &heightRemainingRight) - floatLogicalLeft < floatLogicalWidth)
{ | |
| 1753 logicalTopOffset += std::min(heightRemainingLeft, heightRemainingRig
ht); | |
| 1754 floatLogicalLeft = logicalLeftOffsetForPositioningFloat(logicalTopOf
fset, logicalLeftOffset, false, &heightRemainingLeft); | |
| 1755 } | |
| 1756 floatLogicalLeft = std::max(logicalLeftOffset - borderAndPaddingLogicalL
eft(), floatLogicalLeft); | |
| 1757 } else { | |
| 1758 LayoutUnit heightRemainingLeft = 1; | |
| 1759 LayoutUnit heightRemainingRight = 1; | |
| 1760 floatLogicalLeft = logicalRightOffsetForPositioningFloat(logicalTopOffse
t, logicalRightOffset, false, &heightRemainingRight); | |
| 1761 while (floatLogicalLeft - logicalLeftOffsetForPositioningFloat(logicalTo
pOffset, logicalLeftOffset, false, &heightRemainingLeft) < floatLogicalWidth) { | |
| 1762 logicalTopOffset += std::min(heightRemainingLeft, heightRemainingRig
ht); | |
| 1763 floatLogicalLeft = logicalRightOffsetForPositioningFloat(logicalTopO
ffset, logicalRightOffset, false, &heightRemainingRight); | |
| 1764 } | |
| 1765 // Use the original width of the float here, since the local variable | |
| 1766 // |floatLogicalWidth| was capped to the available line width. See | |
| 1767 // fast/block/float/clamped-right-float.html. | |
| 1768 floatLogicalLeft -= logicalWidthForFloat(floatingObject); | |
| 1769 } | |
| 1770 | |
| 1771 return LayoutPoint(floatLogicalLeft, logicalTopOffset); | |
| 1772 } | 1371 } |
| 1773 | 1372 |
| 1774 FloatingObject* RenderBlockFlow::insertFloatingObject(RenderBox* floatBox) | 1373 FloatingObject* RenderBlockFlow::insertFloatingObject(RenderBox* floatBox) |
| 1775 { | 1374 { |
| 1776 ASSERT(floatBox->isFloating()); | 1375 return 0; |
| 1777 | |
| 1778 // Create the list of special objects if we don't aleady have one | |
| 1779 if (!m_floatingObjects) { | |
| 1780 createFloatingObjects(); | |
| 1781 } else { | |
| 1782 // Don't insert the object again if it's already in the list | |
| 1783 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1784 FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHash
Translator>(floatBox); | |
| 1785 if (it != floatingObjectSet.end()) | |
| 1786 return it->get(); | |
| 1787 } | |
| 1788 | |
| 1789 // Create the special object entry & append it to the list | |
| 1790 | |
| 1791 OwnPtr<FloatingObject> newObj = FloatingObject::create(floatBox); | |
| 1792 | |
| 1793 floatBox->layoutIfNeeded(); | |
| 1794 | |
| 1795 setLogicalWidthForFloat(newObj.get(), logicalWidthForChild(floatBox) + margi
nStartForChild(floatBox) + marginEndForChild(floatBox)); | |
| 1796 | |
| 1797 return m_floatingObjects->add(newObj.release()); | |
| 1798 } | 1376 } |
| 1799 | 1377 |
| 1800 void RenderBlockFlow::removeFloatingObject(RenderBox* floatBox) | 1378 void RenderBlockFlow::removeFloatingObject(RenderBox* floatBox) |
| 1801 { | 1379 { |
| 1802 if (m_floatingObjects) { | 1380 // FIXME(sky): Remove this. |
| 1803 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1804 FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHash
Translator>(floatBox); | |
| 1805 if (it != floatingObjectSet.end()) { | |
| 1806 FloatingObject* floatingObject = it->get(); | |
| 1807 if (childrenInline()) { | |
| 1808 LayoutUnit logicalTop = logicalTopForFloat(floatingObject); | |
| 1809 LayoutUnit logicalBottom = logicalBottomForFloat(floatingObject)
; | |
| 1810 | |
| 1811 // Fix for https://bugs.webkit.org/show_bug.cgi?id=54995. | |
| 1812 if (logicalBottom < 0 || logicalBottom < logicalTop || logicalTo
p == LayoutUnit::max()) { | |
| 1813 logicalBottom = LayoutUnit::max(); | |
| 1814 } else { | |
| 1815 // Special-case zero- and less-than-zero-height floats: thos
e don't touch | |
| 1816 // the line that they're on, but it still needs to be dirtie
d. This is | |
| 1817 // accomplished by pretending they have a height of 1. | |
| 1818 logicalBottom = std::max(logicalBottom, logicalTop + 1); | |
| 1819 } | |
| 1820 if (floatingObject->originatingLine()) { | |
| 1821 if (!selfNeedsLayout()) { | |
| 1822 ASSERT(floatingObject->originatingLine()->renderer() ==
this); | |
| 1823 floatingObject->originatingLine()->markDirty(); | |
| 1824 } | |
| 1825 #if ENABLE(ASSERT) | |
| 1826 floatingObject->setOriginatingLine(0); | |
| 1827 #endif | |
| 1828 } | |
| 1829 markLinesDirtyInBlockRange(0, logicalBottom); | |
| 1830 } | |
| 1831 m_floatingObjects->remove(floatingObject); | |
| 1832 } | |
| 1833 } | |
| 1834 } | 1381 } |
| 1835 | 1382 |
| 1836 void RenderBlockFlow::removeFloatingObjectsBelow(FloatingObject* lastFloat, int
logicalOffset) | 1383 void RenderBlockFlow::removeFloatingObjectsBelow(FloatingObject* lastFloat, int
logicalOffset) |
| 1837 { | 1384 { |
| 1838 if (!containsFloats()) | 1385 // FIXME(sky): Remove this. |
| 1839 return; | |
| 1840 | |
| 1841 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1842 FloatingObject* curr = floatingObjectSet.last().get(); | |
| 1843 while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >
= logicalOffset)) { | |
| 1844 m_floatingObjects->remove(curr); | |
| 1845 if (floatingObjectSet.isEmpty()) | |
| 1846 break; | |
| 1847 curr = floatingObjectSet.last().get(); | |
| 1848 } | |
| 1849 } | 1386 } |
| 1850 | 1387 |
| 1851 bool RenderBlockFlow::positionNewFloats() | 1388 bool RenderBlockFlow::positionNewFloats() |
| 1852 { | 1389 { |
| 1853 if (!m_floatingObjects) | 1390 // FIXME(sky): Remove this. |
| 1854 return false; | 1391 return false; |
| 1855 | |
| 1856 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1857 if (floatingObjectSet.isEmpty()) | |
| 1858 return false; | |
| 1859 | |
| 1860 // If all floats have already been positioned, then we have no work to do. | |
| 1861 if (floatingObjectSet.last()->isPlaced()) | |
| 1862 return false; | |
| 1863 | |
| 1864 // Move backwards through our floating object list until we find a float tha
t has | |
| 1865 // already been positioned. Then we'll be able to move forward, positioning
all of | |
| 1866 // the new floats that need it. | |
| 1867 FloatingObjectSetIterator it = floatingObjectSet.end(); | |
| 1868 --it; // Go to last item. | |
| 1869 FloatingObjectSetIterator begin = floatingObjectSet.begin(); | |
| 1870 FloatingObject* lastPlacedFloatingObject = 0; | |
| 1871 while (it != begin) { | |
| 1872 --it; | |
| 1873 if ((*it)->isPlaced()) { | |
| 1874 lastPlacedFloatingObject = it->get(); | |
| 1875 ++it; | |
| 1876 break; | |
| 1877 } | |
| 1878 } | |
| 1879 | |
| 1880 LayoutUnit logicalTop = logicalHeight(); | |
| 1881 | |
| 1882 // The float cannot start above the top position of the last positioned floa
t. | |
| 1883 if (lastPlacedFloatingObject) | |
| 1884 logicalTop = std::max(logicalTopForFloat(lastPlacedFloatingObject), logi
calTop); | |
| 1885 | |
| 1886 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 1887 // Now walk through the set of unpositioned floats and place them. | |
| 1888 for (; it != end; ++it) { | |
| 1889 FloatingObject* floatingObject = it->get(); | |
| 1890 // The containing block is responsible for positioning floats, so if we
have floats in our | |
| 1891 // list that come from somewhere else, do not attempt to position them. | |
| 1892 if (floatingObject->renderer()->containingBlock() != this) | |
| 1893 continue; | |
| 1894 | |
| 1895 RenderBox* childBox = floatingObject->renderer(); | |
| 1896 | |
| 1897 // FIXME Investigate if this can be removed. crbug.com/370006 | |
| 1898 childBox->setMayNeedPaintInvalidation(true); | |
| 1899 | |
| 1900 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ?
marginStartForChild(childBox) : marginEndForChild(childBox); | |
| 1901 if (childBox->style()->clear() & CLEFT) | |
| 1902 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Left), logicalTop); | |
| 1903 if (childBox->style()->clear() & CRIGHT) | |
| 1904 logicalTop = std::max(lowestFloatLogicalBottom(FloatingObject::Float
Right), logicalTop); | |
| 1905 | |
| 1906 LayoutPoint floatLogicalLocation = computeLogicalLocationForFloat(floati
ngObject, logicalTop); | |
| 1907 | |
| 1908 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); | |
| 1909 | |
| 1910 setLogicalLeftForChild(childBox, floatLogicalLocation.x() + childLogical
LeftMargin); | |
| 1911 setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeF
orChild(childBox)); | |
| 1912 | |
| 1913 SubtreeLayoutScope layoutScope(*childBox); | |
| 1914 childBox->layoutIfNeeded(); | |
| 1915 | |
| 1916 setLogicalTopForFloat(floatingObject, floatLogicalLocation.y()); | |
| 1917 setLogicalHeightForFloat(floatingObject, logicalHeightForChild(childBox)
+ marginBeforeForChild(childBox) + marginAfterForChild(childBox)); | |
| 1918 | |
| 1919 m_floatingObjects->addPlacedObject(floatingObject); | |
| 1920 | |
| 1921 if (ShapeOutsideInfo* shapeOutside = childBox->shapeOutsideInfo()) | |
| 1922 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(childBo
x)); | |
| 1923 } | |
| 1924 return true; | |
| 1925 } | 1392 } |
| 1926 | 1393 |
| 1927 bool RenderBlockFlow::hasOverhangingFloat(RenderBox* renderer) | 1394 bool RenderBlockFlow::hasOverhangingFloat(RenderBox* renderer) |
| 1928 { | 1395 { |
| 1929 if (!m_floatingObjects || !parent()) | 1396 // FIXME(sky): Remove this. |
| 1930 return false; | 1397 return false; |
| 1931 | |
| 1932 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 1933 FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHashTran
slator>(renderer); | |
| 1934 if (it == floatingObjectSet.end()) | |
| 1935 return false; | |
| 1936 | |
| 1937 return logicalBottomForFloat(it->get()) > logicalHeight(); | |
| 1938 } | 1398 } |
| 1939 | 1399 |
| 1940 void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logic
alLeftOffset, LayoutUnit logicalTopOffset) | 1400 void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logic
alLeftOffset, LayoutUnit logicalTopOffset) |
| 1941 { | 1401 { |
| 1942 ASSERT(!avoidsFloats()); | 1402 // FIXME(sky): Remove this. |
| 1943 | |
| 1944 // If we create our own block formatting context then our contents don't int
eract with floats outside it, even those from our parent. | |
| 1945 if (createsBlockFormattingContext()) | |
| 1946 return; | |
| 1947 | |
| 1948 // If the parent or previous sibling doesn't have any floats to add, don't b
other. | |
| 1949 if (!prev->m_floatingObjects) | |
| 1950 return; | |
| 1951 | |
| 1952 logicalLeftOffset += marginLogicalLeft(); | |
| 1953 | |
| 1954 const FloatingObjectSet& prevSet = prev->m_floatingObjects->set(); | |
| 1955 FloatingObjectSetIterator prevEnd = prevSet.end(); | |
| 1956 for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd;
++prevIt) { | |
| 1957 FloatingObject* floatingObject = prevIt->get(); | |
| 1958 if (logicalBottomForFloat(floatingObject) > logicalTopOffset) { | |
| 1959 if (!m_floatingObjects || !m_floatingObjects->set().contains(floatin
gObject)) { | |
| 1960 // We create the floating object list lazily. | |
| 1961 if (!m_floatingObjects) | |
| 1962 createFloatingObjects(); | |
| 1963 | |
| 1964 // Applying the child's margin makes no sense in the case where
the child was passed in. | |
| 1965 // since this margin was added already through the modification
of the |logicalLeftOffset| variable | |
| 1966 // above. |logicalLeftOffset| will equal the margin in this case
, so it's already been taken | |
| 1967 // into account. Only apply this code if prev is the parent, sin
ce otherwise the left margin | |
| 1968 // will get applied twice. | |
| 1969 LayoutSize offset = isHorizontalWritingMode() | |
| 1970 ? LayoutSize(logicalLeftOffset - (prev != parent() ? prev->m
arginLeft() : LayoutUnit()), logicalTopOffset) | |
| 1971 : LayoutSize(logicalTopOffset, logicalLeftOffset - (prev !=
parent() ? prev->marginTop() : LayoutUnit())); | |
| 1972 | |
| 1973 m_floatingObjects->add(floatingObject->copyToNewContainer(offset
)); | |
| 1974 } | |
| 1975 } | |
| 1976 } | |
| 1977 } | 1403 } |
| 1978 | 1404 |
| 1979 void RenderBlockFlow::addOverhangingFloats(RenderBlockFlow* child, bool makeChil
dPaintOtherFloats) | 1405 void RenderBlockFlow::addOverhangingFloats(RenderBlockFlow* child, bool makeChil
dPaintOtherFloats) |
| 1980 { | 1406 { |
| 1981 // Prevent floats from being added to the canvas by the root element, e.g.,
<html>. | 1407 // FIXME(sky): Remove this. |
| 1982 if (!child->containsFloats() || child->createsBlockFormattingContext()) | |
| 1983 return; | |
| 1984 | |
| 1985 LayoutUnit childLogicalTop = child->logicalTop(); | |
| 1986 LayoutUnit childLogicalLeft = child->logicalLeft(); | |
| 1987 | |
| 1988 // Floats that will remain the child's responsibility to paint should factor
into its | |
| 1989 // overflow. | |
| 1990 FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end(); | |
| 1991 for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().beg
in(); childIt != childEnd; ++childIt) { | |
| 1992 FloatingObject* floatingObject = childIt->get(); | |
| 1993 LayoutUnit logicalBottomForFloat = std::min(this->logicalBottomForFloat(
floatingObject), LayoutUnit::max() - childLogicalTop); | |
| 1994 LayoutUnit logicalBottom = childLogicalTop + logicalBottomForFloat; | |
| 1995 | |
| 1996 if (logicalBottom > logicalHeight()) { | |
| 1997 // If the object is not in the list, we add it now. | |
| 1998 if (!containsFloat(floatingObject->renderer())) { | |
| 1999 LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(-chil
dLogicalLeft, -childLogicalTop) : LayoutSize(-childLogicalTop, -childLogicalLeft
); | |
| 2000 bool shouldPaint = false; | |
| 2001 | |
| 2002 // The nearest enclosing layer always paints the float (so that
zindex and stacking | |
| 2003 // behaves properly). We always want to propagate the desire to
paint the float as | |
| 2004 // far out as we can, to the outermost block that overlaps the f
loat, stopping only | |
| 2005 // if we hit a self-painting layer boundary. | |
| 2006 if (floatingObject->renderer()->enclosingFloatPaintingLayer() ==
enclosingFloatPaintingLayer()) { | |
| 2007 floatingObject->setShouldPaint(false); | |
| 2008 shouldPaint = true; | |
| 2009 } | |
| 2010 // We create the floating object list lazily. | |
| 2011 if (!m_floatingObjects) | |
| 2012 createFloatingObjects(); | |
| 2013 | |
| 2014 m_floatingObjects->add(floatingObject->copyToNewContainer(offset
, shouldPaint, true)); | |
| 2015 } | |
| 2016 } else { | |
| 2017 if (makeChildPaintOtherFloats && !floatingObject->shouldPaint() && !
floatingObject->renderer()->hasSelfPaintingLayer() | |
| 2018 && floatingObject->renderer()->isDescendantOf(child) && floating
Object->renderer()->enclosingFloatPaintingLayer() == child->enclosingFloatPainti
ngLayer()) { | |
| 2019 // The float is not overhanging from this block, so if it is a d
escendant of the child, the child should | |
| 2020 // paint it (the other case is that it is intruding into the chi
ld), unless it has its own layer or enclosing | |
| 2021 // layer. | |
| 2022 // If makeChildPaintOtherFloats is false, it means that the chil
d must already know about all the floats | |
| 2023 // it should paint. | |
| 2024 floatingObject->setShouldPaint(true); | |
| 2025 } | |
| 2026 | |
| 2027 // Since the float doesn't overhang, it didn't get put into our list
. We need to go ahead and add its overflow in to the | |
| 2028 // child now. | |
| 2029 if (floatingObject->isDescendant()) | |
| 2030 child->addOverflowFromChild(floatingObject->renderer(), LayoutSi
ze(xPositionForFloatIncludingMargin(floatingObject), yPositionForFloatIncludingM
argin(floatingObject))); | |
| 2031 } | |
| 2032 } | |
| 2033 } | 1408 } |
| 2034 | 1409 |
| 2035 LayoutUnit RenderBlockFlow::lowestFloatLogicalBottom(FloatingObject::Type floatT
ype) const | 1410 LayoutUnit RenderBlockFlow::lowestFloatLogicalBottom(FloatingObject::Type floatT
ype) const |
| 2036 { | 1411 { |
| 2037 if (!m_floatingObjects) | 1412 // FIXME(sky): Remove this. |
| 2038 return 0; | 1413 return 0; |
| 2039 | |
| 2040 return m_floatingObjects->lowestFloatLogicalBottom(floatType); | |
| 2041 } | 1414 } |
| 2042 | 1415 |
| 2043 LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight
, ShapeOutsideFloatOffsetMode offsetMode) const | 1416 LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight
, ShapeOutsideFloatOffsetMode offsetMode) const |
| 2044 { | 1417 { |
| 2045 if (!m_floatingObjects) | 1418 // FIXME(sky): Remove this. |
| 2046 return logicalHeight; | 1419 return logicalHeight; |
| 2047 | |
| 2048 LayoutUnit logicalBottom; | |
| 2049 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 2050 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 2051 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { | |
| 2052 FloatingObject* floatingObject = it->get(); | |
| 2053 LayoutUnit floatLogicalBottom = logicalBottomForFloat(floatingObject); | |
| 2054 ShapeOutsideInfo* shapeOutside = floatingObject->renderer()->shapeOutsid
eInfo(); | |
| 2055 if (shapeOutside && (offsetMode == ShapeOutsideFloatShapeOffset)) { | |
| 2056 LayoutUnit shapeLogicalBottom = logicalTopForFloat(floatingObject) +
marginBeforeForChild(floatingObject->renderer()) + shapeOutside->shapeLogicalBo
ttom(); | |
| 2057 // Use the shapeLogicalBottom unless it extends outside of the margi
n box, in which case it is clipped. | |
| 2058 if (shapeLogicalBottom < floatLogicalBottom) | |
| 2059 floatLogicalBottom = shapeLogicalBottom; | |
| 2060 } | |
| 2061 if (floatLogicalBottom > logicalHeight) | |
| 2062 logicalBottom = logicalBottom ? std::min(floatLogicalBottom, logical
Bottom) : floatLogicalBottom; | |
| 2063 } | |
| 2064 | |
| 2065 return logicalBottom; | |
| 2066 } | 1420 } |
| 2067 | 1421 |
| 2068 bool RenderBlockFlow::hitTestFloats(const HitTestRequest& request, HitTestResult
& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumul
atedOffset) | 1422 bool RenderBlockFlow::hitTestFloats(const HitTestRequest& request, HitTestResult
& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumul
atedOffset) |
| 2069 { | 1423 { |
| 2070 if (!m_floatingObjects) | 1424 // FIXME(sky): Remove this. |
| 2071 return false; | |
| 2072 | |
| 2073 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 2074 FloatingObjectSetIterator begin = floatingObjectSet.begin(); | |
| 2075 for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) { | |
| 2076 --it; | |
| 2077 FloatingObject* floatingObject = it->get(); | |
| 2078 if (floatingObject->shouldPaint() && !floatingObject->renderer()->hasSel
fPaintingLayer()) { | |
| 2079 LayoutUnit xOffset = xPositionForFloatIncludingMargin(floatingObject
) - floatingObject->renderer()->x(); | |
| 2080 LayoutUnit yOffset = yPositionForFloatIncludingMargin(floatingObject
) - floatingObject->renderer()->y(); | |
| 2081 LayoutPoint childPoint = flipFloatForWritingModeForChild(floatingObj
ect, accumulatedOffset + LayoutSize(xOffset, yOffset)); | |
| 2082 if (floatingObject->renderer()->hitTest(request, result, locationInC
ontainer, childPoint)) { | |
| 2083 updateHitTestResult(result, locationInContainer.point() - toLayo
utSize(childPoint)); | |
| 2084 return true; | |
| 2085 } | |
| 2086 } | |
| 2087 } | |
| 2088 | |
| 2089 return false; | 1425 return false; |
| 2090 } | 1426 } |
| 2091 | 1427 |
| 2092 void RenderBlockFlow::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutU
nit& right) const | 1428 void RenderBlockFlow::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutU
nit& right) const |
| 2093 { | 1429 { |
| 2094 // We don't deal with relative positioning. Our assumption is that you shrin
k to fit the lines without accounting | 1430 // We don't deal with relative positioning. Our assumption is that you shrin
k to fit the lines without accounting |
| 2095 // for either overflow or translations via relative positioning. | 1431 // for either overflow or translations via relative positioning. |
| 2096 if (childrenInline()) { | 1432 if (childrenInline()) { |
| 2097 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
{ | 1433 for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox())
{ |
| 2098 if (box->firstChild()) | 1434 if (box->firstChild()) |
| 2099 left = std::min(left, x + static_cast<LayoutUnit>(box->firstChil
d()->x())); | 1435 left = std::min(left, x + static_cast<LayoutUnit>(box->firstChil
d()->x())); |
| 2100 if (box->lastChild()) | 1436 if (box->lastChild()) |
| 2101 right = std::max(right, x + static_cast<LayoutUnit>(ceilf(box->l
astChild()->logicalRight()))); | 1437 right = std::max(right, x + static_cast<LayoutUnit>(ceilf(box->l
astChild()->logicalRight()))); |
| 2102 } | 1438 } |
| 2103 } else { | 1439 } else { |
| 2104 for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox())
{ | 1440 for (RenderBox* obj = firstChildBox(); obj; obj = obj->nextSiblingBox())
{ |
| 2105 if (!obj->isFloatingOrOutOfFlowPositioned()) { | 1441 if (!obj->isFloatingOrOutOfFlowPositioned()) { |
| 2106 if (obj->isRenderBlockFlow() && !obj->hasOverflowClip()) { | 1442 if (obj->isRenderBlockFlow() && !obj->hasOverflowClip()) { |
| 2107 toRenderBlockFlow(obj)->adjustForBorderFit(x + obj->x(), lef
t, right); | 1443 toRenderBlockFlow(obj)->adjustForBorderFit(x + obj->x(), lef
t, right); |
| 2108 } else { | 1444 } else { |
| 2109 // We are a replaced element or some kind of non-block-flow
object. | 1445 // We are a replaced element or some kind of non-block-flow
object. |
| 2110 left = std::min(left, x + obj->x()); | 1446 left = std::min(left, x + obj->x()); |
| 2111 right = std::max(right, x + obj->x() + obj->width()); | 1447 right = std::max(right, x + obj->x() + obj->width()); |
| 2112 } | 1448 } |
| 2113 } | 1449 } |
| 2114 } | 1450 } |
| 2115 } | 1451 } |
| 2116 | |
| 2117 if (m_floatingObjects) { | |
| 2118 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | |
| 2119 FloatingObjectSetIterator end = floatingObjectSet.end(); | |
| 2120 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end
; ++it) { | |
| 2121 FloatingObject* floatingObject = it->get(); | |
| 2122 // Only examine the object if our m_shouldPaint flag is set. | |
| 2123 if (floatingObject->shouldPaint()) { | |
| 2124 LayoutUnit floatLeft = xPositionForFloatIncludingMargin(floating
Object) - floatingObject->renderer()->x(); | |
| 2125 LayoutUnit floatRight = floatLeft + floatingObject->renderer()->
width(); | |
| 2126 left = std::min(left, floatLeft); | |
| 2127 right = std::max(right, floatRight); | |
| 2128 } | |
| 2129 } | |
| 2130 } | |
| 2131 } | 1452 } |
| 2132 | 1453 |
| 2133 void RenderBlockFlow::fitBorderToLinesIfNeeded() | 1454 void RenderBlockFlow::fitBorderToLinesIfNeeded() |
| 2134 { | 1455 { |
| 2135 if (style()->borderFit() == BorderFitBorder || hasOverrideWidth()) | 1456 if (style()->borderFit() == BorderFitBorder || hasOverrideWidth()) |
| 2136 return; | 1457 return; |
| 2137 | 1458 |
| 2138 // Walk any normal flow lines to snugly fit. | 1459 // Walk any normal flow lines to snugly fit. |
| 2139 LayoutUnit left = LayoutUnit::max(); | 1460 LayoutUnit left = LayoutUnit::max(); |
| 2140 LayoutUnit right = LayoutUnit::min(); | 1461 LayoutUnit right = LayoutUnit::min(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2269 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() | 1590 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() |
| 2270 { | 1591 { |
| 2271 if (m_rareData) | 1592 if (m_rareData) |
| 2272 return *m_rareData; | 1593 return *m_rareData; |
| 2273 | 1594 |
| 2274 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); | 1595 m_rareData = adoptPtr(new RenderBlockFlowRareData(this)); |
| 2275 return *m_rareData; | 1596 return *m_rareData; |
| 2276 } | 1597 } |
| 2277 | 1598 |
| 2278 } // namespace blink | 1599 } // namespace blink |
| OLD | NEW |