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" | |
| 31 | 32 |
| 32 namespace blink { | 33 namespace blink { |
| 33 | 34 |
| 34 class RenderMultiColumnSet; | 35 class RenderMultiColumnSet; |
| 36 class RenderMultiColumnSpannerPlaceholder; | |
| 35 | 37 |
| 36 // Flow thread implementation for CSS multicol. This will be inserted as an anon ymous child block of | 38 // Flow thread implementation for CSS multicol. This will be inserted as an anon ymous child block of |
| 37 // the actual multicol container (i.e. the RenderBlockFlow whose style computes to non-auto | 39 // the actual multicol container (i.e. the RenderBlockFlow whose style computes to non-auto |
| 38 // column-count and/or column-width). RenderMultiColumnFlowThread is the heart o f the multicol | 40 // column-count and/or column-width). RenderMultiColumnFlowThread is the heart o f the multicol |
| 39 // implementation, and there is only one instance per multicol container. Child content of the | 41 // implementation, and there is only one instance per multicol container. Child content of the |
| 40 // multicol container is parented into the flow thread at the time of renderer i nsertion. | 42 // multicol container is parented into the flow thread at the time of renderer i nsertion. |
| 41 // | 43 // |
| 42 // Apart from this flow thread child, the multicol container will also have Rend erMultiColumnSet | 44 // Apart from this flow thread child, the multicol container will also have Rend erMultiColumnSet |
| 43 // "region" children, which are used to position the columns visually. The flow thread is in charge | 45 // "region" children, which are used to position the columns visually. The flow thread is in charge |
| 44 // of layout, and, after having calculated the column width, it lays out content as if everything | 46 // of layout, and, after having calculated the column width, it lays out content as if everything |
| 45 // were in one tall single column, except that there will typically be some amou nt of blank space | 47 // were in one tall single column, except that there will typically be some amou nt of blank space |
| 46 // (also known as pagination struts) at the offsets where the actual column boun daries are. This | 48 // (also known as pagination struts) at the offsets where the actual column boun daries are. This |
| 47 // way, content that needs to be preceded by a break will appear at the top of t he next | 49 // way, content that needs to be preceded by a break will appear at the top of t he next |
| 48 // column. Content needs to be preceded by a break when there's a forced break o r when the content | 50 // column. Content needs to be preceded by a break when there's a forced break o r when the content |
| 49 // is unbreakable and cannot fully fit in the same column as the preceding piece of | 51 // is unbreakable and cannot fully fit in the same column as the preceding piece of |
| 50 // content. Although a RenderMultiColumnFlowThread is laid out, it does not take up any space in its | 52 // content. Although a RenderMultiColumnFlowThread is laid out, it does not take up any space in its |
| 51 // container. It's the RenderMultiColumnSet objects that take up the necessary a mount of space, and | 53 // container. It's the RenderMultiColumnSet objects that take up the necessary a mount of space, and |
| 52 // make sure that the columns are painted and hit-tested correctly. | 54 // make sure that the columns are painted and hit-tested correctly. |
| 53 // | 55 // |
| 56 // Column spanner (column-span:all) renderers also become siblings of the column sets, even if they | |
| 57 // occur elsewhere in the DOM tree. A RenderMultiColumnSpannerPlaceholder is cre ated and inserted at | |
| 58 // the position in the render tree where the spanner naturally occurs. The spann er itself is | |
| 59 // reparented as a sibling of the column sets. The containing block of a spanner is the multicol | |
| 60 // container, not its parent block. None of the DOM ancestors between the spanne r and the multicol | |
| 61 // container should affect rendering of the spanner in any way. | |
| 62 // | |
| 54 // 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 |
| 55 // 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 |
| 56 // 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. |
| 57 // | 66 // |
| 58 // 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 |
| 59 // 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 |
| 60 // column sets are laid out. They get their height from the columns that they ho ld. In single | 69 // column sets and spanners are laid out. Column sets get their height from the columns that they |
| 61 // column-row constrained height non-balancing cases this will simply be the sam e as the content | 70 // hold. In single column-row constrained height non-balancing cases without spa nners this will |
| 62 // height of the multicol container itself. In most other cases we'll have to ca lculate optimal | 71 // simply be the same as the content height of the multicol container itself. In most other cases |
| 63 // column heights ourselves, though. This process is referred to as column balan cing, and then we | 72 // we'll have to calculate optimal column heights ourselves, though. This proces s is referred to as |
| 64 // infer the column set height from the flow thread's height. | 73 // column balancing, and then we infer the column set height from the height of the flow thread |
| 74 // portion occupied by each set. Column spanners are just laid out as normal blo cks within the | |
| 75 // multicol container, and get their size and position via the regular layout ma chinery. | |
| 65 // | 76 // |
| 66 // More on column balancing: the columns' height is unknown in the first layout pass when | 77 // More on column balancing: the columns' height is unknown in the first layout pass when |
| 67 // balancing. This means that we cannot insert any implicit (soft / unforced) br eaks (and pagination | 78 // balancing. This means that we cannot insert any implicit (soft / unforced) br eaks (and pagination |
| 68 // struts) when laying out the contents of the flow thread. We'll just lay out e verything in tall | 79 // struts) when laying out the contents of the flow thread. We'll just lay out e verything in tall |
| 69 // single strip. After the initial flow thread layout pass we can determine a te ntative / minimal / | 80 // single strip. After the initial flow thread layout pass we can determine a te ntative / minimal / |
| 70 // initial column height. This is calculated by simply dividing the flow thread' s height by the | 81 // initial column height. This is calculated by simply dividing the flow thread' s height by the |
| 71 // number of specified columns. In the layout pass that follows, we can insert b reaks (and | 82 // number of specified columns. In the layout pass that follows, we can insert b reaks (and |
| 72 // pagination struts) at column boundaries, since we now have a column height. I t may very easily | 83 // pagination struts) at column boundaries, since we now have a column height. I t may very easily |
| 73 // turn out that the calculated height wasn't enough, though. We'll notice this at end of layout. If | 84 // turn out that the calculated height wasn't enough, though. We'll notice this at end of layout. If |
| 74 // we end up with too many columns (i.e. columns overflowing the multicol contai ner), it wasn't | 85 // we end up with too many columns (i.e. columns overflowing the multicol contai ner), it wasn't |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 89 virtual ~RenderMultiColumnFlowThread(); | 100 virtual ~RenderMultiColumnFlowThread(); |
| 90 | 101 |
| 91 static RenderMultiColumnFlowThread* createAnonymous(Document&, RenderStyle* parentStyle); | 102 static RenderMultiColumnFlowThread* createAnonymous(Document&, RenderStyle* parentStyle); |
| 92 | 103 |
| 93 virtual bool isRenderMultiColumnFlowThread() const OVERRIDE FINAL { return t rue; } | 104 virtual bool isRenderMultiColumnFlowThread() const OVERRIDE FINAL { return t rue; } |
| 94 | 105 |
| 95 RenderBlockFlow* multiColumnBlockFlow() const { return toRenderBlockFlow(par ent()); } | 106 RenderBlockFlow* multiColumnBlockFlow() const { return toRenderBlockFlow(par ent()); } |
| 96 | 107 |
| 97 RenderMultiColumnSet* firstMultiColumnSet() const; | 108 RenderMultiColumnSet* firstMultiColumnSet() const; |
| 98 RenderMultiColumnSet* lastMultiColumnSet() const; | 109 RenderMultiColumnSet* lastMultiColumnSet() const; |
| 110 RenderBox* firstColumnSetOrSpanner() const; | |
| 111 static RenderBox* nextColumnSetOrSpannerSiblingOf(const RenderBox*); | |
| 112 static RenderBox* previousColumnSetOrSpannerSiblingOf(const RenderBox*); | |
| 99 | 113 |
| 100 virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE; | 114 RenderMultiColumnSpannerPlaceholder* findColumnSpannerPlaceholder(RenderBox* spanner) const { return m_spannerMap.get(spanner); } |
| 115 | |
| 116 // Find the set inside which the specified renderer would be rendered. | |
| 117 RenderMultiColumnSet* findSetRendering(RenderObject*) const; | |
| 101 | 118 |
| 102 // Populate the flow thread with what's currently its siblings. Called when a regular block | 119 // Populate the flow thread with what's currently its siblings. Called when a regular block |
| 103 // becomes a multicol container. | 120 // becomes a multicol container. |
| 104 void populate(); | 121 void populate(); |
| 105 | 122 |
| 106 // Empty the flow thread by moving everything to the parent. Remove all mult icol specific | 123 // Empty the flow thread by moving everything to the parent. Remove all mult icol specific |
| 107 // renderers. Then destroy the flow thread. Called when a multicol container becomes a regular | 124 // renderers. Then destroy the flow thread. Called when a multicol container becomes a regular |
| 108 // block. | 125 // block. |
| 109 void evacuateAndDestroy(); | 126 void evacuateAndDestroy(); |
| 110 | 127 |
| 111 unsigned columnCount() const { return m_columnCount; } | 128 unsigned columnCount() const { return m_columnCount; } |
| 112 LayoutUnit columnHeightAvailable() const { return m_columnHeightAvailable; } | 129 LayoutUnit columnHeightAvailable() const { return m_columnHeightAvailable; } |
| 113 void setColumnHeightAvailable(LayoutUnit available) { m_columnHeightAvailabl e = available; } | 130 void setColumnHeightAvailable(LayoutUnit available) { m_columnHeightAvailabl e = available; } |
| 114 virtual bool heightIsAuto() const { return !columnHeightAvailable() || multi ColumnBlockFlow()->style()->columnFill() == ColumnFillBalance; } | |
| 115 bool progressionIsInline() const { return m_progressionIsInline; } | 131 bool progressionIsInline() const { return m_progressionIsInline; } |
| 116 | 132 |
| 117 virtual LayoutSize columnOffset(const LayoutPoint&) const OVERRIDE FINAL; | 133 virtual LayoutSize columnOffset(const LayoutPoint&) const OVERRIDE FINAL; |
| 118 | 134 |
| 119 // Do we need to set a new width and lay out? | 135 // Do we need to set a new width and lay out? |
| 120 virtual bool needsNewWidth() const; | 136 virtual bool needsNewWidth() const; |
| 121 | 137 |
| 122 void layoutColumns(bool relayoutChildren, SubtreeLayoutScope&); | 138 void layoutColumns(bool relayoutChildren, SubtreeLayoutScope&); |
| 123 | 139 |
| 124 bool recalculateColumnHeights(); | 140 bool recalculateColumnHeights(); |
| 125 | 141 |
| 142 void advanceToNextColumnSet(RenderMultiColumnSpannerPlaceholder*); | |
| 143 | |
| 126 protected: | 144 protected: |
| 127 RenderMultiColumnFlowThread(); | 145 RenderMultiColumnFlowThread(); |
| 128 void setProgressionIsInline(bool isInline) { m_progressionIsInline = isInlin e; } | 146 void setProgressionIsInline(bool isInline) { m_progressionIsInline = isInlin e; } |
| 129 | 147 |
| 130 virtual void layout() OVERRIDE; | 148 virtual void layout() OVERRIDE; |
| 131 | 149 |
| 132 private: | 150 private: |
| 133 void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const; | 151 void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const; |
| 152 virtual bool isDescendantValidColumnSpanner(RenderObject* descendant) const; | |
| 134 | 153 |
| 135 virtual const char* renderName() const OVERRIDE; | 154 virtual const char* renderName() const OVERRIDE; |
| 136 virtual void addRegionToThread(RenderMultiColumnSet*) OVERRIDE; | 155 virtual void addRegionToThread(RenderMultiColumnSet*) OVERRIDE; |
| 137 virtual void willBeRemovedFromTree() OVERRIDE; | 156 virtual void willBeRemovedFromTree() OVERRIDE; |
| 157 virtual RenderObject* resolveMovedChild(RenderObject* child) const OVERRIDE; | |
| 158 virtual void flowThreadDescendantInserted(RenderObject*) OVERRIDE; | |
| 159 virtual void flowThreadRelativeWillBeRemoved(RenderObject*) OVERRIDE; | |
|
Julien - ping for review
2014/09/03 23:22:23
Relative seems too ambiguous to me (there is a rel
mstensho (USE GERRIT)
2014/09/04 12:14:02
Done.
| |
| 138 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic alTop, LogicalExtentComputedValues&) const OVERRIDE; | 160 virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logic alTop, LogicalExtentComputedValues&) const OVERRIDE; |
| 139 virtual void updateLogicalWidth() OVERRIDE; | 161 virtual void updateLogicalWidth() OVERRIDE; |
| 140 virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) OVERR IDE; | 162 virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) OVERR IDE; |
| 141 virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight ) OVERRIDE; | 163 virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight ) OVERRIDE; |
| 142 virtual RenderMultiColumnSet* columnSetAtBlockOffset(LayoutUnit) const OVERR IDE; | 164 virtual RenderMultiColumnSet* columnSetAtBlockOffset(LayoutUnit) const OVERR IDE; |
| 143 virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) OVERRIDE; | 165 virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) OVERRIDE; |
| 144 virtual bool isPageLogicalHeightKnown() const OVERRIDE; | 166 virtual bool isPageLogicalHeightKnown() const OVERRIDE; |
| 145 | 167 |
| 168 typedef HashMap<RenderBox*, RenderMultiColumnSpannerPlaceholder*> SpannerMap ; | |
| 169 SpannerMap m_spannerMap; | |
| 170 | |
| 171 // The last set we worked on. It's not to be used as the "current set". The concept of a | |
| 172 // "current set" is difficult, since layout may jump back and forth in the t ree, due to wrong | |
| 173 // top location estimates (due to e.g. margin collapsing), and possibly for other reasons. | |
| 174 RenderMultiColumnSet* m_lastSetWorkedOn; | |
|
Julien - ping for review
2014/09/03 23:22:23
Wouldn't this be better passed in as a parameter?
mstensho (USE GERRIT)
2014/09/04 12:14:02
It's used in RenderMultiColumnFlowThread::columnSe
| |
| 175 | |
| 146 unsigned m_columnCount; // The used value of column-count | 176 unsigned m_columnCount; // The used value of column-count |
| 147 LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto. | 177 LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto. |
| 178 bool m_inLayout; // Set while we're laying out the flow thread, during which colum set heights are unknown. | |
|
Julien - ping for review
2014/09/03 23:22:23
Maybe it would be better to call this m_ColumnSetH
mstensho (USE GERRIT)
2014/09/04 12:14:02
Done.
| |
| 148 bool m_inBalancingPass; // Set when relayouting for column balancing. | 179 bool m_inBalancingPass; // Set when relayouting for column balancing. |
| 149 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. |
| 150 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_beingEvacuated; | |
| 151 }; | 183 }; |
| 152 | 184 |
| 153 } // namespace blink | 185 } // namespace blink |
| 154 | 186 |
| 155 #endif // RenderMultiColumnFlowThread_h | 187 #endif // RenderMultiColumnFlowThread_h |
| 156 | 188 |
| OLD | NEW |