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
static fz_error
5
pdf_run_glyph_func(void *xref, fz_obj *rdb, fz_buffer *contents, fz_device *dev, fz_matrix ctm)
6
{
7
	return pdf_run_glyph(xref, rdb, contents, dev, ctm);
8
}
9
 
10
fz_error
11
pdf_load_type3_font(pdf_font_desc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
12
{
13
	fz_error error;
14
	char buf[256];
15
	char *estrings[256];
16
	pdf_font_desc *fontdesc;
17
	fz_obj *encoding;
18
	fz_obj *widths;
19
	fz_obj *charprocs;
20
	fz_obj *obj;
21
	int first, last;
22
	int i, k, n;
23
	fz_rect bbox;
24
	fz_matrix matrix;
25
 
26
	obj = fz_dict_gets(dict, "Name");
27
	if (fz_is_name(obj))
28
		fz_strlcpy(buf, fz_to_name(obj), sizeof buf);
29
	else
30
		sprintf(buf, "Unnamed-T3");
31
 
32
	fontdesc = pdf_new_font_desc();
33
 
34
	obj = fz_dict_gets(dict, "FontMatrix");
35
	matrix = pdf_to_matrix(obj);
36
 
37
	obj = fz_dict_gets(dict, "FontBBox");
38
	bbox = pdf_to_rect(obj);
39
 
40
	fontdesc->font = fz_new_type3_font(buf, matrix);
41
 
42
	fz_set_font_bbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
43
 
44
	/* Encoding */
45
 
46
	for (i = 0; i < 256; i++)
47
		estrings[i] = NULL;
48
 
49
	encoding = fz_dict_gets(dict, "Encoding");
50
	if (!encoding)
51
	{
52
		error = fz_throw("syntaxerror: Type3 font missing Encoding");
53
		goto cleanup;
54
	}
55
 
56
	if (fz_is_name(encoding))
57
		pdf_load_encoding(estrings, fz_to_name(encoding));
58
 
59
	if (fz_is_dict(encoding))
60
	{
61
		fz_obj *base, *diff, *item;
62
 
63
		base = fz_dict_gets(encoding, "BaseEncoding");
64
		if (fz_is_name(base))
65
			pdf_load_encoding(estrings, fz_to_name(base));
66
 
67
		diff = fz_dict_gets(encoding, "Differences");
68
		if (fz_is_array(diff))
69
		{
70
			n = fz_array_len(diff);
71
			k = 0;
72
			for (i = 0; i < n; i++)
73
			{
74
				item = fz_array_get(diff, i);
75
				if (fz_is_int(item))
76
					k = fz_to_int(item);
77
				if (fz_is_name(item))
78
					estrings[k++] = fz_to_name(item);
79
				if (k < 0) k = 0;
80
				if (k > 255) k = 255;
81
			}
82
		}
83
	}
84
 
85
	fontdesc->encoding = pdf_new_identity_cmap(0, 1);
86
 
87
	error = pdf_load_to_unicode(fontdesc, xref, estrings, NULL, fz_dict_gets(dict, "ToUnicode"));
88
	if (error)
89
		goto cleanup;
90
 
91
	/* Widths */
92
 
93
	pdf_set_default_hmtx(fontdesc, 0);
94
 
95
	first = fz_to_int(fz_dict_gets(dict, "FirstChar"));
96
	last = fz_to_int(fz_dict_gets(dict, "LastChar"));
97
 
98
	widths = fz_dict_gets(dict, "Widths");
99
	if (!widths)
100
	{
101
		error = fz_throw("syntaxerror: Type3 font missing Widths");
102
		goto cleanup;
103
	}
104
 
105
	for (i = first; i <= last; i++)
106
	{
107
		float w = fz_to_real(fz_array_get(widths, i - first));
108
		w = fontdesc->font->t3matrix.a * w * 1000;
109
		fontdesc->font->t3widths[i] = w * 0.001f;
110
		pdf_add_hmtx(fontdesc, i, i, w);
111
	}
112
 
113
	pdf_end_hmtx(fontdesc);
114
 
115
	/* Resources -- inherit page resources if the font doesn't have its own */
116
 
117
	fontdesc->font->t3resources = fz_dict_gets(dict, "Resources");
118
	if (!fontdesc->font->t3resources)
119
		fontdesc->font->t3resources = rdb;
120
	if (fontdesc->font->t3resources)
121
		fz_keep_obj(fontdesc->font->t3resources);
122
	if (!fontdesc->font->t3resources)
123
		fz_warn("no resource dictionary for type 3 font!");
124
 
125
	fontdesc->font->t3xref = xref;
126
	fontdesc->font->t3run = pdf_run_glyph_func;
127
 
128
	/* CharProcs */
129
 
130
	charprocs = fz_dict_gets(dict, "CharProcs");
131
	if (!charprocs)
132
	{
133
		error = fz_throw("syntaxerror: Type3 font missing CharProcs");
134
		goto cleanup;
135
	}
136
 
137
	for (i = 0; i < 256; i++)
138
	{
139
		if (estrings[i])
140
		{
141
			obj = fz_dict_gets(charprocs, estrings[i]);
142
			if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj)))
143
			{
144
				error = pdf_load_stream(&fontdesc->font->t3procs[i], xref, fz_to_num(obj), fz_to_gen(obj));
145
				if (error)
146
					goto cleanup;
147
			}
148
		}
149
	}
150
 
151
	*fontdescp = fontdesc;
152
	return fz_okay;
153
 
154
cleanup:
155
	fz_drop_font(fontdesc->font);
156
	fz_free(fontdesc);
157
	return fz_rethrow(error, "cannot load type3 font (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
158
}