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

Side by Side Diff: Source/core/rendering/RenderMultiColumnSet.cpp

Issue 267373005: [New Multicolumn] Use the term "content run" in favor of "forced break". (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 7 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
« no previous file with comments | « Source/core/rendering/RenderMultiColumnSet.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 m_computedColumnHeight = newHeight; 94 m_computedColumnHeight = newHeight;
95 if (m_computedColumnHeight > m_maxColumnHeight) 95 if (m_computedColumnHeight > m_maxColumnHeight)
96 m_computedColumnHeight = m_maxColumnHeight; 96 m_computedColumnHeight = m_maxColumnHeight;
97 // FIXME: the height may also be affected by the enclosing pagination contex t, if any. 97 // FIXME: the height may also be affected by the enclosing pagination contex t, if any.
98 } 98 }
99 99
100 unsigned RenderMultiColumnSet::findRunWithTallestColumns() const 100 unsigned RenderMultiColumnSet::findRunWithTallestColumns() const
101 { 101 {
102 unsigned indexWithLargestHeight = 0; 102 unsigned indexWithLargestHeight = 0;
103 LayoutUnit largestHeight; 103 LayoutUnit largestHeight;
104 LayoutUnit previousOffset; 104 LayoutUnit previousOffset = logicalTopInFlowThread();
105 size_t runCount = m_contentRuns.size(); 105 size_t runCount = m_contentRuns.size();
106 ASSERT(runCount); 106 ASSERT(runCount);
107 for (size_t i = 0; i < runCount; i++) { 107 for (size_t i = 0; i < runCount; i++) {
108 const ContentRun& run = m_contentRuns[i]; 108 const ContentRun& run = m_contentRuns[i];
109 LayoutUnit height = run.columnLogicalHeight(previousOffset); 109 LayoutUnit height = run.columnLogicalHeight(previousOffset);
110 if (largestHeight < height) { 110 if (largestHeight < height) {
111 largestHeight = height; 111 largestHeight = height;
112 indexWithLargestHeight = i; 112 indexWithLargestHeight = i;
113 } 113 }
114 previousOffset = run.breakOffset(); 114 previousOffset = run.breakOffset();
115 } 115 }
116 return indexWithLargestHeight; 116 return indexWithLargestHeight;
117 } 117 }
118 118
119 void RenderMultiColumnSet::distributeImplicitBreaks() 119 void RenderMultiColumnSet::distributeImplicitBreaks()
120 { 120 {
121 #ifndef NDEBUG 121 #ifndef NDEBUG
122 // There should be no implicit breaks assumed at this point. 122 // There should be no implicit breaks assumed at this point.
123 for (unsigned i = 0; i < forcedBreaksCount(); i++) 123 for (unsigned i = 0; i < m_contentRuns.size(); i++)
124 ASSERT(!m_contentRuns[i].assumedImplicitBreaks()); 124 ASSERT(!m_contentRuns[i].assumedImplicitBreaks());
125 #endif // NDEBUG 125 #endif // NDEBUG
126 126
127 // Insert a final content run to encompass all content. This will include ov erflow if this is 127 // Insert a final content run to encompass all content. This will include ov erflow if this is
128 // the last set. 128 // the last set.
129 addForcedBreak(logicalBottomInFlowThread()); 129 addContentRun(logicalBottomInFlowThread());
130 unsigned breakCount = forcedBreaksCount(); 130 unsigned columnCount = m_contentRuns.size();
131 131
132 // If there is room for more breaks (to reach the used value of column-count ), imagine that we 132 // If there is room for more breaks (to reach the used value of column-count ), imagine that we
133 // insert implicit breaks at suitable locations. At any given time, the cont ent run with the 133 // insert implicit breaks at suitable locations. At any given time, the cont ent run with the
134 // currently tallest columns will get another implicit break "inserted", whi ch will increase its 134 // currently tallest columns will get another implicit break "inserted", whi ch will increase its
135 // column count by one and shrink its columns' height. Repeat until we have the desired total 135 // column count by one and shrink its columns' height. Repeat until we have the desired total
136 // number of breaks. The largest column height among the runs will then be t he initial column 136 // number of breaks. The largest column height among the runs will then be t he initial column
137 // height for the balancer to use. 137 // height for the balancer to use.
138 while (breakCount < m_computedColumnCount) { 138 while (columnCount < m_computedColumnCount) {
139 unsigned index = findRunWithTallestColumns(); 139 unsigned index = findRunWithTallestColumns();
140 m_contentRuns[index].assumeAnotherImplicitBreak(); 140 m_contentRuns[index].assumeAnotherImplicitBreak();
141 breakCount++; 141 columnCount++;
142 } 142 }
143 } 143 }
144 144
145 LayoutUnit RenderMultiColumnSet::calculateColumnHeight(bool initial) const 145 LayoutUnit RenderMultiColumnSet::calculateColumnHeight(bool initial) const
146 { 146 {
147 if (initial) { 147 if (initial) {
148 // Start with the lowest imaginable column height. 148 // Start with the lowest imaginable column height. We use the tallest co ntent run (after
149 // having "inserted" implicit breaks), and find its start offset (by loo king at the previous
150 // run's end offset, or, if there's no previous run, the set's start off set in the flow
151 // thread).
149 unsigned index = findRunWithTallestColumns(); 152 unsigned index = findRunWithTallestColumns();
150 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffse t() : LayoutUnit(); 153 LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffse t() : logicalTopInFlowThread();
151 return std::max<LayoutUnit>(m_contentRuns[index].columnLogicalHeight(sta rtOffset), m_minimumColumnHeight); 154 return std::max<LayoutUnit>(m_contentRuns[index].columnLogicalHeight(sta rtOffset), m_minimumColumnHeight);
152 } 155 }
153 156
154 if (columnCount() <= computedColumnCount()) { 157 if (columnCount() <= computedColumnCount()) {
155 // With the current column height, the content fits without creating ove rflowing columns. We're done. 158 // With the current column height, the content fits without creating ove rflowing columns. We're done.
156 return m_computedColumnHeight; 159 return m_computedColumnHeight;
157 } 160 }
158 161
159 if (forcedBreaksCount() >= computedColumnCount()) { 162 if (m_contentRuns.size() >= computedColumnCount()) {
160 // Too many forced breaks to allow any implicit breaks. Initial balancin g should already 163 // Too many forced breaks to allow any implicit breaks. Initial balancin g should already
161 // have set a good height. There's nothing more we should do. 164 // have set a good height. There's nothing more we should do.
162 return m_computedColumnHeight; 165 return m_computedColumnHeight;
163 } 166 }
164 167
165 // If the initial guessed column height wasn't enough, stretch it now. Stret ch by the lowest 168 // If the initial guessed column height wasn't enough, stretch it now. Stret ch by the lowest
166 // amount of space shortage found during layout. 169 // amount of space shortage found during layout.
167 170
168 ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height! 171 ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height!
169 ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If th is happens, we probably have a bug. 172 ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If th is happens, we probably have a bug.
170 if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight()) 173 if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight())
171 return m_computedColumnHeight; // So bail out rather than looping infini tely. 174 return m_computedColumnHeight; // So bail out rather than looping infini tely.
172 175
173 return m_computedColumnHeight + m_minSpaceShortage; 176 return m_computedColumnHeight + m_minSpaceShortage;
174 } 177 }
175 178
176 void RenderMultiColumnSet::clearForcedBreaks() 179 void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage)
177 {
178 m_contentRuns.clear();
179 }
180
181 void RenderMultiColumnSet::addForcedBreak(LayoutUnit offsetFromFirstPage)
182 { 180 {
183 if (!multiColumnFlowThread()->requiresBalancing()) 181 if (!multiColumnFlowThread()->requiresBalancing())
184 return; 182 return;
185 if (!m_contentRuns.isEmpty() && offsetFromFirstPage <= m_contentRuns.last(). breakOffset()) 183 if (!m_contentRuns.isEmpty() && endOffsetFromFirstPage <= m_contentRuns.last ().breakOffset())
186 return; 184 return;
187 // Append another item as long as we haven't exceeded used column count. Wha t ends up in the 185 // Append another item as long as we haven't exceeded used column count. Wha t ends up in the
188 // overflow area shouldn't affect column balancing. 186 // overflow area shouldn't affect column balancing.
189 if (m_contentRuns.size() < m_computedColumnCount) 187 if (m_contentRuns.size() < m_computedColumnCount)
190 m_contentRuns.append(ContentRun(offsetFromFirstPage)); 188 m_contentRuns.append(ContentRun(endOffsetFromFirstPage));
191 } 189 }
192 190
193 bool RenderMultiColumnSet::recalculateColumnHeight(bool initial) 191 bool RenderMultiColumnSet::recalculateColumnHeight(bool initial)
194 { 192 {
195 ASSERT(multiColumnFlowThread()->requiresBalancing()); 193 ASSERT(multiColumnFlowThread()->requiresBalancing());
196 194
197 LayoutUnit oldColumnHeight = m_computedColumnHeight; 195 LayoutUnit oldColumnHeight = m_computedColumnHeight;
198 if (initial) 196 if (initial) {
197 // Post-process the content runs and find out where the implicit breaks will occur.
199 distributeImplicitBreaks(); 198 distributeImplicitBreaks();
199 }
200 LayoutUnit newColumnHeight = calculateColumnHeight(initial); 200 LayoutUnit newColumnHeight = calculateColumnHeight(initial);
201 setAndConstrainColumnHeight(newColumnHeight); 201 setAndConstrainColumnHeight(newColumnHeight);
202 202
203 // After having calculated an initial column height, the multicol container typically needs at 203 // After having calculated an initial column height, the multicol container typically needs at
204 // least one more layout pass with a new column height, but if a height was specified, we only 204 // least one more layout pass with a new column height, but if a height was specified, we only
205 // need to do this if we think that we need less space than specified. Conve rsely, if we 205 // need to do this if we think that we need less space than specified. Conve rsely, if we
206 // determined that the columns need to be as tall as the specified height of the container, we 206 // determined that the columns need to be as tall as the specified height of the container, we
207 // have already laid it out correctly, and there's no need for another pass. 207 // have already laid it out correctly, and there's no need for another pass.
208 208
209 if (m_computedColumnHeight == oldColumnHeight) 209 if (m_computedColumnHeight == oldColumnHeight)
210 return false; // No change. We're done. 210 return false; // No change. We're done.
211 211
212 m_minSpaceShortage = RenderFlowThread::maxLogicalHeight(); 212 m_minSpaceShortage = RenderFlowThread::maxLogicalHeight();
213 clearForcedBreaks(); 213 m_contentRuns.clear();
214 return true; // Need another pass. 214 return true; // Need another pass.
215 } 215 }
216 216
217 void RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage) 217 void RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage)
218 { 218 {
219 if (spaceShortage >= m_minSpaceShortage) 219 if (spaceShortage >= m_minSpaceShortage)
220 return; 220 return;
221 221
222 // The space shortage is what we use as our stretch amount. We need a positi ve number here in 222 // The space shortage is what we use as our stretch amount. We need a positi ve number here in
223 // order to get anywhere. 223 // order to get anywhere.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHe ight(multicolStyle->logicalMaxHeight(), -1); 272 LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHe ight(multicolStyle->logicalMaxHeight(), -1);
273 if (logicalMaxHeight != -1 && m_maxColumnHeight > logicalMaxHeight) 273 if (logicalMaxHeight != -1 && m_maxColumnHeight > logicalMaxHeight)
274 m_maxColumnHeight = logicalMaxHeight; 274 m_maxColumnHeight = logicalMaxHeight;
275 } 275 }
276 m_maxColumnHeight = heightAdjustedForSetOffset(m_maxColumnHeight); 276 m_maxColumnHeight = heightAdjustedForSetOffset(m_maxColumnHeight);
277 m_computedColumnHeight = 0; // Restart balancing. 277 m_computedColumnHeight = 0; // Restart balancing.
278 } else { 278 } else {
279 setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowTh read()->columnHeightAvailable())); 279 setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowTh read()->columnHeightAvailable()));
280 } 280 }
281 281
282 clearForcedBreaks(); 282 m_contentRuns.clear();
283 283
284 // Nuke previously stored minimum column height. Contents may have changed f or all we know. 284 // Nuke previously stored minimum column height. Contents may have changed f or all we know.
285 m_minimumColumnHeight = 0; 285 m_minimumColumnHeight = 0;
286 } 286 }
287 287
288 void RenderMultiColumnSet::expandToEncompassFlowThreadContentsIfNeeded() 288 void RenderMultiColumnSet::expandToEncompassFlowThreadContentsIfNeeded()
289 { 289 {
290 ASSERT(multiColumnFlowThread()->lastMultiColumnSet() == this); 290 ASSERT(multiColumnFlowThread()->lastMultiColumnSet() == this);
291 LayoutRect rect(flowThreadPortionRect()); 291 LayoutRect rect(flowThreadPortionRect());
292 292
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 fragments.append(fragment); 620 fragments.append(fragment);
621 } 621 }
622 } 622 }
623 623
624 const char* RenderMultiColumnSet::renderName() const 624 const char* RenderMultiColumnSet::renderName() const
625 { 625 {
626 return "RenderMultiColumnSet"; 626 return "RenderMultiColumnSet";
627 } 627 }
628 628
629 } 629 }
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderMultiColumnSet.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698