From fb6550fbe69fce7c2de2436cd935f89b7bab9c07 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Sun, 2 Sep 2018 05:52:49 +0000 Subject: Experimental support for XeTeX transparency font feature (S. Hirata). git-svn-id: svn://tug.org/texlive/trunk@48542 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvipdfm-x/ChangeLog | 11 ++ Build/source/texk/dvipdfm-x/cid.c | 5 - Build/source/texk/dvipdfm-x/cid_p.h | 3 +- Build/source/texk/dvipdfm-x/cidtype0.c | 8 +- Build/source/texk/dvipdfm-x/cmap.c | 21 +- Build/source/texk/dvipdfm-x/cmap.h | 4 +- Build/source/texk/dvipdfm-x/cmap_p.h | 4 +- Build/source/texk/dvipdfm-x/configure | 22 +-- Build/source/texk/dvipdfm-x/configure.ac | 2 +- Build/source/texk/dvipdfm-x/dvi.c | 38 ++++ Build/source/texk/dvipdfm-x/fontmap.c | 11 +- Build/source/texk/dvipdfm-x/fontmap.h | 5 +- Build/source/texk/dvipdfm-x/pdfdev.c | 32 +-- Build/source/texk/dvipdfm-x/pdffont.c | 272 ++++++++++++++------------ Build/source/texk/dvipdfm-x/tt_cmap.c | 321 +++++++++++++++++++------------ Build/source/texk/dvipdfm-x/tt_cmap.h | 11 +- Build/source/texk/dvipdfm-x/type0.c | 7 +- 17 files changed, 438 insertions(+), 339 deletions(-) (limited to 'Build/source/texk/dvipdfm-x') diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog index 94cde3fcf3d..bed9d8472e0 100644 --- a/Build/source/texk/dvipdfm-x/ChangeLog +++ b/Build/source/texk/dvipdfm-x/ChangeLog @@ -1,3 +1,14 @@ +2018-09-02 Shunsaku Hirata + + * dvi.c: Experimental support for XeTeX transparency font feature. + * cid.c, cid_p.h, cidtype0.c, cmap.[ch], cmap_p.h, fontmap.[ch], + pdfdev.c, pdffont.c, tt_cmap.[ch], type0.c: + Removed reverse CMap mappings. Do not use cff charset data + directly in pdfdev. Using reverse CMap for ToUnicode creation + causes problems since input CMap can not be assumed to be + always Unicode. Also, current implementation is imcomplete. + * configure.ac: Version 20180902. + 2018-08-28 Shunsaku Hirata * otl_conf.[ch]: Removed. This undocumented feature is no diff --git a/Build/source/texk/dvipdfm-x/cid.c b/Build/source/texk/dvipdfm-x/cid.c index 5e11cc7262e..03b5557422e 100644 --- a/Build/source/texk/dvipdfm-x/cid.c +++ b/Build/source/texk/dvipdfm-x/cid.c @@ -570,7 +570,6 @@ CIDFont_cache_find (const char *map_name, opt->name = NULL; opt->csi = get_cidsysinfo(map_name, fmap_opt); opt->stemv = fmap_opt->stemv; - opt->cff_charsets = NULL; if (!opt->csi && cmap_csi) { /* @@ -651,8 +650,6 @@ CIDFont_cache_find (const char *map_name, font->options = opt; __cache->fonts[font_id] = font; (__cache->num)++; - - fmap_opt->cff_charsets = opt->cff_charsets; } } else if (opt) { release_opt(opt); @@ -708,8 +705,6 @@ release_opt (cid_opt *opt) if (opt->csi->ordering) RELEASE(opt->csi->ordering); RELEASE(opt->csi); - if (opt->cff_charsets) - cff_release_charsets((cff_charsets *) opt->cff_charsets); } RELEASE(opt); } diff --git a/Build/source/texk/dvipdfm-x/cid_p.h b/Build/source/texk/dvipdfm-x/cid_p.h index e509c5b4f32..18666490540 100644 --- a/Build/source/texk/dvipdfm-x/cid_p.h +++ b/Build/source/texk/dvipdfm-x/cid_p.h @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -42,7 +42,6 @@ typedef struct int style; int embed; int stemv; - void *cff_charsets; } cid_opt; struct CIDFont diff --git a/Build/source/texk/dvipdfm-x/cidtype0.c b/Build/source/texk/dvipdfm-x/cidtype0.c index 6308957a910..c6ddf2c17c1 100644 --- a/Build/source/texk/dvipdfm-x/cidtype0.c +++ b/Build/source/texk/dvipdfm-x/cidtype0.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2007-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2007-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. This program is free software; you can redistribute it and/or modify @@ -890,12 +890,6 @@ CIDFont_type0_open (CIDFont *font, const char *name, DPXFCLOSE(fp); return -1; } - - if (is_cid_font) { - cff_read_charsets(cffont); - opt->cff_charsets = cffont->charsets; - cffont->charsets = NULL; - } } else { if (!fp) return -1; diff --git a/Build/source/texk/dvipdfm-x/cmap.c b/Build/source/texk/dvipdfm-x/cmap.c index 2dbf7f96a1f..5e53027af02 100644 --- a/Build/source/texk/dvipdfm-x/cmap.c +++ b/Build/source/texk/dvipdfm-x/cmap.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. This program is free software; you can redistribute it and/or modify @@ -33,6 +33,7 @@ * * TODO: * Only cid(range|char) allowed for CODE_TO_CID and bf(range|char) for CID_TO_CODE ? + * */ #ifdef HAVE_CONFIG_H @@ -109,9 +110,6 @@ CMap_new (void) cmap->mapData->pos = 0; cmap->mapData->data = NEW(MEM_ALLOC_SIZE, unsigned char); - cmap->reverseMap = NEW(65536, int); - memset(cmap->reverseMap, 0, 65536 * sizeof(int)); - return cmap; } @@ -143,9 +141,6 @@ CMap_release (CMap *cmap) } } - if (cmap->reverseMap) - RELEASE(cmap->reverseMap); - RELEASE(cmap); } @@ -365,14 +360,6 @@ CMap_decode (CMap *cmap, return count; } -int -CMap_reverse_decode(CMap *cmap, CID cid) { - int ch = cmap->reverseMap ? cmap->reverseMap[cid] : -1; - if (ch == 0 && cmap->useCMap) - return CMap_reverse_decode(cmap->useCMap, cid); - return ch; -} - char * CMap_get_name (CMap *cmap) { @@ -696,8 +683,6 @@ CMap_add_cidrange (CMap *cmap, for (v = 0, i = 0; i < srcdim - 1; i++) v = (v << 8) + srclo[i]; - cmap->reverseMap[base] = v; - for (c = srclo[srcdim-1]; c <= srchi[srcdim-1]; c++) { if (cur[c].flag != 0) { if (!__silent) @@ -708,8 +693,6 @@ CMap_add_cidrange (CMap *cmap, cur[c].code = get_mem(cmap, 2); cur[c].code[0] = base >> 8; cur[c].code[1] = base & 0xff; - - cmap->reverseMap[base] = (v << 8) + c; } if (base >= CID_MAX) WARN("CID number too large."); diff --git a/Build/source/texk/dvipdfm-x/cmap.h b/Build/source/texk/dvipdfm-x/cmap.h index 6eeab34fba2..bbda82da3ee 100644 --- a/Build/source/texk/dvipdfm-x/cmap.h +++ b/Build/source/texk/dvipdfm-x/cmap.h @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. This program is free software; you can redistribute it and/or modify @@ -106,8 +106,6 @@ extern int CMap_decode (CMap *cmap, const unsigned char **inbuf, int *inbytesleft, unsigned char **outbuf, int *outbytesleft); -extern int CMap_reverse_decode(CMap *cmap, CID cid); - extern void CMap_cache_init (void); extern CMap *CMap_cache_get (int id); extern int CMap_cache_find (const char *cmap_name); diff --git a/Build/source/texk/dvipdfm-x/cmap_p.h b/Build/source/texk/dvipdfm-x/cmap_p.h index e106392abb2..9bea8271c4e 100644 --- a/Build/source/texk/dvipdfm-x/cmap_p.h +++ b/Build/source/texk/dvipdfm-x/cmap_p.h @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. This program is free software; you can redistribute it and/or modify @@ -96,8 +96,6 @@ struct CMap { int minBytesOut; int maxBytesOut; } profile; - - int *reverseMap; }; #endif /* _CMAP_P_H_ */ diff --git a/Build/source/texk/dvipdfm-x/configure b/Build/source/texk/dvipdfm-x/configure index 7fe8cad0eec..8fc5062ff0a 100755 --- a/Build/source/texk/dvipdfm-x/configure +++ b/Build/source/texk/dvipdfm-x/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20180827. +# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20180902. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dvipdfm-x (TeX Live)' PACKAGE_TARNAME='dvipdfm-x--tex-live-' -PACKAGE_VERSION='20180827' -PACKAGE_STRING='dvipdfm-x (TeX Live) 20180827' +PACKAGE_VERSION='20180902' +PACKAGE_STRING='dvipdfm-x (TeX Live) 20180902' PACKAGE_BUGREPORT='tex-k@tug.org' PACKAGE_URL='' @@ -1350,7 +1350,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures dvipdfm-x (TeX Live) 20180827 to adapt to many kinds of systems. +\`configure' configures dvipdfm-x (TeX Live) 20180902 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1421,7 +1421,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20180827:";; + short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20180902:";; esac cat <<\_ACEOF @@ -1551,7 +1551,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -dvipdfm-x (TeX Live) configure 20180827 +dvipdfm-x (TeX Live) configure 20180902 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2390,7 +2390,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by dvipdfm-x (TeX Live) $as_me 20180827, which was +It was created by dvipdfm-x (TeX Live) $as_me 20180902, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -8075,7 +8075,7 @@ fi # Define the identity of the package. PACKAGE='dvipdfm-x--tex-live-' - VERSION='20180827' + VERSION='20180902' cat >>confdefs.h <<_ACEOF @@ -14744,7 +14744,7 @@ Usage: $0 [OPTIONS] Report bugs to ." lt_cl_version="\ -dvipdfm-x (TeX Live) config.lt 20180827 +dvipdfm-x (TeX Live) config.lt 20180902 configured by $0, generated by GNU Autoconf 2.69. Copyright (C) 2011 Free Software Foundation, Inc. @@ -16624,7 +16624,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by dvipdfm-x (TeX Live) $as_me 20180827, which was +This file was extended by dvipdfm-x (TeX Live) $as_me 20180902, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16694,7 +16694,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -dvipdfm-x (TeX Live) config.status 20180827 +dvipdfm-x (TeX Live) config.status 20180902 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/Build/source/texk/dvipdfm-x/configure.ac b/Build/source/texk/dvipdfm-x/configure.ac index 251576a5b0b..7d2ad243d38 100644 --- a/Build/source/texk/dvipdfm-x/configure.ac +++ b/Build/source/texk/dvipdfm-x/configure.ac @@ -7,7 +7,7 @@ dnl This file is free software; the copyright holder dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl -AC_INIT([dvipdfm-x (TeX Live)], [20180827], [tex-k@tug.org]) +AC_INIT([dvipdfm-x (TeX Live)], [20180902], [tex-k@tug.org]) AC_PREREQ([2.65]) AC_CONFIG_SRCDIR([agl.c]) AC_CONFIG_AUX_DIR([../../build-aux]) diff --git a/Build/source/texk/dvipdfm-x/dvi.c b/Build/source/texk/dvipdfm-x/dvi.c index c5607bce672..378582bdeec 100644 --- a/Build/source/texk/dvipdfm-x/dvi.c +++ b/Build/source/texk/dvipdfm-x/dvi.c @@ -46,6 +46,8 @@ #include "pdfdoc.h" #include "pdfparse.h" #include "pdfencrypt.h" +#include "pdfresource.h" +#include "pdfdraw.h" #include "fontmap.h" @@ -144,6 +146,7 @@ static struct loaded_font spt_t size; int source; /* Source is either DVI or VF */ uint32_t rgba_color; + int xgs_id; /* Transparency ExtGState */ struct tt_longMetrics *hvmt; int ascent; int descent; @@ -1490,6 +1493,20 @@ do_fnt (int32_t tex_id) def_fonts[i].point_size); } loaded_fonts[font_id].rgba_color = def_fonts[i].rgba_color; + /* Opacity: 0xff is fully opaque. */ + if ((loaded_fonts[font_id].rgba_color & 0xff) == 0xff) { + loaded_fonts[font_id].xgs_id = -1; + } else { + pdf_obj *xgs_dict; + int a = loaded_fonts[font_id].rgba_color & 0xff; + + /* Inefficient but don't care as transparency is not expected to be frequently used. */ + xgs_dict = pdf_new_dict(); + pdf_add_dict(xgs_dict, pdf_new_name("Type"), pdf_new_name("ExtGState")); + pdf_add_dict(xgs_dict, pdf_new_name("ca"), pdf_new_number(a/255.0)); + pdf_add_dict(xgs_dict, pdf_new_name("CA"), pdf_new_number(a/255.0)); + loaded_fonts[font_id].xgs_id = pdf_defineresource("ExtGState", NULL, xgs_dict, 0); + } loaded_fonts[font_id].source = DVI; def_fonts[i].used = 1; def_fonts[i].font_id = font_id; @@ -1707,6 +1724,23 @@ do_glyphs (int do_actual_text) (double)((unsigned char)(font->rgba_color >> 16) & 0xff) / 255, (double)((unsigned char)(font->rgba_color >> 8) & 0xff) / 255); pdf_color_push(&color, &color); + /* Opacity: + * Enter graphics_mode and then enclose with save/resotre + * since pdf_color_pop() may not restore graphics state. + */ + if (font->xgs_id >= 0) { + pdf_obj *ref; + char resname[16]; + char content[22]; + + sprintf(resname, "Xtx_Gs_%08x", current_font); + ref = pdf_get_resource_reference(font->xgs_id); + pdf_doc_add_page_resource("ExtGState", resname, ref); + graphics_mode(); + pdf_dev_gsave(); + sprintf(content, " /%s gs ", resname); + pdf_doc_add_page_content(content, strlen(content)); + } } for (i = 0; i < slen; i++) { @@ -1755,6 +1789,10 @@ do_glyphs (int do_actual_text) } if (font->rgba_color != 0xffffffff) { + if (font->xgs_id >= 0) { + graphics_mode(); + pdf_dev_grestore(); + } pdf_color_pop(); } RELEASE(xloc); diff --git a/Build/source/texk/dvipdfm-x/fontmap.c b/Build/source/texk/dvipdfm-x/fontmap.c index 4a59ae32c5f..06909a63ab7 100644 --- a/Build/source/texk/dvipdfm-x/fontmap.c +++ b/Build/source/texk/dvipdfm-x/fontmap.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2017 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -76,8 +76,7 @@ pdf_init_fontmap_record (fontmap_rec *mrec) mrec->opt.charcoll = NULL; mrec->opt.style = FONTMAP_STYLE_NONE; mrec->opt.stemv = -1; /* not given explicitly by an option */ - - mrec->opt.cff_charsets = NULL; + mrec->opt.use_glyph_encoding = 0; } void @@ -143,8 +142,7 @@ pdf_copy_fontmap_record (fontmap_rec *dst, const fontmap_rec *src) dst->opt.charcoll = mstrdup(src->opt.charcoll); dst->opt.style = src->opt.style; dst->opt.stemv = src->opt.stemv; - - dst->opt.cff_charsets = src->opt.cff_charsets; + dst->opt.use_glyph_encoding = src->opt.use_glyph_encoding; } @@ -1077,7 +1075,8 @@ pdf_insert_native_fontmap_record (const char *path, uint32_t index, mrec->opt.extend = extend / 65536.0; mrec->opt.slant = slant / 65536.0; mrec->opt.bold = embolden / 65536.0; - + mrec->opt.use_glyph_encoding = 1; + ret = pdf_insert_fontmap_record(mrec->map_name, mrec); pdf_clear_fontmap_record(mrec); RELEASE(mrec); diff --git a/Build/source/texk/dvipdfm-x/fontmap.h b/Build/source/texk/dvipdfm-x/fontmap.h index 8148356a678..568f2e6e38c 100644 --- a/Build/source/texk/dvipdfm-x/fontmap.h +++ b/Build/source/texk/dvipdfm-x/fontmap.h @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -45,14 +45,13 @@ typedef struct fontmap_opt { char *otl_tags; /* currently unused */ char *tounicode; /* not implemented yet */ - void *cff_charsets; - double design_size; /* unused */ char *charcoll; /* Adobe-Japan1-4, etc. */ int index; /* TTC index */ int style; /* ,Bold, etc. */ int stemv; /* StemV value especially for CJK fonts */ + int use_glyph_encoding; /* XeTeX support */ } fontmap_opt; typedef struct fontmap_rec { diff --git a/Build/source/texk/dvipdfm-x/pdfdev.c b/Build/source/texk/dvipdfm-x/pdfdev.c index 553b271dead..488d0bf47dd 100644 --- a/Build/source/texk/dvipdfm-x/pdfdev.c +++ b/Build/source/texk/dvipdfm-x/pdfdev.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2002-2016 by Jin-Hwan Cho and Shunsaku Hirata, + Copyright (C) 2002-2018 by Jin-Hwan Cho and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -52,8 +52,6 @@ #include "pdfdev.h" -#include "cff.h" - static int verbose = 0; void @@ -500,8 +498,6 @@ struct dev_font { int ucs_plane; int is_unicode; - - cff_charsets *cff_charsets; }; static struct dev_font *dev_fonts = NULL; @@ -963,26 +959,8 @@ handle_multibyte_string (struct dev_font *font, p = *str_ptr; length = *str_len; - if (ctype == -1 && font->cff_charsets) { /* freetype glyph indexes */ - /* Convert freetype glyph indexes to CID. */ - const unsigned char *inbuf = p; - unsigned char *outbuf = sbuf0; - for (i = 0; i < length; i += 2) { - unsigned int gid; - gid = *inbuf++ << 8; - gid += *inbuf++; - - gid = cff_charsets_lookup_cid(font->cff_charsets, gid); - - *outbuf++ = gid >> 8; - *outbuf++ = gid & 0xff; - } - - p = sbuf0; - length = outbuf - sbuf0; - } /* _FIXME_ */ - else if (font->is_unicode) { /* UCS-4 */ + if (font->is_unicode) { /* UCS-4 */ if (ctype == 1) { if (length * 4 >= FORMAT_BUF_SIZE) { WARN("Too long string..."); @@ -1045,7 +1023,7 @@ handle_multibyte_string (struct dev_font *font, * encoding. * TODO: A character decomposed to multiple characters. */ - if (ctype != -1 && font->enc_id >= 0) { + if (font->enc_id >= 0) { const unsigned char *inbuf; unsigned char *outbuf; int inbytesleft, outbytesleft; @@ -1316,7 +1294,6 @@ pdf_close_device (void) pdf_release_obj(dev_fonts[i].resource); dev_fonts[i].tex_name = NULL; dev_fonts[i].resource = NULL; - dev_fonts[i].cff_charsets = NULL; } RELEASE(dev_fonts); } @@ -1499,9 +1476,6 @@ pdf_dev_locate_font (const char *font_name, spt_t ptsize) if (font->font_id < 0) return -1; - if (mrec) - font->cff_charsets = mrec->opt.cff_charsets; - /* We found device font here. */ if (i < num_dev_fonts) { font->real_font_index = i; diff --git a/Build/source/texk/dvipdfm-x/pdffont.c b/Build/source/texk/dvipdfm-x/pdffont.c index 71d08fb1d31..6e210f12366 100644 --- a/Build/source/texk/dvipdfm-x/pdffont.c +++ b/Build/source/texk/dvipdfm-x/pdffont.c @@ -1,6 +1,6 @@ /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - Copyright (C) 2008-2017 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, + Copyright (C) 2008-2018 by Jin-Hwan Cho, Matthias Franz, and Shunsaku Hirata, the dvipdfmx project team. Copyright (C) 1998, 1999 by Mark A. Wicks @@ -492,25 +492,22 @@ pdf_close_fonts (void) if (__verbose) { if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) { - MESG("(%s", pdf_font_get_ident(font)); - if (__verbose > 2 && - !pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) { - MESG("[%s+%s]", - pdf_font_get_uniqueTag(font), - pdf_font_get_fontname(font)); - } else if (__verbose > 1) { - MESG("[%s]", - pdf_font_get_fontname(font)); - } - if (__verbose > 1) { - if (pdf_font_get_encoding(font) >= 0) { - MESG("[%s]", - pdf_encoding_get_name(pdf_font_get_encoding(font))); - } else { - MESG("[built-in]"); - } - } - + MESG("(%s", pdf_font_get_ident(font)); + if (__verbose > 2 && + !pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) { + MESG("[%s+%s]", + pdf_font_get_uniqueTag(font), + pdf_font_get_fontname(font)); + } else if (__verbose > 1) { + MESG("[%s]", pdf_font_get_fontname(font)); + } + if (__verbose > 1) { + if (pdf_font_get_encoding(font) >= 0) { + MESG("[%s]", pdf_encoding_get_name(pdf_font_get_encoding(font))); + } else { + MESG("[built-in]"); + } + } } } @@ -521,23 +518,23 @@ pdf_close_fonts (void) switch (font->subtype) { case PDF_FONT_FONTTYPE_TYPE1: if (__verbose) - MESG("[Type1]"); + MESG("[Type1]"); if (!pdf_font_get_flag(font, PDF_FONT_FLAG_BASEFONT)) - pdf_font_load_type1(font); + pdf_font_load_type1(font); break; case PDF_FONT_FONTTYPE_TYPE1C: if (__verbose) - MESG("[Type1C]"); + MESG("[Type1C]"); pdf_font_load_type1c(font); break; case PDF_FONT_FONTTYPE_TRUETYPE: if (__verbose) - MESG("[TrueType]"); + MESG("[TrueType]"); pdf_font_load_truetype(font); break; case PDF_FONT_FONTTYPE_TYPE3: if (__verbose) - MESG("[Type3/PK]"); + MESG("[Type3/PK]"); pdf_font_load_pkfont (font); break; case PDF_FONT_FONTTYPE_TYPE0: @@ -552,7 +549,7 @@ pdf_close_fonts (void) if (__verbose) { if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) - MESG(")"); + MESG(")"); } } @@ -566,22 +563,23 @@ pdf_close_fonts (void) pdf_obj *tounicode; /* Predefined encodings (and those simplified to them) are embedded - as direct objects, but this is purely a matter of taste. */ + * as direct objects, but this is purely a matter of taste. + */ if (enc_obj) pdf_add_dict(font->resource, - pdf_new_name("Encoding"), - PDF_OBJ_NAMETYPE(enc_obj) ? pdf_link_obj(enc_obj) : pdf_ref_obj(enc_obj)); + pdf_new_name("Encoding"), + PDF_OBJ_NAMETYPE(enc_obj) ? pdf_link_obj(enc_obj) : pdf_ref_obj(enc_obj)); - if (!pdf_lookup_dict(font->resource, "ToUnicode") - && (tounicode = pdf_encoding_get_tounicode(font->encoding_id))) - pdf_add_dict(font->resource, - pdf_new_name("ToUnicode"), pdf_ref_obj(tounicode)); + if (!pdf_lookup_dict(font->resource, "ToUnicode") && + (tounicode = pdf_encoding_get_tounicode(font->encoding_id))) + pdf_add_dict(font->resource, + pdf_new_name("ToUnicode"), pdf_ref_obj(tounicode)); } else if (font->subtype == PDF_FONT_FONTTYPE_TRUETYPE) { /* encoding_id < 0 means MacRoman here (but not really) * We use MacRoman as "default" encoding. */ pdf_add_dict(font->resource, pdf_new_name("Encoding"), - pdf_new_name("MacRomanEncoding")); + pdf_new_name("MacRomanEncoding")); } pdf_flush_font(font); @@ -604,7 +602,7 @@ pdf_close_fonts (void) int pdf_font_findresource (const char *tex_name, - double font_scale, fontmap_rec *mrec) + double font_scale, fontmap_rec *mrec) { int font_id = -1; pdf_font *font; @@ -616,56 +614,84 @@ pdf_font_findresource (const char *tex_name, * point sizes would be looked up twice unecessarily.) */ fontname = mrec ? mrec->font_name : tex_name; - if (mrec && mrec->enc_name) { + /* XeTeX specific... + * First try loading GID-to-CID mapping from CFF CID-keyed OpenType font. + * There was a serious bug in xdv support... It was implemented with the wrong + * assumption that CID always equals to GID. + * TODO: There is a possibility that GID-to-CID mapping is not one-to-one. + * Use internal glyph ordering rather than map GID to CIDs. + */ + if (mrec && mrec->opt.use_glyph_encoding) { + int wmode = 0; + /* Should be always Identity-H or Identity-V for XeTeX output. */ + if (mrec->enc_name) { + if (!strcmp(mrec->enc_name, "Identity-V")) + wmode = 1; + else if (!strcmp(mrec->enc_name, "Identity-H")) + wmode = 0; + else { + WARN("Unexpected encoding specified for xdv: %s", mrec->enc_name); + } + /* cmap_id < 0 is returned if ... + * Font is not a CFF font + * GID to CID mapping is identity mapping + * + * TODO: fontmap record still has Identity CMap assigned but actually different CMap + * can be attached to the font here. Should we fix mrec->enc_name here? + */ + cmap_id = otf_try_load_GID_to_CID_map(mrec->font_name, mrec->opt.index, wmode); + } + } + if (cmap_id < 0 && mrec && mrec->enc_name) { #define MAYBE_CMAP(s) (!strstr((s), ".enc") || strstr((s), ".cmap")) if (MAYBE_CMAP(mrec->enc_name)) { cmap_id = CMap_cache_find(mrec->enc_name); if (cmap_id >= 0) { - CMap *cmap; - int cmap_type, minbytes; - - cmap = CMap_cache_get(cmap_id); - cmap_type = CMap_get_type (cmap); - minbytes = CMap_get_profile(cmap, CMAP_PROF_TYPE_INBYTES_MIN); - /* - * Check for output encoding. - */ - if (cmap_type != CMAP_TYPE_IDENTITY && - cmap_type != CMAP_TYPE_CODE_TO_CID && - cmap_type != CMAP_TYPE_TO_UNICODE) { - WARN("Only 16-bit encoding supported for output encoding."); - } - /* - * Turn on map option. - */ - if (minbytes == 2 && mrec->opt.mapc < 0) { - if (__verbose) { - MESG("\n"); - MESG("pdf_font>> Input encoding \"%s\" requires at least 2 bytes.\n", - CMap_get_name(cmap)); - MESG("pdf_font>> The -m <00> option will be assumed for \"%s\".\n", mrec->font_name); - } - mrec->opt.mapc = 0; /* _FIXME_ */ - } + CMap *cmap; + int cmap_type, minbytes; + + cmap = CMap_cache_get(cmap_id); + cmap_type = CMap_get_type (cmap); + minbytes = CMap_get_profile(cmap, CMAP_PROF_TYPE_INBYTES_MIN); + /* + * Check for output encoding. + */ + if (cmap_type != CMAP_TYPE_IDENTITY && + cmap_type != CMAP_TYPE_CODE_TO_CID && + cmap_type != CMAP_TYPE_TO_UNICODE) { + WARN("Only 16-bit encoding supported for output encoding."); + } + /* + * Turn on map option. + */ + if (minbytes == 2 && mrec->opt.mapc < 0) { + if (__verbose) { + MESG("\n"); + MESG("pdf_font>> Input encoding \"%s\" requires at least 2 bytes.\n", + CMap_get_name(cmap)); + MESG("pdf_font>> The -m <00> option will be assumed for \"%s\".\n", mrec->font_name); + } + /* FIXME: The following code modifies mrec. */ + mrec->opt.mapc = 0; + } } else if (!strcmp(mrec->enc_name, "unicode")) { - cmap_id = otf_load_Unicode_CMap(mrec->font_name, - mrec->opt.index, mrec->opt.otl_tags, - ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0)); - if (cmap_id < 0) { - cmap_id = t1_load_UnicodeCMap(mrec->font_name, mrec->opt.otl_tags, - ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0)); - } - if (cmap_id < 0) - ERROR("Failed to read UCS2/UCS4 TrueType cmap..."); + cmap_id = otf_load_Unicode_CMap(mrec->font_name, + mrec->opt.index, mrec->opt.otl_tags, + ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0)); + if (cmap_id < 0) { + cmap_id = t1_load_UnicodeCMap(mrec->font_name, mrec->opt.otl_tags, + ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0)); + } + if (cmap_id < 0) + ERROR("Failed to read UCS2/UCS4 TrueType cmap..."); } } if (cmap_id < 0) { encoding_id = pdf_encoding_findresource(mrec->enc_name); if (encoding_id < 0) - ERROR("Could not find encoding file \"%s\".", mrec->enc_name); + ERROR("Could not find encoding file \"%s\".", mrec->enc_name); } } - if (mrec && cmap_id >= 0) { /* * Composite Font @@ -678,25 +704,25 @@ pdf_font_findresource (const char *tex_name, } for (font_id = 0; - font_id < font_cache.count; font_id++) { + font_id < font_cache.count; font_id++) { font = GET_FONT(font_id); if (font->subtype == PDF_FONT_FONTTYPE_TYPE0 && - font->font_id == type0_id && - font->encoding_id == cmap_id) { - found = 1; - if (__verbose) { - MESG("\npdf_font>> Type0 font \"%s\" (cmap_id=%d) found at font_id=%d.\n", - mrec->font_name, cmap_id, font_id); - } - break; + font->font_id == type0_id && + font->encoding_id == cmap_id) { + found = 1; + if (__verbose) { + MESG("\npdf_font>> Type0 font \"%s\" (cmap_id=%d) found at font_id=%d.\n", + mrec->font_name, cmap_id, font_id); + } + break; } } if (!found) { font_id = font_cache.count; if (font_cache.count >= font_cache.capacity) { - font_cache.capacity += CACHE_ALLOC_SIZE; - font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font); + font_cache.capacity += CACHE_ALLOC_SIZE; + font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font); } font = GET_FONT(font_id); pdf_init_font_struct(font); @@ -708,7 +734,7 @@ pdf_font_findresource (const char *tex_name, font_cache.count++; if (__verbose) { - MESG("\npdf_font>> Type0 font \"%s\"", fontname); + MESG("\npdf_font>> Type0 font \"%s\"", fontname); MESG(" cmap_id=<%s,%d>", mrec->enc_name, font->encoding_id); MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id); } @@ -721,48 +747,48 @@ pdf_font_findresource (const char *tex_name, int found = 0; for (font_id = 0; - font_id < font_cache.count; font_id++) { + font_id < font_cache.count; font_id++) { font = GET_FONT(font_id); switch (font->subtype) { case PDF_FONT_FONTTYPE_TYPE1: case PDF_FONT_FONTTYPE_TYPE1C: case PDF_FONT_FONTTYPE_TRUETYPE: - /* fontname here is font file name. - * We must compare both font file name and encoding - * - * TODO: Embed a font only once if it is used - * with two different encodings - */ - if (!strcmp(fontname, font->ident) && - encoding_id == font->encoding_id) { + /* fontname here is font file name. + * We must compare both font file name and encoding + * + * TODO: Embed a font only once if it is used + * with two different encodings + */ + if (!strcmp(fontname, font->ident) && + encoding_id == font->encoding_id) { if (mrec && mrec->opt.index == font->index) found = 1; - } - break; + } + break; case PDF_FONT_FONTTYPE_TYPE3: - /* There shouldn't be any encoding specified for PK font. - * It must be always font's build-in encoding. - * - * TODO: a PK font with two encodings makes no sense. Change? - */ - if (!strcmp(fontname, font->ident) && - font_scale == font->point_size) { - found = 1; - } - break; + /* There shouldn't be any encoding specified for PK font. + * It must be always font's build-in encoding. + * + * TODO: a PK font with two encodings makes no sense. Change? + */ + if (!strcmp(fontname, font->ident) && + font_scale == font->point_size) { + found = 1; + } + break; case PDF_FONT_FONTTYPE_TYPE0: - break; + break; default: - ERROR("Unknown font type: %d", font->subtype); - break; + ERROR("Unknown font type: %d", font->subtype); + break; } if (found) { - if (__verbose) { - MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", - fontname, encoding_id, font_id); - } - break; + if (__verbose) { + MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", + fontname, encoding_id, font_id); + } + break; } } @@ -770,8 +796,8 @@ pdf_font_findresource (const char *tex_name, if (!found) { font_id = font_cache.count; if (font_cache.count >= font_cache.capacity) { - font_cache.capacity += CACHE_ALLOC_SIZE; - font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font); + font_cache.capacity += CACHE_ALLOC_SIZE; + font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font); } font = GET_FONT(font_id); @@ -787,22 +813,22 @@ pdf_font_findresource (const char *tex_name, font->index = (mrec && mrec->opt.index) ? mrec->opt.index : 0; if (pdf_font_open_type1(font) >= 0) { - font->subtype = PDF_FONT_FONTTYPE_TYPE1; + font->subtype = PDF_FONT_FONTTYPE_TYPE1; } else if (pdf_font_open_type1c(font) >= 0) { - font->subtype = PDF_FONT_FONTTYPE_TYPE1C; + font->subtype = PDF_FONT_FONTTYPE_TYPE1C; } else if (pdf_font_open_truetype(font) >= 0) { - font->subtype = PDF_FONT_FONTTYPE_TRUETYPE; + font->subtype = PDF_FONT_FONTTYPE_TRUETYPE; } else if (pdf_font_open_pkfont(font) >= 0) { - font->subtype = PDF_FONT_FONTTYPE_TYPE3; + font->subtype = PDF_FONT_FONTTYPE_TYPE3; } else { - pdf_clean_font_struct(font); - return -1; + pdf_clean_font_struct(font); + return -1; } font_cache.count++; if (__verbose) { - MESG("\npdf_font>> Simple font \"%s\"", fontname); + MESG("\npdf_font>> Simple font \"%s\"", fontname); MESG(" enc_id=<%s,%d>", (mrec && mrec->enc_name) ? mrec->enc_name : "builtin", font->encoding_id); MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id); diff --git a/Build/source/texk/dvipdfm-x/tt_cmap.c b/Build/source/texk/dvipdfm-x/tt_cmap.c index a32f1752136..533480c58ac 100644 --- a/Build/source/texk/dvipdfm-x/tt_cmap.c +++ b/Build/source/texk/dvipdfm-x/tt_cmap.c @@ -782,8 +782,8 @@ handle_CIDFont (sfnt *sfont, ERROR("No CFF charset data???"); } - map = NEW(num_glyphs * 2, unsigned char); - memset(map, 0, num_glyphs * 2); + map = NEW(65536 * 2, unsigned char); + memset(map, 0, 65536 * 2); switch (charset->format) { case 0: { @@ -791,10 +791,10 @@ handle_CIDFont (sfnt *sfont, cids = charset->data.glyphs; for (gid = 1, i = 0; - i < charset->num_entries; i++) { - map[2*gid ] = (cids[i] >> 8) & 0xff; - map[2*gid+1] = cids[i] & 0xff; - gid++; + i < charset->num_entries; i++) { + map[2*gid ] = (cids[i] >> 8) & 0xff; + map[2*gid+1] = cids[i] & 0xff; + gid++; } } break; @@ -805,15 +805,15 @@ handle_CIDFont (sfnt *sfont, ranges = charset->data.range1; for (gid = 1, i = 0; - i < charset->num_entries; i++) { - cid = ranges[i].first; - count = ranges[i].n_left + 1; /* card8 */ - while (count-- > 0 && - gid <= num_glyphs) { - map[2*gid ] = (cid >> 8) & 0xff; - map[2*gid + 1] = cid & 0xff; - gid++; cid++; - } + i < charset->num_entries; i++) { + cid = ranges[i].first; + count = ranges[i].n_left + 1; /* card8 */ + while (count-- > 0 && + gid <= num_glyphs) { + map[2*gid ] = (cid >> 8) & 0xff; + map[2*gid + 1] = cid & 0xff; + gid++; cid++; + } } } break; @@ -824,23 +824,22 @@ handle_CIDFont (sfnt *sfont, ranges = charset->data.range2; if (charset->num_entries == 1 && - ranges[0].first == 1) { - /* "Complete" CIDFont */ - RELEASE(map); map = NULL; + ranges[0].first == 1) { + /* "Complete" CIDFont */ + RELEASE(map); map = NULL; } else { - /* Not trivial mapping */ - for (gid = 1, i = 0; - i < charset->num_entries; i++) { - cid = ranges[i].first; - count = ranges[i].n_left + 1; - while (count-- > 0 && - gid <= num_glyphs) { - map[2*gid] = (cid >> 8) & 0xff; - map[2*gid+1] = cid & 0xff; - gid++; cid++; - } - } - + /* Not trivial mapping */ + for (gid = 1, i = 0; + i < charset->num_entries; i++) { + cid = ranges[i].first; + count = ranges[i].n_left + 1; + while (count-- > 0 && + gid <= num_glyphs) { + map[2*gid] = (cid >> 8) & 0xff; + map[2*gid+1] = cid & 0xff; + gid++; cid++; + } + } } } break; @@ -1095,13 +1094,17 @@ create_ToUnicode_cmap12 (CMap *cmap, return count; } +/* NOTE: Reverse mapping code which had been placed here is removed since: + * - Implementation of reserve CMap mapping itself is imcomplete. + * - It is wrong to assume that all CMap passed here is Unicode to CID mapping. + * Especially, the second one causes problems. + */ static pdf_obj * create_ToUnicode_cmap (tt_cmap *ttcmap, const char *cmap_name, CMap *cmap_add, const char *used_chars, - sfnt *sfont, - CMap *code_to_cid_cmap) + sfnt *sfont) { pdf_obj *stream = NULL; CMap *cmap; @@ -1119,34 +1122,7 @@ create_ToUnicode_cmap (tt_cmap *ttcmap, /* cmap_add here stores information about all unencoded glyphs which can be * accessed only through OT Layout GSUB table. */ - if (code_to_cid_cmap && cffont && is_cidfont && !cmap_add) { - USHORT i; - for (i = 0; i < 8192; i++) { - int j; - - if (used_chars[i] == 0) - continue; - - for (j = 0; j < 8; j++) { - USHORT cid = 8 * i + j; - int ch; - - if (!is_used_char2(used_chars, cid)) - continue; - - ch = CMap_reverse_decode(code_to_cid_cmap, cid); - if (ch >= 0) { - int len; - unsigned char *p = wbuf + 2; - wbuf[0] = (cid >> 8) & 0xff; - wbuf[1] = cid & 0xff; - len = UC_UTF16BE_encode_char(ch, &p, wbuf + WBUF_SIZE); - CMap_add_bfchar(cmap, wbuf, 2, wbuf + 2, len); - count++; - } - } - } - } else { + { char used_chars_copy[8192]; memcpy(used_chars_copy, used_chars, 8192); @@ -1199,13 +1175,12 @@ pdf_obj * otf_create_ToUnicode_stream (const char *font_name, int ttc_index, /* 0 for non-TTC */ const char *basefont, - const char *used_chars, - int cmap_id) + const char *used_chars) { pdf_obj *cmap_ref = NULL; int res_id; pdf_obj *cmap_obj = NULL; - CMap *cmap_add, *code_to_cid_cmap; + CMap *cmap_add; int cmap_add_id; tt_cmap *ttcmap; char *normalized_font_name; @@ -1264,11 +1239,6 @@ otf_create_ToUnicode_stream (const char *font_name, ERROR("Could not read OpenType/TrueType table directory."); } - code_to_cid_cmap = CMap_cache_get(cmap_id); - cmap_type = CMap_get_type(code_to_cid_cmap); - if (cmap_type != CMAP_TYPE_CODE_TO_CID) - code_to_cid_cmap = NULL; - cmap_add_name = NEW(strlen(font_name)+strlen(",000-UCS32-Add")+1, char); sprintf(cmap_add_name, "%s,%03d-UCS32-Add", font_name, ttc_index); cmap_add_id = CMap_cache_find(cmap_add_name); @@ -1286,8 +1256,7 @@ otf_create_ToUnicode_stream (const char *font_name, continue; if (ttcmap->format == 4 || ttcmap->format == 12) { - cmap_obj = create_ToUnicode_cmap(ttcmap, cmap_name, cmap_add, used_chars, - sfont, code_to_cid_cmap); + cmap_obj = create_ToUnicode_cmap(ttcmap, cmap_name, cmap_add, used_chars, sfont); break; } } @@ -1302,7 +1271,7 @@ otf_create_ToUnicode_stream (const char *font_name, if (cmap_obj) { res_id = pdf_defineresource("CMap", cmap_name, - cmap_obj, PDF_RES_FLUSH_IMMEDIATE); + cmap_obj, PDF_RES_FLUSH_IMMEDIATE); cmap_ref = pdf_get_resource_reference(res_id); } else { cmap_ref = NULL; @@ -1366,7 +1335,7 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon int is_cidfont = 0; sfnt *sfont; ULONG offset = 0; - char *base_name = NULL, *cmap_name = NULL; + char *cmap_name = NULL; FILE *fp = NULL; otl_gsub *gsub_vert = NULL, *gsub_list = NULL; tt_cmap *ttcmap; @@ -1380,13 +1349,46 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon return -1; /* Sorry for this... */ } + /* First look for cache if it was already loaded */ + cmap_name = NEW(strlen(map_name)+strlen("-UCS4-H")+5, char); + if (otl_tags) { + cmap_name = NEW(strlen(map_name)+strlen(otl_tags)+strlen("-UCS4-H")+6, char); + if (wmode) + sprintf(cmap_name, "%s,%03d,%s-UCS4-V", map_name, ttc_index, otl_tags); + else + sprintf(cmap_name, "%s,%03d,%s-UCS4-H", map_name, ttc_index, otl_tags); + } else { + if (wmode) + sprintf(cmap_name, "%s,%03d-UCS4-V", map_name, ttc_index); + else { + sprintf(cmap_name, "%s,%03d-UCS4-H", map_name, ttc_index); + } + } + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + MESG("otf_cmap>> Unicode charmap for font=\"%s\" layout=\"%s\"\n", + map_name, (otl_tags ? otl_tags : "none")); + } + cmap_id = CMap_cache_find(cmap_name); + if (cmap_id >= 0) { + RELEASE(cmap_name); + if (verbose > VERBOSE_LEVEL_MIN) + MESG("otf_cmap>> Found at cmap_id=%d.\n", cmap_id); + + return cmap_id; + } + + /* CMap not found */ fp = DPXFOPEN(map_name, DPX_RES_TYPE_TTFONT); if (!fp) { fp = DPXFOPEN(map_name, DPX_RES_TYPE_OTFONT); } if (!fp) { fp = DPXFOPEN(map_name, DPX_RES_TYPE_DFONT); - if (!fp) return -1; + if (!fp) { + RELEASE(cmap_name); + return -1; + } sfont = dfont_open(fp, ttc_index); } else { sfont = sfnt_open(fp); @@ -1417,19 +1419,8 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon if (sfnt_read_table_directory(sfont, offset) < 0) ERROR("Could not read OpenType/TrueType table directory."); - base_name = NEW(strlen(map_name)+strlen("-UCS4-H")+5, char); - if (wmode) - sprintf(base_name, "%s,%03d-UCS4-V", map_name, ttc_index); - else { - sprintf(base_name, "%s,%03d-UCS4-H", map_name, ttc_index); - } if (otl_tags) { - cmap_name = NEW(strlen(map_name)+strlen(otl_tags)+strlen("-UCS4-H")+6, char); - if (wmode) - sprintf(cmap_name, "%s,%03d,%s-UCS4-V", map_name, ttc_index, otl_tags); - else - sprintf(cmap_name, "%s,%03d,%s-UCS4-H", map_name, ttc_index, otl_tags); /* tounicode_add here is later refered by otf_create_ToUnicode_stream() * for finding additional CID to Unicode mapping entries required by * OTL gsub substitution. @@ -1450,9 +1441,6 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon tounicode_add_id = CMap_cache_add(tounicode_add); } RELEASE(tounicode_add_name); - } else { - cmap_name = NEW(strlen(base_name)+1, char); - strcpy(cmap_name, base_name); } if (sfont->type == SFNT_TYPE_POSTSCRIPT) { @@ -1461,26 +1449,6 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon is_cidfont = 0; } - if (verbose > VERBOSE_LEVEL_MIN) { - MESG("\n"); - MESG("otf_cmap>> Unicode charmap for font=\"%s\" layout=\"%s\"\n", - map_name, (otl_tags ? otl_tags : "none")); - } - cmap_id = CMap_cache_find(cmap_name); - if (cmap_id >= 0) { - RELEASE(cmap_name); - RELEASE(base_name); - if (GIDToCIDMap) - RELEASE(GIDToCIDMap); - sfnt_close(sfont); - DPXFCLOSE(fp); - - if (verbose > VERBOSE_LEVEL_MIN) - MESG("otf_cmap>> Found at cmap_id=%d.\n", cmap_id); - - return cmap_id; - } - ttcmap = tt_cmap_read(sfont, 3, 10); /* Microsoft UCS4 */ if (!ttcmap) { ttcmap = tt_cmap_read(sfont, 3, 1); /* Microsoft UCS2 */ @@ -1533,19 +1501,136 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon otl_gsub_release(gsub_list); gsub_list = NULL; + RELEASE(cmap_name); + if (GIDToCIDMap) + RELEASE(GIDToCIDMap); + if (is_cidfont) { + if (csi.registry) + RELEASE(csi.registry); + if (csi.ordering) + RELEASE(csi.ordering); + } + tt_cmap_release(ttcmap); + sfnt_close(sfont); + DPXFCLOSE(fp); + + return cmap_id; +} + +int +otf_try_load_GID_to_CID_map (const char *map_name, int ttc_index, int wmode) +{ + int cmap_id = -1; + sfnt *sfont; + ULONG offset = 0; + char *cmap_name = NULL; + FILE *fp = NULL; + CIDSysInfo csi = {NULL, NULL, 0}; + int is_cidfont = 0; + unsigned char *GIDToCIDMap = NULL; + + if (!map_name) + return -1; + + if (ttc_index > 999 || ttc_index < 0) { + return -1; /* Sorry for this... */ + } + + /* Check if already loaded */ + cmap_name = NEW(strlen(map_name)+strlen("-GID")+5, char); + sprintf(cmap_name, "%s:%3d-GID", map_name, ttc_index); + cmap_id = CMap_cache_find(cmap_name); + if (cmap_id >= 0) { RELEASE(cmap_name); - RELEASE(base_name); - if (GIDToCIDMap) - RELEASE(GIDToCIDMap); - if (is_cidfont) { - if (csi.registry) - RELEASE(csi.registry); - if (csi.ordering) - RELEASE(csi.ordering); + if (verbose > VERBOSE_LEVEL_MIN) + MESG("otf_cmap>> GID-to-CID mapping found at cmap_id=%d.\n", cmap_id); + + return cmap_id; + } + + fp = DPXFOPEN(map_name, DPX_RES_TYPE_TTFONT); + if (!fp) { + fp = DPXFOPEN(map_name, DPX_RES_TYPE_OTFONT); + } + if (!fp) { + fp = DPXFOPEN(map_name, DPX_RES_TYPE_DFONT); + if (!fp) { + RELEASE(cmap_name); + return -1; } - tt_cmap_release(ttcmap); + sfont = dfont_open(fp, ttc_index); + } else { + sfont = sfnt_open(fp); + } + + if (!sfont) { + ERROR("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name); + } + switch (sfont->type) { + case SFNT_TYPE_TTC: + offset = ttc_read_offset(sfont, ttc_index); + if (offset == 0) { + ERROR("Invalid TTC index"); + } + break; + case SFNT_TYPE_TRUETYPE: + case SFNT_TYPE_POSTSCRIPT: + offset = 0; + break; + case SFNT_TYPE_DFONT: + offset = sfont->offset; + break; + default: + ERROR("Not a OpenType/TrueType/TTC font?: %s", map_name); + break; + } + + if (sfnt_read_table_directory(sfont, offset) < 0) + ERROR("Could not read OpenType/TrueType table directory."); + if (sfont->type != SFNT_TYPE_POSTSCRIPT) { + RELEASE(cmap_name); sfnt_close(sfont); DPXFCLOSE(fp); + return -1; + } - return cmap_id; + /* Read GID-to-CID mapping if CFF OpenType is found. */ + is_cidfont = handle_CIDFont(sfont, &GIDToCIDMap, &csi); + if (is_cidfont) { + if (GIDToCIDMap) { + CMap *cmap; + int32_t gid; + + cmap = CMap_new(); + CMap_set_name (cmap, cmap_name); + CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID); + CMap_set_wmode(cmap, wmode); + CMap_add_codespacerange(cmap, "\x00\x00", "\xff\xff", 2); + CMap_set_CIDSysInfo(cmap, &csi); + + for (gid = 0; gid < 65536; gid++) { + unsigned char src[2]; + src[0] = (gid >> 8) & 0xff; + src[1] = gid & 0xff; + CMap_add_bfchar(cmap, src, 2, &GIDToCIDMap[gid*2], 2); + } + cmap_id = CMap_cache_add(cmap); + if (verbose > VERBOSE_LEVEL_MIN) { + MESG("\n"); + MESG("otf_cmap>> Creating GID-to-CID mapping for font=\"%s\"\n", map_name); + } + } + /* Identity mapping for null GIDToCIDMap */ + } + RELEASE(cmap_name); + if (GIDToCIDMap) + RELEASE(GIDToCIDMap); + if (csi.registry) + RELEASE(csi.registry); + if (csi.ordering) + RELEASE(csi.ordering); + sfnt_close(sfont); + DPXFCLOSE(fp); + + return cmap_id; } diff --git a/Build/source/texk/dvipdfm-x/tt_cmap.h b/Build/source/texk/dvipdfm-x/tt_cmap.h index 8fd51581a8f..be1ed6a4545 100644 --- a/Build/source/texk/dvipdfm-x/tt_cmap.h +++ b/Build/source/texk/dvipdfm-x/tt_cmap.h @@ -69,11 +69,10 @@ extern void tt_cmap_release (tt_cmap *cmap); extern pdf_obj *otf_create_ToUnicode_stream (const char *map_name, int ttc_index, const char *basefont, - const char *used_chars, - int cmap_id); + const char *used_chars); /* CMap ID */ -extern int otf_load_Unicode_CMap (const char *map_name, - int ttc_index, - const char *otl_opts, int wmode); - +extern int otf_load_Unicode_CMap (const char *map_name, + int ttc_index, + const char *otl_opts, int wmode); +extern int otf_try_load_GID_to_CID_map (const char *map_name, int ttc_index, int wmode); #endif /* _TT_CMAP_H_ */ diff --git a/Build/source/texk/dvipdfm-x/type0.c b/Build/source/texk/dvipdfm-x/type0.c index 7c6c9ffaf88..919ed06a3ea 100644 --- a/Build/source/texk/dvipdfm-x/type0.c +++ b/Build/source/texk/dvipdfm-x/type0.c @@ -155,12 +155,13 @@ Type0Font_create_ToUnicode_stream(Type0Font *font) { return otf_create_ToUnicode_stream(CIDFont_get_ident(cidfont), CIDFont_get_opt_index(cidfont), CIDFont_get_fontname(cidfont), - Type0Font_get_usedchars(font), - font->cmap_id); + Type0Font_get_usedchars(font)); } /* Try to load ToUnicode CMap from file system first, if not found fallback to - * font CMap reverse lookup. */ + * font CMap reverse lookup. + * CHANGED: CMap here is not always Unicode to CID mapping. Don't use reverse lookup. + */ static pdf_obj * Type0Font_try_load_ToUnicode_stream(Type0Font *font, char *cmap_base) { char *cmap_name = NEW(strlen(cmap_base) + strlen("-UTF-16"), char); -- cgit v1.2.3