diff options
Diffstat (limited to 'third_party/WebKit/Source/core/layout/svg')
17 files changed, 100 insertions, 128 deletions
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp index 7804493..0414f44 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp @@ -82,9 +82,9 @@ void LayoutSVGBlock::styleDidChange(StyleDifference diff, const ComputedStyle* o SVGResourcesCache::clientStyleChanged(this, diff, styleRef()); } -void LayoutSVGBlock::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed, const PaintInvalidationState* paintInvalidationState) const +void LayoutSVGBlock::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const { - SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, wasFixed, paintInvalidationState); + SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, wasFixed); } void LayoutSVGBlock::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags) const @@ -99,16 +99,14 @@ const LayoutObject* LayoutSVGBlock::pushMappingToContainer(const LayoutBoxModelO return SVGLayoutSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap); } -LayoutRect LayoutSVGBlock::clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const +LayoutRect LayoutSVGBlock::absoluteClippedOverflowRect() const { - return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, paintInvalidationContainer, paintInvalidationState); + return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, *view()); } -bool LayoutSVGBlock::mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState, VisibleRectFlags visibleRectFlags) const +bool LayoutSVGBlock::mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect& rect, VisibleRectFlags visibleRectFlags) const { - FloatRect paintInvalidationRect(rect); - const LayoutSVGRoot& svgRoot = SVGLayoutSupport::mapRectToSVGRootForPaintInvalidation(*this, paintInvalidationRect, rect); - return svgRoot.mapToVisibleRectInAncestorSpace(ancestor, rect, paintInvalidationState, visibleRectFlags); + return SVGLayoutSupport::mapToVisibleRectInAncestorSpace(*this, ancestor, FloatRect(rect), rect); } bool LayoutSVGBlock::nodeAtPoint(HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction) @@ -122,6 +120,7 @@ void LayoutSVGBlock::invalidateTreeIfNeeded(const PaintInvalidationState& paintI if (!shouldCheckForPaintInvalidation(paintInvalidationState)) return; + // TODO(wangxianzhu): Move this to fast path if possible. crbug.com/391054. ForceHorriblySlowRectMapping slowRectMapping(&paintInvalidationState); LayoutBlockFlow::invalidateTreeIfNeeded(paintInvalidationState); } diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.h index ccbc362..1dcca09 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.h @@ -30,9 +30,7 @@ class LayoutSVGBlock : public LayoutBlockFlow { public: explicit LayoutSVGBlock(SVGElement*); - LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* = nullptr) const final; - - void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr, const PaintInvalidationState* = nullptr) const final; + void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr) const final; void mapAncestorToLocal(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip) const final; const LayoutObject* pushMappingToContainer(const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap&) const final; @@ -44,12 +42,14 @@ public: protected: void willBeDestroyed() override; - bool mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect&, const PaintInvalidationState*, VisibleRectFlags = DefaultVisibleRectFlags) const final; + bool mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect&, VisibleRectFlags = DefaultVisibleRectFlags) const final; AffineTransform m_localTransform; bool isOfType(LayoutObjectType type) const override { return type == LayoutObjectSVG || LayoutBlockFlow::isOfType(type); } private: + LayoutRect absoluteClippedOverflowRect() const final; + bool allowsOverflowClip() const final; void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const final; diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGGradientStop.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGGradientStop.h index 739e1b5..51eed2e 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGGradientStop.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGGradientStop.h @@ -42,7 +42,7 @@ public: // This overrides are needed to prevent ASSERTs on <svg><stop /></svg> // LayoutObject's default implementations ASSERT_NOT_REACHED() // https://bugs.webkit.org/show_bug.cgi?id=20400 - LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject*, const PaintInvalidationState* = nullptr) const override { return LayoutRect(); } + LayoutRect localOverflowRectForPaintInvalidation() const override { return LayoutRect(); } FloatRect objectBoundingBox() const override { return FloatRect(); } FloatRect strokeBoundingBox() const override { return FloatRect(); } FloatRect paintInvalidationRectInLocalSVGCoordinates() const override { return FloatRect(); } diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.h index 5f45a37..71dfc0b 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGHiddenContainer.h @@ -41,7 +41,8 @@ protected: private: void paint(const PaintInfo&, const LayoutPoint&) const final; - LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject*, const PaintInvalidationState* = nullptr) const final { return LayoutRect(); } + LayoutRect absoluteClippedOverflowRect() const final { return LayoutRect(); } + FloatRect paintInvalidationRectInLocalSVGCoordinates() const final { return FloatRect(); } void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const final; bool nodeAtFloatPoint(HitTestResult&, const FloatPoint& pointInParent, HitTestAction) final; diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp index 97ee97d..3606e44 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp @@ -21,6 +21,7 @@ #include "core/layout/svg/LayoutSVGInline.h" +#include "core/layout/LayoutView.h" #include "core/layout/svg/LayoutSVGText.h" #include "core/layout/svg/SVGLayoutSupport.h" #include "core/layout/svg/SVGResourcesCache.h" @@ -83,14 +84,14 @@ FloatRect LayoutSVGInline::paintInvalidationRectInLocalSVGCoordinates() const return FloatRect(); } -LayoutRect LayoutSVGInline::clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const +LayoutRect LayoutSVGInline::absoluteClippedOverflowRect() const { - return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, paintInvalidationContainer, paintInvalidationState); + return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, *view()); } -void LayoutSVGInline::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed, const PaintInvalidationState* paintInvalidationState) const +void LayoutSVGInline::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const { - SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, wasFixed, paintInvalidationState); + SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, wasFixed); } const LayoutObject* LayoutSVGInline::pushMappingToContainer(const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const @@ -165,7 +166,7 @@ void LayoutSVGInline::invalidateTreeIfNeeded(const PaintInvalidationState& paint if (reason == PaintInvalidationSVGResourceChange) newPaintInvalidationState.setForceSubtreeInvalidationWithinContainer(); - newPaintInvalidationState.updatePaintOffsetAndClipForChildren(); + newPaintInvalidationState.updateForChildren(); invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); } diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.h index 2d851b1..9680f57 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.h @@ -44,8 +44,8 @@ public: FloatRect strokeBoundingBox() const final; FloatRect paintInvalidationRectInLocalSVGCoordinates() const final; - LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* = nullptr) const final; - void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr, const PaintInvalidationState* = nullptr) const final; + LayoutRect absoluteClippedOverflowRect() const final; + void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr) const final; const LayoutObject* pushMappingToContainer(const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap&) const final; void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const final; diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp index 259d6f3..4ee1f83 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.cpp @@ -231,12 +231,14 @@ void LayoutSVGInlineText::computeNewScaledFontForStyle(LayoutObject* layoutObjec scaledFont.update(document.styleEngine().fontSelector()); } -LayoutRect LayoutSVGInlineText::clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const +LayoutRect LayoutSVGInlineText::absoluteClippedOverflowRect() const { - // FIXME: The following works because LayoutSVGBlock has forced slow rect mapping of the paintInvalidationState. - // Should let this really work with paintInvalidationState's fast mapping and remove the assert. - ASSERT(!paintInvalidationState || !paintInvalidationState->canMapToAncestor(paintInvalidationContainer)); - return parent()->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer, nullptr); + return parent()->absoluteClippedOverflowRect(); +} + +FloatRect LayoutSVGInlineText::paintInvalidationRectInLocalSVGCoordinates() const +{ + return parent()->paintInvalidationRectInLocalSVGCoordinates(); } PassRefPtr<StringImpl> LayoutSVGInlineText::originalText() const diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.h index b8ea64a..5084e1e 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInlineText.h @@ -60,7 +60,8 @@ private: IntRect linesBoundingBox() const override; InlineTextBox* createTextBox(int start, unsigned short length) override; - LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState*) const final; + LayoutRect absoluteClippedOverflowRect() const final; + FloatRect paintInvalidationRectInLocalSVGCoordinates() const final; float m_scalingFactor; Font m_scaledFont; diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp index 76144fa..9681a52 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp @@ -50,14 +50,14 @@ bool LayoutSVGModelObject::isChildAllowed(LayoutObject* child, const ComputedSty return child->isSVG() && !(child->isSVGInline() || child->isSVGInlineText() || child->isSVGGradientStop()); } -LayoutRect LayoutSVGModelObject::clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const +void LayoutSVGModelObject::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const { - return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, paintInvalidationContainer, paintInvalidationState); + SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, wasFixed); } -void LayoutSVGModelObject::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed, const PaintInvalidationState* paintInvalidationState) const +LayoutRect LayoutSVGModelObject::absoluteClippedOverflowRect() const { - SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, wasFixed, paintInvalidationState); + return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, *view()); } void LayoutSVGModelObject::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags) const @@ -143,7 +143,7 @@ void LayoutSVGModelObject::invalidateTreeIfNeeded(const PaintInvalidationState& invalidatePaintIfNeeded(newPaintInvalidationState); clearPaintInvalidationFlags(newPaintInvalidationState); - newPaintInvalidationState.updatePaintOffsetAndClipForChildren(); + newPaintInvalidationState.updateForChildren(); invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); } diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.h index a9a29a7..2552b13c 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.h @@ -47,14 +47,13 @@ public: bool isChildAllowed(LayoutObject*, const ComputedStyle&) const override; - LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* = nullptr) const override; - - FloatRect paintInvalidationRectInLocalSVGCoordinates() const final { return m_paintInvalidationBoundingBox; } + LayoutRect absoluteClippedOverflowRect() const override; + FloatRect paintInvalidationRectInLocalSVGCoordinates() const override { return m_paintInvalidationBoundingBox; } void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const final; void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override; - void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr, const PaintInvalidationState* = nullptr) const final; + void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr) const final; void mapAncestorToLocal(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip) const final; const LayoutObject* pushMappingToContainer(const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap&) const final; void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override; diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp index b2cb115..ed7548a 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.cpp @@ -318,12 +318,13 @@ const AffineTransform& LayoutSVGRoot::localToSVGParentTransform() const return m_localToParentTransform; } -LayoutRect LayoutSVGRoot::clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState) const +LayoutRect LayoutSVGRoot::localOverflowRectForPaintInvalidation() const { - // This is an open-coded aggregate of SVGLayoutSupport::clippedOverflowRectForPaintInvalidation, - // LayoutSVGRoot::mapToVisibleRectInAncestorSpace and LayoutReplaced::clippedOverflowRectForPaintInvalidation. + // This is an open-coded aggregate of SVGLayoutSupport::localOverflowRectForPaintInvalidation, + // and LayoutReplaced::localOverflowRectForPaintInvalidation. // The reason for this is to optimize/minimize the paint invalidation rect when the box is not "decorated" // (does not have background/border/etc.) + // TODO(wangxianzhu): Verify if the optimization is still needed. // Return early for any cases where we don't actually paint. if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent()) @@ -346,18 +347,17 @@ LayoutRect LayoutSVGRoot::clippedOverflowRectForPaintInvalidation(const LayoutBo paintInvalidationRect.unite(decoratedPaintInvalidationRect); } - // Compute the paint invalidation rect in the parent coordinate space. - LayoutRect rect(enclosingIntRect(paintInvalidationRect)); - LayoutReplaced::mapToVisibleRectInAncestorSpace(paintInvalidationContainer, rect, paintInvalidationState); - return rect; + return LayoutRect(enclosingIntRect(paintInvalidationRect)); } -bool LayoutSVGRoot::mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState, VisibleRectFlags visibleRectFlags) const +bool LayoutSVGRoot::mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect& rect, VisibleRectFlags visibleRectFlags) const { // Note that we don't apply the border-box transform here - it's assumed // that whoever called us has done that already. // Apply initial viewport clip + // TODO(crbug.com/597813): We should not apply clip on LayoutSVGRoot's own rect. This clip should + // be applied in children's mapToVisibleRectInAncestorSpace(). if (shouldApplyViewportClip()) { if (visibleRectFlags & EdgeInclusive) { if (!rect.inclusiveIntersect(LayoutRect(pixelSnappedBorderBoxRect()))) @@ -367,17 +367,17 @@ bool LayoutSVGRoot::mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* } } - return LayoutReplaced::mapToVisibleRectInAncestorSpace(ancestor, rect, paintInvalidationState, visibleRectFlags); + return LayoutReplaced::mapToVisibleRectInAncestorSpace(ancestor, rect, visibleRectFlags); } // This method expects local CSS box coordinates. // Callers with local SVG viewport coordinates should first apply the localToBorderBoxTransform // to convert from SVG viewport coordinates to local CSS box coordinates. -void LayoutSVGRoot::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed, const PaintInvalidationState* paintInvalidationState) const +void LayoutSVGRoot::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const { ASSERT(!(mode & IsFixed)); // We should have no fixed content in the SVG layout tree. - LayoutReplaced::mapLocalToAncestor(ancestor, transformState, mode | ApplyContainerFlip, wasFixed, paintInvalidationState); + LayoutReplaced::mapLocalToAncestor(ancestor, transformState, mode | ApplyContainerFlip, wasFixed); } const LayoutObject* LayoutSVGRoot::pushMappingToContainer(const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.h index 27d8ebd..2474972 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGRoot.h @@ -38,7 +38,7 @@ public: bool isEmbeddedThroughFrameContainingSVGDocument() const; void computeIntrinsicSizingInfo(IntrinsicSizingInfo&) const override; - bool mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect&, const PaintInvalidationState*, VisibleRectFlags = DefaultVisibleRectFlags) const override; + bool mapToVisibleRectInAncestorSpace(const LayoutBoxModelObject* ancestor, LayoutRect&, VisibleRectFlags = DefaultVisibleRectFlags) const override; // If you have a LayoutSVGRoot, use firstChild or lastChild instead. void slowFirstChild() const = delete; @@ -101,9 +101,9 @@ private: bool nodeAtPoint(HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override; - LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState* = nullptr) const override; + LayoutRect localOverflowRectForPaintInvalidation() const override; - void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr, const PaintInvalidationState* = nullptr) const override; + void mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = nullptr) const override; const LayoutObject* pushMappingToContainer(const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap&) const override; bool canBeSelectionLeaf() const override { return false; } diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.cpp index abcd05e..b7671c4 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.cpp @@ -295,15 +295,6 @@ float LayoutSVGShape::strokeWidth() const return lengthContext.valueForLength(style()->svgStyle().strokeWidth()); } -LayoutRect LayoutSVGShape::clippedOverflowRectForPaintInvalidation( - const LayoutBoxModelObject* paintInvalidationContainer, - const PaintInvalidationState* paintInvalidationState) const -{ - const float strokeWidthForHairlinePadding = style()->svgStyle().hasStroke() ? strokeWidth() : 0; - return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, - paintInvalidationContainer, paintInvalidationState, strokeWidthForHairlinePadding); -} - LayoutSVGShapeRareData& LayoutSVGShape::ensureRareData() const { if (!m_rareData) diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.h index afe3667..55b53b8 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGShape.h @@ -113,8 +113,6 @@ private: bool strokeContains(const FloatPoint&, bool requiresStroke = true); const AffineTransform& localToSVGParentTransform() const final { return m_localTransform; } - LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutBoxModelObject*, - const PaintInvalidationState* = nullptr) const override; bool isOfType(LayoutObjectType type) const override { return type == LayoutObjectSVGShape || LayoutSVGModelObject::isOfType(type); } void layout() final; diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp index a60f188f..8a66fd8 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGText.cpp @@ -516,11 +516,12 @@ void LayoutSVGText::invalidateTreeIfNeeded(const PaintInvalidationState& paintIn if (reason == PaintInvalidationDelayedFull) paintInvalidationState.pushDelayedPaintInvalidationTarget(*this); + // TODO(wangxianzhu): Move this to fast path if possible. crbug.com/391054. ForceHorriblySlowRectMapping slowRectMapping(&newPaintInvalidationState); if (reason == PaintInvalidationSVGResourceChange) newPaintInvalidationState.setForceSubtreeInvalidationWithinContainer(); - newPaintInvalidationState.updatePaintOffsetAndClipForChildren(); + newPaintInvalidationState.updateForChildren(); invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); } diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp index 5d69308..3ed6613 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp @@ -59,63 +59,53 @@ struct SearchCandidate { float candidateDistance; }; -static inline LayoutRect adjustedEnclosingIntRect(const FloatRect& rect, - const AffineTransform& rootTransform, float strokeWidthForHairlinePadding) -{ - FloatRect adjustedRect = rect; - - if (strokeWidthForHairlinePadding) { - // For hairline strokes (stroke-width < 1 in device space), Skia rasterizes up to 0.4(9) off - // the stroke center. That means enclosingIntRect is not enough - we must also pad to 0.5. - // This is still fragile as it misses out on CC/DSF CTM components. - const FloatSize strokeSize = rootTransform.mapSize( - FloatSize(strokeWidthForHairlinePadding, strokeWidthForHairlinePadding)); - if (strokeSize.width() < 1 || strokeSize.height() < 1) { - const float pad = 0.5f - std::min(strokeSize.width(), strokeSize.height()) / 2; - ASSERT(pad > 0); - adjustedRect.inflate(pad); - } - } - - if (adjustedRect.isEmpty()) - return LayoutRect(); - - return LayoutRect(enclosingIntRect(adjustedRect)); -} - -LayoutRect SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(const LayoutObject& object, - const LayoutBoxModelObject* paintInvalidationContainer, - const PaintInvalidationState* paintInvalidationState, float strokeWidthForHairlinePadding) +FloatRect SVGLayoutSupport::localOverflowRectForPaintInvalidation(const LayoutObject& object) { + // This doesn't apply to LayoutSVGRoot. Use LayoutSVGRoot::localOverflowRectForPaintInvalidation() instead. + ASSERT(!object.isSVGRoot()); + // Return early for any cases where we don't actually paint if (object.styleRef().visibility() != VISIBLE && !object.enclosingLayer()->hasVisibleContent()) - return LayoutRect(); + return FloatRect(); FloatRect paintInvalidationRect = object.paintInvalidationRectInLocalSVGCoordinates(); if (int outlineOutset = object.styleRef().outlineOutsetExtent()) paintInvalidationRect.inflate(outlineOutset); + return paintInvalidationRect; +} - if (paintInvalidationState && paintInvalidationState->canMapToAncestor(paintInvalidationContainer)) { - // Compute accumulated SVG transform and apply to local paint rect. - AffineTransform transform = paintInvalidationState->svgTransform() * object.localToSVGParentTransform(); - - // FIXME: These are quirks carried forward from the old paint invalidation infrastructure. - LayoutRect rect = adjustedEnclosingIntRect(transform.mapRect(paintInvalidationRect), - transform, strokeWidthForHairlinePadding); - // Offset by SVG root paint offset and apply clipping as needed. - rect.move(paintInvalidationState->paintOffset()); - if (paintInvalidationState->isClipped()) - rect.intersect(paintInvalidationState->clipRect()); - return rect; - } - +LayoutRect SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(const LayoutObject& object, const LayoutBoxModelObject& paintInvalidationContainer) +{ LayoutRect rect; - const LayoutSVGRoot& svgRoot = mapRectToSVGRootForPaintInvalidation(object, - paintInvalidationRect, rect, strokeWidthForHairlinePadding); - svgRoot.mapToVisibleRectInAncestorSpace(paintInvalidationContainer, rect, nullptr); + mapToVisibleRectInAncestorSpace(object, &paintInvalidationContainer, localOverflowRectForPaintInvalidation(object), rect); return rect; } +LayoutRect SVGLayoutSupport::transformPaintInvalidationRect(const LayoutObject& object, const AffineTransform& rootTransform, const FloatRect& localRect) +{ + FloatRect adjustedRect = rootTransform.mapRect(localRect); + + if (object.isSVGShape() && object.styleRef().svgStyle().hasStroke()) { + if (float strokeWidthForHairlinePadding = toLayoutSVGShape(object).strokeWidth()) { + // For hairline strokes (stroke-width < 1 in device space), Skia rasterizes up to 0.4(9) off + // the stroke center. That means enclosingIntRect is not enough - we must also pad to 0.5. + // This is still fragile as it misses out on CC/DSF CTM components. + const FloatSize strokeSize = rootTransform.mapSize( + FloatSize(strokeWidthForHairlinePadding, strokeWidthForHairlinePadding)); + if (strokeSize.width() < 1 || strokeSize.height() < 1) { + const float pad = 0.5f - std::min(strokeSize.width(), strokeSize.height()) / 2; + ASSERT(pad > 0); + adjustedRect.inflate(pad); + } + } + } + + if (adjustedRect.isEmpty()) + return LayoutRect(); + + return LayoutRect(enclosingIntRect(adjustedRect)); +} + static const LayoutSVGRoot& computeTransformToSVGRoot(const LayoutObject& object, AffineTransform& rootBorderBoxTransform) { ASSERT(object.isSVG() && !object.isSVGRoot()); @@ -129,28 +119,18 @@ static const LayoutSVGRoot& computeTransformToSVGRoot(const LayoutObject& object return svgRoot; } -const LayoutSVGRoot& SVGLayoutSupport::mapRectToSVGRootForPaintInvalidation(const LayoutObject& object, - const FloatRect& localPaintInvalidationRect, LayoutRect& rect, float strokeWidthForHairlinePadding) +bool SVGLayoutSupport::mapToVisibleRectInAncestorSpace(const LayoutObject& object, const LayoutBoxModelObject* ancestor, const FloatRect& localPaintInvalidationRect, LayoutRect& resultRect, VisibleRectFlags visibleRectFlags) { AffineTransform rootBorderBoxTransform; const LayoutSVGRoot& svgRoot = computeTransformToSVGRoot(object, rootBorderBoxTransform); - - rect = adjustedEnclosingIntRect(rootBorderBoxTransform.mapRect(localPaintInvalidationRect), - rootBorderBoxTransform, strokeWidthForHairlinePadding); - return svgRoot; + resultRect = transformPaintInvalidationRect(object, rootBorderBoxTransform, localPaintInvalidationRect); + return svgRoot.mapToVisibleRectInAncestorSpace(ancestor, resultRect, visibleRectFlags); } -void SVGLayoutSupport::mapLocalToAncestor(const LayoutObject* object, const LayoutBoxModelObject* ancestor, TransformState& transformState, bool* wasFixed, const PaintInvalidationState* paintInvalidationState) +void SVGLayoutSupport::mapLocalToAncestor(const LayoutObject* object, const LayoutBoxModelObject* ancestor, TransformState& transformState, bool* wasFixed) { transformState.applyTransform(object->localToSVGParentTransform()); - if (paintInvalidationState && paintInvalidationState->canMapToAncestor(ancestor)) { - // |svgTransform| contains localToBorderBoxTransform mentioned below. - transformState.applyTransform(paintInvalidationState->svgTransform()); - transformState.move(paintInvalidationState->paintOffset()); - return; - } - LayoutObject* parent = object->parent(); // At the SVG/HTML boundary (aka LayoutSVGRoot), we apply the localToBorderBoxTransform @@ -160,7 +140,7 @@ void SVGLayoutSupport::mapLocalToAncestor(const LayoutObject* object, const Layo transformState.applyTransform(toLayoutSVGRoot(parent)->localToBorderBoxTransform()); MapCoordinatesFlags mode = UseTransforms; - parent->mapLocalToAncestor(ancestor, transformState, mode, wasFixed, paintInvalidationState); + parent->mapLocalToAncestor(ancestor, transformState, mode, wasFixed); } void SVGLayoutSupport::mapAncestorToLocal(const LayoutObject& object, const LayoutBoxModelObject* ancestor, TransformState& transformState) diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h index f3c99a5..426e7f5 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h +++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h @@ -75,12 +75,11 @@ public: static void computeContainerBoundingBoxes(const LayoutObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& paintInvalidationBoundingBox); // Important functions used by nearly all SVG layoutObjects centralizing coordinate transformations / paint invalidation rect calculations - static LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutObject&, - const LayoutBoxModelObject* paintInvalidationContainer, const PaintInvalidationState*, - float strokeWidthForHairlinePadding = 0); - static const LayoutSVGRoot& mapRectToSVGRootForPaintInvalidation(const LayoutObject&, - const FloatRect& localPaintInvalidationRect, LayoutRect&, float strokeWidthForHairlinePadding = 0); - static void mapLocalToAncestor(const LayoutObject*, const LayoutBoxModelObject* ancestor, TransformState&, bool* wasFixed = nullptr, const PaintInvalidationState* = nullptr); + static FloatRect localOverflowRectForPaintInvalidation(const LayoutObject&); + static LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutObject&, const LayoutBoxModelObject& paintInvalidationContainer); + static LayoutRect transformPaintInvalidationRect(const LayoutObject&, const AffineTransform&, const FloatRect&); + static bool mapToVisibleRectInAncestorSpace(const LayoutObject&, const LayoutBoxModelObject* ancestor, const FloatRect& localPaintInvalidationRect, LayoutRect& resultRect, VisibleRectFlags = DefaultVisibleRectFlags); + static void mapLocalToAncestor(const LayoutObject*, const LayoutBoxModelObject* ancestor, TransformState&, bool* wasFixed = nullptr); static void mapAncestorToLocal(const LayoutObject&, const LayoutBoxModelObject* ancestor, TransformState&); static const LayoutObject* pushMappingToContainer(const LayoutObject*, const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap&); |