Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7639 views
1
#include "mupdf/pdf.h"
2
3
static void
4
pdf_run_glyph_func(fz_context *ctx, void *doc, void *rdb, fz_buffer *contents, fz_device *dev, const fz_matrix *ctm, void *gstate, int nested_depth)
5
{
6
pdf_run_glyph(ctx, doc, (pdf_obj *)rdb, contents, dev, ctm, gstate, nested_depth);
7
}
8
9
static void
10
pdf_t3_free_resources(fz_context *ctx, void *doc, void *rdb_)
11
{
12
pdf_obj *rdb = (pdf_obj *)rdb_;
13
pdf_drop_obj(ctx, rdb);
14
}
15
16
pdf_font_desc *
17
pdf_load_type3_font(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *dict)
18
{
19
char buf[256];
20
char *estrings[256];
21
pdf_font_desc *fontdesc = NULL;
22
pdf_obj *encoding;
23
pdf_obj *widths;
24
pdf_obj *charprocs;
25
pdf_obj *obj;
26
int first, last;
27
int i, k, n;
28
fz_rect bbox;
29
fz_matrix matrix;
30
31
fz_var(fontdesc);
32
33
/* Make a new type3 font entry in the document */
34
if (doc->num_type3_fonts == doc->max_type3_fonts)
35
{
36
int new_max = doc->max_type3_fonts * 2;
37
38
if (new_max == 0)
39
new_max = 4;
40
doc->type3_fonts = fz_resize_array(ctx, doc->type3_fonts, new_max, sizeof(*doc->type3_fonts));
41
doc->max_type3_fonts = new_max;
42
}
43
44
fz_try(ctx)
45
{
46
obj = pdf_dict_get(ctx, dict, PDF_NAME_Name);
47
if (pdf_is_name(ctx, obj))
48
fz_strlcpy(buf, pdf_to_name(ctx, obj), sizeof buf);
49
else
50
fz_strlcpy(buf, "Unnamed-T3", sizeof buf);
51
52
fontdesc = pdf_new_font_desc(ctx);
53
54
obj = pdf_dict_get(ctx, dict, PDF_NAME_FontMatrix);
55
pdf_to_matrix(ctx, obj, &matrix);
56
57
obj = pdf_dict_get(ctx, dict, PDF_NAME_FontBBox);
58
fz_transform_rect(pdf_to_rect(ctx, obj, &bbox), &matrix);
59
60
fontdesc->font = fz_new_type3_font(ctx, buf, &matrix);
61
fontdesc->size += sizeof(fz_font) + 256 * (sizeof(fz_buffer*) + sizeof(float));
62
63
fz_set_font_bbox(ctx, fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
64
65
/* Encoding */
66
67
for (i = 0; i < 256; i++)
68
estrings[i] = NULL;
69
70
encoding = pdf_dict_get(ctx, dict, PDF_NAME_Encoding);
71
if (!encoding)
72
{
73
fz_throw(ctx, FZ_ERROR_GENERIC, "syntaxerror: Type3 font missing Encoding");
74
}
75
76
if (pdf_is_name(ctx, encoding))
77
pdf_load_encoding(estrings, pdf_to_name(ctx, encoding));
78
79
if (pdf_is_dict(ctx, encoding))
80
{
81
pdf_obj *base, *diff, *item;
82
83
base = pdf_dict_get(ctx, encoding, PDF_NAME_BaseEncoding);
84
if (pdf_is_name(ctx, base))
85
pdf_load_encoding(estrings, pdf_to_name(ctx, base));
86
87
diff = pdf_dict_get(ctx, encoding, PDF_NAME_Differences);
88
if (pdf_is_array(ctx, diff))
89
{
90
n = pdf_array_len(ctx, diff);
91
k = 0;
92
for (i = 0; i < n; i++)
93
{
94
item = pdf_array_get(ctx, diff, i);
95
if (pdf_is_int(ctx, item))
96
k = pdf_to_int(ctx, item);
97
if (pdf_is_name(ctx, item) && k >= 0 && k < nelem(estrings))
98
estrings[k++] = pdf_to_name(ctx, item);
99
}
100
}
101
}
102
103
fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1);
104
fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding);
105
106
pdf_load_to_unicode(ctx, doc, fontdesc, estrings, NULL, pdf_dict_get(ctx, dict, PDF_NAME_ToUnicode));
107
108
/* Widths */
109
110
pdf_set_default_hmtx(ctx, fontdesc, 0);
111
112
first = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_FirstChar));
113
last = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_LastChar));
114
115
if (first < 0 || last > 255 || first > last)
116
first = last = 0;
117
118
widths = pdf_dict_get(ctx, dict, PDF_NAME_Widths);
119
if (!widths)
120
{
121
fz_throw(ctx, FZ_ERROR_GENERIC, "syntaxerror: Type3 font missing Widths");
122
}
123
124
for (i = first; i <= last; i++)
125
{
126
float w = pdf_to_real(ctx, pdf_array_get(ctx, widths, i - first));
127
w = fontdesc->font->t3matrix.a * w * 1000;
128
fontdesc->font->t3widths[i] = w * 0.001f;
129
pdf_add_hmtx(ctx, fontdesc, i, i, w);
130
}
131
132
pdf_end_hmtx(ctx, fontdesc);
133
134
/* Resources -- inherit page resources if the font doesn't have its own */
135
136
fontdesc->font->t3freeres = pdf_t3_free_resources;
137
fontdesc->font->t3resources = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
138
if (!fontdesc->font->t3resources)
139
fontdesc->font->t3resources = rdb;
140
if (fontdesc->font->t3resources)
141
pdf_keep_obj(ctx, fontdesc->font->t3resources);
142
if (!fontdesc->font->t3resources)
143
fz_warn(ctx, "no resource dictionary for type 3 font!");
144
145
fontdesc->font->t3doc = doc;
146
fontdesc->font->t3run = pdf_run_glyph_func;
147
148
/* CharProcs */
149
150
charprocs = pdf_dict_get(ctx, dict, PDF_NAME_CharProcs);
151
if (!charprocs)
152
{
153
fz_throw(ctx, FZ_ERROR_GENERIC, "syntaxerror: Type3 font missing CharProcs");
154
}
155
156
for (i = 0; i < 256; i++)
157
{
158
if (estrings[i])
159
{
160
obj = pdf_dict_gets(ctx, charprocs, estrings[i]);
161
if (pdf_is_stream(ctx, doc, pdf_to_num(ctx, obj), pdf_to_gen(ctx, obj)))
162
{
163
fontdesc->font->t3procs[i] = pdf_load_stream(ctx, doc, pdf_to_num(ctx, obj), pdf_to_gen(ctx, obj));
164
fontdesc->size += fontdesc->font->t3procs[i]->cap;
165
fontdesc->size += 0; // TODO: display list size calculation
166
}
167
}
168
}
169
}
170
fz_catch(ctx)
171
{
172
if (fontdesc)
173
pdf_drop_font(ctx, fontdesc);
174
fz_rethrow_message(ctx, "cannot load type3 font (%d %d R)", pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
175
}
176
177
doc->type3_fonts[doc->num_type3_fonts++] = fz_keep_font(ctx, fontdesc->font);
178
179
return fontdesc;
180
}
181
182
void pdf_load_type3_glyphs(fz_context *ctx, pdf_document *doc, pdf_font_desc *fontdesc, int nested_depth)
183
{
184
int i;
185
186
fz_try(ctx)
187
{
188
for (i = 0; i < 256; i++)
189
{
190
if (fontdesc->font->t3procs[i])
191
{
192
fz_prepare_t3_glyph(ctx, fontdesc->font, i, nested_depth);
193
fontdesc->size += 0; // TODO: display list size calculation
194
}
195
}
196
}
197
fz_catch(ctx)
198
{
199
fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
200
fz_warn(ctx, "Type3 glyph load failed: %s", fz_caught_message(ctx));
201
}
202
}
203
204