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

KHTML

  • 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
35using namespace WTF;
36
37namespace WebCore {
38
39using namespace SVGNames;
40
41SVGFontElement::SVGFontElement(const QualifiedName& tagName, Document* doc)
42 : SVGStyledElement(tagName, doc)
43 , m_isGlyphCacheValid(false)
44{
45}
46
47SVGFontElement::~SVGFontElement()
48{
49}
50
51void SVGFontElement::invalidateGlyphCache()
52{
53 if (m_isGlyphCacheValid) {
54 m_glyphMap.clear();
55 m_kerningPairs.clear();
56 }
57 m_isGlyphCacheValid = false;
58}
59
60SVGMissingGlyphElement* 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
70void 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.
92static 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
160static 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
195static 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
213static 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
228bool 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
240void 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)
SVGFontElement.h
SVGGlyphElement.h
SVGMissingGlyphElement.h
SVGNames.h
SVGParserUtilities.h
WTF
Definition: IntSizeHash.h:29
WebCore
Definition: CSSHelper.h:7
WebCore::String
DOM::DOMString String
Definition: PlatformString.h:8
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 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-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 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
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
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