diff options
author | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
---|---|---|
committer | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
commit | c6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch) | |
tree | 1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/texk/web2c/luatexdir/font/writefont.c | |
parent | 07ee7222e389b0777456b427a55c22d0e6ffd267 (diff) |
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font/writefont.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/writefont.c | 1090 |
1 files changed, 0 insertions, 1090 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/writefont.c b/Build/source/texk/web2c/luatexdir/font/writefont.c deleted file mode 100644 index 13fa8b7543d..00000000000 --- a/Build/source/texk/web2c/luatexdir/font/writefont.c +++ /dev/null @@ -1,1090 +0,0 @@ -/* - -Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> -Copyright 2006-2010 Taco Hoekwater <taco@luatex.org> - -This file is part of LuaTeX. - -LuaTeX is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your -option) any later version. - -LuaTeX is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public -License for more details. - -You should have received a copy of the GNU General Public License along -with LuaTeX; if not, see <http://www.gnu.org/licenses/>. - -*/ - -#include "ptexlib.h" -#include "lua/luatex-api.h" - -int t1_wide_mode = 0 ; - -void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f); - -static void create_cid_fontdictionary(PDF pdf, internal_font_number f); - -const key_entry font_key[FONT_KEYS_NUM] = { - { "Ascent", "Ascender", 1 }, - { "CapHeight", "CapHeight", 1 }, - { "Descent", "Descender", 1 }, - { "ItalicAngle", "ItalicAngle", 1 }, - { "StemV", "StdVW", 1 }, - { "XHeight", "XHeight", 1 }, - { "FontBBox", "FontBBox", 1 }, - { "", "", 0 }, - { "", "", 0 }, - { "", "", 0 }, - { "FontName", "FontName", 1 } -}; - -/*tex A tree of font dictionaries: */ - -struct avl_table *fo_tree = NULL; - -/*tex A tree of font descriptor objects: */ - -struct avl_table *fd_tree = NULL; - -static int comp_fo_entry(const void *pa, const void *pb, void *p) -{ - (void) p; - return strcmp(((const fo_entry *) pa)->fm->tfm_name, ((const fo_entry *) pb)->fm->tfm_name); -} - -static int comp_fd_entry(const void *pa, const void *pb, void *p) -{ - const fd_entry *p1 = (const fd_entry *) pa, *p2 = (const fd_entry *) pb; - (void) p; - return strcmp(p1->fm->ff_name, p2->fm->ff_name); -} - -/*tex We initialize data structure for |/Type| |/Font|: */ - -static fo_entry *new_fo_entry(void) -{ - fo_entry *fo; - fo = xtalloc(1, fo_entry); - fo->fo_objnum = 0; - fo->tex_font = 0; - fo->fm = NULL; - fo->fd = NULL; - fo->fe = NULL; - fo->cw_objnum = 0; - fo->first_char = 1; - fo->last_char = 0; - fo->tx_tree = NULL; - fo->tounicode_objnum = 0; - return fo; -} - -/*tex We initialize data structure for |/Type| |/FontDescriptor|: */ - -fd_entry *new_fd_entry(internal_font_number f) -{ - fd_entry *fd; - int i; - fd = xtalloc(1, fd_entry); - fd->fd_objnum = 0; - fd->fontname = NULL; - fd->subset_tag = NULL; - fd->ff_found = false; - fd->ff_objnum = 0; - fd->all_glyphs = false; - fd->write_ttf_glyph_names = false; - for (i = 0; i < FONT_KEYS_NUM; i++) { - fd->font_dim[i].val = 0; - fd->font_dim[i].set = false; - } - fd->fe = NULL; - fd->builtin_glyph_names = NULL; - fd->fm = NULL; - fd->tx_tree = NULL; - fd->gl_tree = NULL; - fd->tex_font = f; - return fd; -} - -/*tex - - Only fallback values of font metrics are taken from the TFM info of |f| by - |preset_fontmetrics|. During reading of the font file, these values are - replaced by metrics from the font, if available. - -*/ - -static void preset_fontmetrics(fd_entry * fd, internal_font_number f) -{ - int i; - fd->font_dim[ITALIC_ANGLE_CODE].val = 0; - fd->font_dim[ASCENT_CODE].val = - divide_scaled(char_height(f, 'h'), font_size(f), 3); - fd->font_dim[CAPHEIGHT_CODE].val = - divide_scaled(char_height(f, 'H'), font_size(f), 3); - i = -divide_scaled(char_depth(f, 'y'), font_size(f), 3); - fd->font_dim[DESCENT_CODE].val = i < 0 ? i : 0; - fd->font_dim[STEMV_CODE].val = - divide_scaled(char_width(f, '.') / 3, font_size(f), 3); - fd->font_dim[XHEIGHT_CODE].val = - divide_scaled(get_x_height(f), font_size(f), 3); - fd->font_dim[FONTBBOX1_CODE].val = 0; - fd->font_dim[FONTBBOX2_CODE].val = fd->font_dim[DESCENT_CODE].val; - fd->font_dim[FONTBBOX3_CODE].val = - divide_scaled(get_quad(f), font_size(f), 3); - fd->font_dim[FONTBBOX4_CODE].val = - fd->font_dim[CAPHEIGHT_CODE].val > fd->font_dim[ASCENT_CODE].val ? - fd->font_dim[CAPHEIGHT_CODE].val : fd->font_dim[ASCENT_CODE].val; - for (i = 0; i < INT_KEYS_NUM; i++) - fd->font_dim[i].set = true; -} - -static void fix_fontmetrics(fd_entry * fd) -{ - int i; - intparm *p = (intparm *) fd->font_dim; - /*tex Make sure there is a rectangle. */ - if (p[FONTBBOX3_CODE].val < p[FONTBBOX1_CODE].val) { - i = p[FONTBBOX3_CODE].val; - p[FONTBBOX3_CODE].val = p[FONTBBOX1_CODE].val; - p[FONTBBOX1_CODE].val = i; - } else if (p[FONTBBOX3_CODE].val == p[FONTBBOX1_CODE].val) - p[FONTBBOX3_CODE].val = p[FONTBBOX1_CODE].val + 1; - if (p[FONTBBOX4_CODE].val < p[FONTBBOX2_CODE].val) { - i = p[FONTBBOX4_CODE].val; - p[FONTBBOX4_CODE].val = p[FONTBBOX2_CODE].val; - p[FONTBBOX2_CODE].val = i; - } else if (p[FONTBBOX4_CODE].val == p[FONTBBOX2_CODE].val) - p[FONTBBOX4_CODE].val = p[FONTBBOX2_CODE].val + 1; - if (!p[ASCENT_CODE].set) { - p[ASCENT_CODE].val = p[FONTBBOX4_CODE].val; - p[ASCENT_CODE].set = true; - } - if (!p[DESCENT_CODE].set) { - p[DESCENT_CODE].val = p[FONTBBOX2_CODE].val; - p[DESCENT_CODE].set = true; - } - if (!p[CAPHEIGHT_CODE].set) { - p[CAPHEIGHT_CODE].val = p[FONTBBOX4_CODE].val; - p[CAPHEIGHT_CODE].set = true; - } -} - -static void write_fontmetrics(PDF pdf, fd_entry * fd) -{ - int i; - fix_fontmetrics(fd); - pdf_add_name(pdf, font_key[FONTBBOX1_CODE].pdfname); - pdf_begin_array(pdf); - /* - pdf_check_space; - pdf_printf(pdf, "%i %i %i %i", - (int) fd->font_dim[FONTBBOX1_CODE].val, - (int) fd->font_dim[FONTBBOX2_CODE].val, - (int) fd->font_dim[FONTBBOX3_CODE].val, - (int) fd->font_dim[FONTBBOX4_CODE].val); - */ - pdf_add_int(pdf,(int) fd->font_dim[FONTBBOX1_CODE].val); - pdf_add_int(pdf,(int) fd->font_dim[FONTBBOX2_CODE].val); - pdf_add_int(pdf,(int) fd->font_dim[FONTBBOX3_CODE].val); - pdf_add_int(pdf,(int) fd->font_dim[FONTBBOX4_CODE].val); - /* */ - pdf_end_array(pdf); - for (i = 0; i < GEN_KEY_NUM; i++) - if (fd->font_dim[i].set) - pdf_dict_add_int(pdf, font_key[i].pdfname, fd->font_dim[i].val); -} - -static void preset_fontname(fo_entry * fo, internal_font_number f) -{ - if (fo->fm->ps_name != NULL) { - /*tex We just fallback. */ - fo->fd->fontname = xstrdup(fo->fm->ps_name); - } else if (font_fullname(f) != NULL) { - fo->fd->fontname = xstrdup(font_fullname(f)); - } else { - fo->fd->fontname = xstrdup(fo->fm->tfm_name); - } -} - -static void pdf_dict_add_fontname(PDF pdf, const char *key, fd_entry * fd) -{ - char *s; - size_t l1 = 0, l2; - if (fd->subset_tag != NULL) - l1 = strlen(fd->subset_tag); - l2 = strlen(fd->fontname); - s = xmalloc(l1 + l2 + 2); - if (l1 > 0) - snprintf(s, l1 + l2 + 2, "%s+%s", fd->subset_tag, fd->fontname); - else - snprintf(s, l2 + 1, "%s", fd->fontname); - pdf_dict_add_name(pdf, key, s); - xfree(s); -} - -fd_entry *lookup_fd_entry(char *s) -{ - fd_entry fd; - fm_entry fm; - fm.ff_name = s; - fd.fm = &fm; - if (fd_tree == NULL) { - fd_tree = avl_create(comp_fd_entry, NULL, &avl_xallocator); - } - return (fd_entry *) avl_find(fd_tree, &fd); -} - -static fd_entry *lookup_fontdescriptor(fo_entry * fo) -{ - return lookup_fd_entry(fo->fm->ff_name); -} - -void register_fd_entry(fd_entry * fd) -{ - void **aa; - if (fd_tree == NULL) { - fd_tree = avl_create(comp_fd_entry, NULL, &avl_xallocator); - } - /*tex The font descriptor is not yet registered: */ - if (lookup_fd_entry(fd->fm->ff_name) == NULL) { - /*tex Is this a problem? */ - } else { - /*tex The lookup also can create */ - } - aa = avl_probe(fd_tree, fd); - if (aa == NULL) { - /*tex Is this a problem? */ - } -} - -static void create_fontdescriptor(fo_entry * fo, internal_font_number f) -{ - fo->fd = new_fd_entry(f); - preset_fontname(fo, f); - preset_fontmetrics(fo->fd, f); - /*tex An encoding is needed for \TRUETYPE\ writing: */ - fo->fd->fe = fo->fe; - /*tex A map entry is needed for \TRUETYPE\ writing: */ - fo->fd->fm = fo->fm; - fo->fd->gl_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); -} - -/*tex - - For all used characters of \TeX font |f|, get corresponding glyph names from - external reencoding (.enc) file and collect these in the glyph tree |gl_tree| - of font descriptor |fd| referenced by font dictionary |fo|. - -*/ - -static void mark_reenc_glyphs(fo_entry * fo, internal_font_number f) -{ - int i; - char **g; - void **aa; - if (is_subsetted(fo->fm)) { - /*tex mark glyphs from TeX (externally reencoded characters) */ - g = fo->fe->glyph_names; - for (i = fo->first_char; i <= fo->last_char; i++) { - if (pdf_char_marked(f, i) - && g[i] != notdef - && (char *) avl_find(fo->fd->gl_tree, g[i]) == NULL) { - aa = avl_probe(fo->fd->gl_tree, xstrdup(g[i])); - if (aa == NULL) { - /*tex Is this a problem? */ - } - } - } - } -} - -/*tex - - Function |mark_chars| has 2 uses: - - \startitemize[n] - \startitem Mark characters as chars on \TeX\ level. \stopitem - \startitem Mark encoding pairs used by \TeX\ to optimize encoding vector. \stopitem - \stopitemize - -*/ - -static struct avl_table *mark_chars(fo_entry * fo, struct avl_table *tx_tree, internal_font_number f) -{ - int i, *j; - void **aa; - if (tx_tree == NULL) { - tx_tree = avl_create(comp_int_entry, NULL, &avl_xallocator); - assert(tx_tree != NULL); - } - for (i = fo->first_char; i <= fo->last_char; i++) { - if (pdf_char_marked(f, i) && (int *) avl_find(tx_tree, &i) == NULL) { - j = xtalloc(1, int); - *j = i; - aa = avl_probe(tx_tree, j); - if (aa == NULL) { - /*tex Is this a problem? */ - } - } - } - return tx_tree; -} - -static void get_char_range(fo_entry * fo, internal_font_number f) -{ - int i; - assert(fo != NULL); - /*tex Search for |first_char| and |last_char|. */ - for (i = font_bc(f); i <= font_ec(f); i++) - if (pdf_char_marked(f, i)) - break; - fo->first_char = i; - for (i = font_ec(f); i >= font_bc(f); i--) - if (pdf_char_marked(f, i)) - break; - fo->last_char = i; - if ((fo->first_char > fo->last_char) || !pdf_char_marked(f, fo->first_char)) { - /*tex No character has been used from this font. */ - fo->last_char = 0; - fo->first_char = fo->last_char + 1; - } -} - -static int font_has_subset(internal_font_number f) -{ - int i, s; - /*tex Search for |first_char| and |last_char|. */ - for (i = font_bc(f); i <= font_ec(f); i++) - if (pdf_char_marked(f, i)) - break; - s = i; - for (i = font_ec(f); i >= font_bc(f); i--) - if (pdf_char_marked(f, i)) - break; - if (s > i) - return 0; - else - return 1; -} - -static void write_charwidth_array(PDF pdf, fo_entry * fo, internal_font_number f) -{ - int i, j, *ip, *fip; - struct avl_traverser t; - fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS); - avl_t_init(&t, fo->tx_tree); - fip = (int *) avl_t_first(&t, fo->tx_tree); - pdf_begin_array(pdf); - for (ip = fip, j = *ip; ip != NULL; ip = (int *) avl_t_next(&t)) { - if (ip != fip) - pdf_out(pdf, ' '); - i = *ip; - while (j < i - 1) { - pdf_puts(pdf, "0 "); - j++; - } - j = i; - pdf_print_charwidth(pdf, f, i); - } - pdf_end_array(pdf); - pdf_end_obj(pdf); -} - -/*tex - - Remark: Font objects from embedded PDF files are never registered into - |fo_tree|; they are individually written out. - -*/ - -static fo_entry *lookup_fo_entry(char *s) -{ - fo_entry fo; - fm_entry fm; - fm.tfm_name = s; - fo.fm = &fm; - if (fo_tree == NULL) { - fo_tree = avl_create(comp_fo_entry, NULL, &avl_xallocator); - } - return (fo_entry *) avl_find(fo_tree, &fo); -} - -static void register_fo_entry(fo_entry * fo) -{ - void **aa; - if (fo_tree == NULL) { - fo_tree = avl_create(comp_fo_entry, NULL, &avl_xallocator); - } - if (lookup_fo_entry(fo->fm->tfm_name) == NULL) { - /*tex Is this a problem? */ - } else { - /*tex The lookup also can create */ - } - aa = avl_probe(fo_tree, fo); - if (aa == NULL) { - /*tex Is this a problem? */ - } -} - -/*tex - -In principle we could replace the pdftex derived ttf.otf inclusion part by using -the regular code for this and assigning indices and tounicodes to the character -blobs, but for the moment we keep the current approach. - -*/ - -static void write_fontfile(PDF pdf, fd_entry * fd) -{ - if (is_cidkeyed(fd->fm)) { - if (is_opentype(fd->fm)) { - writetype0(pdf, fd); - } else if (is_truetype(fd->fm)) { - if (!writetype2(pdf, fd)) { - writetype0(pdf,fd); - fd->fm->type |= F_OTF; fd->fm->type ^= F_TRUETYPE; - } - } else if (is_type1(fd->fm)) { - if (t1_wide_mode) { - writet1(pdf, fd, 1); - } else { - writetype1w(pdf, fd); - } - } else { - normal_error("fonts","there is a problem writing the font file (1)"); - } - } else { - if (is_type1(fd->fm)) { - writet1(pdf, fd, 0); - } else if (is_truetype(fd->fm)) { - writettf(pdf, fd); - } else if (is_opentype(fd->fm)) { - writeotf(pdf, fd); - } else { - normal_error("fonts","there is a problem writing the font file (2)"); - } - } - if (!fd->ff_found) - return; - fd->ff_objnum = pdf_create_obj(pdf, obj_type_others, 0); - /*tex The font file stream: */ - pdf_begin_obj(pdf, fd->ff_objnum, OBJSTM_NEVER); - pdf_begin_dict(pdf); - if (is_cidkeyed(fd->fm)) { - /*tex No subtype is used for |TRUETYPE\ based \OPENTYPE\ fonts. */ - if (is_opentype(fd->fm)) { - pdf_dict_add_name(pdf, "Subtype", "CIDFontType0C"); - } else if (is_type1(fd->fm)) { - if (t1_wide_mode) { - pdf_dict_add_int(pdf, "Length1", (int) t1_length1); - pdf_dict_add_int(pdf, "Length2", (int) t1_length2); - pdf_dict_add_int(pdf, "Length3", (int) t1_length3); - } else { - pdf_dict_add_name(pdf, "Subtype", "CIDFontType0C"); - } - } - } else if (is_type1(fd->fm)) { - pdf_dict_add_int(pdf, "Length1", (int) t1_length1); - pdf_dict_add_int(pdf, "Length2", (int) t1_length2); - pdf_dict_add_int(pdf, "Length3", (int) t1_length3); - } else if (is_truetype(fd->fm)) { - pdf_dict_add_int(pdf, "Length1", (int) ttf_length); - } else if (is_opentype(fd->fm)) { - pdf_dict_add_name(pdf, "Subtype", "Type1C"); - } else { - normal_error("fonts","there is a problem writing the font file (3)"); - } - pdf_dict_add_streaminfo(pdf); - pdf_end_dict(pdf); - pdf_begin_stream(pdf); - strbuf_flush(pdf, pdf->fb); - pdf_end_stream(pdf); - pdf_end_obj(pdf); -} - -int cidset = 0; - -static void write_fontdescriptor(PDF pdf, fd_entry * fd) -{ - static const int std_flags[] = { - 1 + 2 + (1 << 5), /* Courier */ - 1 + 2 + (1 << 5) + (1 << 18), /* Courier-Bold */ - 1 + 2 + (1 << 5) + (1 << 6), /* Courier-Oblique */ - 1 + 2 + (1 << 5) + (1 << 6) + (1 << 18), /* Courier-BoldOblique */ - (1 << 5), /* Helvetica */ - (1 << 5) + (1 << 18), /* Helvetica-Bold */ - (1 << 5) + (1 << 6), /* Helvetica-Oblique */ - (1 << 5) + (1 << 6) + (1 << 18), /* Helvetica-BoldOblique */ - 4, /* Symbol */ - 2 + (1 << 5), /* Times-Roman */ - 2 + (1 << 5) + (1 << 18), /* Times-Bold */ - 2 + (1 << 5) + (1 << 6), /* Times-Italic */ - 2 + (1 << 5) + (1 << 6) + (1 << 18), /* Times-BoldItalic */ - 4 /* ZapfDingbats */ - }; - char *glyph; - struct avl_traverser t; - int fd_flags; - /*tex Possibly updated by |write_fontfile|: */ - cidset = 0; - if (fd->fd_objnum == 0) { - int n = 0; - int callback_id = callback_defined(font_descriptor_objnum_provider_callback); - if (callback_id) { - run_callback(callback_id, "S->d", fd->fontname, &n); - } - if (!n) { - n = pdf_create_obj(pdf, obj_type_others, 0); - } - fd->fd_objnum = n; - } - if (is_fontfile(fd->fm) && is_included(fd->fm)) { - /*tex This will set |fd->ff_found| if font file is found: */ - write_fontfile(pdf, fd); - } - pdf_begin_obj(pdf, fd->fd_objnum, OBJSTM_ALWAYS); - pdf_begin_dict(pdf); - pdf_dict_add_name(pdf, "Type", "FontDescriptor"); - pdf_dict_add_fontname(pdf, "FontName", fd); - if (fd->fm->fd_flags != FD_FLAGS_NOT_SET_IN_MAPLINE) { - fd_flags = (int) fd->fm->fd_flags; - } else if (fd->ff_found) { - fd_flags = FD_FLAGS_DEFAULT_EMBED; - } else { - fd_flags = is_std_t1font(fd->fm) ? std_flags[check_std_t1font(fd->fm->ps_name)] : FD_FLAGS_DEFAULT_NON_EMBED; - formatted_warning("map file", - "No flags specified for non-embedded font '%s' (%s), I'm using %i, fix your map entry", - fd->fm->ps_name != NULL ? fd->fm->ps_name : "No name given", - fd->fm->tfm_name, fd_flags); - } - pdf_dict_add_int(pdf, "Flags", fd_flags); - write_fontmetrics(pdf, fd); - if (fd->ff_found) { - if (is_cidkeyed(fd->fm)) { - if (is_type1(fd->fm)) { - if (t1_wide_mode) { - pdf_dict_add_ref(pdf, "FontFile", (int) fd->ff_objnum); - } else { - pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum); - } - } else if (is_truetype(fd->fm)) { - pdf_dict_add_ref(pdf, "FontFile2", (int) fd->ff_objnum); - } else if (is_opentype(fd->fm)) { - pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum); - } else { - normal_error("fonts","there is a problem writing the font file (4)"); - } - } else { - if (is_subsetted(fd->fm) && is_type1(fd->fm)) { - /*tex |/CharSet| is optional; names may appear in any order */ - if ((! pdf->omit_charset) && (pdf->major_version == 1)) { - avl_t_init(&t, fd->gl_tree); - pdf_add_name(pdf, "CharSet"); - pdf_out(pdf, '('); - for (glyph = (char *) avl_t_first(&t, fd->gl_tree); glyph != NULL; glyph = (char *) avl_t_next(&t)) { - pdf_add_name(pdf, glyph); - } - pdf_out(pdf, ')'); - pdf_set_space(pdf); - } - } - if (is_type1(fd->fm)) { - pdf_dict_add_ref(pdf, "FontFile", (int) fd->ff_objnum); - } else if (is_truetype(fd->fm)) { - pdf_dict_add_ref(pdf, "FontFile2", (int) fd->ff_objnum); - } else if (is_opentype(fd->fm)) { - pdf_dict_add_ref(pdf, "FontFile3", (int) fd->ff_objnum); - } else { - normal_error("fonts","there is a problem writing the font file (5)"); - } - } - } - if ((! pdf->omit_cidset) && (pdf->major_version == 1) && (cidset != 0) ) { - pdf_dict_add_ref(pdf, "CIDSet", cidset); - } - /*tex - Currently we don't export the optional keys for CID fonts like |/Style << - /Panose <12-byte string> >>| and we probably never will. - */ - pdf_end_dict(pdf); - pdf_end_obj(pdf); -} - -static void write_fontdescriptors(PDF pdf) -{ - fd_entry *fd; - struct avl_traverser t; - if (fd_tree == NULL) - return; - avl_t_init(&t, fd_tree); - for (fd = (fd_entry *) avl_t_first(&t, fd_tree); fd != NULL; fd = (fd_entry *) avl_t_next(&t)) - write_fontdescriptor(pdf, fd); -} - -static void write_fontdictionary(PDF pdf, fo_entry * fo) -{ - /*tex Write the |/ToUnicode| entry if needed. */ - if (pdf->gen_tounicode > 0 && fo->fd != NULL) { - if (fo->fe != NULL) { - fo->tounicode_objnum = write_tounicode(pdf, fo->fe->glyph_names, fo->fe->name); - } else if (is_type1(fo->fm)) { - fo->tounicode_objnum = write_tounicode(pdf, fo->fd->builtin_glyph_names, fo->fm->tfm_name); - } - } - pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS); - pdf_begin_dict(pdf); - pdf_dict_add_name(pdf, "Type", "Font"); - if (is_type1(fo->fm)) { - pdf_dict_add_name(pdf, "Subtype", "Type1"); - } else if (is_truetype(fo->fm)) { - pdf_dict_add_name(pdf, "Subtype", "TrueType"); - } else if (is_opentype(fo->fm)) { - pdf_dict_add_name(pdf, "Subtype", "Type1"); - } else { - normal_error("fonts","there is a problem writing the font file (6)"); - } - pdf_dict_add_fontname(pdf, "BaseFont", fo->fd); - pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum); - pdf_dict_add_int(pdf, "FirstChar", (int) fo->first_char); - pdf_dict_add_int(pdf, "LastChar", (int) fo->last_char); - pdf_dict_add_ref(pdf, "Widths", (int) fo->cw_objnum); - if ((is_type1(fo->fm) || is_opentype(fo->fm)) && fo->fe != NULL && fo->fe->fe_objnum != 0) { - pdf_dict_add_ref(pdf, "Encoding", (int) fo->fe->fe_objnum); - } - if (fo->tounicode_objnum != 0) { - pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum); - } - if (pdf_font_attr(fo->tex_font) != get_nullstr() && pdf_font_attr(fo->tex_font) != 0) { - pdf_check_space(pdf); - pdf_print(pdf, pdf_font_attr(fo->tex_font)); - pdf_set_space(pdf); - } - pdf_end_dict(pdf); - pdf_end_obj(pdf); -} - -static void write_fontdictionaries(PDF pdf) -{ - fo_entry *fo; - struct avl_traverser t; - if (fo_tree == NULL) - return; - avl_t_init(&t, fo_tree); - for (fo = (fo_entry *) avl_t_first(&t, fo_tree); fo != NULL; fo = (fo_entry *) avl_t_next(&t)) { - write_fontdictionary(pdf, fo); - } -} - -/*tex - - Final flush of all font related stuff by call from \.{Output fonts - definitions} elsewhere. - -*/ - -void write_fontstuff(PDF pdf) -{ - write_fontdescriptors(pdf); - write_fontencodings(pdf); - write_fontdictionaries(pdf); -} - -static void create_fontdictionary(PDF pdf, internal_font_number f) -{ - fo_entry *fo = new_fo_entry(); - fm_entry *fm = font_map(f); - /*tex set |fo->first_char| and |fo->last_char| from |f| */ - get_char_range(fo, f); - if (fo->last_char > 255) - fo->last_char = 255; - fo->fm = fm; - fo->fo_objnum = pdf_font_num(f); - fo->tex_font = f; - if (is_reencoded(fo->fm)) { - /*tex - At least the map entry tells so but it returns |NULL| if the .enc - file couldn't be opened. - */ - fo->fe = get_fe_entry(fo->fm->encname); - if (fo->fe != NULL && (is_type1(fo->fm) || is_opentype(fo->fm))) { - /*tex We don't end up here for truetype fonts. */ - if (fo->fe->fe_objnum == 0) { - /*tex It will be written out */ - fo->fe->fe_objnum = pdf_create_obj(pdf, obj_type_others, 0); - } - /*tex Mark encoding pairs used by TeX to optimize encoding vector. */ - fo->fe->tx_tree = mark_chars(fo, fo->fe->tx_tree, f); - } - } - /*tex For |write_charwidth_array|: */ - fo->tx_tree = mark_chars(fo, fo->tx_tree, f); - write_charwidth_array(pdf, fo, f); - if (!is_builtin(fo->fm)) { - if (is_type1(fo->fm)) { - if ((fo->fd = lookup_fontdescriptor(fo)) == NULL) { - create_fontdescriptor(fo, f); - register_fd_entry(fo->fd); - } - } else { - create_fontdescriptor(fo, f); - } - if (fo->fe != NULL) { - mark_reenc_glyphs(fo, f); - if (!is_type1(fo->fm)) { - /*tex Mark reencoded characters as chars on TeX level. */ - assert(fo->fd->tx_tree == NULL); - fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); - if (is_truetype(fo->fm)) { - fo->fd->write_ttf_glyph_names = true; - } - } - } else { - /*tex Mark non-reencoded characters as chars on TeX level. */ - fo->fd->tx_tree = mark_chars(fo, fo->fd->tx_tree, f); - } - if (!is_type1(fo->fm)) { - write_fontdescriptor(pdf, fo->fd); - } - } else { - /*tex - Builtin fonts still need the \type {/Widths} array and \type - {/FontDescriptor} (to avoid error \quotation {font FOO contains bad - \type {/BBox}}). - */ - create_fontdescriptor(fo, f); - write_fontdescriptor(pdf, fo->fd); - if (!is_std_t1font(fo->fm)) { - formatted_warning("map file", "font '%s' is not a standard font; I suppose it is available to your PDF viewer then", fo->fm->ps_name); - } - } - if (is_type1(fo->fm)) { - register_fo_entry(fo); - } else { - write_fontdictionary(pdf, fo); - } -} - -static int has_ttf_outlines(fm_entry * fm) -{ - FILE *f = fopen(fm->ff_name, "rb"); - if (f != NULL) { - int ch1 = getc(f); - int ch2 = getc(f); - int ch3 = getc(f); - int ch4 = getc(f); - fclose(f); - if (ch1 == 'O' && ch2 == 'T' && ch3 == 'T' && ch4 == 'O') - return 0; - return 1; - } - return 0; -} - -void do_pdf_font(PDF pdf, internal_font_number f) -{ - fm_entry *fm; - /*tex - This is not 100\% true: CID is actually needed whenever (and only) there - are more than 256 separate glyphs used. But for now, we just assume the - user knows what he is doing. In practice this seems to be the case. - */ - if (!font_has_subset(f)) - return; - if (font_encodingbytes(f) == 2) { - /*tex - Create a virtual font map entry, as this is needed by the rest of the - font inclusion mechanism. - */ - fm = font_map(f) = new_fm_entry(); - /*tex Set this to a name or whatever, not a real \TFM\ anyway: */ - fm->tfm_name = font_name(f); - /*tex The actual file: */ - fm->ff_name = font_filename(f); - /*tex The true (used) name: */ - if (font_psname(f) != NULL) { - fm->ps_name = font_psname(f); - } else { - fm->ps_name = font_fullname(f); - } - /*tex Needed for the CIDSystemInfo: */ - fm->encname = font_encodingname(f); - fm->subfont = font_subfont(f); - fm->slant = font_slant(f); - set_slantset(fm); - fm->extend = font_extend(f); - set_extendset(fm); - /*tex Flags can perhaps be done better. */ - fm->fd_flags = 4; - set_inuse(fm); - switch (font_format(f)) { - case opentype_format: - if (has_ttf_outlines(fm)) { - set_truetype(fm); - } else { - set_opentype(fm); - } - break; - case truetype_format: - set_truetype(fm); - break; - case type1_format: - set_type1(fm); - break; - default: - formatted_error("font","file format '%s' for '%s' is incompatible with wide characters", - font_format_name(f), font_name(f)); - } - /*tex This makes \quotation {unknown} default to subsetted inclusion. */ - if (font_embedding(f) != no_embedding) { - set_included(fm); - if (font_embedding(f) != full_embedding) { - set_subsetted(fm); - } - } - set_cidkeyed(fm); - create_cid_fontdictionary(pdf, f); - } else { - /*tex By now |font_map(f)|, if any, should have been set via |pdf_init_font|. */ - if (font_psname(f) != NULL && strstr(font_psname(f),"none")) - writet3user(pdf, f); - else if ((fm = font_map(f)) == NULL || (fm->ps_name == NULL && fm->ff_name == NULL)) - writet3pk(pdf, f); - else - create_fontdictionary(pdf, f); - } -} - -int do_pdf_preroll_font(PDF pdf, internal_font_number f) -{ - if (!font_has_subset(f)) { - return 0; - } else if (font_encodingbytes(f) != 2 && font_psname(f) != NULL && strstr(font_psname(f),"none")) { - prerollt3user(pdf, f); - return 1; - } else { - return 0; - } -} - -/*tex - - The glyph width is included in |glw_entry|, because that width depends on the - value it has in the font where it is actually typeset from, not the font that - is the owner of the fd entry. - - It is possible that the user messes with the metric width, but handling that - properly would require access to the |hmtx| table at this point in the - program. - -*/ - -static int comp_glw_entry(const void *pa, const void *pb, void *p __attribute__ ((unused))) -{ - unsigned short i, j; - i = (unsigned short) (*(const glw_entry *) pa).id; - j = (unsigned short) (*(const glw_entry *) pb).id; - cmp_return(i, j); - return 0; -} - -static void create_cid_fontdescriptor(fo_entry * fo, internal_font_number f) -{ - fo->fd = new_fd_entry(f); - preset_fontname(fo, f); - preset_fontmetrics(fo->fd, f); - /*tex Encoding needed by \TRUETYPE\ writing: */ - fo->fd->fe = fo->fe; - /*tex Map entry needed by \TRUETYPE\ writing */ - fo->fd->fm = fo->fm; - fo->fd->gl_tree = avl_create(comp_glw_entry, NULL, &avl_xallocator); - assert(fo->fd->gl_tree != NULL); -} - -/*tex - - The values |font_bc()| and |font_ec()| are potentially large character ids, - but the strings that are written out use CID indexes, and those are limited - to 16-bit values. - -*/ - -static void mark_cid_subset_glyphs(fo_entry * fo, internal_font_number f) -{ - glw_entry *j; - void *aa; - int l = font_size(f); - int i; - for (i = font_bc(f); i <= font_ec(f); i++) { - if (quick_char_exists(f, i) && char_used(f, i)) { - j = xtalloc(1, glw_entry); - j->id = (unsigned) char_index(f, i); - j->wd = divide_scaled_n(char_width(f, i), l, 10000.0); - if ((glw_entry *) avl_find(fo->fd->gl_tree, j) == NULL) { - aa = avl_probe(fo->fd->gl_tree, j); - if (aa == NULL) { - /*tex Is this a problem? */ - } - } else { - xfree(j); - } - } - } -} - -/*tex - - It is possible to compress the widths array even better, by using the - alternate 'range' syntax and possibly even using /DW to set a default value. - - There is a some optimization here already: glyphs that are not used do not - appear in the widths array at all. - - We have to make sure that we do not output an (incorrect!) width for a - character that exists in the font, but is not used in typesetting. An - enormous negative width is used as sentinel value - -*/ - -static void write_cid_charwidth_array(PDF pdf, fo_entry * fo) -{ - int i, j; - glw_entry *glyph; - struct avl_traverser t; - fo->cw_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_begin_obj(pdf, fo->cw_objnum, OBJSTM_ALWAYS); - avl_t_init(&t, fo->fd->gl_tree); - glyph = (glw_entry *) avl_t_first(&t, fo->fd->gl_tree); - i = (int) glyph->id; - pdf_begin_array(pdf); - pdf_add_int(pdf, i); - pdf_begin_array(pdf); - for (; glyph != NULL; glyph = (glw_entry *) avl_t_next(&t)) { - j = glyph->wd; - if (glyph->id > (unsigned) (i + 1)) { - pdf_end_array(pdf); - pdf_add_int(pdf, glyph->id); - pdf_begin_array(pdf); - j = glyph->wd; - } - pdf_check_space(pdf); - if (j < 0) { - pdf_out(pdf, '-'); - j = -j; - } - pdf_printf(pdf, "%i", (j / 10)); - if ((j % 10) != 0) - pdf_printf(pdf, ".%i", (j % 10)); - i = (int) glyph->id; - pdf_set_space(pdf); - } - pdf_end_array(pdf); - pdf_end_array(pdf); - pdf_end_obj(pdf); -} - -static void destroy_glw_cid_entry(void *pa, void *pb) -{ - glw_entry *e = (glw_entry *) pa; - (void) pb; - xfree(e); -} - -static void create_cid_fontdictionary(PDF pdf, internal_font_number f) -{ - fm_entry *fm = font_map(f); - fo_entry *fo = new_fo_entry(); - /*tex set |fo->first_char| and |fo->last_char| from |f| */ - get_char_range(fo, f); - fo->fm = fm; - fo->fo_objnum = pdf_font_num(f); - fo->tex_font = f; - create_cid_fontdescriptor(fo, f); - mark_cid_subset_glyphs(fo, f); - if (is_subsetted(fo->fm)) { - /*tex - This is a bit sneaky. |make_subset_tag()| actually expects the glyph - tree to contain strings instead of |glw_entry| items. However, all - calculations are done using explicit typecasts, so it works out ok. - */ - make_subset_tag(fo->fd); - } - write_cid_charwidth_array(pdf, fo); - write_fontdescriptor(pdf, fo->fd); - write_cid_fontdictionary(pdf, fo, f); - if (fo->fd) { - if (fo->fd->gl_tree) { - avl_destroy(fo->fd->gl_tree,destroy_glw_cid_entry); - } - xfree(fo->fd); - } - xfree(fo); -} - -void write_cid_fontdictionary(PDF pdf, fo_entry * fo, internal_font_number f) -{ - int i; - fo->tounicode_objnum = write_cid_tounicode(pdf, fo, f); - pdf_begin_obj(pdf, fo->fo_objnum, OBJSTM_ALWAYS); - pdf_begin_dict(pdf); - pdf_dict_add_name(pdf, "Type", "Font"); - pdf_dict_add_name(pdf, "Subtype", "Type0"); - if (font_identity(f) == vertical_identity) { - pdf_dict_add_name(pdf, "Encoding", "Identity-V"); - } else { - pdf_dict_add_name(pdf, "Encoding", "Identity-H"); - } - pdf_dict_add_fontname(pdf, "BaseFont", fo->fd); - i = pdf_create_obj(pdf, obj_type_others, 0); - pdf_add_name(pdf, "DescendantFonts"); - pdf_begin_array(pdf); - pdf_add_ref(pdf, i); - pdf_end_array(pdf); - if (fo->tounicode_objnum != 0) - pdf_dict_add_ref(pdf, "ToUnicode", (int) fo->tounicode_objnum); - pdf_end_dict(pdf); - pdf_end_obj(pdf); - pdf_begin_obj(pdf, i, OBJSTM_ALWAYS); - pdf_begin_dict(pdf); - pdf_dict_add_name(pdf, "Type", "Font"); - if (is_opentype(fo->fm)) { - pdf_dict_add_name(pdf, "Subtype", "CIDFontType0"); - } else if (is_type1(fo->fm)) { - if (t1_wide_mode) { - pdf_dict_add_name(pdf, "Subtype", "CIDFontType0"); - // pdf_dict_add_name(pdf, "CIDToGIDMap", "Identity"); - } else { - pdf_dict_add_name(pdf, "Subtype", "CIDFontType0"); - } - } else { - pdf_dict_add_name(pdf, "Subtype", "CIDFontType2"); - pdf_dict_add_name(pdf, "CIDToGIDMap", "Identity"); - } - pdf_dict_add_fontname(pdf, "BaseFont", fo->fd); - pdf_dict_add_ref(pdf, "FontDescriptor", (int) fo->fd->fd_objnum); - pdf_dict_add_ref(pdf, "W", (int) fo->cw_objnum); - pdf_add_name(pdf, "CIDSystemInfo"); - pdf_begin_dict(pdf); - pdf_dict_add_string(pdf, "Registry", (font_cidregistry(f) ? font_cidregistry(f) : "Adobe")); - pdf_dict_add_string(pdf, "Ordering", (font_cidordering(f) ? font_cidordering(f) : "Identity")); - pdf_dict_add_int(pdf, "Supplement", (int) font_cidsupplement(f)); - pdf_end_dict(pdf); - /*tex - I doubt there is anything useful that could be written here so for now we - comment this. - */ - /* - if (pdf_font_attr(fo->tex_font) != get_nullstr()) { - pdf_out(pdf, '\n'); - pdf_print(pdf_font_attr(fo->tex_font)); - pdf_out(pdf, '\n'); - } - */ - pdf_end_dict(pdf); - pdf_end_obj(pdf); -} |