Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutObject.cpp

Issue 2436283002: Fix LayoutObject::mapLocalToAncestor() for fixed under absolute (Closed)
Patch Set: Rebaseline after rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc.
7 * All rights reserved. 7 * All rights reserved.
8 * Copyright (C) 2009 Google Inc. All rights reserved. 8 * Copyright (C) 2009 Google Inc. All rights reserved.
9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. 9 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved.
10 * (http://www.torchmobile.com/) 10 * (http://www.torchmobile.com/)
(...skipping 2020 matching lines...) Expand 10 before | Expand all | Expand 10 after
2031 return transformState.lastPlanarQuad(); 2031 return transformState.lastPlanarQuad();
2032 } 2032 }
2033 2033
2034 void LayoutObject::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, 2034 void LayoutObject::mapLocalToAncestor(const LayoutBoxModelObject* ancestor,
2035 TransformState& transformState, 2035 TransformState& transformState,
2036 MapCoordinatesFlags mode) const { 2036 MapCoordinatesFlags mode) const {
2037 if (ancestor == this) 2037 if (ancestor == this)
2038 return; 2038 return;
2039 2039
2040 bool ancestorSkipped; 2040 bool ancestorSkipped;
2041 const LayoutObject* o = container(ancestor, &ancestorSkipped); 2041 const LayoutObject* container = this->container(ancestor, &ancestorSkipped);
2042 if (!o) 2042 if (!container)
2043 return; 2043 return;
2044 2044
2045 if (mode & ApplyContainerFlip) { 2045 if (mode & ApplyContainerFlip) {
2046 if (isBox()) { 2046 if (isBox()) {
2047 mode &= ~ApplyContainerFlip; 2047 mode &= ~ApplyContainerFlip;
2048 } else if (o->isBox()) { 2048 } else if (container->isBox()) {
2049 if (o->style()->isFlippedBlocksWritingMode()) { 2049 if (container->style()->isFlippedBlocksWritingMode()) {
2050 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint()); 2050 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint());
2051 transformState.move( 2051 transformState.move(toLayoutBox(container)->flipForWritingMode(
2052 toLayoutBox(o)->flipForWritingMode(LayoutPoint(centerPoint)) - 2052 LayoutPoint(centerPoint)) -
2053 centerPoint); 2053 centerPoint);
2054 } 2054 }
2055 mode &= ~ApplyContainerFlip; 2055 mode &= ~ApplyContainerFlip;
2056 } 2056 }
2057 } 2057 }
2058 2058
2059 LayoutSize containerOffset = offsetFromContainer(o); 2059 LayoutSize containerOffset = offsetFromContainer(container);
2060 if (isLayoutFlowThread()) { 2060 if (isLayoutFlowThread()) {
2061 // So far the point has been in flow thread coordinates (i.e. as if 2061 // So far the point has been in flow thread coordinates (i.e. as if
2062 // everything in the fragmentation context lived in one tall single column). 2062 // everything in the fragmentation context lived in one tall single column).
2063 // Convert it to a visual point now, since we're about to escape the flow 2063 // Convert it to a visual point now, since we're about to escape the flow
2064 // thread. 2064 // thread.
2065 containerOffset += 2065 containerOffset +=
2066 columnOffset(roundedLayoutPoint(transformState.mappedPoint())); 2066 columnOffset(roundedLayoutPoint(transformState.mappedPoint()));
2067 } 2067 }
2068 2068
2069 // Text objects just copy their parent's computed style, so we need to ignore 2069 // Text objects just copy their parent's computed style, so we need to ignore
2070 // them. 2070 // them.
2071 bool preserve3D = 2071 bool preserve3D =
2072 mode & UseTransforms && ((o->style()->preserves3D() && !o->isText()) || 2072 mode & UseTransforms &&
2073 (style()->preserves3D() && !isText())); 2073 ((container->style()->preserves3D() && !container->isText()) ||
2074 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { 2074 (style()->preserves3D() && !isText()));
2075 if (mode & UseTransforms && shouldUseTransformFromContainer(container)) {
2075 TransformationMatrix t; 2076 TransformationMatrix t;
2076 getTransformFromContainer(o, containerOffset, t); 2077 getTransformFromContainer(container, containerOffset, t);
2077 transformState.applyTransform(t, preserve3D 2078 transformState.applyTransform(t, preserve3D
2078 ? TransformState::AccumulateTransform 2079 ? TransformState::AccumulateTransform
2079 : TransformState::FlattenTransform); 2080 : TransformState::FlattenTransform);
2080 } else { 2081 } else {
2081 transformState.move(containerOffset.width(), containerOffset.height(), 2082 transformState.move(containerOffset.width(), containerOffset.height(),
2082 preserve3D ? TransformState::AccumulateTransform 2083 preserve3D ? TransformState::AccumulateTransform
2083 : TransformState::FlattenTransform); 2084 : TransformState::FlattenTransform);
2084 } 2085 }
2085 2086
2086 if (ancestorSkipped) { 2087 if (ancestorSkipped) {
2087 // There can't be a transform between |ancestor| and |o|, because transforms 2088 // There can't be a transform between |ancestor| and |o|, because transforms
2088 // create containers, so it should be safe to just subtract the delta 2089 // create containers, so it should be safe to just subtract the delta
2089 // between the ancestor and |o|. 2090 // between the ancestor and |o|.
2090 LayoutSize containerOffset = ancestor->offsetFromAncestorContainer(o); 2091 LayoutSize containerOffset =
2092 ancestor->offsetFromAncestorContainer(container);
2091 transformState.move(-containerOffset.width(), -containerOffset.height(), 2093 transformState.move(-containerOffset.width(), -containerOffset.height(),
2092 preserve3D ? TransformState::AccumulateTransform 2094 preserve3D ? TransformState::AccumulateTransform
2093 : TransformState::FlattenTransform); 2095 : TransformState::FlattenTransform);
2096 // If the ancestor is fixed, then the rect is already in its coordinates so
2097 // doesn't need viewport-adjusting.
2098 if (ancestor->style()->position() != FixedPosition &&
2099 container->isLayoutView() && styleRef().position() == FixedPosition) {
2100 LayoutRect rect;
2101 toLayoutView(container)->adjustOffsetForFixedPosition(rect);
2102 transformState.move(rect.x(), rect.y());
2103 }
2094 return; 2104 return;
2095 } 2105 }
2096 2106
2097 o->mapLocalToAncestor(ancestor, transformState, mode); 2107 container->mapLocalToAncestor(ancestor, transformState, mode);
2098 } 2108 }
2099 2109
2100 const LayoutObject* LayoutObject::pushMappingToContainer( 2110 const LayoutObject* LayoutObject::pushMappingToContainer(
2101 const LayoutBoxModelObject* ancestorToStopAt, 2111 const LayoutBoxModelObject* ancestorToStopAt,
2102 LayoutGeometryMap& geometryMap) const { 2112 LayoutGeometryMap& geometryMap) const {
2103 ASSERT_NOT_REACHED(); 2113 ASSERT_NOT_REACHED();
2104 return nullptr; 2114 return nullptr;
2105 } 2115 }
2106 2116
2107 void LayoutObject::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, 2117 void LayoutObject::mapAncestorToLocal(const LayoutBoxModelObject* ancestor,
2108 TransformState& transformState, 2118 TransformState& transformState,
2109 MapCoordinatesFlags mode) const { 2119 MapCoordinatesFlags mode) const {
2110 if (this == ancestor) 2120 if (this == ancestor)
2111 return; 2121 return;
2112 2122
2113 bool ancestorSkipped; 2123 bool ancestorSkipped;
2114 LayoutObject* o = container(ancestor, &ancestorSkipped); 2124 LayoutObject* container = this->container(ancestor, &ancestorSkipped);
2115 if (!o) 2125 if (!container)
2116 return; 2126 return;
2117 2127
2118 bool applyContainerFlip = false; 2128 bool applyContainerFlip = false;
2119 if (mode & ApplyContainerFlip) { 2129 if (mode & ApplyContainerFlip) {
2120 if (isBox()) { 2130 if (isBox()) {
2121 mode &= ~ApplyContainerFlip; 2131 mode &= ~ApplyContainerFlip;
2122 } else if (o->isBox()) { 2132 } else if (container->isBox()) {
2123 applyContainerFlip = o->style()->isFlippedBlocksWritingMode(); 2133 applyContainerFlip = container->style()->isFlippedBlocksWritingMode();
2124 mode &= ~ApplyContainerFlip; 2134 mode &= ~ApplyContainerFlip;
2125 } 2135 }
2126 } 2136 }
2127 2137
2128 if (!ancestorSkipped) 2138 if (!ancestorSkipped)
2129 o->mapAncestorToLocal(ancestor, transformState, mode); 2139 container->mapAncestorToLocal(ancestor, transformState, mode);
2130 2140
2131 LayoutSize containerOffset = offsetFromContainer(o); 2141 LayoutSize containerOffset = offsetFromContainer(container);
2132 if (isLayoutFlowThread()) { 2142 if (isLayoutFlowThread()) {
2133 // Descending into a flow thread. Convert to the local coordinate space, 2143 // Descending into a flow thread. Convert to the local coordinate space,
2134 // i.e. flow thread coordinates. 2144 // i.e. flow thread coordinates.
2135 LayoutPoint visualPoint = LayoutPoint(transformState.mappedPoint()); 2145 LayoutPoint visualPoint = LayoutPoint(transformState.mappedPoint());
2136 transformState.move( 2146 transformState.move(
2137 visualPoint - 2147 visualPoint -
2138 toLayoutFlowThread(this)->visualPointToFlowThreadPoint(visualPoint)); 2148 toLayoutFlowThread(this)->visualPointToFlowThreadPoint(visualPoint));
2139 } 2149 }
2140 2150
2141 bool preserve3D = mode & UseTransforms && 2151 bool preserve3D =
2142 (o->style()->preserves3D() || style()->preserves3D()); 2152 mode & UseTransforms &&
2143 if (mode & UseTransforms && shouldUseTransformFromContainer(o)) { 2153 (container->style()->preserves3D() || style()->preserves3D());
2154 if (mode & UseTransforms && shouldUseTransformFromContainer(container)) {
2144 TransformationMatrix t; 2155 TransformationMatrix t;
2145 getTransformFromContainer(o, containerOffset, t); 2156 getTransformFromContainer(container, containerOffset, t);
2146 transformState.applyTransform(t, preserve3D 2157 transformState.applyTransform(t, preserve3D
2147 ? TransformState::AccumulateTransform 2158 ? TransformState::AccumulateTransform
2148 : TransformState::FlattenTransform); 2159 : TransformState::FlattenTransform);
2149 } else { 2160 } else {
2150 transformState.move(containerOffset.width(), containerOffset.height(), 2161 transformState.move(containerOffset.width(), containerOffset.height(),
2151 preserve3D ? TransformState::AccumulateTransform 2162 preserve3D ? TransformState::AccumulateTransform
2152 : TransformState::FlattenTransform); 2163 : TransformState::FlattenTransform);
2153 } 2164 }
2154 2165
2155 if (applyContainerFlip) { 2166 if (applyContainerFlip) {
2156 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint()); 2167 IntPoint centerPoint = roundedIntPoint(transformState.mappedPoint());
2157 transformState.move( 2168 transformState.move(
2158 centerPoint - 2169 centerPoint -
2159 toLayoutBox(o)->flipForWritingMode(LayoutPoint(centerPoint))); 2170 toLayoutBox(container)->flipForWritingMode(LayoutPoint(centerPoint)));
2160 } 2171 }
2161 2172
2162 if (ancestorSkipped) { 2173 if (ancestorSkipped) {
2163 containerOffset = ancestor->offsetFromAncestorContainer(o); 2174 containerOffset = ancestor->offsetFromAncestorContainer(container);
2164 transformState.move(-containerOffset.width(), -containerOffset.height()); 2175 transformState.move(-containerOffset.width(), -containerOffset.height());
2176 // If the ancestor is fixed, then the rect is already in its coordinates so
2177 // doesn't need viewport-adjusting.
2178 if (ancestor->style()->position() != FixedPosition &&
2179 container->isLayoutView() && styleRef().position() == FixedPosition) {
2180 LayoutRect rect;
2181 toLayoutView(container)->adjustOffsetForFixedPosition(rect);
2182 transformState.move(rect.x(), rect.y());
2183 }
2165 } 2184 }
2166 } 2185 }
2167 2186
2168 bool LayoutObject::shouldUseTransformFromContainer( 2187 bool LayoutObject::shouldUseTransformFromContainer(
2169 const LayoutObject* containerObject) const { 2188 const LayoutObject* containerObject) const {
2170 // hasTransform() indicates whether the object has transform, transform-style 2189 // hasTransform() indicates whether the object has transform, transform-style
2171 // or perspective. We just care about transform, so check the layer's 2190 // or perspective. We just care about transform, so check the layer's
2172 // transform directly. 2191 // transform directly.
2173 return (hasLayer() && toLayoutBoxModelObject(this)->layer()->transform()) || 2192 return (hasLayer() && toLayoutBoxModelObject(this)->layer()->transform()) ||
2174 (containerObject && containerObject->style()->hasPerspective()); 2193 (containerObject && containerObject->style()->hasPerspective());
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after
3535 const blink::LayoutObject* root = object1; 3554 const blink::LayoutObject* root = object1;
3536 while (root->parent()) 3555 while (root->parent())
3537 root = root->parent(); 3556 root = root->parent();
3538 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); 3557 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0);
3539 } else { 3558 } else {
3540 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); 3559 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)");
3541 } 3560 }
3542 } 3561 }
3543 3562
3544 #endif 3563 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698