OLD | NEW |
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 14 matching lines...) Expand all Loading... |
25 * Boston, MA 02110-1301, USA. | 25 * Boston, MA 02110-1301, USA. |
26 */ | 26 */ |
27 | 27 |
28 #include "config.h" | 28 #include "config.h" |
29 | 29 |
30 #include "core/layout/svg/LayoutSVGPath.h" | 30 #include "core/layout/svg/LayoutSVGPath.h" |
31 | 31 |
32 #include "core/layout/svg/LayoutSVGResourceMarker.h" | 32 #include "core/layout/svg/LayoutSVGResourceMarker.h" |
33 #include "core/layout/svg/SVGResources.h" | 33 #include "core/layout/svg/SVGResources.h" |
34 #include "core/layout/svg/SVGResourcesCache.h" | 34 #include "core/layout/svg/SVGResourcesCache.h" |
35 #include "core/layout/svg/SVGSubpathData.h" | |
36 #include "core/svg/SVGGeometryElement.h" | 35 #include "core/svg/SVGGeometryElement.h" |
37 #include "wtf/MathExtras.h" | 36 #include "wtf/MathExtras.h" |
38 | 37 |
39 namespace blink { | 38 namespace blink { |
40 | 39 |
41 LayoutSVGPath::LayoutSVGPath(SVGGeometryElement* node) | 40 LayoutSVGPath::LayoutSVGPath(SVGGeometryElement* node) |
42 : LayoutSVGShape(node) | 41 : LayoutSVGShape(node) |
43 { | 42 { |
44 } | 43 } |
45 | 44 |
46 LayoutSVGPath::~LayoutSVGPath() | 45 LayoutSVGPath::~LayoutSVGPath() |
47 { | 46 { |
48 } | 47 } |
49 | 48 |
50 void LayoutSVGPath::updateShapeFromElement() | |
51 { | |
52 LayoutSVGShape::updateShapeFromElement(); | |
53 updateZeroLengthSubpaths(); | |
54 } | |
55 | |
56 void LayoutSVGPath::updateStrokeAndFillBoundingBoxes() | 49 void LayoutSVGPath::updateStrokeAndFillBoundingBoxes() |
57 { | 50 { |
58 LayoutSVGShape::updateStrokeAndFillBoundingBoxes(); | 51 LayoutSVGShape::updateStrokeAndFillBoundingBoxes(); |
59 | 52 |
60 // TODO(pdr): We should only call this in updateShapeFromElement. | 53 // TODO(pdr): We should only call this in updateShapeFromElement. |
61 processMarkerPositions(); | 54 processMarkerPositions(); |
62 if (!m_markerPositions.isEmpty()) | 55 if (!m_markerPositions.isEmpty()) |
63 m_strokeBoundingBox.unite(markerRect(strokeWidth())); | 56 m_strokeBoundingBox.unite(markerRect(strokeWidth())); |
64 | |
65 if (style()->svgStyle().hasStroke()) { | |
66 // FIXME: zero-length subpaths do not respect vector-effect = non-scalin
g-stroke. | |
67 float strokeWidth = this->strokeWidth(); | |
68 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) | |
69 m_strokeBoundingBox.unite(zeroLengthSubpathRect(m_zeroLengthLinecapL
ocations[i], strokeWidth)); | |
70 } | |
71 } | 57 } |
72 | 58 |
73 FloatRect LayoutSVGPath::hitTestStrokeBoundingBox() const | 59 FloatRect LayoutSVGPath::hitTestStrokeBoundingBox() const |
74 { | 60 { |
75 const SVGComputedStyle& svgStyle = style()->svgStyle(); | 61 const SVGComputedStyle& svgStyle = style()->svgStyle(); |
76 if (svgStyle.hasStroke()) | 62 if (svgStyle.hasStroke()) |
77 return m_strokeBoundingBox; | 63 return m_strokeBoundingBox; |
78 | 64 |
79 // Implementation of http://dev.w3.org/fxtf/css-masking-1/#compute-stroke-bo
unding-box | 65 // Implementation of http://dev.w3.org/fxtf/css-masking-1/#compute-stroke-bo
unding-box |
80 // except that we ignore whether the stroke is none. | 66 // except that we ignore whether the stroke is none. |
(...skipping 10 matching lines...) Expand all Loading... |
91 const float miter = svgStyle.strokeMiterLimit(); | 77 const float miter = svgStyle.strokeMiterLimit(); |
92 if (miter < M_SQRT2 && svgStyle.hasSquareCapStyle()) | 78 if (miter < M_SQRT2 && svgStyle.hasSquareCapStyle()) |
93 delta *= M_SQRT2; | 79 delta *= M_SQRT2; |
94 else | 80 else |
95 delta *= miter; | 81 delta *= miter; |
96 } else if (svgStyle.hasSquareCapStyle()) { | 82 } else if (svgStyle.hasSquareCapStyle()) { |
97 delta *= M_SQRT2; | 83 delta *= M_SQRT2; |
98 } | 84 } |
99 | 85 |
100 box.inflate(delta); | 86 box.inflate(delta); |
101 | |
102 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) | |
103 box.unite(zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeW
idth)); | |
104 | |
105 return box; | 87 return box; |
106 } | 88 } |
107 | 89 |
108 bool LayoutSVGPath::shapeDependentStrokeContains(const FloatPoint& point) | |
109 { | |
110 if (LayoutSVGShape::shapeDependentStrokeContains(point)) | |
111 return true; | |
112 | |
113 const SVGComputedStyle& svgStyle = style()->svgStyle(); | |
114 const float strokeWidth = this->strokeWidth(); | |
115 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) { | |
116 ASSERT(svgStyle.hasStroke()); | |
117 if (svgStyle.capStyle() == SquareCap) { | |
118 if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWid
th).contains(point)) | |
119 return true; | |
120 } else { | |
121 ASSERT(svgStyle.capStyle() == RoundCap); | |
122 FloatPoint radiusVector(point.x() - m_zeroLengthLinecapLocations[i].
x(), point.y() - m_zeroLengthLinecapLocations[i].y()); | |
123 if (radiusVector.lengthSquared() < strokeWidth * strokeWidth * .25f) | |
124 return true; | |
125 } | |
126 } | |
127 return false; | |
128 } | |
129 | |
130 bool LayoutSVGPath::shouldStrokeZeroLengthSubpath() const | |
131 { | |
132 // Spec(11.4): Any zero length subpath shall not be stroked if the "stroke-l
inecap" property has a value of butt | |
133 // but shall be stroked if the "stroke-linecap" property has a value of roun
d or square | |
134 return style()->svgStyle().hasStroke() && style()->svgStyle().capStyle() !=
ButtCap; | |
135 } | |
136 | |
137 FloatRect LayoutSVGPath::zeroLengthSubpathRect(const FloatPoint& linecapPosition
, float strokeWidth) | |
138 { | |
139 return FloatRect(linecapPosition.x() - strokeWidth / 2, linecapPosition.y()
- strokeWidth / 2, strokeWidth, strokeWidth); | |
140 } | |
141 | |
142 void LayoutSVGPath::updateZeroLengthSubpaths() | |
143 { | |
144 m_zeroLengthLinecapLocations.clear(); | |
145 | |
146 if (!strokeWidth() || !shouldStrokeZeroLengthSubpath()) | |
147 return; | |
148 | |
149 SVGSubpathData subpathData(m_zeroLengthLinecapLocations); | |
150 path().apply(&subpathData, SVGSubpathData::updateFromPathElement); | |
151 subpathData.pathIsDone(); | |
152 } | |
153 | |
154 FloatRect LayoutSVGPath::markerRect(float strokeWidth) const | 90 FloatRect LayoutSVGPath::markerRect(float strokeWidth) const |
155 { | 91 { |
156 ASSERT(!m_markerPositions.isEmpty()); | 92 ASSERT(!m_markerPositions.isEmpty()); |
157 | 93 |
158 SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(
this); | 94 SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(
this); |
159 ASSERT(resources); | 95 ASSERT(resources); |
160 | 96 |
161 LayoutSVGResourceMarker* markerStart = resources->markerStart(); | 97 LayoutSVGResourceMarker* markerStart = resources->markerStart(); |
162 LayoutSVGResourceMarker* markerMid = resources->markerMid(); | 98 LayoutSVGResourceMarker* markerMid = resources->markerMid(); |
163 LayoutSVGResourceMarker* markerEnd = resources->markerEnd(); | 99 LayoutSVGResourceMarker* markerEnd = resources->markerEnd(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 ASSERT(resources); | 134 ASSERT(resources); |
199 | 135 |
200 LayoutSVGResourceMarker* markerStart = resources->markerStart(); | 136 LayoutSVGResourceMarker* markerStart = resources->markerStart(); |
201 | 137 |
202 SVGMarkerData markerData(m_markerPositions, markerStart ? markerStart->orien
tType() == SVGMarkerOrientAutoStartReverse : false); | 138 SVGMarkerData markerData(m_markerPositions, markerStart ? markerStart->orien
tType() == SVGMarkerOrientAutoStartReverse : false); |
203 path().apply(&markerData, SVGMarkerData::updateFromPathElement); | 139 path().apply(&markerData, SVGMarkerData::updateFromPathElement); |
204 markerData.pathIsDone(); | 140 markerData.pathIsDone(); |
205 } | 141 } |
206 | 142 |
207 } | 143 } |
OLD | NEW |