Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text in svg not work #164

Closed
vipcxj opened this issue Dec 28, 2017 · 15 comments
Closed

Text in svg not work #164

vipcxj opened this issue Dec 28, 2017 · 15 comments

Comments

@vipcxj
Copy link
Contributor

vipcxj commented Dec 28, 2017

just use the example in use case, An exception "java.lang.ArrayIndexOutOfBoundsException: 0" is thrown from sun.font.CompositeFont.getSlotFont(CompositeFont.java 351).
I think it is a font problem. So I change the font-family of text to the font I add by "useFont" which work well in general html tag. However, it does not help.

@rototor
Copy link
Contributor

rototor commented Dec 28, 2017

@vipcxj could you be so kind and paste the full stack trace? Thank you.

@vipcxj
Copy link
Contributor Author

vipcxj commented Dec 29, 2017

Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
at sun.font.CompositeFont.getSlotFont(CompositeFont.java:351)
at sun.font.CompositeGlyphMapper.initMapper(CompositeGlyphMapper.java:81)
at sun.font.CompositeGlyphMapper.(CompositeGlyphMapper.java:62)
at sun.font.CompositeFont.getMapper(CompositeFont.java:409)
at sun.font.CompositeFont.canDisplay(CompositeFont.java:435)
at java.awt.Font.canDisplay(Font.java:1980)
at sun.font.FontResolver.getIndexFor(FontResolver.java:98)
at sun.font.FontResolver.getFontIndex(FontResolver.java:174)
at sun.font.FontResolver.getFontIndex(FontResolver.java:181)
at java.awt.font.TextLine.getFontAtCurrentPos(TextLine.java:1293)
at java.awt.font.TextLayout.standardInit(TextLayout.java:636)
at java.awt.font.TextLayout.(TextLayout.java:538)
at org.apache.batik.gvt.text.BidiAttributedCharacterIterator.(BidiAttributedCharacterIterator.java:122)
at org.apache.batik.bridge.StrokingTextPainter.computeTextRuns(StrokingTextPainter.java:208)
at org.apache.batik.bridge.StrokingTextPainter.getTextRuns(StrokingTextPainter.java:192)
at org.apache.batik.bridge.StrokingTextPainter.getBounds2D(StrokingTextPainter.java:1083)
at org.apache.batik.bridge.TextNode.getPrimitiveBounds(TextNode.java:243)
at org.apache.batik.gvt.AbstractGraphicsNode.getTransformedPrimitiveBounds(AbstractGraphicsNode.java:854)
at org.apache.batik.gvt.AbstractGraphicsNode.getTransformedBounds(AbstractGraphicsNode.java:820)
at org.apache.batik.gvt.CompositeGraphicsNode.getPrimitiveBounds(CompositeGraphicsNode.java:224)
at org.apache.batik.gvt.CompositeGraphicsNode.getTransformedPrimitiveBounds(CompositeGraphicsNode.java:295)
at org.apache.batik.gvt.AbstractGraphicsNode.getTransformedBounds(AbstractGraphicsNode.java:820)
at org.apache.batik.gvt.CompositeGraphicsNode.getPrimitiveBounds(CompositeGraphicsNode.java:207)
at org.apache.batik.gvt.AbstractGraphicsNode.getBounds(AbstractGraphicsNode.java:768)
at org.apache.batik.gvt.AbstractGraphicsNode.paint(AbstractGraphicsNode.java:443)
at com.openhtmltopdf.svgsupport.PDFTranscoder$1.render(PDFTranscoder.java:209)
at com.openhtmltopdf.pdfboxout.PdfBoxOutputDevice.drawWithGraphics(PdfBoxOutputDevice.java:1370)
at com.openhtmltopdf.svgsupport.PDFTranscoder.transcode(PDFTranscoder.java:203)
at org.apache.batik.transcoder.XMLAbstractTranscoder.transcode(XMLAbstractTranscoder.java:142)
at org.apache.batik.transcoder.SVGAbstractTranscoder.transcode(SVGAbstractTranscoder.java:156)
at com.openhtmltopdf.svgsupport.BatikSVGImage.drawSVG(BatikSVGImage.java:163)
at com.openhtmltopdf.pdfboxout.PdfBoxSVGReplacedElement.paint(PdfBoxSVGReplacedElement.java:61)
at com.openhtmltopdf.pdfboxout.PdfBoxOutputDevice.paintReplacedElement(PdfBoxOutputDevice.java:277)
at com.openhtmltopdf.layout.Layer.paintReplacedElement(Layer.java:639)
at com.openhtmltopdf.layout.Layer.paintReplacedElements(Layer.java:596)
at com.openhtmltopdf.layout.Layer.paint(Layer.java:351)
at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.paintPage(PdfBoxRenderer.java:656)
at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.writePDF(PdfBoxRenderer.java:593)
at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.createPDF(PdfBoxRenderer.java:546)
at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.createPDF(PdfBoxRenderer.java:485)
at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.createPDF(PdfBoxRenderer.java:481)
at com.openhtmltopdf.pdfboxout.PdfRendererBuilder.run(PdfRendererBuilder.java:86)
at com.bolan.fzsystem.core.resource.Html2PdfTransformer.lambda$transformTo$0(Html2PdfTransformer.java:92)
... 213 more

@rototor
Copy link
Contributor

rototor commented Dec 29, 2017

You mean, you tried to render this code:

<html>
<body>
<svg version="1.1"
	 baseProfile="full"
	 width="300" height="200"
	 xmlns="http://www.w3.org/2000/svg">
	<rect width="100%" height="100%" fill="red" />
	<circle cx="150" cy="100" r="80" fill="green" />
	<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>
</body>
</html>

and you always get this exception? I can not reproduce that problem on JDK 1.7, JDK 1.8 and JDK 9 on Mac OS 10.13.2. Works for me, sorry :(

What OS and JDK are you using? The exception is in the JDK font library while trying to paint a character from a composite font. Did you change the text to contain non US-Ascii letters? If you are running on Linux: Are your fonts correctly set up? You are using X11, right?

Something seems strange on your setup, because this simple sample should not cause a exception in the JDK font library.

@vipcxj
Copy link
Contributor Author

vipcxj commented Dec 30, 2017

I am on my vacation. I will try to make a unit test to clear the problem in Tuesday.
My platform is windows, and use the jdk of oracle. I add some Chinese fonts. However, there is no chinese text in the example svg code.

@vipcxj
Copy link
Contributor Author

vipcxj commented Jan 2, 2018

I am wrong. I write a unit test. And everything work properly. My develop environment is windows with sun jdk. However, my product environment is linux with open jdk. So I think open jdk may cause the problem. I will do more test.

@vipcxj
Copy link
Contributor Author

vipcxj commented Jan 2, 2018

test-project
This is a test project. I have test it on a wildfly docker container under linux. And the problem occured.
The offical wildfly docker image use open jdk. So I think it maybe a problem.

@rototor
Copy link
Contributor

rototor commented Jan 2, 2018

I cloned your project and added this lines to the Boot-class

    public static void main(String[] argv){
        new Boot().init();
    }

as I never used WildFly and also have not really an idea about how exactly I would build a docker image out of this... (I don't use docker myself).

Works fine for me with Oracle JDK 8 and Oracle JDK 9 on Mac OS 10.13.2 ... so it may be a problem with the JDK.

-> Does this problem also happen, when you comment out all builder.useFont() lines? If not, try to comment in one font by another to find the problematic font.
-> Can you use JDK 9 (just for testing)? They changed a lot in the font rendering / handling with JDK 9, as they integrated a new font glyph layout engine (HarfBuzz) with JDK 9.

@vipcxj
Copy link
Contributor Author

vipcxj commented Jan 2, 2018

Even I comment out all builder.useFont(), the problem is not solved. In fact, without these font files in the classpath, this code work properly in my develop environment with oracle jdk. These fonts are not used at all. I will try to change the jdk of docker image.

@rototor
Copy link
Contributor

rototor commented Jan 2, 2018

Just an idea: Maybe the docker JDK is not a full JDK but a jre-headless? Or the WildFly server is started with the -headless option? But on the other side if the JDK would be headless it should throw an HeadlessException...

@vipcxj
Copy link
Contributor Author

vipcxj commented Jan 2, 2018

I change a docker container with oracle jdk, and the problem is solved. And the console print out a lot of message about using fallback font LiberationSans for base font Times-Roman ...

@vipcxj
Copy link
Contributor Author

vipcxj commented Jan 2, 2018

By the way, I want to make a watermark by svg. Is this possible? Since watermark need a transparent svg image to override the pdf contents.

@rototor
Copy link
Contributor

rototor commented Jan 2, 2018

Adding a watermark should be possible. Do you want to put the watermark in front or in back of the content? The SVG can be transparent, as you can have alpha etc. in a SVG.

Try the following:

  • Define a page-header for your document
  • Put the SVG in the page-header with position:absolute left/top:0 and width/height set to the maximum size.

The header should be drawn before the all other content. For a sample how to define a header you can look here. When the header is drawn no clipping happens, so the header can overlap the page content.

Another way (which I mostly use for bills to give the bill the wished cooperate identity) is to merge a PDF into the background of the generated PDF. I.e. postprocess the generated PDF using PDFBox. See e.g. here

For your use case just putting the SVG in the header may be the easiest solution.

@rototor
Copy link
Contributor

rototor commented Jan 2, 2018

@danfickle I think this issue can be closed.

@vipcxj
Copy link
Contributor Author

vipcxj commented Jan 2, 2018

@rototor Yes, it can be. However which reason cause this exception is still a problem, incomplete jdk or just open jdk it self. By the way, changing the jdk solved me another exception throw by batik.

@danfickle
Copy link
Owner

Appears to be an upstream issue in RedHat 7.4 which is pulled in by the wildly docker file.

jboss-dockerfiles/base-jdk#8 (comment)

@vipcxj vipcxj closed this as completed Jan 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants