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

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

Issue 295373006: [New Multicolumn] Support for paged overflow. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 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
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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height! 186 ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height!
187 ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If th is happens, we probably have a bug. 187 ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If th is happens, we probably have a bug.
188 if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight()) 188 if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight())
189 return m_columnHeight; // So bail out rather than looping infinitely. 189 return m_columnHeight; // So bail out rather than looping infinitely.
190 190
191 return m_columnHeight + m_minSpaceShortage; 191 return m_columnHeight + m_minSpaceShortage;
192 } 192 }
193 193
194 void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage) 194 void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage)
195 { 195 {
196 if (!multiColumnFlowThread()->requiresBalancing()) 196 if (!multiColumnFlowThread()->heightIsAuto())
197 return; 197 return;
198 if (!m_contentRuns.isEmpty() && endOffsetFromFirstPage <= m_contentRuns.last ().breakOffset()) 198 if (!m_contentRuns.isEmpty() && endOffsetFromFirstPage <= m_contentRuns.last ().breakOffset())
199 return; 199 return;
200 // Append another item as long as we haven't exceeded used column count. Wha t ends up in the 200 // Append another item as long as we haven't exceeded used column count. Wha t ends up in the
201 // overflow area shouldn't affect column balancing. 201 // overflow area shouldn't affect column balancing.
202 if (m_contentRuns.size() < usedColumnCount()) 202 if (m_contentRuns.size() < usedColumnCount())
203 m_contentRuns.append(ContentRun(endOffsetFromFirstPage)); 203 m_contentRuns.append(ContentRun(endOffsetFromFirstPage));
204 } 204 }
205 205
206 bool RenderMultiColumnSet::recalculateColumnHeight(BalancedHeightCalculation cal culationMode) 206 bool RenderMultiColumnSet::recalculateColumnHeight(BalancedHeightCalculation cal culationMode)
207 { 207 {
208 ASSERT(multiColumnFlowThread()->requiresBalancing()); 208 ASSERT(multiColumnFlowThread()->heightIsAuto());
209 209
210 LayoutUnit oldColumnHeight = m_columnHeight; 210 LayoutUnit oldColumnHeight = m_columnHeight;
211 if (calculationMode == GuessFromFlowThreadPortion) { 211 if (calculationMode == GuessFromFlowThreadPortion) {
212 // Post-process the content runs and find out where the implicit breaks will occur. 212 // Post-process the content runs and find out where the implicit breaks will occur.
213 distributeImplicitBreaks(); 213 distributeImplicitBreaks();
214 } 214 }
215 LayoutUnit newColumnHeight = calculateColumnHeight(calculationMode); 215 LayoutUnit newColumnHeight = calculateColumnHeight(calculationMode);
216 setAndConstrainColumnHeight(newColumnHeight); 216 setAndConstrainColumnHeight(newColumnHeight);
217 217
218 // After having calculated an initial column height, the multicol container typically needs at 218 // After having calculated an initial column height, the multicol container typically needs at
(...skipping 28 matching lines...) Expand all
247 247
248 void RenderMultiColumnSet::resetColumnHeight() 248 void RenderMultiColumnSet::resetColumnHeight()
249 { 249 {
250 // Nuke previously stored minimum column height. Contents may have changed f or all we know. 250 // Nuke previously stored minimum column height. Contents may have changed f or all we know.
251 m_minimumColumnHeight = 0; 251 m_minimumColumnHeight = 0;
252 252
253 m_maxColumnHeight = calculateMaxColumnHeight(); 253 m_maxColumnHeight = calculateMaxColumnHeight();
254 254
255 LayoutUnit oldColumnHeight = pageLogicalHeight(); 255 LayoutUnit oldColumnHeight = pageLogicalHeight();
256 256
257 if (multiColumnFlowThread()->requiresBalancing()) 257 if (multiColumnFlowThread()->heightIsAuto())
258 m_columnHeight = 0; 258 m_columnHeight = 0;
259 else 259 else
260 setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowTh read()->columnHeightAvailable())); 260 setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowTh read()->columnHeightAvailable()));
261 261
262 if (pageLogicalHeight() != oldColumnHeight) 262 if (pageLogicalHeight() != oldColumnHeight)
263 setChildNeedsLayout(MarkOnlyThis); 263 setChildNeedsLayout(MarkOnlyThis);
264 264
265 // Content runs are only needed in the initial layout pass, in order to find an initial column 265 // Content runs are only needed in the initial layout pass, in order to find an initial column
266 // height, and should have been deleted afterwards. We're about to rebuild t he content runs, so 266 // height, and should have been deleted afterwards. We're about to rebuild t he content runs, so
267 // the list needs to be empty. 267 // the list needs to be empty.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 return count; 330 return count;
331 } 331 }
332 332
333 LayoutRect RenderMultiColumnSet::columnRectAt(unsigned index) const 333 LayoutRect RenderMultiColumnSet::columnRectAt(unsigned index) const
334 { 334 {
335 LayoutUnit colLogicalWidth = pageLogicalWidth(); 335 LayoutUnit colLogicalWidth = pageLogicalWidth();
336 LayoutUnit colLogicalHeight = pageLogicalHeight(); 336 LayoutUnit colLogicalHeight = pageLogicalHeight();
337 LayoutUnit colLogicalTop = borderBefore() + paddingBefore(); 337 LayoutUnit colLogicalTop = borderBefore() + paddingBefore();
338 LayoutUnit colLogicalLeft = borderAndPaddingLogicalLeft(); 338 LayoutUnit colLogicalLeft = borderAndPaddingLogicalLeft();
339 LayoutUnit colGap = columnGap(); 339 LayoutUnit colGap = columnGap();
340 if (style()->isLeftToRightDirection()) 340
341 colLogicalLeft += index * (colLogicalWidth + colGap); 341 if (multiColumnFlowThread()->progressionIsInline()) {
342 else 342 if (style()->isLeftToRightDirection())
343 colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (col LogicalWidth + colGap); 343 colLogicalLeft += index * (colLogicalWidth + colGap);
344 else
345 colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
346 } else {
347 colLogicalTop += index * (colLogicalHeight + colGap);
348 }
344 349
345 if (isHorizontalWritingMode()) 350 if (isHorizontalWritingMode())
346 return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLog icalHeight); 351 return LayoutRect(colLogicalLeft, colLogicalTop, colLogicalWidth, colLog icalHeight);
347 return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogica lWidth); 352 return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogica lWidth);
348 } 353 }
349 354
350 unsigned RenderMultiColumnSet::columnIndexAtOffset(LayoutUnit offset, ColumnInde xCalculationMode mode) const 355 unsigned RenderMultiColumnSet::columnIndexAtOffset(LayoutUnit offset, ColumnInde xCalculationMode mode) const
351 { 356 {
352 LayoutRect portionRect(flowThreadPortionRect()); 357 LayoutRect portionRect(flowThreadPortionRect());
353 358
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 return; 435 return;
431 436
432 paintColumnRules(paintInfo, paintOffset); 437 paintColumnRules(paintInfo, paintOffset);
433 } 438 }
434 439
435 void RenderMultiColumnSet::paintColumnRules(PaintInfo& paintInfo, const LayoutPo int& paintOffset) 440 void RenderMultiColumnSet::paintColumnRules(PaintInfo& paintInfo, const LayoutPo int& paintOffset)
436 { 441 {
437 if (paintInfo.context->paintingDisabled()) 442 if (paintInfo.context->paintingDisabled())
438 return; 443 return;
439 444
445 if (flowThread()->isRenderPagedFlowThread())
446 return;
447
440 RenderStyle* blockStyle = multiColumnBlockFlow()->style(); 448 RenderStyle* blockStyle = multiColumnBlockFlow()->style();
441 const Color& ruleColor = resolveColor(blockStyle, CSSPropertyWebkitColumnRul eColor); 449 const Color& ruleColor = resolveColor(blockStyle, CSSPropertyWebkitColumnRul eColor);
442 bool ruleTransparent = blockStyle->columnRuleIsTransparent(); 450 bool ruleTransparent = blockStyle->columnRuleIsTransparent();
443 EBorderStyle ruleStyle = blockStyle->columnRuleStyle(); 451 EBorderStyle ruleStyle = blockStyle->columnRuleStyle();
444 LayoutUnit ruleThickness = blockStyle->columnRuleWidth(); 452 LayoutUnit ruleThickness = blockStyle->columnRuleWidth();
445 LayoutUnit colGap = columnGap(); 453 LayoutUnit colGap = columnGap();
446 bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent; 454 bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
447 if (!renderRule) 455 if (!renderRule)
448 return; 456 return;
449 457
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 567
560 // Figure out the start and end columns and only check within that range so that we don't walk the 568 // Figure out the start and end columns and only check within that range so that we don't walk the
561 // entire column set. 569 // entire column set.
562 unsigned startColumn = columnIndexAtOffset(layerLogicalTop); 570 unsigned startColumn = columnIndexAtOffset(layerLogicalTop);
563 unsigned endColumn = columnIndexAtOffset(layerLogicalBottom); 571 unsigned endColumn = columnIndexAtOffset(layerLogicalBottom);
564 572
565 LayoutUnit colLogicalWidth = pageLogicalWidth(); 573 LayoutUnit colLogicalWidth = pageLogicalWidth();
566 LayoutUnit colGap = columnGap(); 574 LayoutUnit colGap = columnGap();
567 unsigned colCount = actualColumnCount(); 575 unsigned colCount = actualColumnCount();
568 576
577 RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread();
578 bool progressionIsInline = flowThread->progressionIsInline();
579 bool leftToRight = style()->isLeftToRightDirection();
580
581 LayoutUnit initialBlockOffset = logicalTop() - flowThread->logicalTop();
582
569 for (unsigned i = startColumn; i <= endColumn; i++) { 583 for (unsigned i = startColumn; i <= endColumn; i++) {
570 // Get the portion of the flow thread that corresponds to this column. 584 // Get the portion of the flow thread that corresponds to this column.
571 LayoutRect flowThreadPortion = flowThreadPortionRectAt(i); 585 LayoutRect flowThreadPortion = flowThreadPortionRectAt(i);
572 586
573 // Now get the overflow rect that corresponds to the column. 587 // Now get the overflow rect that corresponds to the column.
574 LayoutRect flowThreadOverflowPortion = flowThreadPortionOverflowRect(flo wThreadPortion, i, colCount, colGap); 588 LayoutRect flowThreadOverflowPortion = flowThreadPortionOverflowRect(flo wThreadPortion, i, colCount, colGap);
575 589
576 // In order to create a fragment we must intersect the portion painted b y this column. 590 // In order to create a fragment we must intersect the portion painted b y this column.
577 LayoutRect clippedRect(layerBoundsInFlowThread); 591 LayoutRect clippedRect(layerBoundsInFlowThread);
578 clippedRect.intersect(flowThreadOverflowPortion); 592 clippedRect.intersect(flowThreadOverflowPortion);
579 if (clippedRect.isEmpty()) 593 if (clippedRect.isEmpty())
580 continue; 594 continue;
581 595
582 // We also need to intersect the dirty rect. We have to apply a translat ion and shift based off 596 // We also need to intersect the dirty rect. We have to apply a translat ion and shift based off
583 // our column index. 597 // our column index.
584 LayoutPoint translationOffset; 598 LayoutPoint translationOffset;
585 LayoutUnit inlineOffset = i * (colLogicalWidth + colGap); 599 LayoutUnit inlineOffset = progressionIsInline ? i * (colLogicalWidth + c olGap) : LayoutUnit();
586 if (!style()->isLeftToRightDirection()) 600 if (!leftToRight)
587 inlineOffset = -inlineOffset; 601 inlineOffset = -inlineOffset;
588 translationOffset.setX(inlineOffset); 602 translationOffset.setX(inlineOffset);
589 LayoutUnit blockOffset = isHorizontalWritingMode() ? -flowThreadPortion. y() : -flowThreadPortion.x(); 603 LayoutUnit blockOffset;
604 if (progressionIsInline)
605 blockOffset = initialBlockOffset + (isHorizontalWritingMode() ? -flo wThreadPortion.y() : -flowThreadPortion.x());
606 else
607 blockOffset = i * colGap;
rune 2014/06/18 22:09:05 I had to stare at this for a while. I think this w
rune 2014/06/19 09:22:19 Never mind renaming. This is in RenderMultiColumnS
590 if (isFlippedBlocksWritingMode(style()->writingMode())) 608 if (isFlippedBlocksWritingMode(style()->writingMode()))
591 blockOffset = -blockOffset; 609 blockOffset = -blockOffset;
592 translationOffset.setY(blockOffset); 610 translationOffset.setY(blockOffset);
593 if (!isHorizontalWritingMode()) 611 if (!isHorizontalWritingMode())
594 translationOffset = translationOffset.transposedPoint(); 612 translationOffset = translationOffset.transposedPoint();
595 // FIXME: The translation needs to include the multicolumn set's content offset within the 613 // FIXME: The translation needs to include the multicolumn set's content offset within the
596 // multicolumn block as well. This won't be an issue until we start crea ting multiple multicolumn sets. 614 // multicolumn block as well. This won't be an issue until we start crea ting multiple multicolumn sets.
597 615
598 // Shift the dirty rect to be in flow thread coordinates with this trans lation applied. 616 // Shift the dirty rect to be in flow thread coordinates with this trans lation applied.
599 LayoutRect translatedDirtyRect(dirtyRect); 617 LayoutRect translatedDirtyRect(dirtyRect);
600 translatedDirtyRect.moveBy(-translationOffset); 618 translatedDirtyRect.moveBy(-translationOffset);
601 619
602 // See if we intersect the dirty rect. 620 // See if we intersect the dirty rect.
603 clippedRect = layerBoundingBox; 621 clippedRect = layerBoundingBox;
604 clippedRect.intersect(translatedDirtyRect); 622 clippedRect.intersect(translatedDirtyRect);
605 if (clippedRect.isEmpty()) 623 if (clippedRect.isEmpty())
606 continue; 624 continue;
607 625
608 // Something does need to paint in this column. Make a fragment now and supply the physical translation 626 // Something does need to paint in this column. Make a fragment now and supply the physical translation
609 // offset and the clip rect for the column with that offset applied. 627 // offset and the clip rect for the column with that offset applied.
610 LayerFragment fragment; 628 LayerFragment fragment;
611 fragment.paginationOffset = translationOffset; 629 fragment.paginationOffset = translationOffset;
612 630
613 LayoutRect flippedFlowThreadOverflowPortion(flowThreadOverflowPortion); 631 LayoutRect flippedFlowThreadOverflowPortion(flowThreadOverflowPortion);
614 // Flip it into more a physical (RenderLayer-style) rectangle. 632 // Flip it into more a physical (RenderLayer-style) rectangle.
615 flowThread()->flipForWritingMode(flippedFlowThreadOverflowPortion); 633 flowThread->flipForWritingMode(flippedFlowThreadOverflowPortion);
616 fragment.paginationClip = flippedFlowThreadOverflowPortion; 634 fragment.paginationClip = flippedFlowThreadOverflowPortion;
617 fragments.append(fragment); 635 fragments.append(fragment);
618 } 636 }
619 } 637 }
620 638
621 void RenderMultiColumnSet::addOverflowFromChildren() 639 void RenderMultiColumnSet::addOverflowFromChildren()
622 { 640 {
623 unsigned colCount = actualColumnCount(); 641 unsigned colCount = actualColumnCount();
624 if (!colCount) 642 if (!colCount)
625 return; 643 return;
626 644
627 LayoutRect lastRect = columnRectAt(colCount - 1); 645 LayoutRect lastRect = columnRectAt(colCount - 1);
628 addLayoutOverflow(lastRect); 646 addLayoutOverflow(lastRect);
629 if (!hasOverflowClip()) 647 if (!hasOverflowClip())
630 addVisualOverflow(lastRect); 648 addVisualOverflow(lastRect);
631 } 649 }
632 650
633 const char* RenderMultiColumnSet::renderName() const 651 const char* RenderMultiColumnSet::renderName() const
634 { 652 {
635 return "RenderMultiColumnSet"; 653 return "RenderMultiColumnSet";
636 } 654 }
637 655
638 } 656 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698