iText Tutorial SourceForge.net Logo iText, a Free Java-PDF library
by
Bruno Lowagie
[Home] [Previous] [TOC] [Next] [PDF]

Part I: Simple iText

Chapter 2: Chunks, Phrases and Paragraphs
Chunk
A Chunk is the smallest significant part of text that can be added to a document.
Chunks can be used as building blocks for other elements such as Phrase, Paragraph, Anchor... A Chunk is a string with a certain font. All other layoutparameters should be defined in the object to which this chunk of text is added.
In the following line, we create a Chunk with as content 'Hello World', written in a red, italic COURIER font of size 20:
Chunk chunk = new Chunk("Hello world", FontFactory.getFont(FontFactory.COURIER, 20, Font.ITALIC, new Color(255, 0, 0)));

Type 1 fonts
In this tutorial, we will allways use Type 1 fonts, except in Chapter 9, there you can learn how to use other fonts as wel.
This are the different Type 1 fonts:
  • Courier (this is a fixed width font)
  • Helvetica
  • Times Roman
  • Symbol
  • ZapfDingbats
Underline / strikethrough
If you want some chunks to be underlined, or if you want to strike a line through a chunk, you can do this simply by changing the style of the font.
Chunk chunk1 = new Chunk("This text is underlined", FontFactory.getFont(FontFactory.HELVETICA, 12, Font.UNDERLINE));
Chunk chunk2 = new Chunk("This font is of type ITALIC | STRIKETHRU", FontFactory.getFont(FontFactory.HELVETICA, 12, Font.ITALIC | Font.STRIKETHRU));

Superscript / subscript
There are some methods that can be invoked on a Chunk. Most of them will be explained in the following chapters, only one of them in this chapter: the method setTextRise(float f). You can use this method to write chunks in super- or subscript.

Background color of a Chunk
If you want to change the backgroundcolor of a Chunk, you can use the method setBackground(Color color). This adds a colored rectangle under the text of the Chunk:
ck.setBackground(new Color(0xFF, 0xFF, 0x00));


In example 1, you can find an overview of the Type 1 fonts and an example of the methods setTextRise, setBackground,... (see Chap0201.pdf).


Phrase
A Phrase is a series of chunks with a certain leading as extra parameter (leading = the space between two lines).
A phrase has a main font, but some chunks within the phrase can have a font that differs from the main font. You can choose from a wide variety of constructors to create a Phrase. Some of them are used in example 2 (see also the resulting pdf).

Ancient Greek
Because greek characters are used very often, there is a feature in the constructors of class Phrase (and derived classes) that take a String as parameter (so if you want to avoid this feature, you should always work with chunks, not with strings).
As you can see in example 3 (Chap0203.pdf), this feature automatically changes the font to Symbol for all characters in the range from 913 to 937 (except 930) and from 945 to 969 (these are the ASCII-values of the ancient greek characters).

Negative leading
This is rather a bug than a feature, but anyway: it is possible to create a phrase (or paragraph) with a negative leading. This has the odd effect of sentences that are written from bottom to top (see Chap0204.java and Chap0204.pdf). This can be useful for instance if you want to move some positions up in a page. Remark: there is no check to see when you are crossing the upper borderline and there is no way to go back to a previous page.


Paragraph
A paragraph is a series of chunks and/or phrases. Just like a phrase, a paragraph has a certain leading. The user can also define a certain indentation; this is the amount of space that is left blank on the right and/or left. A paragraph can also be aligned (to the right, to the left, centered or justified). Every paragraph that is added to a document, starts automatically on a new line.
There are several ways a paragraph can be constructed, here are some examples:
Paragraph p1 = new Paragraph(new Chunk("This is my first paragraph.", FontFactory.getFont(FontFactory.HELVETICA, 12)));
Paragraph p2 = new Paragraph(new Phrase("This is my second paragraph.", FontFactory.getFont(FontFactory.HELVETICA, 12)));
Paragraph p3 = new Paragraph("This is my third paragraph.", FontFactory.getFont(FontFactory.HELVETICA, 12));

All kinds of objects can be added to a paragraph:
p1.add("you can add strings, "); p1.add(new Chunk("you can add chunks ")); p1.add(new Phrase("or you can add phrases.")); Remark: a paragraph has 1 and only 1 leading. If you add phrases or chunks with other fonts, the original leading remains valid. You can change the leading with method setLeading, but then the whole content of the paragraph will have this new leading.
You may want to try example 5 to obtain the following result.
Keeping a paragraph together

In example 6 (Chap0206.pdf) we use the method setKeepTogether(true) in order to try to keep a paragraph on one page. This isn't always possible. For instance: the first paragraph just doesn't fit on one page, so it is split in two. The second one fits on the second page, but the third is deferred to the third page.

Propagation of the font style
There are some rules you should know about 'font propagation'. These rules are explained using example 7 (Chap0207.pdf).

When you create a Phrase or a Paragraph with some content in a certain font (NOT THE DEFAULT FONT) and you add some more content. The fontstyle of the initial object can be propagated if you want to. This is what happens in 'Hello 1!' and 'Hello 2':

Phrase myPhrase = new Phrase("Hello 2! ", new Font(Font.TIMES_NEW_ROMAN, 8, Font.BOLD));
myPhrase.add(new Phrase("some other font ", new Font(Font.HELVETICA, 8, Font.ITALIC)));
myPhrase.add(new Phrase("This is the end of the sentence.\n", new Font(Font.TIMES_NEW_ROMAN, 8, Font.ITALIC)));
document.add(myPhrase);

We start with Times New Roman BOLD, add some text in Helvetica WITHOUT specifying a style and we see the text was changed into BOLD. Then we added some text in Times New Roman with ITALIC as style, the result is a BOLDITALIC font.
If we use the FontFactory to create the Font, the style will not be propagated. This is because the FontFactory uses another technique to construct a font:

myPhrase = new Phrase("Hello 1bis! ", FontFactory.getFont(FontFactory.TIMES_NEW_ROMAN, 8, Font.BOLD));
myPhrase.add(new Phrase("some other font ", FontFactory.getFont(FontFactory.HELVETICA, 8, Font.ITALIC)));
myPhrase.add(new Phrase("This is the end of the sentence.\n", FontFactory.getFont(FontFactory.TIMES_NEW_ROMAN, 8, Font.ITALIC)));
document.add(myPhrase);

With the above code, the style of the text in Helvetica is undefined (so it isn't bold or italic). The extra text in Times New Roman is only printed in italic.

You also see that we added a Paragraph and the added Paragraph behaved as a Phrase!

Paragraph myParagraph = new Paragraph("Hello 1! ", new Font(Font.TIMES_NEW_ROMAN, 8, Font.BOLD));
myParagraph.add(new Paragraph("This is the end of the sentence.",FontFactory.getFont(new Font.TIMES_NEW_ROMAN, 8)));
document.add(myParagraph);

You can avoid this, but you will loose the style propagation. First create your Paragraph WITHOUT specifying a font (in the example, we only give up the leading that is 1.5 times the fontsize); then add the different parts of content.

myParagraph = new Paragraph(12);
myParagraph.add(new Paragraph("Hello 3! ", new Font(Font.TIMES_NEW_ROMAN, 8, Font.BOLD)));
myParagraph.add(new Paragraph("This is the end of the sentence.", new Font(Font.TIMES_NEW_ROMAN, 8, Font.ITALIC)));
document.add(myParagraph);

You also loose the style propagation if you do this with the Phrase-object:

myPhrase = new Phrase(12);
myPhrase.add(new Phrase("Hello 4! ", new Font(Font.TIMES_NEW_ROMAN, 8, Font.BOLD)));
myPhrase.add(new Phrase("This is the end of the sentence.", newFont(Font.TIMES_NEW_ROMAN, 8, Font.ITALIC)));
document.add(myPhrase);

Changing the split character
Normally when some text doesn't fit on a line, the text is split into different parts. First iText looks for a split character. If no splitcharacter is found, the text is cut at the end of the line.
There are some predefined splitcharacters such as ' ' (space) and '-' (hyphen), but you can override these defaults by using the method setSplitCharacter.
In example 8 (Chap0208.pdf) you can see how a chunk is first split when the end of the line is reached. Then the splitcharacter is changed to a '.' (dot) and the line is split at the position of this character.


Hyphenation
If you want part of your text hyphenated, you can set the hyphenation at Chunk level:

// Hyphenating a British text
Chunk ckEN = new Chunk(textEN);
HyphenationAuto autoEN = new HyphenationAuto("en", "GB", 2, 2);
ckEN.setHyphenation(autoEN);
// Hyphenating a Dutch text
Chunk ckNL = new Chunk(textNL);
HyphenationAuto autoNL = new HyphenationAuto("nl", null, 2, 2);
ckNL.setHyphenation(autoNL);

This is demonstrated in the example (Chap02_hyphenation.pdf) for British and American English.
Remark: You need the jar iTextHYPH.jar to make this work. In this jar, you'll find files like:
  • en_GB.hyp
  • en_US.hyp
  • fr.hyp
  • nl.hyp
These files contain all the hyphenation rules that are specific for a certain language (GB english, US english, French, Dutch,...). As you can see the first two parameters correspond with parts of the filename, the third and fourth parameter specify how many characters may be 'orphaned' at the start of a word resp. at the end of a word.
If you want to build a hyph-file yourself for a language that is not supported, you can download a tool to convert standard XML files (used in TeX and FOP) into the hyph-files used by iText.


Some advanced stuff
Because 'simple iText' is so easy to use, the previous sections were pretty trivial. With example 9, I want to spice up this chapter a little bit and demonstrate one of the many nice features of 'advanced PDF'.
In Chapter 12, we will discuss PageEvents. One of these events is called onGenericTag. This event can be triggered by invoking the method setGenericTag on a chunk. This feature can be used for a wide variety of functionalities. In example 9, we want to build a simple glossary. When we add a certain keyword to the document, we trigger an event that adds this keyword and the pagenumber of the page where the keyword is written to a TreeMap. Once we have finished adding content, we retrieve the TreeMap and add a glossary to the document. Please take a look at the resulting pdf. We will use this feature in other context later on in this tutorial.



[Top] [Previous] [TOC] [Next] [PDF]
Page Updated: $Date: 2003/06/25 07:36:34 $
Copyright © 2000, 2001 by Bruno Lowagie
Adolf Baeyensstraat 121, 9040 Gent, BELGIUM,
tel +00 32 92 28 10 97 mailto:itext-questions@lists.sourceforge.net