KHTML
SVGGlyphMap.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef SVGGlyphMap_h
00021 #define SVGGlyphMap_h
00022
00023 #if ENABLE(SVG_FONTS)
00024 #include "SVGGlyphElement.h"
00025
00026 namespace WTF
00027 {
00028 struct QCharHash
00029 {
00030 static unsigned hash(const QChar& c) { return c.unicode(); }
00031 static bool equal(const QChar& a, const QChar& b) { return a == b; }
00032 static const bool safeToCompareToEmptyOrDeleted = false;
00033 };
00034 template<> struct HashTraits<QChar> : public GenericHashTraits<QChar> {
00035 static const bool emptyValueIsZero = true;
00036 static const bool needsDestruction = false;
00037 static const bool needsRef = false;
00038 static QChar deletedValue() { return QChar(-1); }
00039 static bool isDeletedValue(const QChar& c) { return false; }
00040 static QChar constructDeletedValue(QChar*) { return QChar(-1); }
00041 };
00042 template<> struct DefaultHash<QChar>
00043 {
00044 typedef QCharHash Hash;
00045 };
00046 }
00047
00048 namespace WebCore {
00049
00050 struct GlyphMapNode;
00051
00052 typedef HashMap<UChar, RefPtr<GlyphMapNode> > GlyphMapLayer;
00053
00054
00055 struct GlyphMapNode : public RefCounted<GlyphMapNode> {
00056 private:
00057 GlyphMapNode() { }
00058 public:
00059 static PassRefPtr<GlyphMapNode> create() { return adoptRef(new GlyphMapNode); }
00060
00061 Vector<SVGGlyphIdentifier> glyphs;
00062
00063 GlyphMapLayer children;
00064 };
00065
00066 class SVGGlyphMap {
00067
00068 public:
00069 SVGGlyphMap() : m_currentPriority(0) { }
00070
00071 void add(const String& string, const SVGGlyphIdentifier& glyph)
00072 {
00073 size_t len = string.length();
00074 GlyphMapLayer* currentLayer = &m_rootLayer;
00075
00076 RefPtr<GlyphMapNode> node;
00077 for (size_t i = 0; i < len; i++) {
00078 UChar curChar = string[i];
00079 node = currentLayer->get(curChar);
00080 if (!node) {
00081 node = GlyphMapNode::create();
00082 currentLayer->set(curChar, node);
00083 }
00084 currentLayer = &node->children;
00085 }
00086
00087 if (node) {
00088 node->glyphs.append(glyph);
00089 node->glyphs.last().priority = m_currentPriority++;
00090 node->glyphs.last().nameLength = len;
00091 node->glyphs.last().isValid = true;
00092 }
00093 }
00094
00095 static inline bool compareGlyphPriority(const SVGGlyphIdentifier& first, const SVGGlyphIdentifier& second)
00096 {
00097 return first.priority < second.priority;
00098 }
00099
00100 void get(const String& string, Vector<SVGGlyphIdentifier>& glyphs)
00101 {
00102 GlyphMapLayer* currentLayer = &m_rootLayer;
00103
00104 for (size_t i = 0; i < string.length(); i++) {
00105 UChar curChar = string[i];
00106 RefPtr<GlyphMapNode> node = currentLayer->get(curChar);
00107 if (!node)
00108 break;
00109 glyphs.append(node->glyphs);
00110 currentLayer = &node->children;
00111 }
00112 std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority);
00113 }
00114
00115 void clear()
00116 {
00117 m_rootLayer.clear();
00118 m_currentPriority = 0;
00119 }
00120
00121 private:
00122 GlyphMapLayer m_rootLayer;
00123 int m_currentPriority;
00124 };
00125
00126 }
00127
00128 #endif // ENABLE(SVG_FONTS)
00129
00130
00131 #endif //SVGGlyphMap_h