Build, Write and Embed Elements in PDF - Java Sample Code

Sample code to use Apryse SDK's page writing API to generate new pages, embed fonts & images, and copy graphical elements from one page to another. Sample code provided in Python, C++, C#, Java, Node.js (JavaScript), PHP, Ruby and VB.

Learn more about our Server SDK and PDF Editing & Manipulation Library.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6import com.pdftron.common.Matrix2D;
7import com.pdftron.pdf.*;
8import com.pdftron.sdf.SDFDoc;
9import com.pdftron.filters.*;
10import java.io.*;
11
12public class ElementBuilderTest {
13
14
15 public static void main(String[] args) {
16 PDFNet.initialize(PDFTronLicense.Key());
17
18 // Relative path to the folder containing test files.
19 String input_path = "../../TestFiles/";
20 String output_path = "../../TestFiles/Output/";
21
22 InputStream stream = null;
23 try (PDFDoc doc = new PDFDoc()) {
24 ElementBuilder eb = new ElementBuilder(); // ElementBuilder is used to build new
25 // Element objects
26 ElementWriter writer = new ElementWriter(); // ElementWriter is used to write
27 // Elements to the page
28
29 Element element;
30 GState gstate;
31
32 // Start a new page ------------------------------------
33 Page page = doc.pageCreate(new Rect(0, 0, 612, 794));
34
35 writer.begin(page); // begin writing to the page
36
37 // Create an Image that can be reused in the document or on the
38 // same page.
39 Image img = Image.create(doc.getSDFDoc(), (input_path + "peppers.jpg"));
40
41 element = eb.createImage(img, new Matrix2D(img.getImageWidth() / 2, -145, 20, img.getImageHeight() / 2, 200, 150));
42 writer.writePlacedElement(element);
43
44 gstate = element.getGState(); // use the same image (just
45 // change its matrix)
46 gstate.setTransform(200, 0, 0, 300, 50, 450);
47 writer.writePlacedElement(element);
48
49 // use the same image again (just change its matrix).
50 writer.writePlacedElement(eb.createImage(img, 300, 600, 200, -150));
51
52 writer.end(); // save changes to the current page
53 doc.pagePushBack(page);
54
55 // Start a new page ------------------------------------
56 // Construct and draw a path object using different styles
57 page = doc.pageCreate(new Rect(0, 0, 612, 794));
58
59 writer.begin(page); // begin writing to this page
60 eb.reset(); // Reset the GState to default
61
62 eb.pathBegin(); // start constructing the path
63 eb.moveTo(306, 396);
64 eb.curveTo(681, 771, 399.75, 864.75, 306, 771);
65 eb.curveTo(212.25, 864.75, -69, 771, 306, 396);
66 eb.closePath();
67 element = eb.pathEnd(); // the path is now finished
68 element.setPathFill(true); // the path should be filled
69
70 // Set the path color space and color
71 gstate = element.getGState();
72 gstate.setFillColorSpace(ColorSpace.createDeviceCMYK());
73 gstate.setFillColor(new ColorPt(1, 0, 0, 0)); // cyan
74 gstate.setTransform(0.5, 0, 0, 0.5, -20, 300);
75 writer.writePlacedElement(element);
76
77 // Draw the same path using a different stroke color
78 element.setPathStroke(true); // this path is should be
79 // filled and stroked
80 gstate.setFillColor(new ColorPt(0, 0, 1, 0)); // yellow
81 gstate.setStrokeColorSpace(ColorSpace.createDeviceRGB());
82 gstate.setStrokeColor(new ColorPt(1, 0, 0)); // red
83 gstate.setTransform(0.5, 0, 0, 0.5, 280, 300);
84 gstate.setLineWidth(20);
85 writer.writePlacedElement(element);
86
87 // Draw the same path with with a given dash pattern
88 element.setPathFill(false); // this path is should be only
89 // stroked
90 gstate.setStrokeColor(new ColorPt(0, 0, 1)); // blue
91 gstate.setTransform(0.5, 0, 0, 0.5, 280, 0);
92 double[] dash_pattern = {30};
93 gstate.setDashPattern(dash_pattern, 0);
94 writer.writePlacedElement(element);
95
96 // Use the path as a clipping path
97 writer.writeElement(eb.createGroupBegin()); // Save the graphics
98 // state
99 // Start constructing the new path (the old path was lost when
100 // we created
101 // a new Element using CreateGroupBegin()).
102 eb.pathBegin();
103 eb.moveTo(306, 396);
104 eb.curveTo(681, 771, 399.75, 864.75, 306, 771);
105 eb.curveTo(212.25, 864.75, -69, 771, 306, 396);
106 eb.closePath();
107 element = eb.pathEnd(); // path is now constructed
108 element.setPathClip(true); // this path is a clipping path
109 element.setPathStroke(true); // this path should be
110 // filled and stroked
111 gstate = element.getGState();
112 gstate.setTransform(0.5, 0, 0, 0.5, -20, 0);
113
114 writer.writeElement(element);
115
116 writer.writeElement(eb.createImage(img, 100, 300, 400, 600));
117
118 writer.writeElement(eb.createGroupEnd()); // Restore the
119 // graphics state
120
121 writer.end(); // save changes to the current page
122 doc.pagePushBack(page);
123
124
125 // Start a new page ------------------------------------
126 page = doc.pageCreate(new Rect(0, 0, 612, 794));
127
128 writer.begin(page); // begin writing to this page
129 eb.reset(); // Reset the GState to default
130
131 // Begin writing a block of text
132 element = eb.createTextBegin(Font.create(doc, Font.e_times_roman), 12);
133 writer.writeElement(element);
134
135 element = eb.createTextRun("Hello World!");
136 element.setTextMatrix(10, 0, 0, 10, 0, 600);
137 element.getGState().setLeading(15); // Set the spacing
138 // between lines
139 writer.writeElement(element);
140
141 writer.writeElement(eb.createTextNewLine()); // New line
142
143 element = eb.createTextRun("Hello World!");
144 gstate = element.getGState();
145 gstate.setTextRenderMode(GState.e_stroke_text);
146 gstate.setCharSpacing(-1.25);
147 gstate.setWordSpacing(-1.25);
148 writer.writeElement(element);
149
150 writer.writeElement(eb.createTextNewLine()); // New line
151
152 element = eb.createTextRun("Hello World!");
153 gstate = element.getGState();
154 gstate.setCharSpacing(0);
155 gstate.setWordSpacing(0);
156 gstate.setLineWidth(3);
157 gstate.setTextRenderMode(GState.e_fill_stroke_text);
158 gstate.setStrokeColorSpace(ColorSpace.createDeviceRGB());
159 gstate.setStrokeColor(new ColorPt(1, 0, 0)); // red
160 gstate.setFillColorSpace(ColorSpace.createDeviceCMYK());
161 gstate.setFillColor(new ColorPt(1, 0, 0, 0)); // cyan
162 writer.writeElement(element);
163
164
165 writer.writeElement(eb.createTextNewLine()); // New line
166
167 // Set text as a clipping path to the image.
168 element = eb.createTextRun("Hello World!");
169 gstate = element.getGState();
170 gstate.setTextRenderMode(GState.e_clip_text);
171 writer.writeElement(element);
172
173 // Finish the block of text
174 writer.writeElement(eb.createTextEnd());
175
176 // Draw an image that will be clipped by the above text
177 writer.writeElement(eb.createImage(img, 10, 100, 1300, 720));
178
179 writer.end(); // save changes to the current page
180 doc.pagePushBack(page);
181
182 // Start a new page ------------------------------------
183 //
184 // The example illustrates how to embed the external font in a
185 // PDF document.
186 // The example also shows how ElementReader can be used to copy
187 // and modify
188 // Elements between pages.
189
190 ElementReader reader = new ElementReader();
191
192 // Start reading Elements from the last page. We will copy all
193 // Elements to
194 // a new page but will modify the font associated with text.
195 reader.begin((doc.getPage(doc.getPageCount())));
196
197 page = doc.pageCreate(new Rect(0, 0, 1300, 794));
198
199 writer.begin(page); // begin writing to this page
200 eb.reset(); // Reset the GState to default
201
202 // Embed an external font in the document.
203 Font font;
204 File file = new File(input_path, "font.ttf");
205 stream = new FileInputStream(file);
206 font = Font.createTrueTypeFont(doc, stream);
207 //Alternatively, the font can be created from the file path.
208 //font = Font.createTrueTypeFont(doc, (input_path + "font.ttf"));
209
210 while ((element = reader.next()) != null) // Read page
211 // contents
212 {
213 if (element.getType() == Element.e_text) {
214 element.getGState().setFont(font, 12);
215 }
216
217 writer.writeElement(element);
218 }
219
220 reader.end();
221 writer.end(); // save changes to the current page
222
223 doc.pagePushBack(page);
224
225
226 // Start a new page ------------------------------------
227 //
228 // The example illustrates how to embed the external font in a
229 // PDF document.
230 // The example also shows how ElementReader can be used to copy
231 // and modify
232 // Elements between pages.
233
234 // Start reading Elements from the last page. We will copy all
235 // Elements to
236 // a new page but will modify the font associated with text.
237 reader.begin(((doc.getPage(doc.getPageCount()))));
238
239 page = doc.pageCreate(new Rect(0, 0, 1300, 794));
240
241 writer.begin(page); // begin writing to this page
242 eb.reset(); // Reset the GState to default
243
244 // Embed an external font in the document.
245 Font font2 = Font.createType1Font(doc, (input_path + "Misc-Fixed.pfa"));
246
247 while ((element = reader.next()) != null) // Read page contents
248 {
249 if (element.getType() == Element.e_text) {
250 element.getGState().setFont(font2, 12);
251 }
252
253 writer.writeElement(element);
254 }
255
256 reader.end();
257 writer.end(); // save changes to the current page
258 doc.pagePushBack(page);
259
260
261 // Start a new page ------------------------------------
262 page = doc.pageCreate();
263 writer.begin(page); // begin writing to this page
264 eb.reset(); // Reset the GState to default
265
266 // Begin writing a block of text
267 element = eb.createTextBegin(Font.create(doc, Font.e_times_roman), 12);
268 element.setTextMatrix(1.5, 0, 0, 1.5, 50, 600);
269 element.getGState().setLeading(15); // Set the spacing between
270 // lines
271 writer.writeElement(element);
272
273 String para = "A PDF text object consists of operators that can show " +
274 "text strings, move the text position, and set text state and certain " +
275 "other parameters. In addition, there are three parameters that are " +
276 "defined only within a text object and do not persist from one text " +
277 "object to the next: Tm, the text matrix, Tlm, the text line matrix, " +
278 "Trm, the text rendering matrix, actually just an intermediate result " +
279 "that combines the effects of text state parameters, the text matrix " +
280 "(Tm), and the current transformation matrix";
281
282 int para_end = para.length();
283 int text_run = 0;
284 int text_run_end;
285
286 double para_width = 300; // paragraph width is 300 units
287 double cur_width = 0;
288
289 while (text_run < para_end) {
290 text_run_end = para.indexOf(' ', text_run);
291 if (text_run_end < 0)
292 text_run_end = para_end - 1;
293
294 String text = para.substring(text_run, text_run_end + 1);
295 element = eb.createTextRun(text);
296 if (cur_width + element.getTextLength() < para_width) {
297 writer.writeElement(element);
298 cur_width += element.getTextLength();
299 } else {
300 writer.writeElement(eb.createTextNewLine()); // New
301 text = para.substring(text_run, text_run_end + 1); // line
302 element = eb.createTextRun(text);
303 cur_width = element.getTextLength();
304 writer.writeElement(element);
305 }
306
307 text_run = text_run_end + 1;
308 }
309
310 // -----------------------------------------------------------------------
311 // The following code snippet illustrates how to adjust
312 // spacing between
313 // characters (text runs).
314 element = eb.createTextNewLine();
315 writer.writeElement(element); // Skip 2 lines
316 writer.writeElement(element);
317
318 writer.writeElement(eb.createTextRun("An example of space adjustments between inter-characters:"));
319 writer.writeElement(eb.createTextNewLine());
320
321 // Write string "AWAY" without space adjustments between
322 // characters.
323 element = eb.createTextRun("AWAY");
324 writer.writeElement(element);
325
326 writer.writeElement(eb.createTextNewLine());
327
328 // Write string "AWAY" with space adjustments between
329 // characters.
330 element = eb.createTextRun("A");
331 writer.writeElement(element);
332
333 element = eb.createTextRun("W");
334 element.setPosAdjustment(140);
335 writer.writeElement(element);
336
337 element = eb.createTextRun("A");
338 element.setPosAdjustment(140);
339 writer.writeElement(element);
340
341 element = eb.createTextRun("Y again");
342 element.setPosAdjustment(115);
343 writer.writeElement(element);
344
345 // Draw the same strings using direct content output...
346 writer.flush(); // flush pending Element writing operations.
347
348 // You can also write page content directly to the content
349 // stream using
350 // ElementWriter.WriteString(...) and
351 // ElementWriter.WriteBuffer(...) methods.
352 // Note that if you are planning to use these functions you need
353 // to be familiar
354 // with PDF page content operators (see Appendix A in PDF
355 // Reference Manual).
356 // Because it is easy to make mistakes during direct output we
357 // recommend that
358 // you use ElementBuilder and Element interface instead.
359
360 writer.writeString("T* T* "); // Skip 2 lines
361 writer.writeString("(Direct output to PDF page content stream:) Tj T* ");
362 writer.writeString("(AWAY) Tj T* ");
363 writer.writeString("[(A)140(W)140(A)115(Y again)] TJ ");
364
365 // Finish the block of text
366 writer.writeElement(eb.createTextEnd());
367
368 writer.end(); // save changes to the current page
369 doc.pagePushBack(page);
370
371 // Start a new page ------------------------------------
372
373 // Image Masks
374 //
375 // In the opaque imaging model, images mark all areas they
376 // occupy on the page as
377 // if with opaque paint. All portions of the image, whether
378 // black, white, gray,
379 // or color, completely obscure any marks that may previously
380 // have existed in the
381 // same place on the page.
382 // In the graphic arts industry and page layout applications,
383 // however, it is common
384 // to crop or 'mask out' the background of an image and then
385 // place the masked image
386 // on a different background, allowing the existing background
387 // to show through the
388 // masked areas. This sample illustrates how to use image masks.
389
390 page = doc.pageCreate();
391 writer.begin(page); // begin writing to the page
392
393 // Create the Image Mask
394 MappedFile imgf=new MappedFile(input_path + "imagemask.dat");
395 com.pdftron.filters.FilterReader mask_read=new com.pdftron.filters.FilterReader(imgf);
396
397 ColorSpace device_gray = ColorSpace.createDeviceGray();
398 Image mask = Image.create(doc, mask_read, 64, 64, 1, device_gray, Image.e_ascii_hex);
399
400 mask.getSDFObj().putBool("ImageMask", true);
401
402 element = eb.createRect(0, 0, 612, 794);
403 element.setPathStroke(false);
404 element.setPathFill(true);
405 element.getGState().setFillColorSpace(device_gray);
406 element.getGState().setFillColor(new ColorPt(0.8,0,0));
407 writer.writePlacedElement(element);
408
409 element = eb.createImage(mask, new Matrix2D(200, 0, 0, -200, 40, 680));
410 element.getGState().setFillColor(new ColorPt(0.1,0,0));
411 writer.writePlacedElement(element);
412
413 element.getGState().setFillColorSpace(ColorSpace.createDeviceRGB());
414 element.getGState().setFillColor(new ColorPt(1, 0, 0));
415 element = eb.createImage(mask, new Matrix2D(200, 0, 0, -200, 320, 680));
416 writer.writePlacedElement(element);
417
418 element.getGState().setFillColor(new ColorPt(0, 1, 0));
419 element = eb.createImage(mask, new Matrix2D(200, 0, 0, -200, 40, 380));
420 writer.writePlacedElement(element);
421
422 {
423 // This sample illustrates Explicit Masking.
424 img = Image.create(doc, (input_path + "peppers.jpg"));
425
426 // mask is the explicit mask for the primary (base) image
427 img.setMask(mask);
428
429 element = eb.createImage(img, new Matrix2D(200, 0, 0, -200, 320, 380));
430 writer.writePlacedElement(element);
431 }
432
433 writer.end(); // save changes to the current page
434 doc.pagePushBack(page);
435
436 // Transparency sample ----------------------------------
437
438 // Start a new page -------------------------------------
439 page = doc.pageCreate();
440 writer.begin(page); // begin writing to this page
441 eb.reset(); // Reset the GState to default
442
443 // Write some transparent text at the bottom of the page.
444 element = eb.createTextBegin(Font.create(doc, Font.e_times_roman), 100);
445
446 // Set the text knockout attribute. Text knockout must be set
447 // outside of
448 // the text group.
449 gstate = element.getGState();
450 gstate.setTextKnockout(false);
451 gstate.setBlendMode(GState.e_bl_difference);
452 writer.writeElement(element);
453
454 element = eb.createTextRun("Transparency");
455 element.setTextMatrix(1, 0, 0, 1, 30, 30);
456 gstate = element.getGState();
457 gstate.setFillColorSpace(ColorSpace.createDeviceCMYK());
458 gstate.setFillColor(new ColorPt(1, 0, 0, 0));
459
460 gstate.setFillOpacity(0.5);
461 writer.writeElement(element);
462
463 // Write the same text on top the old; shifted by 3 points
464 element.setTextMatrix(1, 0, 0, 1, 33, 33);
465 gstate.setFillColor(new ColorPt(0, 1, 0, 0));
466 gstate.setFillOpacity(0.5);
467
468 writer.writeElement(element);
469 writer.writeElement(eb.createTextEnd());
470
471 // Draw three overlapping transparent circles.
472 eb.pathBegin(); // start constructing the path
473 eb.moveTo(459.223, 505.646);
474 eb.curveTo(459.223, 415.841, 389.85, 343.04, 304.273, 343.04);
475 eb.curveTo(218.697, 343.04, 149.324, 415.841, 149.324, 505.646);
476 eb.curveTo(149.324, 595.45, 218.697, 668.25, 304.273, 668.25);
477 eb.curveTo(389.85, 668.25, 459.223, 595.45, 459.223, 505.646);
478 element = eb.pathEnd();
479 element.setPathFill(true);
480
481 gstate = element.getGState();
482 gstate.setFillColorSpace(ColorSpace.createDeviceRGB());
483 gstate.setFillColor(new ColorPt(0, 0, 1)); // Blue
484 // Circle
485
486 gstate.setBlendMode(GState.e_bl_normal);
487 gstate.setFillOpacity(0.5);
488 writer.writeElement(element);
489
490 // Translate relative to the Blue Circle
491 gstate.setTransform(1, 0, 0, 1, 113, -185);
492 gstate.setFillColor(new ColorPt(0, 1, 0)); // Green
493 // Circle
494 gstate.setFillOpacity(0.5);
495 writer.writeElement(element);
496
497 // Translate relative to the Green Circle
498 gstate.setTransform(1, 0, 0, 1, -220, 0);
499 gstate.setFillColor(new ColorPt(1, 0, 0)); // Red
500 // Circle
501 gstate.setFillOpacity(0.5);
502 writer.writeElement(element);
503
504 writer.end(); // save changes to the current page
505 doc.pagePushBack(page);
506
507 // End page ------------------------------------
508
509 doc.save((output_path + "element_builder.pdf"), SDFDoc.SaveMode.REMOVE_UNUSED, null);
510 System.out.println("Done. Result saved in element_builder.pdf...");
511 } catch (Exception e) {
512 e.printStackTrace();
513 } finally {
514 if (stream != null) {
515 try {
516 stream.close();
517 } catch (Exception ignored) {
518 }
519 }
520 }
521
522 PDFNet.terminate();
523 }
524}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales