1/*
2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org>
4 * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
5 * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#include "config.h"
24#include "SVGTextPositioningElement.h"
25
26#include "RenderSVGInline.h"
27#include "RenderSVGResource.h"
28#include "RenderSVGText.h"
29#include "SVGAltGlyphElement.h"
30#include "SVGNames.h"
31#include "SVGTRefElement.h"
32#include "SVGTSpanElement.h"
33#include "SVGTextElement.h"
34#include <wtf/IsoMallocInlines.h>
35
36namespace WebCore {
37
38WTF_MAKE_ISO_ALLOCATED_IMPL(SVGTextPositioningElement);
39
40SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document& document)
41 : SVGTextContentElement(tagName, document)
42{
43 static std::once_flag onceFlag;
44 std::call_once(onceFlag, [] {
45 PropertyRegistry::registerProperty<SVGNames::xAttr, &SVGTextPositioningElement::m_x>();
46 PropertyRegistry::registerProperty<SVGNames::yAttr, &SVGTextPositioningElement::m_y>();
47 PropertyRegistry::registerProperty<SVGNames::dxAttr, &SVGTextPositioningElement::m_dx>();
48 PropertyRegistry::registerProperty<SVGNames::dyAttr, &SVGTextPositioningElement::m_dy>();
49 PropertyRegistry::registerProperty<SVGNames::rotateAttr, &SVGTextPositioningElement::m_rotate>();
50 });
51}
52
53void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
54{
55 if (name == SVGNames::xAttr) {
56 m_x->baseVal()->parse(value);
57 return;
58 }
59
60 if (name == SVGNames::yAttr) {
61 m_y->baseVal()->parse(value);
62 return;
63 }
64
65 if (name == SVGNames::dxAttr) {
66 m_dx->baseVal()->parse(value);
67 return;
68 }
69
70 if (name == SVGNames::dyAttr) {
71 m_dy->baseVal()->parse(value);
72 return;
73 }
74
75 if (name == SVGNames::rotateAttr) {
76 m_rotate->baseVal()->parse(value);
77 return;
78 }
79
80 SVGTextContentElement::parseAttribute(name, value);
81}
82
83void SVGTextPositioningElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
84{
85 if (name == SVGNames::xAttr || name == SVGNames::yAttr)
86 return;
87 SVGTextContentElement::collectStyleForPresentationAttribute(name, value, style);
88}
89
90bool SVGTextPositioningElement::isPresentationAttribute(const QualifiedName& name) const
91{
92 if (name == SVGNames::xAttr || name == SVGNames::yAttr)
93 return false;
94 return SVGTextContentElement::isPresentationAttribute(name);
95}
96
97void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName)
98{
99 if (PropertyRegistry::isKnownAttribute(attrName)) {
100 InstanceInvalidationGuard guard(*this);
101
102 if (attrName != SVGNames::rotateAttr)
103 updateRelativeLengthsInformation();
104
105 if (auto renderer = this->renderer()) {
106 if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*renderer))
107 textAncestor->setNeedsPositioningValuesUpdate();
108 RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
109 }
110
111 return;
112 }
113
114 SVGTextContentElement::svgAttributeChanged(attrName);
115}
116
117SVGTextPositioningElement* SVGTextPositioningElement::elementFromRenderer(RenderBoxModelObject& renderer)
118{
119 if (!is<RenderSVGText>(renderer) && !is<RenderSVGInline>(renderer))
120 return nullptr;
121
122 ASSERT(renderer.element());
123 SVGElement& element = downcast<SVGElement>(*renderer.element());
124
125 if (!is<SVGTextElement>(element)
126 && !is<SVGTSpanElement>(element)
127#if ENABLE(SVG_FONTS)
128 && !is<SVGAltGlyphElement>(element)
129#endif
130 && !is<SVGTRefElement>(element))
131 return nullptr;
132
133 // FIXME: This should use downcast<>().
134 return &static_cast<SVGTextPositioningElement&>(element);
135}
136
137}
138