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

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

Issue 1162253006: An object may become a column spanner or cease to be one even if column-span doesn't change. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 6 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 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 m_inBalancingPass = needsRelayout; 354 m_inBalancingPass = needsRelayout;
355 return needsRelayout; 355 return needsRelayout;
356 } 356 }
357 357
358 void LayoutMultiColumnFlowThread::columnRuleStyleDidChange() 358 void LayoutMultiColumnFlowThread::columnRuleStyleDidChange()
359 { 359 {
360 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet()) 360 for (LayoutMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; col umnSet = columnSet->nextSiblingMultiColumnSet())
361 columnSet->setShouldDoFullPaintInvalidation(PaintInvalidationStyleChange ); 361 columnSet->setShouldDoFullPaintInvalidation(PaintInvalidationStyleChange );
362 } 362 }
363 363
364 bool LayoutMultiColumnFlowThread::removeSpannerPlaceholderIfNoLongerValid(Layout Box* spannerObjectInFlowThread)
365 {
366 ASSERT(spannerObjectInFlowThread->spannerPlaceholder());
367 if (descendantIsValidColumnSpanner(spannerObjectInFlowThread))
368 return false; // Still a valid spanner.
369
370 // No longer a valid spanner. Get rid of the placeholder.
371 destroySpannerPlaceholder(spannerObjectInFlowThread->spannerPlaceholder());
372 ASSERT(!spannerObjectInFlowThread->spannerPlaceholder());
373
374 // We may have a new containing block, since we're no longer a spanner. Mark it for relayout.
375 spannerObjectInFlowThread->containingBlock()->setNeedsLayoutAndPrefWidthsRec alc(LayoutInvalidationReason::ColumnsChanged);
376
377 // Now generate a column set for this ex-spanner, if needed and none is ther e for us already.
378 flowThreadDescendantWasInserted(spannerObjectInFlowThread);
379
380 return true;
381 }
382
364 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width , unsigned& count) const 383 void LayoutMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width , unsigned& count) const
365 { 384 {
366 LayoutBlock* columnBlock = multiColumnBlockFlow(); 385 LayoutBlock* columnBlock = multiColumnBlockFlow();
367 const ComputedStyle* columnStyle = columnBlock->style(); 386 const ComputedStyle* columnStyle = columnBlock->style();
368 LayoutUnit availableWidth = columnBlock->contentLogicalWidth(); 387 LayoutUnit availableWidth = columnBlock->contentLogicalWidth();
369 LayoutUnit columnGap = columnBlock->columnGap(); 388 LayoutUnit columnGap = columnBlock->columnGap();
370 LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle-> columnWidth())); 389 LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle-> columnWidth()));
371 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount()); 390 unsigned computedColumnCount = max<int>(1, columnStyle->columnCount());
372 391
373 ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidt h()); 392 ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidt h());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 nextColumnBox->destroy(); 470 nextColumnBox->destroy();
452 previousColumnBox->setNeedsLayout(LayoutInvalidationReason::ColumnsC hanged); 471 previousColumnBox->setNeedsLayout(LayoutInvalidationReason::ColumnsC hanged);
453 invalidateColumnSets(); 472 invalidateColumnSets();
454 } 473 }
455 } 474 }
456 placeholder->destroy(); 475 placeholder->destroy();
457 } 476 }
458 477
459 bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d escendant) const 478 bool LayoutMultiColumnFlowThread::descendantIsValidColumnSpanner(LayoutObject* d escendant) const
460 { 479 {
480 // This method needs to behave correctly in the following situations:
481 // - When the descendant doesn't have a spanner placeholder but should have one (return true)
482 // - When the descendant doesn't have a spanner placeholder and still should not have one (return false)
483 // - When the descendant has a spanner placeholder but should no longer have one (return false)
484 // - When the descendant has a spanner placeholder and should still have one (return true)
485
461 // We assume that we're inside the flow thread. This function is not to be c alled otherwise. 486 // We assume that we're inside the flow thread. This function is not to be c alled otherwise.
462 ASSERT(descendant->isDescendantOf(this)); 487 ASSERT(descendant->isDescendantOf(this));
463 488
464 // We're evaluating if the descendant should be turned into a proper spanner . It shouldn't
465 // already be one.
466 ASSERT(!descendant->spannerPlaceholder());
467
468 // The spec says that column-span only applies to in-flow block-level elemen ts. 489 // The spec says that column-span only applies to in-flow block-level elemen ts.
469 if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox () || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned()) 490 if (descendant->style()->columnSpan() != ColumnSpanAll || !descendant->isBox () || descendant->isInline() || descendant->isFloatingOrOutOfFlowPositioned())
470 return false; 491 return false;
471 492
472 if (!descendant->containingBlock()->isLayoutBlockFlow()) { 493 if (!descendant->containingBlock()->isLayoutBlockFlow()) {
473 // Needs to be in a block-flow container, and not e.g. a table. 494 // Needs to be in a block-flow container, and not e.g. a table.
474 return false; 495 return false;
475 } 496 }
476 497
477 // This looks like a spanner, but if we're inside something unbreakable, it' s not to be treated as one. 498 // This looks like a spanner, but if we're inside something unbreakable, it' s not to be treated as one.
478 for (LayoutBlock* ancestor = descendant->containingBlock(); ancestor; ancest or = ancestor->containingBlock()) { 499 for (LayoutBox* ancestor = toLayoutBox(descendant)->parentBox(); ancestor; a ncestor = ancestor->containingBlock()) {
479 if (ancestor->isLayoutFlowThread()) { 500 if (ancestor->isLayoutFlowThread()) {
480 ASSERT(ancestor == this); 501 ASSERT(ancestor == this);
481 return true; 502 return true;
482 } 503 }
483 if (ancestor->spannerPlaceholder()) { 504 if (ancestor->spannerPlaceholder()) {
484 // FIXME: do we want to support nested spanners in a different way? The outer spanner 505 // FIXME: do we want to support nested spanners in a different way? The outer spanner
485 // has already broken out from the columns to become sized by the mu lticol container, 506 // has already broken out from the columns to become sized by the mu lticol container,
486 // which may be good enough for the inner spanner. But margins, bord ers, padding and 507 // which may be good enough for the inner spanner. But margins, bord ers, padding and
487 // explicit widths on the outer spanner, or on any children between the outer and inner 508 // explicit widths on the outer spanner, or on any children between the outer and inner
488 // spanner, will affect the width of the inner spanner this way, whi ch might be 509 // spanner, will affect the width of the inner spanner this way, whi ch might be
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 void LayoutMultiColumnFlowThread::flowThreadDescendantStyleDidChange(LayoutObjec t* descendant, StyleDifference diff, const ComputedStyle& oldStyle) 726 void LayoutMultiColumnFlowThread::flowThreadDescendantStyleDidChange(LayoutObjec t* descendant, StyleDifference diff, const ComputedStyle& oldStyle)
706 { 727 {
707 // If an out-of-flow descendant goes in-flow, we may have to insert a column set. 728 // If an out-of-flow descendant goes in-flow, we may have to insert a column set.
708 if (descendant->isText()) { 729 if (descendant->isText()) {
709 // Text nodes inherit all properties from the parent node (including non -inheritable 730 // Text nodes inherit all properties from the parent node (including non -inheritable
710 // ones). We don't care what its 'position' is. In fact, we _must_ ignor e it, since the 731 // ones). We don't care what its 'position' is. In fact, we _must_ ignor e it, since the
711 // parent may be the multicol container, and having that accidentally le aked into children 732 // parent may be the multicol container, and having that accidentally le aked into children
712 // of the multicol is bad. 733 // of the multicol is bad.
713 return; 734 return;
714 } 735 }
715 if (oldStyle.hasOutOfFlowPosition() && !styleRef().hasOutOfFlowPosition()) 736 if (styleRef().hasOutOfFlowPosition())
737 return;
738
739 // We're not out of flow.
740 if (oldStyle.hasOutOfFlowPosition()) {
741 // ... but we used to be out of flow. So we might need to insert a colum n set (or
742 // spanner placeholder, in case this descendant is now a valid column sp anner).
716 flowThreadDescendantWasInserted(descendant); 743 flowThreadDescendantWasInserted(descendant);
744 return;
745 }
746 if (descendantIsValidColumnSpanner(descendant)) {
747 // We went from being regular column content to becoming a spanner.
748 ASSERT(!toLayoutBox(descendant)->spannerPlaceholder());
749
750 // First remove this as regular column content. Note that this will walk the entire subtree
751 // of |descendant|. There might be spanners there (which won't be spanne rs anymore, since
752 // we're not allowed to nest spanners), whose placeholders must die.
753 flowThreadDescendantWillBeRemoved(descendant);
754
755 createAndInsertSpannerPlaceholder(toLayoutBox(descendant), nextInPreOrde rAfterChildrenSkippingOutOfFlow(this, descendant));
756 }
717 } 757 }
718 758
719 void LayoutMultiColumnFlowThread::computePreferredLogicalWidths() 759 void LayoutMultiColumnFlowThread::computePreferredLogicalWidths()
720 { 760 {
721 LayoutFlowThread::computePreferredLogicalWidths(); 761 LayoutFlowThread::computePreferredLogicalWidths();
722 762
723 // The min/max intrinsic widths calculated really tell how much space elemen ts need when 763 // The min/max intrinsic widths calculated really tell how much space elemen ts need when
724 // laid out inside the columns. In order to eventually end up with the desir ed column width, 764 // laid out inside the columns. In order to eventually end up with the desir ed column width,
725 // we need to convert them to values pertaining to the multicol container. 765 // we need to convert them to values pertaining to the multicol container.
726 const LayoutBlockFlow* multicolContainer = multiColumnBlockFlow(); 766 const LayoutBlockFlow* multicolContainer = multiColumnBlockFlow();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 } 844 }
805 845
806 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const 846 bool LayoutMultiColumnFlowThread::isPageLogicalHeightKnown() const
807 { 847 {
808 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet()) 848 if (LayoutMultiColumnSet* columnSet = lastMultiColumnSet())
809 return columnSet->pageLogicalHeight(); 849 return columnSet->pageLogicalHeight();
810 return false; 850 return false;
811 } 851 }
812 852
813 } 853 }
OLDNEW
« no previous file with comments | « Source/core/layout/LayoutMultiColumnFlowThread.h ('k') | Source/core/layout/LayoutMultiColumnSpannerPlaceholder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698