[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.21-584-g1e41756

zimmermann at webkit.org zimmermann at webkit.org
Fri Feb 26 22:21:25 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 2c8680150f3c70c081543a793786c2438e2583c1
Author: zimmermann at webkit.org <zimmermann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Feb 16 22:51:13 2010 +0000

    2010-02-16  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by David Hyatt.
    
            SVG units don't stay consistently sized on zoom
            https://bugs.webkit.org/show_bug.cgi?id=14004
    
            Large step towards making WebKit an usable SVG viewer.
    
            Make zooming into SVG documents work as expected, in both standalone and XHTML/SVG compound documents.
            SVG applies a global scale to the document, whereas CSS zooms all individual length units (on full-page-zoom).
            Scaling has to be avoided for all SVG specific CSS properties (already works) and for some selected CSS
            properties shared between CSS & SVG that explicitely need a different treatment in the context of SVG.
            To name a few: font-size, letter-spacing, etc. should stay invariant under zoom in SVG document fragments.
    
            Some new rules regarding zooming:
            - "Zoom text only" should never affect SVG documents, neither text nor content should zoom.
              This option doesn't make much sense for SVG, so it's wise to avoid side-effects and disable it.
              In compound documents the SVG would stay as-is and only text of surrounding XHTML content would zoom.
    
            - "Full page zoom" is the only zoom mode affecting SVG. (Panning only works in standalone documents.)
    
            Cover all mentioned cases above by a new set of layout tests.
    
            Tests: svg/zoom/page/absolute-sized-document-no-scrollbars.svg
                   svg/zoom/page/absolute-sized-document-scrollbars.svg
                   svg/zoom/page/relative-sized-document-scrollbars.svg
                   svg/zoom/page/zoom-coords-viewattr-01-b.svg
                   svg/zoom/page/zoom-foreignObject.svg
                   svg/zoom/page/zoom-hixie-mixed-008.xml
                   svg/zoom/page/zoom-hixie-mixed-009.xml
                   svg/zoom/page/zoom-hixie-rendering-model-004.xhtml
                   svg/zoom/page/zoom-svg-float-border-padding.xml
                   svg/zoom/text/absolute-sized-document-no-scrollbars.svg
                   svg/zoom/text/absolute-sized-document-scrollbars.svg
                   svg/zoom/text/relative-sized-document-scrollbars.svg
                   svg/zoom/text/zoom-coords-viewattr-01-b.svg
                   svg/zoom/text/zoom-foreignObject.svg
                   svg/zoom/text/zoom-hixie-mixed-008.xml
                   svg/zoom/text/zoom-hixie-mixed-009.xml
                   svg/zoom/text/zoom-hixie-rendering-model-004.xhtml
                   svg/zoom/text/zoom-svg-float-border-padding.xml
    
            * css/CSSStyleSelector.cpp: Blacklist certain properties not to be zoomed for SVG elements.
            (WebCore::CSSStyleSelector::styleForDocument): Don't zoom font-sizes.
            (WebCore::CSSStyleSelector::applyProperty): Ditto (+ letter/word-spacing).
            (WebCore::CSSStyleSelector::setFontSize): Ditto.
            (WebCore::CSSStyleSelector::getComputedSizeFromSpecifiedSize): Never apply text zoom to SVG.
            * css/CSSStyleSelector.h:
            * css/SVGCSSStyleSelector.cpp: -webkit-shadow + SVG was incorrectly respecting zoom factor.
            (WebCore::CSSStyleSelector::applySVGProperty):
            * page/Frame.cpp:
            (WebCore::Frame::shouldApplyTextZoom): Remove SVG special cases.
            (WebCore::Frame::shouldApplyPageZoom): Ditto.
            (WebCore::Frame::setZoomFactor): Don't force setZoomsTextOnly() - SVG now uses FPZ as well.
            * rendering/RenderSVGRoot.cpp:
            (WebCore::RenderSVGRoot::calcReplacedWidth): CSSPropertyWidth is explicitely not scaled by CSSStyleSelector, fix that for outermost <svg> elements.
            (WebCore::RenderSVGRoot::calcReplacedHeight): Ditto for CSSPropertyHeight.
            (WebCore::RenderSVGRoot::layout): Simplify & cleanup code, take advantage of new calcWidth/Height functionality, no need to scale anything here.
            (WebCore::RenderSVGRoot::paint): Use parentOriginToBorderBox() instead of duplicating code.
            (WebCore::RenderSVGRoot::calcViewport): Simplify code.
            (WebCore::RenderSVGRoot::localToBorderBoxTransform): Calculate viewBoxToViewTransformation() against unscaled width()/height() values.
            * rendering/RenderSVGRoot.h:
            * svg/SVGLength.cpp:
            (WebCore::SVGLength::PercentageOfViewport): Cleanup & document function.
            * svg/SVGSVGElement.cpp:
            (WebCore::SVGSVGElement::currentScale): Return pageZoomFactor(), not just the zoomFactor() - as we want to ignore text-only zoom.
            (WebCore::SVGSVGElement::setCurrentScale): Pass isTextOnly=false to setZoomFactor().
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54834 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b91d2de..83d5374 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,72 @@
+2010-02-16  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by David Hyatt.
+
+        SVG units don't stay consistently sized on zoom
+        https://bugs.webkit.org/show_bug.cgi?id=14004
+
+        Large step towards making WebKit an usable SVG viewer.
+
+        Make zooming into SVG documents work as expected, in both standalone and XHTML/SVG compound documents.
+        SVG applies a global scale to the document, whereas CSS zooms all individual length units (on full-page-zoom).
+        Scaling has to be avoided for all SVG specific CSS properties (already works) and for some selected CSS
+        properties shared between CSS & SVG that explicitely need a different treatment in the context of SVG.
+        To name a few: font-size, letter-spacing, etc. should stay invariant under zoom in SVG document fragments.
+
+        Some new rules regarding zooming:
+        - "Zoom text only" should never affect SVG documents, neither text nor content should zoom.
+          This option doesn't make much sense for SVG, so it's wise to avoid side-effects and disable it.
+          In compound documents the SVG would stay as-is and only text of surrounding XHTML content would zoom.
+
+        - "Full page zoom" is the only zoom mode affecting SVG. (Panning only works in standalone documents.)
+
+        Cover all mentioned cases above by a new set of layout tests.
+
+        Tests: svg/zoom/page/absolute-sized-document-no-scrollbars.svg
+               svg/zoom/page/absolute-sized-document-scrollbars.svg
+               svg/zoom/page/relative-sized-document-scrollbars.svg
+               svg/zoom/page/zoom-coords-viewattr-01-b.svg
+               svg/zoom/page/zoom-foreignObject.svg
+               svg/zoom/page/zoom-hixie-mixed-008.xml
+               svg/zoom/page/zoom-hixie-mixed-009.xml
+               svg/zoom/page/zoom-hixie-rendering-model-004.xhtml
+               svg/zoom/page/zoom-svg-float-border-padding.xml
+               svg/zoom/text/absolute-sized-document-no-scrollbars.svg
+               svg/zoom/text/absolute-sized-document-scrollbars.svg
+               svg/zoom/text/relative-sized-document-scrollbars.svg
+               svg/zoom/text/zoom-coords-viewattr-01-b.svg
+               svg/zoom/text/zoom-foreignObject.svg
+               svg/zoom/text/zoom-hixie-mixed-008.xml
+               svg/zoom/text/zoom-hixie-mixed-009.xml
+               svg/zoom/text/zoom-hixie-rendering-model-004.xhtml
+               svg/zoom/text/zoom-svg-float-border-padding.xml
+
+        * css/CSSStyleSelector.cpp: Blacklist certain properties not to be zoomed for SVG elements.
+        (WebCore::CSSStyleSelector::styleForDocument): Don't zoom font-sizes.
+        (WebCore::CSSStyleSelector::applyProperty): Ditto (+ letter/word-spacing).
+        (WebCore::CSSStyleSelector::setFontSize): Ditto.
+        (WebCore::CSSStyleSelector::getComputedSizeFromSpecifiedSize): Never apply text zoom to SVG.
+        * css/CSSStyleSelector.h:
+        * css/SVGCSSStyleSelector.cpp: -webkit-shadow + SVG was incorrectly respecting zoom factor.
+        (WebCore::CSSStyleSelector::applySVGProperty):
+        * page/Frame.cpp:
+        (WebCore::Frame::shouldApplyTextZoom): Remove SVG special cases.
+        (WebCore::Frame::shouldApplyPageZoom): Ditto.
+        (WebCore::Frame::setZoomFactor): Don't force setZoomsTextOnly() - SVG now uses FPZ as well.
+        * rendering/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::calcReplacedWidth): CSSPropertyWidth is explicitely not scaled by CSSStyleSelector, fix that for outermost <svg> elements.
+        (WebCore::RenderSVGRoot::calcReplacedHeight): Ditto for CSSPropertyHeight.
+        (WebCore::RenderSVGRoot::layout): Simplify & cleanup code, take advantage of new calcWidth/Height functionality, no need to scale anything here.
+        (WebCore::RenderSVGRoot::paint): Use parentOriginToBorderBox() instead of duplicating code.
+        (WebCore::RenderSVGRoot::calcViewport): Simplify code.
+        (WebCore::RenderSVGRoot::localToBorderBoxTransform): Calculate viewBoxToViewTransformation() against unscaled width()/height() values.
+        * rendering/RenderSVGRoot.h:
+        * svg/SVGLength.cpp:
+        (WebCore::SVGLength::PercentageOfViewport): Cleanup & document function.
+        * svg/SVGSVGElement.cpp:
+        (WebCore::SVGSVGElement::currentScale): Return pageZoomFactor(), not just the zoomFactor() - as we want to ignore text-only zoom.
+        (WebCore::SVGSVGElement::setCurrentScale): Pass isTextOnly=false to setZoomFactor().
+
 2010-02-16  Julie Parent  <jparent at chromium.org>
 
         Unreviewed: Chromium build fix.
diff --git a/WebCore/css/CSSStyleSelector.cpp b/WebCore/css/CSSStyleSelector.cpp
index aeed8ad..124eb9f 100644
--- a/WebCore/css/CSSStyleSelector.cpp
+++ b/WebCore/css/CSSStyleSelector.cpp
@@ -1119,7 +1119,8 @@ PassRefPtr<RenderStyle> CSSStyleSelector::styleForDocument(Document* document)
         fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
         int size = CSSStyleSelector::fontSizeForKeyword(document, CSSValueMedium, false);
         fontDescription.setSpecifiedSize(size);
-        fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, fontDescription.isAbsoluteSize(), size, documentStyle->effectiveZoom()));
+        bool useSVGZoomRules = document->isSVGDocument();
+        fontDescription.setComputedSize(CSSStyleSelector::getComputedSizeFromSpecifiedSize(document, documentStyle.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules));
     }
 
     documentStyle->setFontDescription(fontDescription);
@@ -2983,6 +2984,16 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
 
     float zoomFactor = m_style->effectiveZoom();
 
+    // SVG handles zooming in a different way compared to CSS. The whole document is scaled instead
+    // of each individual length value in the render style / tree. CSSPrimitiveValue::computeLength*()
+    // multiplies each resolved length with the zoom multiplier - so for SVG we need to disable that.
+    // Though all CSS values that can be applied to outermost <svg> elements (width/height/border/padding...)
+    // need to respect the scaling. RenderBox (the parent class of RenderSVGRoot) grabs values like
+    // width/height/border/padding/... from the RenderStyle -> for SVG these values would never scale,
+    // if we'd pass a 1.0 zoom factor everyhwere. So we only pass a zoom factor of 1.0 for specific
+    // properties that are NOT allowed to scale within a zoomed SVG document (letter/word-spacing/font-size).
+    bool useSVGZoomRules = m_element && m_element->isSVGElement();
+
     Length l;
     bool apply = false;
 
@@ -3624,7 +3635,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
         } else {
             if (!primitiveValue)
                 return;
-            width = primitiveValue->computeLengthInt(style(), m_rootElementStyle, zoomFactor);
+            width = primitiveValue->computeLengthInt(style(), m_rootElementStyle, useSVGZoomRules ? 1.0f : zoomFactor);
         }
         switch (id) {
         case CSSPropertyLetterSpacing:
@@ -4034,7 +4045,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
         if (primitiveValue->getIdent() == CSSValueNormal)
             lineHeight = Length(-100.0, Percent);
         else if (CSSPrimitiveValue::isUnitTypeLength(type)) {
-            double multiplier = m_style->effectiveZoom();
+            double multiplier = zoomFactor;
             if (m_style->textSizeAdjust() && m_checker.m_document->frame() && m_checker.m_document->frame()->shouldApplyTextZoom())
                 multiplier *= m_checker.m_document->frame()->textZoomFactor();
             lineHeight = Length(primitiveValue->computeLengthIntForLength(style(), m_rootElementStyle,  multiplier), Fixed);
@@ -4516,7 +4527,7 @@ void CSSStyleSelector::applyProperty(int id, CSSValue *value)
                 fontDescription.setUsePrinterFont(m_checker.m_document->printing());
            
                 // Handle the zoom factor.
-                fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(m_checker.m_document, fontDescription.isAbsoluteSize(), fontDescription.specifiedSize(), m_style->effectiveZoom()));
+                fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(m_checker.m_document, m_style.get(), fontDescription.isAbsoluteSize(), fontDescription.specifiedSize(), useSVGZoomRules));
                 if (m_style->setFontDescription(fontDescription))
                     m_fontDirty = true;
             }
@@ -5857,11 +5868,20 @@ void CSSStyleSelector::checkForGenericFamilyChange(RenderStyle* style, RenderSty
 void CSSStyleSelector::setFontSize(FontDescription& fontDescription, float size)
 {
     fontDescription.setSpecifiedSize(size);
-    fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(m_checker.m_document, fontDescription.isAbsoluteSize(), size, m_style->effectiveZoom()));
+
+    bool useSVGZoomRules = m_element && m_element->isSVGElement();
+    fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(m_checker.m_document, m_style.get(), fontDescription.isAbsoluteSize(), size, useSVGZoomRules)); 
 }
 
-float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, bool isAbsoluteSize, float specifiedSize, float zoomFactor)
+float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, RenderStyle* style, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules)
 {
+    float zoomFactor = 1.0f;
+    if (!useSVGZoomRules) {
+        zoomFactor = style->effectiveZoom();
+        if (document->frame() && document->frame()->shouldApplyTextZoom())
+            zoomFactor *= document->frame()->textZoomFactor();
+    }
+
     // We support two types of minimum font size.  The first is a hard override that applies to
     // all fonts.  This is "minSize."  The second type of minimum font size is a "smart minimum"
     // that is applied only when the Web page can't know what size it really asked for, e.g.,
@@ -5878,10 +5898,6 @@ float CSSStyleSelector::getComputedSizeFromSpecifiedSize(Document* document, boo
 
     int minSize = settings->minimumFontSize();
     int minLogicalSize = settings->minimumLogicalFontSize();
-
-    if (document->frame() && document->frame()->shouldApplyTextZoom())
-        zoomFactor *= document->frame()->textZoomFactor();
-
     float zoomedSize = specifiedSize * zoomFactor;
 
     // Apply the hard minimum first.  We only apply the hard minimum if after zooming we're still too small.
diff --git a/WebCore/css/CSSStyleSelector.h b/WebCore/css/CSSStyleSelector.h
index aac1bae..644051c 100644
--- a/WebCore/css/CSSStyleSelector.h
+++ b/WebCore/css/CSSStyleSelector.h
@@ -131,7 +131,7 @@ public:
         void applyPropertyToStyle(int id, CSSValue*, RenderStyle*);
 
     private:
-        static float getComputedSizeFromSpecifiedSize(Document*, bool isAbsoluteSize, float specifiedSize, float zoomFactor = 1.0f);
+        static float getComputedSizeFromSpecifiedSize(Document*, RenderStyle*, bool isAbsoluteSize, float specifiedSize, bool useSVGZoomRules);
 
     public:
         Color getColorFromPrimitiveValue(CSSPrimitiveValue*);
diff --git a/WebCore/css/SVGCSSStyleSelector.cpp b/WebCore/css/SVGCSSStyleSelector.cpp
index 5ba7344..5651a0a 100644
--- a/WebCore/css/SVGCSSStyleSelector.cpp
+++ b/WebCore/css/SVGCSSStyleSelector.cpp
@@ -534,14 +534,12 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
             if (!value->isValueList())
                 return;
 
-            float zoomFactor = m_style->effectiveZoom();
-
             CSSValueList *list = static_cast<CSSValueList*>(value);
             ASSERT(list->length() == 1);
             ShadowValue* item = static_cast<ShadowValue*>(list->itemWithoutBoundsCheck(0));
-            int x = item->x->computeLengthInt(style(), m_rootElementStyle, zoomFactor);
-            int y = item->y->computeLengthInt(style(), m_rootElementStyle, zoomFactor);
-            int blur = item->blur ? item->blur->computeLengthInt(style(), m_rootElementStyle, zoomFactor) : 0;
+            int x = item->x->computeLengthInt(style(), m_rootElementStyle);
+            int y = item->y->computeLengthInt(style(), m_rootElementStyle);
+            int blur = item->blur ? item->blur->computeLengthInt(style(), m_rootElementStyle) : 0;
             Color color;
             if (item->color)
                 color = getColorFromPrimitiveValue(item->color.get());
@@ -564,5 +562,4 @@ void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
 
 }
 
-// vim:ts=4:noet
-#endif // ENABLE(SVG)
+#endif
diff --git a/WebCore/page/Frame.cpp b/WebCore/page/Frame.cpp
index e2f421b..f485ad6 100644
--- a/WebCore/page/Frame.cpp
+++ b/WebCore/page/Frame.cpp
@@ -670,10 +670,6 @@ bool Frame::shouldApplyTextZoom() const
 {
     if (m_zoomFactor == 1.0f || !isZoomFactorTextOnly())
         return false;
-#if ENABLE(SVG)
-    if (m_doc->isSVGDocument())
-        return false;
-#endif
     return true;
 }
 
@@ -681,10 +677,6 @@ bool Frame::shouldApplyPageZoom() const
 {
     if (m_zoomFactor == 1.0f || isZoomFactorTextOnly())
         return false;
-#if ENABLE(SVG)
-    if (m_doc->isSVGDocument())
-        return false;
-#endif
     return true;
 }
 
@@ -694,16 +686,13 @@ void Frame::setZoomFactor(float percent, bool isTextOnly)
         return;
 
 #if ENABLE(SVG)
-    // SVG doesn't care if the zoom factor is text only.  It will always apply a
-    // zoom to the whole SVG.
+    // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
+    // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
     if (m_doc->isSVGDocument()) {
         if (!static_cast<SVGDocument*>(m_doc.get())->zoomAndPanEnabled())
             return;
-        m_zoomFactor = percent;
-        m_page->settings()->setZoomsTextOnly(true); // We do this to avoid doing any scaling of CSS pixels, since the SVG has its own notion of zoom.
         if (m_doc->renderer())
-            m_doc->renderer()->repaint();
-        return;
+            m_doc->renderer()->setNeedsLayout(true);
     }
 #endif
 
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 74172fc..7c14c10 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -77,6 +77,28 @@ void RenderSVGRoot::calcPrefWidths()
     setPrefWidthsDirty(false);
 }
 
+int RenderSVGRoot::calcReplacedWidth(bool includeMaxWidth) const
+{
+    int replacedWidth = RenderBox::calcReplacedWidth(includeMaxWidth);
+    if (!style()->width().isPercent())
+        return replacedWidth;
+
+    // FIXME: Investigate in size rounding issues
+    SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+    return static_cast<int>(roundf(replacedWidth * svg->currentScale()));
+}
+
+int RenderSVGRoot::calcReplacedHeight() const
+{
+    int replacedHeight = RenderBox::calcReplacedHeight();
+    if (!style()->height().isPercent())
+        return replacedHeight;
+
+    // FIXME: Investigate in size rounding issues
+    SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+    return static_cast<int>(roundf(replacedHeight * svg->currentScale()));
+}
+
 void RenderSVGRoot::layout()
 {
     ASSERT(needsLayout());
@@ -84,22 +106,19 @@ void RenderSVGRoot::layout()
     // Arbitrary affine transforms are incompatible with LayoutState.
     view()->disableLayoutState();
 
-    LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout());
+    bool needsLayout = selfNeedsLayout();
+    LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && needsLayout);
 
-    int oldWidth = width();
+    IntSize oldSize(width(), height());
     calcWidth();
-
-    int oldHeight = height();
     calcHeight();
 
-    SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
-    setWidth(static_cast<int>(width() * svg->currentScale()));
-    setHeight(static_cast<int>(height() * svg->currentScale()));
     calcViewport();
 
     // RenderSVGRoot needs to take special care to propagate window size changes to the children,
     // if the outermost <svg> is using relative x/y/width/height values. Hence the additonal parameters.
-    layoutChildren(this, selfNeedsLayout() || (svg->hasRelativeValues() && (width() != oldWidth || height() != oldHeight)));
+    SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+    layoutChildren(this, needsLayout || (svg->hasRelativeValues() && oldSize != size()));
     repainter.repaintAfterLayout();
 
     view()->enableLayoutState();
@@ -123,7 +142,7 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
         return;
 
     IntPoint parentOriginInContainer(parentX, parentY);
-    IntPoint borderBoxOriginInContainer = parentOriginInContainer + IntSize(x(), y());
+    IntPoint borderBoxOriginInContainer = parentOriginInContainer + parentOriginToBorderBox();
 
     if (hasBoxDecorations() && (paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection)) 
         paintBoxDecorations(paintInfo, borderBoxOriginInContainer.x(), borderBoxOriginInContainer.y());
@@ -177,15 +196,16 @@ void RenderSVGRoot::calcViewport()
         // In the normal case of <svg> being stand-alone or in a CSSBoxModel object we use
         // RenderBox::width()/height() (which pulls data from RenderStyle)
         m_viewportSize = FloatSize(width(), height());
-    } else {
-        // In the SVGImage case grab the SVGLength values off of SVGSVGElement and use
-        // the special relativeWidthValue accessors which respect the specified containerSize
-        SVGLength width = svg->width();
-        SVGLength height = svg->height();
-        float viewportWidth = (width.unitType() == LengthTypePercentage) ? svg->relativeWidthValue() : width.value(svg);
-        float viewportHeight = (height.unitType() == LengthTypePercentage) ? svg->relativeHeightValue() : height.value(svg);
-        m_viewportSize = FloatSize(viewportWidth, viewportHeight);
+        return;
     }
+
+    // In the SVGImage case grab the SVGLength values off of SVGSVGElement and use
+    // the special relativeWidthValue accessors which respect the specified containerSize
+    // FIXME: Check how SVGImage + zooming is supposed to be handled?
+    SVGLength width = svg->width();
+    SVGLength height = svg->height();
+    m_viewportSize = FloatSize(width.unitType() == LengthTypePercentage ? svg->relativeWidthValue() : width.value(svg),
+                               height.unitType() == LengthTypePercentage ? svg->relativeHeightValue() : height.value(svg));
 }
 
 // RenderBox methods will expect coordinates w/o any transforms in coordinates
@@ -195,9 +215,9 @@ AffineTransform RenderSVGRoot::localToBorderBoxTransform() const
     IntSize borderAndPadding = borderOriginToContentBox();
     SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
     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;
+    FloatPoint translate = svg->currentTranslate();
+    AffineTransform ctm(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y());
+    return svg->viewBoxToViewTransform(width() / scale, height() / scale) * ctm;
 }
 
 IntSize RenderSVGRoot::parentOriginToBorderBox() const
diff --git a/WebCore/rendering/RenderSVGRoot.h b/WebCore/rendering/RenderSVGRoot.h
index 8ad5e40..da231ac 100644
--- a/WebCore/rendering/RenderSVGRoot.h
+++ b/WebCore/rendering/RenderSVGRoot.h
@@ -50,7 +50,8 @@ private:
     virtual int lineHeight(bool b, bool isRootLineBox = false) const;
     virtual int baselinePosition(bool b, bool isRootLineBox = false) const;
     virtual void calcPrefWidths();
-
+    virtual int calcReplacedWidth(bool includeMaxWidth = true) const;
+    virtual int calcReplacedHeight() const;
     virtual void layout();
     virtual void paint(PaintInfo&, int parentX, int parentY);
 
diff --git a/WebCore/svg/SVGLength.cpp b/WebCore/svg/SVGLength.cpp
index 2884507..e342acf 100644
--- a/WebCore/svg/SVGLength.cpp
+++ b/WebCore/svg/SVGLength.cpp
@@ -280,15 +280,16 @@ float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SV
     float width = 0.0f, height = 0.0f;
     SVGElement* viewportElement = context->viewportElement();
 
+    // PercentageOfViewport() is used to resolve all relative-positioned values within a SVG document (fragment)
     Document* doc = context->document();
     if (doc->documentElement() == context) {
-        // We have to ask the canvas for the full "canvas size"...
-        RenderView* view = toRenderView(doc->renderer());
-        if (view && view->frameView()) {
-            width = view->frameView()->visibleWidth(); // TODO: recheck!
-            height = view->frameView()->visibleHeight(); // TODO: recheck!
+        // Resolve value against outermost <svg> element
+        if (RenderView* view = toRenderView(doc->renderer())) {
+            width = view->viewWidth();
+            height = view->viewHeight();
          }
     } else if (viewportElement && viewportElement->isSVG()) {
+        // Resolve value against nearest viewport element (common case: inner <svg> elements)
         const SVGSVGElement* svg = static_cast<const SVGSVGElement*>(viewportElement);
         if (svg->hasAttribute(SVGNames::viewBoxAttr)) {
             width = svg->viewBox().width();
@@ -298,6 +299,7 @@ float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SV
             height = svg->height().value(svg);
         }
     } else if (context->parent() && !context->parent()->isSVGElement()) {
+        // Resolve value against enclosing non-SVG RenderBox
         if (RenderObject* renderer = context->renderer()) {
             if (renderer->isBox()) {
                 RenderBox* box = toRenderBox(renderer);
@@ -319,6 +321,4 @@ float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SV
 
 }
 
-#endif // ENABLE(SVG)
-
-// vim:ts=4:noet
+#endif
diff --git a/WebCore/svg/SVGSVGElement.cpp b/WebCore/svg/SVGSVGElement.cpp
index cfe1615..ff24c4f 100644
--- a/WebCore/svg/SVGSVGElement.cpp
+++ b/WebCore/svg/SVGSVGElement.cpp
@@ -187,16 +187,19 @@ SVGViewSpec* SVGSVGElement::currentView() const
 
 float SVGSVGElement::currentScale() const
 {
-    if (document() && parentNode() == document())
-        return document()->frame() ? document()->frame()->zoomFactor() : 1;
+    // Only the page zoom factor is relevant for SVG
+    if (Frame* frame = document()->frame())
+        return frame->pageZoomFactor();
     return m_scale;
 }
 
 void SVGSVGElement::setCurrentScale(float scale)
 {
-    if (document() && parentNode() == document()) {
-        if (document()->frame())
-            document()->frame()->setZoomFactor(scale, true);
+    if (Frame* frame = document()->frame()) {
+        // Calling setCurrentScale() on the outermost <svg> element in a standalone SVG document
+        // is allowed to change the page zoom factor, influencing the document size, scrollbars etc.
+        if (parentNode() == document())
+            frame->setZoomFactor(scale, false);
         return;
     }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list