• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KHTML

  • sources
  • kde-4.12
  • kdelibs
  • khtml
  • svg
SVGFontFaceElement.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3  Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@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 #if ENABLE(SVG_FONTS)
24 #include "SVGFontFaceElement.h"
25 #include "CString.h"
26 #include "CSSFontFaceRule.h"
27 #include "CSSFontFaceSrcValue.h"
28 #include "CSSParser.h"
29 #include "CSSProperty.h"
30 #include "CSSPropertyNames.h"
31 #include "CSSStyleSelector.h"
32 #include "CSSStyleSheet.h"
33 #include "CSSValueKeywords.h"
34 #include "CSSValueList.h"
35 #include "FontCache.h"
36 #include "SimpleFontData.h"
37 #include "SVGDefinitionSrcElement.h"
38 #include "SVGFontElement.h"
39 #include "SVGFontFaceSrcElement.h"
40 #include "SVGGlyphElement.h"
41 #include "SVGNames.h"
42 
43 #include <math.h>
44 
45 namespace WebCore {
46 
47 using namespace SVGNames;
48 
49 SVGFontFaceElement::SVGFontFaceElement(const QualifiedName& tagName, Document* doc)
50  : SVGElement(tagName, doc)
51  , m_fontFaceRule(new CSSFontFaceRule(0))
52  , m_styleDeclaration(new CSSMutableStyleDeclaration)
53 {
54  m_styleDeclaration->setParent(document()->mappedElementSheet());
55  m_styleDeclaration->setStrictParsing(true);
56  m_fontFaceRule->setDeclaration(m_styleDeclaration.get());
57  document()->mappedElementSheet()->append(m_fontFaceRule);
58 }
59 
60 SVGFontFaceElement::~SVGFontFaceElement()
61 {
62 }
63 
64 static void mapAttributeToCSSProperty(HashMap<AtomicStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName)
65 {
66  int propertyId = cssPropertyID(attrName.localName());
67  ASSERT(propertyId > 0);
68  propertyNameToIdMap->set(attrName.localName().impl(), propertyId);
69 }
70 
71 static int cssPropertyIdForSVGAttributeName(const QualifiedName& attrName)
72 {
73  if (!attrName.namespaceURI().isNull())
74  return 0;
75 
76  static HashMap<AtomicStringImpl*, int>* propertyNameToIdMap = 0;
77  if (!propertyNameToIdMap) {
78  propertyNameToIdMap = new HashMap<AtomicStringImpl*, int>;
79  // This is a list of all @font-face CSS properties which are exposed as SVG XML attributes
80  // Those commented out are not yet supported by WebCore's style system
81  //mapAttributeToCSSProperty(propertyNameToIdMap, accent_heightAttr);
82  //mapAttributeToCSSProperty(propertyNameToIdMap, alphabeticAttr);
83  //mapAttributeToCSSProperty(propertyNameToIdMap, ascentAttr);
84  //mapAttributeToCSSProperty(propertyNameToIdMap, bboxAttr);
85  //mapAttributeToCSSProperty(propertyNameToIdMap, cap_heightAttr);
86  //mapAttributeToCSSProperty(propertyNameToIdMap, descentAttr);
87  mapAttributeToCSSProperty(propertyNameToIdMap, font_familyAttr);
88  mapAttributeToCSSProperty(propertyNameToIdMap, font_sizeAttr);
89  mapAttributeToCSSProperty(propertyNameToIdMap, font_stretchAttr);
90  mapAttributeToCSSProperty(propertyNameToIdMap, font_styleAttr);
91  mapAttributeToCSSProperty(propertyNameToIdMap, font_variantAttr);
92  mapAttributeToCSSProperty(propertyNameToIdMap, font_weightAttr);
93  //mapAttributeToCSSProperty(propertyNameToIdMap, hangingAttr);
94  //mapAttributeToCSSProperty(propertyNameToIdMap, ideographicAttr);
95  //mapAttributeToCSSProperty(propertyNameToIdMap, mathematicalAttr);
96  //mapAttributeToCSSProperty(propertyNameToIdMap, overline_positionAttr);
97  //mapAttributeToCSSProperty(propertyNameToIdMap, overline_thicknessAttr);
98  //mapAttributeToCSSProperty(propertyNameToIdMap, panose_1Attr);
99  //mapAttributeToCSSProperty(propertyNameToIdMap, slopeAttr);
100  //mapAttributeToCSSProperty(propertyNameToIdMap, stemhAttr);
101  //mapAttributeToCSSProperty(propertyNameToIdMap, stemvAttr);
102  //mapAttributeToCSSProperty(propertyNameToIdMap, strikethrough_positionAttr);
103  //mapAttributeToCSSProperty(propertyNameToIdMap, strikethrough_thicknessAttr);
104  //mapAttributeToCSSProperty(propertyNameToIdMap, underline_positionAttr);
105  //mapAttributeToCSSProperty(propertyNameToIdMap, underline_thicknessAttr);
106  //mapAttributeToCSSProperty(propertyNameToIdMap, unicode_rangeAttr);
107  //mapAttributeToCSSProperty(propertyNameToIdMap, units_per_emAttr);
108  //mapAttributeToCSSProperty(propertyNameToIdMap, v_alphabeticAttr);
109  //mapAttributeToCSSProperty(propertyNameToIdMap, v_hangingAttr);
110  //mapAttributeToCSSProperty(propertyNameToIdMap, v_ideographicAttr);
111  //mapAttributeToCSSProperty(propertyNameToIdMap, v_mathematicalAttr);
112  //mapAttributeToCSSProperty(propertyNameToIdMap, widthsAttr);
113  //mapAttributeToCSSProperty(propertyNameToIdMap, x_heightAttr);
114  }
115 
116  return propertyNameToIdMap->get(attrName.localName().impl());
117 }
118 
119 void SVGFontFaceElement::parseMappedAttribute(MappedAttribute* attr)
120 {
121  int propId = cssPropertyIdForSVGAttributeName(attr->name());
122  if (propId > 0) {
123  m_styleDeclaration->setProperty(propId, attr->value(), false);
124  rebuildFontFace();
125  return;
126  }
127 
128  SVGElement::parseMappedAttribute(attr);
129 }
130 
131 unsigned SVGFontFaceElement::unitsPerEm() const
132 {
133  AtomicString value(getAttribute(units_per_emAttr));
134  if (value.isEmpty())
135  return 1000;
136 
137  return static_cast<unsigned>(ceilf(value.toFloat()));
138 }
139 
140 int SVGFontFaceElement::xHeight() const
141 {
142  AtomicString value(getAttribute(x_heightAttr));
143  if (value.isEmpty())
144  return 0;
145 
146  return static_cast<int>(ceilf(value.toFloat()));
147 }
148 
149 float SVGFontFaceElement::horizontalOriginX() const
150 {
151  if (!m_fontElement)
152  return 0.0f;
153 
154  // Spec: The X-coordinate in the font coordinate system of the origin of a glyph to be used when
155  // drawing horizontally oriented text. (Note that the origin applies to all glyphs in the font.)
156  // If the attribute is not specified, the effect is as if a value of "0" were specified.
157  AtomicString value(m_fontElement->getAttribute(horiz_origin_xAttr));
158  if (value.isEmpty())
159  return 0.0f;
160 
161  return value.toFloat();
162 }
163 
164 float SVGFontFaceElement::horizontalOriginY() const
165 {
166  if (!m_fontElement)
167  return 0.0f;
168 
169  // Spec: The Y-coordinate in the font coordinate system of the origin of a glyph to be used when
170  // drawing horizontally oriented text. (Note that the origin applies to all glyphs in the font.)
171  // If the attribute is not specified, the effect is as if a value of "0" were specified.
172  AtomicString value(m_fontElement->getAttribute(horiz_origin_yAttr));
173  if (value.isEmpty())
174  return 0.0f;
175 
176  return value.toFloat();
177 }
178 
179 float SVGFontFaceElement::horizontalAdvanceX() const
180 {
181  if (!m_fontElement)
182  return 0.0f;
183 
184  // Spec: The default horizontal advance after rendering a glyph in horizontal orientation. Glyph
185  // widths are required to be non-negative, even if the glyph is typically rendered right-to-left,
186  // as in Hebrew and Arabic scripts.
187  AtomicString value(m_fontElement->getAttribute(horiz_adv_xAttr));
188  if (value.isEmpty())
189  return 0.0f;
190 
191  return value.toFloat();
192 }
193 
194 float SVGFontFaceElement::verticalOriginX() const
195 {
196  if (!m_fontElement)
197  return 0.0f;
198 
199  // Spec: The default X-coordinate in the font coordinate system of the origin of a glyph to be used when
200  // drawing vertically oriented text. If the attribute is not specified, the effect is as if the attribute
201  // were set to half of the effective value of attribute horiz-adv-x.
202  AtomicString value(m_fontElement->getAttribute(vert_origin_xAttr));
203  if (value.isEmpty())
204  return horizontalAdvanceX() / 2.0f;
205 
206  return value.toFloat();
207 }
208 
209 float SVGFontFaceElement::verticalOriginY() const
210 {
211  if (!m_fontElement)
212  return 0.0f;
213 
214  // Spec: The default Y-coordinate in the font coordinate system of the origin of a glyph to be used when
215  // drawing vertically oriented text. If the attribute is not specified, the effect is as if the attribute
216  // were set to the position specified by the font's ascent attribute.
217  AtomicString value(m_fontElement->getAttribute(vert_origin_yAttr));
218  if (value.isEmpty())
219  return ascent();
220 
221  return value.toFloat();
222 }
223 
224 float SVGFontFaceElement::verticalAdvanceY() const
225 {
226  if (!m_fontElement)
227  return 0.0f;
228 
229  // Spec: The default vertical advance after rendering a glyph in vertical orientation. If the attribute is
230  // not specified, the effect is as if a value equivalent of one em were specified (see units-per-em).
231  AtomicString value(m_fontElement->getAttribute(vert_adv_yAttr));
232  if (value.isEmpty())
233  return 1.0f;
234 
235  return value.toFloat();
236 }
237 
238 int SVGFontFaceElement::ascent() const
239 {
240  if (!m_fontElement)
241  return 0.0f;
242 
243  // Spec: Same syntax and semantics as the 'ascent' descriptor within an @font-face rule. The maximum
244  // unaccented height of the font within the font coordinate system. If the attribute is not specified,
245  // the effect is as if the attribute were set to the difference between the units-per-em value and the
246  // vert-origin-y value for the corresponding font.
247  AtomicString value(m_fontElement->getAttribute(ascentAttr));
248  if (!value.isEmpty())
249  return static_cast<int>(ceilf(value.toFloat()));
250 
251  value = m_fontElement->getAttribute(vert_origin_yAttr);
252  if (!value.isEmpty())
253  return static_cast<int>(unitsPerEm()) - static_cast<int>(ceilf(value.toFloat()));
254 
255  // Match Batiks default value
256  return static_cast<int>(ceilf(unitsPerEm() * 0.8f));
257 }
258 
259 int SVGFontFaceElement::descent() const
260 {
261  if (!m_fontElement)
262  return 0.0f;
263 
264  // Spec: Same syntax and semantics as the 'descent' descriptor within an @font-face rule. The maximum
265  // unaccented depth of the font within the font coordinate system. If the attribute is not specified,
266  // the effect is as if the attribute were set to the vert-origin-y value for the corresponding font.
267  AtomicString value(m_fontElement->getAttribute(descentAttr));
268  if (!value.isEmpty()) {
269  // Some testcases use a negative descent value, where a positive was meant to be used :(
270  int descent = static_cast<int>(ceilf(value.toFloat()));
271  return descent < 0 ? -descent : descent;
272  }
273 
274  value = m_fontElement->getAttribute(vert_origin_yAttr);
275  if (!value.isEmpty())
276  return static_cast<int>(ceilf(value.toFloat()));
277 
278  // Match Batiks default value
279  return static_cast<int>(ceilf(unitsPerEm() * 0.2f));
280 }
281 
282 String SVGFontFaceElement::fontFamily() const
283 {
284  return m_styleDeclaration->getPropertyValue(CSSPropertyFontFamily);
285 }
286 
287 SVGFontElement* SVGFontFaceElement::associatedFontElement() const
288 {
289  return m_fontElement.get();
290 }
291 
292 void SVGFontFaceElement::rebuildFontFace()
293 {
294  // Ignore changes until we live in the tree
295  if (!parentNode())
296  return;
297 
298  // we currently ignore all but the first src element, alternatively we could concat them
299  SVGFontFaceSrcElement* srcElement = 0;
300  SVGDefinitionSrcElement* definitionSrc = 0;
301 
302  for (Node* child = firstChild(); child; child = child->nextSibling()) {
303  if (child->hasTagName(font_face_srcTag) && !srcElement)
304  srcElement = static_cast<SVGFontFaceSrcElement*>(child);
305  else if (child->hasTagName(definition_srcTag) && !definitionSrc)
306  definitionSrc = static_cast<SVGDefinitionSrcElement*>(child);
307  }
308 
309 #if 0
310  // @font-face (CSSFontFace) does not yet support definition-src, as soon as it does this code should do the trick!
311  if (definitionSrc)
312  m_styleDeclaration->setProperty(CSSPropertyDefinitionSrc, definitionSrc->getAttribute(XLinkNames::hrefAttr), false);
313 #endif
314 
315  bool describesParentFont = parentNode()->hasTagName(fontTag);
316  RefPtr<CSSValueList> list;
317 
318  if (describesParentFont) {
319  m_fontElement = static_cast<SVGFontElement*>(parentNode());
320 
321  list = new CSSValueList; // ### CSSValueListImpl(CSSValueListImpl::Comma);
322  list->append(new CSSFontFaceSrcValue(fontFamily(), true));
323  } else if (srcElement)
324  list = srcElement->srcValue();
325 
326  if (!list)
327  return;
328 
329  // Parse in-memory CSS rules
330  CSSProperty srcProperty(CSSPropertySrc, list);
331  const CSSProperty* srcPropertyRef = &srcProperty;
332  m_styleDeclaration->addParsedProperties(&srcPropertyRef, 1);
333 
334  if (describesParentFont) {
335  // Traverse parsed CSS values and associate CSSFontFaceSrcValue elements with ourselves.
336  RefPtr<CSSValue> src = m_styleDeclaration->getPropertyCSSValue(CSSPropertySrc);
337  CSSValueList* srcList = static_cast<CSSValueList*>(src.get());
338 
339  unsigned srcLength = srcList ? srcList->length() : 0;
340  for (unsigned i = 0; i < srcLength; i++) {
341  if (CSSFontFaceSrcValue* item = static_cast<CSSFontFaceSrcValue*>(srcList->itemWithoutBoundsCheck(i)))
342  item->setSVGFontFaceElement(this);
343  }
344  }
345 
346  document()->updateStyleSelector();
347 }
348 
349 void SVGFontFaceElement::insertedIntoDocument()
350 {
351  rebuildFontFace();
352  SVGElement::insertedIntoDocument();
353 }
354 
355 void SVGFontFaceElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
356 {
357  SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
358  rebuildFontFace();
359 }
360 
361 }
362 
363 #endif // ENABLE(SVG_FONTS)
WebCore::SVGNames::x_heightAttr
DOM::QualifiedName x_heightAttr
Definition: SVGNames.cpp:339
WebCore::SVGNames::horiz_origin_xAttr
DOM::QualifiedName horiz_origin_xAttr
Definition: SVGNames.cpp:188
WebCore::SVGNames::horiz_adv_xAttr
DOM::QualifiedName horiz_adv_xAttr
Definition: SVGNames.cpp:187
WebCore::SVGNames::fontTag
DOM::QualifiedName fontTag
Definition: SVGNames.cpp:63
WebCore::SVGNames::ascentAttr
DOM::QualifiedName ascentAttr
Definition: SVGNames.cpp:110
WebCore::SVGNames::font_familyAttr
DOM::QualifiedName font_familyAttr
Definition: SVGNames.cpp:166
SVGFontElement.h
WebCore::SVGNames::horiz_origin_yAttr
DOM::QualifiedName horiz_origin_yAttr
Definition: SVGNames.cpp:189
WebCore::XLinkNames::hrefAttr
DOM::QualifiedName hrefAttr
Definition: SVGNames.cpp:13
WebCore::SVGNames::font_face_srcTag
DOM::QualifiedName font_face_srcTag
Definition: SVGNames.cpp:67
WebCore::SVGNames::font_variantAttr
DOM::QualifiedName font_variantAttr
Definition: SVGNames.cpp:171
WebCore::SVGNames::vert_origin_xAttr
DOM::QualifiedName vert_origin_xAttr
Definition: SVGNames.cpp:329
SVGFontFaceSrcElement.h
WebCore::SVGNames::font_styleAttr
DOM::QualifiedName font_styleAttr
Definition: SVGNames.cpp:170
SVGNames.h
SVGFontFaceElement.h
WebCore::SVGNames::units_per_emAttr
DOM::QualifiedName units_per_emAttr
Definition: SVGNames.cpp:321
WebCore::SVGNames::vert_adv_yAttr
DOM::QualifiedName vert_adv_yAttr
Definition: SVGNames.cpp:328
WebCore::SVGNames::font_weightAttr
DOM::QualifiedName font_weightAttr
Definition: SVGNames.cpp:172
WebCore::SVGNames::font_stretchAttr
DOM::QualifiedName font_stretchAttr
Definition: SVGNames.cpp:169
SVGGlyphElement.h
WebCore::SVGNames::descentAttr
DOM::QualifiedName descentAttr
Definition: SVGNames.cpp:138
WebCore::SVGNames::definition_srcTag
DOM::QualifiedName definition_srcTag
Definition: SVGNames.cpp:34
WebCore::String
DOM::DOMString String
Definition: PlatformString.h:8
SVGDefinitionSrcElement.h
WebCore::SVGNames::vert_origin_yAttr
DOM::QualifiedName vert_origin_yAttr
Definition: SVGNames.cpp:330
WebCore::SVGNames::font_sizeAttr
DOM::QualifiedName font_sizeAttr
Definition: SVGNames.cpp:167
list
QStringList list(const QString &fileClass)
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:51:22 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal