diff options
Diffstat (limited to 'WebCore/svg')
343 files changed, 9434 insertions, 8548 deletions
diff --git a/WebCore/svg/ElementTimeControl.h b/WebCore/svg/ElementTimeControl.h new file mode 100644 index 0000000..4c185b9 --- /dev/null +++ b/WebCore/svg/ElementTimeControl.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ElementTimeControl_h +#define ElementTimeControl_h + +#if ENABLE(SVG) + +#include "ExceptionCode.h" + +namespace WebCore { + + class ElementTimeControl { + public: + virtual ~ElementTimeControl() {} + virtual bool beginElement(ExceptionCode&) = 0; + virtual bool beginElementAt(float offset, ExceptionCode&) = 0; + virtual bool endElement(ExceptionCode&) = 0; + virtual bool endElementAt(float offset, ExceptionCode&) = 0; + }; + +} + +#endif + +#endif diff --git a/WebCore/svg/ElementTimeControl.idl b/WebCore/svg/ElementTimeControl.idl new file mode 100644 index 0000000..569fefa --- /dev/null +++ b/WebCore/svg/ElementTimeControl.idl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module svg { + + interface [Conditional=SVG, ObjCProtocol] ElementTimeControl { + boolean beginElement() + raises(DOMException); + boolean beginElementAt(in float offset) + raises(DOMException); + boolean endElement() + raises(DOMException); + boolean endElementAt(in float offset) + raises(DOMException); + }; + +} diff --git a/WebCore/svg/Filter.cpp b/WebCore/svg/Filter.cpp new file mode 100644 index 0000000..24a9fb8 --- /dev/null +++ b/WebCore/svg/Filter.cpp @@ -0,0 +1,39 @@ +/* + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#if ENABLE(SVG) && ENABLE(SVG_FILTERS) +#include "Filter.h" + +namespace WebCore { + +Filter::Filter(FilterEffect* effect) + : m_effect(effect) +{ +} + +PassRefPtr<Filter> Filter::create(FilterEffect* effect) +{ + return adoptRef(new Filter(effect)); +} + +} //namespace WebCore + +#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/Filter.h b/WebCore/svg/Filter.h new file mode 100644 index 0000000..f3a110e --- /dev/null +++ b/WebCore/svg/Filter.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef Filter_h +#define Filter_h + +#include "config.h" + +#if ENABLE(SVG) && ENABLE(SVG_FILTERS) +#include "FilterEffect.h" + +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + + class Filter : public RefCounted<Filter> { + public: + static PassRefPtr<Filter> create(FilterEffect*); + + private: + Filter(FilterEffect* effect); + + RefPtr<FilterEffect> m_effect; + }; + +} //namespace WebCore + +#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) +#endif diff --git a/WebCore/svg/FilterBuilder.h b/WebCore/svg/FilterBuilder.h new file mode 100644 index 0000000..630537c --- /dev/null +++ b/WebCore/svg/FilterBuilder.h @@ -0,0 +1,51 @@ +/* + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef FilterBuilder_h +#define FilterBuilder_h + +#include "config.h" + +#if ENABLE(SVG) && ENABLE(SVG_FILTERS) +#include "PlatformString.h" +#include "FilterEffect.h" +#include "Filter.h" + +#include <wtf/HashMap.h> +#include <wtf/PassRefPtr.h> + +namespace WebCore { + + class FilterBuilder : public RefCounted<FilterBuilder> { + public: + void add(const String& id, PassRefPtr<FilterEffect> effect) { m_namedEffects.set(id.impl(), effect); } + FilterEffect* getEffectById(const String& id) const { return m_namedEffects.get(id.impl()).get(); } + + PassRefPtr<Filter> filter() const { return m_filter; } + + private: + HashMap<StringImpl*, RefPtr<FilterEffect> > m_namedEffects; + + RefPtr<Filter> m_filter; + }; + +} //namespace WebCore + +#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) +#endif diff --git a/WebCore/svg/graphics/filters/cg/SVGFETileCg.mm b/WebCore/svg/FilterEffect.cpp index dea9854..24c187c 100644 --- a/WebCore/svg/graphics/filters/cg/SVGFETileCg.mm +++ b/WebCore/svg/FilterEffect.cpp @@ -1,7 +1,5 @@ /* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project + Copyright (C) Alex Mathews <possessedpenguinbob@gmail.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -22,20 +20,23 @@ #include "config.h" #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFETile.h" -#include "SVGFEHelpersCg.h" +#include "FilterEffect.h" namespace WebCore { -CIFilter* SVGFETile::getCIFilter(const FloatRect& bbox) const +FilterEffect::FilterEffect() { - SVGResourceFilter* svgFilter = filter(); - FE_QUARTZ_SETUP_INPUT(@"CIAffineTile"); +} - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; +FilterEffect::~FilterEffect() +{ } +TextStream& FilterEffect::externalRepresentation(TextStream& ts) const +{ + return ts; } +} // namespace WebCore + #endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFEGaussianBlurCg.mm b/WebCore/svg/FilterEffect.h index 13140b6..8f53ae1 100644 --- a/WebCore/svg/graphics/filters/cg/SVGFEGaussianBlurCg.mm +++ b/WebCore/svg/FilterEffect.h @@ -1,7 +1,5 @@ /* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -19,31 +17,32 @@ Boston, MA 02110-1301, USA. */ -#include "config.h" +#ifndef FilterEffect_h +#define FilterEffect_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEGaussianBlur.h" -#include "SVGFEHelpersCg.h" - -namespace WebCore { +#include "TextStream.h" -CIFilter* SVGFEGaussianBlur::getCIFilter(const FloatRect& bbox) const -{ - SVGResourceFilter* svgFilter = filter(); - FE_QUARTZ_SETUP_INPUT(@"CIGaussianPyramid"); +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> - float inputRadius = stdDeviationX(); - if (inputRadius != stdDeviationY()) { - float inputAspectRatio = stdDeviationX()/stdDeviationY(); - // FIXME: inputAspectRatio only support the range .5 to 2.0! - [filter setValue:[NSNumber numberWithFloat:inputAspectRatio] forKey:@"inputAspectRatio"]; - } - [filter setValue:[NSNumber numberWithFloat:inputRadius] forKey:@"inputRadius"]; +namespace WebCore { - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} + class FilterEffect : public RefCounted<FilterEffect> { + public: + virtual ~FilterEffect(); + + virtual void apply() = 0; + virtual void dump() = 0; + + virtual TextStream& externalRepresentation(TextStream&) const; + protected: + FilterEffect(); + }; -} +} // namespace WebCore #endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) + +#endif // FilterEffect_h diff --git a/WebCore/svg/GradientAttributes.h b/WebCore/svg/GradientAttributes.h index c16e961..a5f0f37 100644 --- a/WebCore/svg/GradientAttributes.h +++ b/WebCore/svg/GradientAttributes.h @@ -28,7 +28,7 @@ namespace WebCore { struct GradientAttributes { GradientAttributes() - : m_spreadMethod(SPREADMETHOD_PAD) + : m_spreadMethod(SpreadMethodPad) , m_boundingBoxMode(true) , m_spreadMethodSet(false) , m_boundingBoxModeSet(false) @@ -37,12 +37,12 @@ namespace WebCore { } - SVGGradientSpreadMethod spreadMethod() const { return m_spreadMethod; } + GradientSpreadMethod spreadMethod() const { return m_spreadMethod; } bool boundingBoxMode() const { return m_boundingBoxMode; } AffineTransform gradientTransform() const { return m_gradientTransform; } const Vector<SVGGradientStop>& stops() const { return m_stops; } - void setSpreadMethod(SVGGradientSpreadMethod value) { m_spreadMethod = value; m_spreadMethodSet = true; } + void setSpreadMethod(GradientSpreadMethod value) { m_spreadMethod = value; m_spreadMethodSet = true; } void setBoundingBoxMode(bool value) { m_boundingBoxMode = value; m_boundingBoxModeSet = true; } void setGradientTransform(const AffineTransform& value) { m_gradientTransform = value; m_gradientTransformSet = true; } void setStops(const Vector<SVGGradientStop>& value) { m_stops = value; m_stopsSet = true; } @@ -54,7 +54,7 @@ namespace WebCore private: // Properties - SVGGradientSpreadMethod m_spreadMethod; + GradientSpreadMethod m_spreadMethod; bool m_boundingBoxMode; AffineTransform m_gradientTransform; Vector<SVGGradientStop> m_stops; diff --git a/WebCore/svg/SVGAElement.cpp b/WebCore/svg/SVGAElement.cpp index e050475..9236af4 100644 --- a/WebCore/svg/SVGAElement.cpp +++ b/WebCore/svg/SVGAElement.cpp @@ -39,19 +39,19 @@ #include "RenderSVGTransformableContainer.h" #include "RenderSVGInline.h" #include "ResourceRequest.h" +#include "SVGSMILElement.h" #include "SVGNames.h" #include "XLinkNames.h" namespace WebCore { -using namespace EventNames; - SVGAElement::SVGAElement(const QualifiedName& tagName, Document *doc) : SVGStyledTransformableElement(tagName, doc) , SVGURIReference() , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() + , m_target(this, SVGNames::targetAttr) { } @@ -64,8 +64,6 @@ String SVGAElement::title() const return getAttribute(XLinkNames::titleAttr); } -ANIMATED_PROPERTY_DEFINITIONS(SVGAElement, String, String, string, Target, target, SVGNames::targetAttr, m_target) - void SVGAElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::targetAttr) @@ -90,10 +88,10 @@ void SVGAElement::svgAttributeChanged(const QualifiedName& attrName) // Unlike other SVG*Element classes, SVGAElement only listens to SVGURIReference changes // as none of the other properties changes the linking behaviour for our <a> element. if (SVGURIReference::isKnownAttribute(attrName)) { - bool wasLink = m_isLink; - m_isLink = !href().isNull(); + bool wasLink = isLink(); + setIsLink(!href().isNull()); - if (wasLink != m_isLink) + if (wasLink != isLink()) setChanged(); } } @@ -108,13 +106,13 @@ RenderObject* SVGAElement::createRenderer(RenderArena* arena, RenderStyle* style void SVGAElement::defaultEventHandler(Event* evt) { - if (m_isLink && (evt->type() == clickEvent || (evt->type() == keydownEvent && m_focused))) { + if (isLink() && (evt->type() == eventNames().clickEvent || (evt->type() == eventNames().keydownEvent && focused()))) { MouseEvent* e = 0; - if (evt->type() == clickEvent && evt->isMouseEvent()) + if (evt->type() == eventNames().clickEvent && evt->isMouseEvent()) e = static_cast<MouseEvent*>(evt); KeyboardEvent* k = 0; - if (evt->type() == keydownEvent && evt->isKeyboardEvent()) + if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent()) k = static_cast<KeyboardEvent*>(evt); if (e && e->button() == RightButton) { @@ -138,10 +136,23 @@ void SVGAElement::defaultEventHandler(Event* evt) else if (target.isEmpty()) // if target is empty, default to "_self" or use xlink:target if set target = (getAttribute(XLinkNames::showAttr) == "new") ? "_blank" : "_self"; - String url = parseURL(href()); - if (!evt->defaultPrevented()) + if (!evt->defaultPrevented()) { + String url = parseURL(href()); +#if ENABLE(SVG_ANIMATION) + if (url.startsWith("#")) { + Element* targetElement = document()->getElementById(url.substring(1)); + if (SVGSMILElement::isSMILElement(targetElement)) { + SVGSMILElement* timed = static_cast<SVGSMILElement*>(targetElement); + timed->beginByLinkActivation(); + evt->setDefaultHandled(); + SVGStyledTransformableElement::defaultEventHandler(evt); + return; + } + } +#endif if (document()->frame()) document()->frame()->loader()->urlSelected(document()->completeURL(url), target, evt, false, true); + } evt->setDefaultHandled(); } @@ -187,8 +198,12 @@ bool SVGAElement::isKeyboardFocusable(KeyboardEvent* event) const bool SVGAElement::childShouldCreateRenderer(Node* child) const { - if (static_cast<SVGElement*>(parent())->isTextContent()) - return child->isTextNode(); + // http://www.w3.org/2003/01/REC-SVG11-20030114-errata#linking-text-environment + // The 'a' element may contain any element that its parent may contain, except itself. + if (child->hasTagName(SVGNames::aTag)) + return false; + if (parent() && parent()->isSVGElement()) + return static_cast<SVGElement*>(parent())->childShouldCreateRenderer(child); return SVGElement::childShouldCreateRenderer(child); } diff --git a/WebCore/svg/SVGAElement.h b/WebCore/svg/SVGAElement.h index a1509fd..8890ca4 100644 --- a/WebCore/svg/SVGAElement.h +++ b/WebCore/svg/SVGAElement.h @@ -64,10 +64,7 @@ namespace WebCore { virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGAElement, String, String, Target, target) + ANIMATED_PROPERTY_DECLARATIONS(SVGAElement, SVGNames::aTagString, SVGNames::targetAttrString, String, Target, target) }; } // namespace WebCore diff --git a/WebCore/svg/SVGAltGlyphElement.cpp b/WebCore/svg/SVGAltGlyphElement.cpp new file mode 100644 index 0000000..e88e9b9 --- /dev/null +++ b/WebCore/svg/SVGAltGlyphElement.cpp @@ -0,0 +1,89 @@ +/* + Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> + 2004, 2005, 2006 Rob Buis <buis@kde.org> + Copyright (C) 2008 Apple Computer, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#if ENABLE(SVG_FONTS) +#include "SVGAltGlyphElement.h" + +#include "ExceptionCode.h" +#include "RenderInline.h" +#include "RenderSVGTSpan.h" +#include "SVGGlyphElement.h" +#include "SVGNames.h" +#include "XLinkNames.h" + +namespace WebCore { + +SVGAltGlyphElement::SVGAltGlyphElement(const QualifiedName& tagName, Document* doc) + : SVGTextPositioningElement(tagName, doc) +{ +} + +SVGAltGlyphElement::~SVGAltGlyphElement() +{ +} + +void SVGAltGlyphElement::setGlyphRef(const AtomicString& type, ExceptionCode& ec) +{ + ec = NO_MODIFICATION_ALLOWED_ERR; +} + +const AtomicString& SVGAltGlyphElement::glyphRef() const +{ + return getAttribute(SVGNames::glyphRefAttr); +} + +void SVGAltGlyphElement::setFormat(const AtomicString& type, ExceptionCode& ec) +{ + ec = NO_MODIFICATION_ALLOWED_ERR; +} + +const AtomicString& SVGAltGlyphElement::format() const +{ + return getAttribute(SVGNames::formatAttr); +} + +bool SVGAltGlyphElement::childShouldCreateRenderer(Node* child) const +{ + if (child->isTextNode()) + return true; + return false; +} + +RenderObject* SVGAltGlyphElement::createRenderer(RenderArena* arena, RenderStyle*) +{ + return new (arena) RenderSVGTSpan(this); +} + +SVGGlyphElement* SVGAltGlyphElement::glyphElement() const +{ + Element* elt = document()->getElementById(getTarget(getAttribute(XLinkNames::hrefAttr))); + if (!elt || !elt->hasTagName(SVGNames::glyphTag)) + return 0; + return static_cast<SVGGlyphElement*>(elt); +} + +} + +#endif // ENABLE(SVG) + +// vim:ts=4:noet diff --git a/WebCore/svg/SVGAltGlyphElement.h b/WebCore/svg/SVGAltGlyphElement.h new file mode 100644 index 0000000..91c99e3 --- /dev/null +++ b/WebCore/svg/SVGAltGlyphElement.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> + 2004, 2005, 2006 Rob Buis <buis@kde.org> + Copyright (C) 2008 Apple Computer, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SVGAltGlyphElement_h +#define SVGAltGlyphElement_h + +#if ENABLE(SVG_FONTS) +#include "AtomicString.h" +#include "SVGTextPositioningElement.h" +#include "SVGURIReference.h" + +namespace WebCore { + + class SVGGlyphElement; + + class SVGAltGlyphElement : public SVGTextPositioningElement, + public SVGURIReference { + public: + SVGAltGlyphElement(const QualifiedName&, Document*); + virtual ~SVGAltGlyphElement(); + + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); + bool childShouldCreateRenderer(Node*) const; + + const AtomicString& glyphRef() const; + void setGlyphRef(const AtomicString&, ExceptionCode&); + const AtomicString& format() const; + void setFormat(const AtomicString&, ExceptionCode&); + + SVGGlyphElement* glyphElement() const; + + protected: + virtual const SVGElement* contextElement() const { return this; } + }; + +} // namespace WebCore + +#endif // ENABLE(SVG) +#endif diff --git a/WebCore/svg/SVGAltGlyphElement.idl b/WebCore/svg/SVGAltGlyphElement.idl new file mode 100644 index 0000000..a00e346 --- /dev/null +++ b/WebCore/svg/SVGAltGlyphElement.idl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2008 Apple Computer, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +module svg { + + interface [Conditional=SVG&SVG_FONTS] SVGAltGlyphElement : SVGTextPositioningElement, SVGURIReference { + attribute DOMString glyphRef + setter raises(DOMException); + attribute DOMString format + setter raises(DOMException); + }; + +} diff --git a/WebCore/svg/SVGAngle.cpp b/WebCore/svg/SVGAngle.cpp index 4b7efc2..a0cffa0 100644 --- a/WebCore/svg/SVGAngle.cpp +++ b/WebCore/svg/SVGAngle.cpp @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -21,18 +19,16 @@ */ #include "config.h" +#include "SVGAngle.h" #if ENABLE(SVG) -#include "SVGAngle.h" -#include <math.h> #include <wtf/MathExtras.h> namespace WebCore { SVGAngle::SVGAngle() - : RefCounted<SVGAngle>() - , m_unitType(SVG_ANGLETYPE_UNKNOWN) + : m_unitType(SVG_ANGLETYPE_UNKNOWN) , m_value(0) , m_valueInSpecifiedUnits(0) { @@ -149,27 +145,6 @@ void SVGAngle::convertToSpecifiedUnits(unsigned short unitType) m_unitType = (SVGAngleType)unitType; } -// Helpers -double SVGAngle::todeg(double rad) -{ - return rad2deg(rad); -} - -double SVGAngle::torad(double deg) -{ - return deg2rad(deg); -} - -double SVGAngle::shortestArcBisector(double angle1, double angle2) -{ - double bisector = (angle1 + angle2) / 2; - - if (fabs(angle1 - angle2) > 180) - bisector += 180; - - return bisector; -} - } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGAngle.h b/WebCore/svg/SVGAngle.h index d281076..13b9fd4 100644 --- a/WebCore/svg/SVGAngle.h +++ b/WebCore/svg/SVGAngle.h @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -33,7 +31,10 @@ namespace WebCore { class SVGAngle : public RefCounted<SVGAngle> { public: - SVGAngle(); + static PassRefPtr<SVGAngle> create() + { + return adoptRef(new SVGAngle); + } virtual ~SVGAngle(); enum SVGAngleType { @@ -58,17 +59,12 @@ namespace WebCore { void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits); void convertToSpecifiedUnits(unsigned short unitType); - // Helpers - static double todeg(double rad); - static double torad(double deg); - - // Returns the angle that divides the shortest arc between the two angles. - static double shortestArcBisector(double angle1, double angle2); - // Throughout SVG 1.1 'SVGAngle' is only used for 'SVGMarkerElement' (orient-angle) const QualifiedName& associatedAttributeName() const { return SVGNames::orientAttr; } private: + SVGAngle(); + SVGAngleType m_unitType; float m_value; float m_valueInSpecifiedUnits; diff --git a/WebCore/svg/SVGAnimateColorElement.cpp b/WebCore/svg/SVGAnimateColorElement.cpp index 18135e6..1555f5e 100644 --- a/WebCore/svg/SVGAnimateColorElement.cpp +++ b/WebCore/svg/SVGAnimateColorElement.cpp @@ -22,82 +22,16 @@ */ #include "config.h" -#if ENABLE(SVG) +#if ENABLE(SVG_ANIMATION) #include "SVGAnimateColorElement.h" -#include "Document.h" -#include "TimeScheduler.h" -#include "PlatformString.h" -#include "SVGColor.h" -#include "SVGSVGElement.h" -#include <math.h> -#include <wtf/MathExtras.h> - namespace WebCore { - + SVGAnimateColorElement::SVGAnimateColorElement(const QualifiedName& tagName, Document* doc) - : SVGAnimationElement(tagName, doc) -{ -} - -SVGAnimateColorElement::~SVGAnimateColorElement() + : SVGAnimateElement(tagName, doc) { } -bool SVGAnimateColorElement::updateAnimationBaseValueFromElement() -{ - m_baseColor = SVGColor::colorFromRGBColorString(targetAttributeAnimatedValue()); - m_fromColor = Color(); - m_toColor = Color(); - return true; -} - -void SVGAnimateColorElement::applyAnimatedValueToElement() -{ - if (isAdditive()) - setTargetAttributeAnimatedValue(ColorDistance::addColorsAndClamp(m_baseColor, m_animatedColor).name()); - else - setTargetAttributeAnimatedValue(m_animatedColor.name()); -} - -bool SVGAnimateColorElement::updateAnimatedValue(EAnimationMode animationMode, float timePercentage, unsigned valueIndex, float percentagePast) -{ - if (animationMode == TO_ANIMATION) - // to-animations have a special equation: value = (to - base) * (time/duration) + base - m_animatedColor = ColorDistance(m_baseColor, m_toColor).scaledDistance(timePercentage).addToColorAndClamp(m_baseColor); - else - m_animatedColor = ColorDistance(m_fromColor, m_toColor).scaledDistance(percentagePast).addToColorAndClamp(m_fromColor); - return (m_animatedColor != m_baseColor); -} - -bool SVGAnimateColorElement::calculateFromAndToValues(EAnimationMode animationMode, unsigned valueIndex) -{ - switch (animationMode) { - case FROM_TO_ANIMATION: - m_fromColor = SVGColor::colorFromRGBColorString(m_from); - // fall through - case TO_ANIMATION: - m_toColor = SVGColor::colorFromRGBColorString(m_to); - break; - case FROM_BY_ANIMATION: - m_fromColor = SVGColor::colorFromRGBColorString(m_from); - m_toColor = SVGColor::colorFromRGBColorString(m_by); - break; - case BY_ANIMATION: - m_fromColor = SVGColor::colorFromRGBColorString(m_from); - m_toColor = ColorDistance::addColorsAndClamp(m_fromColor, SVGColor::colorFromRGBColorString(m_by)); - break; - case VALUES_ANIMATION: - m_fromColor = SVGColor::colorFromRGBColorString(m_values[valueIndex]); - m_toColor = ((valueIndex + 1) < m_values.size()) ? SVGColor::colorFromRGBColorString(m_values[valueIndex + 1]) : m_fromColor; - break; - case NO_ANIMATION: - ASSERT_NOT_REACHED(); - } - - return true; -} - } // vim:ts=4:noet diff --git a/WebCore/svg/SVGAnimateColorElement.h b/WebCore/svg/SVGAnimateColorElement.h index 1a9a841..595f0a9 100644 --- a/WebCore/svg/SVGAnimateColorElement.h +++ b/WebCore/svg/SVGAnimateColorElement.h @@ -23,41 +23,21 @@ #ifndef SVGAnimateColorElement_h #define SVGAnimateColorElement_h -#if ENABLE(SVG) +#if ENABLE(SVG_ANIMATION) -#include "SVGAnimationElement.h" -#include "ColorDistance.h" -#include <wtf/RefPtr.h> +#include "SVGAnimateElement.h" namespace WebCore { - class SVGColor; - - class SVGAnimateColorElement : public SVGAnimationElement { + // SVGAnimateElement implements superset of the functionality. + class SVGAnimateColorElement : public SVGAnimateElement { public: SVGAnimateColorElement(const QualifiedName&, Document*); - virtual ~SVGAnimateColorElement(); - - virtual bool updateAnimationBaseValueFromElement(); - virtual void applyAnimatedValueToElement(); - - protected: - virtual const SVGElement* contextElement() const { return this; } - - virtual bool updateAnimatedValue(EAnimationMode, float timePercentage, unsigned valueIndex, float percentagePast); - virtual bool calculateFromAndToValues(EAnimationMode, unsigned valueIndex); - - private: - Color m_baseColor; - Color m_animatedColor; - - Color m_toColor; - Color m_fromColor; }; } // namespace WebCore -#endif // ENABLE(SVG) +#endif // ENABLE(SVG_ANIMATION) #endif // KSVG_SVGAnimateColorElementImpl_H // vim:ts=4:noet diff --git a/WebCore/svg/SVGAnimateColorElement.idl b/WebCore/svg/SVGAnimateColorElement.idl index ad3a0a8..4df1847 100644 --- a/WebCore/svg/SVGAnimateColorElement.idl +++ b/WebCore/svg/SVGAnimateColorElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG] SVGAnimateColorElement : SVGAnimationElement { + interface [Conditional=SVG_ANIMATION] SVGAnimateColorElement : SVGAnimationElement { } }; diff --git a/WebCore/svg/SVGAnimateElement.cpp b/WebCore/svg/SVGAnimateElement.cpp index 4b9cb46..c2a83c0 100644 --- a/WebCore/svg/SVGAnimateElement.cpp +++ b/WebCore/svg/SVGAnimateElement.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> + Copyright (C) 2008 Apple Inc. All rights reserved. This file is part of the KDE project @@ -24,15 +25,23 @@ #if ENABLE(SVG) && ENABLE(SVG_ANIMATION) #include "SVGAnimateElement.h" -#include "TimeScheduler.h" -#include "SVGDocumentExtensions.h" -#include "SVGSVGElement.h" +#include "ColorDistance.h" +#include "FloatConversion.h" +#include "SVGColor.h" +#include "SVGParserUtilities.h" +#include "SVGPathSegList.h" +#include <math.h> + +using namespace std; namespace WebCore { SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document* doc) : SVGAnimationElement(tagName, doc) - , m_currentItem(-1) + , m_propertyType(StringProperty) + , m_fromNumber(0) + , m_toNumber(0) + , m_animatedNumber(numeric_limits<double>::infinity()) { } @@ -40,6 +49,239 @@ SVGAnimateElement::~SVGAnimateElement() { } +static bool parseNumberValueAndUnit(const String& in, double& value, String& unit) +{ + // FIXME: These are from top of my head, figure out all property types that can be animated as numbers. + unsigned unitLength = 0; + String parse = in.stripWhiteSpace(); + if (parse.endsWith("%")) + unitLength = 1; + else if (parse.endsWith("px") || parse.endsWith("pt") || parse.endsWith("em")) + unitLength = 2; + else if (parse.endsWith("deg") || parse.endsWith("rad")) + unitLength = 3; + else if (parse.endsWith("grad")) + unitLength = 4; + String newUnit = parse.right(unitLength); + String number = parse.left(parse.length() - unitLength); + if (!unit.isEmpty() && newUnit != unit || number.isEmpty()) + return false; + UChar last = number[number.length() - 1]; + if (last < '0' || last > '9') + return false; + unit = newUnit; + bool ok; + value = number.toDouble(&ok); + return ok; +} + +SVGAnimateElement::PropertyType SVGAnimateElement::determinePropertyType(const String& attribute) const +{ + // FIXME: We need a full property table for figuring this out reliably. + if (hasTagName(SVGNames::animateColorTag)) + return ColorProperty; + if (attribute == "d") + return PathProperty; + if (attribute == "color" || attribute == "fill" || attribute == "stroke") + return ColorProperty; + return NumberProperty; +} + +void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement) +{ + ASSERT(percentage >= 0.f && percentage <= 1.f); + ASSERT(resultElement); + if (hasTagName(SVGNames::setTag)) + percentage = 1.f; + if (!resultElement->hasTagName(SVGNames::animateTag) && !resultElement->hasTagName(SVGNames::animateColorTag) + && !resultElement->hasTagName(SVGNames::setTag)) + return; + SVGAnimateElement* results = static_cast<SVGAnimateElement*>(resultElement); + // Can't accumulate over a string property. + if (results->m_propertyType == StringProperty && m_propertyType != StringProperty) + return; + if (m_propertyType == NumberProperty) { + // To animation uses contributions from the lower priority animations as the base value. + if (animationMode() == ToAnimation) + m_fromNumber = results->m_animatedNumber; + + double number = (m_toNumber - m_fromNumber) * percentage + m_fromNumber; + + // FIXME: This is not correct for values animation. + if (isAccumulated() && repeat) + number += m_toNumber * repeat; + if (isAdditive() && animationMode() != ToAnimation) + results->m_animatedNumber += number; + else + results->m_animatedNumber = number; + return; + } + if (m_propertyType == ColorProperty) { + if (animationMode() == ToAnimation) + m_fromColor = results->m_animatedColor; + Color color = ColorDistance(m_fromColor, m_toColor).scaledDistance(percentage).addToColorAndClamp(m_fromColor); + // FIXME: Accumulate colors. + if (isAdditive() && animationMode() != ToAnimation) + results->m_animatedColor = ColorDistance::addColorsAndClamp(results->m_animatedColor, color); + else + results->m_animatedColor = color; + return; + } + AnimationMode animationMode = this->animationMode(); + if (m_propertyType == PathProperty) { + if (percentage == 0) + results->m_animatedPath = m_fromPath; + else if (percentage == 1.f) + results->m_animatedPath = m_toPath; + else { + if (m_fromPath && m_toPath) + results->m_animatedPath = SVGPathSegList::createAnimated(m_fromPath.get(), m_toPath.get(), percentage); + else + results->m_animatedPath.clear(); + // Fall back to discrete animation if the paths are not compatible + if (!results->m_animatedPath) + results->m_animatedPath = ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f) + ? m_toPath : m_fromPath; + } + return; + } + ASSERT(animationMode == FromToAnimation || animationMode == ToAnimation || animationMode == ValuesAnimation); + if ((animationMode == FromToAnimation && percentage > 0.5f) || animationMode == ToAnimation || percentage == 1.0f) + results->m_animatedString = m_toString; + else + results->m_animatedString = m_fromString; + // Higher priority replace animation overrides any additive results so far. + results->m_propertyType = StringProperty; +} + +bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const String& toString) +{ + // FIXME: Needs more solid way determine target attribute type. + m_propertyType = determinePropertyType(attributeName()); + if (m_propertyType == ColorProperty) { + m_fromColor = SVGColor::colorFromRGBColorString(fromString); + m_toColor = SVGColor::colorFromRGBColorString(toString); + if (m_fromColor.isValid() && m_toColor.isValid()) + return true; + } else if (m_propertyType == NumberProperty) { + m_numberUnit = String(); + if (parseNumberValueAndUnit(toString, m_toNumber, m_numberUnit)) { + // For to-animations the from number is calculated later + if (animationMode() == ToAnimation || parseNumberValueAndUnit(fromString, m_fromNumber, m_numberUnit)) + return true; + } + } else if (m_propertyType == PathProperty) { + m_fromPath = SVGPathSegList::create(SVGNames::dAttr); + if (pathSegListFromSVGData(m_fromPath.get(), fromString)) { + m_toPath = SVGPathSegList::create(SVGNames::dAttr); + if (pathSegListFromSVGData(m_toPath.get(), toString)) + return true; + } + m_fromPath.clear(); + m_toPath.clear(); + } + m_fromString = fromString; + m_toString = toString; + m_propertyType = StringProperty; + return true; +} + +bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const String& byString) +{ + ASSERT(!hasTagName(SVGNames::setTag)); + m_propertyType = determinePropertyType(attributeName()); + if (m_propertyType == ColorProperty) { + m_fromColor = fromString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(fromString); + m_toColor = ColorDistance::addColorsAndClamp(m_fromColor, SVGColor::colorFromRGBColorString(byString)); + if (!m_fromColor.isValid() || !m_toColor.isValid()) + return false; + } else { + m_numberUnit = String(); + m_fromNumber = 0; + if (!fromString.isEmpty() && !parseNumberValueAndUnit(fromString, m_fromNumber, m_numberUnit)) + return false; + if (!parseNumberValueAndUnit(byString, m_toNumber, m_numberUnit)) + return false; + m_toNumber += m_fromNumber; + } + return true; +} + +void SVGAnimateElement::resetToBaseValue(const String& baseString) +{ + m_animatedString = baseString; + m_propertyType = determinePropertyType(attributeName()); + if (m_propertyType == ColorProperty) { + m_animatedColor = baseString.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(baseString); + if (m_animatedColor.isValid()) + return; + } else if (m_propertyType == NumberProperty) { + if (baseString.isEmpty()) { + m_animatedNumber = 0; + m_numberUnit = String(); + return; + } + if (parseNumberValueAndUnit(baseString, m_animatedNumber, m_numberUnit)) + return; + } else if (m_propertyType == PathProperty) { + m_animatedPath.clear(); + return; + } + m_propertyType = StringProperty; +} + +void SVGAnimateElement::applyResultsToTarget() +{ + String valueToApply; + if (m_propertyType == ColorProperty) + valueToApply = m_animatedColor.name(); + else if (m_propertyType == NumberProperty) + valueToApply = String::number(m_animatedNumber) + m_numberUnit; + else if (m_propertyType == PathProperty) { + if (!m_animatedPath || !m_animatedPath->numberOfItems()) + valueToApply = m_animatedString; + else { + // We need to keep going to string and back because we are currently only able to paint + // "processed" paths where complex shapes are replaced with simpler ones. Path + // morphing needs to be done with unprocessed paths. + // FIXME: This could be optimized if paths were not processed at parse time. + unsigned itemCount = m_animatedPath->numberOfItems(); + ExceptionCode ec; + for (unsigned n = 0; n < itemCount; ++n) { + RefPtr<SVGPathSeg> segment = m_animatedPath->getItem(n, ec); + valueToApply.append(segment->toString() + " "); + } + } + } else + valueToApply = m_animatedString; + + setTargetAttributeAnimatedValue(valueToApply); +} + +float SVGAnimateElement::calculateDistance(const String& fromString, const String& toString) +{ + m_propertyType = determinePropertyType(attributeName()); + if (m_propertyType == NumberProperty) { + double from; + double to; + String unit; + if (!parseNumberValueAndUnit(fromString, from, unit)) + return -1.f; + if (!parseNumberValueAndUnit(toString, to, unit)) + return -1.f; + return narrowPrecisionToFloat(fabs(to - from)); + } else if (m_propertyType == ColorProperty) { + Color from = SVGColor::colorFromRGBColorString(fromString); + if (!from.isValid()) + return -1.f; + Color to = SVGColor::colorFromRGBColorString(toString); + if (!to.isValid()) + return -1.f; + return ColorDistance(from, to).distance(); + } + return -1.f; +} + } // vim:ts=4:noet diff --git a/WebCore/svg/SVGAnimateElement.h b/WebCore/svg/SVGAnimateElement.h index 2b7cf14..b90e5c8 100644 --- a/WebCore/svg/SVGAnimateElement.h +++ b/WebCore/svg/SVGAnimateElement.h @@ -1,6 +1,7 @@ /* Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005 Rob Buis <buis@kde.org> + Copyright (C) 2008 Apple Inc. All rights reserved. This file is part of the KDE project @@ -25,9 +26,11 @@ #if ENABLE(SVG) && ENABLE(SVG_ANIMATION) +#include "Color.h" #include "SVGAnimationElement.h" namespace WebCore { + class SVGPathSegList; class SVGAnimateElement : public SVGAnimationElement { public: @@ -35,15 +38,31 @@ namespace WebCore { virtual ~SVGAnimateElement(); protected: - virtual const SVGElement* contextElement() const { return this; } - - virtual bool updateAnimatedValue(EAnimationMode, float timePercentage, unsigned valueIndex, float percentagePast) { return false; } - virtual bool calculateFromAndToValues(EAnimationMode, unsigned valueIndex) { return false; } + virtual void resetToBaseValue(const String&); + virtual bool calculateFromAndToValues(const String& fromString, const String& toString); + virtual bool calculateFromAndByValues(const String& fromString, const String& byString); + virtual void calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement); + virtual void applyResultsToTarget(); + virtual float calculateDistance(const String& fromString, const String& toString); private: - int m_currentItem; - - String m_savedTo; + enum PropertyType { NumberProperty, ColorProperty, StringProperty, PathProperty }; + PropertyType determinePropertyType(const String& attribute) const; + PropertyType m_propertyType; + + double m_fromNumber; + double m_toNumber; + double m_animatedNumber; + String m_numberUnit; + Color m_fromColor; + Color m_toColor; + Color m_animatedColor; + String m_fromString; + String m_toString; + String m_animatedString; + RefPtr<SVGPathSegList> m_fromPath; + RefPtr<SVGPathSegList> m_toPath; + RefPtr<SVGPathSegList> m_animatedPath; }; } // namespace WebCore diff --git a/WebCore/svg/SVGAnimateMotionElement.cpp b/WebCore/svg/SVGAnimateMotionElement.cpp index 85ffc5d..60ffc47 100644 --- a/WebCore/svg/SVGAnimateMotionElement.cpp +++ b/WebCore/svg/SVGAnimateMotionElement.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2007 Eric Seidel <eric@webkit.org> (C) 2007 Rob Buis <buis@kde.org> + Copyright (C) 2008 Apple Inc. All Rights Reserved. This file is part of the WebKit project @@ -25,10 +26,12 @@ #include "SVGAnimateMotionElement.h" #include "RenderObject.h" +#include "SVGElementInstance.h" #include "SVGMPathElement.h" #include "SVGParserUtilities.h" #include "SVGPathElement.h" #include "SVGTransformList.h" +#include <math.h> namespace WebCore { @@ -36,10 +39,9 @@ using namespace SVGNames; SVGAnimateMotionElement::SVGAnimateMotionElement(const QualifiedName& tagName, Document* doc) : SVGAnimationElement(tagName, doc) - , m_rotateMode(AngleMode) + , m_baseIndexInTransformList(0) , m_angle(0) { - m_calcMode = CALCMODE_PACED; } SVGAnimateMotionElement::~SVGAnimateMotionElement() @@ -50,82 +52,71 @@ bool SVGAnimateMotionElement::hasValidTarget() const { if (!SVGAnimationElement::hasValidTarget()) return false; - if (!targetElement()->isStyledTransformable()) + SVGElement* targetElement = this->targetElement(); + if (!targetElement->isStyledTransformable() && !targetElement->hasTagName(SVGNames::textTag)) return false; // Spec: SVG 1.1 section 19.2.15 - if (targetElement()->hasTagName(gTag) - || targetElement()->hasTagName(defsTag) - || targetElement()->hasTagName(useTag) - || targetElement()->hasTagName(imageTag) - || targetElement()->hasTagName(switchTag) - || targetElement()->hasTagName(pathTag) - || targetElement()->hasTagName(rectTag) - || targetElement()->hasTagName(circleTag) - || targetElement()->hasTagName(ellipseTag) - || targetElement()->hasTagName(lineTag) - || targetElement()->hasTagName(polylineTag) - || targetElement()->hasTagName(polygonTag) - || targetElement()->hasTagName(textTag) - || targetElement()->hasTagName(clipPathTag) - || targetElement()->hasTagName(maskTag) - || targetElement()->hasTagName(aTag) - || targetElement()->hasTagName(foreignObjectTag)) + if (targetElement->hasTagName(gTag) + || targetElement->hasTagName(defsTag) + || targetElement->hasTagName(useTag) + || targetElement->hasTagName(imageTag) + || targetElement->hasTagName(switchTag) + || targetElement->hasTagName(pathTag) + || targetElement->hasTagName(rectTag) + || targetElement->hasTagName(circleTag) + || targetElement->hasTagName(ellipseTag) + || targetElement->hasTagName(lineTag) + || targetElement->hasTagName(polylineTag) + || targetElement->hasTagName(polygonTag) + || targetElement->hasTagName(textTag) + || targetElement->hasTagName(clipPathTag) + || targetElement->hasTagName(maskTag) + || targetElement->hasTagName(aTag) +#if ENABLE(SVG_FOREIGN_OBJECT) + || targetElement->hasTagName(foreignObjectTag) +#endif + ) return true; return false; } void SVGAnimateMotionElement::parseMappedAttribute(MappedAttribute* attr) { - if (attr->name() == SVGNames::rotateAttr) { - if (attr->value() == "auto") - m_rotateMode = AutoMode; - else if (attr->value() == "auto-reverse") - m_rotateMode = AutoReverseMode; - else { - m_rotateMode = AngleMode; - m_angle = attr->value().toFloat(); - } - } else if (attr->name() == SVGNames::keyPointsAttr) { - m_keyPoints.clear(); - parseKeyNumbers(m_keyPoints, attr->value()); - } else if (attr->name() == SVGNames::dAttr) { + if (attr->name() == SVGNames::pathAttr) { m_path = Path(); pathFromSVGData(m_path, attr->value()); } else SVGAnimationElement::parseMappedAttribute(attr); } + +SVGAnimateMotionElement::RotateMode SVGAnimateMotionElement::rotateMode() const +{ + static const AtomicString autoVal("auto"); + static const AtomicString autoReverse("auto-reverse"); + String rotate = getAttribute(SVGNames::rotateAttr); + if (rotate == autoVal) + return RotateAuto; + if (rotate == autoReverse) + return RotateAutoReverse; + return RotateAngle; +} -Path SVGAnimateMotionElement::animationPath() +Path SVGAnimateMotionElement::animationPath() const { - for (Node* child = firstChild(); child; child->nextSibling()) { + for (Node* child = firstChild(); child; child = child->nextSibling()) { if (child->hasTagName(SVGNames::mpathTag)) { SVGMPathElement* mPath = static_cast<SVGMPathElement*>(child); SVGPathElement* pathElement = mPath->pathElement(); if (pathElement) return pathElement->toPathData(); - // The spec would probably have us throw up an error here, but instead we try to fall back to the d value + return Path(); } } - if (hasAttribute(SVGNames::dAttr)) + if (hasAttribute(SVGNames::pathAttr)) return m_path; return Path(); } -bool SVGAnimateMotionElement::updateAnimatedValue(EAnimationMode animationMode, float timePercentage, unsigned valueIndex, float percentagePast) -{ - if (animationMode == TO_ANIMATION) { - // to-animations have a special equation: value = (to - base) * (time/duration) + base - m_animatedTranslation.setWidth((m_toPoint.x() - m_basePoint.x()) * timePercentage + m_basePoint.x()); - m_animatedTranslation.setHeight((m_toPoint.y() - m_basePoint.y()) * timePercentage + m_basePoint.y()); - m_animatedAngle = 0.0f; - } else { - m_animatedTranslation.setWidth(m_pointDiff.width() * percentagePast + m_fromPoint.x()); - m_animatedTranslation.setHeight(m_pointDiff.height() * percentagePast + m_fromPoint.y()); - m_animatedAngle = m_angleDiff * percentagePast + m_fromAngle; - } - return true; -} - static bool parsePoint(const String& s, FloatPoint& point) { if (s.isEmpty()) @@ -146,83 +137,106 @@ static bool parsePoint(const String& s, FloatPoint& point) point = FloatPoint(x, y); - // disallow anying except spaces at the end + // disallow anything except spaces at the end return !skipOptionalSpaces(cur, end); } - -bool SVGAnimateMotionElement::calculateFromAndToValues(EAnimationMode animationMode, unsigned valueIndex) -{ - m_fromAngle = 0.0f; - m_toAngle = 0.0f; - switch (animationMode) { - case FROM_TO_ANIMATION: - parsePoint(m_from, m_fromPoint); - // fall through - case TO_ANIMATION: - parsePoint(m_to, m_toPoint); - break; - case FROM_BY_ANIMATION: - parsePoint(m_from, m_fromPoint); - parsePoint(m_to, m_toPoint); - break; - case BY_ANIMATION: - { - parsePoint(m_from, m_fromPoint); - FloatPoint byPoint; - parsePoint(m_by, byPoint); - m_toPoint = FloatPoint(m_fromPoint.x() + byPoint.x(), m_fromPoint.y() + byPoint.y()); - break; - } - case VALUES_ANIMATION: - parsePoint(m_values[valueIndex], m_fromPoint); - if ((valueIndex + 1) < m_values.size()) - parsePoint(m_values[valueIndex + 1], m_toPoint); - else - m_toPoint = m_fromPoint; - break; - case NO_ANIMATION: - ASSERT_NOT_REACHED(); - } - m_pointDiff = m_toPoint - m_fromPoint; - m_angleDiff = 0.0f; - return (m_pointDiff.width() != 0 || m_pointDiff.height() != 0); +void SVGAnimateMotionElement::resetToBaseValue(const String&) +{ + if (!hasValidTarget()) + return; + SVGElement* target = targetElement(); + AffineTransform* transform = target->supplementalTransform(); + if (!transform) + return; + transform->reset(); } -bool SVGAnimateMotionElement::updateAnimationBaseValueFromElement() +bool SVGAnimateMotionElement::calculateFromAndToValues(const String& fromString, const String& toString) { - if (!targetElement()->isStyledTransformable()) - return false; + parsePoint(fromString, m_fromPoint); + parsePoint(toString, m_toPoint); + return true; +} - m_basePoint = static_cast<SVGStyledTransformableElement*>(targetElement())->getBBox().location(); +bool SVGAnimateMotionElement::calculateFromAndByValues(const String& fromString, const String& byString) +{ + parsePoint(fromString, m_fromPoint); + FloatPoint byPoint; + parsePoint(byString, byPoint); + m_toPoint = FloatPoint(m_fromPoint.x() + byPoint.x(), m_fromPoint.y() + byPoint.y()); return true; } -void SVGAnimateMotionElement::applyAnimatedValueToElement() +void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement*) { - if (!targetElement()->isStyledTransformable()) + SVGElement* target = targetElement(); + if (!target) return; - - SVGStyledTransformableElement* transformableElement = static_cast<SVGStyledTransformableElement*>(targetElement()); - RefPtr<SVGTransformList> transformList = transformableElement->transform(); - if (!transformList) + AffineTransform* transform = target->supplementalTransform(); + if (!transform) return; - ExceptionCode ec; if (!isAdditive()) - transformList->clear(ec); + transform->reset(); + + // FIXME: Implement accumulate. + + if (animationMode() == PathAnimation) { + ASSERT(!animationPath().isEmpty()); + Path path = animationPath(); + float positionOnPath = path.length() * percentage; + bool ok; + FloatPoint position = path.pointAtLength(positionOnPath, ok); + if (ok) { + transform->translate(position.x(), position.y()); + RotateMode rotateMode = this->rotateMode(); + if (rotateMode == RotateAuto || rotateMode == RotateAutoReverse) { + float angle = path.normalAngleAtLength(positionOnPath, ok); + if (rotateMode == RotateAutoReverse) + angle += 180.f; + transform->rotate(angle); + } + } + return; + } + FloatSize diff = m_toPoint - m_fromPoint; + transform->translate(diff.width() * percentage + m_fromPoint.x(), diff.height() * percentage + m_fromPoint.y()); +} + +void SVGAnimateMotionElement::applyResultsToTarget() +{ + // We accumulate to the target element transform list so there is not much to do here. + SVGElement* targetElement = this->targetElement(); + if (targetElement && targetElement->renderer()) + targetElement->renderer()->setNeedsLayout(true); - AffineTransform transform; - transform.rotate(m_animatedAngle); - transform.translate(m_animatedTranslation.width(), m_animatedTranslation.height()); - if (!transform.isIdentity()) { - transformList->appendItem(SVGTransform(transform), ec); - transformableElement->setTransform(transformList.get()); - if (transformableElement->renderer()) - transformableElement->renderer()->setNeedsLayout(true); // should be part of setTransform + // ...except in case where we have additional instances in <use> trees. + HashSet<SVGElementInstance*> instances = targetElement->instancesForElement(); + HashSet<SVGElementInstance*>::iterator end = instances.end(); + for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) { + SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); + ASSERT(shadowTreeElement); + AffineTransform* transform = shadowTreeElement->supplementalTransform(); + AffineTransform* t = targetElement->supplementalTransform(); + transform->setMatrix(t->a(), t->b(), t->c(), t->d(), t->e(), t->f()); + if (shadowTreeElement->renderer()) + shadowTreeElement->renderer()->setNeedsLayout(true); } } +float SVGAnimateMotionElement::calculateDistance(const String& fromString, const String& toString) +{ + FloatPoint from; + FloatPoint to; + if (!parsePoint(fromString, from)) + return -1.f; + if (!parsePoint(toString, to)) + return -1.f; + FloatSize diff = to - from; + return sqrtf(diff.width() * diff.width() + diff.height() * diff.height()); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGAnimateMotionElement.h b/WebCore/svg/SVGAnimateMotionElement.h index 6d9632c..ff58264 100644 --- a/WebCore/svg/SVGAnimateMotionElement.h +++ b/WebCore/svg/SVGAnimateMotionElement.h @@ -1,5 +1,6 @@ /* Copyright (C) 2007 Eric Seidel <eric@webkit.org> + Copyright (C) 2008 Apple Inc. All Rights Reserved. This file is part of the WebKit project @@ -21,7 +22,7 @@ #ifndef SVGAnimateMotionElement_h #define SVGAnimateMotionElement_h -#if ENABLE(SVG) && ENABLE(SVG_ANIMATION) +#if ENABLE(SVG_ANIMATION) #include "SVGAnimationElement.h" #include "AffineTransform.h" @@ -33,50 +34,46 @@ namespace WebCore { public: SVGAnimateMotionElement(const QualifiedName&, Document*); virtual ~SVGAnimateMotionElement(); - + virtual bool hasValidTarget() const; - - virtual bool updateAnimationBaseValueFromElement(); - virtual void applyAnimatedValueToElement(); - + virtual void parseMappedAttribute(MappedAttribute*); - - Path animationPath(); - - protected: - virtual const SVGElement* contextElement() const { return this; } - - virtual bool updateAnimatedValue(EAnimationMode, float timePercentage, unsigned valueIndex, float percentagePast); - virtual bool calculateFromAndToValues(EAnimationMode, unsigned valueIndex); private: - FloatPoint m_basePoint; + virtual void resetToBaseValue(const String&); + virtual bool calculateFromAndToValues(const String& fromString, const String& toString); + virtual bool calculateFromAndByValues(const String& fromString, const String& byString); + virtual void calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement); + virtual void applyResultsToTarget(); + virtual float calculateDistance(const String& fromString, const String& toString); + virtual Path animationPath() const; + + enum RotateMode { + RotateAngle, + RotateAuto, + RotateAutoReverse + }; + RotateMode rotateMode() const; + FloatSize m_animatedTranslation; float m_animatedAngle; - + // Note: we do not support percentage values for to/from coords as the spec implies we should (opera doesn't either) FloatPoint m_fromPoint; float m_fromAngle; FloatPoint m_toPoint; float m_toAngle; - - FloatSize m_pointDiff; - float m_angleDiff; - + + unsigned m_baseIndexInTransformList; + Path m_path; Vector<float> m_keyPoints; - enum RotateMode { - AngleMode, - AutoMode, - AutoReverseMode - }; - RotateMode m_rotateMode; float m_angle; }; } // namespace WebCore -#endif // ENABLE(SVG) +#endif // ENABLE(SVG_ANIMATION) #endif // SVGAnimateMotionElement_h // vim:ts=4:noet diff --git a/WebCore/svg/SVGAnimateTransformElement.cpp b/WebCore/svg/SVGAnimateTransformElement.cpp index c10b98c..c5b4e9d 100644 --- a/WebCore/svg/SVGAnimateTransformElement.cpp +++ b/WebCore/svg/SVGAnimateTransformElement.cpp @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> Copyright (C) 2007 Eric Seidel <eric@webkit.org> + Copyright (C) 2008 Apple Inc. All Rights Reserved. This file is part of the WebKit project @@ -28,12 +29,14 @@ #include "AffineTransform.h" #include "RenderObject.h" #include "SVGAngle.h" +#include "SVGElementInstance.h" #include "SVGParserUtilities.h" #include "SVGSVGElement.h" #include "SVGStyledTransformableElement.h" +#include "SVGTextElement.h" #include "SVGTransform.h" #include "SVGTransformList.h" -#include "TimeScheduler.h" +#include "SVGUseElement.h" #include <math.h> #include <wtf/MathExtras.h> @@ -45,6 +48,7 @@ namespace WebCore { SVGAnimateTransformElement::SVGAnimateTransformElement(const QualifiedName& tagName, Document* doc) : SVGAnimationElement(tagName, doc) , m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN) + , m_baseIndexInTransformList(0) { } @@ -54,7 +58,8 @@ SVGAnimateTransformElement::~SVGAnimateTransformElement() bool SVGAnimateTransformElement::hasValidTarget() const { - return (SVGAnimationElement::hasValidTarget() && targetElement()->isStyledTransformable()); + SVGElement* targetElement = this->targetElement(); + return SVGAnimationElement::hasValidTarget() && (targetElement->isStyledTransformable() || targetElement->hasTagName(SVGNames::textTag)); } void SVGAnimateTransformElement::parseMappedAttribute(MappedAttribute* attr) @@ -74,96 +79,126 @@ void SVGAnimateTransformElement::parseMappedAttribute(MappedAttribute* attr) SVGAnimationElement::parseMappedAttribute(attr); } -bool SVGAnimateTransformElement::updateAnimatedValue(EAnimationMode animationMode, float timePercentage, unsigned valueIndex, float percentagePast) + +static PassRefPtr<SVGTransformList> transformListFor(SVGElement* element) { - if (animationMode == TO_ANIMATION) - // to-animations have a special equation: value = (to - base) * (time/duration) + base - m_animatedTransform = SVGTransformDistance(m_baseTransform, m_toTransform).scaledDistance(timePercentage).addToSVGTransform(m_baseTransform); - else - m_animatedTransform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(percentagePast).addToSVGTransform(m_fromTransform); - return (m_animatedTransform != m_baseTransform); + ASSERT(element); + if (element->isStyledTransformable()) + return static_cast<SVGStyledTransformableElement*>(element)->transform(); + if (element->hasTagName(SVGNames::textTag)) + return static_cast<SVGTextElement*>(element)->transform(); + return 0; } - -bool SVGAnimateTransformElement::updateAnimationBaseValueFromElement() -{ - m_baseTransform = SVGTransform(); - m_toTransform = SVGTransform(); - m_fromTransform = SVGTransform(); - m_animatedTransform = SVGTransform(); - - if (!targetElement()->isStyledTransformable()) - return false; - SVGStyledTransformableElement* transform = static_cast<SVGStyledTransformableElement*>(targetElement()); - RefPtr<SVGTransformList> transformList = transform->transform(); - if (!transformList) - return false; - - m_baseTransform = transformList->concatenateForType(m_type); - - // If a base value is empty, its type should match m_type instead of being unknown. - // It's not certain whether this should be part of SVGTransformList or not -- cying - if (m_baseTransform.type() == SVGTransform::SVG_TRANSFORM_UNKNOWN) - m_baseTransform = SVGTransform(m_type); - - return true; +void SVGAnimateTransformElement::resetToBaseValue(const String& baseValue) +{ + if (!hasValidTarget()) + return; + if (baseValue.isEmpty()) { + ExceptionCode ec; + RefPtr<SVGTransformList> list = transformListFor(targetElement()); + list->clear(ec); + } else + targetElement()->setAttribute(SVGNames::transformAttr, baseValue); } -void SVGAnimateTransformElement::applyAnimatedValueToElement() +void SVGAnimateTransformElement::calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement) { - if (!targetElement()->isStyledTransformable()) - return; - - SVGStyledTransformableElement* transform = static_cast<SVGStyledTransformableElement*>(targetElement()); - RefPtr<SVGTransformList> transformList = transform->transform(); - if (!transformList) + if (!hasValidTarget()) return; - + SVGElement* targetElement = resultElement->targetElement(); + RefPtr<SVGTransformList> transformList = transformListFor(targetElement); + ASSERT(transformList); + ExceptionCode ec; if (!isAdditive()) transformList->clear(ec); + if (isAccumulated() && repeat) { + SVGTransform accumulatedTransform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(repeat).addToSVGTransform(SVGTransform()); + transformList->appendItem(accumulatedTransform, ec); + } + SVGTransform transform = SVGTransformDistance(m_fromTransform, m_toTransform).scaledDistance(percentage).addToSVGTransform(m_fromTransform); + transformList->appendItem(transform, ec); +} - transformList->appendItem(m_animatedTransform, ec); - transform->setTransform(transformList.get()); - if (transform->renderer()) - transform->renderer()->setNeedsLayout(true); // should really be in setTransform +bool SVGAnimateTransformElement::calculateFromAndToValues(const String& fromString, const String& toString) +{ + m_fromTransform = parseTransformValue(fromString); + if (!m_fromTransform.isValid()) + return false; + m_toTransform = parseTransformValue(toString); + return m_toTransform.isValid(); } -bool SVGAnimateTransformElement::calculateFromAndToValues(EAnimationMode animationMode, unsigned valueIndex) +bool SVGAnimateTransformElement::calculateFromAndByValues(const String& fromString, const String& byString) { - switch (animationMode) { - case FROM_TO_ANIMATION: - m_fromTransform = parseTransformValue(m_from); - // fall through - case TO_ANIMATION: - m_toTransform = parseTransformValue(m_to); - break; - case FROM_BY_ANIMATION: - m_fromTransform = parseTransformValue(m_from); - m_toTransform = parseTransformValue(m_by); - break; - case BY_ANIMATION: - m_fromTransform = parseTransformValue(m_from); - m_toTransform = SVGTransformDistance::addSVGTransforms(m_fromTransform, parseTransformValue(m_by)); - break; - case VALUES_ANIMATION: - m_fromTransform = parseTransformValue(m_values[valueIndex]); - m_toTransform = ((valueIndex + 1) < m_values.size()) ? parseTransformValue(m_values[valueIndex + 1]) : m_fromTransform; - break; - case NO_ANIMATION: - ASSERT_NOT_REACHED(); - } - - return true; + + m_fromTransform = parseTransformValue(fromString); + if (!m_fromTransform.isValid()) + return false; + m_toTransform = SVGTransformDistance::addSVGTransforms(m_fromTransform, parseTransformValue(byString)); + return m_toTransform.isValid(); } SVGTransform SVGAnimateTransformElement::parseTransformValue(const String& value) const { + if (value.isEmpty()) + return SVGTransform(m_type); SVGTransform result; - const UChar* ptr = value.characters(); - SVGTransformable::parseTransformValue(m_type, ptr, ptr + value.length(), result); // ignoring return value + // FIXME: This is pretty dumb but parseTransformValue() wants those parenthesis. + String parseString("(" + value + ")"); + const UChar* ptr = parseString.characters(); + SVGTransformable::parseTransformValue(m_type, ptr, ptr + parseString.length(), result); // ignoring return value return result; } + +void SVGAnimateTransformElement::applyResultsToTarget() +{ + if (!hasValidTarget()) + return; + // We accumulate to the target element transform list so there is not much to do here. + SVGElement* targetElement = this->targetElement(); + if (targetElement->renderer()) + targetElement->renderer()->setNeedsLayout(true); + + // ...except in case where we have additional instances in <use> trees. + HashSet<SVGElementInstance*> instances = targetElement->instancesForElement(); + RefPtr<SVGTransformList> transformList = transformListFor(targetElement); + HashSet<SVGElementInstance*>::iterator end = instances.end(); + for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) { + SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); + ASSERT(shadowTreeElement); + if (shadowTreeElement->isStyledTransformable()) + static_cast<SVGStyledTransformableElement*>(shadowTreeElement)->setTransform(transformList.get()); + else if (shadowTreeElement->hasTagName(SVGNames::textTag)) + static_cast<SVGTextElement*>(shadowTreeElement)->setTransform(transformList.get()); + if (shadowTreeElement->renderer()) + shadowTreeElement->renderer()->setNeedsLayout(true); + } +} + +float SVGAnimateTransformElement::calculateDistance(const String& fromString, const String& toString) +{ + // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example) + // is paced separately. To implement this we need to treat each component as individual animation everywhere. + SVGTransform from = parseTransformValue(fromString); + if (!from.isValid()) + return -1.f; + SVGTransform to = parseTransformValue(toString); + if (!to.isValid() || from.type() != to.type()) + return -1.f; + if (to.type() == SVGTransform::SVG_TRANSFORM_TRANSLATE) { + FloatSize diff = to.translate() - from.translate(); + return sqrtf(diff.width() * diff.width() + diff.height() * diff.height()); + } + if (to.type() == SVGTransform::SVG_TRANSFORM_ROTATE) + return fabsf(to.angle() - from.angle()); + if (to.type() == SVGTransform::SVG_TRANSFORM_SCALE) { + FloatSize diff = to.scale() - from.scale(); + return sqrtf(diff.width() * diff.width() + diff.height() * diff.height()); + } + return -1.f; +} } diff --git a/WebCore/svg/SVGAnimateTransformElement.h b/WebCore/svg/SVGAnimateTransformElement.h index 520e927..3c31d17 100644 --- a/WebCore/svg/SVGAnimateTransformElement.h +++ b/WebCore/svg/SVGAnimateTransformElement.h @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> Copyright (C) 2007 Eric Seidel <eric@webkit.org> + Copyright (C) 2008 Apple Inc. All Rights Reserved. This file is part of the KDE project @@ -41,27 +42,23 @@ namespace WebCore { virtual bool hasValidTarget() const; virtual void parseMappedAttribute(MappedAttribute*); - - virtual bool updateAnimationBaseValueFromElement(); - virtual void applyAnimatedValueToElement(); - - protected: - virtual const SVGElement* contextElement() const { return this; } - - virtual bool updateAnimatedValue(EAnimationMode, float timePercentage, unsigned valueIndex, float percentagePast); - virtual bool calculateFromAndToValues(EAnimationMode, unsigned valueIndex); private: + virtual void resetToBaseValue(const String&); + virtual bool calculateFromAndToValues(const String& fromString, const String& toString); + virtual bool calculateFromAndByValues(const String& fromString, const String& byString); + virtual void calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement); + virtual void applyResultsToTarget(); + virtual float calculateDistance(const String& fromString, const String& toString); + SVGTransform parseTransformValue(const String&) const; - void calculateRotationFromMatrix(const AffineTransform&, double& angle, double& cx, double& cy) const; SVGTransform::SVGTransformType m_type; + + unsigned m_baseIndexInTransformList; SVGTransform m_toTransform; SVGTransform m_fromTransform; - - SVGTransform m_baseTransform; - SVGTransform m_animatedTransform; }; } // namespace WebCore diff --git a/WebCore/svg/SVGAnimatedProperty.h b/WebCore/svg/SVGAnimatedProperty.h new file mode 100644 index 0000000..e7439a4 --- /dev/null +++ b/WebCore/svg/SVGAnimatedProperty.h @@ -0,0 +1,460 @@ +/* + Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SVGAnimatedProperty_h +#define SVGAnimatedProperty_h + +#if ENABLE(SVG) +#include "SVGAnimatedTemplate.h" +#include "SVGDocumentExtensions.h" +#include "SynchronizableTypeWrapper.h" + +namespace WebCore { + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + class SVGAnimatedProperty; + + template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> + class SVGAnimatedPropertyTearOff : public SVGAnimatedTemplate<DecoratedType> { + public: + typedef SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName> Self; + typedef SVGAnimatedProperty<OwnerType, AnimatedType, TagName, PropertyName> Creator; + + static PassRefPtr<Self> create(const Creator& creator, const OwnerElement* owner, const QualifiedName& attributeName) + { + return adoptRef(new Self(creator, owner, attributeName)); + } + + virtual DecoratedType baseVal() const; + virtual void setBaseVal(DecoratedType); + + virtual DecoratedType animVal() const; + virtual void setAnimVal(DecoratedType); + + private: + SVGAnimatedPropertyTearOff(const Creator&, const OwnerElement*, const QualifiedName& attributeName); + + Creator& m_creator; + RefPtr<OwnerElement> m_ownerElement; + }; + + // Helper templates mapping owner types to owner elements (for SVG*Element OwnerType is equal to OwnerElement, for non-SVG*Element derived types, they're different) + template<typename OwnerType, bool isDerivedFromSVGElement> + struct GetOwnerElementForType; + + template<typename OwnerType> + struct IsDerivedFromSVGElement; + + // Helper template used for synchronizing SVG <-> XML properties + template<typename OwnerElement, typename DecoratedType> + void synchronizeProperty(const OwnerElement* ownerElement, const QualifiedName& attributeName, DecoratedType baseValue); + + // Abstract base class + class SVGAnimatedPropertyBase : Noncopyable { + public: + virtual ~SVGAnimatedPropertyBase() { } + virtual void synchronize() const = 0; + }; + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + class SVGAnimatedProperty : public SVGAnimatedPropertyBase { + public: + typedef OwnerTypeArg OwnerType; + typedef AnimatedTypeArg AnimatedType; + + typedef typename SVGAnimatedTypeValue<AnimatedType>::StorableType StorableType; + typedef typename SVGAnimatedTypeValue<AnimatedType>::DecoratedType DecoratedType; + + typedef GetOwnerElementForType<OwnerType, IsDerivedFromSVGElement<OwnerType>::value> OwnerElementForType; + typedef typename OwnerElementForType::OwnerElement OwnerElement; + typedef SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName> TearOff; + + // attributeName & attributeIdentifier may differ. For SVGMarkerElement, there are two exposed SVG animatable + // properties: orientType & orientAngle, though only one DOM attribute "orient", handle these cases! + SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName); + SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, const AtomicString& attributeIdentifier); + + // "Forwarding constructors" for primitive type assignment with more than one argument + template<typename T1> + SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, + const T1&); + + template<typename T1> + SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, const AtomicString& attributeIdentifier, + const T1&); + + template<typename T1, typename T2> + SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, + const T1&, const T2&); + + template<typename T1, typename T2> + SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, const AtomicString& attributeIdentifier, + const T1&, const T2&); + + template<typename T1, typename T2, typename T3> + SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, + const T1&, const T2&, const T3&); + + template<typename T1, typename T2, typename T3> + SVGAnimatedProperty(const OwnerType*, const QualifiedName& attributeName, const AtomicString& attributeIdentifier, + const T1&, const T2&, const T3&); + + DecoratedType value() const; + void setValue(DecoratedType); + + DecoratedType baseValue() const; + void setBaseValue(DecoratedType); + + // Tear offs only used by bindings, never in internal code + PassRefPtr<TearOff> animatedTearOff() const; + + virtual void synchronize() const; + + void startAnimation() const; + void stopAnimation(); + + private: + const OwnerElement* ownerElement() const; + + private: + // We're a member variable on stack, living in OwnerType, NO need to ref here. + const OwnerType* m_ownerType; + + const QualifiedName& m_attributeName; + const AtomicString& m_attributeIdentifier; + + mutable SynchronizableTypeWrapper<StorableType> m_value; + }; + + // SVGAnimatedPropertyTearOff implementation + template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> + SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::SVGAnimatedPropertyTearOff(const Creator& creator, + const OwnerElement* owner, + const QualifiedName& attributeName) + : SVGAnimatedTemplate<DecoratedType>(attributeName) + , m_creator(const_cast<Creator&>(creator)) + , m_ownerElement(const_cast<OwnerElement*>(owner)) + { + ASSERT(m_ownerElement); + } + + template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> + DecoratedType SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::baseVal() const + { + return m_creator.baseValue(); + } + + template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> + void SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::setBaseVal(DecoratedType newBaseVal) + { + m_creator.setBaseValue(newBaseVal); + } + + template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> + DecoratedType SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::animVal() const + { + return m_creator.value(); + } + + template<typename OwnerType, typename OwnerElement, typename AnimatedType, typename DecoratedType, const char* TagName, const char* PropertyName> + void SVGAnimatedPropertyTearOff<OwnerType, OwnerElement, AnimatedType, DecoratedType, TagName, PropertyName>::setAnimVal(DecoratedType newAnimVal) + { + m_creator.setValue(newAnimVal); + } + + // SVGAnimatedProperty implementation + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, + const QualifiedName& attributeName) + : m_ownerType(owner) + , m_attributeName(attributeName) + , m_attributeIdentifier(attributeName.localName()) + , m_value() + { + ASSERT(m_ownerType); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, + const QualifiedName& attributeName, + const AtomicString& attributeIdentifier) + : m_ownerType(owner) + , m_attributeName(attributeName) + , m_attributeIdentifier(attributeIdentifier) + , m_value() + { + ASSERT(m_ownerType); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + template<typename T1> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, + const QualifiedName& attributeName, + const T1& arg1) + : m_ownerType(owner) + , m_attributeName(attributeName) + , m_attributeIdentifier(attributeName.localName()) + , m_value(arg1) + { + ASSERT(m_ownerType); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + template<typename T1> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, + const QualifiedName& attributeName, + const AtomicString& attributeIdentifier, + const T1& arg1) + : m_ownerType(owner) + , m_attributeName(attributeName) + , m_attributeIdentifier(attributeIdentifier) + , m_value(arg1) + { + ASSERT(m_ownerType); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + template<typename T1, typename T2> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, + const QualifiedName& attributeName, + const T1& arg1, + const T2& arg2) + : m_ownerType(owner) + , m_attributeName(attributeName) + , m_attributeIdentifier(attributeName.localName()) + , m_value(arg1, arg2) + { + ASSERT(m_ownerType); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + template<typename T1, typename T2> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, + const QualifiedName& attributeName, + const AtomicString& attributeIdentifier, + const T1& arg1, + const T2& arg2) + : m_ownerType(owner) + , m_attributeName(attributeName) + , m_attributeIdentifier(attributeIdentifier) + , m_value(arg1, arg2) + { + ASSERT(m_ownerType); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + template<typename T1, typename T2, typename T3> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, + const QualifiedName& attributeName, + const T1& arg1, + const T2& arg2, + const T3& arg3) + : m_ownerType(owner) + , m_attributeName(attributeName) + , m_attributeIdentifier(attributeName.localName()) + , m_value(arg1, arg2, arg3) + { + ASSERT(m_ownerType); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + template<typename T1, typename T2, typename T3> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::SVGAnimatedProperty(const OwnerType* owner, + const QualifiedName& attributeName, + const AtomicString& attributeIdentifier, + const T1& arg1, + const T2& arg2, + const T3& arg3) + : m_ownerType(owner) + , m_attributeName(attributeName) + , m_attributeIdentifier(attributeIdentifier) + , m_value(arg1, arg2, arg3) + { + ASSERT(m_ownerType); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + typename SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::DecoratedType + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::value() const + { + return m_value; + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::setValue(typename SVGAnimatedProperty::DecoratedType newValue) + { + m_value = newValue; + ownerElement()->setSynchronizedSVGAttributes(false); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + typename SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::DecoratedType + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::baseValue() const + { + const OwnerElement* ownerElement = this->ownerElement(); + SVGDocumentExtensions* extensions = ownerElement->accessDocumentSVGExtensions(); + if (extensions && extensions->hasBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier)) + return extensions->baseValue<DecoratedType>(ownerElement, m_attributeIdentifier); + + return m_value; + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::setBaseValue(typename SVGAnimatedProperty::DecoratedType newValue) + { + const OwnerElement* ownerElement = this->ownerElement(); + SVGDocumentExtensions* extensions = ownerElement->accessDocumentSVGExtensions(); + if (extensions && extensions->hasBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier)) { + extensions->setBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier, newValue); + return; + } + + // Only update stored property, if not animating + m_value = newValue; + ownerElement->setSynchronizedSVGAttributes(false); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + PassRefPtr<typename SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::TearOff> + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::animatedTearOff() const + { + return lookupOrCreateWrapper<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName, TearOff, OwnerElement>(*this, ownerElement(), m_attributeName, m_attributeIdentifier); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::synchronize() const + { + if (!m_value.needsSynchronization()) + return; + + synchronizeProperty<OwnerElement, DecoratedType>(ownerElement(), m_attributeName, baseValue()); + m_value.setSynchronized(); + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::startAnimation() const + { + const OwnerElement* ownerElement = this->ownerElement(); + SVGDocumentExtensions* extensions = ownerElement->accessDocumentSVGExtensions(); + if (extensions) { + ASSERT(!extensions->hasBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier)); + extensions->setBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier, m_value); + } + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + void SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::stopAnimation() + { + const OwnerElement* ownerElement = this->ownerElement(); + SVGDocumentExtensions* extensions = ownerElement->accessDocumentSVGExtensions(); + if (extensions) { + ASSERT(extensions->hasBaseValue<DecoratedType>(ownerElement, m_attributeIdentifier)); + setValue(extensions->baseValue<DecoratedType>(ownerElement, m_attributeIdentifier)); + extensions->removeBaseValue<AnimatedType>(ownerElement, m_attributeIdentifier); + } + } + + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + const typename SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::OwnerElement* + SVGAnimatedProperty<OwnerTypeArg, AnimatedTypeArg, TagName, PropertyName>::ownerElement() const + { + return OwnerElementForType::ownerElement(m_ownerType); + } + + // GetOwnerElementForType implementation + template<typename OwnerType> + struct GetOwnerElementForType<OwnerType, true> : Noncopyable { + typedef OwnerType OwnerElement; + + static const OwnerElement* ownerElement(const OwnerType* type) + { + return type; + } + }; + + template<typename OwnerType> + struct GetOwnerElementForType<OwnerType, false> : Noncopyable { + typedef SVGElement OwnerElement; + + static const OwnerElement* ownerElement(const OwnerType* type) + { + const OwnerElement* context = type->contextElement(); + ASSERT(context); + return context; + } + }; + + // IsDerivedFromSVGElement implementation + template<typename OwnerType> + struct IsDerivedFromSVGElement : Noncopyable { + static const bool value = true; + }; + + class SVGExternalResourcesRequired; + template<> + struct IsDerivedFromSVGElement<SVGExternalResourcesRequired> : Noncopyable { + static const bool value = false; + }; + + class SVGFitToViewBox; + template<> + struct IsDerivedFromSVGElement<SVGFitToViewBox> : Noncopyable { + static const bool value = false; + }; + + class SVGURIReference; + template<> + struct IsDerivedFromSVGElement<SVGURIReference> : Noncopyable { + static const bool value = false; + }; + + // Central function handling the main SVG<->XML synchronization part. + template<typename OwnerElement, typename DecoratedType> + void synchronizeProperty(const OwnerElement* ownerElement, const QualifiedName& attributeName, DecoratedType baseValue) + { + AtomicString value(SVGAnimatedTypeValue<DecoratedType>::toString(baseValue)); + + NamedAttrMap* namedAttrMap = ownerElement->attributes(false); + Attribute* old = namedAttrMap->getAttributeItem(attributeName); + if (old && value.isNull()) + namedAttrMap->removeAttribute(old->name()); + else if (!old && !value.isNull()) + namedAttrMap->addAttribute(const_cast<OwnerElement*>(ownerElement)->createAttribute(QualifiedName(nullAtom, attributeName.localName(), nullAtom), value)); + else if (old && !value.isNull()) + old->setValue(value); + } + + // Helper macro used to register animated properties within SVG* classes + #define ANIMATED_PROPERTY_DECLARATIONS(OwnerType, ElementTag, AttributeTag, AnimatedType, UpperProperty, LowerProperty) \ + private: \ + typedef SVGAnimatedProperty<OwnerType, AnimatedType, ElementTag, AttributeTag> SVGAnimatedProperty##UpperProperty; \ + typedef SVGAnimatedTypeValue<AnimatedType>::DecoratedType DecoratedTypeFor##UpperProperty; \ + SVGAnimatedProperty##UpperProperty m_##LowerProperty; \ + public: \ + DecoratedTypeFor##UpperProperty LowerProperty() const { return m_##LowerProperty.value(); } \ + void set##UpperProperty(DecoratedTypeFor##UpperProperty type) { m_##LowerProperty.setValue(type); } \ + DecoratedTypeFor##UpperProperty LowerProperty##BaseValue() const { return m_##LowerProperty.baseValue(); } \ + void set##UpperProperty##BaseValue(DecoratedTypeFor##UpperProperty type) { m_##LowerProperty.setBaseValue(type); } \ + PassRefPtr<SVGAnimatedProperty##UpperProperty::TearOff> LowerProperty##Animated() const { return m_##LowerProperty.animatedTearOff(); } \ + void synchronize##UpperProperty() const { m_##LowerProperty.synchronize(); } + +}; + +#endif +#endif diff --git a/WebCore/svg/SVGAnimatedTemplate.h b/WebCore/svg/SVGAnimatedTemplate.h index 340596d..3f04c5b 100644 --- a/WebCore/svg/SVGAnimatedTemplate.h +++ b/WebCore/svg/SVGAnimatedTemplate.h @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -24,16 +22,15 @@ #define SVGAnimatedTemplate_h #if ENABLE(SVG) -#include <wtf/RefCounted.h> #include "AtomicString.h" -#include "Attribute.h" +#include "FloatRect.h" +#include "SVGLength.h" +#include <wtf/HashMap.h> namespace WebCore { - - class FloatRect; + class SVGAngle; class SVGElement; - class SVGLength; class SVGLengthList; class SVGNumberList; class SVGPreserveAspectRatio; @@ -47,13 +44,18 @@ namespace WebCore { : element(0) , attributeName(0) { } - + // Deleted value - explicit SVGAnimatedTypeWrapperKey(bool) + SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValueType) : element(reinterpret_cast<SVGElement*>(-1)) - , attributeName(0) - { } - + { + } + + bool isHashTableDeletedValue() const + { + return element == reinterpret_cast<SVGElement*>(-1); + } + SVGAnimatedTypeWrapperKey(const SVGElement* _element, const AtomicString& _attributeName) : element(_element) , attributeName(_attributeName.impl()) @@ -61,12 +63,12 @@ namespace WebCore { ASSERT(element); ASSERT(attributeName); } - + bool operator==(const SVGAnimatedTypeWrapperKey& other) const { return element == other.element && attributeName == other.attributeName; } - + const SVGElement* element; AtomicStringImpl* attributeName; }; @@ -74,9 +76,9 @@ namespace WebCore { struct SVGAnimatedTypeWrapperKeyHash { static unsigned hash(const SVGAnimatedTypeWrapperKey& key) { - return StringImpl::computeHash((::UChar*) &key, sizeof(SVGAnimatedTypeWrapperKey) / sizeof(::UChar)); + return StringImpl::computeHash(reinterpret_cast<const UChar*>(&key), sizeof(SVGAnimatedTypeWrapperKey) / sizeof(UChar)); } - + static bool equal(const SVGAnimatedTypeWrapperKey& a, const SVGAnimatedTypeWrapperKey& b) { return a == b; @@ -84,40 +86,31 @@ namespace WebCore { static const bool safeToCompareToEmptyOrDeleted = true; }; - + struct SVGAnimatedTypeWrapperKeyHashTraits : WTF::GenericHashTraits<SVGAnimatedTypeWrapperKey> { static const bool emptyValueIsZero = true; - static const bool needsDestruction = false; - - static const SVGAnimatedTypeWrapperKey& deletedValue() + + static void constructDeletedValue(SVGAnimatedTypeWrapperKey& slot) { - static SVGAnimatedTypeWrapperKey deletedKey(true); - return deletedKey; + new (&slot) SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValue); } - - static const SVGAnimatedTypeWrapperKey& emptyValue() + + static bool isDeletedValue(const SVGAnimatedTypeWrapperKey& value) { - static SVGAnimatedTypeWrapperKey emptyKey; - return emptyKey; + return value.isHashTableDeletedValue(); } }; - + template<typename BareType> - class SVGAnimatedTemplate : public RefCounted<SVGAnimatedTemplate<BareType> > - { + class SVGAnimatedTemplate : public RefCounted<SVGAnimatedTemplate<BareType> > { public: - SVGAnimatedTemplate(const QualifiedName& attributeName) - : m_associatedAttributeName(attributeName) - { - } - virtual ~SVGAnimatedTemplate() { forgetWrapper(this); } virtual BareType baseVal() const = 0; - virtual void setBaseVal(BareType newBaseVal) = 0; + virtual void setBaseVal(BareType) = 0; virtual BareType animVal() const = 0; - virtual void setAnimVal(BareType newAnimVal) = 0; + virtual void setAnimVal(BareType) = 0; typedef HashMap<SVGAnimatedTypeWrapperKey, SVGAnimatedTemplate<BareType>*, SVGAnimatedTypeWrapperKeyHash, SVGAnimatedTypeWrapperKeyHashTraits > ElementToWrapperMap; typedef typename ElementToWrapperMap::const_iterator ElementToWrapperMapIterator; @@ -127,7 +120,7 @@ namespace WebCore { static ElementToWrapperMap* s_wrapperCache = new ElementToWrapperMap; return s_wrapperCache; } - + static void forgetWrapper(SVGAnimatedTemplate<BareType>* wrapper) { ElementToWrapperMap* cache = wrapperCache(); @@ -141,24 +134,111 @@ namespace WebCore { } } - const QualifiedName& associatedAttributeName() const { return m_associatedAttributeName; } + const QualifiedName& associatedAttributeName() const { return m_associatedAttributeName; } + + protected: + SVGAnimatedTemplate(const QualifiedName& attributeName) + : m_associatedAttributeName(attributeName) + { + } private: - const QualifiedName& m_associatedAttributeName; + const QualifiedName& m_associatedAttributeName; }; - template <class Type, class SVGElementSubClass> - Type* lookupOrCreateWrapper(const SVGElementSubClass* element, const QualifiedName& domAttrName, const AtomicString& attrIdentifier) { + template<typename OwnerTypeArg, typename AnimatedTypeArg, const char* TagName, const char* PropertyName> + class SVGAnimatedProperty; + + template<typename OwnerType, typename AnimatedType, const char* TagName, const char* PropertyName, typename Type, typename OwnerElement> + PassRefPtr<Type> lookupOrCreateWrapper(const SVGAnimatedProperty<OwnerType, AnimatedType, TagName, PropertyName>& creator, + const OwnerElement* element, const QualifiedName& attrName, const AtomicString& attrIdentifier) + { SVGAnimatedTypeWrapperKey key(element, attrIdentifier); - Type* wrapper = static_cast<Type*>(Type::wrapperCache()->get(key)); + RefPtr<Type> wrapper = static_cast<Type*>(Type::wrapperCache()->get(key)); + if (!wrapper) { - wrapper = new Type(element, domAttrName); - Type::wrapperCache()->set(key, wrapper); + wrapper = Type::create(creator, element, attrName); + element->addSVGPropertySynchronizer(attrName, creator); + Type::wrapperCache()->set(key, wrapper.get()); } - return wrapper; + + return wrapper.release(); } - // Common type definitions, to ease IDL generation... + // Default implementation for pointer types + template<typename Type> + struct SVGAnimatedTypeValue : Noncopyable { + typedef RefPtr<Type> StorableType; + typedef Type* DecoratedType; + + static Type null() { return 0; } + static AtomicString toString(Type type) { return type ? AtomicString(type->valueAsString()) : nullAtom; } + }; + + template<> + struct SVGAnimatedTypeValue<bool> : Noncopyable { + typedef bool StorableType; + typedef bool DecoratedType; + + static bool null() { return false; } + static AtomicString toString(bool type) { return type ? "true" : "false"; } + }; + + template<> + struct SVGAnimatedTypeValue<int> : Noncopyable { + typedef int StorableType; + typedef int DecoratedType; + + static int null() { return 0; } + static AtomicString toString(int type) { return String::number(type); } + }; + + template<> + struct SVGAnimatedTypeValue<long> : Noncopyable { + typedef long StorableType; + typedef long DecoratedType; + + static long null() { return 0l; } + static AtomicString toString(long type) { return String::number(type); } + }; + + template<> + struct SVGAnimatedTypeValue<SVGLength> : Noncopyable { + typedef SVGLength StorableType; + typedef SVGLength DecoratedType; + + static SVGLength null() { return SVGLength(); } + static AtomicString toString(const SVGLength& type) { return type.valueAsString(); } + }; + + template<> + struct SVGAnimatedTypeValue<float> : Noncopyable { + typedef float StorableType; + typedef float DecoratedType; + + static float null() { return 0.0f; } + static AtomicString toString(float type) { return String::number(type); } + }; + + template<> + struct SVGAnimatedTypeValue<FloatRect> : Noncopyable { + typedef FloatRect StorableType; + typedef FloatRect DecoratedType; + + static FloatRect null() { return FloatRect(); } + static AtomicString toString(const FloatRect& type) { return String::format("%f %f %f %f", type.x(), type.y(), type.width(), type.height()); } + }; + + template<> + struct SVGAnimatedTypeValue<String> : Noncopyable { + typedef String StorableType; + typedef String DecoratedType; + + static String null() { return String(); } + static AtomicString toString(const String& type) { return type; } + }; + + // Common type definitions, to ease IDL generation. typedef SVGAnimatedTemplate<SVGAngle*> SVGAnimatedAngle; typedef SVGAnimatedTemplate<bool> SVGAnimatedBoolean; typedef SVGAnimatedTemplate<int> SVGAnimatedEnumeration; @@ -171,6 +251,7 @@ namespace WebCore { typedef SVGAnimatedTemplate<FloatRect> SVGAnimatedRect; typedef SVGAnimatedTemplate<String> SVGAnimatedString; typedef SVGAnimatedTemplate<SVGTransformList*> SVGAnimatedTransformList; + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGAnimationElement.cpp b/WebCore/svg/SVGAnimationElement.cpp index 5ccc17f..5910ac8 100644 --- a/WebCore/svg/SVGAnimationElement.cpp +++ b/WebCore/svg/SVGAnimationElement.cpp @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> Copyright (C) 2007 Eric Seidel <eric@webkit.org> + Copyright (C) 2008 Apple Inc. All rights reserved. This file is part of the KDE project @@ -22,726 +23,511 @@ */ #include "config.h" -#if ENABLE(SVG) +#if ENABLE(SVG_ANIMATION) #include "SVGAnimationElement.h" +#include "CSSComputedStyleDeclaration.h" +#include "CSSParser.h" #include "CSSPropertyNames.h" #include "Document.h" +#include "Event.h" +#include "EventListener.h" #include "FloatConversion.h" -#include "SVGParserUtilities.h" -#include "SVGSVGElement.h" +#include "HTMLNames.h" +#include "SVGElementInstance.h" +#include "SVGNames.h" #include "SVGURIReference.h" -#include "TimeScheduler.h" +#include "SVGUseElement.h" #include "XLinkNames.h" -#include <float.h> #include <math.h> -#include <wtf/MathExtras.h> -#include <wtf/Vector.h> using namespace std; namespace WebCore { - + SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document* doc) - : SVGElement(tagName, doc) + : SVGSMILElement(tagName, doc) , SVGTests() , SVGExternalResourcesRequired() - , m_targetElement(0) - , m_connectedToTimer(false) - , m_currentTime(0.0) - , m_simpleDuration(0.0) - , m_fill(FILL_REMOVE) - , m_restart(RESTART_ALWAYS) - , m_calcMode(CALCMODE_LINEAR) - , m_additive(ADDITIVE_REPLACE) - , m_accumulate(ACCUMULATE_NONE) - , m_attributeType(ATTRIBUTETYPE_AUTO) - , m_max(0.0) - , m_min(0.0) - , m_end(0.0) - , m_begin(0.0) - , m_repetitions(0) - , m_repeatCount(0) + , m_animationValid(false) { - } SVGAnimationElement::~SVGAnimationElement() { } - -bool SVGAnimationElement::hasValidTarget() const -{ - return targetElement(); -} - -SVGElement* SVGAnimationElement::targetElement() const -{ - if (!m_targetElement) { - Node *target = 0; - if (!m_href.isEmpty()) { - target = document()->getElementById(SVGURIReference::getTarget(m_href)); - } else if (parentNode()) { - // TODO : do we really need to skip non element nodes? Can that happen at all? - target = parentNode(); - while (target) { - if (target->nodeType() != ELEMENT_NODE) - target = target->parentNode(); - else - break; - } - } - if (target && target->isSVGElement()) - m_targetElement = static_cast<SVGElement*>(target); - } - - return m_targetElement; -} - -float SVGAnimationElement::getEndTime() const -{ - return narrowPrecisionToFloat(m_end); -} - -float SVGAnimationElement::getStartTime() const -{ - return narrowPrecisionToFloat(m_begin); -} - -float SVGAnimationElement::getCurrentTime() const -{ - return narrowPrecisionToFloat(m_currentTime); -} - -float SVGAnimationElement::getSimpleDuration(ExceptionCode&) const -{ - return narrowPrecisionToFloat(m_simpleDuration); -} - -void SVGAnimationElement::parseKeyNumbers(Vector<float>& keyNumbers, const String& value) -{ - float number = 0.0f; - const UChar* ptr = value.characters(); - const UChar* end = ptr + value.length(); - skipOptionalSpaces(ptr, end); - while (ptr < end) { - if (!parseNumber(ptr, end, number, false)) - return; - keyNumbers.append(number); - - if (!skipOptionalSpaces(ptr, end) || *ptr != ';') - return; - ptr++; - skipOptionalSpaces(ptr, end); - } -} - -static void parseKeySplines(Vector<SVGAnimationElement::KeySpline>& keySplines, const String& value) -{ - float number = 0.0f; - SVGAnimationElement::KeySpline keySpline; - - const UChar* ptr = value.characters(); - const UChar* end = ptr + value.length(); - skipOptionalSpaces(ptr, end); - while (ptr < end) { - if (!(parseNumber(ptr, end, number, false) && skipOptionalSpaces(ptr, end))) - return; - keySpline.control1.setX(number); - if (!(parseNumber(ptr, end, number, false) && skipOptionalSpaces(ptr, end))) - return; - keySpline.control1.setY(number); - if (!(parseNumber(ptr, end, number, false) && skipOptionalSpaces(ptr, end))) - return; - keySpline.control2.setX(number); - if (!parseNumber(ptr, end, number, false)) - return; - keySpline.control2.setY(number); - keySplines.append(keySpline); - - if (!skipOptionalSpaces(ptr, end) || *ptr != ';') - return; - ptr++; - skipOptionalSpaces(ptr, end); +static void parseKeyTimes(const String& parse, Vector<float>& result, bool verifyOrder) +{ + result.clear(); + Vector<String> parseList; + parse.split(';', parseList); + for (unsigned n = 0; n < parseList.size(); ++n) { + String timeString = parseList[n]; + bool ok; + float time = timeString.toFloat(&ok); + if (!ok || time < 0 || time > 1.f) + goto fail; + if (verifyOrder) { + if (!n) { + if (time != 0) + goto fail; + } else if (time < result.last()) + goto fail; + } + result.append(time); } -} - -void SVGAnimationElement::parseBeginOrEndValue(double& number, const String& value) -{ - // TODO: Don't use SVGStringList for parsing. - AtomicString dummy; - RefPtr<SVGStringList> valueList = new SVGStringList(QualifiedName(dummy, dummy, dummy)); - valueList->parse(value, ';'); - - ExceptionCode ec = 0; - for (unsigned int i = 0; i < valueList->numberOfItems(); i++) { - String current = valueList->getItem(i, ec); - - if (current.startsWith("accessKey")) { - // Register keyDownEventListener for the character - String character = current.substring(current.length() - 2, 1); - // FIXME: Not implemented! Supposed to register accessKey character - } else if (current.startsWith("wallclock")) { - int firstBrace = current.find('('); - int secondBrace = current.find(')'); - - String wallclockValue = current.substring(firstBrace + 1, secondBrace - firstBrace - 2); - // FIXME: Not implemented! Supposed to use wallClock value - } else if (current.contains('.')) { - int dotPosition = current.find('.'); - - String element = current.substring(0, dotPosition); - String clockValue; - if (current.contains("begin")) - clockValue = current.substring(dotPosition + 6); - else if (current.contains("end")) - clockValue = current.substring(dotPosition + 4); - else if (current.contains("repeat")) - clockValue = current.substring(dotPosition + 7); - else { // DOM2 Event Reference - int plusMinusPosition = -1; - - if (current.contains('+')) - plusMinusPosition = current.find('+'); - else if (current.contains('-')) - plusMinusPosition = current.find('-'); - - String event = current.substring(dotPosition + 1, plusMinusPosition - dotPosition - 1); - clockValue = current.substring(dotPosition + event.length() + 1); - // FIXME: supposed to use DOM Event - } - } else { - number = parseClockValue(current); - if (!isIndefinite(number)) - number *= 1000.0; - // FIXME: supposed to set begin/end time + return; +fail: + result.clear(); +} + +static void parseKeySplines(const String& parse, Vector<UnitBezier>& result) +{ + result.clear(); + Vector<String> parseList; + parse.split(';', parseList); + for (unsigned n = 0; n < parseList.size(); ++n) { + Vector<String> parseSpline; + parseList[n].split(',', parseSpline); + // The spec says the sepator is a space, all tests use commas. Weird. + if (parseSpline.size() == 1) + parseList[n].split(' ', parseSpline); + if (parseSpline.size() != 4) + goto fail; + double curveValues[4]; + for (unsigned i = 0; i < 4; ++i) { + String parseNumber = parseSpline[i]; + bool ok; + curveValues[i] = parseNumber.toDouble(&ok); + if (!ok || curveValues[i] < 0.0 || curveValues[i] > 1.0) + goto fail; } - } + result.append(UnitBezier(curveValues[0], curveValues[1], curveValues[2], curveValues[3])); + } + return; +fail: + result.clear(); } void SVGAnimationElement::parseMappedAttribute(MappedAttribute* attr) { - if (attr->name().matches(XLinkNames::hrefAttr)) - m_href = attr->value(); - else if (attr->name() == SVGNames::attributeNameAttr) - m_attributeName = attr->value(); - else if (attr->name() == SVGNames::attributeTypeAttr) { - if (attr->value() == "CSS") - m_attributeType = ATTRIBUTETYPE_CSS; - else if (attr->value() == "XML") - m_attributeType = ATTRIBUTETYPE_XML; - else if (attr->value() == "auto") - m_attributeType = ATTRIBUTETYPE_AUTO; - } else if (attr->name() == SVGNames::beginAttr) - parseBeginOrEndValue(m_begin, attr->value()); - else if (attr->name() == SVGNames::endAttr) - parseBeginOrEndValue(m_end, attr->value()); - else if (attr->name() == SVGNames::durAttr) { - m_simpleDuration = parseClockValue(attr->value()); - if (!isIndefinite(m_simpleDuration)) - m_simpleDuration *= 1000.0; - } else if (attr->name() == SVGNames::minAttr) { - m_min = parseClockValue(attr->value()); - if (!isIndefinite(m_min)) - m_min *= 1000.0; - } else if (attr->name() == SVGNames::maxAttr) { - m_max = parseClockValue(attr->value()); - if (!isIndefinite(m_max)) - m_max *= 1000.0; - } else if (attr->name() == SVGNames::restartAttr) { - if (attr->value() == "whenNotActive") - m_restart = RESTART_WHENNOTACTIVE; - else if (attr->value() == "never") - m_restart = RESTART_NEVER; - else if (attr->value() == "always") - m_restart = RESTART_ALWAYS; - } else if (attr->name() == SVGNames::repeatCountAttr) { - if (attr->value() == "indefinite") - m_repeatCount = DBL_MAX; - else - m_repeatCount = attr->value().toDouble(); - } else if (attr->name() == SVGNames::repeatDurAttr) - m_repeatDur = attr->value(); - else if (attr->name() == SVGNames::fillAttr) { - if (attr->value() == "freeze") - m_fill = FILL_FREEZE; - else if (attr->value() == "remove") - m_fill = FILL_REMOVE; - } else if (attr->name() == SVGNames::calcModeAttr) { - if (attr->value() == "discrete") - m_calcMode = CALCMODE_DISCRETE; - else if (attr->value() == "linear") - m_calcMode = CALCMODE_LINEAR; - else if (attr->value() == "spline") - m_calcMode = CALCMODE_SPLINE; - else if (attr->value() == "paced") - m_calcMode = CALCMODE_PACED; - } else if (attr->name() == SVGNames::valuesAttr) { - m_values.clear(); - m_values = parseDelimitedString(attr->value(), ';'); - } else if (attr->name() == SVGNames::keyTimesAttr) { - m_keyTimes.clear(); - parseKeyNumbers(m_keyTimes, attr->value()); - } else if (attr->name() == SVGNames::keySplinesAttr) { - m_keySplines.clear(); - parseKeySplines(m_keySplines, attr->value()); - } else if (attr->name() == SVGNames::fromAttr) - m_from = attr->value(); - else if (attr->name() == SVGNames::toAttr) - m_to = attr->value(); - else if (attr->name() == SVGNames::byAttr) - m_by = attr->value(); - else if (attr->name() == SVGNames::additiveAttr) { - if (attr->value() == "sum") - m_additive = ADDITIVE_SUM; - else if (attr->value() == "replace") - m_additive = ADDITIVE_REPLACE; - } else if (attr->name() == SVGNames::accumulateAttr) { - if (attr->value() == "sum") - m_accumulate = ACCUMULATE_SUM; - else if (attr->value() == "none") - m_accumulate = ACCUMULATE_NONE; - } else { + if (attr->name() == SVGNames::valuesAttr) + attr->value().string().split(';', m_values); + else if (attr->name() == SVGNames::keyTimesAttr) + parseKeyTimes(attr->value(), m_keyTimes, true); + else if (attr->name() == SVGNames::keyPointsAttr && hasTagName(SVGNames::animateMotionTag)) { + // This is specified to be an animateMotion attribute only but it is simpler to put it here + // where the other timing calculatations are. + parseKeyTimes(attr->value(), m_keyPoints, false); + } else if (attr->name() == SVGNames::keySplinesAttr) + parseKeySplines(attr->value(), m_keySplines); + else { if (SVGTests::parseMappedAttribute(attr)) return; if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) return; - SVGElement::parseMappedAttribute(attr); + SVGSMILElement::parseMappedAttribute(attr); } } -double SVGAnimationElement::parseClockValue(const String& data) +void SVGAnimationElement::attributeChanged(Attribute* attr, bool preserveDecls) { - DeprecatedString parse = data.deprecatedString().stripWhiteSpace(); - - if (parse == "indefinite") // Saves some time... - return DBL_MAX; - - double result; - - int doublePointOne = parse.find(':'); - int doublePointTwo = parse.find(':', doublePointOne + 1); - - if (doublePointOne != -1 && doublePointTwo != -1) { // Spec: "Full clock values" - unsigned int hours = parse.mid(0, 2).toUInt(); - unsigned int minutes = parse.mid(3, 2).toUInt(); - unsigned int seconds = parse.mid(6, 2).toUInt(); - unsigned int milliseconds = 0; - - result = (3600 * hours) + (60 * minutes) + seconds; - - if (parse.find('.') != -1) { - DeprecatedString temp = parse.mid(9, 2); - milliseconds = temp.toUInt(); - result += (milliseconds * (1 / pow(10.0, int(temp.length())))); - } - } else if (doublePointOne != -1 && doublePointTwo == -1) { // Spec: "Partial clock values" - unsigned int minutes = parse.mid(0, 2).toUInt(); - unsigned int seconds = parse.mid(3, 2).toUInt(); - unsigned int milliseconds = 0; - - result = (60 * minutes) + seconds; - - if (parse.find('.') != -1) { - DeprecatedString temp = parse.mid(6, 2); - milliseconds = temp.toUInt(); - result += (milliseconds * (1 / pow(10.0, int(temp.length())))); - } - } else { // Spec: "Timecount values" - int dotPosition = parse.find('.'); - - if (parse.endsWith("h")) { - if (dotPosition == -1) - result = parse.mid(0, parse.length() - 1).toUInt() * 3600; - else { - result = parse.mid(0, dotPosition).toUInt() * 3600; - DeprecatedString temp = parse.mid(dotPosition + 1, parse.length() - dotPosition - 2); - result += (3600.0 * temp.toUInt()) * (1 / pow(10.0, int(temp.length()))); - } - } else if (parse.endsWith("min")) { - if (dotPosition == -1) - result = parse.mid(0, parse.length() - 3).toUInt() * 60; - else { - result = parse.mid(0, dotPosition).toUInt() * 60; - DeprecatedString temp = parse.mid(dotPosition + 1, parse.length() - dotPosition - 4); - result += (60.0 * temp.toUInt()) * (1 / pow(10.0, int(temp.length()))); - } - } else if (parse.endsWith("ms")) { - if (dotPosition == -1) - result = parse.mid(0, parse.length() - 2).toUInt() / 1000.0; - else { - result = parse.mid(0, dotPosition).toUInt() / 1000.0; - DeprecatedString temp = parse.mid(dotPosition + 1, parse.length() - dotPosition - 3); - result += (temp.toUInt() / 1000.0) * (1 / pow(10.0, int(temp.length()))); - } - } else if (parse.endsWith("s")) { - if (dotPosition == -1) - result = parse.mid(0, parse.length() - 1).toUInt(); - else { - result = parse.mid(0, dotPosition).toUInt(); - DeprecatedString temp = parse.mid(dotPosition + 1, parse.length() - dotPosition - 2); - result += temp.toUInt() * (1 / pow(10.0, int(temp.length()))); - } - } else - result = parse.toDouble(); - } - - return result; + // Assumptions may not hold after an attribute change. + m_animationValid = false; + SVGSMILElement::attributeChanged(attr, preserveDecls); } -void SVGAnimationElement::finishParsingChildren() +float SVGAnimationElement::getStartTime() const { - if (ownerSVGElement()) - ownerSVGElement()->timeScheduler()->addTimer(this, lround(getStartTime())); - SVGElement::finishParsingChildren(); + return narrowPrecisionToFloat(intervalBegin().value()); } -String SVGAnimationElement::targetAttributeAnimatedValue() const +float SVGAnimationElement::getCurrentTime() const { - // FIXME: This method is not entirely correct - // It does not properly grab the true "animVal" instead grabs the baseVal (or something very close) - - if (!targetElement()) - return String(); - - SVGElement* target = targetElement(); - SVGStyledElement* styled = 0; - if (target && target->isStyled()) - styled = static_cast<SVGStyledElement*>(target); - - String ret; - - EAttributeType attributeType = static_cast<EAttributeType>(m_attributeType); - if (attributeType == ATTRIBUTETYPE_AUTO) { - attributeType = ATTRIBUTETYPE_XML; - - // Spec: The implementation should match the attributeName to an attribute - // for the target element. The implementation must first search through the - // list of CSS properties for a matching property name, and if none is found, - // search the default XML namespace for the element. - if (styled && styled->style()) { - if (styled->style()->getPropertyCSSValue(m_attributeName)) - attributeType = ATTRIBUTETYPE_CSS; - } - } - - if (attributeType == ATTRIBUTETYPE_CSS) { - if (styled && styled->style()) - ret = styled->style()->getPropertyValue(m_attributeName); - } - - if (attributeType == ATTRIBUTETYPE_XML || ret.isEmpty()) - ret = targetElement()->getAttribute(m_attributeName); - - return ret; + return narrowPrecisionToFloat(elapsed().value()); } -void SVGAnimationElement::setTargetAttributeAnimatedValue(const String& value) +float SVGAnimationElement::getSimpleDuration(ExceptionCode&) const +{ + return narrowPrecisionToFloat(simpleDuration().value()); +} + +bool SVGAnimationElement::beginElement(ExceptionCode& ec) { - // FIXME: This method is not entirely correct - // It does not properly set the "animVal", rather it sets the "baseVal" - SVGAnimationElement::setTargetAttribute(targetElement(), m_attributeName, value, static_cast<EAttributeType>(m_attributeType)); + return beginElementAt(0, ec); } -void SVGAnimationElement::setTargetAttribute(SVGElement* target, const String& name, const String& value, EAttributeType type) +bool SVGAnimationElement::beginElementAt(float offset, ExceptionCode& ec) { - if (!target || name.isNull() || value.isNull()) - return; - - SVGStyledElement* styled = (target && target->isStyled()) ? static_cast<SVGStyledElement*>(target) : 0; - - EAttributeType attributeType = type; - if (type == ATTRIBUTETYPE_AUTO) { - // Spec: The implementation should match the attributeName to an attribute - // for the target element. The implementation must first search through the - // list of CSS properties for a matching property name, and if none is found, - // search the default XML namespace for the element. - if (styled && styled->style() && styled->style()->getPropertyCSSValue(name)) - attributeType = ATTRIBUTETYPE_CSS; - else - attributeType = ATTRIBUTETYPE_XML; - } - ExceptionCode ec = 0; - if (attributeType == ATTRIBUTETYPE_CSS && styled && styled->style()) - styled->style()->setProperty(name, value, "", ec); - else if (attributeType == ATTRIBUTETYPE_XML) - target->setAttribute(name, value, ec); + addBeginTime(elapsed() + offset); + return true; } -String SVGAnimationElement::attributeName() const +bool SVGAnimationElement::endElement(ExceptionCode& ec) { - return m_attributeName; + return endElementAt(0, ec); } -bool SVGAnimationElement::connectedToTimer() const +bool SVGAnimationElement::endElementAt(float offset, ExceptionCode& ec) { - return m_connectedToTimer; + if (offset < 0) + return false; + + addEndTime(elapsed() + offset); + return true; } -bool SVGAnimationElement::isFrozen() const +SVGAnimationElement::AnimationMode SVGAnimationElement::animationMode() const { - return (m_fill == FILL_FREEZE); + // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#AnimFuncValues + if (hasTagName(SVGNames::setTag)) + return ToAnimation; + if (!animationPath().isEmpty()) + return PathAnimation; + if (hasAttribute(SVGNames::valuesAttr)) + return ValuesAnimation; + if (!toValue().isEmpty()) + return fromValue().isEmpty() ? ToAnimation : FromToAnimation; + if (!byValue().isEmpty()) + return fromValue().isEmpty() ? ByAnimation : FromByAnimation; + return NoAnimation; +} + +SVGAnimationElement::CalcMode SVGAnimationElement::calcMode() const +{ + static const AtomicString discrete("discrete"); + static const AtomicString linear("linear"); + static const AtomicString paced("paced"); + static const AtomicString spline("spline"); + const AtomicString& value = getAttribute(SVGNames::calcModeAttr); + if (value == discrete) + return CalcModeDiscrete; + if (value == linear) + return CalcModeLinear; + if (value == paced) + return CalcModePaced; + if (value == spline) + return CalcModeSpline; + return hasTagName(SVGNames::animateMotionTag) ? CalcModePaced : CalcModeLinear; +} + +SVGAnimationElement::AttributeType SVGAnimationElement::attributeType() const +{ + static const AtomicString css("CSS"); + static const AtomicString xml("XML"); + const AtomicString& value = getAttribute(SVGNames::attributeTypeAttr); + if (value == css) + return AttributeTypeCSS; + if (value == xml) + return AttributeTypeXML; + return AttributeTypeAuto; +} + +String SVGAnimationElement::toValue() const +{ + return getAttribute(SVGNames::toAttr); +} + +String SVGAnimationElement::byValue() const +{ + return getAttribute(SVGNames::byAttr); +} + +String SVGAnimationElement::fromValue() const +{ + return getAttribute(SVGNames::fromAttr); } bool SVGAnimationElement::isAdditive() const { - return (m_additive == ADDITIVE_SUM) || (detectAnimationMode() == BY_ANIMATION); + static const AtomicString sum("sum"); + const AtomicString& value = getAttribute(SVGNames::additiveAttr); + return value == sum || animationMode() == ByAnimation; } bool SVGAnimationElement::isAccumulated() const { - return (m_accumulate == ACCUMULATE_SUM) && (detectAnimationMode() != TO_ANIMATION); -} - -EAnimationMode SVGAnimationElement::detectAnimationMode() const -{ - if (hasAttribute(SVGNames::valuesAttr)) - return VALUES_ANIMATION; - else if ((!m_from.isEmpty() && !m_to.isEmpty()) || (!m_to.isEmpty())) { // to/from-to animation - if (!m_from.isEmpty()) // from-to animation - return FROM_TO_ANIMATION; - else - return TO_ANIMATION; - } else if ((m_from.isEmpty() && m_to.isEmpty() && !m_by.isEmpty()) || - (!m_from.isEmpty() && !m_by.isEmpty())) { // by/from-by animation - if (!m_from.isEmpty()) // from-by animation - return FROM_BY_ANIMATION; - else - return BY_ANIMATION; - } - - return NO_ANIMATION; + static const AtomicString sum("sum"); + const AtomicString& value = getAttribute(SVGNames::accumulateAttr); + return value == sum && animationMode() != ToAnimation; } -double SVGAnimationElement::repeations() const +bool SVGAnimationElement::hasValidTarget() const { - return m_repetitions; + return targetElement(); } - -bool SVGAnimationElement::isIndefinite(double value) -{ - return (value == DBL_MAX); + +bool SVGAnimationElement::attributeIsCSS(const String& attributeName) +{ + // FIXME: We should have a map of all SVG properties and their attribute types so we + // could validate animations better. The spec is very vague about this. + unsigned id = cssPropertyID(attributeName); + // SVG range + if (id >= CSSPropertyClipPath && id <= CSSPropertyWritingMode) + return true; + // Regular CSS properties also in SVG + return id == CSSPropertyColor || id == CSSPropertyDisplay || id == CSSPropertyOpacity + || (id >= CSSPropertyFont && id <= CSSPropertyFontWeight) + || id == CSSPropertyOverflow || id == CSSPropertyVisibility; } - -void SVGAnimationElement::connectTimer() + +bool SVGAnimationElement::targetAttributeIsCSS() const { - ASSERT(!m_connectedToTimer); - ownerSVGElement()->timeScheduler()->connectIntervalTimer(this); - m_connectedToTimer = true; + AttributeType type = attributeType(); + if (type == AttributeTypeCSS) + return true; + if (type == AttributeTypeXML) + return false; + return attributeIsCSS(attributeName()); } -void SVGAnimationElement::disconnectTimer() +void SVGAnimationElement::setTargetAttributeAnimatedValue(const String& value) { - ASSERT(m_connectedToTimer); - ownerSVGElement()->timeScheduler()->disconnectIntervalTimer(this); - m_connectedToTimer = false; -} + if (!hasValidTarget()) + return; + SVGElement* target = targetElement(); + String attributeName = this->attributeName(); + if (!target || attributeName.isEmpty() || value.isNull()) + return; -static double calculateTimePercentage(double elapsedSeconds, double start, double end, double duration, double repetitions) -{ - double percentage = 0.0; - double useElapsed = elapsedSeconds - (duration * repetitions); + // We don't want the instance tree to get rebuild. Instances are updated in the loop below. + if (target->isStyled()) + static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(true); + + ExceptionCode ec; + bool isCSS = targetAttributeIsCSS(); + if (isCSS) { + // FIXME: This should set the override style, not the inline style. + // Sadly override styles are not yet implemented. + target->style()->setProperty(attributeName, value, "", ec); + } else { + // FIXME: This should set the 'presentation' value, not the actual + // attribute value. Whatever that means in practice. + target->setAttribute(attributeName, value, ec); + } - if (duration > 0.0 && end == 0.0) - percentage = 1.0 - (((start + duration) - useElapsed) / duration); - else if (duration > 0.0 && end != 0.0) { - if (duration > end) - percentage = 1.0 - (((start + end) - useElapsed) / end); - else - percentage = 1.0 - (((start + duration) - useElapsed) / duration); - } else if (duration == 0.0 && end != 0.0) - percentage = 1.0 - (((start + end) - useElapsed) / end); + if (target->isStyled()) + static_cast<SVGStyledElement*>(target)->setInstanceUpdatesBlocked(false); - return percentage; + // If the target element is used in an <use> instance tree, update that as well. + HashSet<SVGElementInstance*> instances = target->instancesForElement(); + HashSet<SVGElementInstance*>::iterator end = instances.end(); + for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) { + SVGElement* shadowTreeElement = (*it)->shadowTreeElement(); + ASSERT(shadowTreeElement); + if (isCSS) + shadowTreeElement->style()->setProperty(attributeName, value, "", ec); + else + shadowTreeElement->setAttribute(attributeName, value, ec); + (*it)->correspondingUseElement()->setChanged(); + } } - -static inline void adjustPercentagePastForKeySplines(const Vector<SVGAnimationElement::KeySpline>& keySplines, unsigned valueIndex, float& percentagePast) -{ - if (percentagePast == 0.0f) // values at key times need no spline adjustment + +void SVGAnimationElement::calculateKeyTimesForCalcModePaced() +{ + ASSERT(calcMode() == CalcModePaced); + ASSERT(animationMode() == ValuesAnimation); + + unsigned valuesCount = m_values.size(); + ASSERT(valuesCount > 1); + Vector<float> keyTimesForPaced; + float totalDistance = 0; + keyTimesForPaced.append(0); + for (unsigned n = 0; n < valuesCount - 1; ++n) { + // Distance in any units + float distance = calculateDistance(m_values[n], m_values[n + 1]); + if (distance < 0) + return; + totalDistance += distance; + keyTimesForPaced.append(distance); + } + if (!totalDistance) return; - const SVGAnimationElement::KeySpline& keySpline = keySplines[valueIndex]; - Path path; - path.moveTo(FloatPoint()); - path.addBezierCurveTo(keySpline.control1, keySpline.control2, FloatPoint(1.0f, 1.0f)); - // FIXME: This needs to use a y-at-x function on path, to compute the y value then multiply percentagePast by that value -} -void SVGAnimationElement::valueIndexAndPercentagePastForDistance(float distancePercentage, unsigned& valueIndex, float& percentagePast) -{ - // Unspecified: animation elements which do not support CALCMODE_PACED, we just always show the first value - valueIndex = 0; - percentagePast = 0; + // Normalize. + for (unsigned n = 1; n < keyTimesForPaced.size() - 1; ++n) + keyTimesForPaced[n] = keyTimesForPaced[n - 1] + keyTimesForPaced[n] / totalDistance; + keyTimesForPaced[keyTimesForPaced.size() - 1] = 1.f; + + // Use key times calculated based on pacing instead of the user provided ones. + m_keyTimes.swap(keyTimesForPaced); } -float SVGAnimationElement::calculateTotalDistance() +static inline double solveEpsilon(double duration) { return 1. / (200. * duration); } + +float SVGAnimationElement::calculatePercentForSpline(float percent, unsigned splineIndex) const { - return 0; + ASSERT(calcMode() == CalcModeSpline); + ASSERT(splineIndex < m_keySplines.size()); + UnitBezier bezier = m_keySplines[splineIndex]; + SMILTime duration = simpleDuration(); + if (!duration.isFinite()) + duration = 100.0; + return narrowPrecisionToFloat(bezier.solve(percent, solveEpsilon(duration.value()))); } -static inline void caculateValueIndexForKeyTimes(float timePercentage, const Vector<float>& keyTimes, unsigned& valueIndex, float& lastKeyTime, float& nextKeyTime) +float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const { - unsigned keyTimesCountMinusOne = keyTimes.size() - 1; - valueIndex = 0; - ASSERT(timePercentage >= keyTimes.first()); - while ((valueIndex < keyTimesCountMinusOne) && (timePercentage >= keyTimes[valueIndex + 1])) - valueIndex++; + ASSERT(!m_keyPoints.isEmpty()); + ASSERT(calcMode() != CalcModePaced); + unsigned keyTimesCount = m_keyTimes.size(); + ASSERT(keyTimesCount > 1); + ASSERT(m_keyPoints.size() == keyTimesCount); + + unsigned index; + for (index = 1; index < keyTimesCount; ++index) { + if (m_keyTimes[index] >= percent) + break; + } + --index; + + float fromPercent = m_keyTimes[index]; + float toPercent = m_keyTimes[index + 1]; + float fromKeyPoint = m_keyPoints[index]; + float toKeyPoint = m_keyPoints[index + 1]; + + if (calcMode() == CalcModeDiscrete) + return percent == 1.0f ? toKeyPoint : fromKeyPoint; - lastKeyTime = keyTimes[valueIndex]; - if (valueIndex < keyTimesCountMinusOne) - nextKeyTime = keyTimes[valueIndex + 1]; - else - nextKeyTime = lastKeyTime; + float keyPointPercent = percent == 1.0f ? 1.0f : (percent - fromPercent) / (toPercent - fromPercent); + + if (calcMode() == CalcModeSpline) { + ASSERT(m_keySplines.size() == m_keyPoints.size() - 1); + keyPointPercent = calculatePercentForSpline(keyPointPercent, index); + } + return (toKeyPoint - fromKeyPoint) * keyPointPercent + fromKeyPoint; } - -bool SVGAnimationElement::isValidAnimation() const + +void SVGAnimationElement::currentValuesFromKeyPoints(float percent, float& effectivePercent, String& from, String& to) const { - EAnimationMode animationMode = detectAnimationMode(); - if (!hasValidTarget() || (animationMode == NO_ANIMATION)) - return false; - if (animationMode == VALUES_ANIMATION) { - if (!m_values.size()) - return false; - if (m_keyTimes.size()) { - if ((m_values.size() != m_keyTimes.size()) || (m_keyTimes.first() != 0)) - return false; - if (((m_calcMode == CALCMODE_SPLINE) || (m_calcMode == CALCMODE_LINEAR)) && (m_keyTimes.last() != 1)) - return false; - float lastKeyTime = 0; - for (unsigned x = 0; x < m_keyTimes.size(); x++) { - if (m_keyTimes[x] < lastKeyTime || m_keyTimes[x] > 1) - return false; - } - } - if (m_keySplines.size()) { - if ((m_values.size() - 1) != m_keySplines.size()) - return false; - for (unsigned x = 0; x < m_keyTimes.size(); x++) - if (m_keyTimes[x] < 0 || m_keyTimes[x] > 1) - return false; - } - } - return true; + ASSERT(!m_keyPoints.isEmpty()); + ASSERT(m_keyPoints.size() == m_keyTimes.size()); + ASSERT(calcMode() != CalcModePaced); + effectivePercent = calculatePercentFromKeyPoints(percent); + unsigned index = effectivePercent == 1.0f ? m_values.size() - 2 : static_cast<unsigned>(effectivePercent * (m_values.size() - 1)); + from = m_values[index]; + to = m_values[index + 1]; } - -void SVGAnimationElement::calculateValueIndexAndPercentagePast(float timePercentage, unsigned& valueIndex, float& percentagePast) + +void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& effectivePercent, String& from, String& to) const { - ASSERT(timePercentage <= 1.0f); - ASSERT(isValidAnimation()); - EAnimationMode animationMode = detectAnimationMode(); + unsigned valuesCount = m_values.size(); + ASSERT(m_animationValid); + ASSERT(valuesCount > 1); - // to-animations have their own special handling - if (animationMode == TO_ANIMATION) - return; + CalcMode calcMode = this->calcMode(); + if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced) + return currentValuesFromKeyPoints(percent, effectivePercent, from, to); - // paced is special, caculates values based on distance instead of time - if (m_calcMode == CALCMODE_PACED) { - float totalDistance = calculateTotalDistance(); - float distancePercentage = totalDistance * timePercentage; - valueIndexAndPercentagePastForDistance(distancePercentage, valueIndex, percentagePast); - return; + unsigned keyTimesCount = m_keyTimes.size(); + ASSERT(!keyTimesCount || valuesCount == keyTimesCount); + ASSERT(!keyTimesCount || (keyTimesCount > 1 && m_keyTimes[0] == 0)); + + unsigned index; + for (index = 1; index < keyTimesCount; ++index) { + if (m_keyTimes[index] >= percent) + break; } + --index; - // Figure out what our current index is based on on time - // all further calculations are based on time percentages, to allow unifying keyTimes handling & normal animation - float lastKeyTimePercentage = 0; - float nextKeyTimePercentage = 0; - if (m_keyTimes.size() && (m_keyTimes.size() == m_values.size())) - caculateValueIndexForKeyTimes(timePercentage, m_keyTimes, valueIndex, lastKeyTimePercentage, nextKeyTimePercentage); - else { - unsigned lastPossibleIndex = (m_values.size() ? m_values.size() - 1: 1); - unsigned flooredValueIndex = static_cast<unsigned>(timePercentage * lastPossibleIndex); - valueIndex = flooredValueIndex; - lastKeyTimePercentage = flooredValueIndex / (float)lastPossibleIndex; - nextKeyTimePercentage = (flooredValueIndex + 1) / (float)lastPossibleIndex; + if (calcMode == CalcModeDiscrete) { + if (!keyTimesCount) + index = percent == 1.0f ? valuesCount - 1 : static_cast<unsigned>(percent * valuesCount); + from = m_values[index]; + to = m_values[index]; + effectivePercent = 0.0f; + return; } - // No further caculation is needed if we're exactly on an index. - if (timePercentage == lastKeyTimePercentage || lastKeyTimePercentage == nextKeyTimePercentage) { - percentagePast = 0.0f; - return; + float fromPercent; + float toPercent; + if (keyTimesCount) { + fromPercent = m_keyTimes[index]; + toPercent = m_keyTimes[index + 1]; + } else { + index = static_cast<unsigned>(percent * (valuesCount - 1)); + fromPercent = static_cast<float>(index) / (valuesCount - 1); + toPercent = static_cast<float>(index + 1) / (valuesCount - 1); } - // otherwise we decide what percent after that index - if ((m_calcMode == CALCMODE_SPLINE) && (m_keySplines.size() == (m_values.size() - 1))) - adjustPercentagePastForKeySplines(m_keySplines, valueIndex, percentagePast); - else if (m_calcMode == CALCMODE_DISCRETE) - percentagePast = 0.0f; - else { // default (and fallback) mode: linear - float keyTimeSpan = nextKeyTimePercentage - lastKeyTimePercentage; - float timeSinceLastKeyTime = timePercentage - lastKeyTimePercentage; - percentagePast = (timeSinceLastKeyTime / keyTimeSpan); + if (index == valuesCount - 1) + --index; + from = m_values[index]; + to = m_values[index + 1]; + ASSERT(toPercent > fromPercent); + effectivePercent = percent == 1.0f ? 1.0f : (percent - fromPercent) / (toPercent - fromPercent); + + if (calcMode == CalcModeSpline) { + ASSERT(m_keySplines.size() == m_values.size() - 1); + effectivePercent = calculatePercentForSpline(effectivePercent, index); } } - -bool SVGAnimationElement::updateAnimationBaseValueFromElement() + +void SVGAnimationElement::startedActiveInterval() { - m_baseValue = targetAttributeAnimatedValue(); - return true; -} + m_animationValid = false; -void SVGAnimationElement::applyAnimatedValueToElement() -{ - setTargetAttributeAnimatedValue(m_animatedValue); -} + if (!hasValidTarget()) + return; -void SVGAnimationElement::handleTimerEvent(double elapsedSeconds, double timePercentage) -{ - timePercentage = min(timePercentage, 1.0); - if (!connectedToTimer()) { - connectTimer(); + AnimationMode animationMode = this->animationMode(); + if (animationMode == NoAnimation) return; - } - - // FIXME: accumulate="sum" will not work w/o code similar to this: -// if (isAccumulated() && repeations() != 0.0) -// accumulateForRepetitions(m_repetitions); - - EAnimationMode animationMode = detectAnimationMode(); - - unsigned valueIndex = 0; - float percentagePast = 0; - calculateValueIndexAndPercentagePast(narrowPrecisionToFloat(timePercentage), valueIndex, percentagePast); - - calculateFromAndToValues(animationMode, valueIndex); + if (animationMode == FromToAnimation) + m_animationValid = calculateFromAndToValues(fromValue(), toValue()); + else if (animationMode == ToAnimation) { + // For to-animations the from value is the current accumulated value from lower priority animations. + // The value is not static and is determined during the animation. + m_animationValid = calculateFromAndToValues(String(), toValue()); + } else if (animationMode == FromByAnimation) + m_animationValid = calculateFromAndByValues(fromValue(), byValue()); + else if (animationMode == ByAnimation) + m_animationValid = calculateFromAndByValues(String(), byValue()); + else if (animationMode == ValuesAnimation) { + CalcMode calcMode = this->calcMode(); + m_animationValid = m_values.size() > 1 + && (calcMode == CalcModePaced || !hasAttribute(SVGNames::keyTimesAttr) || hasAttribute(SVGNames::keyPointsAttr) || (m_values.size() == m_keyTimes.size())) + && (calcMode == CalcModeDiscrete || !m_keyTimes.size() || m_keyTimes.last() == 1.0) + && (calcMode != CalcModeSpline || (m_keySplines.size() && (m_keySplines.size() == m_values.size() - 1) || m_keySplines.size() == m_keyPoints.size() - 1)) + && (!hasAttribute(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size())); + if (calcMode == CalcModePaced && m_animationValid) + calculateKeyTimesForCalcModePaced(); + } else if (animationMode == PathAnimation) + m_animationValid = calcMode() == CalcModePaced || !hasAttribute(SVGNames::keyPointsAttr) || (m_keyTimes.size() > 1 && m_keyTimes.size() == m_keyPoints.size()); +} - updateAnimatedValue(animationMode, narrowPrecisionToFloat(timePercentage), valueIndex, percentagePast); +void SVGAnimationElement::updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) +{ + if (!m_animationValid) + return; - if (timePercentage == 1.0) { - if ((m_repeatCount > 0 && m_repetitions < m_repeatCount - 1) || isIndefinite(m_repeatCount)) { - m_repetitions++; - return; - } else - disconnectTimer(); - } + float effectivePercent; + if (animationMode() == ValuesAnimation) { + String from; + String to; + currentValuesForValuesAnimation(percent, effectivePercent, from, to); + if (from != m_lastValuesAnimationFrom || to != m_lastValuesAnimationTo ) { + m_animationValid = calculateFromAndToValues(from, to); + if (!m_animationValid) + return; + m_lastValuesAnimationFrom = from; + m_lastValuesAnimationTo = to; + } + } else if (!m_keyPoints.isEmpty() && calcMode() != CalcModePaced) + effectivePercent = calculatePercentFromKeyPoints(percent); + else + effectivePercent = percent; + + calculateAnimatedValue(effectivePercent, repeat, resultElement); } -bool SVGAnimationElement::updateAnimatedValueForElapsedSeconds(double elapsedSeconds) +void SVGAnimationElement::endedActiveInterval() { - // FIXME: fill="freeze" will not work without saving off the m_stoppedTime in a stop() method and having code similar to this: -// if (isStopped()) { -// if (m_fill == FILL_FREEZE) -// elapsedSeconds = m_stoppedTime; -// else -// return false; -// } - - // Validate animation timing settings: - // #1 (duration > 0) -> fine - // #2 (duration <= 0.0 && end > 0) -> fine - if ((m_simpleDuration <= 0.0 && m_end <= 0.0) || (isIndefinite(m_simpleDuration) && m_end <= 0.0)) - return false; // Ignore dur="0" or dur="-neg" - - double percentage = calculateTimePercentage(elapsedSeconds, m_begin, m_end, m_simpleDuration, m_repetitions); - - if (percentage <= 1.0 || connectedToTimer()) - handleTimerEvent(elapsedSeconds, percentage); - - return true; // value was updated, need to apply } } // vim:ts=4:noet -#endif // ENABLE(SVG) +#endif // ENABLE(SVG_ANIMATION) diff --git a/WebCore/svg/SVGAnimationElement.h b/WebCore/svg/SVGAnimationElement.h index 23d1e88..b4d4b78 100644 --- a/WebCore/svg/SVGAnimationElement.h +++ b/WebCore/svg/SVGAnimationElement.h @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> Copyright (C) 2007 Eric Seidel <eric@webkit.org> + Copyright (C) 2008 Apple Inc. All rights reserved. This file is part of the KDE project @@ -23,171 +24,102 @@ #ifndef SVGAnimationElement_h #define SVGAnimationElement_h -#if ENABLE(SVG) +#if ENABLE(SVG_ANIMATION) +#include "ElementTimeControl.h" +#include "Path.h" +#include "SMILTime.h" +#include "SVGSMILElement.h" #include "SVGExternalResourcesRequired.h" #include "SVGStringList.h" #include "SVGTests.h" +#include "UnitBezier.h" namespace WebCore { + + class ConditionEventListener; + class TimeContainer; - enum EFillMode { - FILL_REMOVE = 0, - FILL_FREEZE - }; - - enum EAdditiveMode { - ADDITIVE_REPLACE = 0, - ADDITIVE_SUM - }; - - enum EAccumulateMode { - ACCUMULATE_NONE = 0, - ACCUMULATE_SUM - }; - - enum ECalcMode { - CALCMODE_DISCRETE = 0, - CALCMODE_LINEAR, - CALCMODE_PACED, - CALCMODE_SPLINE - }; - - enum ERestart { - RESTART_ALWAYS = 0, - RESTART_WHENNOTACTIVE, - RESTART_NEVER - }; - - enum EAttributeType { - ATTRIBUTETYPE_CSS = 0, - ATTRIBUTETYPE_XML, - ATTRIBUTETYPE_AUTO - }; - - // internal - enum EAnimationMode { - NO_ANIMATION = 0, - TO_ANIMATION, - BY_ANIMATION, - VALUES_ANIMATION, - FROM_TO_ANIMATION, - FROM_BY_ANIMATION - }; - - class SVGAnimationElement : public SVGElement, + class SVGAnimationElement : public SVGSMILElement, public SVGTests, - public SVGExternalResourcesRequired + public SVGExternalResourcesRequired, + public ElementTimeControl { public: SVGAnimationElement(const QualifiedName&, Document*); virtual ~SVGAnimationElement(); - - // 'SVGAnimationElement' functions - SVGElement* targetElement() const; - - virtual bool hasValidTarget() const; - bool isValidAnimation() const; - virtual bool isValid() const { return SVGTests::isValid(); } + virtual void parseMappedAttribute(MappedAttribute*); + virtual void attributeChanged(Attribute*, bool preserveDecls); - float getEndTime() const; + // SVGAnimationElement float getStartTime() const; float getCurrentTime() const; float getSimpleDuration(ExceptionCode&) const; - - virtual void parseMappedAttribute(MappedAttribute* attr); - - virtual void finishParsingChildren(); - - virtual bool updateAnimationBaseValueFromElement(); - bool updateAnimatedValueForElapsedSeconds(double elapsedSeconds); - virtual void applyAnimatedValueToElement(); - - String attributeName() const; - - bool connectedToTimer() const; - - bool isFrozen() const; - bool isAdditive() const; - bool isAccumulated() const; - - double repeations() const; - static bool isIndefinite(double value); + + // ElementTimeControl + virtual bool beginElement(ExceptionCode&); + virtual bool beginElementAt(float offset, ExceptionCode&); + virtual bool endElement(ExceptionCode&); + virtual bool endElementAt(float offset, ExceptionCode&); + + static bool attributeIsCSS(const String& attributeName); protected: - mutable SVGElement* m_targetElement; + virtual const SVGElement* contextElement() const { return this; } + + enum CalcMode { CalcModeDiscrete, CalcModeLinear, CalcModePaced, CalcModeSpline }; + CalcMode calcMode() const; - EAnimationMode detectAnimationMode() const; + enum AttributeType { AttributeTypeCSS, AttributeTypeXML, AttributeTypeAuto }; + AttributeType attributeType() const; - static double parseClockValue(const String&); - static void setTargetAttribute(SVGElement* target, const String& name, const String& value, EAttributeType = ATTRIBUTETYPE_AUTO); + String toValue() const; + String byValue() const; + String fromValue() const; - String targetAttributeAnimatedValue() const; - void setTargetAttributeAnimatedValue(const String&); - - void connectTimer(); - void disconnectTimer(); + enum AnimationMode { NoAnimation, ToAnimation, ByAnimation, ValuesAnimation, FromToAnimation, FromByAnimation, PathAnimation }; + AnimationMode animationMode() const; - virtual float calculateTotalDistance(); - virtual void valueIndexAndPercentagePastForDistance(float distancePercentage, unsigned& valueIndex, float& percentagePast); - - void calculateValueIndexAndPercentagePast(float timePercentage, unsigned& valueIndex, float& percentagePast); - - void handleTimerEvent(double elapsedSeconds, double timePercentage); + virtual bool hasValidTarget() const; - virtual bool updateAnimatedValue(EAnimationMode, float timePercentage, unsigned valueIndex, float percentagePast) = 0; - virtual bool calculateFromAndToValues(EAnimationMode, unsigned valueIndex) = 0; + String targetAttributeBaseValue() const; + void setTargetAttributeAnimatedValue(const String&); + bool targetAttributeIsCSS() const; - static void parseKeyNumbers(Vector<float>& keyNumbers, const String& value); - static void parseBeginOrEndValue(double& number, const String& value); - - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - bool m_connectedToTimer : 1; + bool isAdditive() const; + bool isAccumulated() const; + + // from SVGSMILElement + virtual void startedActiveInterval(); + virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement); + virtual void endedActiveInterval(); - double m_currentTime; - double m_simpleDuration; - - // Shared animation properties - unsigned m_fill : 1; // EFillMode m_fill - unsigned m_restart : 2; // ERestart - unsigned m_calcMode : 2; // ECalcMode - unsigned m_additive : 1; // EAdditiveMode - unsigned m_accumulate : 1; // EAccumulateMode - unsigned m_attributeType : 2; // EAttributeType + private: + virtual bool calculateFromAndToValues(const String& fromString, const String& toString) = 0; + virtual bool calculateFromAndByValues(const String& fromString, const String& byString) = 0; + virtual void calculateAnimatedValue(float percentage, unsigned repeat, SVGSMILElement* resultElement) = 0; + virtual float calculateDistance(const String& fromString, const String& toString) { return -1.f; } + virtual Path animationPath() const { return Path(); } - String m_to; - String m_by; - String m_from; - String m_href; - String m_repeatDur; - String m_attributeName; + void currentValuesForValuesAnimation(float percent, float& effectivePercent, String& from, String& to) const; + void calculateKeyTimesForCalcModePaced(); + float calculatePercentFromKeyPoints(float percent) const; + void currentValuesFromKeyPoints(float percent, float& effectivePercent, String& from, String& to) const; + float calculatePercentForSpline(float percent, unsigned splineIndex) const; - String m_baseValue; - String m_animatedValue; - - double m_max; - double m_min; - double m_end; - double m_begin; - - double m_repetitions; - double m_repeatCount; + protected: + bool m_animationValid; Vector<String> m_values; Vector<float> m_keyTimes; - - struct KeySpline { - FloatPoint control1; - FloatPoint control2; - }; - Vector<KeySpline> m_keySplines; + Vector<float> m_keyPoints; + Vector<UnitBezier> m_keySplines; + String m_lastValuesAnimationFrom; + String m_lastValuesAnimationTo; }; } // namespace WebCore #endif // ENABLE(SVG) #endif // SVGAnimationElement_h - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGAnimationElement.idl b/WebCore/svg/SVGAnimationElement.idl index 6a9e94f..afa3cbb 100644 --- a/WebCore/svg/SVGAnimationElement.idl +++ b/WebCore/svg/SVGAnimationElement.idl @@ -25,9 +25,10 @@ module svg { - interface [Conditional=SVG] SVGAnimationElement : SVGElement, + interface [Conditional=SVG_ANIMATION] SVGAnimationElement : SVGElement, SVGTests, - SVGExternalResourcesRequired { + SVGExternalResourcesRequired, + ElementTimeControl { readonly attribute SVGElement targetElement; float getStartTime(); diff --git a/WebCore/svg/SVGCircleElement.cpp b/WebCore/svg/SVGCircleElement.cpp index 9d82960..8817506 100644 --- a/WebCore/svg/SVGCircleElement.cpp +++ b/WebCore/svg/SVGCircleElement.cpp @@ -27,6 +27,7 @@ #include "FloatPoint.h" #include "RenderPath.h" +#include "SVGLength.h" #include "SVGNames.h" namespace WebCore { @@ -36,9 +37,9 @@ SVGCircleElement::SVGCircleElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_cx(SVGLength(this, LengthModeWidth)) - , m_cy(SVGLength(this, LengthModeHeight)) - , m_r(SVGLength(this, LengthModeOther)) + , m_cx(this, SVGNames::cxAttr, LengthModeWidth) + , m_cy(this, SVGNames::cyAttr, LengthModeHeight) + , m_r(this, SVGNames::rAttr, LengthModeOther) { } @@ -46,19 +47,15 @@ SVGCircleElement::~SVGCircleElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGCircleElement, SVGLength, Length, length, Cx, cx, SVGNames::cxAttr, m_cx) -ANIMATED_PROPERTY_DEFINITIONS(SVGCircleElement, SVGLength, Length, length, Cy, cy, SVGNames::cyAttr, m_cy) -ANIMATED_PROPERTY_DEFINITIONS(SVGCircleElement, SVGLength, Length, length, R, r, SVGNames::rAttr, m_r) - void SVGCircleElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::cxAttr) - setCxBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setCxBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::cyAttr) - setCyBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setCyBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::rAttr) { - setRBaseValue(SVGLength(this, LengthModeOther, attr->value())); - if (r().value() < 0.0) + setRBaseValue(SVGLength(LengthModeOther, attr->value())); + if (rBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for circle <r> is not allowed"); } else { if (SVGTests::parseMappedAttribute(attr)) @@ -89,7 +86,7 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName) Path SVGCircleElement::toPathData() const { - return Path::createCircle(FloatPoint(cx().value(), cy().value()), r().value()); + return Path::createCircle(FloatPoint(cx().value(this), cy().value(this)), r().value(this)); } bool SVGCircleElement::hasRelativeValues() const diff --git a/WebCore/svg/SVGCircleElement.h b/WebCore/svg/SVGCircleElement.h index 2e0e8c8..598e51f 100644 --- a/WebCore/svg/SVGCircleElement.h +++ b/WebCore/svg/SVGCircleElement.h @@ -51,11 +51,9 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGLength, SVGLength, Cx, cx) - ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGLength, SVGLength, Cy, cy) - ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGLength, SVGLength, R, r) + ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGNames::circleTagString, SVGNames::cxAttrString, SVGLength, Cx, cx) + ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGNames::circleTagString, SVGNames::cyAttrString, SVGLength, Cy, cy) + ANIMATED_PROPERTY_DECLARATIONS(SVGCircleElement, SVGNames::circleTagString, SVGNames::rAttrString, SVGLength, R, r) }; } // namespace WebCore diff --git a/WebCore/svg/SVGClipPathElement.cpp b/WebCore/svg/SVGClipPathElement.cpp index 440c568..a41bb45 100644 --- a/WebCore/svg/SVGClipPathElement.cpp +++ b/WebCore/svg/SVGClipPathElement.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -38,7 +38,7 @@ SVGClipPathElement::SVGClipPathElement(const QualifiedName& tagName, Document* d , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_clipPathUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) + , m_clipPathUnits(this, SVGNames::clipPathUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) { } @@ -46,8 +46,6 @@ SVGClipPathElement::~SVGClipPathElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGClipPathElement, int, Enumeration, enumeration, ClipPathUnits, clipPathUnits, SVGNames::clipPathUnitsAttr, m_clipPathUnits) - void SVGClipPathElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::clipPathUnitsAttr) { @@ -81,9 +79,9 @@ void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName) m_clipper->invalidate(); } -void SVGClipPathElement::childrenChanged(bool changedByParser) +void SVGClipPathElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGStyledTransformableElement::childrenChanged(changedByParser); + SVGStyledTransformableElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!m_clipper) return; @@ -94,23 +92,22 @@ void SVGClipPathElement::childrenChanged(bool changedByParser) SVGResource* SVGClipPathElement::canvasResource() { if (!m_clipper) - m_clipper = new SVGResourceClipper(); + m_clipper = SVGResourceClipper::create(); else m_clipper->resetClipData(); bool bbox = clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; - RenderStyle* clipPathStyle = styleForRenderer(parent()->renderer()); // FIXME: Manual style resolution is a hack + RefPtr<RenderStyle> clipPathStyle = styleForRenderer(); // FIXME: Manual style resolution is a hack for (Node* n = firstChild(); n; n = n->nextSibling()) { if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) { SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(n); - RenderStyle* pathStyle = document()->styleSelector()->styleForElement(styled, clipPathStyle); - Path pathData = styled->toClipPath(); - // FIXME: How do we know the element has done a layout? - pathData.transform(styled->animatedLocalTransform()); - if (!pathData.isEmpty()) - m_clipper->addClipData(pathData, pathStyle->svgStyle()->clipRule(), bbox); - pathStyle->deref(document()->renderArena()); + RefPtr<RenderStyle> pathStyle = document()->styleSelector()->styleForElement(styled, clipPathStyle.get()); + if (pathStyle->display() != NONE) { + Path pathData = styled->toClipPath(); + if (!pathData.isEmpty()) + m_clipper->addClipData(pathData, pathStyle->svgStyle()->clipRule(), bbox); + } } } if (m_clipper->clipData().isEmpty()) { @@ -118,7 +115,6 @@ SVGResource* SVGClipPathElement::canvasResource() pathData.addRect(FloatRect()); m_clipper->addClipData(pathData, RULE_EVENODD, bbox); } - clipPathStyle->deref(document()->renderArena()); return m_clipper.get(); } diff --git a/WebCore/svg/SVGClipPathElement.h b/WebCore/svg/SVGClipPathElement.h index af707f2..ab7ea68 100644 --- a/WebCore/svg/SVGClipPathElement.h +++ b/WebCore/svg/SVGClipPathElement.h @@ -24,9 +24,9 @@ #define SVGClipPathElement_h #if ENABLE(SVG) -#include "SVGResourceClipper.h" #include "SVGExternalResourcesRequired.h" #include "SVGLangSpace.h" +#include "SVGResourceClipper.h" #include "SVGStyledTransformableElement.h" #include "SVGTests.h" @@ -46,7 +46,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual SVGResource* canvasResource(); @@ -54,9 +54,7 @@ namespace WebCore { virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGClipPathElement, int, int, ClipPathUnits, clipPathUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGClipPathElement, SVGNames::clipPathTagString, SVGNames::clipPathUnitsAttrString, int, ClipPathUnits, clipPathUnits) RefPtr<SVGResourceClipper> m_clipper; }; diff --git a/WebCore/svg/SVGColor.cpp b/WebCore/svg/SVGColor.cpp index 12e9739..b56a80e 100644 --- a/WebCore/svg/SVGColor.cpp +++ b/WebCore/svg/SVGColor.cpp @@ -30,27 +30,23 @@ namespace WebCore { SVGColor::SVGColor() - : CSSValue() - , m_colorType(SVG_COLORTYPE_UNKNOWN) + : m_colorType(SVG_COLORTYPE_UNKNOWN) { } SVGColor::SVGColor(const String& rgbColor) - : CSSValue() - , m_colorType(SVG_COLORTYPE_RGBCOLOR) + : m_colorType(SVG_COLORTYPE_RGBCOLOR) { setRGBColor(rgbColor); } -SVGColor::SVGColor(unsigned short colorType) - : CSSValue() - , m_colorType(colorType) +SVGColor::SVGColor(SVGColorType colorType) + : m_colorType(colorType) { } SVGColor::SVGColor(const Color& c) - : CSSValue() - , m_color(c) + : m_color(c) , m_colorType(SVG_COLORTYPE_RGBCOLOR) { } diff --git a/WebCore/svg/SVGColor.h b/WebCore/svg/SVGColor.h index 213b2bc..e3a4b19 100644 --- a/WebCore/svg/SVGColor.h +++ b/WebCore/svg/SVGColor.h @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -26,18 +24,25 @@ #include "CSSValue.h" #include "Color.h" -#include "PlatformString.h" +#include <wtf/PassRefPtr.h> namespace WebCore { - - typedef int ExceptionCode; - + class SVGColor : public CSSValue { public: - SVGColor(); - SVGColor(const String& rgbColor); - SVGColor(const Color& c); - SVGColor(unsigned short colorType); + static PassRefPtr<SVGColor> create(const String& color) + { + return adoptRef(new SVGColor(color)); + } + static PassRefPtr<SVGColor> create(const Color& color) + { + return adoptRef(new SVGColor(color)); + } + static PassRefPtr<SVGColor> createCurrentColor() + { + return adoptRef(new SVGColor(SVG_COLORTYPE_CURRENTCOLOR)); + } + virtual ~SVGColor(); enum SVGColorType { @@ -64,9 +69,18 @@ namespace WebCore { // Helpers const Color& color() const; - virtual bool isSVGColor() const { return true; } + protected: + SVGColor(); + SVGColor(const String& color); + SVGColor(const Color&); private: + SVGColor(SVGColorType); + + static void create(int); // compile-time guard + + virtual bool isSVGColor() const { return true; } + Color m_color; unsigned short m_colorType; }; diff --git a/WebCore/svg/SVGComponentTransferFunctionElement.cpp b/WebCore/svg/SVGComponentTransferFunctionElement.cpp index 07b348d..f2be038 100644 --- a/WebCore/svg/SVGComponentTransferFunctionElement.cpp +++ b/WebCore/svg/SVGComponentTransferFunctionElement.cpp @@ -31,15 +31,17 @@ namespace WebCore { +char SVGComponentTransferFunctionElementIdentifier[] = "SVGComponentTransferFunctionElement"; + SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) - , m_type(SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN) - , m_tableValues(new SVGNumberList) - , m_slope(1.0f) - , m_intercept(0.0f) - , m_amplitude(1.0f) - , m_exponent(1.0f) - , m_offset(0.0f) + , m_type(this, SVGNames::typeAttr, FECOMPONENTTRANSFER_TYPE_UNKNOWN) + , m_tableValues(this, SVGNames::tableValuesAttr, SVGNumberList::create(SVGNames::tableValuesAttr)) + , m_slope(this, SVGNames::slopeAttr, 1.0f) + , m_intercept(this, SVGNames::interceptAttr) + , m_amplitude(this, SVGNames::amplitudeAttr, 1.0f) + , m_exponent(this, SVGNames::exponentAttr, 1.0f) + , m_offset(this, SVGNames::offsetAttr) { } @@ -47,29 +49,21 @@ SVGComponentTransferFunctionElement::~SVGComponentTransferFunctionElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGComponentTransferFunctionElement, int, Enumeration, enumeration, Type, type, SVGNames::typeAttr, m_type) -ANIMATED_PROPERTY_DEFINITIONS(SVGComponentTransferFunctionElement, SVGNumberList*, NumberList, numberList, TableValues, tableValues, SVGNames::tableValuesAttr, m_tableValues.get()) -ANIMATED_PROPERTY_DEFINITIONS(SVGComponentTransferFunctionElement, float, Number, number, Slope, slope, SVGNames::slopeAttr, m_slope) -ANIMATED_PROPERTY_DEFINITIONS(SVGComponentTransferFunctionElement, float, Number, number, Intercept, intercept, SVGNames::interceptAttr, m_intercept) -ANIMATED_PROPERTY_DEFINITIONS(SVGComponentTransferFunctionElement, float, Number, number, Amplitude, amplitude, SVGNames::amplitudeAttr, m_amplitude) -ANIMATED_PROPERTY_DEFINITIONS(SVGComponentTransferFunctionElement, float, Number, number, Exponent, exponent, SVGNames::exponentAttr, m_exponent) -ANIMATED_PROPERTY_DEFINITIONS(SVGComponentTransferFunctionElement, float, Number, number, Offset, offset, SVGNames::offsetAttr, m_offset) - void SVGComponentTransferFunctionElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); if (attr->name() == SVGNames::typeAttr) { if (value == "identity") - setTypeBaseValue(SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY); + setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_IDENTITY); else if (value == "table") - setTypeBaseValue(SVG_FECOMPONENTTRANSFER_TYPE_TABLE); + setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_TABLE); else if (value == "discrete") - setTypeBaseValue(SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE); + setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_DISCRETE); else if (value == "linear") - setTypeBaseValue(SVG_FECOMPONENTTRANSFER_TYPE_LINEAR); + setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_LINEAR); else if (value == "gamma") - setTypeBaseValue(SVG_FECOMPONENTTRANSFER_TYPE_GAMMA); + setTypeBaseValue(FECOMPONENTTRANSFER_TYPE_GAMMA); } else if (attr->name() == SVGNames::tableValuesAttr) tableValuesBaseValue()->parse(value); @@ -87,10 +81,10 @@ void SVGComponentTransferFunctionElement::parseMappedAttribute(MappedAttribute* SVGElement::parseMappedAttribute(attr); } -SVGComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction() const +ComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction() const { - SVGComponentTransferFunction func; - func.type = (SVGComponentTransferType) type(); + ComponentTransferFunction func; + func.type = (ComponentTransferType) type(); func.slope = slope(); func.intercept = intercept(); func.amplitude = amplitude(); diff --git a/WebCore/svg/SVGComponentTransferFunctionElement.h b/WebCore/svg/SVGComponentTransferFunctionElement.h index eadff18..5e20e37f 100644 --- a/WebCore/svg/SVGComponentTransferFunctionElement.h +++ b/WebCore/svg/SVGComponentTransferFunctionElement.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -22,40 +22,36 @@ #ifndef SVGComponentTransferFunctionElement_h #define SVGComponentTransferFunctionElement_h -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) +#if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGElement.h" -#include "SVGFEComponentTransfer.h" +#include "SVGNumberList.h" +#include "FEComponentTransfer.h" -namespace WebCore -{ - class SVGNumberList; +namespace WebCore { - class SVGComponentTransferFunctionElement : public SVGElement - { + extern char SVGComponentTransferFunctionElementIdentifier[]; + + class SVGComponentTransferFunctionElement : public SVGElement { public: SVGComponentTransferFunctionElement(const QualifiedName&, Document*); virtual ~SVGComponentTransferFunctionElement(); - // 'SVGComponentTransferFunctionElement' functions - // Derived from: 'Element' virtual void parseMappedAttribute(MappedAttribute* attr); - SVGComponentTransferFunction transferFunction() const; + ComponentTransferFunction transferFunction() const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, int, int, Type, type) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGNumberList*, RefPtr<SVGNumberList>, TableValues, tableValues) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, float, float, Slope, slope) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, float, float, Intercept, intercept) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, float, float, Amplitude, amplitude) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, float, float, Exponent, exponent) - ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, float, float, Offset, offset) + ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::typeAttrString, int, Type, type) + ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::tableValuesAttrString, SVGNumberList, TableValues, tableValues) + ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::slopeAttrString, float, Slope, slope) + ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::interceptAttrString, float, Intercept, intercept) + ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::amplitudeAttrString, float, Amplitude, amplitude) + ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::exponentAttrString, float, Exponent, exponent) + ANIMATED_PROPERTY_DECLARATIONS(SVGComponentTransferFunctionElement, SVGComponentTransferFunctionElementIdentifier, SVGNames::offsetAttrString, float, Offset, offset) }; } // namespace WebCore #endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGCursorElement.cpp b/WebCore/svg/SVGCursorElement.cpp index 52e2a7c..161a061 100644 --- a/WebCore/svg/SVGCursorElement.cpp +++ b/WebCore/svg/SVGCursorElement.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -26,59 +26,74 @@ #include "SVGCursorElement.h" #include "Attr.h" -#include "CachedImage.h" -#include "Document.h" -#include "DocLoader.h" #include "SVGNames.h" #include "SVGLength.h" namespace WebCore { -SVGCursorElement::SVGCursorElement(const QualifiedName& tagName, Document *doc) +SVGCursorElement::SVGCursorElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) , SVGTests() , SVGExternalResourcesRequired() , SVGURIReference() - , CachedResourceClient() - , m_x(0, LengthModeWidth) - , m_y(0, LengthModeHeight) + , m_x(this, SVGNames::xAttr, LengthModeWidth) + , m_y(this, SVGNames::yAttr, LengthModeHeight) { - m_cachedImage = 0; } SVGCursorElement::~SVGCursorElement() { - if (m_cachedImage) - m_cachedImage->deref(this); } -ANIMATED_PROPERTY_DEFINITIONS(SVGCursorElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGCursorElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) - -void SVGCursorElement::parseMappedAttribute(MappedAttribute *attr) +void SVGCursorElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(0, LengthModeWidth, attr->value())); + setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(0, LengthModeHeight, attr->value())); + setYBaseValue(SVGLength(LengthModeHeight, attr->value())); else { if (SVGTests::parseMappedAttribute(attr)) return; if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) return; - if (SVGURIReference::parseMappedAttribute(attr)) { - if (m_cachedImage) - m_cachedImage->deref(this); - m_cachedImage = ownerDocument()->docLoader()->requestImage(href()); - if (m_cachedImage) - m_cachedImage->ref(this); + if (SVGURIReference::parseMappedAttribute(attr)) return; - } SVGElement::parseMappedAttribute(attr); } } +void SVGCursorElement::addClient(SVGElement* element) +{ + m_clients.add(element); +} + +void SVGCursorElement::removeClient(SVGElement* element) +{ + m_clients.remove(element); +} + +void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGElement::svgAttributeChanged(attrName); + + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || + SVGTests::isKnownAttribute(attrName) || + SVGExternalResourcesRequired::isKnownAttribute(attrName) || + SVGURIReference::isKnownAttribute(attrName)) { + HashSet<SVGElement*>::const_iterator it = m_clients.begin(); + HashSet<SVGElement*>::const_iterator end = m_clients.end(); + + for (; it != end; ++it) + (*it)->setChanged(); + } +} + +void SVGCursorElement::getSubresourceAttributeStrings(Vector<String>& urls) const +{ + urls.append(href()); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGCursorElement.h b/WebCore/svg/SVGCursorElement.h index 2b6181d..d8d7eba 100644 --- a/WebCore/svg/SVGCursorElement.h +++ b/WebCore/svg/SVGCursorElement.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -24,51 +24,43 @@ #define SVGCursorElement_h #if ENABLE(SVG) - -#include "Image.h" - #include "SVGLength.h" #include "SVGElement.h" #include "SVGTests.h" #include "SVGURIReference.h" #include "SVGExternalResourcesRequired.h" -#include "CachedResourceClient.h" -namespace WebCore -{ +namespace WebCore { + class SVGCursorElement : public SVGElement, - public SVGTests, - public SVGExternalResourcesRequired, - public SVGURIReference, - public CachedResourceClient - { + public SVGTests, + public SVGExternalResourcesRequired, + public SVGURIReference { public: SVGCursorElement(const QualifiedName&, Document*); virtual ~SVGCursorElement(); - + + void addClient(SVGElement*); + void removeClient(SVGElement*); + virtual bool isValid() const { return SVGTests::isValid(); } - // 'SVGCursorElement' functions - virtual void parseMappedAttribute(MappedAttribute *attr); + virtual void parseMappedAttribute(MappedAttribute*); + virtual void svgAttributeChanged(const QualifiedName&); - CachedImage* cachedImage() const { return m_cachedImage; } + virtual void getSubresourceAttributeStrings(Vector<String>&) const; protected: virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - - ANIMATED_PROPERTY_DECLARATIONS(SVGCursorElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGCursorElement, SVGLength, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGCursorElement, SVGNames::cursorTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGCursorElement, SVGNames::cursorTagString, SVGNames::yAttrString, SVGLength, Y, y) - CachedImage *m_cachedImage; + HashSet<SVGElement*> m_clients; }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGDefinitionSrcElement.cpp b/WebCore/svg/SVGDefinitionSrcElement.cpp index 848ba20..1419ec0 100644 --- a/WebCore/svg/SVGDefinitionSrcElement.cpp +++ b/WebCore/svg/SVGDefinitionSrcElement.cpp @@ -32,9 +32,9 @@ SVGDefinitionSrcElement::SVGDefinitionSrcElement(const QualifiedName& tagName, D { } -void SVGDefinitionSrcElement::childrenChanged(bool changedByParser) +void SVGDefinitionSrcElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGElement::childrenChanged(changedByParser); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (parentNode() && parentNode()->hasTagName(SVGNames::font_faceTag)) static_cast<SVGFontFaceElement*>(parentNode())->rebuildFontFace(); } diff --git a/WebCore/svg/SVGDefinitionSrcElement.h b/WebCore/svg/SVGDefinitionSrcElement.h index 111fd86..aaefd05 100644 --- a/WebCore/svg/SVGDefinitionSrcElement.h +++ b/WebCore/svg/SVGDefinitionSrcElement.h @@ -28,7 +28,7 @@ namespace WebCore { public: SVGDefinitionSrcElement(const QualifiedName&, Document*); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); }; } // namespace WebCore diff --git a/WebCore/svg/SVGDefsElement.cpp b/WebCore/svg/SVGDefsElement.cpp index 6e5e541..b084bb2 100644 --- a/WebCore/svg/SVGDefsElement.cpp +++ b/WebCore/svg/SVGDefsElement.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -21,6 +21,7 @@ */ #include "config.h" + #if ENABLE(SVG) #include "SVGDefsElement.h" @@ -45,13 +46,11 @@ bool SVGDefsElement::isValid() const return SVGTests::isValid(); } -RenderObject* SVGDefsElement::createRenderer(RenderArena* arena, RenderStyle* style) +RenderObject* SVGDefsElement::createRenderer(RenderArena* arena, RenderStyle*) { return new (arena) RenderSVGHiddenContainer(this); } } -// vim:ts=4:noet #endif // ENABLE(SVG) - diff --git a/WebCore/svg/SVGDefsElement.h b/WebCore/svg/SVGDefsElement.h index b594ed3..c4cac62 100644 --- a/WebCore/svg/SVGDefsElement.h +++ b/WebCore/svg/SVGDefsElement.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -22,38 +22,32 @@ #ifndef SVGDefsElement_h #define SVGDefsElement_h -#if ENABLE(SVG) +#if ENABLE(SVG) #include "SVGExternalResourcesRequired.h" #include "SVGLangSpace.h" #include "SVGStyledTransformableElement.h" #include "SVGTests.h" -namespace WebCore -{ +namespace WebCore { + class SVGDefsElement : public SVGStyledTransformableElement, public SVGTests, public SVGLangSpace, - public SVGExternalResourcesRequired - { + public SVGExternalResourcesRequired { public: SVGDefsElement(const QualifiedName&, Document*); virtual ~SVGDefsElement(); - + virtual bool isValid() const; - + virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - + protected: virtual const SVGElement* contextElement() const { return this; } - - private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGDescElement.h b/WebCore/svg/SVGDescElement.h index a2244c6..c8bc501 100644 --- a/WebCore/svg/SVGDescElement.h +++ b/WebCore/svg/SVGDescElement.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -22,16 +22,15 @@ #ifndef SVGDescElement_h #define SVGDescElement_h -#if ENABLE(SVG) +#if ENABLE(SVG) #include "SVGLangSpace.h" #include "SVGStyledElement.h" -namespace WebCore -{ +namespace WebCore { + class SVGDescElement : public SVGStyledElement, - public SVGLangSpace - { + public SVGLangSpace { public: SVGDescElement(const QualifiedName&, Document*); virtual ~SVGDescElement(); @@ -45,5 +44,3 @@ namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGDocument.cpp b/WebCore/svg/SVGDocument.cpp index f347b4d..9244873 100644 --- a/WebCore/svg/SVGDocument.cpp +++ b/WebCore/svg/SVGDocument.cpp @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -37,8 +35,8 @@ namespace WebCore { -SVGDocument::SVGDocument(DOMImplementation* i, Frame* frame) - : Document(i, frame) +SVGDocument::SVGDocument(Frame* frame) + : Document(frame, false) { } @@ -59,7 +57,7 @@ void SVGDocument::dispatchZoomEvent(float prevScale, float newScale) { ExceptionCode ec = 0; RefPtr<SVGZoomEvent> event = static_pointer_cast<SVGZoomEvent>(createEvent("SVGZoomEvents", ec)); - event->initEvent(EventNames::zoomEvent, true, false); + event->initEvent(eventNames().zoomEvent, true, false); event->setPreviousScale(prevScale); event->setNewScale(newScale); rootElement()->dispatchEvent(event.release(), ec); @@ -69,7 +67,7 @@ void SVGDocument::dispatchScrollEvent() { ExceptionCode ec = 0; RefPtr<Event> event = createEvent("SVGEvents", ec); - event->initEvent(EventNames::scrollEvent, true, false); + event->initEvent(eventNames().scrollEvent, true, false); rootElement()->dispatchEvent(event.release(), ec); } diff --git a/WebCore/svg/SVGDocument.h b/WebCore/svg/SVGDocument.h index f8bcdbf..1411017 100644 --- a/WebCore/svg/SVGDocument.h +++ b/WebCore/svg/SVGDocument.h @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -35,7 +33,11 @@ namespace WebCore { class SVGDocument : public Document { public: - SVGDocument(DOMImplementation*, Frame*); + static PassRefPtr<SVGDocument> create(Frame* frame) + { + return new SVGDocument(frame); + } + virtual ~SVGDocument(); virtual bool isSVGDocument() const { return true; } @@ -51,6 +53,8 @@ namespace WebCore { void updatePan(const FloatPoint& pos) const; private: + SVGDocument(Frame*); + FloatPoint m_translate; }; diff --git a/WebCore/svg/SVGDocumentExtensions.cpp b/WebCore/svg/SVGDocumentExtensions.cpp index 46a27c7..d7169e1 100644 --- a/WebCore/svg/SVGDocumentExtensions.cpp +++ b/WebCore/svg/SVGDocumentExtensions.cpp @@ -27,16 +27,17 @@ #include "SVGDocumentExtensions.h" #include "AtomicString.h" -#include "Chrome.h" +#include "Console.h" +#include "DOMWindow.h" #include "Document.h" #include "EventListener.h" #include "Frame.h" #include "FrameLoader.h" #include "Page.h" #include "SVGSVGElement.h" -#include "TimeScheduler.h" +#include "SMILTimeContainer.h" #include "XMLTokenizer.h" -#include "kjs_proxy.h" +#include "ScriptController.h" namespace WebCore { @@ -48,15 +49,6 @@ SVGDocumentExtensions::SVGDocumentExtensions(Document* doc) SVGDocumentExtensions::~SVGDocumentExtensions() { deleteAllValues(m_pendingResources); - deleteAllValues(m_elementInstances); -} - -PassRefPtr<EventListener> SVGDocumentExtensions::createSVGEventListener(const String& functionName, const String& code, Node *node) -{ - if (Frame* frame = m_doc->frame()) - if (frame->scriptProxy()->isEnabled()) - return frame->scriptProxy()->createSVGEventHandler(functionName, code, node); - return 0; } void SVGDocumentExtensions::addTimeContainer(SVGSVGElement* element) @@ -76,7 +68,7 @@ void SVGDocumentExtensions::startAnimations() #if ENABLE(SVG_ANIMATION) HashSet<SVGSVGElement*>::iterator end = m_timeContainers.end(); for (HashSet<SVGSVGElement*>::iterator itr = m_timeContainers.begin(); itr != end; ++itr) - (*itr)->timeScheduler()->startAnimations(); + (*itr)->timeContainer()->begin(); #endif } @@ -97,15 +89,13 @@ void SVGDocumentExtensions::unpauseAnimations() void SVGDocumentExtensions::reportWarning(const String& message) { if (Frame* frame = m_doc->frame()) - if (Page* page = frame->page()) - page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, "Warning: " + message, m_doc->tokenizer() ? m_doc->tokenizer()->lineNumber() : 1, String()); + frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, "Warning: " + message, m_doc->tokenizer() ? m_doc->tokenizer()->lineNumber() : 1, String()); } void SVGDocumentExtensions::reportError(const String& message) { if (Frame* frame = m_doc->frame()) - if (Page* page = frame->page()) - page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, "Error: " + message, m_doc->tokenizer() ? m_doc->tokenizer()->lineNumber() : 1, String()); + frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, "Error: " + message, m_doc->tokenizer() ? m_doc->tokenizer()->lineNumber() : 1, String()); } void SVGDocumentExtensions::addPendingResource(const AtomicString& id, SVGStyledElement* obj) @@ -142,37 +132,6 @@ std::auto_ptr<HashSet<SVGStyledElement*> > SVGDocumentExtensions::removePendingR return set; } -void SVGDocumentExtensions::mapInstanceToElement(SVGElementInstance* instance, SVGElement* element) -{ - ASSERT(instance); - ASSERT(element); - - if (m_elementInstances.contains(element)) - m_elementInstances.get(element)->add(instance); - else { - HashSet<SVGElementInstance*>* set = new HashSet<SVGElementInstance*>(); - set->add(instance); - - m_elementInstances.add(element, set); - } -} - -void SVGDocumentExtensions::removeInstanceMapping(SVGElementInstance* instance, SVGElement* element) -{ - ASSERT(instance); - - if (!m_elementInstances.contains(element)) - return; - - m_elementInstances.get(element)->remove(instance); -} - -HashSet<SVGElementInstance*>* SVGDocumentExtensions::instancesForElement(SVGElement* element) const -{ - ASSERT(element); - return m_elementInstances.get(element); -} - } #endif diff --git a/WebCore/svg/SVGDocumentExtensions.h b/WebCore/svg/SVGDocumentExtensions.h index 0b1ed89..cd20a30 100644 --- a/WebCore/svg/SVGDocumentExtensions.h +++ b/WebCore/svg/SVGDocumentExtensions.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006 Apple Computer, Inc. - 2006 Nikolas Zimmermann <zimmermann@kde.org> + 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> This file is part of the WebKit project @@ -24,37 +24,30 @@ #define SVGDocumentExtensions_h #if ENABLE(SVG) - #include <memory> -#include <wtf/Forward.h> + #include <wtf/HashSet.h> #include <wtf/HashMap.h> -#include "FloatRect.h" #include "StringHash.h" #include "StringImpl.h" -#include "AtomicString.h" +#include "SVGAnimatedTemplate.h" namespace WebCore { -class AtomicString; class Document; class EventListener; class Node; class String; -class SVGElement; class SVGElementInstance; class SVGStyledElement; class SVGSVGElement; -class TimeScheduler; class SVGDocumentExtensions { public: SVGDocumentExtensions(Document*); ~SVGDocumentExtensions(); - PassRefPtr<EventListener> createSVGEventListener(const String& functionName, const String& code, Node*); - void addTimeContainer(SVGSVGElement*); void removeTimeContainer(SVGSVGElement*); @@ -69,7 +62,6 @@ private: Document* m_doc; // weak reference HashSet<SVGSVGElement*> m_timeContainers; // For SVG 1.2 support this will need to be made more general. HashMap<String, HashSet<SVGStyledElement*>*> m_pendingResources; - HashMap<SVGElement*, HashSet<SVGElementInstance*>*> m_elementInstances; SVGDocumentExtensions(const SVGDocumentExtensions&); SVGDocumentExtensions& operator=(const SVGDocumentExtensions&); @@ -89,12 +81,6 @@ public: bool isPendingResource(const AtomicString& id) const; std::auto_ptr<HashSet<SVGStyledElement*> > removePendingResource(const AtomicString& id); - // This HashMap maps elements to their instances, when they are used by <use> elements. - // This is needed to synchronize the original element with the internally cloned one. - void mapInstanceToElement(SVGElementInstance*, SVGElement*); - void removeInstanceMapping(SVGElementInstance*, SVGElement*); - HashSet<SVGElementInstance*>* instancesForElement(SVGElement*) const; - // Used by the ANIMATED_PROPERTY_* macros template<typename ValueType> ValueType baseValue(const SVGElement* element, const AtomicString& propertyName) const @@ -103,7 +89,7 @@ public: if (propertyMap) return propertyMap->get(propertyName.impl()); - return 0; + return SVGAnimatedTypeValue<ValueType>::null(); } template<typename ValueType> @@ -139,52 +125,7 @@ public: } }; -// Special handling for WebCore::String -template<> -inline String SVGDocumentExtensions::baseValue<String>(const SVGElement* element, const AtomicString& propertyName) const -{ - HashMap<StringImpl*, String>* propertyMap = baseValueMap<String>()->get(element); - if (propertyMap) - return propertyMap->get(propertyName.impl()); - - return String(); -} - -// Special handling for WebCore::FloatRect -template<> -inline FloatRect SVGDocumentExtensions::baseValue<FloatRect>(const SVGElement* element, const AtomicString& propertyName) const -{ - HashMap<StringImpl*, FloatRect>* propertyMap = baseValueMap<FloatRect>()->get(element); - if (propertyMap) - return propertyMap->get(propertyName.impl()); - - return FloatRect(); -} - -// Special handling for booleans -template<> -inline bool SVGDocumentExtensions::baseValue<bool>(const SVGElement* element, const AtomicString& propertyName) const -{ - HashMap<StringImpl*, bool>* propertyMap = baseValueMap<bool>()->get(element); - if (propertyMap) - return propertyMap->get(propertyName.impl()); - - return false; -} - -// Special handling for doubles -template<> -inline double SVGDocumentExtensions::baseValue<double>(const SVGElement* element, const AtomicString& propertyName) const -{ - HashMap<StringImpl*, double>* propertyMap = baseValueMap<double>()->get(element); - if (propertyMap) - return propertyMap->get(propertyName.impl()); - - return 0.0; -} - } #endif // ENABLE(SVG) - #endif diff --git a/WebCore/svg/SVGElement.cpp b/WebCore/svg/SVGElement.cpp index ecf9736..9ecfe7d 100644 --- a/WebCore/svg/SVGElement.cpp +++ b/WebCore/svg/SVGElement.cpp @@ -1,8 +1,8 @@ /* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> - - This file is part of the KDE project + Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> + Copyright (C) 2008 Apple Inc. All rights reserved. + Copyright (C) 2008 Alp Toker <alp@atoker.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -37,15 +37,16 @@ #include "SVGDocumentExtensions.h" #include "SVGElementInstance.h" #include "SVGNames.h" +#include "SVGResource.h" #include "SVGSVGElement.h" #include "SVGURIReference.h" #include "SVGUseElement.h" #include "XMLNames.h" +#include "RegisteredEventListener.h" namespace WebCore { using namespace HTMLNames; -using namespace EventNames; SVGElement::SVGElement(const QualifiedName& tagName, Document* doc) : StyledElement(tagName, doc) @@ -59,10 +60,7 @@ SVGElement::~SVGElement() bool SVGElement::isSupported(StringImpl* feature, StringImpl* version) const { - if (DOMImplementation::instance()->hasFeature(feature, version)) - return true; - - return DOMImplementation::instance()->hasFeature(feature, version); + return DOMImplementation::hasFeature(feature, version); } String SVGElement::id() const @@ -87,12 +85,12 @@ void SVGElement::setXmlbase(const String& value, ExceptionCode&) SVGSVGElement* SVGElement::ownerSVGElement() const { - Node* n = parentNode(); + Node* n = isShadowNode() ? const_cast<SVGElement*>(this)->shadowParentNode() : parentNode(); while (n) { if (n->hasTagName(SVGNames::svgTag)) return static_cast<SVGSVGElement*>(n); - n = n->parentNode(); + n = n->isShadowNode() ? n->shadowParentNode() : n->parentNode(); } return 0; @@ -113,35 +111,56 @@ SVGElement* SVGElement::viewportElement() const return 0; } -void SVGElement::addSVGEventListener(const AtomicString& eventType, const Attribute* attr) +SVGDocumentExtensions* SVGElement::accessDocumentSVGExtensions() const +{ + + // This function is provided for use by SVGAnimatedProperty to avoid + // global inclusion of Document.h in SVG code. + return document() ? document()->accessSVGExtensions() : 0; +} + +void SVGElement::mapInstanceToElement(SVGElementInstance* instance) { - Element::setHTMLEventListener(eventType, document()->accessSVGExtensions()-> - createSVGEventListener(attr->localName().domString(), attr->value(), this)); + ASSERT(instance); + ASSERT(!m_elementInstances.contains(instance)); + m_elementInstances.add(instance); +} + +void SVGElement::removeInstanceMapping(SVGElementInstance* instance) +{ + ASSERT(instance); + ASSERT(m_elementInstances.contains(instance)); + m_elementInstances.remove(instance); +} + +HashSet<SVGElementInstance*> SVGElement::instancesForElement() const +{ + return m_elementInstances; } void SVGElement::parseMappedAttribute(MappedAttribute* attr) { // standard events if (attr->name() == onloadAttr) - addSVGEventListener(loadEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().loadEvent, attr); else if (attr->name() == onclickAttr) - addSVGEventListener(clickEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().clickEvent, attr); else if (attr->name() == onmousedownAttr) - addSVGEventListener(mousedownEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().mousedownEvent, attr); else if (attr->name() == onmousemoveAttr) - addSVGEventListener(mousemoveEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().mousemoveEvent, attr); else if (attr->name() == onmouseoutAttr) - addSVGEventListener(mouseoutEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().mouseoutEvent, attr); else if (attr->name() == onmouseoverAttr) - addSVGEventListener(mouseoverEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().mouseoverEvent, attr); else if (attr->name() == onmouseupAttr) - addSVGEventListener(mouseupEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().mouseupEvent, attr); else if (attr->name() == SVGNames::onfocusinAttr) - addSVGEventListener(DOMFocusInEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().DOMFocusInEvent, attr); else if (attr->name() == SVGNames::onfocusoutAttr) - addSVGEventListener(DOMFocusOutEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().DOMFocusOutEvent, attr); else if (attr->name() == SVGNames::onactivateAttr) - addSVGEventListener(DOMActivateEvent, attr); + setInlineEventListenerForTypeAndAttribute(eventNames().DOMActivateEvent, attr); else StyledElement::parseMappedAttribute(attr); } @@ -157,6 +176,24 @@ bool SVGElement::haveLoadedRequiredResources() return true; } +static bool hasLoadListener(SVGElement* node) +{ + Node* currentNode = node; + while (currentNode && currentNode->isElementNode()) { + RegisteredEventListenerList *list = static_cast<Element*>(currentNode)->localEventListeners(); + if (list) { + RegisteredEventListenerList::Iterator end = list->end(); + for (RegisteredEventListenerList::Iterator it = list->begin(); it != end; ++it) + if ((*it)->eventType() == eventNames().loadEvent && + (*it)->useCapture() == true || currentNode == node) + return true; + } + currentNode = currentNode->parentNode(); + } + + return false; +} + void SVGElement::sendSVGLoadEventIfPossible(bool sendParentLoadEvents) { RefPtr<SVGElement> currentTarget = this; @@ -164,18 +201,20 @@ void SVGElement::sendSVGLoadEventIfPossible(bool sendParentLoadEvents) RefPtr<Node> parent; if (sendParentLoadEvents) parent = currentTarget->parentNode(); // save the next parent to dispatch too incase dispatching the event changes the tree - - // FIXME: This malloc could be avoided by walking the tree first to check if any listeners are present: http://bugs.webkit.org/show_bug.cgi?id=10264 - RefPtr<Event> event = new Event(loadEvent, false, false); - event->setTarget(currentTarget); - ExceptionCode ignored = 0; - dispatchGenericEvent(this, event.release(), ignored, false); + if (hasLoadListener(currentTarget.get())) { + RefPtr<Event> event = Event::create(eventNames().loadEvent, false, false); + event->setTarget(currentTarget); + ExceptionCode ignored = 0; + currentTarget->dispatchGenericEvent(event.release(), ignored); + } currentTarget = (parent && parent->isSVGElement()) ? static_pointer_cast<SVGElement>(parent) : 0; } } void SVGElement::finishParsingChildren() { + StyledElement::finishParsingChildren(); + // finishParsingChildren() is called when the close tag is reached for an element (e.g. </svg>) // we send SVGLoad events here if we can, otherwise they'll be sent when any required loads finish sendSVGLoadEventIfPossible(); @@ -209,49 +248,37 @@ void SVGElement::insertedIntoDocument() } } -static Node* shadowTreeParentElementForShadowTreeElement(Node* node) +void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls) { - for (Node* n = node; n; n = n->parentNode()) { - if (n->isShadowNode()) - return n->shadowParentNode(); - } + ASSERT(attr); + if (!attr) + return; - return 0; + StyledElement::attributeChanged(attr, preserveDecls); + svgAttributeChanged(attr->name()); } -bool SVGElement::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool tempEvent) +void SVGElement::updateAnimatedSVGAttribute(const String& name) const { - // TODO: This function will be removed in a follow-up patch! - - EventTarget* target = this; - Node* useNode = shadowTreeParentElementForShadowTreeElement(this); - - // If we are a hidden shadow tree element, the target must - // point to our corresponding SVGElementInstance object - if (useNode) { - ASSERT(useNode->hasTagName(SVGNames::useTag)); - SVGUseElement* use = static_cast<SVGUseElement*>(useNode); + ASSERT(!m_areSVGAttributesValid); - SVGElementInstance* instance = use->instanceForShadowTreeElement(this); + if (m_synchronizingSVGAttributes) + return; - if (instance) - target = instance; - } + m_synchronizingSVGAttributes = true; - e->setTarget(target); + if (name.isEmpty()) { + invokeAllSVGPropertySynchronizers(); + setSynchronizedSVGAttributes(true); + } else + invokeSVGPropertySynchronizer(name); - RefPtr<FrameView> view = document()->view(); - return EventTargetNode::dispatchGenericEvent(this, e, ec, tempEvent); + m_synchronizingSVGAttributes = false; } -void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls) +void SVGElement::setSynchronizedSVGAttributes(bool value) const { - ASSERT(attr); - if (!attr) - return; - - StyledElement::attributeChanged(attr, preserveDecls); - svgAttributeChanged(attr->name()); + m_areSVGAttributesValid = value; } } diff --git a/WebCore/svg/SVGElement.h b/WebCore/svg/SVGElement.h index a4672be..0223bf7 100644 --- a/WebCore/svg/SVGElement.h +++ b/WebCore/svg/SVGElement.h @@ -24,160 +24,16 @@ #define SVGElement_h #if ENABLE(SVG) -#include "Document.h" -#include "FloatRect.h" #include "StyledElement.h" -#include "SVGAnimatedTemplate.h" -#include "SVGDocumentExtensions.h" +#include "SVGAnimatedProperty.h" #include "SVGNames.h" -#define ANIMATED_PROPERTY_EMPTY_DECLARATIONS(BareType, NullType, UpperProperty, LowerProperty) \ -public: \ - virtual BareType LowerProperty() const { ASSERT_NOT_REACHED(); return NullType; } \ - virtual void set##UpperProperty(BareType newValue) { ASSERT_NOT_REACHED(); }\ - virtual BareType LowerProperty##BaseValue() const { ASSERT_NOT_REACHED(); return NullType; } \ - virtual void set##UpperProperty##BaseValue(BareType newValue) { ASSERT_NOT_REACHED(); } \ - virtual void start##UpperProperty() const { ASSERT_NOT_REACHED(); } \ - virtual void stop##UpperProperty() { ASSERT_NOT_REACHED(); } - -#define ANIMATED_PROPERTY_FORWARD_DECLARATIONS(ForwardClass, BareType, UpperProperty, LowerProperty) \ -public: \ - virtual BareType LowerProperty() const { return ForwardClass::LowerProperty(); } \ - virtual void set##UpperProperty(BareType newValue) { ForwardClass::set##UpperProperty(newValue); } \ - virtual BareType LowerProperty##BaseValue() const { return ForwardClass::LowerProperty##BaseValue(); } \ - virtual void set##UpperProperty##BaseValue(BareType newValue) { ForwardClass::set##UpperProperty##BaseValue(newValue); } \ - virtual void start##UpperProperty() const { ForwardClass::start##UpperProperty(); } \ - virtual void stop##UpperProperty() { ForwardClass::stop##UpperProperty(); } - -#define ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(ClassType, ClassStorageType, BareType, StorageType, UpperProperty, LowerProperty) \ -class SVGAnimatedTemplate##UpperProperty \ -: public SVGAnimatedTemplate<BareType> \ -{ \ -public: \ - SVGAnimatedTemplate##UpperProperty(const ClassType*, const QualifiedName&); \ - virtual ~SVGAnimatedTemplate##UpperProperty() { } \ - virtual BareType baseVal() const; \ - virtual void setBaseVal(BareType); \ - virtual BareType animVal() const; \ - virtual void setAnimVal(BareType); \ - \ -protected: \ - ClassStorageType m_element; \ -}; \ -public: \ - BareType LowerProperty() const; \ - void set##UpperProperty(BareType); \ - BareType LowerProperty##BaseValue() const; \ - void set##UpperProperty##BaseValue(BareType); \ - PassRefPtr<SVGAnimatedTemplate##UpperProperty> LowerProperty##Animated() const; \ - void start##UpperProperty() const; \ - void stop##UpperProperty(); \ -\ -private: \ - StorageType m_##LowerProperty; - -#define ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassType, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter, ContextElement) \ -ClassName::SVGAnimatedTemplate##UpperProperty::SVGAnimatedTemplate##UpperProperty(const ClassType* element, const QualifiedName& attributeName) \ -: SVGAnimatedTemplate<BareType>(attributeName), m_element(const_cast<ClassType*>(element)) { } \ -\ -BareType ClassName::SVGAnimatedTemplate##UpperProperty::baseVal() const \ -{ \ - return m_element->LowerProperty##BaseValue(); \ -} \ -void ClassName::SVGAnimatedTemplate##UpperProperty::setBaseVal(BareType newBaseVal) \ -{ \ - m_element->set##UpperProperty##BaseValue(newBaseVal); \ -} \ -BareType ClassName::SVGAnimatedTemplate##UpperProperty::animVal() const \ -{ \ - return m_element->LowerProperty(); \ -} \ -void ClassName::SVGAnimatedTemplate##UpperProperty::setAnimVal(BareType newAnimVal) \ -{ \ - m_element->set##UpperProperty(newAnimVal); \ -} \ -BareType ClassName::LowerProperty() const \ -{ \ - return StorageGetter; \ -} \ -void ClassName::set##UpperProperty(BareType newValue) \ -{ \ - m_##LowerProperty = newValue; \ -} \ -BareType ClassName::LowerProperty##BaseValue() const \ -{ \ - const SVGElement* context = ContextElement; \ - ASSERT(context); \ - SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \ - if (extensions && extensions->hasBaseValue<BareType>(context, AttrName)) \ - return extensions->baseValue<BareType>(context, AttrName); \ - return LowerProperty(); \ -} \ -void ClassName::set##UpperProperty##BaseValue(BareType newValue) \ -{ \ - const SVGElement* context = ContextElement; \ - ASSERT(context); \ - SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \ - if (extensions && extensions->hasBaseValue<BareType>(context, AttrName)) { \ - extensions->setBaseValue<BareType>(context, AttrName, newValue); \ - return; \ - } \ - /* Only update stored property, if not animating */ \ - set##UpperProperty(newValue); \ -} \ -\ -void ClassName::start##UpperProperty() const \ -{ \ - const SVGElement* context = ContextElement; \ - ASSERT(context); \ - SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \ - if (extensions) { \ - ASSERT(!extensions->hasBaseValue<BareType>(context, AttrName)); \ - extensions->setBaseValue<BareType>(context, AttrName, LowerProperty()); \ - } \ -} \ -\ -void ClassName::stop##UpperProperty() \ -{ \ - const SVGElement* context = ContextElement; \ - ASSERT(context); \ - SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \ - if (extensions) { \ - ASSERT(extensions->hasBaseValue<BareType>(context, AttrName)); \ - set##UpperProperty(extensions->baseValue<BareType>(context, AttrName)); \ - extensions->removeBaseValue<BareType>(context, AttrName); \ - } \ -} - -// These are the macros which will be used to declare/implement the svg animated properties... -#define ANIMATED_PROPERTY_DECLARATIONS_WITH_CONTEXT(ClassName, BareType, StorageType, UpperProperty, LowerProperty) \ -ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(SVGElement, RefPtr<SVGElement>, BareType, StorageType, UpperProperty, LowerProperty) - -#define ANIMATED_PROPERTY_DECLARATIONS(ClassName, BareType, StorageType, UpperProperty, LowerProperty) \ -ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(ClassName, RefPtr<ClassName>, BareType, StorageType, UpperProperty, LowerProperty) - -#define ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \ -ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, SVGElement, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName.localName(), StorageGetter, contextElement()) \ -PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \ -{ \ - const SVGElement* context = contextElement(); \ - ASSERT(context); \ - return lookupOrCreateWrapper<ClassName::SVGAnimatedTemplate##UpperProperty, SVGElement>(context, AttrName, AttrName.localName()); \ -} - -#define ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, AttrIdentifier, StorageGetter) \ -ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName.localName(), StorageGetter, this) \ -PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \ -{ \ - return lookupOrCreateWrapper<ClassName::SVGAnimatedTemplate##UpperProperty, ClassName>(this, AttrName, AttrIdentifier); \ -} - -#define ANIMATED_PROPERTY_DEFINITIONS(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \ -ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, AttrName.localName(), StorageGetter) - namespace WebCore { - class SVGPreserveAspectRatio; + class AffineTransform; + class Document; + class SVGElementInstance; + class SVGDocumentExtensions; class SVGSVGElement; class SVGElement : public StyledElement { @@ -194,6 +50,7 @@ namespace WebCore { SVGSVGElement* ownerSVGElement() const; SVGElement* viewportElement() const; + SVGDocumentExtensions* accessDocumentSVGExtensions() const; virtual void parseMappedAttribute(MappedAttribute*); @@ -224,26 +81,54 @@ namespace WebCore { virtual void attributeChanged(Attribute*, bool preserveDecls = false); void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false); + + virtual AffineTransform* supplementalTransform() { return 0; } + + virtual void updateAnimatedSVGAttribute(const String&) const; + virtual void setSynchronizedSVGAttributes(bool) const; + + HashSet<SVGElementInstance*> instancesForElement() const; + + // Inlined methods handling SVG property synchronization + void invokeSVGPropertySynchronizer(const String& name) const + { + if (m_svgPropertyMap.contains(name)) { + const SVGAnimatedPropertyBase* property = m_svgPropertyMap.get(name); + ASSERT(property); + + property->synchronize(); + } + } + + void invokeAllSVGPropertySynchronizers() const + { + HashMap<String, const SVGAnimatedPropertyBase*>::const_iterator it = m_svgPropertyMap.begin(); + const HashMap<String, const SVGAnimatedPropertyBase*>::const_iterator end = m_svgPropertyMap.end(); + for (; it != end; ++it) { + const SVGAnimatedPropertyBase* property = it->second; + ASSERT(property); + + property->synchronize(); + } + } + + void addSVGPropertySynchronizer(const QualifiedName& attrName, const SVGAnimatedPropertyBase& base) const + { + m_svgPropertyMap.set(attrName.localName(), &base); + } - // Forwarded properties (declared/defined anywhere else in the inheritance structure) - - // -> For SVGURIReference - ANIMATED_PROPERTY_EMPTY_DECLARATIONS(String, String(), Href, href) - - // -> For SVGFitToViewBox - ANIMATED_PROPERTY_EMPTY_DECLARATIONS(FloatRect, FloatRect(), ViewBox, viewBox) - ANIMATED_PROPERTY_EMPTY_DECLARATIONS(SVGPreserveAspectRatio*, 0, PreserveAspectRatio, preserveAspectRatio) - - // -> For SVGExternalResourcesRequired - ANIMATED_PROPERTY_EMPTY_DECLARATIONS(bool, false, ExternalResourcesRequired, externalResourcesRequired) + private: + friend class SVGElementInstance; - virtual bool dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool tempEvent = false); + void mapInstanceToElement(SVGElementInstance*); + void removeInstanceMapping(SVGElementInstance*); - private: - void addSVGEventListener(const AtomicString& eventType, const Attribute*); virtual bool haveLoadedRequiredResources(); Node* m_shadowParent; + mutable HashMap<String, const SVGAnimatedPropertyBase*> m_svgPropertyMap; + + HashSet<SVGElementInstance*> m_elementInstances; }; } // namespace WebCore diff --git a/WebCore/svg/SVGElementInstance.cpp b/WebCore/svg/SVGElementInstance.cpp index 766720a..e548900 100644 --- a/WebCore/svg/SVGElementInstance.cpp +++ b/WebCore/svg/SVGElementInstance.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> This file is part of the KDE project @@ -24,21 +24,29 @@ #if ENABLE(SVG) #include "SVGElementInstance.h" +#include "ContainerNodeAlgorithms.h" +#include "Document.h" #include "Event.h" +#include "EventException.h" #include "EventListener.h" +#include "EventNames.h" +#include "FrameView.h" +#include "GCController.h" #include "SVGElementInstanceList.h" #include "SVGUseElement.h" -#include <wtf/Assertions.h> +#include <wtf/RefCountedLeakCounter.h> namespace WebCore { -SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement) - : m_refCount(0) - , m_parent(0) +#ifndef NDEBUG +static WTF::RefCountedLeakCounter instanceCounter("WebCoreSVGElementInstance"); +#endif + +SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, SVGElement* originalElement) + : m_needsUpdate(false) , m_useElement(useElement) , m_element(originalElement) - , m_shadowTreeElement(0) , m_previousSibling(0) , m_nextSibling(0) , m_firstChild(0) @@ -48,161 +56,517 @@ SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVG ASSERT(m_element); // Register as instance for passed element. - m_element->document()->accessSVGExtensions()->mapInstanceToElement(this, m_element.get()); + m_element->mapInstanceToElement(this); + +#ifndef NDEBUG + instanceCounter.increment(); +#endif } SVGElementInstance::~SVGElementInstance() { - for (RefPtr<SVGElementInstance> child = m_firstChild; child; child = child->m_nextSibling) - child->setParent(0); +#ifndef NDEBUG + instanceCounter.decrement(); +#endif // Deregister as instance for passed element. - m_element->document()->accessSVGExtensions()->removeInstanceMapping(this, m_element.get()); + m_element->removeInstanceMapping(this); + + removeAllChildrenInContainer<SVGElementInstance, SVGElementInstance>(this); } -SVGElement* SVGElementInstance::correspondingElement() const +PassRefPtr<SVGElementInstanceList> SVGElementInstance::childNodes() { - return m_element.get(); + return SVGElementInstanceList::create(this); } -SVGUseElement* SVGElementInstance::correspondingUseElement() const +void SVGElementInstance::setShadowTreeElement(SVGElement* element) { - return m_useElement; + ASSERT(element); + m_shadowTreeElement = element; } -SVGElementInstance* SVGElementInstance::parentNode() const +void SVGElementInstance::forgetWrapper() { - return parent(); + // FIXME: This is fragile, as discussed with Sam. Need to find a better solution. + // Think about the case where JS explicitely holds "var root = useElement.instanceRoot;". + // We still have to recreate this wrapper somehow. The gc collection below, won't catch it. + + // If the use shadow tree has been rebuilt, just the JSSVGElementInstance objects + // are still holding RefPtrs of SVGElementInstance objects, which prevent us to + // be deleted (and the shadow tree is not destructed as well). Force JS GC. + gcController().garbageCollectNow(); } -PassRefPtr<SVGElementInstanceList> SVGElementInstance::childNodes() +void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child) { - return new SVGElementInstanceList(this); + appendChildToContainer<SVGElementInstance, SVGElementInstance>(child.get(), this); } -SVGElementInstance* SVGElementInstance::previousSibling() const +void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element) { - return m_previousSibling; + if (!element) + return; + + HashSet<SVGElementInstance*> set = element->instancesForElement(); + if (set.isEmpty()) + return; + + // Find all use elements referencing the instances - ask them _once_ to rebuild. + HashSet<SVGElementInstance*>::const_iterator it = set.begin(); + const HashSet<SVGElementInstance*>::const_iterator end = set.end(); + + for (; it != end; ++it) + (*it)->setNeedsUpdate(true); } -SVGElementInstance* SVGElementInstance::nextSibling() const +void SVGElementInstance::setNeedsUpdate(bool value) { - return m_nextSibling; + m_needsUpdate = value; + + if (m_needsUpdate) + correspondingUseElement()->setChanged(); } -SVGElementInstance* SVGElementInstance::firstChild() const +ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const { - return m_firstChild; + if (SVGElement* element = correspondingElement()) + return element->scriptExecutionContext(); + return 0; } -SVGElementInstance* SVGElementInstance::lastChild() const +void SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture) { - return m_lastChild; + if (SVGElement* element = correspondingElement()) + element->addEventListener(eventType, listener, useCapture); } -SVGElement* SVGElementInstance::shadowTreeElement() const +void SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture) { - return m_shadowTreeElement; + if (SVGElement* element = correspondingElement()) + element->removeEventListener(eventType, listener, useCapture); } -void SVGElementInstance::setShadowTreeElement(SVGElement* element) +bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec) { - ASSERT(element); - m_shadowTreeElement = element; + RefPtr<Event> evt(e); + ASSERT(!eventDispatchForbidden()); + if (!evt || evt->type().isEmpty()) { + ec = EventException::UNSPECIFIED_EVENT_TYPE_ERR; + return false; + } + + // The event has to be dispatched to the shadowTreeElement(), not the correspondingElement()! + SVGElement* element = shadowTreeElement(); + if (!element) + return false; + + evt->setTarget(this); + + RefPtr<FrameView> view = element->document()->view(); + return element->dispatchGenericEvent(evt.release(), ec); } -void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child) +EventListener* SVGElementInstance::onabort() const { - child->setParent(this); + return correspondingElement()->inlineEventListenerForType(eventNames().abortEvent); +} - if (m_lastChild) { - child->m_previousSibling = m_lastChild; - m_lastChild->m_nextSibling = child.get(); - } else - m_firstChild = child.get(); +void SVGElementInstance::setOnabort(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().abortEvent, eventListener); +} - m_lastChild = child.get(); +EventListener* SVGElementInstance::onblur() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().blurEvent); } -// Helper function for updateInstance -static bool containsUseChildNode(Node* start) +void SVGElementInstance::setOnblur(PassRefPtr<EventListener> eventListener) { - if (start->hasTagName(SVGNames::useTag)) - return true; + correspondingElement()->setInlineEventListenerForType(eventNames().blurEvent, eventListener); +} - for (Node* current = start->firstChild(); current; current = current->nextSibling()) { - if (containsUseChildNode(current)) - return true; - } +EventListener* SVGElementInstance::onchange() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().changeEvent); +} - return false; +void SVGElementInstance::setOnchange(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().changeEvent, eventListener); } -void SVGElementInstance::updateInstance(SVGElement* element) +EventListener* SVGElementInstance::onclick() const { - ASSERT(element == m_element); - ASSERT(m_shadowTreeElement); + return correspondingElement()->inlineEventListenerForType(eventNames().clickEvent); +} - // TODO: Eventually come up with a more optimized updating logic for the cases below: - // - // <symbol>: We can't just clone the original element, we need to apply - // the same "replace by generated content" logic that SVGUseElement does. - // - // <svg>: <use> on <svg> is too rare to actually implement it faster. - // If someone still wants to do it: recloning, adjusting width/height attributes is enough. - // - // <use>: Too hard to get it right in a fast way. Recloning seems the only option. +void SVGElementInstance::setOnclick(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().clickEvent, eventListener); +} - if (m_element->hasTagName(SVGNames::symbolTag) || - m_element->hasTagName(SVGNames::svgTag) || - containsUseChildNode(m_element.get())) { - m_useElement->buildPendingResource(); - return; - } +EventListener* SVGElementInstance::oncontextmenu() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().contextmenuEvent); +} - // For all other nodes this logic is sufficient. - RefPtr<Node> clone = m_element->cloneNode(true); - SVGElement* svgClone = 0; - if (clone && clone->isSVGElement()) - svgClone = static_cast<SVGElement*>(clone.get()); - ASSERT(svgClone); +void SVGElementInstance::setOncontextmenu(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().contextmenuEvent, eventListener); +} - // Replace node in the <use> shadow tree - ExceptionCode ec = 0; - m_shadowTreeElement->parentNode()->replaceChild(clone.release(), m_shadowTreeElement, ec); - ASSERT(ec == 0); +EventListener* SVGElementInstance::ondblclick() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().dblclickEvent); +} - m_shadowTreeElement = svgClone; +void SVGElementInstance::setOndblclick(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().dblclickEvent, eventListener); } -SVGElementInstance* SVGElementInstance::toSVGElementInstance() +EventListener* SVGElementInstance::onerror() const { - return this; + return correspondingElement()->inlineEventListenerForType(eventNames().errorEvent); } -EventTargetNode* SVGElementInstance::toNode() +void SVGElementInstance::setOnerror(PassRefPtr<EventListener> eventListener) { - return m_element.get(); + correspondingElement()->setInlineEventListenerForType(eventNames().errorEvent, eventListener); } -void SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> eventListener, bool useCapture) +EventListener* SVGElementInstance::onfocus() const { - // FIXME! + return correspondingElement()->inlineEventListenerForType(eventNames().focusEvent); } -void SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* eventListener, bool useCapture) +void SVGElementInstance::setOnfocus(PassRefPtr<EventListener> eventListener) { - // FIXME! + correspondingElement()->setInlineEventListenerForType(eventNames().focusEvent, eventListener); } -bool SVGElementInstance::dispatchEvent(PassRefPtr<Event>, ExceptionCode& ec, bool tempEvent) +EventListener* SVGElementInstance::oninput() const { - // FIXME! - return false; + return correspondingElement()->inlineEventListenerForType(eventNames().inputEvent); } - + +void SVGElementInstance::setOninput(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().inputEvent, eventListener); } -#endif // ENABLE(SVG) +EventListener* SVGElementInstance::onkeydown() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().keydownEvent); +} + +void SVGElementInstance::setOnkeydown(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().keydownEvent, eventListener); +} + +EventListener* SVGElementInstance::onkeypress() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().keypressEvent); +} + +void SVGElementInstance::setOnkeypress(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().keypressEvent, eventListener); +} + +EventListener* SVGElementInstance::onkeyup() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().keyupEvent); +} + +void SVGElementInstance::setOnkeyup(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().keyupEvent, eventListener); +} + +EventListener* SVGElementInstance::onload() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().loadEvent); +} + +void SVGElementInstance::setOnload(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().loadEvent, eventListener); +} + +EventListener* SVGElementInstance::onmousedown() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().mousedownEvent); +} + +void SVGElementInstance::setOnmousedown(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().mousedownEvent, eventListener); +} + +EventListener* SVGElementInstance::onmousemove() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().mousemoveEvent); +} + +void SVGElementInstance::setOnmousemove(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().mousemoveEvent, eventListener); +} + +EventListener* SVGElementInstance::onmouseout() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().mouseoutEvent); +} + +void SVGElementInstance::setOnmouseout(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().mouseoutEvent, eventListener); +} + +EventListener* SVGElementInstance::onmouseover() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().mouseoverEvent); +} + +void SVGElementInstance::setOnmouseover(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().mouseoverEvent, eventListener); +} + +EventListener* SVGElementInstance::onmouseup() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().mouseupEvent); +} + +void SVGElementInstance::setOnmouseup(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().mouseupEvent, eventListener); +} + +EventListener* SVGElementInstance::onmousewheel() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().mousewheelEvent); +} + +void SVGElementInstance::setOnmousewheel(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().mousewheelEvent, eventListener); +} + +EventListener* SVGElementInstance::onbeforecut() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().beforecutEvent); +} + +void SVGElementInstance::setOnbeforecut(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().beforecutEvent, eventListener); +} + +EventListener* SVGElementInstance::oncut() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().cutEvent); +} + +void SVGElementInstance::setOncut(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().cutEvent, eventListener); +} -// vim:ts=4:noet +EventListener* SVGElementInstance::onbeforecopy() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().beforecopyEvent); +} + +void SVGElementInstance::setOnbeforecopy(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().beforecopyEvent, eventListener); +} + +EventListener* SVGElementInstance::oncopy() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().copyEvent); +} + +void SVGElementInstance::setOncopy(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().copyEvent, eventListener); +} + +EventListener* SVGElementInstance::onbeforepaste() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().beforepasteEvent); +} + +void SVGElementInstance::setOnbeforepaste(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().beforepasteEvent, eventListener); +} + +EventListener* SVGElementInstance::onpaste() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().pasteEvent); +} + +void SVGElementInstance::setOnpaste(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().pasteEvent, eventListener); +} + +EventListener* SVGElementInstance::ondragenter() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().dragenterEvent); +} + +void SVGElementInstance::setOndragenter(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().dragenterEvent, eventListener); +} + +EventListener* SVGElementInstance::ondragover() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().dragoverEvent); +} + +void SVGElementInstance::setOndragover(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().dragoverEvent, eventListener); +} + +EventListener* SVGElementInstance::ondragleave() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().dragleaveEvent); +} + +void SVGElementInstance::setOndragleave(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().dragleaveEvent, eventListener); +} + +EventListener* SVGElementInstance::ondrop() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().dropEvent); +} + +void SVGElementInstance::setOndrop(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().dropEvent, eventListener); +} + +EventListener* SVGElementInstance::ondragstart() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().dragstartEvent); +} + +void SVGElementInstance::setOndragstart(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().dragstartEvent, eventListener); +} + +EventListener* SVGElementInstance::ondrag() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().dragEvent); +} + +void SVGElementInstance::setOndrag(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().dragEvent, eventListener); +} + +EventListener* SVGElementInstance::ondragend() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().dragendEvent); +} + +void SVGElementInstance::setOndragend(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().dragendEvent, eventListener); +} + +EventListener* SVGElementInstance::onreset() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().resetEvent); +} + +void SVGElementInstance::setOnreset(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().resetEvent, eventListener); +} + +EventListener* SVGElementInstance::onresize() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().resizeEvent); +} + +void SVGElementInstance::setOnresize(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().resizeEvent, eventListener); +} + +EventListener* SVGElementInstance::onscroll() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().scrollEvent); +} + +void SVGElementInstance::setOnscroll(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().scrollEvent, eventListener); +} + +EventListener* SVGElementInstance::onsearch() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().searchEvent); +} + +void SVGElementInstance::setOnsearch(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().searchEvent, eventListener); +} + +EventListener* SVGElementInstance::onselect() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().selectEvent); +} + +void SVGElementInstance::setOnselect(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().selectEvent, eventListener); +} + +EventListener* SVGElementInstance::onselectstart() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().selectstartEvent); +} + +void SVGElementInstance::setOnselectstart(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().selectstartEvent, eventListener); +} + +EventListener* SVGElementInstance::onsubmit() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().submitEvent); +} + +void SVGElementInstance::setOnsubmit(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().submitEvent, eventListener); +} + +EventListener* SVGElementInstance::onunload() const +{ + return correspondingElement()->inlineEventListenerForType(eventNames().unloadEvent); +} + +void SVGElementInstance::setOnunload(PassRefPtr<EventListener> eventListener) +{ + correspondingElement()->setInlineEventListenerForType(eventNames().unloadEvent, eventListener); +} + +} + +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGElementInstance.h b/WebCore/svg/SVGElementInstance.h index 0e74812..261d34a 100644 --- a/WebCore/svg/SVGElementInstance.h +++ b/WebCore/svg/SVGElementInstance.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> This file is part of the KDE project @@ -23,75 +23,180 @@ #define SVGElementInstance_h #if ENABLE(SVG) - #include "EventTarget.h" +#include "SVGElement.h" +#include "TreeShared.h" #include <wtf/RefPtr.h> #include <wtf/PassRefPtr.h> namespace WebCore { - class SVGElement; + + namespace Private { + template<class GenericNode, class GenericNodeContainer> + void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container); + }; + + class EventListener; + class Frame; class SVGUseElement; class SVGElementInstanceList; - class SVGElementInstance : public EventTarget { + // SVGElementInstance mimics Node, but without providing all its functionality + class SVGElementInstance : public TreeShared<SVGElementInstance>, + public EventTarget + { public: - SVGElementInstance(SVGUseElement*, PassRefPtr<SVGElement> originalElement); + SVGElementInstance(SVGUseElement*, SVGElement* originalElement); virtual ~SVGElementInstance(); - // 'SVGElementInstance' functions - SVGElement* correspondingElement() const; - SVGUseElement* correspondingUseElement() const; + bool needsUpdate() const { return m_needsUpdate; } + void setNeedsUpdate(bool); + + virtual ScriptExecutionContext* scriptExecutionContext() const; + + virtual EventTargetNode* toNode() { return shadowTreeElement(); } + virtual SVGElementInstance* toSVGElementInstance() { return this; } + + virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); + virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); + virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&); + + SVGElement* correspondingElement() const { return m_element.get(); } + SVGUseElement* correspondingUseElement() const { return m_useElement; } + SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); } - SVGElementInstance* parentNode() const; + SVGElementInstance* parentNode() const { return parent(); } PassRefPtr<SVGElementInstanceList> childNodes(); - SVGElementInstance* previousSibling() const; - SVGElementInstance* nextSibling() const; + SVGElementInstance* previousSibling() const { return m_previousSibling; } + SVGElementInstance* nextSibling() const { return m_nextSibling; } + + SVGElementInstance* firstChild() const { return m_firstChild; } + SVGElementInstance* lastChild() const { return m_lastChild; } + + Document* ownerDocument() const { return m_element ? m_element->ownerDocument() : 0; } + + static void invalidateAllInstancesOfElement(SVGElement*); + + using TreeShared<SVGElementInstance>::ref; + using TreeShared<SVGElementInstance>::deref; + + // EventTarget API + EventListener* onabort() const; + void setOnabort(PassRefPtr<EventListener>); + EventListener* onblur() const; + void setOnblur(PassRefPtr<EventListener>); + EventListener* onchange() const; + void setOnchange(PassRefPtr<EventListener>); + EventListener* onclick() const; + void setOnclick(PassRefPtr<EventListener>); + EventListener* oncontextmenu() const; + void setOncontextmenu(PassRefPtr<EventListener>); + EventListener* ondblclick() const; + void setOndblclick(PassRefPtr<EventListener>); + EventListener* onerror() const; + void setOnerror(PassRefPtr<EventListener>); + EventListener* onfocus() const; + void setOnfocus(PassRefPtr<EventListener>); + EventListener* oninput() const; + void setOninput(PassRefPtr<EventListener>); + EventListener* onkeydown() const; + void setOnkeydown(PassRefPtr<EventListener>); + EventListener* onkeypress() const; + void setOnkeypress(PassRefPtr<EventListener>); + EventListener* onkeyup() const; + void setOnkeyup(PassRefPtr<EventListener>); + EventListener* onload() const; + void setOnload(PassRefPtr<EventListener>); + EventListener* onmousedown() const; + void setOnmousedown(PassRefPtr<EventListener>); + EventListener* onmousemove() const; + void setOnmousemove(PassRefPtr<EventListener>); + EventListener* onmouseout() const; + void setOnmouseout(PassRefPtr<EventListener>); + EventListener* onmouseover() const; + void setOnmouseover(PassRefPtr<EventListener>); + EventListener* onmouseup() const; + void setOnmouseup(PassRefPtr<EventListener>); + EventListener* onmousewheel() const; + void setOnmousewheel(PassRefPtr<EventListener>); + EventListener* onbeforecut() const; + void setOnbeforecut(PassRefPtr<EventListener>); + EventListener* oncut() const; + void setOncut(PassRefPtr<EventListener>); + EventListener* onbeforecopy() const; + void setOnbeforecopy(PassRefPtr<EventListener>); + EventListener* oncopy() const; + void setOncopy(PassRefPtr<EventListener>); + EventListener* onbeforepaste() const; + void setOnbeforepaste(PassRefPtr<EventListener>); + EventListener* onpaste() const; + void setOnpaste(PassRefPtr<EventListener>); + EventListener* ondragenter() const; + void setOndragenter(PassRefPtr<EventListener>); + EventListener* ondragover() const; + void setOndragover(PassRefPtr<EventListener>); + EventListener* ondragleave() const; + void setOndragleave(PassRefPtr<EventListener>); + EventListener* ondrop() const; + void setOndrop(PassRefPtr<EventListener>); + EventListener* ondragstart() const; + void setOndragstart(PassRefPtr<EventListener>); + EventListener* ondrag() const; + void setOndrag(PassRefPtr<EventListener>); + EventListener* ondragend() const; + void setOndragend(PassRefPtr<EventListener>); + EventListener* onreset() const; + void setOnreset(PassRefPtr<EventListener>); + EventListener* onresize() const; + void setOnresize(PassRefPtr<EventListener>); + EventListener* onscroll() const; + void setOnscroll(PassRefPtr<EventListener>); + EventListener* onsearch() const; + void setOnsearch(PassRefPtr<EventListener>); + EventListener* onselect() const; + void setOnselect(PassRefPtr<EventListener>); + EventListener* onselectstart() const; + void setOnselectstart(PassRefPtr<EventListener>); + EventListener* onsubmit() const; + void setOnsubmit(PassRefPtr<EventListener>); + EventListener* onunload() const; + void setOnunload(PassRefPtr<EventListener>); - SVGElementInstance* firstChild() const; - SVGElementInstance* lastChild() const; + private: + friend class SVGUseElement; - // Internal usage only! - SVGElement* shadowTreeElement() const; + void appendChild(PassRefPtr<SVGElementInstance> child); void setShadowTreeElement(SVGElement*); + void forgetWrapper(); - // Model the TreeShared concept, integrated within EventTarget inheritance. - virtual void refEventTarget() { ++m_refCount; } - virtual void derefEventTarget() { if (--m_refCount <= 0 && !m_parent) delete this; } + template<class GenericNode, class GenericNodeContainer> + friend void appendChildToContainer(GenericNode* child, GenericNodeContainer* container); - bool hasOneRef() { return m_refCount == 1; } - int refCount() const { return m_refCount; } + template<class GenericNode, class GenericNodeContainer> + friend void removeAllChildrenInContainer(GenericNodeContainer* container); - void setParent(SVGElementInstance* parent) { m_parent = parent; } - SVGElementInstance* parent() const { return m_parent; } + template<class GenericNode, class GenericNodeContainer> + friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer* container); - // SVGElementInstance supports both toSVGElementInstance and toNode since so much mouse handling code depends on toNode returning a valid node. - virtual EventTargetNode* toNode(); - virtual SVGElementInstance* toSVGElementInstance(); + bool hasChildNodes() const { return m_firstChild; } - virtual void addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture); - virtual void removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture); - virtual bool dispatchEvent(PassRefPtr<Event>, ExceptionCode&, bool tempEvent = false); - - private: - SVGElementInstance(const SVGElementInstance&); - SVGElementInstance& operator=(const SVGElementInstance&); + void setFirstChild(SVGElementInstance* child) { m_firstChild = child; } + void setLastChild(SVGElementInstance* child) { m_lastChild = child; } - private: // Helper methods - friend class SVGUseElement; - void appendChild(PassRefPtr<SVGElementInstance> child); + void setNextSibling(SVGElementInstance* sibling) { m_nextSibling = sibling; } + void setPreviousSibling(SVGElementInstance* sibling) { m_previousSibling = sibling; } - friend class SVGStyledElement; - void updateInstance(SVGElement*); + virtual void refEventTarget() { ref(); } + virtual void derefEventTarget() { deref(); } private: - int m_refCount; - SVGElementInstance* m_parent; + bool m_needsUpdate : 1; SVGUseElement* m_useElement; RefPtr<SVGElement> m_element; - SVGElement* m_shadowTreeElement; + RefPtr<SVGElement> m_shadowTreeElement; SVGElementInstance* m_previousSibling; SVGElementInstance* m_nextSibling; @@ -104,5 +209,3 @@ namespace WebCore { #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGElementInstance.idl b/WebCore/svg/SVGElementInstance.idl index fb54e90..92da5a6 100644 --- a/WebCore/svg/SVGElementInstance.idl +++ b/WebCore/svg/SVGElementInstance.idl @@ -1,5 +1,6 @@ /* - * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,7 +25,19 @@ */ module svg { - interface [Conditional=SVG] SVGElementInstance { + + interface [ + Conditional=SVG, + ObjCCustomInternalImpl, + CustomListeners, + CustomPushEventHandlerScope, + GenerateToJS, + GenerateNativeConverter + ] SVGElementInstance +#if defined(LANGUAGE_OBJECTIVE_C) + : Object, EventTarget +#endif /* defined(LANGUAGE_OBJECTIVE_C) */ + { readonly attribute SVGElement correspondingElement; readonly attribute SVGUseElement correspondingUseElement; readonly attribute SVGElementInstance parentNode; @@ -34,16 +47,57 @@ module svg { readonly attribute SVGElementInstance previousSibling; readonly attribute SVGElementInstance nextSibling; -#if defined(LANGUAGE_OBJECTIVE_JAVASCRIPT) - // A manual copy of the EventTarget interface - including it in - // the class inheritance above gives troubles. This works. - void addEventListener(in DOMString type, - in EventListener listener, - in boolean useCapture); - void removeEventListener(in DOMString type, - in EventListener listener, - in boolean useCapture); - boolean dispatchEvent(in Event event) raises(EventException); -#endif + // EventTarget +#if !defined(LANGUAGE_OBJECTIVE_C) + attribute [DontEnum, ProtectedListener] EventListener onabort; + attribute [DontEnum, ProtectedListener] EventListener onblur; + attribute [DontEnum, ProtectedListener] EventListener onchange; + attribute [DontEnum, ProtectedListener] EventListener onclick; + attribute [DontEnum, ProtectedListener] EventListener oncontextmenu; + attribute [DontEnum, ProtectedListener] EventListener ondblclick; + attribute [DontEnum, ProtectedListener] EventListener onerror; + attribute [DontEnum, ProtectedListener] EventListener onfocus; + attribute [DontEnum, ProtectedListener] EventListener oninput; + attribute [DontEnum, ProtectedListener] EventListener onkeydown; + attribute [DontEnum, ProtectedListener] EventListener onkeypress; + attribute [DontEnum, ProtectedListener] EventListener onkeyup; + attribute [DontEnum, ProtectedListener] EventListener onload; + attribute [DontEnum, ProtectedListener] EventListener onmousedown; + attribute [DontEnum, ProtectedListener] EventListener onmousemove; + attribute [DontEnum, ProtectedListener] EventListener onmouseout; + attribute [DontEnum, ProtectedListener] EventListener onmouseover; + attribute [DontEnum, ProtectedListener] EventListener onmouseup; + attribute [DontEnum, ProtectedListener] EventListener onmousewheel; + attribute [DontEnum, ProtectedListener] EventListener onbeforecut; + attribute [DontEnum, ProtectedListener] EventListener oncut; + attribute [DontEnum, ProtectedListener] EventListener onbeforecopy; + attribute [DontEnum, ProtectedListener] EventListener oncopy; + attribute [DontEnum, ProtectedListener] EventListener onbeforepaste; + attribute [DontEnum, ProtectedListener] EventListener onpaste; + attribute [DontEnum, ProtectedListener] EventListener ondragenter; + attribute [DontEnum, ProtectedListener] EventListener ondragover; + attribute [DontEnum, ProtectedListener] EventListener ondragleave; + attribute [DontEnum, ProtectedListener] EventListener ondrop; + attribute [DontEnum, ProtectedListener] EventListener ondragstart; + attribute [DontEnum, ProtectedListener] EventListener ondrag; + attribute [DontEnum, ProtectedListener] EventListener ondragend; + attribute [DontEnum, ProtectedListener] EventListener onreset; + attribute [DontEnum, ProtectedListener] EventListener onresize; + attribute [DontEnum, ProtectedListener] EventListener onscroll; + attribute [DontEnum, ProtectedListener] EventListener onsearch; + attribute [DontEnum, ProtectedListener] EventListener onselect; + attribute [DontEnum, ProtectedListener] EventListener onselectstart; + attribute [DontEnum, ProtectedListener] EventListener onsubmit; + attribute [DontEnum, ProtectedListener] EventListener onunload; + + [Custom] void addEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); + [Custom] void removeEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); + boolean dispatchEvent(in Event event) + raises(EventException); +#endif /* defined(LANGUAGE_OBJECTIVE_C) */ }; } diff --git a/WebCore/svg/SVGElementInstanceList.cpp b/WebCore/svg/SVGElementInstanceList.cpp index 3942599..f039d44 100644 --- a/WebCore/svg/SVGElementInstanceList.cpp +++ b/WebCore/svg/SVGElementInstanceList.cpp @@ -35,27 +35,23 @@ SVGElementInstanceList::~SVGElementInstanceList() { } -unsigned int SVGElementInstanceList::length() const +unsigned SVGElementInstanceList::length() const { - // NOTE: We could use the same caching facilities, "ChildNodeList" uses. + // NOTE: We could use the same caching facilities, like the ones "ChildNodeList" uses. unsigned length = 0; - SVGElementInstance* instance; - for (instance = m_rootInstance->firstChild(); instance; instance = instance->nextSibling()) + for (SVGElementInstance* instance = m_rootInstance->firstChild(); instance; instance = instance->nextSibling()) length++; - return length; } -RefPtr<SVGElementInstance> SVGElementInstanceList::item(unsigned int index) +SVGElementInstance* SVGElementInstanceList::item(unsigned index) { - unsigned int pos = 0; + unsigned pos = 0; SVGElementInstance* instance = m_rootInstance->firstChild(); - while (instance && pos < index) { instance = instance->nextSibling(); pos++; } - return instance; } diff --git a/WebCore/svg/SVGElementInstanceList.h b/WebCore/svg/SVGElementInstanceList.h index 960340a..ef4c73c 100644 --- a/WebCore/svg/SVGElementInstanceList.h +++ b/WebCore/svg/SVGElementInstanceList.h @@ -28,17 +28,20 @@ #include "SVGElementInstance.h" namespace WebCore { + class SVGElementInstanceList : public RefCounted<SVGElementInstanceList> { public: - SVGElementInstanceList(PassRefPtr<SVGElementInstance> rootInstance); + static PassRefPtr<SVGElementInstanceList> create(PassRefPtr<SVGElementInstance> rootInstance) { return adoptRef(new SVGElementInstanceList(rootInstance)); } virtual ~SVGElementInstanceList(); - unsigned int length() const; - RefPtr<SVGElementInstance> item(unsigned int index); + unsigned length() const; + SVGElementInstance* item(unsigned index); private: + SVGElementInstanceList(PassRefPtr<SVGElementInstance> rootInstance); RefPtr<SVGElementInstance> m_rootInstance; }; + } // namespace WebCore #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGEllipseElement.cpp b/WebCore/svg/SVGEllipseElement.cpp index 0f32ed2..a07a9a7 100644 --- a/WebCore/svg/SVGEllipseElement.cpp +++ b/WebCore/svg/SVGEllipseElement.cpp @@ -37,10 +37,10 @@ SVGEllipseElement::SVGEllipseElement(const QualifiedName& tagName, Document* doc , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_cx(this, LengthModeWidth) - , m_cy(this, LengthModeHeight) - , m_rx(this, LengthModeWidth) - , m_ry(this, LengthModeHeight) + , m_cx(this, SVGNames::cxAttr, LengthModeWidth) + , m_cy(this, SVGNames::cyAttr, LengthModeHeight) + , m_rx(this, SVGNames::rxAttr, LengthModeWidth) + , m_ry(this, SVGNames::ryAttr, LengthModeHeight) { } @@ -48,24 +48,19 @@ SVGEllipseElement::~SVGEllipseElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGEllipseElement, SVGLength, Length, length, Cx, cx, SVGNames::cxAttr, m_cx) -ANIMATED_PROPERTY_DEFINITIONS(SVGEllipseElement, SVGLength, Length, length, Cy, cy, SVGNames::cyAttr, m_cy) -ANIMATED_PROPERTY_DEFINITIONS(SVGEllipseElement, SVGLength, Length, length, Rx, rx, SVGNames::rxAttr, m_rx) -ANIMATED_PROPERTY_DEFINITIONS(SVGEllipseElement, SVGLength, Length, length, Ry, ry, SVGNames::ryAttr, m_ry) - void SVGEllipseElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::cxAttr) - setCxBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setCxBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::cyAttr) - setCyBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setCyBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::rxAttr) { - setRxBaseValue(SVGLength(this, LengthModeWidth, attr->value())); - if (rx().value() < 0.0) + setRxBaseValue(SVGLength(LengthModeWidth, attr->value())); + if (rxBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for ellipse <rx> is not allowed"); } else if (attr->name() == SVGNames::ryAttr) { - setRyBaseValue(SVGLength(this, LengthModeHeight, attr->value())); - if (ry().value() < 0.0) + setRyBaseValue(SVGLength(LengthModeHeight, attr->value())); + if (ryBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for ellipse <ry> is not allowed"); } else { if (SVGTests::parseMappedAttribute(attr)) @@ -96,8 +91,8 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName) Path SVGEllipseElement::toPathData() const { - return Path::createEllipse(FloatPoint(cx().value(), cy().value()), - rx().value(), ry().value()); + return Path::createEllipse(FloatPoint(cx().value(this), cy().value(this)), + rx().value(this), ry().value(this)); } bool SVGEllipseElement::hasRelativeValues() const diff --git a/WebCore/svg/SVGEllipseElement.h b/WebCore/svg/SVGEllipseElement.h index 01e8ef5..8c7d3a1 100644 --- a/WebCore/svg/SVGEllipseElement.h +++ b/WebCore/svg/SVGEllipseElement.h @@ -51,12 +51,10 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGLength, SVGLength, Cx, cx) - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGLength, SVGLength, Cy, cy) - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGLength, SVGLength, Rx, rx) - ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGLength, SVGLength, Ry, ry) + ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGNames::ellipseTagString, SVGNames::cxAttrString, SVGLength, Cx, cx) + ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGNames::ellipseTagString, SVGNames::cyAttrString, SVGLength, Cy, cy) + ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGNames::ellipseTagString, SVGNames::rxAttrString, SVGLength, Rx, rx) + ANIMATED_PROPERTY_DECLARATIONS(SVGEllipseElement, SVGNames::ellipseTagString, SVGNames::ryAttrString, SVGLength, Ry, ry) }; } // namespace WebCore diff --git a/WebCore/svg/SVGException.h b/WebCore/svg/SVGException.h index aa82e70..b82adf7 100644 --- a/WebCore/svg/SVGException.h +++ b/WebCore/svg/SVGException.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> - * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,17 +22,17 @@ #ifndef SVGException_h #define SVGException_h -#if ENABLE(SVG) - #include "ExceptionBase.h" +#if ENABLE(SVG) + namespace WebCore { class SVGException : public ExceptionBase { public: - SVGException(const ExceptionCodeDescription& description) - : ExceptionBase(description) + static PassRefPtr<SVGException> create(const ExceptionCodeDescription& description) { + return adoptRef(new SVGException(description)); } static const int SVGExceptionOffset = 300; @@ -43,6 +43,12 @@ namespace WebCore { SVG_INVALID_VALUE_ERR = SVGExceptionOffset + 1, SVG_MATRIX_NOT_INVERTABLE = SVGExceptionOffset + 2 }; + + private: + SVGException(const ExceptionCodeDescription& description) + : ExceptionBase(description) + { + } }; } // namespace WebCore diff --git a/WebCore/svg/SVGExternalResourcesRequired.cpp b/WebCore/svg/SVGExternalResourcesRequired.cpp index f6327e7..d087f64 100644 --- a/WebCore/svg/SVGExternalResourcesRequired.cpp +++ b/WebCore/svg/SVGExternalResourcesRequired.cpp @@ -31,8 +31,10 @@ namespace WebCore { +char SVGExternalResourcesRequiredIdentifier[] = "SVGExternalResourcesRequired"; + SVGExternalResourcesRequired::SVGExternalResourcesRequired() - : m_externalResourcesRequired(false) + : m_externalResourcesRequired(this, SVGNames::externalResourcesRequiredAttr, false) { } @@ -40,8 +42,6 @@ SVGExternalResourcesRequired::~SVGExternalResourcesRequired() { } -ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(SVGExternalResourcesRequired, bool, Boolean, boolean, ExternalResourcesRequired, externalResourcesRequired, SVGNames::externalResourcesRequiredAttr, m_externalResourcesRequired) - bool SVGExternalResourcesRequired::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::externalResourcesRequiredAttr) { diff --git a/WebCore/svg/SVGExternalResourcesRequired.h b/WebCore/svg/SVGExternalResourcesRequired.h index 4078794..0ab6dc9 100644 --- a/WebCore/svg/SVGExternalResourcesRequired.h +++ b/WebCore/svg/SVGExternalResourcesRequired.h @@ -24,11 +24,11 @@ #define SVGExternalResourcesRequired_h #if ENABLE(SVG) -#include <wtf/RefPtr.h> #include "SVGElement.h" namespace WebCore { + extern char SVGExternalResourcesRequiredIdentifier[]; class MappedAttribute; // FIXME: This is wrong for several reasons: @@ -49,11 +49,12 @@ namespace WebCore { bool parseMappedAttribute(MappedAttribute*); bool isKnownAttribute(const QualifiedName&); - protected: virtual const SVGElement* contextElement() const = 0; private: - ANIMATED_PROPERTY_DECLARATIONS_WITH_CONTEXT(SVGExternalResourcesRequired, bool, bool, ExternalResourcesRequired, externalResourcesRequired) + ANIMATED_PROPERTY_DECLARATIONS(SVGExternalResourcesRequired, SVGExternalResourcesRequiredIdentifier, + SVGNames::externalResourcesRequiredAttrString, bool, + ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEBlendElement.cpp b/WebCore/svg/SVGFEBlendElement.cpp index 317b92b..3c8557e 100644 --- a/WebCore/svg/SVGFEBlendElement.cpp +++ b/WebCore/svg/SVGFEBlendElement.cpp @@ -31,34 +31,31 @@ namespace WebCore { SVGFEBlendElement::SVGFEBlendElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_mode(SVG_FEBLEND_MODE_NORMAL) + , m_in1(this, SVGNames::inAttr) + , m_in2(this, SVGNames::in2Attr) + , m_mode(this, SVGNames::modeAttr, FEBLEND_MODE_NORMAL) , m_filterEffect(0) { } SVGFEBlendElement::~SVGFEBlendElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEBlendElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEBlendElement, String, String, string, In2, in2, SVGNames::in2Attr, m_in2) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEBlendElement, int, Enumeration, enumeration, Mode, mode, SVGNames::modeAttr, m_mode) - void SVGFEBlendElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); if (attr->name() == SVGNames::modeAttr) { if (value == "normal") - setModeBaseValue(SVG_FEBLEND_MODE_NORMAL); + setModeBaseValue(FEBLEND_MODE_NORMAL); else if (value == "multiply") - setModeBaseValue(SVG_FEBLEND_MODE_MULTIPLY); + setModeBaseValue(FEBLEND_MODE_MULTIPLY); else if (value == "screen") - setModeBaseValue(SVG_FEBLEND_MODE_SCREEN); + setModeBaseValue(FEBLEND_MODE_SCREEN); else if (value == "darken") - setModeBaseValue(SVG_FEBLEND_MODE_DARKEN); + setModeBaseValue(FEBLEND_MODE_DARKEN); else if (value == "lighten") - setModeBaseValue(SVG_FEBLEND_MODE_LIGHTEN); + setModeBaseValue(FEBLEND_MODE_LIGHTEN); } else if (attr->name() == SVGNames::inAttr) setIn1BaseValue(value); else if (attr->name() == SVGNames::in2Attr) @@ -67,16 +64,23 @@ void SVGFEBlendElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFEBlend* SVGFEBlendElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEBlendElement::filterEffect(SVGResourceFilter* filter) const +{ + ASSERT_NOT_REACHED(); + return 0; +} + +bool SVGFEBlendElement::build(FilterBuilder* builder) { - if (!m_filterEffect) - m_filterEffect = new SVGFEBlend(filter); - - m_filterEffect->setBlendMode((SVGBlendModeType) mode()); - m_filterEffect->setIn(in1()); - m_filterEffect->setIn2(in2()); - setStandardAttributes(m_filterEffect); - return m_filterEffect; + FilterEffect* input1 = builder->getEffectById(in1()); + FilterEffect* input2 = builder->getEffectById(in2()); + + if(!input1 || !input2) + return false; + + builder->add(result(), FEBlend::create(input1, input2, static_cast<BlendModeType> (mode()))); + + return true; } } diff --git a/WebCore/svg/SVGFEBlendElement.h b/WebCore/svg/SVGFEBlendElement.h index 88d2e6f..a85d174 100644 --- a/WebCore/svg/SVGFEBlendElement.h +++ b/WebCore/svg/SVGFEBlendElement.h @@ -24,7 +24,7 @@ #define SVGFEBlendElement_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEBlend.h" +#include "FEBlend.h" #include "SVGFilterPrimitiveStandardAttributes.h" namespace WebCore @@ -36,17 +36,15 @@ namespace WebCore virtual ~SVGFEBlendElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFEBlend* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, String, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, String, String, In2, in2) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, int, int, Mode, mode) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, SVGNames::feBlendTagString, SVGNames::inAttrString, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, SVGNames::feBlendTagString, SVGNames::in2AttrString, String, In2, in2) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEBlendElement, SVGNames::feBlendTagString, SVGNames::modeAttrString, int, Mode, mode) - mutable SVGFEBlend* m_filterEffect; + mutable RefPtr<FEBlend> m_filterEffect; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEColorMatrixElement.cpp b/WebCore/svg/SVGFEColorMatrixElement.cpp index 6a9474c..c3a8f01 100644 --- a/WebCore/svg/SVGFEColorMatrixElement.cpp +++ b/WebCore/svg/SVGFEColorMatrixElement.cpp @@ -33,33 +33,29 @@ namespace WebCore { SVGFEColorMatrixElement::SVGFEColorMatrixElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_type(SVG_FECOLORMATRIX_TYPE_UNKNOWN) - , m_values(new SVGNumberList(SVGNames::valuesAttr)) + , m_in1(this, SVGNames::inAttr) + , m_type(this, SVGNames::typeAttr, FECOLORMATRIX_TYPE_UNKNOWN) + , m_values(this, SVGNames::valuesAttr, SVGNumberList::create(SVGNames::valuesAttr)) , m_filterEffect(0) { } SVGFEColorMatrixElement::~SVGFEColorMatrixElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEColorMatrixElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEColorMatrixElement, int, Enumeration, enumeration, Type, type, SVGNames::typeAttr, m_type) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEColorMatrixElement, SVGNumberList*, NumberList, numberList, Values, values, SVGNames::valuesAttr, m_values.get()) - void SVGFEColorMatrixElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); if (attr->name() == SVGNames::typeAttr) { if (value == "matrix") - setTypeBaseValue(SVG_FECOLORMATRIX_TYPE_MATRIX); + setTypeBaseValue(FECOLORMATRIX_TYPE_MATRIX); else if (value == "saturate") - setTypeBaseValue(SVG_FECOLORMATRIX_TYPE_SATURATE); + setTypeBaseValue(FECOLORMATRIX_TYPE_SATURATE); else if (value == "hueRotate") - setTypeBaseValue(SVG_FECOLORMATRIX_TYPE_HUEROTATE); + setTypeBaseValue(FECOLORMATRIX_TYPE_HUEROTATE); else if (value == "luminanceToAlpha") - setTypeBaseValue(SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA); + setTypeBaseValue(FECOLORMATRIX_TYPE_LUMINANCETOALPHA); } else if (attr->name() == SVGNames::inAttr) setIn1BaseValue(value); @@ -69,13 +65,18 @@ void SVGFEColorMatrixElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFEColorMatrix* SVGFEColorMatrixElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEColorMatrixElement::filterEffect(SVGResourceFilter* filter) const +{ + ASSERT_NOT_REACHED(); + return 0; +} + +bool SVGFEColorMatrixElement::build(FilterBuilder* builder) { - if (!m_filterEffect) - m_filterEffect = new SVGFEColorMatrix(filter); - - m_filterEffect->setIn(in1()); - setStandardAttributes(m_filterEffect); + FilterEffect* input1 = builder->getEffectById(in1()); + + if(!input1) + return false; Vector<float> _values; SVGNumberList* numbers = values(); @@ -85,14 +86,11 @@ SVGFEColorMatrix* SVGFEColorMatrixElement::filterEffect(SVGResourceFilter* filte for (unsigned int i = 0;i < nr;i++) _values.append(numbers->getItem(i, ec)); - m_filterEffect->setValues(_values); - m_filterEffect->setType((SVGColorMatrixType) type()); + builder->add(result(), FEColorMatrix::create(input1, static_cast<ColorMatrixType> (type()), _values)); - return m_filterEffect; + return true; } -} +} //namespace WebCore #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEColorMatrixElement.h b/WebCore/svg/SVGFEColorMatrixElement.h index 0015002..f39db86 100644 --- a/WebCore/svg/SVGFEColorMatrixElement.h +++ b/WebCore/svg/SVGFEColorMatrixElement.h @@ -24,36 +24,30 @@ #define SVGFEColorMatrixElement_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEColorMatrix.h" +#include "FEColorMatrix.h" #include "SVGFilterPrimitiveStandardAttributes.h" +#include "SVGNumberList.h" -namespace WebCore -{ - class SVGNumberList; +namespace WebCore { - class SVGFEColorMatrixElement : public SVGFilterPrimitiveStandardAttributes - { + class SVGFEColorMatrixElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFEColorMatrixElement(const QualifiedName&, Document*); virtual ~SVGFEColorMatrixElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFEColorMatrix* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, String, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, int, int, Type, type) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, SVGNumberList*, RefPtr<SVGNumberList>, Values, values) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, SVGNames::feColorMatrixTagString, SVGNames::inAttrString, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, SVGNames::feColorMatrixTagString, SVGNames::typeAttrString, int, Type, type) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEColorMatrixElement, SVGNames::feColorMatrixTagString, SVGNames::valuesAttrString, SVGNumberList, Values, values) - mutable SVGFEColorMatrix* m_filterEffect; + mutable RefPtr<FEColorMatrix> m_filterEffect; }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEComponentTransferElement.cpp b/WebCore/svg/SVGFEComponentTransferElement.cpp index 2e9ec2e..e1be6ae 100644 --- a/WebCore/svg/SVGFEComponentTransferElement.cpp +++ b/WebCore/svg/SVGFEComponentTransferElement.cpp @@ -38,17 +38,15 @@ namespace WebCore { SVGFEComponentTransferElement::SVGFEComponentTransferElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) + , m_in1(this, SVGNames::inAttr) , m_filterEffect(0) { } SVGFEComponentTransferElement::~SVGFEComponentTransferElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEComponentTransferElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) - void SVGFEComponentTransferElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); @@ -58,26 +56,38 @@ void SVGFEComponentTransferElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFEComponentTransfer* SVGFEComponentTransferElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEComponentTransferElement::filterEffect(SVGResourceFilter* filter) const +{ + ASSERT_NOT_REACHED(); + return 0; +} + +bool SVGFEComponentTransferElement::build(FilterBuilder* builder) { - if (!m_filterEffect) - m_filterEffect = new SVGFEComponentTransfer(filter); + FilterEffect* input1 = builder->getEffectById(in1()); - m_filterEffect->setIn(in1()); - setStandardAttributes(m_filterEffect); + if(!input1) + return false; + + ComponentTransferFunction red; + ComponentTransferFunction green; + ComponentTransferFunction blue; + ComponentTransferFunction alpha; for (Node* n = firstChild(); n != 0; n = n->nextSibling()) { if (n->hasTagName(SVGNames::feFuncRTag)) - m_filterEffect->setRedFunction(static_cast<SVGFEFuncRElement*>(n)->transferFunction()); + red = static_cast<SVGFEFuncRElement*>(n)->transferFunction(); else if (n->hasTagName(SVGNames::feFuncGTag)) - m_filterEffect->setGreenFunction(static_cast<SVGFEFuncGElement*>(n)->transferFunction()); + green = static_cast<SVGFEFuncGElement*>(n)->transferFunction(); else if (n->hasTagName(SVGNames::feFuncBTag)) - m_filterEffect->setBlueFunction(static_cast<SVGFEFuncBElement*>(n)->transferFunction()); + blue = static_cast<SVGFEFuncBElement*>(n)->transferFunction(); else if (n->hasTagName(SVGNames::feFuncATag)) - m_filterEffect->setAlphaFunction(static_cast<SVGFEFuncAElement*>(n)->transferFunction()); + alpha = static_cast<SVGFEFuncAElement*>(n)->transferFunction(); } - - return m_filterEffect; + + builder->add(result(), FEComponentTransfer::create(input1, red, green, blue, alpha)); + + return true; } } diff --git a/WebCore/svg/SVGFEComponentTransferElement.h b/WebCore/svg/SVGFEComponentTransferElement.h index 74827c5..e80ea94 100644 --- a/WebCore/svg/SVGFEComponentTransferElement.h +++ b/WebCore/svg/SVGFEComponentTransferElement.h @@ -25,27 +25,23 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFilterPrimitiveStandardAttributes.h" -#include "SVGFEComponentTransfer.h" +#include "FEComponentTransfer.h" -namespace WebCore -{ +namespace WebCore { - class SVGFEComponentTransferElement : public SVGFilterPrimitiveStandardAttributes - { + class SVGFEComponentTransferElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFEComponentTransferElement(const QualifiedName&, Document*); virtual ~SVGFEComponentTransferElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFEComponentTransfer* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEComponentTransferElement, String, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEComponentTransferElement, SVGNames::feComponentTransferTagString, SVGNames::inAttrString, String, In1, in1) - mutable SVGFEComponentTransfer *m_filterEffect; + mutable RefPtr<FEComponentTransfer> m_filterEffect; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFECompositeElement.cpp b/WebCore/svg/SVGFECompositeElement.cpp index d21aeec..f2fc4dc 100644 --- a/WebCore/svg/SVGFECompositeElement.cpp +++ b/WebCore/svg/SVGFECompositeElement.cpp @@ -32,44 +32,37 @@ namespace WebCore { SVGFECompositeElement::SVGFECompositeElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m__operator(SVG_FECOMPOSITE_OPERATOR_OVER) - , m_k1(0.0f) - , m_k2(0.0f) - , m_k3(0.0f) - , m_k4(0.0f) + , m_in1(this, SVGNames::inAttr) + , m_in2(this, SVGNames::in2Attr) + , m__operator(this, SVGNames::operatorAttr, FECOMPOSITE_OPERATOR_OVER) + , m_k1(this, SVGNames::k1Attr) + , m_k2(this, SVGNames::k2Attr) + , m_k3(this, SVGNames::k3Attr) + , m_k4(this, SVGNames::k4Attr) , m_filterEffect(0) { } SVGFECompositeElement::~SVGFECompositeElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFECompositeElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFECompositeElement, String, String, string, In2, in2, SVGNames::in2Attr, m_in2) -ANIMATED_PROPERTY_DEFINITIONS(SVGFECompositeElement, int, Enumeration, enumeration, _operator, _operator, SVGNames::operatorAttr, m__operator) -ANIMATED_PROPERTY_DEFINITIONS(SVGFECompositeElement, float, Number, number, K1, k1, SVGNames::k1Attr, m_k1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFECompositeElement, float, Number, number, K2, k2, SVGNames::k2Attr, m_k2) -ANIMATED_PROPERTY_DEFINITIONS(SVGFECompositeElement, float, Number, number, K3, k3, SVGNames::k3Attr, m_k3) -ANIMATED_PROPERTY_DEFINITIONS(SVGFECompositeElement, float, Number, number, K4, k4, SVGNames::k4Attr, m_k4) - void SVGFECompositeElement::parseMappedAttribute(MappedAttribute *attr) { const String& value = attr->value(); if (attr->name() == SVGNames::operatorAttr) { if (value == "over") - set_operatorBaseValue(SVG_FECOMPOSITE_OPERATOR_OVER); + set_operatorBaseValue(FECOMPOSITE_OPERATOR_OVER); else if (value == "in") - set_operatorBaseValue(SVG_FECOMPOSITE_OPERATOR_IN); + set_operatorBaseValue(FECOMPOSITE_OPERATOR_IN); else if (value == "out") - set_operatorBaseValue(SVG_FECOMPOSITE_OPERATOR_OUT); + set_operatorBaseValue(FECOMPOSITE_OPERATOR_OUT); else if (value == "atop") - set_operatorBaseValue(SVG_FECOMPOSITE_OPERATOR_ATOP); + set_operatorBaseValue(FECOMPOSITE_OPERATOR_ATOP); else if (value == "xor") - set_operatorBaseValue(SVG_FECOMPOSITE_OPERATOR_XOR); + set_operatorBaseValue(FECOMPOSITE_OPERATOR_XOR); else if (value == "arithmetic") - set_operatorBaseValue(SVG_FECOMPOSITE_OPERATOR_ARITHMETIC); + set_operatorBaseValue(FECOMPOSITE_OPERATOR_ARITHMETIC); } else if (attr->name() == SVGNames::inAttr) setIn1BaseValue(value); @@ -87,25 +80,27 @@ void SVGFECompositeElement::parseMappedAttribute(MappedAttribute *attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFEComposite* SVGFECompositeElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFECompositeElement::filterEffect(SVGResourceFilter* filter) const +{ + ASSERT_NOT_REACHED(); + return 0; +} + +bool SVGFECompositeElement::build(FilterBuilder* builder) { - if (!m_filterEffect) - m_filterEffect = new SVGFEComposite(filter); + FilterEffect* input1 = builder->getEffectById(in1()); + FilterEffect* input2 = builder->getEffectById(in2()); - m_filterEffect->setOperation((SVGCompositeOperationType) _operator()); - m_filterEffect->setIn(in1()); - m_filterEffect->setIn2(in2()); - m_filterEffect->setK1(k1()); - m_filterEffect->setK2(k2()); - m_filterEffect->setK3(k3()); - m_filterEffect->setK4(k4()); - - setStandardAttributes(m_filterEffect); - return m_filterEffect; + if(!input1 || !input2) + return false; + + RefPtr<FilterEffect> addedEffect = FEComposite::create(input1, input2, static_cast<CompositeOperationType> (_operator()), + k1(), k2(), k3(), k4()); + builder->add(result(), addedEffect.release()); + + return true; } } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFECompositeElement.h b/WebCore/svg/SVGFECompositeElement.h index 24fe6ae..89ad7df 100644 --- a/WebCore/svg/SVGFECompositeElement.h +++ b/WebCore/svg/SVGFECompositeElement.h @@ -24,39 +24,33 @@ #define SVGFECompositeElement_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEComposite.h" +#include "FEComposite.h" #include "SVGFilterPrimitiveStandardAttributes.h" -namespace WebCore -{ +namespace WebCore { - class SVGFECompositeElement : public SVGFilterPrimitiveStandardAttributes - { + class SVGFECompositeElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFECompositeElement(const QualifiedName&, Document*); virtual ~SVGFECompositeElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFEComposite* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, String, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, String, String, In2, in2) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, int, int, _operator, _operator) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, float, float, K1, k1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, float, float, K2, k2) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, float, float, K3, k3) - ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, float, float, K4, k4) - - mutable SVGFEComposite* m_filterEffect; + ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::inAttrString, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::in2AttrString, String, In2, in2) + ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::operatorAttrString, int, _operator, _operator) + ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::k1AttrString, float, K1, k1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::k2AttrString, float, K2, k2) + ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::k3AttrString, float, K3, k3) + ANIMATED_PROPERTY_DECLARATIONS(SVGFECompositeElement, SVGNames::feCompositeTagString, SVGNames::k4AttrString, float, K4, k4) + + mutable RefPtr<FEComposite> m_filterEffect; }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEDiffuseLightingElement.cpp b/WebCore/svg/SVGFEDiffuseLightingElement.cpp index d1b3ebd..87fa33a 100644 --- a/WebCore/svg/SVGFEDiffuseLightingElement.cpp +++ b/WebCore/svg/SVGFEDiffuseLightingElement.cpp @@ -34,27 +34,24 @@ namespace WebCore { +char SVGKernelUnitLengthXIdentifier[] = "SVGKernelUnitLengthX"; +char SVGKernelUnitLengthYIdentifier[] = "SVGKernelUnitLengthY"; + SVGFEDiffuseLightingElement::SVGFEDiffuseLightingElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_diffuseConstant(1.0f) - , m_surfaceScale(1.0f) - , m_kernelUnitLengthX(0.0f) - , m_kernelUnitLengthY(0.0f) + , m_in1(this, SVGNames::inAttr) + , m_diffuseConstant(this, SVGNames::diffuseConstantAttr, 1.0f) + , m_surfaceScale(this, SVGNames::surfaceScaleAttr, 1.0f) + , m_kernelUnitLengthX(this, SVGNames::kernelUnitLengthAttr) + , m_kernelUnitLengthY(this, SVGNames::kernelUnitLengthAttr) , m_filterEffect(0) { } SVGFEDiffuseLightingElement::~SVGFEDiffuseLightingElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDiffuseLightingElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDiffuseLightingElement, float, Number, number, DiffuseConstant, diffuseConstant, SVGNames::diffuseConstantAttr, m_diffuseConstant) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDiffuseLightingElement, float, Number, number, SurfaceScale, surfaceScale, SVGNames::surfaceScaleAttr, m_surfaceScale) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDiffuseLightingElement, float, Number, number, KernelUnitLengthX, kernelUnitLengthX, "kernelUnitLengthX", m_kernelUnitLengthX) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDiffuseLightingElement, float, Number, number, KernelUnitLengthY, kernelUnitLengthY, "kernelUnitLengthY", m_kernelUnitLengthY) - void SVGFEDiffuseLightingElement::parseMappedAttribute(MappedAttribute *attr) { const String& value = attr->value(); @@ -76,36 +73,30 @@ void SVGFEDiffuseLightingElement::parseMappedAttribute(MappedAttribute *attr) SVGFilterEffect* SVGFEDiffuseLightingElement::filterEffect(SVGResourceFilter* filter) const { - if (!m_filterEffect) - m_filterEffect = new SVGFEDiffuseLighting(filter); - - m_filterEffect->setIn(in1()); - m_filterEffect->setDiffuseConstant(diffuseConstant()); - m_filterEffect->setSurfaceScale(surfaceScale()); - m_filterEffect->setKernelUnitLengthX(kernelUnitLengthX()); - m_filterEffect->setKernelUnitLengthY(kernelUnitLengthY()); - - SVGFEDiffuseLightingElement* nonConstThis = const_cast<SVGFEDiffuseLightingElement*>(this); + ASSERT_NOT_REACHED(); + return 0; +} - RenderStyle* parentStyle = nonConstThis->styleForRenderer(parent()->renderer()); - RenderStyle* filterStyle = nonConstThis->resolveStyle(parentStyle); +bool SVGFEDiffuseLightingElement::build(FilterBuilder* builder) +{ + FilterEffect* input1 = builder->getEffectById(in1()); + + if(!input1) + return false; + + RefPtr<RenderStyle> filterStyle = styleForRenderer(); + Color color = filterStyle->svgStyle()->lightingColor(); - m_filterEffect->setLightingColor(filterStyle->svgStyle()->lightingColor()); - setStandardAttributes(m_filterEffect); - - parentStyle->deref(document()->renderArena()); - filterStyle->deref(document()->renderArena()); + RefPtr<FilterEffect> addedEffect = FEDiffuseLighting::create(input1, color, surfaceScale(), diffuseConstant(), + kernelUnitLengthX(), kernelUnitLengthY(), findLights()); + builder->add(result(), addedEffect.release()); - updateLights(); - return m_filterEffect; + return true; } -void SVGFEDiffuseLightingElement::updateLights() const +LightSource* SVGFEDiffuseLightingElement::findLights() const { - if (!m_filterEffect) - return; - - SVGLightSource* light = 0; + LightSource* light = 0; for (Node* n = firstChild(); n; n = n->nextSibling()) { if (n->hasTagName(SVGNames::feDistantLightTag) || n->hasTagName(SVGNames::fePointLightTag) || @@ -116,11 +107,9 @@ void SVGFEDiffuseLightingElement::updateLights() const } } - m_filterEffect->setLightSource(light); + return light; } } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEDiffuseLightingElement.h b/WebCore/svg/SVGFEDiffuseLightingElement.h index 4d038b3..70c6777 100644 --- a/WebCore/svg/SVGFEDiffuseLightingElement.h +++ b/WebCore/svg/SVGFEDiffuseLightingElement.h @@ -23,34 +23,36 @@ #define SVGFEDiffuseLightingElement_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) +#include "SVGFELightElement.h" #include "SVGFilterPrimitiveStandardAttributes.h" namespace WebCore { - class SVGFEDiffuseLighting; + + extern char SVGKernelUnitLengthXIdentifier[]; + extern char SVGKernelUnitLengthYIdentifier[]; + + class FEDiffuseLighting; class SVGColor; - class SVGFEDiffuseLightingElement : public SVGFilterPrimitiveStandardAttributes - { + class SVGFEDiffuseLightingElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFEDiffuseLightingElement(const QualifiedName&, Document*); virtual ~SVGFEDiffuseLightingElement(); virtual void parseMappedAttribute(MappedAttribute*); virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, String, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, float, float, DiffuseConstant, diffuseConstant) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, float, float, SurfaceScale, surfaceScale) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, float, float, KernelUnitLengthX, kernelUnitLengthX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, float, float, KernelUnitLengthY, kernelUnitLengthY) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGNames::inAttrString, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGNames::diffuseConstantAttrString, float, DiffuseConstant, diffuseConstant) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGNames::surfaceScaleAttrString, float, SurfaceScale, surfaceScale) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGKernelUnitLengthXIdentifier, float, KernelUnitLengthX, kernelUnitLengthX) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDiffuseLightingElement, SVGNames::feDiffuseLightingTagString, SVGKernelUnitLengthYIdentifier, float, KernelUnitLengthY, kernelUnitLengthY) - mutable SVGFEDiffuseLighting* m_filterEffect; + LightSource* findLights() const; - void updateLights() const; + mutable RefPtr<FEDiffuseLighting> m_filterEffect; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEDisplacementMapElement.cpp b/WebCore/svg/SVGFEDisplacementMapElement.cpp index 8852a65..3b6dfbf 100644 --- a/WebCore/svg/SVGFEDisplacementMapElement.cpp +++ b/WebCore/svg/SVGFEDisplacementMapElement.cpp @@ -29,36 +29,31 @@ namespace WebCore { SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_xChannelSelector(SVG_CHANNEL_A) - , m_yChannelSelector(SVG_CHANNEL_A) - , m_scale(0.0f) + , m_in1(this, SVGNames::inAttr) + , m_in2(this, SVGNames::in2Attr) + , m_xChannelSelector(this, SVGNames::xChannelSelectorAttr, CHANNEL_A) + , m_yChannelSelector(this, SVGNames::yChannelSelectorAttr, CHANNEL_A) + , m_scale(this, SVGNames::scaleAttr) , m_filterEffect(0) { } SVGFEDisplacementMapElement::~SVGFEDisplacementMapElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDisplacementMapElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDisplacementMapElement, String, String, string, In2, in2, SVGNames::in2Attr, m_in2) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDisplacementMapElement, int, Enumeration, enumeration, XChannelSelector, xChannelSelector, SVGNames::xChannelSelectorAttr, m_xChannelSelector) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDisplacementMapElement, int, Enumeration, enumeration, YChannelSelector, yChannelSelector, SVGNames::yChannelSelectorAttr, m_yChannelSelector) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEDisplacementMapElement, float, Number, number, Scale, scale, SVGNames::scaleAttr, m_scale) - -SVGChannelSelectorType SVGFEDisplacementMapElement::stringToChannel(const String& key) +ChannelSelectorType SVGFEDisplacementMapElement::stringToChannel(const String& key) { if (key == "R") - return SVG_CHANNEL_R; + return CHANNEL_R; else if (key == "G") - return SVG_CHANNEL_G; + return CHANNEL_G; else if (key == "B") - return SVG_CHANNEL_B; + return CHANNEL_B; else if (key == "A") - return SVG_CHANNEL_A; + return CHANNEL_A; - return SVG_CHANNEL_UNKNOWN; + return CHANNEL_UNKNOWN; } void SVGFEDisplacementMapElement::parseMappedAttribute(MappedAttribute* attr) @@ -78,19 +73,26 @@ void SVGFEDisplacementMapElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFEDisplacementMap* SVGFEDisplacementMapElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEDisplacementMapElement::filterEffect(SVGResourceFilter* filter) const { - if (!m_filterEffect) - m_filterEffect = new SVGFEDisplacementMap(filter); - - m_filterEffect->setXChannelSelector((SVGChannelSelectorType) xChannelSelector()); - m_filterEffect->setYChannelSelector((SVGChannelSelectorType) yChannelSelector()); - m_filterEffect->setIn(in1()); - m_filterEffect->setIn2(in2()); - m_filterEffect->setScale(scale()); + ASSERT_NOT_REACHED(); + return 0; +} - setStandardAttributes(m_filterEffect); - return m_filterEffect; +bool SVGFEDisplacementMapElement::build(FilterBuilder* builder) +{ + FilterEffect* input1 = builder->getEffectById(in1()); + FilterEffect* input2 = builder->getEffectById(in2()); + + if(!input1 || !input2) + return false; + + + RefPtr<FilterEffect> addedEffect = FEDisplacementMap::create(input1, input2, static_cast<ChannelSelectorType> (xChannelSelector()), + static_cast<ChannelSelectorType> (yChannelSelector()), scale()); + builder->add(result(), addedEffect.release()); + + return true; } } diff --git a/WebCore/svg/SVGFEDisplacementMapElement.h b/WebCore/svg/SVGFEDisplacementMapElement.h index 7f6a109..21b93f4 100644 --- a/WebCore/svg/SVGFEDisplacementMapElement.h +++ b/WebCore/svg/SVGFEDisplacementMapElement.h @@ -31,22 +31,20 @@ namespace WebCore { SVGFEDisplacementMapElement(const QualifiedName& tagName, Document*); virtual ~SVGFEDisplacementMapElement(); - static SVGChannelSelectorType stringToChannel(const String&); + static ChannelSelectorType stringToChannel(const String&); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFEDisplacementMap* filterEffect(SVGResourceFilter*) const; + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); - protected: - virtual const SVGElement* contextElement() const { return this; } - private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, String, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, String, String, In2, in2) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, int, int, XChannelSelector, xChannelSelector) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, int, int, YChannelSelector, yChannelSelector) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, float, float, Scale, scale) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::inAttrString, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::in2AttrString, String, In2, in2) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::xChannelSelectorAttrString, int, XChannelSelector, xChannelSelector) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::yChannelSelectorAttrString, int, YChannelSelector, yChannelSelector) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEDisplacementMapElement, SVGNames::feDisplacementMapTagString, SVGNames::scaleAttrString, float, Scale, scale) - mutable SVGFEDisplacementMap* m_filterEffect; + mutable RefPtr<FEDisplacementMap> m_filterEffect; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEDistantLightElement.cpp b/WebCore/svg/SVGFEDistantLightElement.cpp index e45b447..e9ec48d 100644 --- a/WebCore/svg/SVGFEDistantLightElement.cpp +++ b/WebCore/svg/SVGFEDistantLightElement.cpp @@ -34,9 +34,9 @@ SVGFEDistantLightElement::~SVGFEDistantLightElement() { } -SVGLightSource* SVGFEDistantLightElement::lightSource() const +LightSource* SVGFEDistantLightElement::lightSource() const { - return new SVGDistantLightSource(azimuth(), elevation()); + return new DistantLightSource(azimuth(), elevation()); } } diff --git a/WebCore/svg/SVGFEDistantLightElement.h b/WebCore/svg/SVGFEDistantLightElement.h index fd51e08..e43282f 100644 --- a/WebCore/svg/SVGFEDistantLightElement.h +++ b/WebCore/svg/SVGFEDistantLightElement.h @@ -31,7 +31,7 @@ namespace WebCore SVGFEDistantLightElement(const QualifiedName&, Document*); virtual ~SVGFEDistantLightElement(); - virtual SVGLightSource* lightSource() const; + virtual LightSource* lightSource() const; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEFloodElement.cpp b/WebCore/svg/SVGFEFloodElement.cpp index e9eff9d..98e7d6f 100644 --- a/WebCore/svg/SVGFEFloodElement.cpp +++ b/WebCore/svg/SVGFEFloodElement.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2007 Rob Buis <buis@kde.org> + 2004, 2005, 2007, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -26,6 +26,7 @@ #include "SVGFEFloodElement.h" #include "Attr.h" +#include "Document.h" #include "RenderStyle.h" #include "SVGNames.h" #include "SVGRenderStyle.h" @@ -41,40 +42,29 @@ SVGFEFloodElement::SVGFEFloodElement(const QualifiedName& tagName, Document* doc SVGFEFloodElement::~SVGFEFloodElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEFloodElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) - void SVGFEFloodElement::parseMappedAttribute(MappedAttribute* attr) { - const String& value = attr->value(); - if (attr->name() == SVGNames::inAttr) - setIn1BaseValue(value); - else - SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); + SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFEFlood* SVGFEFloodElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEFloodElement::filterEffect(SVGResourceFilter* filter) const { - if (!m_filterEffect) - m_filterEffect = new SVGFEFlood(filter); - - m_filterEffect->setIn(in1()); - setStandardAttributes(m_filterEffect); + ASSERT_NOT_REACHED(); + return 0; +} - SVGFEFloodElement* nonConstThis = const_cast<SVGFEFloodElement*>(this); +bool SVGFEFloodElement::build(FilterBuilder* builder) +{ + RefPtr<RenderStyle> filterStyle = styleForRenderer(); - RenderStyle* parentStyle = nonConstThis->styleForRenderer(parent()->renderer()); - RenderStyle* filterStyle = nonConstThis->resolveStyle(parentStyle); - - m_filterEffect->setFloodColor(filterStyle->svgStyle()->floodColor()); - m_filterEffect->setFloodOpacity(filterStyle->svgStyle()->floodOpacity()); - - parentStyle->deref(document()->renderArena()); - filterStyle->deref(document()->renderArena()); + Color color = filterStyle->svgStyle()->floodColor(); + float opacity = filterStyle->svgStyle()->floodOpacity(); + + builder->add(result(), FEFlood::create(color, opacity)); - return m_filterEffect; + return true; } } diff --git a/WebCore/svg/SVGFEFloodElement.h b/WebCore/svg/SVGFEFloodElement.h index 9094d5e..046f418 100644 --- a/WebCore/svg/SVGFEFloodElement.h +++ b/WebCore/svg/SVGFEFloodElement.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> + 2004, 2005, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -36,15 +36,11 @@ namespace WebCore virtual ~SVGFEFloodElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFEFlood* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEFloodElement, String, String, In1, in1) - - mutable SVGFEFlood *m_filterEffect; + mutable RefPtr<FEFlood> m_filterEffect; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEFloodElement.idl b/WebCore/svg/SVGFEFloodElement.idl index 406c275..d2356bf 100644 --- a/WebCore/svg/SVGFEFloodElement.idl +++ b/WebCore/svg/SVGFEFloodElement.idl @@ -27,7 +27,6 @@ module svg { interface [Conditional=SVG&SVG_FILTERS] SVGFEFloodElement : SVGElement, SVGFilterPrimitiveStandardAttributes { - readonly attribute SVGAnimatedString in1; }; } diff --git a/WebCore/svg/SVGFEGaussianBlurElement.cpp b/WebCore/svg/SVGFEGaussianBlurElement.cpp index e6d0b39..4fbabe3 100644 --- a/WebCore/svg/SVGFEGaussianBlurElement.cpp +++ b/WebCore/svg/SVGFEGaussianBlurElement.cpp @@ -31,23 +31,22 @@ namespace WebCore { +char SVGStdDeviationXAttrIdentifier[] = "SVGStdDeviationXAttr"; +char SVGStdDeviationYAttrIdentifier[] = "SVGStdDeviationYAttr"; + SVGFEGaussianBlurElement::SVGFEGaussianBlurElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_stdDeviationX(0.0f) - , m_stdDeviationY(0.0f) + , m_in1(this, SVGNames::inAttr) + , m_stdDeviationX(this, SVGNames::stdDeviationAttr) + , m_stdDeviationY(this, SVGNames::stdDeviationAttr) , m_filterEffect(0) { } SVGFEGaussianBlurElement::~SVGFEGaussianBlurElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEGaussianBlurElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEGaussianBlurElement, float, Number, number, StdDeviationX, stdDeviationX, "stdDeviationX", m_stdDeviationX) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEGaussianBlurElement, float, Number, number, StdDeviationY, stdDeviationY, "stdDeviationY", m_stdDeviationY) - void SVGFEGaussianBlurElement::setStdDeviation(float stdDeviationX, float stdDeviationY) { } @@ -67,21 +66,24 @@ void SVGFEGaussianBlurElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFEGaussianBlur* SVGFEGaussianBlurElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEGaussianBlurElement::filterEffect(SVGResourceFilter* filter) const { - if (!m_filterEffect) - m_filterEffect = new SVGFEGaussianBlur(filter); - - m_filterEffect->setIn(in1()); - m_filterEffect->setStdDeviationX(stdDeviationX()); - m_filterEffect->setStdDeviationY(stdDeviationY()); - - setStandardAttributes(m_filterEffect); - return m_filterEffect; + ASSERT_NOT_REACHED(); + return 0; } +bool SVGFEGaussianBlurElement::build(FilterBuilder* builder) +{ + FilterEffect* input1 = builder->getEffectById(in1()); + + if(!input1) + return false; + + builder->add(result(), FEGaussianBlur::create(input1, stdDeviationX(), stdDeviationY())); + + return true; } -#endif // ENABLE(SVG) +} -// vim:ts=4:noet +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGFEGaussianBlurElement.h b/WebCore/svg/SVGFEGaussianBlurElement.h index c1e9292..9e1c15c 100644 --- a/WebCore/svg/SVGFEGaussianBlurElement.h +++ b/WebCore/svg/SVGFEGaussianBlurElement.h @@ -27,11 +27,12 @@ #include "SVGFEGaussianBlur.h" #include "SVGFilterPrimitiveStandardAttributes.h" -namespace WebCore -{ +namespace WebCore { - class SVGFEGaussianBlurElement : public SVGFilterPrimitiveStandardAttributes - { + extern char SVGStdDeviationXAttrIdentifier[]; + extern char SVGStdDeviationYAttrIdentifier[]; + + class SVGFEGaussianBlurElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFEGaussianBlurElement(const QualifiedName&, Document*); virtual ~SVGFEGaussianBlurElement(); @@ -39,22 +40,18 @@ namespace WebCore void setStdDeviation(float stdDeviationX, float stdDeviationY); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFEGaussianBlur* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, String, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, float, float, StdDeviationX, stdDeviationX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, float, float, StdDeviationY, stdDeviationY) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, SVGNames::feGaussianBlurTagString, SVGNames::inAttrString, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, SVGNames::feGaussianBlurTagString, SVGStdDeviationXAttrIdentifier, float, StdDeviationX, stdDeviationX) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEGaussianBlurElement, SVGNames::feGaussianBlurTagString, SVGStdDeviationYAttrIdentifier, float, StdDeviationY, stdDeviationY) - mutable SVGFEGaussianBlur* m_filterEffect; + mutable RefPtr<FEGaussianBlur> m_filterEffect; }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEImageElement.cpp b/WebCore/svg/SVGFEImageElement.cpp index 6ff83ee..e19ee78 100644 --- a/WebCore/svg/SVGFEImageElement.cpp +++ b/WebCore/svg/SVGFEImageElement.cpp @@ -41,7 +41,7 @@ SVGFEImageElement::SVGFEImageElement(const QualifiedName& tagName, Document* doc , SVGURIReference() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_preserveAspectRatio(new SVGPreserveAspectRatio()) + , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) , m_cachedImage(0) , m_filterEffect(0) { @@ -49,13 +49,10 @@ SVGFEImageElement::SVGFEImageElement(const QualifiedName& tagName, Document* doc SVGFEImageElement::~SVGFEImageElement() { - delete m_filterEffect; if (m_cachedImage) - m_cachedImage->deref(this); + m_cachedImage->removeClient(this); } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEImageElement, SVGPreserveAspectRatio*, PreserveAspectRatio, preserveAspectRatio, PreserveAspectRatio, preserveAspectRatio, SVGNames::preserveAspectRatioAttr, m_preserveAspectRatio.get()) - void SVGFEImageElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); @@ -68,10 +65,10 @@ void SVGFEImageElement::parseMappedAttribute(MappedAttribute* attr) if (!href().startsWith("#")) { // FIXME: this code needs to special-case url fragments and later look them up using getElementById instead of loading them here if (m_cachedImage) - m_cachedImage->deref(this); + m_cachedImage->removeClient(this); m_cachedImage = ownerDocument()->docLoader()->requestImage(href()); if (m_cachedImage) - m_cachedImage->ref(this); + m_cachedImage->addClient(this); } return; } @@ -87,24 +84,30 @@ void SVGFEImageElement::parseMappedAttribute(MappedAttribute* attr) void SVGFEImageElement::notifyFinished(CachedResource* finishedObj) { if (finishedObj == m_cachedImage && m_filterEffect) - m_filterEffect->setCachedImage(m_cachedImage); + m_filterEffect->setCachedImage(m_cachedImage.get()); } -SVGFEImage* SVGFEImageElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEImageElement::filterEffect(SVGResourceFilter* filter) const { - if (!m_filterEffect) - m_filterEffect = new SVGFEImage(filter); - - // The resource may already be loaded! - if (m_cachedImage) - m_filterEffect->setCachedImage(m_cachedImage); + ASSERT_NOT_REACHED(); + return 0; +} + +bool SVGFEImageElement::build(FilterBuilder* builder) +{ + if(!m_cachedImage) + return false; - setStandardAttributes(m_filterEffect); - return m_filterEffect; + builder->add(result(), FEImage::create(m_cachedImage.get())); + + return true; } +void SVGFEImageElement::getSubresourceAttributeStrings(Vector<String>& urls) const +{ + urls.append(href()); } -#endif // ENABLE(SVG) +} -// vim:ts=4:noet +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGFEImageElement.h b/WebCore/svg/SVGFEImageElement.h index 1488a64..dc88c0a 100644 --- a/WebCore/svg/SVGFEImageElement.h +++ b/WebCore/svg/SVGFEImageElement.h @@ -24,21 +24,21 @@ #define SVGFEImageElement_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) +#include "CachedResourceHandle.h" #include "SVGFilterPrimitiveStandardAttributes.h" #include "SVGURIReference.h" #include "SVGLangSpace.h" #include "SVGExternalResourcesRequired.h" #include "SVGFEImage.h" +#include "SVGPreserveAspectRatio.h" namespace WebCore { - class SVGPreserveAspectRatio; class SVGFEImageElement : public SVGFilterPrimitiveStandardAttributes, public SVGURIReference, public SVGLangSpace, public SVGExternalResourcesRequired, - public CachedResourceClient - { + public CachedResourceClient { public: SVGFEImageElement(const QualifiedName&, Document*); virtual ~SVGFEImageElement(); @@ -46,25 +46,21 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void notifyFinished(CachedResource*); - protected: - virtual SVGFEImage* filterEffect(SVGResourceFilter*) const; + virtual void getSubresourceAttributeStrings(Vector<String>&) const; + bool build(FilterBuilder*); protected: + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGFEImageElement, SVGPreserveAspectRatio*, RefPtr<SVGPreserveAspectRatio>, PreserveAspectRatio, preserveAspectRatio) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEImageElement, SVGNames::feImageTagString, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) - CachedImage* m_cachedImage; - mutable SVGFEImage* m_filterEffect; + CachedResourceHandle<CachedImage> m_cachedImage; + mutable RefPtr<FEImage> m_filterEffect; }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFELightElement.cpp b/WebCore/svg/SVGFELightElement.cpp index 52c0287..73c088f 100644 --- a/WebCore/svg/SVGFELightElement.cpp +++ b/WebCore/svg/SVGFELightElement.cpp @@ -23,23 +23,24 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFELightElement.h" - #include "SVGNames.h" namespace WebCore { +char SVGFELightElementIdentifier[] = "SVGFELightElement"; + SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) - , m_azimuth(0.0f) - , m_elevation(0.0f) - , m_x(0.0f) - , m_y(0.0f) - , m_z(0.0f) - , m_pointsAtX(0.0f) - , m_pointsAtY(0.0f) - , m_pointsAtZ(0.0f) - , m_specularExponent(1.0f) - , m_limitingConeAngle(0.0f) + , m_azimuth(this, SVGNames::azimuthAttr) + , m_elevation(this, SVGNames::elevationAttr) + , m_x(this, SVGNames::xAttr) + , m_y(this, SVGNames::yAttr) + , m_z(this, SVGNames::zAttr) + , m_pointsAtX(this, SVGNames::pointsAtXAttr) + , m_pointsAtY(this, SVGNames::pointsAtYAttr) + , m_pointsAtZ(this, SVGNames::pointsAtZAttr) + , m_specularExponent(this, SVGNames::specularExponentAttr, 1.0f) + , m_limitingConeAngle(this, SVGNames::limitingConeAngleAttr) { } @@ -47,18 +48,6 @@ SVGFELightElement::~SVGFELightElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, Azimuth, azimuth, SVGNames::azimuthAttr, m_azimuth) -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, Elevation, elevation, SVGNames::elevationAttr, m_elevation) -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, Y, y, SVGNames::yAttr, m_y) - -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, Z, z, SVGNames::zAttr, m_z) -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, PointsAtX, pointsAtX, SVGNames::pointsAtXAttr, m_pointsAtX) -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, PointsAtY, pointsAtY, SVGNames::pointsAtYAttr, m_pointsAtY) -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, PointsAtZ, pointsAtZ, SVGNames::pointsAtZAttr, m_pointsAtZ) -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, SpecularExponent, specularExponent, SVGNames::specularExponentAttr, m_specularExponent) -ANIMATED_PROPERTY_DEFINITIONS(SVGFELightElement, float, Number, number, LimitingConeAngle, limitingConeAngle, SVGNames::limitingConeAngleAttr, m_limitingConeAngle) - void SVGFELightElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); diff --git a/WebCore/svg/SVGFELightElement.h b/WebCore/svg/SVGFELightElement.h index e0b28e7..5c4a785 100644 --- a/WebCore/svg/SVGFELightElement.h +++ b/WebCore/svg/SVGFELightElement.h @@ -26,30 +26,32 @@ #include "SVGElement.h" #include "SVGLightSource.h" -namespace WebCore -{ - class SVGNumberList; - - class SVGFELightElement : public SVGElement - { +namespace WebCore { + + extern char SVGFELightElementIdentifier[]; + + class SVGFELightElement : public SVGElement { public: SVGFELightElement(const QualifiedName&, Document*); virtual ~SVGFELightElement(); - virtual SVGLightSource* lightSource() const = 0; + virtual LightSource* lightSource() const = 0; virtual void parseMappedAttribute(MappedAttribute*); + protected: + virtual const SVGElement* contextElement() const { return this; } + private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, Azimuth, azimuth) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, Elevation, elevation) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, Z, z) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, PointsAtX, pointsAtX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, PointsAtY, pointsAtY) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, PointsAtZ, pointsAtZ) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, SpecularExponent, specularExponent) - ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, float, float, LimitingConeAngle, limitingConeAngle) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::azimuthAttrString, float, Azimuth, azimuth) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::elevationAttrString, float, Elevation, elevation) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::xAttrString, float, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::yAttrString, float, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::zAttrString, float, Z, z) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::pointsAtXAttrString, float, PointsAtX, pointsAtX) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::pointsAtYAttrString, float, PointsAtY, pointsAtY) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::pointsAtZAttrString, float, PointsAtZ, pointsAtZ) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::specularExponentAttrString, float, SpecularExponent, specularExponent) + ANIMATED_PROPERTY_DECLARATIONS(SVGFELightElement, SVGFELightElementIdentifier, SVGNames::limitingConeAngleAttrString, float, LimitingConeAngle, limitingConeAngle) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEMergeElement.cpp b/WebCore/svg/SVGFEMergeElement.cpp index 7c7fd75..5ccf403 100644 --- a/WebCore/svg/SVGFEMergeElement.cpp +++ b/WebCore/svg/SVGFEMergeElement.cpp @@ -38,23 +38,30 @@ SVGFEMergeElement::SVGFEMergeElement(const QualifiedName& tagName, Document* doc SVGFEMergeElement::~SVGFEMergeElement() { - delete m_filterEffect; } -SVGFEMerge* SVGFEMergeElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEMergeElement::filterEffect(SVGResourceFilter* filter) const { - if (!m_filterEffect) - m_filterEffect = new SVGFEMerge(filter); - setStandardAttributes(m_filterEffect); + ASSERT_NOT_REACHED(); + return 0; +} - Vector<String> mergeInputs; +bool SVGFEMergeElement::build(FilterBuilder* builder) +{ + Vector<FilterEffect*> mergeInputs; for (Node* n = firstChild(); n != 0; n = n->nextSibling()) { - if (n->hasTagName(SVGNames::feMergeNodeTag)) - mergeInputs.append(static_cast<SVGFEMergeNodeElement*>(n)->in1()); + if (n->hasTagName(SVGNames::feMergeNodeTag)) { + FilterEffect* mergeEffect = builder->getEffectById(static_cast<SVGFEMergeNodeElement*>(n)->in1()); + mergeInputs.append(mergeEffect); + } } - m_filterEffect->setMergeInputs(mergeInputs); - return m_filterEffect; + if(mergeInputs.isEmpty()) + return false; + + builder->add(result(), FEMerge::create(mergeInputs)); + + return true; } } diff --git a/WebCore/svg/SVGFEMergeElement.h b/WebCore/svg/SVGFEMergeElement.h index 59898bb..6449286 100644 --- a/WebCore/svg/SVGFEMergeElement.h +++ b/WebCore/svg/SVGFEMergeElement.h @@ -27,21 +27,18 @@ #include "SVGFEMerge.h" #include "SVGFilterPrimitiveStandardAttributes.h" -namespace WebCore -{ - class SVGFEMergeElement : public SVGFilterPrimitiveStandardAttributes - { +namespace WebCore { + + class SVGFEMergeElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFEMergeElement(const QualifiedName&, Document*); virtual ~SVGFEMergeElement(); - virtual SVGFEMerge* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - mutable SVGFEMerge* m_filterEffect; + mutable RefPtr<FEMerge> m_filterEffect; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFEMergeNodeElement.cpp b/WebCore/svg/SVGFEMergeNodeElement.cpp index d46ee25..e68f4d7 100644 --- a/WebCore/svg/SVGFEMergeNodeElement.cpp +++ b/WebCore/svg/SVGFEMergeNodeElement.cpp @@ -29,6 +29,7 @@ namespace WebCore { SVGFEMergeNodeElement::SVGFEMergeNodeElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) + , m_in1(this, SVGNames::inAttr) { } @@ -36,8 +37,6 @@ SVGFEMergeNodeElement::~SVGFEMergeNodeElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEMergeNodeElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) - void SVGFEMergeNodeElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); @@ -50,5 +49,3 @@ void SVGFEMergeNodeElement::parseMappedAttribute(MappedAttribute* attr) } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEMergeNodeElement.h b/WebCore/svg/SVGFEMergeNodeElement.h index c601fde..c1abd2f 100644 --- a/WebCore/svg/SVGFEMergeNodeElement.h +++ b/WebCore/svg/SVGFEMergeNodeElement.h @@ -26,10 +26,9 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGElement.h" -namespace WebCore -{ - class SVGFEMergeNodeElement : public SVGElement - { +namespace WebCore { + + class SVGFEMergeNodeElement : public SVGElement { public: SVGFEMergeNodeElement(const QualifiedName&, Document*); virtual ~SVGFEMergeNodeElement(); @@ -40,12 +39,10 @@ namespace WebCore virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEMergeNodeElement, String, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEMergeNodeElement, SVGNames::feMergeNodeTagString, SVGNames::inAttrString, String, In1, in1) }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEOffsetElement.cpp b/WebCore/svg/SVGFEOffsetElement.cpp index 1442159..4fa572f 100644 --- a/WebCore/svg/SVGFEOffsetElement.cpp +++ b/WebCore/svg/SVGFEOffsetElement.cpp @@ -32,21 +32,17 @@ namespace WebCore { SVGFEOffsetElement::SVGFEOffsetElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_dx(0.0f) - , m_dy(0.0f) + , m_in1(this, SVGNames::inAttr) + , m_dx(this, SVGNames::dxAttr) + , m_dy(this, SVGNames::dyAttr) , m_filterEffect(0) { } SVGFEOffsetElement::~SVGFEOffsetElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFEOffsetElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEOffsetElement, float, Number, number, Dx, dx, SVGNames::dxAttr, m_dx) -ANIMATED_PROPERTY_DEFINITIONS(SVGFEOffsetElement, float, Number, number, Dy, dy, SVGNames::dyAttr, m_dy) - void SVGFEOffsetElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); @@ -60,21 +56,24 @@ void SVGFEOffsetElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFEOffset* SVGFEOffsetElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFEOffsetElement::filterEffect(SVGResourceFilter* filter) const +{ + ASSERT_NOT_REACHED(); + return 0; +} + +bool SVGFEOffsetElement::build(FilterBuilder* builder) { - if (!m_filterEffect) - m_filterEffect = new SVGFEOffset(filter); - - m_filterEffect->setIn(in1()); - m_filterEffect->setDx(dx()); - m_filterEffect->setDy(dy()); - - setStandardAttributes(m_filterEffect); - return m_filterEffect; + FilterEffect* input1 = builder->getEffectById(in1()); + + if(!input1) + return false; + + builder->add(result(), FEOffset::create(input1, dx(), dy())); + + return true; } } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEOffsetElement.h b/WebCore/svg/SVGFEOffsetElement.h index 01ee9ea..2d1b0ba 100644 --- a/WebCore/svg/SVGFEOffsetElement.h +++ b/WebCore/svg/SVGFEOffsetElement.h @@ -27,32 +27,26 @@ #include "SVGFilterPrimitiveStandardAttributes.h" #include "SVGFEOffset.h" -namespace WebCore -{ +namespace WebCore { - class SVGFEOffsetElement : public SVGFilterPrimitiveStandardAttributes - { + class SVGFEOffsetElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFEOffsetElement(const QualifiedName&, Document*); virtual ~SVGFEOffsetElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFEOffset* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, String, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, float, float, Dx, dx) - ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, float, float, Dy, dy) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, SVGNames::feOffsetTagString, SVGNames::inAttrString, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, SVGNames::feOffsetTagString, SVGNames::dxAttrString, float, Dx, dx) + ANIMATED_PROPERTY_DECLARATIONS(SVGFEOffsetElement, SVGNames::feOffsetTagString, SVGNames::dyAttrString, float, Dy, dy) - mutable SVGFEOffset* m_filterEffect; + mutable RefPtr<FEOffset> m_filterEffect; }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFEPointLightElement.cpp b/WebCore/svg/SVGFEPointLightElement.cpp index ff33330..f30f6db 100644 --- a/WebCore/svg/SVGFEPointLightElement.cpp +++ b/WebCore/svg/SVGFEPointLightElement.cpp @@ -34,10 +34,10 @@ SVGFEPointLightElement::~SVGFEPointLightElement() { } -SVGLightSource* SVGFEPointLightElement::lightSource() const +LightSource* SVGFEPointLightElement::lightSource() const { FloatPoint3D pos(x(), y(), z()); - return new SVGPointLightSource(pos); + return new PointLightSource(pos); } } diff --git a/WebCore/svg/SVGFEPointLightElement.h b/WebCore/svg/SVGFEPointLightElement.h index 191f7f6..5b72e09 100644 --- a/WebCore/svg/SVGFEPointLightElement.h +++ b/WebCore/svg/SVGFEPointLightElement.h @@ -31,7 +31,7 @@ namespace WebCore SVGFEPointLightElement(const QualifiedName&, Document*); virtual ~SVGFEPointLightElement(); - virtual SVGLightSource* lightSource() const; + virtual LightSource* lightSource() const; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFESpecularLightingElement.cpp b/WebCore/svg/SVGFESpecularLightingElement.cpp index 509794a..c7b7410 100644 --- a/WebCore/svg/SVGFESpecularLightingElement.cpp +++ b/WebCore/svg/SVGFESpecularLightingElement.cpp @@ -35,27 +35,20 @@ namespace WebCore { SVGFESpecularLightingElement::SVGFESpecularLightingElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_specularConstant(1.0f) - , m_specularExponent(1.0f) - , m_surfaceScale(1.0f) - , m_kernelUnitLengthX(0.0f) - , m_kernelUnitLengthY(0.0f) + , m_in1(this, SVGNames::inAttr) + , m_specularConstant(this, SVGNames::specularConstantAttr, 1.0f) + , m_specularExponent(this, SVGNames::specularExponentAttr, 1.0f) + , m_surfaceScale(this, SVGNames::surfaceScaleAttr, 1.0f) + , m_kernelUnitLengthX(this, SVGNames::kernelUnitLengthAttr) + , m_kernelUnitLengthY(this, SVGNames::kernelUnitLengthAttr) , m_filterEffect(0) { } SVGFESpecularLightingElement::~SVGFESpecularLightingElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFESpecularLightingElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) -ANIMATED_PROPERTY_DEFINITIONS(SVGFESpecularLightingElement, float, Number, number, SpecularConstant, specularConstant, SVGNames::specularConstantAttr, m_specularConstant) -ANIMATED_PROPERTY_DEFINITIONS(SVGFESpecularLightingElement, float, Number, number, SpecularExponent, specularExponent, SVGNames::specularExponentAttr, m_specularExponent) -ANIMATED_PROPERTY_DEFINITIONS(SVGFESpecularLightingElement, float, Number, number, SurfaceScale, surfaceScale, SVGNames::surfaceScaleAttr, m_surfaceScale) -ANIMATED_PROPERTY_DEFINITIONS(SVGFESpecularLightingElement, float, Number, number, KernelUnitLengthX, kernelUnitLengthX, "kernelUnitLengthX", m_kernelUnitLengthX) -ANIMATED_PROPERTY_DEFINITIONS(SVGFESpecularLightingElement, float, Number, number, KernelUnitLengthY, kernelUnitLengthY, "kernelUnitLengthY", m_kernelUnitLengthY) - void SVGFESpecularLightingElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); @@ -77,42 +70,17 @@ void SVGFESpecularLightingElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFESpecularLighting* SVGFESpecularLightingElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFESpecularLightingElement::filterEffect(SVGResourceFilter* filter) const { - if (!m_filterEffect) - m_filterEffect = new SVGFESpecularLighting(filter); - - m_filterEffect->setIn(in1()); - m_filterEffect->setSpecularConstant((specularConstant())); - m_filterEffect->setSpecularExponent((specularExponent())); - m_filterEffect->setSurfaceScale((surfaceScale())); - m_filterEffect->setKernelUnitLengthX((kernelUnitLengthX())); - m_filterEffect->setKernelUnitLengthY((kernelUnitLengthY())); - - SVGFESpecularLightingElement* nonConstThis = const_cast<SVGFESpecularLightingElement*>(this); - - RenderStyle* parentStyle = nonConstThis->styleForRenderer(parent()->renderer()); - RenderStyle* filterStyle = nonConstThis->resolveStyle(parentStyle); - - m_filterEffect->setLightingColor(filterStyle->svgStyle()->lightingColor()); - - parentStyle->deref(document()->renderArena()); - filterStyle->deref(document()->renderArena()); - - setStandardAttributes(m_filterEffect); - - updateLights(); - return m_filterEffect; + ASSERT_NOT_REACHED(); + return 0; } -void SVGFESpecularLightingElement::updateLights() const +LightSource* SVGFESpecularLightingElement::findLights() const { - if (!m_filterEffect) - return; - - SVGLightSource* light = 0; + LightSource* light = 0; for (Node* n = firstChild(); n; n = n->nextSibling()) { - if (n->hasTagName(SVGNames::feDistantLightTag) || + if (n->hasTagName(SVGNames::feDistantLightTag) || n->hasTagName(SVGNames::fePointLightTag) || n->hasTagName(SVGNames::feSpotLightTag)) { SVGFELightElement* lightNode = static_cast<SVGFELightElement*>(n); @@ -121,11 +89,27 @@ void SVGFESpecularLightingElement::updateLights() const } } - m_filterEffect->setLightSource(light); + return light; } +bool SVGFESpecularLightingElement::build(FilterBuilder* builder) +{ + FilterEffect* input1 = builder->getEffectById(in1()); + + if(!input1) + return false; + + RefPtr<RenderStyle> filterStyle = styleForRenderer(); + + Color color = filterStyle->svgStyle()->lightingColor(); + + RefPtr<FilterEffect> addedEffect = FESpecularLighting::create(input1, color, surfaceScale(), specularConstant(), + specularExponent(), kernelUnitLengthX(), kernelUnitLengthY(), findLights()); + builder->add(result(), addedEffect.release()); + + return true; } -#endif // ENABLE(SVG) +} -// vim:ts=4:noet +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGFESpecularLightingElement.h b/WebCore/svg/SVGFESpecularLightingElement.h index 435882e..d76cb43 100644 --- a/WebCore/svg/SVGFESpecularLightingElement.h +++ b/WebCore/svg/SVGFESpecularLightingElement.h @@ -26,33 +26,33 @@ #include "SVGFESpecularLighting.h" #include "SVGFilterPrimitiveStandardAttributes.h" -namespace WebCore -{ +namespace WebCore { + + extern char SVGKernelUnitLengthXIdentifier[]; + extern char SVGKernelUnitLengthYIdentifier[]; + class SVGColor; - class SVGFESpecularLightingElement : public SVGFilterPrimitiveStandardAttributes - { + class SVGFESpecularLightingElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFESpecularLightingElement(const QualifiedName&, Document*); virtual ~SVGFESpecularLightingElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFESpecularLighting* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, String, String, In1, in1) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, float, float, SpecularConstant, specularConstant) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, float, float, SpecularExponent, specularExponent) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, float, float, SurfaceScale, surfaceScale) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, float, float, KernelUnitLengthX, kernelUnitLengthX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, float, float, KernelUnitLengthY, kernelUnitLengthY) - - mutable SVGFESpecularLighting* m_filterEffect; + ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGNames::inAttrString, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGNames::specularConstantAttrString, float, SpecularConstant, specularConstant) + ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGNames::specularExponentAttrString, float, SpecularExponent, specularExponent) + ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGNames::surfaceScaleAttrString, float, SurfaceScale, surfaceScale) + ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGKernelUnitLengthXIdentifier, float, KernelUnitLengthX, kernelUnitLengthX) + ANIMATED_PROPERTY_DECLARATIONS(SVGFESpecularLightingElement, SVGNames::feSpecularLightingTagString, SVGKernelUnitLengthYIdentifier, float, KernelUnitLengthY, kernelUnitLengthY) + + mutable RefPtr<FESpecularLighting> m_filterEffect; - void updateLights() const; + LightSource* findLights() const; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFESpotLightElement.cpp b/WebCore/svg/SVGFESpotLightElement.cpp index 7d89f78..5add579 100644 --- a/WebCore/svg/SVGFESpotLightElement.cpp +++ b/WebCore/svg/SVGFESpotLightElement.cpp @@ -34,7 +34,7 @@ SVGFESpotLightElement::~SVGFESpotLightElement() { } -SVGLightSource* SVGFESpotLightElement::lightSource() const +LightSource* SVGFESpotLightElement::lightSource() const { FloatPoint3D pos(x(), y(), z()); @@ -44,7 +44,7 @@ SVGLightSource* SVGFESpotLightElement::lightSource() const pointsAtZ() - pos.z()); direction.normalize(); - return new SVGSpotLightSource(pos, direction, specularExponent(), limitingConeAngle()); + return new SpotLightSource(pos, direction, specularExponent(), limitingConeAngle()); } } diff --git a/WebCore/svg/SVGFESpotLightElement.h b/WebCore/svg/SVGFESpotLightElement.h index 5738201..2989b14 100644 --- a/WebCore/svg/SVGFESpotLightElement.h +++ b/WebCore/svg/SVGFESpotLightElement.h @@ -31,7 +31,7 @@ namespace WebCore SVGFESpotLightElement(const QualifiedName&, Document*); virtual ~SVGFESpotLightElement(); - virtual SVGLightSource* lightSource() const; + virtual LightSource* lightSource() const; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFETileElement.cpp b/WebCore/svg/SVGFETileElement.cpp index 62fc05b..bf90c33 100644 --- a/WebCore/svg/SVGFETileElement.cpp +++ b/WebCore/svg/SVGFETileElement.cpp @@ -33,17 +33,15 @@ namespace WebCore { SVGFETileElement::SVGFETileElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) + , m_in1(this, SVGNames::inAttr) , m_filterEffect(0) { } SVGFETileElement::~SVGFETileElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFETileElement, String, String, string, In1, in1, SVGNames::inAttr, m_in1) - void SVGFETileElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); @@ -53,19 +51,24 @@ void SVGFETileElement::parseMappedAttribute(MappedAttribute* attr) SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFETile* SVGFETileElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFETileElement::filterEffect(SVGResourceFilter* filter) const { - if (!m_filterEffect) - m_filterEffect = new SVGFETile(filter); + ASSERT_NOT_REACHED(); + return 0; +} - m_filterEffect->setIn(in1()); +bool SVGFETileElement::build(FilterBuilder* builder) +{ + FilterEffect* input1 = builder->getEffectById(in1()); - setStandardAttributes(m_filterEffect); - return m_filterEffect; + if(!input1) + return false; + + builder->add(result(), FETile::create(input1)); + + return true; } } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFETileElement.h b/WebCore/svg/SVGFETileElement.h index 256e8a0..ba68115 100644 --- a/WebCore/svg/SVGFETileElement.h +++ b/WebCore/svg/SVGFETileElement.h @@ -27,25 +27,21 @@ #include "SVGFilterPrimitiveStandardAttributes.h" #include "SVGFETile.h" -namespace WebCore -{ +namespace WebCore { - class SVGFETileElement : public SVGFilterPrimitiveStandardAttributes - { + class SVGFETileElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFETileElement(const QualifiedName&, Document*); virtual ~SVGFETileElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFETile* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFETileElement, String, String, In1, in1) + ANIMATED_PROPERTY_DECLARATIONS(SVGFETileElement, SVGNames::feTileTagString, SVGNames::inAttrString, String, In1, in1) - mutable SVGFETile* m_filterEffect; + mutable RefPtr<FETile> m_filterEffect; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFETurbulenceElement.cpp b/WebCore/svg/SVGFETurbulenceElement.cpp index 0abc83c..f51d835 100644 --- a/WebCore/svg/SVGFETurbulenceElement.cpp +++ b/WebCore/svg/SVGFETurbulenceElement.cpp @@ -30,38 +30,33 @@ namespace WebCore { +char SVGBaseFrequencyXIdentifier[] = "SVGBaseFrequencyX"; +char SVGBaseFrequencyYIdentifier[] = "SVGBaseFrequencyY"; + SVGFETurbulenceElement::SVGFETurbulenceElement(const QualifiedName& tagName, Document* doc) : SVGFilterPrimitiveStandardAttributes(tagName, doc) - , m_baseFrequencyX(0.0f) - , m_baseFrequencyY(0.0f) - , m_numOctaves(1) - , m_seed(0.0f) - , m_stitchTiles(SVG_STITCHTYPE_NOSTITCH) - , m_type(SVG_TURBULENCE_TYPE_TURBULENCE) + , m_baseFrequencyX(this, SVGNames::baseFrequencyAttr) + , m_baseFrequencyY(this, SVGNames::baseFrequencyAttr) + , m_numOctaves(this, SVGNames::numOctavesAttr, 1) + , m_seed(this, SVGNames::seedAttr) + , m_stitchTiles(this, SVGNames::stitchTilesAttr, SVG_STITCHTYPE_NOSTITCH) + , m_type(this, SVGNames::typeAttr, FETURBULENCE_TYPE_TURBULENCE) , m_filterEffect(0) { } SVGFETurbulenceElement::~SVGFETurbulenceElement() { - delete m_filterEffect; } -ANIMATED_PROPERTY_DEFINITIONS(SVGFETurbulenceElement, float, Number, number, BaseFrequencyX, baseFrequencyX, "baseFrequencyX", m_baseFrequencyX) -ANIMATED_PROPERTY_DEFINITIONS(SVGFETurbulenceElement, float, Number, number, BaseFrequencyY, baseFrequencyY, "baseFrequencyY", m_baseFrequencyY) -ANIMATED_PROPERTY_DEFINITIONS(SVGFETurbulenceElement, float, Number, number, Seed, seed, SVGNames::seedAttr, m_seed) -ANIMATED_PROPERTY_DEFINITIONS(SVGFETurbulenceElement, long, Integer, integer, NumOctaves, numOctaves, SVGNames::numOctavesAttr, m_numOctaves) -ANIMATED_PROPERTY_DEFINITIONS(SVGFETurbulenceElement, int, Enumeration, enumeration, StitchTiles, stitchTiles, SVGNames::stitchTilesAttr, m_stitchTiles) -ANIMATED_PROPERTY_DEFINITIONS(SVGFETurbulenceElement, int, Enumeration, enumeration, Type, type, SVGNames::typeAttr, m_type) - void SVGFETurbulenceElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); if (attr->name() == SVGNames::typeAttr) { if (value == "fractalNoise") - setTypeBaseValue(SVG_TURBULENCE_TYPE_FRACTALNOISE); + setTypeBaseValue(FETURBULENCE_TYPE_FRACTALNOISE); else if (value == "turbulence") - setTypeBaseValue(SVG_TURBULENCE_TYPE_TURBULENCE); + setTypeBaseValue(FETURBULENCE_TYPE_TURBULENCE); } else if (attr->name() == SVGNames::stitchTilesAttr) { if (value == "stitch") setStitchTilesBaseValue(SVG_STITCHTYPE_STITCH); @@ -76,30 +71,26 @@ void SVGFETurbulenceElement::parseMappedAttribute(MappedAttribute* attr) } else if (attr->name() == SVGNames::seedAttr) setSeedBaseValue(value.toFloat()); else if (attr->name() == SVGNames::numOctavesAttr) - setNumOctavesBaseValue(value.deprecatedString().toUInt()); + setNumOctavesBaseValue(value.toUIntStrict()); else SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(attr); } -SVGFETurbulence* SVGFETurbulenceElement::filterEffect(SVGResourceFilter* filter) const +SVGFilterEffect* SVGFETurbulenceElement::filterEffect(SVGResourceFilter* filter) const { - - if (!m_filterEffect) - m_filterEffect = new SVGFETurbulence(filter); - - m_filterEffect->setType((SVGTurbulanceType) type()); - m_filterEffect->setBaseFrequencyX(baseFrequencyX()); - m_filterEffect->setBaseFrequencyY(baseFrequencyY()); - m_filterEffect->setNumOctaves(numOctaves()); - m_filterEffect->setSeed(seed()); - m_filterEffect->setStitchTiles(stitchTiles() == SVG_STITCHTYPE_STITCH); - - setStandardAttributes(m_filterEffect); - return m_filterEffect; + ASSERT_NOT_REACHED(); + return 0; } +bool SVGFETurbulenceElement::build(FilterBuilder* builder) +{ + RefPtr<FilterEffect> addedEffect = FETurbulence::create(static_cast<TurbulanceType> (type()), baseFrequencyX(), + baseFrequencyY(), numOctaves(), seed(), stitchTiles() == SVG_STITCHTYPE_STITCH); + builder->add(result(), addedEffect.release()); + + return true; } -#endif // ENABLE(SVG) +} -// vim:ts=4:noet +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGFETurbulenceElement.h b/WebCore/svg/SVGFETurbulenceElement.h index a62bf15..bae2d9b 100644 --- a/WebCore/svg/SVGFETurbulenceElement.h +++ b/WebCore/svg/SVGFETurbulenceElement.h @@ -27,40 +27,38 @@ #include "SVGFETurbulence.h" #include "SVGFilterPrimitiveStandardAttributes.h" -namespace WebCore -{ +namespace WebCore { + + extern char SVGBaseFrequencyXIdentifier[]; + extern char SVGBaseFrequencyYIdentifier[]; + enum SVGStitchOptions { SVG_STITCHTYPE_UNKNOWN = 0, SVG_STITCHTYPE_STITCH = 1, SVG_STITCHTYPE_NOSTITCH = 2 }; - class SVGFETurbulenceElement : public SVGFilterPrimitiveStandardAttributes - { + class SVGFETurbulenceElement : public SVGFilterPrimitiveStandardAttributes { public: SVGFETurbulenceElement(const QualifiedName&, Document*); virtual ~SVGFETurbulenceElement(); virtual void parseMappedAttribute(MappedAttribute*); - virtual SVGFETurbulence* filterEffect(SVGResourceFilter*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual SVGFilterEffect* filterEffect(SVGResourceFilter*) const; + bool build(FilterBuilder*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, float, float, BaseFrequencyX, baseFrequencyX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, float, float, BaseFrequencyY, baseFrequencyY) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, long, long, NumOctaves, numOctaves) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, float, float, Seed, seed) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, int, int, StitchTiles, stitchTiles) - ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, int, int, Type, type) + ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGBaseFrequencyXIdentifier, float, BaseFrequencyX, baseFrequencyX) + ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGBaseFrequencyYIdentifier, float, BaseFrequencyY, baseFrequencyY) + ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGNames::numOctavesAttrString, long, NumOctaves, numOctaves) + ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGNames::seedAttrString, float, Seed, seed) + ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGNames::stitchTilesAttrString, int, StitchTiles, stitchTiles) + ANIMATED_PROPERTY_DECLARATIONS(SVGFETurbulenceElement, SVGNames::feTurbulenceTagString, SVGNames::typeAttrString, int, Type, type) - mutable SVGFETurbulence* m_filterEffect; + mutable RefPtr<FETurbulence> m_filterEffect; }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFilterElement.cpp b/WebCore/svg/SVGFilterElement.cpp index 125d084..774232f 100644 --- a/WebCore/svg/SVGFilterElement.cpp +++ b/WebCore/svg/SVGFilterElement.cpp @@ -35,42 +35,31 @@ namespace WebCore { +char SVGFilterResXIdentifier[] = "SVGFilterResX"; +char SVGFilterResYIdentifier[] = "SVGFilterResY"; + SVGFilterElement::SVGFilterElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) , SVGURIReference() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_filterUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_primitiveUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) - , m_filterResX(0) - , m_filterResY(0) + , m_filterUnits(this, SVGNames::filterUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + , m_primitiveUnits(this, SVGNames::primitiveUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) + , m_x(this, SVGNames::xAttr, LengthModeWidth, "-10%") + , m_y(this, SVGNames::yAttr, LengthModeHeight, "-10%") + , m_width(this, SVGNames::widthAttr, LengthModeWidth, "120%") + , m_height(this, SVGNames::heightAttr, LengthModeHeight, "120%") + , m_filterResX(this, SVGNames::filterResAttr) + , m_filterResY(this, SVGNames::filterResAttr) { - // Spec: If the attribute is not specified, the effect is as if a value of "-10%" were specified. - setXBaseValue(SVGLength(this, LengthModeWidth, "-10%")); - setYBaseValue(SVGLength(this, LengthModeHeight, "-10%")); - - // Spec: If the attribute is not specified, the effect is as if a value of "120%" were specified. - setWidthBaseValue(SVGLength(this, LengthModeWidth, "120%")); - setHeightBaseValue(SVGLength(this, LengthModeHeight, "120%")); + // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified. + // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified. } SVGFilterElement::~SVGFilterElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, int, Enumeration, enumeration, FilterUnits, filterUnits, SVGNames::filterUnitsAttr, m_filterUnits) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, int, Enumeration, enumeration, PrimitiveUnits, primitiveUnits, SVGNames::primitiveUnitsAttr, m_primitiveUnits) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, long, Integer, integer, FilterResX, filterResX, "filterResX", m_filterResX) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, long, Integer, integer, FilterResY, filterResY, "filterResY", m_filterResY) - void SVGFilterElement::setFilterRes(unsigned long, unsigned long) const { } @@ -89,17 +78,20 @@ void SVGFilterElement::parseMappedAttribute(MappedAttribute* attr) else if (value == "objectBoundingBox") setPrimitiveUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); } else if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, value)); + setXBaseValue(SVGLength(LengthModeWidth, value)); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, value)); + setYBaseValue(SVGLength(LengthModeHeight, value)); else if (attr->name() == SVGNames::widthAttr) - setWidthBaseValue(SVGLength(this, LengthModeWidth, value)); + setWidthBaseValue(SVGLength(LengthModeWidth, value)); else if (attr->name() == SVGNames::heightAttr) - setHeightBaseValue(SVGLength(this, LengthModeHeight, value)); + setHeightBaseValue(SVGLength(LengthModeHeight, value)); else { - if (SVGURIReference::parseMappedAttribute(attr)) return; - if (SVGLangSpace::parseMappedAttribute(attr)) return; - if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) return; + if (SVGURIReference::parseMappedAttribute(attr)) + return; + if (SVGLangSpace::parseMappedAttribute(attr)) + return; + if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) + return; SVGStyledElement::parseMappedAttribute(attr); } @@ -127,10 +119,10 @@ SVGResource* SVGFilterElement::canvasResource() m_filter->setXBoundingBoxMode(x().unitType() == LengthTypePercentage); m_filter->setYBoundingBoxMode(y().unitType() == LengthTypePercentage); - _x = x().value(); - _y = y().value(); - _width = width().value(); - _height = height().value(); + _x = x().value(this); + _y = y().value(this); + _width = width().value(this); + _height = height().value(this); } m_filter->setFilterRect(FloatRect(_x, _y, _width, _height)); diff --git a/WebCore/svg/SVGFilterElement.h b/WebCore/svg/SVGFilterElement.h index f2d9773..c907b9c 100644 --- a/WebCore/svg/SVGFilterElement.h +++ b/WebCore/svg/SVGFilterElement.h @@ -32,13 +32,14 @@ #include "SVGURIReference.h" namespace WebCore { - class SVGLength; + + extern char SVGFilterResXIdentifier[]; + extern char SVGFilterResYIdentifier[]; class SVGFilterElement : public SVGStyledElement, public SVGURIReference, public SVGLangSpace, - public SVGExternalResourcesRequired - { + public SVGExternalResourcesRequired { public: SVGFilterElement(const QualifiedName&, Document*); virtual ~SVGFilterElement(); @@ -54,17 +55,14 @@ namespace WebCore { virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, int, int, FilterUnits, filterUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, int, int, PrimitiveUnits, primitiveUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGLength, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, long, long, FilterResX, filterResX) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, long, long, FilterResY, filterResY) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::filterUnitsAttrString, int, FilterUnits, filterUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::primitiveUnitsAttrString, int, PrimitiveUnits, primitiveUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGNames::heightAttrString, SVGLength, Height, height) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGFilterResXIdentifier, long, FilterResX, filterResX) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterElement, SVGNames::filterTagString, SVGFilterResYIdentifier, long, FilterResY, filterResY) RefPtr<SVGResourceFilter> m_filter; }; @@ -73,5 +71,3 @@ namespace WebCore { #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp index 59f67e1..eab7bdd 100644 --- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp +++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp @@ -34,43 +34,35 @@ namespace WebCore { +char SVGFilterPrimitiveStandardAttributesIdentifierIdentifier[] = "SVGFilterPrimitiveStandardAttributesIdentifier"; + SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) + , m_x(this, SVGNames::xAttr, LengthModeWidth, "0%") + , m_y(this, SVGNames::yAttr, LengthModeHeight, "0%") + , m_width(this, SVGNames::widthAttr, LengthModeWidth, "100%") + , m_height(this, SVGNames::heightAttr, LengthModeHeight, "100%") + , m_result(this, SVGNames::resultAttr) { - // Spec: If the attribute is not specified, the effect is as if a value of "0%" were specified. - setXBaseValue(SVGLength(this, LengthModeWidth, "0%")); - setYBaseValue(SVGLength(this, LengthModeHeight, "0%")); - - // Spec: If the attribute is not specified, the effect is as if a value of "100%" were specified. - setWidthBaseValue(SVGLength(this, LengthModeWidth, "100%")); - setHeightBaseValue(SVGLength(this, LengthModeHeight, "100%")); + // Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified. + // Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified. } SVGFilterPrimitiveStandardAttributes::~SVGFilterPrimitiveStandardAttributes() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterPrimitiveStandardAttributes, SVGLength, Length, length, X, x, SVGNames::xAttr.localName(), m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterPrimitiveStandardAttributes, SVGLength, Length, length, Y, y, SVGNames::yAttr.localName(), m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterPrimitiveStandardAttributes, SVGLength, Length, length, Width, width, SVGNames::widthAttr.localName(), m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterPrimitiveStandardAttributes, SVGLength, Length, length, Height, height, SVGNames::heightAttr.localName(), m_height) -ANIMATED_PROPERTY_DEFINITIONS(SVGFilterPrimitiveStandardAttributes, String, String, string, Result, result, SVGNames::resultAttr.localName(), m_result) - void SVGFilterPrimitiveStandardAttributes::parseMappedAttribute(MappedAttribute* attr) { const AtomicString& value = attr->value(); if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, value)); + setXBaseValue(SVGLength(LengthModeWidth, value)); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, value)); + setYBaseValue(SVGLength(LengthModeHeight, value)); else if (attr->name() == SVGNames::widthAttr) - setWidthBaseValue(SVGLength(this, LengthModeWidth, value)); + setWidthBaseValue(SVGLength(LengthModeWidth, value)); else if (attr->name() == SVGNames::heightAttr) - setHeightBaseValue(SVGLength(this, LengthModeHeight, value)); + setHeightBaseValue(SVGLength(LengthModeHeight, value)); else if (attr->name() == SVGNames::resultAttr) setResultBaseValue(value); else @@ -99,7 +91,7 @@ void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(SVGFilterEffect _x = x().valueAsPercentage(); } else { filterEffect->setXBoundingBoxMode(false); - _x = x().value(); + _x = x().value(this); } if (y().unitType() == LengthTypePercentage) { @@ -107,7 +99,7 @@ void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(SVGFilterEffect _y = y().valueAsPercentage(); } else { filterEffect->setYBoundingBoxMode(false); - _y = y().value(); + _y = y().value(this); } if (width().unitType() == LengthTypePercentage) { @@ -115,7 +107,7 @@ void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(SVGFilterEffect _width = width().valueAsPercentage(); } else { filterEffect->setWidthBoundingBoxMode(false); - _width = width().value(); + _width = width().value(this); } if (height().unitType() == LengthTypePercentage) { @@ -123,7 +115,7 @@ void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(SVGFilterEffect _height = height().valueAsPercentage(); } else { filterEffect->setHeightBoundingBoxMode(false); - _height = height().value(); + _height = height().value(this); } } @@ -134,5 +126,3 @@ void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(SVGFilterEffect } #endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h index b639282..bbdeb00 100644 --- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h +++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h @@ -24,14 +24,17 @@ #define SVGFilterPrimitiveStandardAttributes_h #if ENABLE(SVG) +#include "FilterBuilder.h" #include "SVGStyledElement.h" namespace WebCore { + + extern char SVGFilterPrimitiveStandardAttributesIdentifier[]; + class SVGFilterEffect; class SVGResourceFilter; - class SVGFilterPrimitiveStandardAttributes : public SVGStyledElement - { + class SVGFilterPrimitiveStandardAttributes : public SVGStyledElement { public: SVGFilterPrimitiveStandardAttributes(const QualifiedName&, Document*); virtual ~SVGFilterPrimitiveStandardAttributes(); @@ -44,22 +47,18 @@ namespace WebCore { virtual bool rendererIsNeeded(RenderStyle*) { return false; } protected: - void setStandardAttributes(SVGFilterEffect*) const; - - protected: virtual const SVGElement* contextElement() const { return this; } + void setStandardAttributes(SVGFilterEffect*) const; private: - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGLength, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, String, String, Result, result) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::heightAttrString, SVGLength, Height, height) + ANIMATED_PROPERTY_DECLARATIONS(SVGFilterPrimitiveStandardAttributes, SVGFilterPrimitiveStandardAttributesIdentifier, SVGNames::resultAttrString, String, Result, result) }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFitToViewBox.cpp b/WebCore/svg/SVGFitToViewBox.cpp index aaaf003..69e077e 100644 --- a/WebCore/svg/SVGFitToViewBox.cpp +++ b/WebCore/svg/SVGFitToViewBox.cpp @@ -26,8 +26,8 @@ #include "SVGFitToViewBox.h" #include "AffineTransform.h" +#include "Document.h" #include "FloatRect.h" -#include "SVGDocumentExtensions.h" #include "SVGNames.h" #include "SVGParserUtilities.h" #include "SVGPreserveAspectRatio.h" @@ -35,9 +35,11 @@ namespace WebCore { +char SVGFitToViewBoxIdentifier[] = "SVGFitToViewBox"; + SVGFitToViewBox::SVGFitToViewBox() - : m_viewBox() - , m_preserveAspectRatio(new SVGPreserveAspectRatio()) + : m_viewBox(this, SVGNames::viewBoxAttr) + , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) { } @@ -45,9 +47,6 @@ SVGFitToViewBox::~SVGFitToViewBox() { } -ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(SVGFitToViewBox, FloatRect, Rect, rect, ViewBox, viewBox, SVGNames::viewBoxAttr, m_viewBox) -ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(SVGFitToViewBox, SVGPreserveAspectRatio*, PreserveAspectRatio, preserveAspectRatio, PreserveAspectRatio, preserveAspectRatio, SVGNames::preserveAspectRatioAttr, m_preserveAspectRatio.get()) - bool SVGFitToViewBox::parseViewBox(const UChar*& c, const UChar* end, float& x, float& y, float& w, float& h, bool validate) { Document* doc = contextElement()->document(); diff --git a/WebCore/svg/SVGFitToViewBox.h b/WebCore/svg/SVGFitToViewBox.h index 16ea1c2..cc612ec 100644 --- a/WebCore/svg/SVGFitToViewBox.h +++ b/WebCore/svg/SVGFitToViewBox.h @@ -25,30 +25,30 @@ #if ENABLE(SVG) #include "SVGElement.h" +#include "SVGPreserveAspectRatio.h" namespace WebCore { + extern char SVGFitToViewBoxIdentifier[]; + class AffineTransform; - class SVGPreserveAspectRatio; class SVGFitToViewBox { public: SVGFitToViewBox(); virtual ~SVGFitToViewBox(); - // 'SVGFitToViewBox' functions bool parseViewBox(const UChar*& start, const UChar* end, float& x, float& y, float& w, float& h, bool validate = true); virtual AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const; bool parseMappedAttribute(MappedAttribute*); bool isKnownAttribute(const QualifiedName&); - protected: virtual const SVGElement* contextElement() const = 0; private: - ANIMATED_PROPERTY_DECLARATIONS_WITH_CONTEXT(SVGFitToViewBox, FloatRect, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_DECLARATIONS_WITH_CONTEXT(SVGFitToViewBox, SVGPreserveAspectRatio*, RefPtr<SVGPreserveAspectRatio>, PreserveAspectRatio, preserveAspectRatio) + ANIMATED_PROPERTY_DECLARATIONS(SVGFitToViewBox, SVGFitToViewBoxIdentifier, SVGNames::viewBoxAttrString, FloatRect, ViewBox, viewBox) + ANIMATED_PROPERTY_DECLARATIONS(SVGFitToViewBox, SVGFitToViewBoxIdentifier, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) }; } // namespace WebCore diff --git a/WebCore/svg/SVGFont.cpp b/WebCore/svg/SVGFont.cpp index 0511acb..ece667f 100644 --- a/WebCore/svg/SVGFont.cpp +++ b/WebCore/svg/SVGFont.cpp @@ -27,8 +27,10 @@ #include "GraphicsContext.h" #include "RenderObject.h" #include "SimpleFontData.h" +#include "SVGAltGlyphElement.h" #include "SVGFontData.h" #include "SVGGlyphElement.h" +#include "SVGGlyphMap.h" #include "SVGFontElement.h" #include "SVGFontFaceElement.h" #include "SVGMissingGlyphElement.h" @@ -107,10 +109,10 @@ static inline SVGGlyphIdentifier::ArabicForm processArabicFormDetection(const UC static Vector<SVGGlyphIdentifier::ArabicForm> charactersWithArabicForm(const String& input, bool rtl) { Vector<SVGGlyphIdentifier::ArabicForm> forms; - unsigned int length = input.length(); + unsigned length = input.length(); bool containsArabic = false; - for (unsigned int i = 0; i < length; ++i) { + for (unsigned i = 0; i < length; ++i) { if (isArabicChar(input[i])) { containsArabic = true; break; @@ -123,17 +125,18 @@ static Vector<SVGGlyphIdentifier::ArabicForm> charactersWithArabicForm(const Str bool lastCharShapesRight = false; // Start identifying arabic forms - if (rtl) + if (rtl) { for (int i = length - 1; i >= 0; --i) forms.prepend(processArabicFormDetection(input[i], lastCharShapesRight, forms.isEmpty() ? 0 : &forms.first())); - else - for (unsigned int i = 0; i < length; ++i) + } else { + for (unsigned i = 0; i < length; ++i) forms.append(processArabicFormDetection(input[i], lastCharShapesRight, forms.isEmpty() ? 0 : &forms.last())); + } return forms; } -static inline bool isCompatibleArabicForm(const SVGGlyphIdentifier& identifier, const Vector<SVGGlyphIdentifier::ArabicForm>& chars, unsigned int startPosition, unsigned int endPosition) +static inline bool isCompatibleArabicForm(const SVGGlyphIdentifier& identifier, const Vector<SVGGlyphIdentifier::ArabicForm>& chars, unsigned startPosition, unsigned endPosition) { if (chars.isEmpty()) return true; @@ -143,7 +146,7 @@ static inline bool isCompatibleArabicForm(const SVGGlyphIdentifier& identifier, ASSERT(end <= chars.end()); for (; it != end; ++it) { - if ((*it) != identifier.arabicForm && (*it) != SVGGlyphIdentifier::None) + if (*it != static_cast<SVGGlyphIdentifier::ArabicForm>(identifier.arabicForm) && *it != SVGGlyphIdentifier::None) return false; } @@ -151,7 +154,7 @@ static inline bool isCompatibleArabicForm(const SVGGlyphIdentifier& identifier, } static inline bool isCompatibleGlyph(const SVGGlyphIdentifier& identifier, bool isVerticalText, const String& language, - const Vector<SVGGlyphIdentifier::ArabicForm>& chars, unsigned int startPosition, unsigned int endPosition) + const Vector<SVGGlyphIdentifier::ArabicForm>& chars, unsigned startPosition, unsigned endPosition) { bool valid = true; @@ -189,8 +192,7 @@ static inline bool isCompatibleGlyph(const SVGGlyphIdentifier& identifier, bool bool found = false; for (; it != end; ++it) { - String cur = (*it); - + const String& cur = *it; if (cur == language || cur == languagePrefix) { found = true; break; @@ -241,52 +243,64 @@ struct SVGTextRunWalker { // Should hold true for SVG text, otherwhise sth. is wrong ASSERT(to - from == run.length()); - int maximumHashKeyLength = m_fontElement->maximumHashKeyLength(); - ASSERT(maximumHashKeyLength >= 0); - Vector<SVGGlyphIdentifier::ArabicForm> chars(charactersWithArabicForm(String(run.data(from), run.length()), run.rtl())); SVGGlyphIdentifier identifier; bool foundGlyph = false; int characterLookupRange; + int endOfScanRange = to + m_walkerData.extraCharsAvailable; + + bool haveAltGlyph = false; + SVGGlyphIdentifier altGlyphIdentifier; + if (RenderObject* renderObject = run.referencingRenderObject()) { + if (renderObject->element() && renderObject->element()->hasTagName(SVGNames::altGlyphTag)) { + SVGGlyphElement* glyphElement = static_cast<SVGAltGlyphElement*>(renderObject->element())->glyphElement(); + if (glyphElement) { + haveAltGlyph = true; + altGlyphIdentifier = glyphElement->buildGlyphIdentifier(); + altGlyphIdentifier.isValid = true; + altGlyphIdentifier.nameLength = to - from; + } + } + } for (int i = from; i < to; ++i) { // If characterLookupRange is > 0, then the font defined ligatures (length of unicode property value > 1). // We have to check wheter the current character & the next character define a ligature. This needs to be // extended to the n-th next character (where n is 'characterLookupRange'), to check for any possible ligature. - characterLookupRange = maximumHashKeyLength + i >= to ? to - i : maximumHashKeyLength; - - while (characterLookupRange > 0 && !foundGlyph) { - String lookupString(run.data(run.rtl() ? run.length() - (i + characterLookupRange) : i), characterLookupRange); - - Vector<SVGGlyphIdentifier> glyphs = m_fontElement->glyphIdentifiersForString(lookupString); - Vector<SVGGlyphIdentifier>::iterator it = glyphs.begin(); - Vector<SVGGlyphIdentifier>::iterator end = glyphs.end(); - - for (; it != end; ++it) { - identifier = *it; - - unsigned int startPosition = run.rtl() ? run.length() - (i + lookupString.length()) : i; - unsigned int endPosition = startPosition + lookupString.length(); - - if (identifier.isValid && isCompatibleGlyph(identifier, isVerticalText, language, chars, startPosition, endPosition)) { - ASSERT(characterLookupRange > 0); - i += characterLookupRange - 1; - - foundGlyph = true; - SVGGlyphElement::inheritUnspecifiedAttributes(identifier, m_fontData); - break; - } + characterLookupRange = endOfScanRange - i; + + String lookupString(run.data(i), characterLookupRange); + Vector<SVGGlyphIdentifier> glyphs; + if (haveAltGlyph) + glyphs.append(altGlyphIdentifier); + else + m_fontElement->getGlyphIdentifiersForString(lookupString, glyphs); + + Vector<SVGGlyphIdentifier>::iterator it = glyphs.begin(); + Vector<SVGGlyphIdentifier>::iterator end = glyphs.end(); + + for (; it != end; ++it) { + identifier = *it; + if (identifier.isValid && isCompatibleGlyph(identifier, isVerticalText, language, chars, i, i + identifier.nameLength)) { + ASSERT(characterLookupRange > 0); + i += identifier.nameLength - 1; + m_walkerData.charsConsumed += identifier.nameLength; + m_walkerData.glyphName = identifier.glyphName; + + foundGlyph = true; + SVGGlyphElement::inheritUnspecifiedAttributes(identifier, m_fontData); + break; } - - characterLookupRange--; } if (!foundGlyph) { + ++m_walkerData.charsConsumed; if (SVGMissingGlyphElement* element = m_fontElement->firstMissingGlyphElement()) { // <missing-glyph> element support identifier = SVGGlyphElement::buildGenericGlyphIdentifier(element); SVGGlyphElement::inheritUnspecifiedAttributes(identifier, m_fontData); + identifier.isValid = true; } else { // Fallback to system font fallback TextRun subRun(run); @@ -317,6 +331,9 @@ struct SVGTextRunWalkerMeasuredLengthData { int at; int from; int to; + int extraCharsAvailable; + int charsConsumed; + String glyphName; float scale; float length; @@ -343,7 +360,21 @@ void floatWidthMissingGlyphCallback(const TextRun& run, SVGTextRunWalkerMeasured data.length += font.floatWidth(run); } -static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& run, int from, int to) + +SVGFontElement* Font::svgFont() const +{ + if (!isSVGFont()) + return 0; + + SVGFontElement* fontElement = 0; + SVGFontFaceElement* fontFaceElement = 0; + if (svgFontAndFontFaceElementForFontData(primaryFont(), fontFaceElement, fontElement)) + return fontElement; + + return 0; +} + +static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& run, int extraCharsAvailable, int from, int to, int& charsConsumed, String& glyphName) { int newFrom = to > from ? from : to; int newTo = to > from ? to : from; @@ -364,6 +395,8 @@ static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& data.at = from; data.from = from; data.to = to; + data.extraCharsAvailable = extraCharsAvailable; + data.charsConsumed = 0; data.scale = convertEmUnitToPixel(font->size(), fontFaceElement->unitsPerEm(), 1.0f); data.length = 0.0f; @@ -380,6 +413,8 @@ static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& SVGTextRunWalker<SVGTextRunWalkerMeasuredLengthData> runWalker(fontData, fontElement, data, floatWidthUsingSVGFontCallback, floatWidthMissingGlyphCallback); runWalker.walk(run, isVerticalText, language, 0, run.length()); + charsConsumed = data.charsConsumed; + glyphName = data.glyphName; return data.length; } @@ -388,78 +423,36 @@ static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& float Font::floatWidthUsingSVGFont(const TextRun& run) const { - return floatWidthOfSubStringUsingSVGFont(this, run, 0, run.length()); + int charsConsumed; + String glyphName; + return floatWidthOfSubStringUsingSVGFont(this, run, 0, 0, run.length(), charsConsumed, glyphName); +} + +float Font::floatWidthUsingSVGFont(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const +{ + return floatWidthOfSubStringUsingSVGFont(this, run, extraCharsAvailable, 0, run.length(), charsConsumed, glyphName); } // Callback & data structures to draw text using SVG Fonts struct SVGTextRunWalkerDrawTextData { - float scale; - bool isVerticalText; - - float xStartOffset; - FloatPoint currentPoint; - FloatPoint glyphOrigin; - - GraphicsContext* context; - RenderObject* renderObject; - - SVGPaintServer* activePaintServer; + int extraCharsAvailable; + int charsConsumed; + String glyphName; + Vector<SVGGlyphIdentifier> glyphIdentifiers; + Vector<UChar> fallbackCharacters; }; bool drawTextUsingSVGFontCallback(const SVGGlyphIdentifier& identifier, SVGTextRunWalkerDrawTextData& data) { - // TODO: Support arbitary SVG content as glyph (currently limited to <glyph d="..."> situations) - if (!identifier.pathData.isEmpty()) { - data.context->save(); - - if (data.isVerticalText) { - data.glyphOrigin.setX(identifier.verticalOriginX * data.scale); - data.glyphOrigin.setY(identifier.verticalOriginY * data.scale); - } - - data.context->translate(data.xStartOffset + data.currentPoint.x() + data.glyphOrigin.x(), data.currentPoint.y() + data.glyphOrigin.y()); - data.context->scale(FloatSize(data.scale, -data.scale)); - - data.context->beginPath(); - data.context->addPath(identifier.pathData); - - SVGPaintTargetType targetType = data.context->textDrawingMode() == cTextStroke ? ApplyToStrokeTargetType : ApplyToFillTargetType; - if (data.activePaintServer->setup(data.context, data.renderObject, targetType)) { - // Spec: Any properties specified on a text elements which represents a length, such as the - // 'stroke-width' property, might produce surprising results since the length value will be - // processed in the coordinate system of the glyph. (TODO: What other lengths? miter-limit? dash-offset?) - if (targetType == ApplyToStrokeTargetType && data.scale != 0.0f) - data.context->setStrokeThickness(data.context->strokeThickness() / data.scale); - - data.activePaintServer->renderPath(data.context, data.renderObject, targetType); - data.activePaintServer->teardown(data.context, data.renderObject, targetType); - } - - data.context->restore(); - } - - if (data.isVerticalText) - data.currentPoint.move(0.0f, identifier.verticalAdvanceY * data.scale); - else - data.currentPoint.move(identifier.horizontalAdvanceX * data.scale, 0.0f); - + data.glyphIdentifiers.append(identifier); return true; } void drawTextMissingGlyphCallback(const TextRun& run, SVGTextRunWalkerDrawTextData& data) { - // Handle system font fallback - FontDescription fontDescription(data.context->font().fontDescription()); - fontDescription.setFamily(FontFamily()); - Font font(fontDescription, 0, 0); // spacing handled by SVG text code. - font.update(data.context->font().fontSelector()); - - font.drawText(data.context, run, data.currentPoint); - - if (data.isVerticalText) - data.currentPoint.move(0.0f, font.floatWidth(run)); - else - data.currentPoint.move(font.floatWidth(run), 0.0f); + ASSERT(run.length() == 1); + data.glyphIdentifiers.append(SVGGlyphIdentifier()); + data.fallbackCharacters.append(run[0]); } void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run, @@ -473,55 +466,119 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run, return; SVGTextRunWalkerDrawTextData data; - data.currentPoint = point; - data.scale = convertEmUnitToPixel(size(), fontFaceElement->unitsPerEm(), 1.0f); + FloatPoint currentPoint = point; + float scale = convertEmUnitToPixel(size(), fontFaceElement->unitsPerEm(), 1.0f); - // Required to be valid for SVG text only. - data.renderObject = run.referencingRenderObject(); - data.activePaintServer = run.activePaintServer(); + SVGPaintServer* activePaintServer = run.activePaintServer(); // If renderObject is not set, we're dealing for HTML text rendered using SVG Fonts. - if (!data.renderObject) { - ASSERT(!data.activePaintServer); + if (!run.referencingRenderObject()) { + ASSERT(!activePaintServer); // TODO: We're only supporting simple filled HTML text so far. SVGPaintServerSolid* solidPaintServer = SVGPaintServer::sharedSolidPaintServer(); solidPaintServer->setColor(context->fillColor()); - data.activePaintServer = solidPaintServer; + activePaintServer = solidPaintServer; } - ASSERT(data.activePaintServer); + ASSERT(activePaintServer); - data.isVerticalText = false; - data.xStartOffset = floatWidthOfSubStringUsingSVGFont(this, run, run.rtl() ? to : 0, run.rtl() ? run.length() : from); - data.glyphOrigin = FloatPoint(); - data.context = context; + int charsConsumed; + String glyphName; + bool isVerticalText = false; + float xStartOffset = floatWidthOfSubStringUsingSVGFont(this, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed, glyphName); + FloatPoint glyphOrigin; String language; // TODO: language matching & svg glyphs should be possible for HTML text, too. - if (data.renderObject) { - data.isVerticalText = isVerticalWritingMode(data.renderObject->style()->svgStyle()); + if (run.referencingRenderObject()) { + isVerticalText = isVerticalWritingMode(run.referencingRenderObject()->style()->svgStyle()); - if (SVGElement* element = static_cast<SVGElement*>(data.renderObject->element())) + if (SVGElement* element = static_cast<SVGElement*>(run.referencingRenderObject()->element())) language = element->getAttribute(XMLNames::langAttr); } - - if (!data.isVerticalText) { - data.glyphOrigin.setX(fontData->horizontalOriginX() * data.scale); - data.glyphOrigin.setY(fontData->horizontalOriginY() * data.scale); + + if (!isVerticalText) { + glyphOrigin.setX(fontData->horizontalOriginX() * scale); + glyphOrigin.setY(fontData->horizontalOriginY() * scale); } + data.extraCharsAvailable = 0; + SVGTextRunWalker<SVGTextRunWalkerDrawTextData> runWalker(fontData, fontElement, data, drawTextUsingSVGFontCallback, drawTextMissingGlyphCallback); - runWalker.walk(run, data.isVerticalText, language, from, to); + runWalker.walk(run, isVerticalText, language, from, to); + + SVGPaintTargetType targetType = context->textDrawingMode() == cTextStroke ? ApplyToStrokeTargetType : ApplyToFillTargetType; + + unsigned numGlyphs = data.glyphIdentifiers.size(); + unsigned fallbackCharacterIndex = 0; + for (unsigned i = 0; i < numGlyphs; ++i) { + const SVGGlyphIdentifier& identifier = data.glyphIdentifiers[run.rtl() ? numGlyphs - i - 1 : i]; + if (identifier.isValid) { + // FIXME: Support arbitary SVG content as glyph (currently limited to <glyph d="..."> situations). + if (!identifier.pathData.isEmpty()) { + context->save(); + + if (isVerticalText) { + glyphOrigin.setX(identifier.verticalOriginX * scale); + glyphOrigin.setY(identifier.verticalOriginY * scale); + } + + context->translate(xStartOffset + currentPoint.x() + glyphOrigin.x(), currentPoint.y() + glyphOrigin.y()); + context->scale(FloatSize(scale, -scale)); + + context->beginPath(); + context->addPath(identifier.pathData); + + if (activePaintServer->setup(context, run.referencingRenderObject(), targetType)) { + // Spec: Any properties specified on a text elements which represents a length, such as the + // 'stroke-width' property, might produce surprising results since the length value will be + // processed in the coordinate system of the glyph. (TODO: What other lengths? miter-limit? dash-offset?) + if (targetType == ApplyToStrokeTargetType && scale != 0.0f) + context->setStrokeThickness(context->strokeThickness() / scale); + + activePaintServer->renderPath(context, run.referencingRenderObject(), targetType); + activePaintServer->teardown(context, run.referencingRenderObject(), targetType); + } + + context->restore(); + } + + if (isVerticalText) + currentPoint.move(0.0f, identifier.verticalAdvanceY * scale); + else + currentPoint.move(identifier.horizontalAdvanceX * scale, 0.0f); + } else { + // Handle system font fallback + FontDescription fontDescription(context->font().fontDescription()); + fontDescription.setFamily(FontFamily()); + Font font(fontDescription, 0, 0); // spacing handled by SVG text code. + font.update(context->font().fontSelector()); + + TextRun fallbackCharacterRun(run); + fallbackCharacterRun.setText(&data.fallbackCharacters[run.rtl() ? data.fallbackCharacters.size() - fallbackCharacterIndex - 1 : fallbackCharacterIndex], 1); + font.drawText(context, fallbackCharacterRun, currentPoint); + + if (isVerticalText) + currentPoint.move(0.0f, font.floatWidth(fallbackCharacterRun)); + else + currentPoint.move(font.floatWidth(fallbackCharacterRun), 0.0f); + + fallbackCharacterIndex++; + } + } } } FloatRect Font::selectionRectForTextUsingSVGFont(const TextRun& run, const IntPoint& point, int height, int from, int to) const { - return FloatRect(point.x() + floatWidthOfSubStringUsingSVGFont(this, run, run.rtl() ? to : 0, run.rtl() ? run.length() : from), - point.y(), floatWidthOfSubStringUsingSVGFont(this, run, from, to), height); + int charsConsumed; + String glyphName; + + return FloatRect(point.x() + floatWidthOfSubStringUsingSVGFont(this, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed, glyphName), + point.y(), floatWidthOfSubStringUsingSVGFont(this, run, 0, from, to, charsConsumed, glyphName), height); } int Font::offsetForPositionForTextUsingSVGFont(const TextRun&, int position, bool includePartialGlyphs) const diff --git a/WebCore/svg/SVGFontData.h b/WebCore/svg/SVGFontData.h index cb2192c..4df3db2 100644 --- a/WebCore/svg/SVGFontData.h +++ b/WebCore/svg/SVGFontData.h @@ -31,7 +31,7 @@ public: SVGFontData(SVGFontFaceElement*); virtual ~SVGFontData(); - SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement.get(); } + SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement; } float horizontalOriginX() const { return m_horizontalOriginX; } float horizontalOriginY() const { return m_horizontalOriginY; } @@ -42,7 +42,13 @@ public: float verticalAdvanceY() const { return m_verticalAdvanceY; } private: - RefPtr<SVGFontFaceElement> m_svgFontFaceElement; + // Ths SVGFontFaceElement is kept alive -- + // 1) in the external font case: by the CSSFontFaceSource, which holds a reference to the external SVG document + // containing the element; + // 2) in the in-document font case: by virtue of being in the document tree and making sure that when it is removed + // from the document, it removes the @font-face rule it owns from the document's mapped element sheet and forces + // a style update. + SVGFontFaceElement* m_svgFontFaceElement; float m_horizontalOriginX; float m_horizontalOriginY; diff --git a/WebCore/svg/SVGFontElement.cpp b/WebCore/svg/SVGFontElement.cpp index a214509..98321f4 100644 --- a/WebCore/svg/SVGFontElement.cpp +++ b/WebCore/svg/SVGFontElement.cpp @@ -23,12 +23,16 @@ #if ENABLE(SVG_FONTS) #include "SVGFontElement.h" +#include "Document.h" #include "Font.h" #include "GlyphPageTreeNode.h" #include "SVGGlyphElement.h" #include "SVGMissingGlyphElement.h" #include "SVGNames.h" #include "SVGParserUtilities.h" +#include <wtf/ASCIICType.h> + +using namespace WTF; namespace WebCore { @@ -36,7 +40,7 @@ using namespace SVGNames; SVGFontElement::SVGFontElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) - , m_maximumHashKeyLength(0) + , m_isGlyphCacheValid(false) { } @@ -44,101 +48,194 @@ SVGFontElement::~SVGFontElement() { } -void SVGFontElement::addGlyphToCache(SVGGlyphElement* glyphElement) +void SVGFontElement::invalidateGlyphCache() { - ASSERT(glyphElement); - - String glyphString = glyphElement->getAttribute(unicodeAttr); - if (glyphString.isEmpty()) // No unicode property, means that glyph will be used in <altGlyph> situations! - return; - - SVGGlyphIdentifier identifier = glyphElement->buildGlyphIdentifier(); - identifier.isValid = true; - - if (glyphString.length() > m_maximumHashKeyLength) - m_maximumHashKeyLength = glyphString.length(); - - GlyphHashMap::iterator glyphsIt = m_glyphMap.find(glyphString); - if (glyphsIt == m_glyphMap.end()) { - Vector<SVGGlyphIdentifier> glyphs; - glyphs.append(identifier); - - m_glyphMap.add(glyphString, glyphs); - } else { - Vector<SVGGlyphIdentifier>& glyphs = (*glyphsIt).second; - glyphs.append(identifier); + if (m_isGlyphCacheValid) { + m_glyphMap.clear(); + m_kerningPairs.clear(); } + m_isGlyphCacheValid = false; } -void SVGFontElement::removeGlyphFromCache(SVGGlyphElement* glyphElement) +SVGMissingGlyphElement* SVGFontElement::firstMissingGlyphElement() const { - ASSERT(glyphElement); - - String glyphString = glyphElement->getAttribute(unicodeAttr); - if (glyphString.isEmpty()) // No unicode property, means that glyph will be used in <altGlyph> situations! - return; - - GlyphHashMap::iterator glyphsIt = m_glyphMap.find(glyphString); - ASSERT(glyphsIt != m_glyphMap.end()); - - Vector<SVGGlyphIdentifier>& glyphs = (*glyphsIt).second; + for (Node* child = firstChild(); child; child = child->nextSibling()) { + if (child->hasTagName(missing_glyphTag)) + return static_cast<SVGMissingGlyphElement*>(child); + } - if (glyphs.size() == 1) - m_glyphMap.remove(glyphString); - else { - SVGGlyphIdentifier identifier = glyphElement->buildGlyphIdentifier(); - identifier.isValid = true; + return 0; +} - Vector<SVGGlyphIdentifier>::iterator it = glyphs.begin(); - Vector<SVGGlyphIdentifier>::iterator end = glyphs.end(); +void SVGFontElement::ensureGlyphCache() const +{ + if (m_isGlyphCacheValid) + return; - unsigned int position = 0; - for (; it != end; ++it) { - if ((*it) == identifier) + for (Node* child = firstChild(); child; child = child->nextSibling()) { + if (child->hasTagName(glyphTag)) { + SVGGlyphElement* glyph = static_cast<SVGGlyphElement*>(child); + String unicode = glyph->getAttribute(unicodeAttr); + if (unicode.length()) + m_glyphMap.add(unicode, glyph->buildGlyphIdentifier()); + } else if (child->hasTagName(hkernTag)) { + SVGHKernElement* hkern = static_cast<SVGHKernElement*>(child); + SVGHorizontalKerningPair kerningPair = hkern->buildHorizontalKerningPair(); + m_kerningPairs.append(kerningPair); + } + } + + m_isGlyphCacheValid = true; +} + +// Returns the number of characters consumed or 0 if no range was found. +static unsigned parseUnicodeRange(const UChar* characters, unsigned length, pair<unsigned, unsigned>& range) +{ + if (length < 2) + return 0; + if (characters[0] != 'U') + return 0; + if (characters[1] != '+') + return 0; + + // Parse the starting hex number (or its prefix). + unsigned start = 0; + unsigned startLength = 0; + for (unsigned i = 2; i < length; ++i) { + if (!isASCIIHexDigit(characters[i])) + break; + if (++startLength > 6) + return 0; + start = (start << 4) | toASCIIHexValue(characters[i]); + } + + // Handle the case of ranges separated by "-" sign. + if (2 + startLength < length && characters[2 + startLength] == '-') { + if (!startLength) + return 0; + + // Parse the ending hex number (or its prefix). + unsigned end = 0; + unsigned endLength = 0; + for (unsigned i = 2 + startLength + 1; i < length; ++i) { + if (!isASCIIHexDigit(characters[i])) break; - - position++; + if (++endLength > 6) + return 0; + end = (end << 4) | toASCIIHexValue(characters[i]); } - - ASSERT(position < glyphs.size()); - glyphs.remove(position); + + if (!endLength) + return 0; + + range.first = start; + range.second = end; + return 2 + startLength + 1 + endLength; } - - // If we remove a glyph from cache, whose unicode property length is equal to - // m_maximumHashKeyLength then we need to recalculate the hash key length, because there - // is either no more glyph with that length, or there are still more glyphs with the maximum length. - if (glyphString.length() == m_maximumHashKeyLength) { - m_maximumHashKeyLength = 0; - - GlyphHashMap::iterator it = m_glyphMap.begin(); - GlyphHashMap::iterator end = m_glyphMap.end(); - - for (; it != end; ++it) { - if ((*it).first.length() > m_maximumHashKeyLength) - m_maximumHashKeyLength = (*it).first.length(); + + // Handle the case of a number with some optional trailing question marks. + unsigned end = start; + for (unsigned i = 2 + startLength; i < length; ++i) { + if (characters[i] != '?') + break; + if (++startLength > 6) + return 0; + start <<= 4; + end = (end << 4) | 0xF; + } + + if (!startLength) + return 0; + + range.first = start; + range.second = end; + return 2 + startLength; +} + +static bool parseUnicodeRangeList(const UChar* characters, unsigned length, Vector<pair<unsigned, unsigned> >& ranges) +{ + ranges.clear(); + if (!length) + return true; + + const UChar* remainingCharacters = characters; + unsigned remainingLength = length; + + while (1) { + pair<unsigned, unsigned> range; + unsigned charactersConsumed = parseUnicodeRange(remainingCharacters, remainingLength, range); + if (charactersConsumed) { + ranges.append(range); + remainingCharacters += charactersConsumed; + remainingLength -= charactersConsumed; + } else { + if (!remainingLength) + return false; + UChar character = remainingCharacters[0]; + if (character == ',') + return false; + ranges.append(make_pair(character, character)); + ++remainingCharacters; + --remainingLength; } + if (!remainingLength) + return true; + if (remainingCharacters[0] != ',') + return false; + ++remainingCharacters; + --remainingLength; } } -SVGMissingGlyphElement* SVGFontElement::firstMissingGlyphElement() const +static bool stringMatchesUnicodeRange(const String& unicodeString, const String& unicodeRangeSpec) { - for (Node* child = firstChild(); child; child = child->nextSibling()) { - if (child->hasTagName(missing_glyphTag)) - return static_cast<SVGMissingGlyphElement*>(child); + Vector<pair<unsigned, unsigned> > ranges; + if (!parseUnicodeRangeList(unicodeRangeSpec.characters(), unicodeRangeSpec.length(), ranges)) + return false; + + if (unicodeString.length() != ranges.size()) + return false; + + for (size_t i = 0; i < unicodeString.length(); ++i) { + UChar c = unicodeString[i]; + if (c < ranges[i].first || c > ranges[i].second) + return false; } - - return 0; + + return true; } - -const Vector<SVGGlyphIdentifier>& SVGFontElement::glyphIdentifiersForString(const String& string) const + +static bool matches(const String& u1, const String& g1, const String& u2, const String& g2, const SVGHorizontalKerningPair& kerningPair) +{ + if (kerningPair.unicode1.length() && !stringMatchesUnicodeRange(u1, kerningPair.unicode1)) + return false; + if (kerningPair.glyphName1.length() && kerningPair.glyphName1 != g1) + return false; + + if (kerningPair.unicode2.length() && !stringMatchesUnicodeRange(u2, kerningPair.unicode2)) + return false; + if (kerningPair.glyphName2.length() && kerningPair.glyphName2 != g2) + return false; + + return true; +} + +bool SVGFontElement::getHorizontalKerningPairForStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2, SVGHorizontalKerningPair& kerningPair) const { - GlyphHashMap::const_iterator it = m_glyphMap.find(string); - if (it == m_glyphMap.end()) { - static Vector<SVGGlyphIdentifier> s_emptyGlyphList; - return s_emptyGlyphList; + for (size_t i = 0; i < m_kerningPairs.size(); ++i) { + if (matches(u1, g1, u2, g2, m_kerningPairs[i])) { + kerningPair = m_kerningPairs[i]; + return true; + } } + + return false; +} - return (*it).second; +void SVGFontElement::getGlyphIdentifiersForString(const String& string, Vector<SVGGlyphIdentifier>& glyphs) const +{ + ensureGlyphCache(); + m_glyphMap.get(string, glyphs); } } diff --git a/WebCore/svg/SVGFontElement.h b/WebCore/svg/SVGFontElement.h index 1005654..42468da 100644 --- a/WebCore/svg/SVGFontElement.h +++ b/WebCore/svg/SVGFontElement.h @@ -24,6 +24,8 @@ #if ENABLE(SVG_FONTS) #include "SVGExternalResourcesRequired.h" #include "SVGGlyphElement.h" +#include "SVGGlyphMap.h" +#include "SVGHKernElement.h" #include "SVGStyledElement.h" namespace WebCore { @@ -36,29 +38,29 @@ namespace WebCore { virtual ~SVGFontElement(); virtual bool rendererIsNeeded(RenderStyle*) { return false; } - virtual const SVGElement* contextElement() const { return this; } - void addGlyphToCache(SVGGlyphElement*); - void removeGlyphFromCache(SVGGlyphElement*); + void invalidateGlyphCache(); - const Vector<SVGGlyphIdentifier>& glyphIdentifiersForString(const String&) const; + void getGlyphIdentifiersForString(const String&, Vector<SVGGlyphIdentifier>&) const; - // Returns the longest hash key length (the 'unicode' property value with the - // highest amount of characters) - ie. for <glyph unicode="ffl"/> it will return 3. - unsigned int maximumHashKeyLength() const { return m_maximumHashKeyLength; } + bool getHorizontalKerningPairForStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2, SVGHorizontalKerningPair& kerningPair) const; SVGMissingGlyphElement* firstMissingGlyphElement() const; + protected: + virtual const SVGElement* contextElement() const { return this; } + private: - typedef HashMap<String, Vector<SVGGlyphIdentifier> > GlyphHashMap; - GlyphHashMap m_glyphMap; + void ensureGlyphCache() const; - unsigned int m_maximumHashKeyLength; + typedef Vector<SVGHorizontalKerningPair> KerningPairVector; + + mutable KerningPairVector m_kerningPairs; + mutable SVGGlyphMap m_glyphMap; + mutable bool m_isGlyphCacheValid; }; } // namespace WebCore #endif // ENABLE(SVG_FONTS) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGFontFaceElement.cpp b/WebCore/svg/SVGFontFaceElement.cpp index cdf0b72..21fd277 100644 --- a/WebCore/svg/SVGFontFaceElement.cpp +++ b/WebCore/svg/SVGFontFaceElement.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2007 Eric Seidel <eric@webkit.org> Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Apple Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -25,15 +26,14 @@ #include "CString.h" #include "CSSFontFaceRule.h" #include "CSSFontFaceSrcValue.h" +#include "CSSParser.h" #include "CSSProperty.h" #include "CSSPropertyNames.h" #include "CSSStyleSelector.h" #include "CSSStyleSheet.h" #include "CSSValueKeywords.h" #include "CSSValueList.h" -#include "FontCache.h" -#include "FontPlatformData.h" -#include "SimpleFontData.h" +#include "Document.h" #include "SVGDefinitionSrcElement.h" #include "SVGFontElement.h" #include "SVGFontFaceSrcElement.h" @@ -48,30 +48,22 @@ using namespace SVGNames; SVGFontFaceElement::SVGFontFaceElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) - , m_fontFaceRule(new CSSFontFaceRule(0)) - , m_styleDeclaration(new CSSMutableStyleDeclaration) + , m_fontFaceRule(CSSFontFaceRule::create()) + , m_styleDeclaration(CSSMutableStyleDeclaration::create()) { m_styleDeclaration->setParent(document()->mappedElementSheet()); m_styleDeclaration->setStrictParsing(true); m_fontFaceRule->setDeclaration(m_styleDeclaration.get()); - document()->mappedElementSheet()->append(m_fontFaceRule); } SVGFontFaceElement::~SVGFontFaceElement() { + removeFromMappedElementSheet(); } -static inline void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName, const char* cssPropertyName = 0) +static void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName) { - int propertyId = 0; - if (cssPropertyName) - propertyId = getPropertyID(cssPropertyName, strlen(cssPropertyName)); - else { - CString propertyName = attrName.localName().domString().utf8(); - propertyId = getPropertyID(propertyName.data(), propertyName.length()); - } - if (propertyId < 1) - fprintf(stderr, "Failed to find property: %s\n", attrName.localName().deprecatedString().ascii()); + int propertyId = cssPropertyID(attrName.localName()); ASSERT(propertyId > 0); propertyNameToIdMap->set(attrName.localName().impl(), propertyId); } @@ -129,7 +121,8 @@ void SVGFontFaceElement::parseMappedAttribute(MappedAttribute* attr) int propId = cssPropertyIdForSVGAttributeName(attr->name()); if (propId > 0) { m_styleDeclaration->setProperty(propId, attr->value(), false); - rebuildFontFace(); + if (inDocument()) + rebuildFontFace(); return; } @@ -138,7 +131,7 @@ void SVGFontFaceElement::parseMappedAttribute(MappedAttribute* attr) unsigned SVGFontFaceElement::unitsPerEm() const { - AtomicString value(getAttribute(units_per_emAttr)); + const AtomicString& value = getAttribute(units_per_emAttr); if (value.isEmpty()) return 1000; @@ -147,11 +140,7 @@ unsigned SVGFontFaceElement::unitsPerEm() const int SVGFontFaceElement::xHeight() const { - AtomicString value(getAttribute(x_heightAttr)); - if (value.isEmpty()) - return 0; - - return static_cast<int>(ceilf(value.toFloat())); + return static_cast<int>(ceilf(getAttribute(x_heightAttr).toFloat())); } float SVGFontFaceElement::horizontalOriginX() const @@ -162,11 +151,7 @@ float SVGFontFaceElement::horizontalOriginX() const // Spec: The X-coordinate in the font coordinate system of the origin of a glyph to be used when // drawing horizontally oriented text. (Note that the origin applies to all glyphs in the font.) // If the attribute is not specified, the effect is as if a value of "0" were specified. - AtomicString value(m_fontElement->getAttribute(horiz_origin_xAttr)); - if (value.isEmpty()) - return 0.0f; - - return value.toFloat(); + return m_fontElement->getAttribute(horiz_origin_xAttr).toFloat(); } float SVGFontFaceElement::horizontalOriginY() const @@ -177,11 +162,7 @@ float SVGFontFaceElement::horizontalOriginY() const // Spec: The Y-coordinate in the font coordinate system of the origin of a glyph to be used when // drawing horizontally oriented text. (Note that the origin applies to all glyphs in the font.) // If the attribute is not specified, the effect is as if a value of "0" were specified. - AtomicString value(m_fontElement->getAttribute(horiz_origin_yAttr)); - if (value.isEmpty()) - return 0.0f; - - return value.toFloat(); + return m_fontElement->getAttribute(horiz_origin_yAttr).toFloat(); } float SVGFontFaceElement::horizontalAdvanceX() const @@ -192,11 +173,7 @@ float SVGFontFaceElement::horizontalAdvanceX() const // Spec: The default horizontal advance after rendering a glyph in horizontal orientation. Glyph // widths are required to be non-negative, even if the glyph is typically rendered right-to-left, // as in Hebrew and Arabic scripts. - AtomicString value(m_fontElement->getAttribute(horiz_adv_xAttr)); - if (value.isEmpty()) - return 0.0f; - - return value.toFloat(); + return m_fontElement->getAttribute(horiz_adv_xAttr).toFloat(); } float SVGFontFaceElement::verticalOriginX() const @@ -207,7 +184,7 @@ float SVGFontFaceElement::verticalOriginX() const // Spec: The default X-coordinate in the font coordinate system of the origin of a glyph to be used when // drawing vertically oriented text. If the attribute is not specified, the effect is as if the attribute // were set to half of the effective value of attribute horiz-adv-x. - AtomicString value(m_fontElement->getAttribute(vert_origin_xAttr)); + const AtomicString& value = m_fontElement->getAttribute(vert_origin_xAttr); if (value.isEmpty()) return horizontalAdvanceX() / 2.0f; @@ -222,7 +199,7 @@ float SVGFontFaceElement::verticalOriginY() const // Spec: The default Y-coordinate in the font coordinate system of the origin of a glyph to be used when // drawing vertically oriented text. If the attribute is not specified, the effect is as if the attribute // were set to the position specified by the font's ascent attribute. - AtomicString value(m_fontElement->getAttribute(vert_origin_yAttr)); + const AtomicString& value = m_fontElement->getAttribute(vert_origin_yAttr); if (value.isEmpty()) return ascent(); @@ -236,7 +213,7 @@ float SVGFontFaceElement::verticalAdvanceY() const // Spec: The default vertical advance after rendering a glyph in vertical orientation. If the attribute is // not specified, the effect is as if a value equivalent of one em were specified (see units-per-em). - AtomicString value(m_fontElement->getAttribute(vert_adv_yAttr)); + const AtomicString& value = m_fontElement->getAttribute(vert_adv_yAttr); if (value.isEmpty()) return 1.0f; @@ -245,20 +222,19 @@ float SVGFontFaceElement::verticalAdvanceY() const int SVGFontFaceElement::ascent() const { - if (!m_fontElement) - return 0.0f; - // Spec: Same syntax and semantics as the 'ascent' descriptor within an @font-face rule. The maximum // unaccented height of the font within the font coordinate system. If the attribute is not specified, // the effect is as if the attribute were set to the difference between the units-per-em value and the // vert-origin-y value for the corresponding font. - AtomicString value(m_fontElement->getAttribute(ascentAttr)); - if (!value.isEmpty()) - return static_cast<int>(ceilf(value.toFloat())); - - value = m_fontElement->getAttribute(vert_origin_yAttr); - if (!value.isEmpty()) - return static_cast<int>(unitsPerEm()) - static_cast<int>(ceilf(value.toFloat())); + const AtomicString& ascentValue = getAttribute(ascentAttr); + if (!ascentValue.isEmpty()) + return static_cast<int>(ceilf(ascentValue.toFloat())); + + if (m_fontElement) { + const AtomicString& vertOriginY = m_fontElement->getAttribute(vert_origin_yAttr); + if (!vertOriginY.isEmpty()) + return static_cast<int>(unitsPerEm()) - static_cast<int>(ceilf(vertOriginY.toFloat())); + } // Match Batiks default value return static_cast<int>(ceilf(unitsPerEm() * 0.8f)); @@ -266,22 +242,23 @@ int SVGFontFaceElement::ascent() const int SVGFontFaceElement::descent() const { - if (!m_fontElement) - return 0.0f; - // Spec: Same syntax and semantics as the 'descent' descriptor within an @font-face rule. The maximum // unaccented depth of the font within the font coordinate system. If the attribute is not specified, // the effect is as if the attribute were set to the vert-origin-y value for the corresponding font. - AtomicString value(m_fontElement->getAttribute(descentAttr)); - if (!value.isEmpty()) { - // Some testcases use a negative descent value, where a positive was meant to be used :( - int descent = static_cast<int>(ceilf(value.toFloat())); + const AtomicString& descentValue = getAttribute(descentAttr); + if (!descentValue.isEmpty()) { + // 14 different W3C SVG 1.1 testcases use a negative descent value, + // where a positive was meant to be used Including: + // animate-elem-24-t.svg, fonts-elem-01-t.svg, fonts-elem-02-t.svg (and 11 others) + int descent = static_cast<int>(ceilf(descentValue.toFloat())); return descent < 0 ? -descent : descent; } - value = m_fontElement->getAttribute(vert_origin_yAttr); - if (!value.isEmpty()) - return static_cast<int>(ceilf(value.toFloat())); + if (m_fontElement) { + const AtomicString& vertOriginY = m_fontElement->getAttribute(vert_origin_yAttr); + if (!vertOriginY.isEmpty()) + return static_cast<int>(ceilf(vertOriginY.toFloat())); + } // Match Batiks default value return static_cast<int>(ceilf(unitsPerEm() * 0.2f)); @@ -289,19 +266,12 @@ int SVGFontFaceElement::descent() const String SVGFontFaceElement::fontFamily() const { - return m_styleDeclaration->getPropertyValue(CSS_PROP_FONT_FAMILY); -} - -SVGFontElement* SVGFontFaceElement::associatedFontElement() const -{ - return m_fontElement.get(); + return m_styleDeclaration->getPropertyValue(CSSPropertyFontFamily); } void SVGFontFaceElement::rebuildFontFace() { - // Ignore changes until we live in the tree - if (!parentNode()) - return; + ASSERT(inDocument()); // we currently ignore all but the first src element, alternatively we could concat them SVGFontFaceSrcElement* srcElement = 0; @@ -317,7 +287,7 @@ void SVGFontFaceElement::rebuildFontFace() #if 0 // @font-face (CSSFontFace) does not yet support definition-src, as soon as it does this code should do the trick! if (definitionSrc) - m_styleDeclaration->setProperty(CSS_PROP_DEFINITION_SRC, definitionSrc->getAttribute(XLinkNames::hrefAttr), false); + m_styleDeclaration->setProperty(CSSPropertyDefinitionSrc, definitionSrc->getAttribute(XLinkNames::hrefAttr), false); #endif bool describesParentFont = parentNode()->hasTagName(fontTag); @@ -326,27 +296,30 @@ void SVGFontFaceElement::rebuildFontFace() if (describesParentFont) { m_fontElement = static_cast<SVGFontElement*>(parentNode()); - list = new CSSValueList; - list->append(new CSSFontFaceSrcValue(fontFamily(), true)); - } else if (srcElement) - list = srcElement->srcValue(); + list = CSSValueList::createCommaSeparated(); + list->append(CSSFontFaceSrcValue::createLocal(fontFamily())); + } else { + m_fontElement = 0; + if (srcElement) + list = srcElement->srcValue(); + } if (!list) return; // Parse in-memory CSS rules - CSSProperty srcProperty(CSS_PROP_SRC, list); + CSSProperty srcProperty(CSSPropertySrc, list); const CSSProperty* srcPropertyRef = &srcProperty; m_styleDeclaration->addParsedProperties(&srcPropertyRef, 1); if (describesParentFont) { // Traverse parsed CSS values and associate CSSFontFaceSrcValue elements with ourselves. - RefPtr<CSSValue> src = m_styleDeclaration->getPropertyCSSValue(CSS_PROP_SRC); + RefPtr<CSSValue> src = m_styleDeclaration->getPropertyCSSValue(CSSPropertySrc); CSSValueList* srcList = static_cast<CSSValueList*>(src.get()); unsigned srcLength = srcList ? srcList->length() : 0; for (unsigned i = 0; i < srcLength; i++) { - if (CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->item(i))) + if (CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->itemWithoutBoundsCheck(i))) item->setSVGFontFaceElement(this); } } @@ -356,15 +329,39 @@ void SVGFontFaceElement::rebuildFontFace() void SVGFontFaceElement::insertedIntoDocument() { + SVGElement::insertedIntoDocument(); + document()->mappedElementSheet()->append(m_fontFaceRule); rebuildFontFace(); } -void SVGFontFaceElement::childrenChanged(bool changedByParser) +void SVGFontFaceElement::removedFromDocument() { - SVGElement::childrenChanged(changedByParser); - rebuildFontFace(); + removeFromMappedElementSheet(); + SVGElement::removedFromDocument(); } +void SVGFontFaceElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +{ + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + if (inDocument()) + rebuildFontFace(); } +void SVGFontFaceElement::removeFromMappedElementSheet() +{ + CSSStyleSheet* mappedElementSheet = document()->mappedElementSheet(); + if (!mappedElementSheet) + return; + + for (unsigned i = 0; i < mappedElementSheet->length(); ++i) { + if (mappedElementSheet->item(i) == m_fontFaceRule) { + mappedElementSheet->remove(i); + break; + } + } + document()->updateStyleSelector(); +} + +} // namespace WebCore + #endif // ENABLE(SVG_FONTS) diff --git a/WebCore/svg/SVGFontFaceElement.h b/WebCore/svg/SVGFontFaceElement.h index 2e62ff9..3c28a89 100644 --- a/WebCore/svg/SVGFontFaceElement.h +++ b/WebCore/svg/SVGFontFaceElement.h @@ -1,6 +1,7 @@ /* Copyright (C) 2007 Eric Seidel <eric@webkit.org> Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Apple Inc. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -37,8 +38,9 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual void insertedIntoDocument(); + virtual void removedFromDocument(); unsigned unitsPerEm() const; int xHeight() const; @@ -52,14 +54,15 @@ namespace WebCore { int descent() const; String fontFamily() const; - SVGFontElement* associatedFontElement() const; + SVGFontElement* associatedFontElement() const { return m_fontElement; } void rebuildFontFace(); + void removeFromMappedElementSheet(); private: RefPtr<CSSFontFaceRule> m_fontFaceRule; RefPtr<CSSMutableStyleDeclaration> m_styleDeclaration; - RefPtr<SVGFontElement> m_fontElement; + SVGFontElement* m_fontElement; }; } // namespace WebCore diff --git a/WebCore/svg/SVGFontFaceFormatElement.cpp b/WebCore/svg/SVGFontFaceFormatElement.cpp index 54f463b..e6dd94b 100644 --- a/WebCore/svg/SVGFontFaceFormatElement.cpp +++ b/WebCore/svg/SVGFontFaceFormatElement.cpp @@ -34,9 +34,9 @@ SVGFontFaceFormatElement::SVGFontFaceFormatElement(const QualifiedName& tagName, { } -void SVGFontFaceFormatElement::childrenChanged(bool changedByParser) +void SVGFontFaceFormatElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGElement::childrenChanged(changedByParser); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!parentNode() || !parentNode()->hasTagName(font_face_uriTag)) return; diff --git a/WebCore/svg/SVGFontFaceFormatElement.h b/WebCore/svg/SVGFontFaceFormatElement.h index f20a165..97828cb 100644 --- a/WebCore/svg/SVGFontFaceFormatElement.h +++ b/WebCore/svg/SVGFontFaceFormatElement.h @@ -29,7 +29,7 @@ class SVGFontFaceFormatElement : public SVGElement { public: SVGFontFaceFormatElement(const QualifiedName&, Document*); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); }; } // namespace WebCore diff --git a/WebCore/svg/SVGFontFaceNameElement.cpp b/WebCore/svg/SVGFontFaceNameElement.cpp index 1825802..91002e1 100644 --- a/WebCore/svg/SVGFontFaceNameElement.cpp +++ b/WebCore/svg/SVGFontFaceNameElement.cpp @@ -34,7 +34,7 @@ SVGFontFaceNameElement::SVGFontFaceNameElement(const QualifiedName& tagName, Doc PassRefPtr<CSSFontFaceSrcValue> SVGFontFaceNameElement::srcValue() const { - return new CSSFontFaceSrcValue(getAttribute(SVGNames::nameAttr), true); + return CSSFontFaceSrcValue::createLocal(getAttribute(SVGNames::nameAttr)); } } diff --git a/WebCore/svg/SVGFontFaceSrcElement.cpp b/WebCore/svg/SVGFontFaceSrcElement.cpp index 0a2d69f..0d72c74 100644 --- a/WebCore/svg/SVGFontFaceSrcElement.cpp +++ b/WebCore/svg/SVGFontFaceSrcElement.cpp @@ -40,7 +40,7 @@ SVGFontFaceSrcElement::SVGFontFaceSrcElement(const QualifiedName& tagName, Docum PassRefPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const { - RefPtr<CSSValueList> list = new CSSValueList; + RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated(); for (Node* child = firstChild(); child; child = child->nextSibling()) { if (child->hasTagName(font_face_uriTag)) list->append(static_cast<SVGFontFaceUriElement*>(child)->srcValue()); @@ -50,9 +50,9 @@ PassRefPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const return list; } -void SVGFontFaceSrcElement::childrenChanged(bool changedByParser) +void SVGFontFaceSrcElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGElement::childrenChanged(changedByParser); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (parentNode() && parentNode()->hasTagName(font_faceTag)) static_cast<SVGFontFaceElement*>(parentNode())->rebuildFontFace(); } diff --git a/WebCore/svg/SVGFontFaceSrcElement.h b/WebCore/svg/SVGFontFaceSrcElement.h index 202ac34..b86f689 100644 --- a/WebCore/svg/SVGFontFaceSrcElement.h +++ b/WebCore/svg/SVGFontFaceSrcElement.h @@ -31,7 +31,7 @@ namespace WebCore { PassRefPtr<CSSValueList> srcValue() const; - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); }; } // namespace WebCore diff --git a/WebCore/svg/SVGFontFaceUriElement.cpp b/WebCore/svg/SVGFontFaceUriElement.cpp index 06781d7..7f6c6d2 100644 --- a/WebCore/svg/SVGFontFaceUriElement.cpp +++ b/WebCore/svg/SVGFontFaceUriElement.cpp @@ -38,15 +38,15 @@ SVGFontFaceUriElement::SVGFontFaceUriElement(const QualifiedName& tagName, Docum PassRefPtr<CSSFontFaceSrcValue> SVGFontFaceUriElement::srcValue() const { - RefPtr<CSSFontFaceSrcValue> src = new CSSFontFaceSrcValue(getAttribute(XLinkNames::hrefAttr), false); + RefPtr<CSSFontFaceSrcValue> src = CSSFontFaceSrcValue::create(getAttribute(XLinkNames::hrefAttr)); AtomicString value(getAttribute(formatAttr)); src->setFormat(value.isEmpty() ? "svg" : value); // Default format return src.release(); } -void SVGFontFaceUriElement::childrenChanged(bool changedByParser) +void SVGFontFaceUriElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGElement::childrenChanged(changedByParser); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!parentNode() || !parentNode()->hasTagName(font_face_srcTag)) return; diff --git a/WebCore/svg/SVGFontFaceUriElement.h b/WebCore/svg/SVGFontFaceUriElement.h index 488365f..cdeb743 100644 --- a/WebCore/svg/SVGFontFaceUriElement.h +++ b/WebCore/svg/SVGFontFaceUriElement.h @@ -31,7 +31,7 @@ namespace WebCore { PassRefPtr<CSSFontFaceSrcValue> srcValue() const; - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); }; } // namespace WebCore diff --git a/WebCore/svg/SVGForeignObjectElement.cpp b/WebCore/svg/SVGForeignObjectElement.cpp index 1d6e2d2..f7c4582 100644 --- a/WebCore/svg/SVGForeignObjectElement.cpp +++ b/WebCore/svg/SVGForeignObjectElement.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2006 Apple Computer, Inc. + (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> This file is part of the WebKit project @@ -38,10 +39,10 @@ SVGForeignObjectElement::SVGForeignObjectElement(const QualifiedName& tagName, D , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) + , m_x(this, SVGNames::xAttr, LengthModeWidth) + , m_y(this, SVGNames::yAttr, LengthModeHeight) + , m_width(this, SVGNames::widthAttr, LengthModeWidth) + , m_height(this, SVGNames::heightAttr, LengthModeHeight) { } @@ -49,25 +50,18 @@ SVGForeignObjectElement::~SVGForeignObjectElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGForeignObjectElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGForeignObjectElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGForeignObjectElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGForeignObjectElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) - -void SVGForeignObjectElement::parseMappedAttribute(MappedAttribute *attr) +void SVGForeignObjectElement::parseMappedAttribute(MappedAttribute* attr) { const AtomicString& value = attr->value(); if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, value)); + setXBaseValue(SVGLength(LengthModeWidth, value)); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, value)); - else if (attr->name() == SVGNames::widthAttr) { - setWidthBaseValue(SVGLength(this, LengthModeWidth, value)); - addCSSProperty(attr, CSS_PROP_WIDTH, value); - } else if (attr->name() == SVGNames::heightAttr) { - setHeightBaseValue(SVGLength(this, LengthModeHeight, value)); - addCSSProperty(attr, CSS_PROP_HEIGHT, value); - } else { + setYBaseValue(SVGLength(LengthModeHeight, value)); + else if (attr->name() == SVGNames::widthAttr) + setWidthBaseValue(SVGLength(LengthModeWidth, value)); + else if (attr->name() == SVGNames::heightAttr) + setHeightBaseValue(SVGLength(LengthModeHeight, value)); + else { if (SVGTests::parseMappedAttribute(attr)) return; if (SVGLangSpace::parseMappedAttribute(attr)) @@ -78,6 +72,85 @@ void SVGForeignObjectElement::parseMappedAttribute(MappedAttribute *attr) } } +// TODO: Move this function in some SVG*Element base class, as SVGSVGElement / SVGImageElement will need the same logic! + +// This function mimics addCSSProperty and StyledElement::attributeChanged. +// In HTML code, you'd always call addCSSProperty from your derived parseMappedAttribute() +// function - though in SVG code we need to move this logic into svgAttributeChanged, in +// order to support SVG DOM changes (which don't use the parseMappedAttribute/attributeChanged). +// If we'd ignore SVG DOM, we could use _exactly_ the same logic as HTML. +static inline void addCSSPropertyAndNotifyAttributeMap(StyledElement* element, const QualifiedName& name, int cssProperty, const String& value) +{ + ASSERT(element); + + if (!element) + return; + + NamedMappedAttrMap* attrs = element->mappedAttributes(); + ASSERT(attrs); + + if (!attrs) + return; + + Attribute* attr = attrs->getAttributeItem(name); + if (!attr || !attr->isMappedAttribute()) + return; + + MappedAttribute* mappedAttr = static_cast<MappedAttribute*>(attr); + + // This logic is only meant to be used for entries that have to be parsed and are mapped to eNone. Assert that. + MappedAttributeEntry entry; + bool needToParse = element->mapToEntry(mappedAttr->name(), entry); + + ASSERT(needToParse); + ASSERT(entry == eNone); + + if (!needToParse || entry != eNone) + return; + + if (mappedAttr->decl()) { + mappedAttr->setDecl(0); + attrs->declRemoved(); + } + + element->setChanged(); + element->addCSSProperty(mappedAttr, cssProperty, value); + + if (CSSMappedAttributeDeclaration* decl = mappedAttr->decl()) { + // Add the decl to the table in the appropriate spot. + element->setMappedAttributeDecl(entry, mappedAttr, decl); + + decl->setMappedState(entry, mappedAttr->name(), mappedAttr->value()); + decl->setParent(0); + decl->setNode(0); + + attrs->declAdded(); + } +} + +void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGStyledTransformableElement::svgAttributeChanged(attrName); + + if (attrName == SVGNames::widthAttr) { + addCSSPropertyAndNotifyAttributeMap(this, attrName, CSSPropertyWidth, width().valueAsString()); + return; + } else if (attrName == SVGNames::heightAttr) { + addCSSPropertyAndNotifyAttributeMap(this, attrName, CSSPropertyHeight, height().valueAsString()); + return; + } + + if (!renderer()) + return; + + if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || + SVGTests::isKnownAttribute(attrName) || + SVGLangSpace::isKnownAttribute(attrName) || + SVGExternalResourcesRequired::isKnownAttribute(attrName) || + SVGStyledTransformableElement::isKnownAttribute(attrName)) + renderer()->setNeedsLayout(true); +} + RenderObject* SVGForeignObjectElement::createRenderer(RenderArena* arena, RenderStyle* style) { return new (arena) RenderForeignObject(this); @@ -92,5 +165,3 @@ bool SVGForeignObjectElement::childShouldCreateRenderer(Node* child) const } // namespace WebCore #endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGForeignObjectElement.h b/WebCore/svg/SVGForeignObjectElement.h index c0d4c04..14dbe68 100644 --- a/WebCore/svg/SVGForeignObjectElement.h +++ b/WebCore/svg/SVGForeignObjectElement.h @@ -23,30 +23,27 @@ #define SVGForeignObjectElement_h #if ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT) - #include "SVGTests.h" #include "SVGLangSpace.h" #include "SVGURIReference.h" #include "SVGStyledTransformableElement.h" #include "SVGExternalResourcesRequired.h" -namespace WebCore -{ +namespace WebCore { class SVGLength; - class SVGDocument; class SVGForeignObjectElement : public SVGStyledTransformableElement, - public SVGTests, - public SVGLangSpace, - public SVGExternalResourcesRequired, - public SVGURIReference - { + public SVGTests, + public SVGLangSpace, + public SVGExternalResourcesRequired, + public SVGURIReference { public: SVGForeignObjectElement(const QualifiedName&, Document*); virtual ~SVGForeignObjectElement(); - + virtual bool isValid() const { return SVGTests::isValid(); } virtual void parseMappedAttribute(MappedAttribute*); + virtual void svgAttributeChanged(const QualifiedName&); bool childShouldCreateRenderer(Node*) const; virtual RenderObject* createRenderer(RenderArena* arena, RenderStyle* style); @@ -55,18 +52,13 @@ namespace WebCore virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGLength, SVGLength, Height, height) + ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGNames::foreignObjectTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGNames::foreignObjectTagString, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGNames::foreignObjectTagString, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGForeignObjectElement, SVGNames::foreignObjectTagString, SVGNames::heightAttrString, SVGLength, Height, height) }; } // namespace WebCore #endif // ENABLE(SVG) && ENABLE(SVG_FOREIGN_OBJECT) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGGElement.cpp b/WebCore/svg/SVGGElement.cpp index 08a79e7..2b50d74 100644 --- a/WebCore/svg/SVGGElement.cpp +++ b/WebCore/svg/SVGGElement.cpp @@ -49,6 +49,7 @@ void SVGGElement::parseMappedAttribute(MappedAttribute* attr) return; if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) return; + SVGStyledTransformableElement::parseMappedAttribute(attr); } @@ -59,23 +60,22 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName) if (!renderer()) return; - if (attrName == SVGNames::clipPathUnitsAttr || - SVGTests::isKnownAttribute(attrName) || + if (SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName) || SVGStyledTransformableElement::isKnownAttribute(attrName)) renderer()->setNeedsLayout(true); } -void SVGGElement::childrenChanged(bool changedByParser) +void SVGGElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGStyledTransformableElement::childrenChanged(changedByParser); + SVGStyledTransformableElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (renderer()) renderer()->setNeedsLayout(true); } -RenderObject* SVGGElement::createRenderer(RenderArena* arena, RenderStyle* style) +RenderObject* SVGGElement::createRenderer(RenderArena* arena, RenderStyle*) { return new (arena) RenderSVGTransformableContainer(this); } diff --git a/WebCore/svg/SVGGElement.h b/WebCore/svg/SVGGElement.h index 25cd712..fe52d05 100644 --- a/WebCore/svg/SVGGElement.h +++ b/WebCore/svg/SVGGElement.h @@ -43,7 +43,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); @@ -51,9 +51,6 @@ namespace WebCore { virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - private: friend class SVGUseElement; AffineTransform localMatrix() const; }; diff --git a/WebCore/svg/SVGGlyphElement.cpp b/WebCore/svg/SVGGlyphElement.cpp index 34c8f3a..ebf5dd0 100644 --- a/WebCore/svg/SVGGlyphElement.cpp +++ b/WebCore/svg/SVGGlyphElement.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2007 Eric Seidel <eric@webkit.org> Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Rob Buis <buis@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -44,22 +45,33 @@ SVGGlyphElement::~SVGGlyphElement() { } -void SVGGlyphElement::insertedIntoDocument() +void SVGGlyphElement::invalidateGlyphCache() { Node* fontNode = parentNode(); if (fontNode && fontNode->hasTagName(fontTag)) { if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) - element->addGlyphToCache(this); + element->invalidateGlyphCache(); } } +void SVGGlyphElement::parseMappedAttribute(MappedAttribute* attr) +{ + if (attr->name() == SVGNames::dAttr) + invalidateGlyphCache(); + else + SVGStyledElement::parseMappedAttribute(attr); +} + +void SVGGlyphElement::insertedIntoDocument() +{ + invalidateGlyphCache(); + SVGStyledElement::insertedIntoDocument(); +} + void SVGGlyphElement::removedFromDocument() { - Node* fontNode = parentNode(); - if (fontNode && fontNode->hasTagName(fontTag)) { - if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) - element->removeGlyphFromCache(this); - } + invalidateGlyphCache(); + SVGStyledElement::removedFromDocument(); } static inline SVGGlyphIdentifier::ArabicForm parseArabicForm(const AtomicString& value) diff --git a/WebCore/svg/SVGGlyphElement.h b/WebCore/svg/SVGGlyphElement.h index 54069bd..62ae263 100644 --- a/WebCore/svg/SVGGlyphElement.h +++ b/WebCore/svg/SVGGlyphElement.h @@ -1,6 +1,7 @@ /* Copyright (C) 2007 Eric Seidel <eric@webkit.org> Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Rob Buis <buis@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -53,6 +54,8 @@ namespace WebCore { : isValid(false) , orientation(Both) , arabicForm(None) + , priority(0) + , nameLength(0) , horizontalAdvanceX(0.0f) , verticalOriginX(0.0f) , verticalOriginY(0.0f) @@ -83,8 +86,10 @@ namespace WebCore { bool isValid : 1; - Orientation orientation : 2; - ArabicForm arabicForm : 3; + unsigned orientation : 2; // Orientation + unsigned arabicForm : 3; // ArabicForm + int priority; + size_t nameLength; String glyphName; float horizontalAdvanceX; @@ -101,6 +106,8 @@ namespace WebCore { SVGGlyphElement(const QualifiedName&, Document*); virtual ~SVGGlyphElement(); + virtual void parseMappedAttribute(MappedAttribute*); + virtual void insertedIntoDocument(); virtual void removedFromDocument(); @@ -114,6 +121,8 @@ namespace WebCore { // Helper function shared between SVGGlyphElement & SVGMissingGlyphElement static SVGGlyphIdentifier buildGenericGlyphIdentifier(const SVGElement*); + private: + void invalidateGlyphCache(); }; } // namespace WebCore diff --git a/WebCore/svg/SVGGlyphMap.h b/WebCore/svg/SVGGlyphMap.h new file mode 100644 index 0000000..b58b155 --- /dev/null +++ b/WebCore/svg/SVGGlyphMap.h @@ -0,0 +1,109 @@ +/* + Copyright (C) 2008 Apple, Inc + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef SVGGlyphMap_h +#define SVGGlyphMap_h + +#if ENABLE(SVG_FONTS) +#include "SVGGlyphElement.h" + + +namespace WebCore { + + struct GlyphMapNode; + + typedef HashMap<UChar, RefPtr<GlyphMapNode> > GlyphMapLayer; + + struct GlyphMapNode : public RefCounted<GlyphMapNode> { + private: + GlyphMapNode() { } + public: + static PassRefPtr<GlyphMapNode> create() { return adoptRef(new GlyphMapNode); } + + Vector<SVGGlyphIdentifier> glyphs; + + GlyphMapLayer children; + }; + + class SVGGlyphMap { + + public: + SVGGlyphMap() : m_currentPriority(0) { } + + void add(const String& string, const SVGGlyphIdentifier& glyph) + { + size_t len = string.length(); + GlyphMapLayer* currentLayer = &m_rootLayer; + + RefPtr<GlyphMapNode> node; + for (size_t i = 0; i < len; i++) { + UChar curChar = string[i]; + node = currentLayer->get(curChar); + if (!node) { + node = GlyphMapNode::create(); + currentLayer->set(curChar, node); + } + currentLayer = &node->children; + } + + if (node) { + node->glyphs.append(glyph); + node->glyphs.last().priority = m_currentPriority++; + node->glyphs.last().nameLength = len; + node->glyphs.last().isValid = true; + } + } + + static inline bool compareGlyphPriority(const SVGGlyphIdentifier& first, const SVGGlyphIdentifier& second) + { + return first.priority < second.priority; + } + + void get(const String& string, Vector<SVGGlyphIdentifier>& glyphs) + { + GlyphMapLayer* currentLayer = &m_rootLayer; + + for (size_t i = 0; i < string.length(); i++) { + UChar curChar = string[i]; + RefPtr<GlyphMapNode> node = currentLayer->get(curChar); + if (!node) + break; + glyphs.append(node->glyphs); + currentLayer = &node->children; + } + std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority); + } + + void clear() + { + m_rootLayer.clear(); + m_currentPriority = 0; + } + + private: + GlyphMapLayer m_rootLayer; + int m_currentPriority; + }; + +} + +#endif // ENABLE(SVG_FONTS) + + +#endif //SVGGlyphMap_h diff --git a/WebCore/svg/SVGGradientElement.cpp b/WebCore/svg/SVGGradientElement.cpp index 88c2bd9..e4e3213 100644 --- a/WebCore/svg/SVGGradientElement.cpp +++ b/WebCore/svg/SVGGradientElement.cpp @@ -38,13 +38,15 @@ namespace WebCore { +char SVGGradientElementIdentifier[] = "SVGGradientElement"; + SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) , SVGURIReference() , SVGExternalResourcesRequired() - , m_spreadMethod(0) - , m_gradientUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_gradientTransform(new SVGTransformList(SVGNames::gradientTransformAttr)) + , m_spreadMethod(this, SVGNames::spreadMethodAttr) + , m_gradientUnits(this, SVGNames::gradientUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + , m_gradientTransform(this, SVGNames::gradientTransformAttr, SVGTransformList::create(SVGNames::gradientTransformAttr)) { } @@ -52,10 +54,6 @@ SVGGradientElement::~SVGGradientElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, int, Enumeration, enumeration, GradientUnits, gradientUnits, SVGNames::gradientUnitsAttr, m_gradientUnits) -ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, SVGTransformList*, TransformList, transformList, GradientTransform, gradientTransform, SVGNames::gradientTransformAttr, m_gradientTransform.get()) -ANIMATED_PROPERTY_DEFINITIONS(SVGGradientElement, int, Enumeration, enumeration, SpreadMethod, spreadMethod, SVGNames::spreadMethodAttr, m_spreadMethod) - void SVGGradientElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::gradientUnitsAttr) { @@ -71,11 +69,11 @@ void SVGGradientElement::parseMappedAttribute(MappedAttribute* attr) } } else if (attr->name() == SVGNames::spreadMethodAttr) { if (attr->value() == "reflect") - setSpreadMethodBaseValue(SVG_SPREADMETHOD_REFLECT); + setSpreadMethodBaseValue(SpreadMethodReflect); else if (attr->value() == "repeat") - setSpreadMethodBaseValue(SVG_SPREADMETHOD_REPEAT); + setSpreadMethodBaseValue(SpreadMethodRepeat); else if (attr->value() == "pad") - setSpreadMethodBaseValue(SVG_SPREADMETHOD_PAD); + setSpreadMethodBaseValue(SpreadMethodPad); } else { if (SVGURIReference::parseMappedAttribute(attr)) return; @@ -102,9 +100,9 @@ void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName) m_resource->invalidate(); } -void SVGGradientElement::childrenChanged(bool changedByParser) +void SVGGradientElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGStyledElement::childrenChanged(changedByParser); + SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (m_resource) m_resource->invalidate(); @@ -119,9 +117,9 @@ SVGResource* SVGGradientElement::canvasResource() { if (!m_resource) { if (gradientType() == LinearGradientPaintServer) - m_resource = new SVGPaintServerLinearGradient(this); + m_resource = SVGPaintServerLinearGradient::create(this); else - m_resource = new SVGPaintServerRadialGradient(this); + m_resource = SVGPaintServerRadialGradient::create(this); } return m_resource.get(); @@ -130,7 +128,7 @@ SVGResource* SVGGradientElement::canvasResource() Vector<SVGGradientStop> SVGGradientElement::buildStops() const { Vector<SVGGradientStop> stops; - RenderStyle* gradientStyle = 0; + RefPtr<RenderStyle> gradientStyle; for (Node* n = firstChild(); n; n = n->nextSibling()) { SVGElement* element = n->isSVGElement() ? static_cast<SVGElement*>(n) : 0; @@ -151,23 +149,18 @@ Vector<SVGGradientStop> SVGGradientElement::buildStops() const // set display="none" - ie. <g display="none"><linearGradient><stop>.. // Unfortunately we have to manually rebuild the stop style. See pservers-grad-19-b.svg if (!gradientStyle) - gradientStyle = const_cast<SVGGradientElement*>(this)->styleForRenderer(parent()->renderer()); + gradientStyle = const_cast<SVGGradientElement*>(this)->styleForRenderer(); - RenderStyle* stopStyle = stop->resolveStyle(gradientStyle); + RefPtr<RenderStyle> stopStyle = stop->resolveStyle(gradientStyle.get()); color = stopStyle->svgStyle()->stopColor(); opacity = stopStyle->svgStyle()->stopOpacity(); - - stopStyle->deref(document()->renderArena()); } stops.append(makeGradientStop(stopOffset, makeRGBA(color.red(), color.green(), color.blue(), int(opacity * 255.)))); } } - if (gradientStyle) - gradientStyle->deref(document()->renderArena()); - return stops; } diff --git a/WebCore/svg/SVGGradientElement.h b/WebCore/svg/SVGGradientElement.h index 420562f..2027258 100644 --- a/WebCore/svg/SVGGradientElement.h +++ b/WebCore/svg/SVGGradientElement.h @@ -27,31 +27,24 @@ #include "SVGPaintServerGradient.h" #include "SVGExternalResourcesRequired.h" #include "SVGStyledElement.h" +#include "SVGTransformList.h" #include "SVGURIReference.h" namespace WebCore { - class SVGGradientElement; - class SVGTransformList; + extern char SVGGradientElementIdentifier[]; class SVGGradientElement : public SVGStyledElement, public SVGURIReference, public SVGExternalResourcesRequired { public: - enum SVGGradientType { - SVG_SPREADMETHOD_UNKNOWN = 0, - SVG_SPREADMETHOD_PAD = 1, - SVG_SPREADMETHOD_REFLECT = 2, - SVG_SPREADMETHOD_REPEAT = 3 - }; - SVGGradientElement(const QualifiedName&, Document*); virtual ~SVGGradientElement(); virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual SVGResource* canvasResource(); @@ -67,13 +60,12 @@ namespace WebCore { Vector<SVGGradientStop> buildStops() const; mutable RefPtr<SVGPaintServerGradient> m_resource; + virtual const SVGElement* contextElement() const { return this; } + protected: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, int, int, SpreadMethod, spreadMethod) - ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, int, int, GradientUnits, gradientUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGTransformList*, RefPtr<SVGTransformList>, GradientTransform, gradientTransform) + ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGGradientElementIdentifier, SVGNames::spreadMethodAttrString, int, SpreadMethod, spreadMethod) + ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGGradientElementIdentifier, SVGNames::gradientUnitsAttrString, int, GradientUnits, gradientUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGGradientElement, SVGGradientElementIdentifier, SVGNames::gradientTransformAttrString, SVGTransformList, GradientTransform, gradientTransform) }; } // namespace WebCore diff --git a/WebCore/svg/SVGHKernElement.cpp b/WebCore/svg/SVGHKernElement.cpp new file mode 100644 index 0000000..f232fdc --- /dev/null +++ b/WebCore/svg/SVGHKernElement.cpp @@ -0,0 +1,81 @@ +/* + Copyright (C) 2007 Eric Seidel <eric@webkit.org> + Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Eric Seidel <eric@webkit.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#if ENABLE(SVG_FONTS) +#include "SVGHKernElement.h" + +#include "SVGFontElement.h" +#include "SVGFontFaceElement.h" +#include "SVGFontData.h" +#include "SVGNames.h" +#include "SVGParserUtilities.h" +#include "SimpleFontData.h" +#include "XMLNames.h" + +namespace WebCore { + +using namespace SVGNames; + +SVGHKernElement::SVGHKernElement(const QualifiedName& tagName, Document* doc) + : SVGElement(tagName, doc) +{ +} + +SVGHKernElement::~SVGHKernElement() +{ +} + +void SVGHKernElement::insertedIntoDocument() +{ + Node* fontNode = parentNode(); + if (fontNode && fontNode->hasTagName(fontTag)) { + if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) + element->invalidateGlyphCache(); + } +} + +void SVGHKernElement::removedFromDocument() +{ + Node* fontNode = parentNode(); + if (fontNode && fontNode->hasTagName(fontTag)) { + if (SVGFontElement* element = static_cast<SVGFontElement*>(fontNode)) + element->invalidateGlyphCache(); + } +} + +SVGHorizontalKerningPair SVGHKernElement::buildHorizontalKerningPair() const +{ + SVGHorizontalKerningPair kerningPair; + + kerningPair.unicode1 = getAttribute(u1Attr); + kerningPair.glyphName1 = getAttribute(g1Attr); + kerningPair.unicode2 = getAttribute(u2Attr); + kerningPair.glyphName2 = getAttribute(g2Attr); + kerningPair.kerning = getAttribute(kAttr).string().toDouble(); + + return kerningPair; +} + +} + +#endif // ENABLE(SVG_FONTS) diff --git a/WebCore/svg/SVGHKernElement.h b/WebCore/svg/SVGHKernElement.h new file mode 100644 index 0000000..6fda779 --- /dev/null +++ b/WebCore/svg/SVGHKernElement.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2007 Eric Seidel <eric@webkit.org> + Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Apple, Inc + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef SVGHKernElement_h +#define SVGHKernElement_h + +#if ENABLE(SVG_FONTS) +#include "SVGStyledElement.h" + +#include <limits> +#include "Path.h" + +namespace WebCore { + + class AtomicString; + struct SVGFontData; + + // Describe an SVG <hkern> element + struct SVGHorizontalKerningPair { + String unicode1; + String glyphName1; + String unicode2; + String glyphName2; + double kerning; + + SVGHorizontalKerningPair() + : kerning(0) + { + } + }; + + class SVGHKernElement : public SVGElement { + public: + SVGHKernElement(const QualifiedName&, Document*); + virtual ~SVGHKernElement(); + + virtual void insertedIntoDocument(); + virtual void removedFromDocument(); + + virtual bool rendererIsNeeded(RenderStyle*) { return false; } + + SVGHorizontalKerningPair buildHorizontalKerningPair() const; + }; + +} // namespace WebCore + +#endif // ENABLE(SVG_FONTS) +#endif diff --git a/WebCore/svg/SVGHKernElement.idl b/WebCore/svg/SVGHKernElement.idl new file mode 100644 index 0000000..1971aef --- /dev/null +++ b/WebCore/svg/SVGHKernElement.idl @@ -0,0 +1,27 @@ +/* + Copyright (C) 2008 Apple Computer, Inc. All rights reserved. + + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +module svg { + + interface [Conditional=SVG&SVG_FONTS] SVGHKernElement : SVGElement { + }; + +} diff --git a/WebCore/svg/SVGImageElement.cpp b/WebCore/svg/SVGImageElement.cpp index 2c6cf33..d7daebc 100644 --- a/WebCore/svg/SVGImageElement.cpp +++ b/WebCore/svg/SVGImageElement.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> 2006 Alexander Kellett <lypanov@kde.org> This file is part of the KDE project @@ -30,7 +30,6 @@ #include "RenderSVGImage.h" #include "SVGDocument.h" #include "SVGLength.h" -#include "SVGNames.h" #include "SVGPreserveAspectRatio.h" #include "SVGSVGElement.h" #include "XLinkNames.h" @@ -43,11 +42,11 @@ SVGImageElement::SVGImageElement(const QualifiedName& tagName, Document* doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGURIReference() - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) - , m_preserveAspectRatio(new SVGPreserveAspectRatio()) + , m_x(this, SVGNames::xAttr, LengthModeWidth) + , m_y(this, SVGNames::yAttr, LengthModeHeight) + , m_width(this, SVGNames::widthAttr, LengthModeWidth) + , m_height(this, SVGNames::heightAttr, LengthModeHeight) + , m_preserveAspectRatio(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()) , m_imageLoader(this) { } @@ -56,31 +55,25 @@ SVGImageElement::~SVGImageElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) -ANIMATED_PROPERTY_DEFINITIONS(SVGImageElement, SVGPreserveAspectRatio*, PreserveAspectRatio, preserveAspectRatio, PreserveAspectRatio, preserveAspectRatio, SVGNames::preserveAspectRatioAttr, m_preserveAspectRatio.get()) - void SVGImageElement::parseMappedAttribute(MappedAttribute *attr) { if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setYBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::preserveAspectRatioAttr) { const UChar* c = attr->value().characters(); const UChar* end = c + attr->value().length(); preserveAspectRatioBaseValue()->parsePreserveAspectRatio(c, end); } else if (attr->name() == SVGNames::widthAttr) { - setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value())); - addCSSProperty(attr, CSS_PROP_WIDTH, attr->value()); - if (width().value() < 0.0) + setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); + addCSSProperty(attr, CSSPropertyWidth, attr->value()); + if (widthBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for image attribute <width> is not allowed"); } else if (attr->name() == SVGNames::heightAttr) { - setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value())); - addCSSProperty(attr, CSS_PROP_HEIGHT, attr->value()); - if (height().value() < 0.0) + setHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); + addCSSProperty(attr, CSSPropertyHeight, attr->value()); + if (heightBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for image attribute <height> is not allowed"); } else { if (SVGTests::parseMappedAttribute(attr)) @@ -106,6 +99,7 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName) if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr || + attrName == SVGNames::preserveAspectRatioAttr || SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName) || @@ -131,15 +125,38 @@ RenderObject* SVGImageElement::createRenderer(RenderArena* arena, RenderStyle* s bool SVGImageElement::haveLoadedRequiredResources() { - return (!externalResourcesRequiredBaseValue() || m_imageLoader.imageComplete()); + return !externalResourcesRequiredBaseValue() || m_imageLoader.haveFiredLoadEvent(); } void SVGImageElement::attach() { SVGStyledTransformableElement::attach(); - m_imageLoader.updateFromElement(); - if (RenderSVGImage* imageObj = static_cast<RenderSVGImage*>(renderer())) + + if (RenderSVGImage* imageObj = static_cast<RenderSVGImage*>(renderer())) { + if (imageObj->hasImage()) + return; + imageObj->setCachedImage(m_imageLoader.image()); + } +} + +void SVGImageElement::insertedIntoDocument() +{ + SVGStyledTransformableElement::insertedIntoDocument(); + + // Update image loader, as soon as we're living in the tree. + // We can only resolve base URIs properly, after that! + m_imageLoader.updateFromElement(); +} + +const QualifiedName& SVGImageElement::imageSourceAttributeName() const +{ + return XLinkNames::hrefAttr; +} + +void SVGImageElement::getSubresourceAttributeStrings(Vector<String>& urls) const +{ + urls.append(href()); } } diff --git a/WebCore/svg/SVGImageElement.h b/WebCore/svg/SVGImageElement.h index c069f0f..bddfddd 100644 --- a/WebCore/svg/SVGImageElement.h +++ b/WebCore/svg/SVGImageElement.h @@ -30,10 +30,10 @@ #include "SVGStyledTransformableElement.h" #include "SVGTests.h" #include "SVGURIReference.h" +#include "SVGPreserveAspectRatio.h" namespace WebCore { - class SVGPreserveAspectRatio; class SVGLength; class SVGImageElement : public SVGStyledTransformableElement, @@ -51,26 +51,24 @@ namespace WebCore { virtual void svgAttributeChanged(const QualifiedName&); virtual void attach(); + virtual void insertedIntoDocument(); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); - + + virtual const QualifiedName& imageSourceAttributeName() const; + virtual void getSubresourceAttributeStrings(Vector<String>&) const; + protected: virtual bool haveLoadedRequiredResources(); - virtual bool hasRelativeValues() const; - - protected: virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGLength, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGPreserveAspectRatio*, RefPtr<SVGPreserveAspectRatio>, PreserveAspectRatio, preserveAspectRatio) + ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::heightAttrString, SVGLength, Height, height) + ANIMATED_PROPERTY_DECLARATIONS(SVGImageElement, SVGNames::imageTagString, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio) SVGImageLoader m_imageLoader; }; diff --git a/WebCore/svg/SVGImageLoader.cpp b/WebCore/svg/SVGImageLoader.cpp index c8ec8ad..6e0915d 100644 --- a/WebCore/svg/SVGImageLoader.cpp +++ b/WebCore/svg/SVGImageLoader.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2005, 2005 Alexander Kellett <lypanov@kde.org> + 2008 Rob Buis <buis@kde.org> This file is part of the WebKit project @@ -20,22 +21,18 @@ */ #include "config.h" -#if ENABLE(SVG) -#include "Attr.h" -#include "DocLoader.h" -#include "Document.h" +#if ENABLE(SVG) +#include "SVGImageLoader.h" +#include "EventNames.h" #include "SVGImageElement.h" -#include "SVGLength.h" -#include "SVGNames.h" - #include "RenderImage.h" namespace WebCore { SVGImageLoader::SVGImageLoader(SVGImageElement* node) - : HTMLImageLoader(node) + : ImageLoader(node) { } @@ -43,46 +40,26 @@ SVGImageLoader::~SVGImageLoader() { } -// FIXME - Refactor most of this code into WebCore::HTMLImageLoader or a shared WebCore::ImageLoader base class -void SVGImageLoader::updateFromElement() -{ - SVGImageElement *imageElement = static_cast<SVGImageElement *>(element()); - WebCore::Document* doc = imageElement->ownerDocument(); - - CachedImage *newImage = 0; - if (!imageElement->href().isEmpty()) { - DeprecatedString uri = imageElement->baseURI().deprecatedString(); - if (!uri.isEmpty()) - uri = KURL(uri, imageElement->href().deprecatedString()).deprecatedString(); - else - uri = imageElement->href().deprecatedString(); - newImage = doc->docLoader()->requestImage(uri); - } - - CachedImage *oldImage = image(); - if (newImage != oldImage) { - setLoadingImage(newImage); - if (newImage) - newImage->ref(this); - if (oldImage) - oldImage->deref(this); - } - - if (RenderImage* renderer = static_cast<RenderImage*>(imageElement->renderer())) - renderer->resetAnimation(); -} - void SVGImageLoader::dispatchLoadEvent() { if (!haveFiredLoadEvent() && image()) { setHaveFiredLoadEvent(true); - if (image()->errorOccurred()) { - // FIXME: We're supposed to put the document in an "error state" per the spec. - } else - static_cast<SVGElement*>(element())->sendSVGLoadEventIfPossible(true); + + if (image()->errorOccurred()) + element()->dispatchEventForType(eventNames().errorEvent, false, false); + else { + SVGImageElement* imageElement = static_cast<SVGImageElement*>(element()); + if (imageElement->externalResourcesRequiredBaseValue()) + imageElement->sendSVGLoadEventIfPossible(true); + } } } +String SVGImageLoader::sourceURI(const AtomicString& attr) const +{ + return parseURL(KURL(element()->baseURI(), attr).string()); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGImageLoader.h b/WebCore/svg/SVGImageLoader.h index a6497c9..a838db8 100644 --- a/WebCore/svg/SVGImageLoader.h +++ b/WebCore/svg/SVGImageLoader.h @@ -21,26 +21,24 @@ #ifndef SVGImageLoader_h #define SVGImageLoader_h -#if ENABLE(SVG) -#include "HTMLImageLoader.h" +#if ENABLE(SVG) +#include "ImageLoader.h" namespace WebCore { class SVGImageElement; - class SVGImageLoader : public HTMLImageLoader { + class SVGImageLoader : public ImageLoader { public: SVGImageLoader(SVGImageElement*); virtual ~SVGImageLoader(); - - virtual void updateFromElement(); + virtual void dispatchLoadEvent(); + virtual String sourceURI(const AtomicString&) const; }; } // namespace WebCore #endif // ENABLE(SVG) #endif // SVGImageLoader_h - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGLength.cpp b/WebCore/svg/SVGLength.cpp index e6ecb82..86714f9 100644 --- a/WebCore/svg/SVGLength.cpp +++ b/WebCore/svg/SVGLength.cpp @@ -33,7 +33,6 @@ #include "RenderView.h" #include "SVGParserUtilities.h" #include "SVGSVGElement.h" -#include "SVGStyledElement.h" #include <math.h> #include <wtf/Assertions.h> @@ -114,10 +113,9 @@ inline SVGLengthType stringToLengthType(const String& string) return LengthTypeUnknown; } -SVGLength::SVGLength(const SVGStyledElement* context, SVGLengthMode mode, const String& valueAsString) +SVGLength::SVGLength(SVGLengthMode mode, const String& valueAsString) : m_valueInSpecifiedUnits(0.0f) , m_unit(storeUnit(mode, LengthTypeNumber)) - , m_context(context) { setValueAsString(valueAsString); } @@ -127,7 +125,7 @@ SVGLengthType SVGLength::unitType() const return extractType(m_unit); } -float SVGLength::value() const +float SVGLength::value(const SVGElement* context) const { SVGLengthType type = extractType(m_unit); if (type == LengthTypeUnknown) @@ -137,13 +135,13 @@ float SVGLength::value() const case LengthTypeNumber: return m_valueInSpecifiedUnits; case LengthTypePercentage: - return SVGLength::PercentageOfViewport(m_valueInSpecifiedUnits / 100.0f, m_context, extractMode(m_unit)); + return SVGLength::PercentageOfViewport(m_valueInSpecifiedUnits / 100.0f, context, extractMode(m_unit)); case LengthTypeEMS: case LengthTypeEXS: { RenderStyle* style = 0; - if (m_context && m_context->renderer()) - style = m_context->renderer()->style(); + if (context && context->renderer()) + style = context->renderer()->style(); if (style) { float useSize = style->fontSize(); ASSERT(useSize > 0); @@ -268,16 +266,16 @@ void SVGLength::newValueSpecifiedUnits(unsigned short type, float value) m_valueInSpecifiedUnits = value; } -void SVGLength::convertToSpecifiedUnits(unsigned short type) +void SVGLength::convertToSpecifiedUnits(unsigned short type, const SVGElement* context) { ASSERT(type <= LengthTypePC); - float valueInUserUnits = value(); + float valueInUserUnits = value(context); m_unit = storeUnit(extractMode(m_unit), (SVGLengthType) type); setValue(valueInUserUnits); } -float SVGLength::PercentageOfViewport(float value, const SVGStyledElement* context, SVGLengthMode mode) +float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SVGLengthMode mode) { ASSERT(context); @@ -298,8 +296,8 @@ float SVGLength::PercentageOfViewport(float value, const SVGStyledElement* conte width = svg->viewBox().width(); height = svg->viewBox().height(); } else { - width = svg->width().value(); - height = svg->height().value(); + width = svg->width().value(svg); + height = svg->height().value(svg); } } else if (context->parent() && !context->parent()->isSVGElement()) { if (RenderObject* renderer = context->renderer()) { diff --git a/WebCore/svg/SVGLength.h b/WebCore/svg/SVGLength.h index 543221f..7846b4a 100644 --- a/WebCore/svg/SVGLength.h +++ b/WebCore/svg/SVGLength.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -24,13 +24,10 @@ #define SVGLength_h #if ENABLE(SVG) - #include "PlatformString.h" namespace WebCore { - class SVGStyledElement; - enum SVGLengthType { LengthTypeUnknown = 0, LengthTypeNumber = 1, @@ -51,6 +48,8 @@ namespace WebCore { LengthModeOther }; + class SVGElement; + class SVGLength { public: // Forward declare these enums in the w3c naming scheme, for IDL generation @@ -68,12 +67,11 @@ namespace WebCore { SVG_LENGTHTYPE_PC = LengthTypePC }; - SVGLength(const SVGStyledElement* context = 0, SVGLengthMode mode = LengthModeOther, const String& valueAsString = String()); + SVGLength(SVGLengthMode mode = LengthModeOther, const String& valueAsString = String()); - // 'SVGLength' functions SVGLengthType unitType() const; - float value() const; + float value(const SVGElement* context) const; void setValue(float); float valueInSpecifiedUnits() const; @@ -85,10 +83,10 @@ namespace WebCore { bool setValueAsString(const String&); void newValueSpecifiedUnits(unsigned short, float valueInSpecifiedUnits); - void convertToSpecifiedUnits(unsigned short); + void convertToSpecifiedUnits(unsigned short, const SVGElement* context); // Helper functions - static float PercentageOfViewport(float value, const SVGStyledElement*, SVGLengthMode); + static float PercentageOfViewport(float value, const SVGElement* context, SVGLengthMode); inline bool isRelative() const { @@ -99,13 +97,9 @@ namespace WebCore { private: float m_valueInSpecifiedUnits; unsigned int m_unit; - - const SVGStyledElement* m_context; }; } // namespace WebCore #endif // ENABLE(SVG) #endif // SVGLength_h - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGLength.idl b/WebCore/svg/SVGLength.idl index 707469e..20748b1 100644 --- a/WebCore/svg/SVGLength.idl +++ b/WebCore/svg/SVGLength.idl @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> Copyright (C) 2006 Apple Computer, Inc. All rights reserved. @@ -39,13 +39,14 @@ module svg { const unsigned short SVG_LENGTHTYPE_PC = 10; readonly attribute unsigned short unitType; - attribute float value; - attribute float valueInSpecifiedUnits; - attribute [ConvertNullToNullString] DOMString valueAsString; + attribute [CustomGetter] float value; + attribute float valueInSpecifiedUnits; + attribute [ConvertNullToNullString] DOMString valueAsString; void newValueSpecifiedUnits(in unsigned short unitType, in float valueInSpecifiedUnits); - void convertToSpecifiedUnits(in unsigned short unitType); + + [Custom] void convertToSpecifiedUnits(in unsigned short unitType); }; } diff --git a/WebCore/svg/SVGLengthList.cpp b/WebCore/svg/SVGLengthList.cpp index c2d8160..20b61d6 100644 --- a/WebCore/svg/SVGLengthList.cpp +++ b/WebCore/svg/SVGLengthList.cpp @@ -38,7 +38,7 @@ SVGLengthList::~SVGLengthList() { } -void SVGLengthList::parse(const String& value, const SVGStyledElement* context, SVGLengthMode mode) +void SVGLengthList::parse(const String& value, SVGLengthMode mode) { ExceptionCode ec = 0; clear(ec); @@ -51,7 +51,7 @@ void SVGLengthList::parse(const String& value, const SVGStyledElement* context, ptr++; if (ptr == start) break; - SVGLength length(context, mode); + SVGLength length(mode); if (!length.setValueAsString(String(start, ptr - start))) return; appendItem(length, ec); @@ -59,6 +59,22 @@ void SVGLengthList::parse(const String& value, const SVGStyledElement* context, } } +String SVGLengthList::valueAsString() const +{ + String result; + + ExceptionCode ec = 0; + for (unsigned int i = 0; i < numberOfItems(); ++i) { + if (i > 0) + result += ", "; + + result += getItem(i, ec).valueAsString(); + ASSERT(ec == 0); + } + + return result; +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGLengthList.h b/WebCore/svg/SVGLengthList.h index af365a1..e83fee8 100644 --- a/WebCore/svg/SVGLengthList.h +++ b/WebCore/svg/SVGLengthList.h @@ -31,10 +31,15 @@ namespace WebCore { class SVGLengthList : public SVGPODList<SVGLength> { public: - SVGLengthList(const QualifiedName&); + static PassRefPtr<SVGLengthList> create(const QualifiedName& attributeName) { return adoptRef(new SVGLengthList(attributeName)); } virtual ~SVGLengthList(); - void parse(const String& value, const SVGStyledElement* context, SVGLengthMode mode); + void parse(const String& value, SVGLengthMode mode); + + String valueAsString() const; + + private: + SVGLengthList(const QualifiedName&); }; } // namespace WebCore diff --git a/WebCore/svg/SVGLineElement.cpp b/WebCore/svg/SVGLineElement.cpp index 3b664d1..12f54e3 100644 --- a/WebCore/svg/SVGLineElement.cpp +++ b/WebCore/svg/SVGLineElement.cpp @@ -37,10 +37,10 @@ SVGLineElement::SVGLineElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_x1(this, LengthModeWidth) - , m_y1(this, LengthModeHeight) - , m_x2(this, LengthModeWidth) - , m_y2(this, LengthModeHeight) + , m_x1(this, SVGNames::x1Attr, LengthModeWidth) + , m_y1(this, SVGNames::y1Attr, LengthModeHeight) + , m_x2(this, SVGNames::x2Attr, LengthModeWidth) + , m_y2(this, SVGNames::y2Attr, LengthModeHeight) { } @@ -48,21 +48,16 @@ SVGLineElement::~SVGLineElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGLineElement, SVGLength, Length, length, X1, x1, SVGNames::x1Attr, m_x1) -ANIMATED_PROPERTY_DEFINITIONS(SVGLineElement, SVGLength, Length, length, Y1, y1, SVGNames::y1Attr, m_y1) -ANIMATED_PROPERTY_DEFINITIONS(SVGLineElement, SVGLength, Length, length, X2, x2, SVGNames::x2Attr, m_x2) -ANIMATED_PROPERTY_DEFINITIONS(SVGLineElement, SVGLength, Length, length, Y2, y2, SVGNames::y2Attr, m_y2) - void SVGLineElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::x1Attr) - setX1BaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setX1BaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::y1Attr) - setY1BaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setY1BaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::x2Attr) - setX2BaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setX2BaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::y2Attr) - setY2BaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setY2BaseValue(SVGLength(LengthModeHeight, attr->value())); else { if (SVGTests::parseMappedAttribute(attr)) @@ -93,8 +88,8 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName) Path SVGLineElement::toPathData() const { - return Path::createLine(FloatPoint(x1().value(), y1().value()), - FloatPoint(x2().value(), y2().value())); + return Path::createLine(FloatPoint(x1().value(this), y1().value(this)), + FloatPoint(x2().value(this), y2().value(this))); } bool SVGLineElement::hasRelativeValues() const diff --git a/WebCore/svg/SVGLineElement.h b/WebCore/svg/SVGLineElement.h index c6dbc08..2d89f5c 100644 --- a/WebCore/svg/SVGLineElement.h +++ b/WebCore/svg/SVGLineElement.h @@ -55,12 +55,10 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGLength, SVGLength, X1, x1) - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGLength, SVGLength, Y1, y1) - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGLength, SVGLength, X2, x2) - ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGLength, SVGLength, Y2, y2) + ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGNames::lineTagString, SVGNames::x1AttrString, SVGLength, X1, x1) + ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGNames::lineTagString, SVGNames::y1AttrString, SVGLength, Y1, y1) + ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGNames::lineTagString, SVGNames::x2AttrString, SVGLength, X2, x2) + ANIMATED_PROPERTY_DECLARATIONS(SVGLineElement, SVGNames::lineTagString, SVGNames::y2AttrString, SVGLength, Y2, y2) }; } // namespace WebCore diff --git a/WebCore/svg/SVGLinearGradientElement.cpp b/WebCore/svg/SVGLinearGradientElement.cpp index 6cddf07..04469a9 100644 --- a/WebCore/svg/SVGLinearGradientElement.cpp +++ b/WebCore/svg/SVGLinearGradientElement.cpp @@ -25,6 +25,7 @@ #if ENABLE(SVG) #include "SVGLinearGradientElement.h" +#include "Document.h" #include "FloatPoint.h" #include "LinearGradientAttributes.h" #include "SVGLength.h" @@ -38,34 +39,28 @@ namespace WebCore { SVGLinearGradientElement::SVGLinearGradientElement(const QualifiedName& tagName, Document* doc) : SVGGradientElement(tagName, doc) - , m_x1(this, LengthModeWidth) - , m_y1(this, LengthModeHeight) - , m_x2(this, LengthModeWidth) - , m_y2(this, LengthModeHeight) + , m_x1(this, SVGNames::x1Attr, LengthModeWidth) + , m_y1(this, SVGNames::y1Attr, LengthModeHeight) + , m_x2(this, SVGNames::x2Attr, LengthModeWidth, "100%") + , m_y2(this, SVGNames::y2Attr, LengthModeHeight) { - // Spec: If the attribute is not specified, the effect is as if a value of "100%" were specified. - setX2BaseValue(SVGLength(this, LengthModeWidth, "100%")); + // Spec: If the x2 attribute is not specified, the effect is as if a value of "100%" were specified. } SVGLinearGradientElement::~SVGLinearGradientElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGLinearGradientElement, SVGLength, Length, length, X1, x1, SVGNames::x1Attr, m_x1) -ANIMATED_PROPERTY_DEFINITIONS(SVGLinearGradientElement, SVGLength, Length, length, Y1, y1, SVGNames::y1Attr, m_y1) -ANIMATED_PROPERTY_DEFINITIONS(SVGLinearGradientElement, SVGLength, Length, length, X2, x2, SVGNames::x2Attr, m_x2) -ANIMATED_PROPERTY_DEFINITIONS(SVGLinearGradientElement, SVGLength, Length, length, Y2, y2, SVGNames::y2Attr, m_y2) - void SVGLinearGradientElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::x1Attr) - setX1BaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setX1BaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::y1Attr) - setY1BaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setY1BaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::x2Attr) - setX2BaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setX2BaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::y2Attr) - setY2BaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setY2BaseValue(SVGLength(LengthModeHeight, attr->value())); else SVGGradientElement::parseMappedAttribute(attr); } @@ -110,10 +105,10 @@ LinearGradientAttributes SVGLinearGradientElement::collectGradientProperties() c while (current) { if (!attributes.hasSpreadMethod() && current->hasAttribute(SVGNames::spreadMethodAttr)) - attributes.setSpreadMethod((SVGGradientSpreadMethod) current->spreadMethod()); + attributes.setSpreadMethod((GradientSpreadMethod) current->spreadMethod()); if (!attributes.hasBoundingBoxMode() && current->hasAttribute(SVGNames::gradientUnitsAttr)) - attributes.setBoundingBoxMode(current->getAttribute(SVGNames::gradientUnitsAttr) == "objectBoundingBox"); + attributes.setBoundingBoxMode(current->gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) attributes.setGradientTransform(current->gradientTransform()->consolidate().matrix()); diff --git a/WebCore/svg/SVGLinearGradientElement.h b/WebCore/svg/SVGLinearGradientElement.h index 496585e..0e1efd4 100644 --- a/WebCore/svg/SVGLinearGradientElement.h +++ b/WebCore/svg/SVGLinearGradientElement.h @@ -45,14 +45,11 @@ namespace WebCore { LinearGradientAttributes collectGradientProperties() const; - protected: - virtual const SVGElement* contextElement() const { return this; } - private: - ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGLength, SVGLength, X1, x1) - ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGLength, SVGLength, Y1, y1) - ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGLength, SVGLength, X2, x2) - ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGLength, SVGLength, Y2, y2) + ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGNames::linearGradientTagString, SVGNames::x1AttrString, SVGLength, X1, x1) + ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGNames::linearGradientTagString, SVGNames::y1AttrString, SVGLength, Y1, y1) + ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGNames::linearGradientTagString, SVGNames::x2AttrString, SVGLength, X2, x2) + ANIMATED_PROPERTY_DECLARATIONS(SVGLinearGradientElement, SVGNames::linearGradientTagString, SVGNames::y2AttrString, SVGLength, Y2, y2) }; } // namespace WebCore diff --git a/WebCore/svg/SVGList.h b/WebCore/svg/SVGList.h index 92c7068..d4f7641 100644 --- a/WebCore/svg/SVGList.h +++ b/WebCore/svg/SVGList.h @@ -28,6 +28,7 @@ #include "SVGListTraits.h" #include <wtf/RefCounted.h> +#include <wtf/PassRefPtr.h> #include <wtf/Vector.h> namespace WebCore { @@ -48,12 +49,7 @@ namespace WebCore { typedef SVGListTypeOperations<Item> TypeOperations; public: - SVGList(const QualifiedName& attributeName) - : m_associatedAttributeName(attributeName) - { - } - - virtual ~SVGList() { m_vector.clear(); } + virtual ~SVGList() { } const QualifiedName& associatedAttributeName() const { return m_associatedAttributeName; } @@ -133,6 +129,12 @@ namespace WebCore { return newItem; } + protected: + SVGList(const QualifiedName& attributeName) + : m_associatedAttributeName(attributeName) + { + } + private: Vector<Item> m_vector; const QualifiedName& m_associatedAttributeName; @@ -141,8 +143,8 @@ namespace WebCore { template<typename Item> class SVGPODListItem : public RefCounted<SVGPODListItem<Item> > { public: - SVGPODListItem() : m_item() { } - SVGPODListItem(const Item& item) : m_item(item) { } + static PassRefPtr<SVGPODListItem> create() { return adoptRef(new SVGPODListItem); } + static PassRefPtr<SVGPODListItem> copy(const Item& item) { return adoptRef(new SVGPODListItem(item)); } operator Item&() { return m_item; } operator const Item&() const { return m_item; } @@ -152,6 +154,9 @@ namespace WebCore { void setValue(Item newItem) { m_item = newItem; } private: + SVGPODListItem() : m_item() { } + SVGPODListItem(const Item& item) : RefCounted<SVGPODListItem<Item> >(), m_item(item) { } + Item m_item; }; @@ -159,11 +164,9 @@ namespace WebCore { class SVGPODList : public SVGList<RefPtr<SVGPODListItem<Item> > > { public: - SVGPODList(const QualifiedName& attributeName) : SVGList<RefPtr<SVGPODListItem<Item> > >(attributeName) { } - Item initialize(Item newItem, ExceptionCode& ec) { - SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::initialize(new SVGPODListItem<Item>(newItem), ec).get()); + SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::initialize(SVGPODListItem<Item>::copy(newItem), ec).get()); if (!ptr) return Item(); @@ -208,7 +211,7 @@ namespace WebCore { Item insertItemBefore(Item newItem, unsigned int index, ExceptionCode& ec) { - SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::insertItemBefore(new SVGPODListItem<Item>(newItem), index, ec).get()); + SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::insertItemBefore(SVGPODListItem<Item>::copy(newItem), index, ec).get()); if (!ptr) return Item(); @@ -217,7 +220,7 @@ namespace WebCore { Item replaceItem(Item newItem, unsigned int index, ExceptionCode& ec) { - SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::replaceItem(new SVGPODListItem<Item>(newItem), index, ec).get()); + SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::replaceItem(SVGPODListItem<Item>::copy(newItem), index, ec).get()); if (!ptr) return Item(); @@ -235,12 +238,16 @@ namespace WebCore { Item appendItem(Item newItem, ExceptionCode& ec) { - SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::appendItem(new SVGPODListItem<Item>(newItem), ec).get()); + SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::appendItem(SVGPODListItem<Item>::copy(newItem), ec).get()); if (!ptr) return Item(); return static_cast<const Item&>(*ptr); } + + protected: + SVGPODList(const QualifiedName& attributeName) + : SVGList<RefPtr<SVGPODListItem<Item> > >(attributeName) { } }; } // namespace WebCore diff --git a/WebCore/svg/SVGLocatable.cpp b/WebCore/svg/SVGLocatable.cpp index 91564a5..956a4f9 100644 --- a/WebCore/svg/SVGLocatable.cpp +++ b/WebCore/svg/SVGLocatable.cpp @@ -40,7 +40,7 @@ SVGLocatable::~SVGLocatable() { } -SVGElement* SVGLocatable::nearestViewportElement(const SVGStyledElement* e) +SVGElement* SVGLocatable::nearestViewportElement(const SVGElement* e) { Node* n = e->parentNode(); while (n && !n->isDocumentNode()) { @@ -58,7 +58,7 @@ SVGElement* SVGLocatable::nearestViewportElement(const SVGStyledElement* e) return 0; } -SVGElement* SVGLocatable::farthestViewportElement(const SVGStyledElement* e) +SVGElement* SVGLocatable::farthestViewportElement(const SVGElement* e) { // FIXME : likely this will be always the <svg> farthest away. // If we have a different implementation of documentElement(), one @@ -83,14 +83,15 @@ SVGElement* SVGLocatable::farthestViewportElement(const SVGStyledElement* e) // Spec: // http://www.w3.org/TR/2005/WD-SVGMobile12-20050413/svgudom.html#svg::SVGLocatable -FloatRect SVGLocatable::getBBox(const SVGStyledElement* e) +FloatRect SVGLocatable::getBBox(const SVGElement* e) { FloatRect bboxRect; + e->document()->updateLayoutIgnorePendingStylesheets(); + if (e && e->renderer()) { // Need this to make sure we have render object dimensions. // See bug 11686. - e->document()->updateLayoutIgnorePendingStylesheets(); bboxRect = e->renderer()->relativeBBox(false); } diff --git a/WebCore/svg/SVGLocatable.h b/WebCore/svg/SVGLocatable.h index d9cf685..b1601ce 100644 --- a/WebCore/svg/SVGLocatable.h +++ b/WebCore/svg/SVGLocatable.h @@ -32,7 +32,6 @@ namespace WebCore { class AffineTransform; class FloatRect; class SVGElement; - class SVGStyledElement; class SVGLocatable { public: @@ -48,11 +47,11 @@ namespace WebCore { virtual AffineTransform getScreenCTM() const = 0; AffineTransform getTransformToElement(SVGElement*, ExceptionCode&) const; - static SVGElement* nearestViewportElement(const SVGStyledElement*); - static SVGElement* farthestViewportElement(const SVGStyledElement*); + static SVGElement* nearestViewportElement(const SVGElement*); + static SVGElement* farthestViewportElement(const SVGElement*); protected: - static FloatRect getBBox(const SVGStyledElement*); + static FloatRect getBBox(const SVGElement*); static AffineTransform getCTM(const SVGElement*); static AffineTransform getScreenCTM(const SVGElement*); }; diff --git a/WebCore/svg/SVGMPathElement.cpp b/WebCore/svg/SVGMPathElement.cpp index 61bf633..b3214ed 100644 --- a/WebCore/svg/SVGMPathElement.cpp +++ b/WebCore/svg/SVGMPathElement.cpp @@ -23,6 +23,8 @@ #if ENABLE(SVG) #include "SVGMPathElement.h" + +#include "Document.h" #include "SVGPathElement.h" namespace WebCore { diff --git a/WebCore/svg/SVGMarkerElement.cpp b/WebCore/svg/SVGMarkerElement.cpp index 5883bb5..6145f7c 100644 --- a/WebCore/svg/SVGMarkerElement.cpp +++ b/WebCore/svg/SVGMarkerElement.cpp @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -36,57 +34,60 @@ namespace WebCore { +char SVGOrientTypeAttrIdentifier[] = "SVGOrientTypeAttr"; +char SVGOrientAngleAttrIdentifier[] = "SVGOrientAngleAttr"; + SVGMarkerElement::SVGMarkerElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGFitToViewBox() - , m_refX(this, LengthModeWidth) - , m_refY(this, LengthModeHeight) - , m_markerWidth(this, LengthModeWidth) - , m_markerHeight(this, LengthModeHeight) - , m_markerUnits(SVG_MARKERUNITS_STROKEWIDTH) - , m_orientType(0) - , m_orientAngle(new SVGAngle()) + , m_refX(this, SVGNames::refXAttr, LengthModeWidth) + , m_refY(this, SVGNames::refYAttr, LengthModeHeight) + , m_markerWidth(this, SVGNames::markerWidthAttr, LengthModeWidth, "3") + , m_markerHeight(this, SVGNames::markerHeightAttr, LengthModeHeight, "3") + , m_markerUnits(this, SVGNames::markerUnitsAttr, SVG_MARKERUNITS_STROKEWIDTH) + , m_orientType(this, SVGNames::orientAttr, SVG_MARKER_ORIENT_ANGLE) + , m_orientAngle(this, SVGNames::orientAttr, SVGAngle::create()) { - // Spec: If the attribute is not specified, the effect is as if a value of "3" were specified. - setMarkerWidthBaseValue(SVGLength(this, LengthModeWidth, "3")); - setMarkerHeightBaseValue(SVGLength(this, LengthModeHeight, "3")); + // Spec: If the markerWidth/markerHeight attribute is not specified, the effect is as if a value of "3" were specified. } SVGMarkerElement::~SVGMarkerElement() { + // Call detach() here because if we wait until ~Node() calls it, we crash during + // RenderSVGViewportContainer destruction, as the renderer assumes that the element + // is still fully constructed. See <https://bugs.webkit.org/show_bug.cgi?id=21293>. + if (renderer()) + detach(); } -ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, RefX, refX, SVGNames::refXAttr, m_refX) -ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, RefY, refY, SVGNames::refYAttr, m_refY) -ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, int, Enumeration, enumeration, MarkerUnits, markerUnits, SVGNames::markerUnitsAttr, m_markerUnits) -ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, MarkerWidth, markerWidth, SVGNames::markerWidthAttr, m_markerWidth) -ANIMATED_PROPERTY_DEFINITIONS(SVGMarkerElement, SVGLength, Length, length, MarkerHeight, markerHeight, SVGNames::markerHeightAttr, m_markerHeight) -ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGMarkerElement, int, Enumeration, enumeration, OrientType, orientType, SVGNames::orientAttr, "orientType", m_orientType) -ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGMarkerElement, SVGAngle*, Angle, angle, OrientAngle, orientAngle, SVGNames::orientAttr, "orientAngle", m_orientAngle.get()) - void SVGMarkerElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::markerUnitsAttr) { if (attr->value() == "userSpaceOnUse") setMarkerUnitsBaseValue(SVG_MARKERUNITS_USERSPACEONUSE); + else if (attr->value() == "strokeWidth") + setMarkerUnitsBaseValue(SVG_MARKERUNITS_STROKEWIDTH); } else if (attr->name() == SVGNames::refXAttr) - setRefXBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setRefXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::refYAttr) - setRefYBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setRefYBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::markerWidthAttr) - setMarkerWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setMarkerWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::markerHeightAttr) - setMarkerHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setMarkerHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::orientAttr) { + RefPtr<SVGAngle> angle = SVGAngle::create(); + if (attr->value() == "auto") - setOrientToAuto(); + setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO); else { - SVGAngle* angle = new SVGAngle(); angle->setValueAsString(attr->value()); - setOrientToAngle(angle); + setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE); } + + setOrientAngleBaseValue(angle.get()); } else { if (SVGLangSpace::parseMappedAttribute(attr)) return; @@ -115,51 +116,68 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) SVGStyledElement::isKnownAttribute(attrName)) { if (renderer()) renderer()->setNeedsLayout(true); - + m_marker->invalidate(); } } -void SVGMarkerElement::childrenChanged(bool changedByParser) +void SVGMarkerElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGStyledElement::childrenChanged(changedByParser); + SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); + + if (!m_marker) + return; if (renderer()) renderer()->setNeedsLayout(true); - if (m_marker) - m_marker->invalidate(); + m_marker->invalidate(); } void SVGMarkerElement::setOrientToAuto() { setOrientTypeBaseValue(SVG_MARKER_ORIENT_AUTO); + + RefPtr<SVGAngle> angle = SVGAngle::create(); + setOrientAngleBaseValue(angle.get()); + + if (!m_marker) + return; + + if (renderer()) + renderer()->setNeedsLayout(true); + + m_marker->invalidate(); } -void SVGMarkerElement::setOrientToAngle(SVGAngle* angle) +void SVGMarkerElement::setOrientToAngle(PassRefPtr<SVGAngle> angle) { setOrientTypeBaseValue(SVG_MARKER_ORIENT_ANGLE); - setOrientAngleBaseValue(angle); + setOrientAngleBaseValue(angle.get()); + + if (!m_marker) + return; + + if (renderer()) + renderer()->setNeedsLayout(true); + + m_marker->invalidate(); } SVGResource* SVGMarkerElement::canvasResource() { if (!m_marker) - m_marker = new SVGResourceMarker(); + m_marker = SVGResourceMarker::create(); m_marker->setMarker(static_cast<RenderSVGViewportContainer*>(renderer())); - // Spec: If the attribute is not specified, the effect is as if a - // value of "0" were specified. - if (!m_orientType) - setOrientToAngle(SVGSVGElement::createSVGAngle()); - - if (orientType() == SVG_MARKER_ORIENT_ANGLE) - m_marker->setAngle(orientAngle()->value()); - else + if (orientType() == SVG_MARKER_ORIENT_ANGLE) { + if (orientAngle()) + m_marker->setAngle(orientAngle()->value()); + } else m_marker->setAutoAngle(); - m_marker->setRef(refX().value(), refY().value()); + m_marker->setRef(refX().value(this), refY().value(this)); m_marker->setUseStrokeWidth(markerUnits() == SVG_MARKERUNITS_STROKEWIDTH); return m_marker.get(); diff --git a/WebCore/svg/SVGMarkerElement.h b/WebCore/svg/SVGMarkerElement.h index 9eaf189..e2e3493 100644 --- a/WebCore/svg/SVGMarkerElement.h +++ b/WebCore/svg/SVGMarkerElement.h @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -24,17 +22,22 @@ #define SVGMarkerElement_h #if ENABLE(SVG) -#include "SVGResourceMarker.h" + +#include "SVGAngle.h" #include "SVGExternalResourcesRequired.h" #include "SVGFitToViewBox.h" #include "SVGLangSpace.h" +#include "SVGResourceMarker.h" #include "SVGStyledElement.h" namespace WebCore { class Document; class SVGAngle; - + + extern char SVGOrientTypeAttrIdentifier[]; + extern char SVGOrientAngleAttrIdentifier[]; + class SVGMarkerElement : public SVGStyledElement, public SVGLangSpace, public SVGExternalResourcesRequired, @@ -56,11 +59,11 @@ namespace WebCore { virtual ~SVGMarkerElement(); void setOrientToAuto(); - void setOrientToAngle(SVGAngle*); + void setOrientToAngle(PassRefPtr<SVGAngle>); virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual SVGResource* canvasResource(); @@ -69,17 +72,13 @@ namespace WebCore { virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, SVGPreserveAspectRatio*, PreserveAspectRatio, preserveAspectRatio) - - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGLength, SVGLength, RefX, refX) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGLength, SVGLength, RefY, refY) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGLength, SVGLength, MarkerWidth, markerWidth) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGLength, SVGLength, MarkerHeight, markerHeight) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, int, int, MarkerUnits, markerUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, int, int, OrientType, orientType) - ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGAngle*, RefPtr<SVGAngle>, OrientAngle, orientAngle) + ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::refXAttrString, SVGLength, RefX, refX) + ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::refYAttrString, SVGLength, RefY, refY) + ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::markerWidthAttrString, SVGLength, MarkerWidth, markerWidth) + ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::markerHeightAttrString, SVGLength, MarkerHeight, markerHeight) + ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGNames::markerUnitsAttrString, int, MarkerUnits, markerUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGOrientTypeAttrIdentifier, int, OrientType, orientType) + ANIMATED_PROPERTY_DECLARATIONS(SVGMarkerElement, SVGNames::markerTagString, SVGOrientAngleAttrIdentifier, SVGAngle, OrientAngle, orientAngle) RefPtr<SVGResourceMarker> m_marker; }; diff --git a/WebCore/svg/SVGMaskElement.cpp b/WebCore/svg/SVGMaskElement.cpp index 9bb2373..9f9ae34 100644 --- a/WebCore/svg/SVGMaskElement.cpp +++ b/WebCore/svg/SVGMaskElement.cpp @@ -48,33 +48,21 @@ SVGMaskElement::SVGMaskElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_maskUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_maskContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) + , m_maskUnits(this, SVGNames::maskUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + , m_maskContentUnits(this, SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) + , m_x(this, SVGNames::xAttr, LengthModeWidth, "-10%") + , m_y(this, SVGNames::yAttr, LengthModeHeight, "-10%") + , m_width(this, SVGNames::widthAttr, LengthModeWidth, "120%") + , m_height(this, SVGNames::heightAttr, LengthModeHeight, "120%") { - // Spec: If the attribute is not specified, the effect is as if a value of "-10%" were specified. - setXBaseValue(SVGLength(this, LengthModeWidth, "-10%")); - setYBaseValue(SVGLength(this, LengthModeHeight, "-10%")); - - // Spec: If the attribute is not specified, the effect is as if a value of "120%" were specified. - setWidthBaseValue(SVGLength(this, LengthModeWidth, "120%")); - setHeightBaseValue(SVGLength(this, LengthModeHeight, "120%")); + // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified. + // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified. } SVGMaskElement::~SVGMaskElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, int, Enumeration, enumeration, MaskUnits, maskUnits, SVGNames::maskUnitsAttr, m_maskUnits) -ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, int, Enumeration, enumeration, MaskContentUnits, maskContentUnits, SVGNames::maskContentUnitsAttr, m_maskContentUnits) -ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) - void SVGMaskElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::maskUnitsAttr) { @@ -88,13 +76,13 @@ void SVGMaskElement::parseMappedAttribute(MappedAttribute* attr) else if (attr->value() == "objectBoundingBox") setMaskContentUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); } else if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setYBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::widthAttr) - setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::heightAttr) - setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); else { if (SVGURIReference::parseMappedAttribute(attr)) return; @@ -126,9 +114,9 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName) m_masker->invalidate(); } -void SVGMaskElement::childrenChanged(bool changedByParser) +void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGStyledElement::childrenChanged(changedByParser); + SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!m_masker) return; @@ -150,10 +138,10 @@ auto_ptr<ImageBuffer> SVGMaskElement::drawMaskerContent(const FloatRect& targetR widthValue = width().valueAsPercentage() * targetRect.width(); heightValue = height().valueAsPercentage() * targetRect.height(); } else { - xValue = x().value(); - yValue = y().value(); - widthValue = width().value(); - heightValue = height().value(); + xValue = x().value(this); + yValue = y().value(this); + widthValue = width().value(this); + heightValue = height().value(this); } IntSize imageSize(lroundf(widthValue), lroundf(heightValue)); @@ -217,7 +205,7 @@ RenderObject* SVGMaskElement::createRenderer(RenderArena* arena, RenderStyle*) SVGResource* SVGMaskElement::canvasResource() { if (!m_masker) - m_masker = new SVGResourceMasker(this); + m_masker = SVGResourceMasker::create(this); return m_masker.get(); } diff --git a/WebCore/svg/SVGMaskElement.h b/WebCore/svg/SVGMaskElement.h index b5580bf..4bcf82f 100644 --- a/WebCore/svg/SVGMaskElement.h +++ b/WebCore/svg/SVGMaskElement.h @@ -46,7 +46,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual SVGResource* canvasResource(); @@ -54,20 +54,16 @@ namespace WebCore { std::auto_ptr<ImageBuffer> drawMaskerContent(const FloatRect& targetRect, FloatRect& maskRect) const; protected: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, int, int, MaskUnits, maskUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, int, int, MaskContentUnits, maskContentUnits) - - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGLength, SVGLength, Height, height) - virtual const SVGElement* contextElement() const { return this; } private: + ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::maskUnitsAttrString, int, MaskUnits, maskUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::maskContentUnitsAttrString, int, MaskContentUnits, maskContentUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGMaskElement, SVGNames::maskTagString, SVGNames::heightAttrString, SVGLength, Height, height) + RefPtr<SVGResourceMasker> m_masker; }; diff --git a/WebCore/svg/SVGNumberList.cpp b/WebCore/svg/SVGNumberList.cpp index 7931eca..be1e895 100644 --- a/WebCore/svg/SVGNumberList.cpp +++ b/WebCore/svg/SVGNumberList.cpp @@ -54,6 +54,22 @@ void SVGNumberList::parse(const String& value) } } +String SVGNumberList::valueAsString() const +{ + String result; + + ExceptionCode ec = 0; + for (unsigned int i = 0; i < numberOfItems(); ++i) { + if (i > 0) + result += ", "; + + result += String::number(getItem(i, ec)); + ASSERT(ec == 0); + } + + return result; +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGNumberList.h b/WebCore/svg/SVGNumberList.h index 1fae5fe..6cd43ff 100644 --- a/WebCore/svg/SVGNumberList.h +++ b/WebCore/svg/SVGNumberList.h @@ -25,6 +25,7 @@ #if ENABLE(SVG) #include "SVGList.h" +#include <wtf/PassRefPtr.h> namespace WebCore { @@ -32,10 +33,15 @@ namespace WebCore { class SVGNumberList : public SVGList<float> { public: - SVGNumberList(const QualifiedName&); + static PassRefPtr<SVGNumberList> create(const QualifiedName& attributeName) { return adoptRef(new SVGNumberList(attributeName)); } virtual ~SVGNumberList(); void parse(const String& value); + + String valueAsString() const; + + private: + SVGNumberList(const QualifiedName&); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPaint.cpp b/WebCore/svg/SVGPaint.cpp index bd27a57..45abe69 100644 --- a/WebCore/svg/SVGPaint.cpp +++ b/WebCore/svg/SVGPaint.cpp @@ -27,21 +27,18 @@ namespace WebCore { SVGPaint::SVGPaint() - : SVGColor() - , m_paintType(SVG_PAINTTYPE_UNKNOWN) + : m_paintType(SVG_PAINTTYPE_UNKNOWN) { } SVGPaint::SVGPaint(const String& uri) - : SVGColor() - , m_paintType(SVG_PAINTTYPE_URI_RGBCOLOR) + : m_paintType(SVG_PAINTTYPE_URI_RGBCOLOR) { setUri(uri); } SVGPaint::SVGPaint(SVGPaintType paintType) - : SVGColor() - , m_paintType(paintType) + : m_paintType(paintType) { } diff --git a/WebCore/svg/SVGPaint.h b/WebCore/svg/SVGPaint.h index e434eae..032f715 100644 --- a/WebCore/svg/SVGPaint.h +++ b/WebCore/svg/SVGPaint.h @@ -3,8 +3,6 @@ 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> Copyright (C) 2006 Samuel Weinig (sam.weinig@gmial.com) - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -26,6 +24,7 @@ #if ENABLE(SVG) #include "SVGColor.h" +#include "PlatformString.h" namespace WebCore { @@ -44,12 +43,27 @@ namespace WebCore { SVG_PAINTTYPE_URI = 107 }; - SVGPaint(); - SVGPaint(const String& uri); - SVGPaint(SVGPaintType); - SVGPaint(SVGPaintType, const String& uri, const String& rgbPaint = String(), const String& iccPaint = String()); - SVGPaint(const Color& c); - SVGPaint(const String& uri, const Color& c); + static PassRefPtr<SVGPaint> create() + { + return adoptRef(new SVGPaint); + } + static PassRefPtr<SVGPaint> create(SVGPaintType type) + { + return adoptRef(new SVGPaint(type)); + } + static PassRefPtr<SVGPaint> create(const Color& color) + { + return adoptRef(new SVGPaint(color)); + } + static PassRefPtr<SVGPaint> create(SVGPaintType type, const String& uri) + { + return adoptRef(new SVGPaint(type, uri, String(), String())); + } + static PassRefPtr<SVGPaint> create(const String& uri, const Color& color) + { + return adoptRef(new SVGPaint(uri, color)); + } + virtual ~SVGPaint(); // 'SVGPaint' functions @@ -64,8 +78,16 @@ namespace WebCore { static SVGPaint* defaultFill(); static SVGPaint* defaultStroke(); - virtual bool isSVGPaint() const { return true; } private: + SVGPaint(); + SVGPaint(const String& uri); + SVGPaint(SVGPaintType); + SVGPaint(SVGPaintType, const String& uri, const String& rgbPaint, const String& iccPaint); + SVGPaint(const Color& c); + SVGPaint(const String& uri, const Color& c); + + virtual bool isSVGPaint() const { return true; } + SVGPaintType m_paintType; String m_uri; }; diff --git a/WebCore/svg/SVGParserUtilities.h b/WebCore/svg/SVGParserUtilities.h index 17c8b1b..8d3c9b2 100644 --- a/WebCore/svg/SVGParserUtilities.h +++ b/WebCore/svg/SVGParserUtilities.h @@ -1,4 +1,4 @@ -/* This file is part of the KDE project +/* Copyright (C) 2002, 2003 The Karbon Developers 2006, 2007 Rob Buis <buis@kde.org> @@ -22,10 +22,10 @@ #define SVGParserUtilities_h #if ENABLE(SVG) -#include <PlatformString.h> +#include "ParserUtilities.h" + +namespace WebCore { -namespace WebCore -{ class Path; class SVGPointList; class SVGPathSegList; @@ -35,18 +35,19 @@ namespace WebCore // SVG allows several different whitespace characters: // http://www.w3.org/TR/SVG/paths.html#PathDataBNF - static inline bool isWhitespace(const UChar& c) { + inline bool isWhitespace(const UChar& c) + { return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); } - static inline bool skipOptionalSpaces(const UChar*& ptr, const UChar* end) + inline bool skipOptionalSpaces(const UChar*& ptr, const UChar* end) { while (ptr < end && isWhitespace(*ptr)) ptr++; return ptr < end; } - static inline bool skipOptionalSpacesOrDelimiter(const UChar*& ptr, const UChar *end, UChar delimiter = ',') + inline bool skipOptionalSpacesOrDelimiter(const UChar*& ptr, const UChar* end, UChar delimiter = ',') { if (ptr < end && !isWhitespace(*ptr) && *ptr != delimiter) return false; @@ -59,28 +60,6 @@ namespace WebCore return ptr < end; } - static inline bool skipString(const UChar*& ptr, const UChar* end, const UChar* name, int length) - { - if (end - ptr < length) - return false; - if (memcmp(name, ptr, sizeof(UChar) * length)) - return false; - ptr += length; - return true; - } - - static inline bool skipString(const UChar*& ptr, const UChar* end, const char* str) - { - int length = strlen(str); - if (end - ptr < length) - return false; - for (int i = 0; i < length; ++i) - if (ptr[i] != str[i]) - return false; - ptr += length; - return true; - } - bool pointsListFromSVGData(SVGPointList* pointsList, const String& points); bool pathFromSVGData(Path& path, const String& d); bool pathSegListFromSVGData(SVGPathSegList* pathSegList, const String& d, bool process = false); @@ -89,4 +68,4 @@ namespace WebCore } // namespace WebCore #endif // ENABLE(SVG) -#endif +#endif // SVGParserUtilities_h diff --git a/WebCore/svg/SVGPathElement.cpp b/WebCore/svg/SVGPathElement.cpp index 2f36b40..bdd60e5 100644 --- a/WebCore/svg/SVGPathElement.cpp +++ b/WebCore/svg/SVGPathElement.cpp @@ -48,7 +48,7 @@ SVGPathElement::SVGPathElement(const QualifiedName& tagName, Document* doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_pathLength(0.0f) + , m_pathLength(this, SVGNames::pathLengthAttr, 0.0f) { } @@ -56,8 +56,6 @@ SVGPathElement::~SVGPathElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGPathElement, float, Number, number, PathLength, pathLength, SVGNames::pathLengthAttr, m_pathLength) - float SVGPathElement::getTotalLength() { // FIXME: this may wish to use the pathSegList instead of the pathdata if that's cheaper to build (or cached) @@ -76,99 +74,99 @@ unsigned long SVGPathElement::getPathSegAtLength(float length) return pathSegList()->getPathSegAtLength(length); } -SVGPathSegClosePath* SVGPathElement::createSVGPathSegClosePath() +PassRefPtr<SVGPathSegClosePath> SVGPathElement::createSVGPathSegClosePath() { - return new SVGPathSegClosePath(); + return SVGPathSegClosePath::create(); } -SVGPathSegMovetoAbs* SVGPathElement::createSVGPathSegMovetoAbs(float x, float y) +PassRefPtr<SVGPathSegMovetoAbs> SVGPathElement::createSVGPathSegMovetoAbs(float x, float y) { - return new SVGPathSegMovetoAbs(x, y); + return SVGPathSegMovetoAbs::create(x, y); } -SVGPathSegMovetoRel* SVGPathElement::createSVGPathSegMovetoRel(float x, float y) +PassRefPtr<SVGPathSegMovetoRel> SVGPathElement::createSVGPathSegMovetoRel(float x, float y) { - return new SVGPathSegMovetoRel(x, y); + return SVGPathSegMovetoRel::create(x, y); } -SVGPathSegLinetoAbs* SVGPathElement::createSVGPathSegLinetoAbs(float x, float y) +PassRefPtr<SVGPathSegLinetoAbs> SVGPathElement::createSVGPathSegLinetoAbs(float x, float y) { - return new SVGPathSegLinetoAbs(x, y); + return SVGPathSegLinetoAbs::create(x, y); } -SVGPathSegLinetoRel* SVGPathElement::createSVGPathSegLinetoRel(float x, float y) +PassRefPtr<SVGPathSegLinetoRel> SVGPathElement::createSVGPathSegLinetoRel(float x, float y) { - return new SVGPathSegLinetoRel(x, y); + return SVGPathSegLinetoRel::create(x, y); } -SVGPathSegCurvetoCubicAbs* SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2) +PassRefPtr<SVGPathSegCurvetoCubicAbs> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2) { - return new SVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2); + return SVGPathSegCurvetoCubicAbs::create(x, y, x1, y1, x2, y2); } -SVGPathSegCurvetoCubicRel* SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2) +PassRefPtr<SVGPathSegCurvetoCubicRel> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2) { - return new SVGPathSegCurvetoCubicRel(x, y, x1, y1, x2, y2); + return SVGPathSegCurvetoCubicRel::create(x, y, x1, y1, x2, y2); } -SVGPathSegCurvetoQuadraticAbs* SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1) +PassRefPtr<SVGPathSegCurvetoQuadraticAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1) { - return new SVGPathSegCurvetoQuadraticAbs(x, y, x1, y1); + return SVGPathSegCurvetoQuadraticAbs::create(x, y, x1, y1); } -SVGPathSegCurvetoQuadraticRel* SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1) +PassRefPtr<SVGPathSegCurvetoQuadraticRel> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1) { - return new SVGPathSegCurvetoQuadraticRel(x, y, x1, y1); + return SVGPathSegCurvetoQuadraticRel::create(x, y, x1, y1); } -SVGPathSegArcAbs* SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) +PassRefPtr<SVGPathSegArcAbs> SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) { - return new SVGPathSegArcAbs(x, y, r1, r2, angle, largeArcFlag, sweepFlag); + return SVGPathSegArcAbs::create(x, y, r1, r2, angle, largeArcFlag, sweepFlag); } -SVGPathSegArcRel* SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) +PassRefPtr<SVGPathSegArcRel> SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) { - return new SVGPathSegArcRel(x, y, r1, r2, angle, largeArcFlag, sweepFlag); + return SVGPathSegArcRel::create(x, y, r1, r2, angle, largeArcFlag, sweepFlag); } -SVGPathSegLinetoHorizontalAbs* SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x) +PassRefPtr<SVGPathSegLinetoHorizontalAbs> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x) { - return new SVGPathSegLinetoHorizontalAbs(x); + return SVGPathSegLinetoHorizontalAbs::create(x); } -SVGPathSegLinetoHorizontalRel* SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x) +PassRefPtr<SVGPathSegLinetoHorizontalRel> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x) { - return new SVGPathSegLinetoHorizontalRel(x); + return SVGPathSegLinetoHorizontalRel::create(x); } -SVGPathSegLinetoVerticalAbs* SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y) +PassRefPtr<SVGPathSegLinetoVerticalAbs> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y) { - return new SVGPathSegLinetoVerticalAbs(y); + return SVGPathSegLinetoVerticalAbs::create(y); } -SVGPathSegLinetoVerticalRel* SVGPathElement::createSVGPathSegLinetoVerticalRel(float y) +PassRefPtr<SVGPathSegLinetoVerticalRel> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y) { - return new SVGPathSegLinetoVerticalRel(y); + return SVGPathSegLinetoVerticalRel::create(y); } -SVGPathSegCurvetoCubicSmoothAbs* SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2) +PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2) { - return new SVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2); + return SVGPathSegCurvetoCubicSmoothAbs::create(x, y, x2, y2); } -SVGPathSegCurvetoCubicSmoothRel* SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2) +PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2) { - return new SVGPathSegCurvetoCubicSmoothRel(x, y, x2, y2); + return SVGPathSegCurvetoCubicSmoothRel::create(x, y, x2, y2); } -SVGPathSegCurvetoQuadraticSmoothAbs* SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y) +PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y) { - return new SVGPathSegCurvetoQuadraticSmoothAbs(x, y); + return SVGPathSegCurvetoQuadraticSmoothAbs::create(x, y); } -SVGPathSegCurvetoQuadraticSmoothRel* SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y) +PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y) { - return new SVGPathSegCurvetoQuadraticSmoothRel(x, y); + return SVGPathSegCurvetoQuadraticSmoothRel::create(x, y); } void SVGPathElement::parseMappedAttribute(MappedAttribute* attr) @@ -179,8 +177,8 @@ void SVGPathElement::parseMappedAttribute(MappedAttribute* attr) if (!pathSegListFromSVGData(pathSegList(), attr->value(), true)) document()->accessSVGExtensions()->reportError("Problem parsing d=\"" + attr->value() + "\""); } else if (attr->name() == SVGNames::pathLengthAttr) { - m_pathLength = attr->value().toFloat(); - if (m_pathLength < 0.0f) + setPathLengthBaseValue(attr->value().toFloat()); + if (pathLengthBaseValue() < 0.0f) document()->accessSVGExtensions()->reportError("A negative value for path attribute <pathLength> is not allowed"); } else { if (SVGTests::parseMappedAttribute(attr)) @@ -211,7 +209,7 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName) SVGPathSegList* SVGPathElement::pathSegList() const { if (!m_pathSegList) - m_pathSegList = new SVGPathSegList(SVGNames::dAttr); + m_pathSegList = SVGPathSegList::create(SVGNames::dAttr); return m_pathSegList.get(); } diff --git a/WebCore/svg/SVGPathElement.h b/WebCore/svg/SVGPathElement.h index 76a8ec4..a39e628 100644 --- a/WebCore/svg/SVGPathElement.h +++ b/WebCore/svg/SVGPathElement.h @@ -67,25 +67,25 @@ namespace WebCore { FloatPoint getPointAtLength(float distance); unsigned long getPathSegAtLength(float distance); - static SVGPathSegClosePath* createSVGPathSegClosePath(); - static SVGPathSegMovetoAbs* createSVGPathSegMovetoAbs(float x, float y); - static SVGPathSegMovetoRel* createSVGPathSegMovetoRel(float x, float y); - static SVGPathSegLinetoAbs* createSVGPathSegLinetoAbs(float x, float y); - static SVGPathSegLinetoRel* createSVGPathSegLinetoRel(float x, float y); - static SVGPathSegCurvetoCubicAbs* createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2); - static SVGPathSegCurvetoCubicRel* createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2); - static SVGPathSegCurvetoQuadraticAbs* createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1); - static SVGPathSegCurvetoQuadraticRel* createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1); - static SVGPathSegArcAbs* createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); - static SVGPathSegArcRel* createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); - static SVGPathSegLinetoHorizontalAbs* createSVGPathSegLinetoHorizontalAbs(float x); - static SVGPathSegLinetoHorizontalRel* createSVGPathSegLinetoHorizontalRel(float x); - static SVGPathSegLinetoVerticalAbs* createSVGPathSegLinetoVerticalAbs(float y); - static SVGPathSegLinetoVerticalRel* createSVGPathSegLinetoVerticalRel(float y); - static SVGPathSegCurvetoCubicSmoothAbs* createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2); - static SVGPathSegCurvetoCubicSmoothRel* createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2); - static SVGPathSegCurvetoQuadraticSmoothAbs* createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y); - static SVGPathSegCurvetoQuadraticSmoothRel* createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y); + static PassRefPtr<SVGPathSegClosePath> createSVGPathSegClosePath(); + static PassRefPtr<SVGPathSegMovetoAbs> createSVGPathSegMovetoAbs(float x, float y); + static PassRefPtr<SVGPathSegMovetoRel> createSVGPathSegMovetoRel(float x, float y); + static PassRefPtr<SVGPathSegLinetoAbs> createSVGPathSegLinetoAbs(float x, float y); + static PassRefPtr<SVGPathSegLinetoRel> createSVGPathSegLinetoRel(float x, float y); + static PassRefPtr<SVGPathSegCurvetoCubicAbs> createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2); + static PassRefPtr<SVGPathSegCurvetoCubicRel> createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2); + static PassRefPtr<SVGPathSegCurvetoQuadraticAbs> createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1); + static PassRefPtr<SVGPathSegCurvetoQuadraticRel> createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1); + static PassRefPtr<SVGPathSegArcAbs> createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); + static PassRefPtr<SVGPathSegArcRel> createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); + static PassRefPtr<SVGPathSegLinetoHorizontalAbs> createSVGPathSegLinetoHorizontalAbs(float x); + static PassRefPtr<SVGPathSegLinetoHorizontalRel> createSVGPathSegLinetoHorizontalRel(float x); + static PassRefPtr<SVGPathSegLinetoVerticalAbs> createSVGPathSegLinetoVerticalAbs(float y); + static PassRefPtr<SVGPathSegLinetoVerticalRel> createSVGPathSegLinetoVerticalRel(float y); + static PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2); + static PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2); + static PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y); + static PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y); // Derived from: 'SVGAnimatedPathData' virtual SVGPathSegList* pathSegList() const; @@ -106,9 +106,7 @@ namespace WebCore { private: mutable RefPtr<SVGPathSegList> m_pathSegList; - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGPathElement, float, float, PathLength, pathLength) + ANIMATED_PROPERTY_DECLARATIONS(SVGPathElement, SVGNames::pathTagString, SVGNames::pathLengthAttrString, float, PathLength, pathLength) }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSeg.h b/WebCore/svg/SVGPathSeg.h index 11f714b..84de92f 100644 --- a/WebCore/svg/SVGPathSeg.h +++ b/WebCore/svg/SVGPathSeg.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -29,15 +29,12 @@ #include <wtf/RefCounted.h> -namespace WebCore -{ +namespace WebCore { class SVGPathElement; class SVGStyledElement; - class SVGPathSeg : public RefCounted<SVGPathSeg> - { + class SVGPathSeg : public RefCounted<SVGPathSeg> { public: - SVGPathSeg() { } virtual ~SVGPathSeg() { } enum SVGPathSegType { @@ -68,8 +65,30 @@ namespace WebCore virtual String toString() const { return ""; } const QualifiedName& associatedAttributeName() const { return SVGNames::dAttr; } + + protected: + SVGPathSeg() { } + }; + + class SVGPathSegSingleCoord : public SVGPathSeg { + public: + SVGPathSegSingleCoord(float x, float y) + : SVGPathSeg() , m_x(x) , m_y(y) {} + + void setX(float x) { m_x = x; } + float x() const { return m_x; } + + void setY(float y) { m_y = y; } + float y() const { return m_y; } + + virtual String toString() const { return pathSegTypeAsLetter() + String::format(" %.6lg %.6lg", m_x, m_y); } + + private: + float m_x; + float m_y; }; + } // namespace WebCore #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGPathSegArc.cpp b/WebCore/svg/SVGPathSegArc.cpp index 605f7fc..a54f057 100644 --- a/WebCore/svg/SVGPathSegArc.cpp +++ b/WebCore/svg/SVGPathSegArc.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,182 +25,16 @@ #if ENABLE(SVG) #include "SVGPathSegArc.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegArcAbs::SVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) - : SVGPathSeg() - , m_x(x) - , m_y(y) - , m_r1(r1) - , m_r2(r2) - , m_angle(angle) - , m_largeArcFlag(largeArcFlag) - , m_sweepFlag(sweepFlag) -{ -} - -SVGPathSegArcAbs::~SVGPathSegArcAbs() -{ -} - -void SVGPathSegArcAbs::setX(float x) -{ - m_x = x; -} - -float SVGPathSegArcAbs::x() const -{ - return m_x; -} - -void SVGPathSegArcAbs::setY(float y) -{ - m_y = y; -} - -float SVGPathSegArcAbs::y() const -{ - return m_y; -} - -void SVGPathSegArcAbs::setR1(float r1) -{ - m_r1 = r1; -} - -float SVGPathSegArcAbs::r1() const + : SVGPathSegArc(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - return m_r1; } -void SVGPathSegArcAbs::setR2(float r2) -{ - m_r2 = r2; -} - -float SVGPathSegArcAbs::r2() const -{ - return m_r2; -} - -void SVGPathSegArcAbs::setAngle(float angle) -{ - m_angle = angle; -} - -float SVGPathSegArcAbs::angle() const -{ - return m_angle; -} - -void SVGPathSegArcAbs::setLargeArcFlag(bool largeArcFlag) -{ - m_largeArcFlag = largeArcFlag; -} - -bool SVGPathSegArcAbs::largeArcFlag() const -{ - return m_largeArcFlag; -} - -void SVGPathSegArcAbs::setSweepFlag(bool sweepFlag) -{ - m_sweepFlag = sweepFlag; -} - -bool SVGPathSegArcAbs::sweepFlag() const -{ - return m_sweepFlag; -} - - - SVGPathSegArcRel::SVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) - : SVGPathSeg() - , m_x(x) - , m_y(y) - , m_r1(r1) - , m_r2(r2) - , m_angle(angle) - , m_largeArcFlag(largeArcFlag) - , m_sweepFlag(sweepFlag) -{ -} - -SVGPathSegArcRel::~SVGPathSegArcRel() -{ -} - -void SVGPathSegArcRel::setX(float x) -{ - m_x = x; -} - -float SVGPathSegArcRel::x() const -{ - return m_x; -} - -void SVGPathSegArcRel::setY(float y) -{ - m_y = y; -} - -float SVGPathSegArcRel::y() const -{ - return m_y; -} - -void SVGPathSegArcRel::setR1(float r1) -{ - m_r1 = r1; -} - -float SVGPathSegArcRel::r1() const -{ - return m_r1; -} - -void SVGPathSegArcRel::setR2(float r2) -{ - m_r2 = r2; -} - -float SVGPathSegArcRel::r2() const -{ - return m_r2; -} - -void SVGPathSegArcRel::setAngle(float angle) -{ - m_angle = angle; -} - -float SVGPathSegArcRel::angle() const -{ - return m_angle; -} - -void SVGPathSegArcRel::setLargeArcFlag(bool largeArcFlag) -{ - m_largeArcFlag = largeArcFlag; -} - -bool SVGPathSegArcRel::largeArcFlag() const -{ - return m_largeArcFlag; -} - -void SVGPathSegArcRel::setSweepFlag(bool sweepFlag) -{ - m_sweepFlag = sweepFlag; -} - -bool SVGPathSegArcRel::sweepFlag() const + : SVGPathSegArc(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { - return m_sweepFlag; } } diff --git a/WebCore/svg/SVGPathSegArc.h b/WebCore/svg/SVGPathSegArc.h index 1a2e544..8611e8a 100644 --- a/WebCore/svg/SVGPathSegArc.h +++ b/WebCore/svg/SVGPathSegArc.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -29,35 +29,33 @@ namespace WebCore { - class SVGPathSegArcAbs : public SVGPathSeg { + class SVGPathSegArc : public SVGPathSeg { public: - SVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); - virtual ~SVGPathSegArcAbs(); + SVGPathSegArc(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) + : m_x(x), m_y(y), m_r1(r1), m_r2(r2), m_angle(angle), m_largeArcFlag(largeArcFlag), m_sweepFlag(sweepFlag) {} - virtual unsigned short pathSegType() const { return PATHSEG_ARC_ABS; } - virtual String pathSegTypeAsLetter() const { return "A"; } - virtual String toString() const { return String::format("A %.6lg %.6lg %.6lg %d %d %.6lg %.6lg", m_r1, m_r2, m_angle, m_largeArcFlag, m_sweepFlag, m_x, m_y); } + virtual String toString() const { return pathSegTypeAsLetter() + String::format(" %.6lg %.6lg %.6lg %d %d %.6lg %.6lg", m_r1, m_r2, m_angle, m_largeArcFlag, m_sweepFlag, m_x, m_y); } - void setX(float x); - float x() const; + void setX(float x) { m_x = x; } + float x() const { return m_x; } - void setY(float y); - float y() const; + void setY(float y) { m_y = y; } + float y() const { return m_y; } - void setR1(float r1); - float r1() const; + void setR1(float r1) { m_r1 = r1; } + float r1() const { return m_r1; } - void setR2(float r2); - float r2() const; + void setR2(float r2) { m_r2 = r2; } + float r2() const { return m_r2; } - void setAngle(float angle); - float angle() const; + void setAngle(float angle) { m_angle = angle; } + float angle() const { return m_angle; } - void setLargeArcFlag(bool largeArcFlag); - bool largeArcFlag() const; + void setLargeArcFlag(bool largeArcFlag) { m_largeArcFlag = largeArcFlag; } + bool largeArcFlag() const { return m_largeArcFlag; } - void setSweepFlag(bool sweepFlag); - bool sweepFlag() const; + void setSweepFlag(bool sweepFlag) { m_sweepFlag = sweepFlag; } + bool sweepFlag() const { return m_sweepFlag; } private: float m_x; @@ -70,45 +68,32 @@ namespace WebCore { bool m_sweepFlag : 1; }; - class SVGPathSegArcRel : public SVGPathSeg { + class SVGPathSegArcAbs : public SVGPathSegArc { public: - SVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); - virtual ~SVGPathSegArcRel(); - - virtual unsigned short pathSegType() const { return PATHSEG_ARC_REL; } - virtual String pathSegTypeAsLetter() const { return "a"; } - virtual String toString() const { return String::format("a %.6lg %.6lg %.6lg %d %d %.6lg %.6lg", m_r1, m_r2, m_angle, m_largeArcFlag, m_sweepFlag, m_x, m_y); } + static PassRefPtr<SVGPathSegArcAbs> create(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) + { + return adoptRef(new SVGPathSegArcAbs(x, y, r1, r2, angle, largeArcFlag, sweepFlag)); + } - void setX(float x); - float x() const; - - void setY(float y); - float y() const; - - void setR1(float r1); - float r1() const; - - void setR2(float r2); - float r2() const; + virtual unsigned short pathSegType() const { return PATHSEG_ARC_ABS; } + virtual String pathSegTypeAsLetter() const { return "A"; } - void setAngle(float angle); - float angle() const; + private: + SVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); + }; - void setLargeArcFlag(bool largeArcFlag); - bool largeArcFlag() const; + class SVGPathSegArcRel : public SVGPathSegArc { + public: + static PassRefPtr<SVGPathSegArcRel> create(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) + { + return adoptRef(new SVGPathSegArcRel(x, y, r1, r2, angle, largeArcFlag, sweepFlag)); + } - void setSweepFlag(bool sweepFlag); - bool sweepFlag() const; + virtual unsigned short pathSegType() const { return PATHSEG_ARC_REL; } + virtual String pathSegTypeAsLetter() const { return "a"; } private: - float m_x; - float m_y; - float m_r1; - float m_r2; - float m_angle; - - bool m_largeArcFlag : 1; - bool m_sweepFlag : 1; + SVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegClosePath.h b/WebCore/svg/SVGPathSegClosePath.h index ce573e8..eb74dea 100644 --- a/WebCore/svg/SVGPathSegClosePath.h +++ b/WebCore/svg/SVGPathSegClosePath.h @@ -32,12 +32,15 @@ namespace WebCore class SVGPathSegClosePath : public SVGPathSeg { public: - SVGPathSegClosePath(); + static PassRefPtr<SVGPathSegClosePath> create() { return adoptRef(new SVGPathSegClosePath); } virtual ~SVGPathSegClosePath(); virtual unsigned short pathSegType() const { return PATHSEG_CLOSEPATH; } virtual String pathSegTypeAsLetter() const { return "Z"; } virtual String toString() const { return "Z"; } + + private: + SVGPathSegClosePath(); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegCurvetoCubic.cpp b/WebCore/svg/SVGPathSegCurvetoCubic.cpp index 304d9c27..14359de 100644 --- a/WebCore/svg/SVGPathSegCurvetoCubic.cpp +++ b/WebCore/svg/SVGPathSegCurvetoCubic.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,161 +25,16 @@ #if ENABLE(SVG) #include "SVGPathSegCurvetoCubic.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegCurvetoCubicAbs::SVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2) - : SVGPathSeg() - , m_x(x) - , m_y(y) - , m_x1(x1) - , m_y1(y1) - , m_x2(x2) - , m_y2(y2) -{ -} - -SVGPathSegCurvetoCubicAbs::~SVGPathSegCurvetoCubicAbs() + : SVGPathSegCurvetoCubic(x, y, x1, y1, x2, y2) { } -void SVGPathSegCurvetoCubicAbs::setX(float x) -{ - m_x = x; -} - -float SVGPathSegCurvetoCubicAbs::x() const -{ - return m_x; -} - -void SVGPathSegCurvetoCubicAbs::setY(float y) -{ - m_y = y; -} - -float SVGPathSegCurvetoCubicAbs::y() const -{ - return m_y; -} - -void SVGPathSegCurvetoCubicAbs::setX1(float x1) -{ - m_x1 = x1; -} - -float SVGPathSegCurvetoCubicAbs::x1() const -{ - return m_x1; -} - -void SVGPathSegCurvetoCubicAbs::setY1(float y1) -{ - m_y1 = y1; -} - -float SVGPathSegCurvetoCubicAbs::y1() const -{ - return m_y1; -} - -void SVGPathSegCurvetoCubicAbs::setX2(float x2) -{ - m_x2 = x2; -} - -float SVGPathSegCurvetoCubicAbs::x2() const -{ - return m_x2; -} - -void SVGPathSegCurvetoCubicAbs::setY2(float y2) -{ - m_y2 = y2; -} - -float SVGPathSegCurvetoCubicAbs::y2() const -{ - return m_y2; -} - - - - SVGPathSegCurvetoCubicRel::SVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2) - : SVGPathSeg() - , m_x(x) - , m_y(y) - , m_x1(x1) - , m_y1(y1) - , m_x2(x2) - , m_y2(y2) -{ -} - -SVGPathSegCurvetoCubicRel::~SVGPathSegCurvetoCubicRel() -{ -} - -void SVGPathSegCurvetoCubicRel::setX(float x) -{ - m_x = x; -} - -float SVGPathSegCurvetoCubicRel::x() const -{ - return m_x; -} - -void SVGPathSegCurvetoCubicRel::setY(float y) -{ - m_y = y; -} - -float SVGPathSegCurvetoCubicRel::y() const -{ - return m_y; -} - -void SVGPathSegCurvetoCubicRel::setX1(float x1) -{ - m_x1 = x1; -} - -float SVGPathSegCurvetoCubicRel::x1() const -{ - return m_x1; -} - -void SVGPathSegCurvetoCubicRel::setY1(float y1) -{ - m_y1 = y1; -} - -float SVGPathSegCurvetoCubicRel::y1() const -{ - return m_y1; -} - -void SVGPathSegCurvetoCubicRel::setX2(float x2) -{ - m_x2 = x2; -} - -float SVGPathSegCurvetoCubicRel::x2() const -{ - return m_x2; -} - -void SVGPathSegCurvetoCubicRel::setY2(float y2) -{ - m_y2 = y2; -} - -float SVGPathSegCurvetoCubicRel::y2() const + : SVGPathSegCurvetoCubic(x, y, x1, y1, x2, y2) { - return m_y2; } } diff --git a/WebCore/svg/SVGPathSegCurvetoCubic.h b/WebCore/svg/SVGPathSegCurvetoCubic.h index fdb1667..68e3311 100644 --- a/WebCore/svg/SVGPathSegCurvetoCubic.h +++ b/WebCore/svg/SVGPathSegCurvetoCubic.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -28,32 +28,30 @@ #include "SVGPathSeg.h" namespace WebCore { - class SVGPathSegCurvetoCubicAbs : public SVGPathSeg { + + class SVGPathSegCurvetoCubic : public SVGPathSeg { public: - SVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2); - virtual ~SVGPathSegCurvetoCubicAbs(); + SVGPathSegCurvetoCubic(float x, float y, float x1, float y1, float x2, float y2) : SVGPathSeg() , m_x(x) , m_y(y) , m_x1(x1) , m_y1(y1) , m_x2(x2) , m_y2(y2) {} - virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_ABS; } - virtual String pathSegTypeAsLetter() const { return "C"; } - virtual String toString() const { return String::format("C %.6lg %.6lg %.6lg %.6lg %.6lg %.6lg", m_x1, m_y1, m_x2, m_y2, m_x, m_y); } + virtual String toString() const { return pathSegTypeAsLetter() + String::format(" %.6lg %.6lg %.6lg %.6lg %.6lg %.6lg", m_x1, m_y1, m_x2, m_y2, m_x, m_y); } - void setX(float); - float x() const; + void setX(float x) { m_x = x; } + float x() const { return m_x; } - void setY(float); - float y() const; + void setY(float y) { m_y = y; } + float y() const { return m_y; } - void setX1(float); - float x1() const; + void setX1(float x1) { m_x1 = x1; } + float x1() const { return m_x1; } - void setY1(float); - float y1() const; + void setY1(float y1) { m_y1 = y1; } + float y1() const { return m_y1; } - void setX2(float); - float x2() const; + void setX2(float x2) { m_x2 = x2; } + float x2() const { return m_x2; } - void setY2(float); - float y2() const; + void setY2(float y2) { m_y2 = y2; } + float y2() const { return m_y2; } private: float m_x; @@ -64,40 +62,32 @@ namespace WebCore { float m_y2; }; - class SVGPathSegCurvetoCubicRel : public SVGPathSeg { + class SVGPathSegCurvetoCubicAbs : public SVGPathSegCurvetoCubic { public: - SVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2); - virtual ~SVGPathSegCurvetoCubicRel(); + static PassRefPtr<SVGPathSegCurvetoCubicAbs> create(float x, float y, float x1, float y1, float x2, float y2) + { + return adoptRef(new SVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2)); + } - virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_REL; } - virtual String pathSegTypeAsLetter() const { return "c"; } - virtual String toString() const { return String::format("c %.6lg %.6lg %.6lg %.6lg %.6lg %.6lg", m_x1, m_y1, m_x2, m_y2, m_x, m_y); } - - void setX(float); - float x() const; - - void setY(float); - float y() const; - - void setX1(float); - float x1() const; + virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_ABS; } + virtual String pathSegTypeAsLetter() const { return "C"; } - void setY1(float); - float y1() const; + private: + SVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2); + }; - void setX2(float); - float x2() const; + class SVGPathSegCurvetoCubicRel : public SVGPathSegCurvetoCubic { + public: + static PassRefPtr<SVGPathSegCurvetoCubicRel> create(float x, float y, float x1, float y1, float x2, float y2) + { + return adoptRef(new SVGPathSegCurvetoCubicRel(x, y, x1, y1, x2, y2)); + } - void setY2(float); - float y2() const; + virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_REL; } + virtual String pathSegTypeAsLetter() const { return "c"; } private: - float m_x; - float m_y; - float m_x1; - float m_y1; - float m_x2; - float m_y2; + SVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegCurvetoCubicSmooth.cpp b/WebCore/svg/SVGPathSegCurvetoCubicSmooth.cpp index 3a7ecef..26babdb 100644 --- a/WebCore/svg/SVGPathSegCurvetoCubicSmooth.cpp +++ b/WebCore/svg/SVGPathSegCurvetoCubicSmooth.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -24,116 +24,16 @@ #if ENABLE(SVG) #include "SVGPathSegCurvetoCubicSmooth.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegCurvetoCubicSmoothAbs::SVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2) - : SVGPathSeg() - , m_x(x) - , m_y(y) - , m_x2(x2) - , m_y2(y2) -{ -} - -SVGPathSegCurvetoCubicSmoothAbs::~SVGPathSegCurvetoCubicSmoothAbs() + : SVGPathSegCurvetoCubicSmooth(x, y, x2, y2) { } -void SVGPathSegCurvetoCubicSmoothAbs::setX(float x) -{ - m_x = x; -} - -float SVGPathSegCurvetoCubicSmoothAbs::x() const -{ - return m_x; -} - -void SVGPathSegCurvetoCubicSmoothAbs::setY(float y) -{ - m_y = y; -} - -float SVGPathSegCurvetoCubicSmoothAbs::y() const -{ - return m_y; -} - -void SVGPathSegCurvetoCubicSmoothAbs::setX2(float x2) -{ - m_x2 = x2; -} - -float SVGPathSegCurvetoCubicSmoothAbs::x2() const -{ - return m_x2; -} - -void SVGPathSegCurvetoCubicSmoothAbs::setY2(float y2) -{ - m_y2 = y2; -} - -float SVGPathSegCurvetoCubicSmoothAbs::y2() const -{ - return m_y2; -} - - - SVGPathSegCurvetoCubicSmoothRel::SVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2) - : SVGPathSeg() - , m_x(x) - , m_y(y) - , m_x2(x2) - , m_y2(y2) -{ -} - -SVGPathSegCurvetoCubicSmoothRel::~SVGPathSegCurvetoCubicSmoothRel() -{ -} - -void SVGPathSegCurvetoCubicSmoothRel::setX(float x) -{ - m_x = x; -} - -float SVGPathSegCurvetoCubicSmoothRel::x() const -{ - return m_x; -} - -void SVGPathSegCurvetoCubicSmoothRel::setY(float y) -{ - m_y = y; -} - -float SVGPathSegCurvetoCubicSmoothRel::y() const -{ - return m_y; -} - -void SVGPathSegCurvetoCubicSmoothRel::setX2(float x2) -{ - m_x2 = x2; -} - -float SVGPathSegCurvetoCubicSmoothRel::x2() const -{ - return m_x2; -} - -void SVGPathSegCurvetoCubicSmoothRel::setY2(float y2) -{ - m_y2 = y2; -} - -float SVGPathSegCurvetoCubicSmoothRel::y2() const + : SVGPathSegCurvetoCubicSmooth(x, y, x2, y2) { - return m_y2; } } diff --git a/WebCore/svg/SVGPathSegCurvetoCubicSmooth.h b/WebCore/svg/SVGPathSegCurvetoCubicSmooth.h index 4c25181..8b8998c 100644 --- a/WebCore/svg/SVGPathSegCurvetoCubicSmooth.h +++ b/WebCore/svg/SVGPathSegCurvetoCubicSmooth.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -29,26 +29,24 @@ namespace WebCore { - class SVGPathSegCurvetoCubicSmoothAbs : public SVGPathSeg { + class SVGPathSegCurvetoCubicSmooth : public SVGPathSeg { public: - SVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2); - virtual ~SVGPathSegCurvetoCubicSmoothAbs(); + SVGPathSegCurvetoCubicSmooth(float x, float y, float x2, float y2) + : SVGPathSeg(), m_x(x), m_y(y), m_x2(x2), m_y2(y) {} - virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; } - virtual String pathSegTypeAsLetter() const { return "S"; } - virtual String toString() const { return String::format("S %.6lg %.6lg %.6lg %.6lg", m_x2, m_y2, m_x, m_y); } + virtual String toString() const { return pathSegTypeAsLetter() + String::format(" %.6lg %.6lg %.6lg %.6lg", m_x2, m_y2, m_x, m_y); } - void setX(float); - float x() const; + void setX(float x) { m_x = x; } + float x() const { return m_x; } - void setY(float); - float y() const; + void setY(float y) { m_y = y; } + float y() const { return m_y; } - void setX2(float); - float x2() const; + void setX2(float x2) { m_x2 = x2; } + float x2() const { return m_x2; } - void setY2(float); - float y2() const; + void setY2(float y2) { m_y2 = y2; } + float y2() const { return m_y2; } private: float m_x; @@ -57,32 +55,26 @@ namespace WebCore { float m_y2; }; - class SVGPathSegCurvetoCubicSmoothRel : public SVGPathSeg { + class SVGPathSegCurvetoCubicSmoothAbs : public SVGPathSegCurvetoCubicSmooth { public: - SVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2); - virtual ~SVGPathSegCurvetoCubicSmoothRel(); - - virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_SMOOTH_REL; } - virtual String pathSegTypeAsLetter() const { return "s"; } - virtual String toString() const { return String::format("s %.6lg %.6lg %.6lg %.6lg", m_x2, m_y2, m_x, m_y); } + static PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> create(float x, float y, float x2, float y2) { return adoptRef(new SVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2)); } - void setX(float); - float x() const; + virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; } + virtual String pathSegTypeAsLetter() const { return "S"; } - void setY(float); - float y() const; + private: + SVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2); + }; - void setX2(float); - float x2() const; + class SVGPathSegCurvetoCubicSmoothRel : public SVGPathSegCurvetoCubicSmooth { + public: + static PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> create(float x, float y, float x2, float y2) { return adoptRef(new SVGPathSegCurvetoCubicSmoothRel(x, y, x2, y2)); } - void setY2(float); - float y2() const; + virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_SMOOTH_REL; } + virtual String pathSegTypeAsLetter() const { return "s"; } private: - float m_x; - float m_y; - float m_x2; - float m_y2; + SVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegCurvetoQuadratic.cpp b/WebCore/svg/SVGPathSegCurvetoQuadratic.cpp index 9402f02..8594fde 100644 --- a/WebCore/svg/SVGPathSegCurvetoQuadratic.cpp +++ b/WebCore/svg/SVGPathSegCurvetoQuadratic.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,117 +25,16 @@ #if ENABLE(SVG) #include "SVGPathSegCurvetoQuadratic.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegCurvetoQuadraticAbs::SVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1) - : SVGPathSeg() - , m_x(x) - , m_y(y) - , m_x1(x1) - , m_y1(y1) -{ -} - -SVGPathSegCurvetoQuadraticAbs::~SVGPathSegCurvetoQuadraticAbs() + : SVGPathSegCurvetoQuadratic(x, y, x1, y1) { } -void SVGPathSegCurvetoQuadraticAbs::setX(float x) -{ - m_x = x; -} - -float SVGPathSegCurvetoQuadraticAbs::x() const -{ - return m_x; -} - -void SVGPathSegCurvetoQuadraticAbs::setY(float y) -{ - m_y = y; -} - -float SVGPathSegCurvetoQuadraticAbs::y() const -{ - return m_y; -} - -void SVGPathSegCurvetoQuadraticAbs::setX1(float x1) -{ - m_x1 = x1; -} - -float SVGPathSegCurvetoQuadraticAbs::x1() const -{ - return m_x1; -} - -void SVGPathSegCurvetoQuadraticAbs::setY1(float y1) -{ - m_y1 = y1; -} - -float SVGPathSegCurvetoQuadraticAbs::y1() const -{ - return m_y1; -} - - - - SVGPathSegCurvetoQuadraticRel::SVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1) - : SVGPathSeg() - , m_x(x) - , m_y(y) - , m_x1(x1) - , m_y1(y1) -{ -} - -SVGPathSegCurvetoQuadraticRel::~SVGPathSegCurvetoQuadraticRel() -{ -} - -void SVGPathSegCurvetoQuadraticRel::setX(float x) -{ - m_x = x; -} - -float SVGPathSegCurvetoQuadraticRel::x() const -{ - return m_x; -} - -void SVGPathSegCurvetoQuadraticRel::setY(float y) -{ - m_y = y; -} - -float SVGPathSegCurvetoQuadraticRel::y() const -{ - return m_y; -} - -void SVGPathSegCurvetoQuadraticRel::setX1(float x1) -{ - m_x1 = x1; -} - -float SVGPathSegCurvetoQuadraticRel::x1() const -{ - return m_x1; -} - -void SVGPathSegCurvetoQuadraticRel::setY1(float y1) -{ - m_y1 = y1; -} - -float SVGPathSegCurvetoQuadraticRel::y1() const + : SVGPathSegCurvetoQuadratic(x, y, x1, y1) { - return m_y1; } } diff --git a/WebCore/svg/SVGPathSegCurvetoQuadratic.h b/WebCore/svg/SVGPathSegCurvetoQuadratic.h index 2d133f2..1625f13 100644 --- a/WebCore/svg/SVGPathSegCurvetoQuadratic.h +++ b/WebCore/svg/SVGPathSegCurvetoQuadratic.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -29,26 +29,24 @@ namespace WebCore { - class SVGPathSegCurvetoQuadraticAbs : public SVGPathSeg { + class SVGPathSegCurvetoQuadratic : public SVGPathSeg { public: - SVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1); - virtual ~SVGPathSegCurvetoQuadraticAbs(); + SVGPathSegCurvetoQuadratic(float x, float y, float x1, float y1) + : SVGPathSeg(), m_x(x), m_y(y), m_x1(x1), m_y1(y1) {} - virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_ABS; } - virtual String pathSegTypeAsLetter() const { return "Q"; } - virtual String toString() const { return String::format("Q %.6lg %.6lg %.6lg %.6lg", m_x1, m_y1, m_x, m_y); } + virtual String toString() const { return pathSegTypeAsLetter() + String::format(" %.6lg %.6lg %.6lg %.6lg", m_x1, m_y1, m_x, m_y); } - void setX(float); - float x() const; + void setX(float x) { m_x = x; } + float x() const { return m_x; } - void setY(float); - float y() const; + void setY(float y) { m_y = y; } + float y() const { return m_y; } - void setX1(float); - float x1() const; + void setX1(float x1) { m_x1 = x1; } + float x1() const { return m_x1; } - void setY1(float); - float y1() const; + void setY1(float y1) { m_y1 = y1; } + float y1() const { return m_y1; } private: float m_x; @@ -57,32 +55,26 @@ namespace WebCore { float m_y1; }; - class SVGPathSegCurvetoQuadraticRel : public SVGPathSeg { + class SVGPathSegCurvetoQuadraticAbs : public SVGPathSegCurvetoQuadratic { public: - SVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1); - virtual ~SVGPathSegCurvetoQuadraticRel(); - - virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_REL; } - virtual String pathSegTypeAsLetter() const { return "q"; } - virtual String toString() const { return String::format("q %.6lg %.6lg %.6lg %.6lg", m_x1, m_y1, m_x, m_y); } + static PassRefPtr<SVGPathSegCurvetoQuadraticAbs> create(float x, float y, float x1, float y1) { return adoptRef(new SVGPathSegCurvetoQuadraticAbs(x, y, x1, y1)); } - void setX(float); - float x() const; + virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_ABS; } + virtual String pathSegTypeAsLetter() const { return "Q"; } - void setY(float); - float y() const; + private: + SVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1); + }; - void setX1(float); - float x1() const; + class SVGPathSegCurvetoQuadraticRel : public SVGPathSegCurvetoQuadratic { + public: + static PassRefPtr<SVGPathSegCurvetoQuadraticRel> create(float x, float y, float x1, float y1) { return adoptRef(new SVGPathSegCurvetoQuadraticRel(x, y, x1, y1)); } - void setY1(float); - float y1() const; + virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_REL; } + virtual String pathSegTypeAsLetter() const { return "q"; } private: - float m_x; - float m_y; - float m_x1; - float m_y1; + SVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegCurvetoQuadraticSmooth.cpp b/WebCore/svg/SVGPathSegCurvetoQuadraticSmooth.cpp index 7026e1d..3377709 100644 --- a/WebCore/svg/SVGPathSegCurvetoQuadraticSmooth.cpp +++ b/WebCore/svg/SVGPathSegCurvetoQuadraticSmooth.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,72 +25,16 @@ #if ENABLE(SVG) #include "SVGPathSegCurvetoQuadraticSmooth.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegCurvetoQuadraticSmoothAbs::SVGPathSegCurvetoQuadraticSmoothAbs(float x, float y) - : SVGPathSeg() - , m_x(x) - , m_y(y) + : SVGPathSegSingleCoord(x, y) { } -SVGPathSegCurvetoQuadraticSmoothAbs::~SVGPathSegCurvetoQuadraticSmoothAbs() -{ -} - -void SVGPathSegCurvetoQuadraticSmoothAbs::setX(float x) -{ - m_x = x; -} - -float SVGPathSegCurvetoQuadraticSmoothAbs::x() const -{ - return m_x; -} - -void SVGPathSegCurvetoQuadraticSmoothAbs::setY(float y) -{ - m_y = y; -} - -float SVGPathSegCurvetoQuadraticSmoothAbs::y() const -{ - return m_y; -} - - - SVGPathSegCurvetoQuadraticSmoothRel::SVGPathSegCurvetoQuadraticSmoothRel(float x, float y) - : SVGPathSeg() - , m_x(x) - , m_y(y) -{ -} - -SVGPathSegCurvetoQuadraticSmoothRel::~SVGPathSegCurvetoQuadraticSmoothRel() -{ -} - -void SVGPathSegCurvetoQuadraticSmoothRel::setX(float x) -{ - m_x = x; -} - -float SVGPathSegCurvetoQuadraticSmoothRel::x() const -{ - return m_x; -} - -void SVGPathSegCurvetoQuadraticSmoothRel::setY(float y) -{ - m_y = y; -} - -float SVGPathSegCurvetoQuadraticSmoothRel::y() const + : SVGPathSegSingleCoord(x, y) { - return m_y; } } diff --git a/WebCore/svg/SVGPathSegCurvetoQuadraticSmooth.h b/WebCore/svg/SVGPathSegCurvetoQuadraticSmooth.h index 2490e33..3017689 100644 --- a/WebCore/svg/SVGPathSegCurvetoQuadraticSmooth.h +++ b/WebCore/svg/SVGPathSegCurvetoQuadraticSmooth.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -29,44 +29,26 @@ namespace WebCore { - class SVGPathSegCurvetoQuadraticSmoothAbs : public SVGPathSeg { + class SVGPathSegCurvetoQuadraticSmoothAbs : public SVGPathSegSingleCoord { public: - SVGPathSegCurvetoQuadraticSmoothAbs(float x, float y); - virtual ~SVGPathSegCurvetoQuadraticSmoothAbs(); + static PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> create(float x, float y) { return adoptRef(new SVGPathSegCurvetoQuadraticSmoothAbs(x, y)); } virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; } virtual String pathSegTypeAsLetter() const { return "T"; } - virtual String toString() const { return String::format("T %.6lg %.6lg", m_x, m_y); } - - void setX(float); - float x() const; - - void setY(float); - float y() const; private: - float m_x; - float m_y; + SVGPathSegCurvetoQuadraticSmoothAbs(float x, float y); }; - class SVGPathSegCurvetoQuadraticSmoothRel : public SVGPathSeg { + class SVGPathSegCurvetoQuadraticSmoothRel : public SVGPathSegSingleCoord { public: - SVGPathSegCurvetoQuadraticSmoothRel(float x, float y); - virtual ~SVGPathSegCurvetoQuadraticSmoothRel(); + static PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> create(float x, float y) { return adoptRef(new SVGPathSegCurvetoQuadraticSmoothRel(x, y)); } virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; } virtual String pathSegTypeAsLetter() const { return "t"; } - virtual String toString() const { return String::format("t %.6lg %.6lg", m_x, m_y); } - - void setX(float); - float x() const; - - void setY(float); - float y() const; private: - float m_x; - float m_y; + SVGPathSegCurvetoQuadraticSmoothRel(float x, float y); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegLineto.cpp b/WebCore/svg/SVGPathSegLineto.cpp index bf94119..ac3a8bd 100644 --- a/WebCore/svg/SVGPathSegLineto.cpp +++ b/WebCore/svg/SVGPathSegLineto.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> + 2004, 2005, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,70 +25,16 @@ #if ENABLE(SVG) #include "SVGPathSegLineto.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegLinetoAbs::SVGPathSegLinetoAbs(float x, float y) - : SVGPathSeg() - , m_x(x) - , m_y(y) -{ -} - -SVGPathSegLinetoAbs::~SVGPathSegLinetoAbs() -{ -} - -void SVGPathSegLinetoAbs::setX(float x) -{ - m_x = x; -} - -float SVGPathSegLinetoAbs::x() const -{ - return m_x; -} - -void SVGPathSegLinetoAbs::setY(float y) -{ - m_y = y; -} - -float SVGPathSegLinetoAbs::y() const + : SVGPathSegSingleCoord(x, y) { - return m_y; } SVGPathSegLinetoRel::SVGPathSegLinetoRel(float x, float y) - : SVGPathSeg() - , m_x(x) - , m_y(y) -{ -} - -SVGPathSegLinetoRel::~SVGPathSegLinetoRel() -{ -} - -void SVGPathSegLinetoRel::setX(float x) -{ - m_x = x; -} - -float SVGPathSegLinetoRel::x() const -{ - return m_x; -} - -void SVGPathSegLinetoRel::setY(float y) -{ - m_y = y; -} - -float SVGPathSegLinetoRel::y() const + : SVGPathSegSingleCoord(x, y) { - return m_y; } } diff --git a/WebCore/svg/SVGPathSegLineto.h b/WebCore/svg/SVGPathSegLineto.h index b2f30fc..1818ad2 100644 --- a/WebCore/svg/SVGPathSegLineto.h +++ b/WebCore/svg/SVGPathSegLineto.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -28,44 +28,27 @@ #include "SVGPathSeg.h" namespace WebCore { - class SVGPathSegLinetoAbs : public SVGPathSeg { + class SVGPathSegLinetoAbs : public SVGPathSegSingleCoord { public: - SVGPathSegLinetoAbs(float x, float y); - virtual ~SVGPathSegLinetoAbs(); + static PassRefPtr<SVGPathSegLinetoAbs> create(float x, float y) { return adoptRef(new SVGPathSegLinetoAbs(x, y)); } virtual unsigned short pathSegType() const { return PATHSEG_LINETO_ABS; } virtual String pathSegTypeAsLetter() const { return "L"; } - virtual String toString() const { return String::format("L %.6lg %.6lg", m_x, m_y); } - - void setX(float); - float x() const; - - void setY(float); - float y() const; private: - float m_x; - float m_y; + SVGPathSegLinetoAbs(float x, float y); }; - class SVGPathSegLinetoRel : public SVGPathSeg { + class SVGPathSegLinetoRel : public SVGPathSegSingleCoord { public: - SVGPathSegLinetoRel(float x, float y); - virtual ~SVGPathSegLinetoRel(); + static PassRefPtr<SVGPathSegLinetoRel> create(float x, float y) { return adoptRef(new SVGPathSegLinetoRel(x, y)); } + virtual unsigned short pathSegType() const { return PATHSEG_LINETO_REL; } virtual String pathSegTypeAsLetter() const { return "l"; } - virtual String toString() const { return String::format("l %.6lg %.6lg", m_x, m_y); } - - void setX(float); - float x() const; - - void setY(float); - float y() const; private: - float m_x; - float m_y; + SVGPathSegLinetoRel(float x, float y); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegLinetoHorizontal.cpp b/WebCore/svg/SVGPathSegLinetoHorizontal.cpp index 5629695..3de2cc7 100644 --- a/WebCore/svg/SVGPathSegLinetoHorizontal.cpp +++ b/WebCore/svg/SVGPathSegLinetoHorizontal.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> + 2004, 2005, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,50 +25,16 @@ #if ENABLE(SVG) #include "SVGPathSegLinetoHorizontal.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegLinetoHorizontalAbs::SVGPathSegLinetoHorizontalAbs(float x) - : SVGPathSeg() - , m_x(x) -{ -} - -SVGPathSegLinetoHorizontalAbs::~SVGPathSegLinetoHorizontalAbs() + : SVGPathSegLinetoHorizontal(x) { } -void SVGPathSegLinetoHorizontalAbs::setX(float x) -{ - m_x = x; -} - -float SVGPathSegLinetoHorizontalAbs::x() const -{ - return m_x; -} - - - SVGPathSegLinetoHorizontalRel::SVGPathSegLinetoHorizontalRel(float x) - : SVGPathSeg() - , m_x(x) -{ -} - -SVGPathSegLinetoHorizontalRel::~SVGPathSegLinetoHorizontalRel() -{ -} - -void SVGPathSegLinetoHorizontalRel::setX(float x) -{ - m_x = x; -} - -float SVGPathSegLinetoHorizontalRel::x() const + : SVGPathSegLinetoHorizontal(x) { - return m_x; } } diff --git a/WebCore/svg/SVGPathSegLinetoHorizontal.h b/WebCore/svg/SVGPathSegLinetoHorizontal.h index 717774c..84965a5 100644 --- a/WebCore/svg/SVGPathSegLinetoHorizontal.h +++ b/WebCore/svg/SVGPathSegLinetoHorizontal.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -29,36 +29,39 @@ namespace WebCore { - class SVGPathSegLinetoHorizontalAbs : public SVGPathSeg { + class SVGPathSegLinetoHorizontal : public SVGPathSeg { public: - SVGPathSegLinetoHorizontalAbs(float x); - virtual ~SVGPathSegLinetoHorizontalAbs(); + SVGPathSegLinetoHorizontal(float x) : SVGPathSeg(), m_x(x) {} - virtual unsigned short pathSegType() const { return PATHSEG_LINETO_HORIZONTAL_ABS; } - virtual String pathSegTypeAsLetter() const { return "H"; } - virtual String toString() const { return String::format("H %.6lg", m_x); } + virtual String toString() const { return pathSegTypeAsLetter() + String::format(" %.6lg", m_x); } - void setX(float); - float x() const; + void setX(float x) { m_x = x; } + float x() const { return m_x; } private: float m_x; }; - class SVGPathSegLinetoHorizontalRel : public SVGPathSeg { + class SVGPathSegLinetoHorizontalAbs : public SVGPathSegLinetoHorizontal { public: - SVGPathSegLinetoHorizontalRel(float x); - virtual ~SVGPathSegLinetoHorizontalRel(); + static PassRefPtr<SVGPathSegLinetoHorizontalAbs> create(float x) { return adoptRef(new SVGPathSegLinetoHorizontalAbs(x)); } + + virtual unsigned short pathSegType() const { return PATHSEG_LINETO_HORIZONTAL_ABS; } + virtual String pathSegTypeAsLetter() const { return "H"; } + + private: + SVGPathSegLinetoHorizontalAbs(float x); + }; + + class SVGPathSegLinetoHorizontalRel : public SVGPathSegLinetoHorizontal { + public: + static PassRefPtr<SVGPathSegLinetoHorizontalRel> create(float x) { return adoptRef(new SVGPathSegLinetoHorizontalRel(x)); } virtual unsigned short pathSegType() const { return PATHSEG_LINETO_HORIZONTAL_REL; } virtual String pathSegTypeAsLetter() const { return "h"; } - virtual String toString() const { return String::format("h %.6lg", m_x); } - - void setX(float); - float x() const; private: - float m_x; + SVGPathSegLinetoHorizontalRel(float x); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegLinetoVertical.cpp b/WebCore/svg/SVGPathSegLinetoVertical.cpp index 6f32c04..4f667ee 100644 --- a/WebCore/svg/SVGPathSegLinetoVertical.cpp +++ b/WebCore/svg/SVGPathSegLinetoVertical.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,53 +25,17 @@ #if ENABLE(SVG) #include "SVGPathSegLinetoVertical.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegLinetoVerticalAbs::SVGPathSegLinetoVerticalAbs(float y) - : SVGPathSeg() - , m_y(y) -{ -} - -SVGPathSegLinetoVerticalAbs::~SVGPathSegLinetoVerticalAbs() -{ -} - -void SVGPathSegLinetoVerticalAbs::setY(float y) -{ - m_y = y; -} - -float SVGPathSegLinetoVerticalAbs::y() const + : SVGPathSegLinetoVertical(y) { - return m_y; } - - - SVGPathSegLinetoVerticalRel::SVGPathSegLinetoVerticalRel(float y) - : SVGPathSeg() - , m_y(y) -{ -} - -SVGPathSegLinetoVerticalRel::~SVGPathSegLinetoVerticalRel() + : SVGPathSegLinetoVertical(y) { } - -void SVGPathSegLinetoVerticalRel::setY(float y) -{ - m_y = y; -} - -float SVGPathSegLinetoVerticalRel::y() const -{ - return m_y; -} - } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGPathSegLinetoVertical.h b/WebCore/svg/SVGPathSegLinetoVertical.h index 24a448a..8d4ba29 100644 --- a/WebCore/svg/SVGPathSegLinetoVertical.h +++ b/WebCore/svg/SVGPathSegLinetoVertical.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -29,36 +29,39 @@ namespace WebCore { - class SVGPathSegLinetoVerticalAbs : public SVGPathSeg { + class SVGPathSegLinetoVertical : public SVGPathSeg { public: - SVGPathSegLinetoVerticalAbs(float y); - virtual~SVGPathSegLinetoVerticalAbs(); + SVGPathSegLinetoVertical(float y) : SVGPathSeg(), m_y(y) {} - virtual unsigned short pathSegType() const { return PATHSEG_LINETO_VERTICAL_ABS; } - virtual String pathSegTypeAsLetter() const { return "V"; } - virtual String toString() const { return String::format("V %.6lg", m_y); } + virtual String toString() const { return pathSegTypeAsLetter() + String::format(" %.6lg", m_y); } - void setY(float); - float y() const; + void setY(float y) { m_y = y; } + float y() const { return m_y; } private: float m_y; }; - class SVGPathSegLinetoVerticalRel : public SVGPathSeg { + class SVGPathSegLinetoVerticalAbs : public SVGPathSegLinetoVertical { public: - SVGPathSegLinetoVerticalRel(float y); - virtual ~SVGPathSegLinetoVerticalRel(); + static PassRefPtr<SVGPathSegLinetoVerticalAbs> create(float y) { return adoptRef(new SVGPathSegLinetoVerticalAbs(y)); } + + virtual unsigned short pathSegType() const { return PATHSEG_LINETO_VERTICAL_ABS; } + virtual String pathSegTypeAsLetter() const { return "V"; } + + private: + SVGPathSegLinetoVerticalAbs(float y); + }; + + class SVGPathSegLinetoVerticalRel : public SVGPathSegLinetoVertical { + public: + static PassRefPtr<SVGPathSegLinetoVerticalRel> create(float y) { return adoptRef(new SVGPathSegLinetoVerticalRel(y)); } virtual unsigned short pathSegType() const { return PATHSEG_LINETO_VERTICAL_REL; } virtual String pathSegTypeAsLetter() const { return "v"; } - virtual String toString() const { return String::format("v %.6lg", m_y); } - - void setY(float); - float y() const; private: - float m_y; + SVGPathSegLinetoVerticalRel(float y); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegList.cpp b/WebCore/svg/SVGPathSegList.cpp index 9a4f21e..8d6fdef 100644 --- a/WebCore/svg/SVGPathSegList.cpp +++ b/WebCore/svg/SVGPathSegList.cpp @@ -29,9 +29,16 @@ #include "FloatPoint.h" #include "Path.h" #include "PathTraversalState.h" +#include "SVGPathSegArc.h" +#include "SVGPathSegClosePath.h" #include "SVGPathSegMoveto.h" #include "SVGPathSegLineto.h" +#include "SVGPathSegLinetoHorizontal.h" +#include "SVGPathSegLinetoVertical.h" #include "SVGPathSegCurvetoCubic.h" +#include "SVGPathSegCurvetoCubicSmooth.h" +#include "SVGPathSegCurvetoQuadratic.h" +#include "SVGPathSegCurvetoQuadraticSmooth.h" namespace WebCore { @@ -100,9 +107,8 @@ Path SVGPathSegList::toPathData() ExceptionCode ec = 0; int len = numberOfItems(); for (int i = 0; i < len; ++i) { - SVGPathSeg* segment = getItem(i, ec).get();; - switch (segment->pathSegType()) - { + SVGPathSeg* segment = getItem(i, ec).get(); + switch (segment->pathSegType()) { case SVGPathSeg::PATHSEG_MOVETO_ABS: { SVGPathSegMovetoAbs* moveTo = static_cast<SVGPathSegMovetoAbs*>(segment); @@ -134,6 +140,120 @@ Path SVGPathSegList::toPathData() return pathData; } + +static inline float blendFunc(float from, float to, float progress) +{ + return (to - from) * progress + from; +} + +#define BLENDPATHSEG1(class, attr1) \ + class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress)) + +#define BLENDPATHSEG2(class, attr1, attr2) \ + class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress), \ + blendFunc(static_cast<class*>(from)->attr2(), static_cast<class*>(to)->attr2(), progress)) + +#define BLENDPATHSEG4(class, attr1, attr2, attr3, attr4) \ + class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress), \ + blendFunc(static_cast<class*>(from)->attr2(), static_cast<class*>(to)->attr2(), progress), \ + blendFunc(static_cast<class*>(from)->attr3(), static_cast<class*>(to)->attr3(), progress), \ + blendFunc(static_cast<class*>(from)->attr4(), static_cast<class*>(to)->attr4(), progress)) + +#define BLENDPATHSEG6(class, attr1, attr2, attr3, attr4, attr5, attr6) \ + class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress), \ + blendFunc(static_cast<class*>(from)->attr2(), static_cast<class*>(to)->attr2(), progress), \ + blendFunc(static_cast<class*>(from)->attr3(), static_cast<class*>(to)->attr3(), progress), \ + blendFunc(static_cast<class*>(from)->attr4(), static_cast<class*>(to)->attr4(), progress), \ + blendFunc(static_cast<class*>(from)->attr5(), static_cast<class*>(to)->attr5(), progress), \ + blendFunc(static_cast<class*>(from)->attr6(), static_cast<class*>(to)->attr6(), progress)) + +#define BLENDPATHSEG7(class, attr1, attr2, attr3, attr4, attr5, bool1, bool2) \ + class::create(blendFunc(static_cast<class*>(from)->attr1(), static_cast<class*>(to)->attr1(), progress), \ + blendFunc(static_cast<class*>(from)->attr2(), static_cast<class*>(to)->attr2(), progress), \ + blendFunc(static_cast<class*>(from)->attr3(), static_cast<class*>(to)->attr3(), progress), \ + blendFunc(static_cast<class*>(from)->attr4(), static_cast<class*>(to)->attr4(), progress), \ + blendFunc(static_cast<class*>(from)->attr5(), static_cast<class*>(to)->attr5(), progress), \ + static_cast<bool>(blendFunc(static_cast<class*>(from)->bool1(), static_cast<class*>(to)->bool1(), progress)), \ + static_cast<bool>(blendFunc(static_cast<class*>(from)->bool2(), static_cast<class*>(to)->bool2(), progress))) + +PassRefPtr<SVGPathSegList> SVGPathSegList::createAnimated(const SVGPathSegList* fromList, const SVGPathSegList* toList, float progress) +{ + unsigned itemCount = fromList->numberOfItems(); + if (!itemCount || itemCount != toList->numberOfItems()) + return 0; + RefPtr<SVGPathSegList> result = create(fromList->associatedAttributeName()); + ExceptionCode ec; + for (unsigned n = 0; n < itemCount; ++n) { + SVGPathSeg* from = fromList->getItem(n, ec).get(); + SVGPathSeg* to = toList->getItem(n, ec).get(); + if (from->pathSegType() == SVGPathSeg::PATHSEG_UNKNOWN || from->pathSegType() != to->pathSegType()) + return 0; + RefPtr<SVGPathSeg> segment = 0; + switch (static_cast<SVGPathSeg::SVGPathSegType>(from->pathSegType())) { + case SVGPathSeg::PATHSEG_CLOSEPATH: + segment = SVGPathSegClosePath::create(); + break; + case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS: + segment = BLENDPATHSEG1(SVGPathSegLinetoHorizontalAbs, x); + break; + case SVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL: + segment = BLENDPATHSEG1(SVGPathSegLinetoHorizontalRel, x); + break; + case SVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS: + segment = BLENDPATHSEG1(SVGPathSegLinetoVerticalAbs, y); + break; + case SVGPathSeg::PATHSEG_LINETO_VERTICAL_REL: + segment = BLENDPATHSEG1(SVGPathSegLinetoVerticalRel, y); + break; + case SVGPathSeg::PATHSEG_MOVETO_ABS: + segment = BLENDPATHSEG2(SVGPathSegMovetoAbs, x, y); + break; + case SVGPathSeg::PATHSEG_MOVETO_REL: + segment = BLENDPATHSEG2(SVGPathSegMovetoRel, x, y); + break; + case SVGPathSeg::PATHSEG_LINETO_ABS: + segment = BLENDPATHSEG2(SVGPathSegLinetoAbs, x, y); + break; + case SVGPathSeg::PATHSEG_LINETO_REL: + segment = BLENDPATHSEG2(SVGPathSegLinetoRel, x, y); + break; + case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: + segment = BLENDPATHSEG6(SVGPathSegCurvetoCubicAbs, x, y, x1, y1, x2, y2); + break; + case SVGPathSeg::PATHSEG_CURVETO_CUBIC_REL: + segment = BLENDPATHSEG6(SVGPathSegCurvetoCubicRel, x, y, x1, y1, x2, y2); + break; + case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS: + segment = BLENDPATHSEG4(SVGPathSegCurvetoCubicSmoothAbs, x, y, x2, y2); + break; + case SVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL: + segment = BLENDPATHSEG4(SVGPathSegCurvetoCubicSmoothRel, x, y, x2, y2); + break; + case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS: + segment = BLENDPATHSEG4(SVGPathSegCurvetoQuadraticAbs, x, y, x1, y1); + break; + case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL: + segment = BLENDPATHSEG4(SVGPathSegCurvetoQuadraticRel, x, y, x1, y1); + break; + case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS: + segment = BLENDPATHSEG2(SVGPathSegCurvetoQuadraticSmoothAbs, x, y); + break; + case SVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: + segment = BLENDPATHSEG2(SVGPathSegCurvetoQuadraticSmoothRel, x, y); + break; + case SVGPathSeg::PATHSEG_ARC_ABS: + segment = BLENDPATHSEG7(SVGPathSegArcAbs, x, y, r1, r2, angle, largeArcFlag, sweepFlag); + break; + case SVGPathSeg::PATHSEG_ARC_REL: + segment = BLENDPATHSEG7(SVGPathSegArcRel, x, y, r1, r2, angle, largeArcFlag, sweepFlag); + break; + case SVGPathSeg::PATHSEG_UNKNOWN: + ASSERT_NOT_REACHED(); + } + result->appendItem(segment, ec); + } + return result.release(); +} } diff --git a/WebCore/svg/SVGPathSegList.h b/WebCore/svg/SVGPathSegList.h index 47e0079..d9325ce 100644 --- a/WebCore/svg/SVGPathSegList.h +++ b/WebCore/svg/SVGPathSegList.h @@ -33,11 +33,16 @@ namespace WebCore { class SVGPathSegList : public SVGList<RefPtr<SVGPathSeg> > { public: - SVGPathSegList(const QualifiedName&); + static PassRefPtr<SVGPathSegList> create(const QualifiedName& attributeName) { return adoptRef(new SVGPathSegList(attributeName)); } virtual ~SVGPathSegList(); unsigned getPathSegAtLength(double); Path toPathData(); + + static PassRefPtr<SVGPathSegList> createAnimated(const SVGPathSegList* fromList, const SVGPathSegList* toList, float progress); + + private: + SVGPathSegList(const QualifiedName&); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPathSegMoveto.cpp b/WebCore/svg/SVGPathSegMoveto.cpp index 2b6ca56..fc67b29 100644 --- a/WebCore/svg/SVGPathSegMoveto.cpp +++ b/WebCore/svg/SVGPathSegMoveto.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,75 +25,17 @@ #if ENABLE(SVG) #include "SVGPathSegMoveto.h" -#include "SVGStyledElement.h" - namespace WebCore { SVGPathSegMovetoAbs::SVGPathSegMovetoAbs(float x, float y) - : SVGPathSeg() - , m_x(x) - , m_y(y) -{ -} - -SVGPathSegMovetoAbs::~SVGPathSegMovetoAbs() -{ -} - -void SVGPathSegMovetoAbs::setX(float x) -{ - m_x = x; -} - -float SVGPathSegMovetoAbs::x() const + : SVGPathSegSingleCoord(x, y) { - return m_x; } -void SVGPathSegMovetoAbs::setY(float y) -{ - m_y = y; -} - -float SVGPathSegMovetoAbs::y() const -{ - return m_y; -} - - - - SVGPathSegMovetoRel::SVGPathSegMovetoRel(float x, float y) - : SVGPathSeg() - , m_x(x) - , m_y(y) + : SVGPathSegSingleCoord(x, y) { } - -SVGPathSegMovetoRel::~SVGPathSegMovetoRel() -{ -} - -void SVGPathSegMovetoRel::setX(float x) -{ - m_x = x; -} - -float SVGPathSegMovetoRel::x() const -{ - return m_x; -} - -void SVGPathSegMovetoRel::setY(float y) -{ - m_y = y; -} - -float SVGPathSegMovetoRel::y() const -{ - return m_y; -} - } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGPathSegMoveto.h b/WebCore/svg/SVGPathSegMoveto.h index 6ba64d8..726b819 100644 --- a/WebCore/svg/SVGPathSegMoveto.h +++ b/WebCore/svg/SVGPathSegMoveto.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -28,44 +28,26 @@ #include "SVGPathSeg.h" namespace WebCore { - class SVGPathSegMovetoAbs : public SVGPathSeg { + class SVGPathSegMovetoAbs : public SVGPathSegSingleCoord { public: - SVGPathSegMovetoAbs(float x, float y); - virtual ~SVGPathSegMovetoAbs(); + static PassRefPtr<SVGPathSegMovetoAbs> create(float x, float y) { return adoptRef(new SVGPathSegMovetoAbs(x, y)); } virtual unsigned short pathSegType() const { return PATHSEG_MOVETO_ABS; } virtual String pathSegTypeAsLetter() const { return "M"; } - virtual String toString() const { return String::format("M %.6lg %.6lg", m_x, m_y); } - - void setX(float); - float x() const; - - void setY(float); - float y() const; private: - float m_x; - float m_y; + SVGPathSegMovetoAbs(float x, float y); }; - class SVGPathSegMovetoRel : public SVGPathSeg { + class SVGPathSegMovetoRel : public SVGPathSegSingleCoord { public: - SVGPathSegMovetoRel(float x, float y); - virtual ~SVGPathSegMovetoRel(); + static PassRefPtr<SVGPathSegMovetoRel> create(float x, float y) { return adoptRef(new SVGPathSegMovetoRel(x, y)); } virtual unsigned short pathSegType() const { return PATHSEG_MOVETO_REL; } virtual String pathSegTypeAsLetter() const { return "m"; } - virtual String toString() const { return String::format("m %.6lg %.6lg", m_x, m_y); } - - void setX(float); - float x() const; - - void setY(float); - float y() const; private: - float m_x; - float m_y; + SVGPathSegMovetoRel(float x, float y); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPatternElement.cpp b/WebCore/svg/SVGPatternElement.cpp index c73bb82..e8ddb7c 100644 --- a/WebCore/svg/SVGPatternElement.cpp +++ b/WebCore/svg/SVGPatternElement.cpp @@ -57,13 +57,13 @@ SVGPatternElement::SVGPatternElement(const QualifiedName& tagName, Document* doc , SVGLangSpace() , SVGExternalResourcesRequired() , SVGFitToViewBox() - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) - , m_patternUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) - , m_patternContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) - , m_patternTransform(new SVGTransformList(SVGNames::patternTransformAttr)) + , m_x(this, SVGNames::xAttr, LengthModeWidth) + , m_y(this, SVGNames::yAttr, LengthModeHeight) + , m_width(this, SVGNames::widthAttr, LengthModeWidth) + , m_height(this, SVGNames::heightAttr, LengthModeHeight) + , m_patternUnits(this, SVGNames::patternUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) + , m_patternContentUnits(this, SVGNames::patternContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) + , m_patternTransform(this, SVGNames::patternTransformAttr, SVGTransformList::create(SVGNames::patternTransformAttr)) { } @@ -71,14 +71,6 @@ SVGPatternElement::~SVGPatternElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGPatternElement, int, Enumeration, enumeration, PatternUnits, patternUnits, SVGNames::patternUnitsAttr, m_patternUnits) -ANIMATED_PROPERTY_DEFINITIONS(SVGPatternElement, int, Enumeration, enumeration, PatternContentUnits, patternContentUnits, SVGNames::patternContentUnitsAttr, m_patternContentUnits) -ANIMATED_PROPERTY_DEFINITIONS(SVGPatternElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGPatternElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGPatternElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGPatternElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) -ANIMATED_PROPERTY_DEFINITIONS(SVGPatternElement, SVGTransformList*, TransformList, transformList, PatternTransform, patternTransform, SVGNames::patternTransformAttr, m_patternTransform.get()) - void SVGPatternElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::patternUnitsAttr) { @@ -98,16 +90,16 @@ void SVGPatternElement::parseMappedAttribute(MappedAttribute* attr) patternTransforms->clear(ec); } } else if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setYBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::widthAttr) { - setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value())); - if (width().value() < 0.0) + setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); + if (widthBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for pattern attribute <width> is not allowed"); } else if (attr->name() == SVGNames::heightAttr) { - setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value())); - if (width().value() < 0.0) + setHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); + if (heightBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for pattern attribute <height> is not allowed"); } else { if (SVGURIReference::parseMappedAttribute(attr)) @@ -144,9 +136,9 @@ void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName) m_resource->invalidate(); } -void SVGPatternElement::childrenChanged(bool changedByParser) +void SVGPatternElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGStyledElement::childrenChanged(changedByParser); + SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!m_resource) return; @@ -172,10 +164,10 @@ void SVGPatternElement::buildPattern(const FloatRect& targetRect) const attributes.width().valueAsPercentage() * targetRect.width(), attributes.height().valueAsPercentage() * targetRect.height()); else - patternBoundaries = FloatRect(attributes.x().value(), - attributes.y().value(), - attributes.width().value(), - attributes.height().value()); + patternBoundaries = FloatRect(attributes.x().value(this), + attributes.y().value(this), + attributes.width().value(this), + attributes.height().value(this)); // Clip pattern boundaries to target boundaries if (patternBoundaries.width() > targetRect.width()) @@ -272,7 +264,7 @@ RenderObject* SVGPatternElement::createRenderer(RenderArena* arena, RenderStyle* SVGResource* SVGPatternElement::canvasResource() { if (!m_resource) - m_resource = new SVGPaintServerPattern(this); + m_resource = SVGPaintServerPattern::create(this); return m_resource.get(); } @@ -297,10 +289,10 @@ PatternAttributes SVGPatternElement::collectPatternProperties() const attributes.setHeight(current->height()); if (!attributes.hasBoundingBoxMode() && current->hasAttribute(SVGNames::patternUnitsAttr)) - attributes.setBoundingBoxMode(current->getAttribute(SVGNames::patternUnitsAttr) == "objectBoundingBox"); + attributes.setBoundingBoxMode(current->patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); if (!attributes.hasBoundingBoxModeContent() && current->hasAttribute(SVGNames::patternContentUnitsAttr)) - attributes.setBoundingBoxModeContent(current->getAttribute(SVGNames::patternContentUnitsAttr) == "objectBoundingBox"); + attributes.setBoundingBoxModeContent(current->patternContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); if (!attributes.hasPatternTransform() && current->hasAttribute(SVGNames::patternTransformAttr)) attributes.setPatternTransform(current->patternTransform()->consolidate().matrix()); diff --git a/WebCore/svg/SVGPatternElement.h b/WebCore/svg/SVGPatternElement.h index f7b6654..2e6399c 100644 --- a/WebCore/svg/SVGPatternElement.h +++ b/WebCore/svg/SVGPatternElement.h @@ -24,21 +24,20 @@ #define SVGPatternElement_h #if ENABLE(SVG) -#include "SVGPaintServerPattern.h" #include "SVGExternalResourcesRequired.h" #include "SVGFitToViewBox.h" #include "SVGLangSpace.h" +#include "SVGPaintServerPattern.h" #include "SVGStyledElement.h" #include "SVGTests.h" +#include "SVGTransformList.h" #include "SVGURIReference.h" - namespace WebCore { struct PatternAttributes; class SVGLength; - class SVGTransformList; class SVGPatternElement : public SVGStyledElement, public SVGURIReference, @@ -54,28 +53,24 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void svgAttributeChanged(const QualifiedName&); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual SVGResource* canvasResource(); protected: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, SVGPreserveAspectRatio*, PreserveAspectRatio, preserveAspectRatio) - - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGLength, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, int, int, PatternUnits, patternUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, int, int, PatternContentUnits, patternContentUnits) - ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGTransformList*, RefPtr<SVGTransformList>, PatternTransform, patternTransform) + virtual const SVGElement* contextElement() const { return this; } - mutable RefPtr<SVGPaintServerPattern> m_resource; + private: + ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::heightAttrString, SVGLength, Height, height) + ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::patternUnitsAttrString, int, PatternUnits, patternUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::patternContentUnitsAttrString, int, PatternContentUnits, patternContentUnits) + ANIMATED_PROPERTY_DECLARATIONS(SVGPatternElement, SVGNames::patternTagString, SVGNames::patternTransformAttrString, SVGTransformList, PatternTransform, patternTransform) - virtual const SVGElement* contextElement() const { return this; } + mutable RefPtr<SVGPaintServerPattern> m_resource; private: friend class SVGPaintServerPattern; diff --git a/WebCore/svg/SVGPointList.cpp b/WebCore/svg/SVGPointList.cpp index 25160bb..c5a6dd2 100644 --- a/WebCore/svg/SVGPointList.cpp +++ b/WebCore/svg/SVGPointList.cpp @@ -23,8 +23,8 @@ #include "config.h" #if ENABLE(SVG) - #include "SVGPointList.h" +#include "PlatformString.h" namespace WebCore { @@ -37,6 +37,24 @@ SVGPointList::~SVGPointList() { } +String SVGPointList::valueAsString() const +{ + String result; + + ExceptionCode ec = 0; + for (unsigned int i = 0; i < numberOfItems(); ++i) { + if (i > 0) + result += " "; + + FloatPoint point = getItem(i, ec); + ASSERT(ec == 0); + + result += String::format("%.6lg %.6lg", point.x(), point.y()); + } + + return result; +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGPointList.h b/WebCore/svg/SVGPointList.h index 1843ef0..d443e2d 100644 --- a/WebCore/svg/SVGPointList.h +++ b/WebCore/svg/SVGPointList.h @@ -26,13 +26,21 @@ #if ENABLE(SVG) #include "SVGList.h" #include "FloatPoint.h" +#include <wtf/PassRefPtr.h> namespace WebCore { + class String; + class SVGPointList : public SVGPODList<FloatPoint> { public: - SVGPointList(const QualifiedName&); + static PassRefPtr<SVGPointList> create(const QualifiedName& attributeName) { return adoptRef(new SVGPointList(attributeName)); } virtual ~SVGPointList(); + + String valueAsString() const; + + private: + SVGPointList(const QualifiedName&); }; } // namespace WebCore diff --git a/WebCore/svg/SVGPolyElement.cpp b/WebCore/svg/SVGPolyElement.cpp index 3af9778..3d15a43 100644 --- a/WebCore/svg/SVGPolyElement.cpp +++ b/WebCore/svg/SVGPolyElement.cpp @@ -28,6 +28,7 @@ #include "Document.h" #include "FloatPoint.h" #include "RenderPath.h" +#include "SVGAnimatedProperty.h" #include "SVGNames.h" #include "SVGParserUtilities.h" #include "SVGPointList.h" @@ -40,7 +41,6 @@ SVGPolyElement::SVGPolyElement(const QualifiedName& tagName, Document* doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGAnimatedPoints() - , m_ignoreAttributeChanges(false) { } @@ -51,7 +51,7 @@ SVGPolyElement::~SVGPolyElement() SVGPointList* SVGPolyElement::points() const { if (!m_points) - m_points = new SVGPointList(SVGNames::pointsAttr); + m_points = SVGPointList::create(SVGNames::pointsAttr); return m_points.get(); } @@ -86,36 +86,14 @@ void SVGPolyElement::parseMappedAttribute(MappedAttribute* attr) void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName) { - if (m_ignoreAttributeChanges) - return; - SVGStyledTransformableElement::svgAttributeChanged(attrName); if (!renderer()) return; if (attrName == SVGNames::pointsAttr) { - m_ignoreAttributeChanges = true; + setSynchronizedSVGAttributes(false); renderer()->setNeedsLayout(true); - - ExceptionCode ec = 0; - - // Spec: Additionally, the 'points' attribute on the original element - // accessed via the XML DOM (e.g., using the getAttribute() method call) - // will reflect any changes made to points. - String _points; - int len = points()->numberOfItems(); - for (int i = 0; i < len; ++i) { - FloatPoint p = points()->getItem(i, ec); - _points += String::format("%.6lg %.6lg ", p.x(), p.y()); - } - - if (RefPtr<Attr> attr = const_cast<SVGPolyElement*>(this)->getAttributeNode(SVGNames::pointsAttr.localName())) { - ExceptionCode ec = 0; - attr->setValue(_points, ec); - } - - m_ignoreAttributeChanges = false; return; } @@ -126,6 +104,27 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName) renderer()->setNeedsLayout(true); } +// Custom SVG<->XML synchronization logic, as SVGPoly*Element doesn't use animated +// properties for this, but a special solution: SVGAnimatedPoints inheritance. +void SVGPolyElement::updateAnimatedSVGAttribute(const String& name) const +{ + ASSERT(!m_areSVGAttributesValid); + + if (m_synchronizingSVGAttributes) + return; + + if (name == SVGNames::pointsAttr.localName()) { + m_synchronizingSVGAttributes = true; + + synchronizeProperty<SVGPolyElement, SVGPointList*>(this, SVGNames::pointsAttr, m_points.get()); + setSynchronizedSVGAttributes(true); + m_synchronizingSVGAttributes = false; + return; + } + + SVGStyledTransformableElement::updateAnimatedSVGAttribute(name); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGPolyElement.h b/WebCore/svg/SVGPolyElement.h index 09ce1df..0de9f1b 100644 --- a/WebCore/svg/SVGPolyElement.h +++ b/WebCore/svg/SVGPolyElement.h @@ -52,14 +52,14 @@ namespace WebCore { virtual bool rendererIsNeeded(RenderStyle* style) { return StyledElement::rendererIsNeeded(style); } virtual bool supportsMarkers() const { return true; } + virtual void updateAnimatedSVGAttribute(const String&) const; + protected: virtual const SVGElement* contextElement() const { return this; } private: bool m_ignoreAttributeChanges : 1; mutable RefPtr<SVGPointList> m_points; - - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGPreserveAspectRatio.cpp b/WebCore/svg/SVGPreserveAspectRatio.cpp index e4223ea..cde4966 100644 --- a/WebCore/svg/SVGPreserveAspectRatio.cpp +++ b/WebCore/svg/SVGPreserveAspectRatio.cpp @@ -25,14 +25,14 @@ #if ENABLE(SVG) #include "SVGPreserveAspectRatio.h" +#include "AffineTransform.h" #include "SVGParserUtilities.h" #include "SVGSVGElement.h" namespace WebCore { SVGPreserveAspectRatio::SVGPreserveAspectRatio() - : RefCounted<SVGPreserveAspectRatio>() - , m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID) + : m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID) , m_meetOrSlice(SVG_MEETORSLICE_MEET) { // FIXME: Should the two values default to UNKNOWN instead? @@ -203,6 +203,59 @@ AffineTransform SVGPreserveAspectRatio::getCTM(double logicX, double logicY, return temp; } +String SVGPreserveAspectRatio::valueAsString() const +{ + String result; + + switch ((SVGPreserveAspectRatioType) align()) { + default: + case SVG_PRESERVEASPECTRATIO_NONE: + result = "none"; + break; + case SVG_PRESERVEASPECTRATIO_XMINYMIN: + result = "xMinYMin"; + break; + case SVG_PRESERVEASPECTRATIO_XMIDYMIN: + result = "xMidYMin"; + break; + case SVG_PRESERVEASPECTRATIO_XMAXYMIN: + result = "xMaxYMin"; + break; + case SVG_PRESERVEASPECTRATIO_XMINYMID: + result = "xMinYMid"; + break; + case SVG_PRESERVEASPECTRATIO_XMIDYMID: + result = "xMidYMid"; + break; + case SVG_PRESERVEASPECTRATIO_XMAXYMID: + result = "xMaxYMid"; + break; + case SVG_PRESERVEASPECTRATIO_XMINYMAX: + result = "xMinYMax"; + break; + case SVG_PRESERVEASPECTRATIO_XMIDYMAX: + result = "xMidYMax"; + break; + case SVG_PRESERVEASPECTRATIO_XMAXYMAX: + result = "xMaxYMax"; + break; + }; + + switch ((SVGMeetOrSliceType) meetOrSlice()) { + default: + case SVG_MEETORSLICE_UNKNOWN: + break; + case SVG_MEETORSLICE_MEET: + result += " meet"; + break; + case SVG_MEETORSLICE_SLICE: + result += " slice"; + break; + }; + + return result; +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGPreserveAspectRatio.h b/WebCore/svg/SVGPreserveAspectRatio.h index 1f56d5a..0dfe940 100644 --- a/WebCore/svg/SVGPreserveAspectRatio.h +++ b/WebCore/svg/SVGPreserveAspectRatio.h @@ -37,6 +37,8 @@ namespace WebCore { class SVGPreserveAspectRatio : public RefCounted<SVGPreserveAspectRatio> { public: + static PassRefPtr<SVGPreserveAspectRatio> create() { return adoptRef(new SVGPreserveAspectRatio); } + enum SVGPreserveAspectRatioType { SVG_PRESERVEASPECTRATIO_UNKNOWN = 0, SVG_PRESERVEASPECTRATIO_NONE = 1, @@ -57,7 +59,6 @@ namespace WebCore { SVG_MEETORSLICE_SLICE = 2 }; - SVGPreserveAspectRatio(); virtual ~SVGPreserveAspectRatio(); void setAlign(unsigned short); @@ -73,10 +74,13 @@ namespace WebCore { // Helper bool parsePreserveAspectRatio(const UChar*& currParam, const UChar* end, bool validate = true); + String valueAsString() const; const QualifiedName& associatedAttributeName() const { return SVGNames::preserveAspectRatioAttr; } - protected: + private: + SVGPreserveAspectRatio(); + unsigned short m_align; unsigned short m_meetOrSlice; }; diff --git a/WebCore/svg/SVGRadialGradientElement.cpp b/WebCore/svg/SVGRadialGradientElement.cpp index 9ec5eb8..1f25ffb 100644 --- a/WebCore/svg/SVGRadialGradientElement.cpp +++ b/WebCore/svg/SVGRadialGradientElement.cpp @@ -41,42 +41,33 @@ namespace WebCore { SVGRadialGradientElement::SVGRadialGradientElement(const QualifiedName& tagName, Document* doc) : SVGGradientElement(tagName, doc) - , m_cx(this, LengthModeWidth) - , m_cy(this, LengthModeHeight) - , m_r(this, LengthModeOther) - , m_fx(this, LengthModeWidth) - , m_fy(this, LengthModeHeight) + , m_cx(this, SVGNames::cxAttr, LengthModeWidth, "50%") + , m_cy(this, SVGNames::cyAttr, LengthModeHeight, "50%") + , m_r(this, SVGNames::rAttr, LengthModeOther, "50%") + , m_fx(this, SVGNames::fxAttr, LengthModeWidth) + , m_fy(this, SVGNames::fyAttr, LengthModeHeight) { - // Spec: If the attribute is not specified, the effect is as if a value of "50%" were specified. - setCxBaseValue(SVGLength(this, LengthModeWidth, "50%")); - setCyBaseValue(SVGLength(this, LengthModeHeight, "50%")); - setRBaseValue(SVGLength(this, LengthModeOther, "50%")); + // Spec: If the cx/cy/r attribute is not specified, the effect is as if a value of "50%" were specified. } SVGRadialGradientElement::~SVGRadialGradientElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGRadialGradientElement, SVGLength, Length, length, Cx, cx, SVGNames::cxAttr, m_cx) -ANIMATED_PROPERTY_DEFINITIONS(SVGRadialGradientElement, SVGLength, Length, length, Cy, cy, SVGNames::cyAttr, m_cy) -ANIMATED_PROPERTY_DEFINITIONS(SVGRadialGradientElement, SVGLength, Length, length, Fx, fx, SVGNames::fxAttr, m_fx) -ANIMATED_PROPERTY_DEFINITIONS(SVGRadialGradientElement, SVGLength, Length, length, Fy, fy, SVGNames::fyAttr, m_fy) -ANIMATED_PROPERTY_DEFINITIONS(SVGRadialGradientElement, SVGLength, Length, length, R, r, SVGNames::rAttr, m_r) - void SVGRadialGradientElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::cxAttr) - setCxBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setCxBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::cyAttr) - setCyBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setCyBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::rAttr) { - setRBaseValue(SVGLength(this, LengthModeOther, attr->value())); - if (r().value() < 0.0) + setRBaseValue(SVGLength(LengthModeOther, attr->value())); + if (rBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for radial gradient radius <r> is not allowed"); } else if (attr->name() == SVGNames::fxAttr) - setFxBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setFxBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::fyAttr) - setFyBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setFyBaseValue(SVGLength(LengthModeHeight, attr->value())); else SVGGradientElement::parseMappedAttribute(attr); } @@ -89,7 +80,7 @@ void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName return; if (attrName == SVGNames::cxAttr || attrName == SVGNames::cyAttr || - attrName == SVGNames::fyAttr || attrName == SVGNames::fyAttr || + attrName == SVGNames::fxAttr || attrName == SVGNames::fyAttr || attrName == SVGNames::rAttr) m_resource->invalidate(); } @@ -123,10 +114,10 @@ RadialGradientAttributes SVGRadialGradientElement::collectGradientProperties() c while (current) { if (!attributes.hasSpreadMethod() && current->hasAttribute(SVGNames::spreadMethodAttr)) - attributes.setSpreadMethod((SVGGradientSpreadMethod) current->spreadMethod()); + attributes.setSpreadMethod((GradientSpreadMethod) current->spreadMethod()); if (!attributes.hasBoundingBoxMode() && current->hasAttribute(SVGNames::gradientUnitsAttr)) - attributes.setBoundingBoxMode(current->getAttribute(SVGNames::gradientUnitsAttr) == "objectBoundingBox"); + attributes.setBoundingBoxMode(current->gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) attributes.setGradientTransform(current->gradientTransform()->consolidate().matrix()); diff --git a/WebCore/svg/SVGRadialGradientElement.h b/WebCore/svg/SVGRadialGradientElement.h index 7007ea5..6813e65 100644 --- a/WebCore/svg/SVGRadialGradientElement.h +++ b/WebCore/svg/SVGRadialGradientElement.h @@ -45,15 +45,12 @@ namespace WebCore { RadialGradientAttributes collectGradientProperties() const; - protected: - virtual const SVGElement* contextElement() const { return this; } - private: - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGLength, SVGLength, Cx, cx) - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGLength, SVGLength, Cy, cy) - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGLength, SVGLength, R, r) - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGLength, SVGLength, Fx, fx) - ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGLength, SVGLength, Fy, fy) + ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::cxAttrString, SVGLength, Cx, cx) + ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::cyAttrString, SVGLength, Cy, cy) + ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::rAttrString, SVGLength, R, r) + ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::fxAttrString, SVGLength, Fx, fx) + ANIMATED_PROPERTY_DECLARATIONS(SVGRadialGradientElement, SVGNames::radialGradientTagString, SVGNames::fyAttrString, SVGLength, Fy, fy) }; } // namespace WebCore diff --git a/WebCore/svg/SVGRectElement.cpp b/WebCore/svg/SVGRectElement.cpp index 6820b9d..367e12e 100644 --- a/WebCore/svg/SVGRectElement.cpp +++ b/WebCore/svg/SVGRectElement.cpp @@ -36,12 +36,12 @@ SVGRectElement::SVGRectElement(const QualifiedName& tagName, Document *doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) - , m_rx(this, LengthModeWidth) - , m_ry(this, LengthModeHeight) + , m_x(this, SVGNames::xAttr, LengthModeWidth) + , m_y(this, SVGNames::yAttr, LengthModeHeight) + , m_width(this, SVGNames::widthAttr, LengthModeWidth) + , m_height(this, SVGNames::heightAttr, LengthModeHeight) + , m_rx(this, SVGNames::rxAttr, LengthModeWidth) + , m_ry(this, SVGNames::ryAttr, LengthModeHeight) { } @@ -49,34 +49,27 @@ SVGRectElement::~SVGRectElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) -ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Rx, rx, SVGNames::rxAttr, m_rx) -ANIMATED_PROPERTY_DEFINITIONS(SVGRectElement, SVGLength, Length, length, Ry, ry, SVGNames::ryAttr, m_ry) - void SVGRectElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setYBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::rxAttr) { - setRxBaseValue(SVGLength(this, LengthModeWidth, attr->value())); - if (rx().value() < 0.0) + setRxBaseValue(SVGLength(LengthModeWidth, attr->value())); + if (rxBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for rect <rx> is not allowed"); } else if (attr->name() == SVGNames::ryAttr) { - setRyBaseValue(SVGLength(this, LengthModeHeight, attr->value())); - if (ry().value() < 0.0) + setRyBaseValue(SVGLength(LengthModeHeight, attr->value())); + if (ryBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for rect <ry> is not allowed"); } else if (attr->name() == SVGNames::widthAttr) { - setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value())); - if (width().value() < 0.0) + setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); + if (widthBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for rect <width> is not allowed"); } else if (attr->name() == SVGNames::heightAttr) { - setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value())); - if (height().value() < 0.0) + setHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); + if (heightBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for rect <height> is not allowed"); } else { if (SVGTests::parseMappedAttribute(attr)) @@ -98,6 +91,7 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr || attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr || + attrName == SVGNames::rxAttr || attrName == SVGNames::ryAttr || SVGTests::isKnownAttribute(attrName) || SVGLangSpace::isKnownAttribute(attrName) || SVGExternalResourcesRequired::isKnownAttribute(attrName) || @@ -107,13 +101,13 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName) Path SVGRectElement::toPathData() const { - FloatRect rect(x().value(), y().value(), width().value(), height().value()); + FloatRect rect(x().value(this), y().value(this), width().value(this), height().value(this)); bool hasRx = hasAttribute(SVGNames::rxAttr); bool hasRy = hasAttribute(SVGNames::ryAttr); if (hasRx || hasRy) { - float _rx = hasRx ? rx().value() : ry().value(); - float _ry = hasRy ? ry().value() : rx().value(); + float _rx = hasRx ? rx().value(this) : ry().value(this); + float _ry = hasRy ? ry().value(this) : rx().value(this); return Path::createRoundedRectangle(rect, FloatSize(_rx, _ry)); } @@ -123,7 +117,8 @@ Path SVGRectElement::toPathData() const bool SVGRectElement::hasRelativeValues() const { return (x().isRelative() || width().isRelative() || - y().isRelative() || height().isRelative()); + y().isRelative() || height().isRelative() || + rx().isRelative() || ry().isRelative()); } } diff --git a/WebCore/svg/SVGRectElement.h b/WebCore/svg/SVGRectElement.h index 244a6ef..2937c23 100644 --- a/WebCore/svg/SVGRectElement.h +++ b/WebCore/svg/SVGRectElement.h @@ -51,14 +51,12 @@ namespace WebCore { virtual bool hasRelativeValues() const; private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGLength, SVGLength, Height, height) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGLength, SVGLength, Rx, rx) - ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGLength, SVGLength, Ry, ry) + ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::heightAttrString, SVGLength, Height, height) + ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::rxAttrString, SVGLength, Rx, rx) + ANIMATED_PROPERTY_DECLARATIONS(SVGRectElement, SVGNames::rectTagString, SVGNames::ryAttrString, SVGLength, Ry, ry) }; } // namespace WebCore diff --git a/WebCore/svg/SVGRenderingIntent.h b/WebCore/svg/SVGRenderingIntent.h index b0510d9..699f228 100644 --- a/WebCore/svg/SVGRenderingIntent.h +++ b/WebCore/svg/SVGRenderingIntent.h @@ -28,8 +28,7 @@ namespace WebCore { -class SVGRenderingIntent : public RefCounted<SVGRenderingIntent> -{ +class SVGRenderingIntent : public RefCounted<SVGRenderingIntent> { public: enum SVGRenderingIntentType { RENDERING_INTENT_UNKNOWN = 0, @@ -40,8 +39,8 @@ public: RENDERING_INTENT_ABSOLUTE_COLORIMETRIC = 5 }; - SVGRenderingIntent() { } - ~SVGRenderingIntent() { } +private: + SVGRenderingIntent() { } }; } // namespace WebCore diff --git a/WebCore/svg/SVGSVGElement.cpp b/WebCore/svg/SVGSVGElement.cpp index db0a209..23a1fd9 100644 --- a/WebCore/svg/SVGSVGElement.cpp +++ b/WebCore/svg/SVGSVGElement.cpp @@ -1,10 +1,8 @@ /* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> 2007 Apple Inc. All rights reserved. - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -48,13 +46,11 @@ #include "SVGViewSpec.h" #include "SVGZoomEvent.h" #include "SelectionController.h" -#include "TextStream.h" -#include "TimeScheduler.h" +#include "SMILTimeContainer.h" namespace WebCore { using namespace HTMLNames; -using namespace EventNames; using namespace SVGNames; SVGSVGElement::SVGSVGElement(const QualifiedName& tagName, Document* doc) @@ -64,34 +60,32 @@ SVGSVGElement::SVGSVGElement(const QualifiedName& tagName, Document* doc) , SVGExternalResourcesRequired() , SVGFitToViewBox() , SVGZoomAndPan() - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) + , m_x(this, SVGNames::xAttr, LengthModeWidth) + , m_y(this, SVGNames::yAttr, LengthModeHeight) + , m_width(this, SVGNames::widthAttr, LengthModeWidth, "100%") + , m_height(this, SVGNames::heightAttr, LengthModeHeight, "100%") , m_useCurrentView(false) - , m_timeScheduler(new TimeScheduler(doc)) + , m_timeContainer(SMILTimeContainer::create(this)) , m_viewSpec(0) , m_containerSize(300, 150) , m_hasSetContainerSize(false) { - setWidthBaseValue(SVGLength(this, LengthModeWidth, "100%")); - setHeightBaseValue(SVGLength(this, LengthModeHeight, "100%")); + doc->registerForDocumentActivationCallbacks(this); } SVGSVGElement::~SVGSVGElement() { - delete m_timeScheduler; - m_timeScheduler = 0; - + document()->unregisterForDocumentActivationCallbacks(this); // There are cases where removedFromDocument() is not called. - // see ContainerNode::removeAllChildren, called by it's destructor. + // see ContainerNode::removeAllChildren, called by its destructor. document()->accessSVGExtensions()->removeTimeContainer(this); -} -ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) + // Call detach() here because if we wait until ~Node() calls it, we crash during + // RenderSVGViewportContainer destruction, as the renderer assumes that the element + // is still fully constructed. See <https://bugs.webkit.org/show_bug.cgi?id=21293>. + if (renderer()) + detach(); +} const AtomicString& SVGSVGElement::contentScriptType() const { @@ -122,11 +116,11 @@ FloatRect SVGSVGElement::viewport() const double _x = 0.0; double _y = 0.0; if (!isOutermostSVG()) { - _x = x().value(); - _y = y().value(); + _x = x().value(this); + _y = y().value(this); } - float w = width().value(); - float h = height().value(); + float w = width().value(this); + float h = height().value(this); AffineTransform viewBox = viewBoxToViewTransform(w, h); double wDouble = w; double hDouble = h; @@ -196,14 +190,14 @@ SVGViewSpec* SVGSVGElement::currentView() const float SVGSVGElement::currentScale() const { if (document() && document()->frame()) - return document()->frame()->zoomFactor() / 100.0f; + return document()->frame()->zoomFactor(); return 1.0f; } void SVGSVGElement::setCurrentScale(float scale) { if (document() && document()->frame()) - document()->frame()->setZoomFactor(static_cast<int>(scale / 100.0f)); + document()->frame()->setZoomFactor(scale, true); } FloatPoint SVGSVGElement::currentTranslate() const @@ -218,45 +212,44 @@ void SVGSVGElement::setCurrentTranslate(const FloatPoint &translation) document()->renderer()->repaint(); } -void SVGSVGElement::addSVGWindowEventListener(const AtomicString& eventType, const Attribute* attr) -{ - // FIXME: None of these should be window events long term. - // Once we propertly support SVGLoad, etc. - RefPtr<EventListener> listener = document()->accessSVGExtensions()-> - createSVGEventListener(attr->localName().domString(), attr->value(), this); - document()->setHTMLWindowEventListener(eventType, listener.release()); -} - void SVGSVGElement::parseMappedAttribute(MappedAttribute* attr) { if (!nearestViewportElement()) { + bool setListener = true; + // Only handle events if we're the outermost <svg> element if (attr->name() == onunloadAttr) - addSVGWindowEventListener(unloadEvent, attr); - else if (attr->name() == onabortAttr) - addSVGWindowEventListener(abortEvent, attr); - else if (attr->name() == onerrorAttr) - addSVGWindowEventListener(errorEvent, attr); + document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().unloadEvent, attr); else if (attr->name() == onresizeAttr) - addSVGWindowEventListener(resizeEvent, attr); + document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().resizeEvent, attr); else if (attr->name() == onscrollAttr) - addSVGWindowEventListener(scrollEvent, attr); + document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().scrollEvent, attr); else if (attr->name() == SVGNames::onzoomAttr) - addSVGWindowEventListener(zoomEvent, attr); + document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().zoomEvent, attr); + else + setListener = false; + + if (setListener) + return; } - if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + + if (attr->name() == onabortAttr) + document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().abortEvent, attr); + else if (attr->name() == onerrorAttr) + document()->setWindowInlineEventListenerForTypeAndAttribute(eventNames().errorEvent, attr); + else if (attr->name() == SVGNames::xAttr) + setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setYBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::widthAttr) { - setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value())); - addCSSProperty(attr, CSS_PROP_WIDTH, attr->value()); - if (width().value() < 0.0) + setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); + addCSSProperty(attr, CSSPropertyWidth, attr->value()); + if (widthBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for svg attribute <width> is not allowed"); } else if (attr->name() == SVGNames::heightAttr) { - setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value())); - addCSSProperty(attr, CSS_PROP_HEIGHT, attr->value()); - if (height().value() < 0.0) + setHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); + addCSSProperty(attr, CSSPropertyHeight, attr->value()); + if (heightBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for svg attribute <height> is not allowed"); } else { if (SVGTests::parseMappedAttribute(attr)) @@ -344,7 +337,7 @@ bool SVGSVGElement::checkEnclosure(SVGElement* element, const FloatRect& rect) void SVGSVGElement::deselectAll() { - document()->frame()->selectionController()->clear(); + document()->frame()->selection()->clear(); } float SVGSVGElement::createSVGNumber() @@ -357,9 +350,9 @@ SVGLength SVGSVGElement::createSVGLength() return SVGLength(); } -SVGAngle* SVGSVGElement::createSVGAngle() +PassRefPtr<SVGAngle> SVGSVGElement::createSVGAngle() { - return new SVGAngle(); + return SVGAngle::create(); } FloatPoint SVGSVGElement::createSVGPoint() @@ -391,10 +384,10 @@ AffineTransform SVGSVGElement::getCTM() const { AffineTransform mat; if (!isOutermostSVG()) - mat.translate(x().value(), y().value()); + mat.translate(x().value(this), y().value(this)); if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) { - AffineTransform viewBox = viewBoxToViewTransform(width().value(), height().value()); + AffineTransform viewBox = viewBoxToViewTransform(width().value(this), height().value(this)); mat = viewBox * mat; } @@ -408,17 +401,16 @@ AffineTransform SVGSVGElement::getScreenCTM() const float rootY = 0.0f; if (RenderObject* renderer = this->renderer()) { - renderer = renderer->parent(); if (isOutermostSVG()) { int tx = 0; int ty = 0; - if (renderer) + if (renderer->parent()) renderer->absolutePosition(tx, ty, true); rootX += tx; rootY += ty; } else { - rootX += x().value(); - rootY += y().value(); + rootX += x().value(this); + rootY += y().value(this); } } @@ -426,7 +418,7 @@ AffineTransform SVGSVGElement::getScreenCTM() const mat.translate(rootX, rootY); if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) { - AffineTransform viewBox = viewBoxToViewTransform(width().value(), height().value()); + AffineTransform viewBox = viewBoxToViewTransform(width().value(this), height().value(this)); mat = viewBox * mat; } @@ -455,24 +447,24 @@ void SVGSVGElement::removedFromDocument() void SVGSVGElement::pauseAnimations() { - if (!m_timeScheduler->animationsPaused()) - m_timeScheduler->toggleAnimations(); + if (!m_timeContainer->isPaused()) + m_timeContainer->pause(); } void SVGSVGElement::unpauseAnimations() { - if (m_timeScheduler->animationsPaused()) - m_timeScheduler->toggleAnimations(); + if (m_timeContainer->isPaused()) + m_timeContainer->resume(); } bool SVGSVGElement::animationsPaused() const { - return m_timeScheduler->animationsPaused(); + return m_timeContainer->isPaused(); } float SVGSVGElement::getCurrentTime() const { - return narrowPrecisionToFloat(m_timeScheduler->elapsed()); + return narrowPrecisionToFloat(m_timeContainer->elapsed().value()); } void SVGSVGElement::setCurrentTime(float /* seconds */) @@ -531,6 +523,16 @@ void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) currentView()->setZoomAndPan(viewElement->zoomAndPan()); renderer()->setNeedsLayout(true); } + +void SVGSVGElement::documentWillBecomeInactive() +{ + pauseAnimations(); +} + +void SVGSVGElement::documentDidBecomeActive() +{ + unpauseAnimations(); +} } diff --git a/WebCore/svg/SVGSVGElement.h b/WebCore/svg/SVGSVGElement.h index 4296938..bd8b7f9 100644 --- a/WebCore/svg/SVGSVGElement.h +++ b/WebCore/svg/SVGSVGElement.h @@ -40,7 +40,7 @@ namespace WebCore class SVGTransform; class SVGViewSpec; class SVGViewElement; - class TimeScheduler; + class SMILTimeContainer; class SVGSVGElement : public SVGStyledLocatableElement, public SVGTests, public SVGLangSpace, @@ -87,7 +87,7 @@ namespace WebCore FloatPoint currentTranslate() const; void setCurrentTranslate(const FloatPoint&); - TimeScheduler* timeScheduler() { return m_timeScheduler; } + SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); } void pauseAnimations(); void unpauseAnimations(); @@ -109,7 +109,7 @@ namespace WebCore static float createSVGNumber(); static SVGLength createSVGLength(); - static SVGAngle* createSVGAngle(); + static PassRefPtr<SVGAngle> createSVGAngle(); static FloatPoint createSVGPoint(); static AffineTransform createSVGMatrix(); static FloatRect createSVGRect(); @@ -145,19 +145,16 @@ namespace WebCore bool isOutermostSVG() const; private: - void addSVGWindowEventListener(const AtomicString& eventType, const Attribute* attr); + ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGNames::svgTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGNames::svgTagString, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGNames::svgTagString, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGNames::svgTagString, SVGNames::heightAttrString, SVGLength, Height, height) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, SVGPreserveAspectRatio*, PreserveAspectRatio, preserveAspectRatio) - - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGSVGElement, SVGLength, SVGLength, Height, height) + virtual void documentWillBecomeInactive(); + virtual void documentDidBecomeActive(); bool m_useCurrentView; - TimeScheduler* m_timeScheduler; + RefPtr<SMILTimeContainer> m_timeContainer; FloatPoint m_translation; mutable OwnPtr<SVGViewSpec> m_viewSpec; IntSize m_containerSize; @@ -168,5 +165,3 @@ namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGSVGElement.idl b/WebCore/svg/SVGSVGElement.idl index 4c3f512..32b4e3c 100644 --- a/WebCore/svg/SVGSVGElement.idl +++ b/WebCore/svg/SVGSVGElement.idl @@ -43,14 +43,14 @@ module svg { /*setter raises(DOMException)*/; attribute core::DOMString contentStyleType /*setter raises(DOMException)*/; - readonly attribute SVGRect viewport; + readonly attribute [Immutable] SVGRect viewport; readonly attribute float pixelUnitToMillimeterX; readonly attribute float pixelUnitToMillimeterY; readonly attribute float screenPixelToMillimeterX; readonly attribute float screenPixelToMillimeterY; attribute boolean useCurrentView /*setter raises(DOMException)*/; - // TODO readonly attribute SVGViewSpec currentView; + // TODO readonly attribute [Immutable] SVGViewSpec currentView; attribute float currentScale /*setter raises(DOMException)*/; readonly attribute SVGPoint currentTranslate; diff --git a/WebCore/svg/SVGScriptElement.cpp b/WebCore/svg/SVGScriptElement.cpp index 1278972..3c3a7a3 100644 --- a/WebCore/svg/SVGScriptElement.cpp +++ b/WebCore/svg/SVGScriptElement.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2007 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -21,9 +21,11 @@ */ #include "config.h" + #if ENABLE(SVG) #include "SVGScriptElement.h" +#include "EventNames.h" #include "SVGNames.h" namespace WebCore { @@ -32,6 +34,7 @@ SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) , SVGURIReference() , SVGExternalResourcesRequired() + , m_data(this, this) { } @@ -39,19 +42,21 @@ SVGScriptElement::~SVGScriptElement() { } -String SVGScriptElement::type() const +void SVGScriptElement::setCreatedByParser(bool createdByParser) { - return m_type; + m_data.setCreatedByParser(createdByParser); } -void SVGScriptElement::setType(const String& type) +String SVGScriptElement::scriptContent() const { - m_type = type; + return m_data.scriptContent(); } void SVGScriptElement::parseMappedAttribute(MappedAttribute* attr) { - if (attr->name() == SVGNames::typeAttr) + const QualifiedName& attrName = attr->name(); + + if (attrName == SVGNames::typeAttr) setType(attr->value()); else { if (SVGURIReference::parseMappedAttribute(attr)) @@ -63,8 +68,145 @@ void SVGScriptElement::parseMappedAttribute(MappedAttribute* attr) } } +void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGElement::svgAttributeChanged(attrName); + + if (SVGURIReference::isKnownAttribute(attrName)) + handleSourceAttribute(m_data, href()); + else if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) { + // Handle dynamic updates of the 'externalResourcesRequired' attribute. Only possible case: changing from 'true' to 'false' + // causes an immediate dispatch of the SVGLoad event. If the attribute value was 'false' before inserting the script element + // in the document, the SVGLoad event has already been dispatched. + if (!externalResourcesRequiredBaseValue() && !m_data.haveFiredLoadEvent() && !m_data.createdByParser()) { + m_data.setHaveFiredLoadEvent(true); + ASSERT(haveLoadedRequiredResources()); + + sendSVGLoadEventIfPossible(); + } + } } -// vim:ts=4:noet -#endif // ENABLE(SVG) +void SVGScriptElement::insertedIntoDocument() +{ + SVGElement::insertedIntoDocument(); + ScriptElement::insertedIntoDocument(m_data, sourceAttributeValue()); + + if (m_data.createdByParser()) + return; + + // Eventually send SVGLoad event now for the dynamically inserted script element + if (!externalResourcesRequiredBaseValue()) { + m_data.setHaveFiredLoadEvent(true); + sendSVGLoadEventIfPossible(); + } +} + +void SVGScriptElement::removedFromDocument() +{ + SVGElement::removedFromDocument(); + ScriptElement::removedFromDocument(m_data); +} + +void SVGScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) +{ + ScriptElement::childrenChanged(m_data); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); +} + +bool SVGScriptElement::isURLAttribute(Attribute* attr) const +{ + return attr->name() == sourceAttributeValue(); +} + +void SVGScriptElement::finishParsingChildren() +{ + ScriptElement::finishParsingChildren(m_data, sourceAttributeValue()); + SVGElement::finishParsingChildren(); + + // A SVGLoad event has been fired by SVGElement::finishParsingChildren. + if (!externalResourcesRequiredBaseValue()) + m_data.setHaveFiredLoadEvent(true); +} + +String SVGScriptElement::type() const +{ + return m_type; +} + +void SVGScriptElement::setType(const String& type) +{ + m_type = type; +} +String SVGScriptElement::scriptCharset() const +{ + return m_data.scriptCharset(); +} + +void SVGScriptElement::getSubresourceAttributeStrings(Vector<String>& urls) const +{ + urls.append(href()); +} + +bool SVGScriptElement::haveLoadedRequiredResources() +{ + return !externalResourcesRequiredBaseValue() || m_data.haveFiredLoadEvent(); +} + +String SVGScriptElement::sourceAttributeValue() const +{ + return href(); +} + +String SVGScriptElement::charsetAttributeValue() const +{ + return String(); +} + +String SVGScriptElement::typeAttributeValue() const +{ + return type(); +} + +String SVGScriptElement::languageAttributeValue() const +{ + return String(); +} + +void SVGScriptElement::dispatchLoadEvent() +{ + bool externalResourcesRequired = externalResourcesRequiredBaseValue(); + + if (m_data.createdByParser()) + ASSERT(externalResourcesRequired != m_data.haveFiredLoadEvent()); + else if (m_data.haveFiredLoadEvent()) { + // If we've already fired an load event and externalResourcesRequired is set to 'true' + // externalResourcesRequired has been modified while loading the <script>. Don't dispatch twice. + if (externalResourcesRequired) + return; + } + + // HTML and SVG differ completly in the 'onload' event handling of <script> elements. + // HTML fires the 'load' event after it sucessfully loaded a remote resource, otherwhise an error event. + // SVG fires the SVGLoad event immediately after parsing the <script> element, if externalResourcesRequired + // is set to 'false', otherwhise it dispatches the 'SVGLoad' event just after loading the remote resource. + if (externalResourcesRequired) { + ASSERT(!m_data.haveFiredLoadEvent()); + + // Dispatch SVGLoad event + m_data.setHaveFiredLoadEvent(true); + ASSERT(haveLoadedRequiredResources()); + + sendSVGLoadEventIfPossible(); + } +} + +void SVGScriptElement::dispatchErrorEvent() +{ + dispatchEventForType(eventNames().errorEvent, true, false); +} + +} + +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGScriptElement.h b/WebCore/svg/SVGScriptElement.h index c2c92bb..0475881 100644 --- a/WebCore/svg/SVGScriptElement.h +++ b/WebCore/svg/SVGScriptElement.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2007 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -22,36 +22,56 @@ #ifndef SVGScriptElement_h #define SVGScriptElement_h -#if ENABLE(SVG) +#if ENABLE(SVG) +#include "ScriptElement.h" #include "SVGElement.h" #include "SVGURIReference.h" #include "SVGExternalResourcesRequired.h" -namespace WebCore -{ - class SVGScriptElement : public SVGElement, - public SVGURIReference, - public SVGExternalResourcesRequired - { +namespace WebCore { + + class SVGScriptElement : public SVGElement + , public SVGURIReference + , public SVGExternalResourcesRequired + , public ScriptElement { public: SVGScriptElement(const QualifiedName&, Document*); virtual ~SVGScriptElement(); - // 'SVGScriptElement' functions + void setCreatedByParser(bool); + virtual String scriptContent() const; + + virtual void parseMappedAttribute(MappedAttribute*); + virtual void insertedIntoDocument(); + virtual void removedFromDocument(); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); + + virtual void svgAttributeChanged(const QualifiedName&); + virtual bool isURLAttribute(Attribute*) const; + virtual void finishParsingChildren(); + String type() const; void setType(const String&); - // Internal - virtual void parseMappedAttribute(MappedAttribute *attr); + virtual String scriptCharset() const; + + virtual void getSubresourceAttributeStrings(Vector<String>&) const; protected: virtual const SVGElement* contextElement() const { return this; } + virtual bool haveLoadedRequiredResources(); - private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) + virtual String sourceAttributeValue() const; + virtual String charsetAttributeValue() const; + virtual String typeAttributeValue() const; + virtual String languageAttributeValue() const; + + virtual void dispatchLoadEvent(); + virtual void dispatchErrorEvent(); + private: + ScriptElementData m_data; String m_type; }; @@ -59,5 +79,3 @@ namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGSetElement.cpp b/WebCore/svg/SVGSetElement.cpp index 1d783e6..5800580 100644 --- a/WebCore/svg/SVGSetElement.cpp +++ b/WebCore/svg/SVGSetElement.cpp @@ -21,37 +21,17 @@ */ #include "config.h" -#if ENABLE(SVG) +#if ENABLE(SVG_ANIMATION) #include "SVGSetElement.h" -#include "TimeScheduler.h" -#include "Document.h" -#include "SVGDocumentExtensions.h" -#include "SVGSVGElement.h" namespace WebCore { - + SVGSetElement::SVGSetElement(const QualifiedName& tagName, Document *doc) - : SVGAnimationElement(tagName, doc) -{ -} - -SVGSetElement::~SVGSetElement() + : SVGAnimateElement(tagName, doc) { } - -bool SVGSetElement::updateAnimatedValue(EAnimationMode, float timePercentage, unsigned valueIndex, float percentagePast) -{ - m_animatedValue = m_to; - return true; -} - -bool SVGSetElement::calculateFromAndToValues(EAnimationMode, unsigned valueIndex) -{ - return true; -} - } // vim:ts=4:noet -#endif // ENABLE(SVG) +#endif // ENABLE(SVG_ANIMATION) diff --git a/WebCore/svg/SVGSetElement.h b/WebCore/svg/SVGSetElement.h index 91fc380..d47e003 100644 --- a/WebCore/svg/SVGSetElement.h +++ b/WebCore/svg/SVGSetElement.h @@ -22,31 +22,22 @@ #ifndef SVGSetElement_h #define SVGSetElement_h -#if ENABLE(SVG) +#if ENABLE(SVG_ANIMATION) -#include "SVGAnimationElement.h" +#include "SVGAnimateElement.h" namespace WebCore { - class SVGSetElement : public SVGAnimationElement + // SVGAnimateElement implements superset of the functionality. + class SVGSetElement : public SVGAnimateElement { public: SVGSetElement(const QualifiedName&, Document*); - virtual ~SVGSetElement(); - - protected: - virtual const SVGElement* contextElement() const { return this; } - - virtual bool updateAnimatedValue(EAnimationMode, float timePercentage, unsigned valueIndex, float percentagePast); - virtual bool calculateFromAndToValues(EAnimationMode, unsigned valueIndex); - - private: - String m_savedTo; }; } // namespace WebCore -#endif // ENABLE(SVG) +#endif // ENABLE(SVG_ANIMATION) #endif // vim:ts=4:noet diff --git a/WebCore/svg/SVGSetElement.idl b/WebCore/svg/SVGSetElement.idl index 132f0ae..2ee36f1 100644 --- a/WebCore/svg/SVGSetElement.idl +++ b/WebCore/svg/SVGSetElement.idl @@ -25,7 +25,7 @@ module svg { - interface [Conditional=SVG] SVGSetElement : SVGAnimationElement { + interface [Conditional=SVG_ANIMATION] SVGSetElement : SVGAnimationElement { }; } diff --git a/WebCore/svg/SVGStopElement.cpp b/WebCore/svg/SVGStopElement.cpp index eb1657f..4747824 100644 --- a/WebCore/svg/SVGStopElement.cpp +++ b/WebCore/svg/SVGStopElement.cpp @@ -34,7 +34,7 @@ namespace WebCore { SVGStopElement::SVGStopElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) - , m_offset(0.0f) + , m_offset(this, SVGNames::offsetAttr, 0.0f) { } @@ -42,8 +42,6 @@ SVGStopElement::~SVGStopElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGStopElement, float, Number, number, Offset, offset, SVGNames::offsetAttr, m_offset) - void SVGStopElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::offsetAttr) { diff --git a/WebCore/svg/SVGStopElement.h b/WebCore/svg/SVGStopElement.h index 84ac4eb..bbfd770 100644 --- a/WebCore/svg/SVGStopElement.h +++ b/WebCore/svg/SVGStopElement.h @@ -40,7 +40,7 @@ namespace WebCore { virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGStopElement, float, float, Offset, offset) + ANIMATED_PROPERTY_DECLARATIONS(SVGStopElement, SVGNames::stopTagString, SVGNames::offsetAttrString, float, Offset, offset) }; } // namespace WebCore diff --git a/WebCore/svg/SVGStringList.h b/WebCore/svg/SVGStringList.h index bf39bc6..1cbe9d2 100644 --- a/WebCore/svg/SVGStringList.h +++ b/WebCore/svg/SVGStringList.h @@ -31,11 +31,14 @@ namespace WebCore { class SVGStringList : public SVGList<String> { public: - SVGStringList(const QualifiedName&); + static PassRefPtr<SVGStringList> create(const QualifiedName& attributeName) { return adoptRef(new SVGStringList(attributeName)); } virtual ~SVGStringList(); void reset(const String& str); void parse(const String& data, UChar delimiter = ','); + + private: + SVGStringList(const QualifiedName&); }; } // namespace WebCore diff --git a/WebCore/svg/SVGStyleElement.cpp b/WebCore/svg/SVGStyleElement.cpp index 27232cc..2612de0 100644 --- a/WebCore/svg/SVGStyleElement.cpp +++ b/WebCore/svg/SVGStyleElement.cpp @@ -103,7 +103,7 @@ void SVGStyleElement::finishParsingChildren() void SVGStyleElement::insertedIntoDocument() { SVGElement::insertedIntoDocument(); - + document()->addStyleSheetCandidateNode(this, m_createdByParser); if (!m_createdByParser) StyleElement::insertedIntoDocument(document(), this); } @@ -111,12 +111,14 @@ void SVGStyleElement::insertedIntoDocument() void SVGStyleElement::removedFromDocument() { SVGElement::removedFromDocument(); + if (document()->renderer()) + document()->removeStyleSheetCandidateNode(this); StyleElement::removedFromDocument(document()); } -void SVGStyleElement::childrenChanged(bool changedByParser) +void SVGStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGElement::childrenChanged(changedByParser); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); StyleElement::process(this); } diff --git a/WebCore/svg/SVGStyleElement.h b/WebCore/svg/SVGStyleElement.h index dbc045c..f0774aa 100644 --- a/WebCore/svg/SVGStyleElement.h +++ b/WebCore/svg/SVGStyleElement.h @@ -37,7 +37,7 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); virtual void insertedIntoDocument(); virtual void removedFromDocument(); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; } virtual void finishParsingChildren(); diff --git a/WebCore/svg/SVGStyleElement.idl b/WebCore/svg/SVGStyleElement.idl index ba065d9..e87b79f 100644 --- a/WebCore/svg/SVGStyleElement.idl +++ b/WebCore/svg/SVGStyleElement.idl @@ -27,7 +27,7 @@ module svg { interface [Conditional=SVG] SVGStyleElement : SVGElement { - attribute AtomicString xmlspace + attribute core::DOMString xmlspace setter raises(DOMException); attribute core::DOMString type setter raises(DOMException); diff --git a/WebCore/svg/SVGStyledElement.cpp b/WebCore/svg/SVGStyledElement.cpp index 2e4141d..466ce3c 100644 --- a/WebCore/svg/SVGStyledElement.cpp +++ b/WebCore/svg/SVGStyledElement.cpp @@ -1,8 +1,6 @@ /* Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2007 Rob Buis <buis@kde.org> - - This file is part of the KDE project + 2004, 2005, 2007, 2008 Rob Buis <buis@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -21,11 +19,11 @@ */ #include "config.h" - #if ENABLE(SVG) #include "SVGStyledElement.h" #include "Attr.h" +#include "CSSParser.h" #include "CSSStyleSelector.h" #include "CString.h" #include "Document.h" @@ -44,8 +42,12 @@ namespace WebCore { using namespace SVGNames; +char SVGStyledElementIdentifier[] = "SVGStyledElement"; +static HashSet<const SVGStyledElement*>* gElementsWithInstanceUpdatesBlocked = 0; + SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* doc) : SVGElement(tagName, doc) + , m_className(this, HTMLNames::classAttr) { } @@ -54,8 +56,6 @@ SVGStyledElement::~SVGStyledElement() SVGResource::removeClient(this); } -ANIMATED_PROPERTY_DEFINITIONS(SVGStyledElement, String, String, string, ClassName, className, HTMLNames::classAttr, m_className) - bool SVGStyledElement::rendererIsNeeded(RenderStyle* style) { // http://www.w3.org/TR/SVG/extend.html#PrivateData @@ -69,15 +69,9 @@ bool SVGStyledElement::rendererIsNeeded(RenderStyle* style) return false; } -static inline void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName, const char* cssPropertyName = 0) +static void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName) { - int propertyId = 0; - if (cssPropertyName) - propertyId = getPropertyID(cssPropertyName, strlen(cssPropertyName)); - else { - CString propertyName = attrName.localName().domString().utf8(); - propertyId = getPropertyID(propertyName.data(), propertyName.length()); - } + int propertyId = cssPropertyID(attrName.localName()); ASSERT(propertyId > 0); propertyNameToIdMap->set(attrName.localName().impl(), propertyId); } @@ -165,17 +159,25 @@ bool SVGStyledElement::mapToEntry(const QualifiedName& attrName, MappedAttribute void SVGStyledElement::parseMappedAttribute(MappedAttribute* attr) { + const QualifiedName& attrName = attr->name(); // NOTE: Any subclass which overrides parseMappedAttribute for a property handled by // cssPropertyIdForSVGAttributeName will also have to override mapToEntry to disable the default eSVG mapping - int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attr->name()); + int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attrName); if (propId > 0) { addCSSProperty(attr, propId, attr->value()); setChanged(); return; } - // id and class are handled by StyledElement - SVGElement::parseMappedAttribute(attr); + // SVG animation has currently requires special storage of values so we set + // the className here. svgAttributeChanged actually causes the resulting + // style updates (instead of StyledElement::parseMappedAttribute). We don't + // tell StyledElement about the change to avoid parsing the class list twice + if (attrName.matches(HTMLNames::classAttr)) + setClassName(attr->value()); + else + // id is handled by StyledElement which SVGElement inherits from + SVGElement::parseMappedAttribute(attr); } bool SVGStyledElement::isKnownAttribute(const QualifiedName& attrName) @@ -192,19 +194,14 @@ void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName) { SVGElement::svgAttributeChanged(attrName); + if (attrName.matches(HTMLNames::classAttr)) + classAttributeChanged(className()); + // If we're the child of a resource element, be sure to invalidate it. invalidateResourcesInAncestorChain(); - SVGDocumentExtensions* extensions = document()->accessSVGExtensions(); - if (!extensions) - return; - - // TODO: Fix bug http://bugs.webkit.org/show_bug.cgi?id=15430 (SVGElementInstances should rebuild themselves lazily) - - // In case we're referenced by a <use> element, we have element instances registered - // to us in the SVGDocumentExtensions. If notifyAttributeChange() is called, we need - // to recursively update all children including ourselves. - updateElementInstance(extensions); + // Invalidate all SVGElementInstances associated with us + SVGElementInstance::invalidateAllInstancesOfElement(this); } void SVGStyledElement::invalidateResourcesInAncestorChain() const @@ -224,66 +221,39 @@ void SVGStyledElement::invalidateResourcesInAncestorChain() const } } -void SVGStyledElement::childrenChanged(bool changedByParser) +void SVGStyledElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGElement::childrenChanged(changedByParser); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (document()->parsing()) return; - SVGDocumentExtensions* extensions = document()->accessSVGExtensions(); - if (!extensions) - return; - - // TODO: Fix bug http://bugs.webkit.org/show_bug.cgi?id=15430 (SVGElementInstances should rebuild themselves lazily) - - // In case we're referenced by a <use> element, we have element instances registered - // to us in the SVGDocumentExtensions. If childrenChanged() is called, we need - // to recursively update all children including ourselves. - updateElementInstance(extensions); -} - -void SVGStyledElement::updateElementInstance(SVGDocumentExtensions* extensions) const -{ - SVGStyledElement* nonConstThis = const_cast<SVGStyledElement*>(this); - HashSet<SVGElementInstance*>* set = extensions->instancesForElement(nonConstThis); - if (!set || set->isEmpty()) - return; - - // We need to be careful here, as the instancesForElement - // hash set may be modified after we call updateInstance! - HashSet<SVGElementInstance*> localCopy; - - // First create a local copy of the hashset - HashSet<SVGElementInstance*>::const_iterator it1 = set->begin(); - const HashSet<SVGElementInstance*>::const_iterator end1 = set->end(); - - for (; it1 != end1; ++it1) - localCopy.add(*it1); - - // Actually nofify instances to update - HashSet<SVGElementInstance*>::const_iterator it2 = localCopy.begin(); - const HashSet<SVGElementInstance*>::const_iterator end2 = localCopy.end(); - - for (; it2 != end2; ++it2) - (*it2)->updateInstance(nonConstThis); + // Invalidate all SVGElementInstances associated with us + SVGElementInstance::invalidateAllInstancesOfElement(this); } -RenderStyle* SVGStyledElement::resolveStyle(RenderStyle* parentStyle) +PassRefPtr<RenderStyle> SVGStyledElement::resolveStyle(RenderStyle* parentStyle) { - if (renderer()) { - RenderStyle* renderStyle = renderer()->style(); - renderStyle->ref(); - return renderStyle; - } - + if (renderer()) + return renderer()->style(); return document()->styleSelector()->styleForElement(this, parentStyle); } PassRefPtr<CSSValue> SVGStyledElement::getPresentationAttribute(const String& name) { - MappedAttribute* cssSVGAttr = mappedAttributes()->getAttributeItem(name); - if (!cssSVGAttr || !cssSVGAttr->style()) + Attribute* attr = mappedAttributes()->getAttributeItem(name, false); + if (!attr || !attr->isMappedAttribute() || !attr->style()) return 0; + + MappedAttribute* cssSVGAttr = static_cast<MappedAttribute*>(attr); + + // FIXME: Is it possible that the style will not be shared at the time this + // is called, but a later addition to the DOM will make it shared? + if (!cssSVGAttr->style()->hasOneRef()) { + cssSVGAttr->setDecl(0); + int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(cssSVGAttr->name()); + addCSSProperty(cssSVGAttr, propId, cssSVGAttr->value()); + } + return cssSVGAttr->style()->getPropertyCSSValue(name); } @@ -293,6 +263,19 @@ void SVGStyledElement::detach() SVGElement::detach(); } +void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates) +{ + if (blockUpdates) { + if (!gElementsWithInstanceUpdatesBlocked) + gElementsWithInstanceUpdatesBlocked = new HashSet<const SVGStyledElement*>; + gElementsWithInstanceUpdatesBlocked->add(this); + } else { + ASSERT(gElementsWithInstanceUpdatesBlocked); + ASSERT(gElementsWithInstanceUpdatesBlocked->contains(this)); + gElementsWithInstanceUpdatesBlocked->remove(this); + } +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGStyledElement.h b/WebCore/svg/SVGStyledElement.h index 231f7ec..e21db97 100644 --- a/WebCore/svg/SVGStyledElement.h +++ b/WebCore/svg/SVGStyledElement.h @@ -24,15 +24,15 @@ #define SVGStyledElement_h #if ENABLE(SVG) -#include "AffineTransform.h" -#include "Path.h" +#include "HTMLNames.h" #include "SVGElement.h" -#include "SVGLength.h" -#include "SVGResource.h" #include "SVGStylable.h" namespace WebCore { + extern char SVGStyledElementIdentifier[]; + class SVGResource; + class SVGStyledElement : public SVGElement, public SVGStylable { public: @@ -55,13 +55,15 @@ namespace WebCore { virtual void svgAttributeChanged(const QualifiedName&); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); // Centralized place to force a manual style resolution. Hacky but needed for now. - RenderStyle* resolveStyle(RenderStyle* parentStyle); + PassRefPtr<RenderStyle> resolveStyle(RenderStyle* parentStyle); void invalidateResourcesInAncestorChain() const; virtual void detach(); + + void setInstanceUpdatesBlocked(bool); protected: virtual bool hasRelativeValues() const { return true; } @@ -69,9 +71,7 @@ namespace WebCore { static int cssPropertyIdForSVGAttributeName(const QualifiedName&); private: - ANIMATED_PROPERTY_DECLARATIONS(SVGStyledElement, String, String, ClassName, className) - - void updateElementInstance(SVGDocumentExtensions*) const; + ANIMATED_PROPERTY_DECLARATIONS(SVGStyledElement, SVGStyledElementIdentifier, HTMLNames::classAttrString, String, ClassName, className) }; } // namespace WebCore diff --git a/WebCore/svg/SVGStyledTransformableElement.cpp b/WebCore/svg/SVGStyledTransformableElement.cpp index 9893ab8..a7b5c41 100644 --- a/WebCore/svg/SVGStyledTransformableElement.cpp +++ b/WebCore/svg/SVGStyledTransformableElement.cpp @@ -35,10 +35,12 @@ namespace WebCore { +char SVGStyledTransformableElementIdentifier[] = "SVGStyledTransformableElement"; + SVGStyledTransformableElement::SVGStyledTransformableElement(const QualifiedName& tagName, Document* doc) : SVGStyledLocatableElement(tagName, doc) , SVGTransformable() - , m_transform(new SVGTransformList(SVGNames::transformAttr)) + , m_transform(this, SVGNames::transformAttr, SVGTransformList::create(SVGNames::transformAttr)) { } @@ -46,8 +48,6 @@ SVGStyledTransformableElement::~SVGStyledTransformableElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGStyledTransformableElement, SVGTransformList*, TransformList, transformList, Transform, transform, SVGNames::transformAttr, m_transform.get()) - AffineTransform SVGStyledTransformableElement::getCTM() const { return SVGTransformable::getCTM(this); @@ -60,7 +60,14 @@ AffineTransform SVGStyledTransformableElement::getScreenCTM() const AffineTransform SVGStyledTransformableElement::animatedLocalTransform() const { - return transform()->concatenate().matrix(); + return m_supplementalTransform ? transform()->concatenate().matrix() * *m_supplementalTransform : transform()->concatenate().matrix(); +} + +AffineTransform* SVGStyledTransformableElement::supplementalTransform() +{ + if (!m_supplementalTransform) + m_supplementalTransform.set(new AffineTransform()); + return m_supplementalTransform.get(); } void SVGStyledTransformableElement::parseMappedAttribute(MappedAttribute* attr) @@ -106,6 +113,14 @@ RenderObject* SVGStyledTransformableElement::createRenderer(RenderArena* arena, return new (arena) RenderPath(style, this); } +Path SVGStyledTransformableElement::toClipPath() const +{ + Path pathData = toPathData(); + // FIXME: How do we know the element has done a layout? + pathData.transform(animatedLocalTransform()); + return pathData; +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGStyledTransformableElement.h b/WebCore/svg/SVGStyledTransformableElement.h index 8e23a51..43ccc68 100644 --- a/WebCore/svg/SVGStyledTransformableElement.h +++ b/WebCore/svg/SVGStyledTransformableElement.h @@ -24,13 +24,15 @@ #define SVGStyledTransformableElement_h #if ENABLE(SVG) +#include "Path.h" #include "SVGStyledLocatableElement.h" #include "SVGTransformable.h" namespace WebCore { + extern char SVGStyledTransformableElementIdentifier[]; + class AffineTransform; - class SVGTransformList; class SVGStyledTransformableElement : public SVGStyledLocatableElement, public SVGTransformable { @@ -46,6 +48,7 @@ namespace WebCore { virtual SVGElement* farthestViewportElement() const; virtual AffineTransform animatedLocalTransform() const; + virtual AffineTransform* supplementalTransform(); virtual FloatRect getBBox() const; @@ -54,11 +57,16 @@ namespace WebCore { // "base class" methods for all the elements which render as paths virtual Path toPathData() const { return Path(); } - virtual Path toClipPath() const { return toPathData(); } + virtual Path toClipPath() const; virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); protected: - ANIMATED_PROPERTY_DECLARATIONS(SVGStyledTransformableElement, SVGTransformList*, RefPtr<SVGTransformList>, Transform, transform) + ANIMATED_PROPERTY_DECLARATIONS(SVGStyledTransformableElement, SVGStyledTransformableElementIdentifier, + SVGNames::transformAttrString, SVGTransformList, Transform, transform) + + private: + // Used by <animateMotion> + OwnPtr<AffineTransform> m_supplementalTransform; }; } // namespace WebCore diff --git a/WebCore/svg/SVGSwitchElement.h b/WebCore/svg/SVGSwitchElement.h index 3bfc275..82153d9 100644 --- a/WebCore/svg/SVGSwitchElement.h +++ b/WebCore/svg/SVGSwitchElement.h @@ -51,8 +51,6 @@ namespace WebCore private: mutable bool m_insideRenderSection; - - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) }; } // namespace WebCore diff --git a/WebCore/svg/SVGSymbolElement.h b/WebCore/svg/SVGSymbolElement.h index eaa0b94..a6ccbce 100644 --- a/WebCore/svg/SVGSymbolElement.h +++ b/WebCore/svg/SVGSymbolElement.h @@ -29,13 +29,12 @@ #include "SVGLangSpace.h" #include "SVGStyledElement.h" -namespace WebCore -{ +namespace WebCore { + class SVGSymbolElement : public SVGStyledElement, public SVGLangSpace, public SVGExternalResourcesRequired, - public SVGFitToViewBox - { + public SVGFitToViewBox { public: SVGSymbolElement(const QualifiedName&, Document*); virtual ~SVGSymbolElement(); @@ -47,15 +46,9 @@ namespace WebCore protected: virtual const SVGElement* contextElement() const { return this; } - - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, SVGPreserveAspectRatio*, PreserveAspectRatio, preserveAspectRatio) }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGTRefElement.h b/WebCore/svg/SVGTRefElement.h index 16ea5c3..88eeef1 100644 --- a/WebCore/svg/SVGTRefElement.h +++ b/WebCore/svg/SVGTRefElement.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -22,15 +22,15 @@ #ifndef SVGTRefElement_h #define SVGTRefElement_h -#if ENABLE(SVG) +#if ENABLE(SVG) #include "SVGTextPositioningElement.h" #include "SVGURIReference.h" -namespace WebCore -{ - class SVGTRefElement : public SVGTextPositioningElement, public SVGURIReference - { +namespace WebCore { + + class SVGTRefElement : public SVGTextPositioningElement, + public SVGURIReference { public: SVGTRefElement(const QualifiedName&, Document*); virtual ~SVGTRefElement(); @@ -44,8 +44,6 @@ namespace WebCore virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - void updateReferencedText(); }; @@ -53,5 +51,3 @@ namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGTSpanElement.cpp b/WebCore/svg/SVGTSpanElement.cpp index 45a7727..eadae1e 100644 --- a/WebCore/svg/SVGTSpanElement.cpp +++ b/WebCore/svg/SVGTSpanElement.cpp @@ -42,8 +42,11 @@ SVGTSpanElement::~SVGTSpanElement() bool SVGTSpanElement::childShouldCreateRenderer(Node* child) const { - if (child->isTextNode() || child->hasTagName(SVGNames::tspanTag) || - child->hasTagName(SVGNames::trefTag) || child->hasTagName(SVGNames::textPathTag)) + if (child->isTextNode() +#if ENABLE(SVG_FONTS) + || child->hasTagName(SVGNames::altGlyphTag) +#endif + || child->hasTagName(SVGNames::tspanTag) || child->hasTagName(SVGNames::trefTag) || child->hasTagName(SVGNames::textPathTag)) return true; return false; diff --git a/WebCore/svg/SVGTSpanElement.h b/WebCore/svg/SVGTSpanElement.h index f2d0303..7a29e96 100644 --- a/WebCore/svg/SVGTSpanElement.h +++ b/WebCore/svg/SVGTSpanElement.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -22,28 +22,22 @@ #ifndef SVGTSpanElement_h #define SVGTSpanElement_h -#if ENABLE(SVG) +#if ENABLE(SVG) #include "SVGTextPositioningElement.h" -namespace WebCore -{ - class SVGTSpanElement : public SVGTextPositioningElement - { +namespace WebCore { + + class SVGTSpanElement : public SVGTextPositioningElement { public: SVGTSpanElement(const QualifiedName&, Document*); virtual ~SVGTSpanElement(); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); bool childShouldCreateRenderer(Node*) const; - - protected: - virtual const SVGElement* contextElement() const { return this; } }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGTests.cpp b/WebCore/svg/SVGTests.cpp index d11e44d..06a81f2 100644 --- a/WebCore/svg/SVGTests.cpp +++ b/WebCore/svg/SVGTests.cpp @@ -2,8 +2,6 @@ Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -44,7 +42,7 @@ SVGTests::~SVGTests() SVGStringList* SVGTests::requiredFeatures() const { if (!m_features) - m_features = new SVGStringList(SVGNames::requiredFeaturesAttr); + m_features = SVGStringList::create(SVGNames::requiredFeaturesAttr); return m_features.get(); } @@ -52,7 +50,7 @@ SVGStringList* SVGTests::requiredFeatures() const SVGStringList* SVGTests::requiredExtensions() const { if (!m_extensions) - m_extensions = new SVGStringList(SVGNames::requiredExtensionsAttr); + m_extensions = SVGStringList::create(SVGNames::requiredExtensionsAttr); return m_extensions.get(); } @@ -60,7 +58,7 @@ SVGStringList* SVGTests::requiredExtensions() const SVGStringList* SVGTests::systemLanguage() const { if (!m_systemLanguage) - m_systemLanguage = new SVGStringList(SVGNames::systemLanguageAttr); + m_systemLanguage = SVGStringList::create(SVGNames::systemLanguageAttr); return m_systemLanguage.get(); } @@ -77,7 +75,7 @@ bool SVGTests::isValid() const if (m_features) { for (unsigned long i = 0; i < m_features->numberOfItems(); i++) { String value = m_features->getItem(i, ec); - if (value.isEmpty() || !DOMImplementation::instance()->hasFeature(value, String())) + if (value.isEmpty() || !DOMImplementation::hasFeature(value, String())) return false; } } diff --git a/WebCore/svg/SVGTextContentElement.cpp b/WebCore/svg/SVGTextContentElement.cpp index 03ed592..e53d662 100644 --- a/WebCore/svg/SVGTextContentElement.cpp +++ b/WebCore/svg/SVGTextContentElement.cpp @@ -1,8 +1,6 @@ /* - Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> - - This file is part of the KDE project + Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> + 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -43,13 +41,15 @@ namespace WebCore { +char SVGTextContentElementIdentifier[] = "SVGTextContentElement"; + SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Document* doc) : SVGStyledElement(tagName, doc) , SVGTests() , SVGLangSpace() , SVGExternalResourcesRequired() - , m_textLength(this, LengthModeOther) - , m_lengthAdjust(LENGTHADJUST_SPACING) + , m_textLength(this, SVGNames::textLengthAttr, LengthModeOther) + , m_lengthAdjust(this, SVGNames::lengthAdjustAttr, LENGTHADJUST_SPACING) { } @@ -57,12 +57,12 @@ SVGTextContentElement::~SVGTextContentElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGTextContentElement, SVGLength, Length, length, TextLength, textLength, SVGNames::textLengthAttr, m_textLength) -ANIMATED_PROPERTY_DEFINITIONS(SVGTextContentElement, int, Enumeration, enumeration, LengthAdjust, lengthAdjust, SVGNames::lengthAdjustAttr, m_lengthAdjust) - -static inline float cummulatedCharacterRangeLength(const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end, SVGInlineTextBox* textBox, +static inline float cumulativeCharacterRangeLength(const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end, SVGInlineTextBox* textBox, int startOffset, long startPosition, long length, bool isVerticalText, long& atCharacter) { + if (!length) + return 0.0f; + float textLength = 0.0f; RenderStyle* style = textBox->textObject()->style(); @@ -73,20 +73,23 @@ static inline float cummulatedCharacterRangeLength(const Vector<SVGChar>::iterat unsigned int newOffset = textBox->start() + (it - start) + startOffset; // Take RTL text into account and pick right glyph width/height. - if (textBox->m_reversed) + if (textBox->direction() == RTL) newOffset = textBox->start() + textBox->end() - newOffset; + // FIXME: does this handle multichar glyphs ok? not sure + int charsConsumed = 0; + String glyphName; if (isVerticalText) - textLength += textBox->calculateGlyphHeight(style, newOffset); + textLength += textBox->calculateGlyphHeight(style, newOffset, 0); else - textLength += textBox->calculateGlyphWidth(style, newOffset); + textLength += textBox->calculateGlyphWidth(style, newOffset, 0, charsConsumed, glyphName); } if (!usesFullRange) { - if (atCharacter < startPosition + length) - atCharacter++; - else if (atCharacter == startPosition + length) + if (atCharacter == startPosition + length - 1) break; + + atCharacter++; } } @@ -136,7 +139,7 @@ struct SVGInlineTextBoxQueryWalker { } case TextLength: { - float textLength = cummulatedCharacterRangeLength(start, end, textBox, startOffset, -1, -1, isVerticalText, m_atCharacter); + float textLength = cumulativeCharacterRangeLength(start, end, textBox, startOffset, -1, -1, isVerticalText, m_atCharacter); if (isVerticalText) m_queryFloatResult += textLength; @@ -151,7 +154,7 @@ struct SVGInlineTextBoxQueryWalker { long startPosition = m_queryStartPosition; long length = m_queryLength; - float textLength = cummulatedCharacterRangeLength(start, end, textBox, startOffset, startPosition, length, isVerticalText, m_atCharacter); + float textLength = cumulativeCharacterRangeLength(start, end, textBox, startOffset, startPosition, length, isVerticalText, m_atCharacter); if (isVerticalText) m_queryFloatResult += textLength; @@ -187,13 +190,18 @@ struct SVGInlineTextBoxQueryWalker { unsigned int newOffset = textBox->start() + (it - start) + startOffset; // Take RTL text into account and pick right glyph width/height. - if (textBox->m_reversed) + if (textBox->direction() == RTL) newOffset = textBox->start() + textBox->end() - newOffset; + int charsConsumed; + String glyphName; + // calculateGlyph{Height,Width} will consume at least one character. This is the number of characters available + // to them beyond that first one. + int extraCharactersAvailable = end - it - 1; if (isVerticalText) - m_queryPointResult.move(it->x, it->y + textBox->calculateGlyphHeight(style, newOffset)); + m_queryPointResult.move(it->x, it->y + textBox->calculateGlyphHeight(style, newOffset, extraCharactersAvailable)); else - m_queryPointResult.move(it->x + textBox->calculateGlyphWidth(style, newOffset), it->y); + m_queryPointResult.move(it->x + textBox->calculateGlyphWidth(style, newOffset, extraCharactersAvailable, charsConsumed, glyphName), it->y); m_stopProcessing = true; return; @@ -363,17 +371,24 @@ static inline SVGInlineTextBoxQueryWalker executeTextQuery(const SVGTextContentE long SVGTextContentElement::getNumberOfChars() const { + document()->updateLayoutIgnorePendingStylesheets(); + return executeTextQuery(this, SVGInlineTextBoxQueryWalker::NumberOfCharacters).longResult(); } float SVGTextContentElement::getComputedTextLength() const { + document()->updateLayoutIgnorePendingStylesheets(); + return executeTextQuery(this, SVGInlineTextBoxQueryWalker::TextLength).floatResult(); } -float SVGTextContentElement::getSubStringLength(long charnum, unsigned long nchars, ExceptionCode& ec) const +float SVGTextContentElement::getSubStringLength(long charnum, long nchars, ExceptionCode& ec) const { - if (charnum < 0 || charnum > getNumberOfChars()) { + document()->updateLayoutIgnorePendingStylesheets(); + + long numberOfChars = getNumberOfChars(); + if (charnum < 0 || nchars < 0 || charnum >= numberOfChars) { ec = INDEX_SIZE_ERR; return 0.0f; } @@ -383,6 +398,8 @@ float SVGTextContentElement::getSubStringLength(long charnum, unsigned long ncha FloatPoint SVGTextContentElement::getStartPositionOfChar(long charnum, ExceptionCode& ec) const { + document()->updateLayoutIgnorePendingStylesheets(); + if (charnum < 0 || charnum > getNumberOfChars()) { ec = INDEX_SIZE_ERR; return FloatPoint(); @@ -393,6 +410,8 @@ FloatPoint SVGTextContentElement::getStartPositionOfChar(long charnum, Exception FloatPoint SVGTextContentElement::getEndPositionOfChar(long charnum, ExceptionCode& ec) const { + document()->updateLayoutIgnorePendingStylesheets(); + if (charnum < 0 || charnum > getNumberOfChars()) { ec = INDEX_SIZE_ERR; return FloatPoint(); @@ -403,6 +422,8 @@ FloatPoint SVGTextContentElement::getEndPositionOfChar(long charnum, ExceptionCo FloatRect SVGTextContentElement::getExtentOfChar(long charnum, ExceptionCode& ec) const { + document()->updateLayoutIgnorePendingStylesheets(); + if (charnum < 0 || charnum > getNumberOfChars()) { ec = INDEX_SIZE_ERR; return FloatRect(); @@ -413,6 +434,8 @@ FloatRect SVGTextContentElement::getExtentOfChar(long charnum, ExceptionCode& ec float SVGTextContentElement::getRotationOfChar(long charnum, ExceptionCode& ec) const { + document()->updateLayoutIgnorePendingStylesheets(); + if (charnum < 0 || charnum > getNumberOfChars()) { ec = INDEX_SIZE_ERR; return 0.0f; @@ -423,13 +446,15 @@ float SVGTextContentElement::getRotationOfChar(long charnum, ExceptionCode& ec) long SVGTextContentElement::getCharNumAtPosition(const FloatPoint& point) const { + document()->updateLayoutIgnorePendingStylesheets(); + return executeTextQuery(this, SVGInlineTextBoxQueryWalker::CharacterNumberAtPosition, 0.0f, 0.0f, point).longResult(); } void SVGTextContentElement::selectSubString(long charnum, long nchars, ExceptionCode& ec) const { long numberOfChars = getNumberOfChars(); - if (charnum < 0 || nchars < 0 || charnum > numberOfChars) { + if (charnum < 0 || nchars < 0 || charnum >= numberOfChars) { ec = INDEX_SIZE_ERR; return; } @@ -440,7 +465,7 @@ void SVGTextContentElement::selectSubString(long charnum, long nchars, Exception ASSERT(document()); ASSERT(document()->frame()); - SelectionController* controller = document()->frame()->selectionController(); + SelectionController* controller = document()->frame()->selection(); if (!controller) return; @@ -465,8 +490,8 @@ void SVGTextContentElement::parseMappedAttribute(MappedAttribute* attr) else if (attr->value() == "spacingAndGlyphs") setLengthAdjustBaseValue(LENGTHADJUST_SPACINGANDGLYPHS); } else if (attr->name() == SVGNames::textLengthAttr) { - setTextLengthBaseValue(SVGLength(this, LengthModeOther, attr->value())); - if (textLength().value() < 0.0) + setTextLengthBaseValue(SVGLength(LengthModeOther, attr->value())); + if (textLengthBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for text attribute <textLength> is not allowed"); } else { if (SVGTests::parseMappedAttribute(attr)) @@ -476,9 +501,9 @@ void SVGTextContentElement::parseMappedAttribute(MappedAttribute* attr) static const AtomicString preserveString("preserve"); if (attr->value() == preserveString) - addCSSProperty(attr, CSS_PROP_WHITE_SPACE, CSS_VAL_PRE); + addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValuePre); else - addCSSProperty(attr, CSS_PROP_WHITE_SPACE, CSS_VAL_NOWRAP); + addCSSProperty(attr, CSSPropertyWhiteSpace, CSSValueNowrap); } return; } @@ -489,8 +514,16 @@ void SVGTextContentElement::parseMappedAttribute(MappedAttribute* attr) } } +bool SVGTextContentElement::isKnownAttribute(const QualifiedName& attrName) +{ + return (attrName.matches(SVGNames::lengthAdjustAttr) || + attrName.matches(SVGNames::textLengthAttr) || + SVGTests::isKnownAttribute(attrName) || + SVGLangSpace::isKnownAttribute(attrName) || + SVGExternalResourcesRequired::isKnownAttribute(attrName) || + SVGStyledElement::isKnownAttribute(attrName)); } -#endif // ENABLE(SVG) +} -// vim:ts=4:noet +#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTextContentElement.h b/WebCore/svg/SVGTextContentElement.h index 570ed6b..d6b9d93 100644 --- a/WebCore/svg/SVGTextContentElement.h +++ b/WebCore/svg/SVGTextContentElement.h @@ -1,6 +1,6 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -30,13 +30,15 @@ #include "SVGTests.h" namespace WebCore { + + extern char SVGTextContentElementIdentifier[]; + class SVGLength; class SVGTextContentElement : public SVGStyledElement, public SVGTests, public SVGLangSpace, - public SVGExternalResourcesRequired - { + public SVGExternalResourcesRequired { public: enum SVGLengthAdjustType { LENGTHADJUST_UNKNOWN = 0, @@ -50,10 +52,9 @@ namespace WebCore { virtual bool isValid() const { return SVGTests::isValid(); } virtual bool isTextContent() const { return true; } - // 'SVGTextContentElement' functions long getNumberOfChars() const; float getComputedTextLength() const; - float getSubStringLength(long charnum, unsigned long nchars, ExceptionCode&) const; + float getSubStringLength(long charnum, long nchars, ExceptionCode&) const; FloatPoint getStartPositionOfChar(long charnum, ExceptionCode&) const; FloatPoint getEndPositionOfChar(long charnum, ExceptionCode&) const; FloatRect getExtentOfChar(long charnum, ExceptionCode&) const; @@ -63,16 +64,17 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); - private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) + bool isKnownAttribute(const QualifiedName&); - ANIMATED_PROPERTY_DECLARATIONS(SVGTextContentElement, SVGLength, SVGLength, TextLength, textLength) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextContentElement, int, int, LengthAdjust, lengthAdjust) + protected: + virtual const SVGElement* contextElement() const { return this; } + + private: + ANIMATED_PROPERTY_DECLARATIONS(SVGTextContentElement, SVGTextContentElementIdentifier, SVGNames::textLengthAttrString, SVGLength, TextLength, textLength) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextContentElement, SVGTextContentElementIdentifier, SVGNames::lengthAdjustAttrString, int, LengthAdjust, lengthAdjust) }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGTextElement.cpp b/WebCore/svg/SVGTextElement.cpp index d316dd0..1ace1a9 100644 --- a/WebCore/svg/SVGTextElement.cpp +++ b/WebCore/svg/SVGTextElement.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -38,7 +38,7 @@ namespace WebCore { SVGTextElement::SVGTextElement(const QualifiedName& tagName, Document* doc) : SVGTextPositioningElement(tagName, doc) , SVGTransformable() - , m_transform(new SVGTransformList(SVGNames::transformAttr)) + , m_transform(this, SVGNames::transformAttr, SVGTransformList::create(SVGNames::transformAttr)) { } @@ -46,8 +46,6 @@ SVGTextElement::~SVGTextElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGTextElement, SVGTransformList*, TransformList, transformList, Transform, transform, SVGNames::transformAttr, m_transform.get()) - void SVGTextElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::transformAttr) { @@ -94,7 +92,14 @@ AffineTransform SVGTextElement::getCTM() const AffineTransform SVGTextElement::animatedLocalTransform() const { - return transform()->concatenate().matrix(); + return m_supplementalTransform ? transform()->concatenate().matrix() * *m_supplementalTransform : transform()->concatenate().matrix(); +} + +AffineTransform* SVGTextElement::supplementalTransform() +{ + if (!m_supplementalTransform) + m_supplementalTransform.set(new AffineTransform()); + return m_supplementalTransform.get(); } RenderObject* SVGTextElement::createRenderer(RenderArena* arena, RenderStyle* style) @@ -104,12 +109,26 @@ RenderObject* SVGTextElement::createRenderer(RenderArena* arena, RenderStyle* st bool SVGTextElement::childShouldCreateRenderer(Node* child) const { - if (child->isTextNode() || child->hasTagName(SVGNames::tspanTag) || - child->hasTagName(SVGNames::trefTag) || child->hasTagName(SVGNames::aTag) || child->hasTagName(SVGNames::textPathTag)) + if (child->isTextNode() +#if ENABLE(SVG_FONTS) + || child->hasTagName(SVGNames::altGlyphTag) +#endif + || child->hasTagName(SVGNames::tspanTag) || child->hasTagName(SVGNames::trefTag) || child->hasTagName(SVGNames::aTag) || child->hasTagName(SVGNames::textPathTag)) return true; return false; } +void SVGTextElement::svgAttributeChanged(const QualifiedName& attrName) +{ + SVGTextPositioningElement::svgAttributeChanged(attrName); + + if (!renderer()) + return; + + if (SVGTextPositioningElement::isKnownAttribute(attrName)) + renderer()->setNeedsLayout(true); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTextElement.h b/WebCore/svg/SVGTextElement.h index 3e5c1e0..3ae6139 100644 --- a/WebCore/svg/SVGTextElement.h +++ b/WebCore/svg/SVGTextElement.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -44,16 +44,18 @@ namespace WebCore { virtual AffineTransform getCTM() const; virtual AffineTransform getScreenCTM() const; virtual AffineTransform animatedLocalTransform() const; + virtual AffineTransform* supplementalTransform(); virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); virtual bool childShouldCreateRenderer(Node*) const; - protected: - virtual const SVGElement* contextElement() const { return this; } + virtual void svgAttributeChanged(const QualifiedName&); private: - mutable AffineTransform m_localMatrix; - ANIMATED_PROPERTY_DECLARATIONS(SVGTextElement, SVGTransformList*, RefPtr<SVGTransformList>, Transform, transform) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextElement, SVGNames::textTagString, SVGNames::transformAttrString, SVGTransformList, Transform, transform) + + // Used by <animateMotion> + OwnPtr<AffineTransform> m_supplementalTransform; }; } // namespace WebCore diff --git a/WebCore/svg/SVGTextPathElement.cpp b/WebCore/svg/SVGTextPathElement.cpp index 47c08f5..d9c5f13 100644 --- a/WebCore/svg/SVGTextPathElement.cpp +++ b/WebCore/svg/SVGTextPathElement.cpp @@ -38,9 +38,9 @@ namespace WebCore { SVGTextPathElement::SVGTextPathElement(const QualifiedName& tagName, Document* doc) : SVGTextContentElement(tagName, doc) , SVGURIReference() - , m_startOffset(this, LengthModeOther) - , m_method(SVG_TEXTPATH_METHODTYPE_ALIGN) - , m_spacing(SVG_TEXTPATH_SPACINGTYPE_EXACT) + , m_startOffset(this, SVGNames::startOffsetAttr, LengthModeOther) + , m_method(this, SVGNames::methodAttr, SVG_TEXTPATH_METHODTYPE_ALIGN) + , m_spacing(this, SVGNames::spacingAttr, SVG_TEXTPATH_SPACINGTYPE_EXACT) { } @@ -48,16 +48,12 @@ SVGTextPathElement::~SVGTextPathElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGTextPathElement, SVGLength, Length, length, StartOffset, startOffset, SVGNames::startOffsetAttr, m_startOffset) -ANIMATED_PROPERTY_DEFINITIONS(SVGTextPathElement, int, Enumeration, enumeration, Method, method, SVGNames::methodAttr, m_method) -ANIMATED_PROPERTY_DEFINITIONS(SVGTextPathElement, int, Enumeration, enumeration, Spacing, spacing, SVGNames::spacingAttr, m_spacing) - void SVGTextPathElement::parseMappedAttribute(MappedAttribute* attr) { const String& value = attr->value(); if (attr->name() == SVGNames::startOffsetAttr) - setStartOffsetBaseValue(SVGLength(this, LengthModeOther, value)); + setStartOffsetBaseValue(SVGLength(LengthModeOther, value)); else if (attr->name() == SVGNames::methodAttr) { if (value == "align") setSpacingBaseValue(SVG_TEXTPATH_METHODTYPE_ALIGN); @@ -82,8 +78,11 @@ RenderObject* SVGTextPathElement::createRenderer(RenderArena* arena, RenderStyle bool SVGTextPathElement::childShouldCreateRenderer(Node* child) const { - if (child->isTextNode() || child->hasTagName(SVGNames::trefTag) || - child->hasTagName(SVGNames::tspanTag) || child->hasTagName(SVGNames::textPathTag)) + if (child->isTextNode() +#if ENABLE(SVG_FONTS) + || child->hasTagName(SVGNames::altGlyphTag) +#endif + || child->hasTagName(SVGNames::trefTag) || child->hasTagName(SVGNames::tspanTag) || child->hasTagName(SVGNames::textPathTag)) return true; return false; diff --git a/WebCore/svg/SVGTextPathElement.h b/WebCore/svg/SVGTextPathElement.h index 4db7a94..e1dd938 100644 --- a/WebCore/svg/SVGTextPathElement.h +++ b/WebCore/svg/SVGTextPathElement.h @@ -65,21 +65,17 @@ namespace WebCore virtual RenderObject* createRenderer(RenderArena*, RenderStyle*); bool childShouldCreateRenderer(Node*) const; - + protected: virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, SVGLength, SVGLength, StartOffset, startOffset) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, int, int, Method, method) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, int, int, Spacing, spacing) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, SVGNames::textPathTagString, SVGNames::startOffsetAttrString, SVGLength, StartOffset, startOffset) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, SVGNames::textPathTagString, SVGNames::methodAttrString, int, Method, method) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextPathElement, SVGNames::textPathTagString, SVGNames::spacingAttrString, int, Spacing, spacing) }; } // namespace WebCore #endif // ENABLE(SVG) #endif - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGTextPositioningElement.cpp b/WebCore/svg/SVGTextPositioningElement.cpp index 346bd1e..e9ceaa1 100644 --- a/WebCore/svg/SVGTextPositioningElement.cpp +++ b/WebCore/svg/SVGTextPositioningElement.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -31,13 +31,15 @@ namespace WebCore { +char SVGTextPositioningElementIdentifier[] = "SVGTextPositioningElement"; + SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document* doc) : SVGTextContentElement(tagName, doc) - , m_x(new SVGLengthList(SVGNames::xAttr)) - , m_y(new SVGLengthList(SVGNames::yAttr)) - , m_dx(new SVGLengthList(SVGNames::dxAttr)) - , m_dy(new SVGLengthList(SVGNames::dyAttr)) - , m_rotate(new SVGNumberList(SVGNames::rotateAttr)) + , m_x(this, SVGNames::xAttr, SVGLengthList::create(SVGNames::xAttr)) + , m_y(this, SVGNames::yAttr, SVGLengthList::create(SVGNames::yAttr)) + , m_dx(this, SVGNames::dxAttr, SVGLengthList::create(SVGNames::dxAttr)) + , m_dy(this, SVGNames::dyAttr, SVGLengthList::create(SVGNames::dyAttr)) + , m_rotate(this, SVGNames::rotateAttr, SVGNumberList::create(SVGNames::rotateAttr)) { } @@ -45,28 +47,32 @@ SVGTextPositioningElement::~SVGTextPositioningElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGTextPositioningElement, SVGLengthList*, LengthList, lengthList, X, x, SVGNames::xAttr, m_x.get()) -ANIMATED_PROPERTY_DEFINITIONS(SVGTextPositioningElement, SVGLengthList*, LengthList, lengthList, Y, y, SVGNames::yAttr, m_y.get()) -ANIMATED_PROPERTY_DEFINITIONS(SVGTextPositioningElement, SVGLengthList*, LengthList, lengthList, Dx, dx, SVGNames::dxAttr, m_dx.get()) -ANIMATED_PROPERTY_DEFINITIONS(SVGTextPositioningElement, SVGLengthList*, LengthList, lengthList, Dy, dy, SVGNames::dyAttr, m_dy.get()) -ANIMATED_PROPERTY_DEFINITIONS(SVGTextPositioningElement, SVGNumberList*, NumberList, numberList, Rotate, rotate, SVGNames::rotateAttr, m_rotate.get()) - void SVGTextPositioningElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::xAttr) - xBaseValue()->parse(attr->value(), this, LengthModeWidth); + xBaseValue()->parse(attr->value(), LengthModeWidth); else if (attr->name() == SVGNames::yAttr) - yBaseValue()->parse(attr->value(), this, LengthModeHeight); + yBaseValue()->parse(attr->value(), LengthModeHeight); else if (attr->name() == SVGNames::dxAttr) - dxBaseValue()->parse(attr->value(), this, LengthModeWidth); + dxBaseValue()->parse(attr->value(), LengthModeWidth); else if (attr->name() == SVGNames::dyAttr) - dyBaseValue()->parse(attr->value(), this, LengthModeHeight); + dyBaseValue()->parse(attr->value(), LengthModeHeight); else if (attr->name() == SVGNames::rotateAttr) rotateBaseValue()->parse(attr->value()); else SVGTextContentElement::parseMappedAttribute(attr); } +bool SVGTextPositioningElement::isKnownAttribute(const QualifiedName& attrName) +{ + return (attrName.matches(SVGNames::xAttr) || + attrName.matches(SVGNames::yAttr) || + attrName.matches(SVGNames::dxAttr) || + attrName.matches(SVGNames::dyAttr) || + attrName.matches(SVGNames::rotateAttr) || + SVGTextContentElement::isKnownAttribute(attrName)); +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTextPositioningElement.h b/WebCore/svg/SVGTextPositioningElement.h index fc4251c..3e01dab 100644 --- a/WebCore/svg/SVGTextPositioningElement.h +++ b/WebCore/svg/SVGTextPositioningElement.h @@ -1,6 +1,6 @@ /* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005, 2006 Rob Buis <buis@kde.org> + 2004, 2005, 2006, 2008 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -25,11 +25,12 @@ #if ENABLE(SVG) #include "SVGTextContentElement.h" +#include "SVGLengthList.h" +#include "SVGNumberList.h" namespace WebCore { - class SVGLengthList; - class SVGNumberList; + extern char SVGTextPositioningElementIdentifier[]; class SVGTextPositioningElement : public SVGTextContentElement { public: @@ -38,12 +39,14 @@ namespace WebCore { virtual void parseMappedAttribute(MappedAttribute*); + bool isKnownAttribute(const QualifiedName&); + private: - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGLengthList*, RefPtr<SVGLengthList>, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGLengthList*, RefPtr<SVGLengthList>, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGLengthList*, RefPtr<SVGLengthList>, Dx, dx) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGLengthList*, RefPtr<SVGLengthList>, Dy, dy) - ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGNumberList*, RefPtr<SVGNumberList>, Rotate, rotate) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::xAttrString, SVGLengthList, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::yAttrString, SVGLengthList, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::dxAttrString, SVGLengthList, Dx, dx) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::dyAttrString, SVGLengthList, Dy, dy) + ANIMATED_PROPERTY_DECLARATIONS(SVGTextPositioningElement, SVGTextPositioningElementIdentifier, SVGNames::rotateAttrString, SVGNumberList, Rotate, rotate) }; } // namespace WebCore diff --git a/WebCore/svg/SVGTimer.cpp b/WebCore/svg/SVGTimer.cpp deleted file mode 100644 index 270793b..0000000 --- a/WebCore/svg/SVGTimer.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - Copyright (C) 2006 Apple Computer, Inc. - Copyright (C) 2007 Eric Seidel <eric@webkit.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" -#if ENABLE(SVG) -#include "SVGTimer.h" - -#include <wtf/HashMap.h> -#include "SVGAnimateTransformElement.h" -#include "SVGAnimateMotionElement.h" -#include "SVGTransformList.h" -#include "SVGAnimateColorElement.h" -#include "SVGStyledTransformableElement.h" - -namespace WebCore { - -SVGTimer::SVGTimer(TimeScheduler* scheduler, double interval, bool singleShot) - : Timer<TimeScheduler>(scheduler, &TimeScheduler::timerFired) - , m_scheduler(scheduler) - , m_interval(interval) - , m_singleShot(singleShot) -{ -} - -void SVGTimer::start() -{ - if (m_singleShot) - startOneShot(m_interval); - else - startRepeating(m_interval); -} - -SVGTimer::TargetAnimationMap SVGTimer::animationsByElement(double elapsedSeconds) -{ - // Build a list of all animations which apply to each element - // FIXME: This list should be sorted by animation priority - TargetAnimationMap targetMap; -#if ENABLE(SVG_ANIMATION) - ExceptionCode ec = 0; - SVGNotifySet::const_iterator end = m_notifySet.end(); - for (SVGNotifySet::const_iterator it = m_notifySet.begin(); it != end; ++it) { - SVGAnimationElement* animation = *it; - - // If we're dealing with a disabled element with fill="freeze", - // we have to take it into account for further calculations. - if (!m_enabledNotifySet.contains(animation)) { - if (!animation->isFrozen()) - continue; - if (elapsedSeconds <= (animation->getStartTime() + animation->getSimpleDuration(ec))) - continue; - } - - SVGElement* target = const_cast<SVGElement*>(animation->targetElement()); - TargetAnimationMap::iterator i = targetMap.find(target); - if (i != targetMap.end()) - i->second.append(animation); - else { - Vector<SVGAnimationElement*> list; - list.append(animation); - targetMap.set(target, list); - } - } -#endif - return targetMap; -} - -// FIXME: This funtion will eventually become part of the AnimationCompositor -void SVGTimer::applyAnimations(double elapsedSeconds, const SVGTimer::TargetAnimationMap& targetMap) -{ -#if ENABLE(SVG_ANIMATION) - TargetAnimationMap::const_iterator targetIterator = targetMap.begin(); - TargetAnimationMap::const_iterator tend = targetMap.end(); - for (; targetIterator != tend; ++targetIterator) { - // FIXME: This is still not 100% correct. Correct would be: - // 1. Walk backwards through the priority list until a replace (!isAdditive()) is found - // -- This optimization is not possible without careful consideration for dependent values (such as cx and fx in SVGRadialGradient) - // 2. Set the initial value (or last replace) as the new animVal - // 3. Call each enabled animation in turn, to have it apply its changes - // 4. After building a new animVal, set it on the element. - - // Currenly we use the actual animVal on the element as "temporary storage" - // and abstract the getting/setting of the attributes into the SVGAnimate* classes - - unsigned count = targetIterator->second.size(); - for (unsigned i = 0; i < count; ++i) { - SVGAnimationElement* animation = targetIterator->second[i]; - - if (!animation->isValidAnimation()) - continue; - - if (!animation->updateAnimationBaseValueFromElement()) - continue; - - if (!animation->updateAnimatedValueForElapsedSeconds(elapsedSeconds)) - continue; - - animation->applyAnimatedValueToElement(); - } - } - - // Make a second pass through the map to avoid multiple setChanged calls on the same element. - for (targetIterator = targetMap.begin(); targetIterator != tend; ++targetIterator) { - SVGElement* key = targetIterator->first; - if (key && key->isStyled()) - static_cast<SVGStyledElement*>(key)->setChanged(); - } -#endif -} - -void SVGTimer::notifyAll() -{ -#if ENABLE(SVG_ANIMATION) - if (m_enabledNotifySet.isEmpty()) - return; - - // First build a list of animation elements per target element - double elapsedSeconds = m_scheduler->elapsed() * 1000.0; // Take time now. - TargetAnimationMap targetMap = animationsByElement(elapsedSeconds); - - // Then composite those animations down to final values and apply - applyAnimations(elapsedSeconds, targetMap); -#endif -} - -void SVGTimer::addNotify(SVGAnimationElement* element, bool enabled) -{ -#if ENABLE(SVG_ANIMATION) - m_notifySet.add(element); - if (enabled) - m_enabledNotifySet.add(element); - else - m_enabledNotifySet.remove(element); -#endif -} - -void SVGTimer::removeNotify(SVGAnimationElement *element) -{ -#if ENABLE(SVG_ANIMATION) - // FIXME: Why do we keep a pointer to the element forever (marked disabled)? - // That can't be right! - - m_enabledNotifySet.remove(element); - if (m_enabledNotifySet.isEmpty()) - stop(); -#endif -} - -} // namespace - -// vim:ts=4:noet -#endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTimer.h b/WebCore/svg/SVGTimer.h deleted file mode 100644 index 19e164c..0000000 --- a/WebCore/svg/SVGTimer.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - Copyright (C) 2006 Apple Computer, Inc. - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#if ENABLE(SVG) - -#include "TimeScheduler.h" -#include "Timer.h" -#include <wtf/HashSet.h> -#include <wtf/HashMap.h> - -namespace WebCore { - -class SVGElement; -class SVGAnimationElement; - -typedef HashSet<SVGAnimationElement*> SVGNotifySet; - -class SVGTimer : private Timer<TimeScheduler> -{ -public: - SVGTimer(TimeScheduler*, double interval, bool singleShot); - - void start(); - using Timer<TimeScheduler>::stop; - using Timer<TimeScheduler>::isActive; - - void notifyAll(); - void addNotify(SVGAnimationElement*, bool enabled = false); - void removeNotify(SVGAnimationElement*); - - static SVGTimer* downcast(Timer<TimeScheduler>* t) { return static_cast<SVGTimer*>(t); } - -private: - typedef HashMap<SVGElement*, Vector<SVGAnimationElement*> > TargetAnimationMap; - TargetAnimationMap animationsByElement(double elapsedTime); - void applyAnimations(double elapsedSeconds, const SVGTimer::TargetAnimationMap& targetMap); - - TimeScheduler* m_scheduler; - double m_interval; - bool m_singleShot; - - SVGNotifySet m_notifySet; - SVGNotifySet m_enabledNotifySet; -}; - -} // namespace - -#endif // ENABLE(SVG) - -// vim:ts=4:noet diff --git a/WebCore/svg/SVGTitleElement.cpp b/WebCore/svg/SVGTitleElement.cpp index dba882c..3e23a1b 100644 --- a/WebCore/svg/SVGTitleElement.cpp +++ b/WebCore/svg/SVGTitleElement.cpp @@ -46,9 +46,9 @@ void SVGTitleElement::removedFromDocument() document()->removeTitle(this); } -void SVGTitleElement::childrenChanged(bool changedByParser) +void SVGTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGElement::childrenChanged(changedByParser); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (inDocument()) document()->setTitle(textContent(), this); } diff --git a/WebCore/svg/SVGTitleElement.h b/WebCore/svg/SVGTitleElement.h index be5a301..cd4768c 100644 --- a/WebCore/svg/SVGTitleElement.h +++ b/WebCore/svg/SVGTitleElement.h @@ -37,7 +37,7 @@ namespace WebCore virtual void insertedIntoDocument(); virtual void removedFromDocument(); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual bool rendererIsNeeded(RenderStyle*) { return false; } }; diff --git a/WebCore/svg/SVGTransform.cpp b/WebCore/svg/SVGTransform.cpp index eab8868..86477e4 100644 --- a/WebCore/svg/SVGTransform.cpp +++ b/WebCore/svg/SVGTransform.cpp @@ -83,7 +83,7 @@ FloatPoint SVGTransform::rotationCenter() const return m_center; } -void SVGTransform::setMatrix(const AffineTransform& matrix) +void SVGTransform::setMatrix(AffineTransform matrix) //const AffineTransform& matrix) { m_type = SVG_TRANSFORM_MATRIX; m_angle = 0; diff --git a/WebCore/svg/SVGTransform.h b/WebCore/svg/SVGTransform.h index a8bcb8e..c3c150c 100644 --- a/WebCore/svg/SVGTransform.h +++ b/WebCore/svg/SVGTransform.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> This file is part of the KDE project @@ -22,12 +22,11 @@ #ifndef SVGTransform_h #define SVGTransform_h -#if ENABLE(SVG) +#if ENABLE(SVG) #include "AffineTransform.h" #include "FloatPoint.h" -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> +#include "SVGNames.h" namespace WebCore { @@ -57,7 +56,9 @@ namespace WebCore { float angle() const; FloatPoint rotationCenter() const; - void setMatrix(const AffineTransform&); +// void setMatrix(const AffineTransform&); + void setMatrix(AffineTransform); + void setTranslate(float tx, float ty); void setScale(float sx, float sy); void setRotate(float angle, float cx, float cy); @@ -70,6 +71,9 @@ namespace WebCore { bool isValid(); + // Throughout SVG 1.1 'SVGTransform' is only used for the 'transform' attribute + const QualifiedName& associatedAttributeName() const { return SVGNames::transformAttr; } + private: SVGTransformType m_type; float m_angle; diff --git a/WebCore/svg/SVGTransformDistance.cpp b/WebCore/svg/SVGTransformDistance.cpp index df86b0f..59c24a5 100644 --- a/WebCore/svg/SVGTransformDistance.cpp +++ b/WebCore/svg/SVGTransformDistance.cpp @@ -77,8 +77,8 @@ SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform, } case SVGTransform::SVG_TRANSFORM_SCALE: { - float scaleX = fromSVGTransform.scale().width() != 0 ? toSVGTransform.scale().width() / fromSVGTransform.scale().width() : toSVGTransform.scale().width() / 0.00001f; - float scaleY = fromSVGTransform.scale().height() != 0 ? toSVGTransform.scale().height() / fromSVGTransform.scale().height() : toSVGTransform.scale().height() / 0.00001f; + float scaleX = toSVGTransform.scale().width() - fromSVGTransform.scale().width(); + float scaleY = toSVGTransform.scale().height() - fromSVGTransform.scale().height(); m_transform.scale(scaleX, scaleY); return; } diff --git a/WebCore/svg/SVGTransformList.cpp b/WebCore/svg/SVGTransformList.cpp index 9b75848..9800922 100644 --- a/WebCore/svg/SVGTransformList.cpp +++ b/WebCore/svg/SVGTransformList.cpp @@ -82,4 +82,16 @@ SVGTransform SVGTransformList::concatenateForType(SVGTransform::SVGTransformType return totalTransform.addToSVGTransform(SVGTransform()); } +String SVGTransformList::valueAsString() const +{ + // TODO: We may want to build a real transform string, instead of concatting to a matrix(...). + SVGTransform transform = concatenate(); + if (transform.type() == SVGTransform::SVG_TRANSFORM_MATRIX) { + AffineTransform matrix = transform.matrix(); + return String::format("matrix(%f %f %f %f %f %f)", matrix.a(), matrix.b(), matrix.c(), matrix.d(), matrix.e(), matrix.f()); + } + + return String(); +} + #endif // ENABLE(SVG) diff --git a/WebCore/svg/SVGTransformList.h b/WebCore/svg/SVGTransformList.h index e41d393..a405c58 100644 --- a/WebCore/svg/SVGTransformList.h +++ b/WebCore/svg/SVGTransformList.h @@ -26,12 +26,15 @@ #if ENABLE(SVG) #include "SVGList.h" #include "SVGTransform.h" +#include <wtf/PassRefPtr.h> namespace WebCore { + class String; + class SVGTransformList : public SVGPODList<SVGTransform> { public: - SVGTransformList(const QualifiedName&); + static PassRefPtr<SVGTransformList> create(const QualifiedName& attributeName) { return adoptRef(new SVGTransformList(attributeName)); } virtual ~SVGTransformList(); SVGTransform createSVGTransformFromMatrix(const AffineTransform&) const; @@ -40,6 +43,11 @@ namespace WebCore { // Internal use only SVGTransform concatenate() const; SVGTransform concatenateForType(SVGTransform::SVGTransformType) const; + + String valueAsString() const; + + private: + SVGTransformList(const QualifiedName&); }; } // namespace WebCore diff --git a/WebCore/svg/SVGTransformable.h b/WebCore/svg/SVGTransformable.h index 1b1813f..de806a3 100644 --- a/WebCore/svg/SVGTransformable.h +++ b/WebCore/svg/SVGTransformable.h @@ -26,13 +26,13 @@ #if ENABLE(SVG) #include "PlatformString.h" #include "SVGLocatable.h" +#include "SVGTransformList.h" namespace WebCore { class AffineTransform; class AtomicString; class SVGTransform; - class SVGTransformList; class QualifiedName; class SVGTransformable : virtual public SVGLocatable { diff --git a/WebCore/svg/SVGURIReference.cpp b/WebCore/svg/SVGURIReference.cpp index 5a2cabc..d18e49a 100644 --- a/WebCore/svg/SVGURIReference.cpp +++ b/WebCore/svg/SVGURIReference.cpp @@ -23,13 +23,12 @@ #if ENABLE(SVG) #include "SVGURIReference.h" -#include "SVGNames.h" -#include "SVGStyledElement.h" -#include "XLinkNames.h" - namespace WebCore { +char SVGURIReferenceIdentifier[] = "SVGURIReference"; + SVGURIReference::SVGURIReference() + : m_href(this, XLinkNames::hrefAttr) { } @@ -37,8 +36,6 @@ SVGURIReference::~SVGURIReference() { } -ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(SVGURIReference, String, String, string, Href, href, XLinkNames::hrefAttr, m_href) - bool SVGURIReference::parseMappedAttribute(MappedAttribute* attr) { if (attr->name().matches(XLinkNames::hrefAttr)) { diff --git a/WebCore/svg/SVGURIReference.h b/WebCore/svg/SVGURIReference.h index 22f2f45..35ac640 100644 --- a/WebCore/svg/SVGURIReference.h +++ b/WebCore/svg/SVGURIReference.h @@ -25,9 +25,11 @@ #if ENABLE(SVG) #include "SVGElement.h" +#include "XLinkNames.h" namespace WebCore { + extern char SVGURIReferenceIdentifier[]; class MappedAttribute; class SVGURIReference { @@ -40,11 +42,10 @@ namespace WebCore { static String getTarget(const String& url); - protected: virtual const SVGElement* contextElement() const = 0; private: - ANIMATED_PROPERTY_DECLARATIONS_WITH_CONTEXT(SVGURIReference, String, String, Href, href) + ANIMATED_PROPERTY_DECLARATIONS(SVGURIReference, SVGURIReferenceIdentifier, XLinkNames::hrefAttrString, String, Href, href) }; } // namespace WebCore diff --git a/WebCore/svg/SVGUnitTypes.h b/WebCore/svg/SVGUnitTypes.h index 8f8b0cd..6be737f 100644 --- a/WebCore/svg/SVGUnitTypes.h +++ b/WebCore/svg/SVGUnitTypes.h @@ -28,8 +28,7 @@ namespace WebCore { -class SVGUnitTypes : public RefCounted<SVGUnitTypes> -{ +class SVGUnitTypes : public RefCounted<SVGUnitTypes> { public: enum SVGUnitType { SVG_UNIT_TYPE_UNKNOWN = 0, @@ -37,8 +36,8 @@ public: SVG_UNIT_TYPE_OBJECTBOUNDINGBOX = 2 }; - SVGUnitTypes() { } - ~SVGUnitTypes() { } +private: + SVGUnitTypes() { } }; } // namespace WebCore diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp index 2944b33..83ad559 100644 --- a/WebCore/svg/SVGUseElement.cpp +++ b/WebCore/svg/SVGUseElement.cpp @@ -35,19 +35,21 @@ #include "CString.h" #include "Document.h" #include "Event.h" +#include "EventListener.h" #include "HTMLNames.h" +#include "NodeRenderStyle.h" +#include "RegisteredEventListener.h" #include "RenderSVGTransformableContainer.h" #include "SVGElementInstance.h" #include "SVGElementInstanceList.h" #include "SVGGElement.h" #include "SVGLength.h" -#include "SVGNames.h" #include "SVGPreserveAspectRatio.h" +#include "SVGSMILElement.h" #include "SVGSVGElement.h" #include "SVGSymbolElement.h" #include "XLinkNames.h" #include "XMLSerializer.h" -#include <wtf/OwnPtr.h> namespace WebCore { @@ -57,10 +59,10 @@ SVGUseElement::SVGUseElement(const QualifiedName& tagName, Document* doc) , SVGLangSpace() , SVGExternalResourcesRequired() , SVGURIReference() - , m_x(this, LengthModeWidth) - , m_y(this, LengthModeHeight) - , m_width(this, LengthModeWidth) - , m_height(this, LengthModeHeight) + , m_x(this, SVGNames::xAttr, LengthModeWidth) + , m_y(this, SVGNames::yAttr, LengthModeHeight) + , m_width(this, SVGNames::widthAttr, LengthModeWidth) + , m_height(this, SVGNames::heightAttr, LengthModeHeight) { } @@ -68,11 +70,6 @@ SVGUseElement::~SVGUseElement() { } -ANIMATED_PROPERTY_DEFINITIONS(SVGUseElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) -ANIMATED_PROPERTY_DEFINITIONS(SVGUseElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) -ANIMATED_PROPERTY_DEFINITIONS(SVGUseElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) -ANIMATED_PROPERTY_DEFINITIONS(SVGUseElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) - SVGElementInstance* SVGUseElement::instanceRoot() const { return m_targetElementInstance.get(); @@ -87,16 +84,16 @@ SVGElementInstance* SVGUseElement::animatedInstanceRoot() const void SVGUseElement::parseMappedAttribute(MappedAttribute* attr) { if (attr->name() == SVGNames::xAttr) - setXBaseValue(SVGLength(this, LengthModeWidth, attr->value())); + setXBaseValue(SVGLength(LengthModeWidth, attr->value())); else if (attr->name() == SVGNames::yAttr) - setYBaseValue(SVGLength(this, LengthModeHeight, attr->value())); + setYBaseValue(SVGLength(LengthModeHeight, attr->value())); else if (attr->name() == SVGNames::widthAttr) { - setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value())); - if (width().value() < 0.0) + setWidthBaseValue(SVGLength(LengthModeWidth, attr->value())); + if (widthBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for use attribute <width> is not allowed"); } else if (attr->name() == SVGNames::heightAttr) { - setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value())); - if (height().value() < 0.0) + setHeightBaseValue(SVGLength(LengthModeHeight, attr->value())); + if (heightBaseValue().value(this) < 0.0) document()->accessSVGExtensions()->reportError("A negative value for use attribute <height> is not allowed"); } else { if (SVGTests::parseMappedAttribute(attr)) @@ -119,10 +116,9 @@ void SVGUseElement::insertedIntoDocument() void SVGUseElement::removedFromDocument() { - SVGElement::removedFromDocument(); - m_targetElementInstance = 0; m_shadowTreeRootElement = 0; + SVGElement::removedFromDocument(); } void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) @@ -139,8 +135,6 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) SVGExternalResourcesRequired::isKnownAttribute(attrName) || SVGURIReference::isKnownAttribute(attrName) || SVGStyledTransformableElement::isKnownAttribute(attrName)) { - // TODO: Now that we're aware of the attribute name, we can finally optimize - // updating <use> attributes - to not reclone every time. buildPendingResource(); if (m_shadowTreeRootElement) @@ -148,9 +142,9 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName) } } -void SVGUseElement::childrenChanged(bool changedByParser) +void SVGUseElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) { - SVGElement::childrenChanged(changedByParser); + SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); if (!attached()) return; @@ -160,9 +154,28 @@ void SVGUseElement::childrenChanged(bool changedByParser) if (m_shadowTreeRootElement) m_shadowTreeRootElement->setChanged(); } + +static bool shadowTreeContainsChangedNodes(SVGElementInstance* target) +{ + if (target->needsUpdate()) + return true; + + for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling()) + if (shadowTreeContainsChangedNodes(instance)) + return true; + + return false; +} void SVGUseElement::recalcStyle(StyleChange change) { + if (attached() && changed() && shadowTreeContainsChangedNodes(m_targetElementInstance.get())) { + buildPendingResource(); + + if (m_shadowTreeRootElement) + m_shadowTreeRootElement->setChanged(); + } + SVGStyledElement::recalcStyle(change); // The shadow tree root element is NOT a direct child element of us. @@ -174,8 +187,8 @@ void SVGUseElement::recalcStyle(StyleChange change) // shadow tree root element, but call attachShadowTree() here. Calling attach() will crash // as the shadow tree root element has no (direct) parent node. Yes, shadow trees are tricky. if (change >= Inherit || m_shadowTreeRootElement->changed()) { - RenderStyle* newStyle = document()->styleSelector()->styleForElement(m_shadowTreeRootElement.get()); - StyleChange ch = m_shadowTreeRootElement->diff(m_shadowTreeRootElement->renderStyle(), newStyle); + RefPtr<RenderStyle> newStyle = document()->styleSelector()->styleForElement(m_shadowTreeRootElement.get()); + StyleChange ch = Node::diff(m_shadowTreeRootElement->renderStyle(), newStyle.get()); if (ch == Detach) { ASSERT(m_shadowTreeRootElement->attached()); m_shadowTreeRootElement->detach(); @@ -184,11 +197,8 @@ void SVGUseElement::recalcStyle(StyleChange change) // attach recalulates the style for all children. No need to do it twice. m_shadowTreeRootElement->setChanged(NoStyleChange); m_shadowTreeRootElement->setHasChangedChild(false); - newStyle->deref(document()->renderArena()); return; } - - newStyle->deref(document()->renderArena()); } // Only change==Detach needs special treatment, for anything else recalcStyle() works. @@ -209,15 +219,31 @@ void dumpInstanceTree(unsigned int& depth, String& text, SVGElementInstance* tar for (unsigned int i = 0; i < depth; ++i) text += " "; - text += String::format("SVGElementInstance (parentNode=%s, firstChild=%s, correspondingElement=%s, id=%s)\n", - parentNodeName.latin1().data(), firstChildNodeName.latin1().data(), elementNodeName.latin1().data(), elementId.latin1().data()); - - depth++; + text += String::format("SVGElementInstance this=%p, (parentNode=%s, firstChild=%s, correspondingElement=%s (%p), shadowTreeElement=%p, id=%s)\n", + targetInstance, parentNodeName.latin1().data(), firstChildNodeName.latin1().data(), elementNodeName.latin1().data(), + element, targetInstance->shadowTreeElement(), elementId.latin1().data()); + + for (unsigned int i = 0; i < depth; ++i) + text += " "; + + HashSet<SVGElementInstance*> elementInstances = element->instancesForElement(); + text += String::format("Corresponding element is associated with %i instance(s):\n", elementInstances.size()); + + HashSet<SVGElementInstance*>::iterator end = elementInstances.end(); + for (HashSet<SVGElementInstance*>::iterator it = elementInstances.begin(); it != end; ++it) { + for (unsigned int i = 0; i < depth; ++i) + text += " "; + + text += String::format(" -> SVGElementInstance this=%p, (refCount: %i, shadowTreeElement in document? %i)\n", + *it, (*it)->refCount(), (*it)->shadowTreeElement()->inDocument()); + } + + ++depth; for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling()) dumpInstanceTree(depth, text, instance); - depth--; + --depth; } #endif @@ -228,6 +254,10 @@ static bool isDisallowedElement(Node* element) if (element->hasTagName(SVGNames::foreignObjectTag)) return true; #endif +#if ENABLE(SVG_ANIMATION) + if (SVGSMILElement::isSMILElement(element)) + return true; +#endif return false; } @@ -271,10 +301,14 @@ void SVGUseElement::buildPendingResource() if (targetElement && targetElement->isSVGElement()) target = static_cast<SVGElement*>(targetElement); + if (m_targetElementInstance) { + m_targetElementInstance->forgetWrapper(); + m_targetElementInstance = 0; + } + // Do not allow self-referencing. // 'target' may be null, if it's a non SVG namespaced element. if (!target || target == this) { - m_targetElementInstance = 0; m_shadowTreeRootElement = 0; return; } @@ -315,8 +349,8 @@ void SVGUseElement::buildPendingResource() // Spec: An additional transformation translate(x,y) is appended to the end // (i.e., right-side) of the transform attribute on the generated 'g', where x // and y represent the values of the x and y attributes on the 'use' element. - if (x().value() != 0.0 || y().value() != 0.0) { - String transformString = String::format("translate(%f, %f)", x().value(), y().value()); + if (x().value(this) != 0.0 || y().value(this) != 0.0) { + String transformString = String::format("translate(%f, %f)", x().value(this), y().value(this)); m_shadowTreeRootElement->setAttribute(SVGNames::transformAttr, transformString); } @@ -351,7 +385,8 @@ void SVGUseElement::buildPendingResource() // Eventually dump shadow tree #ifdef DUMP_SHADOW_TREE ExceptionCode ec = 0; - OwnPtr<XMLSerializer> serializer(new XMLSerializer()); + + PassRefPtr<XMLSerializer> serializer = XMLSerializer::create(); String markup = serializer->serializeToString(m_shadowTreeRootElement.get(), ec); ASSERT(ec == 0); @@ -359,6 +394,9 @@ void SVGUseElement::buildPendingResource() fprintf(stderr, "Dumping <use> shadow tree markup:\n%s\n", markup.latin1().data()); #endif + // Transfer event listeners assigned to the referenced element to our shadow tree elements. + transferEventListenersToShadowTree(m_targetElementInstance.get()); + // The DOM side is setup properly. Now we have to attach the root shadow // tree element manually - using attach() won't work for "shadow nodes". attachShadowTree(); @@ -436,9 +474,7 @@ void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* ta // Create SVGElementInstance object, for both container/non-container nodes. SVGElementInstance* instancePtr = new SVGElementInstance(this, element); - - RefPtr<SVGElementInstance> instance = instancePtr; - targetInstance->appendChild(instance.release()); + targetInstance->appendChild(instancePtr); // Enter recursion, appending new instance tree nodes to the "instance" object. if (element->hasChildNodes()) @@ -447,16 +483,16 @@ void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* ta // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree. if (element->hasTagName(SVGNames::useTag)) - handleDeepUseReferencing(element, instancePtr, foundProblem); + handleDeepUseReferencing(static_cast<SVGUseElement*>(element), instancePtr, foundProblem); } // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree. if (target->hasTagName(SVGNames::useTag)) - handleDeepUseReferencing(target, targetInstance, foundProblem); + handleDeepUseReferencing(static_cast<SVGUseElement*>(target), targetInstance, foundProblem); } -void SVGUseElement::handleDeepUseReferencing(SVGElement* use, SVGElementInstance* targetInstance, bool& foundProblem) +void SVGUseElement::handleDeepUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, bool& foundProblem) { String id = SVGURIReference::getTarget(use->href()); Element* targetElement = document()->getElementById(id); @@ -496,8 +532,8 @@ void SVGUseElement::handleDeepUseReferencing(SVGElement* use, SVGElementInstance void SVGUseElement::alterShadowTreeForSVGTag(SVGElement* target) { - String widthString = String::number(width().value()); - String heightString = String::number(height().value()); + String widthString = String::number(width().value(this)); + String heightString = String::number(height().value(this)); if (hasAttribute(SVGNames::widthAttr)) target->setAttribute(SVGNames::widthAttr, widthString); @@ -506,21 +542,19 @@ void SVGUseElement::alterShadowTreeForSVGTag(SVGElement* target) target->setAttribute(SVGNames::heightAttr, heightString); } -void SVGUseElement::removeDisallowedElementsFromSubtree(Node* element) +void SVGUseElement::removeDisallowedElementsFromSubtree(Node* subtree) { - ExceptionCode ec = 0; - - for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling()) { - if (isDisallowedElement(child.get())) { - ASSERT(child->parent()); - child->parent()->removeChild(child.get(), ec); - ASSERT(ec == 0); - - continue; - } - - if (child->hasChildNodes()) - removeDisallowedElementsFromSubtree(child.get()); + ASSERT(!subtree->inDocument()); + ExceptionCode ec; + Node* node = subtree->firstChild(); + while (node) { + if (isDisallowedElement(node)) { + Node* next = node->traverseNextSibling(subtree); + // The subtree is not in document so this won't generate events that could mutate the tree. + node->parent()->removeChild(node, ec); + node = next; + } else + node = node->traverseNextNode(subtree); } } @@ -585,12 +619,12 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element) // Spec: An additional transformation translate(x,y) is appended to the end // (i.e., right-side) of the transform attribute on the generated 'g', where x // and y represent the values of the x and y attributes on the 'use' element. - if (use->x().value() != 0.0 || use->y().value() != 0.0) { + if (use->x().value(this) != 0.0 || use->y().value(this) != 0.0) { if (!cloneParent->hasAttribute(SVGNames::transformAttr)) { - String transformString = String::format("translate(%f, %f)", use->x().value(), use->y().value()); + String transformString = String::format("translate(%f, %f)", use->x().value(this), use->y().value(this)); cloneParent->setAttribute(SVGNames::transformAttr, transformString); } else { - String transformString = String::format(" translate(%f, %f)", use->x().value(), use->y().value()); + String transformString = String::format(" translate(%f, %f)", use->x().value(this), use->y().value(this)); const AtomicString& transformAttribute = cloneParent->getAttribute(SVGNames::transformAttr); cloneParent->setAttribute(SVGNames::transformAttr, transformAttribute + transformString); } @@ -658,11 +692,11 @@ void SVGUseElement::expandSymbolElementsInShadowTree(Node* element) RefPtr<SVGSVGElement> svgElement = new SVGSVGElement(SVGNames::svgTag, document()); // Transfer all attributes from <symbol> to the new <svg> element - *svgElement->attributes() = *element->attributes(); + svgElement->attributes()->setAttributes(*element->attributes()); // Explicitly re-set width/height values - String widthString = String::number(width().value()); - String heightString = String::number(height().value()); + String widthString = String::number(width().value(this)); + String heightString = String::number(height().value(this)); svgElement->setAttribute(SVGNames::widthAttr, hasAttribute(SVGNames::widthAttr) ? widthString : "100%"); svgElement->setAttribute(SVGNames::heightAttr, hasAttribute(SVGNames::heightAttr) ? heightString : "100%"); @@ -707,24 +741,50 @@ void SVGUseElement::attachShadowTree() // Inspired by RenderTextControl::createSubtreeIfNeeded(). if (renderer()->canHaveChildren() && childShouldCreateRenderer(m_shadowTreeRootElement.get())) { - RenderStyle* style = m_shadowTreeRootElement->styleForRenderer(renderer()); + RefPtr<RenderStyle> style = m_shadowTreeRootElement->styleForRenderer(); - if (m_shadowTreeRootElement->rendererIsNeeded(style)) { - m_shadowTreeRootElement->setRenderer(m_shadowTreeRootElement->createRenderer(document()->renderArena(), style)); + if (m_shadowTreeRootElement->rendererIsNeeded(style.get())) { + m_shadowTreeRootElement->setRenderer(m_shadowTreeRootElement->createRenderer(document()->renderArena(), style.get())); if (RenderObject* shadowRenderer = m_shadowTreeRootElement->renderer()) { - shadowRenderer->setStyle(style); + shadowRenderer->setStyle(style.release()); renderer()->addChild(shadowRenderer, m_shadowTreeRootElement->nextRenderer()); m_shadowTreeRootElement->setAttached(); } } - style->deref(document()->renderArena()); - // This will take care of attaching all shadow tree child nodes. for (Node* child = m_shadowTreeRootElement->firstChild(); child; child = child->nextSibling()) child->attach(); } } + +void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* target) +{ + if (!target) + return; + + SVGElement* originalElement = target->correspondingElement(); + ASSERT(originalElement); + + if (SVGElement* shadowTreeElement = target->shadowTreeElement()) { + if (RegisteredEventListenerList* localEventListeners = originalElement->localEventListeners()) { + RegisteredEventListenerList::Iterator end = localEventListeners->end(); + for (RegisteredEventListenerList::Iterator it = localEventListeners->begin(); it != end; ++it) { + EventListener* listener = (*it)->listener(); + ASSERT(listener); + + // Event listeners created from markup have already been transfered to the shadow tree during cloning! + if (listener->wasCreatedFromMarkup()) + continue; + + shadowTreeElement->addEventListener((*it)->eventType(), listener, (*it)->useCapture()); + } + } + } + + for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling()) + transferEventListenersToShadowTree(instance); +} void SVGUseElement::associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance) { @@ -742,7 +802,9 @@ void SVGUseElement::associateInstancesWithShadowTreeElements(Node* target, SVGEl #endif } else if (originalElement->hasTagName(SVGNames::symbolTag)) { // <symbol> gets replaced by <svg> +#if ENABLE(SVG) && ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) ASSERT(target->nodeName() == SVGNames::svgTag); +#endif } else ASSERT(target->nodeName() == originalElement->nodeName()); @@ -792,7 +854,7 @@ void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVG ASSERT(from); ASSERT(to); - *to->attributes() = *from->attributes(); + to->attributes()->setAttributes(*from->attributes()); ExceptionCode ec = 0; diff --git a/WebCore/svg/SVGUseElement.h b/WebCore/svg/SVGUseElement.h index 0428811..1e5b81c 100644 --- a/WebCore/svg/SVGUseElement.h +++ b/WebCore/svg/SVGUseElement.h @@ -54,7 +54,7 @@ namespace WebCore { virtual void buildPendingResource(); virtual void parseMappedAttribute(MappedAttribute*); - virtual void childrenChanged(bool changedByParser = false); + virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0); virtual void svgAttributeChanged(const QualifiedName&); virtual void recalcStyle(StyleChange = NoChange); @@ -65,31 +65,26 @@ namespace WebCore { virtual Path toClipPath() const; + static void removeDisallowedElementsFromSubtree(Node* element); + SVGElementInstance* instanceForShadowTreeElement(Node* element) const; + protected: virtual const SVGElement* contextElement() const { return this; } private: - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGURIReference, String, Href, href) - - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGLength, SVGLength, X, x) - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGLength, SVGLength, Y, y) - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGLength, SVGLength, Width, width) - ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGLength, SVGLength, Height, height) - - private: - friend class SVGElement; - SVGElementInstance* instanceForShadowTreeElement(Node* element) const; + ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::xAttrString, SVGLength, X, x) + ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::yAttrString, SVGLength, Y, y) + ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::widthAttrString, SVGLength, Width, width) + ANIMATED_PROPERTY_DECLARATIONS(SVGUseElement, SVGNames::useTagString, SVGNames::heightAttrString, SVGLength, Height, height) private: // Instance tree handling void buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundCycle); - void handleDeepUseReferencing(SVGElement* use, SVGElementInstance* targetInstance, bool& foundCycle); + void handleDeepUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, bool& foundCycle); // Shadow tree handling PassRefPtr<SVGSVGElement> buildShadowTreeForSymbolTag(SVGElement* target, SVGElementInstance* targetInstance); void alterShadowTreeForSVGTag(SVGElement* target); - void removeDisallowedElementsFromSubtree(Node* element); void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance); @@ -102,9 +97,10 @@ namespace WebCore { // "Tree connector" void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance); - SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const; + void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const; + void transferEventListenersToShadowTree(SVGElementInstance* target); RefPtr<SVGElement> m_shadowTreeRootElement; RefPtr<SVGElementInstance> m_targetElementInstance; diff --git a/WebCore/svg/SVGViewElement.cpp b/WebCore/svg/SVGViewElement.cpp index 24c08e6..cb16b62 100644 --- a/WebCore/svg/SVGViewElement.cpp +++ b/WebCore/svg/SVGViewElement.cpp @@ -49,7 +49,7 @@ SVGViewElement::~SVGViewElement() SVGStringList* SVGViewElement::viewTarget() const { if (!m_viewTarget) - m_viewTarget = new SVGStringList(SVGNames::viewTargetAttr); + m_viewTarget = SVGStringList::create(SVGNames::viewTargetAttr); return m_viewTarget.get(); } diff --git a/WebCore/svg/SVGViewElement.h b/WebCore/svg/SVGViewElement.h index 17e0d1d..840dea9 100644 --- a/WebCore/svg/SVGViewElement.h +++ b/WebCore/svg/SVGViewElement.h @@ -51,10 +51,6 @@ namespace WebCore { private: mutable RefPtr<SVGStringList> m_viewTarget; - - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGExternalResourcesRequired, bool, ExternalResourcesRequired, externalResourcesRequired) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, FloatRect, ViewBox, viewBox) - ANIMATED_PROPERTY_FORWARD_DECLARATIONS(SVGFitToViewBox, SVGPreserveAspectRatio*, PreserveAspectRatio, preserveAspectRatio) }; } // namespace WebCore diff --git a/WebCore/svg/SVGViewSpec.cpp b/WebCore/svg/SVGViewSpec.cpp index f7a3600..6aa3857 100644 --- a/WebCore/svg/SVGViewSpec.cpp +++ b/WebCore/svg/SVGViewSpec.cpp @@ -23,6 +23,7 @@ #if ENABLE(SVG) #include "SVGViewSpec.h" +#include "Document.h" #include "PlatformString.h" #include "SVGParserUtilities.h" #include "SVGPreserveAspectRatio.h" @@ -35,7 +36,7 @@ namespace WebCore { SVGViewSpec::SVGViewSpec(const SVGSVGElement* contextElement) : SVGFitToViewBox() , SVGZoomAndPan() - , m_transform(new SVGTransformList(SVGNames::transformAttr)) + , m_transform(SVGTransformList::create(SVGNames::transformAttr)) , m_contextElement(contextElement) { } diff --git a/WebCore/svg/SVGViewSpec.h b/WebCore/svg/SVGViewSpec.h index b143634..8624089 100644 --- a/WebCore/svg/SVGViewSpec.h +++ b/WebCore/svg/SVGViewSpec.h @@ -53,7 +53,6 @@ namespace WebCore { String viewTargetString() const { return m_viewTargetString; } SVGElement* viewTarget() const; - protected: virtual const SVGElement* contextElement() const; private: diff --git a/WebCore/svg/SVGZoomEvent.h b/WebCore/svg/SVGZoomEvent.h index 6a92481..a16f131 100644 --- a/WebCore/svg/SVGZoomEvent.h +++ b/WebCore/svg/SVGZoomEvent.h @@ -3,8 +3,6 @@ Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) - This file is part of the KDE project - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either @@ -32,7 +30,7 @@ namespace WebCore { class SVGZoomEvent : public UIEvent { public: - SVGZoomEvent(); + static PassRefPtr<SVGZoomEvent> create() { return adoptRef(new SVGZoomEvent); } virtual ~SVGZoomEvent(); // 'SVGZoomEvent' functions @@ -51,6 +49,8 @@ namespace WebCore { virtual bool isSVGZoomEvent() const; private: + SVGZoomEvent(); + float m_newScale; float m_previousScale; diff --git a/WebCore/svg/SVGZoomEvent.idl b/WebCore/svg/SVGZoomEvent.idl index ac4a1a1..8327bef 100644 --- a/WebCore/svg/SVGZoomEvent.idl +++ b/WebCore/svg/SVGZoomEvent.idl @@ -26,11 +26,11 @@ module svg { interface [Conditional=SVG] SVGZoomEvent : events::UIEvent { - readonly attribute SVGRect zoomRectScreen; + readonly attribute [Immutable] SVGRect zoomRectScreen; readonly attribute float previousScale; - readonly attribute SVGPoint previousTranslate; + readonly attribute [Immutable] SVGPoint previousTranslate; readonly attribute float newScale; - readonly attribute SVGPoint newTranslate; + readonly attribute [Immutable] SVGPoint newTranslate; }; } diff --git a/WebCore/svg/SynchronizableTypeWrapper.h b/WebCore/svg/SynchronizableTypeWrapper.h new file mode 100644 index 0000000..418c76d --- /dev/null +++ b/WebCore/svg/SynchronizableTypeWrapper.h @@ -0,0 +1,180 @@ +/* + Copyright (C) 2008 Nikolas Zimmermann <zimmermann@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef SynchronizableTypeWrapper_h +#define SynchronizableTypeWrapper_h + +#if ENABLE(SVG) +#include <wtf/Noncopyable.h> + +namespace WebCore { + + template<typename StoredType> + class SynchronizableTypeWrapperBase : Noncopyable { + protected: + SynchronizableTypeWrapperBase(); + + template<typename AssignableType> + void assign(AssignableType type); + + bool needsSynchronization() const; + void setSynchronized(); + + protected: + StoredType m_value; + bool m_needsSynchronization; + }; + + template<typename StoredType> + class SynchronizableTypeWrapper : private SynchronizableTypeWrapperBase<StoredType> { + public: + typedef SynchronizableTypeWrapperBase<StoredType> Base; + SynchronizableTypeWrapper(); + + // "Forwarding constructors" for primitive type assignment with more than one argument, for exampe SVGLength + template<typename T1> SynchronizableTypeWrapper(const T1&); + template<typename T1, typename T2> SynchronizableTypeWrapper(const T1&, const T2&); + template<typename T1, typename T2, typename T3> SynchronizableTypeWrapper(const T1&, const T2&, const T3&); + + SynchronizableTypeWrapper& operator=(const StoredType&); + operator StoredType() const; + + using Base::needsSynchronization; + using Base::setSynchronized; + + private: + using Base::m_value; + }; + + template<typename StoredPointerType> + class SynchronizableTypeWrapper<RefPtr<StoredPointerType> > : private SynchronizableTypeWrapperBase<RefPtr<StoredPointerType> > { + public: + typedef SynchronizableTypeWrapperBase<RefPtr<StoredPointerType> > Base; + SynchronizableTypeWrapper(); + SynchronizableTypeWrapper(const PassRefPtr<StoredPointerType>&); + + SynchronizableTypeWrapper& operator=(StoredPointerType*); + operator StoredPointerType*() const; + + using Base::needsSynchronization; + using Base::setSynchronized; + + private: + using Base::m_value; + }; + + // SynchronizableTypeWrapperBase implementation + template<typename StoredType> + inline SynchronizableTypeWrapperBase<StoredType>::SynchronizableTypeWrapperBase() + : m_value() + , m_needsSynchronization(false) + { + } + + template<typename StoredType> template<typename AssignableType> + inline void SynchronizableTypeWrapperBase<StoredType>::assign(AssignableType type) + { + m_value = type; + m_needsSynchronization = true; + } + + template<typename StoredType> + inline bool SynchronizableTypeWrapperBase<StoredType>::needsSynchronization() const + { + return m_needsSynchronization; + } + + template<typename StoredType> + inline void SynchronizableTypeWrapperBase<StoredType>::setSynchronized() + { + m_needsSynchronization = false; + } + + // SynchronizableTypeWrapper implementation for primitive types + template<typename StoredType> + inline SynchronizableTypeWrapper<StoredType>::SynchronizableTypeWrapper() + : Base() + { + } + + template<typename StoredType> template<typename T1> + inline SynchronizableTypeWrapper<StoredType>::SynchronizableTypeWrapper(const T1& arg1) + : Base() + { + m_value = StoredType(arg1); + } + + template<typename StoredType> template<typename T1, typename T2> + inline SynchronizableTypeWrapper<StoredType>::SynchronizableTypeWrapper(const T1& arg1, const T2& arg2) + : Base() + { + m_value = StoredType(arg1, arg2); + } + + template<typename StoredType> template<typename T1, typename T2, typename T3> + inline SynchronizableTypeWrapper<StoredType>::SynchronizableTypeWrapper(const T1& arg1, const T2& arg2, const T3& arg3) + : Base() + { + m_value = StoredType(arg1, arg2, arg3); + } + + template<typename StoredType> + inline SynchronizableTypeWrapper<StoredType>& SynchronizableTypeWrapper<StoredType>::operator=(const StoredType& other) + { + Base::assign(other); + return (*this); + } + + template<typename StoredType> + inline SynchronizableTypeWrapper<StoredType>::operator StoredType() const + { + return m_value; + } + + // SynchronizableTypeWrapper implementation for refcounted types + template<typename StoredPointerType> + inline SynchronizableTypeWrapper<RefPtr<StoredPointerType> >::SynchronizableTypeWrapper() + : Base() + { + } + + template<typename StoredPointerType> + inline SynchronizableTypeWrapper<RefPtr<StoredPointerType> >::SynchronizableTypeWrapper(const PassRefPtr<StoredPointerType>& type) + : Base() + { + Base::m_value = type; + } + + template<typename StoredPointerType> + inline SynchronizableTypeWrapper<RefPtr<StoredPointerType> >& SynchronizableTypeWrapper<RefPtr<StoredPointerType> >::operator=(StoredPointerType* other) + { + Base::assign(other); + return (*this); + } + + template<typename StoredPointerType> + inline SynchronizableTypeWrapper<RefPtr<StoredPointerType> >::operator StoredPointerType*() const + { + return Base::m_value.get(); + } + +}; + +#endif +#endif diff --git a/WebCore/svg/TimeScheduler.cpp b/WebCore/svg/TimeScheduler.cpp deleted file mode 100644 index 25c365b..0000000 --- a/WebCore/svg/TimeScheduler.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - Copyright (C) 2006 Apple Computer, Inc. - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" -#if ENABLE(SVG) -#include "TimeScheduler.h" - -#include "Document.h" -#include "SystemTime.h" -#include "SVGTimer.h" - -namespace WebCore { - -const double staticTimerInterval = 0.050; // 50 ms - -TimeScheduler::TimeScheduler(Document* document) - : m_creationTime(currentTime()) - , m_savedTime(0) - , m_document(document) -{ - // Don't start this timer yet. - m_intervalTimer = new SVGTimer(this, staticTimerInterval, false); -} - -TimeScheduler::~TimeScheduler() -{ - deleteAllValues(m_timerSet); - delete m_intervalTimer; -} - -void TimeScheduler::addTimer(SVGAnimationElement* element, unsigned ms) -{ -#if ENABLE(SVG_ANIMATION) - SVGTimer* svgTimer = new SVGTimer(this, ms * 0.001, true); - svgTimer->addNotify(element, true); - m_timerSet.add(svgTimer); - m_intervalTimer->addNotify(element, false); -#endif -} - -void TimeScheduler::connectIntervalTimer(SVGAnimationElement* element) -{ -#if ENABLE(SVG_ANIMATION) - m_intervalTimer->addNotify(element, true); -#endif -} - -void TimeScheduler::disconnectIntervalTimer(SVGAnimationElement* element) -{ -#if ENABLE(SVG_ANIMATION) - m_intervalTimer->removeNotify(element); -#endif -} - -void TimeScheduler::startAnimations() -{ -#if ENABLE(SVG_ANIMATION) - m_creationTime = currentTime(); - - SVGTimerSet::iterator end = m_timerSet.end(); - for (SVGTimerSet::iterator it = m_timerSet.begin(); it != end; ++it) { - SVGTimer* svgTimer = *it; - if (svgTimer && !svgTimer->isActive()) - svgTimer->start(); - } -#endif -} - -void TimeScheduler::toggleAnimations() -{ -#if ENABLE(SVG_ANIMATION) - if (m_intervalTimer->isActive()) { - m_intervalTimer->stop(); - m_savedTime = currentTime(); - } else { - if (m_savedTime != 0) { - m_creationTime += currentTime() - m_savedTime; - m_savedTime = 0; - } - m_intervalTimer->start(); - } -#endif -} - -bool TimeScheduler::animationsPaused() const -{ - return !m_intervalTimer->isActive(); -} - -void TimeScheduler::timerFired(Timer<TimeScheduler>* baseTimer) -{ -#if ENABLE(SVG_ANIMATION) - // Get the pointer now, because notifyAll could make the document, - // including this TimeScheduler, go away. - RefPtr<Document> doc = m_document; - - SVGTimer* timer = SVGTimer::downcast(baseTimer); - - timer->notifyAll(); - - // FIXME: Is it really safe to look at m_intervalTimer now? - // Isn't it possible the TimeScheduler was deleted already? - // If so, timer, m_timerSet, and m_intervalTimer have all - // been deleted. May need to reference count the TimeScheduler - // to work around this, and ref/deref it in this function. - if (timer != m_intervalTimer) { - ASSERT(!timer->isActive()); - ASSERT(m_timerSet.contains(timer)); - m_timerSet.remove(timer); - delete timer; - - // The singleShot timers of ie. <animate> with begin="3s" are notified - // by the previous call, and now all connections to the interval timer - // are created and now we just need to fire that timer (Niko) - if (!m_intervalTimer->isActive()) - m_intervalTimer->start(); - } - - // Update any 'dirty' shapes. - doc->updateRendering(); -#endif -} - -double TimeScheduler::elapsed() const -{ - return currentTime() - m_creationTime; -} - -} // namespace - -// vim:ts=4:noet -#endif // ENABLE(SVG) diff --git a/WebCore/svg/TimeScheduler.h b/WebCore/svg/TimeScheduler.h deleted file mode 100644 index 12c2439..0000000 --- a/WebCore/svg/TimeScheduler.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - Copyright (C) 2006 Apple Computer, Inc. - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef TimeScheduler_h -#define TimeScheduler_h -#if ENABLE(SVG) - -#include <wtf/HashSet.h> - -namespace WebCore { - class Document; - class SVGAnimationElement; - class SVGTimer; - - template <typename T> class Timer; - - typedef HashSet<SVGTimer*> SVGTimerSet; - - class TimeScheduler { - public: - TimeScheduler(Document*); - ~TimeScheduler(); - - // Adds singleShot Timers - void addTimer(SVGAnimationElement*, unsigned int ms); - - // (Dis-)Connects to interval timer with 'staticTimerInterval' - void connectIntervalTimer(SVGAnimationElement*); - void disconnectIntervalTimer(SVGAnimationElement*); - - void startAnimations(); - void toggleAnimations(); - bool animationsPaused() const; - - // time elapsed in seconds after creation of this object - double elapsed() const; - - private: - friend class SVGTimer; - void timerFired(Timer<TimeScheduler>*); - Document* document() const { return m_document; } - - private: - double m_creationTime; - double m_savedTime; - - SVGTimerSet m_timerSet; - - SVGTimer* m_intervalTimer; - Document* m_document; - }; -} - -#endif // ENABLE(SVG) -#endif - -// vim:ts=4:noet diff --git a/WebCore/svg/animation/SMILTime.cpp b/WebCore/svg/animation/SMILTime.cpp new file mode 100644 index 0000000..70f9487 --- /dev/null +++ b/WebCore/svg/animation/SMILTime.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#if ENABLE(SVG) +#include "SMILTime.h" + +#include <float.h> + +using namespace WebCore; + +const double SMILTime::unresolvedValue = DBL_MAX; +// Just a big value smaller than DBL_MAX. Our times are relative to 0, we don't really need the full range. +const double SMILTime::indefiniteValue = FLT_MAX; + +SMILTime WebCore::operator+(const SMILTime& a, const SMILTime& b) { + if (a.isUnresolved() || b.isUnresolved()) + return SMILTime::unresolved(); + if (a.isIndefinite() || b.isIndefinite()) + return SMILTime::indefinite(); + return a.value() + b.value(); +} + +SMILTime WebCore::operator-(const SMILTime& a, const SMILTime& b) { + if (a.isUnresolved() || b.isUnresolved()) + return SMILTime::unresolved(); + if (a.isIndefinite() || b.isIndefinite()) + return SMILTime::indefinite(); + return a.value() - b.value(); +} + +SMILTime WebCore::operator*(const SMILTime& a, const SMILTime& b) { + if (a.isUnresolved() || b.isUnresolved()) + return SMILTime::unresolved(); + if (a.value() == 0 || b.value() == 0) + return SMILTime(0); + if (a.isIndefinite() || b.isIndefinite()) + return SMILTime::indefinite(); + return a.value() * b.value(); +} +#endif + diff --git a/WebCore/svg/animation/SMILTime.h b/WebCore/svg/animation/SMILTime.h new file mode 100644 index 0000000..5196030 --- /dev/null +++ b/WebCore/svg/animation/SMILTime.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SMILTime_h +#define SMILTime_h + +#if ENABLE(SVG) + +#include <algorithm> + +namespace WebCore { + + class SMILTime { + public: + SMILTime() : m_time(0) { } + SMILTime(double time) : m_time(time) { } + SMILTime(const SMILTime& o) : m_time(o.m_time) { } + + static SMILTime unresolved() { return unresolvedValue; } + static SMILTime indefinite() { return indefiniteValue; } + + SMILTime& operator=(const SMILTime& o) { m_time = o.m_time; return *this; } + double value() const { return m_time; } + + bool isFinite() const { return m_time < indefiniteValue; } + bool isIndefinite() const { return m_time == indefiniteValue; } + bool isUnresolved() const { return m_time == unresolvedValue; } + + private: + static const double unresolvedValue; + static const double indefiniteValue; + + double m_time; + }; + + inline bool operator==(const SMILTime& a, const SMILTime& b) { return a.isFinite() && a.value() == b.value(); } + inline bool operator!=(const SMILTime& a, const SMILTime& b) { return !operator==(a, b); } + inline bool operator>(const SMILTime& a, const SMILTime& b) { return a.value() > b.value(); } + inline bool operator<(const SMILTime& a, const SMILTime& b) { return a.value() < b.value(); } + inline bool operator>=(const SMILTime& a, const SMILTime& b) { return a.value() > b.value() || operator==(a, b); } + inline bool operator<=(const SMILTime& a, const SMILTime& b) { return a.value() < b.value() || operator==(a, b); } + + inline SMILTime max(const SMILTime& a, const SMILTime& b) { return std::max(a.value(), b.value()); } + inline SMILTime min(const SMILTime& a, const SMILTime& b) { return std::min(a.value(), b.value()); } + SMILTime operator+(const SMILTime&, const SMILTime&); + SMILTime operator-(const SMILTime&, const SMILTime&); + // So multiplying times does not make too much sense but SMIL defines it for duration * repeatCount + SMILTime operator*(const SMILTime&, const SMILTime&); +} + +#endif +#endif diff --git a/WebCore/svg/animation/SMILTimeContainer.cpp b/WebCore/svg/animation/SMILTimeContainer.cpp new file mode 100644 index 0000000..0e809fb --- /dev/null +++ b/WebCore/svg/animation/SMILTimeContainer.cpp @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SMILTimeContainer.h" + +#if ENABLE(SVG) + +#include "CSSComputedStyleDeclaration.h" +#include "CSSParser.h" +#include "Document.h" +#include "SVGAnimationElement.h" +#include "SVGSMILElement.h" +#include "SVGSVGElement.h" +#include "SystemTime.h" + +using namespace std; + +namespace WebCore { + +static const double animationFrameDelay = 0.025; + +SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner) + : m_beginTime(0) + , m_pauseTime(0) + , m_accumulatedPauseTime(0) + , m_documentOrderIndexesDirty(false) + , m_timer(this, &SMILTimeContainer::timerFired) + , m_ownerSVGElement(owner) +{ +} + +#if !ENABLE(SVG_ANIMATION) +void SMILTimeContainer::begin() {} +void SMILTimeContainer::pause() {} +void SMILTimeContainer::resume() {} +SMILTime SMILTimeContainer::elapsed() const { return 0; } +bool SMILTimeContainer::isPaused() const { return false; } +void SMILTimeContainer::timerFired(Timer<SMILTimeContainer>*) {} +#else + +void SMILTimeContainer::schedule(SVGSMILElement* animation) +{ + ASSERT(animation->timeContainer() == this); + SMILTime nextFireTime = animation->nextProgressTime(); + if (!nextFireTime.isFinite()) + return; + m_scheduledAnimations.add(animation); + startTimer(0); +} + +void SMILTimeContainer::unschedule(SVGSMILElement* animation) +{ + ASSERT(animation->timeContainer() == this); + + m_scheduledAnimations.remove(animation); +} + +SMILTime SMILTimeContainer::elapsed() const +{ + if (!m_beginTime) + return 0; + return currentTime() - m_beginTime - m_accumulatedPauseTime; +} + +bool SMILTimeContainer::isActive() const +{ + return m_beginTime && !isPaused(); +} + +bool SMILTimeContainer::isPaused() const +{ + return m_pauseTime; +} + +void SMILTimeContainer::begin() +{ + ASSERT(!m_beginTime); + m_beginTime = currentTime(); + updateAnimations(0); +} + +void SMILTimeContainer::pause() +{ + if (!m_beginTime) + return; + ASSERT(!isPaused()); + m_pauseTime = currentTime(); + m_timer.stop(); +} + +void SMILTimeContainer::resume() +{ + if (!m_beginTime) + return; + ASSERT(isPaused()); + m_accumulatedPauseTime += currentTime() - m_pauseTime; + m_pauseTime = 0; + startTimer(0); +} + +void SMILTimeContainer::startTimer(SMILTime fireTime, SMILTime minimumDelay) +{ + if (!m_beginTime || isPaused()) + return; + + if (!fireTime.isFinite()) + return; + + SMILTime delay = max(fireTime - elapsed(), minimumDelay); + m_timer.startOneShot(delay.value()); +} + +void SMILTimeContainer::timerFired(Timer<SMILTimeContainer>*) +{ + ASSERT(m_beginTime); + ASSERT(!m_pauseTime); + SMILTime elapsed = this->elapsed(); + updateAnimations(elapsed); +} + +void SMILTimeContainer::updateDocumentOrderIndexes() +{ + unsigned timingElementCount = 0; + for (Node* node = m_ownerSVGElement; node; node = node->traverseNextNode(m_ownerSVGElement)) { + if (SVGSMILElement::isSMILElement(node)) + static_cast<SVGSMILElement*>(node)->setDocumentOrderIndex(timingElementCount++); + } + m_documentOrderIndexesDirty = false; +} + +struct PriorityCompare { + PriorityCompare(SMILTime elapsed) : m_elapsed(elapsed) {} + bool operator()(SVGSMILElement* a, SVGSMILElement* b) + { + // FIXME: This should also consider possible timing relations between the elements. + SMILTime aBegin = a->intervalBegin(); + SMILTime bBegin = b->intervalBegin(); + // Frozen elements need to be prioritized based on their previous interval. + aBegin = a->isFrozen() && m_elapsed < aBegin ? a->previousIntervalBegin() : aBegin; + bBegin = b->isFrozen() && m_elapsed < bBegin ? b->previousIntervalBegin() : bBegin; + if (aBegin == bBegin) + return a->documentOrderIndex() < b->documentOrderIndex(); + return aBegin < bBegin; + } + SMILTime m_elapsed; +}; + +void SMILTimeContainer::sortByPriority(Vector<SVGSMILElement*>& smilElements, SMILTime elapsed) +{ + if (m_documentOrderIndexesDirty) + updateDocumentOrderIndexes(); + std::sort(smilElements.begin(), smilElements.end(), PriorityCompare(elapsed)); +} + +static bool applyOrderSortFunction(SVGSMILElement* a, SVGSMILElement* b) +{ + if (!a->hasTagName(SVGNames::animateTransformTag) && b->hasTagName(SVGNames::animateTransformTag)) + return true; + return false; +} + +static void sortByApplyOrder(Vector<SVGSMILElement*>& smilElements) +{ + std::sort(smilElements.begin(), smilElements.end(), applyOrderSortFunction); +} + +String SMILTimeContainer::baseValueFor(ElementAttributePair key) +{ + // FIXME: We wouldn't need to do this if we were keeping base values around properly in DOM. + // Currently animation overwrites them so we need to save them somewhere. + BaseValueMap::iterator it = m_savedBaseValues.find(key); + if (it != m_savedBaseValues.end()) + return it->second; + + SVGElement* target = key.first; + String attributeName = key.second; + ASSERT(target); + ASSERT(!attributeName.isEmpty()); + String baseValue; + if (SVGAnimationElement::attributeIsCSS(attributeName)) + baseValue = computedStyle(target)->getPropertyValue(cssPropertyID(attributeName)); + else + baseValue = target->getAttribute(attributeName); + m_savedBaseValues.add(key, baseValue); + return baseValue; +} + +void SMILTimeContainer::updateAnimations(SMILTime elapsed) +{ + SMILTime earliersFireTime = SMILTime::unresolved(); + + Vector<SVGSMILElement*> toAnimate; + copyToVector(m_scheduledAnimations, toAnimate); + + // Sort according to priority. Elements with later begin time have higher priority. + // In case of a tie, document order decides. + // FIXME: This should also consider timing relationships between the elements. Dependents + // have higher priority. + sortByPriority(toAnimate, elapsed); + + // Calculate animation contributions. + typedef HashMap<ElementAttributePair, SVGSMILElement*> ResultElementMap; + ResultElementMap resultsElements; + for (unsigned n = 0; n < toAnimate.size(); ++n) { + SVGSMILElement* animation = toAnimate[n]; + ASSERT(animation->timeContainer() == this); + + SVGElement* targetElement = animation->targetElement(); + if (!targetElement) + continue; + String attributeName = animation->attributeName(); + if (attributeName.isEmpty()) { + if (animation->hasTagName(SVGNames::animateMotionTag)) + attributeName = SVGNames::animateMotionTag.localName(); + else + continue; + } + + // Results are accumulated to the first animation that animates a particular element/attribute pair. + ElementAttributePair key(targetElement, attributeName); + SVGSMILElement* resultElement = resultsElements.get(key); + if (!resultElement) { + resultElement = animation; + resultElement->resetToBaseValue(baseValueFor(key)); + resultsElements.add(key, resultElement); + } + + // This will calculate the contribution from the animation and add it to the resultsElement. + animation->progress(elapsed, resultElement); + + SMILTime nextFireTime = animation->nextProgressTime(); + if (nextFireTime.isFinite()) + earliersFireTime = min(nextFireTime, earliersFireTime); + else if (!animation->isContributing(elapsed)) { + m_scheduledAnimations.remove(animation); + if (m_scheduledAnimations.isEmpty()) + m_savedBaseValues.clear(); + } + } + + Vector<SVGSMILElement*> animationsToApply; + ResultElementMap::iterator end = resultsElements.end(); + for (ResultElementMap::iterator it = resultsElements.begin(); it != end; ++it) + animationsToApply.append(it->second); + + // Sort <animateTranform> to be the last one to be applied. <animate> may change transform attribute as + // well (directly or indirectly by modifying <use> x/y) and this way transforms combine properly. + sortByApplyOrder(animationsToApply); + + // Apply results to target elements. + for (unsigned n = 0; n < animationsToApply.size(); ++n) + animationsToApply[n]->applyResultsToTarget(); + + startTimer(earliersFireTime, animationFrameDelay); + + Document::updateDocumentsRendering(); +} + +#endif + +} + +#endif // ENABLE(SVG) diff --git a/WebCore/svg/animation/SMILTimeContainer.h b/WebCore/svg/animation/SMILTimeContainer.h new file mode 100644 index 0000000..5cef507 --- /dev/null +++ b/WebCore/svg/animation/SMILTimeContainer.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SMILTimeContainer_H +#define SMILTimeContainer_H + +#if ENABLE(SVG) + +#include "PlatformString.h" +#include "SMILTime.h" +#include "StringHash.h" +#include "Timer.h" +#include <wtf/HashSet.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> + +namespace WebCore { + + class SVGElement; + class SVGSMILElement; + class SVGSVGElement; + + class SMILTimeContainer : public RefCounted<SMILTimeContainer> { + public: + static PassRefPtr<SMILTimeContainer> create(SVGSVGElement* owner) { return adoptRef(new SMILTimeContainer(owner)); } + + void schedule(SVGSMILElement*); + void unschedule(SVGSMILElement*); + + SMILTime elapsed() const; + + bool isActive() const; + bool isPaused() const; + + void begin(); + void pause(); + void resume(); + + void setDocumentOrderIndexesDirty() { m_documentOrderIndexesDirty = true; } + + private: + SMILTimeContainer(SVGSVGElement* owner); + + void timerFired(Timer<SMILTimeContainer>*); + void startTimer(SMILTime fireTime, SMILTime minimumDelay = 0); + void updateAnimations(SMILTime elapsed); + + void updateDocumentOrderIndexes(); + void sortByPriority(Vector<SVGSMILElement*>& smilElements, SMILTime elapsed); + + typedef pair<SVGElement*, String> ElementAttributePair; + String baseValueFor(ElementAttributePair); + + double m_beginTime; + double m_pauseTime; + double m_accumulatedPauseTime; + + bool m_documentOrderIndexesDirty; + + Timer<SMILTimeContainer> m_timer; + + typedef HashSet<SVGSMILElement*> TimingElementSet; + TimingElementSet m_scheduledAnimations; + + typedef HashMap<ElementAttributePair, String> BaseValueMap; + BaseValueMap m_savedBaseValues; + + SVGSVGElement* m_ownerSVGElement; + }; +} + +#endif +#endif diff --git a/WebCore/svg/animation/SVGSMILElement.cpp b/WebCore/svg/animation/SVGSMILElement.cpp new file mode 100644 index 0000000..a07a407 --- /dev/null +++ b/WebCore/svg/animation/SVGSMILElement.cpp @@ -0,0 +1,929 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#if ENABLE(SVG_ANIMATION) +#include "SVGSMILElement.h" + +#include "CSSPropertyNames.h" +#include "Document.h" +#include "Event.h" +#include "EventListener.h" +#include "FloatConversion.h" +#include "FrameView.h" +#include "HTMLNames.h" +#include "SVGNames.h" +#include "SVGParserUtilities.h" +#include "SVGSVGElement.h" +#include "SVGURIReference.h" +#include "SMILTimeContainer.h" +#include "XLinkNames.h" +#include <math.h> +#include <wtf/MathExtras.h> +#include <wtf/Vector.h> + +using namespace std; + +namespace WebCore { + +// This is used for duration type time values that can't be negative. +static const double invalidCachedTime = -1.; + +class ConditionEventListener : public EventListener { +public: + static PassRefPtr<ConditionEventListener> create(SVGSMILElement* animation, Element* eventBase, SVGSMILElement::Condition* condition) + { + return adoptRef(new ConditionEventListener(animation, eventBase, condition)); + } + + void unregister() + { + // If this has only one ref then the event base is dead already and we don't need to remove ourself. + if (!hasOneRef()) + m_eventBase->removeEventListener(m_condition->m_name, this, false); + } + + virtual void handleEvent(Event* event, bool isWindowEvent) + { + m_animation->handleConditionEvent(event, m_condition); + } + +private: + ConditionEventListener(SVGSMILElement* animation, Element* eventBase, SVGSMILElement::Condition* condition) + : m_animation(animation) + , m_condition(condition) + , m_eventBase(eventBase) + { + m_eventBase->addEventListener(m_condition->m_name, this, false); + } + + SVGSMILElement* m_animation; + SVGSMILElement::Condition* m_condition; + Element* m_eventBase; +}; + +SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats) + : m_type(type) + , m_beginOrEnd(beginOrEnd) + , m_baseID(baseID) + , m_name(name) + , m_offset(offset) + , m_repeats(repeats) +{ +} + +SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document* doc) + : SVGElement(tagName, doc) + , m_conditionsConnected(false) + , m_hasEndEventConditions(false) + , m_intervalBegin(SMILTime::unresolved()) + , m_intervalEnd(SMILTime::unresolved()) + , m_previousIntervalBegin(SMILTime::unresolved()) + , m_isWaitingForFirstInterval(true) + , m_activeState(Inactive) + , m_lastPercent(0) + , m_lastRepeat(0) + , m_nextProgressTime(0) + , m_documentOrderIndex(0) + , m_cachedDur(invalidCachedTime) + , m_cachedRepeatDur(invalidCachedTime) + , m_cachedRepeatCount(invalidCachedTime) + , m_cachedMin(invalidCachedTime) + , m_cachedMax(invalidCachedTime) +{ +} + +SVGSMILElement::~SVGSMILElement() +{ + disconnectConditions(); + if (m_timeContainer) + m_timeContainer->unschedule(this); +} + +void SVGSMILElement::insertedIntoDocument() +{ + SVGElement::insertedIntoDocument(); +#ifndef NDEBUG + // Verify we are not in <use> instance tree. + for (Node* n = this; n; n = n->parent()) + ASSERT(!n->isShadowNode()); +#endif + SVGSVGElement* owner = ownerSVGElement(); + if (!owner) + return; + m_timeContainer = owner->timeContainer(); + ASSERT(m_timeContainer); + m_timeContainer->setDocumentOrderIndexesDirty(); + reschedule(); +} + +void SVGSMILElement::removedFromDocument() +{ + if (m_timeContainer) { + m_timeContainer->unschedule(this); + m_timeContainer = 0; + } + // Calling disconnectConditions() may kill us if there are syncbase conditions. + // OK, but we don't want to die inside the call. + RefPtr<SVGSMILElement> keepAlive(this); + disconnectConditions(); + SVGElement::removedFromDocument(); +} + +void SVGSMILElement::finishParsingChildren() +{ + SVGElement::finishParsingChildren(); + + // "If no attribute is present, the default begin value (an offset-value of 0) must be evaluated." + if (!hasAttribute(SVGNames::beginAttr)) + m_beginTimes.append(0); + + if (m_isWaitingForFirstInterval) { + resolveFirstInterval(); + reschedule(); + } +} + +SMILTime SVGSMILElement::parseOffsetValue(const String& data) +{ + bool ok; + double result = 0; + String parse = data.stripWhiteSpace(); + if (parse.endsWith("h")) + result = parse.left(parse.length() - 1).toDouble(&ok) * 60 * 60; + else if (parse.endsWith("min")) + result = parse.left(parse.length() - 3).toDouble(&ok) * 60; + else if (parse.endsWith("ms")) + result = parse.left(parse.length() - 2).toDouble(&ok) / 1000; + else if (parse.endsWith("s")) + result = parse.left(parse.length() - 1).toDouble(&ok); + else + result = parse.toDouble(&ok); + if (!ok) + return SMILTime::unresolved(); + return result; +} + +SMILTime SVGSMILElement::parseClockValue(const String& data) +{ + if (data.isNull()) + return SMILTime::unresolved(); + + String parse = data.stripWhiteSpace(); + + static const AtomicString indefiniteValue("indefinite"); + if (parse == indefiniteValue) + return SMILTime::indefinite(); + + double result = 0; + bool ok; + int doublePointOne = parse.find(':'); + int doublePointTwo = parse.find(':', doublePointOne + 1); + if (doublePointOne == 2 && doublePointTwo == 5 && parse.length() >= 8) { + result += parse.substring(0, 2).toUIntStrict(&ok) * 60 * 60; + if (!ok) + return SMILTime::unresolved(); + result += parse.substring(3, 2).toUIntStrict(&ok) * 60; + if (!ok) + return SMILTime::unresolved(); + result += parse.substring(6).toDouble(&ok); + } else if (doublePointOne == 2 && doublePointTwo == -1 && parse.length() >= 5) { + result += parse.substring(0, 2).toUIntStrict(&ok) * 60; + if (!ok) + return SMILTime::unresolved(); + result += parse.substring(3).toDouble(&ok); + } else + return parseOffsetValue(parse); + + if (!ok) + return SMILTime::unresolved(); + return result; +} + +static void sortTimeList(Vector<SMILTime>& timeList) +{ + std::sort(timeList.begin(), timeList.end()); +} + +bool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd) +{ + String parseString = value.stripWhiteSpace(); + + double sign = 1.; + bool ok; + int pos = parseString.find('+'); + if (pos == -1) { + pos = parseString.find('-'); + if (pos != -1) + sign = -1.; + } + String conditionString; + SMILTime offset = 0; + if (pos == -1) + conditionString = parseString; + else { + conditionString = parseString.left(pos).stripWhiteSpace(); + String offsetString = parseString.substring(pos + 1).stripWhiteSpace(); + offset = parseOffsetValue(offsetString); + if (offset.isUnresolved()) + return false; + offset = offset * sign; + } + if (conditionString.isEmpty()) + return false; + pos = conditionString.find('.'); + + String baseID; + String nameString; + if (pos == -1) + nameString = conditionString; + else { + baseID = conditionString.left(pos); + nameString = conditionString.substring(pos + 1); + } + if (nameString.isEmpty()) + return false; + + Condition::Type type; + int repeats = -1; + if (nameString.startsWith("repeat(") && nameString.endsWith(")")) { + // FIXME: For repeat events we just need to add the data carrying TimeEvent class and + // fire the events at appropiate times. + repeats = nameString.substring(7, nameString.length() - 8).toUIntStrict(&ok); + if (!ok) + return false; + nameString = "repeat"; + type = Condition::EventBase; + } else if (nameString == "begin" || nameString == "end") { + if (baseID.isEmpty()) + return false; + type = Condition::Syncbase; + } else if (nameString.startsWith("accesskey(")) { + // FIXME: accesskey() support. + type = Condition::AccessKey; + } else + type = Condition::EventBase; + + m_conditions.append(Condition(type, beginOrEnd, baseID, nameString, offset, repeats)); + + if (type == Condition::EventBase && beginOrEnd == End) + m_hasEndEventConditions = true; + + return true; +} + +bool SVGSMILElement::isSMILElement(Node* node) +{ + if (!node) + return false; + return node->hasTagName(SVGNames::setTag) || node->hasTagName(SVGNames::animateTag) || node->hasTagName(SVGNames::animateMotionTag) + || node->hasTagName(SVGNames::animateTransformTag) || node->hasTagName(SVGNames::animateColorTag); +} + +void SVGSMILElement::parseBeginOrEnd(const String& parseString, BeginOrEnd beginOrEnd) +{ + Vector<SMILTime>& timeList = beginOrEnd == Begin ? m_beginTimes : m_endTimes; + if (beginOrEnd == End) + m_hasEndEventConditions = false; + HashSet<double> existing; + for (unsigned n = 0; n < timeList.size(); ++n) + existing.add(timeList[n].value()); + Vector<String> splitString; + parseString.split(';', splitString); + for (unsigned n = 0; n < splitString.size(); ++n) { + SMILTime value = parseClockValue(splitString[n]); + if (value.isUnresolved()) + parseCondition(splitString[n], beginOrEnd); + else if (!existing.contains(value.value())) + timeList.append(value); + } + sortTimeList(timeList); +} + +void SVGSMILElement::parseMappedAttribute(MappedAttribute* attr) +{ + if (attr->name() == SVGNames::beginAttr) { + if (!m_conditions.isEmpty()) { + disconnectConditions(); + m_conditions.clear(); + parseBeginOrEnd(getAttribute(SVGNames::endAttr), End); + } + parseBeginOrEnd(attr->value().string(), Begin); + if (inDocument()) + connectConditions(); + } else if (attr->name() == SVGNames::endAttr) { + if (!m_conditions.isEmpty()) { + disconnectConditions(); + m_conditions.clear(); + parseBeginOrEnd(getAttribute(SVGNames::beginAttr), Begin); + } + parseBeginOrEnd(attr->value().string(), End); + if (inDocument()) + connectConditions(); + } else + SVGElement::parseMappedAttribute(attr); +} + +void SVGSMILElement::attributeChanged(Attribute* attr, bool preserveDecls) +{ + SVGElement::attributeChanged(attr, preserveDecls); + + const QualifiedName& attrName = attr->name(); + if (attrName == SVGNames::durAttr) + m_cachedDur = invalidCachedTime; + else if (attrName == SVGNames::repeatDurAttr) + m_cachedRepeatDur = invalidCachedTime; + else if (attrName == SVGNames::repeatCountAttr) + m_cachedRepeatCount = invalidCachedTime; + else if (attrName == SVGNames::minAttr) + m_cachedMin = invalidCachedTime; + else if (attrName == SVGNames::maxAttr) + m_cachedMax = invalidCachedTime; + + if (inDocument()) { + if (attrName == SVGNames::beginAttr) + beginListChanged(); + else if (attrName == SVGNames::endAttr) + endListChanged(); + } +} + +void SVGSMILElement::connectConditions() +{ + if (m_conditionsConnected) + disconnectConditions(); + m_conditionsConnected = true; + for (unsigned n = 0; n < m_conditions.size(); ++n) { + Condition& condition = m_conditions[n]; + if (condition.m_type == Condition::EventBase) { + ASSERT(!condition.m_syncbase); + Element* eventBase = condition.m_baseID.isEmpty() ? targetElement() : document()->getElementById(condition.m_baseID); + if (!eventBase) + continue; + ASSERT(!condition.m_eventListener); + condition.m_eventListener = ConditionEventListener::create(this, eventBase, &condition); + } else if (condition.m_type == Condition::Syncbase) { + ASSERT(!condition.m_baseID.isEmpty()); + condition.m_syncbase = document()->getElementById(condition.m_baseID); + if (!isSMILElement(condition.m_syncbase.get())) { + condition.m_syncbase = 0; + continue; + } + SVGSMILElement* syncbase = static_cast<SVGSMILElement*>(condition.m_syncbase.get()); + syncbase->addTimeDependent(this); + } + } +} + +void SVGSMILElement::disconnectConditions() +{ + if (!m_conditionsConnected) + return; + m_conditionsConnected = false; + for (unsigned n = 0; n < m_conditions.size(); ++n) { + Condition& condition = m_conditions[n]; + if (condition.m_type == Condition::EventBase) { + ASSERT(!condition.m_syncbase); + if (condition.m_eventListener) { + condition.m_eventListener->unregister(); + condition.m_eventListener = 0; + } + } else if (condition.m_type == Condition::Syncbase) { + if (condition.m_syncbase) { + ASSERT(isSMILElement(condition.m_syncbase.get())); + static_cast<SVGSMILElement*>(condition.m_syncbase.get())->removeTimeDependent(this); + } + } + condition.m_syncbase = 0; + } +} + +void SVGSMILElement::reschedule() +{ + if (m_timeContainer) + m_timeContainer->schedule(this); +} + +SVGElement* SVGSMILElement::targetElement() const +{ + String href = xlinkHref(); + Node* target = href.isEmpty() ? parentNode() : document()->getElementById(SVGURIReference::getTarget(href)); + if (target && target->isSVGElement()) + return static_cast<SVGElement*>(target); + return 0; +} + +String SVGSMILElement::attributeName() const +{ + return getAttribute(SVGNames::attributeNameAttr).string().stripWhiteSpace(); +} + +SMILTime SVGSMILElement::elapsed() const +{ + return m_timeContainer ? m_timeContainer->elapsed() : 0; +} + +bool SVGSMILElement::isInactive() const +{ + return m_activeState == Inactive; +} + +bool SVGSMILElement::isFrozen() const +{ + return m_activeState == Frozen; +} + +SVGSMILElement::Restart SVGSMILElement::restart() const +{ + static const AtomicString never("never"); + static const AtomicString whenNotActive("whenNotActive"); + const AtomicString& value = getAttribute(SVGNames::restartAttr); + if (value == never) + return RestartNever; + if (value == whenNotActive) + return RestartWhenNotActive; + return RestartAlways; +} + +SVGSMILElement::FillMode SVGSMILElement::fill() const +{ + static const AtomicString freeze("freeze"); + const AtomicString& value = getAttribute(SVGNames::fillAttr); + return value == freeze ? FillFreeze : FillRemove; +} + +String SVGSMILElement::xlinkHref() const +{ + return getAttribute(XLinkNames::hrefAttr); +} + +SMILTime SVGSMILElement::dur() const +{ + if (m_cachedDur != invalidCachedTime) + return m_cachedDur; + const AtomicString& value = getAttribute(SVGNames::durAttr); + SMILTime clockValue = parseClockValue(value); + return m_cachedDur = clockValue <= 0 ? SMILTime::unresolved() : clockValue; +} + +SMILTime SVGSMILElement::repeatDur() const +{ + if (m_cachedRepeatDur != invalidCachedTime) + return m_cachedRepeatDur; + const AtomicString& value = getAttribute(SVGNames::repeatDurAttr); + SMILTime clockValue = parseClockValue(value); + return m_cachedRepeatDur = clockValue < 0 ? SMILTime::unresolved() : clockValue; +} + +// So a count is not really a time but let just all pretend we did not notice. +SMILTime SVGSMILElement::repeatCount() const +{ + if (m_cachedRepeatCount != invalidCachedTime) + return m_cachedRepeatCount; + const AtomicString& value = getAttribute(SVGNames::repeatCountAttr); + if (value.isNull()) + return SMILTime::unresolved(); + + static const AtomicString indefiniteValue("indefinite"); + if (value == indefiniteValue) + return SMILTime::indefinite(); + bool ok; + double result = value.string().toDouble(&ok); + return m_cachedRepeatCount = ok && result > 0 ? result : SMILTime::unresolved(); +} + +SMILTime SVGSMILElement::maxValue() const +{ + if (m_cachedMax != invalidCachedTime) + return m_cachedMax; + const AtomicString& value = getAttribute(SVGNames::maxAttr); + SMILTime result = parseClockValue(value); + return m_cachedMax = (result.isUnresolved() || result < 0) ? SMILTime::indefinite() : result; +} + +SMILTime SVGSMILElement::minValue() const +{ + if (m_cachedMin != invalidCachedTime) + return m_cachedMin; + const AtomicString& value = getAttribute(SVGNames::minAttr); + SMILTime result = parseClockValue(value); + return m_cachedMin = (result.isUnresolved() || result < 0) ? 0 : result; +} + +SMILTime SVGSMILElement::simpleDuration() const +{ + return min(dur(), SMILTime::indefinite()); +} + +void SVGSMILElement::addBeginTime(SMILTime time) +{ + m_beginTimes.append(time); + sortTimeList(m_beginTimes); + beginListChanged(); +} + +void SVGSMILElement::addEndTime(SMILTime time) +{ + m_endTimes.append(time); + sortTimeList(m_endTimes); + endListChanged(); +} + +SMILTime SVGSMILElement::findInstanceTime(BeginOrEnd beginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const +{ + // FIXME: This searches from the beginning which is inefficient. The list is usually not long + // (one entry in common cases) but you can construct a case where it does grow. + const Vector<SMILTime>& list = beginOrEnd == Begin ? m_beginTimes : m_endTimes; + for (unsigned n = 0; n < list.size(); ++n) { + SMILTime time = list[n]; + ASSERT(!time.isUnresolved()); + if (time.isIndefinite() && beginOrEnd == Begin) { + // "The special value "indefinite" does not yield an instance time in the begin list." + continue; + } + if (equalsMinimumOK) { + if (time >= minimumTime) + return time; + } else if (time > minimumTime) + return time; + } + return SMILTime::unresolved(); +} + +SMILTime SVGSMILElement::repeatingDuration() const +{ + // Computing the active duration + // http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur + SMILTime repeatCount = this->repeatCount(); + SMILTime repeatDur = this->repeatDur(); + SMILTime simpleDuration = this->simpleDuration(); + if (simpleDuration == 0 || (repeatDur.isUnresolved() && repeatCount.isUnresolved())) + return simpleDuration; + SMILTime repeatCountDuration = simpleDuration * repeatCount; + return min(repeatCountDuration, min(repeatDur, SMILTime::indefinite())); +} + +SMILTime SVGSMILElement::resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const +{ + // Computing the active duration + // http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur + SMILTime preliminaryActiveDuration; + if (!resolvedEnd.isUnresolved() && dur().isUnresolved() && repeatDur().isUnresolved() && repeatCount().isUnresolved()) + preliminaryActiveDuration = resolvedEnd - resolvedBegin; + else if (!resolvedEnd.isFinite()) + preliminaryActiveDuration = repeatingDuration(); + else + preliminaryActiveDuration = min(repeatingDuration(), resolvedEnd - resolvedBegin); + + SMILTime minValue = this->minValue(); + SMILTime maxValue = this->maxValue(); + if (minValue > maxValue) { + // Ignore both. + // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#MinMax + minValue = 0; + maxValue = SMILTime::indefinite(); + } + return resolvedBegin + min(maxValue, max(minValue, preliminaryActiveDuration)); +} + +void SVGSMILElement::resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const +{ + // See the pseudocode in + // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#Timing-BeginEnd-LifeCycle + SMILTime beginAfter = first ? -numeric_limits<double>::infinity() : m_intervalEnd; + SMILTime lastIntervalTempEnd = numeric_limits<double>::infinity(); + while (true) { + SMILTime tempBegin = findInstanceTime(Begin, beginAfter, true); + if (tempBegin.isUnresolved()) + break; + SMILTime tempEnd; + if (m_endTimes.isEmpty()) + tempEnd = resolveActiveEnd(tempBegin, SMILTime::indefinite()); + else { + tempEnd = findInstanceTime(End, tempBegin, true); + if ((first && tempBegin == tempEnd && tempEnd == lastIntervalTempEnd) || (!first && tempEnd == m_intervalEnd)) + tempEnd = findInstanceTime(End, tempBegin, false); + if (tempEnd.isUnresolved()) { + if (!m_endTimes.isEmpty() && !m_hasEndEventConditions) + break; + } + tempEnd = resolveActiveEnd(tempBegin, tempEnd); + } + if (tempEnd > 0 || !first) { + beginResult = tempBegin; + endResult = tempEnd; + return; + } else if (restart() == RestartNever) + break; + else + beginAfter = tempEnd; + lastIntervalTempEnd = tempEnd; + } + beginResult = SMILTime::unresolved(); + endResult = SMILTime::unresolved(); +} + +void SVGSMILElement::resolveFirstInterval() +{ + SMILTime begin; + SMILTime end; + resolveInterval(true, begin, end); + ASSERT(!begin.isIndefinite()); + + if (!begin.isUnresolved() && (begin != m_intervalBegin || end != m_intervalEnd)) { + bool wasUnresolved = m_intervalBegin.isUnresolved(); + m_intervalBegin = begin; + m_intervalEnd = end; + notifyDependentsIntervalChanged(wasUnresolved ? NewInterval : ExistingInterval); + m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin); + reschedule(); + } +} + +void SVGSMILElement::resolveNextInterval() +{ + SMILTime begin; + SMILTime end; + resolveInterval(false, begin, end); + ASSERT(!begin.isIndefinite()); + + if (!begin.isUnresolved() && begin != m_intervalBegin) { + m_intervalBegin = begin; + m_intervalEnd = end; + notifyDependentsIntervalChanged(NewInterval); + m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin); + } +} + +SMILTime SVGSMILElement::nextProgressTime() const +{ + return m_nextProgressTime; +} + +void SVGSMILElement::beginListChanged() +{ + SMILTime elapsed = this->elapsed(); + if (m_isWaitingForFirstInterval) + resolveFirstInterval(); + else if (elapsed < m_intervalBegin) { + SMILTime newBegin = findInstanceTime(Begin, elapsed, false); + if (newBegin < m_intervalBegin) { + // Begin time changed, re-resolve the interval. + SMILTime oldBegin = m_intervalBegin; + m_intervalBegin = elapsed; + resolveInterval(false, m_intervalBegin, m_intervalEnd); + ASSERT(!m_intervalBegin.isUnresolved()); + if (m_intervalBegin != oldBegin) + notifyDependentsIntervalChanged(ExistingInterval); + } + } + m_nextProgressTime = elapsed; + reschedule(); +} + +void SVGSMILElement::endListChanged() +{ + SMILTime elapsed = this->elapsed(); + if (m_isWaitingForFirstInterval) + resolveFirstInterval(); + else if (elapsed < m_intervalEnd && m_intervalBegin.isFinite()) { + SMILTime newEnd = findInstanceTime(End, m_intervalBegin, false); + if (newEnd < m_intervalEnd) { + newEnd = resolveActiveEnd(m_intervalBegin, newEnd); + if (newEnd != m_intervalEnd) { + m_intervalEnd = newEnd; + notifyDependentsIntervalChanged(ExistingInterval); + } + } + } + m_nextProgressTime = elapsed; + reschedule(); +} + +void SVGSMILElement::checkRestart(SMILTime elapsed) +{ + ASSERT(!m_isWaitingForFirstInterval); + ASSERT(elapsed >= m_intervalBegin); + + Restart restart = this->restart(); + if (restart == RestartNever) + return; + + if (elapsed < m_intervalEnd) { + if (restart != RestartAlways) + return; + SMILTime nextBegin = findInstanceTime(Begin, m_intervalBegin, false); + if (nextBegin < m_intervalEnd) { + m_intervalEnd = nextBegin; + notifyDependentsIntervalChanged(ExistingInterval); + } + } + if (elapsed >= m_intervalEnd) + resolveNextInterval(); +} + +float SVGSMILElement::calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const +{ + SMILTime simpleDuration = this->simpleDuration(); + repeat = 0; + if (simpleDuration.isIndefinite()) { + repeat = 0; + return 0.f; + } + if (simpleDuration == 0) { + repeat = 0; + return 1.f; + } + ASSERT(m_intervalBegin.isFinite()); + ASSERT(simpleDuration.isFinite()); + SMILTime activeTime = elapsed - m_intervalBegin; + SMILTime repeatingDuration = this->repeatingDuration(); + if (elapsed >= m_intervalEnd || activeTime > repeatingDuration) { + repeat = static_cast<unsigned>(repeatingDuration.value() / simpleDuration.value()); + if (fmod(repeatingDuration.value(), simpleDuration.value() == 0.)) + repeat--; + return 1.f; + } + repeat = static_cast<unsigned>(activeTime.value() / simpleDuration.value()); + SMILTime simpleTime = fmod(activeTime.value(), simpleDuration.value()); + return narrowPrecisionToFloat(simpleTime.value() / simpleDuration.value()); +} + +SMILTime SVGSMILElement::calculateNextProgressTime(SMILTime elapsed) const +{ + if (m_activeState == Active) { + // If duration is indefinite the value does not actually change over time. Same is true for <set>. + SMILTime simpleDuration = this->simpleDuration(); + if (simpleDuration.isIndefinite() || hasTagName(SVGNames::setTag)) { + SMILTime repeatCount = this->repeatCount(); + SMILTime repeatingDurationEnd = m_intervalBegin + repeatingDuration(); + // We are supposed to do freeze semantics when repeating ends, even if the element is still active. + // Take care that we get a timer callback at that point. + if (elapsed < repeatingDurationEnd && repeatingDurationEnd < m_intervalEnd && repeatingDurationEnd.isFinite()) + return repeatingDurationEnd; + return m_intervalEnd; + } + return elapsed + 0.025; + } + return m_intervalBegin >= elapsed ? m_intervalBegin : SMILTime::unresolved(); +} + +SVGSMILElement::ActiveState SVGSMILElement::determineActiveState(SMILTime elapsed) const +{ + if (elapsed >= m_intervalBegin && elapsed < m_intervalEnd) + return Active; + + if (m_activeState == Active) + return fill() == FillFreeze ? Frozen : Inactive; + + return m_activeState; +} + +bool SVGSMILElement::isContributing(SMILTime elapsed) const +{ + // Animation does not contribute during the active time if it is past its repeating duration and has fill=remove. + return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_intervalBegin + repeatingDuration())) || m_activeState == Frozen; +} + +void SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement) +{ + ASSERT(m_timeContainer); + ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite()); + + if (!m_conditionsConnected) + connectConditions(); + + if (!m_intervalBegin.isFinite()) { + ASSERT(m_activeState == Inactive); + m_nextProgressTime = SMILTime::unresolved(); + return; + } + + if (elapsed < m_intervalBegin) { + ASSERT(m_activeState != Active); + if (m_activeState == Frozen && resultElement) + updateAnimation(m_lastPercent, m_lastRepeat, resultElement); + m_nextProgressTime = m_intervalBegin; + return; + } + + m_previousIntervalBegin = m_intervalBegin; + + if (m_activeState == Inactive) { + m_isWaitingForFirstInterval = false; + m_activeState = Active; + startedActiveInterval(); + } + + unsigned repeat; + float percent = calculateAnimationPercentAndRepeat(elapsed, repeat); + + checkRestart(elapsed); + + ActiveState oldActiveState = m_activeState; + m_activeState = determineActiveState(elapsed); + + if (isContributing(elapsed)) { + if (resultElement) + updateAnimation(percent, repeat, resultElement); + m_lastPercent = percent; + m_lastRepeat = repeat; + } + + if (oldActiveState == Active && m_activeState != Active) + endedActiveInterval(); + + m_nextProgressTime = calculateNextProgressTime(elapsed); +} + +void SVGSMILElement::notifyDependentsIntervalChanged(NewOrExistingInterval newOrExisting) +{ + ASSERT(m_intervalBegin.isFinite()); + static HashSet<SVGSMILElement*> loopBreaker; + if (loopBreaker.contains(this)) + return; + loopBreaker.add(this); + + TimeDependentSet::iterator end = m_timeDependents.end(); + for (TimeDependentSet::iterator it = m_timeDependents.begin(); it != end; ++it) { + SVGSMILElement* dependent = *it; + dependent->createInstanceTimesFromSyncbase(this, newOrExisting); + } + + loopBreaker.remove(this); +} + +void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval newOrExisting) +{ + // FIXME: To be really correct, this should handle updating exising interval by changing + // the associated times instead of creating new ones. + for (unsigned n = 0; n < m_conditions.size(); ++n) { + Condition& condition = m_conditions[n]; + if (condition.m_type == Condition::Syncbase && condition.m_syncbase == syncbase) { + ASSERT(condition.m_name == "begin" || condition.m_name == "end"); + // No nested time containers in SVG, no need for crazy time space conversions. Phew! + SMILTime time = 0; + if (condition.m_name == "begin") + time = syncbase->m_intervalBegin + condition.m_offset; + else + time = syncbase->m_intervalEnd + condition.m_offset; + ASSERT(time.isFinite()); + if (condition.m_beginOrEnd == Begin) + addBeginTime(time); + else + addEndTime(time); + } + } +} + +void SVGSMILElement::addTimeDependent(SVGSMILElement* animation) +{ + m_timeDependents.add(animation); + if (m_intervalBegin.isFinite()) + animation->createInstanceTimesFromSyncbase(this, NewInterval); +} + +void SVGSMILElement::removeTimeDependent(SVGSMILElement* animation) +{ + m_timeDependents.remove(animation); +} + +void SVGSMILElement::handleConditionEvent(Event* event, Condition* condition) +{ + if (condition->m_beginOrEnd == Begin) + addBeginTime(elapsed() + condition->m_offset); + else + addEndTime(elapsed() + condition->m_offset); +} + +void SVGSMILElement::beginByLinkActivation() +{ + addBeginTime(elapsed()); +} + +} + +#endif + diff --git a/WebCore/svg/animation/SVGSMILElement.h b/WebCore/svg/animation/SVGSMILElement.h new file mode 100644 index 0000000..fac102e --- /dev/null +++ b/WebCore/svg/animation/SVGSMILElement.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef SVGSMILElement_h +#define SVGSMILElement_h +#if ENABLE(SVG_ANIMATION) + +#include "SVGElement.h" +#include "SMILTime.h" +#include <wtf/HashMap.h> + +namespace WebCore { + + class ConditionEventListener; + class SMILTimeContainer; + + // This class implements SMIL interval timing model as needed for SVG animation. + class SVGSMILElement : public SVGElement + { + public: + SVGSMILElement(const QualifiedName&, Document*); + virtual ~SVGSMILElement(); + + static bool isSMILElement(Node* node); + + virtual void parseMappedAttribute(MappedAttribute*); + virtual void attributeChanged(Attribute*, bool preserveDecls); + virtual void insertedIntoDocument(); + virtual void removedFromDocument(); + virtual void finishParsingChildren(); + + SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); } + + SVGElement* targetElement() const; + String attributeName() const; + + void beginByLinkActivation(); + + enum Restart { RestartAlways, RestartWhenNotActive, RestartNever }; + Restart restart() const; + + enum FillMode { FillRemove, FillFreeze }; + FillMode fill() const; + + String xlinkHref() const; + + SMILTime dur() const; + SMILTime repeatDur() const; + SMILTime repeatCount() const; + SMILTime maxValue() const; + SMILTime minValue() const; + + SMILTime elapsed() const; + + SMILTime intervalBegin() const { return m_intervalBegin; } + SMILTime intervalEnd() const { return m_intervalEnd; } + SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; } + SMILTime simpleDuration() const; + + void progress(SMILTime elapsed, SVGSMILElement* resultsElement); + SMILTime nextProgressTime() const; + + static SMILTime parseClockValue(const String&); + static SMILTime parseOffsetValue(const String&); + + bool isContributing(SMILTime elapsed) const; + bool isInactive() const; + bool isFrozen() const; + + unsigned documentOrderIndex() const { return m_documentOrderIndex; } + void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; } + + virtual bool isAdditive() const = 0; + virtual void resetToBaseValue(const String&) = 0; + virtual void applyResultsToTarget() = 0; + +protected: + void addBeginTime(SMILTime time); + void addEndTime(SMILTime time); + +private: + virtual void startedActiveInterval() = 0; + virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) = 0; + virtual void endedActiveInterval() = 0; + + enum BeginOrEnd { Begin, End }; + SMILTime findInstanceTime(BeginOrEnd beginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const; + void resolveFirstInterval(); + void resolveNextInterval(); + void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const; + SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const; + SMILTime repeatingDuration() const; + void checkRestart(SMILTime elapsed); + void beginListChanged(); + void endListChanged(); + void reschedule(); + + // This represents conditions on elements begin or end list that need to be resolved on runtime + // for example <animate begin="otherElement.begin + 8s; button.click" ... /> + struct Condition { + enum Type { EventBase, Syncbase, AccessKey }; + Condition(Type, BeginOrEnd beginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeats = -1); + Type m_type; + BeginOrEnd m_beginOrEnd; + String m_baseID; + String m_name; + SMILTime m_offset; + int m_repeats; + RefPtr<Element> m_syncbase; + RefPtr<ConditionEventListener> m_eventListener; + }; + bool parseCondition(const String&, BeginOrEnd beginOrEnd); + void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd); + + void connectConditions(); + void disconnectConditions(); + + // Event base timing + void handleConditionEvent(Event*, Condition*); + + // Syncbase timing + enum NewOrExistingInterval { NewInterval, ExistingInterval }; + void notifyDependentsIntervalChanged(NewOrExistingInterval); + void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase, NewOrExistingInterval); + void addTimeDependent(SVGSMILElement*); + void removeTimeDependent(SVGSMILElement*); + + enum ActiveState { Inactive, Active, Frozen }; + ActiveState determineActiveState(SMILTime elapsed) const; + float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const; + SMILTime calculateNextProgressTime(SMILTime elapsed) const; + + Vector<Condition> m_conditions; + bool m_conditionsConnected; + bool m_hasEndEventConditions; + + typedef HashSet<SVGSMILElement*> TimeDependentSet; + TimeDependentSet m_timeDependents; + + // Instance time lists + Vector<SMILTime> m_beginTimes; + Vector<SMILTime> m_endTimes; + + // This is the upcoming or current interval + SMILTime m_intervalBegin; + SMILTime m_intervalEnd; + + SMILTime m_previousIntervalBegin; + + bool m_isWaitingForFirstInterval; + + ActiveState m_activeState; + float m_lastPercent; + unsigned m_lastRepeat; + + SMILTime m_nextProgressTime; + + RefPtr<SMILTimeContainer> m_timeContainer; + unsigned m_documentOrderIndex; + + mutable SMILTime m_cachedDur; + mutable SMILTime m_cachedRepeatDur; + mutable SMILTime m_cachedRepeatCount; + mutable SMILTime m_cachedMin; + mutable SMILTime m_cachedMax; + + friend class ConditionEventListener; + }; + +} + +#endif +#endif + diff --git a/WebCore/svg/graphics/SVGImage.cpp b/WebCore/svg/graphics/SVGImage.cpp index c8d5cb1..4427277 100644 --- a/WebCore/svg/graphics/SVGImage.cpp +++ b/WebCore/svg/graphics/SVGImage.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Eric Seidel (eric@webkit.org) + * Copyright (C) 2008 Apple, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,10 +26,10 @@ #include "config.h" #if ENABLE(SVG) +#include "SVGImage.h" #include "CachedPage.h" #include "DocumentLoader.h" -#include "EditCommand.h" #include "FloatRect.h" #include "Frame.h" #include "FrameLoader.h" @@ -37,15 +38,15 @@ #include "ImageObserver.h" #include "NotImplemented.h" #include "Page.h" +#include "RenderView.h" #include "ResourceError.h" #include "SVGDocument.h" -#include "SVGImage.h" #include "SVGLength.h" #include "SVGRenderSupport.h" #include "SVGSVGElement.h" #include "Settings.h" -#include "SVGImageEmptyClients.h" +#include "EmptyClients.h" namespace WebCore { @@ -69,6 +70,8 @@ void SVGImage::setContainerSize(const IntSize& containerSize) if (containerSize.width() <= 0 || containerSize.height() <= 0) return; + if (!m_frame || !m_frame->document()) + return; SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement(); if (!rootElement) return; @@ -78,6 +81,8 @@ void SVGImage::setContainerSize(const IntSize& containerSize) bool SVGImage::usesContainerSize() const { + if (!m_frame || !m_frame->document()) + return false; SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement(); if (!rootElement) return false; @@ -101,18 +106,20 @@ IntSize SVGImage::size() const if (width.unitType() == LengthTypePercentage) svgSize.setWidth(rootElement->relativeWidthValue()); else - svgSize.setWidth(static_cast<int>(width.value())); + svgSize.setWidth(static_cast<int>(width.value(rootElement))); if (height.unitType() == LengthTypePercentage) svgSize.setHeight(rootElement->relativeHeightValue()); else - svgSize.setHeight(static_cast<int>(height.value())); + svgSize.setHeight(static_cast<int>(height.value(rootElement))); return svgSize; } bool SVGImage::hasRelativeWidth() const { + if (!m_frame || !m_frame->document()) + return false; SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement(); if (!rootElement) return false; @@ -122,6 +129,8 @@ bool SVGImage::hasRelativeWidth() const bool SVGImage::hasRelativeHeight() const { + if (!m_frame || !m_frame->document()) + return false; SVGSVGElement* rootElement = static_cast<SVGDocument*>(m_frame->document())->rootElement(); if (!rootElement) return false; @@ -135,10 +144,20 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl return; context->save(); + context->setCompositeOperation(compositeOp); context->clip(enclosingIntRect(dstRect)); + if (compositeOp != CompositeSourceOver) + context->beginTransparencyLayer(1.0f); context->translate(dstRect.location().x(), dstRect.location().y()); context->scale(FloatSize(dstRect.width()/srcRect.width(), dstRect.height()/srcRect.height())); - m_frame->paint(context, enclosingIntRect(srcRect)); + + if (m_frame->view()->needsLayout()) + m_frame->view()->layout(); + m_frame->view()->paint(context, enclosingIntRect(srcRect)); + + if (compositeOp != CompositeSourceOver) + context->endTransparencyLayer(); + context->restore(); if (imageObserver()) @@ -154,18 +173,9 @@ NativeImagePtr SVGImage::nativeImageForCurrentFrame() m_frameCache.set(ImageBuffer::create(size(), false).release()); if (!m_frameCache) // failed to allocate image return 0; - renderSubtreeToImage(m_frameCache.get(), m_frame->renderer()); + renderSubtreeToImage(m_frameCache.get(), m_frame->contentRenderer()); } -#if PLATFORM(CG) - return m_frameCache->cgImage(); -#elif PLATFORM(QT) - return m_frameCache->pixmap(); -#elif PLATFORM(CAIRO) - return m_frameCache->surface(); -#else - notImplemented(); - return 0; -#endif + return m_frameCache->image()->nativeImageForCurrentFrame(); } bool SVGImage::dataChanged(bool allDataReceived) @@ -175,31 +185,33 @@ bool SVGImage::dataChanged(bool allDataReceived) return true; if (allDataReceived) { - static ChromeClient* dummyChromeClient = new SVGEmptyChromeClient; - static FrameLoaderClient* dummyFrameLoaderClient = new SVGEmptyFrameLoaderClient; - static EditorClient* dummyEditorClient = new SVGEmptyEditorClient; - static ContextMenuClient* dummyContextMenuClient = new SVGEmptyContextMenuClient; - static DragClient* dummyDragClient = new SVGEmptyDragClient; - static InspectorClient* dummyInspectorClient = new SVGEmptyInspectorClient; + static ChromeClient* dummyChromeClient = new EmptyChromeClient; + static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient; + static EditorClient* dummyEditorClient = new EmptyEditorClient; + static ContextMenuClient* dummyContextMenuClient = new EmptyContextMenuClient; + static DragClient* dummyDragClient = new EmptyDragClient; + static InspectorClient* dummyInspectorClient = new EmptyInspectorClient; // FIXME: If this SVG ends up loading itself, we'll leak this Frame (and associated DOM & render trees). // The Cache code does not know about CachedImages holding Frames and won't know to break the cycle. m_page.set(new Page(dummyChromeClient, dummyContextMenuClient, dummyEditorClient, dummyDragClient, dummyInspectorClient)); m_page->settings()->setJavaScriptEnabled(false); + m_page->settings()->setPluginsEnabled(false); - m_frame = new Frame(m_page.get(), 0, dummyFrameLoaderClient); - m_frame->init(); + m_frame = Frame::create(m_page.get(), 0, dummyFrameLoaderClient); m_frameView = new FrameView(m_frame.get()); m_frameView->deref(); // FIXME: FrameView starts with a refcount of 1 m_frame->setView(m_frameView.get()); + m_frame->init(); ResourceRequest fakeRequest(KURL("")); m_frame->loader()->load(fakeRequest); // Make sure the DocumentLoader is created m_frame->loader()->cancelContentPolicyCheck(); // cancel any policy checks m_frame->loader()->commitProvisionalLoad(0); m_frame->loader()->setResponseMIMEType("image/svg+xml"); - m_frame->loader()->begin("placeholder.svg"); // create the empty document + m_frame->loader()->begin(KURL()); // create the empty document m_frame->loader()->write(m_data->data(), m_data->size()); m_frame->loader()->end(); + m_frameView->setTransparent(true); // SVG Images are transparent. } return m_frameView; } diff --git a/WebCore/svg/graphics/SVGImage.h b/WebCore/svg/graphics/SVGImage.h index 3e67a7c..994cf91 100644 --- a/WebCore/svg/graphics/SVGImage.h +++ b/WebCore/svg/graphics/SVGImage.h @@ -42,7 +42,10 @@ namespace WebCore { class SVGImage : public Image { public: - SVGImage(ImageObserver*); + static PassRefPtr<SVGImage> create(ImageObserver* observer) + { + return adoptRef(new SVGImage(observer)); + } ~SVGImage(); virtual void setContainerSize(const IntSize&); @@ -54,9 +57,15 @@ namespace WebCore { virtual bool dataChanged(bool allDataReceived); + // FIXME: SVGImages are underreporting decoded sizes and will be unable + // to prune because these functions are not implemented yet. + virtual void destroyDecodedData(bool incremental = false, bool preserveNearbyFrames = false) { } + virtual unsigned decodedSize() const { return 0; } + virtual NativeImagePtr frameAtIndex(size_t) { return 0; } private: + SVGImage(ImageObserver*); virtual void draw(GraphicsContext*, const FloatRect& fromRect, const FloatRect& toRect, CompositeOperator); virtual NativeImagePtr nativeImageForCurrentFrame(); diff --git a/WebCore/svg/graphics/SVGImageEmptyClients.h b/WebCore/svg/graphics/SVGImageEmptyClients.h deleted file mode 100644 index efaaa47..0000000 --- a/WebCore/svg/graphics/SVGImageEmptyClients.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Copyright (C) 2006 Eric Seidel (eric@webkit.org) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SVGImageEmptyClients_h -#define SVGImageEmptyClients_h - -#if ENABLE(SVG) - -#include "ChromeClient.h" -#include "ContextMenuClient.h" -#include "DragClient.h" -#include "EditorClient.h" -#include "FocusDirection.h" -#include "FrameLoaderClient.h" -#include "InspectorClient.h" -#include "SharedBuffer.h" - -/* - This file holds empty Client stubs for use by SVGImage. - SVGImage needs to create a dummy Page->Frame->FrameView tree for use in parsing an SVGDocument. - This tree depends heavily on Clients (usually provided by WebKit classes). - - SVGImage has no way to access the current Page (nor should it, since Images are not tied to a page). - See http://bugs.webkit.org/show_bug.cgi?id=5971 for more discussion on this issue. - - Ideally, whenever you change a Client class, you should add a stub here. - Brittle, yes. Unfortunate, yes. Hopefully temporary. -*/ - -namespace WebCore { - -class SVGEmptyChromeClient : public ChromeClient { -public: - virtual ~SVGEmptyChromeClient() { } - virtual void chromeDestroyed() { } - - virtual void setWindowRect(const FloatRect&) { } - virtual FloatRect windowRect() { return FloatRect(); } - - virtual FloatRect pageRect() { return FloatRect(); } - - virtual float scaleFactor() { return 1.f; } - - virtual void focus() { } - virtual void unfocus() { } - - virtual bool canTakeFocus(FocusDirection) { return false; } - virtual void takeFocus(FocusDirection) { } - - virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&) { return 0; } - virtual void show() { } - - virtual bool canRunModal() { return false; } - virtual void runModal() { } - - virtual void setToolbarsVisible(bool) { } - virtual bool toolbarsVisible() { return false; } - - virtual void setStatusbarVisible(bool) { } - virtual bool statusbarVisible() { return false; } - - virtual void setScrollbarsVisible(bool) { } - virtual bool scrollbarsVisible() { return false; } - - virtual void setMenubarVisible(bool) { } - virtual bool menubarVisible() { return false; } - - virtual void setResizable(bool) { } - - virtual void addMessageToConsole(const String& message, unsigned int lineNumber, const String& sourceID) { } - - virtual bool canRunBeforeUnloadConfirmPanel() { return false; } - virtual bool runBeforeUnloadConfirmPanel(const String& message, Frame* frame) { return true; } - - virtual void closeWindowSoon() { } - - virtual void runJavaScriptAlert(Frame*, const String&) { } - virtual bool runJavaScriptConfirm(Frame*, const String&) { return false; } - virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result) { return false; } - virtual bool shouldInterruptJavaScript() { return false; } - - virtual void setStatusbarText(const String&) { } - - virtual bool tabsToLinks() const { return false; } - - virtual IntRect windowResizerRect() const { return IntRect(); } - virtual void addToDirtyRegion(const IntRect&) { } - virtual void scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect) { } - virtual void updateBackingStore() { } - - virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) { } - - virtual void setToolTip(const String&) { } - - virtual void print(Frame*) { } - - virtual void exceededDatabaseQuota(Frame*, const String&) { } -}; - -class SVGEmptyFrameLoaderClient : public FrameLoaderClient { -public: - virtual ~SVGEmptyFrameLoaderClient() { } - virtual void frameLoaderDestroyed() { } - - virtual bool hasWebView() const { return true; } // mainly for assertions - virtual bool hasFrameView() const { return true; } // ditto - - virtual void makeRepresentation(DocumentLoader*) { } - virtual void forceLayout() { } - virtual void forceLayoutForNonHTML() { } - - virtual void updateHistoryForCommit() { } - - virtual void updateHistoryForBackForwardNavigation() { } - virtual void updateHistoryForReload() { } - virtual void updateHistoryForStandardLoad() { } - virtual void updateHistoryForInternalLoad() { } - - virtual void updateHistoryAfterClientRedirect() { } - - virtual void setCopiesOnScroll() { } - - virtual void detachedFromParent2() { } - virtual void detachedFromParent3() { } - virtual void detachedFromParent4() { } - - virtual void download(ResourceHandle*, const ResourceRequest&, const ResourceRequest&, const ResourceResponse&) { } - - virtual void assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&) { } - virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse) { } - virtual void dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) { } - virtual void dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) { } - virtual void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&) { } - virtual void dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived) { } - virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier) { } - virtual void dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&) { } - virtual bool dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length) { return false; } - - virtual void dispatchDidHandleOnloadEvents() { } - virtual void dispatchDidReceiveServerRedirectForProvisionalLoad() { } - virtual void dispatchDidCancelClientRedirect() { } - virtual void dispatchWillPerformClientRedirect(const KURL&, double interval, double fireDate) { } - virtual void dispatchDidChangeLocationWithinPage() { } - virtual void dispatchWillClose() { } - virtual void dispatchDidReceiveIcon() { } - virtual void dispatchDidStartProvisionalLoad() { } - virtual void dispatchDidReceiveTitle(const String& title) { } - virtual void dispatchDidCommitLoad() { } - virtual void dispatchDidFailProvisionalLoad(const ResourceError&) { } - virtual void dispatchDidFailLoad(const ResourceError&) { } - virtual void dispatchDidFinishDocumentLoad() { } - virtual void dispatchDidFinishLoad() { } - virtual void dispatchDidFirstLayout() { } - - virtual Frame* dispatchCreatePage() { return 0; } - virtual void dispatchShow() { } - - virtual void dispatchDecidePolicyForMIMEType(FramePolicyFunction, const String& MIMEType, const ResourceRequest&) { } - virtual void dispatchDecidePolicyForNewWindowAction(FramePolicyFunction, const NavigationAction&, const ResourceRequest&, const String& frameName) { } - virtual void dispatchDecidePolicyForNavigationAction(FramePolicyFunction, const NavigationAction&, const ResourceRequest&) { } - virtual void cancelPolicyCheck() { } - - virtual void dispatchUnableToImplementPolicy(const ResourceError&) { } - - virtual void dispatchWillSubmitForm(FramePolicyFunction, PassRefPtr<FormState>) { } - - virtual void dispatchDidLoadMainResource(DocumentLoader*) { } - virtual void revertToProvisionalState(DocumentLoader*) { } - virtual void setMainDocumentError(DocumentLoader*, const ResourceError&) { } - virtual void clearUnarchivingState(DocumentLoader*) { } - - virtual void willChangeEstimatedProgress() { } - virtual void didChangeEstimatedProgress() { } - virtual void postProgressStartedNotification() { } - virtual void postProgressEstimateChangedNotification() { } - virtual void postProgressFinishedNotification() { } - - virtual void setMainFrameDocumentReady(bool) { } - - virtual void startDownload(const ResourceRequest&) { } - - virtual void willChangeTitle(DocumentLoader*) { } - virtual void didChangeTitle(DocumentLoader*) { } - - virtual void committedLoad(DocumentLoader*, const char*, int) { } - virtual void finishedLoading(DocumentLoader*) { } - virtual void finalSetupForReplace(DocumentLoader*) { } - - virtual ResourceError cancelledError(const ResourceRequest&) { return ResourceError(); } - virtual ResourceError blockedError(const ResourceRequest&) { return ResourceError(); } - virtual ResourceError cannotShowURLError(const ResourceRequest&) { return ResourceError(); } - virtual ResourceError interruptForPolicyChangeError(const ResourceRequest&) { return ResourceError(); } - - virtual ResourceError cannotShowMIMETypeError(const ResourceResponse&) { return ResourceError(); } - virtual ResourceError fileDoesNotExistError(const ResourceResponse&) { return ResourceError(); } - - virtual bool shouldFallBack(const ResourceError&) { return false; } - - virtual void setDefersLoading(bool) { } - - virtual bool willUseArchive(ResourceLoader*, const ResourceRequest&, const KURL& originalURL) const { return false; } - virtual bool isArchiveLoadPending(ResourceLoader*) const { return false; } - virtual void cancelPendingArchiveLoad(ResourceLoader*) { } - virtual void clearArchivedResources() { } - - virtual bool canHandleRequest(const ResourceRequest&) const { return false; } - virtual bool canShowMIMEType(const String& MIMEType) const { return false; } - virtual bool representationExistsForURLScheme(const String& URLScheme) const { return false; } - virtual String generatedMIMETypeForURLScheme(const String& URLScheme) const { return ""; } - - virtual void frameLoadCompleted() { } - virtual void restoreViewState() { } - virtual void provisionalLoadStarted() { } - virtual bool shouldTreatURLAsSameAsCurrent(const KURL&) const { return false; } - virtual void addHistoryItemForFragmentScroll() { } - virtual void didFinishLoad() { } - virtual void prepareForDataSourceReplacement() { } - - virtual PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) { return new DocumentLoader(request, substituteData); } - virtual void setTitle(const String& title, const KURL&) { } - - virtual String userAgent(const KURL&) { return ""; } - - virtual void savePlatformDataToCachedPage(CachedPage*) { } - virtual void transitionToCommittedFromCachedPage(CachedPage*) { } - virtual void transitionToCommittedForNewPage() { } - - virtual void updateGlobalHistoryForStandardLoad(const KURL&) { } - virtual void updateGlobalHistoryForReload(const KURL&) { } - virtual bool shouldGoToHistoryItem(HistoryItem*) const { return false; } - virtual void saveViewStateToItem(HistoryItem*) { } - virtual bool canCachePage() const { return false; } - - virtual PassRefPtr<Frame> createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, - const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight) { return 0; } - virtual Widget* createPlugin(const IntSize&,Element*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool) { return 0; } - virtual Widget* createJavaAppletWidget(const IntSize&, Element*, const KURL&, const Vector<String>&, const Vector<String>&) { return 0; } - - virtual ObjectContentType objectContentType(const KURL& url, const String& mimeType) { return ObjectContentType(); } - virtual String overrideMediaType() const { return String(); } - - virtual void redirectDataToPlugin(Widget*) {} - virtual void windowObjectCleared() {} - virtual void didPerformFirstNavigation() const {} - - virtual void registerForIconNotification(bool listen) {} - -#if PLATFORM(MAC) - virtual NSCachedURLResponse* willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const { return response; } -#endif - -}; - -class SVGEmptyEditorClient : public EditorClient { -public: - virtual ~SVGEmptyEditorClient() { } - virtual void pageDestroyed() { } - - virtual bool shouldDeleteRange(Range*) { return false; } - virtual bool shouldShowDeleteInterface(HTMLElement*) { return false; } - virtual bool smartInsertDeleteEnabled() { return false; } - virtual bool isContinuousSpellCheckingEnabled() { return false; } - virtual void toggleContinuousSpellChecking() { } - virtual bool isGrammarCheckingEnabled() { return false; } - virtual void toggleGrammarChecking() { } - virtual int spellCheckerDocumentTag() { return -1; } - - virtual bool selectWordBeforeMenuEvent() { return false; } - virtual bool isEditable() { return false; } - - virtual bool shouldBeginEditing(Range*) { return false; } - virtual bool shouldEndEditing(Range*) { return false; } - virtual bool shouldInsertNode(Node*, Range*, EditorInsertAction) { return false; } - // virtual bool shouldInsertNode(Node*, Range* replacingRange, WebViewInsertAction) { return false; } - virtual bool shouldInsertText(String, Range*, EditorInsertAction) { return false; } - virtual bool shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity, bool stillSelecting) { return false; } - - virtual bool shouldApplyStyle(CSSStyleDeclaration*, Range*) { return false; } - virtual bool shouldMoveRangeAfterDelete(Range*, Range*) { return false; } - // virtual bool shouldChangeTypingStyle(CSSStyleDeclaration* fromStyle, CSSStyleDeclaration* toStyle) { return false; } - // virtual bool doCommandBySelector(SEL selector) { return false; } - // - virtual void didBeginEditing() { } - virtual void respondToChangedContents() { } - virtual void respondToChangedSelection() { } - virtual void didEndEditing() { } - virtual void didWriteSelectionToPasteboard() { } - virtual void didSetSelectionTypesForPasteboard() { } - // virtual void webViewDidChangeTypingStyle:(NSNotification *)notification { } - // virtual void webViewDidChangeSelection:(NSNotification *)notification { } - // virtual NSUndoManager* undoManagerForWebView:(WebView *)webView { return 0; } - - virtual void registerCommandForUndo(PassRefPtr<EditCommand>) { } - virtual void registerCommandForRedo(PassRefPtr<EditCommand>) { } - virtual void clearUndoRedoOperations() { } - - virtual bool canUndo() const { return false; } - virtual bool canRedo() const { return false; } - - virtual void undo() { } - virtual void redo() { } - - virtual void handleKeyboardEvent(KeyboardEvent*) { } - virtual void handleInputMethodKeydown(KeyboardEvent*) { } - - virtual void textFieldDidBeginEditing(Element*) { } - virtual void textFieldDidEndEditing(Element*) { } - virtual void textDidChangeInTextField(Element*) { } - virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*) { return false; } - virtual void textWillBeDeletedInTextField(Element*) { } - virtual void textDidChangeInTextArea(Element*) { } - -#if PLATFORM(MAC) - virtual void markedTextAbandoned(Frame*) { } - - // FIXME: This should become SelectionController::toWebArchive() - virtual NSData* dataForArchivedSelection(Frame*) { return 0; } - - virtual NSString* userVisibleString(NSURL*) { return 0; } -#ifdef BUILDING_ON_TIGER - virtual NSArray* pasteboardTypesForSelection(Frame*) { return 0; } -#endif -#endif - virtual void ignoreWordInSpellDocument(const String&) { } - virtual void learnWord(const String&) { } - virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) { } - virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) { } - virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail&) { } - virtual void updateSpellingUIWithMisspelledWord(const String&) { } - virtual void showSpellingUI(bool show) { } - virtual bool spellingUIIsShowing() { return false; } - virtual void getGuessesForWord(const String&, Vector<String>& guesses) { } - virtual void setInputMethodState(bool enabled) { } - - -}; - -class SVGEmptyContextMenuClient : public ContextMenuClient { -public: - virtual ~SVGEmptyContextMenuClient() { } - virtual void contextMenuDestroyed() { } - - virtual PlatformMenuDescription getCustomMenuFromDefaultItems(ContextMenu*) { return 0; } - virtual void contextMenuItemSelected(ContextMenuItem*, const ContextMenu*) { } - - virtual void downloadURL(const KURL& url) { } - virtual void copyImageToClipboard(const HitTestResult&) { } - virtual void searchWithGoogle(const Frame*) { } - virtual void lookUpInDictionary(Frame*) { } - virtual void speak(const String&) { } - virtual void stopSpeaking() { } - -#if PLATFORM(MAC) - virtual void searchWithSpotlight() { } -#endif -}; - -class SVGEmptyDragClient : public DragClient { -public: - virtual ~SVGEmptyDragClient() {} - virtual void willPerformDragDestinationAction(DragDestinationAction, DragData*) { } - virtual void willPerformDragSourceAction(DragSourceAction, const IntPoint&, Clipboard*) { } - virtual DragDestinationAction actionMaskForDrag(DragData*) { return DragDestinationActionNone; } - virtual DragSourceAction dragSourceActionMaskForPoint(const IntPoint&) { return DragSourceActionNone; } - virtual void startDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool) { } - virtual DragImageRef createDragImageForLink(KURL&, const String& label, Frame*) { return 0; } - virtual void dragControllerDestroyed() { } -}; - -class SVGEmptyInspectorClient : public InspectorClient { -public: - virtual ~SVGEmptyInspectorClient() {} - - virtual void inspectorDestroyed() {}; - - virtual Page* createPage() { return 0; }; - - virtual String localizedStringsURL() { return String(); }; - - virtual void showWindow() {}; - virtual void closeWindow() {}; - - virtual void attachWindow() {}; - virtual void detachWindow() {}; - - virtual void highlight(Node*) {}; - virtual void hideHighlight() {}; - virtual void inspectedURLChanged(const String& newURL) {}; -}; - -} - -#endif // ENABLE(SVG) - -#endif // SVGImageEmptyClients_h - diff --git a/WebCore/svg/graphics/SVGPaintServer.cpp b/WebCore/svg/graphics/SVGPaintServer.cpp index 32c0d3c..0240532 100644 --- a/WebCore/svg/graphics/SVGPaintServer.cpp +++ b/WebCore/svg/graphics/SVGPaintServer.cpp @@ -29,6 +29,7 @@ #if ENABLE(SVG) #include "SVGPaintServer.h" +#include "GraphicsContext.h" #include "RenderObject.h" #include "RenderStyle.h" #include "SVGPaintServerSolid.h" @@ -61,9 +62,8 @@ SVGPaintServer* getPaintServerById(Document* document, const AtomicString& id) SVGPaintServerSolid* SVGPaintServer::sharedSolidPaintServer() { - static SVGPaintServerSolid* _sharedSolidPaintServer = 0; - if (!_sharedSolidPaintServer) - _sharedSolidPaintServer = new SVGPaintServerSolid(); + static SVGPaintServerSolid* _sharedSolidPaintServer = SVGPaintServerSolid::create().releaseRef(); + return _sharedSolidPaintServer; } @@ -145,6 +145,19 @@ SVGPaintServer* SVGPaintServer::strokePaintServer(const RenderStyle* style, cons return strokePaintServer; } +void applyStrokeStyleToContext(GraphicsContext* context, RenderStyle* style, const RenderObject* object) +{ + context->setStrokeThickness(SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeWidth(), 1.0f)); + context->setLineCap(style->svgStyle()->capStyle()); + context->setLineJoin(style->svgStyle()->joinStyle()); + if (style->svgStyle()->joinStyle() == MiterJoin) + context->setMiterLimit(style->svgStyle()->strokeMiterLimit()); + + const DashArray& dashes = dashArrayFromRenderingStyle(object->style()); + float dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0f); + context->setLineDash(dashes, dashOffset); +} + DashArray dashArrayFromRenderingStyle(const RenderStyle* style) { DashArray array; @@ -154,7 +167,7 @@ DashArray dashArrayFromRenderingStyle(const RenderStyle* style) CSSPrimitiveValue* dash = 0; unsigned long len = dashes->length(); for (unsigned long i = 0; i < len; i++) { - dash = static_cast<CSSPrimitiveValue*>(dashes->item(i)); + dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i)); if (!dash) continue; diff --git a/WebCore/svg/graphics/SVGPaintServer.h b/WebCore/svg/graphics/SVGPaintServer.h index e66a103..0d37e9f 100644 --- a/WebCore/svg/graphics/SVGPaintServer.h +++ b/WebCore/svg/graphics/SVGPaintServer.h @@ -28,22 +28,13 @@ #if ENABLE(SVG) +#include "DashArray.h" #include "SVGResource.h" #if PLATFORM(CG) #include <ApplicationServices/ApplicationServices.h> #endif -#if PLATFORM(QT) -class QPen; -#endif - -#if PLATFORM(CG) - typedef Vector<CGFloat> DashArray; -#else - typedef Vector<float> DashArray; -#endif - namespace WebCore { enum SVGPaintServerType { @@ -67,7 +58,6 @@ namespace WebCore { class SVGPaintServer : public SVGResource { public: - SVGPaintServer(); virtual ~SVGPaintServer(); virtual SVGResourceType resourceType() const { return PaintServerResourceType; } @@ -94,15 +84,15 @@ namespace WebCore { void clipToFillPath(CGContextRef, const RenderObject*) const; #endif -#if PLATFORM(QT) - void setPenProperties(const RenderObject*, const RenderStyle*, QPen&) const; -#endif + protected: + SVGPaintServer(); }; TextStream& operator<<(TextStream&, const SVGPaintServer&); SVGPaintServer* getPaintServerById(Document*, const AtomicString&); + void applyStrokeStyleToContext(GraphicsContext*, RenderStyle*, const RenderObject*); DashArray dashArrayFromRenderingStyle(const RenderStyle* style); } // namespace WebCore diff --git a/WebCore/svg/graphics/SVGPaintServerGradient.cpp b/WebCore/svg/graphics/SVGPaintServerGradient.cpp index 6a701b8..58dd6bf 100644 --- a/WebCore/svg/graphics/SVGPaintServerGradient.cpp +++ b/WebCore/svg/graphics/SVGPaintServerGradient.cpp @@ -33,14 +33,14 @@ namespace WebCore { -TextStream& operator<<(TextStream& ts, SVGGradientSpreadMethod m) +TextStream& operator<<(TextStream& ts, GradientSpreadMethod m) { switch (m) { - case SPREADMETHOD_PAD: + case SpreadMethodPad: ts << "PAD"; break; - case SPREADMETHOD_REPEAT: + case SpreadMethodRepeat: ts << "REPEAT"; break; - case SPREADMETHOD_REFLECT: + case SpreadMethodReflect: ts << "REFLECT"; break; } @@ -60,7 +60,7 @@ TextStream& operator<<(TextStream& ts, const Vector<SVGGradientStop>& l) } SVGPaintServerGradient::SVGPaintServerGradient(const SVGGradientElement* owner) - : m_spreadMethod(SPREADMETHOD_PAD) + : m_spreadMethod(SpreadMethodPad) , m_boundingBoxMode(true) , m_ownerElement(owner) @@ -91,12 +91,12 @@ void SVGPaintServerGradient::setGradientStops(const Vector<SVGGradientStop>& sto m_stops = stops; } -SVGGradientSpreadMethod SVGPaintServerGradient::spreadMethod() const +GradientSpreadMethod SVGPaintServerGradient::spreadMethod() const { return m_spreadMethod; } -void SVGPaintServerGradient::setGradientSpreadMethod(const SVGGradientSpreadMethod& method) +void SVGPaintServerGradient::setGradientSpreadMethod(const GradientSpreadMethod& method) { m_spreadMethod = method; } @@ -128,7 +128,7 @@ TextStream& SVGPaintServerGradient::externalRepresentation(TextStream& ts) const // abstract, don't stream type ts << "[stops=" << gradientStops() << "]"; - if (spreadMethod() != SPREADMETHOD_PAD) + if (spreadMethod() != SpreadMethodPad) ts << "[method=" << spreadMethod() << "]"; if (!boundingBoxMode()) ts << " [bounding box mode=" << boundingBoxMode() << "]"; diff --git a/WebCore/svg/graphics/SVGPaintServerGradient.h b/WebCore/svg/graphics/SVGPaintServerGradient.h index afab7ab..99dac8e 100644 --- a/WebCore/svg/graphics/SVGPaintServerGradient.h +++ b/WebCore/svg/graphics/SVGPaintServerGradient.h @@ -30,13 +30,17 @@ #include "AffineTransform.h" #include "Color.h" +#include "GraphicsContext.h" #include "SVGPaintServer.h" #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> #if PLATFORM(QT) +#include <qglobal.h> +QT_BEGIN_NAMESPACE class QGradient; +QT_END_NAMESPACE #endif namespace WebCore { @@ -44,30 +48,21 @@ namespace WebCore { class ImageBuffer; class SVGGradientElement; - // FIXME: Remove the spread method enum in SVGGradientElement - enum SVGGradientSpreadMethod { - SPREADMETHOD_PAD = 1, - SPREADMETHOD_REFLECT = 2, - SPREADMETHOD_REPEAT = 3 - }; - #if PLATFORM(CG) typedef std::pair<CGFloat, Color> SVGGradientStop; #else typedef std::pair<float, Color> SVGGradientStop; #endif - class SVGPaintServerGradient : public SVGPaintServer { public: - SVGPaintServerGradient(const SVGGradientElement*); virtual ~SVGPaintServerGradient(); const Vector<SVGGradientStop>& gradientStops() const; void setGradientStops(const Vector<SVGGradientStop>&); - SVGGradientSpreadMethod spreadMethod() const; - void setGradientSpreadMethod(const SVGGradientSpreadMethod&); + GradientSpreadMethod spreadMethod() const; + void setGradientSpreadMethod(const GradientSpreadMethod&); // Gradient start and end points are percentages when used in boundingBox mode. // For instance start point with value (0,0) is top-left and end point with @@ -99,9 +94,12 @@ namespace WebCore { virtual QGradient setupGradient(GraphicsContext*&, const RenderObject*) const = 0; #endif + protected: + SVGPaintServerGradient(const SVGGradientElement* owner); + private: Vector<SVGGradientStop> m_stops; - SVGGradientSpreadMethod m_spreadMethod; + GradientSpreadMethod m_spreadMethod; bool m_boundingBoxMode; AffineTransform m_gradientTransform; const SVGGradientElement* m_ownerElement; @@ -115,7 +113,13 @@ namespace WebCore { } QuartzGradientStop; struct SharedStopCache : public RefCounted<SharedStopCache> { + public: + static PassRefPtr<SharedStopCache> create() { return adoptRef(new SharedStopCache); } + Vector<QuartzGradientStop> m_stops; + + private: + SharedStopCache() { } }; RefPtr<SharedStopCache> m_stopsCache; diff --git a/WebCore/svg/graphics/SVGPaintServerLinearGradient.h b/WebCore/svg/graphics/SVGPaintServerLinearGradient.h index e198830..4b7da32 100644 --- a/WebCore/svg/graphics/SVGPaintServerLinearGradient.h +++ b/WebCore/svg/graphics/SVGPaintServerLinearGradient.h @@ -35,7 +35,7 @@ namespace WebCore { class SVGPaintServerLinearGradient : public SVGPaintServerGradient { public: - SVGPaintServerLinearGradient(const SVGGradientElement* owner); + static PassRefPtr<SVGPaintServerLinearGradient> create(const SVGGradientElement* owner) { return adoptRef(new SVGPaintServerLinearGradient(owner)); } virtual ~SVGPaintServerLinearGradient(); virtual SVGPaintServerType type() const { return LinearGradientPaintServer; } @@ -53,6 +53,8 @@ namespace WebCore { #endif private: + SVGPaintServerLinearGradient(const SVGGradientElement* owner); + FloatPoint m_start; FloatPoint m_end; }; diff --git a/WebCore/svg/graphics/SVGPaintServerPattern.h b/WebCore/svg/graphics/SVGPaintServerPattern.h index 5e7f6ce..65b28e9 100644 --- a/WebCore/svg/graphics/SVGPaintServerPattern.h +++ b/WebCore/svg/graphics/SVGPaintServerPattern.h @@ -44,7 +44,8 @@ namespace WebCore { class SVGPaintServerPattern : public SVGPaintServer { public: - SVGPaintServerPattern(const SVGPatternElement*); + static PassRefPtr<SVGPaintServerPattern> create(const SVGPatternElement* owner) { return adoptRef(new SVGPaintServerPattern(owner)); } + virtual ~SVGPaintServerPattern(); virtual SVGPaintServerType type() const { return PatternPaintServer; } @@ -61,16 +62,14 @@ namespace WebCore { virtual TextStream& externalRepresentation(TextStream&) const; -#if PLATFORM(CG) - virtual bool setup(GraphicsContext*&, const RenderObject*, SVGPaintTargetType, bool isPaintingText) const; - virtual void teardown(GraphicsContext*&, const RenderObject*, SVGPaintTargetType, bool isPaintingText) const; -#endif - -#if PLATFORM(QT) || PLATFORM(CAIRO) virtual bool setup(GraphicsContext*&, const RenderObject*, SVGPaintTargetType, bool isPaintingText) const; +#if PLATFORM(CG) || PLATFORM(QT) + virtual void teardown(GraphicsContext*&, const RenderObject*, SVGPaintTargetType, bool isPaintingText) const; #endif private: + SVGPaintServerPattern(const SVGPatternElement*); + OwnPtr<ImageBuffer> m_tile; const SVGPatternElement* m_ownerElement; AffineTransform m_patternTransform; diff --git a/WebCore/svg/graphics/SVGPaintServerRadialGradient.h b/WebCore/svg/graphics/SVGPaintServerRadialGradient.h index 1f19e3d..265f76b 100644 --- a/WebCore/svg/graphics/SVGPaintServerRadialGradient.h +++ b/WebCore/svg/graphics/SVGPaintServerRadialGradient.h @@ -35,7 +35,7 @@ namespace WebCore { class SVGPaintServerRadialGradient : public SVGPaintServerGradient { public: - SVGPaintServerRadialGradient(const SVGGradientElement* owner); + static PassRefPtr<SVGPaintServerRadialGradient> create(const SVGGradientElement* owner) { return adoptRef(new SVGPaintServerRadialGradient(owner)); } virtual ~SVGPaintServerRadialGradient(); virtual SVGPaintServerType type() const { return RadialGradientPaintServer; } @@ -56,6 +56,8 @@ namespace WebCore { #endif private: + SVGPaintServerRadialGradient(const SVGGradientElement* owner); + float m_radius; FloatPoint m_center; FloatPoint m_focal; diff --git a/WebCore/svg/graphics/SVGPaintServerSolid.h b/WebCore/svg/graphics/SVGPaintServerSolid.h index f05a4e6..0166c87 100644 --- a/WebCore/svg/graphics/SVGPaintServerSolid.h +++ b/WebCore/svg/graphics/SVGPaintServerSolid.h @@ -35,7 +35,7 @@ namespace WebCore { class SVGPaintServerSolid : public SVGPaintServer { public: - SVGPaintServerSolid(); + static PassRefPtr<SVGPaintServerSolid> create() { return adoptRef(new SVGPaintServerSolid); } virtual ~SVGPaintServerSolid(); virtual SVGPaintServerType type() const { return SolidPaintServer; } @@ -45,11 +45,11 @@ namespace WebCore { virtual TextStream& externalRepresentation(TextStream&) const; -#if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(CAIRO) virtual bool setup(GraphicsContext*&, const RenderObject*, SVGPaintTargetType, bool isPaintingText) const; -#endif private: + SVGPaintServerSolid(); + Color m_color; }; diff --git a/WebCore/svg/graphics/SVGResource.h b/WebCore/svg/graphics/SVGResource.h index 5272468..7ee98f6 100644 --- a/WebCore/svg/graphics/SVGResource.h +++ b/WebCore/svg/graphics/SVGResource.h @@ -66,7 +66,6 @@ namespace WebCore { class SVGResource : public RefCounted<SVGResource> { public: - SVGResource(); virtual ~SVGResource(); virtual void invalidate(); @@ -85,6 +84,9 @@ namespace WebCore { static void invalidateClients(HashSet<SVGStyledElement*>); static void removeClient(SVGStyledElement*); + protected: + SVGResource(); + private: HashSet<SVGStyledElement*> m_clients; }; diff --git a/WebCore/svg/graphics/SVGResourceClipper.cpp b/WebCore/svg/graphics/SVGResourceClipper.cpp index 3e52322..f03f5c2 100644 --- a/WebCore/svg/graphics/SVGResourceClipper.cpp +++ b/WebCore/svg/graphics/SVGResourceClipper.cpp @@ -29,7 +29,6 @@ #include "SVGResourceClipper.h" #include "SVGRenderTreeAsText.h" -#include "TextStream.h" namespace WebCore { diff --git a/WebCore/svg/graphics/SVGResourceClipper.h b/WebCore/svg/graphics/SVGResourceClipper.h index d5c1ab7..98c295f 100644 --- a/WebCore/svg/graphics/SVGResourceClipper.h +++ b/WebCore/svg/graphics/SVGResourceClipper.h @@ -63,7 +63,7 @@ namespace WebCore { class SVGResourceClipper : public SVGResource { public: - SVGResourceClipper(); + static PassRefPtr<SVGResourceClipper> create() { return adoptRef(new SVGResourceClipper); } virtual ~SVGResourceClipper(); void resetClipData(); @@ -77,6 +77,7 @@ namespace WebCore { // To be implemented by the specific rendering devices void applyClip(GraphicsContext*, const FloatRect& boundingBox) const; private: + SVGResourceClipper(); ClipDataList m_clipData; }; diff --git a/WebCore/svg/graphics/SVGResourceFilter.cpp b/WebCore/svg/graphics/SVGResourceFilter.cpp index dceda8b..8fb2dfa 100644 --- a/WebCore/svg/graphics/SVGResourceFilter.cpp +++ b/WebCore/svg/graphics/SVGResourceFilter.cpp @@ -26,7 +26,6 @@ #include "SVGRenderTreeAsText.h" #include "SVGFilterEffect.h" -#include "TextStream.h" namespace WebCore { diff --git a/WebCore/svg/graphics/SVGResourceMarker.h b/WebCore/svg/graphics/SVGResourceMarker.h index a78573b..bb4039c 100644 --- a/WebCore/svg/graphics/SVGResourceMarker.h +++ b/WebCore/svg/graphics/SVGResourceMarker.h @@ -38,7 +38,7 @@ namespace WebCore { class SVGResourceMarker : public SVGResource { public: - SVGResourceMarker(); + static PassRefPtr<SVGResourceMarker> create() { return adoptRef(new SVGResourceMarker); } virtual ~SVGResourceMarker(); void setMarker(RenderSVGViewportContainer*); @@ -61,6 +61,7 @@ namespace WebCore { virtual TextStream& externalRepresentation(TextStream&) const; private: + SVGResourceMarker(); double m_refX, m_refY; FloatRect m_cachedBounds; float m_angle; diff --git a/WebCore/svg/graphics/SVGResourceMasker.h b/WebCore/svg/graphics/SVGResourceMasker.h index d530571..f945f56 100644 --- a/WebCore/svg/graphics/SVGResourceMasker.h +++ b/WebCore/svg/graphics/SVGResourceMasker.h @@ -34,6 +34,7 @@ #include <memory> #include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> namespace WebCore { @@ -43,7 +44,7 @@ namespace WebCore { class SVGResourceMasker : public SVGResource { public: - SVGResourceMasker(const SVGMaskElement*); + static PassRefPtr<SVGResourceMasker> create(const SVGMaskElement* ownerElement) { return adoptRef(new SVGResourceMasker(ownerElement)); } virtual ~SVGResourceMasker(); virtual void invalidate(); @@ -55,6 +56,8 @@ namespace WebCore { void applyMask(GraphicsContext*, const FloatRect& boundingBox); private: + SVGResourceMasker(const SVGMaskElement*); + const SVGMaskElement* m_ownerElement; OwnPtr<ImageBuffer> m_mask; diff --git a/WebCore/svg/graphics/cairo/SVGPaintServerGradientCairo.cpp b/WebCore/svg/graphics/cairo/SVGPaintServerGradientCairo.cpp index 7b22f4f..e237962 100644 --- a/WebCore/svg/graphics/cairo/SVGPaintServerGradientCairo.cpp +++ b/WebCore/svg/graphics/cairo/SVGPaintServerGradientCairo.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -43,31 +44,69 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject cairo_matrix_init_identity (&matrix); const cairo_matrix_t gradient_matrix = gradientTransform(); - // TODO: revise this code, it is known not to work in many cases + const SVGRenderStyle* svgStyle = object->style()->svgStyle(); + RenderStyle* style = object->style(); + if (this->type() == LinearGradientPaintServer) { const SVGPaintServerLinearGradient* linear = static_cast<const SVGPaintServerLinearGradient*>(this); if (boundingBoxMode()) { - // TODO: use RenderPathCairo's strokeBBox? - double x1, y1, x2, y2; - cairo_fill_extents(cr, &x1, &y1, &x2, &y2); - cairo_matrix_translate(&matrix, x1, y1); - cairo_matrix_scale(&matrix, x2 - x1, y2 - y1); - cairo_matrix_multiply(&matrix, &matrix, &gradient_matrix); - cairo_matrix_invert(&matrix); + FloatRect bbox = object->relativeBBox(false); + if (bbox.width() == 0 || bbox.height() == 0) { + applyStrokeStyleToContext(context, style, object); + cairo_set_source_rgb(cr, 0, 0, 0); + return true; + } + cairo_matrix_translate(&matrix, bbox.x(), bbox.y()); + cairo_matrix_scale(&matrix, bbox.width(), bbox.height()); } - double x0, x1, y0, y1; - x0 = linear->gradientStart().x(); - y0 = linear->gradientStart().y(); - x1 = linear->gradientEnd().x(); - y1 = linear->gradientEnd().y(); + double x0 = linear->gradientStart().x(); + double y0 = linear->gradientStart().y(); + double x1 = linear->gradientEnd().x(); + double y1 = linear->gradientEnd().y(); + pattern = cairo_pattern_create_linear(x0, y0, x1, y1); } else if (this->type() == RadialGradientPaintServer) { - // const SVGPaintServerRadialGradient* radial = static_cast<const SVGPaintServerRadialGradient*>(this); - // TODO: pattern = cairo_pattern_create_radial(); - return false; + const SVGPaintServerRadialGradient* radial = static_cast<const SVGPaintServerRadialGradient*>(this); + + if (boundingBoxMode()) { + FloatRect bbox = object->relativeBBox(false); + if (bbox.width() == 0 || bbox.height() == 0) { + applyStrokeStyleToContext(context, style, object); + cairo_set_source_rgb(cr, 0, 0, 0); + return true; + } + cairo_matrix_translate(&matrix, bbox.x(), bbox.y()); + cairo_matrix_scale(&matrix, bbox.width(), bbox.height()); + } + + double cx = radial->gradientCenter().x(); + double cy = radial->gradientCenter().y(); + double radius = radial->gradientRadius(); + double fx = radial->gradientFocal().x(); + double fy = radial->gradientFocal().y(); + + fx -= cx; + fy -= cy; + + double fradius = 0.0; + + if (sqrt(fx * fx + fy * fy) >= radius) { + double angle = atan2(fy, fx); + if ((fx + cx) < cx) + fx = cos(angle) * radius + 0.002; + else + fx = cos(angle) * radius - 0.002; + if ((fy + cy) < cy) + fy = sin(angle) * radius + 0.002; + else + fy = sin(angle) * radius - 0.002; + } + + pattern = cairo_pattern_create_radial(fx + cx, fy + cy, fradius, cx, cy, radius); + } else { return false; } @@ -75,13 +114,13 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject cairo_pattern_set_filter(pattern, CAIRO_FILTER_BILINEAR); switch (spreadMethod()) { - case SPREADMETHOD_PAD: + case SpreadMethodPad: cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD); break; - case SPREADMETHOD_REFLECT: + case SpreadMethodReflect: cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REFLECT); break; - case SPREADMETHOD_REPEAT: + case SpreadMethodRepeat: cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); break; default: @@ -89,6 +128,8 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject break; } + cairo_matrix_multiply(&matrix, &matrix, &gradient_matrix); + cairo_matrix_invert(&matrix); cairo_pattern_set_matrix(pattern, &matrix); const Vector<SVGGradientStop>& stops = gradientStops(); @@ -96,10 +137,18 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject for (unsigned i = 0; i < stops.size(); ++i) { float offset = stops[i].first; Color color = stops[i].second; + if (i > 0 && offset < stops[i - 1].first) + offset = stops[i - 1].first; - cairo_pattern_add_color_stop_rgba(pattern, offset, color.red(), color.green(), color.blue(), color.alpha()); + cairo_pattern_add_color_stop_rgba(pattern, offset, color.red() / 255.0, color.green() / 255.0, color.blue() / 255.0, color.alpha() / 255.0); } + if ((type & ApplyToFillTargetType) && svgStyle->hasFill()) + context->setFillRule(svgStyle->fillRule()); + + if ((type & ApplyToStrokeTargetType) && svgStyle->hasStroke()) + applyStrokeStyleToContext(context, style, object); + cairo_set_source(cr, pattern); cairo_pattern_destroy(pattern); diff --git a/WebCore/svg/graphics/cairo/SVGPaintServerPatternCairo.cpp b/WebCore/svg/graphics/cairo/SVGPaintServerPatternCairo.cpp index 6381277..86530bc 100644 --- a/WebCore/svg/graphics/cairo/SVGPaintServerPatternCairo.cpp +++ b/WebCore/svg/graphics/cairo/SVGPaintServerPatternCairo.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,14 +21,59 @@ #include "config.h" #if ENABLE(SVG) -#include "NotImplemented.h" #include "SVGPaintServerPattern.h" +#include "GraphicsContext.h" +#include "Image.h" +#include "ImageBuffer.h" +#include "RenderObject.h" +#include "SVGPatternElement.h" + +#include <wtf/OwnArrayPtr.h> + namespace WebCore { bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const { - notImplemented(); + FloatRect targetRect = object->relativeBBox(false); + + const SVGRenderStyle* svgStyle = object->style()->svgStyle(); + RenderStyle* style = object->style(); + + float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(object, svgStyle->strokeWidth(), 1.0f); + + if (targetRect.width() == 0) + targetRect = FloatRect(targetRect.x(), targetRect.y(), strokeWidth, targetRect.height()); + if (targetRect.height() == 0) + targetRect = FloatRect(targetRect.x(), targetRect.y(), targetRect.width(), strokeWidth); + + m_ownerElement->buildPattern(targetRect); + + cairo_surface_t* image = tile()->image()->nativeImageForCurrentFrame(); + if (!image) + return false; + + cairo_t* cr = context->platformContext(); + + cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image); + cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); + + cairo_pattern_set_filter(pattern, CAIRO_FILTER_BEST); + cairo_matrix_t pattern_matrix = patternTransform(); + cairo_matrix_t matrix = {1, 0, 0, 1, patternBoundaries().x(), patternBoundaries().y()}; + cairo_matrix_multiply(&matrix, &matrix, &pattern_matrix); + cairo_matrix_invert(&matrix); + cairo_pattern_set_matrix(pattern, &matrix); + + if ((type & ApplyToFillTargetType) && svgStyle->hasFill()) + context->setFillRule(svgStyle->fillRule()); + + if ((type & ApplyToStrokeTargetType) && svgStyle->hasStroke()) + applyStrokeStyleToContext(context, style, object); + + cairo_set_source(cr, pattern); + cairo_pattern_destroy(pattern); + return true; } diff --git a/WebCore/svg/graphics/cairo/SVGPaintServerSolidCairo.cpp b/WebCore/svg/graphics/cairo/SVGPaintServerSolidCairo.cpp index 6acc9b2..49e6f55 100644 --- a/WebCore/svg/graphics/cairo/SVGPaintServerSolidCairo.cpp +++ b/WebCore/svg/graphics/cairo/SVGPaintServerSolidCairo.cpp @@ -31,35 +31,22 @@ namespace WebCore { bool SVGPaintServerSolid::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const { // TODO: share this code with other PaintServers - cairo_t* cr = context->platformContext(); - const SVGRenderStyle* style = object->style()->svgStyle(); + + const SVGRenderStyle* svgStyle = object->style()->svgStyle(); + RenderStyle* style = object->style(); float red, green, blue, alpha; color().getRGBA(red, green, blue, alpha); - if ((type & ApplyToFillTargetType) && style->hasFill()) { - alpha = style->fillOpacity(); - - cairo_set_fill_rule(cr, style->fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); + if ((type & ApplyToFillTargetType) && svgStyle->hasFill()) { + alpha = svgStyle->fillOpacity(); + context->setFillRule(svgStyle->fillRule()); } - if ((type & ApplyToStrokeTargetType) && style->hasStroke()) { - alpha = style->strokeOpacity(); - - cairo_set_line_width(cr, SVGRenderStyle::cssPrimitiveToLength(object, style->strokeWidth(), 1.0)); - context->setLineCap(style->capStyle()); - context->setLineJoin(style->joinStyle()); - if (style->joinStyle() == MiterJoin) - context->setMiterLimit(style->strokeMiterLimit()); - - const DashArray& dashes = dashArrayFromRenderingStyle(object->style()); - double* dsh = new double[dashes.size()]; - for (unsigned i = 0 ; i < dashes.size() ; i++) - dsh[i] = dashes[i]; - double dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->strokeDashOffset(), 0.0); - cairo_set_dash(cr, dsh, dashes.size(), dashOffset); - delete[] dsh; + if ((type & ApplyToStrokeTargetType) && svgStyle->hasStroke()) { + alpha = svgStyle->strokeOpacity(); + applyStrokeStyleToContext(context, style, object); } cairo_set_source_rgba(cr, red, green, blue, alpha); diff --git a/WebCore/svg/graphics/cairo/SVGResourceClipperCairo.cpp b/WebCore/svg/graphics/cairo/SVGResourceClipperCairo.cpp index 5900fcd..6aec0ae 100644 --- a/WebCore/svg/graphics/cairo/SVGResourceClipperCairo.cpp +++ b/WebCore/svg/graphics/cairo/SVGResourceClipperCairo.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,6 +23,7 @@ #if ENABLE(SVG) #include "SVGResourceClipper.h" #include "AffineTransform.h" +#include "CairoPath.h" #include "GraphicsContext.h" #include <cairo.h> @@ -30,33 +32,35 @@ namespace WebCore { void SVGResourceClipper::applyClip(GraphicsContext* context, const FloatRect& boundingBox) const { - Vector<ClipData> data = m_clipData.clipData(); - unsigned int count = data.size(); - if (!count) + cairo_t* cr = context->platformContext(); + if (m_clipData.clipData().size() < 1) return; - cairo_t* cr = context->platformContext(); cairo_reset_clip(cr); + context->beginPath(); + + for (unsigned int x = 0; x < m_clipData.clipData().size(); x++) { + ClipData data = m_clipData.clipData()[x]; - for (unsigned int x = 0; x < count; x++) { - Path path = data[x].path; + Path path = data.path; if (path.isEmpty()) continue; path.closeSubpath(); - if (data[x].bboxUnits) { + if (data.bboxUnits) { // Make use of the clipping units AffineTransform transform; transform.translate(boundingBox.x(), boundingBox.y()); transform.scale(boundingBox.width(), boundingBox.height()); path.transform(transform); } + cairo_path_t* clipPath = cairo_copy_path(path.platformPath()->m_cr); + cairo_append_path(cr, clipPath); - cairo_set_fill_rule(cr, data[x].windRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); - - // TODO: review this code, clipping may not be having the desired effect - context->clip(path); + cairo_set_fill_rule(cr, data.windRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); } + + cairo_clip(cr); } } // namespace WebCore diff --git a/WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp b/WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp index 78ea76b..1f690b5 100644 --- a/WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp +++ b/WebCore/svg/graphics/cairo/SVGResourceMaskerCairo.cpp @@ -21,6 +21,7 @@ #if ENABLE(SVG) #include "SVGResourceMasker.h" +#include "Image.h" #include "ImageBuffer.h" #include "GraphicsContext.h" @@ -30,8 +31,11 @@ namespace WebCore { void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& boundingBox) { + if (!m_mask) + return; + cairo_t* cr = context->platformContext(); - cairo_surface_t* surface = m_mask->surface(); + cairo_surface_t* surface = m_mask->image()->nativeImageForCurrentFrame(); if (!surface) return; cairo_pattern_t* mask = cairo_pattern_create_for_surface(surface); diff --git a/WebCore/svg/graphics/cg/CgSupport.cpp b/WebCore/svg/graphics/cg/CgSupport.cpp index 9d4eec7..f9bfb4c 100644 --- a/WebCore/svg/graphics/cg/CgSupport.cpp +++ b/WebCore/svg/graphics/cg/CgSupport.cpp @@ -41,26 +41,6 @@ namespace WebCore { -CGAffineTransform CGAffineTransformMakeMapBetweenRects(CGRect source, CGRect dest) -{ - CGAffineTransform transform = CGAffineTransformMakeTranslation(dest.origin.x - source.origin.x, dest.origin.y - source.origin.y); - transform = CGAffineTransformScale(transform, dest.size.width/source.size.width, dest.size.height/source.size.height); - return transform; -} - -void applyStrokeStyleToContext(GraphicsContext* context, RenderStyle* style, const RenderObject* object) -{ - context->setStrokeThickness(SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeWidth(), 1.0f)); - context->setLineCap(style->svgStyle()->capStyle()); - context->setLineJoin(style->svgStyle()->joinStyle()); - context->setMiterLimit(style->svgStyle()->strokeMiterLimit()); - - const DashArray& dashes = dashArrayFromRenderingStyle(style); - double dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0f); - - CGContextSetLineDash(context->platformContext(), narrowPrecisionToCGFloat(dashOffset), dashes.data(), dashes.size()); -} - CGContextRef scratchContext() { static CGContextRef scratch = 0; @@ -85,7 +65,7 @@ FloatRect strokeBoundingBox(const Path& path, RenderStyle* style, const RenderOb // to make an alternative call... // FIXME: since this is mainly used to decide what to repaint, - // perhaps it would be sufficien to just outset the fill bbox by + // perhaps it would be sufficient to just outset the fill bbox by // the stroke width - that should be way cheaper and simpler than // what we do here. diff --git a/WebCore/svg/graphics/cg/CgSupport.h b/WebCore/svg/graphics/cg/CgSupport.h index 454e5b9..de6e4b3 100644 --- a/WebCore/svg/graphics/cg/CgSupport.h +++ b/WebCore/svg/graphics/cg/CgSupport.h @@ -41,10 +41,6 @@ class RenderStyle; class RenderObject; class GraphicsContext; -CGAffineTransform CGAffineTransformMakeMapBetweenRects(CGRect source, CGRect dest); - -void applyStrokeStyleToContext(GraphicsContext*, RenderStyle*, const RenderObject*); - CGContextRef scratchContext(); FloatRect strokeBoundingBox(const Path& path, RenderStyle*, const RenderObject*); diff --git a/WebCore/svg/graphics/cg/SVGPaintServerGradientCg.cpp b/WebCore/svg/graphics/cg/SVGPaintServerGradientCg.cpp index d1ab090..bfa5017 100644 --- a/WebCore/svg/graphics/cg/SVGPaintServerGradientCg.cpp +++ b/WebCore/svg/graphics/cg/SVGPaintServerGradientCg.cpp @@ -24,7 +24,6 @@ #if ENABLE(SVG) #include "SVGPaintServerGradient.h" -#include "CgSupport.h" #include "FloatConversion.h" #include "GraphicsContext.h" #include "ImageBuffer.h" @@ -138,7 +137,7 @@ static CGShadingRef CGShadingRefForRadialGradient(const SVGPaintServerRadialGrad void SVGPaintServerGradient::updateQuartzGradientStopsCache(const Vector<SVGGradientStop>& stops) { - m_stopsCache = new SharedStopCache; + m_stopsCache = SharedStopCache::create(); Vector<QuartzGradientStop>& stopsCache = m_stopsCache->m_stops; stopsCache.resize(stops.size()); CGFloat previousOffset = 0.0f; @@ -208,7 +207,7 @@ void SVGPaintServerGradient::teardown(GraphicsContext*& context, const RenderObj // Clip current context to mask image (gradient) m_savedContext->concatCTM(transform.inverse()); - CGContextClipToMask(m_savedContext->platformContext(), CGRect(textBoundary), m_imageBuffer->cgImage()); + m_savedContext->clipToImageBuffer(textBoundary, m_imageBuffer); m_savedContext->concatCTM(transform); handleBoundingBoxModeAndGradientTransformation(m_savedContext, maskBBox); @@ -254,20 +253,16 @@ void SVGPaintServerGradient::renderPath(GraphicsContext*& context, const RenderO void SVGPaintServerGradient::handleBoundingBoxModeAndGradientTransformation(GraphicsContext* context, const FloatRect& targetRect) const { - CGContextRef contextRef = context->platformContext(); - if (boundingBoxMode()) { // Choose default gradient bounding box - CGRect gradientBBox = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f); + FloatRect gradientBBox(0.0f, 0.0f, 1.0f, 1.0f); // Generate a transform to map between both bounding boxes - CGAffineTransform gradientIntoObjectBBox = CGAffineTransformMakeMapBetweenRects(gradientBBox, CGRect(targetRect)); - CGContextConcatCTM(contextRef, gradientIntoObjectBBox); + context->concatCTM(makeMapBetweenRects(gradientBBox, targetRect)); } // Apply the gradient's own transform - CGAffineTransform transform = gradientTransform(); - CGContextConcatCTM(contextRef, transform); + context->concatCTM(gradientTransform()); } bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const diff --git a/WebCore/svg/graphics/cg/SVGPaintServerPatternCg.cpp b/WebCore/svg/graphics/cg/SVGPaintServerPatternCg.cpp index e12ff77..416d5fe 100644 --- a/WebCore/svg/graphics/cg/SVGPaintServerPatternCg.cpp +++ b/WebCore/svg/graphics/cg/SVGPaintServerPatternCg.cpp @@ -35,7 +35,11 @@ namespace WebCore { static void patternCallback(void* info, CGContextRef context) { ImageBuffer* patternImage = reinterpret_cast<ImageBuffer*>(info); - CGContextDrawImage(context, CGRect(FloatRect(FloatPoint(), patternImage->size())), patternImage->cgImage()); + CGContextSaveGState(context); + CGContextTranslateCTM(context, 0, patternImage->size().height()); + CGContextScaleCTM(context, 1.0f, -1.0f); + CGContextDrawImage(context, CGRect(FloatRect(FloatPoint(), patternImage->size())), patternImage->image()->getCGImageRef()); + CGContextRestoreGState(context); } bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const diff --git a/WebCore/svg/graphics/cg/SVGPaintServerSolidCg.cpp b/WebCore/svg/graphics/cg/SVGPaintServerSolidCg.cpp index 706f39c..bd2a56f 100644 --- a/WebCore/svg/graphics/cg/SVGPaintServerSolidCg.cpp +++ b/WebCore/svg/graphics/cg/SVGPaintServerSolidCg.cpp @@ -24,42 +24,41 @@ #if ENABLE(SVG) #include "SVGPaintServerSolid.h" +#include "Color.h" +#include "CgSupport.h" #include "GraphicsContext.h" #include "RenderObject.h" -#include "CgSupport.h" namespace WebCore { bool SVGPaintServerSolid::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const { - CGContextRef contextRef = context->platformContext(); - RenderStyle* style = object ? object->style() : 0; + // FIXME: This function does not use any CG-specific calls, however it's not yet + // cross platform, because CG handles fill rule different from other graphics + // platforms. CG makes you use two separate fill calls, other platforms set + // the fill rule state on the context and then call a generic "fillPath" - static CGColorSpaceRef deviceRGBColorSpace = CGColorSpaceCreateDeviceRGB(); // This should be shared from GraphicsContext, or some other central location + RenderStyle* style = object ? object->style() : 0; if ((type & ApplyToFillTargetType) && (!style || style->svgStyle()->hasFill())) { - CGFloat colorComponents[4]; - color().getRGBA(colorComponents[0], colorComponents[1], colorComponents[2], colorComponents[3]); + RGBA32 rgba = color().rgb(); ASSERT(!color().hasAlpha()); if (style) - colorComponents[3] = style->svgStyle()->fillOpacity(); // SVG/CSS colors are not specified w/o alpha + rgba = colorWithOverrideAlpha(rgba, style->svgStyle()->fillOpacity()); - CGContextSetFillColorSpace(contextRef, deviceRGBColorSpace); - CGContextSetFillColor(contextRef, colorComponents); + context->setFillColor(rgba); if (isPaintingText) context->setTextDrawingMode(cTextFill); } if ((type & ApplyToStrokeTargetType) && (!style || style->svgStyle()->hasStroke())) { - CGFloat colorComponents[4]; - color().getRGBA(colorComponents[0], colorComponents[1], colorComponents[2], colorComponents[3]); + RGBA32 rgba = color().rgb(); ASSERT(!color().hasAlpha()); if (style) - colorComponents[3] = style->svgStyle()->strokeOpacity(); // SVG/CSS colors are not specified w/o alpha + rgba = colorWithOverrideAlpha(rgba, style->svgStyle()->strokeOpacity()); - CGContextSetStrokeColorSpace(contextRef, deviceRGBColorSpace); - CGContextSetStrokeColor(contextRef, colorComponents); + context->setStrokeColor(rgba); if (style) applyStrokeStyleToContext(context, style, object); diff --git a/WebCore/svg/graphics/cg/SVGResourceClipperCg.cpp b/WebCore/svg/graphics/cg/SVGResourceClipperCg.cpp index 071afe2..b04a0dc 100644 --- a/WebCore/svg/graphics/cg/SVGResourceClipperCg.cpp +++ b/WebCore/svg/graphics/cg/SVGResourceClipperCg.cpp @@ -30,14 +30,15 @@ #if ENABLE(SVG) #include "SVGResourceClipper.h" +#include "AffineTransform.h" #include "GraphicsContext.h" -#include "CgSupport.h" + +#include <ApplicationServices/ApplicationServices.h> namespace WebCore { void SVGResourceClipper::applyClip(GraphicsContext* context, const FloatRect& boundingBox) const { - CGContextRef cgContext = context->platformContext(); if (m_clipData.clipData().size() < 1) return; @@ -46,24 +47,22 @@ void SVGResourceClipper::applyClip(GraphicsContext* context, const FloatRect& bo context->beginPath(); - CGAffineTransform bboxTransform = CGAffineTransformMakeMapBetweenRects(CGRectMake(0,0,1,1), CGRect(boundingBox)); + AffineTransform bboxTransform = makeMapBetweenRects(FloatRect(0.0f, 0.0f, 1.0f, 1.0f), boundingBox); for (unsigned x = 0; x < m_clipData.clipData().size(); x++) { ClipData data = m_clipData.clipData()[x]; if (data.windRule != clipRule) heterogenousClipRules = true; - CGPathRef clipPath = data.path.platformPath(); - - if (data.bboxUnits) { - CGMutablePathRef transformedPath = CGPathCreateMutable(); - CGPathAddPath(transformedPath, &bboxTransform, clipPath); - CGContextAddPath(cgContext, transformedPath); - CGPathRelease(transformedPath); - } else - CGContextAddPath(cgContext, clipPath); + Path clipPath = data.path; + + if (data.bboxUnits) + clipPath.transform(bboxTransform); + + context->addPath(clipPath); } + CGContextRef cgContext = context->platformContext(); if (m_clipData.clipData().size()) { // FIXME! // We don't currently allow for heterogenous clip rules. diff --git a/WebCore/svg/graphics/cg/SVGResourceMaskerCg.mm b/WebCore/svg/graphics/cg/SVGResourceMaskerCg.mm index 00e62e7..f867f9c 100644 --- a/WebCore/svg/graphics/cg/SVGResourceMaskerCg.mm +++ b/WebCore/svg/graphics/cg/SVGResourceMaskerCg.mm @@ -96,9 +96,10 @@ void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& bou { if (!m_mask) m_mask.set(m_ownerElement->drawMaskerContent(boundingBox, m_maskRect).release()); + if (!m_mask) return; - + IntSize maskSize(static_cast<int>(m_maskRect.width()), static_cast<int>(m_maskRect.height())); clampImageBufferSizeToViewport(m_ownerElement->document()->renderer(), maskSize); @@ -106,19 +107,20 @@ void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& bou auto_ptr<ImageBuffer> grayScaleImage(ImageBuffer::create(maskSize, true)); if (!grayScaleImage.get()) return; - + BEGIN_BLOCK_OBJC_EXCEPTIONS CGContextRef grayScaleContext = grayScaleImage->context()->platformContext(); CIContext* ciGrayscaleContext = [CIContext contextWithCGContext:grayScaleContext options:nil]; // Transform colorized mask to gray scale - CIImage* colorMask = [CIImage imageWithCGImage:m_mask->cgImage()]; + CIImage* colorMask = [CIImage imageWithCGImage:m_mask->image()->getCGImageRef()]; if (!colorMask) return; + CIImage* grayScaleMask = transformImageIntoGrayscaleMask(colorMask); [ciGrayscaleContext drawImage:grayScaleMask atPoint:CGPointZero fromRect:CGRectMake(0, 0, maskSize.width(), maskSize.height())]; - CGContextClipToMask(context->platformContext(), m_maskRect, grayScaleImage->cgImage()); + CGContextClipToMask(context->platformContext(), m_maskRect, grayScaleImage->image()->getCGImageRef()); END_BLOCK_OBJC_EXCEPTIONS } diff --git a/WebCore/svg/graphics/filters/SVGDistantLightSource.h b/WebCore/svg/graphics/filters/SVGDistantLightSource.h index c4ff9b7..25c2045 100644 --- a/WebCore/svg/graphics/filters/SVGDistantLightSource.h +++ b/WebCore/svg/graphics/filters/SVGDistantLightSource.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> @@ -27,23 +28,23 @@ namespace WebCore { -class SVGDistantLightSource : public SVGLightSource { -public: - SVGDistantLightSource(float azimuth, float elevation) - : SVGLightSource(LS_DISTANT) - , m_azimuth(azimuth) - , m_elevation(elevation) - { } + class DistantLightSource : public LightSource { + public: + DistantLightSource(float azimuth, float elevation) + : LightSource(LS_DISTANT) + , m_azimuth(azimuth) + , m_elevation(elevation) + { } - float azimuth() const { return m_azimuth; } - float elevation() const { return m_elevation; } + float azimuth() const { return m_azimuth; } + float elevation() const { return m_elevation; } - virtual TextStream& externalRepresentation(TextStream&) const; + virtual TextStream& externalRepresentation(TextStream&) const; -private: - float m_azimuth; - float m_elevation; -}; + private: + float m_azimuth; + float m_elevation; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEBlend.cpp b/WebCore/svg/graphics/filters/SVGFEBlend.cpp deleted file mode 100644 index bb083e3..0000000 --- a/WebCore/svg/graphics/filters/SVGFEBlend.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - 2005 Eric Seidel <eric@webkit.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEBlend.h" -#include "TextStream.h" - -namespace WebCore { - -SVGFEBlend::SVGFEBlend(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_mode(SVG_FEBLEND_MODE_UNKNOWN) -{ -} - -String SVGFEBlend::in2() const -{ - return m_in2; -} - -void SVGFEBlend::setIn2(const String& in2) -{ - m_in2 = in2; -} - -SVGBlendModeType SVGFEBlend::blendMode() const -{ - return m_mode; -} - -void SVGFEBlend::setBlendMode(SVGBlendModeType mode) -{ - m_mode = mode; -} - -static TextStream& operator<<(TextStream& ts, SVGBlendModeType t) -{ - switch (t) - { - case SVG_FEBLEND_MODE_UNKNOWN: - ts << "UNKNOWN"; break; - case SVG_FEBLEND_MODE_NORMAL: - ts << "NORMAL"; break; - case SVG_FEBLEND_MODE_MULTIPLY: - ts << "MULTIPLY"; break; - case SVG_FEBLEND_MODE_SCREEN: - ts << "SCREEN"; break; - case SVG_FEBLEND_MODE_DARKEN: - ts << "DARKEN"; break; - case SVG_FEBLEND_MODE_LIGHTEN: - ts << "LIGHTEN"; break; - } - return ts; -} - -TextStream& SVGFEBlend::externalRepresentation(TextStream& ts) const -{ - ts << "[type=BLEND] "; - SVGFilterEffect::externalRepresentation(ts); - if (!m_in2.isEmpty()) - ts << " [in2=\"" << m_in2 << "\"]"; - ts << " [blend mode=" << m_mode << "]"; - return ts; -} - -} // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/SVGFEBlend.h b/WebCore/svg/graphics/filters/SVGFEBlend.h deleted file mode 100644 index f8063f7..0000000 --- a/WebCore/svg/graphics/filters/SVGFEBlend.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - 2005 Eric Seidel <eric@webkit.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SVGFEBlend_h -#define SVGFEBlend_h - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" - -namespace WebCore { - -enum SVGBlendModeType { - SVG_FEBLEND_MODE_UNKNOWN = 0, - SVG_FEBLEND_MODE_NORMAL = 1, - SVG_FEBLEND_MODE_MULTIPLY = 2, - SVG_FEBLEND_MODE_SCREEN = 3, - SVG_FEBLEND_MODE_DARKEN = 4, - SVG_FEBLEND_MODE_LIGHTEN = 5 -}; - -class SVGFEBlend : public SVGFilterEffect { -public: - SVGFEBlend(SVGResourceFilter*); - - String in2() const; - void setIn2(const String&); - - SVGBlendModeType blendMode() const; - void setBlendMode(SVGBlendModeType); - - virtual TextStream& externalRepresentation(TextStream&) const; - -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif - -private: - SVGBlendModeType m_mode; - String m_in2; -}; - -} // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) - -#endif // SVGFEBlend_h diff --git a/WebCore/svg/graphics/filters/SVGFEColorMatrix.cpp b/WebCore/svg/graphics/filters/SVGFEColorMatrix.cpp deleted file mode 100644 index 8eb2572..0000000 --- a/WebCore/svg/graphics/filters/SVGFEColorMatrix.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - 2005 Eric Seidel <eric@webkit.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEColorMatrix.h" - -namespace WebCore { - -SVGFEColorMatrix::SVGFEColorMatrix(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_type(SVG_FECOLORMATRIX_TYPE_UNKNOWN) -{ -} - -SVGColorMatrixType SVGFEColorMatrix::type() const -{ - return m_type; -} - -void SVGFEColorMatrix::setType(SVGColorMatrixType type) -{ - m_type = type; -} - -const Vector<float>& SVGFEColorMatrix::values() const -{ - return m_values; -} - -void SVGFEColorMatrix::setValues(const Vector<float> &values) -{ - m_values = values; -} - -static TextStream& operator<<(TextStream& ts, SVGColorMatrixType t) -{ - switch (t) - { - case SVG_FECOLORMATRIX_TYPE_UNKNOWN: - ts << "UNKNOWN"; break; - case SVG_FECOLORMATRIX_TYPE_MATRIX: - ts << "CMT_MATRIX"; break; - case SVG_FECOLORMATRIX_TYPE_SATURATE: - ts << "CMT_SATURATE"; break; - case SVG_FECOLORMATRIX_TYPE_HUEROTATE: - ts << "HUE-ROTATE"; break; - case SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA: - ts << "LUMINANCE-TO-ALPHA"; break; - } - return ts; -} - -TextStream& SVGFEColorMatrix::externalRepresentation(TextStream& ts) const -{ - ts << "[type=COLOR-MATRIX] "; - SVGFilterEffect::externalRepresentation(ts); - ts << " [color matrix type=" << type() << "]" - << " [values=" << values() << "]"; - return ts; -} - -} // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/SVGFEColorMatrix.h b/WebCore/svg/graphics/filters/SVGFEColorMatrix.h deleted file mode 100644 index 0d4eb23..0000000 --- a/WebCore/svg/graphics/filters/SVGFEColorMatrix.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - 2005 Eric Seidel <eric@webkit.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SVGFEColorMatrix_h -#define SVGFEColorMatrix_h - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" -#include "SVGRenderTreeAsText.h" - -namespace WebCore { - -enum SVGColorMatrixType { - SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0, - SVG_FECOLORMATRIX_TYPE_MATRIX = 1, - SVG_FECOLORMATRIX_TYPE_SATURATE = 2, - SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3, - SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4 -}; - -class SVGFEColorMatrix : public SVGFilterEffect { -public: - SVGFEColorMatrix(SVGResourceFilter*); - - SVGColorMatrixType type() const; - void setType(SVGColorMatrixType); - - const Vector<float>& values() const; - void setValues(const Vector<float>&); - - virtual TextStream& externalRepresentation(TextStream&) const; - -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif - -private: - SVGColorMatrixType m_type; - Vector<float> m_values; -}; - -} // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) - -#endif // SVGFEColorMatrix_h diff --git a/WebCore/svg/graphics/filters/SVGFEComponentTransfer.cpp b/WebCore/svg/graphics/filters/SVGFEComponentTransfer.cpp deleted file mode 100644 index 55a1730..0000000 --- a/WebCore/svg/graphics/filters/SVGFEComponentTransfer.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - 2005 Eric Seidel <eric@webkit.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEComponentTransfer.h" -#include "TextStream.h" - -namespace WebCore { - -SVGFEComponentTransfer::SVGFEComponentTransfer(SVGResourceFilter* filter) - : SVGFilterEffect(filter) -{ -} - -SVGComponentTransferFunction SVGFEComponentTransfer::redFunction() const -{ - return m_redFunc; -} - -void SVGFEComponentTransfer::setRedFunction(const SVGComponentTransferFunction& func) -{ - m_redFunc = func; -} - -SVGComponentTransferFunction SVGFEComponentTransfer::greenFunction() const -{ - return m_greenFunc; -} - -void SVGFEComponentTransfer::setGreenFunction(const SVGComponentTransferFunction& func) -{ - m_greenFunc = func; -} - -SVGComponentTransferFunction SVGFEComponentTransfer::blueFunction() const -{ - return m_blueFunc; -} - -void SVGFEComponentTransfer::setBlueFunction(const SVGComponentTransferFunction& func) -{ - m_blueFunc = func; -} - -SVGComponentTransferFunction SVGFEComponentTransfer::alphaFunction() const -{ - return m_alphaFunc; -} - -void SVGFEComponentTransfer::setAlphaFunction(const SVGComponentTransferFunction& func) -{ - m_alphaFunc = func; -} - -static TextStream& operator<<(TextStream& ts, SVGComponentTransferType t) -{ - switch (t) - { - case SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: - ts << "UNKNOWN"; break; - case SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY: - ts << "IDENTITY"; break; - case SVG_FECOMPONENTTRANSFER_TYPE_TABLE: - ts << "TABLE"; break; - case SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE: - ts << "DISCRETE"; break; - case SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: - ts << "LINEAR"; break; - case SVG_FECOMPONENTTRANSFER_TYPE_GAMMA: - ts << "GAMMA"; break; - } - return ts; -} - -static TextStream& operator<<(TextStream& ts, const SVGComponentTransferFunction &func) -{ - ts << "[type=" << func.type << "]"; - switch (func.type) { - case SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: - case SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY: - break; - case SVG_FECOMPONENTTRANSFER_TYPE_TABLE: - case SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE: - { - ts << " [table values="; - Vector<float>::const_iterator itr=func.tableValues.begin(); - if (itr != func.tableValues.end()) { - ts << *itr++; - for (; itr!=func.tableValues.end(); itr++) { - ts << " " << *itr; - } - } - ts << "]"; - break; - } - case SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: - ts << " [slope=" << func.slope << "]" - << " [intercept=" << func.intercept << "]"; - break; - case SVG_FECOMPONENTTRANSFER_TYPE_GAMMA: - ts << " [amplitude=" << func.amplitude << "]" - << " [exponent=" << func.exponent << "]" - << " [offset=" << func.offset << "]"; - break; - } - return ts; -} - -TextStream& SVGFEComponentTransfer::externalRepresentation(TextStream& ts) const -{ - ts << "[type=COMPONENT-TRANSFER] "; - SVGFilterEffect::externalRepresentation(ts); - ts << " [red func=" << redFunction() << "]" - << " [green func=" << greenFunction() << "]" - << " [blue func=" << blueFunction() << "]" - << " [alpha func=" << alphaFunction() << "]"; - return ts; -} - -} // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/SVGFEComponentTransfer.h b/WebCore/svg/graphics/filters/SVGFEComponentTransfer.h deleted file mode 100644 index 32d5e14..0000000 --- a/WebCore/svg/graphics/filters/SVGFEComponentTransfer.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - 2005 Eric Seidel <eric@webkit.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SVGFEComponentTransfer_h -#define SVGFEComponentTransfer_h - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include <wtf/Vector.h> - -#include "SVGFilterEffect.h" -#include "SVGFEDisplacementMap.h" - -#if PLATFORM(CI) -#ifdef __OBJC__ -@class CIImage; -@class CIFilter; -#else -class CIImage; -class CIFilter; -#endif -#endif - -namespace WebCore { - -enum SVGComponentTransferType { - SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0, - SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1, - SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2, - SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3, - SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4, - SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5 -}; - -struct SVGComponentTransferFunction { - SVGComponentTransferFunction() - : type(SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN) - , slope(0.0f) - , intercept(0.0f) - , amplitude(0.0f) - , exponent(0.0f) - , offset(0.0f) - { - } - - SVGComponentTransferType type; - - float slope; - float intercept; - float amplitude; - float exponent; - float offset; - - Vector<float> tableValues; -}; - -class SVGFEComponentTransfer : public SVGFilterEffect { -public: - SVGFEComponentTransfer(SVGResourceFilter*); - - SVGComponentTransferFunction redFunction() const; - void setRedFunction(const SVGComponentTransferFunction&); - - SVGComponentTransferFunction greenFunction() const; - void setGreenFunction(const SVGComponentTransferFunction&); - - SVGComponentTransferFunction blueFunction() const; - void setBlueFunction(const SVGComponentTransferFunction&); - - SVGComponentTransferFunction alphaFunction() const; - void setAlphaFunction(const SVGComponentTransferFunction&); - - virtual TextStream& externalRepresentation(TextStream&) const; - -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; - -private: - CIFilter* getFunctionFilter(SVGChannelSelectorType, CIImage* inputImage) const; -#endif - -private: - SVGComponentTransferFunction m_redFunc; - SVGComponentTransferFunction m_greenFunc; - SVGComponentTransferFunction m_blueFunc; - SVGComponentTransferFunction m_alphaFunc; -}; - -} // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) - -#endif // SVGFEComponentTransfer_h diff --git a/WebCore/svg/graphics/filters/SVGFEComposite.cpp b/WebCore/svg/graphics/filters/SVGFEComposite.cpp deleted file mode 100644 index 4e0dfb5..0000000 --- a/WebCore/svg/graphics/filters/SVGFEComposite.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - 2005 Eric Seidel <eric@webkit.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEComposite.h" -#include "TextStream.h" - -namespace WebCore { - -SVGFEComposite::SVGFEComposite(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_operation(SVG_FECOMPOSITE_OPERATOR_UNKNOWN) - , m_k1(0.0f) - , m_k2(0.0f) - , m_k3(0.0f) - , m_k4(0.0f) -{ -} - -String SVGFEComposite::in2() const -{ - return m_in2; -} - -void SVGFEComposite::setIn2(const String& in2) -{ - m_in2 = in2; -} - -SVGCompositeOperationType SVGFEComposite::operation() const -{ - return m_operation; -} - -void SVGFEComposite::setOperation(SVGCompositeOperationType oper) -{ - m_operation = oper; -} - -float SVGFEComposite::k1() const -{ - return m_k1; -} - -void SVGFEComposite::setK1(float k1) -{ - m_k1 = k1; -} - -float SVGFEComposite::k2() const -{ - return m_k2; -} - -void SVGFEComposite::setK2(float k2) -{ - m_k2 = k2; -} - -float SVGFEComposite::k3() const -{ - return m_k3; -} - -void SVGFEComposite::setK3(float k3) -{ - m_k3 = k3; -} - -float SVGFEComposite::k4() const -{ - return m_k4; -} - -void SVGFEComposite::setK4(float k4) -{ - m_k4 = k4; -} - -TextStream& SVGFEComposite::externalRepresentation(TextStream& ts) const -{ - ts << "[type=COMPOSITE] "; - SVGFilterEffect::externalRepresentation(ts); - if (!in2().isEmpty()) - ts << " [in2=\"" << in2() << "\"]"; - ts << " [k1=" << k1() << " k2=" << k2() << " k3=" << k3() << " k4=" << k4() << "]"; - return ts; -} - -} // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/SVGFEComposite.h b/WebCore/svg/graphics/filters/SVGFEComposite.h deleted file mode 100644 index 7a18047..0000000 --- a/WebCore/svg/graphics/filters/SVGFEComposite.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - 2004, 2005 Rob Buis <buis@kde.org> - 2005 Eric Seidel <eric@webkit.org> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef SVGFEComposite_h -#define SVGFEComposite_h - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" - -namespace WebCore { - -enum SVGCompositeOperationType { - SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0, - SVG_FECOMPOSITE_OPERATOR_OVER = 1, - SVG_FECOMPOSITE_OPERATOR_IN = 2, - SVG_FECOMPOSITE_OPERATOR_OUT = 3, - SVG_FECOMPOSITE_OPERATOR_ATOP = 4, - SVG_FECOMPOSITE_OPERATOR_XOR = 5, - SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6 -}; - -class SVGFEComposite : public SVGFilterEffect { -public: - SVGFEComposite(SVGResourceFilter*); - - String in2() const; - void setIn2(const String&); - - SVGCompositeOperationType operation() const; - void setOperation(SVGCompositeOperationType); - - float k1() const; - void setK1(float); - - float k2() const; - void setK2(float); - - float k3() const; - void setK3(float); - - float k4() const; - void setK4(float); - - virtual TextStream& externalRepresentation(TextStream&) const; - -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif - -private: - SVGCompositeOperationType m_operation; - float m_k1; - float m_k2; - float m_k3; - float m_k4; - String m_in2; -}; - -} // namespace WebCore - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) - -#endif // SVGFEComposite_h diff --git a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp index af2b693..4b82e5a 100644 --- a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp +++ b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.cpp @@ -22,131 +22,153 @@ #include "config.h" #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGRenderTreeAsText.h" #include "SVGFEConvolveMatrix.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFEConvolveMatrix::SVGFEConvolveMatrix(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_kernelSize() - , m_divisor(0.0f) - , m_bias(0.0f) - , m_targetOffset() - , m_edgeMode(SVG_EDGEMODE_UNKNOWN) - , m_kernelUnitLength() - , m_preserveAlpha(false) +FEConvolveMatrix::FEConvolveMatrix(FilterEffect* in, FilterEffect* in2, const FloatSize& kernelSize, + const float& divisor, const float& bias, const FloatSize& targetOffset, EdgeModeType edgeMode, + const FloatPoint& kernelUnitLength, bool preserveAlpha, const Vector<float>& kernelMatrix) + : FilterEffect() + , m_in(in) + , m_in2(in2) + , m_kernelSize(kernelSize) + , m_divisor(divisor) + , m_bias(bias) + , m_targetOffset(targetOffset) + , m_edgeMode(edgeMode) + , m_kernelUnitLength(kernelUnitLength) + , m_preserveAlpha(preserveAlpha) + , m_kernelMatrix(kernelMatrix) +{ +} + +PassRefPtr<FEConvolveMatrix> FEConvolveMatrix::create(FilterEffect* in, FilterEffect* in2, const FloatSize& kernelSize, + const float& divisor, const float& bias, const FloatSize& targetOffset, EdgeModeType edgeMode, + const FloatPoint& kernelUnitLength, bool preserveAlpha, const Vector<float>& kernelMatrix) { + return adoptRef(new FEConvolveMatrix(in, in2, kernelSize, divisor, bias, targetOffset, edgeMode, kernelUnitLength, + preserveAlpha, kernelMatrix)); } -FloatSize SVGFEConvolveMatrix::kernelSize() const + +FloatSize FEConvolveMatrix::kernelSize() const { return m_kernelSize; } -void SVGFEConvolveMatrix::setKernelSize(FloatSize kernelSize) +void FEConvolveMatrix::setKernelSize(FloatSize kernelSize) { m_kernelSize = kernelSize; } -const Vector<float>& SVGFEConvolveMatrix::kernel() const +const Vector<float>& FEConvolveMatrix::kernel() const { return m_kernelMatrix; } -void SVGFEConvolveMatrix::setKernel(const Vector<float>& kernel) +void FEConvolveMatrix::setKernel(const Vector<float>& kernel) { m_kernelMatrix = kernel; } -float SVGFEConvolveMatrix::divisor() const +float FEConvolveMatrix::divisor() const { return m_divisor; } -void SVGFEConvolveMatrix::setDivisor(float divisor) +void FEConvolveMatrix::setDivisor(float divisor) { m_divisor = divisor; } -float SVGFEConvolveMatrix::bias() const +float FEConvolveMatrix::bias() const { return m_bias; } -void SVGFEConvolveMatrix::setBias(float bias) +void FEConvolveMatrix::setBias(float bias) { m_bias = bias; } -FloatSize SVGFEConvolveMatrix::targetOffset() const +FloatSize FEConvolveMatrix::targetOffset() const { return m_targetOffset; } -void SVGFEConvolveMatrix::setTargetOffset(FloatSize targetOffset) +void FEConvolveMatrix::setTargetOffset(FloatSize targetOffset) { m_targetOffset = targetOffset; } -SVGEdgeModeType SVGFEConvolveMatrix::edgeMode() const +EdgeModeType FEConvolveMatrix::edgeMode() const { return m_edgeMode; } -void SVGFEConvolveMatrix::setEdgeMode(SVGEdgeModeType edgeMode) +void FEConvolveMatrix::setEdgeMode(EdgeModeType edgeMode) { m_edgeMode = edgeMode; } -FloatPoint SVGFEConvolveMatrix::kernelUnitLength() const +FloatPoint FEConvolveMatrix::kernelUnitLength() const { return m_kernelUnitLength; } -void SVGFEConvolveMatrix::setKernelUnitLength(FloatPoint kernelUnitLength) +void FEConvolveMatrix::setKernelUnitLength(FloatPoint kernelUnitLength) { m_kernelUnitLength = kernelUnitLength; } -bool SVGFEConvolveMatrix::preserveAlpha() const +bool FEConvolveMatrix::preserveAlpha() const { return m_preserveAlpha; } -void SVGFEConvolveMatrix::setPreserveAlpha(bool preserveAlpha) +void FEConvolveMatrix::setPreserveAlpha(bool preserveAlpha) { m_preserveAlpha = preserveAlpha; } -static TextStream& operator<<(TextStream& ts, SVGEdgeModeType t) +void FEConvolveMatrix::apply() +{ +} + +void FEConvolveMatrix::dump() +{ +} + +static TextStream& operator<<(TextStream& ts, EdgeModeType t) { switch (t) { - case SVG_EDGEMODE_UNKNOWN: + case EDGEMODE_UNKNOWN: ts << "UNKNOWN";break; - case SVG_EDGEMODE_DUPLICATE: + case EDGEMODE_DUPLICATE: ts << "DUPLICATE";break; - case SVG_EDGEMODE_WRAP: + case EDGEMODE_WRAP: ts << "WRAP"; break; - case SVG_EDGEMODE_NONE: + case EDGEMODE_NONE: ts << "NONE"; break; } return ts; } -TextStream& SVGFEConvolveMatrix::externalRepresentation(TextStream& ts) const +TextStream& FEConvolveMatrix::externalRepresentation(TextStream& ts) const { ts << "[type=CONVOLVE-MATRIX] "; - SVGFilterEffect::externalRepresentation(ts); + FilterEffect::externalRepresentation(ts); ts << " [order " << m_kernelSize << "]" - << " [kernel matrix=" << m_kernelMatrix << "]" - << " [divisor=" << m_divisor << "]" - << " [bias=" << m_bias << "]" - << " [target " << m_targetOffset << "]" - << " [edge mode=" << m_edgeMode << "]" - << " [kernel unit length " << m_kernelUnitLength << "]" - << " [preserve alpha=" << m_preserveAlpha << "]"; + << " [kernel matrix=" << m_kernelMatrix << "]" + << " [divisor=" << m_divisor << "]" + << " [bias=" << m_bias << "]" + << " [target " << m_targetOffset << "]" + << " [edge mode=" << m_edgeMode << "]" + << " [kernel unit length " << m_kernelUnitLength << "]" + << " [preserve alpha=" << m_preserveAlpha << "]"; return ts; } diff --git a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h index b9744fa..c3eea2b 100644 --- a/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h +++ b/WebCore/svg/graphics/filters/SVGFEConvolveMatrix.h @@ -23,57 +23,70 @@ #define SVGFEConvolveMatrix_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" +#include "FilterEffect.h" +#include "FloatPoint.h" +#include "FloatSize.h" -namespace WebCore { - -enum SVGEdgeModeType { - SVG_EDGEMODE_UNKNOWN = 0, - SVG_EDGEMODE_DUPLICATE = 1, - SVG_EDGEMODE_WRAP = 2, - SVG_EDGEMODE_NONE = 3 -}; - -class SVGFEConvolveMatrix : public SVGFilterEffect { -public: - SVGFEConvolveMatrix(SVGResourceFilter*); - - FloatSize kernelSize() const; - void setKernelSize(FloatSize); - - const Vector<float>& kernel() const; - void setKernel(const Vector<float>&); - - float divisor() const; - void setDivisor(float); +#include <wtf/Vector.h> - float bias() const; - void setBias(float); - - FloatSize targetOffset() const; - void setTargetOffset(FloatSize); - - SVGEdgeModeType edgeMode() const; - void setEdgeMode(SVGEdgeModeType); - - FloatPoint kernelUnitLength() const; - void setKernelUnitLength(FloatPoint); - - bool preserveAlpha() const; - void setPreserveAlpha(bool); - - virtual TextStream& externalRepresentation(TextStream&) const; +namespace WebCore { -private: - FloatSize m_kernelSize; - float m_divisor; - float m_bias; - FloatSize m_targetOffset; - SVGEdgeModeType m_edgeMode; - FloatPoint m_kernelUnitLength; - bool m_preserveAlpha; - Vector<float> m_kernelMatrix; // maybe should be a real matrix? -}; + enum EdgeModeType { + EDGEMODE_UNKNOWN = 0, + EDGEMODE_DUPLICATE = 1, + EDGEMODE_WRAP = 2, + EDGEMODE_NONE = 3 + }; + + class FEConvolveMatrix : public FilterEffect { + public: + static PassRefPtr<FEConvolveMatrix> create(FilterEffect*, FilterEffect*, const FloatSize&, + const float&, const float&, const FloatSize&, EdgeModeType, const FloatPoint&, + bool, const Vector<float>&); + + FloatSize kernelSize() const; + void setKernelSize(FloatSize); + + const Vector<float>& kernel() const; + void setKernel(const Vector<float>&); + + float divisor() const; + void setDivisor(float); + + float bias() const; + void setBias(float); + + FloatSize targetOffset() const; + void setTargetOffset(FloatSize); + + EdgeModeType edgeMode() const; + void setEdgeMode(EdgeModeType); + + FloatPoint kernelUnitLength() const; + void setKernelUnitLength(FloatPoint); + + bool preserveAlpha() const; + void setPreserveAlpha(bool); + + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; + + private: + FEConvolveMatrix(FilterEffect*, FilterEffect*, const FloatSize&, const float&, const float&, + const FloatSize&, EdgeModeType, const FloatPoint&, bool, const Vector<float>&); + + RefPtr<FilterEffect> m_in; + RefPtr<FilterEffect> m_in2; + FloatSize m_kernelSize; + float m_divisor; + float m_bias; + FloatSize m_targetOffset; + EdgeModeType m_edgeMode; + FloatPoint m_kernelUnitLength; + bool m_preserveAlpha; + Vector<float> m_kernelMatrix; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp b/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp index 2504ca6..6399c5e 100644 --- a/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp +++ b/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.cpp @@ -24,93 +24,106 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGLightSource.h" #include "SVGFEDiffuseLighting.h" -#include "TextStream.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFEDiffuseLighting::SVGFEDiffuseLighting(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_lightingColor() - , m_surfaceScale(0.0f) - , m_diffuseConstant(0.0f) - , m_kernelUnitLengthX(0.0f) - , m_kernelUnitLengthY(0.0f) - , m_lightSource(0) +FEDiffuseLighting::FEDiffuseLighting(FilterEffect* in , const Color& lightingColor, const float& surfaceScale, + const float& diffuseConstant, const float& kernelUnitLengthX, const float& kernelUnitLengthY, LightSource* lightSource) + : FilterEffect() + , m_in(in) + , m_lightingColor(lightingColor) + , m_surfaceScale(surfaceScale) + , m_diffuseConstant(diffuseConstant) + , m_kernelUnitLengthX(kernelUnitLengthX) + , m_kernelUnitLengthY(kernelUnitLengthY) + , m_lightSource(lightSource) { } -SVGFEDiffuseLighting::~SVGFEDiffuseLighting() +PassRefPtr<FEDiffuseLighting> FEDiffuseLighting::create(FilterEffect* in , const Color& lightingColor, + const float& surfaceScale, const float& diffuseConstant, const float& kernelUnitLengthX, + const float& kernelUnitLengthY, LightSource* lightSource) { - delete m_lightSource; + return adoptRef(new FEDiffuseLighting(in, lightingColor, surfaceScale, diffuseConstant, kernelUnitLengthX, kernelUnitLengthY, lightSource)); } -Color SVGFEDiffuseLighting::lightingColor() const +FEDiffuseLighting::~FEDiffuseLighting() +{ +} + +Color FEDiffuseLighting::lightingColor() const { return m_lightingColor; } -void SVGFEDiffuseLighting::setLightingColor(const Color& lightingColor) +void FEDiffuseLighting::setLightingColor(const Color& lightingColor) { m_lightingColor = lightingColor; } -float SVGFEDiffuseLighting::surfaceScale() const +float FEDiffuseLighting::surfaceScale() const { return m_surfaceScale; } -void SVGFEDiffuseLighting::setSurfaceScale(float surfaceScale) +void FEDiffuseLighting::setSurfaceScale(float surfaceScale) { m_surfaceScale = surfaceScale; } -float SVGFEDiffuseLighting::diffuseConstant() const +float FEDiffuseLighting::diffuseConstant() const { return m_diffuseConstant; } -void SVGFEDiffuseLighting::setDiffuseConstant(float diffuseConstant) +void FEDiffuseLighting::setDiffuseConstant(float diffuseConstant) { m_diffuseConstant = diffuseConstant; } -float SVGFEDiffuseLighting::kernelUnitLengthX() const +float FEDiffuseLighting::kernelUnitLengthX() const { return m_kernelUnitLengthX; } -void SVGFEDiffuseLighting::setKernelUnitLengthX(float kernelUnitLengthX) +void FEDiffuseLighting::setKernelUnitLengthX(float kernelUnitLengthX) { m_kernelUnitLengthX = kernelUnitLengthX; } -float SVGFEDiffuseLighting::kernelUnitLengthY() const +float FEDiffuseLighting::kernelUnitLengthY() const { return m_kernelUnitLengthY; } -void SVGFEDiffuseLighting::setKernelUnitLengthY(float kernelUnitLengthY) +void FEDiffuseLighting::setKernelUnitLengthY(float kernelUnitLengthY) { m_kernelUnitLengthY = kernelUnitLengthY; } -const SVGLightSource* SVGFEDiffuseLighting::lightSource() const +const LightSource* FEDiffuseLighting::lightSource() const { - return m_lightSource; + return m_lightSource.get(); } -void SVGFEDiffuseLighting::setLightSource(SVGLightSource* lightSource) +void FEDiffuseLighting::setLightSource(LightSource* lightSource) { - if (m_lightSource != lightSource) { - delete m_lightSource; - m_lightSource = lightSource; - } + m_lightSource = lightSource; +} + +void FEDiffuseLighting::apply() +{ +} + +void FEDiffuseLighting::dump() +{ } -TextStream& SVGFEDiffuseLighting::externalRepresentation(TextStream& ts) const +TextStream& FEDiffuseLighting::externalRepresentation(TextStream& ts) const { ts << "[type=DIFFUSE-LIGHTING] "; - SVGFilterEffect::externalRepresentation(ts); + FilterEffect::externalRepresentation(ts); ts << " [surface scale=" << m_surfaceScale << "]" << " [diffuse constant=" << m_diffuseConstant << "]" << " [kernel unit length " << m_kernelUnitLengthX << ", " << m_kernelUnitLengthY << "]"; diff --git a/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h b/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h index a2ed775..a817ce2 100644 --- a/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h +++ b/WebCore/svg/graphics/filters/SVGFEDiffuseLighting.h @@ -24,49 +24,52 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "Color.h" -#include "SVGFilterEffect.h" +#include "FilterEffect.h" namespace WebCore { -class SVGLightSource; + class LightSource; -class SVGFEDiffuseLighting : public SVGFilterEffect { -public: - SVGFEDiffuseLighting(SVGResourceFilter*); - virtual ~SVGFEDiffuseLighting(); + class FEDiffuseLighting : public FilterEffect { + public: + static PassRefPtr<FEDiffuseLighting> create(FilterEffect*, const Color&, const float&, const float&, + const float&, const float&, LightSource*); + virtual ~FEDiffuseLighting(); - Color lightingColor() const; - void setLightingColor(const Color&); + Color lightingColor() const; + void setLightingColor(const Color&); - float surfaceScale() const; - void setSurfaceScale(float); + float surfaceScale() const; + void setSurfaceScale(float); - float diffuseConstant() const; - void setDiffuseConstant(float); + float diffuseConstant() const; + void setDiffuseConstant(float); - float kernelUnitLengthX() const; - void setKernelUnitLengthX(float); + float kernelUnitLengthX() const; + void setKernelUnitLengthX(float); - float kernelUnitLengthY() const; - void setKernelUnitLengthY(float); + float kernelUnitLengthY() const; + void setKernelUnitLengthY(float); - const SVGLightSource* lightSource() const; - void setLightSource(SVGLightSource*); + const LightSource* lightSource() const; + void setLightSource(LightSource*); - virtual TextStream& externalRepresentation(TextStream&) const; + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; + + private: + FEDiffuseLighting(FilterEffect*, const Color&, const float&, const float&, + const float&, const float&, LightSource*); -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif - -private: - Color m_lightingColor; - float m_surfaceScale; - float m_diffuseConstant; - float m_kernelUnitLengthX; - float m_kernelUnitLengthY; - SVGLightSource* m_lightSource; -}; + RefPtr<FilterEffect> m_in; + Color m_lightingColor; + float m_surfaceScale; + float m_diffuseConstant; + float m_kernelUnitLengthX; + float m_kernelUnitLengthY; + RefPtr<LightSource> m_lightSource; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp index 39b012b..f7996e3 100644 --- a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp +++ b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp @@ -22,84 +22,90 @@ #include "config.h" #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGRenderTreeAsText.h" #include "SVGFEDisplacementMap.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFEDisplacementMap::SVGFEDisplacementMap(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_xChannelSelector(SVG_CHANNEL_UNKNOWN) - , m_yChannelSelector(SVG_CHANNEL_UNKNOWN) - , m_scale(0) -{ -} - -String SVGFEDisplacementMap::in2() const +FEDisplacementMap::FEDisplacementMap(FilterEffect* in, FilterEffect* in2, ChannelSelectorType xChannelSelector, + ChannelSelectorType yChannelSelector, const float& scale) + : FilterEffect() + , m_in(in) + , m_in2(in2) + , m_xChannelSelector(xChannelSelector) + , m_yChannelSelector(yChannelSelector) + , m_scale(scale) { - return m_in2; } -void SVGFEDisplacementMap::setIn2(const String &in2) +PassRefPtr<FEDisplacementMap> FEDisplacementMap::create(FilterEffect* in, FilterEffect* in2, + ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, const float& scale) { - m_in2 = in2; + return adoptRef(new FEDisplacementMap(in, in2, xChannelSelector, yChannelSelector, scale)); } -SVGChannelSelectorType SVGFEDisplacementMap::xChannelSelector() const +ChannelSelectorType FEDisplacementMap::xChannelSelector() const { return m_xChannelSelector; } -void SVGFEDisplacementMap::setXChannelSelector(const SVGChannelSelectorType xChannelSelector) +void FEDisplacementMap::setXChannelSelector(const ChannelSelectorType xChannelSelector) { m_xChannelSelector = xChannelSelector; } -SVGChannelSelectorType SVGFEDisplacementMap::yChannelSelector() const +ChannelSelectorType FEDisplacementMap::yChannelSelector() const { return m_yChannelSelector; } -void SVGFEDisplacementMap::setYChannelSelector(const SVGChannelSelectorType yChannelSelector) +void FEDisplacementMap::setYChannelSelector(const ChannelSelectorType yChannelSelector) { m_yChannelSelector = yChannelSelector; } -float SVGFEDisplacementMap::scale() const +float FEDisplacementMap::scale() const { return m_scale; } -void SVGFEDisplacementMap::setScale(float scale) +void FEDisplacementMap::setScale(float scale) { m_scale = scale; } -static TextStream& operator<<(TextStream& ts, SVGChannelSelectorType t) +void FEDisplacementMap::apply() +{ +} + +void FEDisplacementMap::dump() +{ +} + +static TextStream& operator<<(TextStream& ts, ChannelSelectorType t) { switch (t) { - case SVG_CHANNEL_UNKNOWN: + case CHANNEL_UNKNOWN: ts << "UNKNOWN"; break; - case SVG_CHANNEL_R: + case CHANNEL_R: ts << "RED"; break; - case SVG_CHANNEL_G: + case CHANNEL_G: ts << "GREEN"; break; - case SVG_CHANNEL_B: + case CHANNEL_B: ts << "BLUE"; break; - case SVG_CHANNEL_A: + case CHANNEL_A: ts << "ALPHA"; break; } return ts; } -TextStream& SVGFEDisplacementMap::externalRepresentation(TextStream& ts) const +TextStream& FEDisplacementMap::externalRepresentation(TextStream& ts) const { ts << "[type=DISPLACEMENT-MAP] "; - SVGFilterEffect::externalRepresentation(ts); - if (!in2().isEmpty()) - ts << " [in2=" << in2() << "]"; - ts << " [scale=" << m_scale << "]" + FilterEffect::externalRepresentation(ts); + ts << " [in2=" << m_in2.get() << "]" + << " [scale=" << m_scale << "]" << " [x channel selector=" << m_xChannelSelector << "]" << " [y channel selector=" << m_yChannelSelector << "]"; return ts; diff --git a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.h b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.h index bc45728..0218d57 100644 --- a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.h +++ b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.h @@ -23,46 +23,47 @@ #define SVGFEDisplacementMap_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" +#include "PlatformString.h" +#include "FilterEffect.h" namespace WebCore { -enum SVGChannelSelectorType { - SVG_CHANNEL_UNKNOWN = 0, - SVG_CHANNEL_R = 1, - SVG_CHANNEL_G = 2, - SVG_CHANNEL_B = 3, - SVG_CHANNEL_A = 4 -}; - -class SVGFEDisplacementMap : public SVGFilterEffect { -public: - SVGFEDisplacementMap(SVGResourceFilter*); - - String in2() const; - void setIn2(const String&); - - SVGChannelSelectorType xChannelSelector() const; - void setXChannelSelector(const SVGChannelSelectorType); - - SVGChannelSelectorType yChannelSelector() const; - void setYChannelSelector(const SVGChannelSelectorType); - - float scale() const; - void setScale(float scale); - - virtual TextStream& externalRepresentation(TextStream&) const; - -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif - -private: - SVGChannelSelectorType m_xChannelSelector; - SVGChannelSelectorType m_yChannelSelector; - float m_scale; - String m_in2; -}; + enum ChannelSelectorType { + CHANNEL_UNKNOWN = 0, + CHANNEL_R = 1, + CHANNEL_G = 2, + CHANNEL_B = 3, + CHANNEL_A = 4 + }; + + class FEDisplacementMap : public FilterEffect { + public: + static PassRefPtr<FEDisplacementMap> create(FilterEffect*, FilterEffect*, ChannelSelectorType, + ChannelSelectorType, const float&); + + ChannelSelectorType xChannelSelector() const; + void setXChannelSelector(const ChannelSelectorType); + + ChannelSelectorType yChannelSelector() const; + void setYChannelSelector(const ChannelSelectorType); + + float scale() const; + void setScale(float scale); + + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; + + private: + FEDisplacementMap(FilterEffect*, FilterEffect*, ChannelSelectorType, + ChannelSelectorType, const float&); + + RefPtr<FilterEffect> m_in; + RefPtr<FilterEffect> m_in2; + ChannelSelectorType m_xChannelSelector; + ChannelSelectorType m_yChannelSelector; + float m_scale; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEFlood.cpp b/WebCore/svg/graphics/filters/SVGFEFlood.cpp index 2baeb2e..3d52f63 100644 --- a/WebCore/svg/graphics/filters/SVGFEFlood.cpp +++ b/WebCore/svg/graphics/filters/SVGFEFlood.cpp @@ -22,42 +22,55 @@ #include "config.h" #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGRenderTreeAsText.h" #include "SVGFEFlood.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFEFlood::SVGFEFlood(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_floodColor() - , m_floodOpacity(0.0f) +FEFlood::FEFlood(const Color& floodColor, const float& floodOpacity) + : FilterEffect() + , m_floodColor(floodColor) + , m_floodOpacity(floodOpacity) +{ +} + +PassRefPtr<FEFlood> FEFlood::create(const Color& floodColor, const float& floodOpacity) { + return adoptRef(new FEFlood(floodColor, floodOpacity)); } -Color SVGFEFlood::floodColor() const +Color FEFlood::floodColor() const { return m_floodColor; } -void SVGFEFlood::setFloodColor(const Color& color) +void FEFlood::setFloodColor(const Color& color) { m_floodColor = color; } -float SVGFEFlood::floodOpacity() const +float FEFlood::floodOpacity() const { return m_floodOpacity; } -void SVGFEFlood::setFloodOpacity(float floodOpacity) +void FEFlood::setFloodOpacity(float floodOpacity) { m_floodOpacity = floodOpacity; } -TextStream& SVGFEFlood::externalRepresentation(TextStream& ts) const +void FEFlood::apply() +{ +} + +void FEFlood::dump() +{ +} + +TextStream& FEFlood::externalRepresentation(TextStream& ts) const { ts << "[type=FLOOD] "; - SVGFilterEffect::externalRepresentation(ts); + FilterEffect::externalRepresentation(ts); ts << " [color=" << floodColor() << "]" << " [opacity=" << floodOpacity() << "]"; return ts; diff --git a/WebCore/svg/graphics/filters/SVGFEFlood.h b/WebCore/svg/graphics/filters/SVGFEFlood.h index 4cadf9a..0558774 100644 --- a/WebCore/svg/graphics/filters/SVGFEFlood.h +++ b/WebCore/svg/graphics/filters/SVGFEFlood.h @@ -24,30 +24,30 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "Color.h" -#include "SVGFilterEffect.h" +#include "FilterEffect.h" namespace WebCore { -class SVGFEFlood : public SVGFilterEffect { -public: - SVGFEFlood(SVGResourceFilter*); + class FEFlood : public FilterEffect { + public: + static PassRefPtr<FEFlood> create(const Color&, const float&); - Color floodColor() const; - void setFloodColor(const Color &); + Color floodColor() const; + void setFloodColor(const Color &); - float floodOpacity() const; - void setFloodOpacity(float); + float floodOpacity() const; + void setFloodOpacity(float); - virtual TextStream& externalRepresentation(TextStream&) const; + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif + private: + FEFlood(const Color&, const float&); -private: - Color m_floodColor; - float m_floodOpacity; -}; + Color m_floodColor; + float m_floodOpacity; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEGaussianBlur.cpp b/WebCore/svg/graphics/filters/SVGFEGaussianBlur.cpp index aef9aad..4e64c58 100644 --- a/WebCore/svg/graphics/filters/SVGFEGaussianBlur.cpp +++ b/WebCore/svg/graphics/filters/SVGFEGaussianBlur.cpp @@ -23,41 +23,55 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFEGaussianBlur.h" -#include "TextStream.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFEGaussianBlur::SVGFEGaussianBlur(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_x(0.0f) - , m_y(0.0f) +FEGaussianBlur::FEGaussianBlur(FilterEffect* in, const float& x, const float& y) + : FilterEffect() + , m_in(in) + , m_x(x) + , m_y(y) { } -float SVGFEGaussianBlur::stdDeviationX() const +PassRefPtr<FEGaussianBlur> FEGaussianBlur::create(FilterEffect* in, const float& x, const float& y) +{ + return adoptRef(new FEGaussianBlur(in, x, y)); +} + +float FEGaussianBlur::stdDeviationX() const { return m_x; } -void SVGFEGaussianBlur::setStdDeviationX(float x) +void FEGaussianBlur::setStdDeviationX(float x) { m_x = x; } -float SVGFEGaussianBlur::stdDeviationY() const +float FEGaussianBlur::stdDeviationY() const { return m_y; } -void SVGFEGaussianBlur::setStdDeviationY(float y) +void FEGaussianBlur::setStdDeviationY(float y) { m_y = y; } -TextStream& SVGFEGaussianBlur::externalRepresentation(TextStream& ts) const +void FEGaussianBlur::apply() +{ +} + +void FEGaussianBlur::dump() +{ +} + +TextStream& FEGaussianBlur::externalRepresentation(TextStream& ts) const { ts << "[type=GAUSSIAN-BLUR] "; - SVGFilterEffect::externalRepresentation(ts); + FilterEffect::externalRepresentation(ts); ts << " [std dev. x=" << stdDeviationX() << " y=" << stdDeviationY() << "]"; return ts; } diff --git a/WebCore/svg/graphics/filters/SVGFEGaussianBlur.h b/WebCore/svg/graphics/filters/SVGFEGaussianBlur.h index 28cb9e0..33ad0c7 100644 --- a/WebCore/svg/graphics/filters/SVGFEGaussianBlur.h +++ b/WebCore/svg/graphics/filters/SVGFEGaussianBlur.h @@ -23,30 +23,31 @@ #define SVGFEGaussianBlur_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" +#include "FilterEffect.h" namespace WebCore { -class SVGFEGaussianBlur : public SVGFilterEffect { -public: - SVGFEGaussianBlur(SVGResourceFilter*); + class FEGaussianBlur : public FilterEffect { + public: + static PassRefPtr<FEGaussianBlur> create(FilterEffect*, const float&, const float&); - float stdDeviationX() const; - void setStdDeviationX(float); + float stdDeviationX() const; + void setStdDeviationX(float); - float stdDeviationY() const; - void setStdDeviationY(float); + float stdDeviationY() const; + void setStdDeviationY(float); - virtual TextStream& externalRepresentation(TextStream&) const; + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif + private: + FEGaussianBlur(FilterEffect*, const float&, const float&); -private: - float m_x; - float m_y; -}; + RefPtr<FilterEffect> m_in; + float m_x; + float m_y; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEImage.cpp b/WebCore/svg/graphics/filters/SVGFEImage.cpp index 0c9eaee..2bf83be 100644 --- a/WebCore/svg/graphics/filters/SVGFEImage.cpp +++ b/WebCore/svg/graphics/filters/SVGFEImage.cpp @@ -23,56 +23,60 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFEImage.h" - -#include "SVGResourceFilter.h" -#include "TextStream.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFEImage::SVGFEImage(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_cachedImage(0) +FEImage::FEImage(CachedImage* cachedImage) + : FilterEffect() + , m_cachedImage(cachedImage) +{ +} + +PassRefPtr<FEImage> FEImage::create(CachedImage* cachedImage) { + return adoptRef(new FEImage(cachedImage)); } -SVGFEImage::~SVGFEImage() +FEImage::~FEImage() { if (m_cachedImage) - m_cachedImage->deref(this); + m_cachedImage->removeClient(this); } -CachedImage* SVGFEImage::cachedImage() const +CachedImage* FEImage::cachedImage() const { - return m_cachedImage; + return m_cachedImage.get(); } -void SVGFEImage::setCachedImage(CachedImage* image) +void FEImage::setCachedImage(CachedImage* image) { if (m_cachedImage == image) return; if (m_cachedImage) - m_cachedImage->deref(this); + m_cachedImage->removeClient(this); m_cachedImage = image; if (m_cachedImage) - m_cachedImage->ref(this); + m_cachedImage->addClient(this); } -TextStream& SVGFEImage::externalRepresentation(TextStream& ts) const +void FEImage::apply() { - ts << "[type=IMAGE] "; - SVGFilterEffect::externalRepresentation(ts); - // FIXME: should this dump also object returned by SVGFEImage::image() ? - return ts; +} +void FEImage::dump() +{ } -void SVGFEImage::imageChanged(CachedImage*) +TextStream& FEImage::externalRepresentation(TextStream& ts) const { - if (SVGResourceFilter* filterResource = filter()) - filterResource->invalidate(); + ts << "[type=IMAGE] "; + FilterEffect::externalRepresentation(ts); + // FIXME: should this dump also object returned by SVGFEImage::image() ? + return ts; } } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEImage.h b/WebCore/svg/graphics/filters/SVGFEImage.h index 8245d10..fcf413f 100644 --- a/WebCore/svg/graphics/filters/SVGFEImage.h +++ b/WebCore/svg/graphics/filters/SVGFEImage.h @@ -25,32 +25,31 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "CachedImage.h" #include "CachedResourceClient.h" -#include "SVGFilterEffect.h" +#include "CachedResourceHandle.h" +#include "FilterEffect.h" namespace WebCore { -class SVGFEImage : public SVGFilterEffect - , public CachedResourceClient { -public: - SVGFEImage(SVGResourceFilter*); - virtual ~SVGFEImage(); - - // FIXME: We need to support <svg> (RenderObject*) as well as image data. - - CachedImage* cachedImage() const; - void setCachedImage(CachedImage*); - - virtual TextStream& externalRepresentation(TextStream&) const; - -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif - - virtual void imageChanged(CachedImage*); - -private: - CachedImage* m_cachedImage; -}; + class FEImage : public FilterEffect + , public CachedResourceClient { + public: + static PassRefPtr<FEImage> create(CachedImage*); + virtual ~FEImage(); + + // FIXME: We need to support <svg> (RenderObject*) as well as image data. + + CachedImage* cachedImage() const; + void setCachedImage(CachedImage*); + + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; + + private: + FEImage(CachedImage*); + + CachedResourceHandle<CachedImage> m_cachedImage; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.cpp b/WebCore/svg/graphics/filters/SVGFEMerge.cpp index f4cf2db..8ce15a7 100644 --- a/WebCore/svg/graphics/filters/SVGFEMerge.cpp +++ b/WebCore/svg/graphics/filters/SVGFEMerge.cpp @@ -23,24 +23,43 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFEMerge.h" -#include "TextStream.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -const Vector<String>& SVGFEMerge::mergeInputs() const +FEMerge::FEMerge(const Vector<FilterEffect*>& mergeInputs) + : FilterEffect() + , m_mergeInputs(mergeInputs) +{ +} + +PassRefPtr<FEMerge> FEMerge::create(const Vector<FilterEffect*>& mergeInputs) +{ + return adoptRef(new FEMerge(mergeInputs)); +} + +const Vector<FilterEffect*>& FEMerge::mergeInputs() const { return m_mergeInputs; } -void SVGFEMerge::setMergeInputs(const Vector<String>& mergeInputs) +void FEMerge::setMergeInputs(const Vector<FilterEffect*>& mergeInputs) { m_mergeInputs = mergeInputs; } -TextStream& SVGFEMerge::externalRepresentation(TextStream& ts) const +void FEMerge::apply() +{ +} + +void FEMerge::dump() +{ +} + +TextStream& FEMerge::externalRepresentation(TextStream& ts) const { ts << "[type=MERGE] "; - SVGFilterEffect::externalRepresentation(ts); + FilterEffect::externalRepresentation(ts); ts << "[merge inputs=["; unsigned x = 0; unsigned size = m_mergeInputs.size(); diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.h b/WebCore/svg/graphics/filters/SVGFEMerge.h index 9a0e867..6415c9f 100644 --- a/WebCore/svg/graphics/filters/SVGFEMerge.h +++ b/WebCore/svg/graphics/filters/SVGFEMerge.h @@ -23,26 +23,28 @@ #define SVGFEMerge_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" +#include "FilterEffect.h" -namespace WebCore { +#include <wtf/Vector.h> -class SVGFEMerge : public SVGFilterEffect { -public: - SVGFEMerge(SVGResourceFilter* filter) : SVGFilterEffect(filter) { } +namespace WebCore { - const Vector<String>& mergeInputs() const; - void setMergeInputs(const Vector<String>& mergeInputs); + class FEMerge : public FilterEffect { + public: + static PassRefPtr<FEMerge> create(const Vector<FilterEffect*>&); - virtual TextStream& externalRepresentation(TextStream&) const; + const Vector<FilterEffect*>& mergeInputs() const; + void setMergeInputs(const Vector<FilterEffect*>& mergeInputs); + + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif + private: + FEMerge(const Vector<FilterEffect*>&); -private: - Vector<String> m_mergeInputs; -}; + Vector<FilterEffect*> m_mergeInputs; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp index 4eaad67..7838a8c 100644 --- a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp +++ b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp @@ -23,68 +23,82 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFEMorphology.h" -#include "TextStream.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFEMorphology::SVGFEMorphology(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_operator(SVG_MORPHOLOGY_OPERATOR_UNKNOWN) - , m_radiusX(0.0f) - , m_radiusY(0.0f) +FEMorphology::FEMorphology(FilterEffect* in, MorphologyOperatorType type, const float& radiusX, const float& radiusY) + : FilterEffect() + , m_in(in) + , m_type(type) + , m_radiusX(radiusX) + , m_radiusY(radiusY) { } -SVGMorphologyOperatorType SVGFEMorphology::morphologyOperator() const +PassRefPtr<FEMorphology> FEMorphology::create(FilterEffect* in, MorphologyOperatorType type, const float& radiusX, const float& radiusY) { - return m_operator; + return adoptRef(new FEMorphology(in, type, radiusX, radiusY)); } -void SVGFEMorphology::setMorphologyOperator(SVGMorphologyOperatorType _operator) +MorphologyOperatorType FEMorphology::morphologyOperator() const { - m_operator = _operator; + return m_type; } -float SVGFEMorphology::radiusX() const +void FEMorphology::setMorphologyOperator(MorphologyOperatorType type) +{ + m_type = type; +} + +float FEMorphology::radiusX() const { return m_radiusX; } -void SVGFEMorphology::setRadiusX(float radiusX) +void FEMorphology::setRadiusX(float radiusX) { m_radiusX = radiusX; } -float SVGFEMorphology::radiusY() const +float FEMorphology::radiusY() const { return m_radiusY; } -void SVGFEMorphology::setRadiusY(float radiusY) +void FEMorphology::setRadiusY(float radiusY) { m_radiusY = radiusY; } -static TextStream& operator<<(TextStream& ts, SVGMorphologyOperatorType t) +void FEMorphology::apply() +{ +} + +void FEMorphology::dump() +{ +} + +static TextStream& operator<<(TextStream& ts, MorphologyOperatorType t) { switch (t) { - case SVG_MORPHOLOGY_OPERATOR_UNKNOWN: + case FEMORPHOLOGY_OPERATOR_UNKNOWN: ts << "UNKNOWN"; break; - case SVG_MORPHOLOGY_OPERATOR_ERODE: + case FEMORPHOLOGY_OPERATOR_ERODE: ts << "ERODE"; break; - case SVG_MORPHOLOGY_OPERATOR_DIALATE: + case FEMORPHOLOGY_OPERATOR_DIALATE: ts << "DIALATE"; break; } return ts; } -TextStream& SVGFEMorphology::externalRepresentation(TextStream& ts) const +TextStream& FEMorphology::externalRepresentation(TextStream& ts) const { - ts << "[type=MORPHOLOGY-OPERATOR] "; - SVGFilterEffect::externalRepresentation(ts); + ts << "[type=MORPHOLOGY] "; + FilterEffect::externalRepresentation(ts); ts << " [operator type=" << morphologyOperator() << "]" - << " [radius x=" << radiusX() << " y=" << radiusY() << "]"; + << " [radius x=" << radiusX() << " y=" << radiusY() << "]"; return ts; } diff --git a/WebCore/svg/graphics/filters/SVGFEMorphology.h b/WebCore/svg/graphics/filters/SVGFEMorphology.h index 4ba7131..98ab633 100644 --- a/WebCore/svg/graphics/filters/SVGFEMorphology.h +++ b/WebCore/svg/graphics/filters/SVGFEMorphology.h @@ -23,36 +23,40 @@ #define SVGFEMorphology_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" +#include "FilterEffect.h" namespace WebCore { -enum SVGMorphologyOperatorType { - SVG_MORPHOLOGY_OPERATOR_UNKNOWN = 0, - SVG_MORPHOLOGY_OPERATOR_ERODE = 1, - SVG_MORPHOLOGY_OPERATOR_DIALATE = 2 -}; - -class SVGFEMorphology : public SVGFilterEffect { -public: - SVGFEMorphology(SVGResourceFilter*); - - SVGMorphologyOperatorType morphologyOperator() const; - void setMorphologyOperator(SVGMorphologyOperatorType); - - float radiusX() const; - void setRadiusX(float); - - float radiusY() const; - void setRadiusY(float); - - virtual TextStream& externalRepresentation(TextStream&) const; - -private: - SVGMorphologyOperatorType m_operator; - float m_radiusX; - float m_radiusY; -}; + enum MorphologyOperatorType { + FEMORPHOLOGY_OPERATOR_UNKNOWN = 0, + FEMORPHOLOGY_OPERATOR_ERODE = 1, + FEMORPHOLOGY_OPERATOR_DIALATE = 2 + }; + + class FEMorphology : public FilterEffect { + public: + PassRefPtr<FEMorphology> create(FilterEffect*, MorphologyOperatorType, const float&, const float&); + MorphologyOperatorType morphologyOperator() const; + void setMorphologyOperator(MorphologyOperatorType); + + float radiusX() const; + void setRadiusX(float); + + float radiusY() const; + void setRadiusY(float); + + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; + + private: + FEMorphology(FilterEffect*, MorphologyOperatorType, const float&, const float&); + + RefPtr<FilterEffect> m_in; + MorphologyOperatorType m_type; + float m_radiusX; + float m_radiusY; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEOffset.cpp b/WebCore/svg/graphics/filters/SVGFEOffset.cpp index 024f2cd..c2a0fc9 100644 --- a/WebCore/svg/graphics/filters/SVGFEOffset.cpp +++ b/WebCore/svg/graphics/filters/SVGFEOffset.cpp @@ -23,41 +23,56 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFEOffset.h" -#include "TextStream.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFEOffset::SVGFEOffset(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_dx(0.0f) - , m_dy(0.0f) +FEOffset::FEOffset(FilterEffect* in, const float& dx, const float& dy) + : FilterEffect() + , m_in(in) + , m_dx(dx) + , m_dy(dy) { } -float SVGFEOffset::dx() const +PassRefPtr<FEOffset> FEOffset::create(FilterEffect* in, const float& dx, const float& dy) +{ + return adoptRef(new FEOffset(in, dx, dy)); +} + +float FEOffset::dx() const { return m_dx; } -void SVGFEOffset::setDx(float dx) +void FEOffset::setDx(float dx) { m_dx = dx; } -float SVGFEOffset::dy() const +float FEOffset::dy() const { return m_dy; } -void SVGFEOffset::setDy(float dy) +void FEOffset::setDy(float dy) { m_dy = dy; } -TextStream& SVGFEOffset::externalRepresentation(TextStream& ts) const +void FEOffset::apply() +{ +} + +void FEOffset::dump() +{ +} + +TextStream& FEOffset::externalRepresentation(TextStream& ts) const { - ts << "[type=OFFSET] "; SVGFilterEffect::externalRepresentation(ts) - << " [dx=" << dx() << " dy=" << dy() << "]"; + ts << "[type=OFFSET] "; + FilterEffect::externalRepresentation(ts); + ts << " [dx=" << dx() << " dy=" << dy() << "]"; return ts; } diff --git a/WebCore/svg/graphics/filters/SVGFEOffset.h b/WebCore/svg/graphics/filters/SVGFEOffset.h index 05b427d..86128da 100644 --- a/WebCore/svg/graphics/filters/SVGFEOffset.h +++ b/WebCore/svg/graphics/filters/SVGFEOffset.h @@ -23,30 +23,31 @@ #define SVGFEOffset_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" +#include "FilterEffect.h" namespace WebCore { -class SVGFEOffset : public SVGFilterEffect { -public: - SVGFEOffset(SVGResourceFilter*); + class FEOffset : public FilterEffect { + public: + static PassRefPtr<FEOffset> create(FilterEffect*, const float&, const float&); - float dx() const; - void setDx(float); + float dx() const; + void setDx(float); - float dy() const; - void setDy(float); + float dy() const; + void setDy(float); - virtual TextStream& externalRepresentation(TextStream&) const; + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif + private: + FEOffset(FilterEffect*, const float&, const float&); -private: - float m_dx; - float m_dy; -}; + RefPtr<FilterEffect> m_in; + float m_dx; + float m_dy; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp b/WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp index ba45dae..e3446ed 100644 --- a/WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp +++ b/WebCore/svg/graphics/filters/SVGFESpecularLighting.cpp @@ -23,104 +23,119 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFESpecularLighting.h" -#include "TextStream.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFESpecularLighting::SVGFESpecularLighting(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_lightingColor() - , m_surfaceScale(0.0f) - , m_specularConstant(0.0f) - , m_specularExponent(0.0f) - , m_kernelUnitLengthX(0.0f) - , m_kernelUnitLengthY(0.0f) - , m_lightSource(0) +FESpecularLighting::FESpecularLighting(FilterEffect* in, const Color& lightingColor, const float& surfaceScale, + const float& specularConstant, const float& specularExponent, const float& kernelUnitLengthX, + const float& kernelUnitLengthY, LightSource* lightSource) + : FilterEffect() + , m_in(in) + , m_lightingColor(lightingColor) + , m_surfaceScale(surfaceScale) + , m_specularConstant(specularConstant) + , m_specularExponent(specularExponent) + , m_kernelUnitLengthX(kernelUnitLengthX) + , m_kernelUnitLengthY(kernelUnitLengthY) + , m_lightSource(lightSource) { } -SVGFESpecularLighting::~SVGFESpecularLighting() +PassRefPtr<FESpecularLighting> FESpecularLighting::create(FilterEffect* in, const Color& lightingColor, + const float& surfaceScale, const float& specularConstant, const float& specularExponent, + const float& kernelUnitLengthX, const float& kernelUnitLengthY, LightSource* lightSource) { - delete m_lightSource; + return adoptRef(new FESpecularLighting(in, lightingColor, surfaceScale, specularConstant, specularExponent, + kernelUnitLengthX, kernelUnitLengthY, lightSource)); } -Color SVGFESpecularLighting::lightingColor() const +FESpecularLighting::~FESpecularLighting() +{ +} + +Color FESpecularLighting::lightingColor() const { return m_lightingColor; } -void SVGFESpecularLighting::setLightingColor(const Color& lightingColor) +void FESpecularLighting::setLightingColor(const Color& lightingColor) { m_lightingColor = lightingColor; } -float SVGFESpecularLighting::surfaceScale() const +float FESpecularLighting::surfaceScale() const { return m_surfaceScale; } -void SVGFESpecularLighting::setSurfaceScale(float surfaceScale) +void FESpecularLighting::setSurfaceScale(float surfaceScale) { m_surfaceScale = surfaceScale; } -float SVGFESpecularLighting::specularConstant() const +float FESpecularLighting::specularConstant() const { return m_specularConstant; } -void SVGFESpecularLighting::setSpecularConstant(float specularConstant) +void FESpecularLighting::setSpecularConstant(float specularConstant) { m_specularConstant = specularConstant; } -float SVGFESpecularLighting::specularExponent() const +float FESpecularLighting::specularExponent() const { return m_specularExponent; } -void SVGFESpecularLighting::setSpecularExponent(float specularExponent) +void FESpecularLighting::setSpecularExponent(float specularExponent) { m_specularExponent = specularExponent; } -float SVGFESpecularLighting::kernelUnitLengthX() const +float FESpecularLighting::kernelUnitLengthX() const { return m_kernelUnitLengthX; } -void SVGFESpecularLighting::setKernelUnitLengthX(float kernelUnitLengthX) +void FESpecularLighting::setKernelUnitLengthX(float kernelUnitLengthX) { m_kernelUnitLengthX = kernelUnitLengthX; } -float SVGFESpecularLighting::kernelUnitLengthY() const +float FESpecularLighting::kernelUnitLengthY() const { return m_kernelUnitLengthY; } -void SVGFESpecularLighting::setKernelUnitLengthY(float kernelUnitLengthY) +void FESpecularLighting::setKernelUnitLengthY(float kernelUnitLengthY) { m_kernelUnitLengthY = kernelUnitLengthY; } -const SVGLightSource* SVGFESpecularLighting::lightSource() const +const LightSource* FESpecularLighting::lightSource() const +{ + return m_lightSource.get(); +} + +void FESpecularLighting::setLightSource(LightSource* lightSource) +{ + m_lightSource = lightSource; +} + +void FESpecularLighting::apply() { - return m_lightSource; } -void SVGFESpecularLighting::setLightSource(SVGLightSource* lightSource) +void FESpecularLighting::dump() { - if (m_lightSource != lightSource) { - delete m_lightSource; - m_lightSource = lightSource; - } } -TextStream& SVGFESpecularLighting::externalRepresentation(TextStream& ts) const +TextStream& FESpecularLighting::externalRepresentation(TextStream& ts) const { ts << "[type=SPECULAR-LIGHTING] "; - SVGFilterEffect::externalRepresentation(ts); + FilterEffect::externalRepresentation(ts); ts << " [surface scale=" << m_surfaceScale << "]" << " [specual constant=" << m_specularConstant << "]" << " [specular exponent=" << m_specularExponent << "]"; diff --git a/WebCore/svg/graphics/filters/SVGFESpecularLighting.h b/WebCore/svg/graphics/filters/SVGFESpecularLighting.h index 66e1561..e1c1930 100644 --- a/WebCore/svg/graphics/filters/SVGFESpecularLighting.h +++ b/WebCore/svg/graphics/filters/SVGFESpecularLighting.h @@ -25,51 +25,54 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "Color.h" #include "SVGLightSource.h" -#include "SVGFilterEffect.h" +#include "FilterEffect.h" namespace WebCore { -class SVGFESpecularLighting : public SVGFilterEffect { -public: - SVGFESpecularLighting(SVGResourceFilter*); - virtual ~SVGFESpecularLighting(); + class FESpecularLighting : public FilterEffect { + public: + static PassRefPtr<FESpecularLighting> create(FilterEffect*, const Color&, const float&, const float&, + const float&, const float&, const float&, LightSource*); + virtual ~FESpecularLighting(); - Color lightingColor() const; - void setLightingColor(const Color&); + Color lightingColor() const; + void setLightingColor(const Color&); - float surfaceScale() const; - void setSurfaceScale(float); + float surfaceScale() const; + void setSurfaceScale(float); - float specularConstant() const; - void setSpecularConstant(float); + float specularConstant() const; + void setSpecularConstant(float); - float specularExponent() const; - void setSpecularExponent(float); + float specularExponent() const; + void setSpecularExponent(float); - float kernelUnitLengthX() const; - void setKernelUnitLengthX(float); + float kernelUnitLengthX() const; + void setKernelUnitLengthX(float); - float kernelUnitLengthY() const; - void setKernelUnitLengthY(float); + float kernelUnitLengthY() const; + void setKernelUnitLengthY(float); - const SVGLightSource* lightSource() const; - void setLightSource(SVGLightSource*); + const LightSource* lightSource() const; + void setLightSource(LightSource*); - virtual TextStream& externalRepresentation(TextStream&) const; + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif + private: + FESpecularLighting(FilterEffect*, const Color&, const float&, const float&, const float&, + const float&, const float&, LightSource*); -private: - Color m_lightingColor; - float m_surfaceScale; - float m_specularConstant; - float m_specularExponent; - float m_kernelUnitLengthX; - float m_kernelUnitLengthY; - SVGLightSource* m_lightSource; -}; + RefPtr<FilterEffect> m_in; + Color m_lightingColor; + float m_surfaceScale; + float m_specularConstant; + float m_specularExponent; + float m_kernelUnitLengthX; + float m_kernelUnitLengthY; + RefPtr<LightSource> m_lightSource; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/cg/SVGFEOffsetCg.mm b/WebCore/svg/graphics/filters/SVGFETile.cpp index 46fb045..773a5cd 100644 --- a/WebCore/svg/graphics/filters/cg/SVGFEOffsetCg.mm +++ b/WebCore/svg/graphics/filters/SVGFETile.cpp @@ -1,7 +1,5 @@ /* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -22,23 +20,38 @@ #include "config.h" #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEOffset.h" -#include "SVGFEHelpersCg.h" +#include "SVGFETile.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -CIFilter* SVGFEOffset::getCIFilter(const FloatRect& bbox) const +FETile::FETile(FilterEffect* in) + : FilterEffect() + , m_in(in) { - SVGResourceFilter* svgFilter = filter(); - FE_QUARTZ_SETUP_INPUT(@"CIAffineTransform"); - NSAffineTransform* offsetTransform = [NSAffineTransform transform]; - [offsetTransform translateXBy:dx() yBy:dy()]; - [filter setValue:offsetTransform forKey:@"inputTransform"]; - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; } +PassRefPtr<FETile> FETile::create(FilterEffect* in) +{ + return adoptRef(new FETile(in)); } +void FETile::apply() +{ +} + +void FETile::dump() +{ +} + +TextStream& FETile::externalRepresentation(TextStream& ts) const +{ + ts << "[type=TILE]"; + FilterEffect::externalRepresentation(ts); + return ts; +} + +} // namespace WebCore + #endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) + diff --git a/WebCore/svg/graphics/filters/SVGFETile.h b/WebCore/svg/graphics/filters/SVGFETile.h index 1c3922f..986f6fd 100644 --- a/WebCore/svg/graphics/filters/SVGFETile.h +++ b/WebCore/svg/graphics/filters/SVGFETile.h @@ -23,19 +23,23 @@ #define SVGFETile_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" +#include "FilterEffect.h" namespace WebCore { - -class SVGFETile : public SVGFilterEffect -{ -public: - SVGFETile(SVGResourceFilter* filter) : SVGFilterEffect(filter) { } - -#if PLATFORM(CI) - virtual CIFilter* getCIFilter(const FloatRect& bbox) const; -#endif -}; + + class FETile : public FilterEffect { + public: + static PassRefPtr<FETile> create(FilterEffect*); + + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; + + private: + FETile(FilterEffect*); + + RefPtr<FilterEffect> m_in; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFETurbulence.cpp b/WebCore/svg/graphics/filters/SVGFETurbulence.cpp index 0f9cbaf..9731c49 100644 --- a/WebCore/svg/graphics/filters/SVGFETurbulence.cpp +++ b/WebCore/svg/graphics/filters/SVGFETurbulence.cpp @@ -23,106 +23,121 @@ #if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGFETurbulence.h" -#include "TextStream.h" +#include "SVGRenderTreeAsText.h" namespace WebCore { -SVGFETurbulence::SVGFETurbulence(SVGResourceFilter* filter) - : SVGFilterEffect(filter) - , m_baseFrequencyX(0.0f) - , m_baseFrequencyY(0.0f) - , m_numOctaves(0) - , m_seed(0) - , m_stitchTiles(false) - , m_type(SVG_TURBULENCE_TYPE_UNKNOWN) +FETurbulence::FETurbulence(TurbulanceType type, const float& baseFrequencyX, const float& baseFrequencyY, + const int& numOctaves, const float& seed, bool stitchTiles) + : FilterEffect() + , m_type(type) + , m_baseFrequencyX(baseFrequencyX) + , m_baseFrequencyY(baseFrequencyY) + , m_numOctaves(numOctaves) + , m_seed(seed) + , m_stitchTiles(stitchTiles) { } -SVGTurbulanceType SVGFETurbulence::type() const +PassRefPtr<FETurbulence> FETurbulence::create(TurbulanceType type, const float& baseFrequencyX, const float& baseFrequencyY, + const int& numOctaves, const float& seed, bool stitchTiles) +{ + return adoptRef(new FETurbulence(type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles)); +} + +TurbulanceType FETurbulence::type() const { return m_type; } -void SVGFETurbulence::setType(SVGTurbulanceType type) +void FETurbulence::setType(TurbulanceType type) { m_type = type; } -float SVGFETurbulence::baseFrequencyY() const +float FETurbulence::baseFrequencyY() const { return m_baseFrequencyY; } -void SVGFETurbulence::setBaseFrequencyY(float baseFrequencyY) +void FETurbulence::setBaseFrequencyY(float baseFrequencyY) { m_baseFrequencyY = baseFrequencyY; } -float SVGFETurbulence::baseFrequencyX() const +float FETurbulence::baseFrequencyX() const { return m_baseFrequencyX; } -void SVGFETurbulence::setBaseFrequencyX(float baseFrequencyX) +void FETurbulence::setBaseFrequencyX(float baseFrequencyX) { m_baseFrequencyX = baseFrequencyX; } -float SVGFETurbulence::seed() const +float FETurbulence::seed() const { return m_seed; } -void SVGFETurbulence::setSeed(float seed) +void FETurbulence::setSeed(float seed) { m_seed = seed; } -int SVGFETurbulence::numOctaves() const +int FETurbulence::numOctaves() const { return m_numOctaves; } -void SVGFETurbulence::setNumOctaves(bool numOctaves) +void FETurbulence::setNumOctaves(bool numOctaves) { m_numOctaves = numOctaves; } -bool SVGFETurbulence::stitchTiles() const +bool FETurbulence::stitchTiles() const { return m_stitchTiles; } -void SVGFETurbulence::setStitchTiles(bool stitch) +void FETurbulence::setStitchTiles(bool stitch) { m_stitchTiles = stitch; } -static TextStream& operator<<(TextStream& ts, SVGTurbulanceType t) +void FETurbulence::apply() +{ +} + +void FETurbulence::dump() +{ +} + +static TextStream& operator<<(TextStream& ts, TurbulanceType t) { switch (t) { - case SVG_TURBULENCE_TYPE_UNKNOWN: + case FETURBULENCE_TYPE_UNKNOWN: ts << "UNKNOWN"; break; - case SVG_TURBULENCE_TYPE_TURBULENCE: + case FETURBULENCE_TYPE_TURBULENCE: ts << "TURBULANCE"; break; - case SVG_TURBULENCE_TYPE_FRACTALNOISE: + case FETURBULENCE_TYPE_FRACTALNOISE: ts << "NOISE"; break; } return ts; } -TextStream& SVGFETurbulence::externalRepresentation(TextStream& ts) const +TextStream& FETurbulence::externalRepresentation(TextStream& ts) const { ts << "[type=TURBULENCE] "; - SVGFilterEffect::externalRepresentation(ts); + FilterEffect::externalRepresentation(ts); ts << " [turbulence type=" << type() << "]" << " [base frequency x=" << baseFrequencyX() << " y=" << baseFrequencyY() << "]" << " [seed=" << seed() << "]" << " [num octaves=" << numOctaves() << "]" << " [stitch tiles=" << stitchTiles() << "]"; - return ts; + return ts; } } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFETurbulence.h b/WebCore/svg/graphics/filters/SVGFETurbulence.h index b871416..6977460 100644 --- a/WebCore/svg/graphics/filters/SVGFETurbulence.h +++ b/WebCore/svg/graphics/filters/SVGFETurbulence.h @@ -23,48 +23,54 @@ #define SVGFETurbulence_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFilterEffect.h" +#include "FilterEffect.h" namespace WebCore { -enum SVGTurbulanceType { - SVG_TURBULENCE_TYPE_UNKNOWN = 0, - SVG_TURBULENCE_TYPE_FRACTALNOISE = 1, - SVG_TURBULENCE_TYPE_TURBULENCE = 2 -}; + enum TurbulanceType { + FETURBULENCE_TYPE_UNKNOWN = 0, + FETURBULENCE_TYPE_FRACTALNOISE = 1, + FETURBULENCE_TYPE_TURBULENCE = 2 + }; -class SVGFETurbulence : public SVGFilterEffect { -public: - SVGFETurbulence(SVGResourceFilter*); + class FETurbulence : public FilterEffect { + public: + static PassRefPtr<FETurbulence> create(TurbulanceType, const float&, const float&, const int&, const float&, + bool); - SVGTurbulanceType type() const; - void setType(SVGTurbulanceType); + TurbulanceType type() const; + void setType(TurbulanceType); - float baseFrequencyY() const; - void setBaseFrequencyY(float); + float baseFrequencyY() const; + void setBaseFrequencyY(float); - float baseFrequencyX() const; - void setBaseFrequencyX(float); + float baseFrequencyX() const; + void setBaseFrequencyX(float); - float seed() const; - void setSeed(float); + float seed() const; + void setSeed(float); - int numOctaves() const; - void setNumOctaves(bool); + int numOctaves() const; + void setNumOctaves(bool); - bool stitchTiles() const; - void setStitchTiles(bool); + bool stitchTiles() const; + void setStitchTiles(bool); - virtual TextStream& externalRepresentation(TextStream&) const; + virtual void apply(); + virtual void dump(); + TextStream& externalRepresentation(TextStream& ts) const; -private: - float m_baseFrequencyX; - float m_baseFrequencyY; - int m_numOctaves; - float m_seed; - bool m_stitchTiles; - SVGTurbulanceType m_type; -}; + private: + FETurbulence(TurbulanceType, const float&, const float&, const int&, const float&, + bool); + + TurbulanceType m_type; + float m_baseFrequencyX; + float m_baseFrequencyY; + int m_numOctaves; + float m_seed; + bool m_stitchTiles; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFilterEffect.cpp b/WebCore/svg/graphics/filters/SVGFilterEffect.cpp index 9423dc1..f8e246f 100644 --- a/WebCore/svg/graphics/filters/SVGFilterEffect.cpp +++ b/WebCore/svg/graphics/filters/SVGFilterEffect.cpp @@ -26,7 +26,6 @@ #include "SVGRenderTreeAsText.h" #include "SVGResourceFilter.h" -#include "TextStream.h" namespace WebCore { diff --git a/WebCore/svg/graphics/filters/SVGFilterEffect.h b/WebCore/svg/graphics/filters/SVGFilterEffect.h index f7128fc..d497f8b 100644 --- a/WebCore/svg/graphics/filters/SVGFilterEffect.h +++ b/WebCore/svg/graphics/filters/SVGFilterEffect.h @@ -39,7 +39,7 @@ namespace WebCore { class SVGResourceFilter; class TextStream; -class SVGFilterEffect { +class SVGFilterEffect : public RefCounted<SVGFilterEffect> { public: SVGFilterEffect(SVGResourceFilter*); virtual ~SVGFilterEffect() { } diff --git a/WebCore/svg/graphics/filters/SVGLightSource.cpp b/WebCore/svg/graphics/filters/SVGLightSource.cpp index 517ed50..77611ca 100644 --- a/WebCore/svg/graphics/filters/SVGLightSource.cpp +++ b/WebCore/svg/graphics/filters/SVGLightSource.cpp @@ -35,14 +35,14 @@ static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p) return ts; } -TextStream& SVGPointLightSource::externalRepresentation(TextStream& ts) const +TextStream& PointLightSource::externalRepresentation(TextStream& ts) const { ts << "[type=POINT-LIGHT] "; ts << "[position=\"" << position() << "\"]"; return ts; } -TextStream& SVGSpotLightSource::externalRepresentation(TextStream& ts) const +TextStream& SpotLightSource::externalRepresentation(TextStream& ts) const { ts << "[type=SPOT-LIGHT] "; ts << "[position=\"" << position() << "\"]"; @@ -52,7 +52,7 @@ TextStream& SVGSpotLightSource::externalRepresentation(TextStream& ts) const return ts; } -TextStream& SVGDistantLightSource::externalRepresentation(TextStream& ts) const +TextStream& DistantLightSource::externalRepresentation(TextStream& ts) const { ts << "[type=DISTANT-LIGHT] "; ts << "[azimuth=\"" << azimuth() << "\"]"; diff --git a/WebCore/svg/graphics/filters/SVGLightSource.h b/WebCore/svg/graphics/filters/SVGLightSource.h index 12cf3d0..779e147 100644 --- a/WebCore/svg/graphics/filters/SVGLightSource.h +++ b/WebCore/svg/graphics/filters/SVGLightSource.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> @@ -23,32 +24,32 @@ #define SVGLightSource_h #if ENABLE(SVG) && ENABLE(SVG_FILTERS) +#include <wtf/RefCounted.h> namespace WebCore { -enum SVGLightType { - LS_DISTANT, - LS_POINT, - LS_SPOT -}; + enum LightType { + LS_DISTANT, + LS_POINT, + LS_SPOT + }; -class TextStream; + class TextStream; -class SVGLightSource { -public: - SVGLightSource(SVGLightType type) - : m_type(type) - { } + class LightSource : public RefCounted<LightSource> { + public: + LightSource(LightType type) + : m_type(type) + { } - virtual ~SVGLightSource() { } + virtual ~LightSource() { } - SVGLightType type() const { return m_type; } - virtual TextStream& externalRepresentation(TextStream&) const = 0; - -private: - SVGLightType m_type; -}; + LightType type() const { return m_type; } + virtual TextStream& externalRepresentation(TextStream&) const = 0; + private: + LightType m_type; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGPointLightSource.h b/WebCore/svg/graphics/filters/SVGPointLightSource.h index 71b8f70..099a165 100644 --- a/WebCore/svg/graphics/filters/SVGPointLightSource.h +++ b/WebCore/svg/graphics/filters/SVGPointLightSource.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> @@ -28,20 +29,20 @@ namespace WebCore { -class SVGPointLightSource : public SVGLightSource { -public: - SVGPointLightSource(const FloatPoint3D& position) - : SVGLightSource(LS_POINT) - , m_position(position) - { } + class PointLightSource : public LightSource { + public: + PointLightSource(const FloatPoint3D& position) + : LightSource(LS_POINT) + , m_position(position) + { } - const FloatPoint3D& position() const { return m_position; } + const FloatPoint3D& position() const { return m_position; } - virtual TextStream& externalRepresentation(TextStream&) const; + virtual TextStream& externalRepresentation(TextStream&) const; -private: - FloatPoint3D m_position; -}; + private: + FloatPoint3D m_position; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGSpotLightSource.h b/WebCore/svg/graphics/filters/SVGSpotLightSource.h index 850a5fa..a4aa1fb 100644 --- a/WebCore/svg/graphics/filters/SVGSpotLightSource.h +++ b/WebCore/svg/graphics/filters/SVGSpotLightSource.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> + Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com> + 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> @@ -28,31 +29,31 @@ namespace WebCore { -class SVGSpotLightSource : public SVGLightSource { -public: - SVGSpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction, float specularExponent, float limitingConeAngle) - : SVGLightSource(LS_SPOT) - , m_position(position) - , m_direction(direction) - , m_specularExponent(specularExponent) - , m_limitingConeAngle(limitingConeAngle) - { } + class SpotLightSource : public LightSource { + public: + SpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction, float specularExponent, float limitingConeAngle) + : LightSource(LS_SPOT) + , m_position(position) + , m_direction(direction) + , m_specularExponent(specularExponent) + , m_limitingConeAngle(limitingConeAngle) + { } - const FloatPoint3D& position() const { return m_position; } - const FloatPoint3D& direction() const { return m_direction; } + const FloatPoint3D& position() const { return m_position; } + const FloatPoint3D& direction() const { return m_direction; } - float specularExponent() const { return m_specularExponent; } - float limitingConeAngle() const { return m_limitingConeAngle; } + float specularExponent() const { return m_specularExponent; } + float limitingConeAngle() const { return m_limitingConeAngle; } - virtual TextStream& externalRepresentation(TextStream&) const; + virtual TextStream& externalRepresentation(TextStream&) const; -private: - FloatPoint3D m_position; - FloatPoint3D m_direction; + private: + FloatPoint3D m_position; + FloatPoint3D m_direction; - float m_specularExponent; - float m_limitingConeAngle; -}; + float m_specularExponent; + float m_limitingConeAngle; + }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/cg/SVGFEBlendCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEBlendCg.mm deleted file mode 100644 index 29caaa0..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFEBlendCg.mm +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEBlend.h" -#include "SVGFEHelpersCg.h" - -namespace WebCore { - -CIFilter* SVGFEBlend::getCIFilter(const FloatRect& bbox) const -{ - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - CIFilter* filter = nil; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - switch (blendMode()) { - case SVG_FEBLEND_MODE_UNKNOWN: - return nil; - case SVG_FEBLEND_MODE_NORMAL: - // FIXME: I think this is correct.... - filter = [CIFilter filterWithName:@"CISourceOverCompositing"]; - break; - case SVG_FEBLEND_MODE_MULTIPLY: - filter = [CIFilter filterWithName:@"CIMultiplyBlendMode"]; - break; - case SVG_FEBLEND_MODE_SCREEN: - filter = [CIFilter filterWithName:@"CIScreenBlendMode"]; - break; - case SVG_FEBLEND_MODE_DARKEN: - filter = [CIFilter filterWithName:@"CIDarkenBlendMode"]; - break; - case SVG_FEBLEND_MODE_LIGHTEN: - filter = [CIFilter filterWithName:@"CILightenBlendMode"]; - break; - default: - LOG_ERROR("Unhandled blend mode: %i", blendMode()); - return nil; - } - - [filter setDefaults]; - - CIImage* inputImage = filterPlatformData->inputImage(this); - FE_QUARTZ_CHECK_INPUT(inputImage); - [filter setValue:inputImage forKey:@"inputImage"]; - - CIImage* backgroundImage = filterPlatformData->imageForName(in2()); - FE_QUARTZ_CHECK_INPUT(backgroundImage); - [filter setValue:backgroundImage forKey:@"inputBackgroundImage"]; - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFEColorMatrixCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEColorMatrixCg.mm deleted file mode 100644 index ae6e4aa..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFEColorMatrixCg.mm +++ /dev/null @@ -1,111 +0,0 @@ -/* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEColorMatrix.h" -#include "SVGFEHelpersCg.h" - -#include <wtf/MathExtras.h> - -namespace WebCore { - -#define CMValuesCheck(expected, type) \ - if (values().size() != expected) { \ - NSLog(@"Error, incorrect number of values in ColorMatrix for type \"%s\", expected: %i actual: %i, ignoring filter. Values:", type, expected, values().size()); \ - for (unsigned x=0; x < values().size(); x++) fprintf(stderr, " %f", values()[x]); \ - fprintf(stderr, "\n"); \ - return nil; \ - } - -CIFilter* SVGFEColorMatrix::getCIFilter(const FloatRect& bbox) const -{ - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - CIFilter* filter = nil; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - switch (type()) { - case SVG_FECOLORMATRIX_TYPE_UNKNOWN: - return nil; - case SVG_FECOLORMATRIX_TYPE_MATRIX: - { - CMValuesCheck(20, "matrix"); - filter = [CIFilter filterWithName:@"CIColorMatrix"]; - [filter setDefaults]; - const Vector<float>& v = values(); - [filter setValue:[CIVector vectorWithX:v[0] Y:v[1] Z:v[2] W:v[3]] forKey:@"inputRVector"]; - [filter setValue:[CIVector vectorWithX:v[5] Y:v[6] Z:v[7] W:v[8]] forKey:@"inputGVector"]; - [filter setValue:[CIVector vectorWithX:v[10] Y:v[11] Z:v[12] W:v[13]] forKey:@"inputBVector"]; - [filter setValue:[CIVector vectorWithX:v[15] Y:v[16] Z:v[17] W:v[18]] forKey:@"inputAVector"]; - [filter setValue:[CIVector vectorWithX:v[4] Y:v[9] Z:v[14] W:v[19]] forKey:@"inputBiasVector"]; - break; - } - case SVG_FECOLORMATRIX_TYPE_SATURATE: - { - CMValuesCheck(1, "saturate"); - filter = [CIFilter filterWithName:@"CIColorControls"]; - [filter setDefaults]; - float saturation = values()[0]; - if ((saturation < 0.0) || (saturation > 3.0)) - NSLog(@"WARNING: Saturation adjustment: %f outside supported range."); - [filter setValue:[NSNumber numberWithFloat:saturation] forKey:@"inputSaturation"]; - break; - } - case SVG_FECOLORMATRIX_TYPE_HUEROTATE: - { - CMValuesCheck(1, "hueRotate"); - filter = [CIFilter filterWithName:@"CIHueAdjust"]; - [filter setDefaults]; - float radians = deg2rad(values()[0]); - [filter setValue:[NSNumber numberWithFloat:radians] forKey:@"inputAngle"]; - break; - } - case SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA: - { - CMValuesCheck(0, "luminanceToAlpha"); - // FIXME: I bet there is an easy filter to do this. - filter = [CIFilter filterWithName:@"CIColorMatrix"]; - [filter setDefaults]; - CGFloat zero[4] = {0, 0, 0, 0}; - CGFloat alpha[4] = {0.2125f, 0.7154f, 0.0721f, 0}; - [filter setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputRVector"]; - [filter setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputGVector"]; - [filter setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputBVector"]; - [filter setValue:[CIVector vectorWithValues:alpha count:4] forKey:@"inputAVector"]; - [filter setValue:[CIVector vectorWithValues:zero count:4] forKey:@"inputBiasVector"]; - break; - } - default: - LOG_ERROR("Unhandled ColorMatrix type: %i", type()); - return nil; - } - CIImage *inputImage = filterPlatformData->inputImage(this); - FE_QUARTZ_CHECK_INPUT(inputImage); - [filter setValue:inputImage forKey:@"inputImage"]; - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFEComponentTransferCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEComponentTransferCg.mm deleted file mode 100644 index 61515db..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFEComponentTransferCg.mm +++ /dev/null @@ -1,167 +0,0 @@ -/* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEComponentTransfer.h" -#include "SVGFEHelpersCg.h" - -#import "WKComponentMergeFilter.h" -#import "WKIdentityTransferFilter.h" -#import "WKTableTransferFilter.h" -#import "WKDiscreteTransferFilter.h" -#import "WKLinearTransferFilter.h" -#import "WKGammaTransferFilter.h" - -namespace WebCore { - -static CIImage* genImageFromTable(const Vector<float>& table) -{ - int length = table.size(); - int nBytes = length * 4 * sizeof(float); - float* tableStore = (float *) malloc(nBytes); - NSData* bitmapData = [NSData dataWithBytesNoCopy:tableStore length:nBytes]; - for (Vector<float>::const_iterator it = table.begin(); it != table.end(); it++) { - const float value = *it; - *tableStore++ = value; - *tableStore++ = value; - *tableStore++ = value; - *tableStore++ = value; - } - return [CIImage imageWithBitmapData:bitmapData bytesPerRow:nBytes size:CGSizeMake(length, 1) format:kCIFormatRGBAf colorSpace:nil]; -} - -static void setParametersForComponentFunc(CIFilter* filter, const SVGComponentTransferFunction& func, CIVector* channelSelector) -{ - switch (func.type) { - case SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: - return; - case SVG_FECOMPONENTTRANSFER_TYPE_TABLE: - [filter setValue:genImageFromTable(func.tableValues) forKey:@"inputTable"]; - [filter setValue:channelSelector forKey:@"inputSelector"]; - break; - case SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE: - [filter setValue:genImageFromTable(func.tableValues) forKey:@"inputTable"]; - [filter setValue:channelSelector forKey:@"inputSelector"]; - break; - case SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: - [filter setValue:[NSNumber numberWithFloat:func.slope] forKey:@"inputSlope"]; - [filter setValue:[NSNumber numberWithFloat:func.intercept] forKey:@"inputIntercept"]; - break; - case SVG_FECOMPONENTTRANSFER_TYPE_GAMMA: - [filter setValue:[NSNumber numberWithFloat:func.amplitude] forKey:@"inputAmplitude"]; - [filter setValue:[NSNumber numberWithFloat:func.exponent] forKey:@"inputExponent"]; - [filter setValue:[NSNumber numberWithFloat:func.offset] forKey:@"inputOffset"]; - break; - default: - // identity has no args - break; - } -} - -static CIFilter* filterForComponentFunc(const SVGComponentTransferFunction& func) -{ - CIFilter *filter; - switch (func.type) { - case SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: - case SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY: - filter = [CIFilter filterWithName:@"WKIdentityTransfer"]; - break; - case SVG_FECOMPONENTTRANSFER_TYPE_TABLE: - filter = [CIFilter filterWithName:@"WKTableTransferFilter"]; - break; - case SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE: - filter = [CIFilter filterWithName:@"WKDiscreteTransferFilter"]; - break; - case SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: - filter = [CIFilter filterWithName:@"WKLinearTransfer"]; - break; - case SVG_FECOMPONENTTRANSFER_TYPE_GAMMA: - filter = [CIFilter filterWithName:@"WKGammaTransfer"]; - break; - default: - NSLog(@"WARNING: Unknown function type for feComponentTransfer"); - //and to prevent the entire svg from failing as a result - filter = [CIFilter filterWithName:@"WKIdentityTransfer"]; - break; - } - return filter; -} - -static CIFilter* getFilterForFunc(const SVGComponentTransferFunction& func, CIImage* inputImage, CIVector* channelSelector) -{ - CIFilter* filter = filterForComponentFunc(func); - [filter setDefaults]; - - setParametersForComponentFunc(filter, func, channelSelector); - [filter setValue:inputImage forKey:@"inputImage"]; - return filter; -} - -CIFilter* SVGFEComponentTransfer::getFunctionFilter(SVGChannelSelectorType channel, CIImage* inputImage) const -{ - switch (channel) { - case SVG_CHANNEL_R: - return [getFilterForFunc(redFunction(), inputImage, getVectorForChannel(channel)) valueForKey:@"outputImage"]; - case SVG_CHANNEL_G: - return [getFilterForFunc(greenFunction(), inputImage, getVectorForChannel(channel)) valueForKey:@"outputImage"]; - case SVG_CHANNEL_B: - return [getFilterForFunc(blueFunction(), inputImage, getVectorForChannel(channel)) valueForKey:@"outputImage"]; - case SVG_CHANNEL_A: - return [getFilterForFunc(alphaFunction(), inputImage, getVectorForChannel(channel)) valueForKey:@"outputImage"]; - default: - return nil; - } -} - -CIFilter* SVGFEComponentTransfer::getCIFilter(const FloatRect& bbox) const -{ - [WKComponentMergeFilter class]; - [WKIdentityTransferFilter class]; - [WKTableTransferFilter class]; - [WKDiscreteTransferFilter class]; - [WKLinearTransferFilter class]; - [WKGammaTransferFilter class]; - - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - CIFilter* filter = nil; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - filter = [CIFilter filterWithName:@"WKComponentMerge"]; - if (!filter) - return nil; - [filter setDefaults]; - CIImage* inputImage = filterPlatformData->inputImage(this); - FE_QUARTZ_CHECK_INPUT(inputImage); - - [filter setValue:getFunctionFilter(SVG_CHANNEL_R, inputImage) forKey:@"inputFuncR"]; - [filter setValue:getFunctionFilter(SVG_CHANNEL_G, inputImage) forKey:@"inputFuncG"]; - [filter setValue:getFunctionFilter(SVG_CHANNEL_B, inputImage) forKey:@"inputFuncB"]; - [filter setValue:getFunctionFilter(SVG_CHANNEL_A, inputImage) forKey:@"inputFuncA"]; - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFECompositeCg.mm b/WebCore/svg/graphics/filters/cg/SVGFECompositeCg.mm deleted file mode 100644 index 624612c..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFECompositeCg.mm +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEComposite.h" -#include "SVGFEHelpersCg.h" - -#import "WKArithmeticFilter.h" - -namespace WebCore { - -CIFilter* SVGFEComposite::getCIFilter(const FloatRect& bbox) const -{ - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - CIFilter* filter = nil; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - switch (operation()) { - case SVG_FECOMPOSITE_OPERATOR_UNKNOWN: - return nil; - case SVG_FECOMPOSITE_OPERATOR_OVER: - filter = [CIFilter filterWithName:@"CISourceOverCompositing"]; - break; - case SVG_FECOMPOSITE_OPERATOR_IN: - filter = [CIFilter filterWithName:@"CISourceInCompositing"]; - break; - case SVG_FECOMPOSITE_OPERATOR_OUT: - filter = [CIFilter filterWithName:@"CISourceOutCompositing"]; - break; - case SVG_FECOMPOSITE_OPERATOR_ATOP: - filter = [CIFilter filterWithName:@"CISourceAtopCompositing"]; - break; - case SVG_FECOMPOSITE_OPERATOR_XOR: - //FIXME: I'm not sure this is right... - filter = [CIFilter filterWithName:@"CIExclusionBlendMode"]; - break; - case SVG_FECOMPOSITE_OPERATOR_ARITHMETIC: - [WKArithmeticFilter class]; - filter = [CIFilter filterWithName:@"WKArithmeticFilter"]; - break; - } - - [filter setDefaults]; - CIImage* inputImage = filterPlatformData->inputImage(this); - CIImage* backgroundImage = filterPlatformData->imageForName(in2()); - FE_QUARTZ_CHECK_INPUT(inputImage); - FE_QUARTZ_CHECK_INPUT(backgroundImage); - [filter setValue:inputImage forKey:@"inputImage"]; - [filter setValue:backgroundImage forKey:@"inputBackgroundImage"]; - //FIXME: this seems ugly - if (operation() == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) { - [filter setValue:[NSNumber numberWithFloat:k1()] forKey:@"inputK1"]; - [filter setValue:[NSNumber numberWithFloat:k2()] forKey:@"inputK2"]; - [filter setValue:[NSNumber numberWithFloat:k3()] forKey:@"inputK3"]; - [filter setValue:[NSNumber numberWithFloat:k4()] forKey:@"inputK4"]; - } - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFEDiffuseLightingCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEDiffuseLightingCg.mm deleted file mode 100644 index 981b88b..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFEDiffuseLightingCg.mm +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEDiffuseLighting.h" -#include "SVGFEHelpersCg.h" - -#import "WKDiffuseLightingFilter.h" - -namespace WebCore { - -CIFilter* SVGFEDiffuseLighting::getCIFilter(const FloatRect& bbox) const -{ - const SVGLightSource* light = lightSource(); - if (!light) - return nil; - - [WKDiffuseLightingFilter class]; - - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - - CIFilter* filter; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - filter = [CIFilter filterWithName:@"WKDiffuseLighting"]; - if (!filter) - return nil; - - [filter setDefaults]; - CIImage* inputImage = filterPlatformData->inputImage(this); - FE_QUARTZ_CHECK_INPUT(inputImage); - CIFilter* normals = getNormalMap(inputImage, surfaceScale()); - if (!normals) - return nil; - - CIFilter* lightVectors = getLightVectors(normals, light, surfaceScale()); - if (!lightVectors) - return nil; - - [filter setValue:[normals valueForKey:@"outputImage"] forKey:@"inputNormalMap"]; - [filter setValue:[lightVectors valueForKey:@"outputImage"] forKey:@"inputLightVectors"]; - [filter setValue:ciColor(lightingColor()) forKey:@"inputLightingColor"]; - [filter setValue:[NSNumber numberWithFloat:surfaceScale()] forKey:@"inputSurfaceScale"]; - [filter setValue:[NSNumber numberWithFloat:diffuseConstant()] forKey:@"inputDiffuseConstant"]; - [filter setValue:[NSNumber numberWithFloat:kernelUnitLengthX()] forKey:@"inputKernelUnitLengthX"]; - [filter setValue:[NSNumber numberWithFloat:kernelUnitLengthY()] forKey:@"inputKernelUnitLengthY"]; - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFEDisplacementMapCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEDisplacementMapCg.mm deleted file mode 100644 index 9d482e2..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFEDisplacementMapCg.mm +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEDisplacementMap.h" -#include "SVGFEHelpersCg.h" - -#import "WKDisplacementMapFilter.h" - -namespace WebCore { - -CIFilter* SVGFEDisplacementMap::getCIFilter(const FloatRect& bbox) const -{ - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - - CIFilter* filter = nil; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - [WKDisplacementMapFilter class]; - filter = [CIFilter filterWithName:@"WKDisplacementMapFilter"]; - [filter setDefaults]; - CIImage* inputImage = filterPlatformData->inputImage(this); - CIImage* displacementMap = filterPlatformData->imageForName(in2()); - FE_QUARTZ_CHECK_INPUT(inputImage); - FE_QUARTZ_CHECK_INPUT(displacementMap); - [filter setValue:inputImage forKey:@"inputImage"]; - [filter setValue:displacementMap forKey:@"inputDisplacementMap"]; - [filter setValue:getVectorForChannel(xChannelSelector()) forKey:@"inputXChannelSelector"]; - [filter setValue:getVectorForChannel(yChannelSelector()) forKey:@"inputYChannelSelector"]; - [filter setValue:[NSNumber numberWithFloat:scale()] forKey:@"inputScale"]; - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFEFloodCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEFloodCg.mm deleted file mode 100644 index db46f5b..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFEFloodCg.mm +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEFlood.h" - -#include "AffineTransform.h" -#include "SVGFEHelpersCg.h" -#include "CgSupport.h" - -namespace WebCore { - -CIFilter* SVGFEFlood::getCIFilter(const FloatRect& bbox) const -{ - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - CIFilter* filter; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - filter = [CIFilter filterWithName:@"CIConstantColorGenerator"]; - [filter setDefaults]; - CGColorRef color = cgColor(floodColor()); - CGColorRef withAlpha = CGColorCreateCopyWithAlpha(color, CGColorGetAlpha(color) * floodOpacity()); - CIColor* inputColor = [CIColor colorWithCGColor:withAlpha]; - CGColorRelease(color); - CGColorRelease(withAlpha); - [filter setValue:inputColor forKey:@"inputColor"]; - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.h b/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.h index 176abb5..f35e028 100644 --- a/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.h +++ b/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.h @@ -29,16 +29,16 @@ #include <wtf/MathExtras.h> class Color; -class SVGLightSource; +class LightSource; namespace WebCore { -CIVector* getVectorForChannel(SVGChannelSelectorType channel); +CIVector* getVectorForChannel(ChannelSelectorType channel); CIColor* ciColor(const Color& c); // Lighting CIFilter* getPointLightVectors(CIFilter* normals, CIVector* lightPosition, float surfaceScale); -CIFilter* getLightVectors(CIFilter* normals, const SVGLightSource* light, float surfaceScale); +CIFilter* getLightVectors(CIFilter* normals, const LightSource* light, float surfaceScale); CIFilter* getNormalMap(CIImage* bumpMap, float scale); }; diff --git a/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm index 5c7fc31..0f2eb75 100644 --- a/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm +++ b/WebCore/svg/graphics/filters/cg/SVGFEHelpersCg.mm @@ -39,18 +39,18 @@ namespace WebCore { -CIVector* getVectorForChannel(SVGChannelSelectorType channel) +CIVector* getVectorForChannel(ChannelSelectorType channel) { switch (channel) { - case SVG_CHANNEL_UNKNOWN: + case CHANNEL_UNKNOWN: return nil; - case SVG_CHANNEL_R: + case CHANNEL_R: return [CIVector vectorWithX:1.0f Y:0.0f Z:0.0f W:0.0f]; - case SVG_CHANNEL_G: + case CHANNEL_G: return [CIVector vectorWithX:0.0f Y:1.0f Z:0.0f W:0.0f]; - case SVG_CHANNEL_B: + case CHANNEL_B: return [CIVector vectorWithX:0.0f Y:0.0f Z:1.0f W:0.0f]; - case SVG_CHANNEL_A: + case CHANNEL_A: return [CIVector vectorWithX:0.0f Y:0.0f Z:0.0f W:1.0f]; default: return [CIVector vectorWithX:0.0f Y:0.0f Z:0.0f W:0.0f]; @@ -82,7 +82,7 @@ CIFilter* getPointLightVectors(CIFilter* normals, CIVector* lightPosition, float return nil; } -CIFilter* getLightVectors(CIFilter* normals, const SVGLightSource* light, float surfaceScale) +CIFilter* getLightVectors(CIFilter* normals, const LightSource* light, float surfaceScale) { [WKDistantLightFilter class]; [WKPointLightFilter class]; @@ -94,7 +94,7 @@ CIFilter* getLightVectors(CIFilter* normals, const SVGLightSource* light, float switch (light->type()) { case LS_DISTANT: { - const SVGDistantLightSource* dlight = static_cast<const SVGDistantLightSource*>(light); + const DistantLightSource* dlight = static_cast<const DistantLightSource*>(light); filter = [CIFilter filterWithName:@"WKDistantLight"]; if (!filter) @@ -115,12 +115,12 @@ CIFilter* getLightVectors(CIFilter* normals, const SVGLightSource* light, float } case LS_POINT: { - const SVGPointLightSource* plight = static_cast<const SVGPointLightSource*>(light); + const PointLightSource* plight = static_cast<const PointLightSource*>(light); return getPointLightVectors(normals, [CIVector vectorWithX:plight->position().x() Y:plight->position().y() Z:plight->position().z()], surfaceScale); } case LS_SPOT: { - const SVGSpotLightSource* slight = static_cast<const SVGSpotLightSource*>(light); + const SpotLightSource* slight = static_cast<const SpotLightSource*>(light); filter = [CIFilter filterWithName:@"WKSpotLight"]; if (!filter) return nil; diff --git a/WebCore/svg/graphics/filters/cg/SVGFEImageCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEImageCg.mm deleted file mode 100644 index 2f12274..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFEImageCg.mm +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEImage.h" - -#include "Image.h" -#include "SVGFEHelpersCg.h" -#include "CgSupport.h" - -namespace WebCore { - -CIFilter* SVGFEImage::getCIFilter(const FloatRect& bbox) const -{ - if (!cachedImage()) - return nil; - - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - - CIFilter* filter; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - CIImage* ciImage = [CIImage imageWithCGImage:cachedImage()->image()->getCGImageRef()]; - - filter = [CIFilter filterWithName:@"CIAffineTransform"]; - [filter setDefaults]; - [filter setValue:ciImage forKey:@"inputImage"]; - - FloatRect imageRect = cachedImage()->image()->rect(); - - // Flip image into right origin - CGAffineTransform cgTransform = CGAffineTransformMake(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, imageRect.bottom()); - NSAffineTransform* nsTransform = [NSAffineTransform transform]; - [nsTransform setTransformStruct:*((NSAffineTransformStruct *)&cgTransform)]; - [filter setValue:nsTransform forKey:@"inputTransform"]; - - // Calculate crop rect - FE_QUARTZ_MAP_TO_SUBREGION_PREPARE(bbox); - - // Map between the image rectangle and the crop rect - if (!cropRect.isEmpty()) { - CIFilter* scaleImage = [CIFilter filterWithName:@"CIAffineTransform"]; - [scaleImage setDefaults]; - [scaleImage setValue:[filter valueForKey:@"outputImage"] forKey:@"inputImage"]; - - cgTransform = CGAffineTransformMakeMapBetweenRects(CGRect(imageRect), CGRect(cropRect)); - [nsTransform setTransformStruct:*((NSAffineTransformStruct *)&cgTransform)]; - [scaleImage setValue:nsTransform forKey:@"inputTransform"]; - - filter = scaleImage; - } - - // Actually apply cropping - FE_QUARTZ_MAP_TO_SUBREGION_APPLY(cropRect); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFEMergeCg.mm b/WebCore/svg/graphics/filters/cg/SVGFEMergeCg.mm deleted file mode 100644 index 30a981a..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFEMergeCg.mm +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFEMerge.h" -#include "SVGFEHelpersCg.h" - -namespace WebCore { - -CIFilter* SVGFEMerge::getCIFilter(const FloatRect& bbox) const -{ - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - - CIFilter* filter = nil; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - const Vector<String>& inputs = mergeInputs(); - - CIImage* previousOutput = filterPlatformData->inputImage(this); - for (unsigned x = 0; x < inputs.size(); x++) { - CIImage* inputImage = filterPlatformData->imageForName(inputs[x]); - FE_QUARTZ_CHECK_INPUT(inputImage); - FE_QUARTZ_CHECK_INPUT(previousOutput); - filter = [CIFilter filterWithName:@"CISourceOverCompositing"]; - [filter setDefaults]; - [filter setValue:inputImage forKey:@"inputImage"]; - [filter setValue:previousOutput forKey:@"inputBackgroundImage"]; - previousOutput = [filter valueForKey:@"outputImage"]; - } - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/filters/cg/SVGFESpecularLightingCg.mm b/WebCore/svg/graphics/filters/cg/SVGFESpecularLightingCg.mm deleted file mode 100644 index e872c6a..0000000 --- a/WebCore/svg/graphics/filters/cg/SVGFESpecularLightingCg.mm +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - - This file is part of the KDE project - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - aint with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" - -#if ENABLE(SVG) && ENABLE(SVG_FILTERS) -#include "SVGFESpecularLighting.h" -#include "SVGFEHelpersCg.h" - -#import "WKSpecularLightingFilter.h" - -namespace WebCore { - -CIFilter* SVGFESpecularLighting::getCIFilter(const FloatRect& bbox) const -{ - const SVGLightSource* light = lightSource(); - if (!light) - return nil; - - [WKSpecularLightingFilter class]; - - SVGResourceFilter* svgFilter = filter(); - SVGResourceFilterPlatformDataMac* filterPlatformData = static_cast<SVGResourceFilterPlatformDataMac*>(svgFilter->platformData()); - CIFilter* filter; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - filter = [CIFilter filterWithName:@"WKSpecularLighting"]; - [filter setDefaults]; - CIImage* inputImage = filterPlatformData->inputImage(this); - FE_QUARTZ_CHECK_INPUT(inputImage); - CIFilter* normals = getNormalMap(inputImage, surfaceScale()); - if (!normals) - return nil; - CIFilter* lightVectors = getLightVectors(normals, light, surfaceScale()); - if (!lightVectors) - return nil; - [filter setValue:[normals valueForKey:@"outputImage"] forKey:@"inputNormalMap"]; - [filter setValue:[lightVectors valueForKey:@"outputImage"] forKey:@"inputLightVectors"]; - [filter setValue:ciColor(lightingColor()) forKey:@"inputLightingColor"]; - [filter setValue:[NSNumber numberWithFloat:surfaceScale()] forKey:@"inputSurfaceScale"]; - [filter setValue:[NSNumber numberWithFloat:specularConstant()] forKey:@"inputSpecularConstant"]; - [filter setValue:[NSNumber numberWithFloat:specularExponent()] forKey:@"inputSpecularExponent"]; - [filter setValue:[NSNumber numberWithFloat:kernelUnitLengthX()] forKey:@"inputKernelUnitLengthX"]; - [filter setValue:[NSNumber numberWithFloat:kernelUnitLengthY()] forKey:@"inputKernelUnitLengthY"]; - - FE_QUARTZ_MAP_TO_SUBREGION(bbox); - FE_QUARTZ_OUTPUT_RETURN; -} - -} - -#endif // ENABLE(SVG) && ENABLE(SVG_FILTERS) diff --git a/WebCore/svg/graphics/qt/SVGPaintServerGradientQt.cpp b/WebCore/svg/graphics/qt/SVGPaintServerGradientQt.cpp index 7240c49..113f9a7 100644 --- a/WebCore/svg/graphics/qt/SVGPaintServerGradientQt.cpp +++ b/WebCore/svg/graphics/qt/SVGPaintServerGradientQt.cpp @@ -62,42 +62,42 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject QPainterPath* path(context ? context->currentPath() : 0); Q_ASSERT(path); - RenderStyle* renderStyle = object->style(); + const SVGRenderStyle* svgStyle = object->style()->svgStyle(); + RenderStyle* style = object->style(); QGradient gradient = setupGradient(context, object); painter->setPen(Qt::NoPen); painter->setBrush(Qt::NoBrush); - if (spreadMethod() == SPREADMETHOD_REPEAT) + if (spreadMethod() == SpreadMethodRepeat) gradient.setSpread(QGradient::RepeatSpread); - else if (spreadMethod() == SPREADMETHOD_REFLECT) + else if (spreadMethod() == SpreadMethodReflect) gradient.setSpread(QGradient::ReflectSpread); else gradient.setSpread(QGradient::PadSpread); double opacity = 1.0; - if ((type & ApplyToFillTargetType) && renderStyle->svgStyle()->hasFill()) { + if ((type & ApplyToFillTargetType) && svgStyle->hasFill()) { fillColorArray(gradient, gradientStops(), opacity); QBrush brush(gradient); brush.setMatrix(gradientTransform()); painter->setBrush(brush); - context->setFillRule(renderStyle->svgStyle()->fillRule()); + context->setFillRule(svgStyle->fillRule()); } - if ((type & ApplyToStrokeTargetType) && renderStyle->svgStyle()->hasStroke()) { + if ((type & ApplyToStrokeTargetType) && svgStyle->hasStroke()) { fillColorArray(gradient, gradientStops(), opacity); QPen pen; QBrush brush(gradient); brush.setMatrix(gradientTransform()); - - setPenProperties(object, renderStyle, pen); pen.setBrush(brush); - painter->setPen(pen); + + applyStrokeStyleToContext(context, style, object); } return true; diff --git a/WebCore/svg/graphics/qt/SVGPaintServerPatternQt.cpp b/WebCore/svg/graphics/qt/SVGPaintServerPatternQt.cpp index 119e0b0..70ec14c 100644 --- a/WebCore/svg/graphics/qt/SVGPaintServerPatternQt.cpp +++ b/WebCore/svg/graphics/qt/SVGPaintServerPatternQt.cpp @@ -1,7 +1,6 @@ /* Copyright (C) 2006 Nikolas Zimmermann <wildfox@kde.org> - - This file is part of the KDE project + Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -24,54 +23,66 @@ #if ENABLE(SVG) #include "SVGPaintServerPattern.h" +#include "AffineTransform.h" +#include "GraphicsContext.h" +#include "ImageBuffer.h" +#include "Pattern.h" +#include "RenderObject.h" +#include "SVGPatternElement.h" + +#include <QPainter> +#include <QPainterPath> + namespace WebCore { bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const { - // FIXME: Reactivate old pattern code + Q_ASSERT(context); + Q_ASSERT(object); -/* - QPainter* painter(context ? context->platformContext() : 0); - Q_ASSERT(painter); + FloatRect targetRect = object->relativeBBox(false); + m_ownerElement->buildPattern(targetRect); - QPainterPath* _path = static_cast<QPainterPath*>(qtContext->path()); - Q_ASSERT(_path != 0); + if (!tile()) + return false; - RenderStyle* renderStyle = object->style(); + QPainter* painter = context->platformContext(); + QPainterPath* path = context->currentPath(); + RenderStyle* style = object->style(); + const SVGRenderStyle* svgStyle = object->style()->svgStyle(); + + RefPtr<Pattern> pattern = Pattern::create(tile()->image(), true, true); + + context->save(); painter->setPen(Qt::NoPen); painter->setBrush(Qt::NoBrush); - QImage* patternimage = new QImage(tile()->bits(), tile()->width(), tile()->height(), QImage::Format_ARGB32_Premultiplied); - patternimage->setAlphaBuffer(true); - if (type & APPLY_TO_FILL) { - //QColor c = color(); - //c.setAlphaF(style->fillPainter()->opacity() * style->opacity() * opacity()); - KRenderingFillPainter fillPainter = KSVGPainterFactory::fillPainter(renderStyle, object); - QBrush brush(QPixmap::fromImage(*patternimage)); - _path->setFillRule(fillPainter.fillRule() == RULE_EVENODD ? Qt::OddEvenFill : Qt::WindingFill); + + AffineTransform affine; + affine.translate(patternBoundaries().x(), patternBoundaries().y()); + affine.multiply(patternTransform()); + + QBrush brush(pattern->createPlatformPattern(affine)); + if ((type & ApplyToFillTargetType) && svgStyle->hasFill()) { painter->setBrush(brush); + context->setFillRule(svgStyle->fillRule()); } - if (type & APPLY_TO_STROKE) { - //QColor c = color(); - //c.setAlphaF(style->strokePainter()->opacity() * style->opacity() * opacity()); - KRenderingStrokePainter strokePainter = KSVGPainterFactory::strokePainter(renderStyle, object); + if ((type & ApplyToStrokeTargetType) && svgStyle->hasStroke()) { QPen pen; - QBrush brush(QPixmap::fromImage(*patternimage)); - - setPenProperties(strokePainter, pen); pen.setBrush(brush); painter->setPen(pen); + applyStrokeStyleToContext(context, style, object); } - painter->drawPath(*_path); - - delete patternimage; -*/ - return true; } +void SVGPaintServerPattern::teardown(GraphicsContext*& context, const RenderObject*, SVGPaintTargetType, bool) const +{ + context->restore(); +} + } // namespace WebCore #endif diff --git a/WebCore/svg/graphics/qt/SVGPaintServerQt.cpp b/WebCore/svg/graphics/qt/SVGPaintServerQt.cpp index db20347..801201b 100644 --- a/WebCore/svg/graphics/qt/SVGPaintServerQt.cpp +++ b/WebCore/svg/graphics/qt/SVGPaintServerQt.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2006 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2008 Holger Hans Peter Freyther This file is part of the KDE project @@ -33,39 +34,6 @@ namespace WebCore { -void SVGPaintServer::setPenProperties(const RenderObject* object, const RenderStyle* style, QPen& pen) const -{ - pen.setWidthF(SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeWidth(), 1.0)); - - if (style->svgStyle()->capStyle() == ButtCap) - pen.setCapStyle(Qt::FlatCap); - else if (style->svgStyle()->capStyle() == RoundCap) - pen.setCapStyle(Qt::RoundCap); - - if (style->svgStyle()->joinStyle() == MiterJoin) { - pen.setJoinStyle(Qt::MiterJoin); - pen.setMiterLimit((qreal) style->svgStyle()->strokeMiterLimit()); - } else if(style->svgStyle()->joinStyle() == RoundJoin) - pen.setJoinStyle(Qt::RoundJoin); - - const DashArray& dashes = WebCore::dashArrayFromRenderingStyle(style); - double dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0); - - unsigned int dashLength = !dashes.isEmpty() ? dashes.size() : 0; - if(dashLength) { - QVector<qreal> pattern; - unsigned int count = (dashLength % 2) == 0 ? dashLength : dashLength * 2; - - for(unsigned int i = 0; i < count; i++) - pattern.append(dashes[i % dashLength] / (float)pen.widthF()); - - pen.setDashPattern(pattern); - - Q_UNUSED(dashOffset); - // TODO: dash-offset, does/will qt4 API allow it? (Rob) - } -} - void SVGPaintServer::draw(GraphicsContext*& context, const RenderObject* path, SVGPaintTargetType type) const { if (!setup(context, path, type)) @@ -82,7 +50,7 @@ void SVGPaintServer::teardown(GraphicsContext*&, const RenderObject*, SVGPaintTa void SVGPaintServer::renderPath(GraphicsContext*& context, const RenderObject* path, SVGPaintTargetType type) const { - RenderStyle* renderStyle = path->style(); + RenderStyle* renderStyle = path ? path->style(): 0; QPainter* painter(context ? context->platformContext() : 0); Q_ASSERT(painter); @@ -90,10 +58,10 @@ void SVGPaintServer::renderPath(GraphicsContext*& context, const RenderObject* p QPainterPath* painterPath(context ? context->currentPath() : 0); Q_ASSERT(painterPath); - if ((type & ApplyToFillTargetType) && renderStyle->svgStyle()->hasFill()) + if ((type & ApplyToFillTargetType) && (!renderStyle || renderStyle->svgStyle()->hasFill())) painter->fillPath(*painterPath, painter->brush()); - if ((type & ApplyToStrokeTargetType) && renderStyle->svgStyle()->hasStroke()) + if ((type & ApplyToStrokeTargetType) && (!renderStyle || renderStyle->svgStyle()->hasStroke())) painter->strokePath(*painterPath, painter->pen()); } diff --git a/WebCore/svg/graphics/qt/SVGPaintServerSolidQt.cpp b/WebCore/svg/graphics/qt/SVGPaintServerSolidQt.cpp index 7b06a03..e088df2 100644 --- a/WebCore/svg/graphics/qt/SVGPaintServerSolidQt.cpp +++ b/WebCore/svg/graphics/qt/SVGPaintServerSolidQt.cpp @@ -1,5 +1,6 @@ /* Copyright (C) 2006 Nikolas Zimmermann <wildfox@kde.org> + Copyright (C) 2008 Holger Hans Peter Freyther This file is part of the KDE project @@ -36,27 +37,33 @@ bool SVGPaintServerSolid::setup(GraphicsContext*& context, const RenderObject* o QPainter* painter(context ? context->platformContext() : 0); Q_ASSERT(painter); - RenderStyle* renderStyle = object->style(); + const SVGRenderStyle* svgStyle = object->style()->svgStyle(); + RenderStyle* style = object ? object->style() : 0; // TODO? painter->setOpacity(renderStyle->opacity()); QColor c = color(); - if ((type & ApplyToFillTargetType) && renderStyle->svgStyle()->hasFill()) { - c.setAlphaF(renderStyle->svgStyle()->fillOpacity()); + if ((type & ApplyToFillTargetType) && (!style || svgStyle->hasFill())) { + if (style) + c.setAlphaF(svgStyle->fillOpacity()); QBrush brush(c); painter->setBrush(brush); - context->setFillRule(renderStyle->svgStyle()->fillRule()); + + if (style) + context->setFillRule(svgStyle->fillRule()); /* if(isPaintingText()) ... */ } - if ((type & ApplyToStrokeTargetType) && renderStyle->svgStyle()->hasStroke()) { - c.setAlphaF(renderStyle->svgStyle()->strokeOpacity()); + if ((type & ApplyToStrokeTargetType) && (!style || svgStyle->hasStroke())) { + if (style) + c.setAlphaF(svgStyle->strokeOpacity()); QPen pen(c); - setPenProperties(object, renderStyle, pen); painter->setPen(pen); + if (style) + applyStrokeStyleToContext(context, style, object); /* if(isPaintingText()) ... */ } diff --git a/WebCore/svg/graphics/qt/SVGResourceFilterQt.cpp b/WebCore/svg/graphics/qt/SVGResourceFilterQt.cpp index 557f3dd..cbf90cd 100644 --- a/WebCore/svg/graphics/qt/SVGResourceFilterQt.cpp +++ b/WebCore/svg/graphics/qt/SVGResourceFilterQt.cpp @@ -21,24 +21,26 @@ #include "config.h" -#if ENABLE(SVG) && ENABLE(SVG_EXPERIMENTAL_FEATURES) +#if ENABLE(SVG) && ENABLE(SVG_FILTERS) #include "SVGResourceFilter.h" +#include "NotImplemented.h" namespace WebCore { SVGResourceFilterPlatformData* SVGResourceFilter::createPlatformData() { + notImplemented(); return 0; } void SVGResourceFilter::prepareFilter(GraphicsContext*&, const FloatRect&) { - // FIXME: implement me :-) + notImplemented(); } void SVGResourceFilter::applyFilter(GraphicsContext*&, const FloatRect&) { - // FIXME: implement me :-) + notImplemented(); } } // namespace WebCore diff --git a/WebCore/svg/svgattrs.in b/WebCore/svg/svgattrs.in index 8388133..f1bd66b 100644 --- a/WebCore/svg/svgattrs.in +++ b/WebCore/svg/svgattrs.in @@ -1,3 +1,9 @@ +namespace="SVG" +namespaceURI="http://www.w3.org/2000/svg" +guardFactoryWith="ENABLE(SVG)" +attrsNullNamespace="1" +exportStrings="1" + accent-height accumulate additive diff --git a/WebCore/svg/svgtags.in b/WebCore/svg/svgtags.in index 0aa34e5..c9c4fbc 100644 --- a/WebCore/svg/svgtags.in +++ b/WebCore/svg/svgtags.in @@ -1,14 +1,22 @@ +namespace="SVG" +namespaceURI="http://www.w3.org/2000/svg" +guardFactoryWith="ENABLE(SVG)" +exportStrings="1" + a -#if 0 +#if ENABLE_SVG_FONTS altGlyph +#endif +#if 0 altGlyphDef altGlyphItem #endif -#ifdef ENABLE_SVG_ANIMATION +#if ENABLE_SVG_ANIMATION animate animateColor animateMotion animateTransform +set #endif circle clipPath @@ -22,7 +30,7 @@ definition_src defs desc ellipse -#ifdef ENABLE_SVG_FILTERS +#if ENABLE_SVG_FILTERS feBlend feColorMatrix feComponentTransfer @@ -53,7 +61,7 @@ feTile feTurbulence filter #endif -#ifdef ENABLE_SVG_FONTS +#if ENABLE_SVG_FONTS font font_face font_face_format @@ -61,16 +69,18 @@ font_face_name font_face_src font_face_uri #endif -#ifdef ENABLE_SVG_FOREIGN_OBJECT +#if ENABLE_SVG_FOREIGN_OBJECT foreignObject #endif g -#ifdef ENABLE_SVG_FONTS +#if ENABLE_SVG_FONTS glyph #endif #if 0 glyphRef -hkern +#endif +#if ENABLE_SVG_FONTS +hkern interfaceName=HKernElement #endif image line @@ -78,10 +88,10 @@ linearGradient marker mask metadata -#ifdef ENABLE_SVG_FONTS +#if ENABLE_SVG_FONTS missing_glyph #endif -mpath +mpath interfaceName=MPathElement path pattern polygon @@ -89,19 +99,18 @@ polyline radialGradient rect script -set stop style -svg +svg interfaceName=SVGElement switch symbol text textPath title -tref -tspan +tref interfaceName=TRefElement +tspan interfaceName=TSpanElement use view #if 0 -vkern +vkern interfaceName=VKernElement #endif diff --git a/WebCore/svg/xlinkattrs.in b/WebCore/svg/xlinkattrs.in index 851af1a..f91fb97 100644 --- a/WebCore/svg/xlinkattrs.in +++ b/WebCore/svg/xlinkattrs.in @@ -1,3 +1,7 @@ +namespace="XLink" +namespaceURI="http://www.w3.org/1999/xlink" +exportStrings="1" + actuate arcrole href |