2010-02-09 Dirk Schulze <krit@webkit.org>
authorkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Feb 2010 20:46:59 +0000 (20:46 +0000)
committerkrit@webkit.org <krit@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Feb 2010 20:46:59 +0000 (20:46 +0000)
        Reviewed by Nikolas Zimmermann.

        More optimization for AffineTransform with SVG
        https://bugs.webkit.org/show_bug.cgi?id=34774

        Some optimizations to safe unnecessary summations and multiplications.
        Optimize AffineTransform to handle an identity or translation matrix
        more efficient.
        Added translationRight to avoid multiplications of matrices as much as
        possible.

        No tests added, no change of functionality.

        * platform/graphics/transforms/AffineTransform.cpp:
        (WebCore::AffineTransform::inverse):
        (WebCore::AffineTransform::translate):
        (WebCore::AffineTransform::translateRight):
        * platform/graphics/transforms/AffineTransform.h:
        * rendering/RenderForeignObject.cpp:
        (WebCore::RenderForeignObject::translationForAttributes):
        (WebCore::RenderForeignObject::localToParentTransform):
        * rendering/RenderForeignObject.h:
        * rendering/RenderSVGRoot.cpp:
        (WebCore::RenderSVGRoot::localToBorderBoxTransform):
        (WebCore::RenderSVGRoot::localToRepaintContainerTransform):
        (WebCore::RenderSVGRoot::localToParentTransform):
        * rendering/RenderSVGViewportContainer.cpp:
        (WebCore::RenderSVGViewportContainer::localToParentTransform):
        * rendering/SVGRootInlineBox.cpp:
        (WebCore::applyTextLengthCorrectionToTextChunk):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@54564 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/graphics/transforms/AffineTransform.cpp
WebCore/platform/graphics/transforms/AffineTransform.h
WebCore/rendering/RenderForeignObject.cpp
WebCore/rendering/RenderForeignObject.h
WebCore/rendering/RenderSVGRoot.cpp
WebCore/rendering/RenderSVGViewportContainer.cpp
WebCore/rendering/SVGRootInlineBox.cpp

index 889acfa..3cfc586 100644 (file)
@@ -2,6 +2,39 @@
 
         Reviewed by Nikolas Zimmermann.
 
+        More optimization for AffineTransform with SVG
+        https://bugs.webkit.org/show_bug.cgi?id=34774
+
+        Some optimizations to safe unnecessary summations and multiplications.
+        Optimize AffineTransform to handle an identity or translation matrix
+        more efficient.
+        Added translationRight to avoid multiplications of matrices as much as
+        possible.
+
+        No tests added, no change of functionality.   
+
+        * platform/graphics/transforms/AffineTransform.cpp:
+        (WebCore::AffineTransform::inverse):
+        (WebCore::AffineTransform::translate):
+        (WebCore::AffineTransform::translateRight):
+        * platform/graphics/transforms/AffineTransform.h:
+        * rendering/RenderForeignObject.cpp:
+        (WebCore::RenderForeignObject::translationForAttributes):
+        (WebCore::RenderForeignObject::localToParentTransform):
+        * rendering/RenderForeignObject.h:
+        * rendering/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::localToBorderBoxTransform):
+        (WebCore::RenderSVGRoot::localToRepaintContainerTransform):
+        (WebCore::RenderSVGRoot::localToParentTransform):
+        * rendering/RenderSVGViewportContainer.cpp:
+        (WebCore::RenderSVGViewportContainer::localToParentTransform):
+        * rendering/SVGRootInlineBox.cpp:
+        (WebCore::applyTextLengthCorrectionToTextChunk):
+
+2010-02-09  Dirk Schulze  <krit@webkit.org>
+
+        Reviewed by Nikolas Zimmermann.
+
         SVG patterns with some scale patternTransform are not displayed correctly for small elements
         https://bugs.webkit.org/show_bug.cgi?id=25484
 
index 183bff5..d6688d2 100644 (file)
@@ -136,6 +136,12 @@ AffineTransform AffineTransform::inverse() const
         return AffineTransform();
 
     AffineTransform result;
+    if (isIdentityOrTranslation()) {
+        result.m_transform[4] = -m_transform[4];
+        result.m_transform[5] = -m_transform[5];
+        return result;
+    }
+
     result.m_transform[0] = m_transform[3] / determinant;
     result.m_transform[1] = -m_transform[1] / determinant;
     result.m_transform[2] = -m_transform[2] / determinant;
@@ -194,13 +200,28 @@ AffineTransform& AffineTransform::scale(double sx, double sy)
     return *this;
 }
 
+// *this = *this * translation
 AffineTransform& AffineTransform::translate(double tx, double ty)
 {
+    if (isIdentityOrTranslation()) {
+        m_transform[4] += tx;
+        m_transform[5] += ty;
+        return *this;
+    }
+        
     m_transform[4] += tx * m_transform[0] + ty * m_transform[2];
     m_transform[5] += tx * m_transform[1] + ty * m_transform[3];
     return *this;
 }
 
+// *this = translation * *this
+AffineTransform& AffineTransform::translateRight(double tx, double ty)
+{
+    m_transform[4] += tx;
+    m_transform[5] += ty;
+    return *this;
+}
+
 AffineTransform& AffineTransform::scaleNonUniform(double sx, double sy)
 {
     return scale(sx, sy);
index 30d712d..00631c2 100644 (file)
@@ -100,6 +100,7 @@ public:
     AffineTransform& rotate(double d);
     AffineTransform& rotateFromVector(double x, double y);
     AffineTransform& translate(double tx, double ty);
+    AffineTransform& translateRight(double tx, double ty);
     AffineTransform& shear(double sx, double sy);
     AffineTransform& flipX();
     AffineTransform& flipY();
index d7532b1..5bb4439 100644 (file)
@@ -38,10 +38,10 @@ RenderForeignObject::RenderForeignObject(SVGForeignObjectElement* node)
 {
 }
 
-AffineTransform RenderForeignObject::translationForAttributes() const
+FloatPoint RenderForeignObject::translationForAttributes() const
 {
     SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node());
-    return AffineTransform().translate(foreign->x().value(foreign), foreign->y().value(foreign));
+    return FloatPoint(foreign->x().value(foreign), foreign->y().value(foreign));
 }
 
 void RenderForeignObject::paint(PaintInfo& paintInfo, int, int)
@@ -90,7 +90,8 @@ void RenderForeignObject::computeRectForRepaint(RenderBoxModelObject* repaintCon
 
 const AffineTransform& RenderForeignObject::localToParentTransform() const
 {
-    m_localToParentTransform = localTransform() * translationForAttributes();
+    FloatPoint attributeTranslation(translationForAttributes());
+    m_localToParentTransform = localTransform().translateRight(attributeTranslation.x(), attributeTranslation.y());
     return m_localToParentTransform;
 }
 
index 17057b5..f32069c 100644 (file)
@@ -24,6 +24,7 @@
 #if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT)
 
 #include "AffineTransform.h"
+#include "FloatPoint.h"
 #include "RenderSVGBlock.h"
 
 namespace WebCore {
@@ -55,7 +56,7 @@ public:
     virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed , bool useTransforms, TransformState& transformState) const;
 
  private:
-    AffineTransform translationForAttributes() const;
+    FloatPoint translationForAttributes() const;
 
     virtual AffineTransform localTransform() const { return m_localTransform; }
 
index 78499b1..74172fc 100644 (file)
@@ -192,11 +192,10 @@ void RenderSVGRoot::calcViewport()
 // relative to our borderBox origin.  This method gives us exactly that.
 AffineTransform RenderSVGRoot::localToBorderBoxTransform() const
 {
-    AffineTransform ctm;
     IntSize borderAndPadding = borderOriginToContentBox();
-    ctm.translate(borderAndPadding.width(), borderAndPadding.height());
     SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
-    ctm.scale(svg->currentScale());
+    float scale = svg->currentScale();
+    AffineTransform ctm(scale, 0, 0, scale, borderAndPadding.width(), borderAndPadding.height());
     ctm.translate(svg->currentTranslate().x(), svg->currentTranslate().y());
     return svg->viewBoxToViewTransform(width(), height()) * ctm;
 }
@@ -213,19 +212,18 @@ IntSize RenderSVGRoot::borderOriginToContentBox() const
 
 AffineTransform RenderSVGRoot::localToRepaintContainerTransform(const IntPoint& parentOriginInContainer) const
 {
-    AffineTransform parentToContainer;
-    parentToContainer.translate(parentOriginInContainer.x(), parentOriginInContainer.y());
-    return localToParentTransform() * parentToContainer;
+    AffineTransform parentToContainer(localToParentTransform());
+    return parentToContainer.translateRight(parentOriginInContainer.x(), parentOriginInContainer.y());
 }
 
 const AffineTransform& RenderSVGRoot::localToParentTransform() const
 {
     IntSize parentToBorderBoxOffset = parentOriginToBorderBox();
 
-    AffineTransform borderBoxOriginToParentOrigin;
-    borderBoxOriginToParentOrigin.translate(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height());
+    AffineTransform borderBoxOriginToParentOrigin(localToBorderBoxTransform());
+    borderBoxOriginToParentOrigin.translateRight(parentToBorderBoxOffset.width(), parentToBorderBoxOffset.height());
 
-    m_localToParentTransform = localToBorderBoxTransform() * borderBoxOriginToParentOrigin;
+    m_localToParentTransform = borderBoxOriginToParentOrigin;
     return m_localToParentTransform;
 }
 
index 441faa5..103d9d2 100644 (file)
@@ -107,9 +107,8 @@ AffineTransform RenderSVGViewportContainer::viewportTransform() const
 
 const AffineTransform& RenderSVGViewportContainer::localToParentTransform() const
 {
-    AffineTransform viewportTranslation;
-    viewportTranslation.translate(m_viewport.x(), m_viewport.y());
-    m_localToParentTransform = viewportTransform() * viewportTranslation;
+    AffineTransform viewportTranslation(viewportTransform());
+    m_localToParentTransform = viewportTranslation.translateRight(m_viewport.x(), m_viewport.y());
     return m_localToParentTransform;
     // If this class were ever given a localTransform(), then the above would read:
     // return viewportTransform() * localTransform() * viewportTranslation;
index 3f21e64..d0dd4a8 100644 (file)
@@ -933,9 +933,8 @@ static void applyTextLengthCorrectionToTextChunk(SVGTextChunk& chunk)
         SVGChar& firstChar = *(chunk.start);
 
         // Assure we apply the chunk scaling in the right origin
-        AffineTransform newChunkCtm;
-        newChunkCtm.translate(firstChar.x, firstChar.y);
-        newChunkCtm = chunk.ctm * newChunkCtm;
+        AffineTransform newChunkCtm(chunk.ctm);
+        newChunkCtm.translateRight(firstChar.x, firstChar.y);
         newChunkCtm.translate(-firstChar.x, -firstChar.y);
 
         chunk.ctm = newChunkCtm;