简体   繁体   中英

How can I set a font-family instead of font when using Batik's SVGGraphics2D?

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.

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.

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">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM