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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 traverseSubtree(childBox); | 71 traverseSubtree(childBox); |
72 examineBoxBeforeLeaving(childBox); | 72 examineBoxBeforeLeaving(childBox); |
73 | 73 |
74 m_flowThreadOffset -= offsetForThisChild; | 74 m_flowThreadOffset -= offsetForThisChild; |
75 } | 75 } |
76 } | 76 } |
77 | 77 |
78 InitialColumnHeightFinder::InitialColumnHeightFinder(const MultiColumnFragmentai
nerGroup& group) | 78 InitialColumnHeightFinder::InitialColumnHeightFinder(const MultiColumnFragmentai
nerGroup& group) |
79 : ColumnBalancer(group) | 79 : ColumnBalancer(group) |
80 { | 80 { |
| 81 m_shortestStruts.resize(group.columnSet().usedColumnCount()); |
| 82 for (auto& strut : m_shortestStruts) |
| 83 strut = LayoutUnit::max(); |
81 traverse(); | 84 traverse(); |
82 // 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 |
83 // 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 |
84 // to provide an initial column height. | 87 // to provide an initial column height. |
85 distributeImplicitBreaks(); | 88 distributeImplicitBreaks(); |
86 } | 89 } |
87 | 90 |
88 LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const | 91 LayoutUnit InitialColumnHeightFinder::initialMinimalBalancedHeight() const |
89 { | 92 { |
90 unsigned index = contentRunIndexWithTallestColumns(); | 93 unsigned index = contentRunIndexWithTallestColumns(); |
91 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset()
: group().logicalTopInFlowThread(); | 94 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset()
: group().logicalTopInFlowThread(); |
92 return m_contentRuns[index].columnLogicalHeight(startOffset); | 95 return m_contentRuns[index].columnLogicalHeight(startOffset); |
93 } | 96 } |
94 | 97 |
95 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box) | 98 void InitialColumnHeightFinder::examineBoxAfterEntering(const LayoutBox& box) |
96 { | 99 { |
97 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut()); | 100 ASSERT(isFirstAfterBreak(flowThreadOffset()) || !box.paginationStrut()); |
98 if (box.hasForcedBreakBefore()) | 101 if (box.hasForcedBreakBefore()) { |
99 addContentRun(flowThreadOffset()); | 102 addContentRun(flowThreadOffset()); |
| 103 } else if (isFirstAfterBreak(flowThreadOffset())) { |
| 104 // This box is first after a soft break. |
| 105 recordStrutBeforeOffset(flowThreadOffset(), box.paginationStrut()); |
| 106 } |
| 107 |
100 if (box.hasForcedBreakAfter()) | 108 if (box.hasForcedBreakAfter()) |
101 addContentRun(flowThreadOffset() + box.logicalHeight()); | 109 addContentRun(flowThreadOffset() + box.logicalHeight()); |
102 } | 110 } |
103 | 111 |
104 void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box) | 112 void InitialColumnHeightFinder::examineBoxBeforeLeaving(const LayoutBox& box) |
105 { | 113 { |
106 } | 114 } |
107 | 115 |
108 void InitialColumnHeightFinder::examineLine(const RootInlineBox& line) | 116 void InitialColumnHeightFinder::examineLine(const RootInlineBox& line) |
109 { | 117 { |
| 118 LayoutUnit lineTop = line.lineTopWithLeading(); |
| 119 LayoutUnit lineTopInFlowThread = flowThreadOffset() + lineTop; |
| 120 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); |
| 121 if (isFirstAfterBreak(lineTopInFlowThread)) |
| 122 recordStrutBeforeOffset(lineTopInFlowThread, line.paginationStrut()); |
| 123 } |
| 124 |
| 125 void InitialColumnHeightFinder::recordStrutBeforeOffset(LayoutUnit offsetInFlowT
hread, LayoutUnit strut) |
| 126 { |
| 127 const LayoutMultiColumnSet& columnSet = group().columnSet(); |
| 128 ASSERT(columnSet.usedColumnCount() >= 1); |
| 129 unsigned columnCount = columnSet.usedColumnCount(); |
| 130 ASSERT(m_shortestStruts.size() == columnCount); |
| 131 unsigned index = group().columnIndexAtOffset(offsetInFlowThread - strut, Mul
tiColumnFragmentainerGroup::AssumeNewColumns); |
| 132 if (index >= columnCount) |
| 133 return; |
| 134 m_shortestStruts[index] = std::min(m_shortestStruts[index], strut); |
| 135 } |
| 136 |
| 137 LayoutUnit InitialColumnHeightFinder::spaceUsedByStrutsAt(LayoutUnit offsetInFlo
wThread) const |
| 138 { |
| 139 unsigned stopBeforeColumn = group().columnIndexAtOffset(offsetInFlowThread,
MultiColumnFragmentainerGroup::AssumeNewColumns) + 1; |
| 140 stopBeforeColumn = std::min(stopBeforeColumn, group().columnSet().usedColumn
Count()); |
| 141 ASSERT(stopBeforeColumn <= m_shortestStruts.size()); |
| 142 LayoutUnit totalStrutSpace; |
| 143 for (unsigned i = 0; i < stopBeforeColumn; i++) { |
| 144 if (m_shortestStruts[i] != LayoutUnit::max()) |
| 145 totalStrutSpace += m_shortestStruts[i]; |
| 146 } |
| 147 return totalStrutSpace; |
110 } | 148 } |
111 | 149 |
112 void InitialColumnHeightFinder::addContentRun(LayoutUnit endOffsetInFlowThread) | 150 void InitialColumnHeightFinder::addContentRun(LayoutUnit endOffsetInFlowThread) |
113 { | 151 { |
| 152 endOffsetInFlowThread -= spaceUsedByStrutsAt(endOffsetInFlowThread); |
114 if (!m_contentRuns.isEmpty() && endOffsetInFlowThread <= m_contentRuns.last(
).breakOffset()) | 153 if (!m_contentRuns.isEmpty() && endOffsetInFlowThread <= m_contentRuns.last(
).breakOffset()) |
115 return; | 154 return; |
116 // Append another item as long as we haven't exceeded used column count. Wha
t ends up in the | 155 // Append another item as long as we haven't exceeded used column count. Wha
t ends up in the |
117 // overflow area shouldn't affect column balancing. | 156 // overflow area shouldn't affect column balancing. |
118 if (m_contentRuns.size() < group().columnSet().usedColumnCount()) | 157 if (m_contentRuns.size() < group().columnSet().usedColumnCount()) |
119 m_contentRuns.append(ContentRun(endOffsetInFlowThread)); | 158 m_contentRuns.append(ContentRun(endOffsetInFlowThread)); |
120 } | 159 } |
121 | 160 |
122 unsigned InitialColumnHeightFinder::contentRunIndexWithTallestColumns() const | 161 unsigned InitialColumnHeightFinder::contentRunIndexWithTallestColumns() const |
123 { | 162 { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pend
ingStrut); | 274 recordSpaceShortage(logicalOffsetFromCurrentColumn + lineHeight - m_pend
ingStrut); |
236 m_pendingStrut = LayoutUnit::min(); | 275 m_pendingStrut = LayoutUnit::min(); |
237 return; | 276 return; |
238 } | 277 } |
239 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); | 278 ASSERT(isFirstAfterBreak(lineTopInFlowThread) || !line.paginationStrut()); |
240 if (isFirstAfterBreak(lineTopInFlowThread)) | 279 if (isFirstAfterBreak(lineTopInFlowThread)) |
241 recordSpaceShortage(lineHeight - line.paginationStrut()); | 280 recordSpaceShortage(lineHeight - line.paginationStrut()); |
242 } | 281 } |
243 | 282 |
244 } // namespace blink | 283 } // namespace blink |
OLD | NEW |