| 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 |