以编程方式将viewBox渲染为新的SVGDocument

时间:2019-06-28 16:51:32

标签: java svg batik

我有一个SVGDocument,已通过编程方式从数据库连接中检索为byte[]<svg>元素包含一个适当的viewBox属性,该属性覆盖了现有流程需要呈现为PDF的SVGDocument的一部分。

使用以下(简单)代码,我能够验证viewBox属性是否正确设置:

Element rootElement = svgDocument.getRootElement();
String viewBox = rootElement.getAttribute("viewBox");
log.debug("viewBox={}", viewBox);
// viewBox=-612 0 1224 792

我的目标是使用蜡染getEnclosureList()方法检索NodeList并构建一个新的(裁剪的)SVGDocument,然后将其发送到将呈现PDF的旧式流程。

我尝试使用的代码如下:

SVGRect rectangle = svgDocument.getRootElement().createSVGRect();
rectangle.setX(minX);  // -612
rectangle.setY(minY); // 0
rectangle.setWidth(startingX); // 1224
rectangle.setHeight(startingY); // 792

NodeList croppedNodes = svgDocument.getRootElement().getEnclosureList(rectangle, null);

我的问题是,当我使用这种方法时,SVGSVGContext为null。

我尝试找到如何设置SVGSVGContext的尝试并未成功,这就是为什么我决定在此处发布问题的原因。

使用该解决方案的Apache Batik并没有让我失望,但似乎getEnclosureList()方法可能会返回我完成任务所需的信息。

1 个答案:

答案 0 :(得分:0)

从大量的源代码中开始,我认为我找到了我需要做的事情的答案,这在initSvgDom()方法中有详细说明:

private void someMethod(SVGDocument svgDocument) {
   initSvgDom(svg);

   Element rootElement = svg.getRootElement();

   String viewBox = rootElement.getAttribute("viewBox");
   log.debug("viewBox={}", viewBox);

   String[] viewBoxArray = viewBox.split(" ");

   float minX = Float.valueOf(viewBoxArray[0]);
   float minY = Float.valueOf(viewBoxArray[1]);
   float startingX = Float.valueOf(viewBoxArray[2]);
   float startingY = Float.valueOf(viewBoxArray[3]);

   SVGRect rectangle = svgDocument.getRootElement().createSVGRect();
   rectangle.setX(minX);
   rectangle.setY(minY);
   rectangle.setWidth(startingX);
   rectangle.setHeight(startingY);

   NodeList nodes = svgDocument.getRootElement().getEnclosureList(rectangle, null);

   // nodes contains a list of elements within the specified rectangle, which matches the value of the viewBox within the svgDocument.
  ... do stuff with nodes
}

private void initSvgDom(Document document) {
   UserAgent userAgent = new UserAgentAdapter();
   DocumentLoader loader = new DocumentLoader(userAgent);
   BridgeContext bridgeContext = new BridgeContext(userAgent, loader);
   bridgeContext.setDynamicState(BridgeContext.DYNAMIC);

   (new GVTBuilder()).build(bridgeContext, document);
}