TTF PDFBox embeddable fonts do not work

I use PDFBox to create a document from an existing PDF template, so it opens the file, adds text to it and saves it. It works well, except when using external TTF fonts. I tried different things and looked for 2 days for solutions, but there are not many on PDFBox there.

Here is some code using the "Tardy Kid" font, because it cannot be mistaken for anything else, and it is unlikely to be part of any standard library.

The code executes perfectly, displays the "TardyKid" from println (indicating that the font is loaded and the name succeeds), and displays the text - but this is in Helvetica. The more complex parts of the code that use getStringWidth() to calculate the width also indicate that the width tables have loaded successfully. It just does not display correctly.

The code runs in the context of a larger program that opens an existing PDF document (template) and adds text to it. Everything seems to work fine except

  public void setText ( PDDocument document, String text ) throws IOException { int lastPage = document.getNumberOfPages() - 1; PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(lastPage); PDPageContentStream contentStream = null; try { contentStream = new PDPageContentStream(document,page,true,true,false); File fontFile = new File(m_fontDir, "Tardy_Kid.ttf"); PDFont font = PDTrueTypeFont.loadTTF(document, fontFile); Color color = new Color(196, 18, 47); float x = 100f, y = 700f; System.out.println(font.getBaseFont()); contentStream.setFont(font, 32); contentStream.setNonStrokingColor(color); contentStream.beginText(); contentStream.moveTextPositionByAmount(x,y); contentStream.drawString(text); contentStream.endText(); } finally { if (contentStream != null) { contentStream.close(); } } } 
+4
source share
2 answers

I have found the answer. I'm not sure if this is a bug in the PDFBox or not, but if you open / close the content stream (returned by PDPageContentStream) more than once on the same page, it does not work correctly. Thus, the presence of a content stream open / closed inside the setText routine did not work when the procedure was called more than once on the page. Moving the stream outside the routine and opening / closing it once for the entire page seemed to clear up this problem (and a couple of others).

This is not mentioned anywhere in the documentation or sample code, and at best is very subtle. I would call it a mistake, especially since it "works" (does not throw any exceptions), but creates undefined and / or incorrect results on the page.

+4
source

I had a similar problem that came from a pom update that looked for a pdf file when creating a war file.

The stack trace says "Failed to read the built-in TTF for the TimesNewRoman, Bold font", this, of course, after an error related to the "pushback size" appeared, for which we set a new property value in order to pass (an exception I saw for reference: org.apache.pdfbox.exceptions.WrappedIOException: Could not push back 480478 bytes in order to reparse stream. Try increasing push back buffer using system property org.apache.pdfbox.baseParser.pushBackSize ).

It took us some time, but after the explosion of the war and the attempt to open the pdf file in the war, we noticed that it was damaged, but the pdf file that was in the source was not damaged.

The main reason for our problem was that we added "filtering" to our pom for our resource folder. We made it so that we could use some reflection to get some values ​​on our health check page, but it distorted the pdf file that we found out from the following link: https://bitbucket.org/petermr/xhtml2stm/issues/12 / pdf-files-are-being-corrupted-at-some

Below is an example of the filtering we installed that bit us:

 <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> 

Our solution was to remove it from our pom and recycle how we received information for our health page.

+1
source

Source: https://habr.com/ru/post/1483511/


All Articles