18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright (C) 2008 Apple Inc. All rights reserved.
3dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
4dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * This library is free software; you can redistribute it and/or
5dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * modify it under the terms of the GNU Library General Public
6dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * License as published by the Free Software Foundation; either
7dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * version 2 of the License, or (at your option) any later version.
8dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
9dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * This library is distributed in the hope that it will be useful,
10dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * but WITHOUT ANY WARRANTY; without even the implied warranty of
11dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Library General Public License for more details.
13dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
14dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * You should have received a copy of the GNU Library General Public License
15dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * along with this library; see the file COPYING.LIB.  If not, write to
16dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Boston, MA 02110-1301, USA.
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef SVGGlyphMap_h
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define SVGGlyphMap_h
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if ENABLE(SVG_FONTS)
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SVGGlyphElement.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstruct GlyphMapNode;
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
30f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochtypedef HashMap<UChar, RefPtr<GlyphMapNode> > GlyphMapLayer;
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
32f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstruct GlyphMapNode : public RefCounted<GlyphMapNode> {
33f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochprivate:
34f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    GlyphMapNode() { }
35f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochpublic:
36f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    static PassRefPtr<GlyphMapNode> create() { return adoptRef(new GlyphMapNode); }
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
38f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    Vector<SVGGlyphIdentifier> glyphs;
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    GlyphMapLayer children;
41f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch};
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
43f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochclass SVGGlyphMap {
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
45f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochpublic:
46f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    SVGGlyphMap() : m_currentPriority(0) { }
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
48f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void add(const String& string, const SVGGlyphIdentifier& glyph)
49f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    {
50f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        size_t len = string.length();
51f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        GlyphMapLayer* currentLayer = &m_rootLayer;
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
53f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        RefPtr<GlyphMapNode> node;
54f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        for (size_t i = 0; i < len; ++i) {
55f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            UChar curChar = string[i];
56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            node = currentLayer->get(curChar);
57f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (!node) {
58f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                node = GlyphMapNode::create();
59f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                currentLayer->set(curChar, node);
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
61f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            currentLayer = &node->children;
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
64f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (node) {
65f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            node->glyphs.append(glyph);
66f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            node->glyphs.last().priority = m_currentPriority++;
67f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            node->glyphs.last().nameLength = len;
68f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            node->glyphs.last().isValid = true;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
70f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
71f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
72f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    static inline bool compareGlyphPriority(const SVGGlyphIdentifier& first, const SVGGlyphIdentifier& second)
73f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    {
74f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return first.priority < second.priority;
75f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
76f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
77f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void get(const String& string, Vector<SVGGlyphIdentifier>& glyphs)
78f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    {
79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        GlyphMapLayer* currentLayer = &m_rootLayer;
80f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        for (size_t i = 0; i < string.length(); ++i) {
82f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            UChar curChar = string[i];
83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            RefPtr<GlyphMapNode> node = currentLayer->get(curChar);
84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (!node)
85f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                break;
86f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            glyphs.append(node->glyphs);
87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            currentLayer = &node->children;
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
89f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority);
90f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
92f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void clear()
93f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    {
94f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_rootLayer.clear();
95f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_currentPriority = 0;
96f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
98f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochprivate:
99f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    GlyphMapLayer m_rootLayer;
100f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    int m_currentPriority;
101f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch};
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // ENABLE(SVG_FONTS)
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
108f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif // SVGGlyphMap_h
109