svgSalamander icon indicating copy to clipboard operation
svgSalamander copied to clipboard

Missing Text, if clipping in any object is present

Open jnvoigt opened this issue 6 years ago • 0 comments

If clip-path with a value that is not "none" is present it will clip the Content from any Text-Element. We want to use salamander to render charts from a weblibrary for generating charts.

image
How it should look

image
How it looks rendered with salamander

Sample:

<svg version="1.1"  xmlns="http://www.w3.org/2000/svg" width="350" height="100">
    <defs>
        <clipPath id="clipping">
            <rect x="0" y="0" width="508" height="299" fill="none"></rect>
        </clipPath>
    </defs>
    <g clip-path="url(#clipping)">
        <path fill="rgb(124,181,236)" fill-opacity="0.5"
              d="M 27 14.5 A 22.5 22.5 0 1 1 37 34 Z" stroke="#7cb5ec"
              stroke-width="1" ></path>
    </g>
    <text x="100" text-anchor="middle"  style="color:#333333;font-size:18px;fill:#333333;" y="24">
        <tspan>Missing Text</tspan>
    </text>
</svg>

Rendering Code:

public final class SalamanderSvgConverter {
    private Dimension diagramSize(SVGDiagram diagram) throws IOException {
        int width = (int)Math.ceil((double)diagram.getWidth());
        int height = (int)Math.ceil((double)diagram.getHeight());
        if (width > 0 && height > 0) {
            return new Dimension(width, height);
        } else {
            try {
                Rectangle2D boundingBox = diagram.getRoot().getBoundingBox();
                return new Dimension((int)Math.ceil(boundingBox.getWidth()), (int)Math.ceil(boundingBox.getHeight()));
            } catch (SVGException var5) {
                throw new IOException(var5);
            }
        }
    }

    public void convertToPng(InputStream in, OutputStream out, Dimension size) throws IOException {
        SVGDiagram diagram = this.getDiagram(in);
        Dimension dSize = this.diagramSize(diagram);
        if (size == null) {
            size = new Dimension(dSize);
        }

        BufferedImage image = new BufferedImage(size.width, size.height, 2);
        Graphics2D g = image.createGraphics();

        try {
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            g.setBackground(new Color(0, true));
            if (dSize.width > 0 && dSize.height > 0) {
                AffineTransform transform = new AffineTransform();
                transform.setToScale((double)size.width / (double)dSize.width, (double)size.height / (double)dSize.height);
                g.setTransform(transform);
            }

            try {
                diagram.render(g);
            } catch (SVGException var12) {
                throw new IOException(var12);
            }
        } finally {
            g.dispose();
        }

        ImageIO.write(image, "png", out);
    }

    private SVGDiagram getDiagram(InputStream in) throws IOException {
        SVGUniverse universe = SVGCache.getSVGUniverse();
        URI uri = universe.loadSVG(in, "/dummy", true);
        return universe.getDiagram(uri);
    }
}

jnvoigt avatar Apr 30 '18 11:04 jnvoigt