File indexing completed on 2024-04-28 15:24:34
0001 /* 0002 Copyright (C) 2007 Eric Seidel <eric@webkit.org> 0003 Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "wtf/Platform.h" 0022 0023 #if ENABLE(SVG_FONTS) 0024 #include "SVGGlyphElement.h" 0025 0026 #include "SVGFontElement.h" 0027 //FIXME khtml #include "SVGFontFaceElement.h" 0028 #include "SVGFontData.h" 0029 #include "SVGNames.h" 0030 #include "SVGParserUtilities.h" 0031 //FIXME khtml #include "SimpleFontData.h" 0032 0033 namespace WebCore 0034 { 0035 0036 using namespace SVGNames; 0037 0038 SVGGlyphElement::SVGGlyphElement(const QualifiedName &tagName, Document *doc) 0039 : SVGStyledElement(tagName, doc) 0040 { 0041 } 0042 0043 SVGGlyphElement::~SVGGlyphElement() 0044 { 0045 } 0046 0047 void SVGGlyphElement::insertedIntoDocument() 0048 { 0049 Node *fontNode = parentNode(); 0050 if (fontNode && fontNode->hasTagName(fontTag)) { 0051 if (SVGFontElement *element = static_cast<SVGFontElement *>(fontNode)) { 0052 element->invalidateGlyphCache(); 0053 } 0054 } 0055 SVGStyledElement::insertedIntoDocument(); 0056 } 0057 0058 void SVGGlyphElement::removedFromDocument() 0059 { 0060 Node *fontNode = parentNode(); 0061 if (fontNode && fontNode->hasTagName(fontTag)) { 0062 if (SVGFontElement *element = static_cast<SVGFontElement *>(fontNode)) { 0063 element->invalidateGlyphCache(); 0064 } 0065 } 0066 SVGStyledElement::removedFromDocument(); 0067 } 0068 0069 static inline SVGGlyphIdentifier::ArabicForm parseArabicForm(const AtomicString &value) 0070 { 0071 if (value == "medial") { 0072 return SVGGlyphIdentifier::Medial; 0073 } else if (value == "terminal") { 0074 return SVGGlyphIdentifier::Terminal; 0075 } else if (value == "isolated") { 0076 return SVGGlyphIdentifier::Isolated; 0077 } else if (value == "initial") { 0078 return SVGGlyphIdentifier::Initial; 0079 } 0080 0081 return SVGGlyphIdentifier::None; 0082 } 0083 0084 static inline SVGGlyphIdentifier::Orientation parseOrientation(const AtomicString &value) 0085 { 0086 if (value == "h") { 0087 return SVGGlyphIdentifier::Horizontal; 0088 } else if (value == "v") { 0089 return SVGGlyphIdentifier::Vertical; 0090 } 0091 0092 return SVGGlyphIdentifier::Both; 0093 } 0094 0095 static inline Path parsePathData(const AtomicString &value) 0096 { 0097 Path result; 0098 pathFromSVGData(result, value); 0099 0100 return result; 0101 } 0102 0103 void SVGGlyphElement::inheritUnspecifiedAttributes(SVGGlyphIdentifier &identifier, const SVGFontData *svgFontData) 0104 { 0105 if (identifier.horizontalAdvanceX == SVGGlyphIdentifier::inheritedValue()) { 0106 identifier.horizontalAdvanceX = svgFontData->horizontalAdvanceX(); 0107 } 0108 0109 if (identifier.verticalOriginX == SVGGlyphIdentifier::inheritedValue()) { 0110 identifier.verticalOriginX = svgFontData->verticalOriginX(); 0111 } 0112 0113 if (identifier.verticalOriginY == SVGGlyphIdentifier::inheritedValue()) { 0114 identifier.verticalOriginY = svgFontData->verticalOriginY(); 0115 } 0116 0117 if (identifier.verticalAdvanceY == SVGGlyphIdentifier::inheritedValue()) { 0118 identifier.verticalAdvanceY = svgFontData->verticalAdvanceY(); 0119 } 0120 } 0121 0122 static inline float parseSVGGlyphAttribute(const SVGElement *element, const WebCore::QualifiedName &name) 0123 { 0124 AtomicString value(element->getAttribute(name)); 0125 if (value.isEmpty()) { 0126 return SVGGlyphIdentifier::inheritedValue(); 0127 } 0128 0129 return value.string().string().toFloat(); 0130 } 0131 0132 SVGGlyphIdentifier SVGGlyphElement::buildGenericGlyphIdentifier(const SVGElement *element) 0133 { 0134 SVGGlyphIdentifier identifier; 0135 identifier.pathData = parsePathData(element->getAttribute(dAttr)); 0136 0137 // Spec: The horizontal advance after rendering the glyph in horizontal orientation. 0138 // If the attribute is not specified, the effect is as if the attribute were set to the 0139 // value of the font's horiz-adv-x attribute. Glyph widths are required to be non-negative, 0140 // even if the glyph is typically rendered right-to-left, as in Hebrew and Arabic scripts. 0141 identifier.horizontalAdvanceX = parseSVGGlyphAttribute(element, horiz_adv_xAttr); 0142 0143 // Spec: The X-coordinate in the font coordinate system of the origin of the glyph to be 0144 // used when drawing vertically oriented text. If the attribute is not specified, the effect 0145 // is as if the attribute were set to the value of the font's vert-origin-x attribute. 0146 identifier.verticalOriginX = parseSVGGlyphAttribute(element, vert_origin_xAttr); 0147 0148 // Spec: The Y-coordinate in the font coordinate system of the origin of a glyph to be 0149 // used when drawing vertically oriented text. If the attribute is not specified, the effect 0150 // is as if the attribute were set to the value of the font's vert-origin-y attribute. 0151 identifier.verticalOriginY = parseSVGGlyphAttribute(element, vert_origin_yAttr); 0152 0153 // Spec: The vertical advance after rendering a glyph in vertical orientation. 0154 // If the attribute is not specified, the effect is as if the attribute were set to the 0155 // value of the font's vert-adv-y attribute. 0156 identifier.verticalAdvanceY = parseSVGGlyphAttribute(element, vert_adv_yAttr); 0157 0158 return identifier; 0159 } 0160 0161 SVGGlyphIdentifier SVGGlyphElement::buildGlyphIdentifier() const 0162 { 0163 SVGGlyphIdentifier identifier(buildGenericGlyphIdentifier(this)); 0164 identifier.glyphName = getAttribute(glyph_nameAttr); 0165 identifier.orientation = parseOrientation(getAttribute(orientationAttr)); 0166 identifier.arabicForm = parseArabicForm(getAttribute(arabic_formAttr)); 0167 0168 String language = getAttribute(langAttr); 0169 if (!language.isEmpty()) { 0170 identifier.languages = parseDelimitedString(language, ','); 0171 } 0172 0173 return identifier; 0174 } 0175 0176 } 0177 0178 #endif // ENABLE(SVG_FONTS)