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
28namespace WebCore {
29
30class RenderSVGResourceMarker;
31
32class SVGMarkerData {
33public:
34    enum Type {
35        Unknown = 0,
36        Start,
37        Mid,
38        End
39    };
40
41    SVGMarkerData(const Type& type = Unknown, RenderSVGResourceMarker* marker = 0)
42        : m_type(type)
43        , m_marker(marker)
44    {
45    }
46
47    FloatPoint origin() const { return m_origin; }
48    RenderSVGResourceMarker* marker() const { return m_marker; }
49
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
77    void updateTypeAndMarker(const Type& type, RenderSVGResourceMarker* marker)
78    {
79        m_type = type;
80        m_marker = marker;
81    }
82
83    void updateOutslope(const FloatPoint& point)
84    {
85        m_outslopePoints[0] = m_origin;
86        m_outslopePoints[1] = point;
87    }
88
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
116private:
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