• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 
20 #ifndef SVGGlyphMap_h
21 #define SVGGlyphMap_h
22 
23 #if ENABLE(SVG_FONTS)
24 #include "SVGGlyphElement.h"
25 
26 namespace WebCore {
27 
28 struct GlyphMapNode;
29 
30 typedef HashMap<UChar, RefPtr<GlyphMapNode> > GlyphMapLayer;
31 
32 struct GlyphMapNode : public RefCounted<GlyphMapNode> {
33 private:
GlyphMapNodeGlyphMapNode34     GlyphMapNode() { }
35 public:
createGlyphMapNode36     static PassRefPtr<GlyphMapNode> create() { return adoptRef(new GlyphMapNode); }
37 
38     Vector<SVGGlyphIdentifier> glyphs;
39 
40     GlyphMapLayer children;
41 };
42 
43 class SVGGlyphMap {
44 
45 public:
SVGGlyphMap()46     SVGGlyphMap() : m_currentPriority(0) { }
47 
add(const String & string,const SVGGlyphIdentifier & glyph)48     void add(const String& string, const SVGGlyphIdentifier& glyph)
49     {
50         size_t len = string.length();
51         GlyphMapLayer* currentLayer = &m_rootLayer;
52 
53         RefPtr<GlyphMapNode> node;
54         for (size_t i = 0; i < len; ++i) {
55             UChar curChar = string[i];
56             node = currentLayer->get(curChar);
57             if (!node) {
58                 node = GlyphMapNode::create();
59                 currentLayer->set(curChar, node);
60             }
61             currentLayer = &node->children;
62         }
63 
64         if (node) {
65             node->glyphs.append(glyph);
66             node->glyphs.last().priority = m_currentPriority++;
67             node->glyphs.last().nameLength = len;
68             node->glyphs.last().isValid = true;
69         }
70     }
71 
compareGlyphPriority(const SVGGlyphIdentifier & first,const SVGGlyphIdentifier & second)72     static inline bool compareGlyphPriority(const SVGGlyphIdentifier& first, const SVGGlyphIdentifier& second)
73     {
74         return first.priority < second.priority;
75     }
76 
get(const String & string,Vector<SVGGlyphIdentifier> & glyphs)77     void get(const String& string, Vector<SVGGlyphIdentifier>& glyphs)
78     {
79         GlyphMapLayer* currentLayer = &m_rootLayer;
80 
81         for (size_t i = 0; i < string.length(); ++i) {
82             UChar curChar = string[i];
83             RefPtr<GlyphMapNode> node = currentLayer->get(curChar);
84             if (!node)
85                 break;
86             glyphs.append(node->glyphs);
87             currentLayer = &node->children;
88         }
89         std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority);
90     }
91 
clear()92     void clear()
93     {
94         m_rootLayer.clear();
95         m_currentPriority = 0;
96     }
97 
98 private:
99     GlyphMapLayer m_rootLayer;
100     int m_currentPriority;
101 };
102 
103 }
104 
105 #endif // ENABLE(SVG_FONTS)
106 
107 
108 #endif // SVGGlyphMap_h
109