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 UWP SDK and PDF Editing & Manipulation Library.

1//
2// Copyright (c) 2001-2020 by PDFTron Systems Inc. All Rights Reserved.
3//
4
5using System;
6using System.IO;
7using System.Threading.Tasks;
8using Windows.Foundation;
9
10using pdftron.Common;
11using pdftron.Filters;
12using pdftron.PDF;
13using pdftron.SDF;
14
15using PDFNetUniversalSamples.ViewModels;
16
17namespace PDFNetSamples
18{
19 public sealed class ElementBuilderTest : Sample
20 {
21 public ElementBuilderTest() :
22 base("ElementBuilder", "Illustrates how to use PDFNet page writing API, how to embed fonts and images and how to copy graphical elements from one page to another.")
23 {
24 }
25
26 public override IAsyncAction RunAsync()
27 {
28 return Task.Run(new System.Action(async () => {
29 WriteLine("--------------------------------");
30 WriteLine("Starting ElementBuilder Test...");
31 WriteLine("--------------------------------\n");
32
33 try
34 {
35 PDFDoc doc = new PDFDoc();
36
37 ElementBuilder eb = new ElementBuilder(); // ElementBuilder is used to build new Element objects
38 ElementWriter writer = new ElementWriter(); // ElementWriter is used to write Elements to the page
39
40 // Start a new page ------------------------------------
41 // Position an image stream on several places on the page
42 pdftron.PDF.Page page = doc.PageCreate(new pdftron.PDF.Rect(0, 0, 612, 794));
43
44 writer.Begin(page); // begin writing to this page
45
46 // Create an Image that can be reused multiple times in the document or
47 // multiple on the same page.
48
49 MappedFile img_file = new MappedFile(Path.Combine(InputPath, "peppers.jpg"));
50 FilterReader img_data = new FilterReader(img_file);
51 pdftron.PDF.Image img = pdftron.PDF.Image.Create(new SDFDoc(doc), img_data, 400, 600, 8, ColorSpace.CreateDeviceRGB(), pdftron.PDF.ImageInputFilter.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 pdftron.PDF.Rect(0, 0, 612, 794));
69
70 writer.Begin(page); // begin writing to this page
71 eb.Reset(); // Reset GState to default
72
73 eb.PathBegin(); // start constructing the path
74 eb.MoveTo(306, 396);
75 eb.CurveTo(681, 771, 399.75, 864.75, 306, 771);
76 eb.CurveTo(212.25, 864.75, -69, 771, 306, 396);
77 eb.ClosePath();
78 element = eb.PathEnd(); // the path is now finished
79 element.SetPathFill(true); // the path should be filled
80
81 // Set the path color space and color
82 gstate = element.GetGState();
83 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK());
84 gstate.SetFillColor(new ColorPt(1, 0, 0, 0)); // cyan
85 gstate.SetTransform(0.5, 0, 0, 0.5, -20, 300);
86 writer.WritePlacedElement(element);
87
88 // Draw the same path using a different stroke color
89 element.SetPathStroke(true); // this path is should be filled and stroked
90 gstate.SetFillColor(new ColorPt(0, 0, 1, 0)); // yellow
91 gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
92 gstate.SetStrokeColor(new ColorPt(1, 0, 0)); // red
93 gstate.SetTransform(0.5, 0, 0, 0.5, 280, 300);
94 gstate.SetLineWidth(20);
95 writer.WritePlacedElement(element);
96
97 // Draw the same path with with a given dash pattern
98 element.SetPathFill(false); // this path is should be only stroked
99 gstate.SetStrokeColor(new ColorPt(0, 0, 1)); // blue
100 gstate.SetTransform(0.5, 0, 0, 0.5, 280, 0);
101 double[] dash_pattern = { 30 };
102 gstate.SetDashPattern(dash_pattern, 0);
103 writer.WritePlacedElement(element);
104
105 // Use the path as a clipping path
106 writer.WriteElement(eb.CreateGroupBegin()); // Save the graphics state
107 // Start constructing a new path (the old path was lost when we created
108 // a new Element using CreateGroupBegin()).
109 eb.PathBegin();
110 eb.MoveTo(306, 396);
111 eb.CurveTo(681, 771, 399.75, 864.75, 306, 771);
112 eb.CurveTo(212.25, 864.75, -69, 771, 306, 396);
113 eb.ClosePath();
114 element = eb.PathEnd(); // path is now built
115 element.SetPathClip(true); // this path is a clipping path
116 element.SetPathStroke(true); // this path is should be filled and stroked
117 gstate = element.GetGState();
118 gstate.SetTransform(0.5, 0, 0, 0.5, -20, 0);
119 writer.WriteElement(element);
120 writer.WriteElement(eb.CreateImage(img, 100, 300, 400, 600));
121 writer.WriteElement(eb.CreateGroupEnd()); // Restore the graphics state
122
123 writer.End(); // save changes to the current page
124 doc.PagePushBack(page);
125
126 // Start a new page ------------------------------------
127 page = doc.PageCreate(new pdftron.PDF.Rect(0, 0, 612, 794));
128
129 writer.Begin(page); // begin writing to this page
130 eb.Reset(); // Reset GState to default
131
132 // Begin writing a block of text
133 element = eb.CreateTextBegin(Font.Create(doc.GetSDFDoc(), FontStandardType1Font.e_times_roman), 12);
134 writer.WriteElement(element);
135
136 string data = "Hello World!";
137 element = eb.CreateTextRun(data);
138 element.SetTextMatrix(10, 0, 0, 10, 0, 600);
139 element.GetGState().SetLeading(15); // Set the spacing between lines
140 writer.WriteElement(element);
141
142 writer.WriteElement(eb.CreateTextNewLine()); // New line
143
144 element = eb.CreateTextRun(data);
145 gstate = element.GetGState();
146 gstate.SetTextRenderMode(GStateTextRenderingMode.e_stroke_text);
147 gstate.SetCharSpacing(-1.25);
148 gstate.SetWordSpacing(-1.25);
149 writer.WriteElement(element);
150
151 writer.WriteElement(eb.CreateTextNewLine()); // New line
152
153 element = eb.CreateTextRun(data);
154 gstate = element.GetGState();
155 gstate.SetCharSpacing(0);
156 gstate.SetWordSpacing(0);
157 gstate.SetLineWidth(3);
158 gstate.SetTextRenderMode(GStateTextRenderingMode.e_fill_stroke_text);
159 gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB());
160 gstate.SetStrokeColor(new ColorPt(1, 0, 0)); // red
161 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK());
162 gstate.SetFillColor(new ColorPt(1, 0, 0, 0)); // cyan
163 writer.WriteElement(element);
164
165 writer.WriteElement(eb.CreateTextNewLine()); // New line
166
167 // Set text as a clipping path to the image.
168 element = eb.CreateTextRun(data);
169 gstate = element.GetGState();
170 gstate.SetTextRenderMode(GStateTextRenderingMode.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 PDF document.
185 // The example also shows how ElementReader can be used to copy and modify
186 // Elements between pages.
187
188 ElementReader reader = new ElementReader();
189
190 // Start reading Elements from the last page. We will copy all Elements to
191 // a new page but will modify the font associated with text.
192 reader.Begin(doc.GetPage(doc.GetPageCount()));
193
194 page = doc.PageCreate(new pdftron.PDF.Rect(0, 0, 1300, 794));
195
196 writer.Begin(page); // begin writing to this page
197 eb.Reset(); // Reset GState to default
198
199 // Embed an external font in the document.
200 Font font = Font.CreateTrueTypeFont(doc, Path.Combine(InputPath, "font.ttf"));
201
202 while ((element = reader.Next()) != null) // Read page contents
203 {
204 if (element.GetType() == ElementType.e_text)
205 {
206 element.GetGState().SetFont(font, 12);
207 }
208
209 writer.WriteElement(element);
210 }
211
212 reader.End();
213 writer.End(); // save changes to the current page
214
215 doc.PagePushBack(page);
216
217 // Start a new page ------------------------------------
218 //
219 // The example illustrates how to embed the external font in a PDF document.
220 // The example also shows how ElementReader can be used to copy and modify
221 // Elements between pages.
222
223 // Start reading Elements from the last page. We will copy all Elements to
224 // a new page but will modify the font associated with text.
225 reader.Begin(doc.GetPage(doc.GetPageCount()));
226
227 page = doc.PageCreate(new pdftron.PDF.Rect(0, 0, 1300, 794));
228
229 writer.Begin(page); // begin writing to this page
230 eb.Reset(); // Reset GState to default
231
232 // Embed an external font in the document.
233 Font font2 = Font.CreateType1Font(doc, Path.Combine(InputPath, "Misc-Fixed.pfa"));
234
235 while ((element = reader.Next()) != null) // Read page contents
236 {
237 if (element.GetType() == ElementType.e_text)
238 {
239 element.GetGState().SetFont(font2, 12);
240 }
241 writer.WriteElement(element);
242 }
243
244 reader.End();
245 writer.End(); // save changes to the current page
246 doc.PagePushBack(page);
247
248
249 // Start a new page ------------------------------------
250 page = doc.PageCreate();
251 writer.Begin(page); // begin writing to this page
252 eb.Reset(); // Reset GState to default
253
254 // Begin writing a block of text
255 //System.Drawing.Font sys_font = new System.Drawing.Font("Comic Sans MS", 12);
256 //Font my_font = Font.CreateTrueTypeFont(doc, sys_font, false, false);
257 Font my_font = Font.Create(doc, pdftron.PDF.FontStandardType1Font.e_times_roman);
258 element = eb.CreateTextBegin(my_font, 12);
259 element.SetTextMatrix(1.5, 0, 0, 1.5, 50, 600);
260 element.GetGState().SetLeading(15); // Set the spacing between lines
261 writer.WriteElement(element);
262
263 string para = "A PDF text object consists of operators that can show " +
264 "text strings, move the text position, and set text state and certain " +
265 "other parameters. In addition, there are three parameters that are " +
266 "defined only within a text object and do not persist from one text " +
267 "object to the next: Tm, the text matrix, Tlm, the text line matrix, " +
268 "Trm, the text rendering matrix, actually just an intermediate result " +
269 "that combines the effects of text state parameters, the text matrix " +
270 "(Tm), and the current transformation matrix";
271
272 int para_end = para.Length;
273 int text_run = 0;
274 int text_run_end;
275
276 double para_width = 300; // paragraph width is 300 units
277 double cur_width = 0;
278
279 while (text_run < para_end)
280 {
281 text_run_end = para.IndexOf(' ', text_run);
282 if (text_run_end < 0)
283 text_run_end = para_end - 1;
284
285 string text = para.Substring(text_run, text_run_end - text_run + 1);
286 element = eb.CreateTextRun(text);
287 if (cur_width + element.GetTextLength() < para_width)
288 {
289 writer.WriteElement(element);
290 cur_width += element.GetTextLength();
291 }
292 else
293 {
294 writer.WriteElement(eb.CreateTextNewLine()); // New line
295 text = para.Substring(text_run, text_run_end - text_run + 1);
296 element = eb.CreateTextRun(text);
297 cur_width = element.GetTextLength();
298 writer.WriteElement(element);
299 }
300
301 text_run = text_run_end + 1;
302 }
303
304 // Draw the same strings using direct content output...
305 writer.Flush(); // flush pending Element writing operations.
306
307 // You can also write page content directly to the content stream using
308 // ElementWriter.WriteString(...) and ElementWriter.WriteBuffer(...) methods.
309 // Note that if you are planning to use these functions you need to be familiar
310 // with PDF page content operators (see Appendix A in PDF Reference Manual).
311 // Because it is easy to make mistakes during direct output we recommend that
312 // you use ElementBuilder and Element interface instead.
313 writer.WriteString("T* T* T* "); // New Lines
314 writer.WriteElement(eb.CreateTextNewLine());
315 writer.WriteString("(Direct output to PDF page content stream:) Tj T* ");
316 writer.WriteString("(AWAY) Tj T* ");
317 writer.WriteString("[(A)140(W)140(A)115(Y again)] TJ ");
318
319 // Finish the block of text
320 writer.WriteElement(eb.CreateTextEnd());
321
322 writer.End(); // save changes to the current page
323 doc.PagePushBack(page);
324
325
326 // Transparency sample ----------------------------------
327
328 // Start a new page -------------------------------------
329 page = doc.PageCreate();
330 writer.Begin(page); // begin writing to this page
331 eb.Reset(); // Reset the GState to default
332
333 // Write some transparent text at the bottom of the page.
334 element = eb.CreateTextBegin(Font.Create(doc.GetSDFDoc(), FontStandardType1Font.e_times_roman), 100);
335
336 // Set the text knockout attribute. Text knockout must be set outside of
337 // the text group.
338 gstate = element.GetGState();
339 gstate.SetTextKnockout(false);
340 gstate.SetBlendMode(GStateBlendMode.e_bl_difference);
341 writer.WriteElement(element);
342
343 element = eb.CreateTextRun("Transparency");
344 element.SetTextMatrix(1, 0, 0, 1, 30, 30);
345 gstate = element.GetGState();
346 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK());
347 gstate.SetFillColor(new ColorPt(1, 0, 0, 0));
348
349 gstate.SetFillOpacity(0.5);
350 writer.WriteElement(element);
351
352 // Write the same text on top the old; shifted by 3 points
353 element.SetTextMatrix(1, 0, 0, 1, 33, 33);
354 gstate.SetFillColor(new ColorPt(0, 1, 0, 0));
355 gstate.SetFillOpacity(0.5);
356
357 writer.WriteElement(element);
358 writer.WriteElement(eb.CreateTextEnd());
359
360 // Draw three overlapping transparent circles.
361 eb.PathBegin(); // start constructing the path
362 eb.MoveTo(459.223, 505.646);
363 eb.CurveTo(459.223, 415.841, 389.85, 343.04, 304.273, 343.04);
364 eb.CurveTo(218.697, 343.04, 149.324, 415.841, 149.324, 505.646);
365 eb.CurveTo(149.324, 595.45, 218.697, 668.25, 304.273, 668.25);
366 eb.CurveTo(389.85, 668.25, 459.223, 595.45, 459.223, 505.646);
367 element = eb.PathEnd();
368 element.SetPathFill(true);
369
370 gstate = element.GetGState();
371 gstate.SetFillColorSpace(ColorSpace.CreateDeviceRGB());
372 gstate.SetFillColor(new ColorPt(0, 0, 1)); // Blue Circle
373
374 gstate.SetBlendMode(GStateBlendMode.e_bl_normal);
375 gstate.SetFillOpacity(0.5);
376 writer.WriteElement(element);
377
378 // Translate relative to the Blue Circle
379 gstate.SetTransform(1, 0, 0, 1, 113, -185);
380 gstate.SetFillColor(new ColorPt(0, 1, 0)); // Green Circle
381 gstate.SetFillOpacity(0.5);
382 writer.WriteElement(element);
383
384 // Translate relative to the Green Circle
385 gstate.SetTransform(1, 0, 0, 1, -220, 0);
386 gstate.SetFillColor(new ColorPt(1, 0, 0)); // Red Circle
387 gstate.SetFillOpacity(0.5);
388 writer.WriteElement(element);
389
390 writer.End(); // save changes to the current page
391 doc.PagePushBack(page);
392
393 // End page ------------------------------------
394
395 String output_file_path = Path.Combine(OutputPath, "element_builder.pdf");
396 await doc.SaveAsync(output_file_path, SDFDocSaveOptions.e_remove_unused);
397 doc.Destroy();
398 WriteLine("Done. Result saved in " + output_file_path);
399 await AddFileToOutputList(output_file_path).ConfigureAwait(false);
400 }
401 catch (Exception e)
402 {
403 WriteLine(GetExceptionMessage(e));
404 }
405
406 WriteLine("\n--------------------------------");
407 WriteLine("Done ElementBuilder Test.");
408 WriteLine("--------------------------------\n");
409 })).AsAsyncAction();
410 }
411 }
412}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales