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 |