Commit 54820aa2 authored by rwlbuis's avatar rwlbuis
Browse files

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.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@16601 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0c29eca6
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.
8582cf4c7f667d677a8ce2bd274a4c8f
\ No newline at end of file
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
<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>
16310588467cfc20d551635abc59b784
\ No newline at end of file
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"]
<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>
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.
......@@ -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)
......
......@@ -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;
......
......@@ -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:
......
......@@ -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);
......
......@@ -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
......
......@@ -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; }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment