Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |