danfickle/openhtmltopdf

SVG Attributes NullPointerException

Closed this issue · 8 comments

com.openhtmltopdf.css-parse WARNING:: (null) clip-path is an unrecognized CSS property at line 0. Ignoring declaration. java.lang.NullPointerException at com.openhtmltopdf.swing.NaiveUserAgent$DefaultUriResolver.resolveURI(NaiveUserAgent.java:470) at com.openhtmltopdf.swing.NaiveUserAgent.resolveUri(NaiveUserAgent.java:522) at com.openhtmltopdf.css.parser.CSSParser.getTokenValue(CSSParser.java:1955) at com.openhtmltopdf.css.parser.CSSParser.getTokenValue(CSSParser.java:1922) at com.openhtmltopdf.css.parser.CSSParser.term(CSSParser.java:1601) at com.openhtmltopdf.css.parser.CSSParser.expr(CSSParser.java:1367) at com.openhtmltopdf.css.parser.CSSParser.declaration(CSSParser.java:1304) at com.openhtmltopdf.css.parser.CSSParser.declaration_list(CSSParser.java:743) at com.openhtmltopdf.css.parser.CSSParser.parseDeclaration(CSSParser.java:108) at com.openhtmltopdf.context.StylesheetFactoryImpl.parseStyleDeclaration(StylesheetFactoryImpl.java:109) at com.openhtmltopdf.css.newmatch.Matcher.getElementStyle(Matcher.java:298) at com.openhtmltopdf.css.newmatch.Matcher.access$700(Matcher.java:48) at com.openhtmltopdf.css.newmatch.Matcher$Mapper.getCascadedStyle(Matcher.java:413) at com.openhtmltopdf.css.newmatch.Matcher.getCascadedStyle(Matcher.java:90) at com.openhtmltopdf.context.StyleReference.getCascadedStyle(StyleReference.java:205) at com.openhtmltopdf.layout.SharedContext.getStyle(SharedContext.java:543) at com.openhtmltopdf.layout.SharedContext.getStyle(SharedContext.java:522) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:209) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:224) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:219) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:224) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:219) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:219) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:219) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:219) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:219) at com.openhtmltopdf.bidi.ParagraphSplitter.splitParagraphs(ParagraphSplitter.java:219) at com.openhtmltopdf.bidi.ParagraphSplitter.splitRoot(ParagraphSplitter.java:177) at com.openhtmltopdf.layout.BoxBuilder.splitParagraphs(BoxBuilder.java:93) at com.openhtmltopdf.layout.BoxBuilder.createRootBox(BoxBuilder.java:99) at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.layout(PdfBoxRenderer.java:430) at com.openhtmltopdf.pdfboxout.PdfRendererBuilder.run(PdfRendererBuilder.java:85) at maven.test1.exportToPdfBox(test1.java:53) at maven.test1.main(test1.java:21)

SVG : https://github.com/mapleLeat/maple/blob/master/test

<g transform="matrix(1 0 0 1 0 0)" style="clip-path:url(#SVGID_252_);enable-background:new ;">

"clip-path:url(#SVGID_252_);"
I try to delete this css attribute and the code can run normally.
But if delete the attribute, svg will not be complete.

Is it because of the reason that "clip-path" is not supported?

Yes, according to stack trace it's unsupported CSS property style.

clip-path is an unrecognized CSS property at line 0

@delafer thanks
Can you add this support?
Without this support, some svg displays are incomplete

Your stack trace presents a number of issues, primary that CSS resolution and BIDI should not be performed on replaced elements. However, you can still get it to work, even without downloading and building the source:

  • Make sure you are using absolute urls for your images embedded in SVGs, relative URLs don't work at this stage.
  • Use a width and height attribute on the SVG, we had an issue (now fixed) where CSS width and height was relied upon.
  • Provide a base url to the builder, even a fake one will do, just so long as it is a valid URI and it is not null.
  • Apache Batik hanged when I tried to use an animated gif as the embedded image in SVG, so perhaps avoid gifs.

In working on fixing the replaced elements support I went ahead and created an example of all our replaced elements, so I know if I break anything. The example may be useful for others and is presented below.

<html>
<head>
<style>
@page {
	size: 1520px 4000px;
    margin: 0;
}
body {
	margin: 10px;
}
svg, object, img, math.example {
  border: 2px solid green;
}	
math.example {
   width: 50%;	
}
</style>
</head>
<body>
<br />
<h1>Replaced Elements</h1>
<h2>Images</h2>

<img src="images/image.png"/>
<img src="images/image.jpg"/>
<img src="images/image.gif"/>

<h2>SVG</h2>

<svg version="1.0" id="container_25_r" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 53.86 53.86" style="width: 150px; height: 150px;" width="150" height="150" xml:space="preserve">
<style type="text/css">
	.st0{fill:#FFFFFF;}
	.st1{fill-rule:evenodd;clip-rule:evenodd;fill:none;}
</style>
<g>
	<defs>
		<polygon id="SVGID_251_" points="26.92885,0.99395 31.56755,5.39775 37.59485,3.26125 40.04095,9.17065 46.41705,9.67015 
			46.24705,16.06305 51.86875,19.11285 49.11315,24.88435 53.00875,29.95685 48.14315,34.10975 49.63915,40.32715 
			43.50595,42.14225 42.34265,48.43085 36.00185,47.59385 32.38125,52.86605 26.92885,49.52285 21.47795,52.86605 
			17.85655,47.59385 11.51655,48.43085 10.35325,42.14225 4.22005,40.32715 5.71445,34.10975 0.85125,29.95685 4.74525,24.88435 
			1.98975,19.11285 7.61135,16.06305 7.44225,9.67015 13.81825,9.17065 16.26435,3.26125 22.29165,5.39775 		"></polygon>
	</defs>
	<clipPath id="SVGID_252_">
		<use xlink:href="#SVGID_251_" style="overflow:visible;"></use>
	</clipPath>
	<g transform="matrix(1 0 0 1 0 0)" style="clip-path:url(#SVGID_252_);enable-background:new    ;">
		    <!-- Note the absolute url below. -->
			<image style="overflow:visible;" width="520.4808834253568" height="522.6677778935306" xlink:href="file:///Users/me/Documents/pdf-issues/images/image.png" transform="matrix(0.1642 0 0 0.17775 -8.975796699523926 -20.824996948242188)">
		</image>
	</g>
</g>
<path class="st0" d="M42.24622,20.57948c0.06494-2.0756-1.60019-3.75997-3.57318-3.75997
	c-0.08899,0-0.17156,0.01924-0.25975,0.02806c-0.756-2.87971-3.23486-5.00581-6.21318-5.00581
	c-2.76506,0-5.11084,1.83509-6.03279,4.40373c-0.41207-0.13468-0.83777-0.22848-1.29073-0.22848
	c-2.39307,0-4.44703,2.04433-4.3364,4.56247c0.06414,1.48635,1.29234,2.40831,2.31611,2.40831c4.33078,0,15.78628,0,16.89583,0
	C41.12705,22.98779,42.19171,22.26546,42.24622,20.57948z"></path>
<rect x="0.85125" y="0.99395" class="st1" width="52.1575" height="51.8721"></rect>
</svg>

<h2>MathML</h2>

<math xmlns="http://www.w3.org/1998/Math/MathML" class="example">
<mrow>
  <mi>x</mi>
  <mo>=</mo>
  <mfrac>
    <mrow>
      <mrow>
        <mo>-</mo>
        <mi>b</mi>
      </mrow>
      <mo>&#x022e3;</mo>
      <msqrt>
        <mrow>
          <msup>
            <mi>b</mi>
            <mn>2</mn>
          </msup>
          <mo>-</mo>
          <mrow>
            <mn>4</mn>
            <mo>&#8290;</mo>
            <mi>a</mi>
            <mo>&#8290;</mo>
            <mi>c</mi>
          </mrow>
        </mrow>
      </msqrt>
    </mrow>
    <mrow>
      <mn>2</mn>
      <mo>&#8290;</mo>
      <mi mathvariant="bold-italic">a</mi>
    </mrow>
  </mfrac>
</mrow>
</math>

<h2>Object Drawer</h2>

<object type="cool-line" style="width:200px;height:200px;"/>

<h2>Latex support</h2>

<latex>
 This is a small inline formular: $$a^2 + b^2 = c^2$$. You can use many LaTeX
 features and environments. The exact amount of supported features is depending on
 StruggleTex and JEuclid which are the backing libraries for the LaTeX and MathML support.
</latex>


<h2>Objects module: PDF Background</h2>
<!-- <object type="pdf/background" pdfsrc="output/mytest-180-p.pdf" pdfpage="1" style="width:1px;height:1px"/> -->
Works, but not sized.


<h2>Objects module: JFreeChart Pie</h2>

<object type="jfreechart/pie"
 style="width:400px;height:400px;-fs-page-break-min-height:400px"
 title="Fruit Pie Chart">
 <data name="Apple" value="23.2" url="https://www.google.de?q=apple-pie"/>
 <data name="Pear" value="43.2" url="https://www.google.de?q=pear-pie"/>
 <data name="Orange" value="53.2" url="#start"/>
</object>

<h2>Objects module: JFreeChart Bar</h2>

<object type="jfreechart/bar"
 style="width:400px;height:400px; -fs-page-break-min-height:400px"
 title="Fruit Bar Chart"
 categories-title="Category" series-title="Series">
 <data series="Value" category="Apple" value="23.2" url="#apple"/>
 <data series="Value" category="Pear" value="43.2" url="#pear"/>
 <data series="Value" category="Orange" value="33.2" url="#orange"/>
 <data series="Price/kg" category="Apple" value="2.2"/>
 <data series="Price/kg" category="Pear" value="4.2"/>
 <data series="Price/kg" category="Orange" value="5.2"/>
</object>


</body>
</html>

and the code to get this working:

		PdfRendererBuilder builder = new PdfRendererBuilder();
		FileOutputStream os = new FileOutputStream("/Users/me/Documents/pdf-issues/output/mytest-206.pdf");
		builder.withUri("file:///Users/me/Documents/pdf-issues/issue-206.htm");
		builder.toStream(os);

		builder.useMathMLDrawer(new MathMLDrawer());
		builder.useSVGDrawer(new BatikSVGDrawer());
		builder.addDOMMutator(LaTeXDOMMutator.INSTANCE);
		
		StandardObjectDrawerFactory factory = new StandardObjectDrawerFactory();
		factory.registerDrawer("cool-line", new FSObjectDrawer() {
			
			@Override
			public Map<Shape, String> drawObject(Element e, double x, double y, final double width, final double height,
					OutputDevice outputDevice, RenderingContext ctx, final int dotsPerPixel) {
				
				outputDevice.drawWithGraphics((float) x, (float) y, (float) width / dotsPerPixel, (float) height / dotsPerPixel, new OutputDeviceGraphicsDrawer() {
					
					@Override
					public void render(Graphics2D graphics2d) {
						graphics2d.setColor(Color.RED);
						graphics2d.setStroke(new BasicStroke(10));
						graphics2d.drawLine(0, 0, (int) (width / dotsPerPixel), (int) (height / dotsPerPixel));
					}
				});
				return null;
			}
		});
		
		builder.useObjectDrawerFactory(factory);
		
		builder.run();
		os.close();

Finally, the output:
issue-206

@danfickle thanks
I just tried,Error when using "builder.withHtmlContent", You must use "builder.withUri" this way without error. I don't know why

@mapleLeat

What base URL did you use?

@danfickle
There is no error in using the URL
But directly using the withHtmlContent to load html string will appear above error

@danfickle
can you help me see this problem when you are free
#189

I think this should be fixed. No more NPEs.