Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / svg / SVGPathByteStreamBuilder.cpp
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 #include "config.h"
21
22 #include "core/svg/SVGPathByteStreamBuilder.h"
23
24 #include "core/svg/SVGPathSeg.h"
25 #include "wtf/OwnPtr.h"
26
27 namespace blink {
28
29 // Helper class that coalesces writes to a SVGPathByteStream to a local buffer.
30 class CoalescingBuffer {
31 public:
32     CoalescingBuffer(SVGPathByteStream* byteStream)
33         : m_currentOffset(0)
34         , m_byteStream(byteStream)
35     {
36         ASSERT(byteStream);
37     }
38     ~CoalescingBuffer()
39     {
40         for (size_t i = 0; i < m_currentOffset; ++i)
41             m_byteStream->append(m_bytes[i]);
42     }
43
44     template<typename DataType>
45     void writeType(DataType value)
46     {
47         ByteType<DataType> data;
48         data.value = value;
49         size_t typeSize = sizeof(ByteType<DataType>);
50         ASSERT(m_currentOffset + typeSize <= sizeof(m_bytes));
51         memcpy(m_bytes + m_currentOffset, data.bytes, typeSize);
52         m_currentOffset += typeSize;
53     }
54
55     void writeFlag(bool value) { writeType<bool>(value); }
56     void writeFloat(float value) { writeType<float>(value); }
57     void writeFloatPoint(const FloatPoint& point)
58     {
59         writeType<float>(point.x());
60         writeType<float>(point.y());
61     }
62     void writeSegmentType(unsigned short value) { writeType<unsigned short>(value); }
63
64 private:
65     // Adjust size to fit the largest command (in serialized/byte-stream format).
66     // Currently a cubic segment.
67     size_t m_currentOffset;
68     unsigned char m_bytes[sizeof(unsigned short) + sizeof(FloatPoint) * 3];
69     SVGPathByteStream* m_byteStream;
70 };
71
72 SVGPathByteStreamBuilder::SVGPathByteStreamBuilder()
73     : m_byteStream(0)
74 {
75 }
76
77 void SVGPathByteStreamBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode)
78 {
79     CoalescingBuffer buffer(m_byteStream);
80     buffer.writeSegmentType(mode == RelativeCoordinates ?  PathSegMoveToRel : PathSegMoveToAbs);
81     buffer.writeFloatPoint(targetPoint);
82 }
83
84 void SVGPathByteStreamBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
85 {
86     CoalescingBuffer buffer(m_byteStream);
87     buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToRel : PathSegLineToAbs);
88     buffer.writeFloatPoint(targetPoint);
89 }
90
91 void SVGPathByteStreamBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
92 {
93     CoalescingBuffer buffer(m_byteStream);
94     buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToHorizontalRel : PathSegLineToHorizontalAbs);
95     buffer.writeFloat(x);
96 }
97
98 void SVGPathByteStreamBuilder::lineToVertical(float y, PathCoordinateMode mode)
99 {
100     CoalescingBuffer buffer(m_byteStream);
101     buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToVerticalRel : PathSegLineToVerticalAbs);
102     buffer.writeFloat(y);
103 }
104
105 void SVGPathByteStreamBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
106 {
107     CoalescingBuffer buffer(m_byteStream);
108     buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicRel : PathSegCurveToCubicAbs);
109     buffer.writeFloatPoint(point1);
110     buffer.writeFloatPoint(point2);
111     buffer.writeFloatPoint(targetPoint);
112 }
113
114 void SVGPathByteStreamBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
115 {
116     CoalescingBuffer buffer(m_byteStream);
117     buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicSmoothRel : PathSegCurveToCubicSmoothAbs);
118     buffer.writeFloatPoint(point2);
119     buffer.writeFloatPoint(targetPoint);
120 }
121
122 void SVGPathByteStreamBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
123 {
124     CoalescingBuffer buffer(m_byteStream);
125     buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticRel : PathSegCurveToQuadraticAbs);
126     buffer.writeFloatPoint(point1);
127     buffer.writeFloatPoint(targetPoint);
128 }
129
130 void SVGPathByteStreamBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
131 {
132     CoalescingBuffer buffer(m_byteStream);
133     buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticSmoothRel : PathSegCurveToQuadraticSmoothAbs);
134     buffer.writeFloatPoint(targetPoint);
135 }
136
137 void SVGPathByteStreamBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
138 {
139     CoalescingBuffer buffer(m_byteStream);
140     buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegArcRel : PathSegArcAbs);
141     buffer.writeFloat(r1);
142     buffer.writeFloat(r2);
143     buffer.writeFloat(angle);
144     buffer.writeFlag(largeArcFlag);
145     buffer.writeFlag(sweepFlag);
146     buffer.writeFloatPoint(targetPoint);
147 }
148
149 void SVGPathByteStreamBuilder::closePath()
150 {
151     CoalescingBuffer buffer(m_byteStream);
152     buffer.writeSegmentType(PathSegClosePath);
153 }
154
155 } // namespace blink