1 /*
2  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #ifndef SVGMarkerData_h
21 #define SVGMarkerData_h
22 
23 #if ENABLE(SVG)
24 #include "FloatConversion.h"
25 #include "Path.h"
26 #include <wtf/MathExtras.h>
27 
28 namespace WebCore {
29 
30 class RenderSVGResourceMarker;
31 
32 class SVGMarkerData {
33 public:
34     enum Type {
35         Unknown = 0,
36         Start,
37         Mid,
38         End
39     };
40 
41     SVGMarkerData(const Type& type = Unknown, RenderSVGResourceMarker* marker = 0)
m_type(type)42         : m_type(type)
43         , m_marker(marker)
44     {
45     }
46 
origin()47     FloatPoint origin() const { return m_origin; }
marker()48     RenderSVGResourceMarker* marker() const { return m_marker; }
49 
currentAngle()50     float currentAngle() const
51     {
52         FloatSize inslopeChange = m_inslopePoints[1] - m_inslopePoints[0];
53         FloatSize outslopeChange = m_outslopePoints[1] - m_outslopePoints[0];
54 
55         double inslope = rad2deg(atan2(inslopeChange.height(), inslopeChange.width()));
56         double outslope = rad2deg(atan2(outslopeChange.height(), outslopeChange.width()));
57 
58         double angle = 0;
59         switch (m_type) {
60         case Start:
61             angle = outslope;
62             break;
63         case Mid:
64             angle = (inslope + outslope) / 2;
65             break;
66         case End:
67             angle = inslope;
68             break;
69         default:
70             ASSERT_NOT_REACHED();
71             break;
72         }
73 
74         return narrowPrecisionToFloat(angle);
75     }
76 
updateTypeAndMarker(const Type & type,RenderSVGResourceMarker * marker)77     void updateTypeAndMarker(const Type& type, RenderSVGResourceMarker* marker)
78     {
79         m_type = type;
80         m_marker = marker;
81     }
82 
updateOutslope(const FloatPoint & point)83     void updateOutslope(const FloatPoint& point)
84     {
85         m_outslopePoints[0] = m_origin;
86         m_outslopePoints[1] = point;
87     }
88 
updateMarkerDataForPathElement(const PathElement * element)89     void updateMarkerDataForPathElement(const PathElement* element)
90     {
91         FloatPoint* points = element->points;
92 
93         switch (element->type) {
94         case PathElementAddQuadCurveToPoint:
95             // FIXME: https://bugs.webkit.org/show_bug.cgi?id=33115 (PathElementAddQuadCurveToPoint not handled for <marker>)
96             m_origin = points[1];
97             break;
98         case PathElementAddCurveToPoint:
99             m_inslopePoints[0] = points[1];
100             m_inslopePoints[1] = points[2];
101             m_origin = points[2];
102             break;
103         case PathElementMoveToPoint:
104             m_subpathStart = points[0];
105         case PathElementAddLineToPoint:
106             updateInslope(points[0]);
107             m_origin = points[0];
108             break;
109         case PathElementCloseSubpath:
110             updateInslope(points[0]);
111             m_origin = m_subpathStart;
112             m_subpathStart = FloatPoint();
113         }
114     }
115 
116 private:
updateInslope(const FloatPoint & point)117     void updateInslope(const FloatPoint& point)
118     {
119         m_inslopePoints[0] = m_origin;
120         m_inslopePoints[1] = point;
121     }
122 
123     Type m_type;
124     RenderSVGResourceMarker* m_marker;
125     FloatPoint m_origin;
126     FloatPoint m_subpathStart;
127     FloatPoint m_inslopePoints[2];
128     FloatPoint m_outslopePoints[2];
129 };
130 
131 }
132 
133 #endif // ENABLE(SVG)
134 #endif // SVGMarkerData_h
135