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

Unified Diff: Source/core/layout/svg/LayoutSVGEllipse.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/LayoutSVGEllipse.h ('k') | Source/core/layout/svg/LayoutSVGPath.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/layout/svg/LayoutSVGEllipse.cpp
diff --git a/Source/core/layout/svg/LayoutSVGEllipse.cpp b/Source/core/layout/svg/LayoutSVGEllipse.cpp
index 8809a19effc56498f07bce318b1f8db40dee533e..3c14eb186daec78597a50a6efc3720218c6b85f7 100644
--- a/Source/core/layout/svg/LayoutSVGEllipse.cpp
+++ b/Source/core/layout/svg/LayoutSVGEllipse.cpp
@@ -45,38 +45,44 @@ LayoutSVGEllipse::~LayoutSVGEllipse()
{
}
+void LayoutSVGEllipse::styleDidChange(StyleDifference diff, const ComputedStyle* oldStyle)
+{
+ if (diff.needsFullLayout() && oldStyle) {
+ const SVGComputedStyle& oldSvgStyle = oldStyle->svgStyle();
+ const SVGComputedStyle& svgStyle = style()->svgStyle();
+
+ bool radiusChanged;
+ if (isSVGCircleElement(*element()))
+ radiusChanged = oldSvgStyle.r() != svgStyle.r();
+ else
+ radiusChanged = (oldSvgStyle.rx() != svgStyle.rx()) || (oldSvgStyle.ry() != svgStyle.ry());
+
+ if (oldSvgStyle.cx() != svgStyle.cx()
+ || oldSvgStyle.cy() != svgStyle.cy()
+ || radiusChanged
+ || oldSvgStyle.vectorEffect() != svgStyle.vectorEffect()
+ || hasContinuousStroke(oldSvgStyle) != hasContinuousStroke(svgStyle))
+ setNeedsShapeUpdate();
+ }
+
+ // Superclass will take care of calling clientStyleChanged.
+ LayoutSVGShape::styleDidChange(diff, oldStyle);
+}
+
void LayoutSVGEllipse::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_center = FloatPoint();
- m_radii = FloatSize();
m_usePathFallback = false;
-
calculateRadiiAndCenter();
- // Spec: "A negative value is an error. A value of zero disables rendering of the element."
- if (m_radii.width() < 0 || m_radii.height() < 0)
+ // Fall back to LayoutSVGShape and path-based hit detection if the ellipse
+ // has a non-scaling or discontinuous stroke.
+ if (hasNonScalingStroke() || !hasContinuousStroke(style()->svgStyle())) {
+ LayoutSVGShape::updateShapeFromElement();
+ m_usePathFallback = true;
return;
-
- if (!m_radii.isEmpty()) {
- // Fall back to LayoutSVGShape and path-based hit detection if the ellipse
- // has a non-scaling or discontinuous stroke.
- if (hasNonScalingStroke() || !hasContinuousStroke()) {
- LayoutSVGShape::updateShapeFromElement();
- m_usePathFallback = true;
- return;
- }
}
clearPath();
-
- m_fillBoundingBox = FloatRect(m_center.x() - m_radii.width(), m_center.y() - m_radii.height(), 2 * m_radii.width(), 2 * m_radii.height());
- m_strokeBoundingBox = m_fillBoundingBox;
- if (style()->svgStyle().hasStroke())
- m_strokeBoundingBox.inflate(strokeWidth() / 2);
}
void LayoutSVGEllipse::calculateRadiiAndCenter()
@@ -97,15 +103,41 @@ void LayoutSVGEllipse::calculateRadiiAndCenter()
}
}
+void LayoutSVGEllipse::updateStrokeAndFillBoundingBoxes()
+{
+ // Spec: "A negative value is an error."
+ if (m_radii.width() < 0 || m_radii.height() < 0) {
+ m_fillBoundingBox = FloatRect();
+ m_strokeBoundingBox = FloatRect();
+ return;
+ }
+
+ 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 (!m_radii.isEmpty()) {
+ LayoutSVGShape::updateStrokeAndFillBoundingBoxes();
+ return;
+ }
+ m_usePathFallback = false;
+ clearPath();
+ }
+
+ m_fillBoundingBox = FloatRect(m_center.x() - m_radii.width(), m_center.y() - m_radii.height(), 2 * m_radii.width(), 2 * m_radii.height());
+ m_strokeBoundingBox = m_fillBoundingBox;
+ if (style()->svgStyle().hasStroke())
+ m_strokeBoundingBox.inflate(strokeWidth() / 2);
+}
+
bool LayoutSVGEllipse::shapeDependentStrokeContains(const FloatPoint& point)
{
// The optimized check below for circles does not support non-scaling or
// discontinuous strokes.
if (m_usePathFallback
- || !hasContinuousStroke()
+ || !hasContinuousStroke(style()->svgStyle())
|| m_radii.width() != m_radii.height()) {
- if (!hasPath())
- createPath();
+ if (!m_usePathFallback)
+ LayoutSVGShape::updateShapeFromElement();
return LayoutSVGShape::shapeDependentStrokeContains(point);
}
@@ -126,9 +158,8 @@ bool LayoutSVGEllipse::shapeDependentFillContains(const FloatPoint& point, const
return xrX * xrX + yrY * yrY <= 1.0;
}
-bool LayoutSVGEllipse::hasContinuousStroke() const
+bool LayoutSVGEllipse::hasContinuousStroke(const SVGComputedStyle& svgStyle) const
{
- const SVGComputedStyle& svgStyle = style()->svgStyle();
return svgStyle.strokeDashArray()->isEmpty();
}
« no previous file with comments | « Source/core/layout/svg/LayoutSVGEllipse.h ('k') | Source/core/layout/svg/LayoutSVGPath.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698