iText pdf library
Website search

Chapter 3: Adding content at absolute positions

These examples were written in the context of Chapter 3 of the book "iText in Action - Second Edition".

FestivalOpening.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
 
public class FestivalOpening {
 
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part1/chapter03/festival_opening.pdf";
    /** The movie poster. */
    public static final String RESOURCE = "resources/img/loa.jpg";
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30);
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        // step 3
        document.open();
        // step 4
        // Create and add a Paragraph
        Paragraph p
            = new Paragraph("Foobar Film Festival", new Font(FontFamily.HELVETICA, 22));
        p.setAlignment(Element.ALIGN_CENTER);
        document.add(p);
        // Create and add an Image
        Image img = Image.getInstance(RESOURCE);
        img.setAbsolutePosition(
            (PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2,
            (PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2);
        document.add(img);
        // Now we go to the next page
        document.newPage();
        document.add(p);
        document.add(img);
        // Add text on top of the image
        PdfContentByte over = writer.getDirectContent();
        over.saveState();
        float sinus = (float)Math.sin(Math.PI / 60);
        float cosinus = (float)Math.cos(Math.PI / 60);
        BaseFont bf = BaseFont.createFont();
        over.beginText();
        over.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
        over.setLineWidth(1.5f);
        over.setRGBColorStroke(0xFF, 0x00, 0x00);
        over.setRGBColorFill(0xFF, 0xFF, 0xFF);
        over.setFontAndSize(bf, 36);
        over.setTextMatrix(cosinus, sinus, -sinus, cosinus, 50, 324);
        over.showText("SOLD OUT");
        over.endText();
        over.restoreState();
        // Add a rectangle under the image
        PdfContentByte under = writer.getDirectContentUnder();
        under.saveState();
        under.setRGBColorFill(0xFF, 0xD7, 0x00);
        under.rectangle(5, 5,
            PageSize.POSTCARD.getWidth() - 10, PageSize.POSTCARD.getHeight() - 10);
        under.fill();
        under.restoreState();
        // step 5
        document.close();
    }
}
GraphicsStateStack.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
 
public class GraphicsStateStack {
    
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part1/chapter03/graphics_state.pdf";
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document(new Rectangle(200, 120));
        // step 2
        PdfWriter writer
             = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        // step 3
        document.open();
        // step 4
        PdfContentByte canvas = writer.getDirectContent();
        // state 1:
        canvas.setRGBColorFill(0xFF, 0x45, 0x00);
        // fill a rectangle in state 1
        canvas.rectangle(10, 10, 60, 60);
        canvas.fill();
        canvas.saveState();
        // state 2;
        canvas.setLineWidth(3);
        canvas.setRGBColorFill(0x8B, 0x00, 0x00);
        // fill and stroke a rectangle in state 2
        canvas.rectangle(40, 20, 60, 60);
        canvas.fillStroke();
        canvas.saveState();
        // state 3:
        canvas.concatCTM(1, 0, 0.1f, 1, 0, 0);
        canvas.setRGBColorStroke(0xFF, 0x45, 0x00);
        canvas.setRGBColorFill(0xFF, 0xD7, 0x00);
        // fill and stroke a rectangle in state 3
        canvas.rectangle(70, 30, 60, 60);
        canvas.fillStroke();
        canvas.restoreState();
        // stroke a rectangle in state 2
        canvas.rectangle(100, 40, 60, 60);
        canvas.stroke();
        canvas.restoreState();
        // fill and stroke a rectangle in state 1
        canvas.rectangle(130, 50, 60, 60);
        canvas.fillStroke();
        // step 5
        document.close();
    }
}
MovieTimeTable.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.BaseColor;
 
/**
 * Draws a time table to the direct content using lines and simple shapes.
 */
public class MovieTimeTable {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part1/chapter03/time_table.pdf";
    
    /**
     * Creates a PDF file containing a time table for our filmfestival.
     * @param    filename    the name of the PDF file
     * @throws DocumentException
     * @throws IOException 
     */
    public void createPdf(String filename)
        throws DocumentException, IOException {
        // step 1
        Document document = new Document(PageSize.A4.rotate());
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        drawTimeTable(writer.getDirectContentUnder());
        drawTimeSlots(writer.getDirectContent());
        // step 5
        document.close();
    }
 
    /** The number of locations on our time table. */
    public static final int LOCATIONS = 9;
    /** The number of time slots on our time table. */
    public static final int TIMESLOTS = 32;
    
    /** The offset to the left of our time table. */
    public static final float OFFSET_LEFT = 76;
    /** The width of our time table. */
    public static final float WIDTH = 740;
    /** The offset from the bottom of our time table. */
    public static final float OFFSET_BOTTOM = 36;
    /** The height of our time table */
    public static final float HEIGHT = 504;
    
    /** The offset of the location bar next to our time table. */
    public static final float OFFSET_LOCATION = 26;
    /** The width of the location bar next to our time table. */
    public static final float WIDTH_LOCATION = 48;
    
    /** The height of a bar showing the movies at one specific location. */
    public static final float HEIGHT_LOCATION = HEIGHT / LOCATIONS;
    /** The width of a time slot. */
    public static final float WIDTH_TIMESLOT = WIDTH / TIMESLOTS;
    
    /**
     * Draws the time table for a day at the film festival.
     * @param directcontent a canvas to which the time table has to be drawn.
     */
    protected void drawTimeTable(PdfContentByte directcontent) {        
        directcontent.saveState();
        
        directcontent.setLineWidth(1.2f);
        float llx, lly, urx, ury;
        
        llx = OFFSET_LEFT;
        lly = OFFSET_BOTTOM;
        urx = OFFSET_LEFT + WIDTH;
        ury = OFFSET_BOTTOM + HEIGHT;
        directcontent.moveTo(llx, lly);
        directcontent.lineTo(urx, lly);
        directcontent.lineTo(urx, ury);
        directcontent.lineTo(llx, ury);
        directcontent.closePath();
        directcontent.stroke();
        
        llx = OFFSET_LOCATION;
        lly = OFFSET_BOTTOM;
        urx = OFFSET_LOCATION + WIDTH_LOCATION;
        ury = OFFSET_BOTTOM + HEIGHT;
        directcontent.moveTo(llx, lly);
        directcontent.lineTo(urx, lly);
        directcontent.lineTo(urx, ury);
        directcontent.lineTo(llx, ury);
        directcontent.closePathStroke();
        
        directcontent.setLineWidth(1);
        directcontent.moveTo(OFFSET_LOCATION + WIDTH_LOCATION / 2, OFFSET_BOTTOM);
        directcontent.lineTo(OFFSET_LOCATION + WIDTH_LOCATION / 2, OFFSET_BOTTOM + HEIGHT);
        float y;
        for (int i = 1; i < LOCATIONS; i++) {
            y = OFFSET_BOTTOM + (i * HEIGHT_LOCATION);
            if (i == 2 || i == 6) {
                directcontent.moveTo(OFFSET_LOCATION, y);
                directcontent.lineTo(OFFSET_LOCATION + WIDTH_LOCATION, y);
            }
            else {
                directcontent.moveTo(OFFSET_LOCATION + WIDTH_LOCATION / 2, y);
                directcontent.lineTo(OFFSET_LOCATION + WIDTH_LOCATION, y);
            }
            directcontent.moveTo(OFFSET_LEFT, y);
            directcontent.lineTo(OFFSET_LEFT + WIDTH, y);
        }
        directcontent.stroke();
        
        directcontent.restoreState();
    }
    
    /**
     * Draws the time slots for a day at the film festival.
     * @param directcontent the canvas to which the time table has to be drawn.
     */
    protected void drawTimeSlots(PdfContentByte directcontent) {
        directcontent.saveState();
        float x;
        for (int i = 1; i < TIMESLOTS; i++) {
            x = OFFSET_LEFT + (i * WIDTH_TIMESLOT);
            directcontent.moveTo(x, OFFSET_BOTTOM);
            directcontent.lineTo(x, OFFSET_BOTTOM + HEIGHT);
        }
        directcontent.setLineWidth(0.3f);
        directcontent.setColorStroke(BaseColor.GRAY);
        directcontent.setLineDash(3, 1);
        directcontent.stroke();
        directcontent.restoreState();
    }
    
    /**
     * Main method creating the PDF.
     * @param    args    no arguments needed
     * @throws IOException 
     * @throws DocumentException 
     */
    public static void main(String[] args)
        throws DocumentException, IOException {
        new MovieTimeTable().createPdf(RESULT);
    }
}
MovieTimeBlocks.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Date;
import java.sql.Time;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.Screening;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.html.WebColors;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.BaseColor;
 
/**
 * Draws a time table to the direct content using lines and simple shapes,
 * adding blocks representing a movies.
 */
public class MovieTimeBlocks extends MovieTimeTable {
 
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part1/chapter03/time_blocks.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document(PageSize.A4.rotate());
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfContentByte over = writer.getDirectContent();
        PdfContentByte under = writer.getDirectContentUnder();
        try {
            DatabaseConnection connection = new HsqldbConnection("filmfestival");
            locations = PojoFactory.getLocations(connection);
            List<Date> days = PojoFactory.getDays(connection);
            List<Screening> screenings;
            for (Date day : days) {
                drawTimeTable(under);
                drawTimeSlots(over);
                screenings = PojoFactory.getScreenings(connection, day);
                for (Screening screening : screenings) {
                    drawBlock(screening, under, over);
                }
                document.newPage();
            }
            connection.close();
        }
        catch(SQLException sqle) {
            sqle.printStackTrace();
            document.add(new Paragraph("Database error: " + sqle.getMessage()));
        }
        // step 5
        document.close();
    }
    
    /**
     * Draws a colored block on the time table, corresponding with
     * the screening of a specific movie.
     * @param    screening    a screening POJO, contains a movie and a category
     * @param    under    the canvas to which the block is drawn
     */
    protected void drawBlock(Screening screening, PdfContentByte under, PdfContentByte over) {
        under.saveState();
        BaseColor color = WebColors.getRGBColor(
            "#" + screening.getMovie().getEntry().getCategory().getColor());
        under.setColorFill(color);
        Rectangle rect = getPosition(screening);
        under.rectangle(
                rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight());
        under.fill();
        over.rectangle(
            rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight());
        over.stroke();
        under.restoreState();
    }
    
    /** The "offset time" for our calendar sheets. */
    public static final long TIME930 = Time.valueOf("09:30:00").getTime();
    
    /** The width of one minute. */
    public static final float MINUTE = WIDTH_TIMESLOT / 30f;
    
    /** A list containing all the locations. */
    protected List<String> locations;
    
    /**
     * Calculates the position of a rectangle corresponding with a screening.
     * @param    screening    a screening POJO, contains a movie
     * @return    a Rectangle
     */
    protected Rectangle getPosition(Screening screening) {
        float llx, lly, urx, ury;
        long minutesAfter930 = (screening.getTime().getTime() - TIME930) / 60000l;
        llx = OFFSET_LEFT + (MINUTE * minutesAfter930);
        int location = locations.indexOf(screening.getLocation()) + 1;
        lly = OFFSET_BOTTOM + (LOCATIONS - location) * HEIGHT_LOCATION;
        urx = llx + MINUTE * screening.getMovie().getDuration();
        ury = lly + HEIGHT_LOCATION;
        Rectangle rect = new Rectangle(llx, lly, urx, ury);
        return rect;
    }
    
    /**
     * Main method creating the PDF.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new MovieTimeBlocks().createPdf(RESULT);
    }
}
FoobarFilmFestival.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.BaseColor;
 
public class FoobarFilmFestival {
 
    public static final String RESULT
        = "results/part1/chapter03/foobar_film_festival.pdf";
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        // step 3
        document.open();
        // step 4
        Chunk c;
        String foobar = "Foobar Film Festival";
        // Measuring a String in Helvetica
        Font helvetica = new Font(FontFamily.HELVETICA, 12);
        BaseFont bf_helv = helvetica.getCalculatedBaseFont(false);
        float width_helv = bf_helv.getWidthPoint(foobar, 12);
        c = new Chunk(foobar + ": " + width_helv, helvetica);
        document.add(new Paragraph(c));
        document.add(new Paragraph(String.format("Chunk width: %f", c.getWidthPoint())));
        // Measuring a String in Times
        BaseFont bf_times = BaseFont.createFont(
            "c:/windows/fonts/times.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED);
        Font times = new Font(bf_times, 12);
        float width_times = bf_times.getWidthPoint(foobar, 12);
        c = new Chunk(foobar + ": " + width_times, times);
        document.add(new Paragraph(c));
        document.add(new Paragraph(String.format("Chunk width: %f", c.getWidthPoint())));
        document.add(Chunk.NEWLINE);
        // Ascent and descent of the String
        document.add(new Paragraph("Ascent Helvetica: "
                + bf_helv.getAscentPoint(foobar, 12)));
        document.add(new Paragraph("Ascent Times: "
                + bf_times.getAscentPoint(foobar, 12)));
        document.add(new Paragraph("Descent Helvetica: "
                + bf_helv.getDescentPoint(foobar, 12)));
        document.add(new Paragraph("Descent Times: "
                + bf_times.getDescentPoint(foobar, 12)));
        document.add(Chunk.NEWLINE);
        // Kerned text
        width_helv = bf_helv.getWidthPointKerned(foobar, 12);
        c = new Chunk(foobar + ": " + width_helv, helvetica);
        document.add(new Paragraph(c));
        // Drawing lines to see where the text is added
        PdfContentByte canvas = writer.getDirectContent();
        canvas.saveState();
        canvas.setLineWidth(0.05f);
        canvas.moveTo(400, 806);
        canvas.lineTo(400, 626);
        canvas.moveTo(508.7f, 806);
        canvas.lineTo(508.7f, 626);
        canvas.moveTo(280, 788);
        canvas.lineTo(520, 788);
        canvas.moveTo(280, 752);
        canvas.lineTo(520, 752);
        canvas.moveTo(280, 716);
        canvas.lineTo(520, 716);
        canvas.moveTo(280, 680);
        canvas.lineTo(520, 680);
        canvas.moveTo(280, 644);
        canvas.lineTo(520, 644);
        canvas.stroke();
        canvas.restoreState();
        // Adding text with PdfContentByte.showTextAligned()
        canvas.beginText();
        canvas.setFontAndSize(bf_helv, 12);
        canvas.showTextAligned(Element.ALIGN_LEFT, foobar, 400, 788, 0);
        canvas.showTextAligned(Element.ALIGN_RIGHT, foobar, 400, 752, 0);
        canvas.showTextAligned(Element.ALIGN_CENTER, foobar, 400, 716, 0);
        canvas.showTextAligned(Element.ALIGN_CENTER, foobar, 400, 680, 30);
        canvas.showTextAlignedKerned(Element.ALIGN_LEFT, foobar, 400, 644, 0);
        canvas.endText();
        // More lines to see where the text is added
        canvas.saveState();
        canvas.setLineWidth(0.05f);
        canvas.moveTo(200, 590);
        canvas.lineTo(200, 410);
        canvas.moveTo(400, 590);
        canvas.lineTo(400, 410);
        canvas.moveTo(80, 572);
        canvas.lineTo(520, 572);
        canvas.moveTo(80, 536);
        canvas.lineTo(520, 536);
        canvas.moveTo(80, 500);
        canvas.lineTo(520, 500);
        canvas.moveTo(80, 464);
        canvas.lineTo(520, 464);
        canvas.moveTo(80, 428);
        canvas.lineTo(520, 428);
        canvas.stroke();
        canvas.restoreState();
        // Adding text with ColumnText.showTextAligned()
        Phrase phrase = new Phrase(foobar, times);
        ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 200, 572, 0);
        ColumnText.showTextAligned(canvas, Element.ALIGN_RIGHT, phrase, 200, 536, 0);
        ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 500, 0);
        ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 464, 30);
        ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 428, -30);
        // Chunk attributes
        c = new Chunk(foobar, times);
        c.setHorizontalScaling(0.5f);
        phrase = new Phrase(c);
        ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 572, 0);
        c = new Chunk(foobar, times);
        c.setSkew(15, 15);
        phrase = new Phrase(c);
        ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 536, 0);
        c = new Chunk(foobar, times);
        c.setSkew(0, 25);
        phrase = new Phrase(c);
        ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 500, 0);
        c = new Chunk(foobar, times);
        c.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_STROKE, 0.1f, BaseColor.RED);
        phrase = new Phrase(c);
        ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 464, 0);
        c = new Chunk(foobar, times);
        c.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, 1, null);
        phrase = new Phrase(c);
        ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 428, -0);
        // step 5
        document.close();
    }
}
MovieTextInfo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.sql.Date;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.Screening;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.BaseColor;
 
/**
 * Draws a time table to the direct content using lines and simple shapes,
 * adding blocks representing a movies.
 */
public class MovieTextInfo extends MovieTimeBlocks {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part1/chapter03/calendar.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document(PageSize.A4.rotate());
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfContentByte over = writer.getDirectContent();
        PdfContentByte under = writer.getDirectContentUnder();
        try {
            DatabaseConnection connection = new HsqldbConnection("filmfestival");
            locations = PojoFactory.getLocations(connection);
            List<Date> days = PojoFactory.getDays(connection);
            List<Screening> screenings;
            int d = 1;
            for (Date day : days) {
                drawTimeTable(under);
                drawTimeSlots(over);
                drawInfo(over);
                drawDateInfo(day, d++, over);
                screenings = PojoFactory.getScreenings(connection, day);
                for (Screening screening : screenings) {
                    drawBlock(screening, under, over);
                    drawMovieInfo(screening, over);
                }
                document.newPage();
            }
            connection.close();
        }
        catch(SQLException sqle) {
            sqle.printStackTrace();
            document.add(new Paragraph("Database error: " + sqle.getMessage()));
        }
        // step 5
        document.close();
    }
    
    /** The base font that will be used to write info on the calendar sheet. */
    protected BaseFont bf;
    
    /** A phrase containing a white letter "P" (for Press) */
    protected Phrase press;
 
    /** The different time slots. */
    public static String[] TIME =
        { "09:30", "10:00", "10:30", "11:00", "11:30", "12:00",
          "00:30", "01:00", "01:30", "02:00", "02:30", "03:00",
          "03:30", "04:00", "04:30", "05:00", "05:30", "06:00",
          "06:30", "07:00", "07:30", "08:00", "08:30", "09:00",
          "09:30", "10:00", "10:30", "11:00", "11:30", "12:00",
          "00:30", "01:00" };
    
    /**
     * Draws some text on every calendar sheet.
     * 
     */
    protected void drawInfo(PdfContentByte directcontent) {
        directcontent.beginText();
        directcontent.setFontAndSize(bf, 18);
        float x, y;
        x = (OFFSET_LEFT + WIDTH + OFFSET_LOCATION) / 2;
        y = OFFSET_BOTTOM + HEIGHT + 24;
        directcontent.showTextAligned(Element.ALIGN_CENTER,
            "FOOBAR FILM FESTIVAL", x, y, 0);
        x = OFFSET_LOCATION + WIDTH_LOCATION / 2f - 6;
        y = OFFSET_BOTTOM + HEIGHT_LOCATION;
        directcontent.showTextAligned(Element.ALIGN_CENTER,
            "The Majestic", x, y, 90);
        y = OFFSET_BOTTOM + HEIGHT_LOCATION * 4f;
        directcontent.showTextAligned(Element.ALIGN_CENTER,
            "Googolplex", x, y, 90);
        y = OFFSET_BOTTOM + HEIGHT_LOCATION * 7.5f;
        directcontent.showTextAligned(Element.ALIGN_CENTER,
            "Cinema Paradiso", x, y, 90);
        directcontent.setFontAndSize(bf, 12);
        x = OFFSET_LOCATION + WIDTH_LOCATION - 6;
        for (int i = 0; i < LOCATIONS; i++) {
            y = OFFSET_BOTTOM + ((8.5f - i) * HEIGHT_LOCATION);
            directcontent.showTextAligned(Element.ALIGN_CENTER,
                locations.get(i), x, y, 90);
        }
        directcontent.setFontAndSize(bf, 6);
        y = OFFSET_BOTTOM + HEIGHT + 1;
        for (int i = 0; i < TIMESLOTS; i++) {
            x = OFFSET_LEFT + (i * WIDTH_TIMESLOT);
            directcontent.showTextAligned(Element.ALIGN_LEFT,
                TIME[i], x, y, 45);
        }
        directcontent.endText();
    }
    /**
     * Draws some text on every calendar sheet.
     * 
     */
    protected void drawDateInfo(Date day, int d, PdfContentByte directcontent) {
        directcontent.beginText();
        directcontent.setFontAndSize(bf, 18);
        float x, y;
        x = OFFSET_LOCATION;
        y = OFFSET_BOTTOM + HEIGHT + 24;
        directcontent.showTextAligned(Element.ALIGN_LEFT,
                "Day " + d, x, y, 0);
        x = OFFSET_LEFT + WIDTH;
        directcontent.showTextAligned(Element.ALIGN_RIGHT,
                day.toString(), x, y, 0);
        directcontent.endText();
    }
    
    /**
     * Draws the info about the movie.
     * @throws DocumentException 
     */
    protected void drawMovieInfo(Screening screening, PdfContentByte directcontent)
        throws DocumentException {
        if (screening.isPress()) {
            Rectangle rect = getPosition(screening);
            ColumnText.showTextAligned(directcontent, Element.ALIGN_CENTER,
                    press, (rect.getLeft() + rect.getRight()) / 2,
                    rect.getBottom() + rect.getHeight() / 4, 0);
        }
    }
    
    /**
     * Constructor for the MovieCalendar class; initializes the base font object.
     * @throws IOException 
     * @throws DocumentException 
     */
    public MovieTextInfo() throws DocumentException, IOException {
        bf = BaseFont.createFont();
        Font f = new Font(bf, HEIGHT_LOCATION / 2);
        f.setColor(BaseColor.WHITE);
        press = new Phrase("P", f);
    }
    
    /**
     * Main method creating the PDF.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        new MovieTextInfo().createPdf(RESULT);
    }
}
MovieCalendar.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.IOException;
 
import com.lowagie.filmfestival.Screening;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
 
/**
 * Draws a time table to the direct content using lines and simple shapes,
 * adding blocks representing a movies.
 */
public class MovieCalendar extends MovieTextInfo {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part1/chapter03/movie_calendar.pdf";
    
    /**
     * Draws the info about the movie.
     * @throws DocumentException 
     */
    protected void drawMovieInfo(Screening screening, PdfContentByte directcontent)
        throws DocumentException {
        super.drawMovieInfo(screening, directcontent);
        Rectangle rect = getPosition(screening);
        ColumnText column = new ColumnText(directcontent);
        column.setSimpleColumn(new Phrase(screening.getMovie().getMovieTitle()),
                rect.getLeft(), rect.getBottom(),
                rect.getRight(), rect.getTop(), 18, Element.ALIGN_CENTER);
        column.go();
    }
    
    /**
     * Constructor for the MovieCalendar class; initializes the base font object.
     * @throws IOException 
     * @throws DocumentException 
     */
    public MovieCalendar() throws DocumentException, IOException {
        super();
    }
    
    /**
     * Main method creating the PDF.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        new MovieCalendar().createPdf(RESULT);
    }
}
MovieColumns1.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Country;
import com.lowagie.filmfestival.Director;
import com.lowagie.filmfestival.FilmFonts;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.PojoToElementFactory;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
 
public class MovieColumns1 {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part1/chapter03/movie_columns1.pdf";
    
    /** Definition of two columns */
    public static final float[][] COLUMNS = {
        { 36, 36, 296, 806 } , { 299, 36, 559, 806 }
    };
    
    /**
     * Creates a PDF with information about the movies
     * @param    filename the name of the PDF file that will be created.
     * @throws    DocumentException 
     * @throws    IOException 
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");    
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        List<Movie> movies = PojoFactory.getMovies(connection);
        ColumnText ct = new ColumnText(writer.getDirectContent());
        for (Movie movie : movies) {
            ct.addText(createMovieInformation(movie));
            ct.addText(Chunk.NEWLINE);
        }
        ct.setAlignment(Element.ALIGN_JUSTIFIED);
        ct.setExtraParagraphSpace(6);
        ct.setLeading(0, 1.2f);
        ct.setFollowingIndent(27);
        int linesWritten = 0;
        int column = 0;
        int status = ColumnText.START_COLUMN;
        while (ColumnText.hasMoreText(status)) {
            ct.setSimpleColumn(
                    COLUMNS[column][0], COLUMNS[column][1],
                    COLUMNS[column][2], COLUMNS[column][3]);
            ct.setYLine(COLUMNS[column][3]);
            status = ct.go();
            linesWritten += ct.getLinesWritten();
            column = Math.abs(column - 1);
            if (column == 0)
                document.newPage();
        }
        
        ct.addText(new Phrase("Lines written: " + linesWritten));
        ct.go();
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
    
    /**
     * Creates a Phrase containing information about a movie.
     * @param    movie    the movie for which you want to create a Paragraph
     */
    public Phrase createMovieInformation(Movie movie) {
        Phrase p = new Phrase();
        p.setFont(FilmFonts.NORMAL);
        p.add(new Phrase("Title: ", FilmFonts.BOLDITALIC));
        p.add(PojoToElementFactory.getMovieTitlePhrase(movie));
        p.add(" ");
        if (movie.getOriginalTitle() != null) {
            p.add(new Phrase("Original title: ", FilmFonts.BOLDITALIC));
            p.add(PojoToElementFactory.getOriginalTitlePhrase(movie));
            p.add(" ");
        }
        p.add(new Phrase("Country: ", FilmFonts.BOLDITALIC));
        for (Country country : movie.getCountries()) {
            p.add(PojoToElementFactory.getCountryPhrase(country));
            p.add(" ");
        }
        p.add(new Phrase("Director: ", FilmFonts.BOLDITALIC));
        for (Director director : movie.getDirectors()) {
            p.add(PojoToElementFactory.getDirectorPhrase(director));
            p.add(" ");
        }
        p.add(new Chunk("Year: ", FilmFonts.BOLDITALIC));
        p.add(new Chunk(String.valueOf(movie.getYear()), FilmFonts.NORMAL));
        p.add(new Chunk(" Duration: ", FilmFonts.BOLDITALIC));
        p.add(new Chunk(String.valueOf(movie.getDuration()), FilmFonts.NORMAL));
        p.add(new Chunk(" minutes", FilmFonts.NORMAL));
        p.add(new LineSeparator(0.3f, 100, null, Element.ALIGN_CENTER, -2));
        return p;
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SQLException {
        new MovieColumns1().createPdf(RESULT);
    }
}
MovieColumns2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfWriter;
 
public class MovieColumns2 extends MovieColumns1 {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part1/chapter03/movie_columns2.pdf";
    
    /**
     * Creates a PDF with information about the movies
     * @param    filename the name of the PDF file that will be created.
     * @throws    DocumentException 
     * @throws    IOException 
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");    
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer
             = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        List<Movie> movies = PojoFactory.getMovies(connection);
        ColumnText ct = new ColumnText(writer.getDirectContent());
        ct.setAlignment(Element.ALIGN_JUSTIFIED);
        ct.setExtraParagraphSpace(6);
        ct.setLeading(14);
        ct.setIndent(10);
        ct.setRightIndent(3);
        ct.setSpaceCharRatio(PdfWriter.NO_SPACE_CHAR_RATIO);
        int column = 0;
        int status = ColumnText.START_COLUMN;
        ct.setSimpleColumn(
            COLUMNS[column][0], COLUMNS[column][1],
            COLUMNS[column][2], COLUMNS[column][3]);
        for (Movie movie : movies) {
            ct.addText(createMovieInformation(movie));
            status = ct.go();
            if (ColumnText.hasMoreText(status)) {
                column = Math.abs(column - 1);
                if (column == 0)
                    document.newPage();
                ct.setSimpleColumn(
                    COLUMNS[column][0], COLUMNS[column][1],
                    COLUMNS[column][2], COLUMNS[column][3]);
                ct.setYLine(COLUMNS[column][3]);
                status = ct.go();
            }
        }
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SQLException {
        new MovieColumns2().createPdf(RESULT);
    }
}
MovieColumns3.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfWriter;
 
public class MovieColumns3 extends MovieColumns1 {
 
    /** The resulting PDF file. */
    public static final String RESULT = "results/part1/chapter03/movie_columns3.pdf";
    
    /**
     * Creates a PDF with information about the movies
     * @param    filename the name of the PDF file that will be created.
     * @throws    DocumentException 
     * @throws    IOException 
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        List<Movie> movies = PojoFactory.getMovies(connection);
        ColumnText ct = new ColumnText(writer.getDirectContent());
        int column = 0;
        ct.setSimpleColumn(
            COLUMNS[column][0], COLUMNS[column][1],
            COLUMNS[column][2], COLUMNS[column][3]);
        int status = ColumnText.START_COLUMN;
        Phrase p;
        float y;
        for (Movie movie : movies) {
            y = ct.getYLine();
            p = createMovieInformation(movie);
            ct.addText(p);
            status = ct.go(true);
            if (ColumnText.hasMoreText(status)) {
                column = Math.abs(column - 1);
                if (column == 0)
                    document.newPage();
                ct.setSimpleColumn(
                    COLUMNS[column][0], COLUMNS[column][1],
                    COLUMNS[column][2], COLUMNS[column][3]);
                y = COLUMNS[column][3];
            }
            ct.setYLine(y);
            ct.setText(p);
            status = ct.go(false);
        }
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SQLException {
        new MovieColumns3().createPdf(RESULT);
    }
}
MovieColumns4.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
 
public class MovieColumns4 extends MovieColumns1 {
 
    /** The resulting PDF file. */
    public static final String RESULT = "results/part1/chapter03/movie_columns4.pdf";
    
    public static final float[][] LEFT =
        { { 36,806, 36,670, 108,670, 108,596, 36,596, 36,36 }, 
        { 299,806, 299,484, 336,484, 336,410, 299,410, 299,36 } };
    public static final float[][] RIGHT =
        { { 296,806, 296,484, 259,484, 259,410, 296,410, 296,36 },
        { 559,806, 559,246, 487,246, 487,172, 559,172, 559,36 } };
    
    /**
     * Creates a PDF with information about the movies
     * @param    filename the name of the PDF file that will be created.
     * @throws    DocumentException 
     * @throws    IOException 
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");    
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfContentByte canvas = writer.getDirectContent();
        drawRectangles(canvas);
        List<Movie> movies = PojoFactory.getMovies(connection);
        ColumnText ct = new ColumnText(canvas);
        ct.setAlignment(Element.ALIGN_JUSTIFIED);
        ct.setLeading(14);
        int column = 0;
        ct.setColumns(LEFT[column], RIGHT[column]);
        int status = ColumnText.START_COLUMN;
        Phrase p;
        float y;
        for (Movie movie : movies) {
            y = ct.getYLine();
            p = createMovieInformation(movie);
            ct.addText(p);
            status = ct.go(true);
            if (ColumnText.hasMoreText(status)) {
                column = Math.abs(column - 1);
                if (column == 0) {
                    document.newPage();
                    drawRectangles(canvas);
                }
                ct.setColumns(LEFT[column], RIGHT[column]);
                y = 806;
            }
            ct.setYLine(y);
            ct.setText(p);
            status = ct.go();
        }
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
    
    /**
     * Draws three rectangles
     * @param canvas
     */
    public void drawRectangles(PdfContentByte canvas) {
        canvas.saveState();
        canvas.setGrayFill(0.9f);
        canvas.rectangle(33, 592, 72, 72);
        canvas.rectangle(263, 406, 72, 72);
        canvas.rectangle(491, 168, 72, 72);
        canvas.fillStroke();
        canvas.restoreState();
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     * @throws SQLException
     */
    public static void main(String[] args)
       throws IOException, DocumentException, SQLException {
        new MovieColumns4().createPdf(RESULT);
    }
}
ColumnMovies1.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.FilmFonts;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.PojoToElementFactory;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfWriter;
 
public class ColumnMovies1 {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part1/chapter03/column_movies1.pdf";
    /** Path to the resources. */
    public static final String RESOURCE
        = "resources/posters/%s.jpg";
    
    /** Definition of two columns */
    public static final float[][] COLUMNS = {
        { 36, 36, 224, 579 } , { 230, 36, 418, 579 },
        { 424, 36, 612, 579 } , { 618, 36, 806, 579 }
    };
    
    /**
     * Creates a PDF with information about the movies
     * @param    filename the name of the PDF file that will be created.
     * @throws    DocumentException 
     * @throws    IOException 
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        // step 1
        Document document = new Document(PageSize.A4.rotate());
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        List<Movie> movies = PojoFactory.getMovies(connection);
        ColumnText ct = new ColumnText(writer.getDirectContent());
        int column = 0;
        ct.setSimpleColumn(
            COLUMNS[column][0], COLUMNS[column][1],
            COLUMNS[column][2], COLUMNS[column][3]);
        int status = ColumnText.START_COLUMN;
        float y;
        Image img;
        for (Movie movie : movies) {
            y = ct.getYLine();
            img = Image.getInstance(String.format(RESOURCE, movie.getImdb()));
            img.scaleToFit(80, 1000);
            addContent(ct, movie, img);
            status = ct.go(true);
            if (ColumnText.hasMoreText(status)) {
                column = (column + 1) % 4;
                if (column == 0)
                    document.newPage();
                ct.setSimpleColumn(
                    COLUMNS[column][0], COLUMNS[column][1],
                    COLUMNS[column][2], COLUMNS[column][3]);
                y = COLUMNS[column][3];
            }
            ct.setYLine(y);
            ct.setText(null);
            addContent(ct, movie, img);
            status = ct.go();
        }
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
    
    /**
     * Add content to a ColumnText object.
     * @param ct the ColumnText object
     * @param movie a Movie object
     * @param img the poster of the image
     */
    public void addContent(ColumnText ct, Movie movie, Image img) {
        ct.addElement(img);
        ct.addElement(new Paragraph(movie.getTitle(), FilmFonts.BOLD));
        if (movie.getOriginalTitle() != null) {
            ct.addElement(new Paragraph(movie.getOriginalTitle(), FilmFonts.ITALIC));
        }
        ct.addElement(PojoToElementFactory.getDirectorList(movie));
        ct.addElement(PojoToElementFactory.getYearPhrase(movie));
        ct.addElement(PojoToElementFactory.getDurationPhrase(movie));
        ct.addElement(PojoToElementFactory.getCountryList(movie));
        ct.addElement(Chunk.NEWLINE);
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, DocumentException, SQLException {
        new ColumnMovies1().createPdf(RESULT);
    }
}
ColumnMovies2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import part1.chapter02.StarSeparator;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.FilmFonts;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.PojoToElementFactory;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfWriter;
 
public class ColumnMovies2 {
 
    /** The resulting PDF file. */
    public static final String RESULT = "results/part1/chapter03/column_movies2.pdf";
    
    /** Definition of two columns */
    public static final float[][] COLUMNS = {
        { 40, 36, 219, 579 } , { 234, 36, 414, 579 },
        { 428, 36, 608, 579 } , { 622, 36, 802, 579 }
    };
    
    /**
     * Creates a PDF with information about the movies
     * @param    filename the name of the PDF file that will be created.
     * @throws    DocumentException 
     * @throws    IOException 
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        // step 1
        Document document = new Document(PageSize.A4.rotate());
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        List<Movie> movies = PojoFactory.getMovies(connection);
        ColumnText ct = new ColumnText(writer.getDirectContent());
        int column = 0;
        ct.setSimpleColumn(
            COLUMNS[column][0], COLUMNS[column][1],
            COLUMNS[column][2], COLUMNS[column][3]);
        int status = ColumnText.START_COLUMN;
        float y;
        for (Movie movie : movies) {
            y = ct.getYLine();
            addContent(ct, movie);
            status = ct.go(true);
            if (ColumnText.hasMoreText(status)) {
                column = (column + 1) % 4;
                if (column == 0)
                    document.newPage();
                ct.setSimpleColumn(
                    COLUMNS[column][0], COLUMNS[column][1],
                    COLUMNS[column][2], COLUMNS[column][3]);
                y = COLUMNS[column][3];
            }
            ct.setYLine(y);
            ct.setText(null);
            addContent(ct, movie);
            status = ct.go();
        }
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
    
    /**
     * Adds info about a movie in a ColumnText object
     * @param ct A ColumnText object
     * @param movie A Movie POJO
     */
    public void addContent(ColumnText ct, Movie movie) {
        Paragraph p;
        p = new Paragraph(new Paragraph(movie.getTitle(), FilmFonts.BOLD));
        p.setAlignment(Element.ALIGN_CENTER);
        p.setSpacingBefore(16);
        ct.addElement(p);
        if (movie.getOriginalTitle() != null) {
            p = new Paragraph(movie.getOriginalTitle(), FilmFonts.ITALIC);
            p.setAlignment(Element.ALIGN_RIGHT);
            ct.addElement(p);
        }
        p = new Paragraph();
        p.add(PojoToElementFactory.getYearPhrase(movie));
        p.add(" ");
        p.add(PojoToElementFactory.getDurationPhrase(movie));
        p.setAlignment(Element.ALIGN_JUSTIFIED_ALL);
        ct.addElement(p);
        p = new Paragraph(new Chunk(new StarSeparator()));
        p.setSpacingAfter(12);
        ct.addElement(p);
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, DocumentException, SQLException {
        new ColumnMovies2().createPdf(RESULT);
    }
}
ImageDirect.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.PdfWriter;
 
public class ImageDirect {
 
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part1/chapter03/image_direct.pdf";
    /** The movie poster. */
    public static final String RESOURCE
        = "resources/img/loa.jpg";
    
    public static void main(String[] args)
        throws IOException, DocumentException {
        // step 1
        Document document
            = new Document(PageSize.POSTCARD, 30, 30, 30, 30);
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        writer.setCompressionLevel(0);
        // step 3
        document.open();
        // step 4
        Image img = Image.getInstance(RESOURCE);
        img.setAbsolutePosition((PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2,
                (PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2);
        writer.getDirectContent().addImage(img);
        Paragraph p = new Paragraph("Foobar Film Festival", new Font(FontFamily.HELVETICA, 22));
        p.setAlignment(Element.ALIGN_CENTER);
        document.add(p);
        // step 5
        document.close();
    }
}
ImageSkew.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
 
public class ImageSkew {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part1/chapter03/image_skew.pdf";
    /** The movie poster. */
    public static final String RESOURCE = "resources/img/loa.jpg";
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document(PageSize.POSTCARD.rotate());
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document,
                new FileOutputStream(RESULT));
        writer.setCompressionLevel(0);
        // step 3
        document.open();
        // step 4
        Image img = Image.getInstance(RESOURCE);
        // Add the image to the upper layer
        writer.getDirectContent().addImage(img,
            img.getWidth(), 0, 0.35f * img.getHeight(),
            0.65f * img.getHeight(), 30, 30);
        // step 5
        document.close();
    }
}
ImageInline.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
 
public class ImageInline {
 
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part1/chapter03/image_inline.pdf";
    /** The movie poster. */
    public static final String RESOURCE
        = "resources/img/loa.jpg";
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30);
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document,
                new FileOutputStream(RESULT));
        writer.setCompressionLevel(0);
        // step 3
        document.open();
        // step 4
        Image img = Image.getInstance(RESOURCE);
        img.setAbsolutePosition(
            (PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2,
            (PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2);
        writer.getDirectContent().addImage(img, true);
        // step 5
        document.close();
    }
}
MoviePosters.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
 
public class MoviePosters {
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part1/chapter03/movie_posters.pdf";
    /** Path to the resources. */
    public static final String RESOURCE
        = "resources/posters/%s.jpg";
    
    /**
     * Creates a PDF with information about the movies
     * @param    filename the name of the PDF file that will be created.
     * @throws    DocumentException 
     * @throws    IOException 
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // Creates a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");    
        // step 1
        Document document = new Document(PageSize.A4);
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        writer.setCompressionLevel(0);
        // step 3
        document.open();
        // step 4
        PdfContentByte canvas = writer.getDirectContent();
        // Create the XObject
        PdfTemplate celluloid = canvas.createTemplate(595, 84.2f);
        celluloid.rectangle(8, 8, 579, 68);
        for (float f = 8.25f; f < 581; f+= 6.5f) {
            celluloid.roundRectangle(f, 8.5f, 6, 3, 1.5f);
            celluloid.roundRectangle(f, 72.5f, 6, 3, 1.5f);
        }
        celluloid.setGrayFill(0.1f);
        celluloid.eoFill();
        // Write the XObject to the OutputStream
        writer.releaseTemplate(celluloid);
        // Add the XObject 10 times
        for (int i = 0; i < 10; i++) {
            canvas.addTemplate(celluloid, 0, i * 84.2f);
        }
        // Go to the next page
        document.newPage();
        // Add the XObject 10 times
        for (int i = 0; i < 10; i++) {
            canvas.addTemplate(celluloid, 0, i * 84.2f);
        }
        // Get the movies from the database
        List<Movie> movies = PojoFactory.getMovies(connection);
        Image img;
        float x = 11.5f;
        float y = 769.7f;
        // Loop over the movies and add images
        for (Movie movie : movies) {
            img = Image.getInstance(String.format(RESOURCE, movie.getImdb()));
            img.scaleToFit(1000, 60);
            img.setAbsolutePosition(x + (45 - img.getScaledWidth()) / 2, y);
            canvas.addImage(img);
            x += 48;
            if (x > 578) {
                x = 11.5f;
                y -= 84.2f;
            }
        }
        // Go to the next page
        document.newPage();
        // Add the template using a different CTM
        canvas.addTemplate(celluloid, 0.8f, 0, 0.35f, 0.65f, 0, 600);
        // Wrap the XObject in an Image object
        Image tmpImage = Image.getInstance(celluloid);
        tmpImage.setAbsolutePosition(0, 480);
        document.add(tmpImage);
        // Perform transformations on the image
        tmpImage.setRotationDegrees(30);
        tmpImage.scalePercent(80);
        tmpImage.setAbsolutePosition(30, 500);
        document.add(tmpImage);
        // More transformations
        tmpImage.setRotation((float)Math.PI / 2);
        tmpImage.setAbsolutePosition(200, 300);
        document.add(tmpImage);
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, SQLException, DocumentException {
        new MoviePosters().createPdf(RESULT);
    }
}
MovieTemplates.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part1.chapter03;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.Screening;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
 
/**
 * Draws a time table to the direct content using lines and simple shapes,
 * adding blocks representing a movies.
 */
public class MovieTemplates extends MovieCalendar {
 
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part1/chapter03/movie_templates.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document(PageSize.A4.rotate());
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfContentByte over = writer.getDirectContent();
        PdfContentByte under = writer.getDirectContentUnder();
        try {
            DatabaseConnection connection = new HsqldbConnection("filmfestival");
            locations = PojoFactory.getLocations(connection);
            PdfTemplate t_under = under.createTemplate(
                    PageSize.A4.getHeight(), PageSize.A4.getWidth());
            drawTimeTable(t_under);
            PdfTemplate t_over = over.createTemplate(
                    PageSize.A4.getHeight(), PageSize.A4.getWidth());
            drawTimeSlots(t_over);
            drawInfo(t_over);
            List<Date> days = PojoFactory.getDays(connection);
            List<Screening> screenings;
            int d = 1;
            for (Date day : days) {
                over.addTemplate(t_over, 0, 0);
                under.addTemplate(t_under, 0, 0);
                drawDateInfo(day, d++, over);
                screenings = PojoFactory.getScreenings(connection, day);
                for (Screening screening : screenings) {
                    drawBlock(screening, under, over);
                    drawMovieInfo(screening, over);
                }
                document.newPage();
            }
            connection.close();
        }
        catch(SQLException sqle) {
            sqle.printStackTrace();
            document.add(new Paragraph("Database error: " + sqle.getMessage()));
        }
        // step 5
        document.close();
    }
    
    /**
     * Constructs a MovieTemplates object.
     * @throws DocumentException
     * @throws IOException
     */
    public MovieTemplates() throws DocumentException, IOException {
        super();
    }
    
    /**
     * Main method creating the PDF.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        new MovieTemplates().createPdf(RESULT);
    }
}
FestivalOpening.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class FestivalOpening : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      string RESOURCE = Utility.ResourcePosters;
      // step 1
      using (Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30)) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        // Create and add a Paragraph
        Paragraph p = new Paragraph(
          "Foobar Film Festival", 
          new Font(Font.FontFamily.HELVETICA, 22)
        );
        p.Alignment = Element.ALIGN_CENTER;
        document.Add(p);
        // Create and add an Image
        Image img = Image.GetInstance(Path.Combine(
          Utility.ResourceImage, "loa.jpg"
        ));
        img.SetAbsolutePosition(
          (PageSize.POSTCARD.Width - img.ScaledWidth) / 2,
          (PageSize.POSTCARD.Height - img.ScaledHeight) / 2
        );
        document.Add(img);
        // Now we go to the next page
        document.NewPage();
        document.Add(p);
        document.Add(img);
        // Add text on top of the image
        PdfContentByte over = writer.DirectContent;
        over.SaveState();
        float sinus = (float)Math.Sin(Math.PI / 60);
        float cosinus = (float)Math.Cos(Math.PI / 60);
        BaseFont bf = BaseFont.CreateFont();
        over.BeginText();
        over.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
        over.SetLineWidth(1.5f);
        over.SetRGBColorStroke(0xFF, 0x00, 0x00);
        over.SetRGBColorFill(0xFF, 0xFF, 0xFF);
        over.SetFontAndSize(bf, 36);
        over.SetTextMatrix(cosinus, sinus, -sinus, cosinus, 50, 324);
        over.ShowText("SOLD OUT");
        over.EndText();
        over.RestoreState();
        // Add a rectangle under the image
        PdfContentByte under = writer.DirectContentUnder;
        under.SaveState();
        under.SetRGBColorFill(0xFF, 0xD7, 0x00);
        under.Rectangle(5, 5,
          PageSize.POSTCARD.Width - 10, 
          PageSize.POSTCARD.Height - 10
        );
        under.Fill();
        under.RestoreState();        
      }
    }
// ===========================================================================
  }
}
GraphicsStateStack.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class GraphicsStateStack : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document(new Rectangle(200, 120))) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        PdfContentByte canvas = writer.DirectContent;
        // state 1:
        canvas.SetRGBColorFill(0xFF, 0x45, 0x00);
        // fill a rectangle in state 1
        canvas.Rectangle(10, 10, 60, 60);
        canvas.Fill();
        canvas.SaveState();
        // state 2;
        canvas.SetLineWidth(3);
        canvas.SetRGBColorFill(0x8B, 0x00, 0x00);
        // fill and stroke a rectangle in state 2
        canvas.Rectangle(40, 20, 60, 60);
        canvas.FillStroke();
        canvas.SaveState();
        // state 3:
        canvas.ConcatCTM(1, 0, 0.1f, 1, 0, 0);
        canvas.SetRGBColorStroke(0xFF, 0x45, 0x00);
        canvas.SetRGBColorFill(0xFF, 0xD7, 0x00);
        // fill and stroke a rectangle in state 3
        canvas.Rectangle(70, 30, 60, 60);
        canvas.FillStroke();
        canvas.RestoreState();
        // stroke a rectangle in state 2
        canvas.Rectangle(100, 40, 60, 60);
        canvas.Stroke();
        canvas.RestoreState();
        // fill and stroke a rectangle in state 1
        canvas.Rectangle(130, 50, 60, 60);
        canvas.FillStroke();        
      }
    }
// ===========================================================================
  }
}
MovieTimeTable.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieTimeTable : IWriter {
// ===========================================================================
    public virtual void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.A4.Rotate())) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        DrawTimeTable(writer.DirectContentUnder);
        DrawTimeSlots(writer.DirectContent);
      }
    }
// ---------------------------------------------------------------------------    
    /** The number of locations on our time table. */
    public const int LOCATIONS = 9;
    /** The number of time slots on our time table. */
    public const int TIMESLOTS = 32;
    
    /** The offset to the left of our time table. */
    public const float OFFSET_LEFT = 76;
    /** The width of our time table. */
    public const float WIDTH = 740;
    /** The offset from the bottom of our time table. */
    public const float OFFSET_BOTTOM = 36;
    /** The height of our time table */
    public const float HEIGHT = 504;
    
    /** The offset of the location bar next to our time table. */
    public const float OFFSET_LOCATION = 26;
    /** The width of the location bar next to our time table. */
    public const float WIDTH_LOCATION = 48;
    
    /** The height of a bar showing the movies at one specific location. */
    public static float HEIGHT_LOCATION = HEIGHT / LOCATIONS;
    /** The width of a time slot. */
    public static float WIDTH_TIMESLOT = WIDTH / TIMESLOTS;
// ---------------------------------------------------------------------------    
    /**
     * Draws the time table for a day at the film festival.
     * @param directcontent a canvas to which the time table has to be drawn.
     */
    protected void DrawTimeTable(PdfContentByte directcontent) {        
        directcontent.SaveState();
        directcontent.SetLineWidth(1.2f);
        float llx, lly, urx, ury;
        
        llx = OFFSET_LEFT;
        lly = OFFSET_BOTTOM;
        urx = OFFSET_LEFT + WIDTH;
        ury = OFFSET_BOTTOM + HEIGHT;
        directcontent.MoveTo(llx, lly);
        directcontent.LineTo(urx, lly);
        directcontent.LineTo(urx, ury);
        directcontent.LineTo(llx, ury);
        directcontent.ClosePath();
        directcontent.Stroke();
        
        llx = OFFSET_LOCATION;
        lly = OFFSET_BOTTOM;
        urx = OFFSET_LOCATION + WIDTH_LOCATION;
        ury = OFFSET_BOTTOM + HEIGHT;
        directcontent.MoveTo(llx, lly);
        directcontent.LineTo(urx, lly);
        directcontent.LineTo(urx, ury);
        directcontent.LineTo(llx, ury);
        directcontent.ClosePathStroke();
        
        directcontent.SetLineWidth(1);
        directcontent.MoveTo(
          OFFSET_LOCATION + WIDTH_LOCATION / 2, OFFSET_BOTTOM
        );
        directcontent.LineTo(
          OFFSET_LOCATION + WIDTH_LOCATION / 2, OFFSET_BOTTOM + HEIGHT
        );
        float y;
        for (int i = 1; i < LOCATIONS; i++) {
          y = OFFSET_BOTTOM + (i * HEIGHT_LOCATION);
          if (i == 2 || i == 6) {
            directcontent.MoveTo(OFFSET_LOCATION, y);
            directcontent.LineTo(OFFSET_LOCATION + WIDTH_LOCATION, y);
          }
          else {
            directcontent.MoveTo(OFFSET_LOCATION + WIDTH_LOCATION / 2, y);
            directcontent.LineTo(OFFSET_LOCATION + WIDTH_LOCATION, y);
          }
          directcontent.MoveTo(OFFSET_LEFT, y);
          directcontent.LineTo(OFFSET_LEFT + WIDTH, y);
        }
        directcontent.Stroke();
        directcontent.RestoreState();
    }
// ---------------------------------------------------------------------------    
    /**
     * Draws the time slots for a day at the film festival.
     * @param directcontent the canvas to which the time table has to be drawn.
     */
    protected void DrawTimeSlots(PdfContentByte directcontent) {
      directcontent.SaveState();
      float x;
      for (int i = 1; i < TIMESLOTS; i++) {
        x = OFFSET_LEFT + (i * WIDTH_TIMESLOT);
        directcontent.MoveTo(x, OFFSET_BOTTOM);
        directcontent.LineTo(x, OFFSET_BOTTOM + HEIGHT);
      }
      directcontent.SetLineWidth(0.3f);
      directcontent.SetColorStroke(BaseColor.GRAY);
      directcontent.SetLineDash(3, 1);
      directcontent.Stroke();
      directcontent.RestoreState();
    }    
// ===========================================================================
  }
}
MovieTimeBlocks.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieTimeBlocks : MovieTimeTable {
// ===========================================================================
    /** A list containing all the locations. */
    protected List<String> locations;
// ---------------------------------------------------------------------------        
    public override void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.A4.Rotate())) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.CompressionLevel = 0;
        // step 3
        document.Open();
        // step 4
        PdfContentByte over = writer.DirectContent;
        PdfContentByte under = writer.DirectContentUnder;
        locations = PojoFactory.GetLocations();
        List<string> days = PojoFactory.GetDays();
        List<Screening> screenings;
        foreach (string day in days) {
          DrawTimeTable(under);
          DrawTimeSlots(over);
          screenings = PojoFactory.GetScreenings(day);
          foreach (Screening screening in screenings) {
            DrawBlock(screening, under, over);
          }
          document.NewPage();
        }
      }
    }
// ---------------------------------------------------------------------------        
    /**
     * Draws a colored block on the time table, corresponding with
     * the screening of a specific movie.
     * @param    screening    a screening POJO, contains a movie and a category
     * @param    under    the canvas to which the block is drawn
     */
    protected void DrawBlock(
      Screening screening, PdfContentByte under, PdfContentByte over
    ) {
      under.SaveState();
      BaseColor color = WebColors.GetRGBColor(
        "#" + screening.movie.entry.category.color
      );
      under.SetColorFill(color);
      Rectangle rect = GetPosition(screening);
      under.Rectangle(
        rect.Left, rect.Bottom, rect.Width, rect.Height
      );
      under.Fill();
      over.Rectangle(
        rect.Left, rect.Bottom, rect.Width, rect.Height
      );
      over.Stroke();
      under.RestoreState();
    }
// ---------------------------------------------------------------------------        
    /** The "offset time" for our calendar sheets. */
    // public static long TIME930 = 30600000L;
    public const long TIME930 = 34200000L;
    
    /** The width of one minute. */
    public readonly float MINUTE = WIDTH_TIMESLOT / 30f;
// ---------------------------------------------------------------------------        
    /**
     * Calculates the position of a rectangle corresponding with a screening.
     * @param    screening    a screening POJO, contains a movie
     * @return    a Rectangle
     */
    protected Rectangle GetPosition(Screening screening) {
      float llx, lly, urx, ury;
      // long minutesAfter930 = (screening.getTime().getTime() - TIME930) / 60000L;
      long minutesAfter930 = (
        Utility.GetMilliseconds(screening.Time) - TIME930
      ) / 60000L;
      llx = OFFSET_LEFT + (MINUTE * minutesAfter930);
      int location = locations.IndexOf(screening.Location) + 1;
      lly = OFFSET_BOTTOM + (LOCATIONS - location) * HEIGHT_LOCATION;
      urx = llx + MINUTE * screening.movie.Duration;
      ury = lly + HEIGHT_LOCATION;
      return new Rectangle(llx, lly, urx, ury);
    }
// ===========================================================================
  }
}
FoobarFilmFestival.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class FoobarFilmFestival : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      string RESOURCE = Utility.ResourcePosters;
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        Chunk c;
        String foobar = "Foobar Film Festival";
        // Measuring a String in Helvetica
        Font helvetica = new Font(Font.FontFamily.HELVETICA, 12);
        BaseFont bf_helv = helvetica.GetCalculatedBaseFont(false);
        float width_helv = bf_helv.GetWidthPoint(foobar, 12);
        c = new Chunk(foobar + ": " + width_helv, helvetica);
        document.Add(new Paragraph(c));
        document.Add(new Paragraph(string.Format(
          "Chunk width: {0}", c.GetWidthPoint()
        )));
        // Measuring a String in Times
        BaseFont bf_times = BaseFont.CreateFont(
          "c:/windows/fonts/times.ttf", 
          BaseFont.WINANSI, BaseFont.EMBEDDED
        );
        Font times = new Font(bf_times, 12);
        float width_times = bf_times.GetWidthPoint(foobar, 12);
        c = new Chunk(foobar + ": " + width_times, times);
        document.Add(new Paragraph(c));
        document.Add(new Paragraph(String.Format(
          "Chunk width: {0}", c.GetWidthPoint()
        )));
        document.Add(Chunk.NEWLINE);
        // Ascent and descent of the String
        document.Add(new Paragraph(
          "Ascent Helvetica: " + bf_helv.GetAscentPoint(foobar, 12)
        ));
        document.Add(new Paragraph(
          "Ascent Times: " + bf_times.GetAscentPoint(foobar, 12)
        ));
        document.Add(new Paragraph(
          "Descent Helvetica: " + bf_helv.GetDescentPoint(foobar, 12)
        ));
        document.Add(new Paragraph(
          "Descent Times: " + bf_times.GetDescentPoint(foobar, 12)
        ));
        document.Add(Chunk.NEWLINE);
        // Kerned text
        width_helv = bf_helv.GetWidthPointKerned(foobar, 12);
        c = new Chunk(foobar + ": " + width_helv, helvetica);
        document.Add(new Paragraph(c));
        // Drawing lines to see where the text is added
        PdfContentByte canvas = writer.DirectContent;
        canvas.SaveState();
        canvas.SetLineWidth(0.05f);
        canvas.MoveTo(400, 806);
        canvas.LineTo(400, 626);
        canvas.MoveTo(508.7f, 806);
        canvas.LineTo(508.7f, 626);
        canvas.MoveTo(280, 788);
        canvas.LineTo(520, 788);
        canvas.MoveTo(280, 752);
        canvas.LineTo(520, 752);
        canvas.MoveTo(280, 716);
        canvas.LineTo(520, 716);
        canvas.MoveTo(280, 680);
        canvas.LineTo(520, 680);
        canvas.MoveTo(280, 644);
        canvas.LineTo(520, 644);
        canvas.Stroke();
        canvas.RestoreState();
        // Adding text with PdfContentByte.ShowTextAligned()
        canvas.BeginText();
        canvas.SetFontAndSize(bf_helv, 12);
        canvas.ShowTextAligned(Element.ALIGN_LEFT, foobar, 400, 788, 0);
        canvas.ShowTextAligned(Element.ALIGN_RIGHT, foobar, 400, 752, 0);
        canvas.ShowTextAligned(Element.ALIGN_CENTER, foobar, 400, 716, 0);
        canvas.ShowTextAligned(Element.ALIGN_CENTER, foobar, 400, 680, 30);
        canvas.ShowTextAlignedKerned(Element.ALIGN_LEFT, foobar, 400, 644, 0);
        canvas.EndText();
        // More lines to see where the text is added
        canvas.SaveState();
        canvas.SetLineWidth(0.05f);
        canvas.MoveTo(200, 590);
        canvas.LineTo(200, 410);
        canvas.MoveTo(400, 590);
        canvas.LineTo(400, 410);
        canvas.MoveTo(80, 572);
        canvas.LineTo(520, 572);
        canvas.MoveTo(80, 536);
        canvas.LineTo(520, 536);
        canvas.MoveTo(80, 500);
        canvas.LineTo(520, 500);
        canvas.MoveTo(80, 464);
        canvas.LineTo(520, 464);
        canvas.MoveTo(80, 428);
        canvas.LineTo(520, 428);
        canvas.Stroke();
        canvas.RestoreState();
        // Adding text with ColumnText.ShowTextAligned()
        Phrase phrase = new Phrase(foobar, times);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 200, 572, 0);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_RIGHT, phrase, 200, 536, 0);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 500, 0);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 464, 30);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 428, -30);
        // Chunk attributes
        c = new Chunk(foobar, times);
        c.SetHorizontalScaling(0.5f);
        phrase = new Phrase(c);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 572, 0);
        c = new Chunk(foobar, times);
        c.SetSkew(15, 15);
        phrase = new Phrase(c);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 536, 0);
        c = new Chunk(foobar, times);
        c.SetSkew(0, 25);
        phrase = new Phrase(c);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 500, 0);
        c = new Chunk(foobar, times);
        c.SetTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_STROKE, 0.1f, BaseColor.RED);
        phrase = new Phrase(c);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 464, 0);
        c = new Chunk(foobar, times);
        c.SetTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, 1, null);
        phrase = new Phrase(c);
        ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, phrase, 400, 428, -0);        
      }
    }
// ===========================================================================
  }
}
MovieTextInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
/**
 * Draws a time table to the direct content using lines and simple shapes,
 * adding blocks representing a movies.
 */
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieTextInfo : MovieTimeBlocks {
// ===========================================================================
    public override void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.A4.Rotate())) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        PdfContentByte over = writer.DirectContent;
        PdfContentByte under = writer.DirectContentUnder;
        locations = PojoFactory.GetLocations();
        List<string> days = PojoFactory.GetDays();
        List<Screening> screenings;
        int d = 1;
        foreach (string day in days) {
          DrawTimeTable(under);
          DrawTimeSlots(over);
          DrawInfo(over);
          DrawDateInfo(day, d++, over);
          screenings = PojoFactory.GetScreenings(day);
          foreach (Screening screening in screenings) {
            DrawBlock(screening, under, over);
            DrawMovieInfo(screening, over);
          }
          document.NewPage();
        }
      }
    }
// ---------------------------------------------------------------------------        
    /** The base font that will be used to write info on the calendar sheet. */
    protected BaseFont bf;
    
    /** A phrase containing a white letter "P" (for Press) */
    protected Phrase press;
 
    /** The different time slots. */
    public readonly String[] TIME = { 
      "09:30", "10:00", "10:30", "11:00", "11:30", "12:00",
      "00:30", "01:00", "01:30", "02:00", "02:30", "03:00",
      "03:30", "04:00", "04:30", "05:00", "05:30", "06:00",
      "06:30", "07:00", "07:30", "08:00", "08:30", "09:00",
      "09:30", "10:00", "10:30", "11:00", "11:30", "12:00",
      "00:30", "01:00" 
    };
// ---------------------------------------------------------------------------           
    /**
     * Draws some text on every calendar sheet.
     * 
     */
    protected void DrawInfo(PdfContentByte directcontent) {
      directcontent.BeginText();
      directcontent.SetFontAndSize(bf, 18);
      float x, y;
      x = (OFFSET_LEFT + WIDTH + OFFSET_LOCATION) / 2;
      y = OFFSET_BOTTOM + HEIGHT + 24;
      directcontent.ShowTextAligned(
        Element.ALIGN_CENTER,
        "FOOBAR FILM FESTIVAL", x, y, 0
      );
      x = OFFSET_LOCATION + WIDTH_LOCATION / 2f - 6;
      y = OFFSET_BOTTOM + HEIGHT_LOCATION;
      directcontent.ShowTextAligned(
        Element.ALIGN_CENTER,
        "The Majestic", x, y, 90
      );
      y = OFFSET_BOTTOM + HEIGHT_LOCATION * 4f;
      directcontent.ShowTextAligned(
        Element.ALIGN_CENTER,
        "Googolplex", x, y, 90
      );
      y = OFFSET_BOTTOM + HEIGHT_LOCATION * 7.5f;
      directcontent.ShowTextAligned(
        Element.ALIGN_CENTER,
        "Cinema Paradiso", x, y, 90
      );
      directcontent.SetFontAndSize(bf, 12);
      x = OFFSET_LOCATION + WIDTH_LOCATION - 6;
      for (int i = 0; i < LOCATIONS; i++) {
        y = OFFSET_BOTTOM + ((8.5f - i) * HEIGHT_LOCATION);
        directcontent.ShowTextAligned(
          Element.ALIGN_CENTER,
          locations[i], x, y, 90
        );
      }
      directcontent.SetFontAndSize(bf, 6);
      y = OFFSET_BOTTOM + HEIGHT + 1;
      for (int i = 0; i < TIMESLOTS; i++) {
        x = OFFSET_LEFT + (i * WIDTH_TIMESLOT);
        directcontent.ShowTextAligned(
          Element.ALIGN_LEFT,
          TIME[i], x, y, 45
        );
      }
      directcontent.EndText();
    }
// ---------------------------------------------------------------------------            
    /**
     * Draws some text on every calendar sheet.
     * 
     */
    protected void DrawDateInfo(string day, int d, PdfContentByte directcontent) {
      directcontent.BeginText();
      directcontent.SetFontAndSize(bf, 18);
      float x, y;
      x = OFFSET_LOCATION;
      y = OFFSET_BOTTOM + HEIGHT + 24;
      directcontent.ShowTextAligned(
        Element.ALIGN_LEFT,
        "Day " + d, x, y, 0
      );
      x = OFFSET_LEFT + WIDTH;
      directcontent.ShowTextAligned(
        Element.ALIGN_RIGHT,
        day, x, y, 0
      );
      directcontent.EndText();
    }
// ---------------------------------------------------------------------------            
    /**
     * Draws the info about the movie.
     * @throws DocumentException 
     */
    protected virtual void DrawMovieInfo(
      Screening screening, PdfContentByte directcontent
    ) {
      // if (true) {
      if (screening.Press) {
        Rectangle rect = GetPosition(screening);
        ColumnText.ShowTextAligned(
          directcontent, 
          Element.ALIGN_CENTER,
          press, (rect.Left + rect.Right) / 2,
          rect.Bottom + rect.Height / 4, 0
        );
      }
    }
// ---------------------------------------------------------------------------            
    /**
     * Constructor for the MovieCalendar class; initializes the base font object.
     * @throws IOException 
     * @throws DocumentException 
     */
    public MovieTextInfo() {
      bf = BaseFont.CreateFont();
      Font f = new Font(bf, HEIGHT_LOCATION / 2);
      f.Color = BaseColor.WHITE;
      press = new Phrase("P", f);
    }
// ===========================================================================
  }
}
MovieCalendar.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieCalendar : MovieTextInfo {
// ===========================================================================
    /**
     * Draws the info about the movie.
     * @throws DocumentException 
     */
    protected override void DrawMovieInfo(
      Screening screening, PdfContentByte directcontent
    ) {
      base.DrawMovieInfo(screening, directcontent);
      Rectangle rect = GetPosition(screening);
      ColumnText column = new ColumnText(directcontent);
      column.SetSimpleColumn(
        new Phrase(screening.movie.Title),
        rect.Left, rect.Bottom,
        rect.Right, rect.Top, 18, Element.ALIGN_CENTER
      );
      column.Go();
    }
// ---------------------------------------------------------------------------            
    /**
     * Constructor for the MovieCalendar class; initializes the base font object.
     * @throws IOException 
     * @throws DocumentException 
     */
    public MovieCalendar() : base() {  }
// ===========================================================================
  }
}
MovieColumns1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.draw;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieColumns1 : IWriter {
// ===========================================================================
    public virtual void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        IEnumerable<Movie> movies = PojoFactory.GetMovies();
        ColumnText ct = new ColumnText(writer.DirectContent);
        foreach (Movie movie in movies) {
          ct.AddText(CreateMovieInformation(movie));
          ct.AddText(Chunk.NEWLINE);
        }
        ct.Alignment = Element.ALIGN_JUSTIFIED;
        ct.ExtraParagraphSpace = 6;
        ct.SetLeading(0, 1.2f);
        ct.FollowingIndent = 27;
        int linesWritten = 0;
        int column = 0;
        // iText-ONLY, 'Initial value of the status' => 0
        // iTextSharp **DOES NOT** include this member variable
        // int status = ColumnText.START_COLUMN;
        int status = 0;
        while (ColumnText.HasMoreText(status)) {
          ct.SetSimpleColumn(
            COLUMNS[column][0], COLUMNS[column][1],
            COLUMNS[column][2], COLUMNS[column][3]
          );
          ct.YLine = COLUMNS[column][3];
          status = ct.Go();
          linesWritten += ct.LinesWritten;
          column = Math.Abs(column - 1);
          if (column == 0) document.NewPage();
        }
        
        ct.AddText(new Phrase("Lines written: " + linesWritten));
        ct.Go();
      }
    }
// ---------------------------------------------------------------------------    
    /** Definition of two columns */
    public readonly float[][] COLUMNS = {
      new float[] { 36, 36, 296, 806 },
      new float[] { 299, 36, 559, 806 }
    };
// ---------------------------------------------------------------------------    
    /**
     * Creates a Phrase containing information about a movie.
     * @param    movie    the movie for which you want to create a Paragraph
     */
    public Phrase CreateMovieInformation(Movie movie) {
      Phrase p = new Phrase();
      p.Font = FilmFonts.NORMAL;
      p.Add(new Phrase("Title: ", FilmFonts.BOLDITALIC));
      p.Add(PojoToElementFactory.GetMovieTitlePhrase(movie));
      p.Add(" ");
      if (!string.IsNullOrEmpty(movie.OriginalTitle)) {
        p.Add(new Phrase("Original title: ", FilmFonts.BOLDITALIC));
        p.Add(PojoToElementFactory.GetOriginalTitlePhrase(movie));
        p.Add(" ");
      }
      p.Add(new Phrase("Country: ", FilmFonts.BOLDITALIC));
      foreach (Country country in movie.Countries) {
        p.Add(PojoToElementFactory.GetCountryPhrase(country));
        p.Add(" ");
      }
      p.Add(new Phrase("Director: ", FilmFonts.BOLDITALIC));
      foreach (Director director in movie.Directors) {
        p.Add(PojoToElementFactory.GetDirectorPhrase(director));
        p.Add(" ");
      }
      p.Add(new Chunk("Year: ", FilmFonts.BOLDITALIC));
      p.Add(new Chunk(movie.Year.ToString(), FilmFonts.NORMAL));
      p.Add(new Chunk(" Duration: ", FilmFonts.BOLDITALIC));
      p.Add(new Chunk(movie.Duration.ToString(), FilmFonts.NORMAL));
      p.Add(new Chunk(" minutes", FilmFonts.NORMAL));
      p.Add(new LineSeparator(0.3f, 100, null, Element.ALIGN_CENTER, -2));
      return p;
    }    
// ===========================================================================
  }
}
MovieColumns2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.draw;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieColumns2 : MovieColumns1 {
// ===========================================================================
    public override void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        ColumnText ct = new ColumnText(writer.DirectContent) {
          Alignment = Element.ALIGN_JUSTIFIED, ExtraParagraphSpace = 6, 
          Leading = 14, Indent = 10, RightIndent = 3,
          SpaceCharRatio = PdfWriter.NO_SPACE_CHAR_RATIO
        };
        int column = 0;
        // iText-ONLY, 'Initial value of the status' => 0
        // iTextSharp **DOES NOT** include this member variable
        // int status = ColumnText.START_COLUMN;
        int status = 0;
        ct.SetSimpleColumn(
          COLUMNS[column][0], COLUMNS[column][1],
          COLUMNS[column][2], COLUMNS[column][3]
        );
        IEnumerable<Movie> movies = PojoFactory.GetMovies();
        foreach (Movie movie in movies) {
          ct.AddText(CreateMovieInformation(movie));
          status = ct.Go();
          if (ColumnText.HasMoreText(status)) {
            column = Math.Abs(column - 1);
            if (column == 0) {
              document.NewPage();
            }
            ct.SetSimpleColumn(
              COLUMNS[column][0], COLUMNS[column][1],
              COLUMNS[column][2], COLUMNS[column][3]
            );
            ct.YLine = COLUMNS[column][3];
            status = ct.Go();
          }
        }
      }
    }
// ===========================================================================
  }
}
MovieColumns3.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.draw;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieColumns3 : MovieColumns1 {
// ===========================================================================
    public override void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        ColumnText ct = new ColumnText(writer.DirectContent);
        int column = 0;
        ct.SetSimpleColumn(
          COLUMNS[column][0], COLUMNS[column][1],
          COLUMNS[column][2], COLUMNS[column][3]
        );
        // iText-ONLY, 'Initial value of the status' => 0
        // iTextSharp **DOES NOT** include this member variable
        // int status = ColumnText.START_COLUMN;
        int status = 0;
        Phrase p;
        float y;        
        IEnumerable<Movie> movies = PojoFactory.GetMovies();
        foreach (Movie movie in movies) {
          y = ct.YLine;
          p = CreateMovieInformation(movie);        
          ct.AddText(p);
          status = ct.Go(true);
          if (ColumnText.HasMoreText(status)) {
            column = Math.Abs(column - 1);
            if (column == 0) {
              document.NewPage();
            }
            ct.SetSimpleColumn(
              COLUMNS[column][0], COLUMNS[column][1],
              COLUMNS[column][2], COLUMNS[column][3]
            );
            y = COLUMNS[column][3];
          }
          ct.YLine = y;
          ct.SetText(p);
          status = ct.Go(false);
        }
      }
    }
// ===========================================================================
  }
}
MovieColumns4.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.draw;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieColumns4 : MovieColumns1 {
// ===========================================================================
    public override void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        PdfContentByte canvas = writer.DirectContent;
        DrawRectangles(canvas);
        ColumnText ct = new ColumnText(canvas);
        ct.Alignment = Element.ALIGN_JUSTIFIED;
        ct.Leading = 14;
        int column = 0;
        ct.SetColumns(
          new float[] { 36,806, 36,670, 108,670, 108,596, 36,596, 36,36 }, 
          new float[] { 296,806, 296,484, 259,484, 259,410, 296,410, 296,36 }
        ); 
        ct.SetColumns(LEFT[column], RIGHT[column] );
        // ct.SetColumns(LEFT[column], RIGHT[column]);
        // iText-ONLY, 'Initial value of the status' => 0
        // iTextSharp **DOES NOT** include this member variable
        // int status = ColumnText.START_COLUMN;
        int status = 0;
        Phrase p;
        float y;
        IEnumerable<Movie> movies = PojoFactory.GetMovies();
        foreach (Movie movie in movies) {
          y = ct.YLine;
          p = CreateMovieInformation(movie);
          ct.AddText(p);
          status = ct.Go(true);
          if (ColumnText.HasMoreText(status)) {
            column = Math.Abs(column - 1);
            if (column == 0) {
              document.NewPage();
              DrawRectangles(canvas);
            }
            ct.SetColumns(LEFT[column], RIGHT[column]);
            y = 806;
          }
          ct.YLine = y;
          ct.SetText(p);
          status = ct.Go();
        }        
      }
    }
// ---------------------------------------------------------------------------    
    public readonly float[][] LEFT = { 
      new float[] { 36,806, 36,670, 108,670, 108,596, 36,596, 36,36 }, 
      new float[] { 299,806, 299,484, 336,484, 336,410, 299,410, 299,36 } 
    };
    public readonly float[][] RIGHT = { 
      new float[] { 296,806, 296,484, 259,484, 259,410, 296,410, 296,36 },
      new float[] { 559,806, 559,246, 487,246, 487,172, 559,172, 559,36 } 
    };
// ---------------------------------------------------------------------------    
    /**
     * Draws three rectangles
     * @param canvas
     */
    public void DrawRectangles(PdfContentByte canvas) {
      canvas.SaveState();
      canvas.SetGrayFill(0.9f);
      canvas.Rectangle(33, 592, 72, 72);
      canvas.Rectangle(263, 406, 72, 72);
      canvas.Rectangle(491, 168, 72, 72);
      canvas.FillStroke();
      canvas.RestoreState();
    }    
// ===========================================================================
  }
}
ColumnMovies1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class ColumnMovies1 : IWriter {
// ===========================================================================
    public readonly string RESOURCE = Utility.ResourcePosters;
    /** Definition of two columns */
    public readonly float[,] COLUMNS = new float[,]  {
      { 36, 36, 224, 579 } , { 230, 36, 418, 579 },
      { 424, 36, 612, 579 } , { 618, 36, 806, 579 }
    };
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.A4.Rotate())) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        ColumnText ct = new ColumnText(writer.DirectContent);
        int column = 0;
        ct.SetSimpleColumn(
          COLUMNS[column,0], COLUMNS[column,1],
          COLUMNS[column,2], COLUMNS[column,3]
        );
        // iText-ONLY, 'Initial value of the status' => 0
        // iTextSharp **DOES NOT** include this member variable
        // int status = ColumnText.START_COLUMN;
        int status = 0;
        float y;
        Image img;
        IEnumerable<Movie> movies = PojoFactory.GetMovies();
        foreach (Movie movie in movies) {
          y = ct.YLine;
          img = Image.GetInstance(
            Path.Combine(RESOURCE, movie.Imdb + ".jpg")
          );
          img.ScaleToFit(80, 1000);
          AddContent(ct, movie, img);
          status = ct.Go(true);
          if (ColumnText.HasMoreText(status)) {
            column = (column + 1) % 4;
            if (column == 0) {
              document.NewPage();
            }
            ct.SetSimpleColumn(
              COLUMNS[column, 0], COLUMNS[column, 1],
              COLUMNS[column, 2], COLUMNS[column, 3]
            );
            y = COLUMNS[column, 3];
          }
          ct.YLine = y;
          ct.SetText(null);
          AddContent(ct, movie, img);
          status = ct.Go();
        }
      }
    }
// ---------------------------------------------------------------------------    
    /**
     * Add content to a ColumnText object.
     * @param ct the ColumnText object
     * @param movie a Movie object
     * @param img the poster of the image
     */
    public void AddContent(ColumnText ct, Movie movie, Image img) {
      ct.AddElement(img);
      ct.AddElement(new Paragraph(movie.Title, FilmFonts.BOLD));
      if (!string.IsNullOrEmpty(movie.OriginalTitle)) {
        ct.AddElement(new Paragraph(movie.OriginalTitle, FilmFonts.ITALIC));
      }
      ct.AddElement(PojoToElementFactory.GetDirectorList(movie));
      ct.AddElement(PojoToElementFactory.GetYearPhrase(movie));
      ct.AddElement(PojoToElementFactory.GetDurationPhrase(movie));
      ct.AddElement(PojoToElementFactory.GetCountryList(movie));
      ct.AddElement(Chunk.NEWLINE);
    }    
// ===========================================================================
  }
}
ColumnMovies2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
using kuujinbo.iTextInAction2Ed.Chapter02;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class ColumnMovies2 : IWriter {
// ===========================================================================
    /** Definition of two columns */
    public readonly float[,] COLUMNS = new float[,]  {
      { 40, 36, 219, 579 } , { 234, 36, 414, 579 },
      { 428, 36, 608, 579 } , { 622, 36, 802, 579 }
    };
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.A4.Rotate())) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        ColumnText ct = new ColumnText(writer.DirectContent);
        int column = 0;
        ct.SetSimpleColumn(
          COLUMNS[column,0], COLUMNS[column,1],
          COLUMNS[column,2], COLUMNS[column,3]
        );
        // iText-ONLY, 'Initial value of the status' => 0
        // iTextSharp **DOES NOT** include this member variable
        // int status = ColumnText.START_COLUMN;
        int status = 0;
        float y;
        IEnumerable<Movie> movies = PojoFactory.GetMovies();
        foreach (Movie movie in movies) {
          y = ct.YLine;
          AddContent(ct, movie);
          status = ct.Go(true);
          if (ColumnText.HasMoreText(status)) {
            column = (column + 1) % 4;
            if (column == 0) {
              document.NewPage();
            }
            ct.SetSimpleColumn(
              COLUMNS[column, 0], COLUMNS[column, 1],
              COLUMNS[column, 2], COLUMNS[column, 3]
            );
            y = COLUMNS[column, 3];
          }
          ct.YLine = y;
          ct.SetText(null);
          AddContent(ct, movie);
          status = ct.Go();
        }
      }
    }
// ---------------------------------------------------------------------------    
    /**
     * Add content to a ColumnText object.
     * @param ct the ColumnText object
     * @param movie a Movie object
     * @param img the poster of the image
     */
    public void AddContent(ColumnText ct, Movie movie) {
      Paragraph p;
      p = new Paragraph(new Paragraph(movie.Title, FilmFonts.BOLD));
      p.Alignment = Element.ALIGN_CENTER;
      p.SpacingBefore = 16;
      ct.AddElement(p);
      if (!string.IsNullOrEmpty(movie.OriginalTitle)) {
        p = new Paragraph(movie.OriginalTitle, FilmFonts.ITALIC);
        p.Alignment = Element.ALIGN_RIGHT;
        ct.AddElement(p);
      }
      p = new Paragraph();
      p.Add(PojoToElementFactory.GetYearPhrase(movie));
      p.Add(" ");
      p.Add(PojoToElementFactory.GetDurationPhrase(movie));
      p.Alignment = Element.ALIGN_JUSTIFIED_ALL;
      ct.AddElement(p);
      p = new Paragraph(new Chunk(new StarSeparator()));
      p.SpacingAfter = 12;
      ct.AddElement(p);
  }    
// ===========================================================================
  }
}
ImageDirect.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class ImageDirect : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30)) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.CompressionLevel = 0;
        // step 3
        document.Open();
        // step 4
        Image img = Image.GetInstance(Path.Combine(
          Utility.ResourceImage, "loa.jpg"
        ));
        img.SetAbsolutePosition(
          (PageSize.POSTCARD.Width - img.ScaledWidth) / 2,
          (PageSize.POSTCARD.Height - img.ScaledHeight) / 2
        );
        writer.DirectContent.AddImage(img);
        Paragraph p = new Paragraph(
          "Foobar Film Festival", 
          new Font(Font.FontFamily.HELVETICA, 22)
        );
        p.Alignment = Element.ALIGN_CENTER;
        document.Add(p);        
      }
    }
// ===========================================================================
  }
}
ImageSkew.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class ImageSkew : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.POSTCARD.Rotate())) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.CompressionLevel = 0;
        // step 3
        document.Open();
        // step 4
        Image img = Image.GetInstance(Path.Combine(
          Utility.ResourceImage, "loa.jpg"
        ));
        // Add the image to the upper layer
        writer.DirectContent.AddImage(
          img,
          img.Width, 0, 0.35f * img.Height,
          0.65f * img.Height, 30, 30
        );
      }
    }
// ===========================================================================
  }
}
ImageInline.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class ImageInline : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30)) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.CompressionLevel = 0;
        // step 3
        document.Open();
        // step 4
        Image img = Image.GetInstance(Path.Combine(
          Utility.ResourceImage, "loa.jpg"
        ));
        img.SetAbsolutePosition(
          (PageSize.POSTCARD.Width - img.ScaledWidth) / 2,
          (PageSize.POSTCARD.Height - img.ScaledHeight) / 2
        );
        writer.DirectContent.AddImage(img, true);
      }
    }
// ===========================================================================
  }
}
MoviePosters.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MoviePosters : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.A4)) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.CompressionLevel = 0;
        // step 3
        document.Open();
        // step 4
        PdfContentByte canvas = writer.DirectContent;
        // Create the XObject
        PdfTemplate celluloid = canvas.CreateTemplate(595, 84.2f);
        celluloid.Rectangle(8, 8, 579, 68);
        for (float f = 8.25f; f < 581; f+= 6.5f) {
          celluloid.RoundRectangle(f, 8.5f, 6, 3, 1.5f);
          celluloid.RoundRectangle(f, 72.5f, 6, 3, 1.5f);
        }
        celluloid.SetGrayFill(0.1f);
        celluloid.EoFill();
        // Write the XObject to the OutputStream
        writer.ReleaseTemplate(celluloid);
        // Add the XObject 10 times
        for (int i = 0; i < 10; i++) {
          canvas.AddTemplate(celluloid, 0, i * 84.2f);
        }
        // Go to the next page
        document.NewPage();
        // Add the XObject 10 times
        for (int i = 0; i < 10; i++) {
          canvas.AddTemplate(celluloid, 0, i * 84.2f);
        }
        // Get the movies from the database
        IEnumerable<Movie> movies = PojoFactory.GetMovies();
        Image img;
        float x = 11.5f;
        float y = 769.7f;
        string RESOURCE = Utility.ResourcePosters;
        // Loop over the movies and add images
        foreach (Movie movie in movies) {
          img = Image.GetInstance(Path.Combine(RESOURCE, movie.Imdb + ".jpg"));
          img.ScaleToFit(1000, 60);
          img.SetAbsolutePosition(x + (45 - img.ScaledWidth) / 2, y);
          canvas.AddImage(img);
          x += 48;
          if (x > 578) {
            x = 11.5f;
            y -= 84.2f;
          }
        }
        // Go to the next page
        document.NewPage();
        // Add the template using a different CTM
        canvas.AddTemplate(celluloid, 0.8f, 0, 0.35f, 0.65f, 0, 600);
        // Wrap the XObject in an Image object
        Image tmpImage = Image.GetInstance(celluloid);
        tmpImage.SetAbsolutePosition(0, 480);
        document.Add(tmpImage);
        // Perform transformations on the image
        tmpImage.RotationDegrees = 30;
        tmpImage.ScalePercent(80);
        tmpImage.SetAbsolutePosition(30, 500);
        document.Add(tmpImage);
        // More transformations
        tmpImage.Rotation = (float)Math.PI / 2;
        tmpImage.SetAbsolutePosition(200, 300);
        document.Add(tmpImage);
      }
    }
// ===========================================================================
  }
}
MovieTemplates.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
/**
 * Draws a time table to the direct content using lines and simple shapes,
 * adding blocks representing a movies.
 */
namespace kuujinbo.iTextInAction2Ed.Chapter03 {
  public class MovieTemplates : MovieCalendar {
// ===========================================================================
    public override void Write(Stream stream) {
      // step 1
      using (Document document = new Document(PageSize.A4.Rotate())) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        PdfContentByte over = writer.DirectContent;
        PdfContentByte under = writer.DirectContentUnder;
        locations = PojoFactory.GetLocations();
        PdfTemplate t_under = under.CreateTemplate(
          PageSize.A4.Height, PageSize.A4.Width
        );
        DrawTimeTable(t_under);
        PdfTemplate t_over = over.CreateTemplate(
          PageSize.A4.Height, PageSize.A4.Width
        );
        DrawTimeSlots(t_over);
        DrawInfo(t_over);        
        List<string> days = PojoFactory.GetDays();
        List<Screening> screenings;
        int d = 1;
        foreach (string day in days) {
          over.AddTemplate(t_over, 0, 0);
          under.AddTemplate(t_under, 0, 0);
          DrawDateInfo(day, d++, over);
          screenings = PojoFactory.GetScreenings(day);
          foreach (Screening screening in screenings) {
            DrawBlock(screening, under, over);
            DrawMovieInfo(screening, over);
          }
          document.NewPage();
        }
      }
    }
// ---------------------------------------------------------------------------            
    /**
     * Constructor MovieTemplates object.
     */
    public MovieTemplates() : base() {  }
// ===========================================================================
  }
}


Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now