2016-08-15 6 views
0

私はFlyingSaucerのITextRendererを使用して、XMLとCSSからPDFを作成しています。 SVG画像を参照するCSS背景画像を指定したいと思います。私はPNGでうまく動作しますが、SVGイメージでは動作しません。フライングソーサー付きSVG背景イメージ

SVGノードを置き換えるためにChainedReplacedElementFactoryを作成しようとしましたが、これらのSVGファイルはドキュメントから参照されず、url()を介してCSSから参照されるため動作しません。

FlyingSaucerにCSSから参照されるSVGファイルを扱う方法を教える方法はありますか?

答えて

0

私はこれを理解することができました。そのトリックは、ユーザーエージェントをカスタマイズすることです。その後

class CustomUserAgent extends ITextUserAgent 
{ 
    private final ITextOutputDevice mDevice; 

    public CustomUserAgent(ITextOutputDevice dev) 
    { 
    super(dev); 
    mDevice = dev; 
    } 

    private static final SAXSVGDocumentFactory mFactory = 
    new SAXSVGDocumentFactory(null); 

    private ImageResource getSVGImage(String uri) 
    throws IOException, BadElementException 
    { 
    InputStream is = null; 

    try 
    { 
     is = resolveAndOpenStream(uri); 
     InputStreamReader isr = new InputStreamReader(is); 
     Document doc = mFactory.createSVGDocument(null, isr); 
     UserAgent ua = new UserAgentAdapter(); 
     DocumentLoader loader = new DocumentLoader(ua); 
     BridgeContext ctx = new BridgeContext(ua, loader); 
     ctx.setDynamicState(BridgeContext.DYNAMIC); 
     GVTBuilder builder = new GVTBuilder(); 
     String not_numbers = "[^0-9.,]"; 
     float width = 
     Float.parseFloat(doc.getDocumentElement(). 
         getAttribute("width").replaceAll(not_numbers, "")); 
     float height = 
     Float.parseFloat(doc.getDocumentElement(). 
         getAttribute("height").replaceAll(not_numbers, "")); 
     PdfWriter writer = mDevice.getWriter(); 
     PdfTemplate templ = PdfTemplate.createTemplate(writer, width, height); 
     Graphics2D g2d = templ.createGraphics(width, height); 
     GraphicsNode gfx = builder.build(ctx, doc); 
     gfx.paint(g2d); 
     g2d.dispose(); 
     Image img = new ImgTemplate(templ); 
     img.setAlignment(Image.ALIGN_CENTER); 

     SharedContext shctx = getSharedContext(); 
     float dpi = shctx.getDotsPerPixel(); 
     if (dpi != 1.0f) 
     img.scaleAbsolute(img.getPlainWidth() * dpi, 
          img.getPlainHeight() * dpi); 

     return new ImageResource(uri, new ITextFSImage(img)); 
    } 
    finally 
    { 
     if (is != null) 
     is.close(); 
    } 
    } 

    @Override 
    public ImageResource getImageResource(String uri) 
    { 
    if (uri.endsWith(".svg")) 
    { 
     try 
     { return (getSVGImage(uri)); } 
     catch(IOException io) 
     { throw new RuntimeException(io); } 
     catch(BadElementException be) 
     { throw new RuntimeException(be); } 
    } 
    else 
     return (super.getImageResource(uri)); 
    } 
} 

それを使用するあなただけのレンダラに適用します:

CustomUserAgent callback = 
    new CustomUserAgent(renderer.getOutputDevice()); 
callback.setSharedContext(renderer.getSharedContext()); 
renderer.getSharedContext().setUserAgentCallback(callback); 
+0

我々は我々のプロジェクトでこのコードを使用し、それが動作することがわかりました。しかし、複数のスレッドによって使用される場合、mFactory.createSVGDocument(null、isr)は乱数NullPointerExceptionsをスローし始めます。これの根本的な原因は、mFactoryがstaticとして宣言されていることです。この問題を解決するために、静的宣言を削除しました。 – webguy

関連する問題