Chromium Code Reviews| 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 |