Chapter 15: Page content and structure

This is a code example of iText PDF, discover more.

10th October 2015
admin-marketing

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

PeekABoo.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
/*
 * 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 part4.chapter15;
 
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.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfLayer;
import com.itextpdf.text.pdf.PdfWriter;
 
/**
 * This example was written by Bruno Lowagie. It is part of the book 'iText in
 * Action' by Manning Publications. 
 * ISBN: 1932394796
 * http://www.1t3xt.com/docs/book.php 
 * http://www.manning.com/lowagie/
 */
 
public class PeekABoo {
 
    /** The first resulting PDF. */
    public static String RESULT1 = "results/part4/chapter15/peek-a-boo1.pdf";
    /** The second resulting PDF. */
    public static String RESULT2 = "results/part4/chapter15/peek-a-boo2.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws DocumentException 
     * @throws IOException 
     */
    public void createPdf(String filename, boolean on) throws DocumentException, IOException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document,
            new FileOutputStream(filename));
        writer.setViewerPreferences(PdfWriter.PageModeUseOC);
        writer.setPdfVersion(PdfWriter.VERSION_1_5);
        // step 3
        document.open();
        // step 4
        PdfLayer layer = new PdfLayer("Do you see me?", writer);
        layer.setOn(on);
        BaseFont bf = BaseFont.createFont();
        PdfContentByte cb = writer.getDirectContent();
        cb.beginText();
        cb.setFontAndSize(bf, 18);
        cb.showTextAligned(Element.ALIGN_LEFT, "Do you see me?", 50, 790, 0);
        cb.beginLayer(layer);
        cb.showTextAligned(Element.ALIGN_LEFT, "Peek-a-Boo!!!", 50, 766, 0);
        cb.endLayer();
        cb.endText();
        // step 5
        document.close();
    }
    
    /**
     * A simple example with optional content.
     * 
     * @param args
     *            no arguments needed here
     * @throws IOException 
     * @throws DocumentException 
     */
    public static void main(String[] args) throws DocumentException, IOException {
        PeekABoo peekaboo = new PeekABoo();
        peekaboo.createPdf(RESULT1, true);
        peekaboo.createPdf(RESULT2, false);
    }
}
OptionalContentExample.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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
 
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.PdfLayer;
import com.itextpdf.text.pdf.PdfWriter;
 
public class OptionalContentExample {
 
    /** The resulting PDF. */
    public static String RESULT = "results/part4/chapter15/layer_structure.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws DocumentException 
     * @throws IOException 
     */
    public void createPdf(String filename)
        throws DocumentException, IOException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer =
            PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        writer.setPdfVersion(PdfWriter.VERSION_1_5);
        // step 3
        document.open();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
        PdfLayer nested = new PdfLayer("Nested layers", writer);
        PdfLayer nested_1 = new PdfLayer("Nested layer 1", writer);
        PdfLayer nested_2 = new PdfLayer("Nested layer 2", writer);
        nested.addChild(nested_1);
        nested.addChild(nested_2);
        writer.lockLayer(nested_2);
        cb.beginLayer(nested);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "nested layers"), 50, 775, 0);
        cb.endLayer();
        cb.beginLayer(nested_1);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "nested layer 1"), 100, 800, 0);
        cb.endLayer();
        cb.beginLayer(nested_2);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "nested layer 2"), 100, 750, 0);
        cb.endLayer();
 
        PdfLayer group = PdfLayer.createTitle("Grouped layers", writer);
        PdfLayer layer1 = new PdfLayer("Group: layer 1", writer);
        PdfLayer layer2 = new PdfLayer("Group: layer 2", writer);
        group.addChild(layer1);
        group.addChild(layer2);
        cb.beginLayer(layer1);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "layer 1 in the group"), 50, 700, 0);
        cb.endLayer();
        cb.beginLayer(layer2);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "layer 2 in the group"), 50, 675, 0);
        cb.endLayer();
 
        PdfLayer radiogroup = PdfLayer.createTitle("Radio group", writer);
        PdfLayer radio1 = new PdfLayer("Radiogroup: layer 1", writer);
        radio1.setOn(true);
        PdfLayer radio2 = new PdfLayer("Radiogroup: layer 2", writer);
        radio2.setOn(false);
        PdfLayer radio3 = new PdfLayer("Radiogroup: layer 3", writer);
        radio3.setOn(false);
        radiogroup.addChild(radio1);
        radiogroup.addChild(radio2);
        radiogroup.addChild(radio3);
        ArrayList<PdfLayer> options = new ArrayList<PdfLayer>();
        options.add(radio1);
        options.add(radio2);
        options.add(radio3);
        writer.addOCGRadioGroup(options);
        cb.beginLayer(radio1);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "option 1"), 50, 600, 0);
        cb.endLayer();
        cb.beginLayer(radio2);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "option 2"), 50, 575, 0);
        cb.endLayer();
        cb.beginLayer(radio3);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "option 3"), 50, 550, 0);
        cb.endLayer();
 
        PdfLayer not_printed = new PdfLayer("not printed", writer);
        not_printed.setOnPanel(false);
        not_printed.setPrint("Print", false);
        cb.beginLayer(not_printed);
        ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, new Phrase(
                "PRINT THIS PAGE"), 300, 700, 90);
        cb.endLayer();
 
        PdfLayer zoom = new PdfLayer("Zoom 0.75-1.25", writer);
        zoom.setOnPanel(false);
        zoom.setZoom(0.75f, 1.25f);
        cb.beginLayer(zoom);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
                "Only visible if the zoomfactor is between 75 and 125%"), 30,
                530, 90);
        cb.endLayer();
 
        // step 5
        document.close();
    }
 
    /**
     * A simple example with optional content.
     * 
     * @param args
     *            no arguments needed here
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws DocumentException,
            IOException {
        new OptionalContentExample().createPdf(RESULT);
    }
}
LayerMembershipExample1.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
/*
 * 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 part4.chapter15;
 
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.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfLayer;
import com.itextpdf.text.pdf.PdfLayerMembership;
import com.itextpdf.text.pdf.PdfWriter;
 
public class LayerMembershipExample1 {
 
    /** The resulting PDF. */
    public static String RESULT = "results/part4/chapter15/layer_membership1.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws DocumentException 
     * @throws IOException 
     */
    public void createPdf(String filename) throws DocumentException, IOException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(
                document, new FileOutputStream(RESULT));
        writer.setPdfVersion(PdfWriter.VERSION_1_5);
        // step 3
        document.open();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
 
        PdfLayer dog = new PdfLayer("layer 1", writer);
        PdfLayer tiger = new PdfLayer("layer 2", writer);
        PdfLayer lion = new PdfLayer("layer 3", writer);
        PdfLayerMembership cat = new PdfLayerMembership(writer);
        cat.addMember(tiger);
        cat.addMember(lion);
        PdfLayerMembership no_cat = new PdfLayerMembership(writer);
        no_cat.addMember(tiger);
        no_cat.addMember(lion);
        no_cat.setVisibilityPolicy(PdfLayerMembership.ALLOFF);
        cb.beginLayer(dog);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("dog"),
                50, 775, 0);
        cb.endLayer();
        cb.beginLayer(tiger);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("tiger"),
                50, 750, 0);
        cb.endLayer();
        cb.beginLayer(lion);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("lion"),
                50, 725, 0);
        cb.endLayer();
        cb.beginLayer(cat);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("cat"),
                50, 700, 0);
        cb.endLayer();
        cb.beginLayer(no_cat);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,
                new Phrase("no cat"), 50, 700, 0);
        cb.endLayer();
 
        // step 5
        document.close();
    }
 
    /**
     * A simple example with optional content.
     * 
     * @param args
     *            no arguments needed here
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws DocumentException,
            IOException {
        new LayerMembershipExample1().createPdf(RESULT);
    }
}
LayerMembershipExample2.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
/*
 * 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 part4.chapter15;
 
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.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfLayer;
import com.itextpdf.text.pdf.PdfLayerMembership;
import com.itextpdf.text.pdf.PdfVisibilityExpression;
import com.itextpdf.text.pdf.PdfWriter;
 
public class LayerMembershipExample2 {
 
    /** The resulting PDF. */
    public static String RESULT = "results/part4/chapter15/layer_membership2.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws DocumentException 
     * @throws IOException 
     */
    public void createPdf(String filename) throws DocumentException,
            IOException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(
                document, new FileOutputStream(RESULT));
        writer.setPdfVersion(PdfWriter.VERSION_1_6);
        // step 3
        document.open();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
 
        PdfLayer dog = new PdfLayer("layer 1", writer);
        PdfLayer tiger = new PdfLayer("layer 2", writer);
        PdfLayer lion = new PdfLayer("layer 3", writer);
        PdfLayerMembership cat = new PdfLayerMembership(writer);
        PdfVisibilityExpression ve1 = new PdfVisibilityExpression(PdfVisibilityExpression.OR);
        ve1.add(tiger);
        ve1.add(lion);
        cat.setVisibilityExpression(ve1);
        PdfLayerMembership no_cat = new PdfLayerMembership(writer);
        PdfVisibilityExpression ve2 = new PdfVisibilityExpression(PdfVisibilityExpression.NOT);
        ve2.add(ve1);
        no_cat.setVisibilityExpression(ve2);
        cb.beginLayer(dog);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("dog"),
                50, 775, 0);
        cb.endLayer();
        cb.beginLayer(tiger);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("tiger"),
                50, 750, 0);
        cb.endLayer();
        cb.beginLayer(lion);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("lion"),
                50, 725, 0);
        cb.endLayer();
        cb.beginLayer(cat);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("cat"),
                50, 700, 0);
        cb.endLayer();
        cb.beginLayer(no_cat);
        ColumnText.showTextAligned(cb, Element.ALIGN_LEFT,
                new Phrase("no cat"), 50, 700, 0);
        cb.endLayer();
 
        // step 5
        document.close();
    }
 
    /**
     * A simple example with optional content.
     * 
     * @param args
     *            no arguments needed here
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws DocumentException,
            IOException {
        new LayerMembershipExample2().createPdf(RESULT);
    }
}
OptionalContentActionExample.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
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
 
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.BaseFont;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfLayer;
import com.itextpdf.text.pdf.PdfWriter;
 
public class OptionalContentActionExample {
 
    /** The resulting PDF. */
    public static String RESULT = "results/part4/chapter15/layer_actions.pdf";
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws DocumentException 
     * @throws IOException 
     */
    public void createPdf(String filename) throws DocumentException, IOException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(
                document, new FileOutputStream(RESULT));
        writer.setPdfVersion(PdfWriter.VERSION_1_5);
        // step 3
        document.open();
        // step 4
        PdfLayer a1 = new PdfLayer("answer 1", writer);
        PdfLayer a2 = new PdfLayer("answer 2", writer);
        PdfLayer a3 = new PdfLayer("answer 3", writer);
        a1.setOn(false);
        a2.setOn(false);
        a3.setOn(false);
 
        BaseFont bf = BaseFont.createFont();
        PdfContentByte cb = writer.getDirectContent();
        cb.beginText();
        cb.setFontAndSize(bf, 18);
        cb.showTextAligned(Element.ALIGN_LEFT,
            "Q1: Who is the director of the movie 'Paths of Glory'?", 50, 766, 0);
        cb.showTextAligned(Element.ALIGN_LEFT,
            "Q2: Who directed the movie 'Lawrence of Arabia'?", 50, 718, 0);
        cb.showTextAligned(Element.ALIGN_LEFT,
            "Q3: Who is the director of 'House of Flying Daggers'?", 50, 670, 0);
        cb.endText();
        cb.saveState();
        cb.setRGBColorFill(0xFF, 0x00, 0x00);
        cb.beginText();
        cb.beginLayer(a1);
        cb.showTextAligned(Element.ALIGN_LEFT,
                "A1: Stanley Kubrick", 50, 742, 0);
        cb.endLayer();
        cb.beginLayer(a2);
        cb.showTextAligned(Element.ALIGN_LEFT,
                "A2: David Lean", 50, 694, 0);
        cb.endLayer();
        cb.beginLayer(a3);
        cb.showTextAligned(Element.ALIGN_LEFT,
                "A3: Zhang Yimou", 50, 646, 0);
        cb.endLayer();
        cb.endText();
        cb.restoreState();
 
        ArrayList<Object> stateOn = new ArrayList<Object>();
        stateOn.add("ON");
        stateOn.add(a1);
        stateOn.add(a2);
        stateOn.add(a3);
        PdfAction actionOn = PdfAction.setOCGstate(stateOn, true);
        ArrayList<Object> stateOff = new ArrayList<Object>();
        stateOff.add("OFF");
        stateOff.add(a1);
        stateOff.add(a2);
        stateOff.add(a3);
        PdfAction actionOff = PdfAction.setOCGstate(stateOff, true);
        ArrayList<Object> stateToggle = new ArrayList<Object>();
        stateToggle.add("Toggle");
        stateToggle.add(a1);
        stateToggle.add(a2);
        stateToggle.add(a3);
        PdfAction actionToggle = PdfAction.setOCGstate(stateToggle, true);
        Phrase p = new Phrase("Change the state of the answers:");
        Chunk on = new Chunk(" on ").setAction(actionOn);
        p.add(on);
        Chunk off = new Chunk("/ off ").setAction(actionOff);
        p.add(off);
        Chunk toggle = new Chunk("/ toggle").setAction(actionToggle);
        p.add(toggle);
        document.add(p);
        // step 5
        document.close();
    }
 
    /**
     * A simple example with optional content.
     * 
     * @param args
     *            no arguments needed here
     * @throws IOException
     * @throws DocumentException
     */
    public static void main(String[] args) throws DocumentException,
            IOException {
        new OptionalContentActionExample().createPdf(RESULT);
    }
}
SvgToPdf.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
/*
 * 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 part4.chapter15;
 
import java.awt.Graphics2D;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
 
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.svg.SVGDocument;
 
import com.itextpdf.awt.PdfGraphics2D;
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.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
 
public class SvgToPdf {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part4/chapter15/foobar.pdf";
    /** The map (shapes). */
    public static final String CITY = "resources/xml/foobarcity.svg";
    /** The map (text = street names in English). */
    public static final String STREETS = "resources/xml/foobarstreets.svg";
    
    /** The SVG document factory. */
    protected SAXSVGDocumentFactory factory;
    /** The SVG bridge context. */
    protected BridgeContext ctx;
    /** The GVT builder */
    protected GVTBuilder builder;
    
    /** Creates an SvgToPdf object. */
    public SvgToPdf() {
        String parser = XMLResourceDescriptor.getXMLParserClassName();
        factory = new SAXSVGDocumentFactory(parser);
        
        UserAgent userAgent = new UserAgentAdapter();
        DocumentLoader loader = new DocumentLoader(userAgent);
        ctx = new BridgeContext(userAgent, loader);
        ctx.setDynamicState(BridgeContext.DYNAMIC);
 
        builder = new GVTBuilder();
    }
    
    /**
     * Draws an SVG file to a PdfTemplate.
     * @param map      the template to which the SVG has to be drawn.
     * @param resource the SVG content.
     * @throws IOException
     */
    public void drawSvg(PdfTemplate map, String resource) throws IOException {
        Graphics2D g2d = new PdfGraphics2D(map, 6000, 6000);
        SVGDocument city = factory.createSVGDocument(new File(resource).toURL()
                .toString());
        GraphicsNode mapGraphics = builder.build(ctx, city);
        mapGraphics.paint(g2d);
        g2d.dispose();
    }
    
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException 
     */
    public void createPdf(String filename) throws IOException, DocumentException {
        // step 1
        Document document = new Document(new Rectangle(6000, 6000));
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        // step 3
        document.open();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
        PdfTemplate map = cb.createTemplate(6000, 6000);
        drawSvg(map, CITY);
        cb.addTemplate(map, 0, 0);
        PdfTemplate streets = cb.createTemplate(6000, 6000);
        drawSvg(streets, STREETS);
        cb.addTemplate(streets, 0, 0);
        // step 5
        document.close();
    }
    
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new SvgToPdf().createPdf(RESULT);
    }
}
SvgLayers.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
 
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfLayer;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
 
public class SvgLayers extends SvgToPdf {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part4/chapter15/foobarcity.pdf";
    /** The map. */
    public static final String RUES = "resources/xml/foobarrues.svg";
    /** The map. */
    public static final String STRATEN = "resources/xml/foobarstraten.svg";
 
    
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException 
     */
    public void createPdf(String filename) throws IOException, DocumentException {
        // step 1
        Document document = new Document(new Rectangle(6000, 6000));
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        writer.setViewerPreferences(PdfWriter.PageModeUseOC | PdfWriter.FitWindow);
        writer.setPdfVersion(PdfWriter.VERSION_1_5);
        // step 3
        document.open();
        // step 4
        // CREATE GRID LAYER
        PdfLayer gridLayer = new PdfLayer("Grid", writer);
        gridLayer.setZoom(0.2f, 1);
        gridLayer.setOnPanel(false);
        // CREATE STREET LAYERS
        PdfLayer streetlayer = PdfLayer.createTitle(
                "Streets / Rues / Straten", writer);
        PdfLayer streetlayer_en = new PdfLayer("English", writer);
        streetlayer_en.setOn(true);
        streetlayer_en.setLanguage("en", true);
        PdfLayer streetlayer_fr = new PdfLayer("Fran\u00e7ais", writer);
        streetlayer_fr.setOn(false);
        streetlayer_fr.setLanguage("fr", false);
        PdfLayer streetlayer_nl = new PdfLayer("Nederlands", writer);
        streetlayer_nl.setOn(false);
        streetlayer_nl.setLanguage("nl", false);
        streetlayer.addChild(streetlayer_en);
        streetlayer.addChild(streetlayer_fr);
        streetlayer.addChild(streetlayer_nl);
        ArrayList<PdfLayer> radio = new ArrayList<PdfLayer>();
        radio.add(streetlayer_en);
        radio.add(streetlayer_fr);
        radio.add(streetlayer_nl);
        writer.addOCGRadioGroup(radio);
        // CREATE MAP
        PdfContentByte cb = writer.getDirectContent();
        PdfTemplate map = cb.createTemplate(6000, 6000);
        // DRAW CITY
        drawSvg(map, CITY);
        cb.addTemplate(map, 0, 0);
        PdfTemplate streets = cb.createTemplate(6000, 6000);
        // DRAW STREETS
        drawSvg(streets, STREETS);
        streets.setLayer(streetlayer_en);
        cb.addTemplate(streets, 0, 0);
        PdfTemplate rues = cb.createTemplate(6000, 6000);
        drawSvg(rues, RUES);
        rues.setLayer(streetlayer_fr);
        cb.addTemplate(rues, 0, 0);
        PdfTemplate straten = cb.createTemplate(6000, 6000);
        drawSvg(straten, STRATEN);
        straten.setLayer(streetlayer_nl);
        cb.addTemplate(straten, 0, 0);
        // DRAW GRID
        cb.saveState();
        cb.beginLayer(gridLayer);
        cb.setGrayStroke(0.7f);
        cb.setLineWidth(2);
        for (int i = 0; i < 8; i++) {
            cb.moveTo(1250, 1500 + i * 500);
            cb.lineTo(4750, 1500 + i * 500);
        }
        for (int i = 0; i < 8; i++) {
            cb.moveTo(1250 + i * 500, 1500);
            cb.lineTo(1250 + i * 500, 5000);
        }
        cb.stroke();
        cb.endLayer();
        cb.restoreState();
        
        // CREATE INFO LAYERS
        PdfLayer cityInfoLayer = new PdfLayer("Foobar Info", writer);
        cityInfoLayer.setOn(false);
        PdfLayer hotelLayer = new PdfLayer("Hotel", writer);
        hotelLayer.setOn(false);
        cityInfoLayer.addChild(hotelLayer);
        PdfLayer parkingLayer = new PdfLayer("Parking", writer);
        parkingLayer.setOn(false);
        cityInfoLayer.addChild(parkingLayer);
        PdfLayer businessLayer = new PdfLayer("Industry", writer);
        businessLayer.setOn(false);
        cityInfoLayer.addChild(businessLayer);
        PdfLayer cultureLayer = PdfLayer.createTitle("Leisure and Culture",
                writer);
        PdfLayer goingoutLayer = new PdfLayer("Going out", writer);
        goingoutLayer.setOn(false);
        cultureLayer.addChild(goingoutLayer);
        PdfLayer restoLayer = new PdfLayer("Restaurants", writer);
        restoLayer.setOn(false);
        goingoutLayer.addChild(restoLayer);
        PdfLayer theatreLayer = new PdfLayer("(Movie) Theatres", writer);
        theatreLayer.setOn(false);
        goingoutLayer.addChild(theatreLayer);
        PdfLayer monumentLayer = new PdfLayer("Museums and Monuments",
                writer);
        monumentLayer.setOn(false);
        cultureLayer.addChild(monumentLayer);
        PdfLayer sportsLayer = new PdfLayer("Sports", writer);
        sportsLayer.setOn(false);
        cultureLayer.addChild(sportsLayer);
        // DRAW INFO
        BaseFont font = BaseFont.createFont(
                "c:/windows/fonts/webdings.ttf", BaseFont.WINANSI,
                BaseFont.EMBEDDED);
        cb.saveState();
        cb.beginText();
        cb.setRGBColorFill(0x00, 0x00, 0xFF);
        cb.setFontAndSize(font, 36);
        cb.beginLayer(cityInfoLayer);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x69), 2700, 3100, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x69), 3000, 2050, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x69), 3100, 2550, 0);
        cb.beginLayer(hotelLayer);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2000, 1900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2100, 1950, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2200, 2200, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2700, 3000, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2750, 3050, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2500, 3500, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2300, 2000, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 3250, 2200, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 3300, 2300, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 3400, 3050, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 3250, 3200, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2750, 3800, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2900, 3800, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 3000, 2400, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2000, 2800, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe3), 2600, 3200, 0);
        cb.endLayer(); // hotelLayer
        cb.beginLayer(parkingLayer);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe8), 2400, 2000, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe8), 2100, 2600, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe8), 3300, 2250, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe8), 3000, 3900, 0);
        cb.endLayer(); // parkingLayer
        cb.beginLayer(businessLayer);
        cb.setRGBColorFill(0xC0, 0xC0, 0xC0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3050, 3600, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3200, 3900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3150, 3700, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3260, 3610, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3350, 3750, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3500, 4000, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3500, 3800, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3450, 3700, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x46), 3450, 3600, 0);
        cb.endLayer(); // businessLayer
        cb.endLayer(); // cityInfoLayer
        cb.beginLayer(goingoutLayer);
        cb.beginLayer(restoLayer);
        cb.setRGBColorFill(0xFF, 0x14, 0x93);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 2650, 3500, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 2400, 1900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 2750, 3850, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 2700, 3200, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 2900, 3100, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 2850, 3000, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 2800, 2900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 2300, 2900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 1950, 2650, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 1800, 2750, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 3350, 3150, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 3400, 3100, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xe4), 3250, 3450, 0);
        cb.endLayer(); // restoLayer
        cb.beginLayer(theatreLayer);
        cb.setRGBColorFill(0xDC, 0x14, 0x3C);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xae), 2850, 3300, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xae), 3050, 2900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xae), 2650, 2900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xae), 2750, 2600, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xB8), 2800, 3350, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xB8), 2550, 2850, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xB8), 2850, 3300, 0);
        cb.endLayer(); // theatreLayer
        cb.endLayer(); // goingoutLayer
        cb.beginLayer(monumentLayer);
        cb.setRGBColorFill(0x00, 0x00, 0x00);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x47), 3250, 2750, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x47), 2750, 2900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x47), 2850, 3500, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xad), 2150, 3550, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xad), 3300, 2730, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xad), 2200, 2000, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xad), 2900, 3300, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0xad), 2080, 3000, 0);
        cb.endLayer(); // monumentLayer
        cb.beginLayer(sportsLayer);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x53), 2700, 4050, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x53), 2700, 3900, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x53), 2800, 3980, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x53), 1950, 2800, 0);
        cb.showTextAligned(PdfContentByte.ALIGN_CENTER, String
                .valueOf((char) 0x53), 3700, 2450, 0);
        cb.endLayer(); // sportsLayer
        cb.endText();
        cb.restoreState();
        // step 5
        document.close();
    }
    
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException 
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new SvgLayers().createPdf(RESULT);
    }
}
ObjectData.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
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.PdfStructureElement;
import com.itextpdf.text.pdf.PdfStructureTreeRoot;
import com.itextpdf.text.pdf.PdfWriter;
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Director;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
 
public class ObjectData {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part4/chapter15/objectdata.pdf";
    /** Path to the resources. */
    public static final String RESOURCE
        = "resources/posters/%s.jpg";
    /** SQL statement to get selected directors */
    public static final String SELECTDIRECTORS =
        "SELECT DISTINCT d.id, d.name, d.given_name, count(*) AS c "
        + "FROM film_director d, film_movie_director md "
        + "WHERE d.id = md.director_id AND d.id < 8 "
        + "GROUP BY d.id, d.name, d.given_name ORDER BY id";
    
    /**
     * 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 {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        writer.setTagged();
        writer.setUserProperties(true);
        // step 3
        document.open();
        // step 4
 
        PdfStructureTreeRoot root = writer.getStructureTreeRoot();
        root.mapRole(new PdfName("Directors"), PdfName.H);
        for (int i = 1; i < 8; i++) {
            root.mapRole(new PdfName("director" + i), PdfName.P);
        }
        
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
 
        PdfStructureTreeRoot tree = writer.getStructureTreeRoot();
        PdfStructureElement top = new PdfStructureElement(tree, new PdfName("Directors"));
        
        Map<Integer,PdfStructureElement> directors = new HashMap<Integer,PdfStructureElement>();
        Statement stm = connection.createStatement();
        ResultSet rs = stm.executeQuery(SELECTDIRECTORS);
        int id;
        Director director;
        PdfStructureElement e;
        while (rs.next()) {
            id = rs.getInt("id");
            director = PojoFactory.getDirector(rs);
            e = new PdfStructureElement(top, new PdfName("director" + id));
            PdfDictionary userproperties = new PdfDictionary();
            userproperties.put(PdfName.O, PdfName.USERPROPERTIES);
            PdfArray properties = new PdfArray();
            PdfDictionary property1 = new PdfDictionary();
            property1.put(PdfName.N, new PdfString("Name"));
            property1.put(PdfName.V, new PdfString(director.getName()));            
            properties.add(property1);
            PdfDictionary property2 = new PdfDictionary();
            property2.put(PdfName.N, new PdfString("Given name"));
            property2.put(PdfName.V, new PdfString(director.getGivenName()));            
            properties.add(property2);
            PdfDictionary property3 = new PdfDictionary();
            property3.put(PdfName.N, new PdfString("Posters"));
            property3.put(PdfName.V, new PdfNumber(rs.getInt("c")));            
            properties.add(property3);
            userproperties.put(PdfName.P, properties);
            e.put(PdfName.A, userproperties);
            directors.put(id, e);
        }
        
        Map<Movie,Integer> map = new TreeMap<Movie,Integer>();
        for (int i = 1; i < 8; i++) {
            List<Movie> movies = PojoFactory.getMovies(connection, i);
            for (Movie movie : movies) {
                map.put(movie, i);
            }
        }
        
        PdfContentByte canvas = writer.getDirectContent();
        Image img;
        float x = 11.5f;
        float y = 769.7f;
        for (Map.Entry<Movie,Integer> entry : map.entrySet()) {
            img = Image.getInstance(String.format(RESOURCE, entry.getKey().getImdb()));
            img.scaleToFit(1000, 60);
            img.setAbsolutePosition(x + (45 - img.getScaledWidth()) / 2, y);
            canvas.beginMarkedContentSequence(directors.get(entry.getValue()));
            canvas.addImage(img);
            canvas.endMarkedContentSequence();
            x += 48;
            if (x > 578) {
                x = 11.5f;
                y -= 84.2f;
            }
        }
        // step 5
        document.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 ObjectData().createPdf(RESULT);
    }
}
ReadOutLoud.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
/*
 * 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 part4.chapter15;
 
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.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.PdfStructureElement;
import com.itextpdf.text.pdf.PdfStructureTreeRoot;
import com.itextpdf.text.pdf.PdfWriter;
 
public class ReadOutLoud {
 
    /** The resulting PDF. */
    public static String RESULT = "results/part4/chapter15/read_out_loud.pdf";
    /** A resource that is used in the PDF document. */
    public static String RESOURCE = "resources/posters/0062622.jpg";
 
    /**
     * 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();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document,
                new FileOutputStream(filename));
        writer.setTagged();
        // step 3
        document.open();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
        BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
                BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
        BaseFont bf2 = BaseFont.createFont("c:/windows/fonts/msgothic.ttc,1",
                BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
 
        PdfStructureTreeRoot root = writer.getStructureTreeRoot();
        PdfStructureElement div = new PdfStructureElement(root, new PdfName("Div"));
        PdfDictionary dict;
 
        cb.beginMarkedContentSequence(div);
 
        cb.beginText();
        cb.moveText(36, 788);
        cb.setFontAndSize(bf, 12);
        cb.setLeading(18);
        cb.showText("These are some famous movies by Stanley Kubrick: ");
        dict = new PdfDictionary();
        dict.put(PdfName.E, new PdfString("Doctor"));
        cb.beginMarkedContentSequence(new PdfName("Span"), dict, true);
        cb.newlineShowText("Dr.");
        cb.endMarkedContentSequence();
        cb.showText(" Strangelove or: How I Learned to Stop Worrying and Love the Bomb.");
        dict = new PdfDictionary();
        dict.put(PdfName.E, new PdfString("Eyes Wide Shut."));
        cb.beginMarkedContentSequence(new PdfName("Span"), dict, true);
        cb.newlineShowText("EWS");
        cb.endMarkedContentSequence();
        cb.endText();
        dict = new PdfDictionary();
        dict.put(PdfName.LANG, new PdfString("en-us"));
        dict.put(new PdfName("Alt"), new PdfString("2001: A Space Odyssey."));
        cb.beginMarkedContentSequence(new PdfName("Span"), dict, true);
        Image img = Image.getInstance(RESOURCE);
        img.scaleToFit(1000, 100);
        img.setAbsolutePosition(36, 640);
        cb.addImage(img);
        cb.endMarkedContentSequence();
 
        cb.beginText();
        cb.moveText(36, 620);
        cb.setFontAndSize(bf, 12);
        cb.showText("This is a movie by Akira Kurosawa: ");
        dict = new PdfDictionary();
        dict.put(PdfName.ACTUALTEXT, new PdfString("Seven Samurai."));
        cb.beginMarkedContentSequence(new PdfName("Span"), dict, true);
        cb.setFontAndSize(bf2, 12);
        cb.showText("\u4e03\u4eba\u306e\u4f8d");
        cb.endMarkedContentSequence();
        cb.endText();
        
        cb.endMarkedContentSequence();
        // step 5
        document.close();
    }
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new ReadOutLoud().createPdf(RESULT);
    }
}
StructureParser.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
/*
 * 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 part4.chapter15;
import java.util.List;
 
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfStructureElement;
 
public class StructureParser extends DefaultHandler {
 
    /** The top element in the PDF structure */
    protected PdfStructureElement top;
    /** The list of structure elements */
    protected List<PdfStructureElement> elements;
 
    /** Creates a parser that will parse an XML file into a structure tree. */
    public StructureParser(PdfStructureElement top, List<PdfStructureElement> elements) {
        this.top = top;
        this.elements = elements;
    }
    
    /**
     * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
     *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
     */
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        if ("chapter".equals(qName)) return;
        elements.add(new PdfStructureElement(top, new PdfName(qName)));
    }
}
ContentParser.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
/*
 * 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 part4.chapter15;
 
import java.io.IOException;
import java.util.List;
 
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
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.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfStructureElement;
import com.itextpdf.text.pdf.PdfWriter;
 
public class ContentParser extends DefaultHandler {
 
    /** The StringBuffer that holds the characters. */
    protected StringBuffer buf = new StringBuffer();
 
    /** The document to which content parsed form XML will be added. */
    protected Document document;
    /** The writer to which PDF syntax will be written. */
    protected PdfWriter writer;
    /** The canvas to which content will be written. */
    protected PdfContentByte canvas;
    /** A list with structure elements. */
    protected List<PdfStructureElement> elements;
    /** The current structure element during the parsing process. */
    protected PdfStructureElement current;
    /** The column to which content will be added. */
    protected ColumnText column;
    /** The font used when content elements are created. */
    protected Font font;
    
    /**
     * Creates a new ContentParser
     * @param document
     * @param writer
     * @param elements
     * @throws DocumentException
     * @throws IOException
     */
    public ContentParser(Document document, PdfWriter writer, List<PdfStructureElement> elements)
        throws DocumentException, IOException {
        this.document = document;
        this.writer = writer;
        canvas = writer.getDirectContent();
        column = new ColumnText(canvas);
        column.setSimpleColumn(36, 36, 384, 569);
        this.elements = elements;
        font = new Font(
            BaseFont.createFont("c:/windows/fonts/arial.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED), 12);
    }
 
    /**
     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
     */
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        for (int i = start; i < start + length; i++) {
            if (ch[i] == '\n')
                buf.append(' ');
            else
                buf.append(ch[i]);
        }
    }
 
    /**
     * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
     *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
     */
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        if ("chapter".equals(qName)) return;
        current = elements.get(0);
        elements.remove(0);
        canvas.beginMarkedContentSequence(current);
    }
    
    /**
     * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
     *      java.lang.String, java.lang.String)
     */
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if ("chapter".equals(qName)) return;
        try {
            String s = buf.toString().trim();
            buf = new StringBuffer();
            if (s.length() > 0) {
                Paragraph p = new Paragraph(s, font);
                p.setAlignment(Element.ALIGN_JUSTIFIED);
                column.addElement(p);
                int status = column.go();
                while (ColumnText.hasMoreText(status)) {
                    canvas.endMarkedContentSequence();
                    document.newPage();
                    canvas.beginMarkedContentSequence(current);
                    column.setSimpleColumn(36, 36, 384, 569);
                    status = column.go();
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        canvas.endMarkedContentSequence();
    }
}
StructuredContent.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
/*
 * 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 part4.chapter15;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
 
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfStructureElement;
import com.itextpdf.text.pdf.PdfStructureTreeRoot;
import com.itextpdf.text.pdf.PdfWriter;
 
public class StructuredContent {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part4/chapter15/moby.pdf";
    /** An XML file that will be converted to PDF. */
    public static final String RESOURCE = "resources/xml/moby.xml";
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SAXException
     * @throws ParserConfigurationException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SAXException, ParserConfigurationException {
        Document document = new Document(PageSize.A5);
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        writer.setTagged();
        document.open();
        PdfStructureTreeRoot root = writer.getStructureTreeRoot();
        root.mapRole(new PdfName("chapter"), PdfName.SECT);
        root.mapRole(new PdfName("title"), PdfName.H);
        root.mapRole(new PdfName("para"), PdfName.P);
        PdfStructureElement top = new PdfStructureElement(root, new PdfName("chapter"));
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        List<PdfStructureElement> elements = new ArrayList<PdfStructureElement>();
        parser.parse(
            new InputSource(new FileInputStream(RESOURCE)),
            new StructureParser(top, elements));
        parser.parse(
            new InputSource(new FileInputStream(RESOURCE)),
            new ContentParser(document, writer, elements));
        document.close();
    }
}
ParseTaggedPdf.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
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import javax.xml.parsers.ParserConfigurationException;
 
import org.xml.sax.SAXException;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.TaggedPdfReaderTool;
 
public class ParseTaggedPdf {
 
    /** The resulting XML file. */
    public static final String RESULT
        = "results/part4/chapter15/moby_extracted.xml";
 
    /**
     * Creates a PDF file using a previous example,
     * then parses the document.
     * @param    args    no arguments needed
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SAXException, ParserConfigurationException {
        StructuredContent.main(args);
        TaggedPdfReaderTool readertool = new TaggedPdfReaderTool();
        PdfReader reader = new PdfReader(StructuredContent.RESULT);
        readertool.convertToXml(reader, new FileOutputStream(RESULT));
        reader.close();
    }
}
ParsingHelloWorld.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
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
 
import part1.chapter01.HelloWorld;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.io.RandomAccessSourceFactory;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PRTokeniser;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.parser.ContentByteUtils;
import com.itextpdf.text.pdf.parser.PdfContentStreamProcessor;
import com.itextpdf.text.pdf.parser.RenderListener;
 
public class ParsingHelloWorld {
 
    /** The resulting PDF. */
    public static final String PDF = "results/part4/chapter15/hello_reverse.pdf";
    /** A possible resulting after parsing the PDF. */
    public static final String TEXT1 = "results/part4/chapter15/result1.txt";
    /** A possible resulting after parsing the PDF. */
    public static final String TEXT2 = "results/part4/chapter15/result2.txt";
    /** A possible resulting after parsing the PDF. */
    public static final String TEXT3 = "results/part4/chapter15/result3.txt";
    
    /**
     * Generates a PDF file with the text 'Hello World'
     * @throws DocumentException 
     * @throws IOException 
     */
    public void createPdf(String filename) throws DocumentException, IOException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer
          = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        // we add the text to the direct content, but not in the right order
        PdfContentByte cb = writer.getDirectContent();
        BaseFont bf = BaseFont.createFont();
        cb.beginText();
        cb.setFontAndSize(bf, 12);
        cb.moveText(88.66f, 367); 
        cb.showText("ld");
        cb.moveText(-22f, 0); 
        cb.showText("Wor");
        cb.moveText(-15.33f, 0); 
        cb.showText("llo");
        cb.moveText(-15.33f, 0); 
        cb.showText("He");
        cb.endText();
        // we also add text in a form XObject
        PdfTemplate tmp = cb.createTemplate(250, 25);
        tmp.beginText();
        tmp.setFontAndSize(bf, 12);
        tmp.moveText(0, 7);
        tmp.showText("Hello People");
        tmp.endText();
        cb.addTemplate(tmp, 36, 343);
        // step 5
        document.close();
    }
    
    /**
     * Parses the PDF using PRTokeniser
     * @param src  the path to the original PDF file
     * @param dest the path to the resulting text file
     * @throws IOException
     */
    public void parsePdf(String src, String dest) throws IOException {
        PdfReader reader = new PdfReader(src);
        // we can inspect the syntax of the imported page
        byte[] streamBytes = reader.getPageContent(1);
        PRTokeniser tokenizer = new PRTokeniser(new RandomAccessFileOrArray(new RandomAccessSourceFactory().createSource(streamBytes)));
        PrintWriter out = new PrintWriter(new FileOutputStream(dest));
        while (tokenizer.nextToken()) {
            if (tokenizer.getTokenType() == PRTokeniser.TokenType.STRING) {
                out.println(tokenizer.getStringValue());
            }
        }
        out.flush();
        out.close();
        reader.close();
    }
    
    /**
     * Extracts text from a PDF document.
     * @param src  the original PDF document
     * @param dest the resulting text file
     * @throws IOException
     */
    public void extractText(String src, String dest) throws IOException {
        PrintWriter out = new PrintWriter(new FileOutputStream(dest));
        PdfReader reader = new PdfReader(src);
        RenderListener listener = new MyTextRenderListener(out);
        PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
        PdfDictionary pageDic = reader.getPageN(1);
        PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
        processor.processContent(ContentByteUtils.getContentBytesForPage(reader, 1), resourcesDic);
        out.flush();
        out.close();
        reader.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws DocumentException, IOException {
        ParsingHelloWorld example = new ParsingHelloWorld();
        HelloWorld.main(args);
        example.createPdf(PDF);
        example.parsePdf(HelloWorld.RESULT, TEXT1);
        example.parsePdf(PDF, TEXT2);
        example.extractText(PDF, TEXT3);
    }
}
MyTextRenderListener.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
/*
 * 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 part4.chapter15;
 
import java.io.PrintWriter;
 
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
 
public class MyTextRenderListener implements RenderListener {
 
    /** The print writer to which the information will be written. */
    protected PrintWriter out;
 
    /**
     * Creates a RenderListener that will look for text.
     */
    public MyTextRenderListener(PrintWriter out) {
        this.out = out;
    }
    
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
     */
    public void beginTextBlock() {
        out.print("<");
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
     */
    public void endTextBlock() {
        out.println(">");
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
     *     com.itextpdf.text.pdf.parser.ImageRenderInfo)
     */
    public void renderImage(ImageRenderInfo renderInfo) {
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderText(
     *     com.itextpdf.text.pdf.parser.TextRenderInfo)
     */
    public void renderText(TextRenderInfo renderInfo) {
        out.print("<");
        out.print(renderInfo.getText());
        out.print(">");
    }
}
InspectPageContent.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
/*
 * 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 part4.chapter15;
 
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
 
import part1.chapter03.MovieTemplates;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.parser.PdfContentReaderTool;
 
public class InspectPageContent {
 
    /** Text file containing information about a PDF file. */
    public static final String RESULT = "results/part4/chapter15/calendar_info.txt";
    
    /**
     * Parses object and content information of a PDF into a text file.
     * @param pdf the original PDF
     * @param txt the resulting text
     * @throws IOException
     */
    public void inspectPdf(String pdf, String txt) throws IOException {
        PrintWriter out = new PrintWriter(new FileOutputStream(txt));
        PdfContentReaderTool.listContentStream(new File(pdf), out);
        out.flush();
        out.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new MovieTemplates().createPdf(MovieTemplates.RESULT);
        new InspectPageContent().inspectPdf(MovieTemplates.RESULT, RESULT);
    }
}
ExtractPageContent.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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
 
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.SimpleTextExtractionStrategy;
import com.itextpdf.text.pdf.parser.TextExtractionStrategy;
 
public class ExtractPageContent {
 
    /** The original PDF that will be parsed. */
    public static final String PREFACE = "resources/pdfs/preface.pdf";
    /** The resulting text file. */
    public static final String RESULT = "results/part4/chapter15/preface.txt";
    
    /**
     * Parses a PDF to a plain text file.
     * @param pdf the original PDF
     * @param txt the resulting text
     * @throws IOException
     */
    public void parsePdf(String pdf, String txt) throws IOException {
        PdfReader reader = new PdfReader(pdf);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        PrintWriter out = new PrintWriter(new FileOutputStream(txt));
        TextExtractionStrategy strategy;
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            strategy = parser.processContent(i, new SimpleTextExtractionStrategy());
            out.println(strategy.getResultantText());
        }
        out.flush();
        out.close();
        reader.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        new ExtractPageContent().parsePdf(PREFACE, RESULT);
    }
}
ExtractPageContentSorted1.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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
 
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.LocationTextExtractionStrategy;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.TextExtractionStrategy;
 
public class ExtractPageContentSorted1 {
 
    /** The original PDF that will be parsed. */
    public static final String PREFACE = "resources/pdfs/preface.pdf";
    /** The resulting text file. */
    public static final String RESULT = "results/part4/chapter15/preface_sorted1.txt";
    
    /**
     * Parses a PDF to a plain text file.
     * @param pdf the original PDF
     * @param txt the resulting text
     * @throws IOException
     */
    public void parsePdf(String pdf, String txt) throws IOException {
        PdfReader reader = new PdfReader(pdf);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        PrintWriter out = new PrintWriter(new FileOutputStream(txt));
        TextExtractionStrategy strategy;
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            strategy = parser.processContent(i, new LocationTextExtractionStrategy());
            out.println(strategy.getResultantText());
        }
        out.flush();
        out.close();
        reader.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        new ExtractPageContentSorted1().parsePdf(PREFACE, RESULT);
    }
}
ExtractPageContentSorted2.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
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
 
public class ExtractPageContentSorted2 {
 
    /** The original PDF that will be parsed. */
    public static final String PREFACE = "resources/pdfs/preface.pdf";
    /** The resulting text file. */
    public static final String RESULT = "results/part4/chapter15/preface_sorted2.txt";
    
    /**
     * Parses a specific area of a PDF to a plain text file.
     * @param pdf the original PDF
     * @param txt the resulting text
     * @throws IOException
     */
    public void parsePdf(String pdf, String txt) throws IOException {
        PdfReader reader = new PdfReader(pdf);
        PrintWriter out = new PrintWriter(new FileOutputStream(txt));
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            out.println(PdfTextExtractor.getTextFromPage(reader, i));
        }
        out.flush();
        out.close();
        reader.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new ExtractPageContentSorted2().parsePdf(PREFACE, RESULT);
    }
}
ExtractPageContentArea.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
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.FilteredTextRenderListener;
import com.itextpdf.text.pdf.parser.LocationTextExtractionStrategy;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import com.itextpdf.text.pdf.parser.RegionTextRenderFilter;
import com.itextpdf.text.pdf.parser.RenderFilter;
import com.itextpdf.text.pdf.parser.TextExtractionStrategy;
 
public class ExtractPageContentArea {
 
    /** The original PDF that will be parsed. */
    public static final String PREFACE = "resources/pdfs/preface.pdf";
    /** The resulting text file. */
    public static final String RESULT = "results/part4/chapter15/preface_clipped.txt";
    
    /**
     * Parses a specific area of a PDF to a plain text file.
     * @param pdf the original PDF
     * @param txt the resulting text
     * @throws IOException
     */
    public void parsePdf(String pdf, String txt) throws IOException {
        PdfReader reader = new PdfReader(pdf);
        PrintWriter out = new PrintWriter(new FileOutputStream(txt));
        Rectangle rect = new Rectangle(70, 80, 490, 580);
        RenderFilter filter = new RegionTextRenderFilter(rect);
        TextExtractionStrategy strategy;
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            strategy = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), filter);
            out.println(PdfTextExtractor.getTextFromPage(reader, i, strategy));
        }
        out.flush();
        out.close();
        reader.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new ExtractPageContentArea().parsePdf(PREFACE, RESULT);
    }
}
ShowTextMargins.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
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.TextMarginFinder;
 
public class ShowTextMargins {
 
    /** The original document. */
    public static final String PREFACE = "resources/pdfs/preface.pdf";
    /** The new document to which we've added a border rectangle. */
    public static final String RESULT = "results/part4/chapter15/margins.pdf";
    
    /**
     * Parses a PDF and ads a rectangle showing the text margin.
     * @param src the source PDF
     * @param dest the resulting PDF
     */
    public void addMarginRectangle(String src, String dest)
        throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT));
        TextMarginFinder finder;
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            finder = parser.processContent(i, new TextMarginFinder());
            PdfContentByte cb = stamper.getOverContent(i);
            cb.rectangle(finder.getLlx(), finder.getLly(),
                finder.getWidth(), finder.getHeight());
            cb.stroke();
        }
        stamper.close();
        reader.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new ShowTextMargins().addMarginRectangle(PREFACE, RESULT);
    }
}
MyImageRenderListener.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
/*
 * 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 part4.chapter15;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfImageObject;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
 
public class MyImageRenderListener implements RenderListener {
 
    /** The new document to which we've added a border rectangle. */
    protected String path = "";
 
    /**
     * Creates a RenderListener that will look for images.
     */
    public MyImageRenderListener(String path) {
        this.path = path;
    }
    
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
     */
    public void beginTextBlock() {
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
     */
    public void endTextBlock() {
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
     *     com.itextpdf.text.pdf.parser.ImageRenderInfo)
     */
    public void renderImage(ImageRenderInfo renderInfo) {
        try {
            String filename;
            FileOutputStream os;
            PdfImageObject image = renderInfo.getImage();
            if (image == null) return;
            filename = String.format(path, renderInfo.getRef().getNumber(), image.getFileType());
            os = new FileOutputStream(filename);
            os.write(image.getImageAsBytes());
            os.flush();
            os.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderText(
     *     com.itextpdf.text.pdf.parser.TextRenderInfo)
     */
    public void renderText(TextRenderInfo renderInfo) {
    }
}
ExtractImages.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 part4.chapter15;
 
import java.io.IOException;
 
import part3.chapter10.ImageTypes;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
 
/**
 * Extracts images from a PDF file.
 */
public class ExtractImages {
 
    /** The new document to which we've added a border rectangle. */
    public static final String RESULT = "results/part4/chapter15/Img%s.%s";
    
    /**
     * Parses a PDF and extracts all the images.
     * @param src the source PDF
     * @param dest the resulting PDF
     */
    public void extractImages(String filename)
        throws IOException, DocumentException {
        PdfReader reader = new PdfReader(filename);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        MyImageRenderListener listener = new MyImageRenderListener(RESULT);
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            parser.processContent(i, listener);
        }
        reader.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new ImageTypes().createPdf(ImageTypes.RESULT);
        new ExtractImages().extractImages(ImageTypes.RESULT);
    }
}
PeekABoo.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
/*
 * 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 Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class PeekABoo : IWriter {
// ===========================================================================
    /** The first resulting PDF. */
    public const String RESULT1 = "peek-a-boo1.pdf";
    /** The second resulting PDF. */
    public const String RESULT2 = "peek-a-boo2.pdf";
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        PeekABoo peekaboo = new PeekABoo();
        zip.AddEntry(RESULT1, peekaboo.CreatePdf(true));       
        zip.AddEntry(RESULT2, peekaboo.CreatePdf(false));       
        zip.Save(stream);             
      }
    }    
// ---------------------------------------------------------------------------    
    public byte[] CreatePdf(bool on) {
      using (MemoryStream ms = new MemoryStream()) {
        using (Document document = new Document()) {    
          // step 2
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          writer.ViewerPreferences = PdfWriter.PageModeUseOC;
          writer.PdfVersion = PdfWriter.VERSION_1_5;        
          // step 3
          document.Open();
          // step 4
          PdfLayer layer = new PdfLayer("Do you see me?", writer);
          layer.On = on;
          BaseFont bf = BaseFont.CreateFont();
          PdfContentByte cb = writer.DirectContent;
          cb.BeginText();
          cb.SetFontAndSize(bf, 18);
          cb.ShowTextAligned(Element.ALIGN_LEFT, "Do you see me?", 50, 790, 0);
          cb.BeginLayer(layer);
          cb.ShowTextAligned(Element.ALIGN_LEFT, "Peek-a-Boo!!!", 50, 766, 0);
          cb.EndLayer();
          cb.EndText();
        }
        return ms.ToArray();
      }
    }
// ===========================================================================
  }
}
OptionalContentActionExample.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
/*
 * 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;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class OptionalContentActionExample : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.PdfVersion = PdfWriter.VERSION_1_5;
        // step 3
        document.Open();
        // step 4
        PdfLayer a1 = new PdfLayer("answer 1", writer);
        PdfLayer a2 = new PdfLayer("answer 2", writer);
        PdfLayer a3 = new PdfLayer("answer 3", writer);
        a1.On = false;
        a2.On = false;
        a3.On = false;
 
        BaseFont bf = BaseFont.CreateFont();
        PdfContentByte cb = writer.DirectContent;
        cb.BeginText();
        cb.SetFontAndSize(bf, 18);
        cb.ShowTextAligned(Element.ALIGN_LEFT,
            "Q1: Who is the director of the movie 'Paths of Glory'?", 50, 766, 0);
        cb.ShowTextAligned(Element.ALIGN_LEFT,
            "Q2: Who directed the movie 'Lawrence of Arabia'?", 50, 718, 0);
        cb.ShowTextAligned(Element.ALIGN_LEFT,
            "Q3: Who is the director of 'House of Flying Daggers'?", 50, 670, 0);
        cb.EndText();
        cb.SaveState();
        cb.SetRGBColorFill(0xFF, 0x00, 0x00);
        cb.BeginText();
        cb.BeginLayer(a1);
        cb.ShowTextAligned(Element.ALIGN_LEFT,
                "A1: Stanley Kubrick", 50, 742, 0);
        cb.EndLayer();
        cb.BeginLayer(a2);
        cb.ShowTextAligned(Element.ALIGN_LEFT,
                "A2: David Lean", 50, 694, 0);
        cb.EndLayer();
        cb.BeginLayer(a3);
        cb.ShowTextAligned(Element.ALIGN_LEFT,
                "A3: Zhang Yimou", 50, 646, 0);
        cb.EndLayer();
        cb.EndText();
        cb.RestoreState();
 
        List<Object> stateOn = new List<Object>();
        stateOn.Add("ON");
        stateOn.Add(a1);
        stateOn.Add(a2);
        stateOn.Add(a3);
        PdfAction actionOn = PdfAction.SetOCGstate(stateOn, true);
        List<Object> stateOff = new List<Object>();
        stateOff.Add("OFF");
        stateOff.Add(a1);
        stateOff.Add(a2);
        stateOff.Add(a3);
        PdfAction actionOff = PdfAction.SetOCGstate(stateOff, true);
        List<Object> stateToggle = new List<Object>();
        stateToggle.Add("Toggle");
        stateToggle.Add(a1);
        stateToggle.Add(a2);
        stateToggle.Add(a3);
        PdfAction actionToggle = PdfAction.SetOCGstate(stateToggle, true);
        Phrase p = new Phrase("Change the state of the answers:");
        Chunk on = new Chunk(" on ").SetAction(actionOn);
        p.Add(on);
        Chunk off = new Chunk("/ off ").SetAction(actionOff);
        p.Add(off);
        Chunk toggle = new Chunk("/ toggle").SetAction(actionToggle);
        p.Add(toggle);
        document.Add(p);
      }
    }
// ===========================================================================
  }
}                                 
LayerMembershipExample1.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
/*
 * 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;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class LayerMembershipExample1 : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.PdfVersion = PdfWriter.VERSION_1_5;
        // step 3
        document.Open();
        // step 4
        PdfContentByte cb = writer.DirectContent;
 
        PdfLayer dog = new PdfLayer("layer 1", writer);
        PdfLayer tiger = new PdfLayer("layer 2", writer);
        PdfLayer lion = new PdfLayer("layer 3", writer);
        PdfLayerMembership cat = new PdfLayerMembership(writer);
        cat.AddMember(tiger);
        cat.AddMember(lion);
        PdfLayerMembership no_cat = new PdfLayerMembership(writer);
        no_cat.AddMember(tiger);
        no_cat.AddMember(lion);
        no_cat.VisibilityPolicy = PdfLayerMembership.ALLOFF;
        cb.BeginLayer(dog);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase("dog"), 50, 775, 0
        );
        cb.EndLayer();
        cb.BeginLayer(tiger);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase("tiger"), 50, 750, 0
        );
        cb.EndLayer();
        cb.BeginLayer(lion);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase("lion"), 50, 725, 0
        );
        cb.EndLayer();
        cb.BeginLayer(cat);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase("cat"), 50, 700, 0
        );
        cb.EndLayer();
        cb.BeginLayer(no_cat);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
          new Phrase("no cat"), 50, 700, 0
        );
        cb.EndLayer();
      }
    }
// ===========================================================================
  }
}
LayerMembershipExample2.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
/*
 * 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 System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class LayerMembershipExample2 : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.PdfVersion = PdfWriter.VERSION_1_6;
        // step 3
        document.Open();
        // step 4
        PdfContentByte cb = writer.DirectContent;
 
        PdfLayer dog = new PdfLayer("layer 1", writer);
        PdfLayer tiger = new PdfLayer("layer 2", writer);
        PdfLayer lion = new PdfLayer("layer 3", writer);
        PdfLayerMembership cat = new PdfLayerMembership(writer);
        PdfVisibilityExpression ve1 = new PdfVisibilityExpression(
          PdfVisibilityExpression.OR
        );
        ve1.Add(tiger);
        ve1.Add(lion);
        cat.VisibilityExpression = ve1;
        PdfLayerMembership no_cat = new PdfLayerMembership(writer);
        PdfVisibilityExpression ve2 = new PdfVisibilityExpression(
          PdfVisibilityExpression.NOT
        );
        ve2.Add(ve1);
        no_cat.VisibilityExpression = ve2;
        cb.BeginLayer(dog);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, new Phrase("dog"),
                50, 775, 0);
        cb.EndLayer();
        cb.BeginLayer(tiger);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, new Phrase("tiger"),
                50, 750, 0);
        cb.EndLayer();
        cb.BeginLayer(lion);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, new Phrase("lion"),
                50, 725, 0);
        cb.EndLayer();
        cb.BeginLayer(cat);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, new Phrase("cat"),
                50, 700, 0);
        cb.EndLayer();
        cb.BeginLayer(no_cat);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
                new Phrase("no cat"), 50, 700, 0);
        cb.EndLayer();
      }
    }
// ===========================================================================
  }
}
OptionalContentExample.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
/*
 * 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;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class OptionalContentExample : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.PdfVersion = PdfWriter.VERSION_1_5;
        // step 3
        document.Open();
        // step 4
        PdfContentByte cb = writer.DirectContent;
        PdfLayer nested = new PdfLayer("Nested layers", writer);
        PdfLayer nested_1 = new PdfLayer("Nested layer 1", writer);
        PdfLayer nested_2 = new PdfLayer("Nested layer 2", writer);
        nested.AddChild(nested_1);
        nested.AddChild(nested_2);
        writer.LockLayer(nested_2);
        cb.BeginLayer(nested);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
          new Phrase("nested layers"), 50, 775, 0
        );
        cb.EndLayer();
        cb.BeginLayer(nested_1);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT,
          new Phrase("nested layer 1"), 100, 800, 0
        );
        cb.EndLayer();
        cb.BeginLayer(nested_2);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase("nested layer 2"), 100, 750, 0
        );
        cb.EndLayer();
 
        PdfLayer group = PdfLayer.CreateTitle("Grouped layers", writer);
        PdfLayer layer1 = new PdfLayer("Group: layer 1", writer);
        PdfLayer layer2 = new PdfLayer("Group: layer 2", writer);
        group.AddChild(layer1);
        group.AddChild(layer2);
        cb.BeginLayer(layer1);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase( "layer 1 in the group"), 50, 700, 0
        );
        cb.EndLayer();
        cb.BeginLayer(layer2);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase("layer 2 in the group"), 50, 675, 0
        );
        cb.EndLayer();
 
        PdfLayer radiogroup = PdfLayer.CreateTitle("Radio group", writer);
        PdfLayer radio1 = new PdfLayer("Radiogroup: layer 1", writer);
        radio1.On = true;
        PdfLayer radio2 = new PdfLayer("Radiogroup: layer 2", writer);
        radio2.On = false;
        PdfLayer radio3 = new PdfLayer("Radiogroup: layer 3", writer);
        radio3.On = false;
        radiogroup.AddChild(radio1);
        radiogroup.AddChild(radio2);
        radiogroup.AddChild(radio3);
        List<PdfLayer> options = new List<PdfLayer>();
        options.Add(radio1);
        options.Add(radio2);
        options.Add(radio3);
        writer.AddOCGRadioGroup(options);
        cb.BeginLayer(radio1);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase("option 1"), 50, 600, 0
        );
        cb.EndLayer();
        cb.BeginLayer(radio2);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase("option 2"), 50, 575, 0
        );
        cb.EndLayer();
        cb.BeginLayer(radio3);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, 
          new Phrase(
                "option 3"
          ), 50, 550, 0
        );
        cb.EndLayer();
 
        PdfLayer not_printed = new PdfLayer("not printed", writer);
        not_printed.OnPanel = false;
        not_printed.SetPrint("Print", false);
        cb.BeginLayer(not_printed);
        ColumnText.ShowTextAligned(cb, Element.ALIGN_CENTER, 
          new Phrase(
                "PRINT THIS PAGE"
          ), 300, 700, 90
        );
        cb.EndLayer();
 
        PdfLayer zoom = new PdfLayer("Zoom 0.75-1.25", writer);
        zoom.OnPanel = false;
        zoom.SetZoom(0.75f, 1.25f);
        cb.BeginLayer(zoom);
        ColumnText.ShowTextAligned(
          cb, Element.ALIGN_LEFT, 
          new Phrase(
            "Only visible if the zoomfactor is between 75 and 125%"
          ), 30, 530, 90
        );
        cb.EndLayer();
      }
    }
// ===========================================================================
  }
}
SvgToPdf.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * 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.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class SvgToPdf : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      throw new NotImplementedException(
        "Batik SVG toolkit is only implemented in Java"
      );
    }
// ===========================================================================
  }
}
SvgLayers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 * 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.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class SvgLayers : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      throw new NotImplementedException(
        "Batik SVG toolkit is only implemented in Java"
      );
    }
// ===========================================================================
  }
}
ObjectData.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
/*
 * 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.Data;
using System.Data.Common;
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.Chapter15 {
  public class ObjectData : IWriter {
// ===========================================================================
    /** SQL statement to get selected directors */
    public const string SELECTDIRECTORS =
      @"SELECT DISTINCT d.id, d.name, d.given_name, count(*) AS c 
      FROM film_director d, film_movie_director md
      WHERE d.id = md.director_id AND d.id < 8
      GROUP BY d.id, d.name, d.given_name ORDER BY id";
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.SetTagged();
        writer.UserProperties = true;        
        // step 3
        document.Open();
        // step 4
        PdfStructureTreeRoot tree = writer.StructureTreeRoot;
        PdfStructureElement top = new PdfStructureElement(
          tree, new PdfName("Directors")
        );
        
        Dictionary<int, PdfStructureElement> directors = 
          new Dictionary<int, PdfStructureElement>();
 
        int id;
        Director director;
        PdfStructureElement e;
        DbProviderFactory dbp = AdoDB.Provider;
        using (var c = dbp.CreateConnection()) {
          c.ConnectionString = AdoDB.CS;
          using (DbCommand cmd = c.CreateCommand()) {
            cmd.CommandText = SELECTDIRECTORS;
            c.Open();
            using (var r = cmd.ExecuteReader()) {
              while (r.Read()) {
                id = Convert.ToInt32(r["id"]);
                director = PojoFactory.GetDirector(r);
                e = new PdfStructureElement(top, new PdfName("director" + id));
                PdfDictionary userproperties = new PdfDictionary();
                userproperties.Put(PdfName.O, PdfName.USERPROPERTIES);
                PdfArray properties = new PdfArray();
                PdfDictionary property1 = new PdfDictionary();
                property1.Put(PdfName.N, new PdfString("Name"));
                property1.Put(PdfName.V, new PdfString(director.Name));            
                properties.Add(property1);
                PdfDictionary property2 = new PdfDictionary();
                property2.Put(PdfName.N, new PdfString("Given name"));
                property2.Put(PdfName.V, new PdfString(director.GivenName));            
                properties.Add(property2);
                PdfDictionary property3 = new PdfDictionary();
                property3.Put(PdfName.N, new PdfString("Posters"));
                property3.Put(PdfName.V, new PdfNumber(Convert.ToInt32(r["c"]))); 
                properties.Add(property3);
                userproperties.Put(PdfName.P, properties);
                e.Put(PdfName.A, userproperties);
                directors.Add(id, e);
              }
            }
          }
        }
 
        Dictionary<Movie, int> map = new Dictionary<Movie, int>();
        for (int i = 1; i < 8; i++) {
          foreach (Movie movie in PojoFactory.GetMovies(i)) {
            map.Add(movie, i);
          }
        }
        
        PdfContentByte canvas = writer.DirectContent;
        Image img;
        float x = 11.5f;
        float y = 769.7f;
        string RESOURCE = Utility.ResourcePosters;
        foreach (var entry in map.Keys) {
          img = Image.GetInstance(Path.Combine(RESOURCE, entry.Imdb + ".jpg"));
          img.ScaleToFit(1000, 60);
          img.SetAbsolutePosition(x + (45 - img.ScaledWidth) / 2, y);
          canvas.BeginMarkedContentSequence(directors[map[entry]]);
          canvas.AddImage(img);
          canvas.EndMarkedContentSequence();
          x += 48;
          if (x > 578) {
            x = 11.5f;
            y -= 84.2f;
          }
        }
      }
    }
// ===========================================================================
  }
}
ReadOutLoud.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;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ReadOutLoud : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.SetTagged();
        // step 3
        document.Open();
        // step 4
        PdfContentByte cb = writer.DirectContent;
        BaseFont bf = BaseFont.CreateFont(
          BaseFont.HELVETICA,
          BaseFont.CP1252, BaseFont.NOT_EMBEDDED
        );
        BaseFont bf2 = BaseFont.CreateFont(
          "c:/windows/fonts/msgothic.ttc,1",
          BaseFont.IDENTITY_H, BaseFont.EMBEDDED
        );
 
        PdfStructureTreeRoot root = writer.StructureTreeRoot;
        PdfStructureElement div = new PdfStructureElement(
          root, new PdfName("Div")
        );
        PdfDictionary dict;
 
        cb.BeginMarkedContentSequence(div);
 
        cb.BeginText();
        cb.MoveText(36, 788);
        cb.SetFontAndSize(bf, 12);
        cb.SetLeading(18);
        cb.ShowText("These are some famous movies by Stanley Kubrick: ");
        dict = new PdfDictionary();
        dict.Put(PdfName.E, new PdfString("Doctor"));
        cb.BeginMarkedContentSequence(new PdfName("Span"), dict, true);
        cb.NewlineShowText("Dr.");
        cb.EndMarkedContentSequence();
        cb.ShowText(
          " Strangelove or: How I Learned to Stop Worrying and Love the Bomb."
        );
        dict = new PdfDictionary();
        dict.Put(PdfName.E, new PdfString("Eyes Wide Shut."));
        cb.BeginMarkedContentSequence(new PdfName("Span"), dict, true);
        cb.NewlineShowText("EWS");
        cb.EndMarkedContentSequence();
        cb.EndText();
        dict = new PdfDictionary();
        dict.Put(PdfName.LANG, new PdfString("en-us"));
        dict.Put(new PdfName("Alt"), new PdfString("2001: A Space Odyssey."));
        cb.BeginMarkedContentSequence(new PdfName("Span"), dict, true);
        Image img = Image.GetInstance(Path.Combine(
          Utility.ResourcePosters, "0062622.jpg"
        ));
        img.ScaleToFit(1000, 100);
        img.SetAbsolutePosition(36, 640);
        cb.AddImage(img);
        cb.EndMarkedContentSequence();
 
        cb.BeginText();
        cb.MoveText(36, 620);
        cb.SetFontAndSize(bf, 12);
        cb.ShowText("This is a movie by Akira Kurosawa: ");
        dict = new PdfDictionary();
        dict.Put(PdfName.ACTUALTEXT, new PdfString("Seven Samurai."));
        cb.BeginMarkedContentSequence(new PdfName("Span"), dict, true);
        cb.SetFontAndSize(bf2, 12);
        cb.ShowText("\u4e03\u4eba\u306e\u4f8d");
        cb.EndMarkedContentSequence();
        cb.EndText();
        
        cb.EndMarkedContentSequence();
 
      }
    }
// ===========================================================================
  }
}
StructureParser.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
/*
 * 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 System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;
/* 
 * Java book example uses SAX to parse XML. .NET uses XmlReader class instead of 
 * SAX, so this class is unnecessary.
 * couple of good explanations of the differences between Java and C#:
 * http://www.xml.com/pub/a/2002/03/06/csharpxml.html
 * http://msdn.microsoft.com/en-us/library/aa478996.aspx
*/
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class StructureParser : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      throw new NotImplementedException(
        ".NET uses XmlReader class instead of SAX"
      );
    }
// ===========================================================================
  }
}
ContentParser.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
/*
 * 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 System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;
/* 
 * Java book example uses SAX to parse XML. .NET uses XmlReader class instead of 
 * SAX, so this class is unnecessary.
 * couple of good explanations of the differences between Java and C#:
 * http://www.xml.com/pub/a/2002/03/06/csharpxml.html
 * http://msdn.microsoft.com/en-us/library/aa478996.aspx
*/
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ContentParser : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      throw new NotImplementedException(
        ".NET uses XmlReader class instead of SAX"
      );
    }
// ===========================================================================
  }
}
StructuredContent.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
/*
 * 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.Text;
using System.Text.RegularExpressions;
using Ionic.Zip;
using System.Xml;
using iTextSharp.text;
using iTextSharp.text.pdf;
/* 
 * Java book example uses SAX to parse XML. .NET uses XmlReader class instead of 
 * SAX; i.e. ContentParser & StructureParser classes from book not needed and 
 * are implemented in __THIS__ class
 * 
 * couple of good explanations of the differences between Java and C#:
 * http://www.xml.com/pub/a/2002/03/06/csharpxml.html
 * http://msdn.microsoft.com/en-us/library/aa478996.aspx
 * 
*/
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class StructuredContent : IWriter {
// ===========================================================================
    /** The resulting PDF. */
    public const String RESULT = "moby.pdf";
    /** An XML file that will be converted to PDF. */
    public readonly String RESOURCE = Path.Combine(
      Utility.ResourceXml, "moby.xml"
    );
    /** The StringBuffer that holds the characters. */
    protected StringBuilder buf = new StringBuilder();
 
    /** The document to which content parsed form XML will be added. */
    protected Document document;
    /** The writer to which PDF syntax will be written. */
    protected PdfWriter writer;
    /** The canvas to which content will be written. */
    protected PdfContentByte canvas;
 
    /** The current structure element during the parsing process. */
    protected PdfStructureElement current;
    /** The column to which content will be added. */
    protected ColumnText column;
    /** The font used when content elements are created. */
    protected Font font;    
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        zip.AddFile(RESOURCE, ""); 
        StructuredContent s = new StructuredContent();      
        zip.AddEntry(RESULT, s.CreatePdf());       
        zip.Save(stream);             
      }
    }
// ---------------------------------------------------------------------------    
    public byte[] CreatePdf() {
      using (MemoryStream ms = new MemoryStream()) {
        using (document = new Document(PageSize.A5)) {
          // step 2
          writer = PdfWriter.GetInstance(document, ms);
          writer.SetTagged();
          // step 3
          document.Open();
          // step 4
          PdfStructureTreeRoot root = writer.StructureTreeRoot;
          root.MapRole(new PdfName("chapter"), PdfName.SECT);
          root.MapRole(new PdfName("title"), PdfName.H);
          root.MapRole(new PdfName("para"), PdfName.P);
          top = new PdfStructureElement(
            root, new PdfName("chapter")
          );
          
          canvas = writer.DirectContent;
          column = new ColumnText(canvas);
          column.SetSimpleColumn(36, 36, 384, 569);
          font = new Font( 
            BaseFont.CreateFont(
              "c:/windows/fonts/arial.ttf", BaseFont.WINANSI, BaseFont.EMBEDDED
            ), 12
          );          
          
          using (XmlReader xr = XmlReader.Create(RESOURCE)) {
            xr.MoveToContent();
            while (xr.Read()) {
              switch (xr.NodeType) {
                case XmlNodeType.Element:
                  StartElement(xr.Name);
                  break;
                case XmlNodeType.Text:
                  buf.Append(Regex.Replace(xr.Value.Trim(), "\n", " "));
                  break;
                case XmlNodeType.EndElement:
                  EndElement(xr.Name);
                  break;
              }
            }
          }
        }
        return ms.ToArray();
      }
    }
    
    PdfStructureElement top;
// ---------------------------------------------------------------------------        
// replace [StructureParser|ContentParser].startElement() from Java example
    public void StartElement(string name) {
      switch (name) {
        case "chapter":
          break;
        default:
          current = new PdfStructureElement(top, new PdfName(name));
          canvas.BeginMarkedContentSequence(current);
          break;
      }
    }    
// ---------------------------------------------------------------------------        
// replace ContentParser.endElement() from Java example
    public void EndElement(string name) {   
      if ("chapter".Equals(name)) return;
      
      String s = buf.ToString().Trim();
      buf = new StringBuilder();
      if (s.Length > 0) {
        Paragraph p = new Paragraph(s, font);
        p.Alignment = Element.ALIGN_JUSTIFIED;
        column.AddElement(p);
        int status = column.Go();
        while (ColumnText.HasMoreText(status)) {
          canvas.EndMarkedContentSequence();
          document.NewPage();
          canvas.BeginMarkedContentSequence(current);
          column.SetSimpleColumn(36, 36, 384, 569);
          status = column.Go();
        }
      }
      canvas.EndMarkedContentSequence();    
    }
// ===========================================================================
  }
}
ParseTaggedPdf.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
/*
 * 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.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ParseTaggedPdf : IWriter {
// ===========================================================================
    /** The resulting XML file. */
    public const String RESULT = "moby_extracted.xml";
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        StructuredContent s = new StructuredContent();
        byte[] pdf = s.CreatePdf();
        zip.AddEntry(Utility.ResultFileName(s.ToString() + ".pdf"), pdf); 
        TaggedPdfReaderTool reader = new TaggedPdfReaderTool();
        using (MemoryStream ms = new MemoryStream()) {
          reader.ConvertToXml(new PdfReader(pdf), ms);
          StringBuilder sb =  new StringBuilder();
          foreach (byte b in ms.ToArray()) {
            sb.Append((char) b);
          }
          zip.AddEntry(RESULT, sb.ToString());
        }
        zip.Save(stream);
      }
    }    
// ===========================================================================
    }
}
ParsingHelloWorld.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
/*
 * 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.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.io;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using kuujinbo.iTextInAction2Ed.Chapter01;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ParsingHelloWorld : IWriter {
// ===========================================================================
    /** The resulting PDF. */
    public const String PDF = "hello_reverse.pdf";
    /** A possible resulting after parsing the PDF. */
    public const String TEXT1 = "result1.txt";
    /** A possible resulting after parsing the PDF. */
    public const String TEXT2 = "result2.txt";
    /** A possible resulting after parsing the PDF. */
    public const String TEXT3 = "result3.txt";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        ParsingHelloWorld example = new ParsingHelloWorld();
        byte[] ePdf = example.CreatePdf();
        zip.AddEntry(PDF, ePdf);
        HelloWorld hello = new HelloWorld();
        byte[] hPdf = Utility.PdfBytes(hello);
        zip.AddEntry(Utility.ResultFileName(hello.ToString() + ".pdf"), hPdf);       
        zip.AddEntry(TEXT1, example.ParsePdf(hPdf));
        zip.AddEntry(TEXT2, example.ParsePdf(ePdf));
        zip.AddEntry(TEXT3, example.ExtractText(ePdf));
        zip.Save(stream);             
      }
    }
// --------------------------------------------------------------------------- 
    /**
     * Generates a PDF file with the text 'Hello World'
     */    
    public byte[] CreatePdf() {
      using (MemoryStream ms = new MemoryStream()) {
        using (Document document = new Document()) {
          // step 2
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          // step 3
          document.Open();
          // step 4
          // we add the text to the direct content, but not in the right order
          PdfContentByte cb = writer.DirectContent;
          BaseFont bf = BaseFont.CreateFont();
          cb.BeginText();
          cb.SetFontAndSize(bf, 12);
          cb.MoveText(88.66f, 367); 
          cb.ShowText("ld");
          cb.MoveText(-22f, 0); 
          cb.ShowText("Wor");
          cb.MoveText(-15.33f, 0); 
          cb.ShowText("llo");
          cb.MoveText(-15.33f, 0); 
          cb.ShowText("He");
          cb.EndText();
          // we also add text in a form XObject
          PdfTemplate tmp = cb.CreateTemplate(250, 25);
          tmp.BeginText();
          tmp.SetFontAndSize(bf, 12);
          tmp.MoveText(0, 7);
          tmp.ShowText("Hello People");
          tmp.EndText();
          cb.AddTemplate(tmp, 36, 343);
        }
        return ms.ToArray();
      }
    }
// ---------------------------------------------------------------------------    
    /**
     * Parses the PDF using PRTokeniser
     * @param src the ]original PDF file
]     */
    public string ParsePdf(byte[] src) {
      PdfReader reader = new PdfReader(src);
      // we can inspect the syntax of the imported page
      byte[] streamBytes = reader.GetPageContent(1);
      StringBuilder sb = new StringBuilder();
      PRTokeniser tokenizer = new PRTokeniser(new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateSource(streamBytes)));
      while (tokenizer.NextToken()) {
        if (tokenizer.TokenType == PRTokeniser.TokType.STRING) {
          sb.AppendLine(tokenizer.StringValue);
        }
      }
      return sb.ToString();
    }
// ---------------------------------------------------------------------------    
    /**
     * Extracts text from a PDF document.
     * @param src the original PDF document
     */
    public string ExtractText(byte[] src) {
      PdfReader reader = new PdfReader(src);
      MyTextRenderListener listener = new MyTextRenderListener();
      PdfContentStreamProcessor processor = new PdfContentStreamProcessor(listener);
      PdfDictionary pageDic = reader.GetPageN(1);
      PdfDictionary resourcesDic = pageDic.GetAsDict(PdfName.RESOURCES);
      processor.ProcessContent(
        ContentByteUtils.GetContentBytesForPage(reader, 1), 
        resourcesDic
      );
      return listener.Text.ToString();
    }    
// ===========================================================================
  }
}
MyTextRenderListener.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
/*
 * 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.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class MyTextRenderListener : IRenderListener {
// ===========================================================================
    public StringBuilder Text { get; set; }
// ---------------------------------------------------------------------------
    /**
     * Creates a RenderListener that will look for text.
     */
    public MyTextRenderListener() {
      Text = new StringBuilder();
    }
    
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
     */
    public void BeginTextBlock() {
      Text.Append("<");
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
     */
    public void EndTextBlock() {
      Text.AppendLine(">");
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
     *     com.itextpdf.text.pdf.parser.ImageRenderInfo)
     */
    public void RenderImage(ImageRenderInfo renderInfo) {
    }
 
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderText(
     *     com.itextpdf.text.pdf.parser.TextRenderInfo)
     */
    public void RenderText(TextRenderInfo renderInfo) {
      Text.Append("<");
      Text.Append(renderInfo.GetText());
      Text.Append(">");
    }    
// ===========================================================================
    }
}
InspectPageContent.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
/*
 * 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.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using kuujinbo.iTextInAction2Ed.Chapter03;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class InspectPageContent : IWriter {
// ===========================================================================
    /** Text file containing information about a PDF file. */
    public const String RESULT = "calendar_info.txt";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        MovieTemplates m = new MovieTemplates();
        byte[] mPdf = Utility.PdfBytes(m);
        zip.AddEntry(Utility.ResultFileName(m.ToString() + ".pdf"), mPdf);
        InspectPageContent i = new InspectPageContent();
        zip.AddEntry(RESULT, i.InspectPdf(mPdf));
        zip.Save(stream);             
      }
    }    
// --------------------------------------------------------------------------- 
    /**
     * Parses object and content information of a PDF into a text file.
     * @param pdf the original PDF
     * 
     * this method uses code from; 
     * PdfContentReaderTool.ListContentStreamForPage()
     * so i can pass in a byte array instead of file path
     * 
     */
    public string InspectPdf(byte[] pdf) {
      PdfReader reader = new PdfReader(pdf);
      int maxPageNum = reader.NumberOfPages;
      StringBuilder sb = new StringBuilder();
      for (int pageNum = 1; pageNum <= maxPageNum; pageNum++){
        sb.AppendLine("==============Page " + pageNum + "====================");
        sb.AppendLine("- - - - - Dictionary - - - - - -");
        PdfDictionary pageDictionary = reader.GetPageN(pageNum);
        sb.AppendLine(
          PdfContentReaderTool.GetDictionaryDetail(pageDictionary)
        );
 
        sb.AppendLine("- - - - - XObject Summary - - - - - -");
        sb.AppendLine(PdfContentReaderTool.GetXObjectDetail(
          pageDictionary.GetAsDict(PdfName.RESOURCES))
        );
        
        sb.AppendLine("- - - - - Content Stream - - - - - -");
        RandomAccessFileOrArray f = reader.SafeFile;
 
        byte[] contentBytes = reader.GetPageContent(pageNum, f);
        f.Close();
 
        foreach (byte b in contentBytes) {
          sb.Append((char)b);
        }
        
        sb.AppendLine("- - - - - Text Extraction - - - - - -");
        String extractedText = PdfTextExtractor.GetTextFromPage(
          reader, pageNum, new LocationTextExtractionStrategy()
        );
        if (extractedText.Length != 0) {
          sb.AppendLine(extractedText);
        }
        else {
          sb.AppendLine("No text found on page " + pageNum);
        }
        sb.AppendLine();      
      }   
      return sb.ToString();   
    }    
// ===========================================================================
    }
}
ExtractPageContent.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 System.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ExtractPageContent : IWriter {
// ===========================================================================
    /** The original PDF that will be parsed. */
    public readonly string PREFACE = Path.Combine(
      Utility.ResourcePdf, "preface.pdf"
    );    
    /** The resulting text file. */
    public const String RESULT = "preface.txt";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        zip.AddFile(PREFACE, "");
        PdfReader reader = new PdfReader(PREFACE);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        StringBuilder sb = new StringBuilder();
        ITextExtractionStrategy strategy;
        for (int i = 1; i <= reader.NumberOfPages; i++) {
          strategy = parser.ProcessContent(i, new SimpleTextExtractionStrategy());
          sb.AppendLine(strategy.GetResultantText());
        }
        zip.AddEntry(RESULT, sb.ToString());
        zip.Save(stream);             
      }
    }
// ===========================================================================
  }
}
ExtractPageContentSorted1.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 System.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ExtractPageContentSorted1 : IWriter {
// ===========================================================================
    /** The original PDF that will be parsed. */
    public readonly string PREFACE = Path.Combine(
      Utility.ResourcePdf, "preface.pdf"
    );    
    /** The resulting text file. */
    public const String RESULT = "preface_sorted1.txt";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        zip.AddFile(PREFACE, "");
        PdfReader reader = new PdfReader(PREFACE);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        StringBuilder sb = new StringBuilder();
        ITextExtractionStrategy strategy;
        for (int i = 1; i <= reader.NumberOfPages; i++) {
          strategy = parser.ProcessContent(i, new LocationTextExtractionStrategy());
          sb.AppendLine(strategy.GetResultantText());
        }
        zip.AddEntry(RESULT, sb.ToString());
        zip.Save(stream);             
      }
    }
// ===========================================================================
  }
}
ExtractPageContentSorted2.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
/*
 * 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.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ExtractPageContentSorted2 : IWriter {
// ===========================================================================
    /** The original PDF that will be parsed. */
    public readonly string PREFACE = Path.Combine(
      Utility.ResourcePdf, "preface.pdf"
    );    
    /** The resulting text file. */
    public const String RESULT = "preface_sorted2.txt";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        zip.AddFile(PREFACE, "");
        PdfReader reader = new PdfReader(PREFACE);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= reader.NumberOfPages; i++) {
          sb.AppendLine(PdfTextExtractor.GetTextFromPage(reader, i));
        }
        zip.AddEntry(RESULT, sb.ToString());
        zip.Save(stream);             
      }
    }
// ===========================================================================
  }
}
ExtractPageContentArea.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
/*
 * 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.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ExtractPageContentArea : IWriter {
// ===========================================================================
    /** The original PDF that will be parsed. */
    public readonly string PREFACE = Path.Combine(
      Utility.ResourcePdf, "preface.pdf"
    );    
    /** The resulting text file. */
    public const String RESULT = "preface_clipped.txt";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        zip.AddFile(PREFACE, "");
        PdfReader reader = new PdfReader(PREFACE);
        System.util.RectangleJ rect = new System.util.RectangleJ(
          70, 80, 420, 500
        );
        RenderFilter[] filter = {new RegionTextRenderFilter(rect)};
        ITextExtractionStrategy strategy;
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= reader.NumberOfPages; i++) {
          strategy = new FilteredTextRenderListener(
            new LocationTextExtractionStrategy(), filter
          );
          sb.AppendLine(
            PdfTextExtractor.GetTextFromPage(reader, i, strategy)
          );
        }        
        zip.AddEntry(RESULT, sb.ToString());
        zip.Save(stream);             
      }
    }
// ===========================================================================
  }
}
ShowTextMargins.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
/*
 * 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.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ShowTextMargins : IWriter {
// ===========================================================================
    /** The original PDF that will be parsed. */
    public readonly string PREFACE = Path.Combine(
      Utility.ResourcePdf, "preface.pdf"
    );    
    /** The resulting text file. */
    public const String RESULT = "margins.pdf";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        zip.AddFile(PREFACE, "");
        PdfReader reader = new PdfReader(PREFACE);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        using (MemoryStream ms = new MemoryStream()) {
          using (PdfStamper stamper = new PdfStamper(reader, ms)) {
            TextMarginFinder finder;
            for (int i = 1; i <= reader.NumberOfPages; i++) {
              finder = parser.ProcessContent(i, new TextMarginFinder());
              PdfContentByte cb = stamper.GetOverContent(i);
              cb.Rectangle(
                finder.GetLlx(), finder.GetLly(),
                finder.GetWidth(), finder.GetHeight()
              );
              cb.Stroke();
            }
          }
          zip.AddEntry(RESULT, ms.ToArray());
        }
        zip.Save(stream);             
      }
    }
// ===========================================================================
  }
}
MyImageRenderListener.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
/*
 * 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 System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class MyImageRenderListener : IRenderListener {
// ===========================================================================
    /** the byte array of the extracted images */
    private List<byte[]> _myImages;
    public List<byte[]> MyImages {
      get { return _myImages; }
    }
    /** the file names of the extracted images */
    private List<string> _imageNames;
    public List<string> ImageNames { 
      get { return _imageNames; }
    } 
// ---------------------------------------------------------------------------
    /**
     * Creates a RenderListener that will look for images.
     */
    public MyImageRenderListener() {
      _myImages = new List<byte[]>();
      _imageNames = new List<string>();
    }
// ---------------------------------------------------------------------------
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
     */
    public void BeginTextBlock() { }
// ---------------------------------------------------------------------------     
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
     */
    public void EndTextBlock() { }
// ---------------------------------------------------------------------------     
    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
     *     com.itextpdf.text.pdf.parser.ImageRenderInfo)
     */
    public void RenderImage(ImageRenderInfo renderInfo) {
      try {
        PdfImageObject image = renderInfo.GetImage();
        if (image == null 
/*
 * do not attempt to parse => jbig2 decoder not fully implemented.
 * THE JAVA EXAMPLE INCORRECTLY CREATES A CORRUPT JBIG2 IMAGE
 * BECAUSE THERE IS NO EXPLICIT CHECK. I POSTED TWICE TO THE MAILING
 * LIST, SINCE VERSION 5.1.3 BUT THE ERROR HAS NOT BEEN CORRECTED.
 */
          || image.GetImageBytesType() == PdfImageObject.ImageBytesType.JBIG2
        ) 
        return;
        
        _imageNames.Add(string.Format(
          "Image{0}.{1}", 
          renderInfo.GetRef().Number, image.GetFileType()
        ) );
        _myImages.Add(image.GetImageAsBytes());
      }
      catch {
// pass through any other unsupported image types
      }
    }
 // ---------------------------------------------------------------------------     
   /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderText(
     *     com.itextpdf.text.pdf.parser.TextRenderInfo)
     */
    public void RenderText(TextRenderInfo renderInfo) { }
// ===========================================================================
  }
}
ExtractImages.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
/*
 * 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 Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using kuujinbo.iTextInAction2Ed.Chapter10;
 
namespace kuujinbo.iTextInAction2Ed.Chapter15 {
  public class ExtractImages : IWriter {
// ===========================================================================
    public void Write(Stream stream) {
      ImageTypes it = new ImageTypes();
      using (ZipFile zip = new ZipFile()) {
        byte[] pdf = it.CreatePdf();
        zip.AddEntry(Utility.ResultFileName(it.ToString() + ".pdf"), pdf);
        PdfReader reader = new PdfReader(pdf);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        MyImageRenderListener listener = new MyImageRenderListener();
        for (int i = 1; i <= reader.NumberOfPages; i++) {
          parser.ProcessContent(i, listener);
        } 
        for (int i = 0; i < listener.MyImages.Count; ++i) {
          zip.AddEntry(
            listener.ImageNames[i],
            listener.MyImages[i]
          );
        }         
        zip.Save(stream);
      }
    }
// ===========================================================================
  }
}


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