OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) |
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) |
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. | 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. |
7 * All rights reserved. | 7 * All rights reserved. |
8 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. | 8 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 2094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2105 return; | 2105 return; |
2106 m_rareData->m_spannerPlaceholder = nullptr; | 2106 m_rareData->m_spannerPlaceholder = nullptr; |
2107 } | 2107 } |
2108 | 2108 |
2109 void LayoutBox::setPaginationStrut(LayoutUnit strut) { | 2109 void LayoutBox::setPaginationStrut(LayoutUnit strut) { |
2110 if (!strut && !m_rareData) | 2110 if (!strut && !m_rareData) |
2111 return; | 2111 return; |
2112 ensureRareData().m_paginationStrut = strut; | 2112 ensureRareData().m_paginationStrut = strut; |
2113 } | 2113 } |
2114 | 2114 |
2115 bool LayoutBox::isBreakBetweenControllable(EBreak breakValue) const { | 2115 bool LayoutBox::isBreakBetweenControllable(EBreakBetween breakValue) const { |
2116 if (breakValue == BreakAuto) | 2116 if (breakValue == EBreakBetween::kAuto) |
2117 return true; | 2117 return true; |
2118 // We currently only support non-auto break-before and break-after values on | 2118 // We currently only support non-auto break-before and break-after values on |
2119 // in-flow block level elements, which is the minimum requirement according to | 2119 // in-flow block level elements, which is the minimum requirement according to |
2120 // the spec. | 2120 // the spec. |
2121 if (isInline() || isFloatingOrOutOfFlowPositioned()) | 2121 if (isInline() || isFloatingOrOutOfFlowPositioned()) |
2122 return false; | 2122 return false; |
2123 const LayoutBlock* curr = containingBlock(); | 2123 const LayoutBlock* curr = containingBlock(); |
2124 if (!curr || !curr->isLayoutBlockFlow()) | 2124 if (!curr || !curr->isLayoutBlockFlow()) |
2125 return false; | 2125 return false; |
2126 const LayoutView* layoutView = view(); | 2126 const LayoutView* layoutView = view(); |
2127 bool viewIsPaginated = layoutView->fragmentationContext(); | 2127 bool viewIsPaginated = layoutView->fragmentationContext(); |
2128 if (!viewIsPaginated && !flowThreadContainingBlock()) | 2128 if (!viewIsPaginated && !flowThreadContainingBlock()) |
2129 return false; | 2129 return false; |
2130 while (curr) { | 2130 while (curr) { |
2131 if (curr == layoutView) | 2131 if (curr == layoutView) { |
2132 return viewIsPaginated && breakValue != BreakColumn && | 2132 return viewIsPaginated && breakValue != EBreakBetween::kColumn && |
2133 breakValue != BreakAvoidColumn; | 2133 breakValue != EBreakBetween::kAvoidColumn; |
2134 } | |
2134 if (curr->isLayoutFlowThread()) { | 2135 if (curr->isLayoutFlowThread()) { |
2135 if (breakValue == | 2136 if (breakValue == |
2136 BreakAvoid) // Valid in any kind of fragmentation context. | 2137 EBreakBetween::kAvoid) // Valid in any kind of fragmentation context. |
2137 return true; | 2138 return true; |
2138 bool isMulticolValue = | 2139 bool isMulticolValue = breakValue == EBreakBetween::kColumn || |
2139 breakValue == BreakColumn || breakValue == BreakAvoidColumn; | 2140 breakValue == EBreakBetween::kAvoidColumn; |
2140 if (toLayoutFlowThread(curr)->isLayoutPagedFlowThread()) | 2141 if (toLayoutFlowThread(curr)->isLayoutPagedFlowThread()) |
2141 return !isMulticolValue; | 2142 return !isMulticolValue; |
2142 if (isMulticolValue) | 2143 if (isMulticolValue) |
2143 return true; | 2144 return true; |
2144 // If this is a flow thread for a multicol container, and we have a break | 2145 // If this is a flow thread for a multicol container, and we have a break |
2145 // value for paged, we need to keep looking. | 2146 // value for paged, we need to keep looking. |
2146 } | 2147 } |
2147 if (curr->isFloatingOrOutOfFlowPositioned()) | 2148 if (curr->isFloatingOrOutOfFlowPositioned()) |
2148 return false; | 2149 return false; |
2149 curr = curr->containingBlock(); | 2150 curr = curr->containingBlock(); |
2150 } | 2151 } |
2151 ASSERT_NOT_REACHED(); | 2152 ASSERT_NOT_REACHED(); |
2152 return false; | 2153 return false; |
2153 } | 2154 } |
2154 | 2155 |
2155 bool LayoutBox::isBreakInsideControllable(EBreak breakValue) const { | 2156 bool LayoutBox::isBreakInsideControllable(EBreakInside breakValue) const { |
2156 ASSERT(!isForcedFragmentainerBreakValue(breakValue)); | 2157 if (breakValue == EBreakInside::kAuto) |
2157 if (breakValue == BreakAuto) | |
amoylan
2017/02/07 04:35:02
This ASSERT is not required now that we have split
mstensho (USE GERRIT)
2017/02/07 10:21:34
Acknowledged. Good stuff!
| |
2158 return true; | 2158 return true; |
2159 // First check multicol. | 2159 // First check multicol. |
2160 const LayoutFlowThread* flowThread = flowThreadContainingBlock(); | 2160 const LayoutFlowThread* flowThread = flowThreadContainingBlock(); |
2161 // 'avoid-column' is only valid in a multicol context. | 2161 // 'avoid-column' is only valid in a multicol context. |
2162 if (breakValue == BreakAvoidColumn) | 2162 if (breakValue == EBreakInside::kAvoidColumn) |
2163 return flowThread && !flowThread->isLayoutPagedFlowThread(); | 2163 return flowThread && !flowThread->isLayoutPagedFlowThread(); |
2164 // 'avoid' is valid in any kind of fragmentation context. | 2164 // 'avoid' is valid in any kind of fragmentation context. |
2165 if (breakValue == BreakAvoid && flowThread) | 2165 if (breakValue == EBreakInside::kAvoid && flowThread) |
2166 return true; | 2166 return true; |
2167 ASSERT(breakValue == BreakAvoidPage || breakValue == BreakAvoid); | 2167 DCHECK(breakValue == EBreakInside::kAvoidPage || |
2168 breakValue == EBreakInside::kAvoid); | |
2168 if (view()->fragmentationContext()) | 2169 if (view()->fragmentationContext()) |
2169 return true; // The view is paginated, probably because we're printing. | 2170 return true; // The view is paginated, probably because we're printing. |
2170 if (!flowThread) | 2171 if (!flowThread) |
2171 return false; // We're not inside any pagination context | 2172 return false; // We're not inside any pagination context |
2172 // We're inside a flow thread. We need to be contained by a flow thread for | 2173 // We're inside a flow thread. We need to be contained by a flow thread for |
2173 // paged overflow in order for pagination values to be valid, though. | 2174 // paged overflow in order for pagination values to be valid, though. |
2174 for (const LayoutBlock* ancestor = flowThread; ancestor; | 2175 for (const LayoutBlock* ancestor = flowThread; ancestor; |
2175 ancestor = ancestor->containingBlock()) { | 2176 ancestor = ancestor->containingBlock()) { |
2176 if (ancestor->isLayoutFlowThread() && | 2177 if (ancestor->isLayoutFlowThread() && |
2177 toLayoutFlowThread(ancestor)->isLayoutPagedFlowThread()) | 2178 toLayoutFlowThread(ancestor)->isLayoutPagedFlowThread()) |
2178 return true; | 2179 return true; |
2179 } | 2180 } |
2180 return false; | 2181 return false; |
2181 } | 2182 } |
2182 | 2183 |
2183 EBreak LayoutBox::breakAfter() const { | 2184 EBreakBetween LayoutBox::breakAfter() const { |
2184 EBreak breakValue = style()->breakAfter(); | 2185 EBreakBetween breakValue = style()->breakAfter(); |
2185 if (breakValue == BreakAuto || isBreakBetweenControllable(breakValue)) | 2186 if (breakValue == EBreakBetween::kAuto || |
2187 isBreakBetweenControllable(breakValue)) | |
2186 return breakValue; | 2188 return breakValue; |
2187 return BreakAuto; | 2189 return EBreakBetween::kAuto; |
2188 } | 2190 } |
2189 | 2191 |
2190 EBreak LayoutBox::breakBefore() const { | 2192 EBreakBetween LayoutBox::breakBefore() const { |
2191 EBreak breakValue = style()->breakBefore(); | 2193 EBreakBetween breakValue = style()->breakBefore(); |
2192 if (breakValue == BreakAuto || isBreakBetweenControllable(breakValue)) | 2194 if (breakValue == EBreakBetween::kAuto || |
2195 isBreakBetweenControllable(breakValue)) | |
2193 return breakValue; | 2196 return breakValue; |
2194 return BreakAuto; | 2197 return EBreakBetween::kAuto; |
2195 } | 2198 } |
2196 | 2199 |
2197 EBreak LayoutBox::breakInside() const { | 2200 EBreakInside LayoutBox::breakInside() const { |
2198 EBreak breakValue = style()->breakInside(); | 2201 EBreakInside breakValue = style()->breakInside(); |
2199 if (breakValue == BreakAuto || isBreakInsideControllable(breakValue)) | 2202 if (breakValue == EBreakInside::kAuto || |
2203 isBreakInsideControllable(breakValue)) | |
2200 return breakValue; | 2204 return breakValue; |
2201 return BreakAuto; | 2205 return EBreakInside::kAuto; |
2202 } | 2206 } |
2203 | 2207 |
2204 // At a class A break point [1], the break value with the highest precedence | 2208 // At a class A break point [1], the break value with the highest precedence |
2205 // wins. If the two values have the same precedence (e.g. "left" and "right"), | 2209 // wins. If the two values have the same precedence (e.g. "left" and "right"), |
2206 // the value specified on a latter object wins. | 2210 // the value specified on a latter object wins. |
2207 // | 2211 // |
2208 // [1] https://drafts.csswg.org/css-break/#possible-breaks | 2212 // [1] https://drafts.csswg.org/css-break/#possible-breaks |
2209 static inline int fragmentainerBreakPrecedence(EBreak breakValue) { | 2213 static inline int fragmentainerBreakPrecedence(EBreakBetween breakValue) { |
2210 // "auto" has the lowest priority. | 2214 // "auto" has the lowest priority. |
2211 // "avoid*" values win over "auto". | 2215 // "avoid*" values win over "auto". |
2212 // "avoid-page" wins over "avoid-column". | 2216 // "avoid-page" wins over "avoid-column". |
2213 // "avoid" wins over "avoid-page". | 2217 // "avoid" wins over "avoid-page". |
2214 // Forced break values win over "avoid". | 2218 // Forced break values win over "avoid". |
2215 // Any forced page break value wins over "column" forced break. | 2219 // Any forced page break value wins over "column" forced break. |
2216 // More specific break values (left, right, recto, verso) wins over generic | 2220 // More specific break values (left, right, recto, verso) wins over generic |
2217 // "page" values. | 2221 // "page" values. |
2218 | 2222 |
2219 switch (breakValue) { | 2223 switch (breakValue) { |
2220 default: | 2224 default: |
2221 ASSERT_NOT_REACHED(); | 2225 ASSERT_NOT_REACHED(); |
2222 // fall-through | 2226 // fall-through |
2223 case BreakAuto: | 2227 case EBreakBetween::kAuto: |
2224 return 0; | 2228 return 0; |
2225 case BreakAvoidColumn: | 2229 case EBreakBetween::kAvoidColumn: |
2226 return 1; | 2230 return 1; |
2227 case BreakAvoidPage: | 2231 case EBreakBetween::kAvoidPage: |
2228 return 2; | 2232 return 2; |
2229 case BreakAvoid: | 2233 case EBreakBetween::kAvoid: |
2230 return 3; | 2234 return 3; |
2231 case BreakColumn: | 2235 case EBreakBetween::kColumn: |
2232 return 4; | 2236 return 4; |
2233 case BreakPage: | 2237 case EBreakBetween::kPage: |
2234 return 5; | 2238 return 5; |
2235 case BreakLeft: | 2239 case EBreakBetween::kLeft: |
2236 case BreakRight: | 2240 case EBreakBetween::kRight: |
2237 case BreakRecto: | 2241 case EBreakBetween::kRecto: |
2238 case BreakVerso: | 2242 case EBreakBetween::kVerso: |
2239 return 6; | 2243 return 6; |
2240 } | 2244 } |
2241 } | 2245 } |
2242 | 2246 |
2243 EBreak LayoutBox::joinFragmentainerBreakValues(EBreak firstValue, | 2247 EBreakBetween LayoutBox::joinFragmentainerBreakValues( |
2244 EBreak secondValue) { | 2248 EBreakBetween firstValue, |
2249 EBreakBetween secondValue) { | |
2245 if (fragmentainerBreakPrecedence(secondValue) >= | 2250 if (fragmentainerBreakPrecedence(secondValue) >= |
2246 fragmentainerBreakPrecedence(firstValue)) | 2251 fragmentainerBreakPrecedence(firstValue)) |
2247 return secondValue; | 2252 return secondValue; |
2248 return firstValue; | 2253 return firstValue; |
2249 } | 2254 } |
2250 | 2255 |
2251 EBreak LayoutBox::classABreakPointValue(EBreak previousBreakAfterValue) const { | 2256 EBreakBetween LayoutBox::classABreakPointValue( |
2257 EBreakBetween previousBreakAfterValue) const { | |
2252 // First assert that we're at a class A break point. | 2258 // First assert that we're at a class A break point. |
2253 ASSERT(isBreakBetweenControllable(previousBreakAfterValue)); | 2259 ASSERT(isBreakBetweenControllable(previousBreakAfterValue)); |
2254 | 2260 |
2255 return joinFragmentainerBreakValues(previousBreakAfterValue, breakBefore()); | 2261 return joinFragmentainerBreakValues(previousBreakAfterValue, breakBefore()); |
2256 } | 2262 } |
2257 | 2263 |
2258 bool LayoutBox::needsForcedBreakBefore(EBreak previousBreakAfterValue) const { | 2264 bool LayoutBox::needsForcedBreakBefore( |
2265 EBreakBetween previousBreakAfterValue) const { | |
2259 // Forced break values are only honored when specified on in-flow objects, but | 2266 // Forced break values are only honored when specified on in-flow objects, but |
2260 // floats and out-of-flow positioned objects may be affected by a break-after | 2267 // floats and out-of-flow positioned objects may be affected by a break-after |
2261 // value of the previous in-flow object, even though we're not at a class A | 2268 // value of the previous in-flow object, even though we're not at a class A |
2262 // break point. | 2269 // break point. |
2263 EBreak breakValue = isFloatingOrOutOfFlowPositioned() | 2270 EBreakBetween breakValue = |
2264 ? previousBreakAfterValue | 2271 isFloatingOrOutOfFlowPositioned() |
2265 : classABreakPointValue(previousBreakAfterValue); | 2272 ? previousBreakAfterValue |
2273 : classABreakPointValue(previousBreakAfterValue); | |
2266 return isForcedFragmentainerBreakValue(breakValue); | 2274 return isForcedFragmentainerBreakValue(breakValue); |
2267 } | 2275 } |
2268 | 2276 |
2269 bool LayoutBox::paintedOutputOfObjectHasNoEffectRegardlessOfSize() const { | 2277 bool LayoutBox::paintedOutputOfObjectHasNoEffectRegardlessOfSize() const { |
2270 if (hasNonCompositedScrollbars() || getSelectionState() != SelectionNone || | 2278 if (hasNonCompositedScrollbars() || getSelectionState() != SelectionNone || |
2271 hasBoxDecorationBackground() || styleRef().hasBoxDecorations() || | 2279 hasBoxDecorationBackground() || styleRef().hasBoxDecorations() || |
2272 styleRef().hasVisualOverflowingEffect()) | 2280 styleRef().hasVisualOverflowingEffect()) |
2273 return false; | 2281 return false; |
2274 | 2282 |
2275 // If the box has clip or mask, we need issue paint invalidation to cover | 2283 // If the box has clip or mask, we need issue paint invalidation to cover |
(...skipping 2753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5029 } | 5037 } |
5030 | 5038 |
5031 LayoutBox::PaginationBreakability LayoutBox::getPaginationBreakability() const { | 5039 LayoutBox::PaginationBreakability LayoutBox::getPaginationBreakability() const { |
5032 // TODO(mstensho): It is wrong to check isAtomicInlineLevel() as we | 5040 // TODO(mstensho): It is wrong to check isAtomicInlineLevel() as we |
5033 // actually look for replaced elements. | 5041 // actually look for replaced elements. |
5034 if (isAtomicInlineLevel() || hasUnsplittableScrollingOverflow() || | 5042 if (isAtomicInlineLevel() || hasUnsplittableScrollingOverflow() || |
5035 (parent() && isWritingModeRoot()) || | 5043 (parent() && isWritingModeRoot()) || |
5036 (isOutOfFlowPositioned() && style()->position() == FixedPosition)) | 5044 (isOutOfFlowPositioned() && style()->position() == FixedPosition)) |
5037 return ForbidBreaks; | 5045 return ForbidBreaks; |
5038 | 5046 |
5039 EBreak breakValue = breakInside(); | 5047 EBreakInside breakValue = breakInside(); |
5040 if (breakValue == BreakAvoid || breakValue == BreakAvoidPage || | 5048 if (breakValue == EBreakInside::kAvoid || |
5041 breakValue == BreakAvoidColumn) | 5049 breakValue == EBreakInside::kAvoidPage || |
5050 breakValue == EBreakInside::kAvoidColumn) | |
5042 return AvoidBreaks; | 5051 return AvoidBreaks; |
5043 return AllowAnyBreaks; | 5052 return AllowAnyBreaks; |
5044 } | 5053 } |
5045 | 5054 |
5046 LayoutUnit LayoutBox::lineHeight(bool /*firstLine*/, | 5055 LayoutUnit LayoutBox::lineHeight(bool /*firstLine*/, |
5047 LineDirectionMode direction, | 5056 LineDirectionMode direction, |
5048 LinePositionMode /*linePositionMode*/) const { | 5057 LinePositionMode /*linePositionMode*/) const { |
5049 if (isAtomicInlineLevel()) | 5058 if (isAtomicInlineLevel()) |
5050 return direction == HorizontalLine ? marginHeight() + size().height() | 5059 return direction == HorizontalLine ? marginHeight() + size().height() |
5051 : marginWidth() + size().width(); | 5060 : marginWidth() + size().width(); |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5697 block->adjustChildDebugRect(rect); | 5706 block->adjustChildDebugRect(rect); |
5698 | 5707 |
5699 return rect; | 5708 return rect; |
5700 } | 5709 } |
5701 | 5710 |
5702 bool LayoutBox::shouldClipOverflow() const { | 5711 bool LayoutBox::shouldClipOverflow() const { |
5703 return hasOverflowClip() || styleRef().containsPaint() || hasControlClip(); | 5712 return hasOverflowClip() || styleRef().containsPaint() || hasControlClip(); |
5704 } | 5713 } |
5705 | 5714 |
5706 } // namespace blink | 5715 } // namespace blink |
OLD | NEW |