ElementBuilder

Sample C# 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. 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//
4
5using System;
6using pdftron;
7using pdftron.Common;
8using pdftron.Filters;
9using pdftron.SDF;
10using pdftron.PDF;
11
12namespace ElementBuilderTestCS
13{
14 /// <summary>
15 /// Summary description for Class1.
16 /// </summary>
17 class Class1
18 {
19 private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();
20 static Class1() {}
21
22 /// <summary>
23 /// The main entry point for the application.
24 /// </summary>
25 [STAThread]
26 static void Main(string[] args)
27 {
28 PDFNet.Initialize(PDFTronLicense.Key);
29
30 // Relative path to the folder containing test files.
31 string input_path = "../../../../TestFiles/";
32 string output_path = "../../../../TestFiles/Output/";
33
34
35 try
36 {
37 using (PDFDoc doc = new PDFDoc())
38 using (ElementBuilder eb = new ElementBuilder()) // ElementBuilder is used to build new Element objects
39 using (ElementWriter writer = new ElementWriter()) // ElementWriter is used to write Elements to the page
40 {
41 // Start a new page ------------------------------------
42 // Position an image stream on several places on the page
43 Page page = doc.PageCreate(new Rect(0, 0, 612, 794));
44
45 writer.Begin(page); // begin writing to this page
46
47 // Create an Image that can be reused multiple times in the document or
48 // multiple on the same page.
49 MappedFile img_file = new MappedFile(input_path + "peppers.jpg");
50 FilterReader img_data = new FilterReader(img_file);
51 Image img = Image.Create(doc, img_data, 400, 600, 8, ColorSpace.CreateDeviceRGB(), Image.InputFilter.e_jpeg);
52
53 Element element = eb.CreateImage(img, new Matrix2D(200, -145, 20, 300, 200, 150));
54 writer.WritePlacedElement(element);
55
56 GState gstate = element.GetGState(); // use the same image (just change its matrix)
57 gstate.SetTransform(200, 0, 0, 300, 50, 450);
58 writer.WritePlacedElement(element);
59
60 // use the same image again (just change its matrix).
61 writer.WritePlacedElement(eb.CreateImage(img, 300, 600, 200, -150));
62
63 writer.End(); // save changes to the current page
64 doc.PagePushBack(page);
65
66 // Start a new page ------------------------------------
67 // Construct and draw a path object using different styles
68 page = doc.PageCreate(new Rect(0, 0, 612, 794));
69
70 writer.Begin(page); // begin writing to this page
71 eb.Reset(); // Reset GState to default
72
73
74 eb.PathBegin(); // start constructing the path
75 eb.MoveTo(306, 396);
76 eb.CurveTo(681, 771, 399.75, 864.75, 306, 771);
77 eb.CurveTo(212.25, 864.75, -69, 771, 306, 396);
78 eb.ClosePath();
79 element = eb.PathEnd(); // the path is now finished
80 element.SetPathFill(true); // the path should be filled
81
82 // Set the path color space and color
83 gstate = element.GetGState();
84 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK());
85 gstate.SetFillColor(new ColorPt(1, 0, 0, 0)); // cyan
86 gstate.SetTransform(0.5, 0, 0, 0.5, -20, 300);
87 writer.WritePlacedElement(element);
88
89 // Draw the same path using a different stroke color
90 element.SetPathStroke(true); // this path is should be filled and stroked
91 gstate.SetFillColor(new ColorPt(0, 0, 1, 0)); // yellow
92 gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
93 gstate.SetStrokeColor(new ColorPt(1, 0, 0)); // red
94 gstate.SetTransform(0.5, 0, 0, 0.5, 280, 300);
95 gstate.SetLineWidth(20);
96 writer.WritePlacedElement(element);
97
98 // Draw the same path with with a given dash pattern
99 element.SetPathFill(false); // this path is should be only stroked
100 gstate.SetStrokeColor(new ColorPt(0, 0, 1)); // blue
101 gstate.SetTransform(0.5, 0, 0, 0.5, 280, 0);
102 double[] dash_pattern = {30};
103 gstate.SetDashPattern(dash_pattern, 0);
104 writer.WritePlacedElement(element);
105
106 // Use the path as a clipping path
107 writer.WriteElement(eb.CreateGroupBegin()); // Save the graphics state
108 // Start constructing a new path (the old path was lost when we created
109 // a new Element using CreateGroupBegin()).
110 eb.PathBegin();
111 eb.MoveTo(306, 396);
112 eb.CurveTo(681, 771, 399.75, 864.75, 306, 771);
113 eb.CurveTo(212.25, 864.75, -69, 771, 306, 396);
114 eb.ClosePath();
115 element = eb.PathEnd(); // path is now built
116 element.SetPathClip(true); // this path is a clipping path
117 element.SetPathStroke(true); // this path is should be filled and stroked
118 gstate = element.GetGState();
119 gstate.SetTransform(0.5, 0, 0, 0.5, -20, 0);
120 writer.WriteElement(element);
121 writer.WriteElement(eb.CreateImage(img, 100, 300, 400, 600));
122 writer.WriteElement(eb.CreateGroupEnd()); // Restore the graphics state
123
124 writer.End(); // save changes to the current page
125 doc.PagePushBack(page);
126
127
128 // Start a new page ------------------------------------
129 page = doc.PageCreate(new Rect(0, 0, 612, 794));
130
131 writer.Begin(page); // begin writing to this page
132 eb.Reset(); // Reset GState to default
133
134 // Begin writing a block of text
135 element = eb.CreateTextBegin(Font.Create(doc, Font.StandardType1Font.e_times_roman), 12);
136 writer.WriteElement(element);
137
138 string data = "Hello World!";
139 element = eb.CreateTextRun(data);
140 element.SetTextMatrix(10, 0, 0, 10, 0, 600);
141 element.GetGState().SetLeading(15); // Set the spacing between lines
142 writer.WriteElement(element);
143
144 writer.WriteElement(eb.CreateTextNewLine()); // New line
145
146 element = eb.CreateTextRun(data);
147 gstate = element.GetGState();
148 gstate.SetTextRenderMode(GState.TextRenderingMode.e_stroke_text);
149 gstate.SetCharSpacing(-1.25);
150 gstate.SetWordSpacing(-1.25);
151 writer.WriteElement(element);
152
153 writer.WriteElement(eb.CreateTextNewLine()); // New line
154
155 element = eb.CreateTextRun(data);
156 gstate = element.GetGState();
157 gstate.SetCharSpacing(0);
158 gstate.SetWordSpacing(0);
159 gstate.SetLineWidth(3);
160 gstate.SetTextRenderMode(GState.TextRenderingMode.e_fill_stroke_text);
161 gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
162 gstate.SetStrokeColor(new ColorPt(1, 0, 0)); // red
163 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK());
164 gstate.SetFillColor(new ColorPt(1, 0, 0, 0)); // cyan
165 writer.WriteElement(element);
166
167 writer.WriteElement(eb.CreateTextNewLine()); // New line
168
169 // Set text as a clipping path to the image.
170 element = eb.CreateTextRun(data);
171 gstate = element.GetGState();
172 gstate.SetTextRenderMode(GState.TextRenderingMode.e_clip_text);
173 writer.WriteElement(element);
174
175 // Finish the block of text
176 writer.WriteElement(eb.CreateTextEnd());
177
178 // Draw an image that will be clipped by the above text
179 writer.WriteElement(eb.CreateImage(img, 10, 100, 1300, 720));
180
181 writer.End(); // save changes to the current page
182 doc.PagePushBack(page);
183
184 // Start a new page ------------------------------------
185 //
186 // The example illustrates how to embed the external font in a PDF document.
187 // The example also shows how ElementReader can be used to copy and modify
188 // Elements between pages.
189
190 using (ElementReader reader = new ElementReader())
191 {
192 // Start reading Elements from the last page. We will copy all Elements to
193 // a new page but will modify the font associated with text.
194 reader.Begin(doc.GetPage(doc.GetPageCount()));
195
196 page = doc.PageCreate(new Rect(0, 0, 1300, 794));
197
198 writer.Begin(page); // begin writing to this page
199 eb.Reset(); // Reset GState to default
200
201 // Embed an external font in the document.
202 Font font = Font.CreateTrueTypeFont(doc, input_path + "font.ttf");
203
204 while ((element = reader.Next()) != null) // Read page contents
205 {
206 if (element.GetType() == Element.Type.e_text)
207 {
208 element.GetGState().SetFont(font, 12);
209 }
210
211 writer.WriteElement(element);
212 }
213
214 reader.End();
215 writer.End(); // save changes to the current page
216
217 doc.PagePushBack(page);
218
219
220 // Start a new page ------------------------------------
221 //
222 // The example illustrates how to embed the external font in a PDF document.
223 // The example also shows how ElementReader can be used to copy and modify
224 // Elements between pages.
225
226 // Start reading Elements from the last page. We will copy all Elements to
227 // a new page but will modify the font associated with text.
228 reader.Begin(doc.GetPage(doc.GetPageCount()));
229
230 page = doc.PageCreate(new Rect(0, 0, 1300, 794));
231
232 writer.Begin(page); // begin writing to this page
233 eb.Reset(); // Reset GState to default
234
235 // Embed an external font in the document.
236 Font font2 = Font.CreateType1Font(doc, input_path + "Misc-Fixed.pfa");
237
238 while ((element = reader.Next()) != null) // Read page contents
239 {
240 if (element.GetType() == Element.Type.e_text)
241 {
242 element.GetGState().SetFont(font2, 12);
243 }
244
245 writer.WriteElement(element);
246 }
247
248 reader.End();
249 writer.End(); // save changes to the current page
250 doc.PagePushBack(page);
251
252
253 // Start a new page ------------------------------------
254 page = doc.PageCreate();
255 writer.Begin(page); // begin writing to this page
256 eb.Reset(); // Reset GState to default
257
258 // Begin writing a block of text
259 element = eb.CreateTextBegin(Font.Create(doc, Font.StandardType1Font.e_times_roman), 12);
260 element.SetTextMatrix(1.5, 0, 0, 1.5, 50, 600);
261 element.GetGState().SetLeading(15); // Set the spacing between lines
262 writer.WriteElement(element);
263
264 string para = "A PDF text object consists of operators that can show " +
265 "text strings, move the text position, and set text state and certain " +
266 "other parameters. In addition, there are three parameters that are " +
267 "defined only within a text object and do not persist from one text " +
268 "object to the next: Tm, the text matrix, Tlm, the text line matrix, " +
269 "Trm, the text rendering matrix, actually just an intermediate result " +
270 "that combines the effects of text state parameters, the text matrix " +
271 "(Tm), and the current transformation matrix";
272
273 int para_end = para.Length;
274 int text_run = 0;
275 int text_run_end;
276
277 double para_width = 300; // paragraph width is 300 units
278 double cur_width = 0;
279
280 while (text_run < para_end)
281 {
282 text_run_end = para.IndexOf(' ', text_run);
283 if (text_run_end < 0)
284 text_run_end = para_end - 1;
285
286 string text = para.Substring(text_run, text_run_end-text_run+1);
287 element = eb.CreateTextRun(text);
288 if (cur_width + element.GetTextLength() < para_width)
289 {
290 writer.WriteElement(element);
291 cur_width += element.GetTextLength();
292 }
293 else
294 {
295 writer.WriteElement(eb.CreateTextNewLine()); // New line
296 text = para.Substring(text_run, text_run_end-text_run+1);
297 element = eb.CreateTextRun(text);
298 cur_width = element.GetTextLength();
299 writer.WriteElement(element);
300 }
301
302 text_run = text_run_end+1;
303 }
304
305 // -----------------------------------------------------------------------
306 // The following code snippet illustrates how to adjust spacing between
307 // characters (text runs).
308 element = eb.CreateTextNewLine();
309 writer.WriteElement(element); // Skip 2 lines
310 writer.WriteElement(element);
311
312 writer.WriteElement(eb.CreateTextRun("An example of space adjustments between inter-characters:"));
313 writer.WriteElement(eb.CreateTextNewLine());
314
315 // Write string "AWAY" without space adjustments between characters.
316 element = eb.CreateTextRun("AWAY");
317 writer.WriteElement(element);
318
319 writer.WriteElement(eb.CreateTextNewLine());
320
321 // Write string "AWAY" with space adjustments between characters.
322 element = eb.CreateTextRun("A");
323 writer.WriteElement(element);
324
325 element = eb.CreateTextRun("W");
326 element.SetPosAdjustment(140);
327 writer.WriteElement(element);
328
329 element = eb.CreateTextRun("A");
330 element.SetPosAdjustment(140);
331 writer.WriteElement(element);
332
333 element = eb.CreateTextRun("Y again");
334 element.SetPosAdjustment(115);
335 writer.WriteElement(element);
336
337 // Draw the same strings using direct content output...
338 writer.Flush(); // flush pending Element writing operations.
339
340 // You can also write page content directly to the content stream using
341 // ElementWriter.WriteString(...) and ElementWriter.WriteBuffer(...) methods.
342 // Note that if you are planning to use these functions you need to be familiar
343 // with PDF page content operators (see Appendix A in PDF Reference Manual).
344 // Because it is easy to make mistakes during direct output we recommend that
345 // you use ElementBuilder and Element interface instead.
346 writer.WriteString("T* T* "); // New Lines
347 // writer.WriteElement(eb.CreateTextNewLine());
348 writer.WriteString("(Direct output to PDF page content stream:) Tj T* ");
349 writer.WriteString("(AWAY) Tj T* ");
350 writer.WriteString("[(A)140(W)140(A)115(Y again)] TJ ");
351
352 // Finish the block of text
353 writer.WriteElement(eb.CreateTextEnd());
354
355 writer.End(); // save changes to the current page
356 doc.PagePushBack(page);
357
358 // Start a new page ------------------------------------
359
360 // Image Masks
361 //
362 // In the opaque imaging model, images mark all areas they occupy on the page as
363 // if with opaque paint. All portions of the image, whether black, white, gray,
364 // or color, completely obscure any marks that may previously have existed in the
365 // same place on the page.
366 // In the graphic arts industry and page layout applications, however, it is common
367 // to crop or 'mask out' the background of an image and then place the masked image
368 // on a different background, allowing the existing background to show through the
369 // masked areas. This sample illustrates how to use image masks.
370
371 page = doc.PageCreate();
372 writer.Begin(page); // begin writing to the page
373
374 // Create the Image Mask
375 MappedFile imgf = new MappedFile(input_path + "imagemask.dat");
376 FilterReader mask_read = new FilterReader(imgf);
377
378 ColorSpace device_gray = ColorSpace.CreateDeviceGray();
379 Image mask = Image.Create(doc, mask_read, 64, 64, 1, device_gray, Image.InputFilter.e_ascii_hex);
380
381 mask.GetSDFObj().PutBool("ImageMask", true);
382
383 element = eb.CreateRect(0, 0, 612, 794);
384 element.SetPathStroke(false);
385 element.SetPathFill(true);
386 element.GetGState().SetFillColorSpace(device_gray);
387 element.GetGState().SetFillColor(new ColorPt(0.8));
388 writer.WritePlacedElement(element);
389
390 element = eb.CreateImage(mask, new Matrix2D(200, 0, 0, -200, 40, 680));
391 element.GetGState().SetFillColor(new ColorPt(0.1));
392 writer.WritePlacedElement(element);
393
394 element.GetGState().SetFillColorSpace(ColorSpace.CreateDeviceRGB());
395 element.GetGState().SetFillColor(new ColorPt(1, 0, 0));
396 element = eb.CreateImage(mask, new Matrix2D(200, 0, 0, -200, 320, 680));
397 writer.WritePlacedElement(element);
398
399 element.GetGState().SetFillColor(new ColorPt(0, 1, 0));
400 element = eb.CreateImage(mask, new Matrix2D(200, 0, 0, -200, 40, 380));
401 writer.WritePlacedElement(element);
402
403 {
404 // This sample illustrates Explicit Masking.
405 img = Image.Create(doc, input_path + "peppers.jpg");
406
407 // mask is the explicit mask for the primary (base) image
408 img.SetMask(mask);
409
410 element = eb.CreateImage(img, new Matrix2D(200, 0, 0, -200, 320, 380));
411 writer.WritePlacedElement(element);
412 }
413
414 writer.End(); // save changes to the current page
415 doc.PagePushBack(page);
416
417 // Transparency sample ----------------------------------
418
419 // Start a new page -------------------------------------
420 page = doc.PageCreate();
421 writer.Begin(page); // begin writing to this page
422 eb.Reset(); // Reset the GState to default
423
424 // Write some transparent text at the bottom of the page.
425 element = eb.CreateTextBegin(Font.Create(doc, Font.StandardType1Font.e_times_roman), 100);
426
427 // Set the text knockout attribute. Text knockout must be set outside of
428 // the text group.
429 gstate = element.GetGState();
430 gstate.SetTextKnockout(false);
431 gstate.SetBlendMode(GState.BlendMode.e_bl_difference);
432 writer.WriteElement(element);
433
434 element = eb.CreateTextRun("Transparency");
435 element.SetTextMatrix(1, 0, 0, 1, 30, 30);
436 gstate = element.GetGState();
437 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK());
438 gstate.SetFillColor(new ColorPt(1, 0, 0, 0));
439
440 gstate.SetFillOpacity(0.5);
441 writer.WriteElement(element);
442
443 // Write the same text on top the old; shifted by 3 points
444 element.SetTextMatrix(1, 0, 0, 1, 33, 33);
445 gstate.SetFillColor(new ColorPt(0, 1, 0, 0));
446 gstate.SetFillOpacity(0.5);
447
448 writer.WriteElement(element);
449 writer.WriteElement(eb.CreateTextEnd());
450
451 // Draw three overlapping transparent circles.
452 eb.PathBegin(); // start constructing the path
453 eb.MoveTo(459.223, 505.646);
454 eb.CurveTo(459.223, 415.841, 389.85, 343.04, 304.273, 343.04);
455 eb.CurveTo(218.697, 343.04, 149.324, 415.841, 149.324, 505.646);
456 eb.CurveTo(149.324, 595.45, 218.697, 668.25, 304.273, 668.25);
457 eb.CurveTo(389.85, 668.25, 459.223, 595.45, 459.223, 505.646);
458 element = eb.PathEnd();
459 element.SetPathFill(true);
460
461 gstate = element.GetGState();
462 gstate.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
463 gstate.SetFillColor(new ColorPt(0, 0, 1)); // Blue Circle
464
465 gstate.SetBlendMode(GState.BlendMode.e_bl_normal);
466 gstate.SetFillOpacity(0.5);
467 writer.WriteElement(element);
468
469 // Translate relative to the Blue Circle
470 gstate.SetTransform(1, 0, 0, 1, 113, -185);
471 gstate.SetFillColor(new ColorPt(0, 1, 0)); // Green Circle
472 gstate.SetFillOpacity(0.5);
473 writer.WriteElement(element);
474
475 // Translate relative to the Green Circle
476 gstate.SetTransform(1, 0, 0, 1, -220, 0);
477 gstate.SetFillColor(new ColorPt(1, 0, 0)); // Red Circle
478 gstate.SetFillOpacity(0.5);
479 writer.WriteElement(element);
480
481 writer.End(); // save changes to the current page
482 doc.PagePushBack(page);
483
484 // End page ------------------------------------
485 }
486
487 doc.Save(output_path + "element_builder.pdf", SDFDoc.SaveOptions.e_remove_unused);
488 Console.WriteLine("Done. Result saved in element_builder.pdf...");
489 }
490 }
491 catch (PDFNetException e)
492 {
493 Console.WriteLine(e.Message);
494 }
495 PDFNet.Terminate();
496 }
497 }
498}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales