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

Unified Diff: Source/core/layout/svg/LayoutSVGRect.cpp

Issue 1158583003: Reduce how often LayoutSVGShape::updateShapeFromElement is called (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Put selfHasRelativeLengths back Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/layout/svg/LayoutSVGRect.h ('k') | Source/core/layout/svg/LayoutSVGShape.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/layout/svg/LayoutSVGRect.cpp
diff --git a/Source/core/layout/svg/LayoutSVGRect.cpp b/Source/core/layout/svg/LayoutSVGRect.cpp
index 18b0ccd737b67602e2f4f40fe69236ed49f814fe..d5890dcc06eb45aad4afea34bc4dfaa9973e1542 100644
--- a/Source/core/layout/svg/LayoutSVGRect.cpp
+++ b/Source/core/layout/svg/LayoutSVGRect.cpp
@@ -43,37 +43,64 @@ LayoutSVGRect::~LayoutSVGRect()
{
}
+void LayoutSVGRect::styleDidChange(StyleDifference diff, const ComputedStyle* oldStyle)
+{
+ if (diff.needsFullLayout() && oldStyle) {
+ const SVGComputedStyle& oldSvgStyle = oldStyle->svgStyle();
+ const SVGComputedStyle& svgStyle = style()->svgStyle();
+ if (oldSvgStyle.rx() != svgStyle.rx()
+ || oldSvgStyle.ry() != svgStyle.ry()
+ || oldSvgStyle.vectorEffect() != svgStyle.vectorEffect()
+ || definitelyHasSimpleStroke(oldSvgStyle) != definitelyHasSimpleStroke(svgStyle))
+ setNeedsShapeUpdate();
+ }
+
+ // Superclass will take care of calling clientStyleChanged.
+ LayoutSVGShape::styleDidChange(diff, oldStyle);
+}
+
void LayoutSVGRect::updateShapeFromElement()
{
- // Before creating a new object we need to clear the cached bounding box
- // to avoid using garbage.
- m_fillBoundingBox = FloatRect();
- m_strokeBoundingBox = FloatRect();
m_usePathFallback = false;
- SVGRectElement* rect = toSVGRectElement(element());
- ASSERT(rect);
- SVGLengthContext lengthContext(rect);
+ // Fallback to LayoutSVGShape and path-based hit detection if the rect
+ // has rounded corners or a non-scaling or non-simple stroke.
+ SVGLengthContext lengthContext(toSVGRectElement(element()));
+ if (lengthContext.valueForLength(styleRef().svgStyle().rx(), styleRef(), SVGLengthMode::Width) > 0
+ || lengthContext.valueForLength(styleRef().svgStyle().ry(), styleRef(), SVGLengthMode::Height) > 0
+ || hasNonScalingStroke()
+ || !definitelyHasSimpleStroke(style()->svgStyle())) {
+ LayoutSVGShape::updateShapeFromElement();
+ m_usePathFallback = true;
+ return;
+ }
+
+ clearPath();
+}
+
+void LayoutSVGRect::updateStrokeAndFillBoundingBoxes()
+{
+ SVGLengthContext lengthContext(toSVGRectElement(element()));
FloatSize boundingBoxSize(
lengthContext.valueForLength(styleRef().width(), styleRef(), SVGLengthMode::Width),
lengthContext.valueForLength(styleRef().height(), styleRef(), SVGLengthMode::Height));
// Spec: "A negative value is an error."
- if (boundingBoxSize.width() < 0 || boundingBoxSize.height() < 0)
+ if (boundingBoxSize.width() < 0 || boundingBoxSize.height() < 0) {
+ m_fillBoundingBox = FloatRect();
+ m_strokeBoundingBox = FloatRect();
return;
+ }
- // Spec: "A value of zero disables rendering of the element."
- if (!boundingBoxSize.isEmpty()) {
- // Fallback to LayoutSVGShape and path-based hit detection if the rect
- // has rounded corners or a non-scaling or non-simple stroke.
- if (lengthContext.valueForLength(styleRef().svgStyle().rx(), styleRef(), SVGLengthMode::Width) > 0
- || lengthContext.valueForLength(styleRef().svgStyle().ry(), styleRef(), SVGLengthMode::Height) > 0
- || hasNonScalingStroke()
- || !definitelyHasSimpleStroke()) {
- LayoutSVGShape::updateShapeFromElement();
- m_usePathFallback = true;
+ if (m_usePathFallback) {
+ // Spec: "A value of zero disables rendering of the element." so we can skip
+ // the path fallback and rely on the existing bounding box calculation.
+ if (!boundingBoxSize.isEmpty()) {
+ LayoutSVGShape::updateStrokeAndFillBoundingBoxes();
return;
}
+ m_usePathFallback = false;
+ clearPath();
}
m_fillBoundingBox = FloatRect(
@@ -90,8 +117,8 @@ bool LayoutSVGRect::shapeDependentStrokeContains(const FloatPoint& point)
{
// The optimized code below does not support non-simple strokes so we need
// to fall back to LayoutSVGShape::shapeDependentStrokeContains in these cases.
- if (m_usePathFallback || !definitelyHasSimpleStroke()) {
- if (!hasPath())
+ if (m_usePathFallback || !definitelyHasSimpleStroke(style()->svgStyle())) {
+ if (!m_usePathFallback)
LayoutSVGShape::updateShapeFromElement();
return LayoutSVGShape::shapeDependentStrokeContains(point);
}
@@ -119,10 +146,8 @@ bool LayoutSVGRect::shapeDependentFillContains(const FloatPoint& point, const Wi
}
// Returns true if the stroke is continuous and definitely uses miter joins.
-bool LayoutSVGRect::definitelyHasSimpleStroke() const
+bool LayoutSVGRect::definitelyHasSimpleStroke(const SVGComputedStyle& svgStyle) const
{
- const SVGComputedStyle& svgStyle = style()->svgStyle();
-
// The four angles of a rect are 90 degrees. Using the formula at:
// http://www.w3.org/TR/SVG/painting.html#StrokeMiterlimitProperty
// when the join style of the rect is "miter", the ratio of the miterLength
« no previous file with comments | « Source/core/layout/svg/LayoutSVGRect.h ('k') | Source/core/layout/svg/LayoutSVGShape.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698