15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef SVGGlyphMap_h 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define SVGGlyphMap_h 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if ENABLE(SVG_FONTS) 24d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/svg/SVGParserUtilities.h" 2519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)#include "platform/fonts/Latin1TextIterator.h" 26a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/SVGGlyph.h" 271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/SurrogatePairAwareTextIterator.h" 28e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/HashMap.h" 29e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "wtf/Vector.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 31c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct GlyphMapNode; 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef HashMap<UChar32, RefPtr<GlyphMapNode> > GlyphMapLayer; 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)struct GlyphMapNode : public RefCounted<GlyphMapNode> { 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GlyphMapNode() { } 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static PassRefPtr<GlyphMapNode> create() { return adoptRef(new GlyphMapNode); } 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Vector<SVGGlyph> glyphs; 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GlyphMapLayer children; 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class SVGGlyphMap { 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public: 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGGlyphMap() : m_currentPriority(0) { } 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) void addGlyph(const String& glyphIdentifier, const String& unicodeString, SVGGlyph glyph) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(!glyphIdentifier.isEmpty() || !unicodeString.isEmpty()); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) bool hasGlyphIdentifier = !glyphIdentifier.isEmpty(); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (unicodeString.isEmpty()) { 58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) // Register glyphs with 'id's in the id glyph map and in the glyph table. 59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) ASSERT(hasGlyphIdentifier); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) appendToGlyphTable(glyph); 61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_idGlyphs.add(glyphIdentifier, glyph.tableEntry); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 6402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 65e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch unsigned length = unicodeString.length(); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 67e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch RefPtr<GlyphMapNode> node; 68e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (unicodeString.is8Bit()) { 69e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch Latin1TextIterator textIterator(unicodeString.characters8(), 0, length, length); 70e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch node = findOrCreateNode(textIterator); 71e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } else { 72e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch SurrogatePairAwareTextIterator textIterator(unicodeString.characters16(), 0, length, length); 73e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch node = findOrCreateNode(textIterator); 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!node) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Register glyph associated with an unicode string into the glyph map. 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node->glyphs.append(glyph); 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGGlyph& lastGlyph = node->glyphs.last(); 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastGlyph.priority = m_currentPriority++; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) lastGlyph.unicodeStringLength = length; 8302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the glyph is named, also add it to the named glyph name, and to the glyph table in both cases. 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) appendToGlyphTable(lastGlyph); 86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!lastGlyph.glyphName.isEmpty()) 87d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_namedGlyphs.add(lastGlyph.glyphName, lastGlyph.tableEntry); 88d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (hasGlyphIdentifier) 89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_idGlyphs.add(glyphIdentifier, lastGlyph.tableEntry); 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void appendToGlyphTable(SVGGlyph& glyph) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t tableEntry = m_glyphTable.size(); 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(tableEntry < std::numeric_limits<unsigned short>::max()); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The first table entry starts with 1. 0 denotes an unknown glyph. 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) glyph.tableEntry = tableEntry + 1; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_glyphTable.append(glyph); 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) static inline bool compareGlyphPriority(const SVGGlyph& first, const SVGGlyph& second) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return first.priority < second.priority; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) void collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 109e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch unsigned length = string.length(); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 111e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (!length) 112e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 114e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (string.is8Bit()) { 115e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch Latin1TextIterator textIterator(string.characters8(), 0, length, length); 116e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch collectGlyphsForIterator(textIterator, glyphs); 117e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } else { 118e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch SurrogatePairAwareTextIterator textIterator(string.characters16(), 0, length, length); 119e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch collectGlyphsForIterator(textIterator, glyphs); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 12402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 125d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) void collectGlyphsForStringExact(const String& string, Vector<SVGGlyph>& glyphs) const 126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 127d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) unsigned length = string.length(); 128d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 129d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!length) 130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return; 131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RefPtr<GlyphMapNode> node; 133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (string.is8Bit()) { 134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) Latin1TextIterator textIterator(string.characters8(), 0, length, length); 135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) node = findNode(textIterator); 136d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } else { 137d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) SurrogatePairAwareTextIterator textIterator(string.characters16(), 0, length, length); 138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) node = findNode(textIterator); 139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (node) 142d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) glyphs.appendVector(node->glyphs); 143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) void collectGlyphsForUnicodeRange(const UnicodeRange& unicodeRange, Vector<SVGGlyph>& glyphs) const 146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) for (unsigned character = unicodeRange.first; character <= unicodeRange.second; ++character) { 148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (RefPtr<GlyphMapNode> node = m_rootLayer.get(character)) 149d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) glyphs.appendVector(node->glyphs); 150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 15302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch void clear() 15402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch { 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_rootLayer.clear(); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_glyphTable.clear(); 157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_idGlyphs.clear(); 158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_namedGlyphs.clear(); 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_currentPriority = 0; 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) void dropNamedGlyphMap() 163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 164d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) m_namedGlyphs.clear(); 165d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 166d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SVGGlyph& svgGlyphForGlyph(Glyph glyph) const 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!glyph || glyph > m_glyphTable.size()) { 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DEFINE_STATIC_LOCAL(SVGGlyph, defaultGlyph, ()); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return defaultGlyph; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_glyphTable[glyph - 1]; 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const SVGGlyph& glyphIdentifierForAltGlyphReference(const String& glyphIdentifier) const 177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return svgGlyphForGlyph(m_idGlyphs.get(glyphIdentifier)); 179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SVGGlyph& glyphIdentifierForGlyphName(const String& glyphName) const 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return svgGlyphForGlyph(m_namedGlyphs.get(glyphName)); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private: 187e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch template<typename Iterator> 188e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch PassRefPtr<GlyphMapNode> findOrCreateNode(Iterator& textIterator) 189e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch { 190e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch GlyphMapLayer* currentLayer = &m_rootLayer; 191e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 192e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch RefPtr<GlyphMapNode> node; 193e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch UChar32 character = 0; 194e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch unsigned clusterLength = 0; 195e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch while (textIterator.consume(character, clusterLength)) { 196e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch node = currentLayer->get(character); 197e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (!node) { 198e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch node = GlyphMapNode::create(); 199e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch currentLayer->set(character, node); 200e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 201e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch currentLayer = &node->children; 202e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch textIterator.advance(clusterLength); 203e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 204e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 205e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return node.release(); 206e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 207e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 208e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch template<typename Iterator> 209d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) PassRefPtr<GlyphMapNode> findNode(Iterator& textIterator) const 210d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) { 211d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) const GlyphMapLayer* currentLayer = &m_rootLayer; 212d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) RefPtr<GlyphMapNode> node; 214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) UChar32 character = 0; 215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) unsigned clusterLength = 0; 216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) while (textIterator.consume(character, clusterLength)) { 217d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) node = currentLayer->get(character); 218d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) if (!node) 219d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) break; 220d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) currentLayer = &node->children; 221d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) textIterator.advance(clusterLength); 222d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 223d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 224d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) return node.release(); 225d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) } 226d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) 227d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) template<typename Iterator> 228e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch void collectGlyphsForIterator(Iterator& textIterator, Vector<SVGGlyph>& glyphs) 229e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch { 230e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch GlyphMapLayer* currentLayer = &m_rootLayer; 231e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 232e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch UChar32 character = 0; 233e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch unsigned clusterLength = 0; 234e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch while (textIterator.consume(character, clusterLength)) { 235e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch RefPtr<GlyphMapNode> node = currentLayer->get(character); 236e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch if (!node) 237e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch break; 238d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) glyphs.appendVector(node->glyphs); 239e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch currentLayer = &node->children; 240e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch textIterator.advance(clusterLength); 241e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 242e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch } 243e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GlyphMapLayer m_rootLayer; 2455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) Vector<SVGGlyph> m_glyphTable; 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) HashMap<String, Glyph> m_namedGlyphs; 247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles) HashMap<String, Glyph> m_idGlyphs; 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int m_currentPriority; 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // ENABLE(SVG_FONTS) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif // SVGGlyphMap_h 255