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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 // Some features, such as floats, margin collapsing and fragmentation, require | 200 // Some features, such as floats, margin collapsing and fragmentation, require |
201 // some knowledge about things that happened when laying out previous block | 201 // some knowledge about things that happened when laying out previous block |
202 // child siblings. Only looking at the object currently being laid out isn't | 202 // child siblings. Only looking at the object currently being laid out isn't |
203 // always enough. | 203 // always enough. |
204 class BlockChildrenLayoutInfo { | 204 class BlockChildrenLayoutInfo { |
205 public: | 205 public: |
206 BlockChildrenLayoutInfo(LayoutBlockFlow* blockFlow, | 206 BlockChildrenLayoutInfo(LayoutBlockFlow* blockFlow, |
207 LayoutUnit beforeEdge, | 207 LayoutUnit beforeEdge, |
208 LayoutUnit afterEdge) | 208 LayoutUnit afterEdge) |
209 : m_marginInfo(blockFlow, beforeEdge, afterEdge), | 209 : m_marginInfo(blockFlow, beforeEdge, afterEdge), |
210 m_previousBreakAfterValue(BreakAuto), | 210 m_previousBreakAfterValue(EBreakBetween::kAuto), |
211 m_isAtFirstInFlowChild(true) {} | 211 m_isAtFirstInFlowChild(true) {} |
212 | 212 |
213 // Store multicol layout state before first layout of a block child. The child | 213 // Store multicol layout state before first layout of a block child. The child |
214 // may contain a column spanner. If we need to re-lay out the block child | 214 // may contain a column spanner. If we need to re-lay out the block child |
215 // because our initial logical top estimate was wrong, we need to roll back to | 215 // because our initial logical top estimate was wrong, we need to roll back to |
216 // how things were before laying out the child. | 216 // how things were before laying out the child. |
217 void storeMultiColumnLayoutState(const LayoutFlowThread& flowThread) { | 217 void storeMultiColumnLayoutState(const LayoutFlowThread& flowThread) { |
218 m_multiColumnLayoutState = flowThread.multiColumnLayoutState(); | 218 m_multiColumnLayoutState = flowThread.multiColumnLayoutState(); |
219 } | 219 } |
220 void rollBackToInitialMultiColumnLayoutState(LayoutFlowThread& flowThread) { | 220 void rollBackToInitialMultiColumnLayoutState(LayoutFlowThread& flowThread) { |
221 flowThread.restoreMultiColumnLayoutState(m_multiColumnLayoutState); | 221 flowThread.restoreMultiColumnLayoutState(m_multiColumnLayoutState); |
222 } | 222 } |
223 | 223 |
224 const MarginInfo& marginInfo() const { return m_marginInfo; } | 224 const MarginInfo& marginInfo() const { return m_marginInfo; } |
225 MarginInfo& marginInfo() { return m_marginInfo; } | 225 MarginInfo& marginInfo() { return m_marginInfo; } |
226 LayoutUnit& previousFloatLogicalBottom() { | 226 LayoutUnit& previousFloatLogicalBottom() { |
227 return m_previousFloatLogicalBottom; | 227 return m_previousFloatLogicalBottom; |
228 } | 228 } |
229 | 229 |
230 EBreak previousBreakAfterValue() const { return m_previousBreakAfterValue; } | 230 EBreakBetween previousBreakAfterValue() const { |
231 void setPreviousBreakAfterValue(EBreak value) { | 231 return m_previousBreakAfterValue; |
| 232 } |
| 233 void setPreviousBreakAfterValue(EBreakBetween value) { |
232 m_previousBreakAfterValue = value; | 234 m_previousBreakAfterValue = value; |
233 } | 235 } |
234 | 236 |
235 bool isAtFirstInFlowChild() const { return m_isAtFirstInFlowChild; } | 237 bool isAtFirstInFlowChild() const { return m_isAtFirstInFlowChild; } |
236 void clearIsAtFirstInFlowChild() { m_isAtFirstInFlowChild = false; } | 238 void clearIsAtFirstInFlowChild() { m_isAtFirstInFlowChild = false; } |
237 | 239 |
238 private: | 240 private: |
239 MultiColumnLayoutState m_multiColumnLayoutState; | 241 MultiColumnLayoutState m_multiColumnLayoutState; |
240 MarginInfo m_marginInfo; | 242 MarginInfo m_marginInfo; |
241 LayoutUnit m_previousFloatLogicalBottom; | 243 LayoutUnit m_previousFloatLogicalBottom; |
242 EBreak m_previousBreakAfterValue; | 244 EBreakBetween m_previousBreakAfterValue; |
243 bool m_isAtFirstInFlowChild; | 245 bool m_isAtFirstInFlowChild; |
244 }; | 246 }; |
245 | 247 |
246 LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) : LayoutBlock(node) { | 248 LayoutBlockFlow::LayoutBlockFlow(ContainerNode* node) : LayoutBlock(node) { |
247 static_assert(sizeof(MarginInfo) == sizeof(SameSizeAsMarginInfo), | 249 static_assert(sizeof(MarginInfo) == sizeof(SameSizeAsMarginInfo), |
248 "MarginInfo should stay small"); | 250 "MarginInfo should stay small"); |
249 setChildrenInline(true); | 251 setChildrenInline(true); |
250 } | 252 } |
251 | 253 |
252 LayoutBlockFlow::~LayoutBlockFlow() {} | 254 LayoutBlockFlow::~LayoutBlockFlow() {} |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 // siblings), so steal its break value and join it with what we already have | 749 // siblings), so steal its break value and join it with what we already have |
748 // here. | 750 // here. |
749 setBreakBefore( | 751 setBreakBefore( |
750 joinFragmentainerBreakValues(breakBefore(), child.breakBefore())); | 752 joinFragmentainerBreakValues(breakBefore(), child.breakBefore())); |
751 return; | 753 return; |
752 } | 754 } |
753 | 755 |
754 // Figure out if a forced break should be inserted in front of the child. If | 756 // Figure out if a forced break should be inserted in front of the child. If |
755 // we insert a forced break, the margins on this child may not collapse with | 757 // we insert a forced break, the margins on this child may not collapse with |
756 // those preceding the break. | 758 // those preceding the break. |
757 EBreak classABreakPointValue = | 759 EBreakBetween classABreakPointValue = |
758 child.classABreakPointValue(layoutInfo.previousBreakAfterValue()); | 760 child.classABreakPointValue(layoutInfo.previousBreakAfterValue()); |
759 if (isForcedFragmentainerBreakValue(classABreakPointValue)) { | 761 if (isForcedFragmentainerBreakValue(classABreakPointValue)) { |
760 layoutInfo.marginInfo().clearMargin(); | 762 layoutInfo.marginInfo().clearMargin(); |
761 LayoutUnit oldLogicalTop = logicalHeight(); | 763 LayoutUnit oldLogicalTop = logicalHeight(); |
762 LayoutUnit newLogicalTop = | 764 LayoutUnit newLogicalTop = |
763 applyForcedBreak(oldLogicalTop, classABreakPointValue); | 765 applyForcedBreak(oldLogicalTop, classABreakPointValue); |
764 setLogicalHeight(newLogicalTop); | 766 setLogicalHeight(newLogicalTop); |
765 LayoutUnit paginationStrut = newLogicalTop - oldLogicalTop; | 767 LayoutUnit paginationStrut = newLogicalTop - oldLogicalTop; |
766 child.setPaginationStrut(paginationStrut); | 768 child.setPaginationStrut(paginationStrut); |
767 } | 769 } |
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2111 | 2113 |
2112 estimateWithoutPagination = logicalTopEstimate; | 2114 estimateWithoutPagination = logicalTopEstimate; |
2113 | 2115 |
2114 if (layoutState->isPaginated()) { | 2116 if (layoutState->isPaginated()) { |
2115 if (!layoutInfo.isAtFirstInFlowChild()) { | 2117 if (!layoutInfo.isAtFirstInFlowChild()) { |
2116 // Estimate the need for a forced break in front of this child. The final | 2118 // Estimate the need for a forced break in front of this child. The final |
2117 // break policy at this class A break point isn't known until we have laid | 2119 // break policy at this class A break point isn't known until we have laid |
2118 // out the children of |child|. There may be forced break-before values | 2120 // out the children of |child|. There may be forced break-before values |
2119 // set on first-children inside that get propagated up to the child. | 2121 // set on first-children inside that get propagated up to the child. |
2120 // Just make an estimate with what we know so far. | 2122 // Just make an estimate with what we know so far. |
2121 EBreak breakValue = | 2123 EBreakBetween breakValue = |
2122 child.classABreakPointValue(layoutInfo.previousBreakAfterValue()); | 2124 child.classABreakPointValue(layoutInfo.previousBreakAfterValue()); |
2123 if (isForcedFragmentainerBreakValue(breakValue)) { | 2125 if (isForcedFragmentainerBreakValue(breakValue)) { |
2124 logicalTopEstimate = applyForcedBreak(logicalHeight(), breakValue); | 2126 logicalTopEstimate = applyForcedBreak(logicalHeight(), breakValue); |
2125 // Disregard previous margins, since they will collapse with the | 2127 // Disregard previous margins, since they will collapse with the |
2126 // fragmentainer boundary, due to the forced break. Only apply margins | 2128 // fragmentainer boundary, due to the forced break. Only apply margins |
2127 // that have been specified on the child or its descendants. | 2129 // that have been specified on the child or its descendants. |
2128 if (!discardMarginBefore) | 2130 if (!discardMarginBefore) |
2129 logicalTopEstimate += positiveMarginBefore - negativeMarginBefore; | 2131 logicalTopEstimate += positiveMarginBefore - negativeMarginBefore; |
2130 | 2132 |
2131 // Clearance may already have taken us past the beginning of the next | 2133 // Clearance may already have taken us past the beginning of the next |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2332 if (!child.isWritingModeRoot()) | 2334 if (!child.isWritingModeRoot()) |
2333 return childStyle.marginAfterCollapse() == MarginCollapseSeparate; | 2335 return childStyle.marginAfterCollapse() == MarginCollapseSeparate; |
2334 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) | 2336 if (child.isHorizontalWritingMode() == isHorizontalWritingMode()) |
2335 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; | 2337 return childStyle.marginBeforeCollapse() == MarginCollapseSeparate; |
2336 | 2338 |
2337 // FIXME: See |mustDiscardMarginBeforeForChild| above. | 2339 // FIXME: See |mustDiscardMarginBeforeForChild| above. |
2338 return false; | 2340 return false; |
2339 } | 2341 } |
2340 | 2342 |
2341 LayoutUnit LayoutBlockFlow::applyForcedBreak(LayoutUnit logicalOffset, | 2343 LayoutUnit LayoutBlockFlow::applyForcedBreak(LayoutUnit logicalOffset, |
2342 EBreak breakValue) { | 2344 EBreakBetween breakValue) { |
2343 if (!isForcedFragmentainerBreakValue(breakValue)) | 2345 if (!isForcedFragmentainerBreakValue(breakValue)) |
2344 return logicalOffset; | 2346 return logicalOffset; |
2345 // TODO(mstensho): honor breakValue. There are different types of forced | 2347 // TODO(mstensho): honor breakValue. There are different types of forced |
2346 // breaks. We currently just assume that we want to break to the top of the | 2348 // breaks. We currently just assume that we want to break to the top of the |
2347 // next fragmentainer of the fragmentation context we're in. However, we may | 2349 // next fragmentainer of the fragmentation context we're in. However, we may |
2348 // want to find the next left or right page - even if we're inside a multicol | 2350 // want to find the next left or right page - even if we're inside a multicol |
2349 // container when printing. | 2351 // container when printing. |
2350 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); | 2352 LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset); |
2351 if (!pageLogicalHeight) | 2353 if (!pageLogicalHeight) |
2352 return logicalOffset; // Page height is still unknown, so we cannot insert | 2354 return logicalOffset; // Page height is still unknown, so we cannot insert |
2353 // forced breaks. | 2355 // forced breaks. |
2354 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset( | 2356 LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset( |
2355 logicalOffset, AssociateWithLatterPage); | 2357 logicalOffset, AssociateWithLatterPage); |
2356 if (remainingLogicalHeight == pageLogicalHeight) | 2358 if (remainingLogicalHeight == pageLogicalHeight) |
2357 return logicalOffset; // Don't break if we're already at the block start of | 2359 return logicalOffset; // Don't break if we're already at the block start of |
2358 // a fragmentainer. | 2360 // a fragmentainer. |
2359 | 2361 |
2360 // If this is the first forced break inside this object, store the | 2362 // If this is the first forced break inside this object, store the |
2361 // location. We need this information later if there's a break-inside:avoid | 2363 // location. We need this information later if there's a break-inside:avoid |
2362 // object further up. We need to know if there are any forced breaks inside | 2364 // object further up. We need to know if there are any forced breaks inside |
2363 // such objects, in order to determine whether we need to push it to the next | 2365 // such objects, in order to determine whether we need to push it to the next |
2364 // fragmentainer or not. | 2366 // fragmentainer or not. |
2365 if (!firstForcedBreakOffset()) | 2367 if (!firstForcedBreakOffset()) |
2366 setFirstForcedBreakOffset(logicalOffset); | 2368 setFirstForcedBreakOffset(logicalOffset); |
2367 | 2369 |
2368 return logicalOffset + remainingLogicalHeight; | 2370 return logicalOffset + remainingLogicalHeight; |
2369 } | 2371 } |
2370 | 2372 |
2371 void LayoutBlockFlow::setBreakBefore(EBreak breakValue) { | 2373 void LayoutBlockFlow::setBreakBefore(EBreakBetween breakValue) { |
2372 if (breakValue != BreakAuto && !isBreakBetweenControllable(breakValue)) | 2374 if (breakValue != EBreakBetween::kAuto && |
2373 breakValue = BreakAuto; | 2375 !isBreakBetweenControllable(breakValue)) |
2374 if (breakValue == BreakAuto && !m_rareData) | 2376 breakValue = EBreakBetween::kAuto; |
| 2377 if (breakValue == EBreakBetween::kAuto && !m_rareData) |
2375 return; | 2378 return; |
2376 ensureRareData().m_breakBefore = breakValue; | 2379 ensureRareData().m_breakBefore = static_cast<unsigned>(breakValue); |
2377 } | 2380 } |
2378 | 2381 |
2379 void LayoutBlockFlow::setBreakAfter(EBreak breakValue) { | 2382 void LayoutBlockFlow::setBreakAfter(EBreakBetween breakValue) { |
2380 if (breakValue != BreakAuto && !isBreakBetweenControllable(breakValue)) | 2383 if (breakValue != EBreakBetween::kAuto && |
2381 breakValue = BreakAuto; | 2384 !isBreakBetweenControllable(breakValue)) |
2382 if (breakValue == BreakAuto && !m_rareData) | 2385 breakValue = EBreakBetween::kAuto; |
| 2386 if (breakValue == EBreakBetween::kAuto && !m_rareData) |
2383 return; | 2387 return; |
2384 ensureRareData().m_breakAfter = breakValue; | 2388 ensureRareData().m_breakAfter = static_cast<unsigned>(breakValue); |
2385 } | 2389 } |
2386 | 2390 |
2387 EBreak LayoutBlockFlow::breakBefore() const { | 2391 EBreakBetween LayoutBlockFlow::breakBefore() const { |
2388 return m_rareData ? static_cast<EBreak>(m_rareData->m_breakBefore) | 2392 return m_rareData ? static_cast<EBreakBetween>(m_rareData->m_breakBefore) |
2389 : BreakAuto; | 2393 : EBreakBetween::kAuto; |
2390 } | 2394 } |
2391 | 2395 |
2392 EBreak LayoutBlockFlow::breakAfter() const { | 2396 EBreakBetween LayoutBlockFlow::breakAfter() const { |
2393 return m_rareData ? static_cast<EBreak>(m_rareData->m_breakAfter) : BreakAuto; | 2397 return m_rareData ? static_cast<EBreakBetween>(m_rareData->m_breakAfter) |
| 2398 : EBreakBetween::kAuto; |
2394 } | 2399 } |
2395 | 2400 |
2396 void LayoutBlockFlow::addOverflowFromFloats() { | 2401 void LayoutBlockFlow::addOverflowFromFloats() { |
2397 if (!m_floatingObjects) | 2402 if (!m_floatingObjects) |
2398 return; | 2403 return; |
2399 | 2404 |
2400 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); | 2405 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); |
2401 FloatingObjectSetIterator end = floatingObjectSet.end(); | 2406 FloatingObjectSetIterator end = floatingObjectSet.end(); |
2402 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; | 2407 for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; |
2403 ++it) { | 2408 ++it) { |
(...skipping 2196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4600 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); | 4605 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); |
4601 } | 4606 } |
4602 | 4607 |
4603 void LayoutBlockFlow::invalidateDisplayItemClients( | 4608 void LayoutBlockFlow::invalidateDisplayItemClients( |
4604 PaintInvalidationReason invalidationReason) const { | 4609 PaintInvalidationReason invalidationReason) const { |
4605 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( | 4610 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( |
4606 invalidationReason); | 4611 invalidationReason); |
4607 } | 4612 } |
4608 | 4613 |
4609 } // namespace blink | 4614 } // namespace blink |
OLD | NEW |