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

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp

Issue 1865093004: Add a transform paint property for local SVG transforms (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: dcheck that SVG does not scroll and describe it in a comment Created 4 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 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/paint/PaintPropertyTreeBuilder.h" 5 #include "core/paint/PaintPropertyTreeBuilder.h"
6 6
7 #include "core/frame/FrameView.h" 7 #include "core/frame/FrameView.h"
8 #include "core/layout/LayoutPart.h" 8 #include "core/layout/LayoutPart.h"
9 #include "core/layout/LayoutView.h" 9 #include "core/layout/LayoutView.h"
10 #include "core/paint/ObjectPaintProperties.h" 10 #include "core/paint/ObjectPaintProperties.h"
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 const ComputedStyle& style = box.styleRef(); 170 const ComputedStyle& style = box.styleRef();
171 FloatSize borderBoxSize(box.size()); 171 FloatSize borderBoxSize(box.size());
172 return FloatPoint3D( 172 return FloatPoint3D(
173 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), 173 floatValueForLength(style.transformOriginX(), borderBoxSize.width()),
174 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), 174 floatValueForLength(style.transformOriginY(), borderBoxSize.height()),
175 style.transformOriginZ()); 175 style.transformOriginZ());
176 } 176 }
177 177
178 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo utObject& object, PaintPropertyTreeBuilderContext& context) 178 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo utObject& object, PaintPropertyTreeBuilderContext& context)
179 { 179 {
180 if (object.isSVG() && !object.isSVGRoot()) {
181 const AffineTransform& transform = object.localToSVGParentTransform();
182 if (transform.isIdentity())
183 return nullptr;
184
185 // SVG's transform origin is baked into the localToParentTransform.
186 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = Transf ormPaintPropertyNode::create(
187 transform, FloatPoint3D(0, 0, 0), context.currentTransform);
188 context.currentTransform = newTransformNodeForTransform.get();
189 return newTransformNodeForTransform.release();
190 }
191
192 const ComputedStyle& style = object.styleRef(); 180 const ComputedStyle& style = object.styleRef();
193 if (!object.isBox() || !style.hasTransform()) 181 if (!object.isBox() || !style.hasTransform())
194 return nullptr; 182 return nullptr;
195 183
196 ASSERT(context.paintOffset == LayoutPoint()); 184 ASSERT(context.paintOffset == LayoutPoint());
197 185
198 TransformationMatrix matrix; 186 TransformationMatrix matrix;
199 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin, 187 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin,
200 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties); 188 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties);
201 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create( 189 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create(
202 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); 190 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform);
203 context.currentTransform = newTransformNodeForTransform.get(); 191 context.currentTransform = newTransformNodeForTransform.get();
204 return newTransformNodeForTransform.release(); 192 return newTransformNodeForTransform.release();
205 } 193 }
206 194
195 static PassRefPtr<TransformPaintPropertyNode> createSvgLocalTransformIfNeeded(co nst LayoutObject& object, PaintPropertyTreeBuilderContext& context)
196 {
197 if (!object.isSVG())
198 return nullptr;
199
200 const AffineTransform& transform = object.localToSVGParentTransform();
201 if (transform.isIdentity())
202 return nullptr;
203
204 // SVG's transform origin is baked into the localToSVGParentTransform so we use 0's for the origin.
205 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create(
206 transform, FloatPoint3D(0, 0, 0), context.currentTransform);
207 context.currentTransform = newTransformNodeForTransform.get();
208 return newTransformNodeForTransform.release();
209 }
210
207 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context) 211 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context)
208 { 212 {
209 const ComputedStyle& style = object.styleRef(); 213 const ComputedStyle& style = object.styleRef();
210 if (!style.hasOpacity()) 214 if (!style.hasOpacity())
211 return nullptr; 215 return nullptr;
212 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect); 216 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect);
213 context.currentEffect = newEffectNode.get(); 217 context.currentEffect = newEffectNode.get();
214 return newEffectNode.release(); 218 return newEffectNode.release();
215 } 219 }
216 220
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 328
325 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create( 329 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create(
326 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()), 330 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()),
327 FloatPoint3D(), context.currentTransform); 331 FloatPoint3D(), context.currentTransform);
328 context.currentTransform = newTransformNodeForScrollTranslation.get(); 332 context.currentTransform = newTransformNodeForScrollTranslation.get();
329 return newTransformNodeForScrollTranslation.release(); 333 return newTransformNodeForScrollTranslation.release();
330 } 334 }
331 335
332 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree BuilderContext& context, ClipPaintPropertyNode* newClipNodeForCSSClip, RefPtr<Cl ipPaintPropertyNode>& newClipNodeForCSSClipFixedPosition) 336 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree BuilderContext& context, ClipPaintPropertyNode* newClipNodeForCSSClip, RefPtr<Cl ipPaintPropertyNode>& newClipNodeForCSSClipFixedPosition)
333 { 337 {
338 // TODO(pdr): Always create an SVG transform for the root and remove this pa int offset quirk.
334 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the currentTransform is 339 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the currentTransform is
335 // up-to-date for all children of the svg root element. Additionally, inside SVG, all positioning 340 // up-to-date for all children of the svg root element. Additionally, inside SVG, all positioning
336 // uses transforms. Therefore, we only need to check createdNewTransform and isSVGRoot() to 341 // uses transforms. Therefore, we only need to check createdNewTransform and isSVGRoot() to
337 // ensure out-of-flow and fixed positioning is correct at the svg->html boun dary. 342 // ensure out-of-flow and fixed positioning is correct at the svg->html boun dary.
338 343
339 if (object.canContainAbsolutePositionObjects()) { 344 if (object.canContainAbsolutePositionObjects()) {
340 context.transformForAbsolutePosition = context.currentTransform; 345 context.transformForAbsolutePosition = context.currentTransform;
341 context.paintOffsetForAbsolutePosition = context.paintOffset; 346 context.paintOffsetForAbsolutePosition = context.paintOffset;
342 context.clipForAbsolutePosition = context.currentClip; 347 context.clipForAbsolutePosition = context.currentClip;
343 } 348 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext); 398 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext);
394 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext); 399 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext);
395 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext); 400 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext);
396 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = createCSSClipIfNeeded( object, localContext); 401 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = createCSSClipIfNeeded( object, localContext);
397 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext = recordTreeContextIfNeeded(object, localContext); 402 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext = recordTreeContextIfNeeded(object, localContext);
398 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset = createScrollbarPaintOffsetIfNeeded(object, localContext); 403 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset = createScrollbarPaintOffsetIfNeeded(object, localContext);
399 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli pIfNeeded(object, localContext); 404 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli pIfNeeded(object, localContext);
400 // TODO(trchen): Insert flattening transform here, as specified by 405 // TODO(trchen): Insert flattening transform here, as specified by
401 // http://www.w3.org/TR/css3-transforms/#transform-style-property 406 // http://www.w3.org/TR/css3-transforms/#transform-style-property
402 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext); 407 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext);
408 RefPtr<TransformPaintPropertyNode> newTransformNodeForSvgLocalTransform = cr eateSvgLocalTransformIfNeeded(object, localContext);
403 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext); 409 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext);
404 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClipFixedPosition; 410 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClipFixedPosition;
405 updateOutOfFlowContext(object, localContext, newClipNodeForCSSClip.get(), ne wClipNodeForCSSClipFixedPosition); 411 updateOutOfFlowContext(object, localContext, newClipNodeForCSSClip.get(), ne wClipNodeForCSSClipFixedPosition);
406 412
407 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newClipNodeForCSSClip || newClipNodeForCSSClipFixedPositio n || newClipNodeForOverflowClip || newTransformNodeForPerspective || newTransfor mNodeForScrollTranslation || newTransformNodeForScrollbarPaintOffset || newRecor dedContext) { 413 DCHECK(!newTransformNodeForSvgLocalTransform || !newTransformNodeForScrollTr anslation)
414 << "SVG elements cannot have scroll translation";
415
416 // TODO(pdr): Refactor this to use a less massive if statement.
417 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newClipNodeForCSSClip || newClipNodeForCSSClipFixedPositio n || newClipNodeForOverflowClip || newTransformNodeForPerspective || newTransfor mNodeForSvgLocalTransform || newTransformNodeForScrollTranslation || newTransfor mNodeForScrollbarPaintOffset || newRecordedContext) {
408 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create( 418 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create(
409 newTransformNodeForPaintOffsetTranslation.release(), 419 newTransformNodeForPaintOffsetTranslation.release(),
410 newTransformNodeForTransform.release(), 420 newTransformNodeForTransform.release(),
411 newEffectNode.release(), 421 newEffectNode.release(),
412 newClipNodeForCSSClip.release(), 422 newClipNodeForCSSClip.release(),
413 newClipNodeForCSSClipFixedPosition.release(), 423 newClipNodeForCSSClipFixedPosition.release(),
414 newClipNodeForOverflowClip.release(), 424 newClipNodeForOverflowClip.release(),
415 newTransformNodeForPerspective.release(), 425 newTransformNodeForPerspective.release(),
426 newTransformNodeForSvgLocalTransform.release(),
416 newTransformNodeForScrollTranslation.release(), 427 newTransformNodeForScrollTranslation.release(),
417 newTransformNodeForScrollbarPaintOffset.release(), 428 newTransformNodeForScrollbarPaintOffset.release(),
418 newRecordedContext.release()); 429 newRecordedContext.release());
419 object.setObjectPaintProperties(updatedPaintProperties.release()); 430 object.setObjectPaintProperties(updatedPaintProperties.release());
420 } else { 431 } else {
421 object.clearObjectPaintProperties(); 432 object.clearObjectPaintProperties();
422 } 433 }
423 434
424 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { 435 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) {
425 if (child->isBoxModelObject() || child->isSVG()) 436 if (child->isBoxModelObject() || child->isSVG())
426 walk(*child, localContext); 437 walk(*child, localContext);
427 } 438 }
428 439
429 if (object.isLayoutPart()) { 440 if (object.isLayoutPart()) {
430 Widget* widget = toLayoutPart(object).widget(); 441 Widget* widget = toLayoutPart(object).widget();
431 if (widget && widget->isFrameView()) 442 if (widget && widget->isFrameView())
432 walk(*toFrameView(widget), localContext); 443 walk(*toFrameView(widget), localContext);
433 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). 444 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
434 } 445 }
435 } 446 }
436 447
437 } // namespace blink 448 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698