Changeset 117709 in webkit
- Timestamp:
- May 20, 2012 12:49:45 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r117702 r117709 1 2012-05-20 Philip Rogers <pdr@google.com> 2 3 Fix hit testing on non-scaling strokes 4 https://bugs.webkit.org/show_bug.cgi?id=82628 5 6 Reviewed by Nikolas Zimmermann. 7 8 * platform/chromium/test_expectations.txt: 9 * platform/mac/Skipped: 10 * svg/custom/non-scaling-stroke-expected.txt: 11 * svg/hittest/svg-shapes-non-scale-stroke-expected.txt: Added. 12 * svg/hittest/svg-shapes-non-scale-stroke.html: Added. 13 1 14 2012-05-19 Joshua Bell <jsbell@chromium.org> 2 15 -
trunk/LayoutTests/platform/chromium/test_expectations.txt
r117677 r117709 1281 1281 BUGWK83875 LINUX : svg/text/font-size-below-point-five.svg = PASS TEXT 1282 1282 1283 BUGWK82628 : svg/hittest/svg-ellipse-non-scale-stroke.xhtml = FAIL1284 1285 1283 // It is very hard to see why some of these are failing. The diff must be tiny in some cases. 1286 1284 // Other fail intermittently in a way that is odd - clipping and masking should be stable. -
trunk/LayoutTests/platform/mac/Skipped
r117602 r117709 643 643 fast/table/cell-pref-width-invalidation.html 644 644 645 # https://bugs.webkit.org/show_bug.cgi?id=82628646 svg/hittest/svg-ellipse-non-scale-stroke.xhtml647 648 645 # The inner <input> should now grow to take the full cell's height. 649 646 fast/table/colspanMinWidth-vertical.html -
trunk/LayoutTests/svg/custom/non-scaling-stroke-expected.txt
r109097 r117709 2 2 RenderView at (0,0) size 800x600 3 3 layer at (0,0) size 800x600 4 RenderSVGRoot {svg} at (1 8,12) size 259x3064 RenderSVGRoot {svg} at (12,0) size 287x488 5 5 RenderSVGHiddenContainer {defs} at (0,0) size 0x0 6 6 RenderSVGResourceLinearGradient {linearGradient} [id="grad1"] [gradientUnits=objectBoundingBox] [start=(0,0)] [end=(1,1)] … … 16 16 RenderSVGRect {rect} at (10,10) size 10x10 [fill={[type=SOLID] [color=#FFFF00]}] [x=10.00] [y=10.00] [width=10.00] [height=10.00] 17 17 RenderSVGRect {rect} at (0,0) size 400x50 [x=0.00] [y=0.00] [width=400.00] [height=50.00] 18 RenderSVGContainer {g} at (1 8,12) size 104x66 [transform={m=((1.00,0.00)(0.00,1.00)) t=(20.00,20.00)}]19 RenderSVGRect {rect} at (1 8,12) size 104x66 [transform={m=((0.25,0.00)(0.00,1.00)) t=(0.00,0.00)}] [stroke={[type=LINEAR-GRADIENT] [id="grad1"] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00]20 RenderSVGRect {rect} at (1 8,92) size 104x66 [transform={m=((0.25,0.00)(0.00,1.00)) t=(20.00,100.00)}] [stroke={[type=LINEAR-GRADIENT] [id="grad2"] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00]21 RenderSVGContainer {use} at (1 8,172) size 104x66 [transform={m=((0.25,0.00)(0.00,1.00)) t=(20.00,180.00)}]22 RenderSVGRect {rect} at (1 8,172) size 104x66 [stroke={[type=PATTERN] [id="pattern"] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00]23 RenderSVGContainer {use} at (1 8,252) size 104x66 [transform={m=((0.25,0.00)(0.00,1.00)) t=(20.00,260.00)}]24 RenderSVGRect {rect} at (1 8,252) size 104x66 [stroke={[type=SOLID] [color=#008000] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00]25 RenderSVGContainer {use} at (1 56,12) size 121x66 [transform={m=((0.25,0.00)(0.25,1.00)) t=(160.00,20.00)}]26 RenderSVGRect {rect} at (1 56,12) size 121x66 [stroke={[type=SOLID] [color=#008000] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00]27 RenderSVGContainer {use} at (15 8,89) size 104x217[transform={m=((0.25,0.36)(0.00,1.00)) t=(160.00,100.00)}]28 RenderSVGRect {rect} at (15 8,89) size 104x217[stroke={[type=SOLID] [color=#008000] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00]18 RenderSVGContainer {g} at (12,12) size 116x66 [transform={m=((1.00,0.00)(0.00,1.00)) t=(20.00,20.00)}] 19 RenderSVGRect {rect} at (12,12) size 116x66 [transform={m=((0.25,0.00)(0.00,1.00)) t=(0.00,0.00)}] [stroke={[type=LINEAR-GRADIENT] [id="grad1"] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00] 20 RenderSVGRect {rect} at (12,92) size 116x66 [transform={m=((0.25,0.00)(0.00,1.00)) t=(20.00,100.00)}] [stroke={[type=LINEAR-GRADIENT] [id="grad2"] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00] 21 RenderSVGContainer {use} at (12,172) size 116x66 [transform={m=((0.25,0.00)(0.00,1.00)) t=(20.00,180.00)}] 22 RenderSVGRect {rect} at (12,172) size 116x66 [stroke={[type=PATTERN] [id="pattern"] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00] 23 RenderSVGContainer {use} at (12,252) size 116x66 [transform={m=((0.25,0.00)(0.00,1.00)) t=(20.00,260.00)}] 24 RenderSVGRect {rect} at (12,252) size 116x66 [stroke={[type=SOLID] [color=#008000] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00] 25 RenderSVGContainer {use} at (134,12) size 165x66 [transform={m=((0.25,0.00)(0.25,1.00)) t=(160.00,20.00)}] 26 RenderSVGRect {rect} at (134,12) size 165x66 [stroke={[type=SOLID] [color=#008000] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00] 27 RenderSVGContainer {use} at (152,0) size 116x488 [transform={m=((0.25,0.36)(0.00,1.00)) t=(160.00,100.00)}] 28 RenderSVGRect {rect} at (152,0) size 116x488 [stroke={[type=SOLID] [color=#008000] [stroke width=15.00]}] [x=0.00] [y=0.00] [width=400.00] [height=50.00] -
trunk/Source/WebCore/ChangeLog
r117697 r117709 1 2012-05-20 Philip Rogers <pdr@google.com> 2 3 Fix hit testing on non-scaling strokes 4 https://bugs.webkit.org/show_bug.cgi?id=82628 5 6 Reviewed by Nikolas Zimmermann. 7 8 This change fixes hit testing on non-scaling strokes. It contains fixes for 3 bugs: 9 1) RenderSVGRect::shapeDependentStrokeContains was not falling back to shape-based hit testing. 10 2) m_strokeAndMarkerBoundingBox did not account for non-scaling strokes. 11 3) RenderSVGShape::shapeDependentStrokeContains did not have any support for non-scaling strokes. 12 13 This change also contains some refactoring/cleanup of the non-scale-stroke codepaths. 14 15 Test: svg/hittest/svg-shapes-non-scale-stroke.html 16 17 * rendering/svg/RenderSVGEllipse.cpp: 18 (WebCore::RenderSVGEllipse::createShape): 19 * rendering/svg/RenderSVGRect.cpp: 20 (WebCore::RenderSVGRect::createShape): 21 (WebCore::RenderSVGRect::shapeDependentStrokeContains): 22 * rendering/svg/RenderSVGShape.cpp: 23 (WebCore::RenderSVGShape::shapeDependentStrokeContains): 24 (WebCore::RenderSVGShape::shapeDependentFillContains): 25 (WebCore::RenderSVGShape::nonScalingStrokePath): 26 (WebCore): 27 (WebCore::RenderSVGShape::setupNonScalingStrokeContext): 28 (WebCore::RenderSVGShape::nonScalingStrokeTransform): 29 (WebCore::RenderSVGShape::strokePath): 30 (WebCore::RenderSVGShape::fillAndStrokePath): 31 (WebCore::RenderSVGShape::updateCachedBoundaries): 32 (WebCore::RenderSVGShape::inflateWithStrokeAndMarkerBounds): 33 * rendering/svg/RenderSVGShape.h: 34 (WebCore::RenderSVGShape::hasNonScalingStroke): 35 (RenderSVGShape): 36 1 37 2012-05-19 Emil A Eklund <eae@chromium.org> 2 38 -
trunk/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp
r115201 r117709 56 56 57 57 // Fallback to RenderSVGShape if shape has a non scaling stroke. 58 if ( style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE) {58 if (hasNonScalingStroke()) { 59 59 RenderSVGShape::createShape(); 60 60 setIsPaintingFallback(true); -
trunk/Source/WebCore/rendering/svg/RenderSVGRect.cpp
r115201 r117709 56 56 ASSERT(rect); 57 57 58 bool nonScalingStroke = style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE;59 58 // Fallback to RenderSVGShape if rect has rounded corners. 60 if (rect->hasAttribute(SVGNames::rxAttr) || rect->hasAttribute(SVGNames::ryAttr) || nonScalingStroke) {59 if (rect->hasAttribute(SVGNames::rxAttr) || rect->hasAttribute(SVGNames::ryAttr) || hasNonScalingStroke()) { 61 60 RenderSVGShape::createShape(); 62 61 setIsPaintingFallback(true); … … 139 138 bool RenderSVGRect::shapeDependentStrokeContains(const FloatPoint& point) const 140 139 { 140 if (isPaintingFallback()) 141 return RenderSVGShape::shapeDependentStrokeContains(point); 142 141 143 return m_outerStrokeRect.contains(point, FloatRect::InsideOrOnStroke) && !m_innerStrokeRect.contains(point, FloatRect::InsideButNotOnStroke); 142 144 } -
trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp
r115201 r117709 101 101 bool RenderSVGShape::shapeDependentStrokeContains(const FloatPoint& point) const 102 102 { 103 ASSERT(m_path); 103 104 BoundingRectStrokeStyleApplier applier(this, style()); 105 106 if (hasNonScalingStroke()) { 107 AffineTransform nonScalingTransform = nonScalingStrokeTransform(); 108 Path* usePath = nonScalingStrokePath(m_path.get(), nonScalingTransform); 109 110 return usePath->strokeContains(&applier, nonScalingTransform.mapPoint(point)); 111 } 112 104 113 return m_path->strokeContains(&applier, point); 105 114 } … … 107 116 bool RenderSVGShape::shapeDependentFillContains(const FloatPoint& point, const WindRule fillRule) const 108 117 { 118 ASSERT(m_path); 109 119 return m_path->contains(point, fillRule); 110 120 } … … 198 208 } 199 209 210 Path* RenderSVGShape::nonScalingStrokePath(const Path* path, const AffineTransform& strokeTransform) const 211 { 212 DEFINE_STATIC_LOCAL(Path, tempPath, ()); 213 214 tempPath = *path; 215 tempPath.transform(strokeTransform); 216 217 return &tempPath; 218 } 219 220 bool RenderSVGShape::setupNonScalingStrokeContext(AffineTransform& strokeTransform, GraphicsContextStateSaver& stateSaver) 221 { 222 if (!strokeTransform.isInvertible()) 223 return false; 224 225 stateSaver.save(); 226 stateSaver.context()->concatCTM(strokeTransform.inverse()); 227 return true; 228 } 229 230 AffineTransform RenderSVGShape::nonScalingStrokeTransform() const 231 { 232 SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); 233 return element->getScreenCTM(SVGLocatable::DisallowStyleUpdate); 234 } 235 200 236 bool RenderSVGShape::shouldStrokeZeroLengthSubpath() const 201 237 { … … 224 260 225 261 return &tempPath; 226 }227 228 Path* RenderSVGShape::nonScalingStrokePath(const Path* path, const AffineTransform& strokeTransform)229 {230 DEFINE_STATIC_LOCAL(Path, tempPath, ());231 232 tempPath = *path;233 tempPath.transform(strokeTransform);234 235 return &tempPath;236 }237 238 bool RenderSVGShape::setupNonScalingStrokeTransform(AffineTransform& strokeTransform, GraphicsContextStateSaver& stateSaver)239 {240 SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());241 strokeTransform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate);242 if (!strokeTransform.isInvertible())243 return false;244 245 stateSaver.save();246 stateSaver.context()->concatCTM(strokeTransform.inverse());247 return true;248 262 } 249 263 … … 264 278 265 279 void RenderSVGShape::strokePath(RenderStyle* style, GraphicsContext* context, Path* path, RenderSVGResource* strokePaintingResource, 266 const Color& fallbackColor, bool nonScalingStroke, const AffineTransform& nonScalingStrokeTransform, 267 int applyMode) 280 const Color& fallbackColor, int applyMode) 268 281 { 269 282 if (!style->svgStyle()->hasVisibleStroke()) 270 283 return; 271 Path* usePath = path; 272 if (nonScalingStroke) { 273 usePath = nonScalingStrokePath(path, nonScalingStrokeTransform); 274 } 284 275 285 if (strokePaintingResource->applyResource(this, style, context, applyMode)) { 276 strokePaintingResource->postApplyResource(this, context, applyMode, usePath, this); 277 return; 278 } 286 strokePaintingResource->postApplyResource(this, context, applyMode, path, this); 287 return; 288 } 289 279 290 if (!fallbackColor.isValid()) 280 291 return; 292 281 293 RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource(); 282 294 fallbackResource->setColor(fallbackColor); 283 295 if (fallbackResource->applyResource(this, style, context, applyMode)) 284 fallbackResource->postApplyResource(this, context, applyMode, usePath, this);296 fallbackResource->postApplyResource(this, context, applyMode, path, this); 285 297 } 286 298 … … 296 308 return; 297 309 310 Path* usePath = m_path.get(); 298 311 GraphicsContextStateSaver stateSaver(*context, false); 299 AffineTransform nonScalingStrokeTransform; 300 bool nonScalingStroke = style->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE; 301 if (nonScalingStroke) { 302 if (!setupNonScalingStrokeTransform(nonScalingStrokeTransform, stateSaver)) 312 AffineTransform nonScalingTransform; 313 314 if (hasNonScalingStroke()) { 315 nonScalingTransform = nonScalingStrokeTransform(); 316 if (!setupNonScalingStrokeContext(nonScalingTransform, stateSaver)) 303 317 return; 304 } 305 306 strokePath(style, context, m_path.get(), strokePaintingResource, fallbackColor, nonScalingStroke, nonScalingStrokeTransform, ApplyToStrokeMode); 318 usePath = nonScalingStrokePath(usePath, nonScalingTransform); 319 } 320 321 strokePath(style, context, usePath, strokePaintingResource, fallbackColor, ApplyToStrokeMode); 307 322 308 323 // Spec(11.4): Any zero length subpath shall not be stroked if the "stroke-linecap" property has a value of butt … … 310 325 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) { 311 326 Path* usePath = zeroLengthLinecapPath(m_zeroLengthLinecapLocations[i]); 312 strokePath(style, context, usePath, strokePaintingResource, fallbackColor, nonScalingStroke, nonScalingStrokeTransform, ApplyToFillMode); 313 } 314 327 if (hasNonScalingStroke()) 328 usePath = nonScalingStrokePath(usePath, nonScalingTransform); 329 strokePath(style, context, usePath, strokePaintingResource, fallbackColor, ApplyToFillMode); 330 } 315 331 } 316 332 … … 424 440 425 441 // Add zero-length sub-path linecaps to the fill box 442 // FIXME: zero-length subpaths do not respect vector-effect = non-scaling-stroke. 426 443 float strokeWidth = this->strokeWidth(); 427 444 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) … … 450 467 if (svgStyle->hasStroke()) { 451 468 BoundingRectStrokeStyleApplier strokeStyle(this, style()); 452 m_strokeAndMarkerBoundingBox.unite(path().strokeBoundingRect(&strokeStyle)); 469 470 // SVG1.2 Tiny only defines non scaling stroke for the stroke but not markers. 471 if (hasNonScalingStroke()) { 472 AffineTransform nonScalingTransform = nonScalingStrokeTransform(); 473 if (nonScalingTransform.isInvertible()) { 474 Path* usePath = nonScalingStrokePath(m_path.get(), nonScalingTransform); 475 FloatRect strokeBoundingRect = usePath->strokeBoundingRect(&strokeStyle); 476 strokeBoundingRect = nonScalingTransform.inverse().mapRect(strokeBoundingRect); 477 m_strokeAndMarkerBoundingBox.unite(strokeBoundingRect); 478 } 479 } else 480 m_strokeAndMarkerBoundingBox.unite(path().strokeBoundingRect(&strokeStyle)); 453 481 } 454 482 if (svgStyle->hasMarkers()) { -
trunk/Source/WebCore/rendering/svg/RenderSVGShape.h
r116557 r117709 98 98 99 99 bool hasPath() const { return m_path.get(); } 100 bool hasNonScalingStroke() const { return style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE; } 100 101 101 102 private: … … 119 120 void updateCachedBoundaries(); 120 121 122 AffineTransform nonScalingStrokeTransform() const; 123 bool setupNonScalingStrokeContext(AffineTransform&, GraphicsContextStateSaver&); 124 Path* nonScalingStrokePath(const Path*, const AffineTransform&) const; 125 121 126 Path* zeroLengthLinecapPath(const FloatPoint&); 122 bool setupNonScalingStrokeTransform(AffineTransform&, GraphicsContextStateSaver&);123 Path* nonScalingStrokePath(const Path*, const AffineTransform&);124 127 bool shouldStrokeZeroLengthSubpath() const; 125 128 FloatRect zeroLengthSubpathRect(const FloatPoint&, float) const; … … 127 130 void fillShape(RenderStyle*, GraphicsContext*, Path*, RenderSVGShape*); 128 131 void strokePath(RenderStyle*, GraphicsContext*, Path*, RenderSVGResource*, 129 const Color&, bool, const AffineTransform&,int);132 const Color&, int); 130 133 void fillAndStrokePath(GraphicsContext*); 131 134 void inflateWithStrokeAndMarkerBounds();
Note: See TracChangeset
for help on using the changeset viewer.