Index: third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp |
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp |
index 7cd271a0483aeeac1d94181c48fa79978e263e4c..3fbc2df6a26356626559a7146c09d3d8ff2a0978 100644 |
--- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp |
+++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp |
@@ -145,23 +145,34 @@ void LayoutSVGRoot::layout() { |
updateLogicalWidth(); |
updateLogicalHeight(); |
- buildLocalToBorderBoxTransform(); |
- // TODO(fs): Temporarily, needing a layout implies that the local transform |
- // has changed. This should be updated to be more precise and factor in the |
- // actual (relevant) changes to the computed user-space transform. |
- m_didScreenScaleFactorChange = selfNeedsLayout(); |
+ // The local-to-border-box transform is a function with the following as |
+ // input: |
+ // |
+ // * effective zoom |
+ // * contentWidth/Height |
+ // * viewBox |
+ // * border + padding |
+ // * currentTranslate |
+ // * currentScale |
+ // |
+ // Which means that |transformChange| will notice a change to the scale from |
+ // any of these. |
+ SVGTransformChange transformChange = buildLocalToBorderBoxTransform(); |
+ |
+ // The scale factor from the local-to-border-box transform is all that our |
+ // scale-dependent descendants care about. |
+ m_didScreenScaleFactorChange = transformChange == SVGTransformChange::Full; |
SVGLayoutSupport::layoutResourcesIfNeeded(this); |
// selfNeedsLayout() will cover changes to one (or more) of viewBox, |
- // current{Scale,Translate} and decorations. |
+ // current{Scale,Translate}, decorations and 'overflow'. |
const bool viewportMayHaveChanged = selfNeedsLayout() || oldSize != size(); |
- // The scale of one or more of the SVG elements may have changed, or new |
- // content may have been exposed, so mark the entire subtree as needing paint |
- // invalidation checking. (It is only somewhat by coincidence that this |
- // condition happens to be the same as the one for viewport changes.) |
- if (viewportMayHaveChanged) { |
+ // The scale of one or more of the SVG elements may have changed, content |
+ // (the entire SVG) could have moved or new content may have been exposed, so |
+ // mark the entire subtree as needing paint invalidation checking. |
+ if (transformChange != SVGTransformChange::None || viewportMayHaveChanged) { |
setMayNeedPaintInvalidationSubtree(); |
if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) |
setNeedsPaintPropertyUpdate(); |
@@ -333,21 +344,23 @@ PositionWithAffinity LayoutSVGRoot::positionForPoint(const LayoutPoint& point) { |
// LayoutBox methods will expect coordinates w/o any transforms in coordinates |
// relative to our borderBox origin. This method gives us exactly that. |
-void LayoutSVGRoot::buildLocalToBorderBoxTransform() { |
+SVGTransformChange LayoutSVGRoot::buildLocalToBorderBoxTransform() { |
+ SVGTransformChangeDetector changeDetector(m_localToBorderBoxTransform); |
SVGSVGElement* svg = toSVGSVGElement(node()); |
ASSERT(svg); |
float scale = style()->effectiveZoom(); |
- FloatPoint translate = svg->currentTranslate(); |
- LayoutSize borderAndPadding(borderLeft() + paddingLeft(), |
- borderTop() + paddingTop()); |
m_localToBorderBoxTransform = svg->viewBoxToViewTransform( |
contentWidth() / scale, contentHeight() / scale); |
+ FloatPoint translate = svg->currentTranslate(); |
+ LayoutSize borderAndPadding(borderLeft() + paddingLeft(), |
+ borderTop() + paddingTop()); |
AffineTransform viewToBorderBoxTransform( |
scale, 0, 0, scale, borderAndPadding.width() + translate.x(), |
borderAndPadding.height() + translate.y()); |
viewToBorderBoxTransform.scale(svg->currentScale()); |
m_localToBorderBoxTransform.preMultiply(viewToBorderBoxTransform); |
+ return changeDetector.computeChange(m_localToBorderBoxTransform); |
} |
AffineTransform LayoutSVGRoot::localToSVGParentTransform() const { |