Reviewed by eseidel.
authorrwlbuis <rwlbuis@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Sep 2006 20:29:10 +0000 (20:29 +0000)
committerrwlbuis <rwlbuis@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Sep 2006 20:29:10 +0000 (20:29 +0000)
        http://bugzilla.opendarwin.org/show_bug.cgi?id=11015
        SVG handles em units incorrectly

        Calculate viewport coordinates at layout time, since
        at this point the font size is known and lengths depending
        on font sizes can be calculated correctly.

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

16 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/custom/viewport-em-expected.checksum [new file with mode: 0644]
LayoutTests/svg/custom/viewport-em-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/viewport-em-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/viewport-em.svg [new file with mode: 0644]
LayoutTests/svg/custom/viewport-update2-expected.checksum [new file with mode: 0644]
LayoutTests/svg/custom/viewport-update2-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/viewport-update2-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/viewport-update2.svg [new file with mode: 0644]
WebCore/ChangeLog
WebCore/kcanvas/RenderSVGContainer.cpp
WebCore/kcanvas/RenderSVGContainer.h
WebCore/ksvg2/svg/SVGLength.cpp
WebCore/ksvg2/svg/SVGMarkerElement.cpp
WebCore/ksvg2/svg/SVGSVGElement.cpp
WebCore/ksvg2/svg/SVGSVGElement.h

index 61c1478c53eae23ea6c64bc39c8a082f699bea16..545b8fc1bb43c221cff4ca10e2d65e2fd0328163 100644 (file)
@@ -1,3 +1,20 @@
+2006-09-27  Rob Buis  <buis@kde.org>
+
+        Reviewed by eseidel.
+
+        Testcases for:
+        http://bugzilla.opendarwin.org/show_bug.cgi?id=11015
+        SVG handles em units incorrectly
+
+        * svg/custom/viewport-em-expected.checksum: Added.
+        * svg/custom/viewport-em-expected.png: Added.
+        * svg/custom/viewport-em-expected.txt: Added.
+        * svg/custom/viewport-em.svg: Added.
+        * svg/custom/viewport-update2-expected.checksum: Added.
+        * svg/custom/viewport-update2-expected.png: Added.
+        * svg/custom/viewport-update2-expected.txt: Added.
+        * svg/custom/viewport-update2.svg: Added.
+
 2006-09-27  Eric Seidel  <eric@eseidel.com>
 
         Reviewed by darin.
diff --git a/LayoutTests/svg/custom/viewport-em-expected.checksum b/LayoutTests/svg/custom/viewport-em-expected.checksum
new file mode 100644 (file)
index 0000000..725c138
--- /dev/null
@@ -0,0 +1 @@
+8582cf4c7f667d677a8ce2bd274a4c8f
\ No newline at end of file
diff --git a/LayoutTests/svg/custom/viewport-em-expected.png b/LayoutTests/svg/custom/viewport-em-expected.png
new file mode 100644 (file)
index 0000000..0f84d1a
Binary files /dev/null and b/LayoutTests/svg/custom/viewport-em-expected.png differ
diff --git a/LayoutTests/svg/custom/viewport-em-expected.txt b/LayoutTests/svg/custom/viewport-em-expected.txt
new file mode 100644 (file)
index 0000000..ddc5324
--- /dev/null
@@ -0,0 +1,19 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x226
+  RenderBlock {html} at (0,0) size 800x226
+    RenderBody {body} at (8,16) size 784x202
+      RenderBlock {p} at (0,0) size 784x18 [color=#000080]
+        RenderText {#text} at (0,0) size 264x18
+          text run at (0,0) width 264: "There should be two identical bars below."
+      RenderBlock {p} at (0,34) size 784x18 [color=#000080]
+        RenderText {#text} at (0,0) size 56x18
+          text run at (0,0) width 56: "First bar:"
+      RenderBlock {div} at (0,68) size 160x40 [bgcolor=#000080]
+      RenderBlock {p} at (0,124) size 784x18 [color=#000080]
+        RenderText {#text} at (0,0) size 75x18
+          text run at (0,0) width 75: "Second bar:"
+      RenderBlock (anonymous) at (0,158) size 784x44
+        KCanvasContainer {svg} at (8,174) size 160x40
+          KCanvasItem {rect} at (8,174) size 160x40 [fill={[type=SOLID] [color=#000080]}] [data="M0.00,0.00L100.00,0.00L100.00,100.00L0.00,100.00"]
+        RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/svg/custom/viewport-em.svg b/LayoutTests/svg/custom/viewport-em.svg
new file mode 100644 (file)
index 0000000..2782efd
--- /dev/null
@@ -0,0 +1,18 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+  <title>'em' widths</title>
+  <style type="text/css">
+   p { color: navy; }
+   div { margin: 1em 0; height: 40px; width: 10em; background: navy; }
+  </style>
+ </head>
+ <body>
+  <p>There should be two identical bars below.</p>
+  <p>First bar:</p>
+  <div></div>
+  <p>Second bar:</p>
+  <svg preserveAspectRatio="none" height="40px" width="10em" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
+   <rect x="0" y="0" width="100" height="100" fill="navy"/>
+  </svg>
+ </body>
+</html>
diff --git a/LayoutTests/svg/custom/viewport-update2-expected.checksum b/LayoutTests/svg/custom/viewport-update2-expected.checksum
new file mode 100644 (file)
index 0000000..3a4f1f7
--- /dev/null
@@ -0,0 +1 @@
+16310588467cfc20d551635abc59b784
\ No newline at end of file
diff --git a/LayoutTests/svg/custom/viewport-update2-expected.png b/LayoutTests/svg/custom/viewport-update2-expected.png
new file mode 100644 (file)
index 0000000..3db2634
Binary files /dev/null and b/LayoutTests/svg/custom/viewport-update2-expected.png differ
diff --git a/LayoutTests/svg/custom/viewport-update2-expected.txt b/LayoutTests/svg/custom/viewport-update2-expected.txt
new file mode 100644 (file)
index 0000000..9ba83a1
--- /dev/null
@@ -0,0 +1,5 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+    KCanvasContainer {svg} at (-100,-100) size 300x300
+      KCanvasItem {rect} at (-100,-100) size 300x300 [fill={[type=SOLID] [color=#FF0000]}] [data="M-100.00,-100.00L200.00,-100.00L200.00,200.00L-100.00,200.00"]
+      KCanvasItem {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [data="M0.00,0.00L100.00,0.00L100.00,100.00L0.00,100.00"]
diff --git a/LayoutTests/svg/custom/viewport-update2.svg b/LayoutTests/svg/custom/viewport-update2.svg
new file mode 100644 (file)
index 0000000..81851cc
--- /dev/null
@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg" x="-100px" y="-100px" width="300px" height="300px">
+<script type="text/javascript">
+document.rootElement.x.baseVal.value = 0;
+document.rootElement.y.baseVal.value = 0;
+document.rootElement.width.baseVal.value = 100;
+document.rootElement.height.baseVal.value = 100;
+</script>
+<rect x="-100" y="-100" width="300" height="300" fill="red"/>
+<rect x="0" y="0" width="100" height="100" fill="green"/>
+</svg>
index 5608bbcd337aaa1c122cda2eaa637757cf377821..cee112c3c007021d7dfdc9b2f44c25770b42bfb1 100644 (file)
@@ -1,3 +1,28 @@
+2006-09-27  Rob Buis  <buis@kde.org>
+
+        Reviewed by eseidel.
+
+        http://bugzilla.opendarwin.org/show_bug.cgi?id=11015
+        SVG handles em units incorrectly
+
+        Calculate viewport coordinates at layout time, since
+        at this point the font size is known and lengths depending
+        on font sizes can be calculated correctly.
+
+        * kcanvas/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::layout):
+        (WebCore::RenderSVGContainer::viewport):
+        (WebCore::RenderSVGContainer::calcViewport):
+        * kcanvas/RenderSVGContainer.h:
+        * ksvg2/svg/SVGLength.cpp:
+        (WebCore::SVGLength::updateValue):
+        * ksvg2/svg/SVGMarkerElement.cpp:
+        (WebCore::SVGMarkerElement::createRenderer):
+        * ksvg2/svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::createRenderer):
+        (WebCore::SVGSVGElement::attributeChanged):
+        * ksvg2/svg/SVGSVGElement.h:
+
 2006-09-27  Eric Seidel  <eric@eseidel.com>
 
         Reviewed by darin.
index 6cbf52e12afec1a4aeb1c1be0b3020f30729e50e..86f1217c2f2b8a47314d02399f38da066638f6c0 100644 (file)
@@ -30,6 +30,9 @@
 #include "KRenderingDevice.h"
 #include "SVGStyledElement.h"
 #include "GraphicsContext.h"
+#include "SVGLength.h"
+#include "SVGMarkerElement.h"
+#include "SVGSVGElement.h"
 #include "SVGStyledTransformableElement.h"
 
 namespace WebCore {
@@ -99,6 +102,9 @@ void RenderSVGContainer::layout()
     ASSERT(needsLayout());
     ASSERT(minMaxKnown());
 
+    if (selfNeedsLayout())
+        calcViewport();
+
     IntRect oldBounds;
     bool checkForRepaint = checkForRepaintDuringLayout();
     if (selfNeedsLayout() && checkForRepaint)
@@ -200,14 +206,27 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int parentX, int parentY)
         paintInfo.p->restore();
 }
 
-void RenderSVGContainer::setViewport(const FloatRect& viewport)
+FloatRect RenderSVGContainer::viewport() const
 {
-    m_viewport = viewport;
+    return m_viewport;
 }
 
-FloatRect RenderSVGContainer::viewport() const
+void RenderSVGContainer::calcViewport()
 {
-   return m_viewport;
+    SVGElement* svgelem = static_cast<SVGElement*>(element());
+    if (svgelem->hasTagName(SVGNames::svgTag)) {
+        SVGSVGElement* svg = static_cast<SVGSVGElement*>(element());
+        double x = svg->x()->value();
+        double y = svg->y()->value();
+        double w = svg->width()->value();
+        double h = svg->height()->value();
+        m_viewport = FloatRect(x, y, w, h);
+    } else if (svgelem->hasTagName(SVGNames::markerTag)) {
+        SVGMarkerElement* svg = static_cast<SVGMarkerElement*>(element());
+            double w = svg->markerWidth()->value();
+        double h = svg->markerHeight()->value();
+        m_viewport = FloatRect(0, 0, w, h);
+    }
 }
 
 void RenderSVGContainer::setViewBox(const FloatRect& viewBox)
index a0af4a4da2ef7f07a675dcf3489dc4c3b079e216..ca04d634caecb1b073f38a1c675436f923f281dd 100644 (file)
@@ -43,6 +43,7 @@ enum KCAlign {
 };
 
 class KCanvasRenderingStyle;
+class SVGElement;
 
 class RenderSVGContainer : public RenderContainer
 {
@@ -81,8 +82,7 @@ public:
     
     virtual AffineTransform localTransform() const;
     void setLocalTransform(const AffineTransform&);
-    
-    void setViewport(const FloatRect&);
+   
     FloatRect viewport() const;
 
     void setViewBox(const FloatRect&);
@@ -97,6 +97,7 @@ public:
     AffineTransform viewportTransform() const;
     
 private:
+    void calcViewport(); 
     AffineTransform getAspectRatio(const FloatRect& logical, const FloatRect& physical) const;
 
     bool m_drawsContents : 1;
index 4d8d1da69adc6ebaa366fef3317d5f032c58217c..7365a238a128003bf65228aaad2dfef77a11893a 100644 (file)
@@ -208,8 +208,13 @@ void SVGLength::updateValue(bool notify)
             break;
         case SVG_LENGTHTYPE_EMS:
         case SVG_LENGTHTYPE_EXS:
-            if (m_context && m_context->renderer()) {
-                RenderStyle *style = m_context->renderer()->style();
+        {
+            RenderStyle *style = 0;
+            if (m_context && m_context->renderer())
+                style = m_context->renderer()->style();
+            else if (m_viewportElement && m_viewportElement->renderer())
+                style = m_viewportElement->renderer()->style();
+            if (style) {
                 float useSize = style->fontSize();
                 ASSERT(useSize > 0);
                 if (m_unitType == SVG_LENGTHTYPE_EMS)
@@ -225,6 +230,7 @@ void SVGLength::updateValue(bool notify)
                 m_requiresLayout = true;
             }
             break;
+        }
         case SVG_LENGTHTYPE_UNKNOWN:
         case SVG_LENGTHTYPE_NUMBER:
         case SVG_LENGTHTYPE_PERCENTAGE:
index 9214a094d4a79741445670e32cd948e346bd588e..876f67e54edba1bc688de6c0d203b731a137ae93 100644 (file)
@@ -140,7 +140,6 @@ KCanvasMarker *SVGMarkerElement::canvasResource()
 RenderObject* SVGMarkerElement::createRenderer(RenderArena* arena, RenderStyle* style)
 {
     RenderSVGContainer* markerContainer = new (arena) RenderSVGContainer(this);
-    markerContainer->setViewport(FloatRect(0, 0, markerWidth()->value(), markerHeight()->value()));
     markerContainer->setViewBox(viewBox());
     markerContainer->setAlign(KCAlign(preserveAspectRatio()->align() - 1));
     markerContainer->setSlice(preserveAspectRatio()->meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE);
index 260e90f4509ee78a5ae542ceafd2dd20dc113304..28e7b85c6784dd37f459b39f09c5a15b8a367ce4 100644 (file)
@@ -370,7 +370,6 @@ RenderObject* SVGSVGElement::createRenderer(RenderArena* arena, RenderStyle*)
     RenderSVGContainer* rootContainer = new (arena) RenderSVGContainer(this);
 
     // FIXME: all this setup should be done after attributesChanged, not here.
-    rootContainer->setViewport(FloatRect(x()->value(), y()->value(), width()->value(), height()->value()));
     rootContainer->setViewBox(viewBox());
     rootContainer->setAlign(KCAlign(preserveAspectRatio()->align() - 1));
     rootContainer->setSlice(preserveAspectRatio()->meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE);
@@ -423,6 +422,18 @@ void SVGSVGElement::setCurrentTime(float /* seconds */)
     // TODO
 }
 
+void SVGSVGElement::attributeChanged(Attribute* attr, bool preserveDecls)
+{
+    if (attr->name() == SVGNames::xAttr ||
+        attr->name() == SVGNames::yAttr ||
+        attr->name() == SVGNames::widthAttr ||
+        attr->name() == SVGNames::heightAttr)
+        if (renderer())
+            renderer()->setNeedsLayout(true);
+
+    SVGStyledElement::attributeChanged(attr, preserveDecls);
+}
+
 }
 
 // vim:ts=4:noet
index 706089c519cc6edcaa13762237b292f19bcf9eef..cf15bc306b671ba5c988ea599c6571fb3d0ad0d5 100644 (file)
@@ -129,6 +129,8 @@ namespace WebCore
         // 'virtual SVGZoomAndPan functions
         virtual void setZoomAndPan(unsigned short zoomAndPan);
 
+        virtual void attributeChanged(Attribute*, bool preserveDecls = false);
+
     protected:
         virtual const SVGElement* contextElement() const { return this; }