Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
#include "mupdf/pdf.h"
2
3
pdf_xobject *
4
pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj)
5
{
6
return (pdf_xobject *)fz_keep_storable(ctx, &xobj->storable);
7
}
8
9
void
10
pdf_drop_xobject(fz_context *ctx, pdf_xobject *xobj)
11
{
12
fz_drop_storable(ctx, &xobj->storable);
13
}
14
15
static void
16
pdf_drop_xobject_imp(fz_context *ctx, fz_storable *xobj_)
17
{
18
pdf_xobject *xobj = (pdf_xobject *)xobj_;
19
20
if (xobj->colorspace)
21
fz_drop_colorspace(ctx, xobj->colorspace);
22
pdf_drop_obj(ctx, xobj->resources);
23
pdf_drop_obj(ctx, xobj->contents);
24
pdf_drop_obj(ctx, xobj->me);
25
fz_free(ctx, xobj);
26
}
27
28
static unsigned int
29
pdf_xobject_size(pdf_xobject *xobj)
30
{
31
if (xobj == NULL)
32
return 0;
33
return sizeof(*xobj) + (xobj->colorspace ? xobj->colorspace->size : 0);
34
}
35
36
pdf_xobject *
37
pdf_load_xobject(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
38
{
39
pdf_xobject *form;
40
pdf_obj *obj;
41
42
if ((form = pdf_find_item(ctx, pdf_drop_xobject_imp, dict)) != NULL)
43
{
44
return form;
45
}
46
47
form = fz_malloc_struct(ctx, pdf_xobject);
48
FZ_INIT_STORABLE(form, 1, pdf_drop_xobject_imp);
49
form->document = doc;
50
form->resources = NULL;
51
form->contents = NULL;
52
form->colorspace = NULL;
53
form->me = NULL;
54
form->iteration = 0;
55
56
/* Store item immediately, to avoid possible recursion if objects refer back to this one */
57
pdf_store_item(ctx, dict, form, pdf_xobject_size(form));
58
59
fz_try(ctx)
60
{
61
obj = pdf_dict_get(ctx, dict, PDF_NAME_BBox);
62
pdf_to_rect(ctx, obj, &form->bbox);
63
64
obj = pdf_dict_get(ctx, dict, PDF_NAME_Matrix);
65
if (obj)
66
pdf_to_matrix(ctx, obj, &form->matrix);
67
else
68
form->matrix = fz_identity;
69
70
form->isolated = 0;
71
form->knockout = 0;
72
form->transparency = 0;
73
74
obj = pdf_dict_get(ctx, dict, PDF_NAME_Group);
75
if (obj)
76
{
77
pdf_obj *attrs = obj;
78
79
form->isolated = pdf_to_bool(ctx, pdf_dict_get(ctx, attrs, PDF_NAME_I));
80
form->knockout = pdf_to_bool(ctx, pdf_dict_get(ctx, attrs, PDF_NAME_K));
81
82
obj = pdf_dict_get(ctx, attrs, PDF_NAME_S);
83
if (pdf_name_eq(ctx, obj, PDF_NAME_Transparency))
84
form->transparency = 1;
85
86
obj = pdf_dict_get(ctx, attrs, PDF_NAME_CS);
87
if (obj)
88
{
89
fz_try(ctx)
90
{
91
form->colorspace = pdf_load_colorspace(ctx, doc, obj);
92
}
93
fz_catch(ctx)
94
{
95
fz_warn(ctx, "cannot load xobject colorspace");
96
}
97
}
98
}
99
100
form->resources = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
101
if (form->resources)
102
pdf_keep_obj(ctx, form->resources);
103
104
form->contents = pdf_keep_obj(ctx, dict);
105
}
106
fz_catch(ctx)
107
{
108
pdf_remove_item(ctx, pdf_drop_xobject_imp, dict);
109
pdf_drop_xobject(ctx, form);
110
fz_rethrow_message(ctx, "cannot load xobject content stream (%d %d R)", pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
111
}
112
form->me = pdf_keep_obj(ctx, dict);
113
114
return form;
115
}
116
117
pdf_obj *
118
pdf_new_xobject(fz_context *ctx, pdf_document *doc, const fz_rect *bbox, const fz_matrix *mat)
119
{
120
int idict_num;
121
pdf_obj *idict = NULL;
122
pdf_obj *dict = NULL;
123
pdf_xobject *form = NULL;
124
pdf_obj *obj = NULL;
125
pdf_obj *res = NULL;
126
pdf_obj *procset = NULL;
127
128
fz_var(idict);
129
fz_var(dict);
130
fz_var(form);
131
fz_var(obj);
132
fz_var(res);
133
fz_var(procset);
134
fz_try(ctx)
135
{
136
dict = pdf_new_dict(ctx, doc, 0);
137
138
obj = pdf_new_rect(ctx, doc, bbox);
139
pdf_dict_put(ctx, dict, PDF_NAME_BBox, obj);
140
pdf_drop_obj(ctx, obj);
141
obj = NULL;
142
143
obj = pdf_new_int(ctx, doc, 1);
144
pdf_dict_put(ctx, dict, PDF_NAME_FormType, obj);
145
pdf_drop_obj(ctx, obj);
146
obj = NULL;
147
148
obj = pdf_new_int(ctx, doc, 0);
149
pdf_dict_put(ctx, dict, PDF_NAME_Length, obj);
150
pdf_drop_obj(ctx, obj);
151
obj = NULL;
152
153
obj = pdf_new_matrix(ctx, doc, mat);
154
pdf_dict_put(ctx, dict, PDF_NAME_Matrix, obj);
155
pdf_drop_obj(ctx, obj);
156
obj = NULL;
157
158
res = pdf_new_dict(ctx, doc, 0);
159
procset = pdf_new_array(ctx, doc, 2);
160
pdf_array_push(ctx, procset, PDF_NAME_PDF);
161
pdf_array_push(ctx, procset, PDF_NAME_Text);
162
pdf_dict_put(ctx, res, PDF_NAME_ProcSet, procset);
163
pdf_drop_obj(ctx, procset);
164
procset = NULL;
165
pdf_dict_put(ctx, dict, PDF_NAME_Resources, res);
166
167
pdf_dict_put(ctx, dict, PDF_NAME_Subtype, PDF_NAME_Form);
168
169
pdf_dict_put(ctx, dict, PDF_NAME_Type, PDF_NAME_XObject);
170
171
form = fz_malloc_struct(ctx, pdf_xobject);
172
FZ_INIT_STORABLE(form, 1, pdf_drop_xobject_imp);
173
form->document = doc;
174
form->resources = NULL;
175
form->contents = NULL;
176
form->colorspace = NULL;
177
form->me = NULL;
178
form->iteration = 0;
179
180
form->bbox = *bbox;
181
182
form->matrix = *mat;
183
184
form->isolated = 0;
185
form->knockout = 0;
186
form->transparency = 0;
187
188
form->resources = res;
189
res = NULL;
190
191
idict_num = pdf_create_object(ctx, doc);
192
pdf_update_object(ctx, doc, idict_num, dict);
193
idict = pdf_new_indirect(ctx, doc, idict_num, 0);
194
pdf_drop_obj(ctx, dict);
195
dict = NULL;
196
197
pdf_store_item(ctx, idict, form, pdf_xobject_size(form));
198
199
form->contents = pdf_keep_obj(ctx, idict);
200
form->me = pdf_keep_obj(ctx, idict);
201
202
pdf_drop_xobject(ctx, form);
203
form = NULL;
204
}
205
fz_catch(ctx)
206
{
207
pdf_drop_obj(ctx, procset);
208
pdf_drop_obj(ctx, res);
209
pdf_drop_obj(ctx, obj);
210
pdf_drop_obj(ctx, dict);
211
pdf_drop_obj(ctx, idict);
212
pdf_drop_xobject(ctx, form);
213
fz_rethrow_message(ctx, "failed to create xobject)");
214
}
215
216
return idict;
217
}
218
219
void pdf_update_xobject_contents(fz_context *ctx, pdf_document *doc, pdf_xobject *form, fz_buffer *buffer)
220
{
221
pdf_update_stream(ctx, doc, form->contents, buffer, 0);
222
form->iteration ++;
223
}
224
225