Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
#include "mupdf.h"
3
 
4
void
5
pdf_free_link(pdf_link *link)
6
{
7
	if (link->next)
8
		pdf_free_link(link->next);
9
	if (link->dest)
10
		fz_drop_obj(link->dest);
11
	fz_free(link);
12
}
13
 
14
static fz_obj *
15
resolve_dest(pdf_xref *xref, fz_obj *dest)
16
{
17
	if (fz_is_name(dest) || fz_is_string(dest))
18
	{
19
		dest = pdf_lookup_dest(xref, dest);
20
		return resolve_dest(xref, dest);
21
	}
22
 
23
	else if (fz_is_array(dest))
24
	{
25
		return dest;
26
	}
27
 
28
	else if (fz_is_dict(dest))
29
	{
30
		dest = fz_dict_gets(dest, "D");
31
		return resolve_dest(xref, dest);
32
	}
33
 
34
	else if (fz_is_indirect(dest))
35
		return dest;
36
 
37
	return NULL;
38
}
39
 
40
pdf_link *
41
pdf_load_link(pdf_xref *xref, fz_obj *dict)
42
{
43
	fz_obj *dest;
44
	fz_obj *action;
45
	fz_obj *obj;
46
	fz_rect bbox;
47
	pdf_link_kind kind;
48
 
49
	dest = NULL;
50
 
51
	obj = fz_dict_gets(dict, "Rect");
52
	if (obj)
53
		bbox = pdf_to_rect(obj);
54
	else
55
		bbox = fz_empty_rect;
56
 
57
	obj = fz_dict_gets(dict, "Dest");
58
	if (obj)
59
	{
60
		kind = PDF_LINK_GOTO;
61
		dest = resolve_dest(xref, obj);
62
	}
63
 
64
	action = fz_dict_gets(dict, "A");
65
 
66
	/* fall back to additional action button's down/up action */
67
	if (!action)
68
		action = fz_dict_getsa(fz_dict_gets(dict, "AA"), "U", "D");
69
 
70
	if (action)
71
	{
72
		obj = fz_dict_gets(action, "S");
73
		if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "GoTo"))
74
		{
75
			kind = PDF_LINK_GOTO;
76
			dest = resolve_dest(xref, fz_dict_gets(action, "D"));
77
		}
78
		else if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "URI"))
79
		{
80
			kind = PDF_LINK_URI;
81
			dest = fz_dict_gets(action, "URI");
82
		}
83
		else if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "Launch"))
84
		{
85
			kind = PDF_LINK_LAUNCH;
86
			dest = fz_dict_gets(action, "F");
87
		}
88
		else if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "Named"))
89
		{
90
			kind = PDF_LINK_NAMED;
91
			dest = fz_dict_gets(action, "N");
92
		}
93
		else if (fz_is_name(obj) && (!strcmp(fz_to_name(obj), "GoToR")))
94
		{
95
			kind = PDF_LINK_ACTION;
96
			dest = action;
97
		}
98
		else
99
		{
100
			dest = NULL;
101
		}
102
	}
103
 
104
	if (dest)
105
	{
106
		pdf_link *link = fz_malloc(sizeof(pdf_link));
107
		link->kind = kind;
108
		link->rect = bbox;
109
		link->dest = fz_keep_obj(dest);
110
		link->next = NULL;
111
		return link;
112
	}
113
 
114
	return NULL;
115
}
116
 
117
void
118
pdf_load_links(pdf_link **linkp, pdf_xref *xref, fz_obj *annots)
119
{
120
	pdf_link *link, *head, *tail;
121
	fz_obj *obj;
122
	int i;
123
 
124
	head = tail = NULL;
125
	link = NULL;
126
 
127
	for (i = 0; i < fz_array_len(annots); i++)
128
	{
129
		obj = fz_array_get(annots, i);
130
		link = pdf_load_link(xref, obj);
131
		if (link)
132
		{
133
			if (!head)
134
				head = tail = link;
135
			else
136
			{
137
				tail->next = link;
138
				tail = link;
139
			}
140
		}
141
	}
142
 
143
	*linkp = head;
144
}
145
 
146
void
147
pdf_free_annot(pdf_annot *annot)
148
{
149
	if (annot->next)
150
		pdf_free_annot(annot->next);
151
	if (annot->ap)
152
		pdf_drop_xobject(annot->ap);
153
	if (annot->obj)
154
		fz_drop_obj(annot->obj);
155
	fz_free(annot);
156
}
157
 
158
static void
159
pdf_transform_annot(pdf_annot *annot)
160
{
161
	fz_matrix matrix = annot->ap->matrix;
162
	fz_rect bbox = annot->ap->bbox;
163
	fz_rect rect = annot->rect;
164
	float w, h, x, y;
165
 
166
	bbox = fz_transform_rect(matrix, bbox);
167
	w = (rect.x1 - rect.x0) / (bbox.x1 - bbox.x0);
168
	h = (rect.y1 - rect.y0) / (bbox.y1 - bbox.y0);
169
	x = rect.x0 - bbox.x0;
170
	y = rect.y0 - bbox.y0;
171
 
172
	annot->matrix = fz_concat(fz_scale(w, h), fz_translate(x, y));
173
}
174
 
175
void
176
pdf_load_annots(pdf_annot **annotp, pdf_xref *xref, fz_obj *annots)
177
{
178
	pdf_annot *annot, *head, *tail;
179
	fz_obj *obj, *ap, *as, *n, *rect;
180
	pdf_xobject *form;
181
	fz_error error;
182
	int i;
183
 
184
	head = tail = NULL;
185
	annot = NULL;
186
 
187
	for (i = 0; i < fz_array_len(annots); i++)
188
	{
189
		obj = fz_array_get(annots, i);
190
 
191
		rect = fz_dict_gets(obj, "Rect");
192
		ap = fz_dict_gets(obj, "AP");
193
		as = fz_dict_gets(obj, "AS");
194
		if (fz_is_dict(ap))
195
		{
196
			n = fz_dict_gets(ap, "N"); /* normal state */
197
 
198
			/* lookup current state in sub-dictionary */
199
			if (!pdf_is_stream(xref, fz_to_num(n), fz_to_gen(n)))
200
				n = fz_dict_get(n, as);
201
 
202
			if (pdf_is_stream(xref, fz_to_num(n), fz_to_gen(n)))
203
			{
204
				error = pdf_load_xobject(&form, xref, n);
205
				if (error)
206
				{
207
					fz_catch(error, "ignoring broken annotation");
208
					continue;
209
				}
210
 
211
				annot = fz_malloc(sizeof(pdf_annot));
212
				annot->obj = fz_keep_obj(obj);
213
				annot->rect = pdf_to_rect(rect);
214
				annot->ap = form;
215
				annot->next = NULL;
216
 
217
				pdf_transform_annot(annot);
218
 
219
				if (annot)
220
				{
221
					if (!head)
222
						head = tail = annot;
223
					else
224
					{
225
						tail->next = annot;
226
						tail = annot;
227
					}
228
				}
229
			}
230
		}
231
	}
232
 
233
	*annotp = head;
234
}