5

I currently have the following code using Batik's SVGGraphics2D:

...
final SVGGraphics2D svgGraphics2D = new SVGGraphics2D(svgGeneratorContext, false);
svgGraphics2D.setSVGCanvasSize(new Dimension(width, height));
svgGraphics2D.setFont(font);
...

As a result, if font is an available Font on the system on which the code is executed, the correct attribute is added to the resulting SVG file.

However, if the font is missing (for instance "Verdana" on a linux box) a default font is used (font-family:'Dialog' is added).

Thus, instead of specifying a font, I would like to pass a font-family in order to have font-family="DejaVu Sans,Verdana,Geneva,sans-serif" in the resulting SVG. How can I achieve this knowing that, if I'm not wrong, the API only accepts Font parameters ?

I hope that there's a easier way than using a xslt to transform the xml output.

Thank you in advance.

Kraal
  • 2,387
  • 1
  • 14
  • 29
  • Regarding bounty: I'm looking for a general solution to add CSS attributes, not just fonts. The use of SVGGraphics2D is an absolute requirement. – GKFX Jun 07 '17 at 21:22
  • https://stackoverflow.com/questions/38890844/how-to-add-an-attribute-to-an-svg-produced-by-apache-batik and https://stackoverflow.com/questions/14314035/how-to-change-attribute-of-an-svg-image-in-batik-while-in-program ask essentially the same question but provide no answers. There is a possibility that Batic is well and truly dead and just chills on Apache graveyard, and you should search for another Java+SVG library or may be change your approach completely. – Oleg Estekhin Jun 09 '17 at 06:08
  • @OlegEstekhin That is what it looks like. While a real answer would be great, I'm more likely to be accepting some sort of dubious hack that gets the job done, provided it's vaguely reasonable. – GKFX Jun 09 '17 at 06:30

2 Answers2

2

If you have a (licensed) font file, say as resource, you might do:

    InputStream is = SomeClass.getResourceAsStream("/fonts/DejaVu Sans.ttf");
    Font font = Font.createFont(Font.TRUETYPE_FONT, is);
    GraphicsEnvironment.getLocalGraphicsEnvironment();
    ge.registerFont(font);

This is a general way to deliver an application with its own font.

Then in the SVG you can embed the exact font for stand-alone svg files.

I wonder that it is not possible to do:

font-family="'DejaVu Sans',Verdana,Geneva,sans-serif"

as that would be the CSS way.

Joop Eggen
  • 96,344
  • 7
  • 73
  • 121
  • What you've described is what the OP already had, a single font. Embedding the font is one workaround to the OP's problem, but I'll award a bounty to a solution that gives more control over CSS if one appears. Thanks! – GKFX Jun 08 '17 at 04:31
  • 1
    @GKFX indeed I have points enough. But I wanted to mention the capability to provide a font with the application, without the operating system having it installed, and for the final svg embedding it. CSS would be nice. – Joop Eggen Jun 08 '17 at 20:26
0

Given a width, height, and Swing component (label), the following code will export an SVG document with viewBox and font-family attributes set on the root svg element:

final var dom = getDOMImplementation();
final var ns = "http://www.w3.org/2000/svg";
final var doc = dom.createDocument( ns, "svg", null );
final var context = createDefault( doc );
context.setPrecision( 5 );

final var generator = new SVGGraphics2D( context, false );
generator.setSVGCanvasSize( new Dimension( width, height ) );
label.paintComponent( generator );

Element root = generator.getRoot();
final String viewBox = format( "0 0 %d %d", width, height );
root.setAttribute( SVG_VIEW_BOX_ATTRIBUTE, viewBox );
root.setAttribute( "font-family", "Arial" );

try( final var out = new OutputStreamWriter(
    new FileOutputStream( "/tmp/saved.svg" ), UTF_8 ) ) {
  generator.stream( root, out );
}

Produces:

<svg
  stroke-dasharray="none"
  shape-rendering="auto"
  xmlns="http://www.w3.org/2000/svg"
  font-family="Arial"
  width="305"
  text-rendering="auto"
  fill-opacity="1"
  contentScriptType="text/ecmascript"
  color-interpolation="auto"
  color-rendering="auto"
  preserveAspectRatio="xMidYMid meet"
  font-size="12px"
  viewBox="0 0 3 3"
  fill="black"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  stroke="black"
  image-rendering="auto"
  stroke-miterlimit="10"
  zoomAndPan="magnify"
  version="1.0"
  stroke-linecap="square"
  stroke-linejoin="miter"
  contentStyleType="text/css"
  font-style="normal"
  height="311"
  stroke-width="1"
  stroke-dashoffset="0"
  font-weight="normal"
  stroke-opacity="1">
Dave Jarvis
  • 28,853
  • 37
  • 164
  • 291