1/*
2 * Copyright (C) Research In Motion Limited 2010-2011. 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#include "config.h"
21#include "core/svg/SVGPathStringBuilder.h"
22
23#include "wtf/text/WTFString.h"
24
25namespace WebCore {
26
27String SVGPathStringBuilder::result()
28{
29    unsigned size = m_stringBuilder.length();
30    if (!size)
31        return String();
32
33    // Remove trailing space.
34    m_stringBuilder.resize(size - 1);
35    return m_stringBuilder.toString();
36}
37
38void SVGPathStringBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode)
39{
40    if (mode == AbsoluteCoordinates)
41        m_stringBuilder.append("M " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
42    else
43        m_stringBuilder.append("m " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
44}
45
46void SVGPathStringBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
47{
48    if (mode == AbsoluteCoordinates)
49        m_stringBuilder.append("L " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
50    else
51        m_stringBuilder.append("l " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
52}
53
54void SVGPathStringBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
55{
56    if (mode == AbsoluteCoordinates)
57        m_stringBuilder.append("H " + String::number(x) + ' ');
58    else
59        m_stringBuilder.append("h " + String::number(x) + ' ');
60}
61
62void SVGPathStringBuilder::lineToVertical(float y, PathCoordinateMode mode)
63{
64    if (mode == AbsoluteCoordinates)
65        m_stringBuilder.append("V " + String::number(y) + ' ');
66    else
67        m_stringBuilder.append("v " + String::number(y) + ' ');
68}
69
70void SVGPathStringBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
71{
72    if (mode == AbsoluteCoordinates) {
73        m_stringBuilder.append("C " + String::number(point1.x()) + ' ' + String::number(point1.y())
74                              + ' ' + String::number(point2.x()) + ' ' + String::number(point2.y())
75                              + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
76        return;
77    }
78
79    m_stringBuilder.append("c " + String::number(point1.x()) + ' ' + String::number(point1.y())
80                          + ' ' + String::number(point2.x()) + ' ' + String::number(point2.y())
81                          + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
82}
83
84void SVGPathStringBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
85{
86    if (mode == AbsoluteCoordinates) {
87        m_stringBuilder.append("S " + String::number(point2.x()) + ' ' + String::number(point2.y())
88                              + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
89        return;
90    }
91
92    m_stringBuilder.append("s " + String::number(point2.x()) + ' ' + String::number(point2.y())
93                          + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
94}
95
96void SVGPathStringBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
97{
98    if (mode == AbsoluteCoordinates) {
99        m_stringBuilder.append("Q " + String::number(point1.x()) + ' ' + String::number(point1.y())
100                              + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
101        return;
102    }
103
104    m_stringBuilder.append("q " + String::number(point1.x()) + ' ' + String::number(point1.y())
105                          + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
106}
107
108void SVGPathStringBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
109{
110    if (mode == AbsoluteCoordinates)
111        m_stringBuilder.append("T " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
112    else
113        m_stringBuilder.append("t " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
114}
115
116void SVGPathStringBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
117{
118    if (mode == AbsoluteCoordinates) {
119        m_stringBuilder.append("A " + String::number(r1) + ' ' + String::number(r2)
120                              + ' ' + String::number(angle) + ' ' + String::number(largeArcFlag) + ' ' + String::number(sweepFlag)
121                              + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
122        return;
123    }
124
125    m_stringBuilder.append("a " + String::number(r1) + ' ' + String::number(r2)
126                          + ' ' + String::number(angle) + ' ' + String::number(largeArcFlag) + ' ' + String::number(sweepFlag)
127                          + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
128}
129
130void SVGPathStringBuilder::closePath()
131{
132    m_stringBuilder.append("Z ");
133}
134
135} // namespace WebCore
136