-
Notifications
You must be signed in to change notification settings - Fork 71
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.
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.
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);
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.
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);
For a complete example demonstrating all those features have a look at LowLevelText.java resp. at the result PDF lowleveltext.pdf.