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

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

Issue 2808613002: Apply container offset and scroll between transform and container perspective. (Closed)
Patch Set: none Created 3 years, 8 months 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) 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 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 LayoutRect result = LayoutRect(LayoutRect::InfiniteIntRect()); 1161 LayoutRect result = LayoutRect(LayoutRect::InfiniteIntRect());
1162 if (ShouldClipOverflow()) 1162 if (ShouldClipOverflow())
1163 result = OverflowClipRect(LayoutPoint()); 1163 result = OverflowClipRect(LayoutPoint());
1164 1164
1165 if (HasClip()) 1165 if (HasClip())
1166 result.Intersect(ClipRect(LayoutPoint())); 1166 result.Intersect(ClipRect(LayoutPoint()));
1167 1167
1168 return result; 1168 return result;
1169 } 1169 }
1170 1170
1171 bool LayoutBox::MapVisualRectToContainer(
1172 const LayoutObject* container_object,
1173 const LayoutPoint& container_offset,
1174 const LayoutObject* ancestor,
1175 VisualRectFlags visual_rect_flags,
1176 TransformState& transform_state) const {
1177 bool preserve3D = container_object->Style()->Preserves3D();
1178
1179 TransformState::TransformAccumulation accumulation =
1180 preserve3D ? TransformState::kAccumulateTransform
1181 : TransformState::kFlattenTransform;
1182
1183 // If there is no transform on this box, adjust for container offset and
1184 // container scrolling, then apply container clip.
1185 if (!ShouldUseTransformFromContainer(container_object)) {
1186 transform_state.MoveBy(container_offset, accumulation);
1187 if (container_object->IsBox() && container_object != ancestor &&
1188 !ToLayoutBox(container_object)
1189 ->MapScrollingContentsRectToBoxSpace(transform_state, accumulation,
1190 visual_rect_flags))
1191 return false;
1192 return true;
1193 }
1194
1195 // Otherwise, apply the following:
1196 // 1. Transform.
1197 // 2. Container offset.
1198 // 3. Container scroll offset.
1199 // 4. Perspective applied by container.
1200 // 5. Transform flattening.
1201 // 6. Expansion for pixel snapping.
1202 // 7. Container clip.
1203
1204 // 1. Transform.
1205 TransformationMatrix transform;
1206 if (Layer() && Layer()->Transform())
1207 transform.Multiply(Layer()->CurrentTransform());
1208
1209 // 2. Container offset.
1210 transform.TranslateRight(container_offset.X().ToFloat(),
1211 container_offset.Y().ToFloat());
1212
1213 // 3. Container scroll offset.
1214 if (container_object->IsBox() && container_object != ancestor &&
1215 container_object->HasOverflowClip()) {
1216 IntSize offset = -ToLayoutBox(container_object)->ScrolledContentOffset();
1217 transform.TranslateRight(offset.Width(), offset.Height());
1218 }
1219
1220 // 4. Perspective applied by container.
1221 if (container_object && container_object->HasLayer() &&
1222 container_object->Style()->HasPerspective()) {
1223 // Perspective on the container affects us, so we have to factor it in here.
1224 DCHECK(container_object->HasLayer());
1225 FloatPoint perspective_origin =
1226 ToLayoutBoxModelObject(container_object)->Layer()->PerspectiveOrigin();
1227
1228 TransformationMatrix perspective_matrix;
1229 perspective_matrix.ApplyPerspective(
1230 container_object->Style()->Perspective());
1231 perspective_matrix.ApplyTransformOrigin(perspective_origin.X(),
1232 perspective_origin.Y(), 0);
1233
1234 transform = perspective_matrix * transform;
1235 }
1236
1237 // 5. Transform flattening.
1238 transform_state.ApplyTransform(transform, accumulation);
1239
1240 // 6. Expansion for pixel snapping.
1241 // Use enclosingBoundingBox because we cannot properly compute pixel
1242 // snapping for painted elements within the transform since we don't know
1243 // the desired subpixel accumulation at this point, and the transform may
1244 // include a scale.
1245 if (!preserve3D) {
1246 transform_state.Flatten();
1247 transform_state.SetQuad(
1248 FloatQuad(transform_state.LastPlanarQuad().EnclosingBoundingBox()));
1249 }
1250
1251 // 7. Container clip.
1252 if (container_object->IsBox() && container_object != ancestor &&
1253 container_object->HasClipRelatedProperty()) {
1254 return ToLayoutBox(container_object)
1255 ->ApplyBoxClips(transform_state, accumulation, visual_rect_flags);
1256 }
1257
1258 return true;
1259 }
1260
1171 bool LayoutBox::MapScrollingContentsRectToBoxSpace( 1261 bool LayoutBox::MapScrollingContentsRectToBoxSpace(
1172 TransformState& transform_state, 1262 TransformState& transform_state,
1173 TransformState::TransformAccumulation accumulation, 1263 TransformState::TransformAccumulation accumulation,
1174 VisualRectFlags visual_rect_flags) const { 1264 VisualRectFlags visual_rect_flags) const {
1175 if (!HasClipRelatedProperty()) 1265 if (!HasClipRelatedProperty())
1176 return true; 1266 return true;
1177 1267
1178 if (HasOverflowClip()) { 1268 if (HasOverflowClip()) {
1179 LayoutSize offset = LayoutSize(-ScrolledContentOffset()); 1269 LayoutSize offset = LayoutSize(-ScrolledContentOffset());
1180 transform_state.Move(offset, accumulation); 1270 transform_state.Move(offset, accumulation);
1181 } 1271 }
1182 1272
1273 return ApplyBoxClips(transform_state, accumulation, visual_rect_flags);
1274 }
1275
1276 bool LayoutBox::ApplyBoxClips(
1277 TransformState& transform_state,
1278 TransformState::TransformAccumulation accumulation,
1279 VisualRectFlags visual_rect_flags) const {
1183 // This won't work fully correctly for fixed-position elements, who should 1280 // This won't work fully correctly for fixed-position elements, who should
1184 // receive CSS clip but for whom the current object is not in the containing 1281 // receive CSS clip but for whom the current object is not in the containing
1185 // block chain. 1282 // block chain.
1186 LayoutRect clip_rect = ClippingRect(); 1283 LayoutRect clip_rect = ClippingRect();
1187 1284
1188 transform_state.Flatten(); 1285 transform_state.Flatten();
1189 LayoutRect rect(transform_state.LastPlanarQuad().EnclosingBoundingBox()); 1286 LayoutRect rect(transform_state.LastPlanarQuad().EnclosingBoundingBox());
1190 bool does_intersect; 1287 bool does_intersect;
1191 if (visual_rect_flags & kEdgeInclusive) { 1288 if (visual_rect_flags & kEdgeInclusive) {
1192 does_intersect = rect.InclusiveIntersect(clip_rect); 1289 does_intersect = rect.InclusiveIntersect(clip_rect);
(...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2422 ToLayoutInline(container)->OffsetForInFlowPositionedInline(*this)); 2519 ToLayoutInline(container)->OffsetForInFlowPositionedInline(*this));
2423 } else if (style_to_use.HasInFlowPosition() && Layer()) { 2520 } else if (style_to_use.HasInFlowPosition() && Layer()) {
2424 // Apply the relative position offset when invalidating a rectangle. The 2521 // Apply the relative position offset when invalidating a rectangle. The
2425 // layer is translated, but the layout box isn't, so we need to do this to 2522 // layer is translated, but the layout box isn't, so we need to do this to
2426 // get the right dirty rect. Since this is called from 2523 // get the right dirty rect. Since this is called from
2427 // LayoutObject::setStyle, the relative position flag on the LayoutObject 2524 // LayoutObject::setStyle, the relative position flag on the LayoutObject
2428 // has been cleared, so use the one on the style(). 2525 // has been cleared, so use the one on the style().
2429 container_offset.Move(Layer()->OffsetForInFlowPosition()); 2526 container_offset.Move(Layer()->OffsetForInFlowPosition());
2430 } 2527 }
2431 2528
2432 bool preserve3d = container->Style()->Preserves3D();
2433
2434 TransformState::TransformAccumulation accumulation =
2435 preserve3d ? TransformState::kAccumulateTransform
2436 : TransformState::kFlattenTransform;
2437
2438 if (skip_info.FilterSkipped()) { 2529 if (skip_info.FilterSkipped()) {
2439 InflateVisualRectForFilterUnderContainer(transform_state, *container, 2530 InflateVisualRectForFilterUnderContainer(transform_state, *container,
2440 ancestor); 2531 ancestor);
2441 } 2532 }
2442 2533
2443 // We are now in our parent container's coordinate space. Apply our transform 2534 if (!MapVisualRectToContainer(container, container_offset, ancestor,
2444 // to obtain a bounding box in the parent's coordinate space that encloses us. 2535 visual_rect_flags, transform_state))
2445 if (ShouldUseTransformFromContainer(container)) {
2446 TransformationMatrix t;
2447 GetTransformFromContainer(container, ToLayoutSize(container_offset), t);
2448 transform_state.ApplyTransform(t, accumulation);
2449
2450 // Use enclosingBoundingBox because we cannot properly compute pixel
2451 // snapping for painted elements within the transform since we don't know
2452 // the desired subpixel accumulation at this point, and the transform may
2453 // include a scale.
2454 if (!preserve3d) {
2455 transform_state.Flatten();
2456 transform_state.SetQuad(
2457 FloatQuad(transform_state.LastPlanarQuad().EnclosingBoundingBox()));
2458 }
2459 } else {
2460 transform_state.Move(ToLayoutSize(container_offset), accumulation);
2461 }
2462
2463 // FIXME: We ignore the lightweight clipping rect that controls use, since if
2464 // |o| is in mid-layout, its controlClipRect will be wrong. For overflow clip
2465 // we use the values cached by the layer.
2466 if (container->IsBox() && container != ancestor &&
2467 !ToLayoutBox(container)->MapScrollingContentsRectToBoxSpace(
2468 transform_state, accumulation, visual_rect_flags))
2469 return false; 2536 return false;
2470 2537
2471 if (skip_info.AncestorSkipped()) { 2538 if (skip_info.AncestorSkipped()) {
2539 bool preserve3D = container->Style()->Preserves3D();
2540 TransformState::TransformAccumulation accumulation =
2541 preserve3D ? TransformState::kAccumulateTransform
2542 : TransformState::kFlattenTransform;
2543
2472 // If the ancestor is below the container, then we need to map the rect into 2544 // If the ancestor is below the container, then we need to map the rect into
2473 // ancestor's coordinates. 2545 // ancestor's coordinates.
2474 LayoutSize container_offset = 2546 LayoutSize container_offset =
2475 ancestor->OffsetFromAncestorContainer(container); 2547 ancestor->OffsetFromAncestorContainer(container);
2476 transform_state.Move(-container_offset, accumulation); 2548 transform_state.Move(-container_offset, accumulation);
2477 // If the ancestor is fixed, then the rect is already in its coordinates so 2549 // If the ancestor is fixed, then the rect is already in its coordinates so
2478 // doesn't need viewport-adjusting. 2550 // doesn't need viewport-adjusting.
2479 if (ancestor->Style()->GetPosition() != EPosition::kFixed && 2551 if (ancestor->Style()->GetPosition() != EPosition::kFixed &&
2480 container->IsLayoutView() && position == EPosition::kFixed) { 2552 container->IsLayoutView() && position == EPosition::kFixed) {
2481 transform_state.Move( 2553 transform_state.Move(
(...skipping 3337 matching lines...) Expand 10 before | Expand all | Expand 10 after
5819 void LayoutBox::MutableForPainting:: 5891 void LayoutBox::MutableForPainting::
5820 SavePreviousContentBoxSizeAndLayoutOverflowRect() { 5892 SavePreviousContentBoxSizeAndLayoutOverflowRect() {
5821 auto& rare_data = GetLayoutBox().EnsureRareData(); 5893 auto& rare_data = GetLayoutBox().EnsureRareData();
5822 rare_data.has_previous_content_box_size_and_layout_overflow_rect_ = true; 5894 rare_data.has_previous_content_box_size_and_layout_overflow_rect_ = true;
5823 rare_data.previous_content_box_size_ = GetLayoutBox().ContentBoxRect().size(); 5895 rare_data.previous_content_box_size_ = GetLayoutBox().ContentBoxRect().size();
5824 rare_data.previous_layout_overflow_rect_ = 5896 rare_data.previous_layout_overflow_rect_ =
5825 GetLayoutBox().LayoutOverflowRect(); 5897 GetLayoutBox().LayoutOverflowRect();
5826 } 5898 }
5827 5899
5828 } // namespace blink 5900 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBox.h ('k') | third_party/WebKit/Source/core/layout/LayoutObject.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698