| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google 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 are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 LayoutUnit positiveMargin() const { return m_positiveMargin; } | 146 LayoutUnit positiveMargin() const { return m_positiveMargin; } |
| 147 LayoutUnit negativeMargin() const { return m_negativeMargin; } | 147 LayoutUnit negativeMargin() const { return m_negativeMargin; } |
| 148 bool discardMargin() const { return m_discardMargin; } | 148 bool discardMargin() const { return m_discardMargin; } |
| 149 LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; } | 149 LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; } |
| 150 }; | 150 }; |
| 151 static bool inNormalFlow(LayoutBox* child) | 151 static bool inNormalFlow(LayoutBox* child) |
| 152 { | 152 { |
| 153 LayoutBlock* curr = child->containingBlock(); | 153 LayoutBlock* curr = child->containingBlock(); |
| 154 LayoutView* layoutView = child->view(); | 154 LayoutView* layoutView = child->view(); |
| 155 while (curr && curr != layoutView) { | 155 while (curr && curr != layoutView) { |
| 156 if (curr->hasColumns() || curr->isLayoutFlowThread()) | 156 if (curr->isLayoutFlowThread()) |
| 157 return true; | 157 return true; |
| 158 if (curr->isFloatingOrOutOfFlowPositioned()) | 158 if (curr->isFloatingOrOutOfFlowPositioned()) |
| 159 return false; | 159 return false; |
| 160 curr = curr->containingBlock(); | 160 curr = curr->containingBlock(); |
| 161 } | 161 } |
| 162 return true; | 162 return true; |
| 163 } | 163 } |
| 164 | 164 |
| 165 LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) | 165 LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) |
| 166 : LayoutBlock(node) | 166 : LayoutBlock(node) |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 } | 202 } |
| 203 | 203 |
| 204 void LayoutBlockFlow::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogi
calHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight) | 204 void LayoutBlockFlow::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogi
calHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight) |
| 205 { | 205 { |
| 206 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | 206 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { |
| 207 LogicalExtentComputedValues computedValues; | 207 LogicalExtentComputedValues computedValues; |
| 208 computeLogicalHeight(LayoutUnit(), logicalTop(), computedValues); | 208 computeLogicalHeight(LayoutUnit(), logicalTop(), computedValues); |
| 209 LayoutUnit columnHeight = computedValues.m_extent - borderAndPaddingLogi
calHeight() - scrollbarLogicalHeight(); | 209 LayoutUnit columnHeight = computedValues.m_extent - borderAndPaddingLogi
calHeight() - scrollbarLogicalHeight(); |
| 210 pageLogicalHeightChanged = columnHeight != flowThread->columnHeightAvail
able(); | 210 pageLogicalHeightChanged = columnHeight != flowThread->columnHeightAvail
able(); |
| 211 flowThread->setColumnHeightAvailable(std::max<LayoutUnit>(columnHeight,
0)); | 211 flowThread->setColumnHeightAvailable(std::max<LayoutUnit>(columnHeight,
0)); |
| 212 } else if (hasColumns()) { | |
| 213 ColumnInfo* colInfo = columnInfo(); | |
| 214 | |
| 215 if (!pageLogicalHeight) { | |
| 216 LayoutUnit oldLogicalHeight = logicalHeight(); | |
| 217 setLogicalHeight(0); | |
| 218 // We need to go ahead and set our explicit page height if one exist
s, so that we can | |
| 219 // avoid doing two layout passes. | |
| 220 updateLogicalHeight(); | |
| 221 LayoutUnit columnHeight = contentLogicalHeight(); | |
| 222 if (columnHeight > 0) { | |
| 223 pageLogicalHeight = columnHeight; | |
| 224 hasSpecifiedPageLogicalHeight = true; | |
| 225 } | |
| 226 setLogicalHeight(oldLogicalHeight); | |
| 227 } | |
| 228 if (colInfo->columnHeight() != pageLogicalHeight && everHadLayout()) { | |
| 229 colInfo->setColumnHeight(pageLogicalHeight); | |
| 230 pageLogicalHeightChanged = true; | |
| 231 } | |
| 232 | |
| 233 if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight) | |
| 234 colInfo->clearForcedBreaks(); | |
| 235 } else if (isLayoutFlowThread()) { | 212 } else if (isLayoutFlowThread()) { |
| 236 LayoutFlowThread* flowThread = toLayoutFlowThread(this); | 213 LayoutFlowThread* flowThread = toLayoutFlowThread(this); |
| 237 | 214 |
| 238 // FIXME: This is a hack to always make sure we have a page logical heig
ht, if said height | 215 // FIXME: This is a hack to always make sure we have a page logical heig
ht, if said height |
| 239 // is known. The page logical height thing in LayoutState is meaningless
for flow | 216 // is known. The page logical height thing in LayoutState is meaningless
for flow |
| 240 // thread-based pagination (page height isn't necessarily uniform throug
hout the flow | 217 // thread-based pagination (page height isn't necessarily uniform throug
hout the flow |
| 241 // thread), but as long as it is used universally as a means to determin
e whether page | 218 // thread), but as long as it is used universally as a means to determin
e whether page |
| 242 // height is known or not, we need this. Page height is unknown when col
umn balancing is | 219 // height is known or not, we need this. Page height is unknown when col
umn balancing is |
| 243 // enabled and flow thread height is still unknown (i.e. during the firs
t layout pass). When | 220 // enabled and flow thread height is still unknown (i.e. during the firs
t layout pass). When |
| 244 // it's unknown, we need to prevent the pagination code from assuming pa
ge breaks everywhere | 221 // it's unknown, we need to prevent the pagination code from assuming pa
ge breaks everywhere |
| 245 // and thereby eating every top margin. It should be trivial to clean up
and get rid of this | 222 // and thereby eating every top margin. It should be trivial to clean up
and get rid of this |
| 246 // hack once the old multicol implementation is gone. | 223 // hack once the old multicol implementation is gone. |
| 247 pageLogicalHeight = flowThread->isPageLogicalHeightKnown() ? LayoutUnit(
1) : LayoutUnit(); | 224 pageLogicalHeight = flowThread->isPageLogicalHeightKnown() ? LayoutUnit(
1) : LayoutUnit(); |
| 248 | 225 |
| 249 pageLogicalHeightChanged = flowThread->pageLogicalSizeChanged(); | 226 pageLogicalHeightChanged = flowThread->pageLogicalSizeChanged(); |
| 250 } | 227 } |
| 251 } | 228 } |
| 252 | 229 |
| 253 bool LayoutBlockFlow::shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight,
LayoutUnit layoutOverflowLogicalBottom) const | |
| 254 { | |
| 255 // FIXME: We don't balance properly at all in the presence of forced page br
eaks. We need to understand what | |
| 256 // the distance between forced page breaks is so that we can avoid making th
e minimum column height too tall. | |
| 257 ColumnInfo* colInfo = columnInfo(); | |
| 258 LayoutUnit columnHeight = pageLogicalHeight; | |
| 259 const int minColumnCount = colInfo->forcedBreaks() + 1; | |
| 260 const int desiredColumnCount = colInfo->desiredColumnCount(); | |
| 261 if (minColumnCount >= desiredColumnCount) { | |
| 262 // The forced page breaks are in control of the balancing. Just set the
column height to the | |
| 263 // maximum page break distance. | |
| 264 if (!pageLogicalHeight) { | |
| 265 LayoutUnit distanceBetweenBreaks = std::max<LayoutUnit>(colInfo->max
imumDistanceBetweenForcedBreaks(), | |
| 266 view()->layoutState()->pageLogicalOffset(*this, borderBefore() +
paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset()); | |
| 267 columnHeight = std::max(colInfo->minimumColumnHeight(), distanceBetw
eenBreaks); | |
| 268 } | |
| 269 } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeight,
desiredColumnCount)) { | |
| 270 // Now that we know the intrinsic height of the columns, we have to reba
lance them. | |
| 271 columnHeight = std::max<LayoutUnit>(colInfo->minimumColumnHeight(), ceil
f(layoutOverflowLogicalBottom.toFloat() / desiredColumnCount)); | |
| 272 } | |
| 273 | |
| 274 if (columnHeight && columnHeight != pageLogicalHeight) { | |
| 275 pageLogicalHeight = columnHeight; | |
| 276 return true; | |
| 277 } | |
| 278 | |
| 279 return false; | |
| 280 } | |
| 281 | |
| 282 void LayoutBlockFlow::setColumnCountAndHeight(unsigned count, LayoutUnit pageLog
icalHeight) | |
| 283 { | |
| 284 ColumnInfo* colInfo = columnInfo(); | |
| 285 if (pageLogicalHeight) | |
| 286 colInfo->setColumnCountAndHeight(count, pageLogicalHeight); | |
| 287 | |
| 288 if (columnCount(colInfo)) { | |
| 289 setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeigh
t() + borderAfter() + paddingAfter() + scrollbarLogicalHeight()); | |
| 290 m_overflow.clear(); | |
| 291 } | |
| 292 } | |
| 293 | |
| 294 void LayoutBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak) | 230 void LayoutBlockFlow::setBreakAtLineToAvoidWidow(int lineToBreak) |
| 295 { | 231 { |
| 296 ASSERT(lineToBreak >= 0); | 232 ASSERT(lineToBreak >= 0); |
| 297 ensureRareData(); | 233 ensureRareData(); |
| 298 ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow); | 234 ASSERT(!m_rareData->m_didBreakAtLineToAvoidWidow); |
| 299 m_rareData->m_lineBreakToAvoidWidow = lineToBreak; | 235 m_rareData->m_lineBreakToAvoidWidow = lineToBreak; |
| 300 } | 236 } |
| 301 | 237 |
| 302 void LayoutBlockFlow::setDidBreakAtLineToAvoidWidow() | 238 void LayoutBlockFlow::setDidBreakAtLineToAvoidWidow() |
| 303 { | 239 { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 // descendants every time in |isSelfCollapsingBlock|. We reset it here so th
at |isSelfCollapsingBlock| attempts to burrow | 278 // descendants every time in |isSelfCollapsingBlock|. We reset it here so th
at |isSelfCollapsingBlock| attempts to burrow |
| 343 // at least once and so that it always gives a reliable result reflecting th
e latest layout. | 279 // at least once and so that it always gives a reliable result reflecting th
e latest layout. |
| 344 m_hasOnlySelfCollapsingChildren = false; | 280 m_hasOnlySelfCollapsingChildren = false; |
| 345 | 281 |
| 346 if (!relayoutChildren && simplifiedLayout()) | 282 if (!relayoutChildren && simplifiedLayout()) |
| 347 return; | 283 return; |
| 348 | 284 |
| 349 LayoutAnalyzer::BlockScope analyzer(*this); | 285 LayoutAnalyzer::BlockScope analyzer(*this); |
| 350 SubtreeLayoutScope layoutScope(*this); | 286 SubtreeLayoutScope layoutScope(*this); |
| 351 | 287 |
| 352 // Multiple passes might be required for column and pagination based layout | 288 // Multiple passes might be required for column based layout. |
| 353 // In the case of the old column code the number of passes will only be two | 289 // The number of passes could be as high as the number of columns. |
| 354 // however, in the newer column code the number of passes could equal the | |
| 355 // number of columns. | |
| 356 bool done = false; | 290 bool done = false; |
| 357 LayoutUnit pageLogicalHeight = 0; | 291 LayoutUnit pageLogicalHeight = 0; |
| 358 while (!done) | 292 while (!done) |
| 359 done = layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope)
; | 293 done = layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope)
; |
| 360 | 294 |
| 361 LayoutView* layoutView = view(); | 295 LayoutView* layoutView = view(); |
| 362 if (layoutView->layoutState()->pageLogicalHeight()) | 296 if (layoutView->layoutState()->pageLogicalHeight()) |
| 363 setPageLogicalOffset(layoutView->layoutState()->pageLogicalOffset(*this,
logicalTop())); | 297 setPageLogicalOffset(layoutView->layoutState()->pageLogicalOffset(*this,
logicalTop())); |
| 364 | 298 |
| 365 updateLayerTransformAfterLayout(); | 299 updateLayerTransformAfterLayout(); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 392 relayoutChildren |= logicalWidthChanged; | 326 relayoutChildren |= logicalWidthChanged; |
| 393 | 327 |
| 394 rebuildFloatsFromIntruding(); | 328 rebuildFloatsFromIntruding(); |
| 395 | 329 |
| 396 bool pageLogicalHeightChanged = false; | 330 bool pageLogicalHeightChanged = false; |
| 397 bool hasSpecifiedPageLogicalHeight = false; | 331 bool hasSpecifiedPageLogicalHeight = false; |
| 398 checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightCh
anged, hasSpecifiedPageLogicalHeight); | 332 checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightCh
anged, hasSpecifiedPageLogicalHeight); |
| 399 if (pageLogicalHeightChanged) | 333 if (pageLogicalHeightChanged) |
| 400 relayoutChildren = true; | 334 relayoutChildren = true; |
| 401 | 335 |
| 402 LayoutState state(*this, locationOffset(), pageLogicalHeight, pageLogicalHei
ghtChanged, columnInfo(), logicalWidthChanged); | 336 LayoutState state(*this, locationOffset(), pageLogicalHeight, pageLogicalHei
ghtChanged, logicalWidthChanged); |
| 403 | 337 |
| 404 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg,
to track | 338 // We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg,
to track |
| 405 // our current maximal positive and negative margins. These values are used
when we | 339 // our current maximal positive and negative margins. These values are used
when we |
| 406 // are collapsed with adjacent blocks, so for example, if you have block A a
nd B | 340 // are collapsed with adjacent blocks, so for example, if you have block A a
nd B |
| 407 // collapsing together, then you'd take the maximal positive margin from bot
h A and B | 341 // collapsing together, then you'd take the maximal positive margin from bot
h A and B |
| 408 // and subtract it from the maximal negative margin from both A and B to get
the | 342 // and subtract it from the maximal negative margin from both A and B to get
the |
| 409 // true collapsed margin. This algorithm is recursive, so when we finish lay
out() | 343 // true collapsed margin. This algorithm is recursive, so when we finish lay
out() |
| 410 // our block knows its current maximal positive/negative values. | 344 // our block knows its current maximal positive/negative values. |
| 411 // | 345 // |
| 412 // Start out by setting our margin values to our current margins. Table cell
s have | 346 // Start out by setting our margin values to our current margins. Table cell
s have |
| (...skipping 24 matching lines...) Expand all Loading... |
| 437 | 371 |
| 438 // Expand our intrinsic height to encompass floats. | 372 // Expand our intrinsic height to encompass floats. |
| 439 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsNew
FormattingContext()) | 373 if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsNew
FormattingContext()) |
| 440 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); | 374 setLogicalHeight(lowestFloatLogicalBottom() + afterEdge); |
| 441 | 375 |
| 442 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { | 376 if (LayoutMultiColumnFlowThread* flowThread = multiColumnFlowThread()) { |
| 443 if (flowThread->recalculateColumnHeights()) { | 377 if (flowThread->recalculateColumnHeights()) { |
| 444 setChildNeedsLayout(MarkOnlyThis); | 378 setChildNeedsLayout(MarkOnlyThis); |
| 445 return false; | 379 return false; |
| 446 } | 380 } |
| 447 } else if (hasColumns()) { | |
| 448 OwnPtr<OverflowModel> savedOverflow = m_overflow.release(); | |
| 449 if (childrenInline()) | |
| 450 addOverflowFromInlineChildren(); | |
| 451 else | |
| 452 addOverflowFromBlockChildren(); | |
| 453 LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? la
youtOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - padd
ingBefore(); | |
| 454 m_overflow = savedOverflow.release(); | |
| 455 | |
| 456 if (!hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(pageLo
gicalHeight, layoutOverflowLogicalBottom)) { | |
| 457 setEverHadLayout(true); | |
| 458 return false; | |
| 459 } | |
| 460 | |
| 461 setColumnCountAndHeight(ceilf(layoutOverflowLogicalBottom.toFloat() / pa
geLogicalHeight.toFloat()), pageLogicalHeight.toFloat()); | |
| 462 } | 381 } |
| 463 | 382 |
| 464 if (shouldBreakAtLineToAvoidWidow()) { | 383 if (shouldBreakAtLineToAvoidWidow()) { |
| 465 setEverHadLayout(true); | 384 setEverHadLayout(true); |
| 466 return false; | 385 return false; |
| 467 } | 386 } |
| 468 | 387 |
| 469 // Calculate our new height. | 388 // Calculate our new height. |
| 470 LayoutUnit oldHeight = logicalHeight(); | 389 LayoutUnit oldHeight = logicalHeight(); |
| 471 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); | 390 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 // We're at the very top of a page or column. | 780 // We're at the very top of a page or column. |
| 862 if (lineBox != firstRootBox()) | 781 if (lineBox != firstRootBox()) |
| 863 lineBox.setIsFirstAfterPageBreak(true); | 782 lineBox.setIsFirstAfterPageBreak(true); |
| 864 if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage()) | 783 if (lineBox != firstRootBox() || offsetFromLogicalTopOfFirstPage()) |
| 865 setPageBreak(logicalOffset, lineHeight); | 784 setPageBreak(logicalOffset, lineHeight); |
| 866 } | 785 } |
| 867 } | 786 } |
| 868 | 787 |
| 869 LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(LayoutBox& child, LayoutU
nit logicalOffset, bool includeMargins) | 788 LayoutUnit LayoutBlockFlow::adjustForUnsplittableChild(LayoutBox& child, LayoutU
nit logicalOffset, bool includeMargins) |
| 870 { | 789 { |
| 871 bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns() || flo
wThreadContainingBlock(); | 790 bool checkColumnBreaks = flowThreadContainingBlock(); |
| 872 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); | 791 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); |
| 873 bool isUnsplittable = child.isUnsplittableForPagination() || (checkColumnBre
aks && child.style()->columnBreakInside() == PBAVOID) | 792 bool isUnsplittable = child.isUnsplittableForPagination() || (checkColumnBre
aks && child.style()->columnBreakInside() == PBAVOID) |
| 874 || (checkPageBreaks && child.style()->pageBreakInside() == PBAVOID); | 793 || (checkPageBreaks && child.style()->pageBreakInside() == PBAVOID); |
| 875 if (!isUnsplittable) | 794 if (!isUnsplittable) |
| 876 return logicalOffset; | 795 return logicalOffset; |
| 877 LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargi
ns ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit()); | 796 LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargi
ns ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit()); |
| 878 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); | 797 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); |
| 879 updateMinimumPageHeight(logicalOffset, childLogicalHeight); | 798 updateMinimumPageHeight(logicalOffset, childLogicalHeight); |
| 880 if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight) | 799 if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight) |
| 881 return logicalOffset; | 800 return logicalOffset; |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1724 return childStyle.marginBeforeCollapse() == MSEPARATE; | 1643 return childStyle.marginBeforeCollapse() == MSEPARATE; |
| 1725 | 1644 |
| 1726 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 1645 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
| 1727 return false; | 1646 return false; |
| 1728 } | 1647 } |
| 1729 | 1648 |
| 1730 LayoutUnit LayoutBlockFlow::applyBeforeBreak(LayoutBox& child, LayoutUnit logica
lOffset) | 1649 LayoutUnit LayoutBlockFlow::applyBeforeBreak(LayoutBox& child, LayoutUnit logica
lOffset) |
| 1731 { | 1650 { |
| 1732 // FIXME: Add page break checking here when we support printing. | 1651 // FIXME: Add page break checking here when we support printing. |
| 1733 LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 1652 LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
| 1734 bool isInsideMulticolFlowThread = flowThread; | 1653 bool checkColumnBreaks = flowThread; |
| 1735 bool checkColumnBreaks = isInsideMulticolFlowThread || view()->layoutState()
->isPaginatingColumns(); | |
| 1736 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); // FIXME: Once columns can print we have to check this. | 1654 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); // FIXME: Once columns can print we have to check this. |
| 1737 bool checkBeforeAlways = (checkColumnBreaks && child.style()->columnBreakBef
ore() == PBALWAYS) | 1655 bool checkBeforeAlways = (checkColumnBreaks && child.style()->columnBreakBef
ore() == PBALWAYS) |
| 1738 || (checkPageBreaks && child.style()->pageBreakBefore() == PBALWAYS); | 1656 || (checkPageBreaks && child.style()->pageBreakBefore() == PBALWAYS); |
| 1739 if (checkBeforeAlways && inNormalFlow(&child)) { | 1657 if (checkBeforeAlways && inNormalFlow(&child)) { |
| 1740 if (checkColumnBreaks) { | 1658 if (checkColumnBreaks) { |
| 1741 if (isInsideMulticolFlowThread) { | 1659 LayoutUnit offsetBreakAdjustment = 0; |
| 1742 LayoutUnit offsetBreakAdjustment = 0; | 1660 if (flowThread->addForcedColumnBreak(offsetFromLogicalTopOfFirstPage
() + logicalOffset, &child, true, &offsetBreakAdjustment)) |
| 1743 if (flowThread->addForcedColumnBreak(offsetFromLogicalTopOfFirst
Page() + logicalOffset, &child, true, &offsetBreakAdjustment)) | 1661 return logicalOffset + offsetBreakAdjustment; |
| 1744 return logicalOffset + offsetBreakAdjustment; | |
| 1745 } else { | |
| 1746 view()->layoutState()->addForcedColumnBreak(child, logicalOffset
); | |
| 1747 } | |
| 1748 } | 1662 } |
| 1749 return nextPageLogicalTop(logicalOffset, IncludePageBoundary); | 1663 return nextPageLogicalTop(logicalOffset, IncludePageBoundary); |
| 1750 } | 1664 } |
| 1751 return logicalOffset; | 1665 return logicalOffset; |
| 1752 } | 1666 } |
| 1753 | 1667 |
| 1754 LayoutUnit LayoutBlockFlow::applyAfterBreak(LayoutBox& child, LayoutUnit logical
Offset, MarginInfo& marginInfo) | 1668 LayoutUnit LayoutBlockFlow::applyAfterBreak(LayoutBox& child, LayoutUnit logical
Offset, MarginInfo& marginInfo) |
| 1755 { | 1669 { |
| 1756 // FIXME: Add page break checking here when we support printing. | 1670 // FIXME: Add page break checking here when we support printing. |
| 1757 LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 1671 LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
| 1758 bool isInsideMulticolFlowThread = flowThread; | 1672 bool checkColumnBreaks = flowThread; |
| 1759 bool checkColumnBreaks = isInsideMulticolFlowThread || view()->layoutState()
->isPaginatingColumns(); | |
| 1760 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); // FIXME: Once columns can print we have to check this. | 1673 bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogi
calHeight(); // FIXME: Once columns can print we have to check this. |
| 1761 bool checkAfterAlways = (checkColumnBreaks && child.style()->columnBreakAfte
r() == PBALWAYS) | 1674 bool checkAfterAlways = (checkColumnBreaks && child.style()->columnBreakAfte
r() == PBALWAYS) |
| 1762 || (checkPageBreaks && child.style()->pageBreakAfter() == PBALWAYS); | 1675 || (checkPageBreaks && child.style()->pageBreakAfter() == PBALWAYS); |
| 1763 if (checkAfterAlways && inNormalFlow(&child)) { | 1676 if (checkAfterAlways && inNormalFlow(&child)) { |
| 1764 // So our margin doesn't participate in the next collapsing steps. | 1677 // So our margin doesn't participate in the next collapsing steps. |
| 1765 marginInfo.clearMargin(); | 1678 marginInfo.clearMargin(); |
| 1766 | 1679 |
| 1767 if (checkColumnBreaks) { | 1680 if (checkColumnBreaks) { |
| 1768 if (isInsideMulticolFlowThread) { | 1681 LayoutUnit offsetBreakAdjustment = 0; |
| 1769 LayoutUnit offsetBreakAdjustment = 0; | 1682 if (flowThread->addForcedColumnBreak(offsetFromLogicalTopOfFirstPage
() + logicalOffset, &child, false, &offsetBreakAdjustment)) |
| 1770 if (flowThread->addForcedColumnBreak(offsetFromLogicalTopOfFirst
Page() + logicalOffset, &child, false, &offsetBreakAdjustment)) | 1683 return logicalOffset + offsetBreakAdjustment; |
| 1771 return logicalOffset + offsetBreakAdjustment; | |
| 1772 } else { | |
| 1773 view()->layoutState()->addForcedColumnBreak(child, logicalOffset
); | |
| 1774 } | |
| 1775 } | 1684 } |
| 1776 return nextPageLogicalTop(logicalOffset, IncludePageBoundary); | 1685 return nextPageLogicalTop(logicalOffset, IncludePageBoundary); |
| 1777 } | 1686 } |
| 1778 return logicalOffset; | 1687 return logicalOffset; |
| 1779 } | 1688 } |
| 1780 | 1689 |
| 1781 void LayoutBlockFlow::addOverflowFromFloats() | 1690 void LayoutBlockFlow::addOverflowFromFloats() |
| 1782 { | 1691 { |
| 1783 if (!m_floatingObjects) | 1692 if (!m_floatingObjects) |
| 1784 return; | 1693 return; |
| 1785 | 1694 |
| 1786 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 1695 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
| 1787 FloatingObjectSetIterator end = floatingObjectSet.end(); | 1696 FloatingObjectSetIterator end = floatingObjectSet.end(); |
| 1788 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { | 1697 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++
it) { |
| 1789 FloatingObject* floatingObject = it->get(); | 1698 FloatingObject* floatingObject = it->get(); |
| 1790 if (floatingObject->isDescendant()) | 1699 if (floatingObject->isDescendant()) |
| 1791 addOverflowFromChild(floatingObject->layoutObject(), LayoutSize(xPos
itionForFloatIncludingMargin(floatingObject), yPositionForFloatIncludingMargin(f
loatingObject))); | 1700 addOverflowFromChild(floatingObject->layoutObject(), LayoutSize(xPos
itionForFloatIncludingMargin(floatingObject), yPositionForFloatIncludingMargin(f
loatingObject))); |
| 1792 } | 1701 } |
| 1793 } | 1702 } |
| 1794 | 1703 |
| 1795 void LayoutBlockFlow::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomp
uteFloats) | 1704 void LayoutBlockFlow::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomp
uteFloats) |
| 1796 { | 1705 { |
| 1797 LayoutBlock::computeOverflow(oldClientAfterEdge, recomputeFloats); | 1706 LayoutBlock::computeOverflow(oldClientAfterEdge, recomputeFloats); |
| 1798 if (!hasColumns() && (recomputeFloats || createsNewFormattingContext() || ha
sSelfPaintingLayer())) | 1707 if (recomputeFloats || createsNewFormattingContext() || hasSelfPaintingLayer
()) |
| 1799 addOverflowFromFloats(); | 1708 addOverflowFromFloats(); |
| 1800 } | 1709 } |
| 1801 | 1710 |
| 1802 RootInlineBox* LayoutBlockFlow::createAndAppendRootInlineBox() | 1711 RootInlineBox* LayoutBlockFlow::createAndAppendRootInlineBox() |
| 1803 { | 1712 { |
| 1804 RootInlineBox* rootBox = createRootInlineBox(); | 1713 RootInlineBox* rootBox = createRootInlineBox(); |
| 1805 m_lineBoxes.appendLineBox(rootBox); | 1714 m_lineBoxes.appendLineBox(rootBox); |
| 1806 | 1715 |
| 1807 return rootBox; | 1716 return rootBox; |
| 1808 } | 1717 } |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2104 paintInvalidationLogicalLeft = std::min(paintInvalidationLogicalLeft, lo
gicalLeftLayoutOverflow()); | 2013 paintInvalidationLogicalLeft = std::min(paintInvalidationLogicalLeft, lo
gicalLeftLayoutOverflow()); |
| 2105 paintInvalidationLogicalRight = std::max(paintInvalidationLogicalRight,
logicalRightLayoutOverflow()); | 2014 paintInvalidationLogicalRight = std::max(paintInvalidationLogicalRight,
logicalRightLayoutOverflow()); |
| 2106 } | 2015 } |
| 2107 | 2016 |
| 2108 LayoutRect paintInvalidationRect; | 2017 LayoutRect paintInvalidationRect; |
| 2109 if (isHorizontalWritingMode()) | 2018 if (isHorizontalWritingMode()) |
| 2110 paintInvalidationRect = LayoutRect(paintInvalidationLogicalLeft, m_paint
InvalidationLogicalTop, paintInvalidationLogicalRight - paintInvalidationLogical
Left, m_paintInvalidationLogicalBottom - m_paintInvalidationLogicalTop); | 2019 paintInvalidationRect = LayoutRect(paintInvalidationLogicalLeft, m_paint
InvalidationLogicalTop, paintInvalidationLogicalRight - paintInvalidationLogical
Left, m_paintInvalidationLogicalBottom - m_paintInvalidationLogicalTop); |
| 2111 else | 2020 else |
| 2112 paintInvalidationRect = LayoutRect(m_paintInvalidationLogicalTop, paintI
nvalidationLogicalLeft, m_paintInvalidationLogicalBottom - m_paintInvalidationLo
gicalTop, paintInvalidationLogicalRight - paintInvalidationLogicalLeft); | 2021 paintInvalidationRect = LayoutRect(m_paintInvalidationLogicalTop, paintI
nvalidationLogicalLeft, m_paintInvalidationLogicalBottom - m_paintInvalidationLo
gicalTop, paintInvalidationLogicalRight - paintInvalidationLogicalLeft); |
| 2113 | 2022 |
| 2114 // The paint invalidation rect may be split across columns, in which case ad
justRectForColumns() will return the union. | |
| 2115 adjustRectForColumns(paintInvalidationRect); | |
| 2116 | |
| 2117 if (hasOverflowClip()) { | 2023 if (hasOverflowClip()) { |
| 2118 // Adjust the paint invalidation rect for scroll offset | 2024 // Adjust the paint invalidation rect for scroll offset |
| 2119 paintInvalidationRect.move(-scrolledContentOffset()); | 2025 paintInvalidationRect.move(-scrolledContentOffset()); |
| 2120 | 2026 |
| 2121 // Don't allow this rect to spill out of our overflow box. | 2027 // Don't allow this rect to spill out of our overflow box. |
| 2122 paintInvalidationRect.intersect(LayoutRect(LayoutPoint(), size())); | 2028 paintInvalidationRect.intersect(LayoutRect(LayoutPoint(), size())); |
| 2123 } | 2029 } |
| 2124 | 2030 |
| 2125 // Make sure the rect is still non-empty after intersecting for overflow abo
ve | 2031 // Make sure the rect is still non-empty after intersecting for overflow abo
ve |
| 2126 if (!paintInvalidationRect.isEmpty()) { | 2032 if (!paintInvalidationRect.isEmpty()) { |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2499 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(*childB
ox)); | 2405 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(*childB
ox)); |
| 2500 | 2406 |
| 2501 if (width) | 2407 if (width) |
| 2502 width->shrinkAvailableWidthForNewFloatIfNeeded(floatingObject); | 2408 width->shrinkAvailableWidthForNewFloatIfNeeded(floatingObject); |
| 2503 } | 2409 } |
| 2504 return true; | 2410 return true; |
| 2505 } | 2411 } |
| 2506 | 2412 |
| 2507 bool LayoutBlockFlow::hasOverhangingFloat(LayoutBox* layoutBox) | 2413 bool LayoutBlockFlow::hasOverhangingFloat(LayoutBox* layoutBox) |
| 2508 { | 2414 { |
| 2509 if (!m_floatingObjects || hasColumns() || !parent()) | 2415 if (!m_floatingObjects || !parent()) |
| 2510 return false; | 2416 return false; |
| 2511 | 2417 |
| 2512 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 2418 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
| 2513 FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHashTran
slator>(layoutBox); | 2419 FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHashTran
slator>(layoutBox); |
| 2514 if (it == floatingObjectSet.end()) | 2420 if (it == floatingObjectSet.end()) |
| 2515 return false; | 2421 return false; |
| 2516 | 2422 |
| 2517 return logicalBottomForFloat(it->get()) > logicalHeight(); | 2423 return logicalBottomForFloat(it->get()) > logicalHeight(); |
| 2518 } | 2424 } |
| 2519 | 2425 |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2745 flippedBlockRect.moveBy(rootBlockPhysicalPosition); | 2651 flippedBlockRect.moveBy(rootBlockPhysicalPosition); |
| 2746 clipOutPositionedObjects(*clipScope, flippedBlockRect.location(), positi
onedObjects()); | 2652 clipOutPositionedObjects(*clipScope, flippedBlockRect.location(), positi
onedObjects()); |
| 2747 if (isBody() || isDocumentElement()) // The <body> must make sure to exa
mine its containingBlock's positioned objects. | 2653 if (isBody() || isDocumentElement()) // The <body> must make sure to exa
mine its containingBlock's positioned objects. |
| 2748 for (LayoutBlock* cb = containingBlock(); cb && !cb->isLayoutView();
cb = cb->containingBlock()) | 2654 for (LayoutBlock* cb = containingBlock(); cb && !cb->isLayoutView();
cb = cb->containingBlock()) |
| 2749 clipOutPositionedObjects(*clipScope, cb->location(), cb->positio
nedObjects()); // FIXME: Not right for flipped writing modes. | 2655 clipOutPositionedObjects(*clipScope, cb->location(), cb->positio
nedObjects()); // FIXME: Not right for flipped writing modes. |
| 2750 clipOutFloatingObjects(rootBlock, *clipScope, rootBlockPhysicalPosition,
offsetFromRootBlock); | 2656 clipOutFloatingObjects(rootBlock, *clipScope, rootBlockPhysicalPosition,
offsetFromRootBlock); |
| 2751 } | 2657 } |
| 2752 | 2658 |
| 2753 GapRects result; | 2659 GapRects result; |
| 2754 | 2660 |
| 2755 if (hasColumns() || hasTransformRelatedProperty() || style()->columnSpan()) | 2661 if (hasTransformRelatedProperty() || style()->columnSpan()) |
| 2756 return result; | 2662 return result; |
| 2757 | 2663 |
| 2758 if (childrenInline()) | 2664 if (childrenInline()) |
| 2759 result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offse
tFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); | 2665 result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offse
tFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); |
| 2760 else | 2666 else |
| 2761 result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offset
FromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); | 2667 result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offset
FromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); |
| 2762 | 2668 |
| 2763 // Go ahead and fill the vertical gap all the way to the bottom of our block
if the selection extends past our block. | 2669 // Go ahead and fill the vertical gap all the way to the bottom of our block
if the selection extends past our block. |
| 2764 if (rootBlock == this && (selectionState() != SelectionBoth && selectionStat
e() != SelectionEnd)) { | 2670 if (rootBlock == this && (selectionState() != SelectionBoth && selectionStat
e() != SelectionEnd)) { |
| 2765 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPositio
n, offsetFromRootBlock, | 2671 result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPositio
n, offsetFromRootBlock, |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3061 // Paged overflow is currently done using the multicol implementation. | 2967 // Paged overflow is currently done using the multicol implementation. |
| 3062 return LayoutPagedFlowThread::createAnonymous(document(), styleRef()); | 2968 return LayoutPagedFlowThread::createAnonymous(document(), styleRef()); |
| 3063 default: | 2969 default: |
| 3064 ASSERT_NOT_REACHED(); | 2970 ASSERT_NOT_REACHED(); |
| 3065 return nullptr; | 2971 return nullptr; |
| 3066 } | 2972 } |
| 3067 } | 2973 } |
| 3068 | 2974 |
| 3069 void LayoutBlockFlow::createOrDestroyMultiColumnFlowThreadIfNeeded(const Compute
dStyle* oldStyle) | 2975 void LayoutBlockFlow::createOrDestroyMultiColumnFlowThreadIfNeeded(const Compute
dStyle* oldStyle) |
| 3070 { | 2976 { |
| 3071 if (!RuntimeEnabledFeatures::regionBasedColumnsEnabled()) | |
| 3072 return; | |
| 3073 | |
| 3074 // Paged overflow trumps multicol in this implementation. Ideally, it should
be possible to have | 2977 // Paged overflow trumps multicol in this implementation. Ideally, it should
be possible to have |
| 3075 // both paged overflow and multicol on the same element, but then we need tw
o flow | 2978 // both paged overflow and multicol on the same element, but then we need tw
o flow |
| 3076 // threads. Anyway, this is nothing to worry about until we can actually nes
t multicol properly | 2979 // threads. Anyway, this is nothing to worry about until we can actually nes
t multicol properly |
| 3077 // inside other fragmentation contexts. | 2980 // inside other fragmentation contexts. |
| 3078 FlowThreadType type = flowThreadType(styleRef()); | 2981 FlowThreadType type = flowThreadType(styleRef()); |
| 3079 | 2982 |
| 3080 if (multiColumnFlowThread()) { | 2983 if (multiColumnFlowThread()) { |
| 3081 ASSERT(oldStyle); | 2984 ASSERT(oldStyle); |
| 3082 if (type != flowThreadType(*oldStyle)) { | 2985 if (type != flowThreadType(*oldStyle)) { |
| 3083 // If we're no longer to be multicol/paged, destroy the flow thread.
Also destroy it | 2986 // If we're no longer to be multicol/paged, destroy the flow thread.
Also destroy it |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3150 FrameView* frameView = document().view(); | 3053 FrameView* frameView = document().view(); |
| 3151 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); | 3054 LayoutUnit top = (style()->position() == FixedPosition) ? 0 : frameView->scr
ollOffset().height(); |
| 3152 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); | 3055 int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height(
); |
| 3153 if (size().height() < visibleHeight) | 3056 if (size().height() < visibleHeight) |
| 3154 top += (visibleHeight - size().height()) / 2; | 3057 top += (visibleHeight - size().height()) / 2; |
| 3155 setY(top); | 3058 setY(top); |
| 3156 dialog->setCentered(top); | 3059 dialog->setCentered(top); |
| 3157 } | 3060 } |
| 3158 | 3061 |
| 3159 } // namespace blink | 3062 } // namespace blink |
| OLD | NEW |