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 return m_contentRuns[index].columnLogicalHeight(startOffset); | 95 LayoutUnit logicalHeightEstimate = m_contentRuns[index].columnLogicalHeight(
startOffset); |
| 96 return std::max(logicalHeightEstimate, m_minimumColumnLogicalHeight); |
96 } | 97 } |
97 | 98 |
98 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box) | 99 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box) |
99 { | 100 { |
100 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut()); | 101 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut()); |
101 if (box.hasForcedBreakBefore()) { | 102 if (box.hasForcedBreakBefore()) { |
102 addContentRun(flowThreadOffset()); | 103 addContentRun(flowThreadOffset()); |
103 } else if (isFirstAfterBreak(flowThreadOffset())) { | 104 } else if (isFirstAfterBreak(flowThreadOffset())) { |
104 // This box is first after a soft break. | 105 // This box is first after a soft break. |
105 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut()); | 106 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut()); |
106 } | 107 } |
107 | 108 |
108 if (box.hasForcedBreakAfter()) | 109 if (box.hasForcedBreakAfter()) |
109 addContentRun(flowThreadOffset() + box.logicalHeight()); | 110 addContentRun(flowThreadOffset() + box.logicalHeight()); |
| 111 |
| 112 if (box.paginationBreakability() != LayoutBox::AllowAnyBreaks) { |
| 113 LayoutUnit unsplittableLogicalHeight = box.logicalHeight(); |
| 114 if (box.isFloating()) |
| 115 unsplittableLogicalHeight += box.marginBefore() + box.marginAfter(); |
| 116 if (m_minimumColumnLogicalHeight < unsplittableLogicalHeight) |
| 117 m_minimumColumnLogicalHeight = unsplittableLogicalHeight; |
| 118 } |
110 } | 119 } |
111 | 120 |
112 void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box) | 121 void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box) |
113 { | 122 { |
114 } | 123 } |
115 | 124 |
| 125 static inline LayoutUnit columnLogicalHeightRequirementForLine(const ComputedSty
le& style, const RootInlineBox& lastLine) |
| 126 { |
| 127 // 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. |
| 129 unsigned minimumLineCount = std::max<unsigned>(style.hasAutoOrphans() ? 1 :
style.orphans(), style.widows()); |
| 130 const RootInlineBox* firstLine = &lastLine; |
| 131 for (unsigned i = 1; i < minimumLineCount && firstLine->prevRootBox(); i++) |
| 132 firstLine = firstLine->prevRootBox(); |
| 133 return lastLine.lineBottomWithLeading() - firstLine->lineTopWithLeading(); |
| 134 } |
| 135 |
116 void InitialColumnHeightFinder::examineLine(const RootInlineBox& line) | 136 void InitialColumnHeightFinder::examineLine(const RootInlineBox& line) |
117 { | 137 { |
118 LayoutUnit lineTop = line.lineTopWithLeading(); | 138 LayoutUnit lineTop = line.lineTopWithLeading(); |
119 LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop; | 139 LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop; |
| 140 LayoutUnit minimumLogialHeight = columnLogicalHeightRequirementForLine(line.
block().styleRef(), line); |
| 141 if (m_minimumColumnLogicalHeight < minimumLogialHeight) |
| 142 m_minimumColumnLogicalHeight = minimumLogialHeight; |
120 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); | 143 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); |
121 if (isFirstAfterBreak(lineTopInFlowThread)) | 144 if (isFirstAfterBreak(lineTopInFlowThread)) |
122 recordStrutBeforeOffset(lineTopInFlowThread, line.paginationStrut()); | 145 recordStrutBeforeOffset(lineTopInFlowThread, line.paginationStrut()); |
123 } | 146 } |
124 | 147 |
125 void InitialColumnHeightFinder::recordStrutBeforeOffset(LayoutUnit offsetInFlowT
hread, LayoutUnit strut) | 148 void InitialColumnHeightFinder::recordStrutBeforeOffset(LayoutUnit offsetInFlowT
hread, LayoutUnit strut) |
126 { | 149 { |
127 const LayoutMultiColumnSet& columnSet = group().columnSet(); | 150 const LayoutMultiColumnSet& columnSet = group().columnSet(); |
128 ASSERT(columnSet.usedColumnCount() >= 1); | 151 ASSERT(columnSet.usedColumnCount() >= 1); |
129 unsigned columnCount = columnSet.usedColumnCount(); | 152 unsigned columnCount = columnSet.usedColumnCount(); |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pend
ingStrut); | 298 recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pend
ingStrut); |
276 m_pendingStrut = LayoutUnit::min(); | 299 m_pendingStrut = LayoutUnit::min(); |
277 return; | 300 return; |
278 } | 301 } |
279 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); | 302 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); |
280 if (isFirstAfterBreak(lineTopInFlowThread)) | 303 if (isFirstAfterBreak(lineTopInFlowThread)) |
281 recordSpaceShortage(lineHeight - line.paginationStrut()); | 304 recordSpaceShortage(lineHeight - line.paginationStrut()); |
282 } | 305 } |
283 | 306 |
284 } // namespace blink | 307 } // namespace blink |
OLD | NEW |