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}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
3// Consult LICENSE.txt regarding license information.
4//---------------------------------------------------------------------------------------
5
6package main
7import (
8 "fmt"
9 "strings"
10 . "pdftron"
11)
12
13import "pdftron/Samples/LicenseKey/GO"
14
15// Relative path to the folder containing the test files.
16var inputPath = "../../TestFiles/"
17var outputPath = "../../TestFiles/Output/"
18
19func Find(s, substr string, offset int) int {
20 if len(s) < offset {
21 return -1
22 }
23 if idx := strings.Index(s[offset:], substr); idx >= 0 {
24 return offset + idx
25 }
26 return -1
27}
28
29//-----------------------------------------------------------------------------------------------------------------------
30func main(){
31 PDFNetInitialize(PDFTronLicense.Key)
32
33 doc := NewPDFDoc()
34
35 // ElementBuilder is used to build new Element objects
36 eb := NewElementBuilder()
37 // ElementWriter is used to write Elements to the page
38 writer := NewElementWriter()
39
40 // Start a new page ------------------------------------
41 page := doc.PageCreate(NewRect(0.0, 0.0, 612.0, 794.0))
42
43 writer.Begin(page) // begin writing to the page
44
45 // Create an Image that can be reused in the document or on the same page.
46 img := ImageCreate(doc.GetSDFDoc(), inputPath + "peppers.jpg")
47
48 element := eb.CreateImage(img, NewMatrix2D(float64(img.GetImageWidth()/2), -145.0, 20.0, float64(img.GetImageHeight()/2), 200.0, 150.0))
49 writer.WritePlacedElement(element)
50
51 gstate := element.GetGState() // use the same image (just change its matrix)
52 gstate.SetTransform(200.0, 0.0, 0.0, 300.0, 50.0, 450.0)
53 writer.WritePlacedElement(element)
54
55 // use the same image again (just change its matrix)
56 writer.WritePlacedElement(eb.CreateImage(img, 300.0, 600.0, 200.0, -150.0))
57
58 writer.End() // save changes to the current page
59 doc.PagePushBack(page)
60
61 // Start a new page ------------------------------------
62 // Construct and draw a path object using different styles
63 page = doc.PageCreate(NewRect(0.0, 0.0, 612.0, 794.0))
64
65 writer.Begin(page) // begin writing to this page
66 eb.Reset() // Reset the GState to default
67
68 eb.PathBegin() // start constructing the path
69 eb.MoveTo(306.0, 396.0)
70 eb.CurveTo(681.0, 771.0, 399.75, 864.75, 306.0, 771.0)
71 eb.CurveTo(212.25, 864.75, -69, 771.0, 306.0, 396.0)
72 eb.ClosePath()
73 element = eb.PathEnd() // the path is now finished
74 element.SetPathFill(true) // the path should be filled
75
76 // Set the path color space and color
77 gstate = element.GetGState()
78 gstate.SetFillColorSpace(ColorSpaceCreateDeviceCMYK())
79 gstate.SetFillColor(NewColorPt(1.0, 0.0, 0.0, 0.0)) // cyan
80 gstate.SetTransform(0.5, 0.0, 0.0, 0.5, -20.0, 300.0)
81 writer.WritePlacedElement(element)
82
83 // Draw the same path using a different stroke color
84 element.SetPathStroke(true) // this path is should be filled and stroked
85 gstate.SetFillColor(NewColorPt(0.0, 0.0, 1.0, 0.0)) // yellow
86 gstate.SetStrokeColorSpace(ColorSpaceCreateDeviceRGB())
87 gstate.SetStrokeColor(NewColorPt(1.0, 0.0, 0.0)) // red
88 gstate.SetTransform(0.5, 0.0, 0.0, 0.5, 280.0, 300.0)
89 gstate.SetLineWidth(20)
90 writer.WritePlacedElement(element)
91
92 // Draw the same path with a given dash pattern
93 element.SetPathFill(false) // this path should be only stroked
94
95 gstate.SetStrokeColor(NewColorPt(0.0,0.0,1.0)) // blue
96 gstate.SetTransform(0.5, 0.0, 0.0, 0.5, 280.0, 0.0)
97 dashPattern := NewVectorDouble()
98 dashPattern.Add(30.0)
99 gstate.SetDashPattern(dashPattern, 0)
100 writer.WritePlacedElement(element)
101
102 // Use the path as a clipping path
103 writer.WriteElement(eb.CreateGroupBegin()) // Save the graphics state
104 // Start constructing the new path (the old path was lost when we created
105 // a new Element using CreateGroupBegin()).
106 eb.PathBegin()
107 eb.MoveTo(306.0, 396.0)
108 eb.CurveTo(681.0, 771.0, 399.75, 864.75, 306.0, 771.0)
109 eb.CurveTo(212.25, 864.75, -69.0, 771.0, 306.0, 396.0)
110 eb.ClosePath()
111 element = eb.PathEnd() // path is now constructed
112 element.SetPathClip(true) // this path is a clipping path
113 element.SetPathStroke(true) // this path should be filled and stroked
114 gstate = element.GetGState()
115 gstate.SetTransform(0.5, 0.0, 0.0, 0.5, -20.0, 0.0)
116
117 writer.WriteElement(element)
118
119 writer.WriteElement(eb.CreateImage(img, 100.0, 300.0, 400.0, 600.0))
120
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(NewRect(0.0, 0.0, 612.0, 794.0))
128
129 writer.Begin(page) // begin writing to this page
130 eb.Reset() // Reset the GState to default
131
132 // Begin writing a block of text
133 element = eb.CreateTextBegin(FontCreate(doc.GetSDFDoc(), FontE_times_roman), 12.0)
134 writer.WriteElement(element)
135
136 element = eb.CreateTextRun("Hello World!")
137 element.SetTextMatrix(10.0, 0.0, 0.0, 10.0, 0.0, 600.0)
138 element.GetGState().SetLeading(15) // Set the spacing 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(GStateE_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(GStateE_fill_stroke_text)
158 gstate.SetStrokeColorSpace(ColorSpaceCreateDeviceRGB())
159 gstate.SetStrokeColor(NewColorPt(1.0, 0.0, 0.0)) // red
160 gstate.SetFillColorSpace(ColorSpaceCreateDeviceCMYK())
161 gstate.SetFillColor(NewColorPt(1.0, 0.0, 0.0, 0.0)) // cyan
162 writer.WriteElement(element)
163
164 writer.WriteElement(eb.CreateTextNewLine()) // New line
165
166 // Set text as a clipping path to the image.
167 element = eb.CreateTextRun("Hello World!")
168 gstate = element.GetGState()
169 gstate.SetTextRenderMode(GStateE_clip_text)
170 writer.WriteElement(element)
171
172 // Finish the block of text
173 writer.WriteElement(eb.CreateTextEnd())
174
175 // Draw an image that will be clipped by the above text
176 writer.WriteElement(eb.CreateImage(img, 10.0, 100.0, 1300.0, 720.0))
177
178 writer.End() // save changes to the current page
179 doc.PagePushBack(page)
180
181 // Start a new page ------------------------------------
182 //
183 // The example illustrates how to embed the external font in a PDF document.
184 // The example also shows how ElementReader can be used to copy and modify
185 // Elements between pages.
186
187 reader := NewElementReader()
188
189 // Start reading Elements from the last page. We will copy all Elements to
190 // a new page but will modify the font associated with text.
191 reader.Begin(doc.GetPage(uint(doc.GetPageCount())))
192
193 page = doc.PageCreate(NewRect(0.0, 0.0, 1300.0, 794.0))
194
195 writer.Begin(page) // begin writing to this page
196 eb.Reset() // Reset the GState to default
197
198 // Embed an external font in the document.
199 font := FontCreateTrueTypeFont(doc.GetSDFDoc(), (inputPath + "font.ttf"))
200 element = reader.Next()
201 for element.GetMp_elem().Swigcptr() != 0{
202 if element.GetType() == ElementE_text{
203 element.GetGState().SetFont(font, 12.0)
204 }
205 writer.WriteElement(element)
206 element = reader.Next()
207 }
208
209
210 reader.End()
211 writer.End() // save changes to the current page
212 doc.PagePushBack(page)
213
214 // Start a new page ------------------------------------
215 //
216 // The example illustrates how to embed the external font in a PDF document.
217 // The example also shows how ElementReader can be used to copy and modify
218 // Elements between pages.
219
220 // Start reading Elements from the last page. We will copy all Elements to
221 // a new page but will modify the font associated with text.
222 reader.Begin(doc.GetPage(uint(doc.GetPageCount())))
223
224 page = doc.PageCreate(NewRect(0.0, 0.0, 1300.0, 794.0))
225
226 writer.Begin(page) // begin writing to this page
227 eb.Reset() // Reset the GState to default
228
229 // Embed an external font in the document.
230 font2 := FontCreateType1Font(doc.GetSDFDoc(), (inputPath + "Misc-Fixed.pfa"))
231
232 element = reader.Next()
233 for element.GetMp_elem().Swigcptr() != 0{
234 if element.GetType() == ElementE_text{
235 element.GetGState().SetFont(font2, 12.0)
236 }
237 writer.WriteElement(element)
238 element = reader.Next()
239 }
240
241 reader.End()
242 writer.End() // save changes to the current page
243 doc.PagePushBack(page)
244 // Start a new page ------------------------------------
245 page = doc.PageCreate()
246 writer.Begin(page) // begin writing to this page
247 eb.Reset() // Reset the GState to default
248
249 // Begin writing a block of text
250 element = eb.CreateTextBegin(FontCreate(doc.GetSDFDoc(), FontE_times_roman), 12.0)
251 element.SetTextMatrix(1.5, 0.0, 0.0, 1.5, 50.0, 600.0)
252 element.GetGState().SetLeading(15) // Set the spacing between lines
253 writer.WriteElement(element)
254
255 para := "A PDF text object consists of operators that can show " +
256 "text strings, move the text position, and set text state and certain " +
257 "other parameters. In addition, there are three parameters that are " +
258 "defined only within a text object and do not persist from one text " +
259 "object to the next: Tm, the text matrix, Tlm, the text line matrix, " +
260 "Trm, the text rendering matrix, actually just an intermediate result " +
261 "that combines the effects of text state parameters, the text matrix " +
262 "(Tm), and the current transformation matrix\n"
263
264 paraEnd := len(para)
265 textRun := 0
266
267 paraWidth := 300 // paragraph width is 300 units
268 curWidth := 0
269
270 for textRun < paraEnd{
271 textRunEnd := Find(para, " ", textRun)
272 if textRunEnd < 0{
273 textRunEnd = paraEnd - 1
274 }
275 text := para[textRun:textRunEnd+1]
276 element = eb.CreateTextRun(text)
277 if curWidth + int(element.GetTextLength() )< paraWidth{
278 writer.WriteElement(element)
279 curWidth = curWidth + int(element.GetTextLength())
280 }else{
281 writer.WriteElement(eb.CreateTextNewLine()) // new line
282 element = eb.CreateTextRun(text)
283 curWidth = int(element.GetTextLength())
284 writer.WriteElement(element)
285 }
286 textRun = textRunEnd + 1
287 }
288
289 // -----------------------------------------------------------------------
290 // The following code snippet illustrates how to adjust spacing between
291 // characters (text runs).
292 element = eb.CreateTextNewLine()
293 writer.WriteElement(element) // Skip 2 lines
294 writer.WriteElement(element)
295
296 writer.WriteElement(eb.CreateTextRun("An example of space adjustments between inter-characters:"))
297 writer.WriteElement(eb.CreateTextNewLine())
298
299 // Write string "AWAY" without space adjustments between characters.
300 element = eb.CreateTextRun("AWAY")
301 writer.WriteElement(element)
302
303 writer.WriteElement(eb.CreateTextNewLine())
304
305 // Write string "AWAY" with space adjustments between characters.
306 element = eb.CreateTextRun("A")
307 writer.WriteElement(element)
308
309 element = eb.CreateTextRun("W")
310 element.SetPosAdjustment(140)
311 writer.WriteElement(element)
312
313 element = eb.CreateTextRun("A")
314 element.SetPosAdjustment(140)
315 writer.WriteElement(element)
316
317 element = eb.CreateTextRun("Y again")
318 element.SetPosAdjustment(115)
319 writer.WriteElement(element)
320
321 // Draw the same strings using direct content output...
322 writer.Flush() // flush pending Element writing operations.
323
324 // You can also write page content directly to the content stream using
325 // ElementWriter.WriteString(...) and ElementWriter.WriteBuffer(...) methods.
326 // Note that if you are planning to use these functions you need to be familiar
327 // with PDF page content operators (see Appendix A in PDF Reference Manual).
328 // Because it is easy to make mistakes during direct output we recommend that
329 // you use ElementBuilder and Element interface instead.
330
331 writer.WriteString("T* T* ") // Skip 2 lines
332 writer.WriteString("(Direct output to PDF page content stream:) Tj T* ")
333 writer.WriteString("(AWAY) Tj T* ")
334 writer.WriteString("[(A)140(W)140(A)115(Y again)] TJ ")
335
336 // Finish the block of text
337 writer.WriteElement(eb.CreateTextEnd())
338
339 writer.End() // save changes to the current page
340 doc.PagePushBack(page)
341
342 // Start a new page ------------------------------------
343
344 // Image Masks
345 //
346 // In the opaque imaging model, images mark all areas they occupy on the page as
347 // if with opaque paint. All portions of the image, whether black, white, gray,
348 // or color, completely obscure any marks that may previously have existed in the
349 // same place on the page.
350 // In the graphic arts industry and page layout applications, however, it is common
351 // to crop or 'mask out' the background of an image and then place the masked image
352 // on a different background, allowing the existing background to show through the
353 // masked areas. This sample illustrates how to use image masks.
354
355 page = doc.PageCreate()
356 writer.Begin(page) // begin writing to the page
357
358 // Create the Image Mask
359 imgf := NewMappedFile(inputPath + "imagemask.dat")
360 maskRead := NewFilterReader(imgf)
361
362 deviceGray := ColorSpaceCreateDeviceGray()
363 mask := ImageCreate(doc.GetSDFDoc(), maskRead, 64, 64, 1, deviceGray, ImageE_ascii_hex)
364
365 mask.GetSDFObj().PutBool("ImageMask", true)
366
367 element = eb.CreateRect(0, 0, 612, 794)
368 element.SetPathStroke(false)
369 element.SetPathFill(true)
370 element.GetGState().SetFillColorSpace(deviceGray)
371 element.GetGState().SetFillColor(NewColorPt(0.8))
372 writer.WritePlacedElement(element)
373
374 element = eb.CreateImage(mask, NewMatrix2D(200.0, 0.0, 0.0, -200.0, 40.0, 680.0))
375 element.GetGState().SetFillColor(NewColorPt(0.1))
376 writer.WritePlacedElement(element)
377
378 element.GetGState().SetFillColorSpace(ColorSpaceCreateDeviceRGB())
379 element.GetGState().SetFillColor(NewColorPt(1.0, 0.0, 0.0))
380 element = eb.CreateImage(mask, NewMatrix2D(200.0, 0.0, 0.0, -200.0, 320.0, 680.0))
381 writer.WritePlacedElement(element)
382
383 element.GetGState().SetFillColor(NewColorPt(0.0, 1.0, 0.0))
384 element = eb.CreateImage(mask, NewMatrix2D(200.0, 0.0, 0.0, -200.0, 40.0, 380.0))
385 writer.WritePlacedElement(element)
386
387 // This sample illustrates Explicit Masking.
388 img = ImageCreate(doc.GetSDFDoc(), (inputPath + "peppers.jpg"))
389
390 // mask is the explicit mask for the primary (base) image
391 img.SetMask(mask)
392
393 element = eb.CreateImage(img, NewMatrix2D(200.0, 0.0, 0.0, -200.0, 320.0, 380.0))
394 writer.WritePlacedElement(element)
395
396 writer.End() // save changes to the current page
397 doc.PagePushBack(page)
398
399 // Transparency sample ----------------------------------
400
401 // Start a new page -------------------------------------
402 page = doc.PageCreate()
403 writer.Begin(page) // begin writing to this page
404 eb.Reset() // Reset the GState to default
405
406 // Write some transparent text at the bottom of the page.
407 element = eb.CreateTextBegin(FontCreate(doc.GetSDFDoc(), FontE_times_roman), 100.0)
408
409 // Set the text knockout attribute. Text knockout must be set outside of
410 // the text group.
411 gstate = element.GetGState()
412 gstate.SetTextKnockout(false)
413 gstate.SetBlendMode(GStateE_bl_difference)
414 writer.WriteElement(element)
415
416 element = eb.CreateTextRun("Transparency")
417 element.SetTextMatrix(1.0, 0.0, 0.0, 1.0, 30.0, 30.0)
418 gstate = element.GetGState()
419 gstate.SetFillColorSpace(ColorSpaceCreateDeviceCMYK())
420 gstate.SetFillColor(NewColorPt(1.0, 0.0, 0.0, 0.0))
421
422 gstate.SetFillOpacity(0.5)
423 writer.WriteElement(element)
424
425 // Write the same text on top the old; shifted by 3 points
426 element.SetTextMatrix(1.0, 0.0, 0.0, 1.0, 33.0, 33.0)
427 gstate.SetFillColor(NewColorPt(0.0, 1.0, 0.0, 0.0))
428 gstate.SetFillOpacity(0.5)
429
430 writer.WriteElement(element)
431 writer.WriteElement(eb.CreateTextEnd())
432
433 // Draw three overlapping transparent circles.
434 eb.PathBegin() // start constructing the path
435 eb.MoveTo(459.223, 505.646)
436 eb.CurveTo(459.223, 415.841, 389.85, 343.04, 304.273, 343.04)
437 eb.CurveTo(218.697, 343.04, 149.324, 415.841, 149.324, 505.646)
438 eb.CurveTo(149.324, 595.45, 218.697, 668.25, 304.273, 668.25)
439 eb.CurveTo(389.85, 668.25, 459.223, 595.45, 459.223, 505.646)
440 element = eb.PathEnd()
441 element.SetPathFill(true)
442
443 gstate = element.GetGState()
444 gstate.SetFillColorSpace(ColorSpaceCreateDeviceRGB())
445 gstate.SetFillColor(NewColorPt(0.0, 0.0, 1.0)) // Blue Circle
446
447 gstate.SetBlendMode(GStateE_bl_normal)
448 gstate.SetFillOpacity(0.5)
449 writer.WriteElement(element)
450
451 // Translate relative to the Blue Circle
452 gstate.SetTransform(1.0, 0.0, 0.0, 1.0, 113.0, -185.0)
453 gstate.SetFillColor(NewColorPt(0.0, 1.0, 0.0)) // Green Circle
454 gstate.SetFillOpacity(0.5)
455 writer.WriteElement(element)
456
457 // Translate relative to the Green Circle
458 gstate.SetTransform(1.0, 0.0, 0.0, 1.0, -220.0, 0.0)
459 gstate.SetFillColor(NewColorPt(1.0, 0.0, 0.0)) // Red Circle
460 gstate.SetFillOpacity(0.5)
461 writer.WriteElement(element)
462
463 writer.End() // save changes to the current page
464 doc.PagePushBack(page)
465
466 // End page ------------------------------------
467
468 doc.Save((outputPath + "element_builder.pdf"), uint(SDFDocE_remove_unused))
469 doc.Close()
470 PDFNetTerminate()
471 fmt.Println("Done. Result saved in element_builder.pdf...")
472}
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}
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6#include <SDF/Obj.h>
7#include <PDF/PDFNet.h>
8#include <PDF/PDFDoc.h>
9#include <PDF/ElementBuilder.h>
10#include <PDF/ElementWriter.h>
11#include <PDF/ElementReader.h>
12
13#include <Filters/MappedFile.h>
14#include <Filters/FilterReader.h>
15
16#include <SDF/SDFDoc.h>
17#include <iostream>
18#include "../../LicenseKey/CPP/LicenseKey.h"
19
20using namespace std;
21using namespace pdftron;
22using namespace SDF;
23using namespace PDF;
24using namespace Filters;
25
26int main(int argc, char *argv[])
27{
28 int ret = 0;
29 PDFNet::Initialize(LicenseKey);
30
31 // Relative path to the folder containing test files.
32 string input_path = "../../TestFiles/";
33 string output_path = "../../TestFiles/Output/";
34
35 try
36 {
37 PDFDoc doc;
38
39 ElementBuilder eb; // ElementBuilder is used to build new Element objects
40 ElementWriter writer; // ElementWriter is used to write Elements to the page
41
42 Element element;
43 GState gstate;
44
45 // Start a new page ------------------------------------
46 Page page = doc.PageCreate(Rect(0, 0, 612, 794));
47
48 writer.Begin(page); // begin writing to the page
49
50 // Create an Image that can be reused in the document or on the same page.
51 Image img = Image::Create(doc, (input_path + "peppers.jpg").c_str());
52
53 element = eb.CreateImage(img, Common::Matrix2D(img.GetImageWidth()/2, -145, 20, img.GetImageHeight()/2, 200, 150));
54 writer.WritePlacedElement(element);
55
56 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(Rect(0, 0, 612, 794));
69
70 writer.Begin(page); // begin writing to this page
71 eb.Reset(); // Reset the 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(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(ColorPt(0, 0, 1, 0)); // yellow
91 gstate.SetStrokeColorSpace(ColorSpace::CreateDeviceRGB());
92 gstate.SetStrokeColor(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(ColorPt(0, 0, 1)); // blue
100 gstate.SetTransform(0.5, 0, 0, 0.5, 280, 0);
101 vector<double> dash_pattern;
102 dash_pattern.push_back(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 the 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 constructed
116 element.SetPathClip(true); // this path is a clipping path
117 element.SetPathStroke(true); // this path should be filled and stroked
118 gstate = element.GetGState();
119 gstate.SetTransform(0.5, 0, 0, 0.5, -20, 0);
120
121 writer.WriteElement(element);
122
123 writer.WriteElement(eb.CreateImage(img, 100, 300, 400, 600));
124
125 writer.WriteElement(eb.CreateGroupEnd()); // Restore the graphics state
126
127 writer.End(); // save changes to the current page
128 doc.PagePushBack(page);
129
130
131 // Start a new page ------------------------------------
132 page = doc.PageCreate(Rect(0, 0, 612, 794));
133
134 writer.Begin(page); // begin writing to this page
135 eb.Reset(); // Reset the GState to default
136
137 // Begin writing a block of text
138 element = eb.CreateTextBegin(Font::Create(doc, Font::e_times_roman), 12);
139 writer.WriteElement(element);
140
141 element = eb.CreateTextRun("Hello World!");
142 element.SetTextMatrix(10, 0, 0, 10, 0, 600);
143 element.GetGState().SetLeading(15); // Set the spacing between lines
144 writer.WriteElement(element);
145
146 writer.WriteElement(eb.CreateTextNewLine()); // New line
147
148 element = eb.CreateTextRun("Hello World!");
149 gstate = element.GetGState();
150 gstate.SetTextRenderMode(GState::e_stroke_text);
151 gstate.SetCharSpacing(-1.25);
152 gstate.SetWordSpacing(-1.25);
153 writer.WriteElement(element);
154
155 writer.WriteElement(eb.CreateTextNewLine()); // New line
156
157 element = eb.CreateTextRun("Hello World!");
158 gstate = element.GetGState();
159 gstate.SetCharSpacing(0);
160 gstate.SetWordSpacing(0);
161 gstate.SetLineWidth(3);
162 gstate.SetTextRenderMode(GState::e_fill_stroke_text);
163 gstate.SetStrokeColorSpace(ColorSpace::CreateDeviceRGB());
164 gstate.SetStrokeColor(ColorPt(1, 0, 0)); // red
165 gstate.SetFillColorSpace(ColorSpace::CreateDeviceCMYK());
166 gstate.SetFillColor(ColorPt(1, 0, 0, 0)); // cyan
167 writer.WriteElement(element);
168
169
170 writer.WriteElement(eb.CreateTextNewLine()); // New line
171
172 // Set text as a clipping path to the image.
173 element = eb.CreateTextRun("Hello World!");
174 gstate = element.GetGState();
175 gstate.SetTextRenderMode(GState::e_clip_text);
176 writer.WriteElement(element);
177
178 // Finish the block of text
179 writer.WriteElement(eb.CreateTextEnd());
180
181 // Draw an image that will be clipped by the above text
182 writer.WriteElement(eb.CreateImage(img, 10, 100, 1300, 720));
183
184 writer.End(); // save changes to the current page
185 doc.PagePushBack(page);
186
187 // Start a new page ------------------------------------
188 //
189 // The example illustrates how to embed the external font in a PDF document.
190 // The example also shows how ElementReader can be used to copy and modify
191 // Elements between pages.
192
193 ElementReader reader;
194
195 // Start reading Elements from the last page. We will copy all Elements to
196 // a new page but will modify the font associated with text.
197 reader.Begin(doc.GetPage(doc.GetPageCount()));
198
199 page = doc.PageCreate(Rect(0, 0, 1300, 794));
200
201 writer.Begin(page); // begin writing to this page
202 eb.Reset(); // Reset the GState to default
203
204 // Embed an external font in the document.
205 Font font = Font::CreateTrueTypeFont(doc, (input_path + "font.ttf").c_str());
206
207 while ((element = reader.Next())==true) // Read page contents
208 {
209 if (element.GetType() == Element::e_text)
210 {
211 element.GetGState().SetFont(font, 12);
212 }
213
214 writer.WriteElement(element);
215 }
216
217 reader.End();
218 writer.End(); // save changes to the current page
219
220 doc.PagePushBack(page);
221
222
223 // Start a new page ------------------------------------
224 //
225 // The example illustrates how to embed the external font in a PDF document.
226 // The example also shows how ElementReader can be used to copy and modify
227 // Elements between pages.
228
229 // Start reading Elements from the last page. We will copy all Elements to
230 // a new page but will modify the font associated with text.
231 reader.Begin(doc.GetPage(doc.GetPageCount()));
232
233 page = doc.PageCreate(Rect(0, 0, 1300, 794));
234
235 writer.Begin(page); // begin writing to this page
236 eb.Reset(); // Reset the GState to default
237
238 // Embed an external font in the document.
239 Font font2 = Font::CreateType1Font(doc, (input_path + "Misc-Fixed.pfa").c_str());
240
241 while ((element = reader.Next())) // Read page contents
242 {
243 if (element.GetType() == Element::e_text)
244 {
245 element.GetGState().SetFont(font2, 12);
246 }
247
248 writer.WriteElement(element);
249 }
250
251 reader.End();
252 writer.End(); // save changes to the current page
253 doc.PagePushBack(page);
254
255
256 // Start a new page ------------------------------------
257 page = doc.PageCreate();
258 writer.Begin(page); // begin writing to this page
259 eb.Reset(); // Reset the GState to default
260
261 // Begin writing a block of text
262 element = eb.CreateTextBegin(Font::Create(doc, Font::e_times_roman), 12);
263 element.SetTextMatrix(1.5, 0, 0, 1.5, 50, 600);
264 element.GetGState().SetLeading(15); // Set the spacing between lines
265 writer.WriteElement(element);
266
267 const char* para = "A PDF text object consists of operators that can show "
268 "text strings, move the text position, and set text state and certain "
269 "other parameters. In addition, there are three parameters that are "
270 "defined only within a text object and do not persist from one text "
271 "object to the next: Tm, the text matrix, Tlm, the text line matrix, "
272 "Trm, the text rendering matrix, actually just an intermediate result "
273 "that combines the effects of text state parameters, the text matrix "
274 "(Tm), and the current transformation matrix";
275
276 const char* para_end = para + strlen(para);
277 const char* text_run = para;
278 const char* text_run_end;
279
280 double para_width = 300; // paragraph width is 300 units
281 double cur_width = 0;
282
283 while (text_run < para_end)
284 {
285 text_run_end = strchr(text_run, ' ');
286 if (!text_run_end) text_run_end = para_end;
287
288 element = eb.CreateTextRun(text_run, UInt32(text_run_end-text_run+1));
289 if (cur_width + element.GetTextLength() < para_width)
290 {
291 writer.WriteElement(element);
292 cur_width += element.GetTextLength();
293 }
294 else
295 {
296 writer.WriteElement(eb.CreateTextNewLine()); // New line
297 element = eb.CreateTextRun(text_run, UInt32(text_run_end-text_run+1));
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
347 writer.WriteString("T* T* "); // Skip 2 lines
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(input_path + "imagemask.dat");
376 FilterReader mask_read(imgf);
377
378 ColorSpace device_gray = ColorSpace::CreateDeviceGray();
379 Image mask = Image::Create(doc, mask_read, 64, 64, 1, device_gray, Image::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(ColorPt(0.8));
388 writer.WritePlacedElement(element);
389
390 element = eb.CreateImage(mask, Common::Matrix2D(200, 0, 0, -200, 40, 680));
391 element.GetGState().SetFillColor(ColorPt(0.1));
392 writer.WritePlacedElement(element);
393
394 element.GetGState().SetFillColorSpace(ColorSpace::CreateDeviceRGB());
395 element.GetGState().SetFillColor(ColorPt(1, 0, 0));
396 element = eb.CreateImage(mask, Common::Matrix2D(200, 0, 0, -200, 320, 680));
397 writer.WritePlacedElement(element);
398
399 element.GetGState().SetFillColor(ColorPt(0, 1, 0));
400 element = eb.CreateImage(mask, Common::Matrix2D(200, 0, 0, -200, 40, 380));
401 writer.WritePlacedElement(element);
402
403 {
404 // This sample illustrates Explicit Masking.
405 Image img = Image::Create(doc, (input_path + "peppers.jpg").c_str());
406
407 // mask is the explicit mask for the primary (base) image
408 img.SetMask(mask);
409
410 element = eb.CreateImage(img, Common::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::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::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(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(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(ColorPt(0, 0, 1)); // Blue Circle
464
465 gstate.SetBlendMode(GState::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(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(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 doc.Save((output_path + "element_builder.pdf").c_str(), SDFDoc::e_remove_unused, NULL);
487 // doc.Save((output_path + "element_builder.pdf").c_str(), Doc::e_linearized, NULL);
488 cout << "Done. Result saved in element_builder.pdf..." << endl;
489 }
490 catch(Common::Exception& e)
491 {
492 cout << e << endl;
493 ret = 1;
494 }
495 catch(...)
496 {
497 cout << "Unknown Exception" << endl;
498 ret = 1;
499 }
500
501 PDFNet::Terminate();
502 return ret;
503}
1<?php
2#---------------------------------------------------------------------------------------
3# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
4# Consult LICENSE.txt regarding license information.
5#---------------------------------------------------------------------------------------
6if(file_exists("../../../PDFNetC/Lib/PDFNetPHP.php"))
7include("../../../PDFNetC/Lib/PDFNetPHP.php");
8include("../../LicenseKey/PHP/LicenseKey.php");
9
10# This sample illustrates how to edit existing text strings.
11
12# Relative path to the folder containing the test files.
13$input_path = getcwd()."/../../TestFiles/";
14$output_path = $input_path."Output/";
15
16 PDFNet::Initialize($LicenseKey);
17 PDFNet::GetSystemFontList(); // Wait for fonts to be loaded if they haven't already. This is done because PHP can run into errors when shutting down if font loading is still in progress.
18 $doc = new PDFDoc();
19 $builder = new ElementBuilder(); // ElementBuilder is used to build new Element objects
20 $writer = new ElementWriter(); // ElementWriter is used to write Elements to the page
21
22 // Start a new page ------------------------------------
23 $page = $doc->PageCreate(new Rect(0.0, 0.0, 612.0, 794.0));
24
25 $writer->Begin($page); // begin writing to the page
26
27 // Create an Image that can be reused in the document or on the same page.
28 $img = Image::Create($doc->GetSDFDoc(), $input_path."peppers.jpg");
29
30 $element = $builder->CreateImage($img, new Matrix2D((double)($img->GetImageWidth()/2), -145.0, 20.0, (double)($img->GetImageHeight()/2), 200.0, 150.0));
31 $writer->WritePlacedElement($element);
32 $gstate = $element->GetGState(); // use the same image (just change its matrix)
33 $gstate->SetTransform(200.0, 0.0, 0.0, 300.0, 50.0, 450.0);
34 $writer->WritePlacedElement($element);
35
36 // use the same image again (just change its matrix).
37 $writer->WritePlacedElement($builder->CreateImage($img, 300.0, 600.0, 200.0, -150.0));
38
39 $writer->End(); // save changes to the current page
40 $doc->PagePushBack($page);
41
42 // Start a new page ------------------------------------
43 // Construct and draw a path object using different styles
44 $page = $doc->PageCreate(new Rect(0.0, 0.0, 612.0, 794.0));
45
46 $writer->Begin($page); // begin writing to this page
47 $builder->Reset(); // Reset the GState to default
48
49 $builder->PathBegin(); // start constructing the path
50 $builder->MoveTo(306, 396);
51 $builder->CurveTo(681, 771, 399.75, 864.75, 306, 771);
52 $builder->CurveTo(212.25, 864.75, -69, 771, 306, 396);
53 $builder->ClosePath();
54 $element = $builder->PathEnd(); // the path is now finished
55 $element->SetPathFill(true); // the path should be filled
56
57 // Set the path color space and color
58 $gstate = $element->GetGState();
59 $gstate->SetFillColorSpace(ColorSpace::CreateDeviceCMYK());
60 $gstate->SetFillColor(new ColorPt(1.0, 0.0, 0.0, 0.0)); // cyan
61 $gstate->SetTransform(0.5, 0.0, 0.0, 0.5, -20.0, 300.0);
62 $writer->WritePlacedElement($element);
63
64 // Draw the same path using a different stroke color
65 $element->SetPathStroke(true); // this path is should be filled and stroked
66 $gstate->SetFillColor(new ColorPt(0.0, 0.0, 1.0, 0.0)); // yellow
67 $gstate->SetStrokeColorSpace(ColorSpace::CreateDeviceRGB());
68 $gstate->SetStrokeColor(new ColorPt(1.0, 0.0, 0.0)); // red
69 $gstate->SetTransform(0.5, 0.0, 0.0, 0.5, 280.0, 300.0);
70 $gstate->SetLineWidth(20.0);
71 $writer->WritePlacedElement($element);
72
73 // Draw the same path with with a given dash pattern
74 $element->SetPathFill(false); // this path is should be only stroked
75
76 $gstate->SetStrokeColor(new ColorPt(0.0, 0.0, 1.0)); // blue
77 $gstate->SetTransform(0.5, 0.0, 0.0, 0.5, 280.0, 0.0);
78 $gstate->SetDashPattern(array(30.0), 0);
79 $writer->WritePlacedElement($element);
80
81 // Use the path as a clipping path
82 $writer->WriteElement($builder->CreateGroupBegin()); // Save the graphics state
83 // Start constructing the new path (the old path was lost when we created
84 // a new Element using CreateGroupBegin()).
85 $builder->PathBegin();
86 $builder->MoveTo(306, 396);
87 $builder->CurveTo(681, 771, 399.75, 864.75, 306, 771);
88 $builder->CurveTo(212.25, 864.75, -69, 771, 306, 396);
89 $builder->ClosePath();
90 $element = $builder->PathEnd(); // path is now constructed
91 $element->SetPathClip(true); // this path is a clipping path
92 $element->SetPathStroke(true); // this path should be filled and stroked
93 $gstate = $element->GetGState();
94 $gstate->SetTransform(0.5, 0.0, 0.0, 0.5, -20.0, 0.0);
95
96 $writer->WriteElement($element);
97
98 $writer->WriteElement($builder->CreateImage($img, 100.0, 300.0, 400.0, 600.0));
99
100 $writer->WriteElement($builder->CreateGroupEnd()); // Restore the graphics state
101
102 $writer->End(); // save changes to the current page
103 $doc->PagePushBack($page);
104
105 // Start a new page ------------------------------------
106 $page = $doc->PageCreate(new Rect(0.0, 0.0, 612.0, 794.0));
107
108 $writer->Begin($page); // begin writing to this page
109 $builder->Reset(); // Reset the GState to default
110
111 // Begin writing a block of text
112 $element = $builder->CreateTextBegin(Font::Create($doc->GetSDFDoc(), Font::e_times_roman), 12.0);
113 $writer->WriteElement($element);
114
115 $element = $builder->CreateTextRun("Hello World!");
116 $element->SetTextMatrix(10.0, 0.0, 0.0, 10.0, 0.0, 600.0);
117 $element->GetGState()->SetLeading(15); // Set the spacing between lines
118 $writer->WriteElement($element);
119
120 $writer->WriteElement($builder->CreateTextNewLine()); // New line
121
122 $element = $builder->CreateTextRun("Hello World!");
123 $gstate = $element->GetGState();
124 $gstate->SetTextRenderMode(GState::e_stroke_text);
125 $gstate->SetCharSpacing(-1.25);
126 $gstate->SetWordSpacing(-1.25);
127 $writer->WriteElement($element);
128
129 $writer->WriteElement($builder->CreateTextNewLine()); // New line
130
131 $element = $builder->CreateTextRun("Hello World!");
132 $gstate = $element->GetGState();
133 $gstate->SetCharSpacing(0);
134 $gstate->SetWordSpacing(0);
135 $gstate->SetLineWidth(3);
136 $gstate->SetTextRenderMode(GState::e_fill_stroke_text);
137 $gstate->SetStrokeColorSpace(ColorSpace::CreateDeviceRGB());
138 $gstate->SetStrokeColor(new ColorPt(1.0, 0.0, 0.0)); // red
139 $gstate->SetFillColorSpace(ColorSpace::CreateDeviceCMYK());
140 $gstate->SetFillColor(new ColorPt(1.0, 0.0, 0.0, 0.0)); // cyan
141 $writer->WriteElement($element);
142
143 $writer->WriteElement($builder->CreateTextNewLine()); // New line
144
145 // Set text as a clipping path to the image.
146 $element = $builder->CreateTextRun("Hello World!");
147 $gstate = $element->GetGState();
148 $gstate->SetTextRenderMode(GState::e_clip_text);
149 $writer->WriteElement($element);
150
151 // Finish the block of text
152 $writer->WriteElement($builder->CreateTextEnd());
153
154 // Draw an image that will be clipped by the above text
155 $writer->WriteElement($builder->CreateImage($img, 10.0, 100.0, 1300.0, 720.0));
156
157 $writer->End(); // save changes to the current page
158 $doc->PagePushBack($page);
159
160 // Start a new page ------------------------------------
161 //
162 // The example illustrates how to embed the external font in a PDF document.
163 // The example also shows how ElementReader can be used to copy and modify
164 // Elements between pages.
165
166 $reader = new ElementReader();
167
168 // Start reading Elements from the last page. We will copy all Elements to
169 // a new page but will modify the font associated with text.
170 $reader->Begin($doc->GetPage($doc->GetPageCount()));
171
172 $page = $doc->PageCreate(new Rect(0.0, 0.0, 1300.0, 794.0));
173
174 $writer->Begin($page); // begin writing to this page
175 $builder->Reset(); // Reset the GState to default
176
177 // Embed an external font in the document.
178 $font = Font::CreateTrueTypeFont($doc->GetSDFDoc(), $input_path."font.ttf");
179
180 while (($element = $reader->Next()) != null) // Read page contents
181 {
182 if ($element->GetType() == Element::e_text)
183 {
184 $element->GetGState()->SetFont($font, 12);
185 }
186 $writer->WriteElement($element);
187 }
188
189 $reader->End();
190 $writer->End(); // save changes to the current page
191
192 $doc->PagePushBack($page);
193
194
195 // Start a new page ------------------------------------
196 //
197 // The example illustrates how to embed the external font in a PDF document.
198 // The example also shows how ElementReader can be used to copy and modify
199 // Elements between pages.
200
201 // Start reading Elements from the last page. We will copy all Elements to
202 // a new page but will modify the font associated with text.
203 $reader->Begin($doc->GetPage($doc->GetPageCount()));
204
205 $page = $doc->PageCreate(new Rect(0.0, 0.0, 1300.0, 794.0));
206
207 $writer->Begin($page); // begin writing to this page
208 $builder->Reset(); // Reset the GState to default
209
210 // Embed an external font in the document.
211 $font2 = Font::CreateType1Font($doc->GetSDFDoc(), $input_path."Misc-Fixed.pfa");
212
213 while (($element = $reader->Next())) // Read page contents
214 {
215 if ($element->GetType() == Element::e_text)
216 {
217 $element->GetGState()->SetFont($font2, 12);
218 }
219
220 $writer->WriteElement($element);
221 }
222
223 $reader->End();
224 $writer->End(); // save changes to the current page
225 $doc->PagePushBack($page);
226
227 // Start a new page ------------------------------------
228 $page = $doc->PageCreate();
229 $writer->Begin($page); // begin writing to this page
230 $builder->Reset(); // Reset the GState to default
231
232 // Begin writing a block of text
233 $element = $builder->CreateTextBegin(Font::Create($doc->GetSDFDoc(), Font::e_times_roman), 12.0);
234 $element->SetTextMatrix(1.5, 0.0, 0.0, 1.5, 50.0, 600.0);
235 $element->GetGState()->SetLeading(15); // Set the spacing between lines
236 $writer->WriteElement($element);
237
238 $para = "A PDF text object consists of operators that can show ".
239 "text strings, move the text position, and set text state and certain ".
240 "other parameters. In addition, there are three parameters that are ".
241 "defined only within a text object and do not persist from one text ".
242 "object to the next: Tm, the text matrix, Tlm, the text line matrix, ".
243 "Trm, the text rendering matrix, actually just an intermediate result ".
244 "that combines the effects of text state parameters, the text matrix ".
245 "(Tm), and the current transformation matrix";
246
247 $para_end = strlen($para);
248 $text_run = 0;
249
250 $para_width = 300;
251 $cur_width = 0;
252
253 while ($text_run < $para_end)
254 {
255 $text_run_end = strpos($para, ' ', $text_run);
256 if (!$text_run_end) $text_run_end = $para_end;
257
258 $text = substr($para, $text_run, $text_run_end-$text_run+1);
259 $element = $builder->CreateTextRun($text);
260 if ($cur_width + $element->GetTextLength() < $para_width)
261 {
262 $writer->WriteElement($element);
263 $cur_width += $element->GetTextLength();
264 }
265 else
266 {
267 $writer->WriteElement($builder->CreateTextNewLine()); // New line
268 $element = $builder->CreateTextRun($text);
269 $cur_width = $element->GetTextLength();
270 $writer->WriteElement($element);
271 }
272
273 $text_run = $text_run_end+1;
274 }
275
276 // -----------------------------------------------------------------------
277 // The following code snippet illustrates how to adjust spacing between
278 // characters (text runs).
279 $element = $builder->CreateTextNewLine();
280 $writer->WriteElement($element); // Skip 2 lines
281 $writer->WriteElement($element);
282
283 $writer->WriteElement($builder->CreateTextRun("An example of space adjustments between inter-characters:"));
284 $writer->WriteElement($builder->CreateTextNewLine());
285
286 // Write string "AWAY" without space adjustments between characters.
287 $element = $builder->CreateTextRun("AWAY");
288 $writer->WriteElement($element);
289
290 $writer->WriteElement($builder->CreateTextNewLine());
291
292 // Write string "AWAY" with space adjustments between characters.
293 $element = $builder->CreateTextRun("A");
294 $writer->WriteElement($element);
295
296 $element = $builder->CreateTextRun("W");
297 $element->SetPosAdjustment(140);
298 $writer->WriteElement($element);
299
300 $element = $builder->CreateTextRun("A");
301 $element->SetPosAdjustment(140);
302 $writer->WriteElement($element);
303
304 $element = $builder->CreateTextRun("Y again");
305 $element->SetPosAdjustment(115);
306 $writer->WriteElement($element);
307
308 // Draw the same strings using direct content output...
309 $writer->Flush(); // flush pending Element writing operations.
310
311 // You can also write page content directly to the content stream using
312 // ElementWriter.WriteString(...) and ElementWriter.WriteBuffer(...) methods.
313 // Note that if you are planning to use these functions you need to be familiar
314 // with PDF page content operators (see Appendix A in PDF Reference Manual).
315 // Because it is easy to make mistakes during direct output we recommend that
316 // you use ElementBuilder and Element interface instead.
317
318 $writer->WriteString("T* T* "); // Skip 2 lines
319 $writer->WriteString("(Direct output to PDF page content stream:) Tj T* ");
320 $writer->WriteString("(AWAY) Tj T* ");
321 $writer->WriteString("[(A)140(W)140(A)115(Y again)] TJ ");
322
323 // Finish the block of text
324 $writer->WriteElement($builder->CreateTextEnd());
325
326 $writer->End(); // save changes to the current page
327 $doc->PagePushBack($page);
328
329 // Start a new page ------------------------------------
330
331 // Image Masks
332 //
333 // In the opaque imaging model, images mark all areas they occupy on the page as
334 // if with opaque paint. All portions of the image, whether black, white, gray,
335 // or color, completely obscure any marks that may previously have existed in the
336 // same place on the page.
337 // In the graphic arts industry and page layout applications, however, it is common
338 // to crop or 'mask out' the background of an image and then place the masked image
339 // on a different background, allowing the existing background to show through the
340 // masked areas. This sample illustrates how to use image masks.
341
342 $page = $doc->PageCreate();
343 $writer->Begin($page); // begin writing to the page
344
345 // Create the Image Mask
346 $imgf = new MappedFile($input_path."imagemask.dat");
347 $mask_read = new FilterReader($imgf);
348
349 $device_gray = ColorSpace::CreateDeviceGray();
350 $mask = Image::Create($doc->GetSDFDoc(), $mask_read, 64, 64, 1, $device_gray, Image::e_ascii_hex);
351
352 $mask->GetSDFObj()->PutBool("ImageMask", true);
353
354 $element = $builder->CreateRect(0, 0, 612, 794);
355 $element->SetPathStroke(false);
356 $element->SetPathFill(true);
357 $element->GetGState()->SetFillColorSpace($device_gray);
358 $element->GetGState()->SetFillColor(new ColorPt(0.8));
359 $writer->WritePlacedElement($element);
360
361 $element = $builder->CreateImage($mask, new Matrix2D(200.0, 0.0, 0.0, -200.0, 40.0, 680.0));
362 $element->GetGState()->SetFillColor(new ColorPt(0.1));
363 $writer->WritePlacedElement($element);
364
365 $element->GetGState()->SetFillColorSpace(ColorSpace::CreateDeviceRGB());
366 $element->GetGState()->SetFillColor(new ColorPt(1.0, 0.0, 0.0));
367 $element = $builder->CreateImage($mask, new Matrix2D(200.0, 0.0, 0.0, -200.0, 320.0, 680.0));
368 $writer->WritePlacedElement($element);
369
370 $element->GetGState()->SetFillColor(new ColorPt(0.0, 1.0, 0.0));
371 $element = $builder->CreateImage($mask, new Matrix2D(200.0, 0.0, 0.0, -200.0, 40.0, 380.0));
372 $writer->WritePlacedElement($element);
373
374 // This sample illustrates Explicit Masking.
375 $img = Image::Create($doc->GetSDFDoc(), $input_path."peppers.jpg");
376
377 // mask is the explicit mask for the primary (base) image
378 $img->SetMask($mask);
379
380 $element = $builder->CreateImage($img, new Matrix2D(200.0, 0.0, 0.0, -200.0, 320.0, 380.0));
381 $writer->WritePlacedElement($element);
382
383 $writer->End(); // save changes to the current page
384 $doc->PagePushBack($page);
385
386 // Transparency sample ----------------------------------
387
388 // Start a new page -------------------------------------
389 $page = $doc->PageCreate();
390 $writer->Begin($page); // begin writing to this page
391 $builder->Reset(); // Reset the GState to default
392
393 // Write some transparent text at the bottom of the page.
394 $element = $builder->CreateTextBegin(Font::Create($doc->GetSDFDoc(), Font::e_times_roman), 100.0);
395
396 // Set the text knockout attribute. Text knockout must be set outside of
397 // the text group.
398 $gstate = $element->GetGState();
399 $gstate->SetTextKnockout(false);
400 $gstate->SetBlendMode(GState::e_bl_difference);
401 $writer->WriteElement($element);
402
403 $element = $builder->CreateTextRun("Transparency");
404 $element->SetTextMatrix(1.0, 0.0, 0.0, 1.0, 30.0, 30.0);
405 $gstate = $element->GetGState();
406 $gstate->SetFillColorSpace(ColorSpace::CreateDeviceCMYK());
407 $gstate->SetFillColor(new ColorPt(1.0, 0.0, 0.0, 0.0));
408
409 $gstate->SetFillOpacity(0.5);
410 $writer->WriteElement($element);
411
412 // Write the same text on top the old; shifted by 3 points
413 $element->SetTextMatrix(1.0, 0.0, 0.0, 1.0, 33.0, 33.0);
414 $gstate->SetFillColor(new ColorPt(0.0, 1.0, 0.0, 0.0));
415 $gstate->SetFillOpacity(0.5);
416
417 $writer->WriteElement($element);
418 $writer->WriteElement($builder->CreateTextEnd());
419
420 // Draw three overlapping transparent circles.
421 $builder->PathBegin(); // start constructing the path
422 $builder->MoveTo(459.223, 505.646);
423 $builder->CurveTo(459.223, 415.841, 389.85, 343.04, 304.273, 343.04);
424 $builder->CurveTo(218.697, 343.04, 149.324, 415.841, 149.324, 505.646);
425 $builder->CurveTo(149.324, 595.45, 218.697, 668.25, 304.273, 668.25);
426 $builder->CurveTo(389.85, 668.25, 459.223, 595.45, 459.223, 505.646);
427 $element = $builder->PathEnd();
428 $element->SetPathFill(true);
429
430 $gstate = $element->GetGState();
431 $gstate->SetFillColorSpace(ColorSpace::CreateDeviceRGB());
432 $gstate->SetFillColor(new ColorPt(0.0, 0.0, 1.0));
433
434 $gstate->SetBlendMode(GState::e_bl_normal);
435 $gstate->SetFillOpacity(0.5);
436 $writer->WriteElement($element);
437
438 // Translate relative to the Blue Circle
439 $gstate->SetTransform(1.0, 0.0, 0.0, 1.0, 113.0, -185.0);
440 $gstate->SetFillColor(new ColorPt(0.0, 1.0, 0.0)); // Green Circle
441 $gstate->SetFillOpacity(0.5);
442 $writer->WriteElement($element);
443
444 // Translate relative to the Green Circle
445 $gstate->SetTransform(1.0, 0.0, 0.0, 1.0, -220.0, 0.0);
446 $gstate->SetFillColor(new ColorPt(1.0, 0.0, 0.0)); // Red Circle
447 $gstate->SetFillOpacity(0.5);
448 $writer->WriteElement($element);
449
450 $writer->End(); // save changes to the current page
451 $doc->PagePushBack($page);
452
453 // End page ------------------------------------
454
455 $doc->Save($output_path."element_builder.pdf", SDFDoc::e_remove_unused);
456 PDFNet::Terminate();
457 echo "Done. Result saved in element_builder.pdf...\n";
458?>
1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6const { PDFNet } = require('@pdftron/pdfnet-node');
7const PDFTronLicense = require('../LicenseKey/LicenseKey');
8
9((exports) => {
10
11 exports.runElementBuilderTest = () => {
12
13 const main = async() => {
14 let ret = 0;
15
16 // Relative path to the folder containing test files.
17 const inputPath = '../TestFiles/';
18
19 try {
20 const doc = await PDFNet.PDFDoc.create();
21
22 // ElementBuilder is used to build new Element objects
23 const eb = await PDFNet.ElementBuilder.create();
24 // ElementWriter is used to write Elements to the page
25 const writer = await PDFNet.ElementWriter.create();
26
27 let element;
28 let gstate;
29
30 // Start a new page ------------------------------------
31
32 const pageRect = await PDFNet.Rect.init(0, 0, 612, 794);
33 let page = await doc.pageCreate(pageRect);
34
35 // begin writing to the page
36 writer.beginOnPage(page);
37
38 // Create an Image that can be reused in the document or on the same page.
39 const img = await PDFNet.Image.createFromFile(doc, inputPath + 'peppers.jpg');
40
41 element = await eb.createImageFromMatrix(img, await PDFNet.Matrix2D.create((await img.getImageWidth()) / 2, -145, 20, (await img.getImageHeight()) / 2, 200, 150));
42 writer.writePlacedElement(element);
43
44 // use the same image (just change its matrix)
45 gstate = await element.getGState();
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(await eb.createImageScaled(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 = await doc.pageCreate(pageRect);
58
59 // begin writing to this page
60 writer.beginOnPage(page);
61 // Reset the GState to default
62 eb.reset();
63
64 // start constructing the path
65 eb.pathBegin();
66 eb.moveTo(306, 396);
67 eb.curveTo(681, 771, 399.75, 864.75, 306, 771);
68 eb.curveTo(212.25, 864.75, -69, 771, 306, 396);
69 eb.closePath();
70 // the path is now finished
71 element = await eb.pathEnd();
72 // the path should be filled
73 element.setPathFill(true);
74
75 // Set the path color space and color
76 gstate = await element.getGState();
77 gstate.setFillColorSpace(await PDFNet.ColorSpace.createDeviceCMYK());
78 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(1, 0, 0, 0)); // cyan
79 gstate.setTransform(0.5, 0, 0, 0.5, -20, 300);
80 writer.writePlacedElement(element);
81
82 // Draw the same path using a different stroke color
83 // this path is should be filled and stroked
84 element.setPathStroke(true);
85 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(0, 0, 1, 0)); // yellow
86 gstate.setStrokeColorSpace(await PDFNet.ColorSpace.createDeviceRGB());
87 gstate.setStrokeColorWithColorPt(await PDFNet.ColorPt.init(1, 0, 0)); // red
88 gstate.setTransform(0.5, 0, 0, 0.5, 280, 300);
89 gstate.setLineWidth(20);
90 writer.writePlacedElement(element);
91
92 // Draw the same path with with a given dash pattern
93 // this path is should be only stroked
94 element.setPathFill(false);
95 gstate.setStrokeColorWithColorPt(await PDFNet.ColorPt.init(0, 0, 1)); // blue
96 gstate.setTransform(0.5, 0, 0, 0.5, 280, 0);
97 const dashPattern = [];
98 dashPattern.push(30);
99 gstate.setDashPattern(dashPattern, 0);
100 writer.writePlacedElement(element);
101
102 // Use the path as a clipping path
103 // Save the graphics state
104 writer.writeElement(await eb.createGroupBegin());
105 // Start constructing the new path (the old path was lost when we created
106 // a new Element using CreateGroupBegin()).
107 eb.pathBegin();
108 eb.moveTo(306, 396);
109 eb.curveTo(681, 771, 399.75, 864.75, 306, 771);
110 eb.curveTo(212.25, 864.75, -69, 771, 306, 396);
111 eb.closePath();
112 // path is now constructed
113 element = await eb.pathEnd();
114 // this path is a clipping path
115 element.setPathClip(true);
116 // this path should be filled and stroked
117 element.setPathStroke(true);
118 gstate = await element.getGState();
119 gstate.setTransform(0.5, 0, 0, 0.5, -20, 0);
120
121 writer.writeElement(element);
122
123 writer.writeElement(await eb.createImageScaled(img, 100, 300, 400, 600));
124
125 // Restore the graphics state
126 writer.writeElement(await eb.createGroupEnd());
127
128 writer.end(); // save changes to the current page
129 doc.pagePushBack(page);
130
131
132 // Start a new page ------------------------------------
133 page = await doc.pageCreate(pageRect);
134
135 // begin writing to this page
136 writer.beginOnPage(page);
137 // Reset the GState to default
138 eb.reset();
139
140 // Begin writing a block of text
141 element = await eb.createTextBeginWithFont(await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_times_roman), 12);
142 writer.writeElement(element);
143
144 element = await eb.createNewTextRun('Hello World!');
145 element.setTextMatrixEntries(10, 0, 0, 10, 0, 600);
146 gstate = await element.getGState();
147 // Set the spacing between lines
148 gstate.setLeading(15);
149 writer.writeElement(element);
150
151 writer.writeElement(await eb.createTextNewLine()); // New line
152
153 element = await eb.createNewTextRun('Hello World!');
154 gstate = await element.getGState();
155 gstate.setTextRenderMode(PDFNet.GState.TextRenderingMode.e_stroke_text);
156 gstate.setCharSpacing(-1.25);
157 gstate.setWordSpacing(-1.25);
158 writer.writeElement(element);
159
160 writer.writeElement(await eb.createTextNewLine()); // New line
161
162 element = await eb.createNewTextRun('Hello World!');
163 gstate = await element.getGState();
164 gstate.setCharSpacing(0);
165 gstate.setWordSpacing(0);
166 gstate.setLineWidth(3);
167 gstate.setTextRenderMode(PDFNet.GState.TextRenderingMode.e_fill_stroke_text);
168 gstate.setStrokeColorSpace(await PDFNet.ColorSpace.createDeviceRGB());
169 gstate.setStrokeColorWithColorPt(await PDFNet.ColorPt.init(1, 0, 0)); // red
170 gstate.setFillColorSpace(await PDFNet.ColorSpace.createDeviceCMYK());
171 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(1, 0, 0, 0)); // cyan
172 writer.writeElement(element);
173
174
175 writer.writeElement(await eb.createTextNewLine()); // New line
176
177 // Set text as a clipping path to the image.
178 element = await eb.createNewTextRun('Hello World!');
179 gstate = await element.getGState();
180 gstate.setTextRenderMode(PDFNet.GState.TextRenderingMode.e_clip_text);
181 writer.writeElement(element);
182
183 // Finish the block of text
184 writer.writeElement(await eb.createTextEnd());
185
186 // Draw an image that will be clipped by the above text
187 writer.writeElement(await eb.createImageScaled(img, 10, 100, 1300, 720));
188
189 writer.end(); // save changes to the current page
190 doc.pagePushBack(page);
191
192 // Start a new page ------------------------------------
193 //
194 // The example illustrates how to embed the external font in a PDF document.
195 // The example also shows how ElementReader can be used to copy and modify
196 // Elements between pages.
197
198 const reader = await PDFNet.ElementReader.create();
199
200 // Start reading Elements from the last page. We will copy all Elements to
201 // a new page but will modify the font associated with text.
202 reader.beginOnPage(await doc.getPage(await doc.getPageCount()));
203
204 page = await doc.pageCreate(await PDFNet.Rect.init(0, 0, 1300, 794));
205
206 // begin writing to this page
207 writer.beginOnPage(page);
208 // Reset the GState to default
209 eb.reset();
210
211 const font = await PDFNet.Font.createTrueTypeFont(doc, inputPath + 'font.ttf');
212
213 // Read page contents
214 while ((element = await reader.next())) {
215 if ((await element.getType()) === PDFNet.Element.Type.e_text) {
216 (await element.getGState()).setFont(font, 12);
217 }
218
219 writer.writeElement(element);
220 }
221
222 reader.end();
223 writer.end(); // save changes to the current page
224
225 doc.pagePushBack(page);
226
227
228 // Start a new page ------------------------------------
229 //
230 // The example also shows how ElementReader can be used to copy and modify
231 // Elements between pages.
232
233 // Start reading Elements from the last page. We will copy all Elements to
234 // a new page but will modify the font associated with text.
235 reader.beginOnPage(await doc.getPage(await doc.getPageCount()));
236
237 page = await doc.pageCreate(await PDFNet.Rect.init(0, 0, 1300, 794));
238
239 // begin writing to this page
240 writer.beginOnPage(page);
241 // Reset the GState to default
242 eb.reset();
243
244 // Embed an external font in the document.
245 const font2 = await PDFNet.Font.createType1Font(doc, inputPath + 'Misc-Fixed.pfa');
246
247 // Read page contents
248 while ((element = await reader.next())) {
249 if ((await element.getType()) === PDFNet.Element.Type.e_text) {
250 (await element.getGState()).setFont(font2, 12);
251 }
252 writer.writeElement(element);
253 }
254
255 reader.end();
256 writer.end(); // save changes to the current page
257 doc.pagePushBack(page);
258
259
260 // Start a new page ------------------------------------
261 page = await doc.pageCreate();
262 // begin writing to this page
263 writer.beginOnPage(page);
264 // Reset the GState to default
265 eb.reset();
266
267 // Begin writing a block of text
268 element = await eb.createTextBeginWithFont(await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_times_roman), 12);
269 element.setTextMatrixEntries(1.5, 0, 0, 1.5, 50, 600);
270 // Set the spacing between lines
271 (await element.getGState()).setLeading(15);
272 writer.writeElement(element);
273
274
275 const para = 'A PDF text object consists of operators that can show '
276 + 'text strings, move the text position, and set text state and certain '
277 + 'other parameters. In addition, there are three parameters that are '
278 + 'defined only within a text object and do not persist from one text '
279 + 'object to the next: Tm, the text matrix, Tlm, the text line matrix, '
280 + 'Trm, the text rendering matrix, actually just an intermediate result '
281 + 'that combines the effects of text state parameters, the text matrix '
282 + '(Tm), and the current transformation matrix';
283
284 const paraEnd = para.length;
285 let textRun = 0;
286 let textRunEnd;
287
288 const paraWidth = 300; // paragraph width is 300 units
289 let curWidth = 0;
290
291 while (textRun < paraEnd) {
292 textRunEnd = para.indexOf(' ', textRun);
293 if (textRunEnd < 0) {
294 textRunEnd = paraEnd - 1;
295 }
296
297 let text = para.substring(textRun, textRunEnd + 1);
298 element = await eb.createNewTextRun(text);
299 if (curWidth + (await element.getTextLength()) < paraWidth) {
300 curWidth += await element.getTextLength();
301 } else {
302 writer.writeElement(await eb.createTextNewLine()); // New line
303 element = await eb.createNewTextRun(text);
304 curWidth = await element.getTextLength();
305 }
306 writer.writeElement(element);
307
308 textRun = textRunEnd + 1;
309 }
310
311 // -----------------------------------------------------------------------
312 // The following code snippet illustrates how to adjust spacing between
313 // characters (text runs).
314 element = await eb.createTextNewLine();
315 writer.writeElement(element); // Skip 2 lines
316 writer.writeElement(element);
317
318 writer.writeElement(await eb.createNewTextRun('An example of space adjustments between inter-characters:'));
319 writer.writeElement(await eb.createTextNewLine());
320
321 // Write string "AWAY" without space adjustments between characters.
322 element = await eb.createNewTextRun('AWAY');
323 writer.writeElement(element);
324
325 writer.writeElement(await eb.createTextNewLine());
326
327 // Write string "AWAY" with space adjustments between characters.
328 element = await eb.createNewTextRun('A');
329 writer.writeElement(element);
330
331 element = await eb.createNewTextRun('W');
332 element.setPosAdjustment(140);
333 writer.writeElement(element);
334
335 element = await eb.createNewTextRun('A');
336 element.setPosAdjustment(140);
337 writer.writeElement(element);
338
339 element = await eb.createNewTextRun('Y again');
340 element.setPosAdjustment(115);
341 writer.writeElement(element);
342
343 // Draw the same strings using direct content output...
344 writer.flush(); // flush pending Element writing operations.
345
346 // You can also write page content directly to the content stream using
347 // ElementWriter.WriteString(...) and ElementWriter.WriteBuffer(...) methods.
348 // Note that if you are planning to use these functions you need to be familiar
349 // with PDF page content operators (see Appendix A in PDF Reference Manual).
350 // Because it is easy to make mistakes during direct output we recommend that
351 // you use ElementBuilder and Element interface instead.
352
353 writer.writeString('T* T* '); // Skip 2 lines
354 writer.writeString('(Direct output to PDF page content stream:) Tj T* ');
355 writer.writeString('(AWAY) Tj T* ');
356 writer.writeString('[(A)140(W)140(A)115(Y again)] TJ ');
357
358 // Finish the block of text
359 writer.writeElement(await eb.createTextEnd());
360
361 writer.end(); // save changes to the current page
362 doc.pagePushBack(page);
363
364 // Start a new page ------------------------------------
365
366 // Image Masks
367 //
368 // In the opaque imaging model, images mark all areas they occupy on the page as
369 // if with opaque paint. All portions of the image, whether black, white, gray,
370 // or color, completely obscure any marks that may previously have existed in the
371 // same place on the page.
372 // In the graphic arts industry and page layout applications, however, it is common
373 // to crop or 'mask out' the background of an image and then place the masked image
374 // on a different background, allowing the existing background to show through the
375 // masked areas. This sample illustrates how to use image masks.
376
377 page = await doc.pageCreate();
378 // begin writing to the page
379 writer.beginOnPage(page);
380
381 // Create the Image Mask
382 const embedFile = await PDFNet.Filter.createMappedFileFromUString(inputPath + 'imagemask.dat');
383 const maskRead = await PDFNet.FilterReader.create(embedFile);
384
385 const deviceGray = await PDFNet.ColorSpace.createDeviceGray();
386 const mask = await PDFNet.Image.createDirectFromStream(doc, maskRead, 64, 64, 1, deviceGray, PDFNet.Image.InputFilter.e_ascii_hex);
387
388 (await mask.getSDFObj()).putBool('ImageMask', true);
389
390 element = await eb.createRect(0, 0, 612, 794);
391 element.setPathStroke(false);
392 element.setPathFill(true);
393 gstate = await element.getGState();
394
395 gstate.setFillColorSpace(deviceGray);
396 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(0.8));
397 writer.writePlacedElement(element);
398
399 element = await eb.createImageFromMatrix(mask, await PDFNet.Matrix2D.create(200, 0, 0, -200, 40, 680));
400 (await element.getGState()).setFillColorWithColorPt(await PDFNet.ColorPt.init(0.1));
401 writer.writePlacedElement(element);
402
403 gstate = await element.getGState();
404 gstate.setFillColorSpace(await PDFNet.ColorSpace.createDeviceRGB());
405 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(1, 0, 0));
406 element = await eb.createImageFromMatrix(mask, await PDFNet.Matrix2D.create(200, 0, 0, -200, 320, 680));
407 writer.writePlacedElement(element);
408
409 (await element.getGState()).setFillColorWithColorPt(await PDFNet.ColorPt.init(0, 1, 0));
410 element = await eb.createImageFromMatrix(mask, await PDFNet.Matrix2D.create(200, 0, 0, -200, 40, 380));
411 writer.writePlacedElement(element);
412
413 {
414 // This sample illustrates Explicit Masking.
415 const img = await PDFNet.Image.createFromFile(doc, (inputPath + 'peppers.jpg'));
416
417 // mask is the explicit mask for the primary (base) image
418 img.setMask(mask);
419
420 element = await eb.createImageFromMatrix(img, await PDFNet.Matrix2D.create(200, 0, 0, -200, 320, 380));
421 writer.writePlacedElement(element);
422 }
423
424 writer.end(); // save changes to the current page
425 doc.pagePushBack(page);
426
427 // Transparency sample ----------------------------------
428
429 // Start a new page -------------------------------------
430 page = await doc.pageCreate();
431 // begin writing to this page
432 writer.beginOnPage(page);
433 // Reset the GState to default
434 eb.reset();
435
436 // Write some transparent text at the bottom of the page.
437 element = await eb.createTextBeginWithFont(await PDFNet.Font.create(doc, PDFNet.Font.StandardType1Font.e_times_roman), 100);
438
439 // Set the text knockout attribute. Text knockout must be set outside of
440 // the text group.
441 gstate = await element.getGState();
442 gstate.setTextKnockout(false);
443 gstate.setBlendMode(PDFNet.GState.BlendMode.e_bl_difference);
444 writer.writeElement(element);
445
446 element = await eb.createNewTextRun('Transparency');
447 element.setTextMatrixEntries(1, 0, 0, 1, 30, 30);
448 gstate = await element.getGState();
449 gstate.setFillColorSpace(await PDFNet.ColorSpace.createDeviceCMYK());
450 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(1, 0, 0, 0));
451
452 gstate.setFillOpacity(0.5);
453 writer.writeElement(element);
454
455 // Write the same text on top the old; shifted by 3 points
456 element.setTextMatrixEntries(1, 0, 0, 1, 33, 33);
457 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(0, 1, 0, 0));
458 gstate.setFillOpacity(0.5);
459
460 writer.writeElement(element);
461 writer.writeElement(await eb.createTextEnd());
462
463 // Draw three overlapping transparent circles.
464 // start constructing the path
465 eb.pathBegin();
466 eb.moveTo(459.223, 505.646);
467 eb.curveTo(459.223, 415.841, 389.85, 343.04, 304.273, 343.04);
468 eb.curveTo(218.697, 343.04, 149.324, 415.841, 149.324, 505.646);
469 eb.curveTo(149.324, 595.45, 218.697, 668.25, 304.273, 668.25);
470 eb.curveTo(389.85, 668.25, 459.223, 595.45, 459.223, 505.646);
471 element = await eb.pathEnd();
472 element.setPathFill(true);
473
474 gstate = await element.getGState();
475 gstate.setFillColorSpace(await PDFNet.ColorSpace.createDeviceRGB());
476 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(0, 0, 1)); // Blue Circle
477
478 gstate.setBlendMode(PDFNet.GState.BlendMode.e_bl_normal);
479 gstate.setFillOpacity(0.5);
480 writer.writeElement(element);
481
482 // Translate relative to the Blue Circle
483 gstate.setTransform(1, 0, 0, 1, 113, -185);
484 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(0, 1, 0)); // Green Circle
485 gstate.setFillOpacity(0.5);
486 writer.writeElement(element);
487
488 // Translate relative to the Green Circle
489 gstate.setTransform(1, 0, 0, 1, -220, 0);
490 gstate.setFillColorWithColorPt(await PDFNet.ColorPt.init(1, 0, 0)); // Red Circle
491 gstate.setFillOpacity(0.5);
492 writer.writeElement(element);
493
494 writer.end(); // save changes to the current page
495 doc.pagePushBack(page);
496
497 // End page ------------------------------------
498
499 await doc.save('../TestFiles/Output/element_builder.pdf', PDFNet.SDFDoc.SaveOptions.e_remove_unused);
500
501 console.log('Done. Result saved in element_builder.pdf...');
502 } catch (e) {
503 console.log(e);
504 ret = 1;
505 }
506 return ret;
507 };
508
509 PDFNet.runWithCleanup(main, PDFTronLicense.Key).catch(function(error){console.log('Error: ' + JSON.stringify(error));}).then(function(){return PDFNet.shutdown();});
510 };
511 exports.runElementBuilderTest();
512})(exports);
513// eslint-disable-next-line spaced-comment
514//# sourceURL=ElementBuilderTest.js
1#---------------------------------------------------------------------------------------
2# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
3# Consult LICENSE.txt regarding license information.
4#---------------------------------------------------------------------------------------
5
6import site
7site.addsitedir("../../../PDFNetC/Lib")
8import sys
9from PDFNetPython import *
10
11sys.path.append("../../LicenseKey/PYTHON")
12from LicenseKey import *
13
14# Relative path to the folder containing the test files.
15input_path = "../../TestFiles/"
16output_path = "../../TestFiles/Output/"
17
18def main():
19 PDFNet.Initialize(LicenseKey)
20
21 doc = PDFDoc()
22
23 # ElementBuilder is used to build new Element objects
24 eb = ElementBuilder()
25 # ElementWriter is used to write Elements to the page
26 writer = ElementWriter()
27
28 # Start a new page ------------------------------------
29 page = doc.PageCreate(Rect(0, 0, 612, 794))
30
31 writer.Begin(page) # begin writing to the page
32
33 # Create an Image that can be reused in the document or on the same page.
34 img = Image.Create(doc.GetSDFDoc(), input_path + "peppers.jpg")
35
36 element = eb.CreateImage(img, Matrix2D(img.GetImageWidth()/2, -145, 20, img.GetImageHeight()/2, 200, 150))
37 writer.WritePlacedElement(element)
38
39 gstate = element.GetGState() # use the same image (just change its matrix)
40 gstate.SetTransform(200, 0, 0, 300, 50, 450)
41 writer.WritePlacedElement(element)
42
43 # use the same image again (just change its matrix)
44 writer.WritePlacedElement(eb.CreateImage(img, 300, 600, 200, -150))
45
46 writer.End() # save changes to the current page
47 doc.PagePushBack(page)
48
49 # Start a new page ------------------------------------
50 # Construct and draw a path object using different styles
51 page = doc.PageCreate(Rect(0, 0, 612, 794))
52
53 writer.Begin(page) # begin writing to this page
54 eb.Reset() # Reset the GState to default
55
56 eb.PathBegin() # start constructing the path
57 eb.MoveTo(306, 396)
58 eb.CurveTo(681, 771, 399.75, 864.75, 306, 771)
59 eb.CurveTo(212.25, 864.75, -69, 771, 306, 396)
60 eb.ClosePath()
61 element = eb.PathEnd() # the path is now finished
62 element.SetPathFill(True) # the path should be filled
63
64 # Set the path color space and color
65 gstate = element.GetGState()
66 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK())
67 gstate.SetFillColor(ColorPt(1, 0, 0, 0)) # cyan
68 gstate.SetTransform(0.5, 0, 0, 0.5, -20, 300)
69 writer.WritePlacedElement(element)
70
71 # Draw the same path using a different stroke color
72 element.SetPathStroke(True) # this path is should be filled and stroked
73 gstate.SetFillColor(ColorPt(0, 0, 1, 0)) # yellow
74 gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB())
75 gstate.SetStrokeColor(ColorPt(1, 0, 0)) # red
76 gstate.SetTransform(0.5, 0, 0, 0.5, 280, 300)
77 gstate.SetLineWidth(20)
78 writer.WritePlacedElement(element)
79
80 # Draw the same path with a given dash pattern
81 element.SetPathFill(False) # this path should be only stroked
82
83 gstate.SetStrokeColor(ColorPt(0,0,1)) # blue
84 gstate.SetTransform(0.5, 0, 0, 0.5, 280, 0)
85 dash_pattern = VectorDouble()
86 dash_pattern.append(30)
87 gstate.SetDashPattern(dash_pattern, 0)
88 writer.WritePlacedElement(element)
89
90 # Use the path as a clipping path
91 writer.WriteElement(eb.CreateGroupBegin()) # Save the graphics state
92 # Start constructing the new path (the old path was lost when we created
93 # a new Element using CreateGroupBegin()).
94 eb.PathBegin()
95 eb.MoveTo(306, 396)
96 eb.CurveTo(681, 771, 399.75, 864.75, 306, 771)
97 eb.CurveTo(212.25, 864.75, -69, 771, 306, 396)
98 eb.ClosePath()
99 element = eb.PathEnd() # path is now constructed
100 element.SetPathClip(True) # this path is a clipping path
101 element.SetPathStroke(True) # this path should be filled and stroked
102 gstate = element.GetGState()
103 gstate.SetTransform(0.5, 0, 0, 0.5, -20, 0)
104
105 writer.WriteElement(element)
106
107 writer.WriteElement(eb.CreateImage(img, 100, 300, 400, 600))
108
109 writer.WriteElement(eb.CreateGroupEnd()) # Restore the graphics state
110
111 writer.End() # save changes to the current page
112 doc.PagePushBack(page)
113
114 # Start a new page ------------------------------------
115 page = doc.PageCreate(Rect(0, 0, 612, 794))
116
117 writer.Begin(page) # begin writing to this page
118 eb.Reset() # Reset the GState to default
119
120 # Begin writing a block of text
121 element = eb.CreateTextBegin(Font.Create(doc.GetSDFDoc(), Font.e_times_roman), 12)
122 writer.WriteElement(element)
123
124 element = eb.CreateTextRun("Hello World!")
125 element.SetTextMatrix(10, 0, 0, 10, 0, 600)
126 element.GetGState().SetLeading(15) # Set the spacing between lines
127 writer.WriteElement(element)
128
129 writer.WriteElement(eb.CreateTextNewLine()) # New line
130
131 element = eb.CreateTextRun("Hello World!")
132 gstate = element.GetGState()
133 gstate.SetTextRenderMode(GState.e_stroke_text)
134 gstate.SetCharSpacing(-1.25)
135 gstate.SetWordSpacing(-1.25)
136 writer.WriteElement(element)
137
138 writer.WriteElement(eb.CreateTextNewLine()) # New line
139
140 element = eb.CreateTextRun("Hello World!")
141 gstate = element.GetGState()
142 gstate.SetCharSpacing(0)
143 gstate.SetWordSpacing(0)
144 gstate.SetLineWidth(3)
145 gstate.SetTextRenderMode(GState.e_fill_stroke_text)
146 gstate.SetStrokeColorSpace(ColorSpace.CreateDeviceRGB())
147 gstate.SetStrokeColor(ColorPt(1, 0, 0)) # red
148 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK())
149 gstate.SetFillColor(ColorPt(1, 0, 0, 0)) # cyan
150 writer.WriteElement(element)
151
152 writer.WriteElement(eb.CreateTextNewLine()) # New line
153
154 # Set text as a clipping path to the image.
155 element = eb.CreateTextRun("Hello World!")
156 gstate = element.GetGState()
157 gstate.SetTextRenderMode(GState.e_clip_text)
158 writer.WriteElement(element)
159
160 # Finish the block of text
161 writer.WriteElement(eb.CreateTextEnd())
162
163 # Draw an image that will be clipped by the above text
164 writer.WriteElement(eb.CreateImage(img, 10, 100, 1300, 720))
165
166 writer.End() # save changes to the current page
167 doc.PagePushBack(page)
168
169 # Start a new page ------------------------------------
170 #
171 # The example illustrates how to embed the external font in a PDF document.
172 # The example also shows how ElementReader can be used to copy and modify
173 # Elements between pages.
174
175 reader = ElementReader()
176
177 # Start reading Elements from the last page. We will copy all Elements to
178 # a new page but will modify the font associated with text.
179 reader.Begin(doc.GetPage(doc.GetPageCount()))
180
181 page = doc.PageCreate(Rect(0, 0, 1300, 794))
182
183 writer.Begin(page) # begin writing to this page
184 eb.Reset() # Reset the GState to default
185
186 # Embed an external font in the document.
187 font = Font.CreateTrueTypeFont(doc.GetSDFDoc(), (input_path + "font.ttf"))
188
189 element = reader.Next()
190 while element != None: # Read page contents
191 if element.GetType() == Element.e_text:
192 element.GetGState().SetFont(font, 12)
193 writer.WriteElement(element)
194 element = reader.Next()
195
196 reader.End()
197 writer.End() # save changes to the current page
198 doc.PagePushBack(page)
199
200 # Start a new page ------------------------------------
201 #
202 # The example illustrates how to embed the external font in a PDF document.
203 # The example also shows how ElementReader can be used to copy and modify
204 # Elements between pages.
205
206 # Start reading Elements from the last page. We will copy all Elements to
207 # a new page but will modify the font associated with text.
208 reader.Begin(doc.GetPage(doc.GetPageCount()))
209
210 page = doc.PageCreate(Rect(0, 0, 1300, 794))
211
212 writer.Begin(page) # begin writing to this page
213 eb.Reset() # Reset the GState to default
214
215 # Embed an external font in the document.
216 font2 = Font.CreateType1Font(doc.GetSDFDoc(), (input_path + "Misc-Fixed.pfa"))
217
218 element = reader.Next()
219 while element != None:
220 if element.GetType() == Element.e_text:
221 element.GetGState().SetFont(font2, 12)
222 writer.WriteElement(element)
223 element = reader.Next()
224
225 reader.End()
226 writer.End() # save changes to the current page
227 doc.PagePushBack(page)
228
229 # Start a new page ------------------------------------
230 page = doc.PageCreate()
231 writer.Begin(page) # begin writing to this page
232 eb.Reset() # Reset the GState to default
233
234 # Begin writing a block of text
235 element = eb.CreateTextBegin(Font.Create(doc.GetSDFDoc(), Font.e_times_roman), 12)
236 element.SetTextMatrix(1.5, 0, 0, 1.5, 50, 600)
237 element.GetGState().SetLeading(15) # Set the spacing between lines
238 writer.WriteElement(element)
239
240 para = ("A PDF text object consists of operators that can show "
241 "text strings, move the text position, and set text state and certain "
242 "other parameters. In addition, there are three parameters that are "
243 "defined only within a text object and do not persist from one text "
244 "object to the next: Tm, the text matrix, Tlm, the text line matrix, "
245 "Trm, the text rendering matrix, actually just an intermediate result "
246 "that combines the effects of text state parameters, the text matrix "
247 "(Tm), and the current transformation matrix")
248
249 para_end = len(para)
250 text_run = 0
251
252 para_width = 300 # paragraph width is 300 units
253 cur_width = 0
254
255 while text_run < para_end:
256 text_run_end = para.find(' ', text_run)
257 if text_run_end < 0:
258 text_run_end = para_end - 1
259
260 text = para[text_run:text_run_end+1]
261 element = eb.CreateTextRun(text)
262 if cur_width + element.GetTextLength() < para_width:
263 writer.WriteElement(element)
264 cur_width = cur_width + element.GetTextLength()
265 else:
266 writer.WriteElement(eb.CreateTextNewLine()) # new line
267 element = eb.CreateTextRun(text)
268 cur_width = element.GetTextLength()
269 writer.WriteElement(element)
270 text_run = text_run_end + 1
271
272 # -----------------------------------------------------------------------
273 # The following code snippet illustrates how to adjust spacing between
274 # characters (text runs).
275 element = eb.CreateTextNewLine()
276 writer.WriteElement(element) # Skip 2 lines
277 writer.WriteElement(element)
278
279 writer.WriteElement(eb.CreateTextRun("An example of space adjustments between inter-characters:"))
280 writer.WriteElement(eb.CreateTextNewLine())
281
282 # Write string "AWAY" without space adjustments between characters.
283 element = eb.CreateTextRun("AWAY")
284 writer.WriteElement(element)
285
286 writer.WriteElement(eb.CreateTextNewLine())
287
288 # Write string "AWAY" with space adjustments between characters.
289 element = eb.CreateTextRun("A")
290 writer.WriteElement(element)
291
292 element = eb.CreateTextRun("W")
293 element.SetPosAdjustment(140)
294 writer.WriteElement(element)
295
296 element = eb.CreateTextRun("A")
297 element.SetPosAdjustment(140)
298 writer.WriteElement(element)
299
300 element = eb.CreateTextRun("Y again")
301 element.SetPosAdjustment(115)
302 writer.WriteElement(element)
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
314 writer.WriteString("T* T* ") # Skip 2 lines
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 # Start a new page ------------------------------------
326
327 # Image Masks
328 #
329 # In the opaque imaging model, images mark all areas they occupy on the page as
330 # if with opaque paint. All portions of the image, whether black, white, gray,
331 # or color, completely obscure any marks that may previously have existed in the
332 # same place on the page.
333 # In the graphic arts industry and page layout applications, however, it is common
334 # to crop or 'mask out' the background of an image and then place the masked image
335 # on a different background, allowing the existing background to show through the
336 # masked areas. This sample illustrates how to use image masks.
337
338 page = doc.PageCreate()
339 writer.Begin(page) # begin writing to the page
340
341 # Create the Image Mask
342 imgf = MappedFile(input_path + "imagemask.dat")
343 mask_read = FilterReader(imgf)
344
345 device_gray = ColorSpace.CreateDeviceGray()
346 mask = Image.Create(doc.GetSDFDoc(), mask_read, 64, 64, 1, device_gray, Image.e_ascii_hex)
347
348 mask.GetSDFObj().PutBool("ImageMask", True)
349
350 element = eb.CreateRect(0, 0, 612, 794)
351 element.SetPathStroke(False)
352 element.SetPathFill(True)
353 element.GetGState().SetFillColorSpace(device_gray)
354 element.GetGState().SetFillColor(ColorPt(0.8))
355 writer.WritePlacedElement(element)
356
357 element = eb.CreateImage(mask, Matrix2D(200, 0, 0, -200, 40, 680))
358 element.GetGState().SetFillColor(ColorPt(0.1))
359 writer.WritePlacedElement(element)
360
361 element.GetGState().SetFillColorSpace(ColorSpace.CreateDeviceRGB())
362 element.GetGState().SetFillColor(ColorPt(1, 0, 0))
363 element = eb.CreateImage(mask, Matrix2D(200, 0, 0, -200, 320, 680))
364 writer.WritePlacedElement(element)
365
366 element.GetGState().SetFillColor(ColorPt(0, 1, 0))
367 element = eb.CreateImage(mask, Matrix2D(200, 0, 0, -200, 40, 380))
368 writer.WritePlacedElement(element)
369
370 # This sample illustrates Explicit Masking.
371 img = Image.Create(doc.GetSDFDoc(), (input_path + "peppers.jpg"))
372
373 # mask is the explicit mask for the primary (base) image
374 img.SetMask(mask)
375
376 element = eb.CreateImage(img, Matrix2D(200, 0, 0, -200, 320, 380))
377 writer.WritePlacedElement(element)
378
379 writer.End() # save changes to the current page
380 doc.PagePushBack(page)
381
382 # Transparency sample ----------------------------------
383
384 # Start a new page -------------------------------------
385 page = doc.PageCreate()
386 writer.Begin(page) # begin writing to this page
387 eb.Reset() # Reset the GState to default
388
389 # Write some transparent text at the bottom of the page.
390 element = eb.CreateTextBegin(Font.Create(doc.GetSDFDoc(), Font.e_times_roman), 100)
391
392 # Set the text knockout attribute. Text knockout must be set outside of
393 # the text group.
394 gstate = element.GetGState()
395 gstate.SetTextKnockout(False)
396 gstate.SetBlendMode(GState.e_bl_difference)
397 writer.WriteElement(element)
398
399 element = eb.CreateTextRun("Transparency")
400 element.SetTextMatrix(1, 0, 0, 1, 30, 30)
401 gstate = element.GetGState()
402 gstate.SetFillColorSpace(ColorSpace.CreateDeviceCMYK())
403 gstate.SetFillColor(ColorPt(1, 0, 0, 0))
404
405 gstate.SetFillOpacity(0.5)
406 writer.WriteElement(element)
407
408 # Write the same text on top the old; shifted by 3 points
409 element.SetTextMatrix(1, 0, 0, 1, 33, 33)
410 gstate.SetFillColor(ColorPt(0, 1, 0, 0))
411 gstate.SetFillOpacity(0.5)
412
413 writer.WriteElement(element)
414 writer.WriteElement(eb.CreateTextEnd())
415
416 # Draw three overlapping transparent circles.
417 eb.PathBegin() # start constructing the path
418 eb.MoveTo(459.223, 505.646)
419 eb.CurveTo(459.223, 415.841, 389.85, 343.04, 304.273, 343.04)
420 eb.CurveTo(218.697, 343.04, 149.324, 415.841, 149.324, 505.646)
421 eb.CurveTo(149.324, 595.45, 218.697, 668.25, 304.273, 668.25)
422 eb.CurveTo(389.85, 668.25, 459.223, 595.45, 459.223, 505.646)