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 17 matching lines...) Expand all Loading... | |
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" | 35 #include "core/layout/svg/SVGSubpathData.h" |
36 #include "core/svg/SVGGraphicsElement.h" | 36 #include "core/svg/SVGGraphicsElement.h" |
37 | 37 |
38 #include <cmath> | |
fs
2015/03/31 14:53:59
(I think it's pretty common to just pull in wtf/Ma
| |
39 | |
38 namespace blink { | 40 namespace blink { |
39 | 41 |
40 LayoutSVGPath::LayoutSVGPath(SVGGraphicsElement* node) | 42 LayoutSVGPath::LayoutSVGPath(SVGGraphicsElement* node) |
41 : LayoutSVGShape(node) | 43 : LayoutSVGShape(node) |
42 { | 44 { |
43 } | 45 } |
44 | 46 |
45 LayoutSVGPath::~LayoutSVGPath() | 47 LayoutSVGPath::~LayoutSVGPath() |
46 { | 48 { |
47 } | 49 } |
48 | 50 |
49 void LayoutSVGPath::updateShapeFromElement() | 51 void LayoutSVGPath::updateShapeFromElement() |
50 { | 52 { |
51 LayoutSVGShape::updateShapeFromElement(); | 53 LayoutSVGShape::updateShapeFromElement(); |
52 processMarkerPositions(); | 54 processMarkerPositions(); |
53 updateZeroLengthSubpaths(); | 55 updateZeroLengthSubpaths(); |
54 | 56 |
55 m_strokeBoundingBox = calculateUpdatedStrokeBoundingBox(); | 57 m_strokeBoundingBox = calculateUpdatedStrokeBoundingBox(); |
56 } | 58 } |
57 | 59 |
60 FloatRect LayoutSVGPath::hitTestStrokeBoundingBox() const | |
61 { | |
62 const SVGLayoutStyle& svgStyle = style()->svgStyle(); | |
63 if (svgStyle.hasStroke()) | |
64 return m_strokeBoundingBox; | |
65 | |
66 FloatRect result = m_fillBoundingBox; | |
67 const float strokeWidth = this->strokeWidth(); | |
68 | |
69 if (svgStyle.joinStyle() == MiterJoin) { | |
fs
2015/03/31 14:54:00
Could you pull this out into a helper?
http://dev
| |
70 // We need to consider the miterlimit, because the would-be stroke | |
71 // bounding box could extend outward quite far at a sharp angle along | |
72 // the path. | |
73 // | |
74 // Per http://www.w3.org/TR/SVG/painting.html#StrokeMiterlimitProperty | |
75 // the maximum miterLength is: | |
76 // stroke-width * miterlimit | |
77 // Inflate the result by the maximum of that amount and half the | |
78 // stroke-width. | |
79 // | |
80 // Note that because the miterLength is the distance between the outer | |
81 // tip and the inner corner of the miter, this technically overshoots | |
82 // a bit. | |
83 result.inflate(std::max(strokeWidth * svgStyle.strokeMiterLimit(), strok eWidth / 2)); | |
84 } else { | |
85 result.inflate(strokeWidth / 2); | |
86 } | |
87 | |
88 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) | |
89 result.unite(zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], stro keWidth)); | |
90 | |
91 return result; | |
92 } | |
93 | |
58 FloatRect LayoutSVGPath::calculateUpdatedStrokeBoundingBox() const | 94 FloatRect LayoutSVGPath::calculateUpdatedStrokeBoundingBox() const |
59 { | 95 { |
60 FloatRect strokeBoundingBox = m_strokeBoundingBox; | 96 FloatRect strokeBoundingBox = m_strokeBoundingBox; |
61 | 97 |
62 if (!m_markerPositions.isEmpty()) | 98 if (!m_markerPositions.isEmpty()) |
63 strokeBoundingBox.unite(markerRect(strokeWidth())); | 99 strokeBoundingBox.unite(markerRect(strokeWidth())); |
64 | 100 |
65 if (style()->svgStyle().hasStroke()) { | 101 if (style()->svgStyle().hasStroke()) { |
66 // FIXME: zero-length subpaths do not respect vector-effect = non-scalin g-stroke. | 102 // FIXME: zero-length subpaths do not respect vector-effect = non-scalin g-stroke. |
67 float strokeWidth = this->strokeWidth(); | 103 float strokeWidth = this->strokeWidth(); |
68 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) | 104 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) |
69 strokeBoundingBox.unite(zeroLengthSubpathRect(m_zeroLengthLinecapLoc ations[i], strokeWidth)); | 105 strokeBoundingBox.unite(zeroLengthSubpathRect(m_zeroLengthLinecapLoc ations[i], strokeWidth)); |
70 } | 106 } |
71 | 107 |
72 return strokeBoundingBox; | 108 return strokeBoundingBox; |
73 } | 109 } |
74 | 110 |
75 bool LayoutSVGPath::shapeDependentStrokeContains(const FloatPoint& point) | 111 bool LayoutSVGPath::shapeDependentStrokeContains(const FloatPoint& point) |
76 { | 112 { |
77 if (LayoutSVGShape::shapeDependentStrokeContains(point)) | 113 if (LayoutSVGShape::shapeDependentStrokeContains(point)) |
78 return true; | 114 return true; |
79 | 115 |
80 const SVGLayoutStyle& svgStyle = style()->svgStyle(); | 116 const SVGLayoutStyle& svgStyle = style()->svgStyle(); |
117 const float strokeWidth = this->strokeWidth(); | |
81 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) { | 118 for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) { |
82 ASSERT(svgStyle.hasStroke()); | 119 ASSERT(svgStyle.hasStroke()); |
83 float strokeWidth = this->strokeWidth(); | |
84 if (svgStyle.capStyle() == SquareCap) { | 120 if (svgStyle.capStyle() == SquareCap) { |
85 if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWid th).contains(point)) | 121 if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWid th).contains(point)) |
86 return true; | 122 return true; |
87 } else { | 123 } else { |
88 ASSERT(svgStyle.capStyle() == RoundCap); | 124 ASSERT(svgStyle.capStyle() == RoundCap); |
89 FloatPoint radiusVector(point.x() - m_zeroLengthLinecapLocations[i]. x(), point.y() - m_zeroLengthLinecapLocations[i].y()); | 125 FloatPoint radiusVector(point.x() - m_zeroLengthLinecapLocations[i]. x(), point.y() - m_zeroLengthLinecapLocations[i].y()); |
90 if (radiusVector.lengthSquared() < strokeWidth * strokeWidth * .25f) | 126 if (radiusVector.lengthSquared() < strokeWidth * strokeWidth * .25f) |
91 return true; | 127 return true; |
92 } | 128 } |
93 } | 129 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 ASSERT(resources); | 201 ASSERT(resources); |
166 | 202 |
167 LayoutSVGResourceMarker* markerStart = resources->markerStart(); | 203 LayoutSVGResourceMarker* markerStart = resources->markerStart(); |
168 | 204 |
169 SVGMarkerData markerData(m_markerPositions, markerStart ? markerStart->orien tType() == SVGMarkerOrientAutoStartReverse : false); | 205 SVGMarkerData markerData(m_markerPositions, markerStart ? markerStart->orien tType() == SVGMarkerOrientAutoStartReverse : false); |
170 path().apply(&markerData, SVGMarkerData::updateFromPathElement); | 206 path().apply(&markerData, SVGMarkerData::updateFromPathElement); |
171 markerData.pathIsDone(); | 207 markerData.pathIsDone(); |
172 } | 208 } |
173 | 209 |
174 } | 210 } |
OLD | NEW |