~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/svg/SVGTextPathElement.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
 
3
 * Copyright (C) 2010 Rob Buis <rwlbuis@gmail.com>
 
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
#if ENABLE(SVG)
 
24
#include "SVGTextPathElement.h"
 
25
 
 
26
#include "Attribute.h"
 
27
#include "NodeRenderingContext.h"
 
28
#include "RenderSVGResource.h"
 
29
#include "RenderSVGTextPath.h"
 
30
#include "SVGElementInstance.h"
 
31
#include "SVGNames.h"
 
32
 
 
33
namespace WebCore {
 
34
 
 
35
// Animated property definitions
 
36
DEFINE_ANIMATED_LENGTH(SVGTextPathElement, SVGNames::startOffsetAttr, StartOffset, startOffset)
 
37
DEFINE_ANIMATED_ENUMERATION(SVGTextPathElement, SVGNames::methodAttr, Method, method, SVGTextPathMethodType)
 
38
DEFINE_ANIMATED_ENUMERATION(SVGTextPathElement, SVGNames::spacingAttr, Spacing, spacing, SVGTextPathSpacingType)
 
39
DEFINE_ANIMATED_STRING(SVGTextPathElement, XLinkNames::hrefAttr, Href, href)
 
40
 
 
41
BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextPathElement)
 
42
    REGISTER_LOCAL_ANIMATED_PROPERTY(startOffset)
 
43
    REGISTER_LOCAL_ANIMATED_PROPERTY(method)
 
44
    REGISTER_LOCAL_ANIMATED_PROPERTY(spacing)
 
45
    REGISTER_LOCAL_ANIMATED_PROPERTY(href)
 
46
    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextContentElement)
 
47
END_REGISTER_ANIMATED_PROPERTIES
 
48
 
 
49
inline SVGTextPathElement::SVGTextPathElement(const QualifiedName& tagName, Document* document)
 
50
    : SVGTextContentElement(tagName, document)
 
51
    , m_startOffset(LengthModeOther)
 
52
    , m_method(SVGTextPathMethodAlign)
 
53
    , m_spacing(SVGTextPathSpacingExact)
 
54
{
 
55
    ASSERT(hasTagName(SVGNames::textPathTag));
 
56
    registerAnimatedPropertiesForSVGTextPathElement();
 
57
}
 
58
 
 
59
PassRefPtr<SVGTextPathElement> SVGTextPathElement::create(const QualifiedName& tagName, Document* document)
 
60
{
 
61
    return adoptRef(new SVGTextPathElement(tagName, document));
 
62
}
 
63
 
 
64
SVGTextPathElement::~SVGTextPathElement()
 
65
{
 
66
    clearResourceReferences();
 
67
}
 
68
 
 
69
void SVGTextPathElement::clearResourceReferences()
 
70
{
 
71
    ASSERT(document());
 
72
    document()->accessSVGExtensions()->removeAllTargetReferencesForElement(this);
 
73
}
 
74
 
 
75
bool SVGTextPathElement::isSupportedAttribute(const QualifiedName& attrName)
 
76
{
 
77
    DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
 
78
    if (supportedAttributes.isEmpty()) {
 
79
        SVGURIReference::addSupportedAttributes(supportedAttributes);
 
80
        supportedAttributes.add(SVGNames::startOffsetAttr);
 
81
        supportedAttributes.add(SVGNames::methodAttr);
 
82
        supportedAttributes.add(SVGNames::spacingAttr);
 
83
    }
 
84
    return supportedAttributes.contains<QualifiedName, SVGAttributeHashTranslator>(attrName);
 
85
}
 
86
 
 
87
void SVGTextPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 
88
{
 
89
    SVGParsingError parseError = NoError;
 
90
 
 
91
    if (!isSupportedAttribute(name))
 
92
        SVGTextContentElement::parseAttribute(name, value);
 
93
    else if (name == SVGNames::startOffsetAttr)
 
94
        setStartOffsetBaseValue(SVGLength::construct(LengthModeOther, value, parseError));
 
95
    else if (name == SVGNames::methodAttr) {
 
96
        SVGTextPathMethodType propertyValue = SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
 
97
        if (propertyValue > 0)
 
98
            setMethodBaseValue(propertyValue);
 
99
    } else if (name == SVGNames::spacingAttr) {
 
100
        SVGTextPathSpacingType propertyValue = SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value);
 
101
        if (propertyValue > 0)
 
102
            setSpacingBaseValue(propertyValue);
 
103
    } else if (SVGURIReference::parseAttribute(name, value)) {
 
104
    } else
 
105
        ASSERT_NOT_REACHED();
 
106
 
 
107
    reportAttributeParsingError(parseError, name, value);
 
108
}
 
109
 
 
110
void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName)
 
111
{
 
112
    if (!isSupportedAttribute(attrName)) {
 
113
        SVGTextContentElement::svgAttributeChanged(attrName);
 
114
        return;
 
115
    }
 
116
 
 
117
    SVGElementInstance::InvalidationGuard invalidationGuard(this);
 
118
 
 
119
    if (SVGURIReference::isKnownAttribute(attrName)) {
 
120
        buildPendingResource();
 
121
        return;
 
122
    }
 
123
 
 
124
    if (attrName == SVGNames::startOffsetAttr)
 
125
        updateRelativeLengthsInformation();
 
126
 
 
127
    if (RenderObject* object = renderer())
 
128
        RenderSVGResource::markForLayoutAndParentResourceInvalidation(object);
 
129
}
 
130
 
 
131
RenderObject* SVGTextPathElement::createRenderer(RenderArena* arena, RenderStyle*)
 
132
{
 
133
    return new (arena) RenderSVGTextPath(this);
 
134
}
 
135
 
 
136
bool SVGTextPathElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
 
137
{
 
138
    if (childContext.node()->isTextNode()
 
139
        || childContext.node()->hasTagName(SVGNames::aTag)
 
140
        || childContext.node()->hasTagName(SVGNames::trefTag)
 
141
        || childContext.node()->hasTagName(SVGNames::tspanTag))
 
142
        return true;
 
143
 
 
144
    return false;
 
145
}
 
146
 
 
147
bool SVGTextPathElement::rendererIsNeeded(const NodeRenderingContext& context)
 
148
{
 
149
    if (parentNode()
 
150
        && (parentNode()->hasTagName(SVGNames::aTag)
 
151
            || parentNode()->hasTagName(SVGNames::textTag)))
 
152
        return StyledElement::rendererIsNeeded(context);
 
153
 
 
154
    return false;
 
155
}
 
156
 
 
157
void SVGTextPathElement::buildPendingResource()
 
158
{
 
159
    clearResourceReferences();
 
160
    if (!inDocument())
 
161
        return;
 
162
 
 
163
    String id;
 
164
    Element* target = SVGURIReference::targetElementFromIRIString(href(), document(), &id);
 
165
    if (!target) {
 
166
        if (hasPendingResources() || id.isEmpty())
 
167
            return;
 
168
 
 
169
        document()->accessSVGExtensions()->addPendingResource(id, this);
 
170
        ASSERT(hasPendingResources());
 
171
    } else if (target->isSVGElement()) {
 
172
        // Register us with the target in the dependencies map. Any change of hrefElement
 
173
        // that leads to relayout/repainting now informs us, so we can react to it.
 
174
        document()->accessSVGExtensions()->addElementReferencingTarget(this, static_cast<SVGElement*>(target));
 
175
    }
 
176
}
 
177
 
 
178
Node::InsertionNotificationRequest SVGTextPathElement::insertedInto(ContainerNode* rootParent)
 
179
{
 
180
    SVGTextContentElement::insertedInto(rootParent);
 
181
    buildPendingResource();
 
182
    return InsertionDone;
 
183
}
 
184
 
 
185
void SVGTextPathElement::removedFrom(ContainerNode* rootParent)
 
186
{
 
187
    SVGTextContentElement::removedFrom(rootParent);
 
188
    if (rootParent->inDocument())
 
189
        clearResourceReferences();
 
190
}
 
191
 
 
192
bool SVGTextPathElement::selfHasRelativeLengths() const
 
193
{
 
194
    return startOffset().isRelative()
 
195
        || SVGTextContentElement::selfHasRelativeLengths();
 
196
}
 
197
 
 
198
}
 
199
 
 
200
#endif // ENABLE(SVG)