SVG text bare minimum


Hi Jules,

I'd like to help with implementing a bare minimum SVG text support, i.e. positioning, color, font (but no tspan support), this for easing localization of SVGs. Could you give a hint on what to think about in SVGState::parseText to get me started ?





Hi Rob

Would love to help, but without spending a long time reading the SVG specs I don't really have much to offer! The aim will be to return a DrawableText object, so I guess that if a font, colour and transform can be extracted that'd probably be enough to get something going..


Thanks Jules, that might actually be enough ;)



Ok, here's a start to kick it off :)  :

    Drawable* parseText (const XmlPath& xml)
        Array<float> xCoords, yCoords, dxCoords, dyCoords;
        getCoordList (xCoords,  getInheritedAttribute (xml, "x"),  true, true);
        getCoordList (yCoords,  getInheritedAttribute (xml, "y"),  true, false);
        getCoordList (dxCoords, getInheritedAttribute (xml, "dx"), true, true);
        getCoordList (dyCoords, getInheritedAttribute (xml, "dy"), true, false);
        const float fontSize = getCoordLength(getStyleAttribute(xml, "font-size"), 1.0f);
        int fontStyle = Font::plain;
        const String fontStyleStr = getStyleAttribute(xml, "font-style");
        if (fontStyleStr == "italic")
            fontStyle |= Font::italic;
        const String fontWeight = getStyleAttribute(xml, "font-weight");
        if (fontWeight == "bold")
            fontStyle |= Font::bold;
        const String anchorStr = getStyleAttribute(xml, "text-anchor");
        const String fontFamily = getStyleAttribute(xml, "font-family");
        DrawableComposite* dc = new DrawableComposite();
        forEachXmlChildElement (*xml, e)
            if (e->isTextElement())
                const String text (e->getText().trim());
                GlyphArrangement ga;
                ga.addLineOfText(Font(fontFamily, fontSize, fontStyle), text, xCoords[0], yCoords[0]);
                Rectangle<float> bb = ga.getBoundingBox(0, -1, true);
                if (anchorStr == "middle")
                    ga.moveRangeOfGlyphs(0, -1, -bb.getWidth()/2.0f, 0.f);
                else if (anchorStr == "end")
                    ga.moveRangeOfGlyphs(0, -1, -bb.getWidth(), 0.f);
                Path path;
                dc->addAndMakeVisible( parseShape (xml.getChild (e), path) );
            else if (e->hasTagNameIgnoringNamespace ("tspan"))
                dc->addAndMakeVisible( parseText (xml.getChild (e)) );
        return dc;


Cool. I don't think I have any test SVGs to try it though - do you know of any examples online somewhere?


No, not right off the bat, but I've used Inkscape to create SVGs. I tried to attach a sample file, but the web interface refused it :(


Haha... this was a cool web service: