- Revision
- 156024
- Author
- wei...@apple.com
- Date
- 2013-09-17 23:05:09 -0700 (Tue, 17 Sep 2013)
Log Message
Shrink SVGPathStringBuilder
https://bugs.webkit.org/show_bug.cgi?id=121536
Reviewed by Anders Carlsson.
- Use StringBuilder everywhere to avoid unnecessary temporary
String objects and code size bloat.
- Also did a drive by FINAL / OVERRIDE pass.
As an example of the win, the function SVGPathStringBuilder::arcTo
went from being 6120 bytes down to just 378 bytes.
* svg/SVGPathStringBuilder.cpp:
(WebCore::SVGPathStringBuilder::SVGPathStringBuilder):
(WebCore::SVGPathStringBuilder::~SVGPathStringBuilder):
(WebCore::SVGPathStringBuilder::cleanup):
(WebCore::SVGPathStringBuilder::incrementPathSegmentCount):
(WebCore::SVGPathStringBuilder::continueConsuming):
It wasn't helpful for these to be inlined, so move them to
the implementation file.
(WebCore::appendFlag):
(WebCore::appendNumber):
(WebCore::appendPoint):
Added helpers.
(WebCore::SVGPathStringBuilder::moveTo):
(WebCore::SVGPathStringBuilder::lineTo):
(WebCore::SVGPathStringBuilder::lineToHorizontal):
(WebCore::SVGPathStringBuilder::lineToVertical):
(WebCore::SVGPathStringBuilder::curveToCubic):
(WebCore::SVGPathStringBuilder::curveToCubicSmooth):
(WebCore::SVGPathStringBuilder::curveToQuadratic):
(WebCore::SVGPathStringBuilder::curveToQuadraticSmooth):
(WebCore::SVGPathStringBuilder::arcTo):
(WebCore::SVGPathStringBuilder::closePath):
* svg/SVGPathStringBuilder.h:
Stopped using operator+ and removed duplicate string building logic in each build
type (e.g. both sides of the PathCoordinateMode condition were doing almost identical
work).
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (156023 => 156024)
--- trunk/Source/WebCore/ChangeLog 2013-09-18 05:00:18 UTC (rev 156023)
+++ trunk/Source/WebCore/ChangeLog 2013-09-18 06:05:09 UTC (rev 156024)
@@ -1,5 +1,48 @@
2013-09-17 Sam Weinig <s...@webkit.org>
+ Shrink SVGPathStringBuilder
+ https://bugs.webkit.org/show_bug.cgi?id=121536
+
+ Reviewed by Anders Carlsson.
+
+ - Use StringBuilder everywhere to avoid unnecessary temporary
+ String objects and code size bloat.
+ - Also did a drive by FINAL / OVERRIDE pass.
+
+ As an example of the win, the function SVGPathStringBuilder::arcTo
+ went from being 6120 bytes down to just 378 bytes.
+
+ * svg/SVGPathStringBuilder.cpp:
+ (WebCore::SVGPathStringBuilder::SVGPathStringBuilder):
+ (WebCore::SVGPathStringBuilder::~SVGPathStringBuilder):
+ (WebCore::SVGPathStringBuilder::cleanup):
+ (WebCore::SVGPathStringBuilder::incrementPathSegmentCount):
+ (WebCore::SVGPathStringBuilder::continueConsuming):
+ It wasn't helpful for these to be inlined, so move them to
+ the implementation file.
+
+ (WebCore::appendFlag):
+ (WebCore::appendNumber):
+ (WebCore::appendPoint):
+ Added helpers.
+
+ (WebCore::SVGPathStringBuilder::moveTo):
+ (WebCore::SVGPathStringBuilder::lineTo):
+ (WebCore::SVGPathStringBuilder::lineToHorizontal):
+ (WebCore::SVGPathStringBuilder::lineToVertical):
+ (WebCore::SVGPathStringBuilder::curveToCubic):
+ (WebCore::SVGPathStringBuilder::curveToCubicSmooth):
+ (WebCore::SVGPathStringBuilder::curveToQuadratic):
+ (WebCore::SVGPathStringBuilder::curveToQuadraticSmooth):
+ (WebCore::SVGPathStringBuilder::arcTo):
+ (WebCore::SVGPathStringBuilder::closePath):
+ * svg/SVGPathStringBuilder.h:
+ Stopped using operator+ and removed duplicate string building logic in each build
+ type (e.g. both sides of the PathCoordinateMode condition were doing almost identical
+ work).
+
+2013-09-17 Sam Weinig <s...@webkit.org>
+
CTTE: Convert some straggling Element subclasses constructors to take a Document&
https://bugs.webkit.org/show_bug.cgi?id=121533
Modified: trunk/Source/WebCore/svg/SVGPathStringBuilder.cpp (156023 => 156024)
--- trunk/Source/WebCore/svg/SVGPathStringBuilder.cpp 2013-09-18 05:00:18 UTC (rev 156023)
+++ trunk/Source/WebCore/svg/SVGPathStringBuilder.cpp 2013-09-18 06:05:09 UTC (rev 156024)
@@ -25,6 +25,14 @@
namespace WebCore {
+SVGPathStringBuilder::SVGPathStringBuilder()
+{
+}
+
+SVGPathStringBuilder::~SVGPathStringBuilder()
+{
+}
+
String SVGPathStringBuilder::result()
{
unsigned size = m_stringBuilder.length();
@@ -36,101 +44,142 @@
return m_stringBuilder.toString();
}
+void SVGPathStringBuilder::cleanup()
+{
+ m_stringBuilder.clear();
+}
+
+void SVGPathStringBuilder::incrementPathSegmentCount()
+{
+}
+
+bool SVGPathStringBuilder::continueConsuming()
+{
+ return true;
+}
+
+static void appendFlag(StringBuilder& stringBuilder, bool flag)
+{
+ stringBuilder.append(flag ? '1' : '0');
+ stringBuilder.append(' ');
+}
+
+static void appendNumber(StringBuilder& stringBuilder, float number)
+{
+ stringBuilder.appendNumber(number);
+ stringBuilder.append(' ');
+}
+
+static void appendPoint(StringBuilder& stringBuilder, const FloatPoint& point)
+{
+ stringBuilder.appendNumber(point.x());
+ stringBuilder.append(' ');
+ stringBuilder.appendNumber(point.y());
+ stringBuilder.append(' ');
+}
+
void SVGPathStringBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode)
{
if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("M " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ m_stringBuilder.appendLiteral("M ");
else
- m_stringBuilder.append("m " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ m_stringBuilder.appendLiteral("m ");
+
+ appendPoint(m_stringBuilder, targetPoint);
}
void SVGPathStringBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
{
if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("L " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ m_stringBuilder.appendLiteral("L ");
else
- m_stringBuilder.append("l " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ m_stringBuilder.appendLiteral("l ");
+
+ appendPoint(m_stringBuilder, targetPoint);
}
void SVGPathStringBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
{
if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("H " + String::number(x) + ' ');
+ m_stringBuilder.appendLiteral("H ");
else
- m_stringBuilder.append("h " + String::number(x) + ' ');
+ m_stringBuilder.appendLiteral("h ");
+
+ appendNumber(m_stringBuilder, x);
}
void SVGPathStringBuilder::lineToVertical(float y, PathCoordinateMode mode)
{
if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("V " + String::number(y) + ' ');
+ m_stringBuilder.appendLiteral("V ");
else
- m_stringBuilder.append("v " + String::number(y) + ' ');
+ m_stringBuilder.appendLiteral("v ");
+
+ appendNumber(m_stringBuilder, y);
}
void SVGPathStringBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates) {
- m_stringBuilder.append("C " + String::number(point1.x()) + ' ' + String::number(point1.y())
- + ' ' + String::number(point2.x()) + ' ' + String::number(point2.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- return;
- }
+ if (mode == AbsoluteCoordinates)
+ m_stringBuilder.appendLiteral("C ");
+ else
+ m_stringBuilder.appendLiteral("c ");
- m_stringBuilder.append("c " + String::number(point1.x()) + ' ' + String::number(point1.y())
- + ' ' + String::number(point2.x()) + ' ' + String::number(point2.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ appendPoint(m_stringBuilder, point1);
+ appendPoint(m_stringBuilder, point2);
+ appendPoint(m_stringBuilder, targetPoint);
}
void SVGPathStringBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates) {
- m_stringBuilder.append("S " + String::number(point2.x()) + ' ' + String::number(point2.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- return;
- }
+ if (mode == AbsoluteCoordinates)
+ m_stringBuilder.appendLiteral("S ");
+ else
+ m_stringBuilder.appendLiteral("s ");
- m_stringBuilder.append("s " + String::number(point2.x()) + ' ' + String::number(point2.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ appendPoint(m_stringBuilder, point2);
+ appendPoint(m_stringBuilder, targetPoint);
}
void SVGPathStringBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates) {
- m_stringBuilder.append("Q " + String::number(point1.x()) + ' ' + String::number(point1.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- return;
- }
+ if (mode == AbsoluteCoordinates)
+ m_stringBuilder.appendLiteral("Q ");
+ else
+ m_stringBuilder.appendLiteral("q ");
- m_stringBuilder.append("q " + String::number(point1.x()) + ' ' + String::number(point1.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ appendPoint(m_stringBuilder, point1);
+ appendPoint(m_stringBuilder, targetPoint);
}
void SVGPathStringBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
{
if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("T " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ m_stringBuilder.appendLiteral("T ");
else
- m_stringBuilder.append("t " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ m_stringBuilder.appendLiteral("t ");
+
+ appendPoint(m_stringBuilder, targetPoint);
}
void SVGPathStringBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates) {
- m_stringBuilder.append("A " + String::number(r1) + ' ' + String::number(r2)
- + ' ' + String::number(angle) + ' ' + String::number(largeArcFlag) + ' ' + String::number(sweepFlag)
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- return;
- }
+ if (mode == AbsoluteCoordinates)
+ m_stringBuilder.appendLiteral("A ");
+ else
+ m_stringBuilder.appendLiteral("a ");
- m_stringBuilder.append("a " + String::number(r1) + ' ' + String::number(r2)
- + ' ' + String::number(angle) + ' ' + String::number(largeArcFlag) + ' ' + String::number(sweepFlag)
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ appendNumber(m_stringBuilder, r1);
+ appendNumber(m_stringBuilder, r2);
+ appendNumber(m_stringBuilder, angle);
+ appendFlag(m_stringBuilder, largeArcFlag);
+ appendFlag(m_stringBuilder, sweepFlag);
+ appendPoint(m_stringBuilder, targetPoint);
}
void SVGPathStringBuilder::closePath()
{
- m_stringBuilder.append("Z ");
+ m_stringBuilder.appendLiteral("Z ");
}
} // namespace WebCore
Modified: trunk/Source/WebCore/svg/SVGPathStringBuilder.h (156023 => 156024)
--- trunk/Source/WebCore/svg/SVGPathStringBuilder.h 2013-09-18 05:00:18 UTC (rev 156023)
+++ trunk/Source/WebCore/svg/SVGPathStringBuilder.h 2013-09-18 06:05:09 UTC (rev 156024)
@@ -21,34 +21,36 @@
#define SVGPathStringBuilder_h
#if ENABLE(SVG)
-#include "FloatPoint.h"
#include "SVGPathConsumer.h"
#include <wtf/text/StringBuilder.h>
namespace WebCore {
-class SVGPathStringBuilder : public SVGPathConsumer {
+class SVGPathStringBuilder FINAL : public SVGPathConsumer {
public:
+ SVGPathStringBuilder();
+ ~SVGPathStringBuilder();
+
String result();
private:
- virtual void cleanup() { m_stringBuilder.clear(); }
- virtual void incrementPathSegmentCount() { }
- virtual bool continueConsuming() { return true; }
+ virtual void cleanup() OVERRIDE;
+ virtual void incrementPathSegmentCount() OVERRIDE;
+ virtual bool continueConsuming() OVERRIDE;
// Used in UnalteredParsing/NormalizedParsing modes.
- virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode);
- virtual void lineTo(const FloatPoint&, PathCoordinateMode);
- virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void closePath();
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) OVERRIDE;
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void closePath() OVERRIDE;
// Only used in UnalteredParsing mode.
- virtual void lineToHorizontal(float, PathCoordinateMode);
- virtual void lineToVertical(float, PathCoordinateMode);
- virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode);
- virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode);
+ virtual void lineToHorizontal(float, PathCoordinateMode) OVERRIDE;
+ virtual void lineToVertical(float, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) OVERRIDE;
StringBuilder m_stringBuilder;
};