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 |