File indexing completed on 2024-04-28 15:24:34

0001 /*
0002    Copyright (C) 2008 Apple, Inc
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018  */
0019 
0020 #ifndef SVGGlyphMap_h
0021 #define SVGGlyphMap_h
0022 
0023 #if ENABLE(SVG_FONTS)
0024 #include "SVGGlyphElement.h"
0025 
0026 namespace WTF
0027 {
0028 struct QCharHash {
0029     static unsigned hash(const QChar &c)
0030     {
0031         return c.unicode();
0032     }
0033     static bool equal(const QChar &a, const QChar &b)
0034     {
0035         return a == b;
0036     }
0037     static const bool safeToCompareToEmptyOrDeleted = false;
0038 };
0039 template<> struct HashTraits<QChar> : public GenericHashTraits<QChar> {
0040     static const bool emptyValueIsZero = true;
0041     static const bool needsDestruction = false;
0042     static const bool needsRef = false;
0043     static QChar deletedValue()
0044     {
0045         return QChar(-1);
0046     }
0047     static bool isDeletedValue(const QChar &)
0048     {
0049         return false;
0050     }
0051     static QChar constructDeletedValue(QChar *)
0052     {
0053         return QChar(-1);
0054     }
0055 };
0056 template<> struct DefaultHash<QChar> {
0057     typedef QCharHash Hash;
0058 };
0059 }
0060 
0061 namespace WebCore
0062 {
0063 
0064 struct GlyphMapNode;
0065 
0066 typedef HashMap<UChar, RefPtr<GlyphMapNode> > GlyphMapLayer;
0067 
0068 struct GlyphMapNode : public RefCounted<GlyphMapNode> {
0069 private:
0070     GlyphMapNode() { }
0071 public:
0072     static PassRefPtr<GlyphMapNode> create()
0073     {
0074         return adoptRef(new GlyphMapNode);
0075     }
0076 
0077     Vector<SVGGlyphIdentifier> glyphs;
0078 
0079     GlyphMapLayer children;
0080 };
0081 
0082 class SVGGlyphMap
0083 {
0084 
0085 public:
0086     SVGGlyphMap() : m_currentPriority(0) { }
0087 
0088     void add(const String &string, const SVGGlyphIdentifier &glyph)
0089     {
0090         size_t len = string.length();
0091         GlyphMapLayer *currentLayer = &m_rootLayer;
0092 
0093         RefPtr<GlyphMapNode> node;
0094         for (size_t i = 0; i < len; i++) {
0095             UChar curChar = string[i];
0096             node = currentLayer->get(curChar);
0097             if (!node) {
0098                 node = GlyphMapNode::create();
0099                 currentLayer->set(curChar, node);
0100             }
0101             currentLayer = &node->children;
0102         }
0103 
0104         if (node) {
0105             node->glyphs.append(glyph);
0106             node->glyphs.last().priority = m_currentPriority++;
0107             node->glyphs.last().nameLength = len;
0108             node->glyphs.last().isValid = true;
0109         }
0110     }
0111 
0112     static inline bool compareGlyphPriority(const SVGGlyphIdentifier &first, const SVGGlyphIdentifier &second)
0113     {
0114         return first.priority < second.priority;
0115     }
0116 
0117     void get(const String &string, Vector<SVGGlyphIdentifier> &glyphs)
0118     {
0119         GlyphMapLayer *currentLayer = &m_rootLayer;
0120 
0121         for (size_t i = 0; i < string.length(); i++) {
0122             UChar curChar = string[i];
0123             RefPtr<GlyphMapNode> node = currentLayer->get(curChar);
0124             if (!node) {
0125                 break;
0126             }
0127             glyphs.append(node->glyphs);
0128             currentLayer = &node->children;
0129         }
0130         std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority);
0131     }
0132 
0133     void clear()
0134     {
0135         m_rootLayer.clear();
0136         m_currentPriority = 0;
0137     }
0138 
0139 private:
0140     GlyphMapLayer m_rootLayer;
0141     int m_currentPriority;
0142 };
0143 
0144 }
0145 
0146 #endif // ENABLE(SVG_FONTS)
0147 
0148 #endif //SVGGlyphMap_h