beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / font / writefont.w
blob81a8b0f9b045372f05db753576dc633ebd581eff
1 % writefont.w
3 % Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
4 % Copyright 2006-2010 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 "lua/luatex-api.h"
27 void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f);
28 static void create_cid_fontdictionary(PDF pdf, internal_font_number f);
30 const key_entry font_key[FONT_KEYS_NUM] = {
31 {"Ascent", "Ascender", 1}
32 , {"CapHeight", "CapHeight", 1}
33 , {"Descent", "Descender", 1}
34 , {"ItalicAngle", "ItalicAngle", 1}
35 , {"StemV", "StdVW", 1}
36 , {"XHeight", "XHeight", 1}
37 , {"FontBBox", "FontBBox", 1}
38 , {"", "", 0}
39 , {"", "", 0}
40 , {"", "", 0}
41 , {"FontName", "FontName", 1}
46 struct avl_table *fo_tree = NULL; /* tree of font dictionaries */
47 struct avl_table *fd_tree = NULL; /* tree of font descriptor objects */
49 static int comp_fo_entry(const void *pa, const void *pb, void *p)
51 (void) p;
52 return strcmp(((const fo_entry *) pa)->fm->tfm_name,
53 ((const fo_entry *) pb)->fm->tfm_name);
56 static int comp_fd_entry(const void *pa, const void *pb, void *p)
58 const fd_entry *p1 = (const fd_entry *) pa, *p2 = (const fd_entry *) pb;
59 (void) p;
60 assert(p1->fm != NULL && is_fontfile(p1->fm) &&
61 p2->fm != NULL && is_fontfile(p2->fm));
62 return strcmp(p1->fm->ff_name, p2->fm->ff_name);
65 @ initialize data structure for /Type /Font
67 static fo_entry *new_fo_entry(void)
69 fo_entry *fo;
70 fo = xtalloc(1, fo_entry);
71 fo->fo_objnum = 0;
72 fo->tex_font = 0;
73 fo->fm = NULL;
74 fo->fd = NULL;
75 fo->fe = NULL;
76 fo->cw_objnum = 0;
77 fo->first_char = 1;
78 fo->last_char = 0;
79 fo->tx_tree = NULL;
80 fo->tounicode_objnum = 0;
81 return fo;
84 @ initialize data structure for /Type /FontDescriptor
86 fd_entry *new_fd_entry(void)
88 fd_entry *fd;
89 int i;
90 fd = xtalloc(1, fd_entry);
91 fd->fd_objnum = 0;
92 fd->fontname = NULL;
93 fd->subset_tag = NULL;
94 fd->ff_found = false;
95 fd->ff_objnum = 0;
96 fd->all_glyphs = false;
97 fd->write_ttf_glyph_names = false;
98 for (i = 0; i < FONT_KEYS_NUM; i++) {
99 fd->font_dim[i].val = 0;
100 fd->font_dim[i].set = false;
102 fd->fe = NULL;
103 fd->builtin_glyph_names = NULL;
104 fd->fm = NULL;
105 fd->tx_tree = NULL;
106 fd->gl_tree = NULL;
107 return fd;
111 Only fallback values of font metrics are taken from the TFM info
112 of |f| by |preset_fontmetrics|. During reading of the font file,
113 these values are replaced by metrics from the font, if available.
116 static void preset_fontmetrics(fd_entry * fd, internal_font_number f)
118 int i;
119 fd->font_dim[ITALIC_ANGLE_CODE].val = 0;
120 fd->font_dim[ASCENT_CODE].val =
121 divide_scaled(char_height(f, 'h'), font_size(f), 3);
122 fd->font_dim[CAPHEIGHT_CODE].val =
123 divide_scaled(char_height(f, 'H'), font_size(f), 3);
124 i = -divide_scaled(char_depth(f, 'y'), font_size(f), 3);
125 fd->font_dim[DESCENT_CODE].val = i < 0 ? i : 0;
126 fd->font_dim[STEMV_CODE].val =
127 divide_scaled(char_width(f, '.') / 3, font_size(f), 3);
128 fd->font_dim[XHEIGHT_CODE].val =
129 divide_scaled(get_x_height(f), font_size(f), 3);
130 fd->font_dim[FONTBBOX1_CODE].val = 0;
131 fd->font_dim[FONTBBOX2_CODE].val = fd->font_dim[DESCENT_CODE].val;
132 fd->font_dim[FONTBBOX3_CODE].val =
133 divide_scaled(get_quad(f), font_size(f), 3);
134 fd->font_dim[FONTBBOX4_CODE].val =
135 fd->font_dim[CAPHEIGHT_CODE].val > fd->font_dim[ASCENT_CODE].val ?
136 fd->font_dim[CAPHEIGHT_CODE].val : fd->font_dim[ASCENT_CODE].val;
137 for (i = 0; i < INT_KEYS_NUM; i++)
138 fd->font_dim[i].set = true;
141 static void fix_fontmetrics(fd_entry * fd)
143 int i;
144 intparm *p = (intparm *) fd->font_dim;
145 assert(p[FONTBBOX1_CODE].set && p[FONTBBOX2_CODE].set
146 && p[FONTBBOX3_CODE].set && p[FONTBBOX4_CODE].set);
147 /* make sure there is a rectangle */
148 if (p[FONTBBOX3_CODE].val < p[FONTBBOX1_CODE].val) {
149 i = p[FONTBBOX3_CODE].val;
150 p[FONTBBOX3_CODE].val = p[FONTBBOX1_CODE].val;
151 p[FONTBBOX1_CODE].val = i;
152 } else if (p[FONTBBOX3_CODE].val == p[FONTBBOX1_CODE].val)
153 p[FONTBBOX3_CODE].val = p[FONTBBOX1_CODE].val + 1;
154 if (p[FONTBBOX4_CODE].val < p[FONTBBOX2_CODE].val) {
155 i = p[FONTBBOX4_CODE].val;
156 p[FONTBBOX4_CODE].val = p[FONTBBOX2_CODE].val;
157 p[FONTBBOX2_CODE].val = i;
158 } else if (p[FONTBBOX4_CODE].val == p[FONTBBOX2_CODE].val)
159 p[FONTBBOX4_CODE].val = p[FONTBBOX2_CODE].val + 1;
160 if (!p[ASCENT_CODE].set) {
161 p[ASCENT_CODE].val = p[FONTBBOX4_CODE].val;
162 p[ASCENT_CODE].set = true;
164 if (!p[DESCENT_CODE].set) {
165 p[DESCENT_CODE].val = p[FONTBBOX2_CODE].val;
166 p[DESCENT_CODE].set = true;
168 if (!p[CAPHEIGHT_CODE].set) {
169 p[CAPHEIGHT_CODE].val = p[FONTBBOX4_CODE].val;
170 p[CAPHEIGHT_CODE].set = true;
174 static void write_fontmetrics(PDF pdf, fd_entry * fd)
176 int i;
177 fix_fontmetrics(fd);
178 pdf_add_name(pdf, font_key[FONTBBOX1_CODE].pdfname);
179 pdf_begin_array(pdf);
180 pdf_printf(pdf, "%i %i %i %i", (int) fd->font_dim[FONTBBOX1_CODE].val,
181 (int) fd->font_dim[FONTBBOX2_CODE].val,
182 (int) fd->font_dim[FONTBBOX3_CODE].val,
183 (int) fd->font_dim[FONTBBOX4_CODE].val);
184 pdf_end_array(pdf);
185 for (i = 0; i < GEN_KEY_NUM; i++)
186 if (fd->font_dim[i].set)
187 pdf_dict_add_int(pdf, font_key[i].pdfname, fd->font_dim[i].val);
192 static void preset_fontname(fo_entry * fo, internal_font_number f)
194 if (fo->fm->ps_name != NULL)
195 fo->fd->fontname = xstrdup(fo->fm->ps_name); /* just fallback */
196 else if (font_fullname(f) != NULL)
197 fo->fd->fontname = xstrdup(font_fullname(f));
198 else
199 fo->fd->fontname = xstrdup(fo->fm->tfm_name);
202 static void pdf_dict_add_fontname(PDF pdf, const char *key, fd_entry * fd)
204 char *s;
205 size_t l1 = 0, l2;
206 assert(fd->fontname != NULL);
207 assert(key != NULL);
208 if (fd->subset_tag != NULL)
209 l1 = strlen(fd->subset_tag);
210 l2 = strlen(fd->fontname);
211 s = xmalloc(l1 + l2 + 2);
212 if (l1 > 0)
213 snprintf(s, l1 + l2 + 2, "%s+%s", fd->subset_tag, fd->fontname);
214 else
215 snprintf(s, l2 + 1, "%s", fd->fontname);
216 pdf_dict_add_name(pdf, key, s);
217 xfree(s);
222 fd_entry *lookup_fd_entry(char *s)
224 fd_entry fd;
225 fm_entry fm;
226 assert(s != NULL);
227 fm.ff_name = s;
228 fd.fm = &fm;
229 if (fd_tree == NULL) {
230 fd_tree = avl_create(comp_fd_entry, NULL, &avl_xallocator);
231 assert(fd_tree != NULL);
233 return (fd_entry *) avl_find(fd_tree, &fd);
236 static fd_entry *lookup_fontdescriptor(fo_entry * fo)
238 assert(fo != NULL);
239 assert(fo->fm != NULL);
240 assert(is_fontfile(fo->fm));
241 return lookup_fd_entry(fo->fm->ff_name);
244 void register_fd_entry(fd_entry * fd)
246 void **aa;
247 if (fd_tree == NULL) {
248 fd_tree = avl_create(comp_fd_entry, NULL, &avl_xallocator);
249 assert(fd_tree != NULL);
251 assert(fd != NULL && fd->fm != NULL && is_fontfile(fd->fm));
252 assert(lookup_fd_entry(fd->fm->ff_name) == NULL); /* font descriptor not yet registered */
253 aa = avl_probe(fd_tree, fd);
254 assert(aa != NULL);
257 static void create_fontdescriptor(fo_entry * fo, internal_font_number f)
259 assert(fo != NULL);
260 assert(fo->fm != NULL);
261 assert(fo->fd == NULL);
262 fo->fd = new_fd_entry();
263 preset_fontname(fo, f);
264 preset_fontmetrics(fo->fd, f);
265 fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */
266 fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */
267 fo->fd->gl_tree = avl_create(comp_string_entry, NULL, &avl_xallocator);
268 assert(fo->fd->gl_tree != NULL);
272 For all used characters of \TeX font |f|, get corresponding glyph names
273 from external reencoding (.enc) file and collect these in the glyph
274 tree |gl_tree| of font descriptor |fd| referenced by font dictionary |fo|.
277 static void mark_reenc_glyphs(fo_entry * fo, internal_font_number f)
279 int i;
280 char **g;
281 void **aa;
282 assert(fo->fe != NULL);
283 if (is_subsetted(fo->fm)) {
284 assert(is_included(fo->fm));
285 /* mark glyphs from TeX (externally reencoded characters) */
286 g = fo->fe->glyph_names;
287 for (i = fo->first_char; i <= fo->last_char; i++) {
288 if (pdf_char_marked(f, i) && g[i] != notdef
289 && (char *) avl_find(fo->fd->gl_tree, g[i]) == NULL) {
290 aa = avl_probe(fo->fd->gl_tree, xstrdup(g[i]));
291 assert(aa != NULL);
298 Function |mark_chars| has 2 uses:
299 \item 1. Mark characters as chars on \TeX\ level.
300 \item 2. Mark encoding pairs used by \TeX\ to optimize encoding vector.
303 static struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree,
304 internal_font_number f)
306 int i, *j;
307 void **aa;
308 if (tx_tree == NULL) {
309 tx_tree = avl_create(comp_int_entry, NULL, &avl_xallocator);
310 assert(tx_tree != NULL);
312 for (i = fo->first_char; i <= fo->last_char; i++) {
313 if (pdf_char_marked(f, i) && (int *) avl_find(tx_tree, &i) == NULL) {
314 j = xtalloc(1, int);
315 *j = i;
316 aa = avl_probe(tx_tree, j);
317 assert(aa != NULL);
320 return tx_tree;
325 static void get_char_range(fo_entry * fo, internal_font_number f)
327 int i;
328 assert(fo != NULL);
329 for (i = font_bc(f); i <= font_ec(f); i++) /* search for |first_char| and |last_char| */
330 if (pdf_char_marked(f, i))
331 break;
332 fo->first_char = i;
333 for (i = font_ec(f); i >= font_bc(f); i--)
334 if (pdf_char_marked(f, i))
335 break;
336 fo->last_char = i;
337 if ((fo->first_char > fo->last_char)
338 || !pdf_char_marked(f, fo->first_char)) { /* no character used from this font */
339 fo->last_char = 0;
340 fo->first_char = fo->last_char + 1;
344 static int font_has_subset(internal_font_number f)
346 int i, s;
347 for (i = font_bc(f); i <= font_ec(f); i++) /* search for |first_char| and |last_char| */
348 if (pdf_char_marked(f, i))
349 break;
350 s = i;
351 for (i = font_ec(f); i >= font_bc(f); i--)
352 if (pdf_char_marked(f, i))
353 break;
354 if (s > i)
355 return 0;
356 else
357 return 1;
362 static void write_charwidth_array(PDF pdf, fo_entry * fo,
363 internal_font_number f)
365 int i, j, *ip, *fip;
366 struct avl_traverser t;
367 assert(fo->tx_tree != NULL);
368 assert(fo->cw_objnum == 0);
369 fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0);
370 pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS);
371 avl_t_init(&t, fo->tx_tree);
372 fip = (int *) avl_t_first(&t, fo->tx_tree);
373 assert(fip != NULL);
374 pdf_begin_array(pdf);
375 for (ip = fip, j = *ip; ip != NULL; ip = (int *) avl_t_next(&t)) {
376 if (ip != fip)
377 pdf_out(pdf, ' ');
378 i = *ip;
379 while (j < i - 1) {
380 pdf_puts(pdf, "0 ");
381 j++;
383 j = i;
384 pdf_print_charwidth(pdf, f, i);
386 pdf_end_array(pdf);
387 pdf_end_obj(pdf);
390 @ Remark: Font objects from embedded PDF files are never registered
391 into |fo_tree|; they are individually written out.
393 static fo_entry *lookup_fo_entry(char *s)
395 fo_entry fo;
396 fm_entry fm;
397 assert(s != NULL);
398 fm.tfm_name = s;
399 fo.fm = &fm;
400 if (fo_tree == NULL) {
401 fo_tree = avl_create(comp_fo_entry, NULL, &avl_xallocator);
402 assert(fo_tree != NULL);
404 return (fo_entry *) avl_find(fo_tree, &fo);
407 static void register_fo_entry(fo_entry * fo)
409 void **aa;
410 if (fo_tree == NULL) {
411 fo_tree = avl_create(comp_fo_entry, NULL, &avl_xallocator);
412 assert(fo_tree != NULL);
414 assert(fo != NULL);
415 assert(fo->fm != NULL);
416 assert(fo->fm->tfm_name != NULL);
417 assert(lookup_fo_entry(fo->fm->tfm_name) == NULL);
418 aa = avl_probe(fo_tree, fo);
419 assert(aa != NULL);
424 static void write_fontfile(PDF pdf, fd_entry * fd)
426 assert(is_included(fd->fm));
427 /* In principle we could replace the pdftex derived ttf.otf inclusion part */
428 /* by using the regular code for this and assigning indices and tounicodes */
429 /* to the character blobs, but for the moment we keep the current approach */
430 if (is_cidkeyed(fd->fm)) {
431 if (is_opentype(fd->fm)) {
432 writetype0(pdf, fd);
433 } else if (is_truetype(fd->fm)) {
434 if (!writetype2(pdf, fd)) {
435 writetype0(pdf,fd);
436 fd->fm->type |= F_OTF; fd->fm->type ^= F_TRUETYPE;
438 } else if (is_type1(fd->fm))
439 writetype1w(pdf, fd);
440 else
441 assert(0);
442 } else {
443 if (is_type1(fd->fm))
444 writet1(pdf, fd);
445 else if (is_truetype(fd->fm))
446 writettf(pdf, fd);
447 else if (is_opentype(fd->fm))
448 writeotf(pdf, fd);
449 else
450 assert(0);
452 if (!fd->ff_found)
453 return;
454 assert(fd->ff_objnum == 0);
455 fd->ff_objnum = pdf_create_obj(pdf, obj_type_others, 0);
456 pdf_begin_obj(pdf, fd->ff_objnum, OBJSTM_NEVER); /* font file stream */
457 pdf_begin_dict(pdf);
458 if (is_cidkeyed(fd->fm)) {
459 /* No subtype is used for TrueType-based OpenType fonts */
460 if (is_opentype(fd->fm) || is_type1(fd->fm))
461 pdf_dict_add_name(pdf, "Subtype", "CIDFontType0C");
462 #if 0
463 else
464 pdf_dict_add_name(pdf, "Subtype", "OpenType");
465 #endif
466 } else {
467 if (is_type1(fd->fm)) {
468 pdf_dict_add_int(pdf, "Length1", (int) t1_length1);
469 pdf_dict_add_int(pdf, "Length2", (int) t1_length2);
470 pdf_dict_add_int(pdf, "Length3", (int) t1_length3);
471 } else if (is_truetype(fd->fm))
472 pdf_dict_add_int(pdf, "Length1", (int) ttf_length);
473 else if (is_opentype(fd->fm))
474 pdf_dict_add_name(pdf, "Subtype", "Type1C");
475 else
476 assert(0);
478 pdf_dict_add_streaminfo(pdf);
479 pdf_end_dict(pdf);
480 pdf_begin_stream(pdf);
481 strbuf_flush(pdf, pdf->fb);
482 pdf_end_stream(pdf);
483 pdf_end_obj(pdf);
488 int cidset = 0;
489 static void write_fontdescriptor(PDF pdf, fd_entry * fd)
491 static const int std_flags[] = {
492 /* indices for << start with 0, but bits start with 1, so the numbers
493 * for << are 1 lower than the bits in table 5.20 */
494 /* *INDENT-OFF* */
495 1 + 2 + (1 << 5), /* Courier */
496 1 + 2 + (1 << 5) + (1 << 18),/* Courier-Bold */
497 1 + 2 + (1 << 5) + (1 << 6), /* Courier-Oblique */
498 1 + 2 + (1 << 5) + (1 << 6) + (1 << 18),/* Courier-BoldOblique */
499 (1 << 5), /* Helvetica */
500 (1 << 5) + (1 << 18),/* Helvetica-Bold */
501 (1 << 5) + (1 << 6), /* Helvetica-Oblique */
502 (1 << 5) + (1 << 6) + (1 << 18),/* Helvetica-BoldOblique */
503 4, /* Symbol */
504 2 + (1 << 5), /* Times-Roman */
505 2 + (1 << 5) + (1 << 18),/* Times-Bold */
506 2 + (1 << 5) + (1 << 6), /* Times-Italic */
507 2 + (1 << 5) + (1 << 6) + (1 << 18),/* Times-BoldItalic */
508 4 /* ZapfDingbats */
509 /* *INDENT-ON* */
511 char *glyph;
512 struct avl_traverser t;
513 int fd_flags;
514 assert(fd != NULL && fd->fm != NULL);
515 cidset = 0; /* possibly updated by |write_fontfile| */
516 if (is_fontfile(fd->fm) && is_included(fd->fm))
517 write_fontfile(pdf, fd); /* this will set |fd->ff_found| if font file is found */
518 if (fd->fd_objnum == 0)
519 fd->fd_objnum = pdf_create_obj(pdf, obj_type_others, 0);
520 pdf_begin_obj(pdf, fd->fd_objnum, OBJSTM_ALWAYS);
521 pdf_begin_dict(pdf);
522 pdf_dict_add_name(pdf, "Type", "FontDescriptor");
523 pdf_dict_add_fontname(pdf, "FontName", fd);
524 if (fd->fm->fd_flags != FD_FLAGS_NOT_SET_IN_MAPLINE)
525 fd_flags = (int) fd->fm->fd_flags;
526 else if (fd->ff_found)
527 fd_flags = FD_FLAGS_DEFAULT_EMBED;
528 else {
529 fd_flags = is_std_t1font(fd->fm)
530 ? std_flags[check_std_t1font(fd->fm->ps_name)]
531 : FD_FLAGS_DEFAULT_NON_EMBED;
532 formatted_warning("map file",
533 "No flags specified for non-embedded font '%s' (%s), I'm using %i, fix your map entry",
534 fd->fm->ps_name != NULL ? fd->fm->ps_name : "No name given",
535 fd->fm->tfm_name, fd_flags);
537 pdf_dict_add_int(pdf, "Flags", fd_flags);
538 write_fontmetrics(pdf, fd);
539 if (fd->ff_found) {
540 if (is_cidkeyed(fd->fm)) {
541 if (is_type1(fd->fm))
542 pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum);
543 else if (is_truetype(fd->fm))
544 pdf_dict_add_ref(pdf, "FontFile2", (int) fd->ff_objnum);
545 else if (is_opentype(fd->fm))
546 pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum);
547 else
548 assert(0);
549 } else {
550 if (is_subsetted(fd->fm) && is_type1(fd->fm)) {
551 /* /CharSet is optional; names may appear in any order */
552 assert(fd->gl_tree != NULL);
553 avl_t_init(&t, fd->gl_tree);
554 pdf_add_name(pdf, "CharSet");
555 pdf_out(pdf, '(');
556 for (glyph = (char *) avl_t_first(&t, fd->gl_tree);
557 glyph != NULL; glyph = (char *) avl_t_next(&t))
558 pdf_add_name(pdf, glyph);
559 pdf_out(pdf, ')');
560 pdf->cave = 0;
562 if (is_type1(fd->fm))
563 pdf_dict_add_ref(pdf, "FontFile", (int) fd->ff_objnum);
564 else if (is_truetype(fd->fm))
565 pdf_dict_add_ref(pdf, "FontFile2", (int) fd->ff_objnum);
566 else if (is_opentype(fd->fm))
567 pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum);
568 else
569 assert(0);
572 if (cidset != 0)
573 pdf_dict_add_ref(pdf, "CIDSet", cidset);
574 /* TODO: Other optional keys for CID fonts.
575 The most interesting one is
576 \.{/Style << /Panose <12-byte string>>>}
578 pdf_end_dict(pdf);
579 pdf_end_obj(pdf);
582 static void write_fontdescriptors(PDF pdf)
584 fd_entry *fd;
585 struct avl_traverser t;
586 if (fd_tree == NULL)
587 return;
588 avl_t_init(&t, fd_tree);
589 for (fd = (fd_entry *) avl_t_first(&t, fd_tree); fd != NULL;
590 fd = (fd_entry *) avl_t_next(&t))
591 write_fontdescriptor(pdf, fd);
596 static void write_fontdictionary(PDF pdf, fo_entry * fo)
598 assert(fo != NULL);
599 assert(fo->fm != NULL);
600 assert(fo->fo_objnum != 0); /* reserved as |pdf_font_num(f)| elsewhere */
602 /* write ToUnicode entry if needed */
603 if (pdf->gen_tounicode > 0 && fo->fd != NULL) {
604 if (fo->fe != NULL) {
605 fo->tounicode_objnum =
606 write_tounicode(pdf, fo->fe->glyph_names, fo->fe->name);
607 } else if (is_type1(fo->fm)) {
608 assert(fo->fd->builtin_glyph_names != NULL);
609 fo->tounicode_objnum =
610 write_tounicode(pdf, fo->fd->builtin_glyph_names,
611 fo->fm->tfm_name);
614 pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS);
615 pdf_begin_dict(pdf);
616 pdf_dict_add_name(pdf, "Type", "Font");
617 if (is_type1(fo->fm))
618 pdf_dict_add_name(pdf, "Subtype", "Type1");
619 else if (is_truetype(fo->fm))
620 pdf_dict_add_name(pdf, "Subtype", "TrueType");
621 else if (is_opentype(fo->fm))
622 pdf_dict_add_name(pdf, "Subtype", "Type1");
623 else
624 assert(0);
625 assert(fo->fd != NULL && fo->fd->fd_objnum != 0);
626 pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
627 pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum);
628 assert(fo->cw_objnum != 0);
629 pdf_dict_add_int(pdf, "FirstChar", (int) fo->first_char);
630 pdf_dict_add_int(pdf, "LastChar", (int) fo->last_char);
631 pdf_dict_add_ref(pdf, "Widths", (int) fo->cw_objnum);
632 if ((is_type1(fo->fm) || is_opentype(fo->fm)) && fo->fe != NULL
633 && fo->fe->fe_objnum != 0)
634 pdf_dict_add_ref(pdf, "Encoding", (int) fo->fe->fe_objnum);
635 if (fo->tounicode_objnum != 0)
636 pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum);
637 if (pdf_font_attr(fo->tex_font) != get_nullstr() &&
638 pdf_font_attr(fo->tex_font) != 0) {
639 pdf_print(pdf, pdf_font_attr(fo->tex_font));
640 pdf_out(pdf, '\n');
642 pdf_end_dict(pdf);
643 pdf_end_obj(pdf);
646 static void write_fontdictionaries(PDF pdf)
648 fo_entry *fo;
649 struct avl_traverser t;
650 if (fo_tree == NULL)
651 return;
652 avl_t_init(&t, fo_tree);
653 for (fo = (fo_entry *) avl_t_first(&t, fo_tree); fo != NULL;
654 fo = (fo_entry *) avl_t_next(&t))
655 write_fontdictionary(pdf, fo);
658 @ Final flush of all font related stuff by call from
659 \.{Output fonts definitions} elsewhere
662 void write_fontstuff(PDF pdf)
664 write_fontdescriptors(pdf);
665 write_fontencodings(pdf); /* see \.{writeenc.w} */
666 write_fontdictionaries(pdf);
671 static void create_fontdictionary(PDF pdf, internal_font_number f)
673 fo_entry *fo = new_fo_entry();
674 fm_entry *fm = font_map(f);
675 get_char_range(fo, f); /* set |fo->first_char| and |fo->last_char| from |f| */
676 if (fo->last_char > 255)
677 fo->last_char = 255; /* added 9-4-2008, mantis \#25 */
678 assert(fo->last_char >= fo->first_char);
679 fo->fm = fm;
680 fo->fo_objnum = pdf_font_num(f);
681 fo->tex_font = f;
682 if (is_reencoded(fo->fm)) { /* at least the map entry tells so */
683 fo->fe = get_fe_entry(fo->fm->encname); /* returns |NULL| if .enc file couldn't be opened */
684 if (fo->fe != NULL && (is_type1(fo->fm) || is_opentype(fo->fm))) {
685 if (fo->fe->fe_objnum == 0)
686 fo->fe->fe_objnum = pdf_create_obj(pdf, obj_type_others, 0); /* then it will be written out */
687 /* mark encoding pairs used by TeX to optimize encoding vector */
688 fo->fe->tx_tree = mark_chars(fo, fo->fe->tx_tree, f);
691 fo->tx_tree = mark_chars(fo, fo->tx_tree, f); /* for |write_charwidth_array| */
692 write_charwidth_array(pdf, fo, f);
693 if (!is_builtin(fo->fm)) {
694 if (is_type1(fo->fm)) {
695 if ((fo->fd = lookup_fontdescriptor(fo)) == NULL) {
696 create_fontdescriptor(fo, f);
697 register_fd_entry(fo->fd);
699 } else
700 create_fontdescriptor(fo, f);
701 if (fo->fe != NULL) {
702 mark_reenc_glyphs(fo, f);
703 if (!is_type1(fo->fm)) {
704 /* mark reencoded characters as chars on TeX level */
705 assert(fo->fd->tx_tree == NULL);
706 fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f);
707 if (is_truetype(fo->fm))
708 fo->fd->write_ttf_glyph_names = true;
710 } else
711 /* mark non-reencoded characters as chars on TeX level */
712 fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f);
713 if (!is_type1(fo->fm))
714 write_fontdescriptor(pdf, fo->fd);
715 } else {
716 /* builtin fonts still need the /Widths array and /FontDescriptor
717 * (to avoid error 'font FOO contains bad /BBox')
719 create_fontdescriptor(fo, f);
720 write_fontdescriptor(pdf, fo->fd);
721 if (!is_std_t1font(fo->fm))
722 formatted_warning("map file", "font '%s' is not a standard font; I suppose it is available to your PDF viewer then",
723 fo->fm->ps_name);
725 if (is_type1(fo->fm))
726 register_fo_entry(fo);
727 else
728 write_fontdictionary(pdf, fo);
733 static int has_ttf_outlines(fm_entry * fm)
735 FILE *f = fopen(fm->ff_name, "rb");
736 if (f != NULL) {
737 int ch1 = getc(f);
738 int ch2 = getc(f);
739 int ch3 = getc(f);
740 int ch4 = getc(f);
741 fclose(f);
742 if (ch1 == 'O' && ch2 == 'T' && ch3 == 'T' && ch4 == 'O')
743 return 0;
744 return 1;
746 return 0;
749 void do_pdf_font(PDF pdf, internal_font_number f)
751 int del_file = 0;
752 fm_entry *fm;
753 /* TODO This is not 100\% true: CID is actually needed whenever (and
754 only) there are more than 256 separate glyphs used. But for
755 now, just assume the user knows what he is doing;
757 if (!font_has_subset(f))
758 return;
760 if (font_encodingbytes(f) == 2) {
761 /* Create a virtual font map entry, as this is needed by the
762 rest of the font inclusion mechanism.
764 fm = font_map(f) = new_fm_entry();
765 fm->tfm_name = font_name(f); /* or whatever, not a real tfm */
766 fm->ff_name = font_filename(f); /* the actual file */
767 if (font_psname(f) != NULL)
768 fm->ps_name = font_psname(f); /* the true name */
769 else
770 fm->ps_name = font_fullname(f); /* the true name */
771 if (fm->ff_name
772 && strlen(fm->ff_name) >= 6
773 && strstr(fm->ff_name,
774 ".dfont") == (fm->ff_name + strlen(fm->ff_name) - 6)) {
775 /* In case of a .dfont, we will extract the correct ttf here,
776 and adjust |fm->ff_name| to point to the temporary file.
777 This file will be deleted later. Todo: keep a nicer name
778 somewhere for the terminal message.
780 char *s = FindResourceTtfFont(fm->ff_name, fm->ps_name);
781 if (s != NULL) {
782 fm->ff_name = s;
783 del_file = 1;
784 } else {
785 formatted_error("font","file '%s' does not contain font '%s'",fm->ff_name, fm->ps_name);
788 fm->encname = font_encodingname(f); /* for the CIDSystemInfo */
789 fm->slant = font_slant(f); /* slant factor */
790 set_slantset(fm);
791 fm->extend = font_extend(f); /* extension factor */
792 set_extendset(fm);
793 fm->fd_flags = 4; /* can perhaps be done better */
794 set_inuse(fm);
796 switch (font_format(f)) {
797 case opentype_format:
798 if (has_ttf_outlines(fm)) {
799 set_truetype(fm);
800 } else {
801 set_opentype(fm);
803 break;
804 case truetype_format:
805 set_truetype(fm);
806 break;
807 case type1_format:
808 set_type1(fm);
809 break;
810 default:
811 formatted_error("font","file format '%s' for '%s' is incompatible with wide characters",
812 font_format_name(f), font_name(f));
814 /* This makes "unknown" default to subsetted inclusion */
815 if (font_embedding(f) != no_embedding) {
816 set_included(fm);
817 if (font_embedding(f) != full_embedding) {
818 set_subsetted(fm);
821 set_cidkeyed(fm);
822 create_cid_fontdictionary(pdf, f);
824 if (del_file)
825 unlink(fm->ff_name);
827 } else {
828 /* by now |font_map(f)|, if any, should have been set via |pdf_init_font()| */
829 if ((fm = font_map(f)) == NULL
830 || (fm->ps_name == NULL && fm->ff_name == NULL))
831 writet3(pdf, f);
832 else
833 create_fontdictionary(pdf, f);
837 @ The glyph width is included in |glw_entry|, because that width
838 depends on the value it has in the font where it is actually
839 typeset from, not the font that is the 'owner' of the fd entry.
841 TODO: It is possible that the user messes with the metric width,
842 but handling that properly would require access to the 'hmtx' table
843 at this point in the program.
846 static int comp_glw_entry(const void *pa, const void *pb, void *p
847 __attribute__ ((unused)))
849 unsigned short i, j;
851 i = (unsigned short) (*(const glw_entry *) pa).id;
852 j = (unsigned short) (*(const glw_entry *) pb).id;
853 cmp_return(i, j);
854 return 0;
857 static void create_cid_fontdescriptor(fo_entry * fo, internal_font_number f)
859 assert(fo != NULL);
860 assert(fo->fm != NULL);
861 assert(fo->fd == NULL);
862 fo->fd = new_fd_entry();
863 preset_fontname(fo, f);
864 preset_fontmetrics(fo->fd, f);
865 fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */
866 fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */
867 fo->fd->gl_tree = avl_create(comp_glw_entry, NULL, &avl_xallocator);
868 assert(fo->fd->gl_tree != NULL);
872 @ The values |font_bc()| and |font_ec()| are potentially large
873 character ids, but the strings that are written out use CID
874 indexes, and those are limited to 16-bit values.
877 static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f)
879 int i, k, l;
880 glw_entry *j;
881 void *aa;
882 for (k = 1; k <= max_font_id(); k++) {
883 if (k == f || -f == pdf_font_num(k)) {
884 l = font_size(k);
885 for (i = font_bc(k); i <= font_ec(k); i++) {
886 if (quick_char_exists(k, i) && char_used(k, i)) {
887 j = xtalloc(1, glw_entry);
888 j->id = (unsigned) char_index(k, i);
889 j->wd = divide_scaled_n(char_width(k, i), l, 10000.0);
890 if ((glw_entry *) avl_find(fo->fd->gl_tree, j) == NULL) {
891 aa = avl_probe(fo->fd->gl_tree, j);
892 assert(aa != NULL);
893 } else {
894 xfree(j);
903 @ It is possible to compress the widths array even better, by using the
904 alternate 'range' syntax and possibly even using /DW to set
905 a default value.
907 There is a some optimization here already: glyphs that are
908 not used do not appear in the widths array at all.
910 We have to make sure that we do not output an (incorrect!)
911 width for a character that exists in the font, but is not used
912 in typesetting. An enormous negative width is used as sentinel value
915 static void write_cid_charwidth_array(PDF pdf, fo_entry * fo)
917 int i, j;
918 glw_entry *glyph;
919 struct avl_traverser t;
921 assert(fo->cw_objnum == 0);
922 fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0);
923 pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS);
924 avl_t_init(&t, fo->fd->gl_tree);
925 glyph = (glw_entry *) avl_t_first(&t, fo->fd->gl_tree);
926 assert(glyph != NULL);
927 i = (int) glyph->id;
928 pdf_begin_array(pdf);
929 pdf_add_int(pdf, i);
930 pdf_begin_array(pdf);
931 for (; glyph != NULL; glyph = (glw_entry *) avl_t_next(&t)) {
932 j = glyph->wd;
933 if (glyph->id > (unsigned) (i + 1)) {
934 pdf_end_array(pdf);
935 pdf_add_int(pdf, glyph->id);
936 pdf_begin_array(pdf);
937 j = glyph->wd;
939 if (glyph->id == (unsigned) (i + 1))
940 pdf_out(pdf, ' ');
942 if (j < 0) {
943 pdf_out(pdf, '-');
944 j = -j;
947 pdf_printf(pdf, "%i", (j / 10));
948 if ((j % 10) != 0)
949 pdf_printf(pdf, ".%i", (j % 10));
951 i = (int) glyph->id;
953 pdf_end_array(pdf);
954 pdf_end_array(pdf);
955 pdf_end_obj(pdf);
958 static void destroy_glw_cid_entry(void *pa, void *pb)
960 glw_entry *e = (glw_entry *) pa;
961 (void) pb;
962 xfree(e);
966 static void create_cid_fontdictionary(PDF pdf, internal_font_number f)
968 fm_entry *fm = font_map(f);
969 fo_entry *fo = new_fo_entry();
970 get_char_range(fo, f); /* set |fo->first_char| and |fo->last_char| from |f| */
971 assert(fo->last_char >= fo->first_char);
972 fo->fm = fm;
973 fo->fo_objnum = pdf_font_num(f);
974 fo->tex_font = f;
975 create_cid_fontdescriptor(fo, f);
976 mark_cid_subset_glyphs(fo, f);
977 if (is_subsetted(fo->fm)) {
979 this is a bit sneaky. |make_subset_tag()| actually expects the glyph tree
980 to contain strings instead of |glw_entry| items. However, all calculations
981 are done using explicit typecasts, so it works out ok.
983 make_subset_tag(fo->fd);
985 write_cid_charwidth_array(pdf, fo);
986 write_fontdescriptor(pdf, fo->fd);
988 write_cid_fontdictionary(pdf, fo, f);
989 if (fo->fd) {
990 if (fo->fd->gl_tree){
991 avl_destroy(fo->fd->gl_tree,destroy_glw_cid_entry);
993 xfree(fo->fd);
995 xfree(fo);
998 @ @c
999 void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f)
1001 int i;
1003 fo->tounicode_objnum = write_cid_tounicode(pdf, fo, f);
1005 pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS);
1006 pdf_begin_dict(pdf);
1007 pdf_dict_add_name(pdf, "Type", "Font");
1008 pdf_dict_add_name(pdf, "Subtype", "Type0");
1009 pdf_dict_add_name(pdf, "Encoding", "Identity-H");
1010 pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
1011 i = pdf_create_obj(pdf, obj_type_others, 0);
1012 pdf_add_name(pdf, "DescendantFonts");
1013 pdf_begin_array(pdf);
1014 pdf_add_ref(pdf, i);
1015 pdf_end_array(pdf);
1016 /* todo: the ToUnicode CMap */
1017 if (fo->tounicode_objnum != 0)
1018 pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum);
1019 pdf_end_dict(pdf);
1020 pdf_end_obj(pdf);
1022 pdf_begin_obj(pdf, i, OBJSTM_ALWAYS);
1023 pdf_begin_dict(pdf);
1024 pdf_dict_add_name(pdf, "Type", "Font");
1025 if (is_opentype(fo->fm) || is_type1(fo->fm)) {
1026 pdf_dict_add_name(pdf, "Subtype", "CIDFontType0");
1027 } else {
1028 pdf_dict_add_name(pdf, "Subtype", "CIDFontType2");
1029 pdf_dict_add_name(pdf, "CIDToGIDMap", "Identity");
1031 pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
1032 pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum);
1033 pdf_dict_add_ref(pdf, "W", (int) fo->cw_objnum);
1034 pdf_add_name(pdf, "CIDSystemInfo");
1035 pdf_begin_dict(pdf);
1036 pdf_dict_add_string(pdf, "Registry",
1037 (font_cidregistry(f) ? font_cidregistry(f) : "Adobe"));
1038 pdf_dict_add_string(pdf, "Ordering",
1039 (font_cidordering(f) ? font_cidordering(f) :
1040 "Identity"));
1041 pdf_dict_add_int(pdf, "Supplement", (int) font_cidsupplement(f));
1042 pdf_end_dict(pdf);
1044 /* I doubt there is anything useful that could be written here */
1045 #if 0
1046 if (pdf_font_attr(fo->tex_font) != get_nullstr()) {
1047 pdf_out(pdf, '\n');
1048 pdf_print(pdf_font_attr(fo->tex_font));
1049 pdf_out(pdf, '\n');
1051 #endif
1052 pdf_end_dict(pdf);
1053 pdf_end_obj(pdf);