Index: Source/WebCore/rendering/svg/RenderSVGPath.cpp |
=================================================================== |
--- Source/WebCore/rendering/svg/RenderSVGPath.cpp (revision 97063) |
+++ Source/WebCore/rendering/svg/RenderSVGPath.cpp (working copy) |
@@ -100,9 +100,6 @@ |
if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), fallbackColor)) |
return false; |
- if (shouldStrokeZeroLengthSubpath()) |
- return zeroLengthSubpathRect().contains(point); |
- |
BoundingRectStrokeStyleApplier strokeStyle(this, style()); |
return m_path.strokeContains(&strokeStyle, point); |
} |
@@ -152,53 +149,6 @@ |
setNeedsLayout(false); |
} |
-bool RenderSVGPath::shouldStrokeZeroLengthSubpath() const |
-{ |
- // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt |
- // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square |
- return style()->svgStyle()->hasStroke() && style()->svgStyle()->capStyle() != ButtCap && !m_fillBoundingBox.width() && !m_fillBoundingBox.height(); |
-} |
- |
-FloatRect RenderSVGPath::zeroLengthSubpathRect() const |
-{ |
- SVGElement* svgElement = static_cast<SVGElement*>(node()); |
- float strokeWidth = style()->svgStyle()->strokeWidth().value(svgElement); |
- return FloatRect(m_fillBoundingBox.x() - strokeWidth / 2, m_fillBoundingBox.y() - strokeWidth / 2, strokeWidth, strokeWidth); |
-} |
- |
-void RenderSVGPath::setupSquareCapPath(Path*& usePath, int& applyMode) |
-{ |
- // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt |
- // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square |
- DEFINE_STATIC_LOCAL(Path, tempPath, ()); |
- |
- applyMode = ApplyToFillMode; |
- usePath = &tempPath; |
- usePath->clear(); |
- if (style()->svgStyle()->capStyle() == SquareCap) |
- usePath->addRect(zeroLengthSubpathRect()); |
- else |
- usePath->addEllipse(zeroLengthSubpathRect()); |
-} |
- |
-bool RenderSVGPath::setupNonScalingStrokePath(Path*& usePath, GraphicsContextStateSaver& stateSaver) |
-{ |
- DEFINE_STATIC_LOCAL(Path, tempPath, ()); |
- |
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); |
- AffineTransform nonScalingStrokeTransform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate); |
- if (!nonScalingStrokeTransform.isInvertible()) |
- return false; |
- |
- tempPath = m_path; |
- usePath = &tempPath; |
- tempPath.transform(nonScalingStrokeTransform); |
- |
- stateSaver.save(); |
- stateSaver.context()->concatCTM(nonScalingStrokeTransform.inverse()); |
- return true; |
-} |
- |
void RenderSVGPath::fillAndStrokePath(GraphicsContext* context) |
{ |
RenderStyle* style = this->style(); |
@@ -220,30 +170,31 @@ |
if (!strokePaintingResource) |
return; |
- Path* usePath = &m_path; |
- int applyMode = ApplyToStrokeMode; |
+ Path path; |
bool nonScalingStroke = style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE; |
GraphicsContextStateSaver stateSaver(*context, false); |
+ if (nonScalingStroke) { |
+ SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); |
+ AffineTransform nonScalingStrokeTransform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate); |
+ if (!nonScalingStrokeTransform.isInvertible()) |
+ return; |
- // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt |
- // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square |
- // FIXME: this does not work for zero-length subpaths, only when total path is zero-length |
- if (shouldStrokeZeroLengthSubpath()) |
- setupSquareCapPath(usePath, applyMode); |
- else if (nonScalingStroke) { |
- if (!setupNonScalingStrokePath(usePath, stateSaver)) |
- return; |
+ path = m_path; |
+ path.transform(nonScalingStrokeTransform); |
+ |
+ stateSaver.save(); |
+ context->concatCTM(nonScalingStrokeTransform.inverse()); |
} |
- if (strokePaintingResource->applyResource(this, style, context, applyMode)) |
- strokePaintingResource->postApplyResource(this, context, applyMode, usePath); |
+ if (strokePaintingResource->applyResource(this, style, context, ApplyToStrokeMode)) |
+ strokePaintingResource->postApplyResource(this, context, ApplyToStrokeMode, nonScalingStroke ? &path : &m_path); |
else if (fallbackColor.isValid()) { |
RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource(); |
fallbackResource->setColor(fallbackColor); |
- if (fallbackResource->applyResource(this, style, context, applyMode)) |
- fallbackResource->postApplyResource(this, context, applyMode, usePath); |
+ if (fallbackResource->applyResource(this, style, context, ApplyToStrokeMode)) |
+ fallbackResource->postApplyResource(this, context, ApplyToStrokeMode, nonScalingStroke ? &path : &m_path); |
} |
} |
@@ -359,16 +310,6 @@ |
// Cache _unclipped_ fill bounding box, used for calculations in resources |
m_fillBoundingBox = m_path.boundingRect(); |
- // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-linecap’ property has a value of butt |
- // but shall be stroked if the ‘stroke-linecap’ property has a value of round or square |
- if (shouldStrokeZeroLengthSubpath()) { |
- m_strokeAndMarkerBoundingBox = zeroLengthSubpathRect(); |
- // Cache smallest possible repaint rectangle |
- m_repaintBoundingBox = m_strokeAndMarkerBoundingBox; |
- SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox); |
- return; |
- } |
- |
// Cache _unclipped_ stroke bounding box, used for calculations in resources (includes marker boundaries) |
m_strokeAndMarkerBoundingBox = m_fillBoundingBox; |