 Chromium Code Reviews
 Chromium Code Reviews Issue 1461923005:
  When balancing columns, we must check inner multicols for unbreakable content.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1461923005:
  When balancing columns, we must check inner multicols for unbreakable content.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "config.h" | 5 #include "config.h" | 
| 6 | 6 | 
| 7 #include "core/layout/ColumnBalancer.h" | 7 #include "core/layout/ColumnBalancer.h" | 
| 8 | 8 | 
| 9 #include "core/layout/LayoutMultiColumnSet.h" | 9 #include "core/layout/LayoutMultiColumnSet.h" | 
| 10 | 10 | 
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 // We have now found each explicit / forced break, and their location. Now w e need to figure out | 85 // We have now found each explicit / forced break, and their location. Now w e need to figure out | 
| 86 // how many additional implicit / soft breaks we need and guess where they w ill occur, in order | 86 // how many additional implicit / soft breaks we need and guess where they w ill occur, in order | 
| 87 // to provide an initial column height. | 87 // to provide an initial column height. | 
| 88 distributeImplicitBreaks(); | 88 distributeImplicitBreaks(); | 
| 89 } | 89 } | 
| 90 | 90 | 
| 91 LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const | 91 LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const | 
| 92 { | 92 { | 
| 93 unsigned index = contentRunIndexWithTallestColumns(); | 93 unsigned index = contentRunIndexWithTallestColumns(); | 
| 94 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : group().logicalTopInFlowThread(); | 94 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : group().logicalTopInFlowThread(); | 
| 95 LayoutUnit logicalHeightEstimate = m_contentRuns[index].columnLogicalHeight( startOffset); | 95 return m_contentRuns[index].columnLogicalHeight(startOffset); | 
| 96 return std::max(logicalHeightEstimate, m_minimumColumnLogicalHeight); | |
| 97 } | 96 } | 
| 98 | 97 | 
| 99 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box) | 98 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box) | 
| 100 { | 99 { | 
| 101 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut()); | 100 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut()); | 
| 102 if (box.hasForcedBreakBefore()) { | 101 if (box.hasForcedBreakBefore()) { | 
| 103 addContentRun(flowThreadOffset()); | 102 addContentRun(flowThreadOffset()); | 
| 104 } else if (isFirstAfterBreak(flowThreadOffset())) { | 103 } else if (isFirstAfterBreak(flowThreadOffset())) { | 
| 105 // This box is first after a soft break. | 104 // This box is first after a soft break. | 
| 106 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut()); | 105 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut()); | 
| 107 } | 106 } | 
| 108 | 107 | 
| 109 if (box.hasForcedBreakAfter()) | 108 if (box.hasForcedBreakAfter()) | 
| 110 addContentRun(flowThreadOffset() + box.logicalHeight()); | 109 addContentRun(flowThreadOffset() + box.logicalHeight()); | 
| 111 | 110 | 
| 112 if (box.paginationBreakability() != LayoutBox::AllowAnyBreaks) { | 111 if (box.paginationBreakability() != LayoutBox::AllowAnyBreaks) { | 
| 113 LayoutUnit unsplittableLogicalHeight = box.logicalHeight(); | 112 LayoutUnit unsplittableLogicalHeight = box.logicalHeight(); | 
| 114 if (box.isFloating()) | 113 if (box.isFloating()) | 
| 115 unsplittableLogicalHeight += box.marginBefore() + box.marginAfter(); | 114 unsplittableLogicalHeight += box.marginBefore() + box.marginAfter(); | 
| 116 if (m_minimumColumnLogicalHeight < unsplittableLogicalHeight) | 115 if (m_tallestUnbreakableLogicalHeight < unsplittableLogicalHeight) | 
| 
leviw_travelin_and_unemployed
2015/11/20 22:26:31
I like max(). Clearly, max(countFolksWhoLikeMax(fo
 
mstensho (USE GERRIT)
2015/11/23 09:06:31
Done.
 | |
| 117 m_minimumColumnLogicalHeight = unsplittableLogicalHeight; | 116 m_tallestUnbreakableLogicalHeight = unsplittableLogicalHeight; | 
| 117 } else if (box.isLayoutBlockFlow()) { | |
| 118 if (LayoutMultiColumnFlowThread* innerFlowThread = toLayoutBlockFlow(box ).multiColumnFlowThread()) { | |
| 119 LayoutUnit offsetInInnerFlowThread = flowThreadOffset() - innerFlowT hread->blockOffsetInEnclosingFlowThread(); | |
| 120 LayoutUnit innerUnbreakableHeight = innerFlowThread->tallestUnbreaka bleLogicalHeight(offsetInInnerFlowThread); | |
| 121 if (m_tallestUnbreakableLogicalHeight < innerUnbreakableHeight) | |
| 122 m_tallestUnbreakableLogicalHeight = innerUnbreakableHeight; | |
| 123 } | |
| 118 } | 124 } | 
| 119 } | 125 } | 
| 120 | 126 | 
| 121 void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box) | 127 void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box) | 
| 122 { | 128 { | 
| 123 } | 129 } | 
| 124 | 130 | 
| 125 static inline LayoutUnit columnLogicalHeightRequirementForLine(const ComputedSty le& style, const RootInlineBox& lastLine) | 131 static inline LayoutUnit columnLogicalHeightRequirementForLine(const ComputedSty le& style, const RootInlineBox& lastLine) | 
| 126 { | 132 { | 
| 127 // We may require a certain minimum number of lines per page in order to sat isfy | 133 // We may require a certain minimum number of lines per page in order to sat isfy | 
| 128 // orphans and widows, and that may affect the minimum page height. | 134 // orphans and widows, and that may affect the minimum page height. | 
| 129 unsigned minimumLineCount = std::max<unsigned>(style.hasAutoOrphans() ? 1 : style.orphans(), style.widows()); | 135 unsigned minimumLineCount = std::max<unsigned>(style.hasAutoOrphans() ? 1 : style.orphans(), style.widows()); | 
| 130 const RootInlineBox* firstLine = &lastLine; | 136 const RootInlineBox* firstLine = &lastLine; | 
| 131 for (unsigned i = 1; i < minimumLineCount && firstLine->prevRootBox(); i++) | 137 for (unsigned i = 1; i < minimumLineCount && firstLine->prevRootBox(); i++) | 
| 132 firstLine = firstLine->prevRootBox(); | 138 firstLine = firstLine->prevRootBox(); | 
| 133 return lastLine.lineBottomWithLeading() - firstLine->lineTopWithLeading(); | 139 return lastLine.lineBottomWithLeading() - firstLine->lineTopWithLeading(); | 
| 134 } | 140 } | 
| 135 | 141 | 
| 136 void InitialColumnHeightFinder::examineLine(const RootInlineBox& line) | 142 void InitialColumnHeightFinder::examineLine(const RootInlineBox& line) | 
| 137 { | 143 { | 
| 138 LayoutUnit lineTop = line.lineTopWithLeading(); | 144 LayoutUnit lineTop = line.lineTopWithLeading(); | 
| 139 LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop; | 145 LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop; | 
| 140 LayoutUnit minimumLogialHeight = columnLogicalHeightRequirementForLine(line. block().styleRef(), line); | 146 LayoutUnit minimumLogialHeight = columnLogicalHeightRequirementForLine(line. block().styleRef(), line); | 
| 141 if (m_minimumColumnLogicalHeight < minimumLogialHeight) | 147 if (m_tallestUnbreakableLogicalHeight < minimumLogialHeight) | 
| 142 m_minimumColumnLogicalHeight = minimumLogialHeight; | 148 m_tallestUnbreakableLogicalHeight = minimumLogialHeight; | 
| 143 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); | 149 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); | 
| 144 if (isFirstAfterBreak(lineTopInFlowThread)) | 150 if (isFirstAfterBreak(lineTopInFlowThread)) | 
| 145 recordStrutBeforeOffset(lineTopInFlowThread, line.paginationStrut()); | 151 recordStrutBeforeOffset(lineTopInFlowThread, line.paginationStrut()); | 
| 146 } | 152 } | 
| 147 | 153 | 
| 148 void InitialColumnHeightFinder::recordStrutBeforeOffset(LayoutUnit offsetInFlowT hread, LayoutUnit strut) | 154 void InitialColumnHeightFinder::recordStrutBeforeOffset(LayoutUnit offsetInFlowT hread, LayoutUnit strut) | 
| 149 { | 155 { | 
| 150 const LayoutMultiColumnSet& columnSet = group().columnSet(); | 156 const LayoutMultiColumnSet& columnSet = group().columnSet(); | 
| 151 ASSERT(columnSet.usedColumnCount() >= 1); | 157 ASSERT(columnSet.usedColumnCount() >= 1); | 
| 152 unsigned columnCount = columnSet.usedColumnCount(); | 158 unsigned columnCount = columnSet.usedColumnCount(); | 
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pend ingStrut); | 304 recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pend ingStrut); | 
| 299 m_pendingStrut = LayoutUnit::min(); | 305 m_pendingStrut = LayoutUnit::min(); | 
| 300 return; | 306 return; | 
| 301 } | 307 } | 
| 302 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); | 308 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); | 
| 303 if (isFirstAfterBreak(lineTopInFlowThread)) | 309 if (isFirstAfterBreak(lineTopInFlowThread)) | 
| 304 recordSpaceShortage(lineHeight - line.paginationStrut()); | 310 recordSpaceShortage(lineHeight - line.paginationStrut()); | 
| 305 } | 311 } | 
| 306 | 312 | 
| 307 } // namespace blink | 313 } // namespace blink | 
| OLD | NEW |