| 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();
|
| }
|
|
|
|
|