Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
#include "mupdf/pdf.h"
2
3
pdf_obj *pdf_get_inheritable(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *key)
4
{
5
pdf_obj *fobj = NULL;
6
7
while (!fobj && obj)
8
{
9
fobj = pdf_dict_get(ctx, obj, key);
10
11
if (!fobj)
12
obj = pdf_dict_get(ctx, obj, PDF_NAME_Parent);
13
}
14
15
return fobj ? fobj : pdf_dict_get(ctx, pdf_dict_get(ctx, pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root), PDF_NAME_AcroForm), key);
16
}
17
18
char *pdf_get_string_or_stream(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
19
{
20
int len = 0;
21
char *buf = NULL;
22
fz_buffer *strmbuf = NULL;
23
char *text = NULL;
24
25
fz_var(strmbuf);
26
fz_var(text);
27
fz_try(ctx)
28
{
29
if (pdf_is_string(ctx, obj))
30
{
31
len = pdf_to_str_len(ctx, obj);
32
buf = pdf_to_str_buf(ctx, obj);
33
}
34
else if (pdf_is_stream(ctx, doc, pdf_to_num(ctx, obj), pdf_to_gen(ctx, obj)))
35
{
36
strmbuf = pdf_load_stream(ctx, doc, pdf_to_num(ctx, obj), pdf_to_gen(ctx, obj));
37
len = fz_buffer_storage(ctx, strmbuf, (unsigned char **)&buf);
38
}
39
40
if (buf)
41
{
42
text = fz_malloc(ctx, len+1);
43
memcpy(text, buf, len);
44
text[len] = 0;
45
}
46
}
47
fz_always(ctx)
48
{
49
fz_drop_buffer(ctx, strmbuf);
50
}
51
fz_catch(ctx)
52
{
53
fz_free(ctx, text);
54
fz_rethrow(ctx);
55
}
56
57
return text;
58
}
59
60
char *pdf_field_value(fz_context *ctx, pdf_document *doc, pdf_obj *field)
61
{
62
return pdf_get_string_or_stream(ctx, doc, pdf_get_inheritable(ctx, doc, field, PDF_NAME_V));
63
}
64
65
int pdf_get_field_flags(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
66
{
67
return pdf_to_int(ctx, pdf_get_inheritable(ctx, doc, obj, PDF_NAME_Ff));
68
}
69
70
static pdf_obj *get_field_type_name(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
71
{
72
return pdf_get_inheritable(ctx, doc, obj, PDF_NAME_FT);
73
}
74
75
int pdf_field_type(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
76
{
77
pdf_obj *type = get_field_type_name(ctx, doc, obj);
78
int flags = pdf_get_field_flags(ctx, doc, obj);
79
80
if (pdf_name_eq(ctx, type, PDF_NAME_Btn))
81
{
82
if (flags & Ff_Pushbutton)
83
return PDF_WIDGET_TYPE_PUSHBUTTON;
84
else if (flags & Ff_Radio)
85
return PDF_WIDGET_TYPE_RADIOBUTTON;
86
else
87
return PDF_WIDGET_TYPE_CHECKBOX;
88
}
89
else if (pdf_name_eq(ctx, type, PDF_NAME_Tx))
90
return PDF_WIDGET_TYPE_TEXT;
91
else if (pdf_name_eq(ctx, type, PDF_NAME_Ch))
92
{
93
if (flags & Ff_Combo)
94
return PDF_WIDGET_TYPE_COMBOBOX;
95
else
96
return PDF_WIDGET_TYPE_LISTBOX;
97
}
98
else if (pdf_name_eq(ctx, type, PDF_NAME_Sig))
99
return PDF_WIDGET_TYPE_SIGNATURE;
100
else
101
return PDF_WIDGET_TYPE_NOT_WIDGET;
102
}
103
104
void pdf_set_field_type(fz_context *ctx, pdf_document *doc, pdf_obj *obj, int type)
105
{
106
int setbits = 0;
107
int clearbits = 0;
108
pdf_obj *typename = NULL;
109
110
switch(type)
111
{
112
case PDF_WIDGET_TYPE_PUSHBUTTON:
113
typename = PDF_NAME_Btn;
114
setbits = Ff_Pushbutton;
115
break;
116
case PDF_WIDGET_TYPE_CHECKBOX:
117
typename = PDF_NAME_Btn;
118
clearbits = Ff_Pushbutton;
119
setbits = Ff_Radio;
120
break;
121
case PDF_WIDGET_TYPE_RADIOBUTTON:
122
typename = PDF_NAME_Btn;
123
clearbits = (Ff_Pushbutton|Ff_Radio);
124
break;
125
case PDF_WIDGET_TYPE_TEXT:
126
typename = PDF_NAME_Tx;
127
break;
128
case PDF_WIDGET_TYPE_LISTBOX:
129
typename = PDF_NAME_Ch;
130
clearbits = Ff_Combo;
131
break;
132
case PDF_WIDGET_TYPE_COMBOBOX:
133
typename = PDF_NAME_Ch;
134
setbits = Ff_Combo;
135
break;
136
case PDF_WIDGET_TYPE_SIGNATURE:
137
typename = PDF_NAME_Sig;
138
break;
139
}
140
141
if (typename)
142
pdf_dict_put_drop(ctx, obj, PDF_NAME_FT, typename);
143
144
if (setbits != 0 || clearbits != 0)
145
{
146
int bits = pdf_to_int(ctx, pdf_dict_get(ctx, obj, PDF_NAME_Ff));
147
bits &= ~clearbits;
148
bits |= setbits;
149
pdf_dict_put_drop(ctx, obj, PDF_NAME_Ff, pdf_new_int(ctx, doc, bits));
150
}
151
}
152
153