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

Side by Side Diff: Source/core/layout/LayoutMultiColumnFlowThread.cpp

Issue 1292163002: Initial support for nested multicol layout. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: code review Created 5 years, 4 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 | Annotate | Revision Log
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 10 matching lines...) Expand all
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/layout/LayoutMultiColumnFlowThread.h" 27 #include "core/layout/LayoutMultiColumnFlowThread.h"
28 28
29 #include "core/layout/LayoutMultiColumnSet.h" 29 #include "core/layout/LayoutMultiColumnSet.h"
30 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h" 30 #include "core/layout/LayoutMultiColumnSpannerPlaceholder.h"
31 #include "core/layout/MultiColumnFragmentainerGroup.h"
31 32
32 namespace blink { 33 namespace blink {
33 34
34 LayoutMultiColumnFlowThread::LayoutMultiColumnFlowThread() 35 LayoutMultiColumnFlowThread::LayoutMultiColumnFlowThread()
35 : m_lastSetWorkedOn(nullptr) 36 : m_lastSetWorkedOn(nullptr)
36 , m_columnCount(1) 37 , m_columnCount(1)
37 , m_columnHeightAvailable(0) 38 , m_columnHeightAvailable(0)
38 , m_inBalancingPass(false) 39 , m_inBalancingPass(false)
39 , m_needsColumnHeightsRecalculation(false) 40 , m_needsColumnHeightsRecalculation(false)
40 , m_progressionIsInline(true) 41 , m_progressionIsInline(true)
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 destroy(); 264 destroy();
264 } 265 }
265 266
266 LayoutSize LayoutMultiColumnFlowThread::columnOffset(const LayoutPoint& point) c onst 267 LayoutSize LayoutMultiColumnFlowThread::columnOffset(const LayoutPoint& point) c onst
267 { 268 {
268 if (!hasValidColumnSetInfo()) 269 if (!hasValidColumnSetInfo())
269 return LayoutSize(0, 0); 270 return LayoutSize(0, 0);
270 271
271 LayoutPoint flowThreadPoint = flipForWritingMode(point); 272 LayoutPoint flowThreadPoint = flipForWritingMode(point);
272 LayoutUnit blockOffset = isHorizontalWritingMode() ? flowThreadPoint.y() : f lowThreadPoint.x(); 273 LayoutUnit blockOffset = isHorizontalWritingMode() ? flowThreadPoint.y() : f lowThreadPoint.x();
273 LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(blockOffset); 274 return flowThreadTranslationAtOffset(blockOffset);
274 if (!columnSet)
275 return LayoutSize(0, 0);
276 return columnSet->flowThreadTranslationAtOffset(blockOffset);
277 } 275 }
278 276
279 bool LayoutMultiColumnFlowThread::needsNewWidth() const 277 bool LayoutMultiColumnFlowThread::needsNewWidth() const
280 { 278 {
281 LayoutUnit newWidth; 279 LayoutUnit newWidth;
282 unsigned dummyColumnCount; // We only care if used column-width changes. 280 unsigned dummyColumnCount; // We only care if used column-width changes.
283 calculateColumnCountAndWidth(newWidth, dummyColumnCount); 281 calculateColumnCountAndWidth(newWidth, dummyColumnCount);
284 return newWidth != logicalWidth(); 282 return newWidth != logicalWidth();
285 } 283 }
286 284
285 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const
286 {
287 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet())
288 return columnSet->isPageLogicalHeightKnown();
289 return false;
290 }
291
292 LayoutSize LayoutMultiColumnFlowThread::flowThreadTranslationAtOffset(LayoutUnit offsetInFlowThread) const
293 {
294 LayoutMultiColumnSet* columnSet = columnSetAtBlockOffset(offsetInFlowThread) ;
295 if (!columnSet)
296 return LayoutSize(0, 0);
297 return columnSet->flowThreadTranslationAtOffset(offsetInFlowThread);
298 }
299
287 LayoutPoint LayoutMultiColumnFlowThread::visualPointToFlowThreadPoint(const Layo utPoint& visualPoint) const 300 LayoutPoint LayoutMultiColumnFlowThread::visualPointToFlowThreadPoint(const Layo utPoint& visualPoint) const
288 { 301 {
289 LayoutUnit blockOffset = isHorizontalWritingMode() ? visualPoint.y() : visua lPoint.x(); 302 LayoutUnit blockOffset = isHorizontalWritingMode() ? visualPoint.y() : visua lPoint.x();
290 const LayoutMultiColumnSet* columnSet = nullptr; 303 const LayoutMultiColumnSet* columnSet = nullptr;
291 for (const LayoutMultiColumnSet* candidate = firstMultiColumnSet(); candidat e; candidate = candidate->nextSiblingMultiColumnSet()) { 304 for (const LayoutMultiColumnSet* candidate = firstMultiColumnSet(); candidat e; candidate = candidate->nextSiblingMultiColumnSet()) {
292 columnSet = candidate; 305 columnSet = candidate;
293 if (candidate->logicalBottom() > blockOffset) 306 if (candidate->logicalBottom() > blockOffset)
294 break; 307 break;
295 } 308 }
296 return columnSet ? columnSet->visualPointToFlowThreadPoint(toLayoutPoint(vis ualPoint + location() - columnSet->location())) : visualPoint; 309 return columnSet ? columnSet->visualPointToFlowThreadPoint(toLayoutPoint(vis ualPoint + location() - columnSet->location())) : visualPoint;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 if (!needsLayout()) { 350 if (!needsLayout()) {
338 // Just before the multicol container (our parent LayoutBlockFlow) finis hes laying out, it 351 // Just before the multicol container (our parent LayoutBlockFlow) finis hes laying out, it
339 // will call recalculateColumnHeights() on us unconditionally, but we on ly want that method 352 // will call recalculateColumnHeights() on us unconditionally, but we on ly want that method
340 // to do any work if we actually laid out the flow thread. Otherwise, th e balancing 353 // to do any work if we actually laid out the flow thread. Otherwise, th e balancing
341 // machinery would kick in needlessly, and trigger additional layout pas ses. Furthermore, we 354 // machinery would kick in needlessly, and trigger additional layout pas ses. Furthermore, we
342 // actually depend on a proper flowthread layout pass in order to do bal ancing, since it's 355 // actually depend on a proper flowthread layout pass in order to do bal ancing, since it's
343 // flowthread layout that sets up content runs. 356 // flowthread layout that sets up content runs.
344 return; 357 return;
345 } 358 }
346 359
360 m_blockOffsetInEnclosingFlowThread = enclosingFlowThread() ? multiColumnBloc kFlow()->offsetFromLogicalTopOfFirstPage() : LayoutUnit();
361
347 for (LayoutBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co lumnBox->nextSiblingMultiColumnBox()) { 362 for (LayoutBox* columnBox = firstMultiColumnBox(); columnBox; columnBox = co lumnBox->nextSiblingMultiColumnBox()) {
348 if (!columnBox->isLayoutMultiColumnSet()) { 363 if (!columnBox->isLayoutMultiColumnSet()) {
349 ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no ot her type is expected. 364 ASSERT(columnBox->isLayoutMultiColumnSpannerPlaceholder()); // no ot her type is expected.
350 m_needsColumnHeightsRecalculation = true; 365 m_needsColumnHeightsRecalculation = true;
351 continue; 366 continue;
352 } 367 }
353 LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox); 368 LayoutMultiColumnSet* columnSet = toLayoutMultiColumnSet(columnBox);
354 if (!m_inBalancingPass) { 369 if (!m_inBalancingPass) {
355 // This is the initial layout pass. We need to reset the column heig ht, because contents 370 // This is the initial layout pass. We need to reset the column heig ht, because contents
356 // typically have changed. 371 // typically have changed.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 429
415 // We may have a new containing block, since we're no longer a spanner. Mark it for relayout. 430 // We may have a new containing block, since we're no longer a spanner. Mark it for relayout.
416 spannerObjectInFlowThread->containingBlock()->setNeedsLayoutAndPrefWidthsRec alc(LayoutInvalidationReason::ColumnsChanged); 431 spannerObjectInFlowThread->containingBlock()->setNeedsLayoutAndPrefWidthsRec alc(LayoutInvalidationReason::ColumnsChanged);
417 432
418 // Now generate a column set for this ex-spanner, if needed and none is ther e for us already. 433 // Now generate a column set for this ex-spanner, if needed and none is ther e for us already.
419 flowThreadDescendantWasInserted(spannerObjectInFlowThread); 434 flowThreadDescendantWasInserted(spannerObjectInFlowThread);
420 435
421 return true; 436 return true;
422 } 437 }
423 438
439 LayoutMultiColumnFlowThread* LayoutMultiColumnFlowThread::enclosingFlowThread() const
440 {
441 if (multiColumnBlockFlow()->isInsideFlowThread())
442 return toLayoutMultiColumnFlowThread(locateFlowThreadContainingBlockOf(* multiColumnBlockFlow()));
443 return nullptr;
444 }
445
446 bool LayoutMultiColumnFlowThread::hasFragmentainerGroupForColumnAt(LayoutUnit of fsetInFlowThread) const
447 {
448 // If there's no enclosing flow thread, there'll always be only one fragment ainer group, and it
449 // can hold as many columns as we like. We shouldn't even be here in that ca se.
450 ASSERT(enclosingFlowThread());
451
452 LayoutMultiColumnSet* lastColumnSet = lastMultiColumnSet();
453 if (!lastColumnSet) {
454 ASSERT_NOT_REACHED();
455 return true;
456 }
457 if (lastColumnSet->logicalTopInFlowThread() > offsetInFlowThread)
458 return true;
459 const MultiColumnFragmentainerGroup& lastRow = lastColumnSet->lastFragmentai nerGroup();
460 if (lastRow.logicalTopInFlowThread() > offsetInFlowThread)
461 return true;
462 return offsetInFlowThread - lastRow.logicalTopInFlowThread() < lastRow.logic alHeight() * lastColumnSet->usedColumnCount();
463 }
464
465 void LayoutMultiColumnFlowThread::appendNewFragmentainerGroupIfNeeded(LayoutUnit offsetInFlowThread)
466 {
467 LayoutMultiColumnFlowThread* enclosingFlowThread = this->enclosingFlowThread ();
468 if (!enclosingFlowThread)
469 return; // Not nested. We'll never need more rows than the one we alread y have then.
470 if (!hasFragmentainerGroupForColumnAt(offsetInFlowThread)) {
471 // We have run out of columns here, so we add another row to hold more c olumns. When we add
472 // a new row, it implicitly means that we're inserting another column in our enclosing
473 // multicol container. That in turn may mean that we've run out of colum ns there too.
474 const MultiColumnFragmentainerGroup& newRow = lastMultiColumnSet()->appe ndNewFragmentainerGroup();
475 enclosingFlowThread->appendNewFragmentainerGroupIfNeeded(newRow.blockOff setInEnclosingFlowThread());
476 }
477 }
478
424 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width , unsigned& count) const 479 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width , unsigned& count) const
425 { 480 {
426 LayoutBlock* columnBlock = multiColumnBlockFlow(); 481 LayoutBlock* columnBlock = multiColumnBlockFlow();
427 const ComputedStyle* columnStyle = columnBlock->style(); 482 const ComputedStyle* columnStyle = columnBlock->style();
428 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); 483 LayoutUnit availableWidth = columnBlock->contentLogicalWidth();
429 LayoutUnit columnGap = columnBlock->columnGap(); 484 LayoutUnit columnGap = columnBlock->columnGap();
430 LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle-> columnWidth())); 485 LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle-> columnWidth()));
431 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount()); 486 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount());
432 487
433 ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidt h()); 488 ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidt h());
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 { 964 {
910 if (LayoutMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) { 965 if (LayoutMultiColumnSet* multicolSet = columnSetAtBlockOffset(offset)) {
911 multicolSet->addContentRun(offset); 966 multicolSet->addContentRun(offset);
912 if (offsetBreakAdjustment) 967 if (offsetBreakAdjustment)
913 *offsetBreakAdjustment = pageLogicalHeightForOffset(offset) ? pageRe mainingLogicalHeightForOffset(offset, AssociateWithFormerPage) : LayoutUnit(); 968 *offsetBreakAdjustment = pageLogicalHeightForOffset(offset) ? pageRe mainingLogicalHeightForOffset(offset, AssociateWithFormerPage) : LayoutUnit();
914 return true; 969 return true;
915 } 970 }
916 return false; 971 return false;
917 } 972 }
918 973
919 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const
920 {
921 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet())
922 return columnSet->isPageLogicalHeightKnown();
923 return false;
924 }
925
926 } 974 }
OLDNEW
« no previous file with comments | « Source/core/layout/LayoutMultiColumnFlowThread.h ('k') | Source/core/layout/LayoutMultiColumnSet.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698