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
/>.
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}
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
)
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
;
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
)
70 fo
= xtalloc
(1, fo_entry
);
80 fo-
>tounicode_objnum
= 0;
84 @ initialize data structure for
/Type
/FontDescriptor
86 fd_entry
*new_fd_entry
(void
)
90 fd
= xtalloc
(1, fd_entry
);
93 fd-
>subset_tag
= NULL;
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
;
103 fd-
>builtin_glyph_names
= NULL;
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
)
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
)
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
)
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
);
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
));
199 fo-
>fd-
>fontname
= xstrdup
(fo-
>fm-
>tfm_name
);
202 static void pdf_dict_add_fontname
(PDF pdf
, const char
*key
, fd_entry
* fd
)
206 assert
(fd-
>fontname
!= NULL);
208 if
(fd-
>subset_tag
!= NULL)
209 l1
= strlen
(fd-
>subset_tag
);
210 l2
= strlen
(fd-
>fontname
);
211 s
= xmalloc
(l1
+ l2
+ 2);
213 snprintf
(s
, l1
+ l2
+ 2, "%s+%s", fd-
>subset_tag
, fd-
>fontname
);
215 snprintf
(s
, l2
+ 1, "%s", fd-
>fontname
);
216 pdf_dict_add_name
(pdf
, key
, s
);
222 fd_entry
*lookup_fd_entry
(char
*s
)
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
)
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
)
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
);
257 static void create_fontdescriptor
(fo_entry
* fo
, internal_font_number f
)
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
)
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
]));
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
)
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) {
316 aa
= avl_probe
(tx_tree
, j
);
325 static void get_char_range
(fo_entry
* fo
, internal_font_number f
)
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
))
333 for
(i
= font_ec
(f
); i
>= font_bc
(f
); i--
)
334 if
(pdf_char_marked
(f
, i
))
337 if
((fo-
>first_char
> fo-
>last_char
)
338 ||
!pdf_char_marked
(f
, fo-
>first_char
)) { /* no character used from this font
*/
340 fo-
>first_char
= fo-
>last_char
+ 1;
344 static int font_has_subset
(internal_font_number f
)
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
))
351 for
(i
= font_ec
(f
); i
>= font_bc
(f
); i--
)
352 if
(pdf_char_marked
(f
, i
))
362 static void write_charwidth_array
(PDF pdf
, fo_entry
* fo
,
363 internal_font_number f
)
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);
374 pdf_begin_array
(pdf
);
375 for
(ip
= fip
, j
= *ip
; ip
!= NULL; ip
= (int
*) avl_t_next
(&t)) {
384 pdf_print_charwidth
(pdf
, f
, i
);
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
)
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
)
410 if
(fo_tree
== NULL) {
411 fo_tree
= avl_create
(comp_fo_entry
, NULL, &avl_xallocator);
412 assert
(fo_tree
!= 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
);
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
)) {
433 } else if
(is_truetype
(fd-
>fm
)) {
434 if
(!writetype2
(pdf
, fd
)) {
436 fd-
>fm-
>type |
= F_OTF
; fd-
>fm-
>type ^
= F_TRUETYPE
;
438 } else if
(is_type1
(fd-
>fm
))
439 writetype1w
(pdf
, fd
);
443 if
(is_type1
(fd-
>fm
))
445 else if
(is_truetype
(fd-
>fm
))
447 else if
(is_opentype
(fd-
>fm
))
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
*/
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");
464 pdf_dict_add_name
(pdf
, "Subtype", "OpenType");
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");
478 pdf_dict_add_streaminfo
(pdf
);
480 pdf_begin_stream
(pdf
);
481 strbuf_flush
(pdf
, pdf-
>fb
);
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 */
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
*/
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
*/
512 struct avl_traverser t
;
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
);
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
;
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
);
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
);
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");
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
);
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
);
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
>>>}
582 static void write_fontdescriptors
(PDF pdf
)
585 struct avl_traverser t
;
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
)
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
,
614 pdf_begin_obj
(pdf
, fo-
>fo_objnum
, OBJSTM_ALWAYS
);
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");
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
));
646 static void write_fontdictionaries
(PDF pdf
)
649 struct avl_traverser t
;
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
);
680 fo-
>fo_objnum
= pdf_font_num
(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
);
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
;
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
);
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",
725 if
(is_type1
(fo-
>fm
))
726 register_fo_entry
(fo
);
728 write_fontdictionary
(pdf
, fo
);
733 static int has_ttf_outlines
(fm_entry
* fm
)
735 FILE *f
= fopen
(fm-
>ff_name
, "rb");
742 if
(ch1
== 'O'
&& ch2 == 'T' && ch3 == 'T' && ch4 == 'O')
749 void do_pdf_font
(PDF pdf
, internal_font_number f
)
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
))
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
*/
770 fm-
>ps_name
= font_fullname
(f
); /* the true 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
);
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
*/
791 fm-
>extend
= font_extend
(f
); /* extension factor
*/
793 fm-
>fd_flags
= 4; /* can perhaps be done better
*/
796 switch
(font_format
(f
)) {
797 case opentype_format
:
798 if
(has_ttf_outlines
(fm
)) {
804 case truetype_format
:
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
) {
817 if
(font_embedding
(f
) != full_embedding
) {
822 create_cid_fontdictionary
(pdf
, f
);
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))
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
)))
851 i
= (unsigned short
) (*(const glw_entry
*) pa
).id
;
852 j
= (unsigned short
) (*(const glw_entry
*) pb
).id
;
857 static void create_cid_fontdescriptor
(fo_entry
* fo
, internal_font_number f
)
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
)
882 for
(k
= 1; k
<= max_font_id
(); k
++) {
883 if
(k
== f ||
-f
== pdf_font_num
(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
);
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
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
)
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);
928 pdf_begin_array
(pdf
);
930 pdf_begin_array
(pdf
);
931 for
(; glyph
!= NULL; glyph
= (glw_entry
*) avl_t_next
(&t)) {
933 if
(glyph-
>id
> (unsigned
) (i
+ 1)) {
935 pdf_add_int
(pdf
, glyph-
>id
);
936 pdf_begin_array
(pdf
);
939 if
(glyph-
>id
== (unsigned
) (i
+ 1))
947 pdf_printf
(pdf
, "%i", (j
/ 10));
949 pdf_printf
(pdf
, ".%i", (j
% 10));
958 static void destroy_glw_cid_entry
(void
*pa
, void
*pb
)
960 glw_entry
*e
= (glw_entry
*) pa
;
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
);
973 fo-
>fo_objnum
= pdf_font_num
(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
);
990 if
(fo-
>fd-
>gl_tree
){
991 avl_destroy
(fo-
>fd-
>gl_tree
,destroy_glw_cid_entry
);
999 void write_cid_fontdictionary
(PDF pdf
, fo_entry
* fo
, internal_font_number f
)
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
);
1016 /* todo
: the ToUnicode CMap
*/
1017 if
(fo-
>tounicode_objnum
!= 0)
1018 pdf_dict_add_ref
(pdf
, "ToUnicode", (int
) fo-
>tounicode_objnum
);
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");
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
) :
1041 pdf_dict_add_int
(pdf
, "Supplement", (int
) font_cidsupplement
(f
));
1044 /* I doubt there is anything useful that could be written here
*/
1046 if
(pdf_font_attr
(fo-
>tex_font
) != get_nullstr
()) {
1048 pdf_print
(pdf_font_attr
(fo-
>tex_font
));