Changeset 88557 in webkit
- Timestamp:
- Jun 10, 2011, 1:15:10 PM (15 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
-
ChangeLog (modified) (1 diff)
-
platform/graphics/SVGGlyph.h (modified) (4 diffs)
-
rendering/svg/SVGTextRunRenderingContext.cpp (modified) (1 diff)
-
svg/SVGFontData.cpp (modified) (2 diffs)
-
svg/SVGFontElement.cpp (modified) (8 diffs)
-
svg/SVGFontElement.h (modified) (4 diffs)
-
svg/SVGGlyphMap.h (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r88556 r88557 1 2011-06-10 Nikolas Zimmermann <nzimmermann@rim.com> 2 3 Reviewed by Rob Buis. 4 5 Integrate SVG Fonts within GlyphPage concept, removing the special SVG code paths from Font, making it possible to reuse the simple text code path for SVG Fonts 6 https://bugs.webkit.org/show_bug.cgi?id=59085 7 8 Add glyph table to SVGFontElement mapping between SVGGlyph <-> Glyph 9 https://bugs.webkit.org/show_bug.cgi?id=62441 10 11 Preparation patch 1: Introduce the internal glyph table in SVGGlyphMap that will be used to identify each 12 SVGGlyph identifier with a Glyph (which is just an ushort). It will be used by follow-up patches. 13 14 Doesn't affect any test so far. 15 16 * platform/graphics/SVGGlyph.h: 17 (WebCore::SVGGlyph::SVGGlyph): 18 (WebCore::SVGGlyph::operator==): 19 * rendering/svg/SVGTextRunRenderingContext.cpp: 20 (WebCore::SVGTextRunWalker::walk): 21 * svg/SVGFontData.cpp: 22 (WebCore::SVGFontData::initializeFontData): 23 * svg/SVGFontElement.cpp: 24 (WebCore::SVGFontElement::SVGFontElement): 25 (WebCore::SVGFontElement::registerLigaturesInGlyphCache): 26 (WebCore::SVGFontElement::ensureGlyphCache): 27 (WebCore::kerningForPairOfStringsAndGlyphs): 28 (WebCore::SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs): 29 (WebCore::SVGFontElement::verticalKerningForPairOfStringsAndGlyphs): 30 (WebCore::SVGFontElement::collectGlyphsForString): 31 (WebCore::SVGFontElement::collectGlyphsForGlyphName): 32 (WebCore::SVGFontElement::svgGlyphForGlyph): 33 (WebCore::SVGFontElement::missingGlyph): 34 * svg/SVGFontElement.h: 35 (WebCore::SVGKerningPair::SVGKerningPair): 36 * svg/SVGGlyphMap.h: 37 (WebCore::SVGGlyphMap::addGlyphByUnicodeString): 38 (WebCore::SVGGlyphMap::addGlyphByName): 39 (WebCore::SVGGlyphMap::appendToGlyphTable): 40 (WebCore::SVGGlyphMap::collectGlyphsForString): 41 (WebCore::SVGGlyphMap::clear): 42 (WebCore::SVGGlyphMap::svgGlyphForGlyph): 43 (WebCore::SVGGlyphMap::glyphIdentifierForGlyphName): 44 1 45 2011-06-10 Emil A Eklund <eae@chromium.org> 2 46 -
trunk/Source/WebCore/platform/graphics/SVGGlyph.h
r84498 r88557 25 25 26 26 #if ENABLE(SVG_FONTS) 27 #include "Glyph.h" 27 28 #include "Path.h" 28 29 … … 55 56 , arabicForm(None) 56 57 , priority(0) 58 , tableEntry(0) 57 59 , unicodeStringLength(0) 58 60 , horizontalAdvanceX(0) … … 75 77 && orientation == other.orientation 76 78 && arabicForm == other.arabicForm 79 && tableEntry == other.tableEntry 77 80 && unicodeStringLength == other.unicodeStringLength 78 81 && glyphName == other.glyphName … … 89 92 unsigned arabicForm : 3; // ArabicForm 90 93 int priority; 94 Glyph tableEntry; 91 95 size_t unicodeStringLength; 92 96 String glyphName; -
trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
r88139 r88557 153 153 glyphs.append(altGlyphIdentifier); 154 154 else 155 m_fontElement-> getGlyphIdentifiersForString(lookupString, glyphs);155 m_fontElement->collectGlyphsForString(lookupString, glyphs); 156 156 157 157 Vector<SVGGlyph>::iterator it = glyphs.begin(); -
trunk/Source/WebCore/svg/SVGFontData.cpp
r87152 r88557 60 60 // Fallback if x_heightAttr is not specified for the font element. 61 61 Vector<SVGGlyph> letterXGlyphs; 62 associatedFontElement-> getGlyphIdentifiersForString(String("x", 1), letterXGlyphs);62 associatedFontElement->collectGlyphsForString(String("x", 1), letterXGlyphs); 63 63 xHeight = letterXGlyphs.isEmpty() ? 2 * ascent / 3 : letterXGlyphs.first().horizontalAdvanceX * scale; 64 64 } … … 73 73 74 74 Vector<SVGGlyph> spaceGlyphs; 75 associatedFontElement-> getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs);75 associatedFontElement->collectGlyphsForString(String(" ", 1), spaceGlyphs); 76 76 fontData->setSpaceWidth(spaceGlyphs.isEmpty() ? xHeight : spaceGlyphs.first().horizontalAdvanceX * scale); 77 77 78 78 Vector<SVGGlyph> numeralZeroGlyphs; 79 associatedFontElement-> getGlyphIdentifiersForString(String("0", 1), numeralZeroGlyphs);79 associatedFontElement->collectGlyphsForString(String("0", 1), numeralZeroGlyphs); 80 80 fontData->setAvgCharWidth(numeralZeroGlyphs.isEmpty() ? fontData->spaceWidth() : numeralZeroGlyphs.first().horizontalAdvanceX * scale); 81 81 82 82 Vector<SVGGlyph> letterWGlyphs; 83 associatedFontElement-> getGlyphIdentifiersForString(String("W", 1), letterWGlyphs);83 associatedFontElement->collectGlyphsForString(String("W", 1), letterWGlyphs); 84 84 fontData->setMaxCharWidth(letterWGlyphs.isEmpty() ? ascent : letterWGlyphs.first().horizontalAdvanceX * scale); 85 85 -
trunk/Source/WebCore/svg/SVGFontElement.cpp
r86050 r88557 42 42 inline SVGFontElement::SVGFontElement(const QualifiedName& tagName, Document* document) 43 43 : SVGStyledElement(tagName, document) 44 , m_missingGlyph(0) 44 45 , m_isGlyphCacheValid(false) 45 46 { … … 80 81 } 81 82 82 void SVGFontElement::ensureGlyphCache() const 83 void SVGFontElement::registerLigaturesInGlyphCache(Vector<String>& ligatures) 84 { 85 ASSERT(!ligatures.isEmpty()); 86 87 // Register each character of a ligature in the map, if not present. 88 // Eg. If only a "fi" ligature is present, but not "f" and "i", the 89 // GlyphPage will not contain any entries for "f" and "i", so the 90 // SVGFont is not used to render the text "fi1234". Register an 91 // empty SVGGlyph with the character, so the SVG Font will be used 92 // to render the text. If someone tries to render "f2" the SVG Font 93 // will not be able to find a glyph for "f", but handles the fallback 94 // character substitution properly through glyphDataForCharacter(). 95 Vector<SVGGlyph> glyphs; 96 size_t ligaturesSize = ligatures.size(); 97 for (size_t i = 0; i < ligaturesSize; ++i) { 98 const String& unicode = ligatures[i]; 99 100 unsigned unicodeLength = unicode.length(); 101 ASSERT(unicodeLength > 1); 102 103 const UChar* characters = unicode.characters(); 104 for (unsigned i = 0; i < unicodeLength; ++i) { 105 String lookupString(characters + i, 1); 106 m_glyphMap.collectGlyphsForString(lookupString, glyphs); 107 if (!glyphs.isEmpty()) { 108 glyphs.clear(); 109 continue; 110 } 111 112 // This glyph is never meant to be used for rendering, only as identifier as a part of a ligature. 113 SVGGlyph newGlyphPart; 114 /* FIXME: Enable this once with the next patch. 115 newGlyphPart.isPartOfLigature = true; 116 */ 117 m_glyphMap.addGlyphByUnicodeString(lookupString, newGlyphPart); 118 } 119 } 120 } 121 122 void SVGFontElement::ensureGlyphCache() 83 123 { 84 124 if (m_isGlyphCacheValid) 85 125 return; 86 126 127 SVGMissingGlyphElement* firstMissingGlyphElement = 0; 128 Vector<String> ligatures; 87 129 for (Node* child = firstChild(); child; child = child->nextSibling()) { 88 130 if (child->hasTagName(SVGNames::glyphTag)) { 89 131 SVGGlyphElement* glyph = static_cast<SVGGlyphElement*>(child); 90 132 String unicode = glyph->getAttribute(SVGNames::unicodeAttr); 91 if (unicode.length()) 92 m_glyphMap.add(unicode, glyph->buildGlyphIdentifier()); 133 SVGGlyph svgGlyph = glyph->buildGlyphIdentifier(); 134 unsigned unicodeLength = unicode.length(); 135 136 // Register named glyphs in the glyph table as well. 137 if (!unicodeLength) { 138 m_glyphMap.addGlyphByName(glyph->getIdAttribute(), svgGlyph); 139 continue; 140 } 141 142 // Register ligatures, if needed. 143 if (unicodeLength > 1) 144 ligatures.append(unicode); 145 146 m_glyphMap.addGlyphByUnicodeString(unicode, svgGlyph); 93 147 } else if (child->hasTagName(SVGNames::hkernTag)) { 94 148 SVGHKernElement* hkern = static_cast<SVGHKernElement*>(child); … … 97 151 SVGVKernElement* vkern = static_cast<SVGVKernElement*>(child); 98 152 vkern->buildVerticalKerningPair(m_verticalKerningPairs); 99 } 100 } 101 153 } else if (child->hasTagName(SVGNames::missing_glyphTag) && !firstMissingGlyphElement) 154 firstMissingGlyphElement = static_cast<SVGMissingGlyphElement*>(child); 155 } 156 157 /* FIXME: Register each character of each ligature, if needed. 158 This is not needed yet, turn it on with the next patch. With the current SVG Fonts code it would break fonts-glyph-04-t.svg 159 if (!ligatures.isEmpty()) 160 registerLigaturesInGlyphCache(ligatures); 161 */ 162 163 // Register missing-glyph element, if present. 164 if (firstMissingGlyphElement) { 165 SVGGlyph svgGlyph = SVGGlyphElement::buildGenericGlyphIdentifier(firstMissingGlyphElement); 166 m_glyphMap.appendToGlyphTable(svgGlyph); 167 m_missingGlyph = svgGlyph.tableEntry; 168 ASSERT(m_missingGlyph > 0); 169 } 170 102 171 m_isGlyphCacheValid = true; 103 172 } … … 133 202 return false; 134 203 } 135 204 136 205 static bool matches(const String& u1, const String& g1, const String& u2, const String& g2, const SVGKerningPair& kerningPair) 137 206 { … … 147 216 } 148 217 149 static float kerningForPairOfStringsAndGlyphs( KerningPairVector& kerningPairs, const String& u1, const String& g1, const String& u2, const String& g2)218 static float kerningForPairOfStringsAndGlyphs(const KerningPairVector& kerningPairs, const String& u1, const String& g1, const String& u2, const String& g2) 150 219 { 151 220 KerningPairVector::const_iterator it = kerningPairs.end() - 1; … … 156 225 } 157 226 158 return 0 .0f;227 return 0; 159 228 } 160 229 … … 162 231 { 163 232 if (m_horizontalKerningPairs.isEmpty()) 164 return 0 .0f;233 return 0; 165 234 166 235 return kerningForPairOfStringsAndGlyphs(m_horizontalKerningPairs, u1, g1, u2, g2); … … 170 239 { 171 240 if (m_verticalKerningPairs.isEmpty()) 172 return 0 .0f;241 return 0; 173 242 174 243 return kerningForPairOfStringsAndGlyphs(m_verticalKerningPairs, u1, g1, u2, g2); 175 244 } 176 245 177 void SVGFontElement::getGlyphIdentifiersForString(const String& string, Vector<SVGGlyph>& glyphs) const 178 { 179 ensureGlyphCache(); 180 m_glyphMap.get(string, glyphs); 246 void SVGFontElement::collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs) 247 { 248 ensureGlyphCache(); 249 m_glyphMap.collectGlyphsForString(string, glyphs); 250 } 251 252 void SVGFontElement::collectGlyphsForGlyphName(const String& glyphName, Vector<SVGGlyph>& glyphs) 253 { 254 ensureGlyphCache(); 255 // FIXME: We only support glyphName -> single glyph mapping so far. 256 glyphs.append(m_glyphMap.glyphIdentifierForGlyphName(glyphName)); 257 } 258 259 SVGGlyph SVGFontElement::svgGlyphForGlyph(Glyph glyph) 260 { 261 ensureGlyphCache(); 262 return m_glyphMap.svgGlyphForGlyph(glyph); 263 } 264 265 Glyph SVGFontElement::missingGlyph() 266 { 267 ensureGlyphCache(); 268 return m_missingGlyph; 181 269 } 182 270 -
trunk/Source/WebCore/svg/SVGFontElement.h
r87125 r88557 44 44 45 45 SVGKerningPair() 46 : kerning(0 .0f)46 : kerning(0) 47 47 { 48 48 } … … 59 59 60 60 void invalidateGlyphCache(); 61 62 void getGlyphIdentifiersForString(const String&, Vector<SVGGlyph>&) const;61 void collectGlyphsForString(const String&, Vector<SVGGlyph>&); 62 void collectGlyphsForGlyphName(const String&, Vector<SVGGlyph>&); 63 63 64 64 float horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const; 65 65 float verticalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const; 66 66 67 // Used by SimpleFontData/WidthIterator. 68 SVGGlyph svgGlyphForGlyph(Glyph); 69 Glyph missingGlyph(); 70 67 71 SVGMissingGlyphElement* firstMissingGlyphElement() const; 68 72 … … 75 79 virtual AttributeToPropertyTypeMap& attributeToPropertyTypeMap(); 76 80 77 void ensureGlyphCache() const; 81 void ensureGlyphCache(); 82 void registerLigaturesInGlyphCache(Vector<String>&); 78 83 79 84 // Animated property declarations … … 82 87 DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired) 83 88 84 mutable KerningPairVector m_horizontalKerningPairs; 85 mutable KerningPairVector m_verticalKerningPairs; 86 mutable SVGGlyphMap m_glyphMap; 87 mutable bool m_isGlyphCacheValid; 89 KerningPairVector m_horizontalKerningPairs; 90 KerningPairVector m_verticalKerningPairs; 91 SVGGlyphMap m_glyphMap; 92 Glyph m_missingGlyph; 93 bool m_isGlyphCacheValid; 88 94 }; 89 95 -
trunk/Source/WebCore/svg/SVGGlyphMap.h
r84498 r88557 22 22 23 23 #if ENABLE(SVG_FONTS) 24 #include "SVGGlyph.h" 24 25 #include "SVGGlyphElement.h" 26 27 #include <wtf/HashMap.h> 28 #include <wtf/Vector.h> 25 29 26 30 namespace WebCore { 27 31 28 32 struct GlyphMapNode; 33 class SVGFontData; 29 34 30 35 typedef HashMap<UChar, RefPtr<GlyphMapNode> > GlyphMapLayer; … … 46 51 SVGGlyphMap() : m_currentPriority(0) { } 47 52 48 void add (const String& string, const SVGGlyph& glyph)53 void addGlyphByUnicodeString(const String& string, const SVGGlyph& glyph) 49 54 { 50 55 size_t len = string.length(); … … 64 69 if (node) { 65 70 node->glyphs.append(glyph); 66 node->glyphs.last().priority = m_currentPriority++; 67 node->glyphs.last().unicodeStringLength = len; 68 node->glyphs.last().isValid = true; 71 72 SVGGlyph& svgGlyph = node->glyphs.last(); 73 svgGlyph.priority = m_currentPriority++; 74 svgGlyph.unicodeStringLength = len; 75 svgGlyph.isValid = true; 76 appendToGlyphTable(svgGlyph); 69 77 } 78 } 79 80 void addGlyphByName(const String& glyphName, SVGGlyph& glyph) 81 { 82 if (glyphName.isEmpty()) 83 return; 84 appendToGlyphTable(glyph); 85 m_namedGlyphs.add(glyphName, glyph.tableEntry); 86 } 87 88 void appendToGlyphTable(SVGGlyph& glyph) 89 { 90 size_t tableEntry = m_glyphTable.size(); 91 ASSERT(tableEntry < std::numeric_limits<unsigned short>::max()); 92 93 // The first table entry starts with 1. 0 denotes an unknown glyph. 94 glyph.tableEntry = tableEntry + 1; 95 m_glyphTable.append(glyph); 70 96 } 71 97 … … 75 101 } 76 102 77 void get(const String& string, Vector<SVGGlyph>& glyphs)103 void collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs) 78 104 { 79 105 GlyphMapLayer* currentLayer = &m_rootLayer; 80 106 81 for (size_t i = 0; i < string.length(); ++i) { 107 size_t length = string.length(); 108 for (size_t i = 0; i < length; ++i) { 82 109 UChar curChar = string[i]; 83 110 RefPtr<GlyphMapNode> node = currentLayer->get(curChar); … … 89 116 std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority); 90 117 } 91 118 92 119 void clear() 93 120 { 94 m_rootLayer.clear(); 121 m_rootLayer.clear(); 122 m_glyphTable.clear(); 95 123 m_currentPriority = 0; 124 } 125 126 const SVGGlyph& svgGlyphForGlyph(Glyph glyph) const 127 { 128 if (!glyph || glyph > m_glyphTable.size()) { 129 DEFINE_STATIC_LOCAL(SVGGlyph, defaultGlyph, ()); 130 return defaultGlyph; 131 } 132 return m_glyphTable[glyph - 1]; 133 } 134 135 const SVGGlyph& glyphIdentifierForGlyphName(const String& glyphName) const 136 { 137 return svgGlyphForGlyph(m_namedGlyphs.get(glyphName)); 96 138 } 97 139 98 140 private: 99 141 GlyphMapLayer m_rootLayer; 142 Vector<SVGGlyph, 256> m_glyphTable; 143 HashMap<String, Glyph> m_namedGlyphs; 100 144 int m_currentPriority; 101 145 }; … … 104 148 105 149 #endif // ENABLE(SVG_FONTS) 106 107 108 150 #endif // SVGGlyphMap_h
Note:
See TracChangeset
for help on using the changeset viewer.