| 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
|
|
|