fix getsup (HH)
[luatex.git] / source / texk / web2c / luatexdir / font / writefont.w
blob66c26fa7c167871efd7b7ee9c4572679975a8b3e
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 ((! pdf->omit_cidset) && (cidset != 0)) {
573 pdf_dict_add_ref(pdf, "CIDSet", cidset);
575 /* TODO: Other optional keys for CID fonts.
576 The most interesting one is
577 \.{/Style << /Panose <12-byte string>>>}
579 pdf_end_dict(pdf);
580 pdf_end_obj(pdf);
583 static void write_fontdescriptors(PDF pdf)
585 fd_entry *fd;
586 struct avl_traverser t;
587 if (fd_tree == NULL)
588 return;
589 avl_t_init(&t, fd_tree);
590 for (fd = (fd_entry *) avl_t_first(&t, fd_tree); fd != NULL;
591 fd = (fd_entry *) avl_t_next(&t))
592 write_fontdescriptor(pdf, fd);
597 static void write_fontdictionary(PDF pdf, fo_entry * fo)
599 assert(fo != NULL);
600 assert(fo->fm != NULL);
601 assert(fo->fo_objnum != 0); /* reserved as |pdf_font_num(f)| elsewhere */
603 /* write ToUnicode entry if needed */
604 if (pdf->gen_tounicode > 0 && fo->fd != NULL) {
605 if (fo->fe != NULL) {
606 fo->tounicode_objnum =
607 write_tounicode(pdf, fo->fe->glyph_names, fo->fe->name);
608 } else if (is_type1(fo->fm)) {
609 assert(fo->fd->builtin_glyph_names != NULL);
610 fo->tounicode_objnum =
611 write_tounicode(pdf, fo->fd->builtin_glyph_names,
612 fo->fm->tfm_name);
615 pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS);
616 pdf_begin_dict(pdf);
617 pdf_dict_add_name(pdf, "Type", "Font");
618 if (is_type1(fo->fm))
619 pdf_dict_add_name(pdf, "Subtype", "Type1");
620 else if (is_truetype(fo->fm))
621 pdf_dict_add_name(pdf, "Subtype", "TrueType");
622 else if (is_opentype(fo->fm))
623 pdf_dict_add_name(pdf, "Subtype", "Type1");
624 else
625 assert(0);
626 assert(fo->fd != NULL && fo->fd->fd_objnum != 0);
627 pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
628 pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum);
629 assert(fo->cw_objnum != 0);
630 pdf_dict_add_int(pdf, "FirstChar", (int) fo->first_char);
631 pdf_dict_add_int(pdf, "LastChar", (int) fo->last_char);
632 pdf_dict_add_ref(pdf, "Widths", (int) fo->cw_objnum);
633 if ((is_type1(fo->fm) || is_opentype(fo->fm)) && fo->fe != NULL
634 && fo->fe->fe_objnum != 0)
635 pdf_dict_add_ref(pdf, "Encoding", (int) fo->fe->fe_objnum);
636 if (fo->tounicode_objnum != 0)
637 pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum);
638 if (pdf_font_attr(fo->tex_font) != get_nullstr() &&
639 pdf_font_attr(fo->tex_font) != 0) {
640 pdf_print(pdf, pdf_font_attr(fo->tex_font));
641 pdf_out(pdf, '\n');
643 pdf_end_dict(pdf);
644 pdf_end_obj(pdf);
647 static void write_fontdictionaries(PDF pdf)
649 fo_entry *fo;
650 struct avl_traverser t;
651 if (fo_tree == NULL)
652 return;
653 avl_t_init(&t, fo_tree);
654 for (fo = (fo_entry *) avl_t_first(&t, fo_tree); fo != NULL;
655 fo = (fo_entry *) avl_t_next(&t))
656 write_fontdictionary(pdf, fo);
659 @ Final flush of all font related stuff by call from
660 \.{Output fonts definitions} elsewhere
663 void write_fontstuff(PDF pdf)
665 write_fontdescriptors(pdf);
666 write_fontencodings(pdf); /* see \.{writeenc.w} */
667 write_fontdictionaries(pdf);
672 static void create_fontdictionary(PDF pdf, internal_font_number f)
674 fo_entry *fo = new_fo_entry();
675 fm_entry *fm = font_map(f);
676 get_char_range(fo, f); /* set |fo->first_char| and |fo->last_char| from |f| */
677 if (fo->last_char > 255)
678 fo->last_char = 255; /* added 9-4-2008, mantis \#25 */
679 assert(fo->last_char >= fo->first_char);
680 fo->fm = fm;
681 fo->fo_objnum = pdf_font_num(f);
682 fo->tex_font = f;
683 if (is_reencoded(fo->fm)) { /* at least the map entry tells so */
684 fo->fe = get_fe_entry(fo->fm->encname); /* returns |NULL| if .enc file couldn't be opened */
685 if (fo->fe != NULL && (is_type1(fo->fm) || is_opentype(fo->fm))) { /* not entered for truetype */
686 if (fo->fe->fe_objnum == 0)
687 fo->fe->fe_objnum = pdf_create_obj(pdf, obj_type_others, 0); /* then it will be written out */
688 /* mark encoding pairs used by TeX to optimize encoding vector */
689 fo->fe->tx_tree = mark_chars(fo, fo->fe->tx_tree, f);
692 fo->tx_tree = mark_chars(fo, fo->tx_tree, f); /* for |write_charwidth_array| */
693 write_charwidth_array(pdf, fo, f);
694 if (!is_builtin(fo->fm)) {
695 if (is_type1(fo->fm)) {
696 if ((fo->fd = lookup_fontdescriptor(fo)) == NULL) {
697 create_fontdescriptor(fo, f);
698 register_fd_entry(fo->fd);
700 } else
701 create_fontdescriptor(fo, f);
702 if (fo->fe != NULL) {
703 mark_reenc_glyphs(fo, f);
704 if (!is_type1(fo->fm)) {
705 /* mark reencoded characters as chars on TeX level */
706 assert(fo->fd->tx_tree == NULL);
707 fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f);
708 if (is_truetype(fo->fm))
709 fo->fd->write_ttf_glyph_names = true;
711 } else
712 /* mark non-reencoded characters as chars on TeX level */
713 fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f);
714 if (!is_type1(fo->fm))
715 write_fontdescriptor(pdf, fo->fd);
716 } else {
717 /* builtin fonts still need the /Widths array and /FontDescriptor
718 * (to avoid error 'font FOO contains bad /BBox')
720 create_fontdescriptor(fo, f);
721 write_fontdescriptor(pdf, fo->fd);
722 if (!is_std_t1font(fo->fm))
723 formatted_warning("map file", "font '%s' is not a standard font; I suppose it is available to your PDF viewer then",
724 fo->fm->ps_name);
726 if (is_type1(fo->fm))
727 register_fo_entry(fo);
728 else
729 write_fontdictionary(pdf, fo);
734 static int has_ttf_outlines(fm_entry * fm)
736 FILE *f = fopen(fm->ff_name, "rb");
737 if (f != NULL) {
738 int ch1 = getc(f);
739 int ch2 = getc(f);
740 int ch3 = getc(f);
741 int ch4 = getc(f);
742 fclose(f);
743 if (ch1 == 'O' && ch2 == 'T' && ch3 == 'T' && ch4 == 'O')
744 return 0;
745 return 1;
747 return 0;
750 void do_pdf_font(PDF pdf, internal_font_number f)
752 int del_file = 0;
753 fm_entry *fm;
754 /* TODO This is not 100\% true: CID is actually needed whenever (and
755 only) there are more than 256 separate glyphs used. But for
756 now, just assume the user knows what he is doing;
758 if (!font_has_subset(f))
759 return;
761 if (font_encodingbytes(f) == 2) {
762 /* Create a virtual font map entry, as this is needed by the
763 rest of the font inclusion mechanism.
765 fm = font_map(f) = new_fm_entry();
766 fm->tfm_name = font_name(f); /* or whatever, not a real tfm */
767 fm->ff_name = font_filename(f); /* the actual file */
768 if (font_psname(f) != NULL)
769 fm->ps_name = font_psname(f); /* the true name */
770 else
771 fm->ps_name = font_fullname(f); /* the true name */
772 if (fm->ff_name
773 && strlen(fm->ff_name) >= 6
774 && strstr(fm->ff_name,
775 ".dfont") == (fm->ff_name + strlen(fm->ff_name) - 6)) {
776 /* In case of a .dfont, we will extract the correct ttf here,
777 and adjust |fm->ff_name| to point to the temporary file.
778 This file will be deleted later. Todo: keep a nicer name
779 somewhere for the terminal message.
781 char *s = FindResourceTtfFont(fm->ff_name, fm->ps_name);
782 if (s != NULL) {
783 fm->ff_name = s;
784 del_file = 1;
785 } else {
786 formatted_error("font","file '%s' does not contain font '%s'",fm->ff_name, fm->ps_name);
789 fm->encname = font_encodingname(f); /* for the CIDSystemInfo */
790 fm->slant = font_slant(f); /* slant factor */
791 set_slantset(fm);
792 fm->extend = font_extend(f); /* extension factor */
793 set_extendset(fm);
794 fm->fd_flags = 4; /* can perhaps be done better */
795 set_inuse(fm);
797 switch (font_format(f)) {
798 case opentype_format:
799 if (has_ttf_outlines(fm)) {
800 set_truetype(fm);
801 } else {
802 set_opentype(fm);
804 break;
805 case truetype_format:
806 set_truetype(fm);
807 break;
808 case type1_format:
809 set_type1(fm);
810 break;
811 default:
812 formatted_error("font","file format '%s' for '%s' is incompatible with wide characters",
813 font_format_name(f), font_name(f));
815 /* This makes "unknown" default to subsetted inclusion */
816 if (font_embedding(f) != no_embedding) {
817 set_included(fm);
818 if (font_embedding(f) != full_embedding) {
819 set_subsetted(fm);
822 set_cidkeyed(fm);
823 create_cid_fontdictionary(pdf, f);
825 if (del_file)
826 unlink(fm->ff_name);
828 } else {
829 /* by now |font_map(f)|, if any, should have been set via |pdf_init_font()| */
830 if ((fm = font_map(f)) == NULL
831 || (fm->ps_name == NULL && fm->ff_name == NULL))
832 writet3(pdf, f);
833 else
834 create_fontdictionary(pdf, f);
838 @ The glyph width is included in |glw_entry|, because that width
839 depends on the value it has in the font where it is actually
840 typeset from, not the font that is the 'owner' of the fd entry.
842 TODO: It is possible that the user messes with the metric width,
843 but handling that properly would require access to the 'hmtx' table
844 at this point in the program.
847 static int comp_glw_entry(const void *pa, const void *pb, void *p
848 __attribute__ ((unused)))
850 unsigned short i, j;
852 i = (unsigned short) (*(const glw_entry *) pa).id;
853 j = (unsigned short) (*(const glw_entry *) pb).id;
854 cmp_return(i, j);
855 return 0;
858 static void create_cid_fontdescriptor(fo_entry * fo, internal_font_number f)
860 assert(fo != NULL);
861 assert(fo->fm != NULL);
862 assert(fo->fd == NULL);
863 fo->fd = new_fd_entry();
864 preset_fontname(fo, f);
865 preset_fontmetrics(fo->fd, f);
866 fo->fd->fe = fo->fe; /* encoding needed by TrueType writing */
867 fo->fd->fm = fo->fm; /* map entry needed by TrueType writing */
868 fo->fd->gl_tree = avl_create(comp_glw_entry, NULL, &avl_xallocator);
869 assert(fo->fd->gl_tree != NULL);
873 @ The values |font_bc()| and |font_ec()| are potentially large
874 character ids, but the strings that are written out use CID
875 indexes, and those are limited to 16-bit values.
878 static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f)
880 int i, k, l;
881 glw_entry *j;
882 void *aa;
883 for (k = 1; k <= max_font_id(); k++) {
884 if (k == f || -f == pdf_font_num(k)) {
885 l = font_size(k);
886 for (i = font_bc(k); i <= font_ec(k); i++) {
887 if (quick_char_exists(k, i) && char_used(k, i)) {
888 j = xtalloc(1, glw_entry);
889 j->id = (unsigned) char_index(k, i);
890 j->wd = divide_scaled_n(char_width(k, i), l, 10000.0);
891 if ((glw_entry *) avl_find(fo->fd->gl_tree, j) == NULL) {
892 aa = avl_probe(fo->fd->gl_tree, j);
893 assert(aa != NULL);
894 } else {
895 xfree(j);
904 @ It is possible to compress the widths array even better, by using the
905 alternate 'range' syntax and possibly even using /DW to set
906 a default value.
908 There is a some optimization here already: glyphs that are
909 not used do not appear in the widths array at all.
911 We have to make sure that we do not output an (incorrect!)
912 width for a character that exists in the font, but is not used
913 in typesetting. An enormous negative width is used as sentinel value
916 static void write_cid_charwidth_array(PDF pdf, fo_entry * fo)
918 int i, j;
919 glw_entry *glyph;
920 struct avl_traverser t;
922 assert(fo->cw_objnum == 0);
923 fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0);
924 pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS);
925 avl_t_init(&t, fo->fd->gl_tree);
926 glyph = (glw_entry *) avl_t_first(&t, fo->fd->gl_tree);
927 assert(glyph != NULL);
928 i = (int) glyph->id;
929 pdf_begin_array(pdf);
930 pdf_add_int(pdf, i);
931 pdf_begin_array(pdf);
932 for (; glyph != NULL; glyph = (glw_entry *) avl_t_next(&t)) {
933 j = glyph->wd;
934 if (glyph->id > (unsigned) (i + 1)) {
935 pdf_end_array(pdf);
936 pdf_add_int(pdf, glyph->id);
937 pdf_begin_array(pdf);
938 j = glyph->wd;
940 if (glyph->id == (unsigned) (i + 1))
941 pdf_out(pdf, ' ');
943 if (j < 0) {
944 pdf_out(pdf, '-');
945 j = -j;
948 pdf_printf(pdf, "%i", (j / 10));
949 if ((j % 10) != 0)
950 pdf_printf(pdf, ".%i", (j % 10));
952 i = (int) glyph->id;
954 pdf_end_array(pdf);
955 pdf_end_array(pdf);
956 pdf_end_obj(pdf);
959 static void destroy_glw_cid_entry(void *pa, void *pb)
961 glw_entry *e = (glw_entry *) pa;
962 (void) pb;
963 xfree(e);
967 static void create_cid_fontdictionary(PDF pdf, internal_font_number f)
969 fm_entry *fm = font_map(f);
970 fo_entry *fo = new_fo_entry();
971 get_char_range(fo, f); /* set |fo->first_char| and |fo->last_char| from |f| */
972 assert(fo->last_char >= fo->first_char);
973 fo->fm = fm;
974 fo->fo_objnum = pdf_font_num(f);
975 fo->tex_font = f;
976 create_cid_fontdescriptor(fo, f);
977 mark_cid_subset_glyphs(fo, f);
978 if (is_subsetted(fo->fm)) {
980 this is a bit sneaky. |make_subset_tag()| actually expects the glyph tree
981 to contain strings instead of |glw_entry| items. However, all calculations
982 are done using explicit typecasts, so it works out ok.
984 make_subset_tag(fo->fd);
986 write_cid_charwidth_array(pdf, fo);
987 write_fontdescriptor(pdf, fo->fd);
989 write_cid_fontdictionary(pdf, fo, f);
990 if (fo->fd) {
991 if (fo->fd->gl_tree){
992 avl_destroy(fo->fd->gl_tree,destroy_glw_cid_entry);
994 xfree(fo->fd);
996 xfree(fo);
999 @ @c
1000 void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f)
1002 int i;
1004 fo->tounicode_objnum = write_cid_tounicode(pdf, fo, f);
1006 pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS);
1007 pdf_begin_dict(pdf);
1008 pdf_dict_add_name(pdf, "Type", "Font");
1009 pdf_dict_add_name(pdf, "Subtype", "Type0");
1010 if (font_identity(f) == vertical_identity) {
1011 pdf_dict_add_name(pdf, "Encoding", "Identity-V");
1012 } else {
1013 pdf_dict_add_name(pdf, "Encoding", "Identity-H");
1015 pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
1016 i = pdf_create_obj(pdf, obj_type_others, 0);
1017 pdf_add_name(pdf, "DescendantFonts");
1018 pdf_begin_array(pdf);
1019 pdf_add_ref(pdf, i);
1020 pdf_end_array(pdf);
1021 /* todo: the ToUnicode CMap */
1022 if (fo->tounicode_objnum != 0)
1023 pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum);
1024 pdf_end_dict(pdf);
1025 pdf_end_obj(pdf);
1027 pdf_begin_obj(pdf, i, OBJSTM_ALWAYS);
1028 pdf_begin_dict(pdf);
1029 pdf_dict_add_name(pdf, "Type", "Font");
1030 if (is_opentype(fo->fm) || is_type1(fo->fm)) {
1031 pdf_dict_add_name(pdf, "Subtype", "CIDFontType0");
1032 } else {
1033 pdf_dict_add_name(pdf, "Subtype", "CIDFontType2");
1034 pdf_dict_add_name(pdf, "CIDToGIDMap", "Identity");
1036 pdf_dict_add_fontname(pdf, "BaseFont", fo->fd);
1037 pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum);
1038 pdf_dict_add_ref(pdf, "W", (int) fo->cw_objnum);
1039 pdf_add_name(pdf, "CIDSystemInfo");
1040 pdf_begin_dict(pdf);
1041 pdf_dict_add_string(pdf, "Registry",
1042 (font_cidregistry(f) ? font_cidregistry(f) : "Adobe"));
1043 pdf_dict_add_string(pdf, "Ordering",
1044 (font_cidordering(f) ? font_cidordering(f) :
1045 "Identity"));
1046 pdf_dict_add_int(pdf, "Supplement", (int) font_cidsupplement(f));
1047 pdf_end_dict(pdf);
1049 /* I doubt there is anything useful that could be written here */
1050 #if 0
1051 if (pdf_font_attr(fo->tex_font) != get_nullstr()) {
1052 pdf_out(pdf, '\n');
1053 pdf_print(pdf_font_attr(fo->tex_font));
1054 pdf_out(pdf, '\n');
1056 #endif
1057 pdf_end_dict(pdf);
1058 pdf_end_obj(pdf);