Changeset 156393 in webkit


Ignore:
Timestamp:
Sep 25, 2013 7:19:19 AM (11 years ago)
Author:
allan.jensen@digia.com
Message:

Support kerning with SVG web fonts
https://bugs.webkit.org/show_bug.cgi?id=117540

Source/WebCore:

Reviewed by Stephen Chenney.

Adds the glue to WidthIterator to take advantage of kerning in SVG web fonts.
To supply SVG font kerning with its required text input, the signature of
applyFontTransforms has been extended.

Since SVG font kerning was extremely slow, it has been sped up by replacing
the iteration over all possible kerning definitions with a hash-map based
lookup of the leading symbol to be kerned. The new algorithm provides a
roughly 100x speed-up in SVG font kerning.

Test: fast/text/svg-font-face-with-kerning.html

  • platform/graphics/TextRun.h:

(WebCore::TextRun::string):

  • platform/graphics/WidthIterator.cpp:

(WebCore::applyFontTransforms):
(WebCore::WidthIterator::advanceInternal):

  • rendering/svg/SVGTextRunRenderingContext.cpp:

(WebCore::SVGTextRunRenderingContext::applySVGKerning):

  • rendering/svg/SVGTextRunRenderingContext.h:
  • svg/SVGFontElement.cpp:

(WebCore::SVGFontElement::invalidateGlyphCache):
(WebCore::SVGFontElement::ensureGlyphCache):
(WebCore::SVGKerningMap::clear):
(WebCore::SVGKerningMap::insert):
(WebCore::stringMatchesUnicodeRange):
(WebCore::stringMatchesGlyphName):
(WebCore::stringMatchesUnicodeName):
(WebCore::matches):
(WebCore::kerningForPairOfStringsAndGlyphs):
(WebCore::SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs):
(WebCore::SVGFontElement::verticalKerningForPairOfStringsAndGlyphs):

  • svg/SVGFontElement.h:

(WebCore::SVGKerning::SVGKerning):
(WebCore::SVGKerningMap::isEmpty):

  • svg/SVGHKernElement.cpp:

(WebCore::SVGHKernElement::buildHorizontalKerningPair):

  • svg/SVGHKernElement.h:
  • svg/SVGVKernElement.cpp:

(WebCore::SVGVKernElement::buildVerticalKerningPair):

  • svg/SVGVKernElement.h:

LayoutTests:

Added test of SVG web font kerning.

Reviewed by Stephen Chenney.

  • fast/text/svg-font-face-with-kerning-expected.png: Added.
  • fast/text/svg-font-face-with-kerning-expected.txt: Added.
  • fast/text/svg-font-face-with-kerning.html: Added.
Location:
trunk
Files:
3 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r156392 r156393  
     12013-09-25  Allan Sandfeld Jensen  <allan.jensen@digia.com>
     2
     3        Support kerning with SVG web fonts
     4        https://bugs.webkit.org/show_bug.cgi?id=117540
     5
     6        Added test of SVG web font kerning.
     7
     8        Reviewed by Stephen Chenney.
     9
     10        * fast/text/svg-font-face-with-kerning-expected.png: Added.
     11        * fast/text/svg-font-face-with-kerning-expected.txt: Added.
     12        * fast/text/svg-font-face-with-kerning.html: Added.
     13
    1142013-09-25  Anton Obzhirov  <a.obzhirov@samsung.com>
    215
  • trunk/Source/WebCore/ChangeLog

    r156391 r156393  
     12013-09-25  Allan Sandfeld Jensen  <allan.jensen@digia.com>
     2
     3        Support kerning with SVG web fonts
     4        https://bugs.webkit.org/show_bug.cgi?id=117540
     5
     6        Reviewed by Stephen Chenney.
     7
     8        Adds the glue to WidthIterator to take advantage of kerning in SVG web fonts.
     9        To supply SVG font kerning with its required text input, the signature of
     10        applyFontTransforms has been extended.
     11
     12        Since SVG font kerning was extremely slow, it has been sped up by replacing
     13        the iteration over all possible kerning definitions with a hash-map based
     14        lookup of the leading symbol to be kerned. The new algorithm provides a
     15        roughly 100x speed-up in SVG font kerning.
     16
     17        Test: fast/text/svg-font-face-with-kerning.html
     18
     19        * platform/graphics/TextRun.h:
     20        (WebCore::TextRun::string):
     21        * platform/graphics/WidthIterator.cpp:
     22        (WebCore::applyFontTransforms):
     23        (WebCore::WidthIterator::advanceInternal):
     24        * rendering/svg/SVGTextRunRenderingContext.cpp:
     25        (WebCore::SVGTextRunRenderingContext::applySVGKerning):
     26        * rendering/svg/SVGTextRunRenderingContext.h:
     27        * svg/SVGFontElement.cpp:
     28        (WebCore::SVGFontElement::invalidateGlyphCache):
     29        (WebCore::SVGFontElement::ensureGlyphCache):
     30        (WebCore::SVGKerningMap::clear):
     31        (WebCore::SVGKerningMap::insert):
     32        (WebCore::stringMatchesUnicodeRange):
     33        (WebCore::stringMatchesGlyphName):
     34        (WebCore::stringMatchesUnicodeName):
     35        (WebCore::matches):
     36        (WebCore::kerningForPairOfStringsAndGlyphs):
     37        (WebCore::SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs):
     38        (WebCore::SVGFontElement::verticalKerningForPairOfStringsAndGlyphs):
     39        * svg/SVGFontElement.h:
     40        (WebCore::SVGKerning::SVGKerning):
     41        (WebCore::SVGKerningMap::isEmpty):
     42        * svg/SVGHKernElement.cpp:
     43        (WebCore::SVGHKernElement::buildHorizontalKerningPair):
     44        * svg/SVGHKernElement.h:
     45        * svg/SVGVKernElement.cpp:
     46        (WebCore::SVGVKernElement::buildVerticalKerningPair):
     47        * svg/SVGVKernElement.h:
     48
    1492013-09-25  Andrei Parvu  <parvu@adobe.com>
    250
  • trunk/Source/WebCore/platform/graphics/TextRun.h

    r141816 r156393  
    166166    int length() const { return m_len; }
    167167    int charactersLength() const { return m_charactersLength; }
     168    String string() const
     169    {
     170        if (is8Bit())
     171            return String(m_data.characters8, m_len);
     172        return String(m_data.characters16, m_len);
     173    }
    168174
    169175#if ENABLE(8BIT_TEXTRUN)
     
    210216        virtual void drawSVGGlyphs(GraphicsContext*, const TextRun&, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const = 0;
    211217        virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const = 0;
     218        virtual bool applySVGKerning(const SimpleFontData*, WidthIterator&, GlyphBuffer*, int from) const = 0;
    212219#endif
    213220    };
  • trunk/Source/WebCore/platform/graphics/WidthIterator.cpp

    r154674 r156393  
    103103typedef Vector<pair<int, OriginalAdvancesForCharacterTreatedAsSpace>, 64> CharactersTreatedAsSpace;
    104104
    105 static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace)
     105static inline float applyFontTransforms(GlyphBuffer* glyphBuffer, bool ltr, int& lastGlyphCount, const SimpleFontData* fontData, WidthIterator& iterator, TypesettingFeatures typesettingFeatures, CharactersTreatedAsSpace& charactersTreatedAsSpace)
    106106{
    107107    ASSERT(typesettingFeatures & (Kerning | Ligatures));
     
    122122        glyphBuffer->reverse(lastGlyphCount, glyphBufferSize - lastGlyphCount);
    123123
    124     fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures);
     124    // We need to handle transforms on SVG fonts internally, since they are rendered internally.
     125    if (fontData->isSVGFont()) {
     126        ASSERT(iterator.run().renderingContext());
     127        // SVG font ligatures are handled during glyph selection, only kerning remaining.
     128        if (typesettingFeatures & Kerning)
     129            iterator.run().renderingContext()->applySVGKerning(fontData, iterator, glyphBuffer, lastGlyphCount);
     130    } else
     131        fontData->applyTransforms(glyphBuffer->glyphs(lastGlyphCount), advances + lastGlyphCount, glyphBufferSize - lastGlyphCount, typesettingFeatures);
    125132
    126133    if (!ltr)
     
    194201        if (fontData != lastFontData && width) {
    195202            if (shouldApplyFontTransforms()) {
    196                 m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, m_typesettingFeatures, charactersTreatedAsSpace);
     203                m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, *this, m_typesettingFeatures, charactersTreatedAsSpace);
    197204                lastGlyphCount = glyphBuffer->size(); // applyFontTransforms doesn't update when there had been only one glyph.
    198205            }
     
    316323
    317324    if (shouldApplyFontTransforms())
    318         m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, m_typesettingFeatures, charactersTreatedAsSpace);
     325        m_runWidthSoFar += applyFontTransforms(glyphBuffer, m_run.ltr(), lastGlyphCount, lastFontData, *this, m_typesettingFeatures, charactersTreatedAsSpace);
    319326
    320327    unsigned consumedCharacters = textIterator.currentCharacter() - m_currentCharacter;
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp

    r149813 r156393  
    7373    if (m_state.replicaLayer)
    7474        m_state.replicaLayer->computeTransformsRecursive();
    75     for (size_t i = 0; i < m_children.size(); ++i)
     75    for (size_t i = 0; i < m_children.size(); ++i) {
     76        RELEASE_ASSERT(m_children[i]->m_parent == this);
    7677        m_children[i]->computeTransformsRecursive();
     78    }
    7779
    7880    // Reorder children if needed on the way back up.
  • trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp

    r150730 r156393  
    8282    return it.runWidthSoFar();
    8383}
    84  
     84
     85bool SVGTextRunRenderingContext::applySVGKerning(const SimpleFontData* fontData, WidthIterator& iterator, GlyphBuffer* glyphBuffer, int from) const
     86{
     87    ASSERT(glyphBuffer);
     88    ASSERT(glyphBuffer->size() > 1);
     89    SVGFontElement* fontElement = 0;
     90    SVGFontFaceElement* fontFaceElement = 0;
     91
     92    svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
     93    if (!fontElement || !fontFaceElement)
     94        return false;
     95
     96    float scale = scaleEmToUnits(fontData->platformData().size(), fontFaceElement->unitsPerEm());
     97
     98    String lastGlyphName;
     99    String lastUnicodeString;
     100    int characterOffset = iterator.m_currentCharacter;
     101    String text = iterator.run().string();
     102    const int glyphCount = glyphBuffer->size() - from;
     103    GlyphBufferAdvance* advances = glyphBuffer->advances(from);
     104
     105    for (int i = 0; i < glyphCount; ++i) {
     106        Glyph glyph = glyphBuffer->glyphAt(from + i);
     107        if (!glyph)
     108            continue;
     109        float kerning = 0;
     110        SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
     111        String unicodeString = text.substring(characterOffset, svgGlyph.unicodeStringLength);
     112        if (i >= 1) {
     113            // FIXME: Support vertical text.
     114            kerning = fontElement->horizontalKerningForPairOfStringsAndGlyphs(lastUnicodeString, lastGlyphName, unicodeString, svgGlyph.glyphName);
     115            advances[i - 1].setWidth(advances[i - 1].width() - kerning * scale);
     116        }
     117        lastGlyphName = svgGlyph.glyphName;
     118        lastUnicodeString = unicodeString;
     119        characterOffset += svgGlyph.unicodeStringLength;
     120    }
     121
     122    return true;
     123}
     124
    85125void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const TextRun& run, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
    86126{
  • trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h

    r95901 r156393  
    4646    virtual void drawSVGGlyphs(GraphicsContext*, const TextRun&, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
    4747    virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const;
     48    virtual bool applySVGKerning(const SimpleFontData*, WidthIterator&, GlyphBuffer*, int from) const;
    4849#endif
    4950
  • trunk/Source/WebCore/svg/SVGFontElement.cpp

    r155815 r156393  
    6464    if (m_isGlyphCacheValid) {
    6565        m_glyphMap.clear();
    66         m_horizontalKerningPairs.clear();
    67         m_verticalKerningPairs.clear();
     66        m_horizontalKerningMap.clear();
     67        m_verticalKerningMap.clear();
    6868    }
    6969    m_isGlyphCacheValid = false;
     
    140140        } else if (isSVGHKernElement(element)) {
    141141            SVGHKernElement* hkern = toSVGHKernElement(element);
    142             hkern->buildHorizontalKerningPair(m_horizontalKerningPairs);
     142            hkern->buildHorizontalKerningPair(m_horizontalKerningMap);
    143143        } else if (isSVGVKernElement(element)) {
    144144            SVGVKernElement* vkern = toSVGVKernElement(element);
    145             vkern->buildVerticalKerningPair(m_verticalKerningPairs);
     145            vkern->buildVerticalKerningPair(m_verticalKerningMap);
    146146        } else if (isSVGMissingGlyphElement(element) && !firstMissingGlyphElement)
    147147            firstMissingGlyphElement = toSVGMissingGlyphElement(element);
     
    163163}
    164164
    165 static bool stringMatchesUnicodeRange(const String& unicodeString, const UnicodeRanges& ranges, const HashSet<String>& unicodeValues)
     165void SVGKerningMap::clear()
     166{
     167    unicodeMap.clear();
     168    glyphMap.clear();
     169    kerningUnicodeRangeMap.clear();
     170}
     171
     172void SVGKerningMap::insert(const SVGKerningPair& kerningPair)
     173{
     174    SVGKerning svgKerning;
     175    svgKerning.kerning = kerningPair.kerning;
     176    svgKerning.unicodeRange2 = kerningPair.unicodeRange2;
     177    svgKerning.unicodeName2 = kerningPair.unicodeName2;
     178    svgKerning.glyphName2 = kerningPair.glyphName2;
     179
     180    HashSet<String>::const_iterator uIt = kerningPair.unicodeName1.begin();
     181    const HashSet<String>::const_iterator uEnd = kerningPair.unicodeName1.end();
     182    for (; uIt != uEnd; ++uIt) {
     183        if (unicodeMap.contains(*uIt))
     184            unicodeMap.get(*uIt)->append(svgKerning);
     185        else {
     186            OwnPtr<SVGKerningVector> newVector = adoptPtr(new SVGKerningVector);
     187            newVector->append(svgKerning);
     188            unicodeMap.add(*uIt, newVector.release());
     189        }
     190    }
     191
     192    HashSet<String>::const_iterator gIt = kerningPair.glyphName1.begin();
     193    const HashSet<String>::const_iterator gEnd = kerningPair.glyphName1.end();
     194    for (; gIt != gEnd; ++gIt) {
     195        if (glyphMap.contains(*gIt))
     196            glyphMap.get(*gIt)->append(svgKerning);
     197        else {
     198            OwnPtr<SVGKerningVector> newVector = adoptPtr(new SVGKerningVector);
     199            newVector->append(svgKerning);
     200            glyphMap.add(*gIt, newVector.release());
     201        }
     202    }
     203
     204    if (!kerningPair.unicodeRange1.isEmpty())
     205        kerningUnicodeRangeMap.append(kerningPair);
     206}
     207
     208static inline bool stringMatchesUnicodeRange(const String& unicodeString, const UnicodeRanges& ranges)
    166209{
    167210    if (unicodeString.isEmpty())
     
    177220    }
    178221
    179     if (!unicodeValues.isEmpty())
    180         return unicodeValues.contains(unicodeString);
    181    
    182222    return false;
    183223}
    184224
    185 static bool stringMatchesGlyphName(const String& glyphName, const HashSet<String>& glyphValues)
     225static inline bool stringMatchesGlyphName(const String& glyphName, const HashSet<String>& glyphValues)
    186226{
    187227    if (glyphName.isEmpty())
    188228        return false;
    189229
    190     if (!glyphValues.isEmpty())
    191         return glyphValues.contains(glyphName);
    192    
    193     return false;
    194 }
    195 
    196 static bool matches(const String& u1, const String& g1, const String& u2, const String& g2, const SVGKerningPair& kerningPair)
    197 {
    198     if (!stringMatchesUnicodeRange(u1, kerningPair.unicodeRange1, kerningPair.unicodeName1)
    199         && !stringMatchesGlyphName(g1, kerningPair.glyphName1))
     230    return glyphValues.contains(glyphName);
     231}
     232
     233static inline bool stringMatchesUnicodeName(const String& unicodeName, const HashSet<String>& unicodeValues)
     234{
     235    if (unicodeName.isEmpty())
    200236        return false;
    201237
    202     if (!stringMatchesUnicodeRange(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)
    203         && !stringMatchesGlyphName(g2, kerningPair.glyphName2))
    204         return false;
    205 
    206     return true;
    207 }
    208 
    209 static float kerningForPairOfStringsAndGlyphs(const KerningPairVector& kerningPairs, const String& u1, const String& g1, const String& u2, const String& g2)
    210 {
    211     KerningPairVector::const_iterator it = kerningPairs.end() - 1;
    212     const KerningPairVector::const_iterator begin = kerningPairs.begin() - 1;
    213     for (; it != begin; --it) {
    214         if (matches(u1, g1, u2, g2, *it))
    215             return it->kerning;
     238    return unicodeValues.contains(unicodeName);
     239}
     240
     241static inline bool matches(const String& u2, const String& g2, const SVGKerning& svgKerning)
     242{
     243    return stringMatchesGlyphName(g2, svgKerning.glyphName2)
     244        || stringMatchesUnicodeName(u2, svgKerning.unicodeName2)
     245        || stringMatchesUnicodeRange(u2, svgKerning.unicodeRange2);
     246}
     247
     248static inline bool matches(const String& u1, const String& u2, const String& g2, const SVGKerningPair& svgKerningPair)
     249{
     250    return stringMatchesUnicodeRange(u1, svgKerningPair.unicodeRange1) && matches(u2, g2, svgKerningPair);
     251}
     252
     253static inline float kerningForPairOfStringsAndGlyphs(const SVGKerningMap& kerningMap, const String& u1, const String& g1, const String& u2, const String& g2)
     254{
     255    if (!g1.isEmpty() && kerningMap.glyphMap.contains(g1)) {
     256        SVGKerningVector* kerningVector = kerningMap.glyphMap.get(g1);
     257        SVGKerningVector::const_iterator it = kerningVector->end() - 1;
     258        const SVGKerningVector::const_iterator begin = kerningVector->begin() - 1;
     259        for (; it != begin; --it) {
     260            if (matches(u2, g2, *it))
     261                return it->kerning;
     262        }
     263    }
     264
     265    if (!u1.isEmpty()) {
     266        if (kerningMap.unicodeMap.contains(u1)) {
     267            SVGKerningVector* kerningVector = kerningMap.unicodeMap.get(u1);
     268            SVGKerningVector::const_iterator it = kerningVector->end() - 1;
     269            const SVGKerningVector::const_iterator begin = kerningVector->begin() - 1;
     270            for (; it != begin; --it) {
     271                if (matches(u2, g2, *it))
     272                    return it->kerning;
     273            }
     274        }
     275
     276        if (!kerningMap.kerningUnicodeRangeMap.isEmpty()) {
     277            Vector<SVGKerningPair>::const_iterator it = kerningMap.kerningUnicodeRangeMap.end() - 1;
     278            const Vector<SVGKerningPair>::const_iterator begin = kerningMap.kerningUnicodeRangeMap.begin() - 1;
     279            for (; it != begin; --it) {
     280                if (matches(u1, u2, g2, *it))
     281                    return it->kerning;
     282            }
     283        }
    216284    }
    217285
     
    221289float SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const
    222290{
    223     if (m_horizontalKerningPairs.isEmpty())
     291    if (m_horizontalKerningMap.isEmpty())
    224292        return 0;
    225293
    226     return kerningForPairOfStringsAndGlyphs(m_horizontalKerningPairs, u1, g1, u2, g2);
     294    return kerningForPairOfStringsAndGlyphs(m_horizontalKerningMap, u1, g1, u2, g2);
    227295}
    228296
    229297float SVGFontElement::verticalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const
    230298{
    231     if (m_verticalKerningPairs.isEmpty())
     299    if (m_verticalKerningMap.isEmpty())
    232300        return 0;
    233301
    234     return kerningForPairOfStringsAndGlyphs(m_verticalKerningPairs, u1, g1, u2, g2);
     302    return kerningForPairOfStringsAndGlyphs(m_verticalKerningMap, u1, g1, u2, g2);
    235303}
    236304
  • trunk/Source/WebCore/svg/SVGFontElement.h

    r155815 r156393  
    3232namespace WebCore {
    3333
    34 // Describe an SVG <hkern>/<vkern> element
    35 struct SVGKerningPair {
     34// Describe an SVG <hkern>/<vkern> element already matched on the first symbol.
     35struct SVGKerning {
    3636    float kerning;
    37     UnicodeRanges unicodeRange1;
    3837    UnicodeRanges unicodeRange2;
    39     HashSet<String> unicodeName1;
    4038    HashSet<String> unicodeName2;
    41     HashSet<String> glyphName1;
    4239    HashSet<String> glyphName2;
    43    
    44     SVGKerningPair()
     40
     41    SVGKerning()
    4542        : kerning(0)
    46     {
    47     }
     43    { }
    4844};
    4945
    50 typedef Vector<SVGKerningPair> KerningPairVector;
     46// Describe an SVG <hkern>/<vkern> element
     47struct SVGKerningPair : public SVGKerning {
     48    UnicodeRanges unicodeRange1;
     49    HashSet<String> unicodeName1;
     50    HashSet<String> glyphName1;
     51};
     52
     53typedef Vector<SVGKerning> SVGKerningVector;
     54
     55struct SVGKerningMap {
     56    HashMap<String, OwnPtr<SVGKerningVector> > unicodeMap;
     57    HashMap<String, OwnPtr<SVGKerningVector> > glyphMap;
     58    Vector<SVGKerningPair> kerningUnicodeRangeMap;
     59
     60    bool isEmpty() const { return unicodeMap.isEmpty() && glyphMap.isEmpty() && kerningUnicodeRangeMap.isEmpty(); }
     61    void clear();
     62    void insert(const SVGKerningPair&);
     63};
    5164
    5265class SVGMissingGlyphElement;   
     
    8295    END_DECLARE_ANIMATED_PROPERTIES
    8396
    84     KerningPairVector m_horizontalKerningPairs;
    85     KerningPairVector m_verticalKerningPairs;
     97    SVGKerningMap m_horizontalKerningMap;
     98    SVGKerningMap m_verticalKerningMap;
    8699    SVGGlyphMap m_glyphMap;
    87100    Glyph m_missingGlyph;
  • trunk/Source/WebCore/svg/SVGHKernElement.cpp

    r155815 r156393  
    6060}
    6161
    62 void SVGHKernElement::buildHorizontalKerningPair(KerningPairVector& kerningPairs)
     62void SVGHKernElement::buildHorizontalKerningPair(SVGKerningMap& kerningMap)
    6363{
    6464    String u1 = fastGetAttribute(SVGNames::u1Attr);
     
    7575        && parseKerningUnicodeString(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)) {
    7676        kerningPair.kerning = fastGetAttribute(SVGNames::kAttr).string().toFloat();
    77         kerningPairs.append(kerningPair);
     77        kerningMap.insert(kerningPair);
    7878    }
    7979}
  • trunk/Source/WebCore/svg/SVGHKernElement.h

    r155815 r156393  
    3232    static PassRefPtr<SVGHKernElement> create(const QualifiedName&, Document&);
    3333
    34     void buildHorizontalKerningPair(KerningPairVector&);
     34    void buildHorizontalKerningPair(SVGKerningMap&);
    3535
    3636private:
  • trunk/Source/WebCore/svg/SVGVKernElement.cpp

    r155815 r156393  
    6161}
    6262
    63 void SVGVKernElement::buildVerticalKerningPair(KerningPairVector& kerningPairs)
     63void SVGVKernElement::buildVerticalKerningPair(SVGKerningMap& kerningMap)
    6464{
    6565    String u1 = fastGetAttribute(SVGNames::u1Attr);
     
    7676        && parseKerningUnicodeString(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)) {
    7777        kerningPair.kerning = fastGetAttribute(SVGNames::kAttr).string().toFloat();
    78         kerningPairs.append(kerningPair);
     78        kerningMap.insert(kerningPair);
    7979    }
    8080}
  • trunk/Source/WebCore/svg/SVGVKernElement.h

    r155815 r156393  
    3131    static PassRefPtr<SVGVKernElement> create(const QualifiedName&, Document&);
    3232
    33     void buildVerticalKerningPair(KerningPairVector&);
     33    void buildVerticalKerningPair(SVGKerningMap&);
    3434
    3535private:
Note: See TracChangeset for help on using the changeset viewer.