• 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
SVGFontElement.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
3  Copyright (C) 2007 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 #include "wtf/Platform.h"
23 
24 #if ENABLE(SVG_FONTS)
25 #include "SVGFontElement.h"
26 
27 //#include "Font.h"
28 //FIXME khtml #include "GlyphPageTreeNode.h"
29 #include "SVGGlyphElement.h"
30 #include "SVGMissingGlyphElement.h"
31 #include "SVGNames.h"
32 #include "SVGParserUtilities.h"
33 #include <wtf/ASCIICType.h>
34 
35 using namespace WTF;
36 
37 namespace WebCore {
38 
39 using namespace SVGNames;
40 
41 SVGFontElement::SVGFontElement(const QualifiedName& tagName, Document* doc)
42  : SVGStyledElement(tagName, doc)
43  , m_isGlyphCacheValid(false)
44 {
45 }
46 
47 SVGFontElement::~SVGFontElement()
48 {
49 }
50 
51 void SVGFontElement::invalidateGlyphCache()
52 {
53  if (m_isGlyphCacheValid) {
54  m_glyphMap.clear();
55  m_kerningPairs.clear();
56  }
57  m_isGlyphCacheValid = false;
58 }
59 
60 SVGMissingGlyphElement* SVGFontElement::firstMissingGlyphElement() const
61 {
62  for (Node* child = firstChild(); child; child = child->nextSibling()) {
63  if (child->hasTagName(missing_glyphTag))
64  return static_cast<SVGMissingGlyphElement*>(child);
65  }
66 
67  return 0;
68 }
69 
70 void SVGFontElement::ensureGlyphCache() const
71 {
72  if (m_isGlyphCacheValid)
73  return;
74 
75  for (Node* child = firstChild(); child; child = child->nextSibling()) {
76  if (child->hasTagName(glyphTag)) {
77  SVGGlyphElement* glyph = static_cast<SVGGlyphElement*>(child);
78  String unicode = glyph->getAttribute(unicodeAttr);
79  if (unicode.length())
80  m_glyphMap.add(unicode, glyph->buildGlyphIdentifier());
81  } else if (child->hasTagName(hkernTag)) {
82  SVGHKernElement* hkern = static_cast<SVGHKernElement*>(child);
83  SVGHorizontalKerningPair kerningPair = hkern->buildHorizontalKerningPair();
84  m_kerningPairs.append(kerningPair);
85  }
86  }
87 
88  m_isGlyphCacheValid = true;
89 }
90 
91 // Returns the number of characters consumed or 0 if no range was found.
92 static unsigned parseUnicodeRange(const UChar* characters, unsigned length, pair<unsigned, unsigned>& range)
93 {
94  Q_UNUSED(characters);
95  Q_UNUSED(length);
96  Q_UNUSED(range);
97  // FIXME khtml
98  return 0;
99  /*if (length < 2)
100  return 0;
101  if (characters[0] != 'U')
102  return 0;
103  if (characters[1] != '+')
104  return 0;
105 
106  // Parse the starting hex number (or its prefix).
107  unsigned start = 0;
108  unsigned startLength = 0;
109  for (unsigned i = 2; i < length; ++i) {
110  if (!isASCIIHexDigit(characters[i]))
111  break;
112  if (++startLength > 6)
113  return 0;
114  start = (start << 4) | toASCIIHexValue(characters[i]);
115  }
116 
117  // Handle the case of ranges separated by "-" sign.
118  if (2 + startLength < length && characters[2 + startLength] == '-') {
119  if (!startLength)
120  return 0;
121 
122  // Parse the ending hex number (or its prefix).
123  unsigned end = 0;
124  unsigned endLength = 0;
125  for (unsigned i = 2 + startLength + 1; i < length; ++i) {
126  if (!isASCIIHexDigit(characters[i]))
127  break;
128  if (++endLength > 6)
129  return 0;
130  end = (end << 4) | toASCIIHexValue(characters[i]);
131  }
132 
133  if (!endLength)
134  return 0;
135 
136  range.first = start;
137  range.second = end;
138  return 2 + startLength + 1 + endLength;
139  }
140 
141  // Handle the case of a number with some optional trailing question marks.
142  unsigned end = start;
143  for (unsigned i = 2 + startLength; i < length; ++i) {
144  if (characters[i] != '?')
145  break;
146  if (++startLength > 6)
147  return 0;
148  start <<= 4;
149  end = (end << 4) | 0xF;
150  }
151 
152  if (!startLength)
153  return 0;
154 
155  range.first = start;
156  range.second = end;
157  return 2 + startLength;*/
158 }
159 
160 static bool parseUnicodeRangeList(const UChar* characters, unsigned length, Vector<pair<unsigned, unsigned> >& ranges)
161 {
162  ranges.clear();
163  if (!length)
164  return true;
165 
166  const UChar* remainingCharacters = characters;
167  unsigned remainingLength = length;
168 
169  while (1) {
170  pair<unsigned, unsigned> range;
171  unsigned charactersConsumed = parseUnicodeRange(remainingCharacters, remainingLength, range);
172  if (charactersConsumed) {
173  ranges.append(range);
174  remainingCharacters += charactersConsumed;
175  remainingLength -= charactersConsumed;
176  } else {
177  if (!remainingLength)
178  return false;
179  UChar character = remainingCharacters[0];
180  if (character == ',')
181  return false;
182  ranges.append(make_pair(character.unicode(), character.unicode()));
183  ++remainingCharacters;
184  --remainingLength;
185  }
186  if (!remainingLength)
187  return true;
188  if (remainingCharacters[0] != ',')
189  return false;
190  ++remainingCharacters;
191  --remainingLength;
192  }
193 }
194 
195 static bool stringMatchesUnicodeRange(const String& unicodeString, const String& unicodeRangeSpec)
196 {
197  Vector<pair<unsigned, unsigned> > ranges;
198  if (!parseUnicodeRangeList(unicodeRangeSpec.characters(), unicodeRangeSpec.length(), ranges))
199  return false;
200 
201  if (unicodeString.length() != ranges.size())
202  return false;
203 
204  for (size_t i = 0; i < unicodeString.length(); ++i) {
205  UChar c = unicodeString[i];
206  if (c < ranges[i].first || c > ranges[i].second)
207  return false;
208  }
209 
210  return true;
211 }
212 
213 static bool matches(const String& u1, const String& g1, const String& u2, const String& g2, const SVGHorizontalKerningPair& kerningPair)
214 {
215  if (kerningPair.unicode1.length() && !stringMatchesUnicodeRange(u1, kerningPair.unicode1))
216  return false;
217  if (kerningPair.glyphName1.length() && kerningPair.glyphName1 != g1)
218  return false;
219 
220  if (kerningPair.unicode2.length() && !stringMatchesUnicodeRange(u2, kerningPair.unicode2))
221  return false;
222  if (kerningPair.glyphName2.length() && kerningPair.glyphName2 != g2)
223  return false;
224 
225  return true;
226 }
227 
228 bool SVGFontElement::getHorizontalKerningPairForStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2, SVGHorizontalKerningPair& kerningPair) const
229 {
230  for (size_t i = 0; i < m_kerningPairs.size(); ++i) {
231  if (matches(u1, g1, u2, g2, m_kerningPairs[i])) {
232  kerningPair = m_kerningPairs[i];
233  return true;
234  }
235  }
236 
237  return false;
238 }
239 
240 void SVGFontElement::getGlyphIdentifiersForString(const String& string, Vector<SVGGlyphIdentifier>& glyphs) const
241 {
242  ensureGlyphCache();
243  m_glyphMap.get(string, glyphs);
244 }
245 
246 }
247 
248 #endif // ENABLE(SVG_FONTS)
WebCore::SVGNames::missing_glyphTag
DOM::QualifiedName missing_glyphTag
Definition: SVGNames.cpp:80
WebCore::SVGNames::unicodeAttr
DOM::QualifiedName unicodeAttr
Definition: SVGNames.cpp:318
SVGParserUtilities.h
SVGFontElement.h
SVGMissingGlyphElement.h
WebCore::SVGNames::glyphTag
DOM::QualifiedName glyphTag
Definition: SVGNames.cpp:71
WebCore::SVGNames::hkernTag
DOM::QualifiedName hkernTag
Definition: SVGNames.cpp:73
SVGNames.h
SVGGlyphElement.h
WebCore::String
DOM::DOMString String
Definition: PlatformString.h:8
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