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) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) | 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. |
7 * Copyright (C) 2009 Google Inc. All rights reserved. | 7 * Copyright (C) 2009 Google Inc. All rights reserved. |
8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
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 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 o->m_bitfields.setPreferredLogicalWidthsDirty(true); | 874 o->m_bitfields.setPreferredLogicalWidthsDirty(true); |
875 if (o->style()->hasOutOfFlowPosition()) { | 875 if (o->style()->hasOutOfFlowPosition()) { |
876 // A positioned object has no effect on the min/max width of its con
taining block ever. | 876 // A positioned object has no effect on the min/max width of its con
taining block ever. |
877 // We can optimize this case and not go up any further. | 877 // We can optimize this case and not go up any further. |
878 break; | 878 break; |
879 } | 879 } |
880 o = container; | 880 o = container; |
881 } | 881 } |
882 } | 882 } |
883 | 883 |
884 LayoutObject* LayoutObject::containerForAbsolutePosition(const LayoutBoxModelObj
ect* paintInvalidationContainer, bool* paintInvalidationContainerSkipped) const | 884 LayoutObject* LayoutObject::containerForAbsolutePosition(const LayoutBoxModelObj
ect* ancestor, bool* ancestorSkipped) const |
885 { | 885 { |
886 // We technically just want our containing block, but | 886 // We technically just want our containing block, but |
887 // we may not have one if we're part of an uninstalled | 887 // we may not have one if we're part of an uninstalled |
888 // subtree. We'll climb as high as we can though. | 888 // subtree. We'll climb as high as we can though. |
889 for (LayoutObject* object = parent(); object; object = object->parent()) { | 889 for (LayoutObject* object = parent(); object; object = object->parent()) { |
890 if (object->canContainAbsolutePositionObjects()) | 890 if (object->canContainAbsolutePositionObjects()) |
891 return object; | 891 return object; |
892 | 892 |
893 if (paintInvalidationContainerSkipped && object == paintInvalidationCont
ainer) | 893 if (ancestorSkipped && object == ancestor) |
894 *paintInvalidationContainerSkipped = true; | 894 *ancestorSkipped = true; |
895 } | 895 } |
896 return nullptr; | 896 return nullptr; |
897 } | 897 } |
898 | 898 |
899 LayoutBlock* LayoutObject::containerForFixedPosition(const LayoutBoxModelObject*
paintInvalidationContainer, bool* paintInvalidationContainerSkipped) const | 899 LayoutBlock* LayoutObject::containerForFixedPosition(const LayoutBoxModelObject*
ancestor, bool* ancestorSkipped) const |
900 { | 900 { |
901 ASSERT(!paintInvalidationContainerSkipped || !*paintInvalidationContainerSki
pped); | 901 ASSERT(!ancestorSkipped || !*ancestorSkipped); |
902 ASSERT(!isText()); | 902 ASSERT(!isText()); |
903 | 903 |
904 LayoutObject* ancestor = parent(); | 904 LayoutObject* object = parent(); |
905 for (; ancestor && !ancestor->canContainFixedPositionObjects(); ancestor = a
ncestor->parent()) { | 905 for (; object && !object->canContainFixedPositionObjects(); object = object-
>parent()) { |
906 if (paintInvalidationContainerSkipped && ancestor == paintInvalidationCo
ntainer) | 906 if (ancestorSkipped && object == ancestor) |
907 *paintInvalidationContainerSkipped = true; | 907 *ancestorSkipped = true; |
908 } | 908 } |
909 | 909 |
910 ASSERT(!ancestor || !ancestor->isAnonymousBlock()); | 910 ASSERT(!object || !object->isAnonymousBlock()); |
911 return toLayoutBlock(ancestor); | 911 return toLayoutBlock(object); |
912 } | 912 } |
913 | 913 |
914 LayoutBlock* LayoutObject::containingBlockForAbsolutePosition() const | 914 LayoutBlock* LayoutObject::containingBlockForAbsolutePosition() const |
915 { | 915 { |
916 LayoutObject* o = containerForAbsolutePosition(); | 916 LayoutObject* o = containerForAbsolutePosition(); |
917 | 917 |
918 // For relpositioned inlines, we return the nearest non-anonymous enclosing
block. We don't try | 918 // For relpositioned inlines, we return the nearest non-anonymous enclosing
block. We don't try |
919 // to return the inline itself. This allows us to avoid having a positioned
objects | 919 // to return the inline itself. This allows us to avoid having a positioned
objects |
920 // list in all LayoutInlines and lets us return a strongly-typed LayoutBlock
* result | 920 // list in all LayoutInlines and lets us return a strongly-typed LayoutBlock
* result |
921 // from this method. The container() method can actually be used to obtain
the | 921 // from this method. The container() method can actually be used to obtain
the |
(...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2238 mapAncestorToLocal(ancestor, transformState, mode); | 2238 mapAncestorToLocal(ancestor, transformState, mode); |
2239 transformState.flatten(); | 2239 transformState.flatten(); |
2240 return transformState.lastPlanarQuad(); | 2240 return transformState.lastPlanarQuad(); |
2241 } | 2241 } |
2242 | 2242 |
2243 void LayoutObject::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, Tran
sformState& transformState, MapCoordinatesFlags mode) const | 2243 void LayoutObject::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, Tran
sformState& transformState, MapCoordinatesFlags mode) const |
2244 { | 2244 { |
2245 if (ancestor == this) | 2245 if (ancestor == this) |
2246 return; | 2246 return; |
2247 | 2247 |
2248 bool containerSkipped; | 2248 bool ancestorSkipped; |
2249 const LayoutObject* o = container(ancestor, &containerSkipped); | 2249 const LayoutObject* o = container(ancestor, &ancestorSkipped); |
2250 if (!o) | 2250 if (!o) |
2251 return; | 2251 return; |
2252 | 2252 |
2253 if (mode & ApplyContainerFlip) { | 2253 if (mode & ApplyContainerFlip) { |
2254 if (isBox()) { | 2254 if (isBox()) { |
2255 mode &= ~ApplyContainerFlip; | 2255 mode &= ~ApplyContainerFlip; |
2256 } else if (o->isBox()) { | 2256 } else if (o->isBox()) { |
2257 if (o->style()->isFlippedBlocksWritingMode()) { | 2257 if (o->style()->isFlippedBlocksWritingMode()) { |
2258 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoin
t()); | 2258 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoin
t()); |
2259 transformState.move(toLayoutBox(o)->flipForWritingMode(LayoutPoi
nt(centerPoint)) - centerPoint); | 2259 transformState.move(toLayoutBox(o)->flipForWritingMode(LayoutPoi
nt(centerPoint)) - centerPoint); |
(...skipping 13 matching lines...) Expand all Loading... |
2273 // Text objects just copy their parent's computed style, so we need to ignor
e them. | 2273 // Text objects just copy their parent's computed style, so we need to ignor
e them. |
2274 bool preserve3D = mode & UseTransforms && ((o->style()->preserves3D() && !o-
>isText()) || (style()->preserves3D() && !isText())); | 2274 bool preserve3D = mode & UseTransforms && ((o->style()->preserves3D() && !o-
>isText()) || (style()->preserves3D() && !isText())); |
2275 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { | 2275 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { |
2276 TransformationMatrix t; | 2276 TransformationMatrix t; |
2277 getTransformFromContainer(o, containerOffset, t); | 2277 getTransformFromContainer(o, containerOffset, t); |
2278 transformState.applyTransform(t, preserve3D ? TransformState::Accumulate
Transform : TransformState::FlattenTransform); | 2278 transformState.applyTransform(t, preserve3D ? TransformState::Accumulate
Transform : TransformState::FlattenTransform); |
2279 } else { | 2279 } else { |
2280 transformState.move(containerOffset.width(), containerOffset.height(), p
reserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransfo
rm); | 2280 transformState.move(containerOffset.width(), containerOffset.height(), p
reserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransfo
rm); |
2281 } | 2281 } |
2282 | 2282 |
2283 if (containerSkipped) { | 2283 if (ancestorSkipped) { |
2284 // There can't be a transform between |ancestor| and |o|, because transf
orms create | 2284 // There can't be a transform between |ancestor| and |o|, because transf
orms create |
2285 // containers, so it should be safe to just subtract the delta between t
he ancestor and |o|. | 2285 // containers, so it should be safe to just subtract the delta between t
he ancestor and |o|. |
2286 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(o); | 2286 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(o); |
2287 transformState.move(-containerOffset.width(), -containerOffset.height(),
preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTrans
form); | 2287 transformState.move(-containerOffset.width(), -containerOffset.height(),
preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTrans
form); |
2288 return; | 2288 return; |
2289 } | 2289 } |
2290 | 2290 |
2291 o->mapLocalToAncestor(ancestor, transformState, mode); | 2291 o->mapLocalToAncestor(ancestor, transformState, mode); |
2292 } | 2292 } |
2293 | 2293 |
2294 const LayoutObject* LayoutObject::pushMappingToContainer(const LayoutBoxModelObj
ect* ancestorToStopAt, LayoutGeometryMap& geometryMap) const | 2294 const LayoutObject* LayoutObject::pushMappingToContainer(const LayoutBoxModelObj
ect* ancestorToStopAt, LayoutGeometryMap& geometryMap) const |
2295 { | 2295 { |
2296 ASSERT_NOT_REACHED(); | 2296 ASSERT_NOT_REACHED(); |
2297 return nullptr; | 2297 return nullptr; |
2298 } | 2298 } |
2299 | 2299 |
2300 void LayoutObject::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, Tran
sformState& transformState, MapCoordinatesFlags mode) const | 2300 void LayoutObject::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, Tran
sformState& transformState, MapCoordinatesFlags mode) const |
2301 { | 2301 { |
2302 if (this == ancestor) | 2302 if (this == ancestor) |
2303 return; | 2303 return; |
2304 | 2304 |
2305 bool containerSkipped; | 2305 bool ancestorSkipped; |
2306 LayoutObject* o = container(ancestor, &containerSkipped); | 2306 LayoutObject* o = container(ancestor, &ancestorSkipped); |
2307 if (!o) | 2307 if (!o) |
2308 return; | 2308 return; |
2309 | 2309 |
2310 bool applyContainerFlip = false; | 2310 bool applyContainerFlip = false; |
2311 if (mode & ApplyContainerFlip) { | 2311 if (mode & ApplyContainerFlip) { |
2312 if (isBox()) { | 2312 if (isBox()) { |
2313 mode &= ~ApplyContainerFlip; | 2313 mode &= ~ApplyContainerFlip; |
2314 } else if (o->isBox()) { | 2314 } else if (o->isBox()) { |
2315 applyContainerFlip = o->style()->isFlippedBlocksWritingMode(); | 2315 applyContainerFlip = o->style()->isFlippedBlocksWritingMode(); |
2316 mode &= ~ApplyContainerFlip; | 2316 mode &= ~ApplyContainerFlip; |
2317 } | 2317 } |
2318 } | 2318 } |
2319 | 2319 |
2320 if (!containerSkipped) | 2320 if (!ancestorSkipped) |
2321 o->mapAncestorToLocal(ancestor, transformState, mode); | 2321 o->mapAncestorToLocal(ancestor, transformState, mode); |
2322 | 2322 |
2323 LayoutSize containerOffset = offsetFromContainer(o); | 2323 LayoutSize containerOffset = offsetFromContainer(o); |
2324 if (o->isLayoutFlowThread()) { | 2324 if (o->isLayoutFlowThread()) { |
2325 // Descending into a flow thread. Convert to the local coordinate space,
i.e. flow thread coordinates. | 2325 // Descending into a flow thread. Convert to the local coordinate space,
i.e. flow thread coordinates. |
2326 LayoutPoint visualPoint = LayoutPoint(transformState.mappedPoint()); | 2326 LayoutPoint visualPoint = LayoutPoint(transformState.mappedPoint()); |
2327 transformState.move(visualPoint - toLayoutFlowThread(o)->visualPointToFl
owThreadPoint(visualPoint)); | 2327 transformState.move(visualPoint - toLayoutFlowThread(o)->visualPointToFl
owThreadPoint(visualPoint)); |
2328 } | 2328 } |
2329 | 2329 |
2330 bool preserve3D = mode & UseTransforms && (o->style()->preserves3D() || styl
e()->preserves3D()); | 2330 bool preserve3D = mode & UseTransforms && (o->style()->preserves3D() || styl
e()->preserves3D()); |
2331 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { | 2331 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { |
2332 TransformationMatrix t; | 2332 TransformationMatrix t; |
2333 getTransformFromContainer(o, containerOffset, t); | 2333 getTransformFromContainer(o, containerOffset, t); |
2334 transformState.applyTransform(t, preserve3D ? TransformState::Accumulate
Transform : TransformState::FlattenTransform); | 2334 transformState.applyTransform(t, preserve3D ? TransformState::Accumulate
Transform : TransformState::FlattenTransform); |
2335 } else { | 2335 } else { |
2336 transformState.move(containerOffset.width(), containerOffset.height(), p
reserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransfo
rm); | 2336 transformState.move(containerOffset.width(), containerOffset.height(), p
reserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransfo
rm); |
2337 } | 2337 } |
2338 | 2338 |
2339 if (applyContainerFlip) { | 2339 if (applyContainerFlip) { |
2340 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint()); | 2340 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint()); |
2341 transformState.move(centerPoint - toLayoutBox(o)->flipForWritingMode(Lay
outPoint(centerPoint))); | 2341 transformState.move(centerPoint - toLayoutBox(o)->flipForWritingMode(Lay
outPoint(centerPoint))); |
2342 } | 2342 } |
2343 | 2343 |
2344 if (containerSkipped) { | 2344 if (ancestorSkipped) { |
2345 containerOffset = ancestor->offsetFromAncestorContainer(o); | 2345 containerOffset = ancestor->offsetFromAncestorContainer(o); |
2346 transformState.move(-containerOffset.width(), -containerOffset.height())
; | 2346 transformState.move(-containerOffset.width(), -containerOffset.height())
; |
2347 } | 2347 } |
2348 } | 2348 } |
2349 | 2349 |
2350 bool LayoutObject::shouldUseTransformFromContainer(const LayoutObject* container
Object) const | 2350 bool LayoutObject::shouldUseTransformFromContainer(const LayoutObject* container
Object) const |
2351 { | 2351 { |
2352 // hasTransform() indicates whether the object has transform, transform-styl
e or perspective. We just care about transform, | 2352 // hasTransform() indicates whether the object has transform, transform-styl
e or perspective. We just care about transform, |
2353 // so check the layer's transform directly. | 2353 // so check the layer's transform directly. |
2354 return (hasLayer() && toLayoutBoxModelObject(this)->layer()->transform()) ||
(containerObject && containerObject->style()->hasPerspective()); | 2354 return (hasLayer() && toLayoutBoxModelObject(this)->layer()->transform()) ||
(containerObject && containerObject->style()->hasPerspective()); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2578 | 2578 |
2579 if (layoutObject->document().settings() && layoutObject->document().settings
()->shouldRespectImageOrientation()) | 2579 if (layoutObject->document().settings() && layoutObject->document().settings
()->shouldRespectImageOrientation()) |
2580 return RespectImageOrientation; | 2580 return RespectImageOrientation; |
2581 | 2581 |
2582 if (layoutObject->style() && layoutObject->style()->respectImageOrientation(
) == RespectImageOrientation) | 2582 if (layoutObject->style() && layoutObject->style()->respectImageOrientation(
) == RespectImageOrientation) |
2583 return RespectImageOrientation; | 2583 return RespectImageOrientation; |
2584 | 2584 |
2585 return DoNotRespectImageOrientation; | 2585 return DoNotRespectImageOrientation; |
2586 } | 2586 } |
2587 | 2587 |
2588 LayoutObject* LayoutObject::container(const LayoutBoxModelObject* paintInvalidat
ionContainer, bool* paintInvalidationContainerSkipped) const | 2588 LayoutObject* LayoutObject::container(const LayoutBoxModelObject* ancestor, bool
* ancestorSkipped) const |
2589 { | 2589 { |
2590 if (paintInvalidationContainerSkipped) | 2590 if (ancestorSkipped) |
2591 *paintInvalidationContainerSkipped = false; | 2591 *ancestorSkipped = false; |
2592 | 2592 |
2593 LayoutObject* o = parent(); | 2593 LayoutObject* o = parent(); |
2594 | 2594 |
2595 if (isTextOrSVGChild()) | 2595 if (isTextOrSVGChild()) |
2596 return o; | 2596 return o; |
2597 | 2597 |
2598 EPosition pos = m_style->position(); | 2598 EPosition pos = m_style->position(); |
2599 if (pos == FixedPosition) | 2599 if (pos == FixedPosition) |
2600 return containerForFixedPosition(paintInvalidationContainer, paintInvali
dationContainerSkipped); | 2600 return containerForFixedPosition(ancestor, ancestorSkipped); |
2601 | 2601 |
2602 if (pos == AbsolutePosition) | 2602 if (pos == AbsolutePosition) |
2603 return containerForAbsolutePosition(paintInvalidationContainer, paintInv
alidationContainerSkipped); | 2603 return containerForAbsolutePosition(ancestor, ancestorSkipped); |
2604 | 2604 |
2605 if (isColumnSpanAll()) { | 2605 if (isColumnSpanAll()) { |
2606 LayoutObject* multicolContainer = spannerPlaceholder()->container(); | 2606 LayoutObject* multicolContainer = spannerPlaceholder()->container(); |
2607 if (paintInvalidationContainerSkipped && paintInvalidationContainer) { | 2607 if (ancestorSkipped && ancestor) { |
2608 // We jumped directly from the spanner to the multicol container. Ne
ed to check if | 2608 // We jumped directly from the spanner to the multicol container. Ne
ed to check if |
2609 // we skipped |paintInvalidationContainer| on the way. | 2609 // we skipped |paintInvalidationContainer| on the way. |
2610 for (LayoutObject* walker = parent(); walker && walker != multicolCo
ntainer; walker = walker->parent()) { | 2610 for (LayoutObject* walker = parent(); walker && walker != multicolCo
ntainer; walker = walker->parent()) { |
2611 if (walker == paintInvalidationContainer) { | 2611 if (walker == ancestor) { |
2612 *paintInvalidationContainerSkipped = true; | 2612 *ancestorSkipped = true; |
2613 break; | 2613 break; |
2614 } | 2614 } |
2615 } | 2615 } |
2616 } | 2616 } |
2617 return multicolContainer; | 2617 return multicolContainer; |
2618 } | 2618 } |
2619 | 2619 |
2620 return o; | 2620 return o; |
2621 } | 2621 } |
2622 | 2622 |
(...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3706 const blink::LayoutObject* root = object1; | 3706 const blink::LayoutObject* root = object1; |
3707 while (root->parent()) | 3707 while (root->parent()) |
3708 root = root->parent(); | 3708 root = root->parent(); |
3709 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3709 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
3710 } else { | 3710 } else { |
3711 fprintf(stderr, "Cannot showLayoutTree. Root is (nil)\n"); | 3711 fprintf(stderr, "Cannot showLayoutTree. Root is (nil)\n"); |
3712 } | 3712 } |
3713 } | 3713 } |
3714 | 3714 |
3715 #endif | 3715 #endif |
OLD | NEW |