Annotation

Sample Obj-C code to use Apryse 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 iOS 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#import <OBJC/PDFNetOBJC.h>
7#import <Foundation/Foundation.h>
8
9//std::string output_path = "../../TestFiles/Output/";
10//std::string input_path = "../../TestFiles/";
11
12void AnnotationHighLevelAPI(PTPDFDoc *doc)
13{
14 // The following code snippet traverses all annotations in the document
15 NSLog(@"Traversing all annotations in the document...");
16
17 int page_num = 1;
18 PTPageIterator* itr;
19 for (itr = [doc GetPageIterator: 1]; [itr HasNext]; [itr Next])
20 {
21 NSLog(@"Page %d: ", page_num++);
22
23 PTPage* page = [itr Current];
24 int num_annots = [page GetNumAnnots];
25 int i = 0;
26 for (i=0; i<num_annots; ++i)
27 {
28 PTAnnot* annot = [page GetAnnot: i];
29 if (![annot IsValid]) continue;
30 NSLog(@"Annot Type: %@", [[[[annot GetSDFObj] Get: @"Subtype"] Value] GetName]);
31
32 PTPDFRect* bbox = [annot GetRect];
33
34 NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
35 formatter.numberStyle = NSNumberFormatterDecimalStyle;
36 formatter.maximumFractionDigits = 4;
37 NSString *x1 = [formatter stringFromNumber:[NSNumber numberWithDouble:[bbox GetX1]]];
38 NSString *y1 = [formatter stringFromNumber:[NSNumber numberWithDouble:[bbox GetY1]]];
39 NSString *x2 = [formatter stringFromNumber:[NSNumber numberWithDouble:[bbox GetX2]]];
40 NSString *y2 = [formatter stringFromNumber:[NSNumber numberWithDouble:[bbox GetY2]]];
41
42 NSLog(@" Position: %s, %s, %s, %s", [x1 UTF8String], [y1 UTF8String], [x2 UTF8String], [y2 UTF8String]);
43
44 switch ([annot GetType])
45 {
46 case e_ptLink:
47 {
48 PTLink *link = [[PTLink alloc] initWithAnn: annot];
49 PTAction* action = [link GetAction];
50 if (![action IsValid])
51 {
52 continue;
53 }
54 if ([action GetType] == e_ptGoTo)
55 {
56 PTDestination* dest = [action GetDest];
57 if (![dest IsValid]) {
58 NSLog(@" Destination is not valid\n");
59 }
60 else {
61 int page_num = [[dest GetPage] GetIndex];
62 NSLog(@" Links to: page number %d in this document\n", page_num);
63 }
64 }
65 else if ([action GetType] == e_ptURI)
66 {
67 NSString *uri = [[[[action GetSDFObj] Get: @"URI"] Value] GetAsPDFText];
68 NSLog(@" Links to: %@\n", uri);
69 }
70 // ...
71 }
72 break;
73 case e_ptWidget:
74 break;
75 case e_ptFileAttachment:
76 break;
77 // ...
78 default:
79 break;
80 }
81 }
82 }
83
84 // Use the high-level API to create new annotations.
85 PTPage *first_page = [doc GetPage:1];
86
87 // Create a hyperlink...
88 PTLink *hyperlink = [PTLink CreateWithAction: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 85 y1: 570 x2: 503 y2: 524] action: [PTAction CreateURI: [doc GetSDFDoc] uri: @"http://www.pdftron.com"]];
89 [first_page AnnotPushBack: hyperlink];
90
91 // Create an intra-document link...
92 PTAction *goto_page_3 = [PTAction CreateGoto: [PTDestination CreateFitH: [doc GetPage:3] top: 0]];
93 PTLink *link = [PTLink CreateWithAction: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 85 y1: 458 x2: 503 y2: 502] action: goto_page_3];
94
95 [link SetColor: [[PTColorPt alloc] initWithX: 0 y:0 z:1 w:0] numcomp: 3];
96
97 // Add the new annotation to the first page
98 [first_page AnnotPushBack: link];
99
100 // Create a stamp annotation ...
101 PTRubberStamp *stamp = [PTRubberStamp Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 30 y1: 30 x2: 300 y2: 200] icon: e_ptDraft];
102 [stamp SetRubberStampIconName: @"Draft"];
103 [first_page AnnotPushBack: stamp];
104
105 // Create a file attachment annotation (embed the 'peppers.jpg').
106 PTFileAttachment *file_attach = [PTFileAttachment CreateFileAttchWithPath: [doc GetSDFDoc] pos:[[PTPDFRect alloc] initWithX1: 80 y1: 280 x2: 108 y2: 320] path: @"../../TestFiles/peppers.jpg" icon_name: e_ptPushPin];
107 [first_page AnnotPushBack: file_attach];
108
109 PTInk* ink = [PTInk Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 110 y1: 10 x2: 300 y2: 200]];
110 PTPDFPoint* pt3 = [[PTPDFPoint alloc] initWithPx: 110 py: 10];
111 //pt3.x = 110; pt3.y = 10;
112 [ink SetPoint: 0 pointindex: 0 pt: pt3];
113 [pt3 setX: 150]; [pt3 setY: 50];
114 [ink SetPoint: 0 pointindex: 1 pt: pt3];
115 [pt3 setX: 190]; [pt3 setY: 60];
116 [ink SetPoint: 0 pointindex: 2 pt: pt3];
117 [pt3 setX: 180]; [pt3 setY: 90];
118 [ink SetPoint: 1 pointindex: 0 pt: pt3];
119 [pt3 setX: 190]; [pt3 setY: 95];
120 [ink SetPoint: 1 pointindex: 1 pt: pt3];
121 [pt3 setX: 200]; [pt3 setY: 100];
122 [ink SetPoint: 1 pointindex: 2 pt: pt3];
123 [pt3 setX: 166]; [pt3 setY: 86];
124 [ink SetPoint: 2 pointindex: 0 pt: pt3];
125 [pt3 setX: 196]; [pt3 setY: 96];
126 [ink SetPoint: 2 pointindex: 1 pt: pt3];
127 [pt3 setX: 221]; [pt3 setY: 121];
128 [ink SetPoint: 2 pointindex: 2 pt: pt3];
129 [pt3 setX: 288]; [pt3 setY: 188];
130 [ink SetPoint: 2 pointindex: 3 pt: pt3];
131 [ink SetColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 1 w: 0] numcomp: 3];
132 [first_page AnnotPushBack: ink];
133
134 //Create a Polygon annotation..
135 //Polygon *poly2 = [Polygon Create: doc PDFRect[100, 60, 300, 480]];
136 //Point *pllp;
137 //pllp.x=105;
138 //pllp.y=68;
139 //poly2.SetVertex(0, pllp);
140 //pllp.x=155;
141 //pllp.y=92;
142 //poly2.SetVertex(1, pllp);
143 //pllp.x=189;
144 //pllp.y=133;
145 //poly2.SetVertex(2, pllp);
146 //pllp.x=200;
147 //pllp.y=140;
148 //poly2.SetVertex(3, pllp);
149 //pllp.x=230;
150 //pllp.y=389;
151 //poly2.SetVertex(4, pllp);
152 //pllp.x=300;
153 //pllp.y=405;
154 //poly2.SetVertex(5, pllp);
155 //poly2.SetColor(ColorPt(0, 0, 1), 3);
156 //poly2.SetInteriorColor(ColorPt(1, 0, 0), 3);
157 //first_page.AnnotPushBack(poly2);
158
159 // ...
160}
161
162void AnnotationLowLevelAPI(PTPDFDoc *doc)
163{
164 PTPage* page = [doc GetPage: 1];
165
166 PTObj* annots = [page GetAnnots];
167
168 if (!annots)
169 {
170 // If there are no annotations, create a new annotation
171 // array for the page.
172 annots = [doc CreateIndirectArray];
173 [[page GetSDFObj] Put: @"Annots" obj:annots];
174 }
175
176 // Create a Text annotation
177 PTObj * annot = [doc CreateIndirectDict];
178 [annot PutName: @"Subtype" name: @"Text"];
179 [annot PutBool: @"Open" value: YES];
180 [annot PutString: @"Contents" value: @"The quick brown fox ate the lazy mouse."];
181 [annot PutRect: @"Rect" x1:266 y1:116 x2:430 y2:204];
182
183 // Insert the annotation in the page annotation array
184 [annots PushBack:annot ];
185
186 // Create a Link annotation
187 PTObj * link1 = [doc CreateIndirectDict];
188 [link1 PutName: @"Subtype" name: @"Link"];
189 PTDestination *dest = [PTDestination CreateFit: [doc GetPage: 2]];
190 [link1 Put: @"Dest" obj:[dest GetSDFObj]];
191 [link1 PutRect: @"Rect" x1:85 y1:705 x2:503 y2:661];
192 [annots PushBack: link1];
193
194 // Create another Link annotation
195 PTObj * link2 = [doc CreateIndirectDict];
196 [link2 PutName: @"Subtype" name: @"Link"];
197 PTDestination *dest2 = [PTDestination CreateFit: [doc GetPage:3]];
198 [link2 Put: @"Dest" obj:[dest2 GetSDFObj]];
199 [link2 PutRect: @"Rect" x1:85 y1:638 x2:503 y2:594];
200 [annots PushBack: link2];
201
202 // Note that PDFNet API can be used to modify existing annotations.
203 // In the following example we will modify the second link annotation
204 // (link2) so that it points to the 10th page. We also use a different
205 // destination page fit type.
206
207 // link2 = annots.GetAt(annots.Size()-1);
208 [link2 Put: @"Dest" obj: [[PTDestination CreateXYZ: [doc GetPage: 10] left:100 top:792-70 zoom:10] GetSDFObj]];
209
210 // Create a third link annotation with a hyperlink action (all other
211 // annotation types can be created in a similar way)
212 PTObj * link3 = [doc CreateIndirectDict];
213 [link3 PutName: @"Subtype" name: @"Link"];
214 [link3 PutRect: @"Rect" x1:85 y1:570 x2:503 y2:524];
215
216 // Create a URI action
217 PTObj * action = [link3 PutDict: @"A"];
218 [action PutName: @"S" name: @"URI"];
219 [action PutString: @"URI" value: @"http://www.pdftron.com"];
220
221 [annots PushBack: link3];
222}
223
224void CreateTestAnnots(PTPDFDoc *doc)
225{
226 PTElementWriter *ew = [[PTElementWriter alloc] init];
227 PTElementBuilder *eb = [[PTElementBuilder alloc] init];
228 PTElement *element = [[PTElement alloc] init];
229
230 PTPage *first_page = [doc PageCreate: [[PTPDFRect alloc] initWithX1: 0 y1: 0 x2: 600 y2: 600]];
231 [doc PagePushBack: first_page];
232 [ew WriterBeginWithPage: first_page placement: e_ptoverlay page_coord_sys: NO compress: NO resources: NULL]; // begin writing to this page
233 [ew End]; // save changes to the current page
234
235 //
236 // Test of a free text annotation.
237 //
238 {
239 PTFreeText *txtannot = [PTFreeText Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 10 y1: 400 x2: 160 y2: 570]];
240 [txtannot SetContents: @"\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
241 "\n\nAha!\n\nAnd there was much rejoicing!"];
242 //std::vector<double> dash( 2, 2.0 );
243 [txtannot SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptsolid b_width: 1 b_hr: 10 b_vr: 20] oldStyleOnly: YES];
244 [txtannot SetQuaddingFormat: 0];
245 [first_page AnnotPushBack: txtannot];
246 [txtannot RefreshAppearance];
247 }
248 {
249 PTFreeText *txtannot = [PTFreeText Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 100 y1: 100 x2: 350 y2: 500]];
250 [txtannot SetContentRect: [[PTPDFRect alloc] initWithX1: 200 y1: 200 x2: 350 y2: 500]];
251 [txtannot SetContents: @"\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
252 "\n\nAha!\n\nAnd there was much rejoicing!"];
253 [txtannot SetCalloutLinePointsWithKneePoint: [[PTPDFPoint alloc] initWithPx: 200 py: 300] p2: [[PTPDFPoint alloc] initWithPx: 150 py: 290] p3: [[PTPDFPoint alloc] initWithPx: 110 py: 110]];
254 //std::vector<double> dash( 2, 2.0 );
255 [txtannot SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptsolid b_width: 1 b_hr: 10 b_vr: 20 ] oldStyleOnly: YES];
256 [txtannot SetEndingStyle: e_ptClosedArrow];
257 [txtannot SetColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 0 w: 0] numcomp: 3];
258 [txtannot SetQuaddingFormat: 1];
259 [first_page AnnotPushBack: txtannot];
260 [txtannot RefreshAppearance];
261 }
262 {
263 PTFreeText *txtannot = [PTFreeText Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 400 y1: 10 x2: 550 y2: 400]];
264 [txtannot SetContents: @"\n\nSome swift brown fox snatched a gray hare out of the air by freezing it with an angry glare."
265 "\n\nAha!\n\nAnd there was much rejoicing!"];
266 [txtannot SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptsolid b_width: 1 b_hr: 10 b_vr: 20 ] oldStyleOnly: YES];
267 [txtannot SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 1 w: 0] numcomp: 3];
268 [txtannot SetOpacity: 0.2 ];
269 [txtannot SetQuaddingFormat: 2];
270 [first_page AnnotPushBack: txtannot];
271 [txtannot RefreshAppearance];
272 }
273
274 PTPage *page = [doc PageCreate: [[PTPDFRect alloc] initWithX1: 0 y1: 0 x2: 600 y2: 600]];
275 [doc PagePushBack: page];
276 [ew WriterBeginWithPage: page placement: e_ptoverlay page_coord_sys: YES compress: YES resources: NULL]; // begin writing to this page
277 [eb Reset: [[PTGState alloc] init]]; // Reset the GState to default
278 [ew End]; // save changes to the current page
279
280 {
281 //Create a Line annotation...
282 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 250 y1: 250 x2: 400 y2: 400]];
283 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 350 py: 270]];
284 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 260 py: 370]];
285 [line SetStartStyle: e_ptl_Square];
286 [line SetEndStyle: e_ptl_Circle];
287 [line SetColor: [[PTColorPt alloc] initWithX: 0.3 y: 0.5 z: 0 w: 0] numcomp: 3];
288 [line SetContents: @"Dashed Captioned"];
289 [line SetShowCaption: YES];
290 [line SetCaptionPosition: e_ptTop ];
291 NSMutableArray *dash = [NSMutableArray arrayWithCapacity: 2];
292 [dash addObject: @2.0];
293 [dash addObject: @2.0];
294 [line SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptdashed b_width: 2 b_hr: 0 b_vr: 0 b_dash: dash] oldStyleOnly: NO];
295 [line RefreshAppearance];
296 [page AnnotPushBack: line];
297 }
298 {
299 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 347 y1: 377 x2: 600 y2: 600]];
300 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 385 py: 410]];
301 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 540 py: 555]];
302 [line SetStartStyle: e_ptl_Circle];
303 [line SetEndStyle: e_ptOpenArrow];
304 [line SetColor: [[PTColorPt alloc] initWithX: 1 y: 0 z: 0 w: 0] numcomp: 3];
305 [line SetContents: @"Inline Caption"];
306 [line SetShowCaption: YES];
307 [line SetCaptionPosition: e_ptInline ];
308 [line SetLeaderLineExtensionLength: 4];
309 [line SetLeaderLineLength: -12 ];
310 [line SetLeaderLineOffset: 2];
311 [line RefreshAppearance];
312 [page AnnotPushBack: line];
313 }
314 {
315 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 10 y1: 400 x2: 200 y2: 600]];
316 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 25 py: 426]];
317 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 180 py: 555]];
318 [line SetStartStyle: e_ptl_Circle];
319 [line SetEndStyle: e_ptl_Square];
320 [line SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 1 w: 0] numcomp: 3];
321 [line SetInteriorColor: [[PTColorPt alloc] initWithX: 1 y: 0 z: 0 w: 0] CompNum: 3];
322 [line SetContents: @"Offset Caption"];
323 [line SetShowCaption: YES];
324 [line SetCaptionPosition: e_ptTop ];
325 [line SetTextHOffset: -60];
326 [line SetTextVOffset: 10];
327 [line RefreshAppearance];
328 [page AnnotPushBack: line];
329 }
330 {
331 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 200 y1: 10 x2: 400 y2: 70]];
332 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 220 py: 25]];
333 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 370 py: 60]];
334 [line SetStartStyle: e_ptButt];
335 [line SetEndStyle: e_ptOpenArrow];
336 [line SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 1 w: 0] numcomp: 3];
337 [line SetContents: @"Regular Caption"];
338 [line SetShowCaption: YES];
339 [line SetCaptionPosition: e_ptTop ];
340 [line RefreshAppearance];
341 [page AnnotPushBack: line];
342 }
343 {
344 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 200 y1: 70 x2: 400 y2: 130]];
345 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 220 py: 111]];
346 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 370 py: 78]];
347 [line SetStartStyle: e_ptl_Circle];
348 [line SetEndStyle: e_ptDiamond];
349 [line SetContents: @"Circle to Diamond"];
350 [line SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 1 w: 0] numcomp: 3];
351 [line SetInteriorColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 0 w: 0] CompNum: 3];
352 [line SetShowCaption: YES];
353 [line SetCaptionPosition: e_ptTop];
354 [line RefreshAppearance];
355 [page AnnotPushBack: line];
356 }
357 {
358 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 10 y1: 100 x2: 160 y2: 200]];
359 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 15 py: 110]];
360 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 150 py: 190]];
361 [line SetStartStyle: e_ptSlash];
362 [line SetEndStyle: e_ptClosedArrow];
363 [line SetContents: @"Slash to CArrow"];
364 [line SetColor: [[PTColorPt alloc] initWithX: 1 y: 0 z: 0 w: 0] numcomp: 3];
365 [line SetInteriorColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 1 w: 0] CompNum: 3];
366 [line SetShowCaption: YES];
367 [line SetCaptionPosition: e_ptTop];
368 [line RefreshAppearance];
369 [page AnnotPushBack: line];
370 }
371 {
372 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 270 y1: 270 x2: 570 y2: 433]];
373 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 300 py: 400]];
374 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 550 py: 300]];
375 [line SetStartStyle: e_ptRClosedArrow];
376 [line SetEndStyle: e_ptROpenArrow];
377 [line SetContents: @"ROpen & RClosed arrows"];
378 [line SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 1 w: 0] numcomp: 3];
379 [line SetInteriorColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 0 w: 0] CompNum: 3];
380 [line SetShowCaption: YES];
381 [line SetCaptionPosition: e_ptTop];
382 [line RefreshAppearance];
383 [page AnnotPushBack: line];
384 }
385 {
386 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 195 y1: 395 x2: 205 y2: 505]];
387 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 200 py: 400]];
388 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 200 py: 500]];
389 [line RefreshAppearance];
390 [page AnnotPushBack: line];
391 }
392 {
393 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 55 y1: 299 x2: 150 y2: 301]];
394 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 55 py: 300]];
395 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 155 py: 300]];
396 [line SetStartStyle: e_ptl_Circle];
397 [line SetEndStyle: e_ptl_Circle];
398 [line SetContents: @"Caption that's longer than its line."];
399 [line SetColor: [[PTColorPt alloc] initWithX: 1 y: 0 z: 1 w: 0] numcomp: 3];
400 [line SetInteriorColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 0 w: 0] CompNum: 3];
401 [line SetShowCaption: YES];
402 [line SetCaptionPosition: e_ptTop];
403 [line RefreshAppearance];
404 [page AnnotPushBack: line];
405 }
406 {
407 PTLineAnnot *line=[PTLineAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 300 y1: 200 x2: 290 y2: 234]];
408 [line SetStartPoint: [[PTPDFPoint alloc] initWithPx: 310 py: 210]];
409 [line SetEndPoint: [[PTPDFPoint alloc] initWithPx: 380 py: 220]];
410 [line SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 0 w: 0] numcomp: 3];
411 [line RefreshAppearance];
412 [page AnnotPushBack: line];
413 }
414
415 PTPage *page3 = [doc PageCreate: [[PTPDFRect alloc] initWithX1: 0 y1: 0 x2: 600 y2: 600]];
416 [ew WriterBeginWithPage: page3 placement: e_ptoverlay page_coord_sys: YES compress: YES resources: NULL]; // begin writing to the page
417 [ew End]; // save changes to the current page
418 [doc PagePushBack: page3];
419 {
420 PTCircle *circle=[PTCircle Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 300 y1: 300 x2: 390 y2: 350]];
421 [circle SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 0 w: 0] numcomp: 3];
422 [circle RefreshAppearance];
423 [page3 AnnotPushBack: circle];
424 }
425 {
426 PTCircle *circle=[PTCircle Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 100 y1: 100 x2: 200 y2: 200]];
427 [circle SetColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 0 w: 0] numcomp: 3];
428 [circle SetInteriorColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 1 w: 0] CompNum: 3];
429 NSMutableArray *dash = [NSMutableArray arrayWithCapacity: 2];
430 [dash addObject: @2.0];
431 [dash addObject: @4.0];
432 [circle SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptdashed b_width: 3 b_hr: 0 b_vr: 0 b_dash: dash] oldStyleOnly: NO];
433 [circle SetPadding: 2];
434 [circle RefreshAppearance];
435 [page3 AnnotPushBack: circle];
436 }
437 {
438 PTSquare *sq = [PTSquare Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 10 y1: 200 x2: 80 y2: 300]];
439 [sq SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 0 w: 0] numcomp: 3];
440 [sq RefreshAppearance];
441 [page3 AnnotPushBack: sq];
442 }
443 {
444 PTSquare *sq = [PTSquare Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 500 y1: 200 x2: 580 y2: 300]];
445 [sq SetColor: [[PTColorPt alloc] initWithX: 1 y: 0 z: 0 w: 0] numcomp: 3];
446 [sq SetInteriorColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 1 w: 0] CompNum: 3];
447 NSMutableArray *dash = [NSMutableArray arrayWithCapacity: 2];
448 [dash addObject: @4.0];
449 [dash addObject: @2.0];
450 [sq SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptdashed b_width: 6 b_hr: 0 b_vr: 0 b_dash: dash] oldStyleOnly: NO];
451 [sq SetPadding: 4];
452 [sq RefreshAppearance];
453 [page3 AnnotPushBack: sq];
454 }
455 {
456 PTPolygon *poly = [PTPolygon Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 5 y1: 500 x2: 125 y2: 590]];
457 [poly SetColor: [[PTColorPt alloc] initWithX: 1 y: 0 z: 0 w: 0] numcomp: 3];
458 [poly SetInteriorColor: [[PTColorPt alloc] initWithX: 1 y: 1 z: 0 w: 0] CompNum: 3];
459 [poly SetVertex: 0 pt: [[PTPDFPoint alloc] initWithPx: 12 py: 510]];
460 [poly SetVertex: 1 pt: [[PTPDFPoint alloc] initWithPx: 100 py: 510]];
461 [poly SetVertex: 2 pt: [[PTPDFPoint alloc] initWithPx: 100 py: 555]];
462 [poly SetVertex: 3 pt: [[PTPDFPoint alloc] initWithPx: 35 py: 544]];
463 [poly SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptsolid b_width: 4 b_hr: 0 b_vr: 0] oldStyleOnly: NO];
464 [poly SetPadding: 4];
465 [poly RefreshAppearance];
466 [page3 AnnotPushBack: poly];
467 }
468 {
469 PTPolygon *poly = [PTPolygon Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 400 y1: 10 x2: 500 y2: 90]];
470 [poly SetColor: [[PTColorPt alloc] initWithX: 1 y: 0 z: 0 w: 0] numcomp: 3];
471 [poly SetInteriorColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 0 w: 0] CompNum: 3];
472 [poly SetVertex: 0 pt: [[PTPDFPoint alloc] initWithPx: 405 py: 20]];
473 [poly SetVertex: 1 pt: [[PTPDFPoint alloc] initWithPx: 440 py: 40]];
474 [poly SetVertex: 2 pt: [[PTPDFPoint alloc] initWithPx: 410 py: 60]];
475 [poly SetVertex: 3 pt: [[PTPDFPoint alloc] initWithPx: 470 py: 80]];
476 [poly SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptsolid b_width: 2 b_hr: 0 b_vr: 0] oldStyleOnly: NO];
477 [poly SetPadding: 4];
478 [poly SetStartStyle: e_ptRClosedArrow];
479 [poly SetEndStyle: e_ptClosedArrow];
480 [poly RefreshAppearance];
481 [page3 AnnotPushBack: poly];
482 }
483 {
484 PTLink *lk = [PTLink Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 5 y1: 5 x2: 55 y2: 24]];
485 //lk.SetColor( ColorPt(0,1,0), 3 );
486 [lk RefreshAppearance];
487 [page3 AnnotPushBack: lk];
488 }
489
490
491 PTPage *page4 = [doc PageCreate: [[PTPDFRect alloc] initWithX1: 0 y1: 0 x2: 600 y2: 600]];
492 [ew WriterBeginWithPage: page4 placement: e_ptoverlay page_coord_sys: YES compress: YES resources: NULL]; // begin writing to the page
493 [ew End]; // save changes to the current page
494 [doc PagePushBack: page4];
495
496 {
497 [ew WriterBeginWithPage: page4 placement: e_ptoverlay page_coord_sys: YES compress: YES resources: NULL];
498 PTFont *font = [PTFont Create: [doc GetSDFDoc] type: e_pthelvetica embed: NO];
499 element = [eb CreateTextBeginWithFont: font font_sz: 16];
500 [element SetPathFill: YES];
501 [ew WriteElement: element];
502 element = [eb CreateTextRunWithFont: @"Some random text on the page" font: font font_sz: 16];
503 [element SetTextMatrix: 1 b: 0 c: 0 d: 1 h: 100 v: 500];
504 [ew WriteElement: element];
505 [ew WriteElement: [eb CreateTextEnd]];
506 [ew End];
507 }
508 {
509 PTHighlightAnnot *hl = [PTHighlightAnnot Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 100 y1: 490 x2: 150 y2: 515]];
510 [hl SetColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 0 w: 0] numcomp: 3];
511 [hl RefreshAppearance];
512 [page4 AnnotPushBack: hl];
513 }
514 {
515 PTSquiggly *sq = [PTSquiggly Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 100 y1: 450 x2: 250 y2: 600]];
516 //sq.SetColor( ColorPt(1,0,0), 3 );
517 PTPDFPoint *p1 = [[PTPDFPoint alloc] initWithPx: 122 py: 455];
518 PTPDFPoint *p2 = [[PTPDFPoint alloc] initWithPx: 240 py: 545];
519 PTPDFPoint *p3 = [[PTPDFPoint alloc] initWithPx: 230 py: 595];
520 PTPDFPoint *p4 = [[PTPDFPoint alloc] initWithPx: 101 py: 500];
521 [sq SetQuadPoint: 0 qp: [[PTQuadPoint alloc] initWithP11: p1 p22: p2 p33: p3 p44: p4]];
522 [sq RefreshAppearance];
523 [page4 AnnotPushBack: sq];
524 }
525 {
526 PTCaret *cr = [PTCaret Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 100 y1: 40 x2: 129 y2: 69]];
527 [cr SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 1 w: 0] numcomp: 3];
528 [cr SetSymbol: @"P"];
529 [cr RefreshAppearance];
530 [page4 AnnotPushBack: cr];
531 }
532
533
534 PTPage *page5 = [doc PageCreate: [[PTPDFRect alloc] initWithX1: 0 y1: 0 x2: 600 y2: 600]];
535 [ew WriterBeginWithPage: page5 placement: e_ptoverlay page_coord_sys: YES compress: YES resources: NULL]; // begin writing to the page
536 [ew End]; // save changes to the current page
537 [doc PagePushBack: page5];
538 PTFileSpec *fs = [PTFileSpec Create: [doc GetSDFDoc] path: [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"butterfly.png"] embed: NO];
539 PTPage *page6 = [doc PageCreate: [[PTPDFRect alloc] initWithX1: 0 y1: 0 x2: 600 y2: 600]];
540 [ew WriterBeginWithPage: page6 placement: e_ptoverlay page_coord_sys: YES compress: YES resources: NULL]; // begin writing to the page
541 [ew End]; // save changes to the current page
542 [doc PagePushBack: page6];
543
544 int ipage;
545 for( ipage =0; ipage < 2; ++ipage ) {
546 int iann;
547 for( iann =0; iann < 100; iann++ ) {
548 if( ! (iann > e_ptTag) ) {
549 PTFileAttachment *fa = [PTFileAttachment CreateFileAttchWithFileSpec: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 50+50*iann y1: 100 x2: 70+50*iann y2: 120] fs: fs icon_name: iann];
550 if(ipage) [fa SetColor: [[PTColorPt alloc] initWithX: 1 y: 1 z: 0 w: 0] numcomp: 3];
551 [fa RefreshAppearance];
552 if( ipage == 0 )
553 [page5 AnnotPushBack: fa];
554 else
555 [page6 AnnotPushBack: fa];
556 }
557 if( iann > e_ptNote ) break;
558 PTText *txt = [PTText Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 10+iann*50 y1: 200 x2: 30+iann*50 y2: 220]];
559 [txt SetTextIconType: iann];
560 [txt SetContents: [txt GetIconName]];
561 if( ipage ) [txt SetColor: [[PTColorPt alloc] initWithX: 1 y: 1 z: 0 w: 0] numcomp: 3];
562 [txt RefreshAppearance];
563 if( ipage == 0 )
564 [page5 AnnotPushBack: txt];
565 else
566 [page6 AnnotPushBack: txt];
567 }
568 }
569 {
570 PTText *txt = [PTText Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 10 y1: 20 x2: 30 y2: 40]];
571 [txt SetTextIconName: @"UserIcon"];
572 [txt SetContents: @"User defined icon, unrecognized by appearance generator"];
573 [txt SetColor: [[PTColorPt alloc] initWithX: 0 y: 1 z: 0 w: 0] numcomp: 3];
574 [txt RefreshAppearance];
575 [page6 AnnotPushBack: txt];
576 }
577 {
578 PTInk *ink = [PTInk Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 100 y1: 400 x2: 200 y2: 550]];
579 [ink SetColor: [[PTColorPt alloc] initWithX: 0 y: 0 z: 1 w: 0] numcomp: 3];
580 [ink SetPoint: 1 pointindex: 3 pt: [[PTPDFPoint alloc] initWithPx: 220 py: 505]];
581 [ink SetPoint: 1 pointindex: 0 pt: [[PTPDFPoint alloc] initWithPx: 100 py: 490]];
582 [ink SetPoint: 0 pointindex: 1 pt: [[PTPDFPoint alloc] initWithPx: 120 py: 410]];
583 [ink SetPoint: 0 pointindex: 0 pt: [[PTPDFPoint alloc] initWithPx: 100 py: 400]];
584 [ink SetPoint: 1 pointindex: 2 pt: [[PTPDFPoint alloc] initWithPx: 180 py: 490]];
585 [ink SetPoint: 1 pointindex: 1 pt: [[PTPDFPoint alloc] initWithPx: 140 py: 440]];
586 [ink SetBorderStyle: [[PTBorderStyle alloc] initWithS: e_ptsolid b_width: 3 b_hr: 0 b_vr: 0] oldStyleOnly: NO];
587 [ink RefreshAppearance];
588 [page6 AnnotPushBack: ink];
589 }
590
591
592 PTPage *page7 = [doc PageCreate: [[PTPDFRect alloc] initWithX1: 0 y1: 0 x2: 600 y2: 600]];
593 [ew WriterBeginWithPage: page7 placement: e_ptoverlay page_coord_sys: YES compress: YES resources: NULL]; // begin writing to the page
594 [ew End]; // save changes to the current page
595 [doc PagePushBack: page7];
596
597 {
598 PTSound *snd = [PTSound Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 100 y1: 500 x2: 120 y2: 520]];
599 [snd SetColor: [[PTColorPt alloc] initWithX: 1 y: 1 z: 0 w: 0] numcomp: 3];
600 [snd SetSoundIconType: e_ptSpeaker];
601 [snd RefreshAppearance];
602 [page7 AnnotPushBack: snd];
603 }
604 {
605 PTSound *snd = [PTSound Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 200 y1: 500 x2: 220 y2: 520]];
606 [snd SetColor: [[PTColorPt alloc] initWithX: 1 y: 1 z: 0 w: 0] numcomp: 3];
607 [snd SetSoundIconType: e_ptMic];
608 [snd RefreshAppearance];
609 [page7 AnnotPushBack: snd];
610 }
611
612
613
614
615 PTPage *page8 = [doc PageCreate: [[PTPDFRect alloc] initWithX1: 0 y1: 0 x2: 600 y2: 600]];
616 [ew WriterBeginWithPage: page8 placement: e_ptoverlay page_coord_sys: YES compress: YES resources: NULL]; // begin writing to the page
617 [ew End]; // save changes to the current page
618 [doc PagePushBack: page8];
619
620 int ipage1;
621 for( ipage1 =0; ipage1 < 2; ++ipage1 ) {
622 double px = 5, py = 520;
623 PTRubberStampIcon istamp;
624 for( istamp = e_ptApproved; istamp <= e_ptDraft; istamp = istamp + 1 ) {
625 PTRubberStamp *st = [PTRubberStamp Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 1 y1: 2 x2: 200 y2: 200] icon:e_ptDraft];
626 [st SetRubberStampIconType: istamp];
627 [st SetContents: [st GetIconName]];
628 [st SetRect: [[PTPDFRect alloc] initWithX1: px y1: py x2: px+100 y2: py+25]];
629 py = py - 100;
630 if( py < 0 ) {
631 py = 520;
632 px = px + 200;
633 }
634 if( ipage == 0 )
635 //[page7 AnnotPushBack: st];
636 ;
637 else {
638 [page8 AnnotPushBack: st];
639 [st RefreshAppearance];
640 }
641 }
642 }
643 PTRubberStamp *st = [PTRubberStamp Create: [doc GetSDFDoc] pos: [[PTPDFRect alloc] initWithX1: 400 y1: 5 x2: 550 y2: 45] icon: e_ptDraft];
644 [st SetRubberStampIconName: @"UserStamp"];
645 [st SetContents: @"User defined stamp"];
646 [page8 AnnotPushBack: st];
647 [st RefreshAppearance];
648}
649
650int main(int argc, char *argv[])
651{
652 @autoreleasepool {
653
654 int ret = 0;
655 [PTPDFNet Initialize: 0];
656
657 @try
658 {
659 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/numbered.pdf"];
660 [doc InitSecurityHandler];
661
662 // An example of using SDF/Cos API to add any type of annotations.
663 AnnotationLowLevelAPI(doc);
664 [doc SaveToFile: @"../../TestFiles/Output/annotation_test1.pdf" flags: e_ptlinearized];
665 NSLog(@"%@", @"Done. Results saved in annotation_test1.pdf");
666
667 // An example of using the high-level PDFNet API to read existing annotations,
668 // to edit existing annotations, and to create new annotation from scratch.
669 AnnotationHighLevelAPI(doc);
670 [doc SaveToFile: @"../../TestFiles/Output/annotation_test2.pdf" flags: e_ptlinearized];
671 NSLog(@"%@", @"Done. Results saved in annotation_test2.pdf");
672
673 // an example of creating various annotations in a brand new document
674 PTPDFDoc *doc1 = [[PTPDFDoc alloc] init];
675 CreateTestAnnots( doc1 );
676 [doc1 SaveToFile: @"../../TestFiles/Output/new_annot_test_api.pdf" flags: e_ptlinearized];
677 NSLog(@"%@", @"Saved new_annot_test_api.pdf");
678 }
679 @catch(NSException *e)
680 {
681 NSLog(@"%@", e.reason);
682 ret = 1;
683 }
684 [PTPDFNet Terminate: 0];
685 return ret;
686
687 }
688
689}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales