22 #include "wtf/Platform.h"
33 #include <wtf/ASCIICType.h>
39 using namespace SVGNames;
41 SVGFontElement::SVGFontElement(
const QualifiedName& tagName, Document* doc)
42 : SVGStyledElement(tagName, doc)
43 , m_isGlyphCacheValid(false)
47 SVGFontElement::~SVGFontElement()
51 void SVGFontElement::invalidateGlyphCache()
53 if (m_isGlyphCacheValid) {
55 m_kerningPairs.clear();
57 m_isGlyphCacheValid =
false;
60 SVGMissingGlyphElement* SVGFontElement::firstMissingGlyphElement()
const
62 for (Node* child = firstChild(); child; child = child->nextSibling()) {
64 return static_cast<SVGMissingGlyphElement*>(child);
70 void SVGFontElement::ensureGlyphCache()
const
72 if (m_isGlyphCacheValid)
75 for (Node* child = firstChild(); child; child = child->nextSibling()) {
77 SVGGlyphElement* glyph =
static_cast<SVGGlyphElement*
>(child);
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);
88 m_isGlyphCacheValid =
true;
92 static unsigned parseUnicodeRange(
const UChar* characters,
unsigned length, pair<unsigned, unsigned>& range)
160 static bool parseUnicodeRangeList(
const UChar* characters,
unsigned length, Vector<pair<unsigned, unsigned> >& ranges)
166 const UChar* remainingCharacters = characters;
167 unsigned remainingLength = length;
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;
177 if (!remainingLength)
179 UChar character = remainingCharacters[0];
180 if (character ==
',')
182 ranges.append(make_pair(character.unicode(), character.unicode()));
183 ++remainingCharacters;
186 if (!remainingLength)
188 if (remainingCharacters[0] !=
',')
190 ++remainingCharacters;
195 static bool stringMatchesUnicodeRange(
const String& unicodeString,
const String& unicodeRangeSpec)
197 Vector<pair<unsigned, unsigned> > ranges;
198 if (!parseUnicodeRangeList(unicodeRangeSpec.characters(), unicodeRangeSpec.length(), ranges))
201 if (unicodeString.length() != ranges.size())
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)
213 static bool matches(
const String& u1,
const String& g1,
const String& u2,
const String& g2,
const SVGHorizontalKerningPair& kerningPair)
215 if (kerningPair.unicode1.length() && !stringMatchesUnicodeRange(u1, kerningPair.unicode1))
217 if (kerningPair.glyphName1.length() && kerningPair.glyphName1 != g1)
220 if (kerningPair.unicode2.length() && !stringMatchesUnicodeRange(u2, kerningPair.unicode2))
222 if (kerningPair.glyphName2.length() && kerningPair.glyphName2 != g2)
228 bool SVGFontElement::getHorizontalKerningPairForStringsAndGlyphs(
const String& u1,
const String& g1,
const String& u2,
const String& g2, SVGHorizontalKerningPair& kerningPair)
const
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];
240 void SVGFontElement::getGlyphIdentifiersForString(
const String&
string, Vector<SVGGlyphIdentifier>& glyphs)
const
243 m_glyphMap.get(
string, glyphs);
248 #endif // ENABLE(SVG_FONTS)
DOM::QualifiedName missing_glyphTag
DOM::QualifiedName unicodeAttr
DOM::QualifiedName glyphTag
DOM::QualifiedName hkernTag