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

NullPointerException returning PdfImageElement in custom ReplacedElementFactory class. #111

Closed
syedkaleem29 opened this issue Aug 4, 2017 · 5 comments

Comments

@syedkaleem29
Copy link

syedkaleem29 commented Aug 4, 2017

I have defined my own image replacement factory which based on the value of the src attribute get the location of the image file. Converts file into a byte array and then renders the image for the PDF.

To achieve this I used the following code in createReplacedElement method of my class.

FSImage image = new PdfBoxImage(imageBytes, "");
return new PdfBoxImageElement(image);

Which in all sense should work because a PdfBoxImage was created and it was returned as ReplacedElementFactory. Just like in the source code of PdfBoxReplacedElementFactory.

The real catch here is PdfBoxImage has another member field PDImageXObject which is set to null in my case and the PdfBoxOutputDevice uses this object. Hence, the NPE.

So does this mean the constructor PdfBoxImage(byte[], String) is useless?

Logs for reference

java.lang.NullPointerException
	at org.apache.pdfbox.pdmodel.PDResources.add(PDResources.java:675)
	at org.apache.pdfbox.pdmodel.PDResources.add(PDResources.java:640)
	at org.apache.pdfbox.pdmodel.PDPageContentStream.drawImage(PDPageContentStream.java:613)
	at com.openhtmltopdf.pdfboxout.PdfContentStreamAdapter.drawImage(PdfContentStreamAdapter.java:279)
	at com.openhtmltopdf.pdfboxout.PdfBoxOutputDevice.drawImage(PdfBoxOutputDevice.java:944)
	at com.openhtmltopdf.pdfboxout.PdfBoxImageElement.paint(PdfBoxImageElement.java:73)
	at com.openhtmltopdf.pdfboxout.PdfBoxOutputDevice.paintReplacedElement(PdfBoxOutputDevice.java:274)
	at com.openhtmltopdf.layout.Layer.paintReplacedElement(Layer.java:639)
	at com.openhtmltopdf.layout.Layer.paintReplacedElements(Layer.java:596)
	at com.openhtmltopdf.layout.Layer.paintAsLayer(Layer.java:570)
	at com.openhtmltopdf.render.BlockBox.paintInline(BlockBox.java:265)
	at com.openhtmltopdf.layout.Layer.paintInlineContent(Layer.java:287)
	at com.openhtmltopdf.layout.Layer.paint(Layer.java:350)
	at com.openhtmltopdf.pdfboxout.PdfBoxRenderer.paintPage(PdfBoxRenderer.java:654)
	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)

Finally, this was possible in flying-saucer.
So is this an issue? or am I doing something terribly wrong?
Waiting for your response.

@danfickle
Copy link
Owner

Hi @syedkaleem29
Could you try calling PdfBoxOutputDevice::realizeImage() with your newly created PdfBoxImage. The output device is available from the renderer via getOutputDevice(). Alternatively, you can create your own xobject, it should be a couple of lines of code, as seen in realizeImage.

Thanks for using the library and let us know how you go.

@syedkaleem29
Copy link
Author

syedkaleem29 commented Aug 6, 2017

Hi @danfickle,

I got the image to work thanks a lot for that.

I am using this library for RTL support and The text in pdf and browser are completely different styling though I know the alphabets are the same.

I am using font from a file using

PDF:
screen shot 2017-08-06 at 6 33 36 pm
Browser:
screen shot 2017-08-06 at 6 34 07 pm

I saw the source code for ICUBidiReordered and also read the documentation of ArabicShaping everything's seems to be in place. They use the using the same LETTERS_SHAPE constant as per the ArabicShaping Document. So, if I am not wrong they are using the BiDi Algorithm.

Even your online sand box shows disjointed Arabic text. Please guide me on this one.

Also, is it possible to associate a hyperlink with an image?

Thanks a lot for your awesome library and support.

@danfickle
Copy link
Owner

Hi @syedkaleem29

It should be possible to use an image as a hyperlink. Are you having a specific difficulty?

In regards to the Arabic shaping issue, it's a bit of hit and miss with fonts. Specifically, the project just converts Arabic text characters into their presentational format equivalents (beginning, middle or end). Therefore, this will only work if the font supports those characters. Browsers, on the other hand, use a text shaping engine (harfbuzz) and don't need the presentational characters in the font.

I can tell you the setup of the showcase document if that is any help. Firstly, this is the settings:

             PdfRendererBuilder builder = new PdfRendererBuilder();
        	 
        	 builder.useUnicodeBidiSplitter(new ICUBidiSplitter.ICUBidiSplitterFactory());
        	 builder.useUnicodeBidiReorderer(new ICUBidiReorderer());
        	 builder.defaultTextDirection(TextDirection.LTR);
        	 builder.useUnicodeLineBreaker(new ICUBreakers.ICULineBreaker(Locale.US));
        	 builder.useUnicodeCharacterBreaker(new ICUBreakers.ICUCharacterBreaker(Locale.US));
        	 builder.useUnicodeToLowerTransformer(new ICUTransformers.ICUToLowerTransformer(Locale.US));
        	 builder.useUnicodeToUpperTransformer(new ICUTransformers.ICUToUpperTransformer(Locale.US));
        	 builder.useUnicodeToTitleTransformer(new ICUTransformers.ICUToTitleTransformer(Locale.US));

Then the html element has direction set to auto to enable BIDI for the entire document.

<html dir="auto">

Finally the font used is:

@font-face {
	src: url(NotoNaskhArabic-Regular.ttf);
	font-family: 'open-arab';
}

You may also with to read PDF-BOX 3550 - Text shaping for an insight into text shaping with PDFs.

@syedkaleem29
Copy link
Author

syedkaleem29 commented Aug 9, 2017

Hey, @danfickle thank you so much the font works now. You are right only Noto Naskh Arabic works.
Also, Thank you for the code snippet of the showcase document.

I have only two more issues.

The image I replaced using the custom Replaced factory has an attribute which is an external link and that needs to be annotated to the image. The image is of type PdfBoxImage. Should I use a PdfBoxLinkManager? Also, it would be great to have no HTML changes. Because I do not have the liberty for that in my project.

It was done in flying saucer using Image.setAnnotation.

The print dialogue of the browser needs to open based on a boolean value. I just want to know how to add the open print dialogue box action to the PdfCreationListener class.

Pardon for this silly question. Is it possible for me to use ITextRenderer at all?

Edit: Even if having around my image is my only option I am getting a blue line below the image.
Can I know how to avoid this?

@syedkaleem29
Copy link
Author

@danfickle

I have a few doubts. I believe Flying saucer uses IText to convert PDF from XHTML. Am I right? and this project uses PDFBox to do the same even though being a clone of the flying saucer. May I know the reason behind this?

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

2 participants