PDF Annotation - Add/Edit - C++ Sample Code

Sample code to use Apryse Server SDK for adding or editing PDF annotations. The annotation types included in this sample are: hyperlink, intra-document link, stamp, rubber stamp, file attachment, sound, text, free-text, line, circle, square, polygon, polyline, highlight, squiggly, caret, and ink. Learn more about our Server SDK and PDF Annotation Library.

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6#include <PDF/PDFNet.h>
7#include <PDF/PDFDoc.h>
8#include <PDF/ElementBuilder.h>
9#include <PDF/ElementReader.h>
10#include <PDF/ElementWriter.h>
11#include <PDF/Annot.h>
12#include <SDF/Obj.h>
13#include <iostream>
14#include "../../LicenseKey/CPP/LicenseKey.h"
15
16using namespace pdftron;
17using namespace SDF;
18using namespace PDF;
19using namespace std;
20
21
22std::string output_path = "../../TestFiles/Output/";
23std::string input_path = "../../TestFiles/";
24
25void AnnotationHighLevelAPI(PDFDoc& doc)
26{
27 // The following code snippet traverses all annotations in the document
28 cout << "Traversing all annotations in the document..." << endl;
29
30 UString uri;
31 int page_num=1;
32 for (PageIterator itr = doc.GetPageIterator(); itr.HasNext(); itr.Next())
33 {
34 cout << "Page " << page_num++ << ": " << endl;
35
36 Page page = itr.Current();
37 int num_annots = page.GetNumAnnots();
38 for (int i=0; i<num_annots; ++i)
39 {
40 Annot annot = page.GetAnnot(i);
41 if (!annot.IsValid()) continue;
42 cout << "Annot Type: " << annot.GetSDFObj().Get("Subtype").Value().GetName() << endl;
43
44 Rect bbox = annot.GetRect();
45 cout << " Position: " << bbox.x1
46 << ", " << bbox.y1
47 << ", " << bbox.x2
48 << ", " << bbox.y2 << endl;
49
50 switch (annot.GetType())
51 {
52 case Annot::e_Link:
53 {
54 Annots::Link link(annot);
55 Action action = link.GetAction();
56 if (!action.IsValid()) continue;
57 if (action.GetType() == Action::e_GoTo)
58 {
59 Destination dest = action.GetDest();
60 if (!dest.IsValid()) {
61 cout << " Destination is not valid" << endl;
62 }
63 else {
64 int page_num = dest.GetPage().GetIndex();
65 cout << " Links to: page number " << page_num << " in this document" << endl;
66 }
67 }
68 else if (action.GetType() == Action::e_URI)
69 {
70 action.GetSDFObj().Get("URI").Value().GetAsPDFText(uri);
71 cout << " Links to: " << uri << endl;
72 }
73 // ...
74 }
75 break;
76 case Annot::e_Widget:
77 break;
78 case Annot::e_FileAttachment:
79 break;
80 // ...
81 default:
82 break;
83 }
84 }
85 }
86
87 // Use the high-level API to create new annotations.
88 Page first_page = doc.GetPage(1);
89
90 // Create a hyperlink...
91 Annots::Link hyperlink = Annots::Link::Create(doc, Rect(85, 570, 503, 524), Action::CreateURI(doc, "http://www.pdftron.com"));
92 first_page.AnnotPushBack(hyperlink);
93
94 // Create an intra-document link...
95 Action goto_page_3 = Action::CreateGoto(Destination::CreateFitH(doc.GetPage(3), 0));
96 Annots::Link link = Annots::Link::Create(doc, Rect(85, 458, 503, 502), goto_page_3);
97 link.SetColor(ColorPt(0, 0, 1));
98
99 // Add the new annotation to the first page
100 first_page.AnnotPushBack(link);
101
102 // Create a stamp annotation ...
103 Annots::RubberStamp stamp = Annots::RubberStamp::Create(doc, Rect(30, 30, 300, 200));
104 stamp.SetIcon("Draft");
105 first_page.AnnotPushBack(stamp);
106
107 // Create a file attachment annotation (embed the 'peppers.jpg').
108 Annots::FileAttachment file_attach = Annots::FileAttachment::Create(doc, Rect(80, 280, 108, 320), (input_path + "peppers.jpg").c_str());
109 first_page.AnnotPushBack(file_attach);
110
111
112 Annots::Ink ink = Annots::Ink::Create(doc, Rect(110, 10, 300, 200));
113 Point pt3(110, 10);
114 //pt3.x = 110; pt3.y = 10;
115 ink.SetPoint(0, 0, pt3);
116 pt3.x = 150; pt3.y = 50;
117 ink.SetPoint(0, 1, pt3);
118 pt3.x = 190; pt3.y = 60;
119 ink.SetPoint(0, 2, pt3);
120 pt3.x = 180; pt3.y = 90;
121 ink.SetPoint(1, 0, pt3);
122 pt3.x = 190; pt3.y = 95;
123 ink.SetPoint(1, 1, pt3);
124 pt3.x = 200; pt3.y = 100;
125 ink.SetPoint(1, 2, pt3);
126 pt3.x = 166; pt3.y = 86;
127 ink.SetPoint(2, 0, pt3);
128 pt3.x = 196; pt3.y = 96;
129 ink.SetPoint(2, 1, pt3);
130 pt3.x = 221; pt3.y = 121;
131 ink.SetPoint(2, 2, pt3);
132 pt3.x = 288; pt3.y = 188;
133 ink.SetPoint(2, 3, pt3);
134 ink.SetColor(ColorPt(0, 1, 1), 3);
135 first_page.AnnotPushBack(ink);
136
137}
138
139void AnnotationLowLevelAPI(PDFDoc& doc)
140{
141 Page page = (doc.GetPageIterator()).Current();
142
143 Obj annots = page.GetAnnots();
144
145 if (!annots)
146 {
147 // If there are no annotations, create a new annotation
148 // array for the page.
149 annots = doc.CreateIndirectArray();
150 page.GetSDFObj().Put("Annots", annots);
151 }
152
153 // Create a Text annotation
154 Obj annot = doc.CreateIndirectDict();
155 annot.PutName("Subtype", "Text");
156 annot.PutBool("Open", true);
157 annot.PutString("Contents", "The quick brown fox ate the lazy mouse.");
158 annot.PutRect("Rect", 266, 116, 430, 204);
159
160 // Insert the annotation in the page annotation array
161 annots.PushBack(annot);
162
163 // Create a Link annotation
164 Obj link1 = doc.CreateIndirectDict();
165 link1.PutName("Subtype", "Link");
166 Destination dest = Destination::CreateFit(doc.GetPage(2));
167 link1.Put("Dest", dest.GetSDFObj());
168 link1.PutRect("Rect", 85, 705, 503, 661);
169 annots.PushBack(link1);
170
171 // Create another Link annotation
172 Obj link2 = doc.CreateIndirectDict();
173 link2.PutName("Subtype", "Link");
174 Destination dest2 = Destination::CreateFit(doc.GetPage(3));
175 link2.Put("Dest", dest2.GetSDFObj());
176 link2.PutRect("Rect", 85, 638, 503, 594);
177 annots.PushBack(link2);
178
179 // Note that PDFNet API can be used to modify existing annotations.
180 // In the following example we will modify the second link annotation
181 // (link2) so that it points to the 10th page. We also use a different
182 // destination page fit type.
183
184 // link2 = annots.GetAt(annots.Size()-1);
185 link2.Put("Dest",
186 Destination::CreateXYZ(doc.GetPage(10), 100, 792-70, 10).GetSDFObj());
187
188 // Create a third link annotation with a hyperlink action (all other
189 // annotation types can be created in a similar way)
190 Obj link3 = doc.CreateIndirectDict();
191 link3.PutName("Subtype", "Link");
192 link3.PutRect("Rect", 85, 570, 503, 524);
193
194 // Create a URI action
195 Obj action = link3.PutDict("A");
196 action.PutName("S", "URI");
197 action.PutString("URI", "http://www.pdftron.com");
198
199 annots.PushBack(link3);
200}
201
202
203void CreateTestAnnots(PDFDoc& doc) {
204 using namespace pdftron;
205 using namespace SDF;
206 using namespace PDF;
207 using namespace Annots;
208
209
210 ElementWriter ew;
211 ElementBuilder eb;
212 Element element ;
213
214 Page first_page= doc.PageCreate(Rect(0, 0, 600, 600));
215 doc.PagePushBack(first_page);
216 ew.Begin(first_page, ElementWriter::e_overlay, false ); // begin writing to this page
217 ew.End(); // save changes to the current page
218
219 //
220 // Test of a free text annotation.
221 //
222 {
223 Annots::FreeText txtannot = Annots::FreeText::Create( doc, Rect(10, 400, 160, 570) );
224 txtannot.SetContents( UString("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
225 "\n\nAha!\n\nAnd there was much rejoicing!" ) );
226 //std::vector<double> dash( 2, 2.0 );
227 txtannot.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 1, 10, 20 ), false);
228 txtannot.SetQuaddingFormat(0);
229 first_page.AnnotPushBack(txtannot);
230 txtannot.RefreshAppearance();
231 }
232 {
233 Annots::FreeText txtannot = Annots::FreeText::Create( doc, Rect(100, 100, 350, 500) );
234 txtannot.SetContentRect( Rect( 200, 200, 350, 500 ) );
235 txtannot.SetContents( UString("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
236 "\n\nAha!\n\nAnd there was much rejoicing!" ) );
237 txtannot.SetCalloutLinePoints( Point(200,300), Point(150,290), Point(110,110) );
238 //std::vector<double> dash( 2, 2.0 );
239 txtannot.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 1, 10, 20 ), false);
240 txtannot.SetEndingStyle( Line::e_ClosedArrow );
241 txtannot.SetColor( ColorPt( 0, 1, 0 ) );
242 txtannot.SetQuaddingFormat(1);
243 first_page.AnnotPushBack(txtannot);
244 txtannot.RefreshAppearance();
245 }
246 {
247 Annots::FreeText txtannot = Annots::FreeText::Create( doc, Rect(400, 10, 550, 400) );
248 txtannot.SetContents( UString("\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
249 "\n\nAha!\n\nAnd there was much rejoicing!" ) );
250 txtannot.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 1, 10, 20 ), false);
251 txtannot.SetColor( ColorPt( 0, 0, 1 ) );
252 txtannot.SetOpacity( 0.2 );
253 txtannot.SetQuaddingFormat(2);
254 first_page.AnnotPushBack(txtannot);
255 txtannot.RefreshAppearance();
256 }
257
258 Page page= doc.PageCreate(Rect(0, 0, 600, 600));
259 doc.PagePushBack(page);
260 ew.Begin(page, ElementWriter::e_overlay, false ); // begin writing to this page
261 eb.Reset(); // Reset the GState to default
262 ew.End(); // save changes to the current page
263
264 {
265 //Create a Line annotation...
266 Line line=Line::Create(doc, Rect(250, 250, 400, 400));
267 line.SetStartPoint( Point(350, 270 ) );
268 line.SetEndPoint( Point(260,370) );
269 line.SetStartStyle(Line::e_Square);
270 line.SetEndStyle(Line::e_Circle);
271 line.SetColor(ColorPt(.3, .5, 0), 3);
272 line.SetContents( UString("Dashed Captioned") );
273 line.SetShowCaption(true);
274 line.SetCaptionPosition( Line::e_Top );
275 std::vector<double> dash( 2, 2.0 );
276 line.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_dashed, 2, 0, 0, dash ) );
277 line.RefreshAppearance();
278 page.AnnotPushBack(line);
279 }
280 {
281 Line line=Line::Create(doc, Rect(347, 377, 600, 600));
282 line.SetStartPoint( Point(385, 410 ) );
283 line.SetEndPoint( Point(540,555) );
284 line.SetStartStyle(Line::e_Circle);
285 line.SetEndStyle(Line::e_OpenArrow);
286 line.SetColor(ColorPt(1, 0, 0), 3);
287 line.SetInteriorColor(ColorPt(0, 1, 0), 3);
288 line.SetContents( UString("Inline Caption") );
289 line.SetShowCaption(true);
290 line.SetCaptionPosition( Line::e_Inline );
291 line.SetLeaderLineExtensionLength( 4. );
292 line.SetLeaderLineLength( -12. );
293 line.SetLeaderLineOffset( 2. );
294 line.RefreshAppearance();
295 page.AnnotPushBack(line);
296 }
297 {
298 Line line=Line::Create(doc, Rect(10, 400, 200, 600));
299 line.SetStartPoint( Point(25, 426 ) );
300 line.SetEndPoint( Point(180,555) );
301 line.SetStartStyle(Line::e_Circle);
302 line.SetEndStyle(Line::e_Square);
303 line.SetColor(ColorPt(0, 0, 1), 3);
304 line.SetInteriorColor(ColorPt(1, 0, 0), 3);
305 line.SetContents( UString("Offset Caption") );
306 line.SetShowCaption(true);
307 line.SetCaptionPosition( Line::e_Top );
308 line.SetTextHOffset( -60 );
309 line.SetTextVOffset( 10 );
310 line.RefreshAppearance();
311 page.AnnotPushBack(line);
312 }
313 {
314 Line line=Line::Create(doc, Rect(200, 10, 400, 70));
315 line.SetStartPoint( Point(220, 25 ) );
316 line.SetEndPoint( Point(370,60) );
317 line.SetStartStyle(Line::e_Butt);
318 line.SetEndStyle(Line::e_OpenArrow);
319 line.SetColor(ColorPt(0, 0, 1), 3);
320 line.SetContents( UString("Regular Caption") );
321 line.SetShowCaption(true);
322 line.SetCaptionPosition( Line::e_Top );
323 line.RefreshAppearance();
324 page.AnnotPushBack(line);
325 }
326 {
327 Line line=Line::Create(doc, Rect(200, 70, 400, 130));
328 line.SetStartPoint( Point(220, 111 ) );
329 line.SetEndPoint( Point(370,78) );
330 line.SetStartStyle(Line::e_Circle);
331 line.SetEndStyle(Line::e_Diamond);
332 line.SetContents( UString("Circle to Diamond") );
333 line.SetColor(ColorPt(0, 0, 1), 3);
334 line.SetInteriorColor(ColorPt(0, 1, 0), 3);
335 line.SetShowCaption(true);
336 line.SetCaptionPosition( Line::e_Top );
337 line.RefreshAppearance();
338 page.AnnotPushBack(line);
339 }
340 {
341 Line line=Line::Create(doc, Rect(10, 100, 160, 200));
342 line.SetStartPoint( Point(15, 110 ) );
343 line.SetEndPoint( Point(150, 190) );
344 line.SetStartStyle(Line::e_Slash);
345 line.SetEndStyle(Line::e_ClosedArrow);
346 line.SetContents( UString("Slash to CArrow") );
347 line.SetColor(ColorPt(1, 0, 0), 3);
348 line.SetInteriorColor(ColorPt(0, 1, 1), 3);
349 line.SetShowCaption(true);
350 line.SetCaptionPosition( Line::e_Top );
351 line.RefreshAppearance();
352 page.AnnotPushBack(line);
353 }
354 {
355 Line line=Line::Create(doc, Rect( 270, 270, 570, 433 ));
356 line.SetStartPoint( Point(300, 400 ) );
357 line.SetEndPoint( Point(550, 300) );
358 line.SetStartStyle(Line::e_RClosedArrow);
359 line.SetEndStyle(Line::e_ROpenArrow);
360 line.SetContents( UString("ROpen & RClosed arrows") );
361 line.SetColor(ColorPt(0, 0, 1), 3);
362 line.SetInteriorColor(ColorPt(0, 1, 0), 3);
363 line.SetShowCaption(true);
364 line.SetCaptionPosition( Line::e_Top );
365 line.RefreshAppearance();
366 page.AnnotPushBack(line);
367 }
368 {
369 Line line=Line::Create(doc, Rect( 195, 395, 205, 505 ));
370 line.SetStartPoint( Point(200, 400 ) );
371 line.SetEndPoint( Point(200, 500) );
372 line.RefreshAppearance();
373 page.AnnotPushBack(line);
374 }
375 {
376 Line line=Line::Create(doc, Rect( 55, 299, 150, 301 ));
377 line.SetStartPoint( Point(55, 300 ) );
378 line.SetEndPoint( Point(155, 300) );
379 line.SetStartStyle(Line::e_Circle);
380 line.SetEndStyle(Line::e_Circle);
381 line.SetContents( UString("Caption that's longer than its line.") );
382 line.SetColor(ColorPt(1, 0, 1), 3);
383 line.SetInteriorColor(ColorPt(0, 1, 0), 3);
384 line.SetShowCaption(true);
385 line.SetCaptionPosition( Line::e_Top );
386 line.RefreshAppearance();
387 page.AnnotPushBack(line);
388 }
389 {
390 Line line=Line::Create(doc, Rect( 300, 200, 390, 234 ));
391 line.SetStartPoint( Point(310, 210 ) );
392 line.SetEndPoint( Point(380, 220) );
393 line.SetColor(ColorPt(0, 0, 0), 3);
394 line.RefreshAppearance();
395 page.AnnotPushBack(line);
396 }
397
398 Page page3 = doc.PageCreate(Rect(0, 0, 600, 600));
399 ew.Begin(page3); // begin writing to the page
400 ew.End(); // save changes to the current page
401 doc.PagePushBack(page3);
402 {
403 Circle circle=Circle::Create(doc, Rect( 300, 300, 390, 350 ));
404 circle.SetColor(ColorPt(0, 0, 0), 3);
405 circle.RefreshAppearance();
406 page3.AnnotPushBack(circle);
407 }
408 {
409 Circle circle=Circle::Create(doc, Rect( 100, 100, 200, 200 ));
410 circle.SetColor(ColorPt(0, 1, 0), 3);
411 circle.SetInteriorColor(ColorPt(0, 0, 1), 3);
412 std::vector<double> dash( 2 ); dash[0]=2;dash[1]=4;
413 circle.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_dashed, 3, 0, 0, dash ) );
414 circle.SetPadding( 2 );
415 circle.RefreshAppearance();
416 page3.AnnotPushBack(circle);
417 }
418 {
419 Square sq = Square::Create( doc, Rect(10,200, 80, 300 ) );
420 sq.SetColor(ColorPt(0, 0, 0), 3);
421 sq.RefreshAppearance();
422 page3.AnnotPushBack( sq );
423 }
424 {
425 Square sq = Square::Create( doc, Rect(500,200, 580, 300 ) );
426 sq.SetColor(ColorPt(1, 0, 0), 3);
427 sq.SetInteriorColor(ColorPt(0, 1, 1), 3);
428 std::vector<double> dash( 2 ); dash[0]=4;dash[1]=2;
429 sq.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_dashed, 6, 0, 0, dash ) );
430 sq.SetPadding( 4 );
431 sq.RefreshAppearance();
432 page3.AnnotPushBack( sq );
433 }
434 {
435 Polygon poly = Polygon::Create(doc, Rect(5, 500, 125, 590));
436 poly.SetColor(ColorPt(1, 0, 0), 3);
437 poly.SetInteriorColor(ColorPt(1, 1, 0), 3);
438 poly.SetVertex(0, Point(12,510) );
439 poly.SetVertex(1, Point(100,510) );
440 poly.SetVertex(2, Point(100,555) );
441 poly.SetVertex(3, Point(35,544) );
442 poly.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 4, 0, 0 ) );
443 poly.SetPadding( 4 );
444 poly.RefreshAppearance();
445 page3.AnnotPushBack( poly );
446 }
447 {
448 PolyLine poly = PolyLine::Create(doc, Rect(400, 10, 500, 90));
449 poly.SetColor(ColorPt(1, 0, 0), 3);
450 poly.SetInteriorColor(ColorPt(0, 1, 0), 3);
451 poly.SetVertex(0, Point(405,20) );
452 poly.SetVertex(1, Point(440,40) );
453 poly.SetVertex(2, Point(410,60) );
454 poly.SetVertex(3, Point(470,80) );
455 poly.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 2, 0, 0 ) );
456 poly.SetPadding( 4 );
457 poly.SetStartStyle( Line::e_RClosedArrow );
458 poly.SetEndStyle( Line::e_ClosedArrow );
459 poly.RefreshAppearance();
460 page3.AnnotPushBack( poly );
461 }
462 {
463 Link lk = Link::Create( doc, Rect(5,5,55,24) );
464 //lk.SetColor( ColorPt(0,1,0), 3 );
465 lk.RefreshAppearance();
466 page3.AnnotPushBack( lk );
467 }
468
469
470 Page page4 = doc.PageCreate(Rect(0, 0, 600, 600));
471 ew.Begin(page4); // begin writing to the page
472 ew.End(); // save changes to the current page
473 doc.PagePushBack(page4);
474
475 {
476 ew.Begin( page4 );
477 Font font = Font::Create(doc, Font::e_helvetica);
478 element = eb.CreateTextBegin( font, 16 );
479 element.SetPathFill(true);
480 ew.WriteElement(element);
481 element = eb.CreateTextRun( "Some random text on the page", font, 16 );
482 element.SetTextMatrix(1, 0, 0, 1, 100, 500 );
483 ew.WriteElement(element);
484 ew.WriteElement( eb.CreateTextEnd() );
485 ew.End();
486 }
487 {
488 Highlight hl = Highlight::Create( doc, Rect(100,490,150,515) );
489 hl.SetColor( ColorPt(0,1,0), 3 );
490 hl.RefreshAppearance();
491 page4.AnnotPushBack( hl );
492 }
493 {
494 Squiggly sq = Squiggly::Create( doc, Rect(100,450,250,600) );
495 //sq.SetColor( ColorPt(1,0,0), 3 );
496 sq.SetQuadPoint( 0, QuadPoint( Point( 122,455), Point(240, 545), Point(230, 595), Point(101,500 ) ) );
497 sq.RefreshAppearance();
498 page4.AnnotPushBack( sq );
499 }
500 {
501 Caret cr = Caret::Create( doc, Rect(100,40,129,69) );
502 cr.SetColor( ColorPt(0,0,1), 3 );
503 cr.SetSymbol( "P" );
504 cr.RefreshAppearance();
505 page4.AnnotPushBack( cr );
506 }
507
508
509 Page page5 = doc.PageCreate(Rect(0, 0, 600, 600));
510 ew.Begin(page5); // begin writing to the page
511 ew.End(); // save changes to the current page
512 doc.PagePushBack(page5);
513 FileSpec fs = FileSpec::Create( doc, (input_path + "butterfly.png").c_str(), false );
514 Page page6 = doc.PageCreate(Rect(0, 0, 600, 600));
515 ew.Begin(page6); // begin writing to the page
516 ew.End(); // save changes to the current page
517 doc.PagePushBack(page6);
518
519 {
520 Text txt = Text::Create( doc, Rect( 10, 20, 30, 40 ) );
521 txt.SetIcon( "UserIcon" );
522 txt.SetContents( "User defined icon, unrecognized by appearance generator" );
523 txt.SetColor( ColorPt(0,1,0) );
524 txt.RefreshAppearance();
525 page6.AnnotPushBack( txt );
526 }
527 {
528 Ink ink = Ink::Create( doc, Rect( 100, 400, 200, 550 ) );
529 ink.SetColor( ColorPt(0,0,1) );
530 ink.SetPoint( 1, 3, Point( 220, 505) );
531 ink.SetPoint( 1, 0, Point( 100, 490) );
532 ink.SetPoint( 0, 1, Point( 120, 410) );
533 ink.SetPoint( 0, 0, Point( 100, 400) );
534 ink.SetPoint( 1, 2, Point( 180, 490) );
535 ink.SetPoint( 1, 1, Point( 140, 440) );
536 ink.SetBorderStyle( Annot::BorderStyle( Annot::BorderStyle::e_solid, 3, 0, 0 ) );
537 ink.RefreshAppearance();
538 page6.AnnotPushBack( ink );
539 }
540
541
542 Page page7 = doc.PageCreate(Rect(0, 0, 600, 600));
543 ew.Begin(page7); // begin writing to the page
544 ew.End(); // save changes to the current page
545 doc.PagePushBack(page7);
546
547 {
548 Sound snd = Sound::Create( doc, Rect( 100, 500, 120, 520 ) );
549 snd.SetColor( ColorPt(1,1,0) );
550 snd.SetIcon( Sound::e_Speaker );
551 snd.RefreshAppearance();
552 page7.AnnotPushBack( snd );
553 }
554 {
555 Sound snd = Sound::Create( doc, Rect( 200, 500, 220, 520 ) );
556 snd.SetColor( ColorPt(1,1,0) );
557 snd.SetIcon( Sound::e_Mic );
558 snd.RefreshAppearance();
559 page7.AnnotPushBack( snd );
560 }
561
562
563
564
565 Page page8 = doc.PageCreate(Rect(0, 0, 600, 600));
566 ew.Begin(page8); // begin writing to the page
567 ew.End(); // save changes to the current page
568 doc.PagePushBack(page8);
569
570 for( int ipage =0; ipage < 2; ++ipage ) {
571 double px = 5, py = 520;
572 for( RubberStamp::Icon istamp = RubberStamp::e_Approved;
573 istamp <= RubberStamp::e_Draft;
574 istamp = static_cast<RubberStamp::Icon>( static_cast<int>(istamp) + 1 ) ) {
575 RubberStamp st = RubberStamp::Create( doc, Rect(1,1,100,100) );
576 st.SetIcon( istamp );
577 st.SetContents( UString( st.GetIconName() ) );
578 st.SetRect( Rect(px, py, px+100, py+25 ) );
579 py -= 100;
580 if( py < 0 ) {
581 py = 520;
582 px += 200;
583 }
584 if( ipage == 0 )
585 //page7.AnnotPushBack( st );
586 ;
587 else {
588 page8.AnnotPushBack( st );
589 st.RefreshAppearance();
590 }
591 }
592 }
593 RubberStamp st = RubberStamp::Create( doc, Rect(400,5,550,45) );
594 st.SetIcon( "UserStamp" );
595 st.SetContents( "User defined stamp" );
596 page8.AnnotPushBack( st );
597 st.RefreshAppearance();
598
599
600
601}
602
603
604
605
606int main(int argc, char *argv[])
607{
608 int ret = 0;
609 PDFNet::Initialize(LicenseKey);
610
611 std::string output_path = "../../TestFiles/Output/";
612
613 try
614 {
615 PDFDoc doc((input_path + "numbered.pdf").c_str());
616 doc.InitSecurityHandler();
617
618 // An example of using SDF/Cos API to add any type of annotations.
619 AnnotationLowLevelAPI(doc);
620 doc.Save((output_path + "annotation_test1.pdf").c_str(), SDFDoc::e_linearized, 0);
621 cout << "Done. Results saved in annotation_test1.pdf" << endl;
622
623 // An example of using the high-level PDFNet API to read existing annotations,
624 // to edit existing annotations, and to create new annotation from scratch.
625 AnnotationHighLevelAPI(doc);
626 doc.Save((output_path + "annotation_test2.pdf").c_str(), SDFDoc::e_linearized, 0);
627 cout << "Done. Results saved in annotation_test2.pdf" << endl;
628
629 // an example of creating various annotations in a brand new document
630 PDFDoc doc1;
631 CreateTestAnnots( doc1 );
632 doc1.Save(output_path + "new_annot_test_api.pdf", SDFDoc::e_linearized, 0);
633 cout << "Saved new_annot_test_api.pdf" << std::endl;
634 }
635 catch(Common::Exception& e)
636 {
637 cout << e << std::endl;
638 ret = 1;
639 }
640 catch(...)
641 {
642 cout << "Unknown Exception" << std::endl;
643 ret = 1;
644 }
645
646 PDFNet::Terminate();
647 return ret;
648}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales