OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2012 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 10 matching lines...) Expand all Loading... | |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 | 26 |
27 #ifndef RenderMultiColumnFlowThread_h | 27 #ifndef RenderMultiColumnFlowThread_h |
28 #define RenderMultiColumnFlowThread_h | 28 #define RenderMultiColumnFlowThread_h |
29 | 29 |
30 #include "core/rendering/RenderFlowThread.h" | 30 #include "core/rendering/RenderFlowThread.h" |
31 #include "wtf/HashMap.h" | |
32 | 31 |
33 namespace blink { | 32 namespace blink { |
34 | 33 |
35 class RenderMultiColumnSet; | 34 class RenderMultiColumnSet; |
36 class RenderMultiColumnSpannerSet; | 35 class RenderMultiColumnSpannerPlaceholder; |
37 | 36 |
38 // Flow thread implementation for CSS multicol. This will be inserted as an anon ymous child block of | 37 // Flow thread implementation for CSS multicol. This will be inserted as an anon ymous child block of |
39 // the actual multicol container (i.e. the RenderBlockFlow whose style computes to non-auto | 38 // the actual multicol container (i.e. the RenderBlockFlow whose style computes to non-auto |
40 // column-count and/or column-width). RenderMultiColumnFlowThread is the heart o f the multicol | 39 // column-count and/or column-width). RenderMultiColumnFlowThread is the heart o f the multicol |
41 // implementation, and there is only one instance per multicol container. Child content of the | 40 // implementation, and there is only one instance per multicol container. Child content of the |
42 // multicol container is parented into the flow thread at the time of renderer i nsertion. | 41 // multicol container is parented into the flow thread at the time of renderer i nsertion. |
43 // | 42 // |
44 // Apart from this flow thread child, the multicol container will also have Rend erMultiColumnSet | 43 // Apart from this flow thread child, the multicol container will also have Rend erMultiColumnSet |
45 // "region" children, which are used to position the columns visually. The flow thread is in charge | 44 // "region" children, which are used to position the columns visually. The flow thread is in charge |
46 // of layout, and, after having calculated the column width, it lays out content as if everything | 45 // of layout, and, after having calculated the column width, it lays out content as if everything |
47 // were in one tall single column, except that there will typically be some amou nt of blank space | 46 // were in one tall single column, except that there will typically be some amou nt of blank space |
48 // (also known as pagination struts) at the offsets where the actual column boun daries are. This | 47 // (also known as pagination struts) at the offsets where the actual column boun daries are. This |
49 // way, content that needs to be preceded by a break will appear at the top of t he next | 48 // way, content that needs to be preceded by a break will appear at the top of t he next |
50 // column. Content needs to be preceded by a break when there's a forced break o r when the content | 49 // column. Content needs to be preceded by a break when there's a forced break o r when the content |
51 // is unbreakable and cannot fully fit in the same column as the preceding piece of | 50 // is unbreakable and cannot fully fit in the same column as the preceding piece of |
52 // content. Although a RenderMultiColumnFlowThread is laid out, it does not take up any space in its | 51 // content. Although a RenderMultiColumnFlowThread is laid out, it does not take up any space in its |
53 // container. It's the RenderMultiColumnSet objects that take up the necessary a mount of space, and | 52 // container. It's the RenderMultiColumnSet objects that take up the necessary a mount of space, and |
54 // make sure that the columns are painted and hit-tested correctly. | 53 // make sure that the columns are painted and hit-tested correctly. |
55 // | 54 // |
56 // If there is any column content inside the multicol container, we create a | 55 // If there is any column content inside the multicol container, we create a |
57 // RenderMultiColumnSet. We only need to create multiple sets if there are spann ers | 56 // RenderMultiColumnSet. We only need to create multiple sets if there are spann ers |
58 // (column-span:all) in the multicol container. When a spanner is inserted, cont ent preceding it | 57 // (column-span:all) in the multicol container. When a spanner is inserted, cont ent preceding it |
59 // gets its own set, and content succeeding it will get another set. The spanner itself will also | 58 // gets its own set, and content succeeding it will get another set. The spanner itself will also |
60 // get its own set (RenderMultiColumnSpannerSet). | 59 // get its own placeholder between the sets (RenderMultiColumnSpannerPlaceholder ), so that it gets |
60 // positioned and sized correctly. The column-span:all element is inside the flo w thread, but its | |
61 // containing block is the multicol container. | |
61 // | 62 // |
62 // The width of the flow thread is the same as the column width. The width of a column set is the | 63 // The width of the flow thread is the same as the column width. The width of a column set is the |
63 // same as the content box width of the multicol container; in other words exact ly enough to hold | 64 // same as the content box width of the multicol container; in other words exact ly enough to hold |
64 // the number of columns to be used, stacked horizontally, plus column gaps betw een them. | 65 // the number of columns to be used, stacked horizontally, plus column gaps betw een them. |
65 // | 66 // |
66 // Since it's the first child of the multicol container, the flow thread is laid out first, albeit | 67 // Since it's the first child of the multicol container, the flow thread is laid out first, albeit |
67 // in a slightly special way, since it's not to take up any space in its ancesto rs. Afterwards, the | 68 // in a slightly special way, since it's not to take up any space in its ancesto rs. Afterwards, the |
68 // column sets are laid out. Column sets get their height from the columns that they hold. In single | 69 // column sets are laid out. Column sets get their height from the columns that they hold. In single |
69 // column-row constrained height non-balancing cases without spanners this will simply be the same | 70 // column-row constrained height non-balancing cases without spanners this will simply be the same |
70 // as the content height of the multicol container itself. In most other cases w e'll have to | 71 // as the content height of the multicol container itself. In most other cases w e'll have to |
(...skipping 28 matching lines...) Expand all Loading... | |
99 | 100 |
100 static RenderMultiColumnFlowThread* createAnonymous(Document&, RenderStyle* parentStyle); | 101 static RenderMultiColumnFlowThread* createAnonymous(Document&, RenderStyle* parentStyle); |
101 | 102 |
102 virtual bool isRenderMultiColumnFlowThread() const override final { return t rue; } | 103 virtual bool isRenderMultiColumnFlowThread() const override final { return t rue; } |
103 | 104 |
104 RenderBlockFlow* multiColumnBlockFlow() const { return toRenderBlockFlow(par ent()); } | 105 RenderBlockFlow* multiColumnBlockFlow() const { return toRenderBlockFlow(par ent()); } |
105 | 106 |
106 RenderMultiColumnSet* firstMultiColumnSet() const; | 107 RenderMultiColumnSet* firstMultiColumnSet() const; |
107 RenderMultiColumnSet* lastMultiColumnSet() const; | 108 RenderMultiColumnSet* lastMultiColumnSet() const; |
108 | 109 |
109 // Return the spanner set (if any) that contains the specified renderer. Thi s includes the | 110 // Return the first column set or spanner placeholder. |
110 // renderer for the element that actually establishes the spanner too. | 111 RenderBox* firstMultiColumnBox() const |
111 RenderMultiColumnSpannerSet* containingColumnSpannerSet(const RenderObject* descendant) const; | 112 { |
113 return nextSiblingBox(); | |
114 } | |
115 // Return the last column set or spanner placeholder. | |
116 RenderBox* lastMultiColumnBox() const | |
117 { | |
118 RenderBox* lastSiblingBox = multiColumnBlockFlow()->lastChildBox(); | |
119 return lastSiblingBox != this ? lastSiblingBox : 0; | |
Julien - ping for review
2014/12/11 19:09:37
This comparison warrants some explanations as it d
mstensho (USE GERRIT)
2014/12/11 21:01:14
Done.
| |
120 } | |
121 // Return the previous sibling column set or spanner placeholder. | |
122 static RenderBox* previousSiblingMultiColumnBoxOf(RenderBox* renderer) | |
Julien - ping for review
2014/12/11 19:09:38
Those are plain weird being static instead of on R
mstensho (USE GERRIT)
2014/12/11 21:01:14
Indeed. I was afraid to bloat RenderBox too much,
| |
123 { | |
124 RenderBox* previousBox = renderer->previousSiblingBox(); | |
125 if (previousBox->isRenderFlowThread()) | |
126 return 0; | |
127 return previousBox; | |
128 } | |
129 // Return the next sibling column set or spanner placeholder. | |
130 static RenderBox* nextSiblingMultiColumnBoxOf(RenderBox* renderer) | |
131 { | |
132 return renderer->nextSiblingBox(); | |
133 } | |
134 | |
135 // Return the spanner placeholder that belongs to the spanner in the contain ing block chain, if | |
136 // any. This includes the renderer for the element that actually establishes the spanner too. | |
137 RenderMultiColumnSpannerPlaceholder* containingColumnSpannerPlaceholder(cons t RenderObject* descendant) const; | |
112 | 138 |
113 // Populate the flow thread with what's currently its siblings. Called when a regular block | 139 // Populate the flow thread with what's currently its siblings. Called when a regular block |
114 // becomes a multicol container. | 140 // becomes a multicol container. |
115 void populate(); | 141 void populate(); |
116 | 142 |
117 // Empty the flow thread by moving everything to the parent. Remove all mult icol specific | 143 // Empty the flow thread by moving everything to the parent. Remove all mult icol specific |
118 // renderers. Then destroy the flow thread. Called when a multicol container becomes a regular | 144 // renderers. Then destroy the flow thread. Called when a multicol container becomes a regular |
119 // block. | 145 // block. |
120 void evacuateAndDestroy(); | 146 void evacuateAndDestroy(); |
121 | 147 |
(...skipping 14 matching lines...) Expand all Loading... | |
136 | 162 |
137 protected: | 163 protected: |
138 RenderMultiColumnFlowThread(); | 164 RenderMultiColumnFlowThread(); |
139 void setProgressionIsInline(bool isInline) { m_progressionIsInline = isInlin e; } | 165 void setProgressionIsInline(bool isInline) { m_progressionIsInline = isInlin e; } |
140 | 166 |
141 virtual void layout() override; | 167 virtual void layout() override; |
142 | 168 |
143 private: | 169 private: |
144 void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const; | 170 void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const; |
145 void createAndInsertMultiColumnSet(); | 171 void createAndInsertMultiColumnSet(); |
146 void createAndInsertSpannerSet(RenderBox* spanner); | 172 void createAndInsertSpannerPlaceholder(RenderBox* spanner); |
147 virtual bool descendantIsValidColumnSpanner(RenderObject* descendant) const; | 173 virtual bool descendantIsValidColumnSpanner(RenderObject* descendant) const; |
148 | 174 |
149 virtual const char* renderName() const override; | 175 virtual const char* renderName() const override; |
150 virtual void addRegionToThread(RenderMultiColumnSet*) override; | 176 virtual void addRegionToThread(RenderMultiColumnSet*) override; |
151 virtual void willBeRemovedFromTree() override; | 177 virtual void willBeRemovedFromTree() override; |
152 virtual void flowThreadDescendantWasInserted(RenderObject*) override; | 178 virtual void flowThreadDescendantWasInserted(RenderObject*) override; |
179 virtual void flowThreadDescendantWillBeRemoved(RenderObject*) override; | |
153 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic alTop, LogicalExtentComputedValues&) const override; | 180 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic alTop, LogicalExtentComputedValues&) const override; |
154 virtual void updateLogicalWidth() override; | 181 virtual void updateLogicalWidth() override; |
155 virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) overr ide; | 182 virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) overr ide; |
156 virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight ) override; | 183 virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight ) override; |
157 virtual RenderMultiColumnSet* columnSetAtBlockOffset(LayoutUnit) const overr ide; | 184 virtual RenderMultiColumnSet* columnSetAtBlockOffset(LayoutUnit) const overr ide; |
158 virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) override; | 185 virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) override; |
159 virtual bool isPageLogicalHeightKnown() const override; | 186 virtual bool isPageLogicalHeightKnown() const override; |
160 | 187 |
161 typedef HashMap<const RenderObject*, RenderMultiColumnSpannerSet*> SpannerMa p; | |
162 SpannerMap m_spannerMap; | |
163 | |
164 unsigned m_columnCount; // The used value of column-count | 188 unsigned m_columnCount; // The used value of column-count |
165 LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto. | 189 LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto. |
166 bool m_inBalancingPass; // Set when relayouting for column balancing. | 190 bool m_inBalancingPass; // Set when relayouting for column balancing. |
167 bool m_needsColumnHeightsRecalculation; // Set when we need to recalculate t he column set heights after layout. | 191 bool m_needsColumnHeightsRecalculation; // Set when we need to recalculate t he column set heights after layout. |
168 bool m_progressionIsInline; // Always true for regular multicol. False for p aged-y overflow. | 192 bool m_progressionIsInline; // Always true for regular multicol. False for p aged-y overflow. |
193 bool m_isBeingEvacuated; | |
169 }; | 194 }; |
170 | 195 |
171 } // namespace blink | 196 } // namespace blink |
172 | 197 |
173 #endif // RenderMultiColumnFlowThread_h | 198 #endif // RenderMultiColumnFlowThread_h |
174 | |
OLD | NEW |