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

Side by Side Diff: Source/core/layout/svg/LayoutSVGShape.cpp

Issue 1158583003: Reduce how often LayoutSVGShape::updateShapeFromElement is called (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix marker regression Created 5 years, 6 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 | Annotate | Revision Log
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 * Copyright (C) 2011 Renata Hodovan <reni@webkit.org> 9 * Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
10 * Copyright (C) 2011 University of Szeged 10 * Copyright (C) 2011 University of Szeged
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 , m_needsBoundariesUpdate(false) // Default is false, the cached rects are e mpty from the beginning. 49 , m_needsBoundariesUpdate(false) // Default is false, the cached rects are e mpty from the beginning.
50 , m_needsShapeUpdate(true) // Default is true, so we grab a Path object once from SVGGeometryElement. 50 , m_needsShapeUpdate(true) // Default is true, so we grab a Path object once from SVGGeometryElement.
51 , m_needsTransformUpdate(true) // Default is true, so we grab a AffineTransf orm object once from SVGGeometryElement. 51 , m_needsTransformUpdate(true) // Default is true, so we grab a AffineTransf orm object once from SVGGeometryElement.
52 { 52 {
53 } 53 }
54 54
55 LayoutSVGShape::~LayoutSVGShape() 55 LayoutSVGShape::~LayoutSVGShape()
56 { 56 {
57 } 57 }
58 58
59 void LayoutSVGShape::createPath() 59 void LayoutSVGShape::styleDidChange(StyleDifference diff, const ComputedStyle* o ldStyle)
60 {
61 if (diff.needsFullLayout()) {
62 if (oldStyle && (oldStyle->svgStyle().vectorEffect() != style()->svgStyl e().vectorEffect()))
63 setNeedsShapeUpdate();
64 }
65
66 // LayoutSVGModelObject will take care of calling clientStyleChanged.
67 LayoutSVGModelObject::styleDidChange(diff, oldStyle);
68 }
69
70 void LayoutSVGShape::updateShapeFromElement()
60 { 71 {
61 if (!m_path) 72 if (!m_path)
62 m_path = adoptPtr(new Path()); 73 m_path = adoptPtr(new Path());
63 *m_path = toSVGGeometryElement(element())->asPath(); 74 *m_path = toSVGGeometryElement(element())->asPath();
64 } 75 }
65 76
66 void LayoutSVGShape::updateShapeFromElement() 77 void LayoutSVGShape::updateStrokeAndFillBoundingBoxes()
67 { 78 {
68 createPath(); 79 m_fillBoundingBox = path().boundingRect();
69 80
70 m_fillBoundingBox = calculateObjectBoundingBox(); 81 m_strokeBoundingBox = m_fillBoundingBox;
71 m_strokeBoundingBox = calculateStrokeBoundingBox(); 82 if (style()->svgStyle().hasStroke()) {
83 StrokeData strokeData;
84 SVGLayoutSupport::applyStrokeStyleToStrokeData(strokeData, styleRef(), * this);
85 if (hasNonScalingStroke()) {
86 AffineTransform nonScalingTransform = nonScalingStrokeTransform();
87 if (nonScalingTransform.isInvertible()) {
88 Path* usePath = nonScalingStrokePath(m_path.get(), nonScalingTra nsform);
89 FloatRect strokeBoundingRect = usePath->strokeBoundingRect(strok eData);
90 strokeBoundingRect = nonScalingTransform.inverse().mapRect(strok eBoundingRect);
91 m_strokeBoundingBox.unite(strokeBoundingRect);
92 }
93 } else {
94 m_strokeBoundingBox.unite(path().strokeBoundingRect(strokeData));
95 }
96 }
72 } 97 }
73 98
74 FloatRect LayoutSVGShape::hitTestStrokeBoundingBox() const 99 FloatRect LayoutSVGShape::hitTestStrokeBoundingBox() const
75 { 100 {
76 if (style()->svgStyle().hasStroke()) 101 if (style()->svgStyle().hasStroke())
77 return m_strokeBoundingBox; 102 return m_strokeBoundingBox;
78 103
79 // Implementation of http://dev.w3.org/fxtf/css-masking-1/#compute-stroke-bo unding-box 104 // Implementation of http://dev.w3.org/fxtf/css-masking-1/#compute-stroke-bo unding-box
80 // for the <rect> / <ellipse> / <circle> case except that we ignore whether 105 // for the <rect> / <ellipse> / <circle> case except that we ignore whether
81 // the stroke is none. 106 // the stroke is none.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } else { 170 } else {
146 m_localTransform = 0; 171 m_localTransform = 0;
147 } 172 }
148 } 173 }
149 174
150 void LayoutSVGShape::layout() 175 void LayoutSVGShape::layout()
151 { 176 {
152 bool updateCachedBoundariesInParents = false; 177 bool updateCachedBoundariesInParents = false;
153 LayoutAnalyzer::Scope analyzer(*this); 178 LayoutAnalyzer::Scope analyzer(*this);
154 179
155 if (m_needsShapeUpdate || m_needsBoundariesUpdate) { 180 if (m_needsBoundariesUpdate && toSVGGeometryElement(element())->selfHasRelat iveLengths())
fs 2015/06/16 10:54:02 I think this needs to consider the "new" geometric
pdr. 2015/06/17 03:50:49 I think we can just check for the exact property c
181 m_needsShapeUpdate = true;
182
183 if (m_needsShapeUpdate)
156 updateShapeFromElement(); 184 updateShapeFromElement();
157 m_needsShapeUpdate = false; 185
186 if (m_needsBoundariesUpdate || m_needsShapeUpdate) {
187 updateStrokeAndFillBoundingBoxes();
158 updatePaintInvalidationBoundingBox(); 188 updatePaintInvalidationBoundingBox();
159 m_needsBoundariesUpdate = false; 189 m_needsBoundariesUpdate = false;
190 m_needsShapeUpdate = false;
160 updateCachedBoundariesInParents = true; 191 updateCachedBoundariesInParents = true;
161 } 192 }
162 193
163 if (m_needsTransformUpdate) { 194 if (m_needsTransformUpdate) {
164 updateLocalTransform(); 195 updateLocalTransform();
165 m_needsTransformUpdate = false; 196 m_needsTransformUpdate = false;
166 updateCachedBoundariesInParents = true; 197 updateCachedBoundariesInParents = true;
167 } 198 }
168 199
169 // Invalidate all resources of this client if our layout changed. 200 // Invalidate all resources of this client if our layout changed.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 if (request.svgClipContent()) 265 if (request.svgClipContent())
235 fillRule = svgStyle.clipRule(); 266 fillRule = svgStyle.clipRule();
236 if ((hitRules.canHitBoundingBox && objectBoundingBox().contains(localPoi nt)) 267 if ((hitRules.canHitBoundingBox && objectBoundingBox().contains(localPoi nt))
237 || (hitRules.canHitStroke && (svgStyle.hasStroke() || !hitRules.requ ireStroke) && strokeContains(localPoint, hitRules.requireStroke)) 268 || (hitRules.canHitStroke && (svgStyle.hasStroke() || !hitRules.requ ireStroke) && strokeContains(localPoint, hitRules.requireStroke))
238 || (hitRules.canHitFill && (svgStyle.hasFill() || !hitRules.requireF ill) && fillContains(localPoint, hitRules.requireFill, fillRule))) 269 || (hitRules.canHitFill && (svgStyle.hasFill() || !hitRules.requireF ill) && fillContains(localPoint, hitRules.requireFill, fillRule)))
239 return true; 270 return true;
240 } 271 }
241 return false; 272 return false;
242 } 273 }
243 274
244 FloatRect LayoutSVGShape::calculateObjectBoundingBox() const
245 {
246 return path().boundingRect();
247 }
248
249 FloatRect LayoutSVGShape::calculateStrokeBoundingBox() const
250 {
251 ASSERT(m_path);
252 FloatRect strokeBoundingBox = m_fillBoundingBox;
253
254 if (style()->svgStyle().hasStroke()) {
255 StrokeData strokeData;
256 SVGLayoutSupport::applyStrokeStyleToStrokeData(strokeData, styleRef(), * this);
257 if (hasNonScalingStroke()) {
258 AffineTransform nonScalingTransform = nonScalingStrokeTransform();
259 if (nonScalingTransform.isInvertible()) {
260 Path* usePath = nonScalingStrokePath(m_path.get(), nonScalingTra nsform);
261 FloatRect strokeBoundingRect = usePath->strokeBoundingRect(strok eData);
262 strokeBoundingRect = nonScalingTransform.inverse().mapRect(strok eBoundingRect);
263 strokeBoundingBox.unite(strokeBoundingRect);
264 }
265 } else {
266 strokeBoundingBox.unite(path().strokeBoundingRect(strokeData));
267 }
268 }
269
270 return strokeBoundingBox;
271 }
272
273 void LayoutSVGShape::updatePaintInvalidationBoundingBox() 275 void LayoutSVGShape::updatePaintInvalidationBoundingBox()
274 { 276 {
275 m_paintInvalidationBoundingBox = strokeBoundingBox(); 277 m_paintInvalidationBoundingBox = strokeBoundingBox();
276 if (strokeWidth() < 1.0f && !m_paintInvalidationBoundingBox.isEmpty()) 278 if (strokeWidth() < 1.0f && !m_paintInvalidationBoundingBox.isEmpty())
277 m_paintInvalidationBoundingBox.inflate(1); 279 m_paintInvalidationBoundingBox.inflate(1);
278 SVGLayoutSupport::intersectPaintInvalidationRectWithResources(this, m_paintI nvalidationBoundingBox); 280 SVGLayoutSupport::intersectPaintInvalidationRectWithResources(this, m_paintI nvalidationBoundingBox);
279 } 281 }
280 282
281 float LayoutSVGShape::strokeWidth() const 283 float LayoutSVGShape::strokeWidth() const
282 { 284 {
283 SVGLengthContext lengthContext(element()); 285 SVGLengthContext lengthContext(element());
284 return lengthContext.valueForLength(style()->svgStyle().strokeWidth()); 286 return lengthContext.valueForLength(style()->svgStyle().strokeWidth());
285 } 287 }
286 288
287 } 289 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698