beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / font / writet3.w
blobc7cc79a722f3ec12cc7ee966705e2eeb904e23f0
1 % writet3.w
3 % Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
4 % Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
6 % This file is part of LuaTeX.
8 % LuaTeX is free software; you can redistribute it and/or modify it under
9 % the terms of the GNU General Public License as published by the Free
10 % Software Foundation; either version 2 of the License, or (at your
11 % option) any later version.
13 % LuaTeX is distributed in the hope that it will be useful, but WITHOUT
14 % ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 % FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 % License for more details.
18 % You should have received a copy of the GNU General Public License along
19 % with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
21 @ @c
24 #include "ptexlib.h"
25 #include <kpathsea/tex-glyph.h>
26 #include <kpathsea/magstep.h>
27 #include <string.h>
29 #define T3_BUF_SIZE 1024
31 typedef char t3_line_entry;
32 define_array(t3_line);
34 FILE *t3_file;
35 static boolean t3_image_used;
37 static int t3_char_procs[256];
38 static float t3_char_widths[256];
39 static int t3_glyph_num;
40 static float t3_font_scale;
41 static int t3_b0, t3_b1, t3_b2, t3_b3;
42 static boolean is_pk_font;
44 /* not static because used by pkin.c */
45 unsigned char *t3_buffer = NULL;
46 int t3_size = 0;
47 int t3_curbyte = 0;
49 #define t3_check_eof() \
50 if (t3_eof()) \
51 normal_error("type 3","unexpected end of file");
55 static void update_bbox(int llx, int lly, int urx, int ury, boolean is_first_glyph)
57 if (is_first_glyph) {
58 t3_b0 = llx;
59 t3_b1 = lly;
60 t3_b2 = urx;
61 t3_b3 = ury;
62 } else {
63 if (llx < t3_b0)
64 t3_b0 = llx;
65 if (lly < t3_b1)
66 t3_b1 = lly;
67 if (urx > t3_b2)
68 t3_b2 = urx;
69 if (ury > t3_b3)
70 t3_b3 = ury;
74 /* fixed precision 3 (+5 in pdfgen.w)*/
76 #define get_pk_font_scale(pdf,f,scale_factor) \
77 divide_scaled(scale_factor, divide_scaled(font_size(f),one_hundred_bp,pk_decimal_digits(pdf,2)), 0)
79 #define pk_char_width(pdf,f,w,scale_factor) \
80 divide_scaled(divide_scaled(w,font_size(f),pk_decimal_digits(pdf,4)), get_pk_font_scale(pdf,f,scale_factor), 0)
84 static boolean writepk(PDF pdf, internal_font_number f)
86 kpse_glyph_file_type font_ret;
87 int llx, lly, urx, ury;
88 int cw, rw, i, j;
89 pdffloat pf;
90 halfword *row;
91 char *name;
92 chardesc cd;
93 boolean is_null_glyph, check_preamble;
94 int dpi = 0;
95 int newdpi = 0;
96 int callback_id = 0;
97 int file_opened = 0;
98 xfree(t3_buffer);
99 t3_curbyte = 0;
100 t3_size = 0;
102 callback_id = callback_defined(find_pk_file_callback);
104 if (pdf->pk_fixed_dpi) {
105 newdpi = pdf->pk_resolution;
106 } else {
107 newdpi = dpi;
110 if (callback_id > 0) {
111 /* <base>.dpi/<fontname>.<tdpi>pk */
112 dpi = round((float) pdf->pk_resolution * (((float) font_size(f)) / (float) font_dsize(f)));
113 cur_file_name = font_name(f);
114 run_callback(callback_id, "Sd->S", cur_file_name, (int) newdpi, &name);
115 if (name == NULL || strlen(name) == 0) {
116 formatted_warning("type 3","font %s at %i not found", cur_file_name, (int) dpi);
117 return false;
119 } else {
120 dpi = (int) kpse_magstep_fix(
121 (unsigned) round ((float)pdf->pk_resolution * ((float)font_size(f)/(float)font_dsize(f))),
122 (unsigned) pdf->pk_resolution, NULL
124 cur_file_name = font_name(f);
125 name = kpse_find_pk(cur_file_name, (unsigned) dpi, &font_ret);
126 if (name == NULL || !FILESTRCASEEQ(cur_file_name, font_ret.name)
127 || !kpse_bitmap_tolerance((float) font_ret.dpi, (float) dpi)) {
128 formatted_error("type 3","font %s at %i not found", cur_file_name, (int) dpi);
129 return false;
132 callback_id = callback_defined(read_pk_file_callback);
133 if (callback_id > 0) {
134 if (!(run_callback(callback_id, "S->bSd", name, &file_opened, &t3_buffer, &t3_size) && file_opened && t3_size > 0)) {
135 formatted_warning("type 3","font %s at %i not found", cur_file_name, (int) dpi);
136 cur_file_name = NULL;
137 return false;
139 } else {
140 t3_file = xfopen(name, FOPEN_RBIN_MODE);
141 recorder_record_input(name);
142 t3_read_file();
143 t3_close();
145 t3_image_used = true;
146 is_pk_font = true;
147 report_start_file(filetype_font,(char *) name);
148 cd.rastersize = 256;
149 cd.raster = xtalloc((unsigned long) cd.rastersize, halfword);
150 check_preamble = true;
151 while (readchar(check_preamble, &cd) != 0) {
152 check_preamble = false;
153 if (!pdf_char_marked(f, cd.charcode))
154 continue;
155 t3_char_widths[cd.charcode] = (float) pk_char_width(pdf, f, get_charwidth(f, cd.charcode), pdf->pk_scale_factor);
156 if (cd.cwidth < 1 || cd.cheight < 1) {
157 cd.xescape = cd.cwidth = round(t3_char_widths[cd.charcode] / 100.0);
158 cd.cheight = 1;
159 cd.xoff = 0;
160 cd.yoff = 0;
161 is_null_glyph = true;
162 } else
163 is_null_glyph = false;
164 llx = -cd.xoff;
165 lly = cd.yoff - cd.cheight + 1;
166 urx = cd.cwidth + llx + 1;
167 ury = cd.cheight + lly;
168 update_bbox(llx, lly, urx, ury, t3_glyph_num == 0);
169 t3_glyph_num++;
170 t3_char_procs[cd.charcode] = pdf_create_obj(pdf, obj_type_others, 0);
171 pdf_begin_obj(pdf, t3_char_procs[cd.charcode], OBJSTM_NEVER);
172 pdf_begin_dict(pdf);
173 pdf_dict_add_streaminfo(pdf);
174 pdf_end_dict(pdf);
175 pdf_begin_stream(pdf);
176 setpdffloat(pf, (int64_t) t3_char_widths[cd.charcode], 2);
177 print_pdffloat(pdf, pf);
178 pdf_printf(pdf, " 0 %i %i %i %i d1\n", (int) llx, (int) lly, (int) urx, (int) ury);
179 if (is_null_glyph)
180 goto end_stream;
181 pdf_printf(pdf, "q\n%i 0 0 %i %i %i cm\nBI\n",
182 (int) (dpi * cd.cwidth / newdpi),
183 (int) (dpi * cd.cheight / newdpi),
184 (int) llx, (int) lly);
185 pdf_printf(pdf, "/W %i\n/H %i\n", (int) cd.cwidth, (int) cd.cheight);
186 pdf_puts(pdf, "/IM true\n/BPC 1\n/D [1 0]\nID ");
187 cw = (cd.cwidth + 7) / 8;
188 rw = (cd.cwidth + 15) / 16;
189 row = cd.raster;
190 for (i = 0; i < cd.cheight; i++) {
191 for (j = 0; j < rw - 1; j++) {
192 pdf_out(pdf, (unsigned char) (*row / 256));
193 pdf_out(pdf, (unsigned char) (*row % 256));
194 row++;
196 pdf_out(pdf, (unsigned char) (*row / 256));
197 if (2 * rw == cw)
198 pdf_out(pdf, (unsigned char) (*row % 256));
199 row++;
201 pdf_puts(pdf, "\nEI\nQ\n");
202 end_stream:
203 pdf_end_stream(pdf);
204 pdf_end_obj(pdf);
206 xfree(cd.raster);
207 cur_file_name = NULL;
208 return true;
213 void writet3(PDF pdf, internal_font_number f)
215 int i;
216 char s[32];
217 int wptr, eptr, cptr;
218 int first_char, last_char;
219 int pk_font_scale;
220 pdffloat pf;
221 boolean is_notdef;
223 t3_glyph_num = 0;
224 t3_image_used = false;
225 for (i = 0; i < 256; i++) {
226 t3_char_procs[i] = 0;
227 t3_char_widths[i] = 0;
229 is_pk_font = false;
231 xfree(t3_buffer);
232 t3_curbyte = 0;
233 t3_size = 0;
234 if (!writepk(pdf, f))
235 return;
236 for (i = font_bc(f); i <= font_ec(f); i++)
237 if (pdf_char_marked(f, i))
238 break;
239 first_char = i;
240 for (i = font_ec(f); i > first_char; i--)
241 if (pdf_char_marked(f, i))
242 break;
243 last_char = i;
245 /* Type 3 font dictionary */
246 pdf_begin_obj(pdf, pdf_font_num(f), OBJSTM_ALWAYS);
247 pdf_begin_dict(pdf);
248 pdf_dict_add_name(pdf, "Type", "Font");
249 pdf_dict_add_name(pdf, "Subtype", "Type3");
250 snprintf(s, 31, "F%i", (int) f);
251 pdf_dict_add_name(pdf, "Name", s);
252 if (pdf_font_attr(f) != get_nullstr() && pdf_font_attr(f) != 0) {
253 pdf_out(pdf, '\n');
254 pdf_print(pdf, pdf_font_attr(f));
255 pdf_out(pdf, '\n');
257 if (is_pk_font) {
258 pk_font_scale = get_pk_font_scale(pdf,f,pdf->pk_scale_factor);
259 pdf_add_name(pdf, "FontMatrix");
260 pdf_begin_array(pdf);
261 setpdffloat(pf, (int64_t) pk_font_scale, 5);
262 print_pdffloat(pdf, pf);
263 pdf_puts(pdf, " 0 0 ");
264 print_pdffloat(pdf, pf);
265 pdf_puts(pdf, " 0 0");
266 pdf_end_array(pdf);
267 } else {
268 pdf_add_name(pdf, "FontMatrix");
269 pdf_begin_array(pdf);
270 pdf_printf(pdf, "%g 0 0 %g 0 0", (double) t3_font_scale, (double) t3_font_scale);
271 pdf_end_array(pdf);
273 pdf_add_name(pdf, font_key[FONTBBOX1_CODE].pdfname);
274 pdf_begin_array(pdf);
275 pdf_add_int(pdf, (int) t3_b0);
276 pdf_add_int(pdf, (int) t3_b1);
277 pdf_add_int(pdf, (int) t3_b2);
278 pdf_add_int(pdf, (int) t3_b3);
279 pdf_end_array(pdf);
280 pdf_add_name(pdf, "Resources");
281 pdf_begin_dict(pdf);
282 pdf_add_name(pdf, "ProcSet");
283 pdf_begin_array(pdf);
284 pdf_add_name(pdf, "PDF");
285 if (t3_image_used) {
286 pdf_add_name(pdf, "ImageB");
288 pdf_end_array(pdf);
289 pdf_end_dict(pdf);
290 pdf_dict_add_int(pdf, "FirstChar", first_char);
291 pdf_dict_add_int(pdf, "LastChar", last_char);
292 wptr = pdf_create_obj(pdf, obj_type_others, 0);
293 eptr = pdf_create_obj(pdf, obj_type_others, 0);
294 cptr = pdf_create_obj(pdf, obj_type_others, 0);
295 pdf_dict_add_ref(pdf, "Widths", (int) wptr);
296 pdf_dict_add_ref(pdf, "Encoding", (int) eptr);
297 pdf_dict_add_ref(pdf, "CharProcs", (int) cptr);
298 pdf_end_dict(pdf);
299 pdf_end_obj(pdf);
301 /* chars width array */
302 pdf_begin_obj(pdf, wptr, OBJSTM_ALWAYS);
303 pdf_begin_array(pdf);
304 if (is_pk_font) {
305 for (i = first_char; i <= last_char; i++) {
306 setpdffloat(pf, (int64_t) t3_char_widths[i], 2);
307 print_pdffloat(pdf, pf);
308 pdf_out(pdf, ' ');
310 } else {
311 for (i = first_char; i <= last_char; i++) {
312 pdf_add_int(pdf, (int) t3_char_widths[i]);
315 pdf_end_array(pdf);
316 pdf_end_obj(pdf);
318 /* encoding dictionary */
319 pdf_begin_obj(pdf, eptr, OBJSTM_ALWAYS);
320 pdf_begin_dict(pdf);
321 pdf_dict_add_name(pdf, "Type", "Encoding");
322 pdf_add_name(pdf, "Differences");
323 pdf_begin_array(pdf);
324 pdf_add_int(pdf, first_char);
325 if (t3_char_procs[first_char] == 0) {
326 pdf_add_name(pdf, notdef);
327 is_notdef = true;
328 } else {
329 snprintf(s, 31, "a%i", first_char);
330 pdf_add_name(pdf, s);
331 is_notdef = false;
333 for (i = first_char + 1; i <= last_char; i++) {
334 if (t3_char_procs[i] == 0) {
335 if (!is_notdef) {
336 pdf_add_int(pdf, i);
337 pdf_add_name(pdf, notdef);
338 is_notdef = true;
340 } else {
341 if (is_notdef) {
342 pdf_add_int(pdf, i);
343 is_notdef = false;
345 snprintf(s, 31, "a%i", i);
346 pdf_add_name(pdf, s);
349 pdf_end_array(pdf);
350 pdf_end_dict(pdf);
351 pdf_end_obj(pdf);
353 /* CharProcs dictionary */
354 pdf_begin_obj(pdf, cptr, OBJSTM_ALWAYS);
355 pdf_begin_dict(pdf);
356 for (i = first_char; i <= last_char; i++) {
357 if (t3_char_procs[i] != 0) {
358 snprintf(s, 31, "a%i", (int) i);
359 pdf_dict_add_ref(pdf, s, (int) t3_char_procs[i]);
362 pdf_end_dict(pdf);
363 pdf_end_obj(pdf);
364 report_stop_file(filetype_font);
365 cur_file_name = NULL;