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

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

Issue 789433006: [New Multicolumn] Let a spanner's containing block be the multicol container. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years 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
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
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * 12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS IN..0TERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 20 * PROFITS; OR BUSINESS IN..0TERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
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 #include "config.h" 26 #include "config.h"
27 #include "core/rendering/RenderMultiColumnFlowThread.h" 27 #include "core/rendering/RenderMultiColumnFlowThread.h"
28 28
29 #include "core/rendering/RenderMultiColumnSet.h" 29 #include "core/rendering/RenderMultiColumnSet.h"
30 #include "core/rendering/RenderMultiColumnSpannerSet.h" 30 #include "core/rendering/RenderMultiColumnSpannerPlaceholder.h"
31 31
32 namespace blink { 32 namespace blink {
33 33
34 RenderMultiColumnFlowThread::RenderMultiColumnFlowThread() 34 RenderMultiColumnFlowThread::RenderMultiColumnFlowThread()
35 : m_columnCount(1) 35 : m_columnCount(1)
36 , m_columnHeightAvailable(0) 36 , m_columnHeightAvailable(0)
37 , m_inBalancingPass(false) 37 , m_inBalancingPass(false)
38 , m_needsColumnHeightsRecalculation(false) 38 , m_needsColumnHeightsRecalculation(false)
39 , m_progressionIsInline(true) 39 , m_progressionIsInline(true)
40 , m_isBeingEvacuated(false)
40 { 41 {
41 setFlowThreadState(InsideInFlowThread); 42 setFlowThreadState(InsideInFlowThread);
42 } 43 }
43 44
44 RenderMultiColumnFlowThread::~RenderMultiColumnFlowThread() 45 RenderMultiColumnFlowThread::~RenderMultiColumnFlowThread()
45 { 46 {
46 } 47 }
47 48
48 RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Docume nt& document, RenderStyle* parentStyle) 49 RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Docume nt& document, RenderStyle* parentStyle)
49 { 50 {
(...skipping 14 matching lines...) Expand all
64 65
65 RenderMultiColumnSet* RenderMultiColumnFlowThread::lastMultiColumnSet() const 66 RenderMultiColumnSet* RenderMultiColumnFlowThread::lastMultiColumnSet() const
66 { 67 {
67 for (RenderObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; s ibling = sibling->previousSibling()) { 68 for (RenderObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; s ibling = sibling->previousSibling()) {
68 if (sibling->isRenderMultiColumnSet()) 69 if (sibling->isRenderMultiColumnSet())
69 return toRenderMultiColumnSet(sibling); 70 return toRenderMultiColumnSet(sibling);
70 } 71 }
71 return 0; 72 return 0;
72 } 73 }
73 74
74 RenderMultiColumnSpannerSet* RenderMultiColumnFlowThread::containingColumnSpanne rSet(const RenderObject* descendant) const 75 RenderMultiColumnSpannerPlaceholder* RenderMultiColumnFlowThread::containingColu mnSpannerPlaceholder(const RenderObject* descendant) const
75 { 76 {
76 ASSERT(descendant->isDescendantOf(this)); 77 ASSERT(descendant->isDescendantOf(this));
77 78
78 // Before we spend time on searching the ancestry, see if there's a quick wa y to determine 79 // Before we spend time on searching the ancestry, see if there's a quick wa y to determine
79 // whether there might be any spanners at all. 80 // whether there might be any spanners at all.
80 RenderMultiColumnSet* firstSet = firstMultiColumnSet(); 81 RenderBox* firstBox = firstMultiColumnBox();
81 if (!firstSet || (firstSet == lastMultiColumnSet() && !firstSet->isRenderMul tiColumnSpannerSet())) 82 if (!firstBox || (firstBox == lastMultiColumnBox() && firstBox->isRenderMult iColumnSet()))
82 return 0; 83 return 0;
83 84
84 // We have spanners. See if the renderer in question is one or inside of one then. 85 // We have spanners. See if the renderer in question is one or inside of one then.
85 for (const RenderObject* ancestor = descendant; ancestor && ancestor != this ; ancestor = ancestor->parent()) { 86 for (const RenderObject* ancestor = descendant; ancestor && ancestor != this ; ancestor = ancestor->parent()) {
86 if (RenderMultiColumnSpannerSet* spanner = m_spannerMap.get(ancestor)) 87 if (RenderMultiColumnSpannerPlaceholder* placeholder = ancestor->spanner Placeholder())
87 return spanner; 88 return placeholder;
88 } 89 }
89 return 0; 90 return 0;
90 } 91 }
91 92
92 void RenderMultiColumnFlowThread::populate() 93 void RenderMultiColumnFlowThread::populate()
93 { 94 {
94 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); 95 RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
95 ASSERT(!nextSibling()); 96 ASSERT(!nextSibling());
96 // Reparent children preceding the flow thread into the flow thread. It's mu lticol content 97 // Reparent children preceding the flow thread into the flow thread. It's mu lticol content
97 // now. At this point there's obviously nothing after the flow thread, but r enderers (column 98 // now. At this point there's obviously nothing after the flow thread, but r enderers (column
98 // sets and spanners) will be inserted there as we insert elements into the flow thread. 99 // sets and spanners) will be inserted there as we insert elements into the flow thread.
99 multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), thi s, true); 100 multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), thi s, true);
100 } 101 }
101 102
102 void RenderMultiColumnFlowThread::evacuateAndDestroy() 103 void RenderMultiColumnFlowThread::evacuateAndDestroy()
103 { 104 {
104 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); 105 RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
106 m_isBeingEvacuated = true;
105 107
106 // Remove all sets. 108 // Remove all sets and spanners.
107 while (RenderMultiColumnSet* columnSet = firstMultiColumnSet()) 109 while (RenderBox* columnBox = firstMultiColumnBox()) {
108 columnSet->destroy(); 110 ASSERT(columnBox->isAnonymous());
111 columnBox->destroy();
112 }
109 113
110 ASSERT(!previousSibling()); 114 ASSERT(!previousSibling());
111 ASSERT(!nextSibling()); 115 ASSERT(!nextSibling());
112 116
113 // Finally we can promote all flow thread's children. Before we move them to the flow thread's 117 // Finally we can promote all flow thread's children. Before we move them to the flow thread's
114 // container, we need to unregister the flow thread, so that they aren't jus t re-added again to 118 // container, we need to unregister the flow thread, so that they aren't jus t re-added again to
115 // the flow thread that we're trying to empty. 119 // the flow thread that we're trying to empty.
116 multicolContainer->resetMultiColumnFlowThread(); 120 multicolContainer->resetMultiColumnFlowThread();
117 moveAllChildrenTo(multicolContainer, true); 121 moveAllChildrenTo(multicolContainer, true);
118 122
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 // Just before the multicol container (our parent RenderBlockFlow) finis hes laying out, it 159 // Just before the multicol container (our parent RenderBlockFlow) finis hes laying out, it
156 // will call recalculateColumnHeights() on us unconditionally, but we on ly want that method 160 // will call recalculateColumnHeights() on us unconditionally, but we on ly want that method
157 // to do any work if we actually laid out the flow thread. Otherwise, th e balancing 161 // to do any work if we actually laid out the flow thread. Otherwise, th e balancing
158 // machinery would kick in needlessly, and trigger additional layout pas ses. Furthermore, we 162 // machinery would kick in needlessly, and trigger additional layout pas ses. Furthermore, we
159 // actually depend on a proper flowthread layout pass in order to do bal ancing, since it's 163 // actually depend on a proper flowthread layout pass in order to do bal ancing, since it's
160 // flowthread layout that sets up content runs. 164 // flowthread layout that sets up content runs.
161 m_needsColumnHeightsRecalculation = false; 165 m_needsColumnHeightsRecalculation = false;
162 return; 166 return;
163 } 167 }
164 168
165 for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet()) { 169 for (RenderBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co lumnBox->nextSiblingBox()) {
166 if (!m_inBalancingPass) { 170 if (columnBox->isRenderMultiColumnSet()) {
Julien - ping for review 2014/12/11 19:09:37 Should we early continue by flipping the condition
mstensho (USE GERRIT) 2014/12/11 21:01:14 Done.
167 // This is the initial layout pass. We need to reset the column heig ht, because contents 171 RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(columnBox);
168 // typically have changed. 172 if (!m_inBalancingPass) {
169 columnSet->resetColumnHeight(); 173 // This is the initial layout pass. We need to reset the column height, because contents
174 // typically have changed.
175 columnSet->resetColumnHeight();
176 }
177 } else {
178 ASSERT(columnBox->isRenderMultiColumnSpannerPlaceholder()); // no ot her type is expected.
170 } 179 }
171 } 180 }
172 181
173 invalidateRegions(); 182 invalidateRegions();
174 m_needsColumnHeightsRecalculation = heightIsAuto(); 183 m_needsColumnHeightsRecalculation = heightIsAuto();
175 layout(); 184 layout();
176 } 185 }
177 186
178 bool RenderMultiColumnFlowThread::recalculateColumnHeights() 187 bool RenderMultiColumnFlowThread::recalculateColumnHeights()
179 { 188 {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 240
232 void RenderMultiColumnFlowThread::createAndInsertMultiColumnSet() 241 void RenderMultiColumnFlowThread::createAndInsertMultiColumnSet()
233 { 242 {
234 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); 243 RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
235 RenderMultiColumnSet* newSet = RenderMultiColumnSet::createAnonymous(this, m ulticolContainer->style()); 244 RenderMultiColumnSet* newSet = RenderMultiColumnSet::createAnonymous(this, m ulticolContainer->style());
236 multicolContainer->RenderBlock::addChild(newSet); 245 multicolContainer->RenderBlock::addChild(newSet);
237 invalidateRegions(); 246 invalidateRegions();
238 247
239 // We cannot handle immediate column set siblings (and there's no need for i t, either). 248 // We cannot handle immediate column set siblings (and there's no need for i t, either).
240 // There has to be at least one spanner separating them. 249 // There has to be at least one spanner separating them.
241 ASSERT(!newSet->previousSiblingMultiColumnSet() || newSet->previousSiblingMu ltiColumnSet()->isRenderMultiColumnSpannerSet()); 250 ASSERT(!previousSiblingMultiColumnBoxOf(newSet) || !previousSiblingMultiColu mnBoxOf(newSet)->isRenderMultiColumnSet());
242 ASSERT(!newSet->nextSiblingMultiColumnSet() || newSet->nextSiblingMultiColum nSet()->isRenderMultiColumnSpannerSet()); 251 ASSERT(!nextSiblingMultiColumnBoxOf(newSet) || !nextSiblingMultiColumnBoxOf( newSet)->isRenderMultiColumnSet());
243 } 252 }
244 253
245 void RenderMultiColumnFlowThread::createAndInsertSpannerSet(RenderBox* spanner) 254 void RenderMultiColumnFlowThread::createAndInsertSpannerPlaceholder(RenderBox* s panner)
246 { 255 {
247 RenderBlockFlow* multicolContainer = multiColumnBlockFlow(); 256 RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
248 RenderMultiColumnSpannerSet* newSpannerSet = RenderMultiColumnSpannerSet::cr eateAnonymous(this, multicolContainer->style(), spanner); 257 RenderMultiColumnSpannerPlaceholder* newPlaceholder = RenderMultiColumnSpann erPlaceholder::createAnonymous(multicolContainer->style(), spanner);
249 multicolContainer->RenderBlock::addChild(newSpannerSet); 258 multicolContainer->RenderBlock::addChild(newPlaceholder);
250 m_spannerMap.add(spanner, newSpannerSet); 259 spanner->setSpannerPlaceholder(newPlaceholder);
251 invalidateRegions();
252 } 260 }
253 261
254 bool RenderMultiColumnFlowThread::descendantIsValidColumnSpanner(RenderObject* d escendant) const 262 bool RenderMultiColumnFlowThread::descendantIsValidColumnSpanner(RenderObject* d escendant) const
255 { 263 {
256 // We assume that we're inside the flow thread. This function is not to be c alled otherwise. 264 // We assume that we're inside the flow thread. This function is not to be c alled otherwise.
257 ASSERT(descendant->isDescendantOf(this)); 265 ASSERT(descendant->isDescendantOf(this));
258 266
267 // We're evaluating if the descendant should be turned into a proper spanner . It shouldn't
268 // already be one.
269 ASSERT(!descendant->spannerPlaceholder());
270
259 // The spec says that column-span only applies to in-flow block-level elemen ts. 271 // The spec says that column-span only applies to in-flow block-level elemen ts.
260 if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox () || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned()) 272 if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox () || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned())
261 return false; 273 return false;
262 274
263 if (!descendant->containingBlock()->isRenderBlockFlow()) { 275 if (!descendant->containingBlock()->isRenderBlockFlow()) {
264 // Needs to be in a block-flow container, and not e.g. a table. 276 // Needs to be in a block-flow container, and not e.g. a table.
265 return false; 277 return false;
266 } 278 }
267 279
268 // This looks like a spanner, but if we're inside something unbreakable, it' s not to be treated as one. 280 // This looks like a spanner, but if we're inside something unbreakable, it' s not to be treated as one.
269 for (RenderBlock* ancestor = descendant->containingBlock(); ancestor && ance stor->flowThreadContainingBlock() == this; ancestor = ancestor->containingBlock( )) { 281 for (RenderBlock* ancestor = descendant->containingBlock(); ancestor; ancest or = ancestor->containingBlock()) {
270 if (ancestor->isRenderFlowThread()) { 282 if (ancestor->isRenderFlowThread()) {
271 ASSERT(ancestor == this); 283 ASSERT(ancestor == this);
272 return true; 284 return true;
273 } 285 }
274 if (m_spannerMap.get(ancestor)) { 286 if (ancestor->spannerPlaceholder()) {
275 // FIXME: do we want to support nested spanners in a different way? The outer spanner 287 // FIXME: do we want to support nested spanners in a different way? The outer spanner
276 // has already broken out from the columns to become sized by the mu lticol container, 288 // has already broken out from the columns to become sized by the mu lticol container,
277 // which may be good enough for the inner spanner. But margins, bord ers, padding and 289 // which may be good enough for the inner spanner. But margins, bord ers, padding and
278 // explicit widths on the outer spanner, or on any children between the outer and inner 290 // explicit widths on the outer spanner, or on any children between the outer and inner
279 // spanner, will affect the width of the inner spanner this way, whi ch might be 291 // spanner, will affect the width of the inner spanner this way, whi ch might be
280 // undesirable. The spec has nothing to say on the matter. 292 // undesirable. The spec has nothing to say on the matter.
281 return false; // Ignore nested spanners. 293 return false; // Ignore nested spanners.
282 } 294 }
283 if (ancestor->isUnsplittableForPagination()) 295 if (ancestor->isUnsplittableForPagination())
284 return false; 296 return false;
(...skipping 14 matching lines...) Expand all
299 ASSERT(it != m_multiColumnSetList.end()); 311 ASSERT(it != m_multiColumnSetList.end());
300 m_multiColumnSetList.insertBefore(it, columnSet); 312 m_multiColumnSetList.insertBefore(it, columnSet);
301 } else { 313 } else {
302 m_multiColumnSetList.add(columnSet); 314 m_multiColumnSetList.add(columnSet);
303 } 315 }
304 columnSet->setIsValid(true); 316 columnSet->setIsValid(true);
305 } 317 }
306 318
307 void RenderMultiColumnFlowThread::willBeRemovedFromTree() 319 void RenderMultiColumnFlowThread::willBeRemovedFromTree()
308 { 320 {
309 m_spannerMap.clear();
310 // Detach all column sets from the flow thread. Cannot destroy them at this point, since they 321 // Detach all column sets from the flow thread. Cannot destroy them at this point, since they
311 // are siblings of this object, and there may be pointers to this object's s ibling somewhere 322 // are siblings of this object, and there may be pointers to this object's s ibling somewhere
312 // further up on the call stack. 323 // further up on the call stack.
313 for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet()) 324 for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet())
314 columnSet->detachRegion(); 325 columnSet->detachRegion();
315 multiColumnBlockFlow()->resetMultiColumnFlowThread(); 326 multiColumnBlockFlow()->resetMultiColumnFlowThread();
316 RenderFlowThread::willBeRemovedFromTree(); 327 RenderFlowThread::willBeRemovedFromTree();
317 } 328 }
318 329
319 void RenderMultiColumnFlowThread::flowThreadDescendantWasInserted(RenderObject* descendant) 330 void RenderMultiColumnFlowThread::flowThreadDescendantWasInserted(RenderObject* descendant)
320 { 331 {
332 ASSERT(!m_isBeingEvacuated);
321 // Go through the subtree that was just inserted and create column sets (nee ded by regular 333 // Go through the subtree that was just inserted and create column sets (nee ded by regular
322 // column content) and spanner sets (one needed by each spanner). 334 // column content) and spanner placeholders (one needed by each spanner).
323 for (RenderObject* renderer = descendant; renderer; renderer = renderer->nex tInPreOrder(descendant)) { 335 for (RenderObject* renderer = descendant; renderer; renderer = renderer->nex tInPreOrder(descendant)) {
324 if (containingColumnSpannerSet(renderer)) 336 if (containingColumnSpannerPlaceholder(renderer))
325 continue; // Inside a column spanner set. Nothing to do, then. 337 continue; // Inside a column spanner. Nothing to do, then.
326 if (descendantIsValidColumnSpanner(renderer)) { 338 if (descendantIsValidColumnSpanner(renderer)) {
327 // This renderer is a spanner, so it needs to establish a spanner se t. 339 // This renderer is a spanner, so it needs to establish a spanner pl aceholder.
328 createAndInsertSpannerSet(toRenderBox(renderer)); 340 createAndInsertSpannerPlaceholder(toRenderBox(renderer));
329 continue; 341 continue;
330 } 342 }
331 // This renderer is regular column content (i.e. not a spanner). Create a set if necessary. 343 // This renderer is regular column content (i.e. not a spanner). Create a set if necessary.
332 RenderMultiColumnSet* lastSet = lastMultiColumnSet(); 344 RenderBox* lastColumnBox = lastMultiColumnBox();
333 if (!lastSet || lastSet->isRenderMultiColumnSpannerSet()) 345 if (!lastColumnBox || !lastColumnBox->isRenderMultiColumnSet())
334 createAndInsertMultiColumnSet(); 346 createAndInsertMultiColumnSet();
335 } 347 }
336 } 348 }
337 349
350 void RenderMultiColumnFlowThread::flowThreadDescendantWillBeRemoved(RenderObject * descendant)
351 {
352 if (m_isBeingEvacuated)
353 return;
354 RenderObject* next;
355 // Remove spanner placeholders that are no longer needed, and merge column s ets around them.
356 for (RenderObject* renderer = descendant; renderer; renderer = next) {
357 RenderMultiColumnSpannerPlaceholder* placeholder = renderer->spannerPlac eholder();
358 if (!placeholder) {
359 next = renderer->nextInPreOrder(descendant);
360 continue;
361 }
362 next = renderer->nextInPreOrderAfterChildren(descendant); // It's a span ner. Its children are of no interest to us.
363 if (RenderBox* nextColumnBox = nextSiblingMultiColumnBoxOf(placeholder)) {
364 RenderBox* previousColumnBox = previousSiblingMultiColumnBoxOf(place holder);
365 if (nextColumnBox && nextColumnBox->isRenderMultiColumnSet()
366 && previousColumnBox && previousColumnBox->isRenderMultiColumnSe t()) {
367 // Need to merge two column sets.
368 nextColumnBox->destroy();
369 previousColumnBox->setNeedsLayout();
370 invalidateRegions();
371 }
372 }
373 placeholder->destroy();
374 }
375 }
376
338 void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const 377 void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
339 { 378 {
340 // We simply remain at our intrinsic height. 379 // We simply remain at our intrinsic height.
341 computedValues.m_extent = logicalHeight; 380 computedValues.m_extent = logicalHeight;
342 computedValues.m_position = logicalTop; 381 computedValues.m_position = logicalTop;
343 } 382 }
344 383
345 void RenderMultiColumnFlowThread::updateLogicalWidth() 384 void RenderMultiColumnFlowThread::updateLogicalWidth()
346 { 385 {
347 LayoutUnit columnWidth; 386 LayoutUnit columnWidth;
348 calculateColumnCountAndWidth(columnWidth, m_columnCount); 387 calculateColumnCountAndWidth(columnWidth, m_columnCount);
349 setLogicalWidth(columnWidth); 388 setLogicalWidth(columnWidth);
350 } 389 }
351 390
352 void RenderMultiColumnFlowThread::layout() 391 void RenderMultiColumnFlowThread::layout()
353 { 392 {
354 RenderFlowThread::layout(); 393 RenderFlowThread::layout();
355 if (RenderMultiColumnSet* lastSet = lastMultiColumnSet()) 394 if (RenderMultiColumnSet* lastSet = lastMultiColumnSet()) {
356 lastSet->expandToEncompassFlowThreadContentsIfNeeded(); 395 if (!nextSiblingMultiColumnBoxOf(lastSet))
396 lastSet->expandToEncompassFlowThreadContentsIfNeeded();
397 }
357 } 398 }
358 399
359 void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spa ceShortage) 400 void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spa ceShortage)
360 { 401 {
361 // Only positive values are interesting (and allowed) here. Zero space short age may be reported 402 // Only positive values are interesting (and allowed) here. Zero space short age may be reported
362 // when we're at the top of a column and the element has zero height. Ignore this, and also 403 // when we're at the top of a column and the element has zero height. Ignore this, and also
363 // ignore any negative values, which may occur when we set an early break in order to honor 404 // ignore any negative values, which may occur when we set an early break in order to honor
364 // widows in the next column. 405 // widows in the next column.
365 if (spaceShortage <= 0) 406 if (spaceShortage <= 0)
366 return; 407 return;
(...skipping 26 matching lines...) Expand all
393 } 434 }
394 435
395 bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const 436 bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const
396 { 437 {
397 if (RenderMultiColumnSet* columnSet = lastMultiColumnSet()) 438 if (RenderMultiColumnSet* columnSet = lastMultiColumnSet())
398 return columnSet->pageLogicalHeight(); 439 return columnSet->pageLogicalHeight();
399 return false; 440 return false;
400 } 441 }
401 442
402 } 443 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698