如何在使用Batik的SVGGraphics2D时设置字体族而非字体?

5

我目前使用Batik的SVGGraphics2D,代码如下:

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

因此,如果font在执行代码的系统上是可用的Font,则将正确的属性添加到生成的SVG文件中。
但是,如果缺少字体(例如在Linux框中的“Verdana”),则会使用默认字体(添加font-family:'Dialog')。
因此,我想传递一个font-family而不是指定一个字体,以便在生成的SVG中有font-family="DejaVu Sans,Verdana,Geneva,sans-serif"。如果我没有错,API只接受Font参数,那么我该如何实现这一点?
我希望有更简单的方法,而不是使用xslt来转换xml输出。
提前感谢您。

关于赏金:我正在寻找一个通用的解决方案来添加CSS属性,而不仅仅是字体。必须使用SVGGraphics2D库。 - GKFX
以下两个与编程有关的内容:https://stackoverflow.com/questions/38890844/how-to-add-an-attribute-to-an-svg-produced-by-apache-batik 和 https://stackoverflow.com/questions/14314035/how-to-change-attribute-of-an-svg-image-in-batik-while-in-program 本质上是相同的问题,但没有提供答案。Batic 可能已经死亡并被埋葬在 Apache 墓地中,你应该寻找另一个 Java+SVG 库,或者完全改变你的方法。 - Oleg Estekhin
@OlegEstekhin 这就是它的样子。虽然一个真正的答案会很好,但我更可能接受一些能完成任务的可疑黑客技巧,只要它大致合理。 - GKFX
2个回答

2
如果你有一个(已授权的)字体文件,比如说作为资源,你可以这样做:
    InputStream is = SomeClass.getResourceAsStream("/fonts/DejaVu Sans.ttf");
    Font font = Font.createFont(Font.TRUETYPE_FONT, is);
    GraphicsEnvironment.getLocalGraphicsEnvironment();
    ge.registerFont(font);

这是一种通用的应用程序字体传递方式。

然后在SVG中,您可以嵌入独立的svg文件所需的确切字体。

我想知道是否不可能实现以下操作:

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

因为这是CSS的方式。


你所描述的是OP已经拥有的,一个单一的字体。嵌入字体是解决OP问题的一种方法,但如果有更多控制CSS的解决方案出现,我将授予赏金。谢谢! - GKFX
1
@GKFX 确实我有足够的积分。但是我想提到的是能够在应用程序中提供字体,而无需安装操作系统,并将其嵌入最终的SVG中。CSS会很好。 - Joop Eggen

0

给定一个widthheight和Swing组件(label),以下代码将导出一个带有在根svg元素上设置的viewBoxfont-family属性的SVG文档:

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 );
}

生成:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接