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 "core/layout/LayoutMultiColumnSet.h" | 5 #include "core/layout/LayoutMultiColumnSet.h" |
6 | 6 |
7 namespace blink { | 7 namespace blink { |
8 | 8 |
9 // A column balancer traverses a portion of the subtree of a flow thread that be
longs to one or | 9 // A column balancer traverses a portion of the subtree of a flow thread that be
longs to one or |
10 // more fragmentainer groups within one column set, in order to collect certain
data to be used for | 10 // more fragmentainer groups within one column set, in order to collect certain
data to be used for |
(...skipping 16 matching lines...) Expand all Loading... |
27 } | 27 } |
28 | 28 |
29 LayoutUnit offsetFromColumnLogicalTop(LayoutUnit offsetInFlowThread) const | 29 LayoutUnit offsetFromColumnLogicalTop(LayoutUnit offsetInFlowThread) const |
30 { | 30 { |
31 return offsetInFlowThread - groupAtOffset(offsetInFlowThread).columnLogi
calTopForOffset(offsetInFlowThread); | 31 return offsetInFlowThread - groupAtOffset(offsetInFlowThread).columnLogi
calTopForOffset(offsetInFlowThread); |
32 } | 32 } |
33 | 33 |
34 // Flow thread offset for the layout object that we're currently examining. | 34 // Flow thread offset for the layout object that we're currently examining. |
35 LayoutUnit flowThreadOffset() const { return m_flowThreadOffset; } | 35 LayoutUnit flowThreadOffset() const { return m_flowThreadOffset; } |
36 | 36 |
37 EBreak previousBreakAfterValue() const { return m_previousBreakAfterValue; } | |
38 | |
39 // Return true if the specified offset is at the top of a column, as long as
it's not the first | 37 // Return true if the specified offset is at the top of a column, as long as
it's not the first |
40 // column in the flow thread portion. | 38 // column in the flow thread portion. |
41 bool isFirstAfterBreak(LayoutUnit flowThreadOffset) const | 39 bool isFirstAfterBreak(LayoutUnit flowThreadOffset) const |
42 { | 40 { |
43 if (flowThreadOffset <= m_logicalTopInFlowThread) { | 41 if (flowThreadOffset <= m_logicalTopInFlowThread) { |
44 // The first column is either not after any break at all, or after a
break in a | 42 // The first column is either not after any break at all, or after a
break in a |
45 // previous fragmentainer group. | 43 // previous fragmentainer group. |
46 return false; | 44 return false; |
47 } | 45 } |
48 return flowThreadOffset == groupAtOffset(flowThreadOffset).columnLogical
TopForOffset(flowThreadOffset); | 46 return flowThreadOffset == groupAtOffset(flowThreadOffset).columnLogical
TopForOffset(flowThreadOffset); |
49 } | 47 } |
50 | 48 |
51 bool isLogicalTopWithinBounds(LayoutUnit logicalTopInFlowThread) const | 49 bool isLogicalTopWithinBounds(LayoutUnit logicalTopInFlowThread) const |
52 { | 50 { |
53 return logicalTopInFlowThread >= m_logicalTopInFlowThread | 51 return logicalTopInFlowThread >= m_logicalTopInFlowThread |
54 && logicalTopInFlowThread < m_logicalBottomInFlowThread; | 52 && logicalTopInFlowThread < m_logicalBottomInFlowThread; |
55 } | 53 } |
56 | 54 |
57 bool isLogicalBottomWithinBounds(LayoutUnit logicalBottomInFlowThread) const | 55 bool isLogicalBottomWithinBounds(LayoutUnit logicalBottomInFlowThread) const |
58 { | 56 { |
59 return logicalBottomInFlowThread > m_logicalTopInFlowThread | 57 return logicalBottomInFlowThread > m_logicalTopInFlowThread |
60 && logicalBottomInFlowThread <= m_logicalBottomInFlowThread; | 58 && logicalBottomInFlowThread <= m_logicalBottomInFlowThread; |
61 } | 59 } |
62 | 60 |
63 // Examine and collect column balancing data from a layout box that has been
found to intersect | 61 // Examine and collect column balancing data from a layout box that has been
found to intersect |
64 // with the flow thread portion we're examining. Does not recurse into | 62 // with the flow thread portion we're examining. Does not recurse into |
65 // children. flowThreadOffset() will return the offset from |box| to the flo
w thread. Two hooks | 63 // children. flowThreadOffset() will return the offset from |box| to the flo
w thread. Two hooks |
66 // are provided here. The first one is called right after entering and befor
e traversing the | 64 // are provided here. The first one is called right after entering and befor
e traversing the |
67 // subtree of the box, and the second one right after having traversed the s
ubtree. | 65 // subtree of the box, and the second one right after having traversed the s
ubtree. |
68 virtual void examineBoxAfterEntering(const LayoutBox&) = 0; | 66 virtual void examineBoxAfterEntering(const LayoutBox&, EBreak previousBreakA
fterValue) = 0; |
69 virtual void examineBoxBeforeLeaving(const LayoutBox&) = 0; | 67 virtual void examineBoxBeforeLeaving(const LayoutBox&) = 0; |
70 | 68 |
71 // Examine and collect column balancing data from a line that has been found
to intersect with | 69 // Examine and collect column balancing data from a line that has been found
to intersect with |
72 // the flow thread portion. Does not recurse into layout objects on that lin
e. | 70 // the flow thread portion. Does not recurse into layout objects on that lin
e. |
73 virtual void examineLine(const RootInlineBox&) = 0; | 71 virtual void examineLine(const RootInlineBox&) = 0; |
74 | 72 |
75 // Examine and collect column balancing data for everything in the flow thre
ad portion. Will | 73 // Examine and collect column balancing data for everything in the flow thre
ad portion. Will |
76 // trigger calls to examineBoxAfterEntering(), examineBoxBeforeLeaving() and
examineLine() for | 74 // trigger calls to examineBoxAfterEntering(), examineBoxBeforeLeaving() and
examineLine() for |
77 // interesting boxes and lines. | 75 // interesting boxes and lines. |
78 void traverse(); | 76 void traverse(); |
79 | 77 |
80 private: | 78 private: |
81 void traverseSubtree(const LayoutBox&); | 79 void traverseSubtree(const LayoutBox&); |
82 | 80 |
83 const LayoutMultiColumnSet& m_columnSet; | 81 const LayoutMultiColumnSet& m_columnSet; |
84 const LayoutUnit m_logicalTopInFlowThread; | 82 const LayoutUnit m_logicalTopInFlowThread; |
85 const LayoutUnit m_logicalBottomInFlowThread; | 83 const LayoutUnit m_logicalBottomInFlowThread; |
86 | 84 |
87 LayoutUnit m_flowThreadOffset; | 85 LayoutUnit m_flowThreadOffset; |
88 | |
89 // The break-after value from the previous in-flow block-level object to be
joined with the | |
90 // break-before value of the next in-flow block-level object. | |
91 EBreak m_previousBreakAfterValue; | |
92 }; | 86 }; |
93 | 87 |
94 // After an initial layout pass, we know the height of the contents of a flow th
read. Based on | 88 // After an initial layout pass, we know the height of the contents of a flow th
read. Based on |
95 // this, we can estimate an initial minimal column height. This class will colle
ct the necessary | 89 // this, we can estimate an initial minimal column height. This class will colle
ct the necessary |
96 // information from the layout objects to make this estimate. This estimate may
be used to perform | 90 // information from the layout objects to make this estimate. This estimate may
be used to perform |
97 // another layout iteration. If we after such a layout iteration cannot fit the
contents with the | 91 // another layout iteration. If we after such a layout iteration cannot fit the
contents with the |
98 // given column height without creating overflowing columns, we will have to str
etch the columns by | 92 // given column height without creating overflowing columns, we will have to str
etch the columns by |
99 // some amount and lay out again. We may need to do this several times (but typi
cally not more | 93 // some amount and lay out again. We may need to do this several times (but typi
cally not more |
100 // times than the number of columns that we have). The amount to stretch is prov
ided by the sister | 94 // times than the number of columns that we have). The amount to stretch is prov
ided by the sister |
101 // of this class, named MinimumSpaceShortageFinder. | 95 // of this class, named MinimumSpaceShortageFinder. |
102 class InitialColumnHeightFinder final : public ColumnBalancer { | 96 class InitialColumnHeightFinder final : public ColumnBalancer { |
103 public: | 97 public: |
104 InitialColumnHeightFinder(const LayoutMultiColumnSet&, LayoutUnit logicalTop
InFlowThread, LayoutUnit logicalBottomInFlowThread); | 98 InitialColumnHeightFinder(const LayoutMultiColumnSet&, LayoutUnit logicalTop
InFlowThread, LayoutUnit logicalBottomInFlowThread); |
105 | 99 |
106 LayoutUnit initialMinimalBalancedHeight() const; | 100 LayoutUnit initialMinimalBalancedHeight() const; |
107 | 101 |
108 // Height of the tallest piece of unbreakable content. This is the minimum c
olumn logical height | 102 // Height of the tallest piece of unbreakable content. This is the minimum c
olumn logical height |
109 // required to avoid fragmentation where it shouldn't occur (inside unbreaka
ble content, between | 103 // required to avoid fragmentation where it shouldn't occur (inside unbreaka
ble content, between |
110 // orphans and widows, etc.). This will be used as a hint to the column bala
ncer to help set a | 104 // orphans and widows, etc.). This will be used as a hint to the column bala
ncer to help set a |
111 // good initial column height. | 105 // good initial column height. |
112 LayoutUnit tallestUnbreakableLogicalHeight() const { return m_tallestUnbreak
ableLogicalHeight; } | 106 LayoutUnit tallestUnbreakableLogicalHeight() const { return m_tallestUnbreak
ableLogicalHeight; } |
113 | 107 |
114 private: | 108 private: |
115 void examineBoxAfterEntering(const LayoutBox&); | 109 void examineBoxAfterEntering(const LayoutBox&, EBreak previousBreakAfterValu
e); |
116 void examineBoxBeforeLeaving(const LayoutBox&); | 110 void examineBoxBeforeLeaving(const LayoutBox&); |
117 void examineLine(const RootInlineBox&); | 111 void examineLine(const RootInlineBox&); |
118 | 112 |
119 // Record that there's a pagination strut that ends at the specified |offset
InFlowThread|, which | 113 // Record that there's a pagination strut that ends at the specified |offset
InFlowThread|, which |
120 // is an offset exactly at the top of some column. | 114 // is an offset exactly at the top of some column. |
121 void recordStrutBeforeOffset(LayoutUnit offsetInFlowThread, LayoutUnit strut
); | 115 void recordStrutBeforeOffset(LayoutUnit offsetInFlowThread, LayoutUnit strut
); |
122 | 116 |
123 // Return the accumulated space used by struts at all column boundaries prec
eding the specified | 117 // Return the accumulated space used by struts at all column boundaries prec
eding the specified |
124 // flowthread offset. | 118 // flowthread offset. |
125 LayoutUnit spaceUsedByStrutsAt(LayoutUnit offsetInFlowThread) const; | 119 LayoutUnit spaceUsedByStrutsAt(LayoutUnit offsetInFlowThread) const; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 // the column height by the minimum space shortage at column breaks. This class
finds the minimum | 184 // the column height by the minimum space shortage at column breaks. This class
finds the minimum |
191 // space shortage after having laid out with the current column height. | 185 // space shortage after having laid out with the current column height. |
192 class MinimumSpaceShortageFinder final : public ColumnBalancer { | 186 class MinimumSpaceShortageFinder final : public ColumnBalancer { |
193 public: | 187 public: |
194 MinimumSpaceShortageFinder(const LayoutMultiColumnSet&, LayoutUnit logicalTo
pInFlowThread, LayoutUnit logicalBottomInFlowThread); | 188 MinimumSpaceShortageFinder(const LayoutMultiColumnSet&, LayoutUnit logicalTo
pInFlowThread, LayoutUnit logicalBottomInFlowThread); |
195 | 189 |
196 LayoutUnit minimumSpaceShortage() const { return m_minimumSpaceShortage; } | 190 LayoutUnit minimumSpaceShortage() const { return m_minimumSpaceShortage; } |
197 unsigned forcedBreaksCount() const { return m_forcedBreaksCount; } | 191 unsigned forcedBreaksCount() const { return m_forcedBreaksCount; } |
198 | 192 |
199 private: | 193 private: |
200 void examineBoxAfterEntering(const LayoutBox&); | 194 void examineBoxAfterEntering(const LayoutBox&, EBreak previousBreakAfterValu
e); |
201 void examineBoxBeforeLeaving(const LayoutBox&); | 195 void examineBoxBeforeLeaving(const LayoutBox&); |
202 void examineLine(const RootInlineBox&); | 196 void examineLine(const RootInlineBox&); |
203 | 197 |
204 void recordSpaceShortage(LayoutUnit shortage) | 198 void recordSpaceShortage(LayoutUnit shortage) |
205 { | 199 { |
206 // Only positive values are interesting (and allowed) here. Zero space s
hortage may | 200 // Only positive values are interesting (and allowed) here. Zero space s
hortage may |
207 // be reported when we're at the top of a column and the element has zer
o | 201 // be reported when we're at the top of a column and the element has zer
o |
208 // height. | 202 // height. |
209 if (shortage > 0) | 203 if (shortage > 0) |
210 m_minimumSpaceShortage = std::min(m_minimumSpaceShortage, shortage); | 204 m_minimumSpaceShortage = std::min(m_minimumSpaceShortage, shortage); |
211 } | 205 } |
212 | 206 |
213 // The smallest amout of space shortage that caused a column break. | 207 // The smallest amout of space shortage that caused a column break. |
214 LayoutUnit m_minimumSpaceShortage; | 208 LayoutUnit m_minimumSpaceShortage; |
215 | 209 |
216 // Set when breaking before a block, and we're looking for the first unbreak
able descendant, in | 210 // Set when breaking before a block, and we're looking for the first unbreak
able descendant, in |
217 // order to report correct space shortage for that one. | 211 // order to report correct space shortage for that one. |
218 LayoutUnit m_pendingStrut; | 212 LayoutUnit m_pendingStrut; |
219 | 213 |
220 unsigned m_forcedBreaksCount; | 214 unsigned m_forcedBreaksCount; |
221 }; | 215 }; |
222 | 216 |
223 } // namespace blink | 217 } // namespace blink |
OLD | NEW |