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

Side by Side Diff: Source/WebCore/rendering/svg/RenderSVGPath.cpp

Issue 8222009: Revert 91125 - 2011-07-15 Rob Buis <rbuis@rim.com> (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/874/
Patch Set: Created 9 years, 2 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 unified diff | Download patch
« no previous file with comments | « Source/WebCore/rendering/svg/RenderSVGPath.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2008 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005, 2008 Rob Buis <buis@kde.org>
4 * Copyright (C) 2005, 2007 Eric Seidel <eric@webkit.org> 4 * Copyright (C) 2005, 2007 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2009 Google, Inc. 5 * Copyright (C) 2009 Google, Inc.
6 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 7 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
8 * Copyright (C) 2009 Jeff Schiller <codedread@gmail.com> 8 * Copyright (C) 2009 Jeff Schiller <codedread@gmail.com>
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 93
94 bool RenderSVGPath::strokeContains(const FloatPoint& point, bool requiresStroke) 94 bool RenderSVGPath::strokeContains(const FloatPoint& point, bool requiresStroke)
95 { 95 {
96 if (!m_strokeAndMarkerBoundingBox.contains(point)) 96 if (!m_strokeAndMarkerBoundingBox.contains(point))
97 return false; 97 return false;
98 98
99 Color fallbackColor; 99 Color fallbackColor;
100 if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style (), fallbackColor)) 100 if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style (), fallbackColor))
101 return false; 101 return false;
102 102
103 if (shouldStrokeZeroLengthSubpath())
104 return zeroLengthSubpathRect().contains(point);
105
106 BoundingRectStrokeStyleApplier strokeStyle(this, style()); 103 BoundingRectStrokeStyleApplier strokeStyle(this, style());
107 return m_path.strokeContains(&strokeStyle, point); 104 return m_path.strokeContains(&strokeStyle, point);
108 } 105 }
109 106
110 void RenderSVGPath::layout() 107 void RenderSVGPath::layout()
111 { 108 {
112 LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsL ayout()); 109 LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsL ayout());
113 SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableE lement*>(node()); 110 SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableE lement*>(node());
114 111
115 bool updateCachedBoundariesInParents = false; 112 bool updateCachedBoundariesInParents = false;
(...skipping 29 matching lines...) Expand all
145 } 142 }
146 143
147 // If our bounds changed, notify the parents. 144 // If our bounds changed, notify the parents.
148 if (updateCachedBoundariesInParents) 145 if (updateCachedBoundariesInParents)
149 RenderSVGModelObject::setNeedsBoundariesUpdate(); 146 RenderSVGModelObject::setNeedsBoundariesUpdate();
150 147
151 repainter.repaintAfterLayout(); 148 repainter.repaintAfterLayout();
152 setNeedsLayout(false); 149 setNeedsLayout(false);
153 } 150 }
154 151
155 bool RenderSVGPath::shouldStrokeZeroLengthSubpath() const
156 {
157 // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-l inecap’ property has a value of butt
158 // but shall be stroked if the ‘stroke-linecap’ property has a value of roun d or square
159 return style()->svgStyle()->hasStroke() && style()->svgStyle()->capStyle() ! = ButtCap && !m_fillBoundingBox.width() && !m_fillBoundingBox.height();
160 }
161
162 FloatRect RenderSVGPath::zeroLengthSubpathRect() const
163 {
164 SVGElement* svgElement = static_cast<SVGElement*>(node());
165 float strokeWidth = style()->svgStyle()->strokeWidth().value(svgElement);
166 return FloatRect(m_fillBoundingBox.x() - strokeWidth / 2, m_fillBoundingBox. y() - strokeWidth / 2, strokeWidth, strokeWidth);
167 }
168
169 void RenderSVGPath::setupSquareCapPath(Path*& usePath, int& applyMode)
170 {
171 // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-l inecap’ property has a value of butt
172 // but shall be stroked if the ‘stroke-linecap’ property has a value of roun d or square
173 DEFINE_STATIC_LOCAL(Path, tempPath, ());
174
175 applyMode = ApplyToFillMode;
176 usePath = &tempPath;
177 usePath->clear();
178 if (style()->svgStyle()->capStyle() == SquareCap)
179 usePath->addRect(zeroLengthSubpathRect());
180 else
181 usePath->addEllipse(zeroLengthSubpathRect());
182 }
183
184 bool RenderSVGPath::setupNonScalingStrokePath(Path*& usePath, GraphicsContextSta teSaver& stateSaver)
185 {
186 DEFINE_STATIC_LOCAL(Path, tempPath, ());
187
188 SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableE lement*>(node());
189 AffineTransform nonScalingStrokeTransform = element->getScreenCTM(SVGLocatab le::DisallowStyleUpdate);
190 if (!nonScalingStrokeTransform.isInvertible())
191 return false;
192
193 tempPath = m_path;
194 usePath = &tempPath;
195 tempPath.transform(nonScalingStrokeTransform);
196
197 stateSaver.save();
198 stateSaver.context()->concatCTM(nonScalingStrokeTransform.inverse());
199 return true;
200 }
201
202 void RenderSVGPath::fillAndStrokePath(GraphicsContext* context) 152 void RenderSVGPath::fillAndStrokePath(GraphicsContext* context)
203 { 153 {
204 RenderStyle* style = this->style(); 154 RenderStyle* style = this->style();
205 155
206 Color fallbackColor; 156 Color fallbackColor;
207 if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintin gResource(this, style, fallbackColor)) { 157 if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintin gResource(this, style, fallbackColor)) {
208 if (fillPaintingResource->applyResource(this, style, context, ApplyToFil lMode)) 158 if (fillPaintingResource->applyResource(this, style, context, ApplyToFil lMode))
209 fillPaintingResource->postApplyResource(this, context, ApplyToFillMo de, &m_path); 159 fillPaintingResource->postApplyResource(this, context, ApplyToFillMo de, &m_path);
210 else if (fallbackColor.isValid()) { 160 else if (fallbackColor.isValid()) {
211 RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::s haredSolidPaintingResource(); 161 RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::s haredSolidPaintingResource();
212 fallbackResource->setColor(fallbackColor); 162 fallbackResource->setColor(fallbackColor);
213 if (fallbackResource->applyResource(this, style, context, ApplyToFil lMode)) 163 if (fallbackResource->applyResource(this, style, context, ApplyToFil lMode))
214 fallbackResource->postApplyResource(this, context, ApplyToFillMo de, &m_path); 164 fallbackResource->postApplyResource(this, context, ApplyToFillMo de, &m_path);
215 } 165 }
216 } 166 }
217 167
218 fallbackColor = Color(); 168 fallbackColor = Color();
219 RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintin gResource(this, style, fallbackColor); 169 RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintin gResource(this, style, fallbackColor);
220 if (!strokePaintingResource) 170 if (!strokePaintingResource)
221 return; 171 return;
222 172
223 Path* usePath = &m_path; 173 Path path;
224 int applyMode = ApplyToStrokeMode;
225 174
226 bool nonScalingStroke = style->svgStyle()->vectorEffect() == VE_NON_SCALING_ STROKE; 175 bool nonScalingStroke = style->svgStyle()->vectorEffect() == VE_NON_SCALING_ STROKE;
227 176
228 GraphicsContextStateSaver stateSaver(*context, false); 177 GraphicsContextStateSaver stateSaver(*context, false);
178 if (nonScalingStroke) {
179 SVGStyledTransformableElement* element = static_cast<SVGStyledTransforma bleElement*>(node());
180 AffineTransform nonScalingStrokeTransform = element->getScreenCTM(SVGLoc atable::DisallowStyleUpdate);
181 if (!nonScalingStrokeTransform.isInvertible())
182 return;
229 183
230 // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-l inecap’ property has a value of butt 184 path = m_path;
231 // but shall be stroked if the ‘stroke-linecap’ property has a value of roun d or square 185 path.transform(nonScalingStrokeTransform);
232 // FIXME: this does not work for zero-length subpaths, only when total path is zero-length 186
233 if (shouldStrokeZeroLengthSubpath()) 187 stateSaver.save();
234 setupSquareCapPath(usePath, applyMode); 188 context->concatCTM(nonScalingStrokeTransform.inverse());
235 else if (nonScalingStroke) {
236 if (!setupNonScalingStrokePath(usePath, stateSaver))
237 return;
238 } 189 }
239 190
240 if (strokePaintingResource->applyResource(this, style, context, applyMode)) 191 if (strokePaintingResource->applyResource(this, style, context, ApplyToStrok eMode))
241 strokePaintingResource->postApplyResource(this, context, applyMode, useP ath); 192 strokePaintingResource->postApplyResource(this, context, ApplyToStrokeMo de, nonScalingStroke ? &path : &m_path);
242 else if (fallbackColor.isValid()) { 193 else if (fallbackColor.isValid()) {
243 RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::share dSolidPaintingResource(); 194 RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::share dSolidPaintingResource();
244 fallbackResource->setColor(fallbackColor); 195 fallbackResource->setColor(fallbackColor);
245 if (fallbackResource->applyResource(this, style, context, applyMode)) 196 if (fallbackResource->applyResource(this, style, context, ApplyToStrokeM ode))
246 fallbackResource->postApplyResource(this, context, applyMode, usePat h); 197 fallbackResource->postApplyResource(this, context, ApplyToStrokeMode , nonScalingStroke ? &path : &m_path);
247 } 198 }
248 } 199 }
249 200
250 void RenderSVGPath::paint(PaintInfo& paintInfo, const LayoutPoint&) 201 void RenderSVGPath::paint(PaintInfo& paintInfo, const LayoutPoint&)
251 { 202 {
252 if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || m_path.isEmpty()) 203 if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || m_path.isEmpty())
253 return; 204 return;
254 205
255 FloatRect boundingBox = repaintRectInLocalCoordinates(); 206 FloatRect boundingBox = repaintRectInLocalCoordinates();
256 if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTr ansform, paintInfo)) 207 if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTr ansform, paintInfo))
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 if (m_path.isEmpty()) { 303 if (m_path.isEmpty()) {
353 m_fillBoundingBox = FloatRect(); 304 m_fillBoundingBox = FloatRect();
354 m_strokeAndMarkerBoundingBox = FloatRect(); 305 m_strokeAndMarkerBoundingBox = FloatRect();
355 m_repaintBoundingBox = FloatRect(); 306 m_repaintBoundingBox = FloatRect();
356 return; 307 return;
357 } 308 }
358 309
359 // Cache _unclipped_ fill bounding box, used for calculations in resources 310 // Cache _unclipped_ fill bounding box, used for calculations in resources
360 m_fillBoundingBox = m_path.boundingRect(); 311 m_fillBoundingBox = m_path.boundingRect();
361 312
362 // Spec(11.4): Any zero length subpath shall not be stroked if the ‘stroke-l inecap’ property has a value of butt
363 // but shall be stroked if the ‘stroke-linecap’ property has a value of roun d or square
364 if (shouldStrokeZeroLengthSubpath()) {
365 m_strokeAndMarkerBoundingBox = zeroLengthSubpathRect();
366 // Cache smallest possible repaint rectangle
367 m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
368 SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBound ingBox);
369 return;
370 }
371
372 // Cache _unclipped_ stroke bounding box, used for calculations in resources (includes marker boundaries) 313 // Cache _unclipped_ stroke bounding box, used for calculations in resources (includes marker boundaries)
373 m_strokeAndMarkerBoundingBox = m_fillBoundingBox; 314 m_strokeAndMarkerBoundingBox = m_fillBoundingBox;
374 315
375 const SVGRenderStyle* svgStyle = style()->svgStyle(); 316 const SVGRenderStyle* svgStyle = style()->svgStyle();
376 if (svgStyle->hasStroke()) { 317 if (svgStyle->hasStroke()) {
377 BoundingRectStrokeStyleApplier strokeStyle(this, style()); 318 BoundingRectStrokeStyleApplier strokeStyle(this, style());
378 m_strokeAndMarkerBoundingBox.unite(m_path.strokeBoundingRect(&strokeStyl e)); 319 m_strokeAndMarkerBoundingBox.unite(m_path.strokeBoundingRect(&strokeStyl e));
379 } 320 }
380 321
381 if (svgStyle->hasMarkers()) { 322 if (svgStyle->hasMarkers()) {
382 FloatRect markerBounds = calculateMarkerBoundsIfNeeded(); 323 FloatRect markerBounds = calculateMarkerBoundsIfNeeded();
383 if (!markerBounds.isEmpty()) 324 if (!markerBounds.isEmpty())
384 m_strokeAndMarkerBoundingBox.unite(markerBounds); 325 m_strokeAndMarkerBoundingBox.unite(markerBounds);
385 } 326 }
386 327
387 // Cache smallest possible repaint rectangle 328 // Cache smallest possible repaint rectangle
388 m_repaintBoundingBox = m_strokeAndMarkerBoundingBox; 329 m_repaintBoundingBox = m_strokeAndMarkerBoundingBox;
389 SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingB ox); 330 SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingB ox);
390 } 331 }
391 332
392 } 333 }
393 334
394 #endif // ENABLE(SVG) 335 #endif // ENABLE(SVG)
OLDNEW
« no previous file with comments | « Source/WebCore/rendering/svg/RenderSVGPath.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698