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

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

Issue 792803002: [New Multicolumn] Layout support for column-span:all. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@347325-placeholder
Patch Set: Code review. If there are no sets, return early. Created 5 years, 11 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
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 14 matching lines...) Expand all
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/RenderMultiColumnSpannerPlaceholder.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_lastSetWorkedOn(0)
36 , m_columnCount(1)
36 , m_columnHeightAvailable(0) 37 , m_columnHeightAvailable(0)
37 , m_inBalancingPass(false) 38 , m_inBalancingPass(false)
38 , m_needsColumnHeightsRecalculation(false) 39 , m_needsColumnHeightsRecalculation(false)
39 , m_progressionIsInline(true) 40 , m_progressionIsInline(true)
40 , m_isBeingEvacuated(false) 41 , m_isBeingEvacuated(false)
41 { 42 {
42 setFlowThreadState(InsideInFlowThread); 43 setFlowThreadState(InsideInFlowThread);
43 } 44 }
44 45
45 RenderMultiColumnFlowThread::~RenderMultiColumnFlowThread() 46 RenderMultiColumnFlowThread::~RenderMultiColumnFlowThread()
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 } 144 }
144 145
145 bool RenderMultiColumnFlowThread::needsNewWidth() const 146 bool RenderMultiColumnFlowThread::needsNewWidth() const
146 { 147 {
147 LayoutUnit newWidth; 148 LayoutUnit newWidth;
148 unsigned dummyColumnCount; // We only care if used column-width changes. 149 unsigned dummyColumnCount; // We only care if used column-width changes.
149 calculateColumnCountAndWidth(newWidth, dummyColumnCount); 150 calculateColumnCountAndWidth(newWidth, dummyColumnCount);
150 return newWidth != logicalWidth(); 151 return newWidth != logicalWidth();
151 } 152 }
152 153
154 RenderMultiColumnSet* RenderMultiColumnFlowThread::columnSetAtBlockOffset(Layout Unit offset) const
155 {
156 if (m_lastSetWorkedOn) {
157 // Layout in progress. We are calculating the set heights as we speak, s o the column set range
158 // information is not up-to-date.
159 return m_lastSetWorkedOn;
160 }
161
162 ASSERT(!m_regionsInvalidated);
163 if (m_multiColumnSetList.isEmpty())
164 return 0;
165 if (offset <= 0)
166 return m_multiColumnSetList.first();
167
168 MultiColumnSetSearchAdapter adapter(offset);
169 m_multiColumnSetIntervalTree.allOverlapsWithAdapter<MultiColumnSetSearchAdap ter>(adapter);
170
171 // If no set was found, the offset is in the flow thread overflow.
172 if (!adapter.result() && !m_multiColumnSetList.isEmpty())
173 return m_multiColumnSetList.last();
174 return adapter.result();
175 }
176
153 void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa youtScope& layoutScope) 177 void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLa youtScope& layoutScope)
154 { 178 {
155 if (relayoutChildren) 179 if (relayoutChildren)
156 layoutScope.setChildNeedsLayout(this); 180 layoutScope.setChildNeedsLayout(this);
157 181
182 m_needsColumnHeightsRecalculation = false;
158 if (!needsLayout()) { 183 if (!needsLayout()) {
159 // Just before the multicol container (our parent RenderBlockFlow) finis hes laying out, it 184 // Just before the multicol container (our parent RenderBlockFlow) finis hes laying out, it
160 // will call recalculateColumnHeights() on us unconditionally, but we on ly want that method 185 // will call recalculateColumnHeights() on us unconditionally, but we on ly want that method
161 // to do any work if we actually laid out the flow thread. Otherwise, th e balancing 186 // to do any work if we actually laid out the flow thread. Otherwise, th e balancing
162 // machinery would kick in needlessly, and trigger additional layout pas ses. Furthermore, we 187 // machinery would kick in needlessly, and trigger additional layout pas ses. Furthermore, we
163 // actually depend on a proper flowthread layout pass in order to do bal ancing, since it's 188 // actually depend on a proper flowthread layout pass in order to do bal ancing, since it's
164 // flowthread layout that sets up content runs. 189 // flowthread layout that sets up content runs.
165 m_needsColumnHeightsRecalculation = false;
166 return; 190 return;
167 } 191 }
168 192
169 for (RenderBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co lumnBox->nextSiblingBox()) { 193 for (RenderBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co lumnBox->nextSiblingMultiColumnBox()) {
170 if (!columnBox->isRenderMultiColumnSet()) { 194 if (!columnBox->isRenderMultiColumnSet()) {
171 ASSERT(columnBox->isRenderMultiColumnSpannerPlaceholder()); // no ot her type is expected. 195 ASSERT(columnBox->isRenderMultiColumnSpannerPlaceholder()); // no ot her type is expected.
196 m_needsColumnHeightsRecalculation = true;
172 continue; 197 continue;
173 } 198 }
174 RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(columnBox); 199 RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(columnBox);
175 if (!m_inBalancingPass) { 200 if (!m_inBalancingPass) {
176 // This is the initial layout pass. We need to reset the column heig ht, because contents 201 // This is the initial layout pass. We need to reset the column heig ht, because contents
177 // typically have changed. 202 // typically have changed.
178 columnSet->resetColumnHeight(); 203 columnSet->resetColumnHeight();
179 } 204 }
205 if (!m_needsColumnHeightsRecalculation)
206 m_needsColumnHeightsRecalculation = columnSet->heightIsAuto();
180 } 207 }
181 208
182 invalidateRegions(); 209 invalidateRegions();
183 m_needsColumnHeightsRecalculation = heightIsAuto();
184 layout(); 210 layout();
185 } 211 }
186 212
187 bool RenderMultiColumnFlowThread::recalculateColumnHeights() 213 bool RenderMultiColumnFlowThread::recalculateColumnHeights()
188 { 214 {
189 // All column sets that needed layout have now been laid out, so we can fina lly validate them. 215 // All column sets that needed layout have now been laid out, so we can fina lly validate them.
190 validateRegions(); 216 validateRegions();
191 217
192 if (!m_needsColumnHeightsRecalculation) 218 if (!m_needsColumnHeightsRecalculation)
193 return false; 219 return false;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 { 346 {
321 // Detach all column sets from the flow thread. Cannot destroy them at this point, since they 347 // Detach all column sets from the flow thread. Cannot destroy them at this point, since they
322 // are siblings of this object, and there may be pointers to this object's s ibling somewhere 348 // are siblings of this object, and there may be pointers to this object's s ibling somewhere
323 // further up on the call stack. 349 // further up on the call stack.
324 for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet()) 350 for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet())
325 columnSet->detachRegion(); 351 columnSet->detachRegion();
326 multiColumnBlockFlow()->resetMultiColumnFlowThread(); 352 multiColumnBlockFlow()->resetMultiColumnFlowThread();
327 RenderFlowThread::willBeRemovedFromTree(); 353 RenderFlowThread::willBeRemovedFromTree();
328 } 354 }
329 355
356 LayoutUnit RenderMultiColumnFlowThread::skipColumnSpanner(RenderBox* renderer, L ayoutUnit logicalTopInFlowThread)
357 {
358 ASSERT(renderer->isColumnSpanAll());
359 RenderMultiColumnSpannerPlaceholder* placeholder = renderer->spannerPlacehol der();
360 LayoutUnit adjustment;
361 RenderBox* previousColumnBox = placeholder->previousSiblingMultiColumnBox();
362 if (previousColumnBox && previousColumnBox->isRenderMultiColumnSet()) {
363 // Pad flow thread offset to a column boundary, so that any column conte nt that's supposed
364 // to come after the spanner doesn't bleed into the column row preceding the spanner.
365 RenderMultiColumnSet* previousSet = toRenderMultiColumnSet(previousColum nBox);
366 if (previousSet->pageLogicalHeight()) {
367 LayoutUnit columnLogicalTopInFlowThread = previousSet->pageLogicalTo pForOffset(logicalTopInFlowThread);
368 if (columnLogicalTopInFlowThread != logicalTopInFlowThread) {
369 adjustment = columnLogicalTopInFlowThread + previousSet->pageLog icalHeight() - logicalTopInFlowThread;
370 logicalTopInFlowThread += adjustment;
371 }
372 }
373 previousSet->endFlow(logicalTopInFlowThread);
374 }
375 RenderBox* nextColumnBox = placeholder->nextSiblingMultiColumnBox();
376 if (nextColumnBox && nextColumnBox->isRenderMultiColumnSet()) {
377 RenderMultiColumnSet* nextSet = toRenderMultiColumnSet(nextColumnBox);
378 m_lastSetWorkedOn = nextSet;
379 nextSet->beginFlow(logicalTopInFlowThread);
380 }
381 return adjustment;
382 }
383
330 void RenderMultiColumnFlowThread::flowThreadDescendantWasInserted(RenderObject* descendant) 384 void RenderMultiColumnFlowThread::flowThreadDescendantWasInserted(RenderObject* descendant)
331 { 385 {
332 ASSERT(!m_isBeingEvacuated); 386 ASSERT(!m_isBeingEvacuated);
333 // Go through the subtree that was just inserted and create column sets (nee ded by regular 387 // Go through the subtree that was just inserted and create column sets (nee ded by regular
334 // column content) and spanner placeholders (one needed by each spanner). 388 // column content) and spanner placeholders (one needed by each spanner).
335 for (RenderObject* renderer = descendant; renderer; renderer = renderer->nex tInPreOrder(descendant)) { 389 for (RenderObject* renderer = descendant; renderer; renderer = renderer->nex tInPreOrder(descendant)) {
336 if (containingColumnSpannerPlaceholder(renderer)) 390 if (containingColumnSpannerPlaceholder(renderer))
337 continue; // Inside a column spanner. Nothing to do, then. 391 continue; // Inside a column spanner. Nothing to do, then.
338 if (descendantIsValidColumnSpanner(renderer)) { 392 if (descendantIsValidColumnSpanner(renderer)) {
339 // This renderer is a spanner, so it needs to establish a spanner pl aceholder. 393 // This renderer is a spanner, so it needs to establish a spanner pl aceholder.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 437
384 void RenderMultiColumnFlowThread::updateLogicalWidth() 438 void RenderMultiColumnFlowThread::updateLogicalWidth()
385 { 439 {
386 LayoutUnit columnWidth; 440 LayoutUnit columnWidth;
387 calculateColumnCountAndWidth(columnWidth, m_columnCount); 441 calculateColumnCountAndWidth(columnWidth, m_columnCount);
388 setLogicalWidth(columnWidth); 442 setLogicalWidth(columnWidth);
389 } 443 }
390 444
391 void RenderMultiColumnFlowThread::layout() 445 void RenderMultiColumnFlowThread::layout()
392 { 446 {
447 ASSERT(!m_lastSetWorkedOn);
448 m_lastSetWorkedOn = firstMultiColumnSet();
449 if (m_lastSetWorkedOn)
450 m_lastSetWorkedOn->beginFlow(LayoutUnit());
393 RenderFlowThread::layout(); 451 RenderFlowThread::layout();
394 if (RenderMultiColumnSet* lastSet = lastMultiColumnSet()) { 452 if (RenderMultiColumnSet* lastSet = lastMultiColumnSet()) {
395 if (!lastSet->nextSiblingMultiColumnBox()) 453 ASSERT(lastSet == m_lastSetWorkedOn);
454 if (!lastSet->nextSiblingMultiColumnBox()) {
455 lastSet->endFlow(logicalHeight());
396 lastSet->expandToEncompassFlowThreadContentsIfNeeded(); 456 lastSet->expandToEncompassFlowThreadContentsIfNeeded();
457 }
397 } 458 }
459 m_lastSetWorkedOn = 0;
398 } 460 }
399 461
400 void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spa ceShortage) 462 void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spa ceShortage)
401 { 463 {
402 // Only positive values are interesting (and allowed) here. Zero space short age may be reported 464 // Only positive values are interesting (and allowed) here. Zero space short age may be reported
403 // when we're at the top of a column and the element has zero height. Ignore this, and also 465 // when we're at the top of a column and the element has zero height. Ignore this, and also
404 // ignore any negative values, which may occur when we set an early break in order to honor 466 // ignore any negative values, which may occur when we set an early break in order to honor
405 // widows in the next column. 467 // widows in the next column.
406 if (spaceShortage <= 0) 468 if (spaceShortage <= 0)
407 return; 469 return;
408 470
409 if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) 471 if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset))
410 multicolSet->recordSpaceShortage(spaceShortage); 472 multicolSet->recordSpaceShortage(spaceShortage);
411 } 473 }
412 474
413 void RenderMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, Lay outUnit minHeight) 475 void RenderMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, Lay outUnit minHeight)
414 { 476 {
415 if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) 477 if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset))
416 multicolSet->updateMinimumColumnHeight(minHeight); 478 multicolSet->updateMinimumColumnHeight(minHeight);
417 } 479 }
418 480
419 RenderMultiColumnSet* RenderMultiColumnFlowThread::columnSetAtBlockOffset(Layout Unit /*offset*/) const
420 {
421 // For now there's only one column set, so this is easy:
422 return firstMultiColumnSet();
423 }
424
425 bool RenderMultiColumnFlowThread::addForcedRegionBreak(LayoutUnit offset, Render Object* /*breakChild*/, bool /*isBefore*/, LayoutUnit* offsetBreakAdjustment) 481 bool RenderMultiColumnFlowThread::addForcedRegionBreak(LayoutUnit offset, Render Object* /*breakChild*/, bool /*isBefore*/, LayoutUnit* offsetBreakAdjustment)
426 { 482 {
427 if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) { 483 if (RenderMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) {
428 multicolSet->addContentRun(offset); 484 multicolSet->addContentRun(offset);
429 if (offsetBreakAdjustment) 485 if (offsetBreakAdjustment)
430 *offsetBreakAdjustment = pageLogicalHeightForOffset(offset) ? pageRe mainingLogicalHeightForOffset(offset, IncludePageBoundary) : LayoutUnit(); 486 *offsetBreakAdjustment = pageLogicalHeightForOffset(offset) ? pageRe mainingLogicalHeightForOffset(offset, IncludePageBoundary) : LayoutUnit();
431 return true; 487 return true;
432 } 488 }
433 return false; 489 return false;
434 } 490 }
435 491
436 bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const 492 bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const
437 { 493 {
438 if (RenderMultiColumnSet* columnSet = lastMultiColumnSet()) 494 if (RenderMultiColumnSet* columnSet = lastMultiColumnSet())
439 return columnSet->pageLogicalHeight(); 495 return columnSet->pageLogicalHeight();
440 return false; 496 return false;
441 } 497 }
442 498
443 } 499 }
OLDNEW
« no previous file with comments | « Source/core/rendering/RenderMultiColumnFlowThread.h ('k') | Source/core/rendering/RenderMultiColumnFlowThreadTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698