Chromium Code Reviews| Index: third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h |
| diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h |
| index 7715ca37c70e514b656e94e254409281a9c6fb7c..5abb779a3ce00f329c3aad4e491ab5bd5e37ab76 100644 |
| --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h |
| +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h |
| @@ -37,91 +37,109 @@ class LayoutMultiColumnSpannerPlaceholder; |
| // What to translate *to* when translating from a flow thread coordinate space. |
| enum class CoordinateSpaceConversion { |
| - // Just translate to the nearest containing coordinate space (i.e. where our multicol container |
| - // lives) of this flow thread, i.e. don't walk ancestral flow threads, if any. |
| + // Just translate to the nearest containing coordinate space (i.e. where our |
| + // multicol container lives) of this flow thread, i.e. don't walk ancestral |
| + // flow threads, if any. |
| Containing, |
| // Translate to visual coordinates, by walking all ancestral flow threads. |
| Visual |
| }; |
| -// Flow thread implementation for CSS multicol. This will be inserted as an anonymous child block of |
| -// the actual multicol container (i.e. the LayoutBlockFlow whose style computes to non-auto |
| -// column-count and/or column-width). LayoutMultiColumnFlowThread is the heart of the multicol |
| -// implementation, and there is only one instance per multicol container. Child content of the |
| -// multicol container is parented into the flow thread at the time of layoutObject insertion. |
| +// Flow thread implementation for CSS multicol. This will be inserted as an |
| +// anonymous child block of the actual multicol container (i.e. the |
| +// LayoutBlockFlow whose style computes to non-auto column-count and/or |
| +// column-width). LayoutMultiColumnFlowThread is the heart of the multicol |
| +// implementation, and there is only one instance per multicol container. Child |
| +// content of the multicol container is parented into the flow thread at the |
| +// time of layoutObject insertion. |
| // |
| -// Apart from this flow thread child, the multicol container will also have LayoutMultiColumnSet |
| -// children, which are used to position the columns visually. The flow thread is in charge |
| -// of layout, and, after having calculated the column width, it lays out content as if everything |
| -// were in one tall single column, except that there will typically be some amount of blank space |
| -// (also known as pagination struts) at the offsets where the actual column boundaries are. This |
| -// way, content that needs to be preceded by a break will appear at the top of the next |
| -// column. Content needs to be preceded by a break when there's a forced break or when the content |
| -// is unbreakable and cannot fully fit in the same column as the preceding piece of |
| -// content. Although a LayoutMultiColumnFlowThread is laid out, it does not take up any space in its |
| -// container. It's the LayoutMultiColumnSet objects that take up the necessary amount of space, and |
| -// make sure that the columns are painted and hit-tested correctly. |
| +// Apart from this flow thread child, the multicol container will also have |
| +// LayoutMultiColumnSet children, which are used to position the columns |
| +// visually. The flow thread is in charge of layout, and, after having |
| +// calculated the column width, it lays out content as if everything were in one |
| +// tall single column, except that there will typically be some amount of blank |
| +// space (also known as pagination struts) at the offsets where the actual |
| +// column boundaries are. This way, content that needs to be preceded by a break |
| +// will appear at the top of the next column. Content needs to be preceded by a |
| +// break when there's a forced break or when the content is unbreakable and |
| +// cannot fully fit in the same column as the preceding piece of content. |
| +// Although a LayoutMultiColumnFlowThread is laid out, it does not take up any |
| +// space in its container. It's the LayoutMultiColumnSet objects that take up |
| +// the necessary amount of space, and make sure that the columns are painted and |
| +// hit-tested correctly. |
| // |
| // If there is any column content inside the multicol container, we create a |
| -// LayoutMultiColumnSet. We only need to create multiple sets if there are spanners |
| -// (column-span:all) in the multicol container. When a spanner is inserted, content preceding it |
| -// gets its own set, and content succeeding it will get another set. The spanner itself will also |
| -// get its own placeholder between the sets (LayoutMultiColumnSpannerPlaceholder), so that it gets |
| -// positioned and sized correctly. The column-span:all element is inside the flow thread, but its |
| -// containing block is the multicol container. |
| +// LayoutMultiColumnSet. We only need to create multiple sets if there are |
| +// spanners (column-span:all) in the multicol container. When a spanner is |
| +// inserted, content preceding it gets its own set, and content succeeding it |
| +// will get another set. The spanner itself will also get its own placeholder |
| +// between the sets (LayoutMultiColumnSpannerPlaceholder), so that it gets |
| +// positioned and sized correctly. The column-span:all element is inside the |
| +// flow thread, but its containing block is the multicol container. |
| // |
| // Some invariants for the layout tree structure for multicol: |
| // - A multicol container is always a LayoutBlockFlow |
| // - Every multicol container has one and only one LayoutMultiColumnFlowThread |
| -// - All multicol DOM children and pseudo-elements associated with the multicol container are |
| -// reparented into the flow thread |
| -// - The LayoutMultiColumnFlowThread is the first child of the multicol container |
| -// - A multicol container may only have LayoutMultiColumnFlowThread, LayoutMultiColumnSet and |
| -// LayoutMultiColumnSpannerPlaceholder children |
| -// - A LayoutMultiColumnSet may not be adjacent to another LayoutMultiColumnSet; there are no |
| -// use-cases for it, and there are also implementation limitations behind this requirement. |
| -// - The flow thread is not in the containing block chain for children that are not to be laid out |
| -// in columns. This means column spanners and absolutely positioned children whose containing |
| -// block is outside column content |
| -// - Each spanner (column-span:all) establishes a LayoutMultiColumnSpannerPlaceholder |
| +// - All multicol DOM children and pseudo-elements associated with the multicol |
| +// container are reparented into the flow thread. |
| +// - The LayoutMultiColumnFlowThread is the first child of the multicol |
| +// container. |
| +// - A multicol container may only have LayoutMultiColumnFlowThread, |
| +// LayoutMultiColumnSet and LayoutMultiColumnSpannerPlaceholder children. |
| +// - A LayoutMultiColumnSet may not be adjacent to another LayoutMultiColumnSet; |
| +// there are no use-cases for it, and there are also implementation |
| +// limitations behind this requirement. |
| +// - The flow thread is not in the containing block chain for children that are |
| +// not to be laid out in columns. This means column spanners and absolutely |
| +// positioned children whose containing block is outside column content |
| +// - Each spanner (column-span:all) establishes a |
| +// LayoutMultiColumnSpannerPlaceholder |
| // |
| -// The width of the flow thread is the same as the column width. The width of a column set is the |
| -// same as the content box width of the multicol container; in other words exactly enough to hold |
| -// the number of columns to be used, stacked horizontally, plus column gaps between them. |
| +// The width of the flow thread is the same as the column width. The width of a |
| +// column set is the same as the content box width of the multicol container; in |
| +// other words exactly enough to hold the number of columns to be used, stacked |
| +// horizontally, plus column gaps between them. |
| // |
| -// Since it's the first child of the multicol container, the flow thread is laid out first, albeit |
| -// in a slightly special way, since it's not to take up any space in its ancestors. Afterwards, the |
| -// column sets are laid out. Column sets get their height from the columns that they hold. In single |
| -// column-row constrained height non-balancing cases without spanners this will simply be the same |
| -// as the content height of the multicol container itself. In most other cases we'll have to |
| -// calculate optimal column heights ourselves, though. This process is referred to as column |
| -// balancing, and then we infer the column set height from the height of the flow thread portion |
| -// occupied by each set. |
| +// Since it's the first child of the multicol container, the flow thread is laid |
| +// out first, albeit in a slightly special way, since it's not to take up any |
| +// space in its ancestors. Afterwards, the column sets are laid out. Column sets |
| +// get their height from the columns that they hold. In single column-row |
| +// constrained height non-balancing cases without spanners this will simply be |
| +// the same as the content height of the multicol container itself. In most |
| +// other cases we'll have to calculate optimal column heights ourselves, though. |
| +// This process is referred to as column balancing, and then we infer the column |
| +// set height from the height of the flow thread portion occupied by each set. |
| // |
| -// More on column balancing: the columns' height is unknown in the first layout pass when |
| -// balancing. This means that we cannot insert any implicit (soft / unforced) breaks (and pagination |
| -// struts) when laying out the contents of the flow thread. We'll just lay out everything in tall |
| -// single strip. After the initial flow thread layout pass we can determine a tentative / minimal / |
| -// initial column height. This is calculated by simply dividing the flow thread's height by the |
| -// number of specified columns. In the layout pass that follows, we can insert breaks (and |
| -// pagination struts) at column boundaries, since we now have a column height. It may very easily |
| -// turn out that the calculated height wasn't enough, though. We'll notice this at end of layout. If |
| -// we end up with too many columns (i.e. columns overflowing the multicol container), it wasn't |
| -// enough. In this case we need to increase the column heights. We'll increase them by the lowest |
| -// amount of space that could possibly affect where the breaks occur. We'll relayout (to find new |
| -// break points and the new lowest amount of space increase that could affect where they occur, in |
| -// case we need another round) until we've reached an acceptable height (where everything fits |
| -// perfectly in the number of columns that we have specified). The rule of thumb is that we |
| -// shouldn't have to perform more of such iterations than the number of columns that we have. |
| +// More on column balancing: the columns' height is unknown in the first layout |
| +// pass when balancing. This means that we cannot insert any implicit (soft / |
| +// unforced) breaks (and pagination struts) when laying out the contents of the |
| +// flow thread. We'll just lay out everything in tall single strip. After the |
| +// initial flow thread layout pass we can determine a tentative / minimal / |
| +// initial column height. This is calculated by simply dividing the flow |
| +// thread's height by the number of specified columns. In the layout pass that |
| +// follows, we can insert breaks (and pagination struts) at column boundaries, |
| +// since we now have a column height. |
| +// It may very easily turn out that the calculated height wasn't enough, though. |
| +// We'll notice this at end of layout. If we end up with too many columns (i.e. |
| +// columns overflowing the multicol container), it wasn't enough. In this case |
| +// we need to increase the column heights. We'll increase them by the lowest |
| +// amount of space that could possibly affect where the breaks occur. We'll |
| +// relayout (to find new break points and the new lowest amount of space |
| +// increase that could affect where they occur, in case we need another round) |
| +// until we've reached an acceptable height (where everything fits perfectly in |
| +// the number of columns that we have specified). The rule of thumb is that we |
| +// shouldn't have to perform more of such iterations than the number of columns |
| +// that we have. |
| // |
| -// For each layout iteration done for column balancing, the flow thread will need a deep layout if |
| -// column heights changed in the previous pass, since column height changes may affect break points |
| -// and pagination struts anywhere in the tree, and currently no way exists to do this in a more |
| -// optimized manner. |
| +// For each layout iteration done for column balancing, the flow thread will |
| +// need a deep layout if column heights changed in the previous pass, since |
| +// column height changes may affect break points and pagination struts anywhere |
| +// in the tree, and currently no way exists to do this in a more optimized |
| +// manner. |
| // |
| // There's also some documentation online: |
| -// https://sites.google.com/a/chromium.org/dev/developers/design-documents/multi-column-layout |
| +// dev/developers/design-documents/multi-column-layout |
|
pdr.
2016/10/07 02:49:40
Should this be https://www.chromium.org/developers
eae
2016/10/07 16:38:13
Yes, I tried to change it from sites.google.com to
|
| class CORE_EXPORT LayoutMultiColumnFlowThread : public LayoutFlowThread, |
| public FragmentationContext { |
| public: |
| @@ -145,42 +163,46 @@ class CORE_EXPORT LayoutMultiColumnFlowThread : public LayoutFlowThread, |
| // Return the last column set or spanner placeholder. |
| LayoutBox* lastMultiColumnBox() const { |
| LayoutBox* lastSiblingBox = multiColumnBlockFlow()->lastChildBox(); |
| - // The flow thread is the first child of the multicol container. If the flow thread is also |
| - // the last child, it means that there are no siblings; i.e. we have no column boxes. |
| + // The flow thread is the first child of the multicol container. If the flow |
| + // thread is also the last child, it means that there are no siblings; i.e. |
| + // we have no column boxes. |
| return lastSiblingBox != this ? lastSiblingBox : 0; |
| } |
| - // Find the first set inside which the specified layoutObject (which is a flowthread descendant) would be rendered. |
| + // Find the first set inside which the specified layoutObject (which is a |
| + // flowthread descendant) would be rendered. |
| LayoutMultiColumnSet* mapDescendantToColumnSet(LayoutObject*) const; |
| - // Return the spanner placeholder that belongs to the spanner in the containing block chain, if |
| - // any. This includes the layoutObject for the element that actually establishes the spanner too. |
| + // Return the spanner placeholder that belongs to the spanner in the |
| + // containing block chain, if any. This includes the layoutObject for the |
| + // element that actually establishes the spanner too. |
| LayoutMultiColumnSpannerPlaceholder* containingColumnSpannerPlaceholder( |
| const LayoutObject* descendant) const; |
| - // Populate the flow thread with what's currently its siblings. Called when a regular block |
| - // becomes a multicol container. |
| + // Populate the flow thread with what's currently its siblings. Called when a |
| + // regular block becomes a multicol container. |
| void populate(); |
| - // Empty the flow thread by moving everything to the parent. Remove all multicol specific |
| - // layoutObjects. Then destroy the flow thread. Called when a multicol container becomes a regular |
| - // block. |
| + // Empty the flow thread by moving everything to the parent. Remove all |
| + // multicol specific layoutObjects. Then destroy the flow thread. Called when |
| + // a multicol container becomes a regular block. |
| void evacuateAndDestroy(); |
| unsigned columnCount() const { return m_columnCount; } |
| - // Total height available to columns and spanners. This is the multicol container's content box |
| - // logical height, or 0 if auto. |
| + // Total height available to columns and spanners. This is the multicol |
| + // container's content box logical height, or 0 if auto. |
| LayoutUnit columnHeightAvailable() const { return m_columnHeightAvailable; } |
| void setColumnHeightAvailable(LayoutUnit available) { |
| m_columnHeightAvailable = available; |
| } |
| - // Maximum content box logical height for the multicol container. This takes CSS logical |
| - // 'height' and 'max-height' into account. LayoutUnit::max() is returned if nothing constrains |
| - // the height of the multicol container. This method only deals with used values of CSS |
| - // properties, and it does not consider enclosing fragmentation contexts -- that's something |
| - // that needs to be calculated per fragmentainer group. |
| + // Maximum content box logical height for the multicol container. This takes |
| + // CSS logical 'height' and 'max-height' into account. LayoutUnit::max() is |
| + // returned if nothing constrains the height of the multicol container. This |
| + // method only deals with used values of CSS properties, and it does not |
| + // consider enclosing fragmentation contexts -- that's something that needs to |
| + // be calculated per fragmentainer group. |
| LayoutUnit maxColumnLogicalHeight() const; |
| bool progressionIsInline() const { return m_progressionIsInline; } |
| @@ -213,23 +235,27 @@ class CORE_EXPORT LayoutMultiColumnFlowThread : public LayoutFlowThread, |
| void layoutColumns(SubtreeLayoutScope&); |
| - // Skip past a column spanner during flow thread layout. Spanners are not laid out inside the |
| - // flow thread, since the flow thread is not in a spanner's containing block chain (since the |
| - // containing block is the multicol container). |
| + // Skip past a column spanner during flow thread layout. Spanners are not laid |
| + // out inside the flow thread, since the flow thread is not in a spanner's |
| + // containing block chain (since the containing block is the multicol |
| + // container). |
| void skipColumnSpanner(LayoutBox*, LayoutUnit logicalTopInFlowThread); |
| - // Returns true if at least one column got a new height after flow thread layout (during column |
| - // set layout), in which case we need another layout pass. Column heights may change after flow |
| - // thread layout because of balancing. We may have to do multiple layout passes, depending on |
| - // how the contents is fitted to the changed column heights. In most cases, laying out again |
| - // twice or even just once will suffice. Sometimes we need more passes than that, though, but |
| - // the number of retries should not exceed the number of columns, unless we have a bug. |
| + // Returns true if at least one column got a new height after flow thread |
| + // layout (during column set layout), in which case we need another layout |
| + // pass. Column heights may change after flow thread layout because of |
| + // balancing. We may have to do multiple layout passes, depending on how the |
| + // contents is fitted to the changed column heights. In most cases, laying out |
| + // again twice or even just once will suffice. Sometimes we need more passes |
| + // than that, though, but the number of retries should not exceed the number |
| + // of columns, unless we have a bug. |
| bool columnHeightsChanged() const { return m_columnHeightsChanged; } |
| void setColumnHeightsChanged() { m_columnHeightsChanged = true; } |
| void columnRuleStyleDidChange(); |
| - // Remove the spanner placeholder and return true if the specified object is no longer a valid spanner. |
| + // Remove the spanner placeholder and return true if the specified object is |
| + // no longer a valid spanner. |
| bool removeSpannerPlaceholderIfNoLongerValid( |
| LayoutBox* spannerObjectInFlowThread); |
| @@ -240,9 +266,10 @@ class CORE_EXPORT LayoutMultiColumnFlowThread : public LayoutFlowThread, |
| return m_blockOffsetInEnclosingFragmentationContext; |
| } |
| - // If we've run out of columns in the last fragmentainer group (column row), we have to insert |
| - // another fragmentainer group in order to hold more columns. This means that we're moving to |
| - // the next outer column (in the enclosing fragmentation context). |
| + // If we've run out of columns in the last fragmentainer group (column row), |
| + // we have to insert another fragmentainer group in order to hold more |
| + // columns. This means that we're moving to the next outer column (in the |
| + // enclosing fragmentation context). |
| void appendNewFragmentainerGroupIfNeeded(LayoutUnit offsetInFlowThread, |
| PageBoundaryRule); |
| @@ -294,28 +321,32 @@ class CORE_EXPORT LayoutMultiColumnFlowThread : public LayoutFlowThread, |
| MultiColumnLayoutState multiColumnLayoutState() const override; |
| void restoreMultiColumnLayoutState(const MultiColumnLayoutState&) override; |
| - // The last set we worked on. It's not to be used as the "current set". The concept of a |
| - // "current set" is difficult, since layout may jump back and forth in the tree, due to wrong |
| - // top location estimates (due to e.g. margin collapsing), and possibly for other reasons. |
| + // The last set we worked on. It's not to be used as the "current set". The |
| + // concept of a "current set" is difficult, since layout may jump back and |
| + // forth in the tree, due to wrong top location estimates (due to e.g. margin |
| + // collapsing), and possibly for other reasons. |
| LayoutMultiColumnSet* m_lastSetWorkedOn; |
| - unsigned m_columnCount; // The used value of column-count |
| - LayoutUnit |
| - m_columnHeightAvailable; // Total height available to columns, or 0 if auto. |
| + // The used value of column-count |
| + unsigned m_columnCount; |
| + // Total height available to columns, or 0 if auto. |
| + LayoutUnit m_columnHeightAvailable; |
| - // Cached block offset from this flow thread to the enclosing fragmentation context, if any. In |
| + // Cached block offset from this flow thread to the enclosing fragmentation |
| + // context, if any. In |
| // the coordinate space of the enclosing fragmentation context. |
| LayoutUnit m_blockOffsetInEnclosingFragmentationContext; |
| - bool |
| - m_columnHeightsChanged; // Set when column heights are out of sync with actual layout. |
| - bool |
| - m_progressionIsInline; // Always true for regular multicol. False for paged-y overflow. |
| + // Set when column heights are out of sync with actual layout. |
| + bool m_columnHeightsChanged; |
| + // Always true for regular multicol. False for paged-y overflow. |
| + bool m_progressionIsInline; |
| bool m_isBeingEvacuated; |
| }; |
| -// Cannot use DEFINE_LAYOUT_OBJECT_TYPE_CASTS here, because isMultiColumnFlowThread() is defined in |
| -// LayoutFlowThread, not in LayoutObject. |
| +// Cannot use DEFINE_LAYOUT_OBJECT_TYPE_CASTS here, because |
| +// isMultiColumnFlowThread() is defined in LayoutFlowThread, not in |
| +// LayoutObject. |
| DEFINE_TYPE_CASTS(LayoutMultiColumnFlowThread, |
| LayoutFlowThread, |
| object, |