bool SVGGlyphRefElement::hasValidGlyphElement(AtomicString& glyphName) const
{
    // FIXME: We only support xlink:href so far.
    // https://bugs.webkit.org/show_bug.cgi?id=64787
    Element* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), document(), &glyphName);
    return isSVGGlyphElement(element);
}
Exemple #2
0
void SVGFontElement::ensureGlyphCache()
{
    if (m_isGlyphCacheValid)
        return;

    KerningPairVector horizontalKerningPairs;
    KerningPairVector verticalKerningPairs;

    SVGMissingGlyphElement* firstMissingGlyphElement = 0;
    Vector<String> ligatures;
    for (SVGElement* element = Traversal<SVGElement>::firstChild(*this); element; element = Traversal<SVGElement>::nextSibling(*element)) {
        if (isSVGGlyphElement(*element)) {
            SVGGlyphElement& glyph = toSVGGlyphElement(*element);
            AtomicString unicode = glyph.fastGetAttribute(SVGNames::unicodeAttr);
            AtomicString glyphId = glyph.getIdAttribute();
            if (glyphId.isEmpty() && unicode.isEmpty())
                continue;

            m_glyphMap.addGlyph(glyphId, unicode, glyph.buildGlyphIdentifier());

            // Register ligatures, if needed, don't mix up with surrogate pairs though!
            if (unicode.length() > 1 && !U16_IS_SURROGATE(unicode[0]))
                ligatures.append(unicode.string());
        } else if (isSVGHKernElement(*element)) {
            toSVGHKernElement(*element).buildHorizontalKerningPair(horizontalKerningPairs);
        } else if (isSVGVKernElement(*element)) {
            toSVGVKernElement(*element).buildVerticalKerningPair(verticalKerningPairs);
        } else if (isSVGMissingGlyphElement(*element) && !firstMissingGlyphElement) {
            firstMissingGlyphElement = toSVGMissingGlyphElement(element);
        }
    }

    // Build the kerning tables.
    buildKerningTable(horizontalKerningPairs, m_horizontalKerningTable);
    buildKerningTable(verticalKerningPairs, m_verticalKerningTable);

    // The glyph-name->glyph-id map won't be needed/used after having built the kerning table(s).
    m_glyphMap.dropNamedGlyphMap();

    // Register each character of each ligature, if needed.
    if (!ligatures.isEmpty())
        registerLigaturesInGlyphCache(ligatures);

    // Register missing-glyph element, if present.
    if (firstMissingGlyphElement) {
        SVGGlyph svgGlyph = SVGGlyphElement::buildGenericGlyphIdentifier(firstMissingGlyphElement);
        m_glyphMap.appendToGlyphTable(svgGlyph);
        m_missingGlyph = svgGlyph.tableEntry;
        ASSERT(m_missingGlyph > 0);
    }

    m_isGlyphCacheValid = true;
}
bool SVGAltGlyphElement::hasValidGlyphElements(Vector<AtomicString>& glyphNames) const
{
    AtomicString target;
    Element* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), treeScope(), &target);
    if (!element)
        return false;

    if (isSVGGlyphElement(*element)) {
        glyphNames.append(target);
        return true;
    }

    if (isSVGAltGlyphDefElement(*element) && toSVGAltGlyphDefElement(*element).hasValidGlyphElements(glyphNames))
        return true;

    return false;
}
void SVGFontElement::ensureGlyphCache()
{
    if (m_isGlyphCacheValid)
        return;

    const SVGMissingGlyphElement* firstMissingGlyphElement = nullptr;
    Vector<String> ligatures;
    for (auto& child : childrenOfType<SVGElement>(*this)) {
        if (isSVGGlyphElement(child)) {
            SVGGlyphElement& glyph = toSVGGlyphElement(child);
            AtomicString unicode = glyph.fastGetAttribute(SVGNames::unicodeAttr);
            AtomicString glyphId = glyph.getIdAttribute();
            if (glyphId.isEmpty() && unicode.isEmpty())
                continue;

            m_glyphMap.addGlyph(glyphId, unicode, glyph.buildGlyphIdentifier());

            // Register ligatures, if needed, don't mix up with surrogate pairs though!
            if (unicode.length() > 1 && !U16_IS_SURROGATE(unicode[0]))
                ligatures.append(unicode.string());
        } else if (isSVGHKernElement(child)) {
            SVGHKernElement& hkern = toSVGHKernElement(child);
            hkern.buildHorizontalKerningPair(m_horizontalKerningMap);
        } else if (isSVGVKernElement(child)) {
            SVGVKernElement& vkern = toSVGVKernElement(child);
            vkern.buildVerticalKerningPair(m_verticalKerningMap);
        } else if (isSVGMissingGlyphElement(child) && !firstMissingGlyphElement)
            firstMissingGlyphElement = &toSVGMissingGlyphElement(child);
    }

    // Register each character of each ligature, if needed.
    if (!ligatures.isEmpty())
        registerLigaturesInGlyphCache(ligatures);

    // Register missing-glyph element, if present.
    if (firstMissingGlyphElement) {
        SVGGlyph svgGlyph = SVGGlyphElement::buildGenericGlyphIdentifier(firstMissingGlyphElement);
        m_glyphMap.appendToGlyphTable(svgGlyph);
        m_missingGlyph = svgGlyph.tableEntry;
        ASSERT(m_missingGlyph > 0);
    }

    m_isGlyphCacheValid = true;
}