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 #ifndef MultiColumnFragmentainerGroup_h | 5 #ifndef MultiColumnFragmentainerGroup_h |
6 #define MultiColumnFragmentainerGroup_h | 6 #define MultiColumnFragmentainerGroup_h |
7 | 7 |
8 #include "core/layout/LayoutMultiColumnFlowThread.h" | 8 #include "core/layout/LayoutMultiColumnFlowThread.h" |
9 #include "wtf/Allocator.h" | 9 #include "wtf/Allocator.h" |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... |
24 // because of forced breaks, for example). If there are multiple fragmentainer g
roups, the actual | 24 // because of forced breaks, for example). If there are multiple fragmentainer g
roups, the actual |
25 // column count must not exceed the used column count (the one calculated based
on column-count and | 25 // column count must not exceed the used column count (the one calculated based
on column-count and |
26 // column-width from CSS), or they'd overflow the outer fragmentainer in the inl
ine direction. If we | 26 // column-width from CSS), or they'd overflow the outer fragmentainer in the inl
ine direction. If we |
27 // need more columns than what a group has room for, we'll create another group
and put them there | 27 // need more columns than what a group has room for, we'll create another group
and put them there |
28 // (and make them appear in the next outer fragmentainer). | 28 // (and make them appear in the next outer fragmentainer). |
29 class MultiColumnFragmentainerGroup { | 29 class MultiColumnFragmentainerGroup { |
30 ALLOW_ONLY_INLINE_ALLOCATION(); | 30 ALLOW_ONLY_INLINE_ALLOCATION(); |
31 public: | 31 public: |
32 MultiColumnFragmentainerGroup(LayoutMultiColumnSet&); | 32 MultiColumnFragmentainerGroup(LayoutMultiColumnSet&); |
33 | 33 |
| 34 const LayoutMultiColumnSet& columnSet() const { return m_columnSet; } |
| 35 |
| 36 bool isFirstGroup() const; |
34 bool isLastGroup() const; | 37 bool isLastGroup() const; |
35 | 38 |
36 // Position within the LayoutMultiColumnSet. | 39 // Position within the LayoutMultiColumnSet. |
37 LayoutUnit logicalTop() const { return m_logicalTop; } | 40 LayoutUnit logicalTop() const { return m_logicalTop; } |
38 void setLogicalTop(LayoutUnit logicalTop) { m_logicalTop = logicalTop; } | 41 void setLogicalTop(LayoutUnit logicalTop) { m_logicalTop = logicalTop; } |
39 | 42 |
40 LayoutUnit logicalHeight() const { return m_columnHeight; } | 43 LayoutUnit logicalHeight() const { return m_columnHeight; } |
41 | 44 |
42 LayoutSize offsetFromColumnSet() const; | 45 LayoutSize offsetFromColumnSet() const; |
43 | 46 |
44 // Return the block offset from the enclosing flow thread, if nested. In the
coordinate space | 47 // Return the block offset from the enclosing flow thread, if nested. In the
coordinate space |
45 // of the enclosing flow thread. | 48 // of the enclosing flow thread. |
46 LayoutUnit blockOffsetInEnclosingFlowThread() const; | 49 LayoutUnit blockOffsetInEnclosingFlowThread() const; |
47 | 50 |
48 // The top of our flow thread portion | 51 // The top of our flow thread portion |
49 LayoutUnit logicalTopInFlowThread() const { return m_logicalTopInFlowThread;
} | 52 LayoutUnit logicalTopInFlowThread() const { return m_logicalTopInFlowThread;
} |
50 void setLogicalTopInFlowThread(LayoutUnit logicalTopInFlowThread) { m_logica
lTopInFlowThread = logicalTopInFlowThread; } | 53 void setLogicalTopInFlowThread(LayoutUnit logicalTopInFlowThread) { m_logica
lTopInFlowThread = logicalTopInFlowThread; } |
51 | 54 |
52 // The bottom of our flow thread portion | 55 // The bottom of our flow thread portion |
53 LayoutUnit logicalBottomInFlowThread() const { return m_logicalBottomInFlowT
hread; } | 56 LayoutUnit logicalBottomInFlowThread() const { return m_logicalBottomInFlowT
hread; } |
54 void setLogicalBottomInFlowThread(LayoutUnit logicalBottomInFlowThread) { AS
SERT(logicalBottomInFlowThread >= m_logicalTopInFlowThread); m_logicalBottomInFl
owThread = logicalBottomInFlowThread; } | 57 void setLogicalBottomInFlowThread(LayoutUnit logicalBottomInFlowThread) { AS
SERT(logicalBottomInFlowThread >= m_logicalTopInFlowThread); m_logicalBottomInFl
owThread = logicalBottomInFlowThread; } |
55 | 58 |
56 // The height of our flow thread portion | 59 // The height of our flow thread portion |
57 LayoutUnit logicalHeightInFlowThread() const { return m_logicalBottomInFlowT
hread - m_logicalTopInFlowThread; } | 60 LayoutUnit logicalHeightInFlowThread() const { return m_logicalBottomInFlowT
hread - m_logicalTopInFlowThread; } |
58 | 61 |
59 bool heightIsAuto() const; | 62 bool heightIsAuto() const; |
60 void resetColumnHeight(); | 63 void resetColumnHeight(); |
61 void addContentRun(LayoutUnit endOffsetInFlowThread); | |
62 void updateMinimumColumnHeight(LayoutUnit height) { m_minimumColumnHeight =
std::max(height, m_minimumColumnHeight); } | 64 void updateMinimumColumnHeight(LayoutUnit height) { m_minimumColumnHeight =
std::max(height, m_minimumColumnHeight); } |
63 void recordSpaceShortage(LayoutUnit); | |
64 bool recalculateColumnHeight(BalancedColumnHeightCalculation calculationMode
); | 65 bool recalculateColumnHeight(BalancedColumnHeightCalculation calculationMode
); |
65 | 66 |
66 LayoutSize flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread) cons
t; | 67 LayoutSize flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread) cons
t; |
67 LayoutUnit columnLogicalTopForOffset(LayoutUnit offsetInFlowThread) const; | 68 LayoutUnit columnLogicalTopForOffset(LayoutUnit offsetInFlowThread) const; |
68 LayoutPoint visualPointToFlowThreadPoint(const LayoutPoint& visualPoint) con
st; | 69 LayoutPoint visualPointToFlowThreadPoint(const LayoutPoint& visualPoint) con
st; |
69 LayoutRect fragmentsBoundingBox(const LayoutRect& boundingBoxInFlowThread) c
onst; | 70 LayoutRect fragmentsBoundingBox(const LayoutRect& boundingBoxInFlowThread) c
onst; |
70 | 71 |
71 void collectLayerFragments(PaintLayerFragments&, const LayoutRect& layerBoun
dingBox, const LayoutRect& dirtyRect) const; | 72 void collectLayerFragments(PaintLayerFragments&, const LayoutRect& layerBoun
dingBox, const LayoutRect& dirtyRect) const; |
72 LayoutRect calculateOverflow() const; | 73 LayoutRect calculateOverflow() const; |
73 | 74 |
74 // The "CSS actual" value of column-count. This includes overflowing columns
, if any. | 75 // The "CSS actual" value of column-count. This includes overflowing columns
, if any. |
75 unsigned actualColumnCount() const; | 76 unsigned actualColumnCount() const; |
76 | 77 |
77 private: | 78 private: |
78 LayoutUnit heightAdjustedForRowOffset(LayoutUnit height) const; | 79 LayoutUnit heightAdjustedForRowOffset(LayoutUnit height) const; |
79 LayoutUnit calculateMaxColumnHeight() const; | 80 LayoutUnit calculateMaxColumnHeight() const; |
80 void setAndConstrainColumnHeight(LayoutUnit); | 81 void setAndConstrainColumnHeight(LayoutUnit); |
81 | 82 |
82 // Return the index of the content run with the currently tallest columns, t
aking all implicit | |
83 // breaks assumed so far into account. | |
84 unsigned findRunWithTallestColumns() const; | |
85 | |
86 // Given the current list of content runs, make assumptions about where we n
eed to insert | |
87 // implicit breaks (if there's room for any at all; depending on the number
of explicit breaks), | |
88 // and store the results. This is needed in order to balance the columns. | |
89 void distributeImplicitBreaks(); | |
90 | |
91 LayoutUnit calculateColumnHeight(BalancedColumnHeightCalculation) const; | 83 LayoutUnit calculateColumnHeight(BalancedColumnHeightCalculation) const; |
92 | 84 |
93 LayoutRect columnRectAt(unsigned columnIndex) const; | 85 LayoutRect columnRectAt(unsigned columnIndex) const; |
94 LayoutUnit logicalTopInFlowThreadAt(unsigned columnIndex) const { return m_l
ogicalTopInFlowThread + columnIndex * m_columnHeight; } | 86 LayoutUnit logicalTopInFlowThreadAt(unsigned columnIndex) const { return m_l
ogicalTopInFlowThread + columnIndex * m_columnHeight; } |
95 LayoutRect flowThreadPortionRectAt(unsigned columnIndex) const; | 87 LayoutRect flowThreadPortionRectAt(unsigned columnIndex) const; |
96 LayoutRect flowThreadPortionOverflowRectAt(unsigned columnIndex) const; | 88 LayoutRect flowThreadPortionOverflowRectAt(unsigned columnIndex) const; |
97 | 89 |
98 enum ColumnIndexCalculationMode { | 90 enum ColumnIndexCalculationMode { |
99 ClampToExistingColumns, // Stay within the range of already existing col
umns. | 91 ClampToExistingColumns, // Stay within the range of already existing col
umns. |
100 AssumeNewColumns // Allow column indices outside the range of already ex
isting columns. | 92 AssumeNewColumns // Allow column indices outside the range of already ex
isting columns. |
(...skipping 15 matching lines...) Expand all Loading... |
116 LayoutMultiColumnSet& m_columnSet; | 108 LayoutMultiColumnSet& m_columnSet; |
117 | 109 |
118 LayoutUnit m_logicalTop; | 110 LayoutUnit m_logicalTop; |
119 LayoutUnit m_logicalTopInFlowThread; | 111 LayoutUnit m_logicalTopInFlowThread; |
120 LayoutUnit m_logicalBottomInFlowThread; | 112 LayoutUnit m_logicalBottomInFlowThread; |
121 | 113 |
122 LayoutUnit m_columnHeight; | 114 LayoutUnit m_columnHeight; |
123 | 115 |
124 // The following variables are used when balancing the column set. | 116 // The following variables are used when balancing the column set. |
125 LayoutUnit m_maxColumnHeight; // Maximum column height allowed. | 117 LayoutUnit m_maxColumnHeight; // Maximum column height allowed. |
126 LayoutUnit m_minSpaceShortage; // The smallest amout of space shortage that
caused a column break. | |
127 LayoutUnit m_minimumColumnHeight; | 118 LayoutUnit m_minimumColumnHeight; |
128 | |
129 // A run of content without explicit (forced) breaks; i.e. a flow thread por
tion between two | |
130 // explicit breaks, between flow thread start and an explicit break, between
an explicit break | |
131 // and flow thread end, or, in cases when there are no explicit breaks at al
l: between flow | |
132 // thread portion start and flow thread portion end. We need to know where t
he explicit breaks | |
133 // are, in order to figure out where the implicit breaks will end up, so tha
t we get the columns | |
134 // properly balanced. A content run starts out as representing one single co
lumn, and will | |
135 // represent one additional column for each implicit break "inserted" there. | |
136 class ContentRun { | |
137 public: | |
138 ContentRun(LayoutUnit breakOffset) | |
139 : m_breakOffset(breakOffset) | |
140 , m_assumedImplicitBreaks(0) { } | |
141 | |
142 unsigned assumedImplicitBreaks() const { return m_assumedImplicitBreaks;
} | |
143 void assumeAnotherImplicitBreak() { m_assumedImplicitBreaks++; } | |
144 LayoutUnit breakOffset() const { return m_breakOffset; } | |
145 | |
146 // Return the column height that this content run would require, conside
ring the implicit | |
147 // breaks assumed so far. | |
148 LayoutUnit columnLogicalHeight(LayoutUnit startOffset) const { return ce
ilf((m_breakOffset - startOffset).toFloat() / float(m_assumedImplicitBreaks + 1)
); } | |
149 | |
150 private: | |
151 LayoutUnit m_breakOffset; // Flow thread offset where this run ends. | |
152 unsigned m_assumedImplicitBreaks; // Number of implicit breaks in this r
un assumed so far. | |
153 }; | |
154 Vector<ContentRun, 1> m_contentRuns; | |
155 }; | 119 }; |
156 | 120 |
157 // List of all fragmentainer groups within a column set. There will always be at
least one | 121 // List of all fragmentainer groups within a column set. There will always be at
least one |
158 // group. Deleting the one group is not allowed (or possible). There will be mor
e than one group if | 122 // group. Deleting the one group is not allowed (or possible). There will be mor
e than one group if |
159 // the owning column set lives in multiple outer fragmentainers (e.g. multicol i
nside paged media). | 123 // the owning column set lives in multiple outer fragmentainers (e.g. multicol i
nside paged media). |
160 class CORE_EXPORT MultiColumnFragmentainerGroupList { | 124 class CORE_EXPORT MultiColumnFragmentainerGroupList { |
161 DISALLOW_ALLOCATION(); | 125 DISALLOW_ALLOCATION(); |
162 public: | 126 public: |
163 MultiColumnFragmentainerGroupList(LayoutMultiColumnSet&); | 127 MultiColumnFragmentainerGroupList(LayoutMultiColumnSet&); |
164 ~MultiColumnFragmentainerGroupList(); | 128 ~MultiColumnFragmentainerGroupList(); |
(...skipping 26 matching lines...) Expand all Loading... |
191 | 155 |
192 private: | 156 private: |
193 LayoutMultiColumnSet& m_columnSet; | 157 LayoutMultiColumnSet& m_columnSet; |
194 | 158 |
195 Vector<MultiColumnFragmentainerGroup, 1> m_groups; | 159 Vector<MultiColumnFragmentainerGroup, 1> m_groups; |
196 }; | 160 }; |
197 | 161 |
198 } // namespace blink | 162 } // namespace blink |
199 | 163 |
200 #endif // MultiColumnFragmentainerGroup_h | 164 #endif // MultiColumnFragmentainerGroup_h |
OLD | NEW |