1 /*
2  * << Haru Free PDF Library >> -- hpdf_destination.c
3  *
4  * URL: http://libharu.org
5  *
6  * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7  * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
8  *
9  * Permission to use, copy, modify, distribute and sell this software
10  * and its documentation for any purpose is hereby granted without fee,
11  * provided that the above copyright notice appear in all copies and
12  * that both that copyright notice and this permission notice appear
13  * in supporting documentation.
14  * It is provided "as is" without express or implied warranty.
15  *
16  */
17 
18 #include "hpdf_conf.h"
19 #include "hpdf_utils.h"
20 #include "hpdf.h"
21 
22 const char * const HPDF_DESTINATION_TYPE_NAMES[] = {
23         "XYZ",
24         "Fit",
25         "FitH",
26         "FitV",
27         "FitR",
28         "FitB",
29         "FitBH",
30         "FitBV",
31         NULL
32 };
33 
34 /*----------------------------------------------------------------------------*/
35 /*----- HPDF_Destination -----------------------------------------------------*/
36 
37 HPDF_Destination
HPDF_Destination_New(HPDF_MMgr mmgr,HPDF_Page target,HPDF_Xref xref)38 HPDF_Destination_New  (HPDF_MMgr   mmgr,
39                        HPDF_Page   target,
40                        HPDF_Xref   xref)
41 {
42     HPDF_Destination dst;
43 
44     HPDF_PTRACE((" HPDF_Destination_New\n"));
45 
46     if (!HPDF_Page_Validate (target)) {
47         HPDF_SetError (mmgr->error, HPDF_INVALID_PAGE, 0);
48         return NULL;
49     }
50 
51     dst = HPDF_Array_New (mmgr);
52     if (!dst)
53         return NULL;
54 
55     dst->header.obj_class |= HPDF_OSUBCLASS_DESTINATION;
56 
57     if (HPDF_Xref_Add (xref, dst) != HPDF_OK)
58         return NULL;
59 
60     /* first item of array must be target page */
61     if (HPDF_Array_Add (dst, target) != HPDF_OK)
62         return NULL;
63 
64     /* default type is HPDF_FIT */
65     if (HPDF_Array_AddName (dst,
66             HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT]) != HPDF_OK)
67         return NULL;
68 
69     return dst;
70 }
71 
72 
73 HPDF_BOOL
HPDF_Destination_Validate(HPDF_Destination dst)74 HPDF_Destination_Validate (HPDF_Destination  dst)
75 {
76     HPDF_Obj_Header *header = (HPDF_Obj_Header *)dst;
77     HPDF_Page target;
78 
79     if (!dst || header->obj_class !=
80                 (HPDF_OCLASS_ARRAY | HPDF_OSUBCLASS_DESTINATION))
81         return HPDF_FALSE;
82 
83     /* destination-types not defined. */
84     if (dst->list->count < 2)
85         return HPDF_FALSE;
86 
87     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
88     if (!HPDF_Page_Validate (target)) {
89 	    HPDF_SetError (dst->error, HPDF_INVALID_PAGE, 0);
90         return HPDF_FALSE;
91     }
92 
93     return HPDF_TRUE;
94 }
95 
96 
97 HPDF_EXPORT(HPDF_STATUS)
HPDF_Destination_SetXYZ(HPDF_Destination dst,HPDF_REAL left,HPDF_REAL top,HPDF_REAL zoom)98 HPDF_Destination_SetXYZ  (HPDF_Destination  dst,
99                           HPDF_REAL         left,
100                           HPDF_REAL         top,
101                           HPDF_REAL         zoom)
102 {
103     HPDF_STATUS ret = HPDF_OK;
104     HPDF_Page target;
105 
106     HPDF_PTRACE((" HPDF_Destination_SetXYZ\n"));
107 
108     if (!HPDF_Destination_Validate (dst))
109         return HPDF_INVALID_DESTINATION;
110 
111     if (left < 0 || top < 0 || zoom < 0.08 || zoom > 32)
112         return HPDF_RaiseError (dst->error, HPDF_INVALID_PARAMETER, 0);
113 
114 
115     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
116 
117     if (dst->list->count > 1) {
118         HPDF_Array_Clear (dst);
119         ret += HPDF_Array_Add (dst, target);
120     }
121 
122     ret += HPDF_Array_AddName (dst,
123                 HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_XYZ]);
124     ret += HPDF_Array_AddReal (dst, left);
125     ret += HPDF_Array_AddReal (dst, top);
126     ret += HPDF_Array_AddReal (dst, zoom);
127 
128     if (ret != HPDF_OK)
129         return HPDF_CheckError (dst->error);
130 
131     return HPDF_OK;
132 }
133 
134 
135 HPDF_EXPORT(HPDF_STATUS)
HPDF_Destination_SetFit(HPDF_Destination dst)136 HPDF_Destination_SetFit  (HPDF_Destination  dst)
137 {
138     HPDF_STATUS ret = HPDF_OK;
139     HPDF_Page target;
140 
141     HPDF_PTRACE((" HPDF_Destination_SetFit\n"));
142 
143     if (!HPDF_Destination_Validate (dst))
144         return HPDF_INVALID_DESTINATION;
145 
146     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
147 
148     if (dst->list->count > 1) {
149         HPDF_Array_Clear (dst);
150         ret += HPDF_Array_Add (dst, target);
151     }
152 
153     ret += HPDF_Array_AddName (dst,
154                 HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT]);
155 
156     if (ret != HPDF_OK)
157         return HPDF_CheckError (dst->error);
158 
159     return HPDF_OK;
160 }
161 
162 
163 HPDF_EXPORT(HPDF_STATUS)
HPDF_Destination_SetFitH(HPDF_Destination dst,HPDF_REAL top)164 HPDF_Destination_SetFitH  (HPDF_Destination  dst,
165                            HPDF_REAL         top)
166 {
167     HPDF_STATUS ret = HPDF_OK;
168     HPDF_Page target;
169 
170     HPDF_PTRACE((" HPDF_Destination_SetFitH\n"));
171 
172     if (!HPDF_Destination_Validate (dst))
173         return HPDF_INVALID_DESTINATION;
174 
175     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
176 
177     if (dst->list->count > 1) {
178         HPDF_Array_Clear (dst);
179         ret += HPDF_Array_Add (dst, target);
180     }
181 
182     ret += HPDF_Array_AddName (dst,
183                 HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT_H]);
184     ret += HPDF_Array_AddReal (dst, top);
185 
186     if (ret != HPDF_OK)
187         return HPDF_CheckError (dst->error);
188 
189     return HPDF_OK;
190 }
191 
192 HPDF_EXPORT(HPDF_STATUS)
HPDF_Destination_SetFitV(HPDF_Destination dst,HPDF_REAL left)193 HPDF_Destination_SetFitV  (HPDF_Destination  dst,
194                            HPDF_REAL         left)
195 {
196     HPDF_STATUS ret = HPDF_OK;
197     HPDF_Page target;
198 
199     HPDF_PTRACE((" HPDF_Destination_SetFitV\n"));
200 
201     if (!HPDF_Destination_Validate (dst))
202         return HPDF_INVALID_DESTINATION;
203 
204     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
205 
206     if (dst->list->count > 1) {
207         HPDF_Array_Clear (dst);
208         ret += HPDF_Array_Add (dst, target);
209     }
210 
211     ret += HPDF_Array_AddName (dst,
212                 HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT_V]);
213     ret += HPDF_Array_AddReal (dst, left);
214 
215     if (ret != HPDF_OK)
216         return HPDF_CheckError (dst->error);
217 
218     return HPDF_OK;
219 }
220 
221 
222 HPDF_EXPORT(HPDF_STATUS)
HPDF_Destination_SetFitR(HPDF_Destination dst,HPDF_REAL left,HPDF_REAL bottom,HPDF_REAL right,HPDF_REAL top)223 HPDF_Destination_SetFitR  (HPDF_Destination  dst,
224                            HPDF_REAL         left,
225                            HPDF_REAL         bottom,
226                            HPDF_REAL         right,
227                            HPDF_REAL         top)
228 {
229     HPDF_STATUS ret = HPDF_OK;
230     HPDF_Page target;
231 
232     HPDF_PTRACE((" HPDF_Destination_SetFitR\n"));
233 
234     if (!HPDF_Destination_Validate (dst))
235         return HPDF_INVALID_DESTINATION;
236 
237     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
238 
239     if (dst->list->count > 1) {
240         HPDF_Array_Clear (dst);
241         ret += HPDF_Array_Add (dst, target);
242     }
243 
244     ret += HPDF_Array_AddName (dst,
245                 HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT_R]);
246     ret += HPDF_Array_AddReal (dst, left);
247     ret += HPDF_Array_AddReal (dst, bottom);
248     ret += HPDF_Array_AddReal (dst, right);
249     ret += HPDF_Array_AddReal (dst, top);
250 
251     if (ret != HPDF_OK)
252         return HPDF_CheckError (dst->error);
253 
254     return HPDF_OK;
255 }
256 
257 
258 HPDF_EXPORT(HPDF_STATUS)
HPDF_Destination_SetFitB(HPDF_Destination dst)259 HPDF_Destination_SetFitB  (HPDF_Destination  dst)
260 {
261     HPDF_STATUS ret = HPDF_OK;
262     HPDF_Page target;
263 
264     HPDF_PTRACE((" HPDF_Destination_SetFitB\n"));
265 
266     if (!HPDF_Destination_Validate (dst))
267         return HPDF_INVALID_DESTINATION;
268 
269     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
270 
271     if (dst->list->count > 1) {
272         HPDF_Array_Clear (dst);
273         ret += HPDF_Array_Add (dst, target);
274     }
275 
276     ret += HPDF_Array_AddName (dst,
277                 HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT_B]);
278 
279     if (ret != HPDF_OK)
280         return HPDF_CheckError (dst->error);
281 
282     return HPDF_OK;
283 }
284 
285 
286 HPDF_EXPORT(HPDF_STATUS)
HPDF_Destination_SetFitBH(HPDF_Destination dst,HPDF_REAL top)287 HPDF_Destination_SetFitBH  (HPDF_Destination  dst,
288                             HPDF_REAL         top)
289 {
290     HPDF_STATUS ret = HPDF_OK;
291     HPDF_Page target;
292 
293     HPDF_PTRACE((" HPDF_Destination_SetFitBH\n"));
294 
295     if (!HPDF_Destination_Validate (dst))
296         return HPDF_INVALID_DESTINATION;
297 
298     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
299 
300     if (dst->list->count > 1) {
301         HPDF_Array_Clear (dst);
302         ret += HPDF_Array_Add (dst, target);
303     }
304 
305     ret += HPDF_Array_AddName (dst,
306                 HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT_BH]);
307     ret += HPDF_Array_AddReal (dst, top);
308 
309     if (ret != HPDF_OK)
310         return HPDF_CheckError (dst->error);
311 
312     return HPDF_OK;
313 }
314 
315 HPDF_EXPORT(HPDF_STATUS)
HPDF_Destination_SetFitBV(HPDF_Destination dst,HPDF_REAL left)316 HPDF_Destination_SetFitBV  (HPDF_Destination  dst,
317                             HPDF_REAL         left)
318 {
319     HPDF_STATUS ret = HPDF_OK;
320     HPDF_Page target;
321 
322     HPDF_PTRACE((" HPDF_Destination_SetFitBV\n"));
323 
324     if (!HPDF_Destination_Validate (dst))
325         return HPDF_INVALID_DESTINATION;
326 
327     target = (HPDF_Page)HPDF_Array_GetItem (dst, 0, HPDF_OCLASS_DICT);
328 
329     if (dst->list->count > 1) {
330         HPDF_Array_Clear (dst);
331         ret += HPDF_Array_Add (dst, target);
332     }
333 
334     ret += HPDF_Array_AddName (dst,
335                 HPDF_DESTINATION_TYPE_NAMES[(HPDF_INT)HPDF_FIT_BV]);
336     ret += HPDF_Array_AddReal (dst, left);
337 
338     if (ret != HPDF_OK)
339         return HPDF_CheckError (dst->error);
340 
341     return HPDF_OK;
342 
343 }
344 
345