Index: Source/core/svg/SVGPathByteStreamBuilder.cpp |
diff --git a/Source/core/svg/SVGPathByteStreamBuilder.cpp b/Source/core/svg/SVGPathByteStreamBuilder.cpp |
index 31e50d06dd70c18eea2f9f848907691ea1d52b02..85a58a220bc85f7fb5e7b96413a07d2ca28832f1 100644 |
--- a/Source/core/svg/SVGPathByteStreamBuilder.cpp |
+++ b/Source/core/svg/SVGPathByteStreamBuilder.cpp |
@@ -26,6 +26,49 @@ |
namespace WebCore { |
+// Helper class that coalesces writes to a SVGPathByteStream to a local buffer. |
+class CoalescingBuffer { |
+public: |
+ CoalescingBuffer(SVGPathByteStream* byteStream) |
+ : m_currentOffset(0) |
+ , m_byteStream(byteStream) |
+ { |
+ ASSERT(byteStream); |
+ } |
+ ~CoalescingBuffer() |
+ { |
+ for (size_t i = 0; i < m_currentOffset; ++i) |
+ m_byteStream->append(m_bytes[i]); |
Chris Evans
2014/02/05 18:54:48
Drive-by: I was looking at this recently and notic
|
+ } |
+ |
+ template<typename DataType> |
+ void writeType(DataType value) |
+ { |
+ ByteType<DataType> data; |
+ data.value = value; |
+ size_t typeSize = sizeof(ByteType<DataType>); |
+ ASSERT(m_currentOffset + typeSize <= sizeof(m_bytes)); |
+ memcpy(m_bytes + m_currentOffset, data.bytes, typeSize); |
+ m_currentOffset += typeSize; |
+ } |
+ |
+ void writeFlag(bool value) { writeType<bool>(value); } |
+ void writeFloat(float value) { writeType<float>(value); } |
+ void writeFloatPoint(const FloatPoint& point) |
+ { |
+ writeType<float>(point.x()); |
+ writeType<float>(point.y()); |
+ } |
+ void writeSegmentType(unsigned short value) { writeType<unsigned short>(value); } |
+ |
+private: |
+ // Adjust size to fit the largest command (in serialized/byte-stream format). |
+ // Currently a cubic segment. |
+ size_t m_currentOffset; |
+ unsigned char m_bytes[sizeof(unsigned short) + sizeof(FloatPoint) * 3]; |
+ SVGPathByteStream* m_byteStream; |
+}; |
+ |
SVGPathByteStreamBuilder::SVGPathByteStreamBuilder() |
: m_byteStream(0) |
{ |
@@ -33,80 +76,80 @@ SVGPathByteStreamBuilder::SVGPathByteStreamBuilder() |
void SVGPathByteStreamBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegMoveToRel : PathSegMoveToAbs); |
- writeFloatPoint(targetPoint); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegMoveToRel : PathSegMoveToAbs); |
+ buffer.writeFloatPoint(targetPoint); |
} |
void SVGPathByteStreamBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegLineToRel : PathSegLineToAbs); |
- writeFloatPoint(targetPoint); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToRel : PathSegLineToAbs); |
+ buffer.writeFloatPoint(targetPoint); |
} |
void SVGPathByteStreamBuilder::lineToHorizontal(float x, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegLineToHorizontalRel : PathSegLineToHorizontalAbs); |
- writeFloat(x); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToHorizontalRel : PathSegLineToHorizontalAbs); |
+ buffer.writeFloat(x); |
} |
void SVGPathByteStreamBuilder::lineToVertical(float y, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegLineToVerticalRel : PathSegLineToVerticalAbs); |
- writeFloat(y); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToVerticalRel : PathSegLineToVerticalAbs); |
+ buffer.writeFloat(y); |
} |
void SVGPathByteStreamBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicRel : PathSegCurveToCubicAbs); |
- writeFloatPoint(point1); |
- writeFloatPoint(point2); |
- writeFloatPoint(targetPoint); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicRel : PathSegCurveToCubicAbs); |
+ buffer.writeFloatPoint(point1); |
+ buffer.writeFloatPoint(point2); |
+ buffer.writeFloatPoint(targetPoint); |
} |
void SVGPathByteStreamBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicSmoothRel : PathSegCurveToCubicSmoothAbs); |
- writeFloatPoint(point2); |
- writeFloatPoint(targetPoint); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicSmoothRel : PathSegCurveToCubicSmoothAbs); |
+ buffer.writeFloatPoint(point2); |
+ buffer.writeFloatPoint(targetPoint); |
} |
void SVGPathByteStreamBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticRel : PathSegCurveToQuadraticAbs); |
- writeFloatPoint(point1); |
- writeFloatPoint(targetPoint); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticRel : PathSegCurveToQuadraticAbs); |
+ buffer.writeFloatPoint(point1); |
+ buffer.writeFloatPoint(targetPoint); |
} |
void SVGPathByteStreamBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticSmoothRel : PathSegCurveToQuadraticSmoothAbs); |
- writeFloatPoint(targetPoint); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticSmoothRel : PathSegCurveToQuadraticSmoothAbs); |
+ buffer.writeFloatPoint(targetPoint); |
} |
void SVGPathByteStreamBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode) |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(mode == RelativeCoordinates ? PathSegArcRel : PathSegArcAbs); |
- writeFloat(r1); |
- writeFloat(r2); |
- writeFloat(angle); |
- writeFlag(largeArcFlag); |
- writeFlag(sweepFlag); |
- writeFloatPoint(targetPoint); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegArcRel : PathSegArcAbs); |
+ buffer.writeFloat(r1); |
+ buffer.writeFloat(r2); |
+ buffer.writeFloat(angle); |
+ buffer.writeFlag(largeArcFlag); |
+ buffer.writeFlag(sweepFlag); |
+ buffer.writeFloatPoint(targetPoint); |
} |
void SVGPathByteStreamBuilder::closePath() |
{ |
- ASSERT(m_byteStream); |
- writeSegmentType(PathSegClosePath); |
+ CoalescingBuffer buffer(m_byteStream); |
+ buffer.writeSegmentType(PathSegClosePath); |
} |
} // namespace WebCore |