+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.
--- /dev/null
+8582cf4c7f667d677a8ce2bd274a4c8f
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+<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>
--- /dev/null
+16310588467cfc20d551635abc59b784
\ No newline at end of file
--- /dev/null
+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"]
--- /dev/null
+<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.
#include "KRenderingDevice.h"
#include "SVGStyledElement.h"
#include "GraphicsContext.h"
+#include "SVGLength.h"
+#include "SVGMarkerElement.h"
+#include "SVGSVGElement.h"
#include "SVGStyledTransformableElement.h"
namespace WebCore {
ASSERT(needsLayout());
ASSERT(minMaxKnown());
+ if (selfNeedsLayout())
+ calcViewport();
+
IntRect oldBounds;
bool checkForRepaint = checkForRepaintDuringLayout();
if (selfNeedsLayout() && checkForRepaint)
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)
};
class KCanvasRenderingStyle;
+class SVGElement;
class RenderSVGContainer : public RenderContainer
{
virtual AffineTransform localTransform() const;
void setLocalTransform(const AffineTransform&);
-
- void setViewport(const FloatRect&);
+
FloatRect viewport() const;
void setViewBox(const FloatRect&);
AffineTransform viewportTransform() const;
private:
+ void calcViewport();
AffineTransform getAspectRatio(const FloatRect& logical, const FloatRect& physical) const;
bool m_drawsContents : 1;
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)
m_requiresLayout = true;
}
break;
+ }
case SVG_LENGTHTYPE_UNKNOWN:
case SVG_LENGTHTYPE_NUMBER:
case SVG_LENGTHTYPE_PERCENTAGE:
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);
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);
// 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
// 'virtual SVGZoomAndPan functions
virtual void setZoomAndPan(unsigned short zoomAndPan);
+ virtual void attributeChanged(Attribute*, bool preserveDecls = false);
+
protected:
virtual const SVGElement* contextElement() const { return this; }