Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: third_party/WebKit/Source/core/layout/ColumnBalancer.h

Issue 1399493002: Column balancing refactoring. Don't propagate data during layout. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more code review Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/layout/MultiColumnFragmentainerGroup.h"
6
7 namespace blink {
8
9 // A column balancer traverses the portion of the subtree of a flow thread that belongs to a given
10 // fragmentainer group, in order to collect certain data to be used for column b alancing. This is an
11 // abstract class that just walks the subtree and leaves it to subclasses to act ualy collect data.
12 class ColumnBalancer {
13 protected:
14 ColumnBalancer(const MultiColumnFragmentainerGroup&);
15
16 const MultiColumnFragmentainerGroup& group() const { return m_group; }
17
18 // Flow thread offset for the layout object that we're currently examining.
19 LayoutUnit flowThreadOffset() const { return m_flowThreadOffset; }
20
21 // Return true if the specified offset is at the top of a column, as long as it's not the first
22 // column in the multicol container.
23 bool isFirstAfterBreak(LayoutUnit flowThreadOffset) const
24 {
25 if (flowThreadOffset != m_group.columnLogicalTopForOffset(flowThreadOffs et))
26 return false; // Not at the top of a column.
27 // The first column in the first group isn't after any break.
28 return flowThreadOffset > m_group.logicalTopInFlowThread() || !m_group.i sFirstGroup();
29 }
30
31 // Examine and collect column balancing data from a layout box that has been found to intersect
32 // with this fragmentainer group. Does not recurse into children. flowThread Offset() will
33 // return the offset from |box| to the flow thread. Two hooks are provided h ere. The first one
34 // is called right after entering and before traversing the subtree of the b ox, and the second
35 // one right after having traversed the subtree.
36 virtual void examineBoxAfterEntering(const LayoutBox&) = 0;
37 virtual void examineBoxBeforeLeaving(const LayoutBox&) = 0;
38
39 // Examine and collect column balancing data from a line that has been found to intersect with
40 // this fragmentainer group. Does not recurse into layout objects on that li ne.
41 virtual void examineLine(const RootInlineBox&) = 0;
42
43 // Examine and collect column balancing data for everything in the fragmenta iner group. Will
44 // trigger calls to examineBoxAfterEntering(), examineBoxBeforeLeaving() and examineLine() for
45 // interesting boxes and lines.
46 void traverse();
47
48 private:
49 void traverseSubtree(const LayoutBox&);
50
51 const MultiColumnFragmentainerGroup& m_group;
52 LayoutUnit m_flowThreadOffset;
53 };
54
55 // After an initial layout pass, we know the height of the contents of a flow th read. Based on
56 // this, we can estimate an initial minimal column height. This class will colle ct the necessary
57 // information from the layout objects to make this estimate. This estimate may be used to perform
58 // another layout iteration. If we after such a layout iteration cannot fit the contents with the
59 // given column height without creating overflowing columns, we will have to str etch the columns by
60 // some amount and lay out again. We may need to do this several times (but typi cally not more
61 // times than the number of columns that we have). The amount to stretch is prov ided by the sister
62 // of this class, named MinimumSpaceShortageFinder.
63 class InitialColumnHeightFinder final : public ColumnBalancer {
64 public:
65 static LayoutUnit initialMinimalBalancedHeight(const MultiColumnFragmentaine rGroup& group)
66 {
67 return InitialColumnHeightFinder(group).initialMinimalBalancedHeight();
68 }
69
70 private:
71 InitialColumnHeightFinder(const MultiColumnFragmentainerGroup&);
72
73 LayoutUnit initialMinimalBalancedHeight() const;
74
75 void examineBoxAfterEntering(const LayoutBox&);
76 void examineBoxBeforeLeaving(const LayoutBox&);
77 void examineLine(const RootInlineBox&);
78
79 // Add a content run, specified by its end position. A content run is append ed at every
80 // forced/explicit break and at the end of the column set. The content runs are used to
81 // determine where implicit/soft breaks will occur, in order to calculate an initial column
82 // height.
83 void addContentRun(LayoutUnit endOffsetInFlowThread);
84
85 // Return the index of the content run with the currently tallest columns, t aking all implicit
86 // breaks assumed so far into account.
87 unsigned contentRunIndexWithTallestColumns() const;
88
89 // Given the current list of content runs, make assumptions about where we n eed to insert
90 // implicit breaks (if there's room for any at all; depending on the number of explicit breaks),
91 // and store the results. This is needed in order to balance the columns.
92 void distributeImplicitBreaks();
93
94 // A run of content without explicit (forced) breaks; i.e. a flow thread por tion between two
95 // explicit breaks, between flow thread start and an explicit break, between an explicit break
96 // and flow thread end, or, in cases when there are no explicit breaks at al l: between flow
97 // thread portion start and flow thread portion end. We need to know where t he explicit breaks
98 // are, in order to figure out where the implicit breaks will end up, so tha t we get the columns
99 // properly balanced. A content run starts out as representing one single co lumn, and will
100 // represent one additional column for each implicit break "inserted" there.
101 class ContentRun {
102 public:
103 ContentRun(LayoutUnit breakOffset)
104 : m_breakOffset(breakOffset)
105 , m_assumedImplicitBreaks(0) { }
106
107 unsigned assumedImplicitBreaks() const { return m_assumedImplicitBreaks; }
108 void assumeAnotherImplicitBreak() { m_assumedImplicitBreaks++; }
109 LayoutUnit breakOffset() const { return m_breakOffset; }
110
111 // Return the column height that this content run would require, conside ring the implicit
112 // breaks assumed so far.
113 LayoutUnit columnLogicalHeight(LayoutUnit startOffset) const { return ce ilf((m_breakOffset - startOffset).toFloat() / float(m_assumedImplicitBreaks + 1) ); }
114
115 private:
116 LayoutUnit m_breakOffset; // Flow thread offset where this run ends.
117 unsigned m_assumedImplicitBreaks; // Number of implicit breaks in this r un assumed so far.
118 };
119 Vector<ContentRun, 32> m_contentRuns;
120 };
121
122 // If we have previously used InitialColumnHeightFinder to estimate an initial c olumn height, and
123 // that didn't result in tall enough columns, we need subsequent layout passes w here we increase
124 // the column height by the minimum space shortage at column breaks. This class finds the minimum
125 // space shortage after having laid out with the current column height.
126 class MinimumSpaceShortageFinder final : public ColumnBalancer {
127 public:
128 MinimumSpaceShortageFinder(const MultiColumnFragmentainerGroup&);
129
130 LayoutUnit minimumSpaceShortage() const { return m_minimumSpaceShortage; }
131 unsigned forcedBreaksCount() const { return m_forcedBreaksCount; }
132
133 private:
134 void examineBoxAfterEntering(const LayoutBox&);
135 void examineBoxBeforeLeaving(const LayoutBox&);
136 void examineLine(const RootInlineBox&);
137
138 void recordSpaceShortage(LayoutUnit shortage)
139 {
140 // Only positive values are interesting (and allowed) here. Zero space s hortage may
141 // be reported when we're at the top of a column and the element has zer o
142 // height.
143 if (shortage > 0)
144 m_minimumSpaceShortage = std::min(m_minimumSpaceShortage, shortage);
145 }
146
147 // The smallest amout of space shortage that caused a column break.
148 LayoutUnit m_minimumSpaceShortage;
149
150 // Set when breaking before a block, and we're looking for the first unbreak able descendant, in
151 // order to report correct space shortage for that one.
152 LayoutUnit m_pendingStrut;
153
154 unsigned m_forcedBreaksCount;
155 };
156
157 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/core.gypi ('k') | third_party/WebKit/Source/core/layout/ColumnBalancer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698