1/*
2 * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21#include "config.h"
22
23#include "core/svg/SVGStopElement.h"
24
25#include "SVGNames.h"
26#include "core/rendering/svg/RenderSVGGradientStop.h"
27#include "core/rendering/svg/RenderSVGResource.h"
28#include "core/svg/SVGElementInstance.h"
29
30namespace WebCore {
31
32// Animated property definitions
33DEFINE_ANIMATED_NUMBER(SVGStopElement, SVGNames::offsetAttr, Offset, offset)
34
35BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGStopElement)
36    REGISTER_LOCAL_ANIMATED_PROPERTY(offset)
37    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
38END_REGISTER_ANIMATED_PROPERTIES
39
40inline SVGStopElement::SVGStopElement(const QualifiedName& tagName, Document* document)
41    : SVGElement(tagName, document)
42    , m_offset(0)
43{
44    ASSERT(hasTagName(SVGNames::stopTag));
45    ScriptWrappable::init(this);
46    registerAnimatedPropertiesForSVGStopElement();
47}
48
49PassRefPtr<SVGStopElement> SVGStopElement::create(const QualifiedName& tagName, Document* document)
50{
51    return adoptRef(new SVGStopElement(tagName, document));
52}
53
54bool SVGStopElement::isSupportedAttribute(const QualifiedName& attrName)
55{
56    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
57    if (supportedAttributes.isEmpty())
58        supportedAttributes.add(SVGNames::offsetAttr);
59    return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
60}
61
62void SVGStopElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
63{
64    if (!isSupportedAttribute(name)) {
65        SVGElement::parseAttribute(name, value);
66        return;
67    }
68
69    if (name == SVGNames::offsetAttr) {
70        if (value.endsWith('%'))
71            setOffsetBaseValue(value.string().left(value.length() - 1).toFloat() / 100.0f);
72        else
73            setOffsetBaseValue(value.toFloat());
74        return;
75    }
76
77    ASSERT_NOT_REACHED();
78}
79
80void SVGStopElement::svgAttributeChanged(const QualifiedName& attrName)
81{
82    if (!isSupportedAttribute(attrName)) {
83        SVGElement::svgAttributeChanged(attrName);
84        return;
85    }
86
87    SVGElementInstance::InvalidationGuard invalidationGuard(this);
88
89    if (!renderer())
90        return;
91
92    if (attrName == SVGNames::offsetAttr) {
93        RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
94        return;
95    }
96
97    ASSERT_NOT_REACHED();
98}
99
100RenderObject* SVGStopElement::createRenderer(RenderStyle*)
101{
102    return new RenderSVGGradientStop(this);
103}
104
105bool SVGStopElement::rendererIsNeeded(const NodeRenderingContext&)
106{
107    return true;
108}
109
110Color SVGStopElement::stopColorIncludingOpacity() const
111{
112    RenderStyle* style = renderer() ? renderer()->style() : 0;
113    // FIXME: This check for null style exists to address Bug WK 90814, a rare crash condition in
114    // which the renderer or style is null. This entire class is scheduled for removal (Bug WK 86941)
115    // and we will tolerate this null check until then.
116    if (!style || !style->svgStyle())
117        return Color(Color::transparent); // Transparent black.
118
119    const SVGRenderStyle* svgStyle = style->svgStyle();
120    return colorWithOverrideAlpha(svgStyle->stopColor().rgb(), svgStyle->stopOpacity());
121}
122
123}
124