⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 88557 in webkit


Ignore:
Timestamp:
Jun 10, 2011, 1:15:10 PM (15 years ago)
Author:
Nikolas Zimmermann
Message:

2011-06-10 Nikolas Zimmermann <nzimmermann@rim.com>

Reviewed by Rob Buis.

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
https://bugs.webkit.org/show_bug.cgi?id=59085

Add glyph table to SVGFontElement mapping between SVGGlyph <-> Glyph
https://bugs.webkit.org/show_bug.cgi?id=62441

Preparation patch 1: Introduce the internal glyph table in SVGGlyphMap that will be used to identify each
SVGGlyph identifier with a Glyph (which is just an ushort). It will be used by follow-up patches.

Doesn't affect any test so far.

  • platform/graphics/SVGGlyph.h: (WebCore::SVGGlyph::SVGGlyph): (WebCore::SVGGlyph::operator==):
  • rendering/svg/SVGTextRunRenderingContext.cpp: (WebCore::SVGTextRunWalker::walk):
  • svg/SVGFontData.cpp: (WebCore::SVGFontData::initializeFontData):
  • svg/SVGFontElement.cpp: (WebCore::SVGFontElement::SVGFontElement): (WebCore::SVGFontElement::registerLigaturesInGlyphCache): (WebCore::SVGFontElement::ensureGlyphCache): (WebCore::kerningForPairOfStringsAndGlyphs): (WebCore::SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs): (WebCore::SVGFontElement::verticalKerningForPairOfStringsAndGlyphs): (WebCore::SVGFontElement::collectGlyphsForString): (WebCore::SVGFontElement::collectGlyphsForGlyphName): (WebCore::SVGFontElement::svgGlyphForGlyph): (WebCore::SVGFontElement::missingGlyph):
  • svg/SVGFontElement.h: (WebCore::SVGKerningPair::SVGKerningPair):
  • svg/SVGGlyphMap.h: (WebCore::SVGGlyphMap::addGlyphByUnicodeString): (WebCore::SVGGlyphMap::addGlyphByName): (WebCore::SVGGlyphMap::appendToGlyphTable): (WebCore::SVGGlyphMap::collectGlyphsForString): (WebCore::SVGGlyphMap::clear): (WebCore::SVGGlyphMap::svgGlyphForGlyph): (WebCore::SVGGlyphMap::glyphIdentifierForGlyphName):
Location:
trunk/Source/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r88556 r88557  
     12011-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
    1452011-06-10  Emil A Eklund  <eae@chromium.org>
    246
  • trunk/Source/WebCore/platform/graphics/SVGGlyph.h

    r84498 r88557  
    2525
    2626#if ENABLE(SVG_FONTS)
     27#include "Glyph.h"
    2728#include "Path.h"
    2829
     
    5556        , arabicForm(None)
    5657        , priority(0)
     58        , tableEntry(0)
    5759        , unicodeStringLength(0)
    5860        , horizontalAdvanceX(0)
     
    7577            && orientation == other.orientation
    7678            && arabicForm == other.arabicForm
     79            && tableEntry == other.tableEntry
    7780            && unicodeStringLength == other.unicodeStringLength
    7881            && glyphName == other.glyphName
     
    8992    unsigned arabicForm : 3; // ArabicForm
    9093    int priority;
     94    Glyph tableEntry;
    9195    size_t unicodeStringLength;
    9296    String glyphName;
  • trunk/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp

    r88139 r88557  
    153153                glyphs.append(altGlyphIdentifier);
    154154            else
    155                 m_fontElement->getGlyphIdentifiersForString(lookupString, glyphs);
     155                m_fontElement->collectGlyphsForString(lookupString, glyphs);
    156156
    157157            Vector<SVGGlyph>::iterator it = glyphs.begin();
  • trunk/Source/WebCore/svg/SVGFontData.cpp

    r87152 r88557  
    6060        // Fallback if x_heightAttr is not specified for the font element.
    6161        Vector<SVGGlyph> letterXGlyphs;
    62         associatedFontElement->getGlyphIdentifiersForString(String("x", 1), letterXGlyphs);
     62        associatedFontElement->collectGlyphsForString(String("x", 1), letterXGlyphs);
    6363        xHeight = letterXGlyphs.isEmpty() ? 2 * ascent / 3 : letterXGlyphs.first().horizontalAdvanceX * scale;
    6464    }
     
    7373
    7474    Vector<SVGGlyph> spaceGlyphs;
    75     associatedFontElement->getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs);
     75    associatedFontElement->collectGlyphsForString(String(" ", 1), spaceGlyphs);
    7676    fontData->setSpaceWidth(spaceGlyphs.isEmpty() ? xHeight : spaceGlyphs.first().horizontalAdvanceX * scale);
    7777
    7878    Vector<SVGGlyph> numeralZeroGlyphs;
    79     associatedFontElement->getGlyphIdentifiersForString(String("0", 1), numeralZeroGlyphs);
     79    associatedFontElement->collectGlyphsForString(String("0", 1), numeralZeroGlyphs);
    8080    fontData->setAvgCharWidth(numeralZeroGlyphs.isEmpty() ? fontData->spaceWidth() : numeralZeroGlyphs.first().horizontalAdvanceX * scale);
    8181
    8282    Vector<SVGGlyph> letterWGlyphs;
    83     associatedFontElement->getGlyphIdentifiersForString(String("W", 1), letterWGlyphs);
     83    associatedFontElement->collectGlyphsForString(String("W", 1), letterWGlyphs);
    8484    fontData->setMaxCharWidth(letterWGlyphs.isEmpty() ? ascent : letterWGlyphs.first().horizontalAdvanceX * scale);
    8585
  • trunk/Source/WebCore/svg/SVGFontElement.cpp

    r86050 r88557  
    4242inline SVGFontElement::SVGFontElement(const QualifiedName& tagName, Document* document)
    4343    : SVGStyledElement(tagName, document)
     44    , m_missingGlyph(0)
    4445    , m_isGlyphCacheValid(false)
    4546{
     
    8081}
    8182
    82 void SVGFontElement::ensureGlyphCache() const
     83void 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
     122void SVGFontElement::ensureGlyphCache()
    83123{
    84124    if (m_isGlyphCacheValid)
    85125        return;
    86126
     127    SVGMissingGlyphElement* firstMissingGlyphElement = 0;
     128    Vector<String> ligatures;
    87129    for (Node* child = firstChild(); child; child = child->nextSibling()) {
    88130        if (child->hasTagName(SVGNames::glyphTag)) {
    89131            SVGGlyphElement* glyph = static_cast<SVGGlyphElement*>(child);
    90132            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);
    93147        } else if (child->hasTagName(SVGNames::hkernTag)) {
    94148            SVGHKernElement* hkern = static_cast<SVGHKernElement*>(child);
     
    97151            SVGVKernElement* vkern = static_cast<SVGVKernElement*>(child);
    98152            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
    102171    m_isGlyphCacheValid = true;
    103172}
     
    133202    return false;
    134203}
    135    
     204
    136205static bool matches(const String& u1, const String& g1, const String& u2, const String& g2, const SVGKerningPair& kerningPair)
    137206{
     
    147216}
    148217
    149 static float kerningForPairOfStringsAndGlyphs(KerningPairVector& kerningPairs, const String& u1, const String& g1, const String& u2, const String& g2)
     218static float kerningForPairOfStringsAndGlyphs(const KerningPairVector& kerningPairs, const String& u1, const String& g1, const String& u2, const String& g2)
    150219{
    151220    KerningPairVector::const_iterator it = kerningPairs.end() - 1;
     
    156225    }
    157226
    158     return 0.0f;
     227    return 0;
    159228}
    160229   
     
    162231{
    163232    if (m_horizontalKerningPairs.isEmpty())
    164         return 0.0f;
     233        return 0;
    165234
    166235    return kerningForPairOfStringsAndGlyphs(m_horizontalKerningPairs, u1, g1, u2, g2);
     
    170239{
    171240    if (m_verticalKerningPairs.isEmpty())
    172         return 0.0f;
     241        return 0;
    173242
    174243    return kerningForPairOfStringsAndGlyphs(m_verticalKerningPairs, u1, g1, u2, g2);
    175244}
    176245
    177 void SVGFontElement::getGlyphIdentifiersForString(const String& string, Vector<SVGGlyph>& glyphs) const
    178 {
    179     ensureGlyphCache();
    180     m_glyphMap.get(string, glyphs);
     246void SVGFontElement::collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs)
     247{
     248    ensureGlyphCache();
     249    m_glyphMap.collectGlyphsForString(string, glyphs);
     250}
     251
     252void 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
     259SVGGlyph SVGFontElement::svgGlyphForGlyph(Glyph glyph)
     260{
     261    ensureGlyphCache();
     262    return m_glyphMap.svgGlyphForGlyph(glyph);
     263}
     264   
     265Glyph SVGFontElement::missingGlyph()
     266{
     267    ensureGlyphCache();
     268    return m_missingGlyph;
    181269}
    182270
  • trunk/Source/WebCore/svg/SVGFontElement.h

    r87125 r88557  
    4444   
    4545    SVGKerningPair()
    46         : kerning(0.0f)
     46        : kerning(0)
    4747    {
    4848    }
     
    5959
    6060    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>&);
    6363
    6464    float horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const;
    6565    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
    6771    SVGMissingGlyphElement* firstMissingGlyphElement() const;
    6872
     
    7579    virtual AttributeToPropertyTypeMap& attributeToPropertyTypeMap();
    7680
    77     void ensureGlyphCache() const;
     81    void ensureGlyphCache();
     82    void registerLigaturesInGlyphCache(Vector<String>&);
    7883
    7984    // Animated property declarations
     
    8287    DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
    8388
    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;
    8894};
    8995
  • trunk/Source/WebCore/svg/SVGGlyphMap.h

    r84498 r88557  
    2222
    2323#if ENABLE(SVG_FONTS)
     24#include "SVGGlyph.h"
    2425#include "SVGGlyphElement.h"
     26
     27#include <wtf/HashMap.h>
     28#include <wtf/Vector.h>
    2529
    2630namespace WebCore {
    2731
    2832struct GlyphMapNode;
     33class SVGFontData;
    2934
    3035typedef HashMap<UChar, RefPtr<GlyphMapNode> > GlyphMapLayer;
     
    4651    SVGGlyphMap() : m_currentPriority(0) { }
    4752
    48     void add(const String& string, const SVGGlyph& glyph)
     53    void addGlyphByUnicodeString(const String& string, const SVGGlyph& glyph)
    4954    {
    5055        size_t len = string.length();
     
    6469        if (node) {
    6570            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);
    6977        }
     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);
    7096    }
    7197
     
    75101    }
    76102
    77     void get(const String& string, Vector<SVGGlyph>& glyphs)
     103    void collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs)
    78104    {
    79105        GlyphMapLayer* currentLayer = &m_rootLayer;
    80106
    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) {
    82109            UChar curChar = string[i];
    83110            RefPtr<GlyphMapNode> node = currentLayer->get(curChar);
     
    89116        std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority);
    90117    }
    91 
     118   
    92119    void clear()
    93120    {
    94         m_rootLayer.clear();
     121        m_rootLayer.clear();
     122        m_glyphTable.clear();
    95123        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));
    96138    }
    97139
    98140private:
    99141    GlyphMapLayer m_rootLayer;
     142    Vector<SVGGlyph, 256> m_glyphTable;
     143    HashMap<String, Glyph> m_namedGlyphs;
    100144    int m_currentPriority;
    101145};
     
    104148
    105149#endif // ENABLE(SVG_FONTS)
    106 
    107 
    108150#endif // SVGGlyphMap_h
Note: See TracChangeset for help on using the changeset viewer.