| 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 // The flow thread is the first child of the multicol container. If the
flow thread is also |
| 120 // the last child, it means that there are no siblings; i.e. we have no
column boxes. |
| 121 return lastSiblingBox != this ? lastSiblingBox : 0; |
| 122 } |
| 123 |
| 124 // Return the spanner placeholder that belongs to the spanner in the contain
ing block chain, if |
| 125 // any. This includes the renderer for the element that actually establishes
the spanner too. |
| 126 RenderMultiColumnSpannerPlaceholder* containingColumnSpannerPlaceholder(cons
t RenderObject* descendant) const; |
| 112 | 127 |
| 113 // Populate the flow thread with what's currently its siblings. Called when
a regular block | 128 // Populate the flow thread with what's currently its siblings. Called when
a regular block |
| 114 // becomes a multicol container. | 129 // becomes a multicol container. |
| 115 void populate(); | 130 void populate(); |
| 116 | 131 |
| 117 // Empty the flow thread by moving everything to the parent. Remove all mult
icol specific | 132 // 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 | 133 // renderers. Then destroy the flow thread. Called when a multicol container
becomes a regular |
| 119 // block. | 134 // block. |
| 120 void evacuateAndDestroy(); | 135 void evacuateAndDestroy(); |
| 121 | 136 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 136 | 151 |
| 137 protected: | 152 protected: |
| 138 RenderMultiColumnFlowThread(); | 153 RenderMultiColumnFlowThread(); |
| 139 void setProgressionIsInline(bool isInline) { m_progressionIsInline = isInlin
e; } | 154 void setProgressionIsInline(bool isInline) { m_progressionIsInline = isInlin
e; } |
| 140 | 155 |
| 141 virtual void layout() override; | 156 virtual void layout() override; |
| 142 | 157 |
| 143 private: | 158 private: |
| 144 void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const; | 159 void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const; |
| 145 void createAndInsertMultiColumnSet(); | 160 void createAndInsertMultiColumnSet(); |
| 146 void createAndInsertSpannerSet(RenderBox* spanner); | 161 void createAndInsertSpannerPlaceholder(RenderBox* spanner); |
| 147 virtual bool descendantIsValidColumnSpanner(RenderObject* descendant) const; | 162 virtual bool descendantIsValidColumnSpanner(RenderObject* descendant) const; |
| 148 | 163 |
| 149 virtual const char* renderName() const override; | 164 virtual const char* renderName() const override; |
| 150 virtual void addRegionToThread(RenderMultiColumnSet*) override; | 165 virtual void addRegionToThread(RenderMultiColumnSet*) override; |
| 151 virtual void willBeRemovedFromTree() override; | 166 virtual void willBeRemovedFromTree() override; |
| 152 virtual void flowThreadDescendantWasInserted(RenderObject*) override; | 167 virtual void flowThreadDescendantWasInserted(RenderObject*) override; |
| 168 virtual void flowThreadDescendantWillBeRemoved(RenderObject*) override; |
| 153 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic
alTop, LogicalExtentComputedValues&) const override; | 169 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic
alTop, LogicalExtentComputedValues&) const override; |
| 154 virtual void updateLogicalWidth() override; | 170 virtual void updateLogicalWidth() override; |
| 155 virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) overr
ide; | 171 virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) overr
ide; |
| 156 virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight
) override; | 172 virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight
) override; |
| 157 virtual RenderMultiColumnSet* columnSetAtBlockOffset(LayoutUnit) const overr
ide; | 173 virtual RenderMultiColumnSet* columnSetAtBlockOffset(LayoutUnit) const overr
ide; |
| 158 virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool
isBefore, LayoutUnit* offsetBreakAdjustment = 0) override; | 174 virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool
isBefore, LayoutUnit* offsetBreakAdjustment = 0) override; |
| 159 virtual bool isPageLogicalHeightKnown() const override; | 175 virtual bool isPageLogicalHeightKnown() const override; |
| 160 | 176 |
| 161 typedef HashMap<const RenderObject*, RenderMultiColumnSpannerSet*> SpannerMa
p; | |
| 162 SpannerMap m_spannerMap; | |
| 163 | |
| 164 unsigned m_columnCount; // The used value of column-count | 177 unsigned m_columnCount; // The used value of column-count |
| 165 LayoutUnit m_columnHeightAvailable; // Total height available to columns, or
0 if auto. | 178 LayoutUnit m_columnHeightAvailable; // Total height available to columns, or
0 if auto. |
| 166 bool m_inBalancingPass; // Set when relayouting for column balancing. | 179 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. | 180 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. | 181 bool m_progressionIsInline; // Always true for regular multicol. False for p
aged-y overflow. |
| 182 bool m_isBeingEvacuated; |
| 169 }; | 183 }; |
| 170 | 184 |
| 171 } // namespace blink | 185 } // namespace blink |
| 172 | 186 |
| 173 #endif // RenderMultiColumnFlowThread_h | 187 #endif // RenderMultiColumnFlowThread_h |
| 174 | |
| OLD | NEW |