void MinimumSpaceShortageFinder::examineBoxAfterEntering(const LayoutBox& box) { if (box.hasForcedBreakBefore()) m_forcedBreaksCount++; if (box.hasForcedBreakAfter()) m_forcedBreaksCount++; // Look for breaks before the child box. bool isFirstAfterBreak = this->isFirstAfterBreak(flowThreadOffset()); ASSERT(isFirstAfterBreak || !box.paginationStrut()); LayoutBox::PaginationBreakability breakability = box.paginationBreakability(); if (isFirstAfterBreak && !box.hasForcedBreakBefore()) { // This box is first after a soft break. LayoutUnit strut = box.paginationStrut(); // Figure out how much more space we would need to prevent it from being pushed to the next column. recordSpaceShortage(box.logicalHeight() - strut); if (breakability != LayoutBox::ForbidBreaks && m_pendingStrut == LayoutUnit::min()) { // We now want to look for the first piece of unbreakable content (e.g. a line or a // block-displayed image) inside this block. That ought to be a good candidate for // minimum space shortage; a much better one than reporting space shortage for the // entire block (which we'll also do (further down), in case we couldn't find anything // more suitable). m_pendingStrut = strut; } } if (breakability != LayoutBox::ForbidBreaks) { // See if this breakable box crosses column boundaries. LayoutUnit bottomInFlowThread = flowThreadOffset() + box.logicalHeight(); if (isFirstAfterBreak || group().columnLogicalTopForOffset(flowThreadOffset()) != group().columnLogicalTopForOffset(bottomInFlowThread)) { // If the child crosses a column boundary, record space shortage, in case nothing // inside it has already done so. The column balancer needs to know by how much it // has to stretch the columns to make more content fit. If no breaks are reported // (but do occur), the balancer will have no clue. Only measure the space after the // last column boundary, in case it crosses more than one. LayoutUnit spaceUsedInLastColumn = bottomInFlowThread - group().columnLogicalTopForOffset(bottomInFlowThread); recordSpaceShortage(spaceUsedInLastColumn); } } // If this is an inner multicol container, look for space shortage inside it. if (!box.isLayoutBlockFlow()) return; LayoutMultiColumnFlowThread* flowThread = toLayoutBlockFlow(box).multiColumnFlowThread(); if (!flowThread) return; for (const LayoutMultiColumnSet* columnSet = flowThread->firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) { for (const MultiColumnFragmentainerGroup& row : columnSet->fragmentainerGroups()) { MinimumSpaceShortageFinder innerFinder(row); recordSpaceShortage(innerFinder.minimumSpaceShortage()); } } }
void MinimumSpaceShortageFinder::examineBoxAfterEntering( const LayoutBox& box, LayoutUnit childLogicalHeight, EBreak previousBreakAfterValue) { LayoutBox::PaginationBreakability breakability = box.getPaginationBreakability(); // Look for breaks before the child box. if (isLogicalTopWithinBounds(flowThreadOffset() - box.paginationStrut())) { if (box.needsForcedBreakBefore(previousBreakAfterValue)) { m_forcedBreaksCount++; } else { if (isFirstAfterBreak(flowThreadOffset())) { // This box is first after a soft break. LayoutUnit strut = box.paginationStrut(); // Figure out how much more space we would need to prevent it from being // pushed to the next column. recordSpaceShortage(childLogicalHeight - strut); if (breakability != LayoutBox::ForbidBreaks && m_pendingStrut == LayoutUnit::min()) { // We now want to look for the first piece of unbreakable content // (e.g. a line or a block-displayed image) inside this block. That // ought to be a good candidate for minimum space shortage; a much // better one than reporting space shortage for the entire block // (which we'll also do (further down), in case we couldn't find // anything more suitable). m_pendingStrut = strut; } } } } if (breakability != LayoutBox::ForbidBreaks) { // See if this breakable box crosses column boundaries. LayoutUnit bottomInFlowThread = flowThreadOffset() + childLogicalHeight; const MultiColumnFragmentainerGroup& group = groupAtOffset(flowThreadOffset()); if (isFirstAfterBreak(flowThreadOffset()) || group.columnLogicalTopForOffset(flowThreadOffset()) != group.columnLogicalTopForOffset(bottomInFlowThread)) { // If the child crosses a column boundary, record space shortage, in case // nothing inside it has already done so. The column balancer needs to // know by how much it has to stretch the columns to make more content // fit. If no breaks are reported (but do occur), the balancer will have // no clue. Only measure the space after the last column boundary, in case // it crosses more than one. LayoutUnit spaceUsedInLastColumn = bottomInFlowThread - group.columnLogicalTopForOffset(bottomInFlowThread); recordSpaceShortage(spaceUsedInLastColumn); } } // If this is an inner multicol container, look for space shortage inside it. if (!box.isLayoutBlockFlow()) return; LayoutMultiColumnFlowThread* flowThread = toLayoutBlockFlow(box).multiColumnFlowThread(); if (!flowThread || flowThread->isLayoutPagedFlowThread()) return; for (const LayoutMultiColumnSet* columnSet = flowThread->firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) { // Establish an inner shortage finder for this column set in the inner // multicol container. We need to let it walk through all fragmentainer // groups in one go, or we'd miss the column boundaries between each // fragmentainer group. We need to record space shortage there too. MinimumSpaceShortageFinder innerFinder( *columnSet, columnSet->logicalTopInFlowThread(), columnSet->logicalBottomInFlowThread()); recordSpaceShortage(innerFinder.minimumSpaceShortage()); } }