Index: third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp |
diff --git a/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp b/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp |
index 86b63718bb82623379f1cc66414b51d059e7459b..74f54f70ef79f35306987d48384359f1fdd7bcc0 100644 |
--- a/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp |
+++ b/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp |
@@ -26,19 +26,18 @@ |
namespace blink { |
-// Helper class that coalesces writes to a SVGPathByteStream to a local buffer. |
-class CoalescingBuffer { |
+namespace { |
+ |
+class StreamBufferHelper { |
public: |
- CoalescingBuffer(SVGPathByteStream& byteStream) |
- : m_currentOffset(0) |
- , m_byteStream(byteStream) |
- { |
- } |
- ~CoalescingBuffer() |
+ StreamBufferHelper(SVGPathByteStream& byteStream, size_t bytesToReserve) |
+ : m_buffer(byteStream.appendUninitialized(bytesToReserve)) |
{ |
- for (size_t i = 0; i < m_currentOffset; ++i) |
- m_byteStream.append(m_bytes[i]); |
+#if ENABLE(ASSERT) |
+ m_expectedEnd = m_buffer + bytesToReserve; |
+#endif |
} |
+ ~StreamBufferHelper() { ASSERT(m_expectedEnd == m_buffer); } |
template<typename DataType> |
void writeType(DataType value) |
@@ -47,8 +46,8 @@ public: |
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; |
+ memcpy(m_buffer, data.bytes, typeSize); |
+ m_buffer += typeSize; |
} |
void writeFlag(bool value) { writeType<bool>(value); } |
@@ -61,21 +60,47 @@ public: |
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; |
+ unsigned char* m_buffer; |
+#if ENABLE(ASSERT) |
+ const unsigned char* m_expectedEnd; |
+#endif |
}; |
+} |
+ |
SVGPathByteStreamBuilder::SVGPathByteStreamBuilder(SVGPathByteStream& byteStream) |
: m_byteStream(byteStream) |
{ |
} |
+static const unsigned char commandParamLength[] = { |
+ 0, |
+ /* PathSegClosePath */ 0, |
+ /* PathSegMoveToAbs */ sizeof(FloatPoint), |
+ /* PathSegMoveToRel */ sizeof(FloatPoint), |
+ /* PathSegLineToAbs */ sizeof(FloatPoint), |
+ /* PathSegLineToRel */ sizeof(FloatPoint), |
+ /* PathSegCurveToCubicAbs */ 3 * sizeof(FloatPoint), |
+ /* PathSegCurveToCubicRel */ 3 * sizeof(FloatPoint), |
+ /* PathSegCurveToQuadraticAbs */ 2 * sizeof(FloatPoint), |
+ /* PathSegCurveToQuadraticRel */ 2 * sizeof(FloatPoint), |
+ /* PathSegArcAbs */ 2 * sizeof(FloatPoint) + 1 * sizeof(float) + 2 * sizeof(bool), |
+ /* PathSegArcRel */ 2 * sizeof(FloatPoint) + 1 * sizeof(float) + 2 * sizeof(bool), |
+ /* PathSegLineToHorizontalAbs */ sizeof(float), |
+ /* PathSegLineToHorizontalRel */ sizeof(float), |
+ /* PathSegLineToVerticalAbs */ sizeof(float), |
+ /* PathSegLineToVerticalRel */ sizeof(float), |
+ /* PathSegCurveToCubicSmoothAbs */ 2 * sizeof(FloatPoint), |
+ /* PathSegCurveToCubicSmoothRel */ 2 * sizeof(FloatPoint), |
+ /* PathSegCurveToQuadraticSmoothAbs */ sizeof(FloatPoint), |
+ /* PathSegCurveToQuadraticSmoothRel */ sizeof(FloatPoint) |
+}; |
+ |
void SVGPathByteStreamBuilder::emitSegment(const PathSegmentData& segment) |
{ |
- CoalescingBuffer buffer(m_byteStream); |
+ ASSERT(segment.command > PathSegUnknown && segment.command <= PathSegCurveToQuadraticSmoothRel); |
+ size_t commandLength = sizeof(unsigned short) + commandParamLength[segment.command]; |
+ StreamBufferHelper buffer(m_byteStream, commandLength); |
buffer.writeSegmentType(segment.command); |
switch (segment.command) { |