2 Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3 Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
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.
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.
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.
22 #include "wtf/Platform.h"
25 #include "SVGGlyphElement.h"
27 #include "SVGFontElement.h"
28 //FIXME khtml #include "SVGFontFaceElement.h"
29 #include "SVGFontData.h"
31 #include "SVGParserUtilities.h"
32 //FIXME khtml #include "SimpleFontData.h"
33 //FIXME khtml #include "XMLNames.h"
37 using namespace SVGNames
;
39 SVGGlyphElement::SVGGlyphElement(const QualifiedName
& tagName
, Document
* doc
)
40 : SVGStyledElement(tagName
, doc
)
44 SVGGlyphElement::~SVGGlyphElement()
48 void SVGGlyphElement::insertedIntoDocument()
50 Node
* fontNode
= parentNode();
51 if (fontNode
&& fontNode
->hasTagName(fontTag
)) {
52 if (SVGFontElement
* element
= static_cast<SVGFontElement
*>(fontNode
))
53 element
->invalidateGlyphCache();
55 SVGStyledElement::insertedIntoDocument();
58 void SVGGlyphElement::removedFromDocument()
60 Node
* fontNode
= parentNode();
61 if (fontNode
&& fontNode
->hasTagName(fontTag
)) {
62 if (SVGFontElement
* element
= static_cast<SVGFontElement
*>(fontNode
))
63 element
->invalidateGlyphCache();
65 SVGStyledElement::removedFromDocument();
68 static inline SVGGlyphIdentifier::ArabicForm
parseArabicForm(const AtomicString
& value
)
70 if (value
== "medial")
71 return SVGGlyphIdentifier::Medial
;
72 else if (value
== "terminal")
73 return SVGGlyphIdentifier::Terminal
;
74 else if (value
== "isolated")
75 return SVGGlyphIdentifier::Isolated
;
76 else if (value
== "initial")
77 return SVGGlyphIdentifier::Initial
;
79 return SVGGlyphIdentifier::None
;
82 static inline SVGGlyphIdentifier::Orientation
parseOrientation(const AtomicString
& value
)
85 return SVGGlyphIdentifier::Horizontal
;
86 else if (value
== "v")
87 return SVGGlyphIdentifier::Vertical
;
89 return SVGGlyphIdentifier::Both
;
92 static inline Path
parsePathData(const AtomicString
& value
)
95 pathFromSVGData(result
, value
);
100 void SVGGlyphElement::inheritUnspecifiedAttributes(SVGGlyphIdentifier
& identifier
, const SVGFontData
* svgFontData
)
102 if (identifier
.horizontalAdvanceX
== SVGGlyphIdentifier::inheritedValue())
103 identifier
.horizontalAdvanceX
= svgFontData
->horizontalAdvanceX();
105 if (identifier
.verticalOriginX
== SVGGlyphIdentifier::inheritedValue())
106 identifier
.verticalOriginX
= svgFontData
->verticalOriginX();
108 if (identifier
.verticalOriginY
== SVGGlyphIdentifier::inheritedValue())
109 identifier
.verticalOriginY
= svgFontData
->verticalOriginY();
111 if (identifier
.verticalAdvanceY
== SVGGlyphIdentifier::inheritedValue())
112 identifier
.verticalAdvanceY
= svgFontData
->verticalAdvanceY();
115 static inline float parseSVGGlyphAttribute(const SVGElement
* element
, const WebCore::QualifiedName
& name
)
117 AtomicString
value(element
->getAttribute(name
));
119 return SVGGlyphIdentifier::inheritedValue();
121 return value
.string().string().toFloat();
124 SVGGlyphIdentifier
SVGGlyphElement::buildGenericGlyphIdentifier(const SVGElement
* element
)
126 SVGGlyphIdentifier identifier
;
127 identifier
.pathData
= parsePathData(element
->getAttribute(dAttr
));
129 // Spec: The horizontal advance after rendering the glyph in horizontal orientation.
130 // If the attribute is not specified, the effect is as if the attribute were set to the
131 // value of the font's horiz-adv-x attribute. Glyph widths are required to be non-negative,
132 // even if the glyph is typically rendered right-to-left, as in Hebrew and Arabic scripts.
133 identifier
.horizontalAdvanceX
= parseSVGGlyphAttribute(element
, horiz_adv_xAttr
);
135 // Spec: The X-coordinate in the font coordinate system of the origin of the glyph to be
136 // used when drawing vertically oriented text. If the attribute is not specified, the effect
137 // is as if the attribute were set to the value of the font's vert-origin-x attribute.
138 identifier
.verticalOriginX
= parseSVGGlyphAttribute(element
, vert_origin_xAttr
);
140 // Spec: The Y-coordinate in the font coordinate system of the origin of a glyph to be
141 // used when drawing vertically oriented text. If the attribute is not specified, the effect
142 // is as if the attribute were set to the value of the font's vert-origin-y attribute.
143 identifier
.verticalOriginY
= parseSVGGlyphAttribute(element
, vert_origin_yAttr
);
145 // Spec: The vertical advance after rendering a glyph in vertical orientation.
146 // If the attribute is not specified, the effect is as if the attribute were set to the
147 // value of the font's vert-adv-y attribute.
148 identifier
.verticalAdvanceY
= parseSVGGlyphAttribute(element
, vert_adv_yAttr
);
153 SVGGlyphIdentifier
SVGGlyphElement::buildGlyphIdentifier() const
155 SVGGlyphIdentifier
identifier(buildGenericGlyphIdentifier(this));
156 identifier
.glyphName
= getAttribute(glyph_nameAttr
);
157 identifier
.orientation
= parseOrientation(getAttribute(orientationAttr
));
158 identifier
.arabicForm
= parseArabicForm(getAttribute(arabic_formAttr
));
160 String language
= getAttribute(langAttr
);
161 if (!language
.isEmpty())
162 identifier
.languages
= parseDelimitedString(language
, ',');
169 #endif // ENABLE(SVG_FONTS)