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

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

Issue 551263005: *** DO NOT LAND *** Implement column-span:all without reparenting renderers. Work in progress. (Closed) Base URL: git:blink.git@new-multicol-no-renderer-reparenting
Patch Set: Copy margin properties from a spanner to its spanner set, to simplify code. Created 6 years, 3 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
« no previous file with comments | « no previous file | Source/core/rendering/RenderBox.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 child->setY(logicalTop); 541 child->setY(logicalTop);
542 } else { 542 } else {
543 child->setX(logicalTop); 543 child->setX(logicalTop);
544 } 544 }
545 } 545 }
546 546
547 void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom) 547 void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom)
548 { 548 {
549 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore(); 549 LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
550 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore(); 550 LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore();
551 bool isColumnSpanner = child->isColumnSpanAll();
552
553 if (isColumnSpanner) {
554 // Margins of a column spanner cannot collapse with anything.
555 setLogicalHeight(logicalHeight() + marginInfo.margin());
556 marginInfo.clearMargin();
557 LayoutUnit adjustment = flowThreadContainingBlock()->enterColumnSpanner( child, logicalHeight());
558 setLogicalHeight(logicalHeight() + adjustment);
559 }
551 560
552 // The child is a normal flow object. Compute the margins we will use for co llapsing now. 561 // The child is a normal flow object. Compute the margins we will use for co llapsing now.
553 child->computeAndSetBlockDirectionMargins(this); 562 child->computeAndSetBlockDirectionMargins(this);
554 563
555 // Try to guess our correct logical top position. In most cases this guess w ill 564 // Try to guess our correct logical top position. In most cases this guess w ill
556 // be correct. Only if we're wrong (when we compute the real logical top pos ition) 565 // be correct. Only if we're wrong (when we compute the real logical top pos ition)
557 // will we have to potentially relayout. 566 // will we have to potentially relayout.
558 LayoutUnit estimateWithoutPagination; 567 LayoutUnit estimateWithoutPagination;
559 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo , estimateWithoutPagination); 568 LayoutUnit logicalTopEstimate = estimateLogicalTopPosition(child, marginInfo , estimateWithoutPagination);
560 569
561 bool isColumnSpanner = child->isColumnSpanAll();
562 if (isColumnSpanner) {
563 LayoutUnit margin = child->marginBefore();
564 logicalTopEstimate -= margin;
565 flowThreadContainingBlock()->enterColumnSpanner(child, logicalTopEstimat e);
566 logicalTopEstimate += margin;
567 }
568
569 // Cache our old rect so that we can dirty the proper paint invalidation rec ts if the child moves. 570 // Cache our old rect so that we can dirty the proper paint invalidation rec ts if the child moves.
570 LayoutRect oldRect = child->frameRect(); 571 LayoutRect oldRect = child->frameRect();
571 LayoutUnit oldLogicalTop = logicalTopForChild(child); 572 LayoutUnit oldLogicalTop = logicalTopForChild(child);
572 573
573 // Go ahead and position the child as though it didn't collapse with the top . 574 // Go ahead and position the child as though it didn't collapse with the top .
574 setLogicalTopForChild(child, logicalTopEstimate); 575 setLogicalTopForChild(child, logicalTopEstimate);
575 576
576 RenderBlockFlow* childRenderBlockFlow = child->isRenderBlockFlow() ? toRende rBlockFlow(child) : 0; 577 RenderBlockFlow* childRenderBlockFlow = child->isRenderBlockFlow() ? toRende rBlockFlow(child) : 0;
577 bool markDescendantsWithFloats = false; 578 bool markDescendantsWithFloats = false;
578 if (logicalTopEstimate != oldLogicalTop && childRenderBlockFlow && !childRen derBlockFlow->avoidsFloats() && childRenderBlockFlow->containsFloats()) { 579 if (logicalTopEstimate != oldLogicalTop && childRenderBlockFlow && !childRen derBlockFlow->avoidsFloats() && childRenderBlockFlow->containsFloats()) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 727
727 // Our guess was wrong. Make the child lay itself out again. 728 // Our guess was wrong. Make the child lay itself out again.
728 child->layoutIfNeeded(); 729 child->layoutIfNeeded();
729 } 730 }
730 731
731 LayoutUnit oldTop = logicalTopAfterClear; 732 LayoutUnit oldTop = logicalTopAfterClear;
732 733
733 // If the object has a page or column break value of "before", then we shoul d shift to the top of the next page. 734 // If the object has a page or column break value of "before", then we shoul d shift to the top of the next page.
734 LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear); 735 LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear);
735 736
736 if (child->isColumnSpanAll())
737 result += flowThreadContainingBlock()->spannerLogicalTopAdjustment(child , result - child->marginBefore());
738
739 // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one. 737 // For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
740 LayoutUnit logicalTopBeforeUnsplittableAdjustment = result; 738 LayoutUnit logicalTopBeforeUnsplittableAdjustment = result;
741 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil d(child, result); 739 LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChil d(child, result);
742 740
743 LayoutUnit paginationStrut = 0; 741 LayoutUnit paginationStrut = 0;
744 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme nt - logicalTopBeforeUnsplittableAdjustment; 742 LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustme nt - logicalTopBeforeUnsplittableAdjustment;
745 LayoutUnit childLogicalHeight = child->logicalHeight(); 743 LayoutUnit childLogicalHeight = child->logicalHeight();
746 if (unsplittableAdjustmentDelta) { 744 if (unsplittableAdjustmentDelta) {
747 setPageBreak(result, childLogicalHeight - unsplittableAdjustmentDelta); 745 setPageBreak(result, childLogicalHeight - unsplittableAdjustmentDelta);
748 paginationStrut = unsplittableAdjustmentDelta; 746 paginationStrut = unsplittableAdjustmentDelta;
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 // top to get new posTop and negTop values. 1174 // top to get new posTop and negTop values.
1177 if (childIsSelfCollapsing) { 1175 if (childIsSelfCollapsing) {
1178 posTop = std::max(posTop, childMargins.positiveMarginAfter()); 1176 posTop = std::max(posTop, childMargins.positiveMarginAfter());
1179 negTop = std::max(negTop, childMargins.negativeMarginAfter()); 1177 negTop = std::max(negTop, childMargins.negativeMarginAfter());
1180 } 1178 }
1181 1179
1182 // See if the top margin is quirky. We only care if this child has 1180 // See if the top margin is quirky. We only care if this child has
1183 // margins that will collapse with us. 1181 // margins that will collapse with us.
1184 bool topQuirk = hasMarginBeforeQuirk(child); 1182 bool topQuirk = hasMarginBeforeQuirk(child);
1185 1183
1186 if (marginInfo.canCollapseWithMarginBefore() && !mustSeparateMarginBeforeFor Child(child)) { 1184 if (marginInfo.canCollapseWithMarginBefore()) {
1187 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) { 1185 if (!childDiscardMarginBefore && !marginInfo.discardMargin()) {
1188 // This child is collapsing with the top of the 1186 // This child is collapsing with the top of the
1189 // block. If it has larger margin values, then we need to update 1187 // block. If it has larger margin values, then we need to update
1190 // our own maximal values. 1188 // our own maximal values.
1191 if (!document().inQuirksMode() || !marginInfo.quirkContainer() || !t opQuirk) 1189 if (!document().inQuirksMode() || !marginInfo.quirkContainer() || !t opQuirk)
1192 setMaxMarginBeforeValues(std::max(posTop, maxPositiveMarginBefor e()), std::max(negTop, maxNegativeMarginBefore())); 1190 setMaxMarginBeforeValues(std::max(posTop, maxPositiveMarginBefor e()), std::max(negTop, maxNegativeMarginBefore()));
1193 1191
1194 // The minute any of the margins involved isn't a quirk, don't 1192 // The minute any of the margins involved isn't a quirk, don't
1195 // collapse it away, even if the margin is smaller (www.webreference .com 1193 // collapse it away, even if the margin is smaller (www.webreference .com
1196 // has an example of this, a <dt> with 0.8em author-specified inside 1194 // has an example of this, a <dt> with 0.8em author-specified inside
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1461 RenderBox* grandchildBox = childBlockFlow->firstChildBox(); 1459 RenderBox* grandchildBox = childBlockFlow->firstChildBox();
1462 for ( ; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) { 1460 for ( ; grandchildBox; grandchildBox = grandchildBox->nextSiblingBox()) {
1463 if (!grandchildBox->isFloatingOrOutOfFlowPositioned()) 1461 if (!grandchildBox->isFloatingOrOutOfFlowPositioned())
1464 break; 1462 break;
1465 } 1463 }
1466 1464
1467 // Give up if there is clearance on the box, since it probably won't collaps e into us. 1465 // Give up if there is clearance on the box, since it probably won't collaps e into us.
1468 if (!grandchildBox || grandchildBox->style()->clear() != CNONE) 1466 if (!grandchildBox || grandchildBox->style()->clear() != CNONE)
1469 return; 1467 return;
1470 1468
1471 if (childBlockFlow->mustSeparateMarginBeforeForChild(grandchildBox))
1472 return;
1473
1474 // Make sure to update the block margins now for the grandchild box so that we're looking at current values. 1469 // Make sure to update the block margins now for the grandchild box so that we're looking at current values.
1475 if (grandchildBox->needsLayout()) { 1470 if (grandchildBox->needsLayout()) {
1476 grandchildBox->computeAndSetBlockDirectionMargins(this); 1471 grandchildBox->computeAndSetBlockDirectionMargins(this);
1477 if (grandchildBox->isRenderBlock()) { 1472 if (grandchildBox->isRenderBlock()) {
1478 RenderBlock* grandchildBlock = toRenderBlock(grandchildBox); 1473 RenderBlock* grandchildBlock = toRenderBlock(grandchildBox);
1479 grandchildBlock->setHasMarginBeforeQuirk(grandchildBox->style()->has MarginBeforeQuirk()); 1474 grandchildBlock->setHasMarginBeforeQuirk(grandchildBox->style()->has MarginBeforeQuirk());
1480 grandchildBlock->setHasMarginAfterQuirk(grandchildBox->style()->hasM arginAfterQuirk()); 1475 grandchildBlock->setHasMarginAfterQuirk(grandchildBox->style()->hasM arginAfterQuirk());
1481 } 1476 }
1482 } 1477 }
1483 1478
1484 // Collapse the margin of the grandchild box with our own to produce an esti mate. 1479 // Collapse the margin of the grandchild box with our own to produce an esti mate.
1485 childBlockFlow->marginBeforeEstimateForChild(grandchildBox, positiveMarginBe fore, negativeMarginBefore, discardMarginBefore); 1480 childBlockFlow->marginBeforeEstimateForChild(grandchildBox, positiveMarginBe fore, negativeMarginBefore, discardMarginBefore);
1486 } 1481 }
1487 1482
1488 LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox* child, const M arginInfo& marginInfo, LayoutUnit& estimateWithoutPagination) 1483 LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox* child, const M arginInfo& marginInfo, LayoutUnit& estimateWithoutPagination)
1489 { 1484 {
1490 // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological 1485 // FIXME: We need to eliminate the estimation of vertical position, because when it's wrong we sometimes trigger a pathological
1491 // relayout if there are intruding floats. 1486 // relayout if there are intruding floats.
1492 LayoutUnit logicalTopEstimate = logicalHeight(); 1487 LayoutUnit logicalTopEstimate = logicalHeight();
1493 if (!marginInfo.canCollapseWithMarginBefore() || mustSeparateMarginBeforeFor Child(child)) { 1488 if (!marginInfo.canCollapseWithMarginBefore()) {
1494 LayoutUnit positiveMarginBefore = 0; 1489 LayoutUnit positiveMarginBefore = 0;
1495 LayoutUnit negativeMarginBefore = 0; 1490 LayoutUnit negativeMarginBefore = 0;
1496 bool discardMarginBefore = false; 1491 bool discardMarginBefore = false;
1497 if (child->selfNeedsLayout()) { 1492 if (child->selfNeedsLayout()) {
1498 // Try to do a basic estimation of how the collapse is going to go. 1493 // Try to do a basic estimation of how the collapse is going to go.
1499 marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMa rginBefore, discardMarginBefore); 1494 marginBeforeEstimateForChild(child, positiveMarginBefore, negativeMa rginBefore, discardMarginBefore);
1500 } else { 1495 } else {
1501 // Use the cached collapsed margin values from a previous layout. Mo st of the time they 1496 // Use the cached collapsed margin values from a previous layout. Mo st of the time they
1502 // will be right. 1497 // will be right.
1503 RenderBlockFlow::MarginValues marginValues = marginValuesForChild(ch ild); 1498 RenderBlockFlow::MarginValues marginValues = marginValuesForChild(ch ild);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 if (pos == RenderBlockFlowRareData::positiveMarginAfterDefault(this) && neg == RenderBlockFlowRareData::negativeMarginAfterDefault(this)) 1673 if (pos == RenderBlockFlowRareData::positiveMarginAfterDefault(this) && neg == RenderBlockFlowRareData::negativeMarginAfterDefault(this))
1679 return; 1674 return;
1680 m_rareData = adoptPtrWillBeNoop(new RenderBlockFlowRareData(this)); 1675 m_rareData = adoptPtrWillBeNoop(new RenderBlockFlowRareData(this));
1681 } 1676 }
1682 m_rareData->m_margins.setPositiveMarginAfter(pos); 1677 m_rareData->m_margins.setPositiveMarginAfter(pos);
1683 m_rareData->m_margins.setNegativeMarginAfter(neg); 1678 m_rareData->m_margins.setNegativeMarginAfter(neg);
1684 } 1679 }
1685 1680
1686 bool RenderBlockFlow::mustSeparateMarginBeforeForChild(const RenderBox* child) c onst 1681 bool RenderBlockFlow::mustSeparateMarginBeforeForChild(const RenderBox* child) c onst
1687 { 1682 {
1688 if (child->isColumnSpanAll()) 1683 ASSERT(!child->selfNeedsLayout());
1689 return true;
1690 const RenderStyle* childStyle = child->style(); 1684 const RenderStyle* childStyle = child->style();
1691 if (!child->isWritingModeRoot()) 1685 if (!child->isWritingModeRoot())
1692 return childStyle->marginBeforeCollapse() == MSEPARATE; 1686 return childStyle->marginBeforeCollapse() == MSEPARATE;
1693 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) 1687 if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
1694 return childStyle->marginAfterCollapse() == MSEPARATE; 1688 return childStyle->marginAfterCollapse() == MSEPARATE;
1695 1689
1696 // FIXME: See |mustDiscardMarginBeforeForChild| above. 1690 // FIXME: See |mustDiscardMarginBeforeForChild| above.
1697 return false; 1691 return false;
1698 } 1692 }
1699 1693
1700 bool RenderBlockFlow::mustSeparateMarginAfterForChild(const RenderBox* child) co nst 1694 bool RenderBlockFlow::mustSeparateMarginAfterForChild(const RenderBox* child) co nst
1701 { 1695 {
1702 if (child->isColumnSpanAll()) 1696 ASSERT(!child->selfNeedsLayout());
1703 return true;
1704 const RenderStyle* childStyle = child->style(); 1697 const RenderStyle* childStyle = child->style();
1705 if (!child->isWritingModeRoot()) 1698 if (!child->isWritingModeRoot())
1706 return childStyle->marginAfterCollapse() == MSEPARATE; 1699 return childStyle->marginAfterCollapse() == MSEPARATE;
1707 if (child->isHorizontalWritingMode() == isHorizontalWritingMode()) 1700 if (child->isHorizontalWritingMode() == isHorizontalWritingMode())
1708 return childStyle->marginBeforeCollapse() == MSEPARATE; 1701 return childStyle->marginBeforeCollapse() == MSEPARATE;
1709 1702
1710 // FIXME: See |mustDiscardMarginBeforeForChild| above. 1703 // FIXME: See |mustDiscardMarginBeforeForChild| above.
1711 return false; 1704 return false;
1712 } 1705 }
1713 1706
(...skipping 1210 matching lines...) Expand 10 before | Expand all | Expand 10 after
2924 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData() 2917 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData()
2925 { 2918 {
2926 if (m_rareData) 2919 if (m_rareData)
2927 return *m_rareData; 2920 return *m_rareData;
2928 2921
2929 m_rareData = adoptPtrWillBeNoop(new RenderBlockFlowRareData(this)); 2922 m_rareData = adoptPtrWillBeNoop(new RenderBlockFlowRareData(this));
2930 return *m_rareData; 2923 return *m_rareData;
2931 } 2924 }
2932 2925
2933 } // namespace blink 2926 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | Source/core/rendering/RenderBox.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698