Skip to content

Text API

Ralf Stuckert edited this page Apr 12, 2016 · 2 revisions

Text API

At the heart of PDFBox-Layout is the package rst.pdfbox.layout.text, which can be used to draw styled text directly with the PDFBox API. Means all core features like word-wrapping, text-styling, alignment and markup are independent from document-layout and pagination layer. Let's just dive in with a basic example:

final PDDocument test = new PDDocument();
final PDPage page = new PDPage(Constants.A4);
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();

test.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(test, page,
    true, true);

TextFlow text = new TextFlow();
text.addText("This is some ", 11, PDType1Font.COURIER);
text.addText("simple example ", 20, PDType1Font.HELVETICA_BOLD_OBLIQUE);
text.addText("text", 7, PDType1Font.HELVETICA);
text.drawText(contentStream, new Position(50, pageHeight - 50),
    Alignment.Left);

contentStream.close();

final OutputStream outputStream = new FileOutputStream("test.pdf");
test.save(outputStream);
test.close();

Let's go through it step by step. At first we create a PDDocument and a PDPage with an A4 media box, and create the PDPageContentStream to draw to. So far plain PDFBox API, but now we create a TextFlow, which is a text container comparable to the Paragraph we already know. We add some text to the TextFlow: the StyledText is a fragment of text associated with a font, font-size and a text-color (black by default). We three text fragments with different fonts and sizes to the TextFlow before we draw the text. The drawText()method of the TextFlow takes the PDPageContentStream, the position, and the text alignment as parameters. That's it. We close the content stream and save the document to a file.

Position and Size

TextFlow implements the Area interface, which specifies the two methods getHeight() and getWidth(), which return the measures of the text flown in order to be drawn. They both take the fonts and font sizes into account, where the height of line is given by the maximum height of a fragment. The width is given by the longest line. You can alter the original size by performing word wrapping resp. setting the max width.

The method drawText() wants a position to draw to:

text.drawText(contentStream, new Position(50, pageHeight - 50),
    Alignment.Left);

This position - in PDFBox coordinates - is used as the upper left corner of the text block. This may feel a bit unusual, but was necessary for layout and pagination.

Word Wrapping

As already said, you can also perform word wrapping with this API. Base of word wrapping is the interface maximum width. If an element implements this interface - and TextFlow does - you may call the method setMaxWidth() to set a maximum width, and the text container will do its best to not exceed the maximum width by word wrapping the text:

TextFlow text = new TextFlow();
text.setMaxWidth(100);
...
text.drawText(contentStream, new Position(50, pageHeight - 50),
    Alignment.Left);

Alignment

As you might have already seen, you can specify a text alignment in the TextFlow.draw() method:

text.drawText(contentStream, new Position(50, pageHeight - 50),
    Alignment.Left);

The alignment tells the draw method what to do with extra horizontal space, where the extra space is the difference between the width of the text container and the current line to draw. This means, that the alignment is effective only in case of multiple lines. Currently, Left, Center and Right alignment is support. See aligned.pdf for some alignment examples.

Markup

Like described in Markup, TextFlow has both methods addText() and addMarkup(), so you can easily use the markup here:

TextFlow text = new TextFlow();
...
text.addMarkup("Markup supports *bold*, _italic_, and *even _mixed* markup_.\n",
    11, BaseFont.Helvetica);

Complete Example

For a complete example demonstrating all those features have a look at LowLevelText.java resp. at the result PDF lowleveltext.pdf.

Clone this wiki locally