| 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 15 matching lines...) Expand all Loading... |
| 26 #ifndef LayoutMultiColumnSet_h | 26 #ifndef LayoutMultiColumnSet_h |
| 27 #define LayoutMultiColumnSet_h | 27 #define LayoutMultiColumnSet_h |
| 28 | 28 |
| 29 #include "core/CoreExport.h" | 29 #include "core/CoreExport.h" |
| 30 #include "core/layout/LayoutMultiColumnFlowThread.h" | 30 #include "core/layout/LayoutMultiColumnFlowThread.h" |
| 31 #include "core/layout/MultiColumnFragmentainerGroup.h" | 31 #include "core/layout/MultiColumnFragmentainerGroup.h" |
| 32 #include "wtf/Vector.h" | 32 #include "wtf/Vector.h" |
| 33 | 33 |
| 34 namespace blink { | 34 namespace blink { |
| 35 | 35 |
| 36 // A set of columns in a multicol container. A column set is inserted as an anon
ymous child of the | 36 // A set of columns in a multicol container. A column set is inserted as an |
| 37 // actual multicol container (i.e. the layoutObject whose style computes to non-
auto column-count and/or | 37 // anonymous child of the actual multicol container (i.e. the layoutObject whose |
| 38 // column-width), next to the flow thread. There'll be one column set for each c
ontiguous run of | 38 // style computes to non-auto column-count and/or column-width), next to the |
| 39 // column content. The only thing that can interrupt a contiguous run of column
content is a column | 39 // flow thread. There'll be one column set for each contiguous run of column |
| 40 // spanner, which means that if there are no spanners, there'll only be one colu
mn set. | 40 // content. The only thing that can interrupt a contiguous run of column content |
| 41 // is a column spanner, which means that if there are no spanners, there'll |
| 42 // only be one column set. |
| 41 // | 43 // |
| 42 // Since a spanner interrupts an otherwise contiguous run of column content, ins
erting one may | 44 // Since a spanner interrupts an otherwise contiguous run of column content, |
| 43 // result in the creation of additional new column sets. A placeholder for the s
panning layoutObject has | 45 // inserting one may result in the creation of additional new column sets. A |
| 44 // to be placed in between the column sets that come before and after the spanne
r, if there's | 46 // placeholder for the spanning layoutObject has to be placed in between the |
| 45 // actually column content both before and after the spanner. | 47 // column sets that come before and after the spanner, if there's actually |
| 48 // column content both before and after the spanner. |
| 46 // | 49 // |
| 47 // A column set has no children on its own, but is merely used to slice a portio
n of the tall | 50 // A column set has no children on its own, but is merely used to slice a |
| 48 // "single-column" flow thread into actual columns visually, to convert from flo
w thread coordinates | 51 // portion of the tall "single-column" flow thread into actual columns visually, |
| 49 // to visual ones. It is in charge of both positioning columns correctly relativ
ely to the parent | 52 // to convert from flow thread coordinates to visual ones. It is in charge of |
| 50 // multicol container, and to calculate the correct translation for each column'
s contents, and to | 53 // both positioning columns correctly relatively to the parent multicol |
| 51 // paint any rules between them. LayoutMultiColumnSet objects are used for paint
ing, hit testing, | 54 // container, and to calculate the correct translation for each column's |
| 52 // and any other type of operation that requires mapping from flow thread coordi
nates to visual | 55 // contents, and to paint any rules between them. LayoutMultiColumnSet objects |
| 53 // coordinates. | 56 // are used for painting, hit testing, and any other type of operation that |
| 57 // requires mapping from flow thread coordinates to visual coordinates. |
| 54 // | 58 // |
| 55 // Columns are normally laid out in the inline progression direction, but if the
multicol container | 59 // Columns are normally laid out in the inline progression direction, but if the |
| 56 // is inside another fragmentation context (e.g. paged media, or an another mult
icol container), we | 60 // multicol container is inside another fragmentation context (e.g. paged media, |
| 57 // may need to group the columns, so that we get one MultiColumnFragmentainerGro
up for each outer | 61 // or an another multicol container), we may need to group the columns, so |
| 58 // fragmentainer (page / column) that the inner multicol container lives in. Eac
h fragmentainer | 62 // that we get one MultiColumnFragmentainerGroup for each outer fragmentainer |
| 59 // group has its own column height, but the column height is uniform within a gr
oup. | 63 // (page / column) that the inner multicol container lives in. Each |
| 64 // fragmentainer group has its own column height, but the column height is |
| 65 // uniform within a group. |
| 60 class CORE_EXPORT LayoutMultiColumnSet : public LayoutBlockFlow { | 66 class CORE_EXPORT LayoutMultiColumnSet : public LayoutBlockFlow { |
| 61 public: | 67 public: |
| 62 static LayoutMultiColumnSet* createAnonymous( | 68 static LayoutMultiColumnSet* createAnonymous( |
| 63 LayoutFlowThread&, | 69 LayoutFlowThread&, |
| 64 const ComputedStyle& parentStyle); | 70 const ComputedStyle& parentStyle); |
| 65 | 71 |
| 66 const MultiColumnFragmentainerGroup& firstFragmentainerGroup() const { | 72 const MultiColumnFragmentainerGroup& firstFragmentainerGroup() const { |
| 67 return m_fragmentainerGroups.first(); | 73 return m_fragmentainerGroups.first(); |
| 68 } | 74 } |
| 69 const MultiColumnFragmentainerGroup& lastFragmentainerGroup() const { | 75 const MultiColumnFragmentainerGroup& lastFragmentainerGroup() const { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 LayoutBlockFlow* multiColumnBlockFlow() const { | 124 LayoutBlockFlow* multiColumnBlockFlow() const { |
| 119 return toLayoutBlockFlow(parent()); | 125 return toLayoutBlockFlow(parent()); |
| 120 } | 126 } |
| 121 LayoutMultiColumnFlowThread* multiColumnFlowThread() const { | 127 LayoutMultiColumnFlowThread* multiColumnFlowThread() const { |
| 122 return toLayoutMultiColumnFlowThread(flowThread()); | 128 return toLayoutMultiColumnFlowThread(flowThread()); |
| 123 } | 129 } |
| 124 | 130 |
| 125 LayoutMultiColumnSet* nextSiblingMultiColumnSet() const; | 131 LayoutMultiColumnSet* nextSiblingMultiColumnSet() const; |
| 126 LayoutMultiColumnSet* previousSiblingMultiColumnSet() const; | 132 LayoutMultiColumnSet* previousSiblingMultiColumnSet() const; |
| 127 | 133 |
| 128 // Return true if we have a fragmentainer group that can hold a column at the
specified flow thread block offset. | 134 // Return true if we have a fragmentainer group that can hold a column at the |
| 135 // specified flow thread block offset. |
| 129 bool hasFragmentainerGroupForColumnAt(LayoutUnit bottomOffsetInFlowThread, | 136 bool hasFragmentainerGroupForColumnAt(LayoutUnit bottomOffsetInFlowThread, |
| 130 PageBoundaryRule) const; | 137 PageBoundaryRule) const; |
| 131 | 138 |
| 132 MultiColumnFragmentainerGroup& appendNewFragmentainerGroup(); | 139 MultiColumnFragmentainerGroup& appendNewFragmentainerGroup(); |
| 133 | 140 |
| 134 // Logical top relative to the content edge of the multicol container. | 141 // Logical top relative to the content edge of the multicol container. |
| 135 LayoutUnit logicalTopFromMulticolContentEdge() const; | 142 LayoutUnit logicalTopFromMulticolContentEdge() const; |
| 136 | 143 |
| 137 LayoutUnit logicalTopInFlowThread() const; | 144 LayoutUnit logicalTopInFlowThread() const; |
| 138 LayoutUnit logicalBottomInFlowThread() const; | 145 LayoutUnit logicalBottomInFlowThread() const; |
| 139 LayoutUnit logicalHeightInFlowThread() const { | 146 LayoutUnit logicalHeightInFlowThread() const { |
| 140 return logicalBottomInFlowThread() - logicalTopInFlowThread(); | 147 return logicalBottomInFlowThread() - logicalTopInFlowThread(); |
| 141 } | 148 } |
| 142 | 149 |
| 143 // Return the amount of flow thread contents that the specified fragmentainer
group can hold | 150 // Return the amount of flow thread contents that the specified fragmentainer |
| 144 // without overflowing. | 151 // group can hold without overflowing. |
| 145 LayoutUnit fragmentainerGroupCapacity( | 152 LayoutUnit fragmentainerGroupCapacity( |
| 146 const MultiColumnFragmentainerGroup& group) const { | 153 const MultiColumnFragmentainerGroup& group) const { |
| 147 return group.logicalHeight() * usedColumnCount(); | 154 return group.logicalHeight() * usedColumnCount(); |
| 148 } | 155 } |
| 149 | 156 |
| 150 LayoutRect flowThreadPortionRect() const; | 157 LayoutRect flowThreadPortionRect() const; |
| 151 LayoutRect flowThreadPortionOverflowRect() const; | 158 LayoutRect flowThreadPortionOverflowRect() const; |
| 152 LayoutRect overflowRectForFlowThreadPortion( | 159 LayoutRect overflowRectForFlowThreadPortion( |
| 153 const LayoutRect& flowThreadPortionRect, | 160 const LayoutRect& flowThreadPortionRect, |
| 154 bool isFirstPortion, | 161 bool isFirstPortion, |
| 155 bool isLastPortion) const; | 162 bool isLastPortion) const; |
| 156 | 163 |
| 157 // The used CSS value of column-count, i.e. how many columns there are room fo
r without overflowing. | 164 // The used CSS value of column-count, i.e. how many columns there are room |
| 165 // for without overflowing. |
| 158 unsigned usedColumnCount() const { | 166 unsigned usedColumnCount() const { |
| 159 return multiColumnFlowThread()->columnCount(); | 167 return multiColumnFlowThread()->columnCount(); |
| 160 } | 168 } |
| 161 | 169 |
| 162 bool heightIsAuto() const; | 170 bool heightIsAuto() const; |
| 163 | 171 |
| 164 // Find the column that contains the given block offset, and return the transl
ation needed to | 172 // Find the column that contains the given block offset, and return the |
| 165 // get from flow thread coordinates to visual coordinates. | 173 // translation needed to get from flow thread coordinates to visual |
| 174 // coordinates. |
| 166 LayoutSize flowThreadTranslationAtOffset(LayoutUnit, | 175 LayoutSize flowThreadTranslationAtOffset(LayoutUnit, |
| 167 PageBoundaryRule, | 176 PageBoundaryRule, |
| 168 CoordinateSpaceConversion) const; | 177 CoordinateSpaceConversion) const; |
| 169 | 178 |
| 170 LayoutPoint visualPointToFlowThreadPoint( | 179 LayoutPoint visualPointToFlowThreadPoint( |
| 171 const LayoutPoint& visualPoint) const; | 180 const LayoutPoint& visualPoint) const; |
| 172 | 181 |
| 173 // (Re-)calculate the column height if it's auto. This is first and foremost n
eeded by sets that | 182 // (Re-)calculate the column height if it's auto. This is first and foremost |
| 174 // are to balance the column height, but even when it isn't to be balanced, th
is is necessary if | 183 // needed by sets that are to balance the column height, but even when it |
| 175 // the multicol container's height is constrained. | 184 // isn't to be balanced, this is necessary if the multicol container's height |
| 185 // is constrained. |
| 176 bool recalculateColumnHeight(); | 186 bool recalculateColumnHeight(); |
| 177 | 187 |
| 178 // Reset previously calculated column height. Will mark for layout if needed. | 188 // Reset previously calculated column height. Will mark for layout if needed. |
| 179 void resetColumnHeight(); | 189 void resetColumnHeight(); |
| 180 | 190 |
| 181 void storeOldPosition() { m_oldLogicalTop = logicalTop(); } | 191 void storeOldPosition() { m_oldLogicalTop = logicalTop(); } |
| 182 bool isInitialHeightCalculated() const { return m_initialHeightCalculated; } | 192 bool isInitialHeightCalculated() const { return m_initialHeightCalculated; } |
| 183 | 193 |
| 184 // Layout of flow thread content that's to be rendered inside this column set
begins. This | 194 // Layout of flow thread content that's to be rendered inside this column set |
| 185 // happens at the beginning of flow thread layout, and when advancing from a p
revious column set | 195 // begins. This happens at the beginning of flow thread layout, and when |
| 186 // or spanner to this one. | 196 // advancing from a previous column set or spanner to this one. |
| 187 void beginFlow(LayoutUnit offsetInFlowThread); | 197 void beginFlow(LayoutUnit offsetInFlowThread); |
| 188 | 198 |
| 189 // Layout of flow thread content that was to be rendered inside this column se
t has | 199 // Layout of flow thread content that was to be rendered inside this column |
| 190 // finished. This happens at end of flow thread layout, and when advancing to
the next column | 200 // set has finished. This happens at end of flow thread layout, and when |
| 191 // set or spanner. | 201 // advancing to the next column set or spanner. |
| 192 void endFlow(LayoutUnit offsetInFlowThread); | 202 void endFlow(LayoutUnit offsetInFlowThread); |
| 193 | 203 |
| 194 void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override; | 204 void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override; |
| 195 void layout() override; | 205 void layout() override; |
| 196 | 206 |
| 197 void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, | 207 void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, |
| 198 LayoutUnit& maxLogicalWidth) const final; | 208 LayoutUnit& maxLogicalWidth) const final; |
| 199 | 209 |
| 200 void attachToFlowThread(); | 210 void attachToFlowThread(); |
| 201 void detachFromFlowThread(); | 211 void detachFromFlowThread(); |
| 202 | 212 |
| 203 // The top of the page nearest to the specified block offset. All in flowthrea
d coordinates. | 213 // The top of the page nearest to the specified block offset. All in |
| 214 // flowthread coordinates. |
| 204 LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const; | 215 LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const; |
| 205 | 216 |
| 206 LayoutRect fragmentsBoundingBox( | 217 LayoutRect fragmentsBoundingBox( |
| 207 const LayoutRect& boundingBoxInFlowThread) const; | 218 const LayoutRect& boundingBoxInFlowThread) const; |
| 208 | 219 |
| 209 LayoutUnit columnGap() const; | 220 LayoutUnit columnGap() const; |
| 210 | 221 |
| 211 // The "CSS actual" value of column-count. This includes overflowing columns,
if any. | 222 // The "CSS actual" value of column-count. This includes overflowing columns, |
| 223 // if any. |
| 212 unsigned actualColumnCount() const; | 224 unsigned actualColumnCount() const; |
| 213 | 225 |
| 214 const char* name() const override { return "LayoutMultiColumnSet"; } | 226 const char* name() const override { return "LayoutMultiColumnSet"; } |
| 215 | 227 |
| 216 // Sets |columnRuleBounds| to the bounds of each column rule rect's painted ex
tent, adjusted by paint offset, | 228 // Sets |columnRuleBounds| to the bounds of each column rule rect's painted |
| 217 // before pixel snapping. Returns true if column rules should be painted at al
l. | 229 // extent, adjusted by paint offset, before pixel snapping. Returns true if |
| 230 // column rules should be painted at all. |
| 218 bool computeColumnRuleBounds(const LayoutPoint& paintOffset, | 231 bool computeColumnRuleBounds(const LayoutPoint& paintOffset, |
| 219 Vector<LayoutRect>& columnRuleBounds) const; | 232 Vector<LayoutRect>& columnRuleBounds) const; |
| 220 | 233 |
| 221 LayoutRect localOverflowRectForPaintInvalidation() const override; | 234 LayoutRect localOverflowRectForPaintInvalidation() const override; |
| 222 | 235 |
| 223 protected: | 236 protected: |
| 224 LayoutMultiColumnSet(LayoutFlowThread*); | 237 LayoutMultiColumnSet(LayoutFlowThread*); |
| 225 | 238 |
| 226 private: | 239 private: |
| 227 void insertedIntoTree() final; | 240 void insertedIntoTree() final; |
| 228 void willBeRemovedFromTree() final; | 241 void willBeRemovedFromTree() final; |
| 229 | 242 |
| 230 bool isSelfCollapsingBlock() const override { return false; } | 243 bool isSelfCollapsingBlock() const override { return false; } |
| 231 | 244 |
| 232 void computeLogicalHeight(LayoutUnit logicalHeight, | 245 void computeLogicalHeight(LayoutUnit logicalHeight, |
| 233 LayoutUnit logicalTop, | 246 LayoutUnit logicalTop, |
| 234 LogicalExtentComputedValues&) const override; | 247 LogicalExtentComputedValues&) const override; |
| 235 PositionWithAffinity positionForPoint(const LayoutPoint&) override; | 248 PositionWithAffinity positionForPoint(const LayoutPoint&) override; |
| 236 | 249 |
| 237 void paintObject(const PaintInfo&, | 250 void paintObject(const PaintInfo&, |
| 238 const LayoutPoint& paintOffset) const override; | 251 const LayoutPoint& paintOffset) const override; |
| 239 | 252 |
| 240 void addOverflowFromChildren() override; | 253 void addOverflowFromChildren() override; |
| 241 | 254 |
| 242 MultiColumnFragmentainerGroupList m_fragmentainerGroups; | 255 MultiColumnFragmentainerGroupList m_fragmentainerGroups; |
| 243 LayoutFlowThread* m_flowThread; | 256 LayoutFlowThread* m_flowThread; |
| 244 | 257 |
| 245 // Height of the tallest piece of unbreakable content. This is the minimum col
umn logical height | 258 // Height of the tallest piece of unbreakable content. This is the minimum |
| 246 // required to avoid fragmentation where it shouldn't occur (inside unbreakabl
e content, between | 259 // column logical height required to avoid fragmentation where it shouldn't |
| 247 // orphans and widows, etc.). We only store this so that outer fragmentation c
ontexts (if any) | 260 // occur (inside unbreakable content, between orphans and widows, etc.). |
| 248 // can query this when calculating their own minimum. Note that we don't store
this value in | 261 // We only store this so that outer fragmentation contexts (if any) can query |
| 249 // every fragmentainer group (but rather here, in the column set), since we on
ly need the | 262 // this when calculating their own minimum. Note that we don't store this |
| 250 // largest one among them. | 263 // value in every fragmentainer group (but rather here, in the column set), |
| 264 // since we only need the largest one among them. |
| 251 LayoutUnit m_tallestUnbreakableLogicalHeight; | 265 LayoutUnit m_tallestUnbreakableLogicalHeight; |
| 252 | 266 |
| 253 // Logical top in previous layout pass. | 267 // Logical top in previous layout pass. |
| 254 LayoutUnit m_oldLogicalTop; | 268 LayoutUnit m_oldLogicalTop; |
| 255 | 269 |
| 256 bool m_initialHeightCalculated; | 270 bool m_initialHeightCalculated; |
| 257 }; | 271 }; |
| 258 | 272 |
| 259 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutMultiColumnSet, isLayoutMultiColumnSet()); | 273 DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutMultiColumnSet, isLayoutMultiColumnSet()); |
| 260 | 274 |
| 261 } // namespace blink | 275 } // namespace blink |
| 262 | 276 |
| 263 #endif // LayoutMultiColumnSet_h | 277 #endif // LayoutMultiColumnSet_h |
| OLD | NEW |