Title: [156024] trunk/Source/WebCore
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;
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to