Skip to content
carlosame edited this page Jul 9, 2024 · 6 revisions

The echosvg-svggen module can generate SVG images using an SVG-specific Graphics2D implementation. Assuming that you are familiar with Graphics2D, the following example shows the basic usage of svggen.

First, let's have an example class that writes to a Graphics2D. Please change the used fonts if you prefer others, or your system does not have them installed.

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.TextAttribute;
import java.util.HashMap;
import java.util.Map;

/**
 * Draw text with decoration attributes.
 */
public class FontDecorationPainter {

    @Override
    public void paint(Graphics2D g) {
        // Set anti-aliasing
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // Set a background color
        Color backgroundColor = new Color(0x08081a);
        g.setBackground(backgroundColor);

        // Set default font
        g.setFont(new Font("Arial", Font.BOLD, 12));

        // Create a font with the desired attributes, including STRIKETHROUGH
        Map<TextAttribute, Object> attributes = new HashMap<>();
        attributes.put(TextAttribute.FAMILY, "Helvetica");
        attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_EXTRABOLD);
        attributes.put(TextAttribute.SIZE, 20);
        attributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
        Font fontST = new Font(attributes);

        // A similar font but with UNDERLINE instead of STRIKETHROUGH
        Map<TextAttribute, Object> attributes2 = new HashMap<>(attributes);
        attributes2.remove(TextAttribute.STRIKETHROUGH);
        attributes2.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
        Font fontUL = new Font(attributes2);

        // Set the STRIKETHROUGH font and a color
        g.setFont(fontST);
        g.setPaint(new Color(0x666699));
        // Draw a string
        g.drawString("Strike Through", 10, 40);

        // Now draw with a different color and the UNDERLINE font
        g.setPaint(Color.black);
        g.setFont(fontUL);
        g.translate(0, 30);
        // Draw a new string
        g.drawString("Underline", 10, 70);
    }

}

Then we need a few svggen classes to produce the SVG.

import java.awt.Dimension;
import java.awt.Font;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;

import io.sf.carte.echosvg.svggen.SVGGeneratorContext;
import io.sf.carte.echosvg.svggen.SVGGeneratorContext.GraphicContextDefaults;
import io.sf.carte.echosvg.svggen.SVGGraphics2D;

public class SVGGraphics2DExample {

    /**
     * Generate SVG from the drawings of the <code>FontDecorationPainter</code> class.
     * 
     * @param filename the filename to write the SVG to.
     * @throws IOException in case of I/O error.
     */
    public static void generateSVG(String filename) throws IOException {
        FontDecorationPainter painter = new FontDecorationPainter();

        SVGGraphics2D g2d = createSVGGraphics2D();

        // Set some appropriate dimension
        g2d.setSVGCanvasSize(new Dimension(300, 400));

        try (FileWriter fw = new FileWriter(filename, StandardCharsets.UTF_8)) {
            painter.paint(g2d);
            g2d.stream(fw);
            fw.flush();
        }
    }

    /**
     * Creates a <code>SVGGraphics2D</code> with certain defaults.
     * 
     * @return the <code>SVGGraphics2D</code>.
     */
    static SVGGraphics2D createSVGGraphics2D() {
        // We need a Document that holds an SVG root element.
        // First obtain a DocumentBuilder as a way to get it.
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);

        DocumentBuilder builder;
        try {
            builder = factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            throw new IllegalStateException(e);
        }

        // Now the document which is what is needed
        Document doc = builder.newDocument();
        
        // Create a SVG DTD
        DocumentType dtd = builder.getDOMImplementation().createDocumentType("svg",
                "-//W3C//DTD SVG 1.1//EN",
                "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd");
        // And the root element in the SVG namespace
        Element svgRoot = doc.createElementNS("http://www.w3.org/2000/svg", "svg");

        // Append those to the document
        doc.appendChild(dtd);
        doc.appendChild(svgRoot);

        /*
         * Now the document is ready: let's create some context objects and
         * then the SVGGraphics2D.
         */

        // For simplicity, create a generator context with some defaults
        SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(doc);
        // Set a comment to put in the SVG documents, overriding the default
        ctx.setComment("Generated by My Application");

        // Create the context defaults, with a default font just in case
        GraphicContextDefaults defaults = new GraphicContextDefaults();
        defaults.setFont(new Font("Arial", Font.PLAIN, 12));
        // Set the defaults
        ctx.setGraphicContextDefaults(defaults);
        // We want *some* precision
        ctx.setPrecision(9);

        return new SVGGraphics2D(ctx, false);
    }

}

and executing the generateSVG("filename.svg") method, the SVG would be written to the filename.svg file.

Clone this wiki locally