Bookmarks

Sample Obj-C code to use Apryse SDK for programmatically reading and editing existing outline items, and for creating new PDF bookmarks using the high-level API. Learn more about our iOS SDK and PDF Editing & Manipulation 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#include <stdio.h>
9
10//-----------------------------------------------------------------------------------------
11// The sample code illustrates how to read and edit existing outline items and create
12// new bookmarks using the high-level API.
13//-----------------------------------------------------------------------------------------
14
15void PrintIndent(PTBookmark *item)
16{
17 int ident = [item GetIndent] - 1;
18 int i=0;
19 for (int i=0; i<ident; ++i) printf(" ");
20}
21
22// Prints out the outline tree to the standard output
23void PrintOutlineTree(PTBookmark *item)
24{
25 for (; [item IsValid]; item=[item GetNext])
26 {
27 PrintIndent(item);
28 if ([item IsOpen]) {
29 printf("- %s ACTION -> ", [[item GetTitle] UTF8String]);
30 }
31 else {
32 printf("+ %s ACTION -> ", [[item GetTitle] UTF8String]);
33 }
34
35 // Print Action
36 PTAction *action = [item GetAction];
37 if ([action IsValid]) {
38 if ([action GetType] == e_ptGoTo) {
39 PTDestination *dest = [action GetDest];
40 if ([dest IsValid]) {
41 PTPage *page = [dest GetPage];
42 printf("GoTo Page #%d\n", [page GetIndex]);
43 }
44 }
45 else {
46 puts("Not a 'GoTo' action");
47 }
48 } else {
49 puts("NULL");
50 }
51
52 if ([item HasChildren]) // Recursively print children sub-trees
53 {
54 PrintOutlineTree([item GetFirstChild]);
55 }
56 }
57}
58
59int main(int argc, char *argv[])
60{
61 @autoreleasepool {
62 int ret = 0;
63 [PTPDFNet Initialize: 0];
64
65 // The following example illustrates how to create and edit the outline tree
66 // using high-level Bookmark methods.
67 @try
68 {
69 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/numbered.pdf"];
70 [doc InitSecurityHandler];
71
72 // Lets first create the root bookmark items.
73 PTBookmark *red = [PTBookmark Create: doc in_title: @"Red"];
74 PTBookmark *green = [PTBookmark Create: doc in_title: @"Green"];
75 PTBookmark *blue = [PTBookmark Create: doc in_title: @"Blue"];
76
77 [doc AddRootBookmark: red];
78 [doc AddRootBookmark: green];
79 [doc AddRootBookmark: blue];
80
81 // You can also add new root bookmarks using Bookmark.AddNext("...")
82 [blue AddNextWithTitle: @"foo"];
83 [blue AddNextWithTitle: @"bar"];
84
85 // We can now associate new bookmarks with page destinations:
86
87 // The following example creates an 'explicit' destination (see
88 // section '8.2.1 Destinations' in PDF Reference for more details)
89 PTDestination *red_dest = [PTDestination CreateFit: [doc GetPage: 1]];
90 [red SetAction: [PTAction CreateGoto: red_dest]];
91
92 // Create an explicit destination to the first green page in the document
93 [green SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 10]]]];
94
95 // The following example creates a 'named' destination (see
96 // section '8.2.1 Destinations' in PDF Reference for more details)
97 // Named destinations have certain advantages over explicit destinations.
98 char* buf = "blue1";
99 NSData* key = [NSData dataWithBytes: (const void*)buf length: 5];
100 PTAction *blue_action = [PTAction CreateGotoWithNamedDestination: key key_sz: 5 dest: [PTDestination CreateFit: [doc GetPage: 19]]];
101
102 [blue SetAction: blue_action];
103
104 // We can now add children Bookmarks
105 PTBookmark *sub_red1 = [red AddChildWithTitle: @"Red - Page 1"];
106 [sub_red1 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 1]]]];
107 PTBookmark *sub_red2 = [red AddChildWithTitle: @"Red - Page 2"];
108 [sub_red2 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 2]]]];
109 PTBookmark *sub_red3 = [red AddChildWithTitle: @"Red - Page 3"];
110 [sub_red3 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 3]]]];
111 PTBookmark *sub_red4 = [sub_red3 AddChildWithTitle: @"Red - Page 4"];
112 [sub_red4 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 4]]]];
113 PTBookmark *sub_red5 = [sub_red3 AddChildWithTitle: @"Red - Page 5"];
114 [sub_red5 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 5]]]];
115 PTBookmark *sub_red6 = [sub_red3 AddChildWithTitle: @"Red - Page 6"];
116 [sub_red6 SetAction: [PTAction CreateGoto: [PTDestination CreateFit: [doc GetPage: 6]]]];
117
118 // Example of how to find and delete a bookmark by title text.
119 PTBookmark *foo = [[doc GetFirstBookmark] Find: @"foo"];
120 if ([foo IsValid])
121 {
122 [foo Delete];
123 }
124 else
125 {
126 assert(FALSE);
127 }
128
129 PTBookmark *bar = [[doc GetFirstBookmark] Find: @"bar"];
130 if ([bar IsValid])
131 {
132 [bar Delete];
133 }
134 else
135 {
136 assert(FALSE);
137 }
138
139 // Adding color to Bookmarks. Color and other formatting can help readers
140 // get around more easily in large PDF documents.
141 [red SetColor: 1 in_g: 0 in_b: 0];
142 [green SetColor: 0 in_g: 1 in_b: 0];
143 [green SetFlags: 2]; // set bold font
144 [blue SetColor: 0 in_g: 0 in_b: 1];
145 [blue SetFlags: 3]; // set bold and italic
146
147 [doc SaveToFile: @"../../TestFiles/Output/bookmark.pdf" flags: 0];
148 puts("Done. Result saved in bookmark.pdf");
149 }
150 @catch(NSException *e)
151 {
152 printf("%s\n", [e.reason UTF8String]);
153 ret = 1;
154 }
155
156
157 // The following example illustrates how to traverse the outline tree using
158 // Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(),
159 // Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
160 @try
161 {
162 // Open the document that was saved in the previous code sample
163 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/Output/bookmark.pdf"];
164 [doc InitSecurityHandler];
165
166 PTBookmark *root = [doc GetFirstBookmark];
167 PrintOutlineTree(root);
168
169 puts("Done.");
170 }
171 @catch(NSException *e)
172 {
173 printf("%s\n", [e.reason UTF8String]);
174 ret = 1;
175 }
176
177 // The following example illustrates how to create a Bookmark to a page
178 // in a remote document. A remote go-to action is similar to an ordinary
179 // go-to action, but jumps to a destination in another PDF file instead
180 // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF
181 // Reference Manual for details.
182 @try
183 {
184 // Open the document that was saved in the previous code sample
185 PTPDFDoc *doc = [[PTPDFDoc alloc] initWithFilepath: @"../../TestFiles/Output/bookmark.pdf"];
186 [doc InitSecurityHandler];
187
188 // Create file specification (the file referred to by the remote bookmark)
189 PTObj * file_spec = [doc CreateIndirectDict];
190 [file_spec PutName: @"Type" name: @"Filespec"];
191 [file_spec PutString: @"F" value: @"bookmark.pdf"];
192 PTFileSpec *spec = [[PTFileSpec alloc] initWithF: file_spec];
193 PTAction *goto_remote = [PTAction CreateGotoRemoteWithNewWindow: spec page_num: 5 new_window: TRUE];
194
195 PTBookmark *remoteBookmark1 = [PTBookmark Create: doc in_title: @"REMOTE BOOKMARK 1"];
196 [remoteBookmark1 SetAction: goto_remote];
197 [doc AddRootBookmark: remoteBookmark1];
198
199 // Create another remote bookmark, but this time using the low-level SDF/Cos API.
200 // Create a remote action
201 PTBookmark *remoteBookmark2 = [PTBookmark Create: doc in_title: @"REMOTE BOOKMARK 2"];
202 [doc AddRootBookmark: remoteBookmark2];
203
204 PTObj * gotoR = [[remoteBookmark2 GetSDFObj] PutDict: @"A"];
205 {
206 [gotoR PutName: @"S" name: @"GoToR"]; // Set action type
207 [gotoR PutBool: @"NewWindow" value: TRUE];
208
209 // Set the file specification
210 [gotoR Put: @"F" obj: file_spec];
211
212 // jump to the first page. Note that pages are indexed from 0.
213 PTObj * dest = [gotoR PutArray: @"D"]; // Set the destination
214 [dest PushBackNumber: 9];
215 [dest PushBackName: @"Fit"];
216 }
217
218 [doc SaveToFile: @"../../TestFiles/Output/bookmark_remote.pdf" flags: e_ptlinearized];
219
220 puts("Done. Result saved in bookmark_remote.pdf");
221 }
222 @catch(NSException *e)
223 {
224 printf("%s\n", [e.reason UTF8String]);
225 ret = 1;
226 }
227 [PTPDFNet Terminate: 0];
228 return ret;
229 }
230}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales