diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2020-09-22 01:13:44 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2020-09-22 01:13:44 +0000 |
commit | 80096425836c7c322a5ffb3dd7e96e2247d062d0 (patch) | |
tree | 8ae4ac314bfc16df9612ea963ea89b2d43f77c75 | |
parent | 8094b6f91848cffa0cc19c67ee75413307b2b264 (diff) |
Simplify font related code. Fix a bug in determinant calculation. (S. Hirata)
git-svn-id: svn://tug.org/texlive/trunk@56400 c570f23f-e606-0410-a88d-b1316a301751
28 files changed, 2229 insertions, 2550 deletions
diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog index 84997bbc54a..eb545679bcf 100644 --- a/Build/source/texk/dvipdfm-x/ChangeLog +++ b/Build/source/texk/dvipdfm-x/ChangeLog @@ -1,3 +1,16 @@ +2020-09-22 Shunsaku Hirata <shunsaku.hirata74@gmail.com> + + * cid.[ch], cidtype0.[ch], cidtype2.[ch], pdfdev.c, + pdffont.[ch], pkfont.[ch], truetype.[ch], type0.[ch], + type1.[ch], type1c.[ch]: Revise font related code and largely + simplify it. Type0 and CIDFont now use the same struct as + simple fonts. + * Makefile.am, cid_p.h: Remove cid_p.h. + * pdfdraw.[ch]: Fix a bug in calculation of determinant. + Enable few functions for future improvement. + * dpxutil.c: Fix a bug in the roll operation. + * configure.ac: Version 20200922. + 2020-09-07 Shunsaku Hirata <shunsaku.hirata74@gmail.com> * spc_misc.c: Fix a bug that the upper limit of stack id is wrong. diff --git a/Build/source/texk/dvipdfm-x/Makefile.am b/Build/source/texk/dvipdfm-x/Makefile.am index 160a03028e2..c738137d3d0 100644 --- a/Build/source/texk/dvipdfm-x/Makefile.am +++ b/Build/source/texk/dvipdfm-x/Makefile.am @@ -26,7 +26,6 @@ xdvipdfmx_SOURCES = \ cid_basefont.h \ cid.c \ cid.h \ - cid_p.h \ cidtype0.c \ cidtype0.h \ cidtype2.c \ diff --git a/Build/source/texk/dvipdfm-x/Makefile.in b/Build/source/texk/dvipdfm-x/Makefile.in index c86fc81ea0d..d68d9c40961 100644 --- a/Build/source/texk/dvipdfm-x/Makefile.in +++ b/Build/source/texk/dvipdfm-x/Makefile.in @@ -669,7 +669,6 @@ xdvipdfmx_SOURCES = \ cid_basefont.h \ cid.c \ cid.h \ - cid_p.h \ cidtype0.c \ cidtype0.h \ cidtype2.c \ diff --git a/Build/source/texk/dvipdfm-x/cid.c b/Build/source/texk/dvipdfm-x/cid.c index 42554ad3123..bb3fb18604c 100644 --- a/Build/source/texk/dvipdfm-x/cid.c +++ b/Build/source/texk/dvipdfm-x/cid.c @@ -40,14 +40,8 @@ #include "cidtype0.h" #include "cidtype2.h" -#include "cid_p.h" #include "cid.h" -#include "cff.h" - -#define CIDFONT_DEBUG 3 -#define CIDFONT_DEBUG_STR "CIDFont" - #define PDF_CID_SUPPORT_MIN 2 #define PDF_CID_SUPPORT_MAX 6 @@ -104,6 +98,7 @@ CIDSysInfo CSI_UNICODE = { /* * Optional supplement after alias name. */ + static struct { const char *name; int index; @@ -115,275 +110,134 @@ static struct { }; static void release_opt (cid_opt *opt); -static CIDSysInfo *get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt); - -static int cidoptflags = 0; - -#if 0 -int -CIDFont_require_version (void) -{ - return PDF_CID_SUPPORT_MIN; -} -#endif - -static CIDFont * -CIDFont_new (void) -{ - CIDFont *font = NULL; - - font = NEW(1, struct CIDFont); - - font->name = NULL; - font->fontname = NULL; - font->ident = NULL; - - /* - * CIDFont - */ - font->subtype = -1; - font->flags = FONT_FLAG_NONE; - font->csi = NULL; - font->options = NULL; - (font->parent)[0] = -1; /* Horizontal */ - (font->parent)[1] = -1; /* Vertical */ +static int get_cidsysinfo (CIDSysInfo *csi, const char *map_name, fontmap_opt *fmap_opt); - /* - * PDF Font Resource - */ - font->indirect = NULL; - font->fontdict = NULL; - font->descriptor = NULL; - - return font; -} - -/* It does write PDF objects. */ -static void -CIDFont_flush (CIDFont *font) -{ - if (font) { - if (font->indirect) pdf_release_obj(font->indirect); - font->indirect = NULL; - if (font->fontdict) pdf_release_obj(font->fontdict); - font->fontdict = NULL; - if (font->descriptor) pdf_release_obj(font->descriptor); - font->descriptor = NULL; - } -} - -static void -CIDFont_release (CIDFont *font) -{ - if (font) { - if (font->indirect) - ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR); - if (font->fontdict) - ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR); - if (font->descriptor) - ERROR("%s: Object not flushed.", CIDFONT_DEBUG_STR); - - if (font->fontname) RELEASE(font->fontname); - if (font->name) RELEASE(font->name); - if (font->ident) RELEASE(font->ident); - if (font->csi) { - if (font->csi->registry) - RELEASE(font->csi->registry); - if (font->csi->ordering) - RELEASE(font->csi->ordering); - RELEASE(font->csi); - } - if (font->options) - release_opt(font->options); - } -} - -char * -CIDFont_get_fontname (CIDFont *font) -{ - ASSERT(font); - return font->fontname; -} - -char * -CIDFont_get_ident (CIDFont *font) -{ - ASSERT(font); - return font->ident; -} +int opt_flags_cidfont = 0; int -CIDFont_get_opt_index (CIDFont *font) +CIDFont_is_ACCFont (pdf_font *font) { - int opt_index; + int i; + CIDSysInfo *csi; ASSERT(font); - if (font->options) - opt_index = font->options->index; - else { - opt_index = 0; + csi = &font->cid.csi; + for (i = ACC_START; i <= ACC_END ; i++) { + if (!strcmp(csi->registry, CIDFont_stdcc_def[i].registry) && + !strcmp(csi->ordering, CIDFont_stdcc_def[i].ordering)) + return 1; } - return opt_index; -} - -int -CIDFont_get_subtype (CIDFont *font) -{ - ASSERT(font); - return font->subtype; + return 0; } int -CIDFont_get_embedding (CIDFont *font) +CIDFont_is_UCSFont (pdf_font *font) { - ASSERT(font); - return font->options->embed; -} + CIDSysInfo *csi; -CIDSysInfo * -CIDFont_get_CIDSysInfo (CIDFont *font) -{ ASSERT(font); - return font->csi; -} - -/* - * Returns ID of parent Type0 font - * wmode: 0 for horizontal, 1 for vertical - */ -int -CIDFont_get_parent_id (CIDFont *font, int wmode) -{ - ASSERT(font); + csi = &font->cid.csi; - if (wmode < 0 || wmode > 1) - ERROR("%s: Invalid wmode value.", CIDFONT_DEBUG_STR); + if (!strcmp(csi->ordering, "UCS") || + !strcmp(csi->ordering, "UCS2")) + return 1; - return (font->parent)[wmode]; + return 0; } -pdf_obj * -CIDFont_get_resource (CIDFont *font) +char * +CIDFont_get_usedchars (pdf_font *font) { - ASSERT(font); - - if (!font->indirect) - font->indirect = pdf_ref_obj(font->fontdict); + if (!font->usedchars) { + font->usedchars = NEW(8192, char); + memset(font->usedchars, 0, 8192*sizeof(char)); + } - return pdf_link_obj(font->indirect); + return font->usedchars; } -/* - * Set parent Type0 font. - */ -void -CIDFont_attach_parent (CIDFont *font, int parent_id, int wmode) +char * +CIDFont_get_usedchars_v (pdf_font *font) { - ASSERT(font); - - if (wmode < 0 || wmode > 1) - ERROR("%s: Invalid wmode value.", CIDFONT_DEBUG_STR); - - if (font->parent[wmode] >= 0) - WARN("%s: CIDFont already have a parent Type1 font.", CIDFONT_DEBUG_STR); + if (!font->cid.usedchars_v) { + font->cid.usedchars_v = NEW(8192, char); + memset(font->cid.usedchars_v, 0, 8192*sizeof(char)); + } - font->parent[wmode] = parent_id; + return font->cid.usedchars_v; } -int -CIDFont_is_ACCFont (CIDFont *font) + +static int +source_font_type (pdf_font *font) { - int i; + int type = PDF_FONT_FONTTYPE_CIDTYPE0; ASSERT(font); - if (!font->csi) - ERROR("%s: CIDSystemInfo undefined.", CIDFONT_DEBUG_STR); - - for (i = ACC_START; i <= ACC_END ; i++) { - if (!strcmp(font->csi->registry, CIDFont_stdcc_def[i].registry) && - !strcmp(font->csi->ordering, CIDFont_stdcc_def[i].ordering)) - return 1; + if (font->flags & CIDFONT_FLAG_TYPE1) { + type = PDF_FONT_FONTTYPE_TYPE1; + } else if (font->flags & CIDFONT_FLAG_TYPE1C) { + type = PDF_FONT_FONTTYPE_TYPE1C; + } else if (font->flags & CIDFONT_FLAG_TRUETYPE) { + type = PDF_FONT_FONTTYPE_TRUETYPE; } - return 0; -} - -int -CIDFont_is_UCSFont (CIDFont *font) -{ - ASSERT(font); - if (!strcmp(font->csi->ordering, "UCS") || - !strcmp(font->csi->ordering, "UCS2")) - return 1; - return 0; + return type; } -/* FIXME */ -int -CIDFont_get_flag (CIDFont *font, int mask) +void +pdf_font_load_cidfont (pdf_font *font) { - ASSERT(font); - return ((font->flags & mask) ? 1 : 0); -} + int error = 0; -static void -CIDFont_dofont (CIDFont *font) -{ - if (!font || !font->indirect) + if (!font || !font->reference) return; if (dpx_conf.verbose_level > 0) - MESG(":%s", font->ident); + MESG(":%s", font->filename); if (dpx_conf.verbose_level > 1) { if (font->fontname) MESG("[%s]", font->fontname); } switch (font->subtype) { - case CIDFONT_TYPE0: + case PDF_FONT_FONTTYPE_CIDTYPE0: if(dpx_conf.verbose_level > 0) MESG("[CIDFontType0]"); - if (CIDFont_get_flag(font, CIDFONT_FLAG_TYPE1)) - CIDFont_type0_t1dofont(font); - else if (CIDFont_get_flag(font, CIDFONT_FLAG_TYPE1C)) - CIDFont_type0_t1cdofont(font); - else - CIDFont_type0_dofont(font); + switch (source_font_type(font)) { + case PDF_FONT_FONTTYPE_TYPE1: + error = CIDFont_type0_t1dofont(font); + break; + case PDF_FONT_FONTTYPE_TYPE1C: + error = CIDFont_type0_t1cdofont(font); + break; + default: + error = CIDFont_type0_dofont(font); + break; + } break; - case CIDFONT_TYPE2: + case PDF_FONT_FONTTYPE_CIDTYPE2: if(dpx_conf.verbose_level > 0) MESG("[CIDFontType2]"); - CIDFont_type2_dofont(font); - break; - default: - ERROR("%s: Unknown CIDFontType %d.", CIDFONT_DEBUG_STR, font->subtype); + error = CIDFont_type2_dofont(font); break; } -} - -/* - * - */ -int -CIDFont_is_BaseFont (CIDFont *font) -{ - ASSERT(font); - return (font->flags & FONT_FLAG_BASEFONT) ? 1 : 0; + if (error) + ERROR("Error occurred while loading font: %s", font->filename); + + return; } #include "pdfparse.h" #include "cid_basefont.h" -static int CIDFont_base_open (CIDFont *font, - const char *name, CIDSysInfo *cmap_csi, cid_opt *opt); - static int -CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_opt *opt) +CIDFont_base_open (pdf_font *font, const char *name, cid_opt *opt) { pdf_obj *fontdict, *descriptor; char *fontname = NULL; @@ -433,7 +287,7 @@ CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_op } font->fontname = fontname; - font->flags |= FONT_FLAG_BASEFONT; + font->flags |= PDF_FONT_FLAG_BASEFONT; { char *registry, *ordering; int supplement; @@ -446,22 +300,12 @@ CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_op registry = pdf_string_value(pdf_lookup_dict(tmp, "Registry")); ordering = pdf_string_value(pdf_lookup_dict(tmp, "Ordering")); supplement = pdf_number_value(pdf_lookup_dict(tmp, "Supplement")); - if (cmap_csi) { /* NULL for accept any */ - if (strcmp(registry, cmap_csi->registry) || - strcmp(ordering, cmap_csi->ordering)) - ERROR("Inconsistent CMap used for CID-keyed font %s.", - cid_basefont[idx].fontname); - else if (supplement < cmap_csi->supplement) { - WARN("CMap has higher supplement number than CIDFont: %s", fontname); - WARN("Some chracters may not be displayed or printed."); - } - } - font->csi = NEW(1, CIDSysInfo); - font->csi->registry = NEW(strlen(registry)+1, char); - font->csi->ordering = NEW(strlen(ordering)+1, char); - strcpy(font->csi->registry, registry); - strcpy(font->csi->ordering, ordering); - font->csi->supplement = supplement; + + font->cid.csi.registry = NEW(strlen(registry)+1, char); + font->cid.csi.ordering = NEW(strlen(ordering)+1, char); + strcpy(font->cid.csi.registry, registry); + strcpy(font->cid.csi.ordering, ordering); + font->cid.csi.supplement = supplement; } { @@ -473,15 +317,15 @@ CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_op type = pdf_name_value(tmp); if (!strcmp(type, "CIDFontType0")) - font->subtype = CIDFONT_TYPE0; + font->subtype = PDF_FONT_FONTTYPE_CIDTYPE0; else if (!strcmp(type, "CIDFontType2")) - font->subtype = CIDFONT_TYPE2; + font->subtype = PDF_FONT_FONTTYPE_CIDTYPE2; else { ERROR("Unknown CIDFontType \"%s\"", type); } } - if (cidoptflags & CIDFONT_FORCE_FIXEDPITCH) { + if (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH) { if (pdf_lookup_dict(fontdict, "W")) { pdf_remove_dict(fontdict, "W"); } @@ -495,7 +339,7 @@ CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_op pdf_add_dict(descriptor, pdf_new_name("Type"), pdf_new_name("FontDescriptor")); pdf_add_dict(descriptor, pdf_new_name("FontName"), pdf_new_name(fontname)); - font->fontdict = fontdict; + font->resource = fontdict; font->descriptor = descriptor; opt->embed = 0; @@ -503,184 +347,154 @@ CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_op return 0; } - - -#define CACHE_ALLOC_SIZE 16u - -struct FontCache { - int num; - int max; - CIDFont **fonts; -}; - -static struct FontCache *__cache = NULL; - -#define CHECK_ID(n) do {\ - if (! __cache)\ - ERROR("%s: CIDFont cache not initialized.", CIDFONT_DEBUG_STR);\ - if ((n) < 0 || (n) >= __cache->num)\ - ERROR("%s: Invalid ID %d", CIDFONT_DEBUG_STR, (n));\ - } while (0) - -static void -CIDFont_cache_init (void) -{ - if (__cache) - ERROR("%s: Already initialized.", CIDFONT_DEBUG_STR); - - __cache = NEW(1, struct FontCache); - - __cache->max = CACHE_ALLOC_SIZE; - __cache->fonts = NEW(__cache->max, struct CIDFont *); - __cache->num = 0; -} - -CIDFont * -CIDFont_cache_get (int font_id) -{ - CHECK_ID(font_id); - return __cache->fonts[font_id]; -} - -/* - * cmap_csi is NULL if CMap is Identity. - */ int -CIDFont_cache_find (const char *map_name, - CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt) +pdf_font_cidfont_lookup_cache (pdf_font *fonts, int count, const char *map_name, CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt) { - int font_id = -1; - CIDFont *font = NULL; - cid_opt *opt = NULL; - - if (!__cache) - CIDFont_cache_init(); - - opt = NEW(1, cid_opt); - opt->style = fmap_opt->style; - opt->index = fmap_opt->index; - opt->embed = (fmap_opt->flags & FONTMAP_OPT_NOEMBED) ? 0 : 1; - opt->name = NULL; - opt->csi = get_cidsysinfo(map_name, fmap_opt); - opt->stemv = fmap_opt->stemv; - - if (!opt->csi && cmap_csi) { + int font_id = -1; + pdf_font *font = NULL; + cid_opt opt; + int has_csi; + + ASSERT(fonts); + + opt.style = fmap_opt->style; + opt.embed = (fmap_opt->flags & FONTMAP_OPT_NOEMBED) ? 0 : 1; + opt.csi.registry = NULL; + opt.csi.ordering = NULL; + opt.csi.supplement = 0; + has_csi = get_cidsysinfo(&opt.csi, map_name, fmap_opt); + opt.stemv = fmap_opt->stemv; + + if (!has_csi && cmap_csi) { /* * No CIDSystemInfo supplied explicitly. Copy from CMap's one if available. * It is not neccesary for CID-keyed fonts. But TrueType requires them. */ - opt->csi = NEW(1, CIDSysInfo); - opt->csi->registry = NEW(strlen(cmap_csi->registry)+1, char); - strcpy(opt->csi->registry, cmap_csi->registry); - opt->csi->ordering = NEW(strlen(cmap_csi->ordering)+1, char); - strcpy(opt->csi->ordering, cmap_csi->ordering); - opt->csi->supplement = cmap_csi->supplement; + opt.csi.registry = NEW(strlen(cmap_csi->registry)+1, char); + strcpy(opt.csi.registry, cmap_csi->registry); + opt.csi.ordering = NEW(strlen(cmap_csi->ordering)+1, char); + strcpy(opt.csi.ordering, cmap_csi->ordering); + opt.csi.supplement = cmap_csi->supplement; + has_csi = 1; } /* * Here, we do not compare font->ident and map_name because of * implicit CIDSystemInfo supplied by CMap for TrueType. */ - for (font_id = 0; font_id < __cache->num; font_id++) { - font = __cache->fonts[font_id]; - if (!strcmp(font->name, map_name) && - font->options->style == opt->style && - font->options->index == opt->index) { - if (font->options->embed == opt->embed) { + for (font_id = 0; font_id < count; font_id++) { + font = &fonts[font_id]; + if (font->subtype != PDF_FONT_FONTTYPE_CIDTYPE0 && + font->subtype != PDF_FONT_FONTTYPE_CIDTYPE2) + continue; + if (!strcmp(font->filename, map_name) && + font->cid.options.style == opt.style && + font->index == fmap_opt->index) { + if (font->cid.options.embed == opt.embed) { /* * Case 1: CSI not available (Identity CMap) * Font is TrueType --> continue * Font is CIDFont --> break * Case 2: CSI matched --> break */ - if (!opt->csi) { - if (font->subtype == CIDFONT_TYPE2) + if (!has_csi) { + if (font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2) continue; else break; - } else if (!strcmp(font->csi->registry, opt->csi->registry) && - !strcmp(font->csi->ordering, opt->csi->ordering)) { - if (font->subtype == CIDFONT_TYPE2) - font->csi->supplement = - MAX(opt->csi->supplement, font->csi->supplement); + } else if (!strcmp(font->cid.csi.registry, opt.csi.registry) && + !strcmp(font->cid.csi.ordering, opt.csi.ordering)) { + if (font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2) + font->cid.csi.supplement = + MAX(opt.csi.supplement, font->cid.csi.supplement); /* FIXME: font modified */ break; } - } else if (CIDFont_is_BaseFont(font)) { - opt->embed = 0; + } else if (font->flags & PDF_FONT_FLAG_BASEFONT) { break; } } } + release_opt(&opt); - if (font_id < __cache->num && cmap_csi) { - if (strcmp(font->csi->registry, cmap_csi->registry) || - strcmp(font->csi->ordering, cmap_csi->ordering)) - ERROR("%s: Incompatible CMap for CIDFont \"%s\"", - CIDFONT_DEBUG_STR, map_name); - } - - if (font_id == __cache->num) { - font = CIDFont_new(); - if (CIDFont_type0_open(font, map_name, cmap_csi, opt, 0) < 0 && - CIDFont_type2_open(font, map_name, cmap_csi, opt) < 0 && - CIDFont_type0_open(font, map_name, cmap_csi, opt, - CIDFONT_FLAG_TYPE1) < 0 && - CIDFont_type0_open(font, map_name, cmap_csi, opt, - CIDFONT_FLAG_TYPE1C) < 0 && - CIDFont_base_open (font, map_name, cmap_csi, opt) < 0) { - CIDFont_release(font); - release_opt(opt); - return -1; - } else { - if (__cache->num >= __cache->max) { - __cache->max += CACHE_ALLOC_SIZE; - __cache->fonts = RENEW(__cache->fonts, - __cache->max, struct CIDFont *); - } - font->name = NEW(strlen(map_name)+1, char); - strcpy(font->name, map_name); - font->ident = NEW(strlen(map_name)+1, char); - strcpy(font->ident, map_name); - font->options = opt; - __cache->fonts[font_id] = font; - (__cache->num)++; - } - } else if (opt) { - release_opt(opt); - } - - return font_id; + return (font_id < count) ? font_id : -1; } -void -CIDFont_cache_close (void) +int +pdf_font_open_cidfont (pdf_font *font, const char *map_name, CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt) { - int font_id; - - if (__cache) { - for (font_id = 0; - font_id < __cache->num; font_id++) { - CIDFont *font; - - font = __cache->fonts[font_id]; - - if (dpx_conf.verbose_level > 0) - MESG("(CID"); - - CIDFont_dofont (font); - CIDFont_flush (font); - CIDFont_release(font); + cid_opt opt; + int has_csi; + + opt.style = fmap_opt->style; + opt.embed = (fmap_opt->flags & FONTMAP_OPT_NOEMBED) ? 0 : 1; + opt.csi.registry = NULL; + opt.csi.ordering = NULL; + opt.csi.supplement = 0; + has_csi = get_cidsysinfo(&opt.csi, map_name, fmap_opt); + opt.stemv = fmap_opt->stemv; + + if (!has_csi && cmap_csi) { + /* + * No CIDSystemInfo supplied explicitly. Copy from CMap's one if available. + * It is not neccesary for CID-keyed fonts. But TrueType requires them. + */ + opt.csi.registry = NEW(strlen(cmap_csi->registry)+1, char); + strcpy(opt.csi.registry, cmap_csi->registry); + opt.csi.ordering = NEW(strlen(cmap_csi->ordering)+1, char); + strcpy(opt.csi.ordering, cmap_csi->ordering); + opt.csi.supplement = cmap_csi->supplement; + has_csi = 1; + } - RELEASE(font); + if (CIDFont_type0_open(font, map_name, fmap_opt->index, &opt) < 0 && + CIDFont_type2_open(font, map_name, fmap_opt->index, &opt) < 0 && + CIDFont_type0_open_from_t1 (font, map_name, fmap_opt->index, &opt) < 0 && + CIDFont_type0_open_from_t1c(font, map_name, fmap_opt->index, &opt) < 0 && + CIDFont_base_open (font, map_name, &opt) < 0) { + release_opt(&opt); + return -1; + } - if (dpx_conf.verbose_level > 0) - MESG(")"); + font->filename = NEW(strlen(map_name)+1, char); + strcpy(font->filename, map_name); + font->ident = NEW(strlen(map_name)+1, char); + strcpy(font->ident, map_name); + font->index = fmap_opt->index; + font->cid.options = opt; + + if (font->cid.csi.registry && font->cid.csi.ordering) { + if (cmap_csi) { + if (strcmp(font->cid.csi.registry, cmap_csi->registry) || + strcmp(font->cid.csi.ordering, cmap_csi->ordering)) { + WARN("Inconsistent ROS found:\n"); + MESG("\tFont: %s-%s-%d\n", font->cid.csi.registry, font->cid.csi.ordering, font->cid.csi.supplement); + MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement); + ERROR("Incompatible CMap specified for this font."); + } + if (font->cid.csi.supplement < cmap_csi->supplement) { + font->cid.csi.supplement = cmap_csi->supplement; + } + } + } else { + ASSERT(font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2); + if (cmap_csi) { + font->cid.csi.registry = NEW(strlen(cmap_csi->registry)+1, char); + strcpy(font->cid.csi.registry, cmap_csi->registry); + font->cid.csi.ordering = NEW(strlen(cmap_csi->ordering)+1, char); + strcpy(font->cid.csi.ordering, cmap_csi->ordering); + font->cid.csi.supplement = cmap_csi->supplement; + } else { /* This means font's internal glyph ordering. */ + font->cid.csi.registry = NEW(strlen("Adobe")+1, char); + strcpy(font->cid.csi.registry, "Adobe"); + font->cid.csi.ordering = NEW(strlen("Identity")+1, char); + strcpy(font->cid.csi.ordering, "Identity"); + font->cid.csi.supplement = 0; } - RELEASE(__cache->fonts); - RELEASE(__cache); - __cache = NULL; } + + return 0; } + /******************************* OPTIONS *******************************/ /* @@ -692,20 +506,16 @@ CIDFont_cache_close (void) static void release_opt (cid_opt *opt) { - if (opt->csi) { - if (opt->csi->registry) - RELEASE(opt->csi->registry); - if (opt->csi->ordering) - RELEASE(opt->csi->ordering); - RELEASE(opt->csi); - } - RELEASE(opt); + if (opt->csi.registry) + RELEASE(opt->csi.registry); + if (opt->csi.ordering) + RELEASE(opt->csi.ordering); } -static CIDSysInfo * -get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt) +static int +get_cidsysinfo (CIDSysInfo *csi, const char *map_name, fontmap_opt *fmap_opt) { - CIDSysInfo *csi = NULL; + int has_csi = 0; int sup_idx; int i, csi_idx = -1, n, m; @@ -713,7 +523,7 @@ get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt) sup_idx = (sup_idx > SUP_IDX_MAX) ? SUP_IDX_MAX : sup_idx; if (!fmap_opt || !fmap_opt->charcoll) - return NULL; + return 0; /* First try alias for standard one. */ for (i = 0; CIDFont_stdcc_alias[i].name != NULL; i++) { @@ -721,7 +531,6 @@ get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt) if (!strncmp(fmap_opt->charcoll, CIDFont_stdcc_alias[i].name, n)) { csi_idx = CIDFont_stdcc_alias[i].index; - csi = NEW(1, CIDSysInfo); csi->registry = NEW(strlen(CIDFont_stdcc_def[csi_idx].registry)+1, char); strcpy(csi->registry, CIDFont_stdcc_def[csi_idx].registry); csi->ordering = NEW(strlen(CIDFont_stdcc_def[csi_idx].ordering)+1, char); @@ -731,31 +540,28 @@ get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt) } else { /* Use heighest supported value for current output PDF version. */ csi->supplement = CIDFont_stdcc_def[csi_idx].supplement[sup_idx]; } + has_csi = 1; break; } } - if (csi == NULL) { + if (!has_csi) { char *p, *q; p = (char *) fmap_opt->charcoll; - csi = NEW(1, CIDSysInfo); /* Full REGISTRY-ORDERING-SUPPLEMENT */ p = strchr(fmap_opt->charcoll, '-'); if (!p || p[1] == '\0') - ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", - CIDFONT_DEBUG_STR, fmap_opt->charcoll); + ERROR("String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", fmap_opt->charcoll); p++; q = strchr(p, '-'); if (!q || q[1] == '\0') - ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", - CIDFONT_DEBUG_STR, fmap_opt->charcoll); + ERROR("String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", fmap_opt->charcoll); q++; if (!isdigit((unsigned char)q[0])) - ERROR("%s: String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", - CIDFONT_DEBUG_STR, fmap_opt->charcoll); + ERROR("String can't be converted to REGISTRY-ORDERING-SUPPLEMENT: %s", fmap_opt->charcoll); n = strlen(fmap_opt->charcoll) - strlen(p) - 1; csi->registry = NEW(n+1, char); @@ -769,6 +575,8 @@ get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt) csi->supplement = (int) strtoul(q, NULL, 10); + has_csi = 1; + /* Check for standart character collections. */ for (i = 0; CIDFont_stdcc_def[i].ordering != NULL; i++) { if ((CIDFont_stdcc_def[i].registry && @@ -783,22 +591,19 @@ get_cidsysinfo (const char *map_name, fontmap_opt *fmap_opt) if (csi && csi_idx >= 0) { if (csi->supplement > CIDFont_stdcc_def[csi_idx].supplement[sup_idx] && (fmap_opt->flags & FONTMAP_OPT_NOEMBED)) { - WARN("%s: Heighest supplement number supported in PDF-%d.%d for %s-%s is %d.", - CIDFONT_DEBUG_STR, pdf_get_version_major(), pdf_get_version_minor(), + WARN("Heighest supplement number supported in PDF-%d.%d for %s-%s is %d.", + pdf_get_version_major(), pdf_get_version_minor(), csi->registry, csi->ordering, CIDFont_stdcc_def[csi_idx].supplement[sup_idx]); - WARN("%s: Some character may not shown without embedded font (--> %s).", - CIDFONT_DEBUG_STR, map_name); + WARN("Some character may not shown without embedded font (--> %s).", map_name); } } - return csi; + return has_csi; } void CIDFont_set_flags (int flags) { - CIDFont_type0_set_flags(flags); - CIDFont_type2_set_flags(flags); - cidoptflags |= flags; + opt_flags_cidfont |= flags; } diff --git a/Build/source/texk/dvipdfm-x/cid.h b/Build/source/texk/dvipdfm-x/cid.h index cf713dc3b4a..0e5457e0e54 100644 --- a/Build/source/texk/dvipdfm-x/cid.h +++ b/Build/source/texk/dvipdfm-x/cid.h @@ -21,59 +21,26 @@ #ifndef _CID_H_ #define _CID_H_ -/* CIDFont types */ -#define CIDFONT_TYPE0 1 -#define CIDFONT_TYPE2 2 - -typedef struct { - char *registry; - char *ordering; - int supplement; -} CIDSysInfo; +#include "pdffont.h" extern CIDSysInfo CSI_IDENTITY; extern CIDSysInfo CSI_UNICODE; -typedef struct CIDFont CIDFont; - -#if 0 -extern int CIDFont_require_version (void); -#endif +extern int opt_flags_cidfont; extern void CIDFont_set_flags (int flags); #define CIDFONT_FORCE_FIXEDPITCH (1 << 1) -#include "pdfobj.h" -#include "type0.h" - -/* FIXME */ -/* Converted from Type 1 */ -#define CIDFONT_FLAG_TYPE1 (1 << 8) -#define CIDFONT_FLAG_TYPE1C (1 << 9) -#define CIDFONT_FLAG_TRUETYPE (1 << 10) - -extern char *CIDFont_get_fontname (CIDFont *font); - -extern char *CIDFont_get_ident (CIDFont *font); /* FIXME */ -extern int CIDFont_get_opt_index (CIDFont *font); /* FIXME */ +extern char *CIDFont_get_usedchars (pdf_font *font); +extern char *CIDFont_get_usedchars_v (pdf_font *font); -extern int CIDFont_get_flag (CIDFont *font, int mask); - -extern int CIDFont_get_subtype (CIDFont *font); -extern int CIDFont_get_embedding (CIDFont *font); -extern pdf_obj *CIDFont_get_resource (CIDFont *font); -extern CIDSysInfo *CIDFont_get_CIDSysInfo (CIDFont *font); - -extern void CIDFont_attach_parent (CIDFont *font, int parent_id, int wmode); -extern int CIDFont_get_parent_id (CIDFont *font, int wmode); - -extern int CIDFont_is_BaseFont (CIDFont *font); -extern int CIDFont_is_ACCFont (CIDFont *font); -extern int CIDFont_is_UCSFont (CIDFont *font); +extern int CIDFont_is_ACCFont (pdf_font *font); +extern int CIDFont_is_UCSFont (pdf_font *font); #include "fontmap.h" -extern int CIDFont_cache_find (const char *map_name, CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt); -extern CIDFont *CIDFont_cache_get (int fnt_id); -extern void CIDFont_cache_close (void); +extern int pdf_font_cidfont_lookup_cache (pdf_font *fonts, int count, const char *map_name, CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt); + +extern int pdf_font_open_cidfont (pdf_font *font, const char *map_name, CIDSysInfo *cmap_csi, fontmap_opt *fmap_opt); +extern void pdf_font_load_cidfont (pdf_font *font); #endif /* _CID_H_ */ diff --git a/Build/source/texk/dvipdfm-x/cid_p.h b/Build/source/texk/dvipdfm-x/cid_p.h deleted file mode 100644 index d0701d4893e..00000000000 --- a/Build/source/texk/dvipdfm-x/cid_p.h +++ /dev/null @@ -1,68 +0,0 @@ -/* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002-2020 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team. - - Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> - - This program 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. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -*/ - -#ifndef _CID_P_H_ -#define _CID_P_H_ - -#define FONT_FLAG_NONE 0 -#define FONT_FLAG_BASEFONT (1 << 0) -#define FONT_FLAG_ACCFONT (1 << 1) -#define FONT_FLAG_UCSFONT (1 << 2) - -#include "fontmap.h" -#define FONT_STYLE_NONE FONTMAP_STYLE_NONE -#define FONT_STYLE_BOLD FONTMAP_STYLE_BOLD -#define FONT_STYLE_ITALIC FONTMAP_STYLE_ITALIC -#define FONT_STYLE_BOLDITALIC FONTMAP_STYLE_BOLDITALIC - -typedef struct -{ - char *name; /* Unused */ - CIDSysInfo *csi; - int index; - int style; - int embed; - int stemv; -} cid_opt; - -struct CIDFont -{ - char *ident; /* Map record entry */ - char *name; /* Fontname or filename */ - char *fontname; /* PostScript font name */ - /* - * CIDFont Specific - */ - int subtype; /* CIDFONT_TYPE0 or CIDFONT_TYPE2 */ - int flags; /* BASEFONT */ - int parent[2]; /* Parent type0 font of this CID-keyed font: H, V */ - CIDSysInfo *csi; /* Character collection */ - cid_opt *options; /* Options from map record */ - /* - * PDF Font Resource - */ - pdf_obj *indirect; /* Indirect reference to CIDFont dictionary */ - pdf_obj *fontdict; /* CIDFont dictionary */ - pdf_obj *descriptor; /* FontDescriptor */ -}; - -#endif /* _CID_P_H_ */ diff --git a/Build/source/texk/dvipdfm-x/cidtype0.c b/Build/source/texk/dvipdfm-x/cidtype0.c index cb47521de8c..d6c10fa1d19 100644 --- a/Build/source/texk/dvipdfm-x/cidtype0.c +++ b/Build/source/texk/dvipdfm-x/cidtype0.c @@ -57,7 +57,6 @@ #include "cmap.h" #include "type0.h" #include "cid.h" -#include "cid_p.h" #include "cidtype0.h" /* Type1 --> CFF CIDFont */ @@ -71,14 +70,6 @@ #include "cmap_write.h" #include "fontmap.h" -static int opt_flags = 0; - -void -CIDFont_type0_set_flags (int flags) -{ - opt_flags = flags; -} - /* * PDF Reference 3rd. ed., p.340, "Glyph Metrics in CID Fonts". */ @@ -87,16 +78,17 @@ CIDFont_type0_set_flags (int flags) #endif static void -add_CIDHMetrics (pdf_obj *fontdict, +add_CIDHMetrics (sfnt *sfont, pdf_obj *fontdict, unsigned char *CIDToGIDMap, unsigned short last_cid, struct tt_maxp_table *maxp, struct tt_head_table *head, struct tt_longMetrics *hmtx) { pdf_obj *w_array, *an_array = NULL; - int cid, start = 0, prev = 0; - double defaultAdvanceWidth; - int empty = 1; + int cid, start = 0, prev = 0; + double defaultAdvanceWidth; + int empty = 1; + (void) sfont; /* unsed */ defaultAdvanceWidth = PDFUNIT(hmtx[0].advance); /* * We alway use format: @@ -164,15 +156,15 @@ add_CIDVMetrics (sfnt *sfont, pdf_obj *fontdict, struct tt_head_table *head, struct tt_longMetrics *hmtx) { pdf_obj *w2_array, *an_array = NULL; - int cid; + int cid; #if 0 - int prev = 0, start = 0; + int prev = 0, start = 0; #endif struct tt_VORG_table *vorg; struct tt_vhea_table *vhea = NULL; struct tt_longMetrics *vmtx = NULL; - double defaultAdvanceHeight, defaultVertOriginY; - int empty = 1; + double defaultAdvanceHeight, defaultVertOriginY; + int empty = 1; /* * No accurate vertical metrics can be obtained by simple way if the @@ -323,7 +315,7 @@ add_CIDMetrics (sfnt *sfont, pdf_obj *fontdict, sfnt_locate_table(sfont, "hmtx"); hmtx = tt_read_longMetrics(sfont, maxp->numGlyphs, hhea->numOfLongHorMetrics, hhea->numOfExSideBearings); - add_CIDHMetrics(fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx); + add_CIDHMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx); if (need_vmetrics) add_CIDVMetrics(sfont, fontdict, CIDToGIDMap, last_cid, maxp, head, hmtx); @@ -339,12 +331,12 @@ add_CIDMetrics (sfnt *sfont, pdf_obj *fontdict, * Create an instance of embeddable font. */ static int -write_fontfile (CIDFont *font, cff_font *cffont) +write_fontfile (pdf_font *font, cff_font *cffont) { - cff_index *topdict, *fdarray, *private; + cff_index *topdict, *fdarray, *private; unsigned char *dest; - int destlen = 0, i, size; - int offset, topdict_offset, fdarray_offset; + int destlen = 0, i, size; + int offset, topdict_offset, fdarray_offset; /* DICT sizes (offset set to long int) */ topdict = cff_new_index(1); @@ -467,130 +459,8 @@ write_fontfile (CIDFont *font, cff_font *cffont) return destlen; } -static char * -CIDFont_type0_get_used_chars(CIDFont *font) { - int parent_id; - char *used_chars; - - if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 && - (parent_id = CIDFont_get_parent_id(font, 1)) < 0) - ERROR("No parent Type 0 font !"); - - used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); - if (!used_chars) - ERROR("Unexpected error: Font not actually used???"); - - return used_chars; -} - -typedef struct -{ - FILE *fp; - sfnt *sfont; - cff_font *cffont; -} CIDType0Info; - -typedef enum { - CID_OPEN_ERROR_NO_ERROR = 0, - CID_OPEN_ERROR_CANNOT_OPEN_FILE = -1, - CID_OPEN_ERROR_NOT_SFNT_FONT = -2, - CID_OPEN_ERROR_NO_CFF_TABLE = -3, - CID_OPEN_ERROR_CANNOT_OPEN_CFF_FONT = -4, - CID_OPEN_ERROR_NOT_CIDFONT = -5, - CID_OPEN_ERROR_IS_CIDFONT = -6, -} CIDType0Error; - -static void -CIDType0Error_Show (CIDType0Error error, const char *name) -{ - switch (error) { - case CID_OPEN_ERROR_CANNOT_OPEN_FILE: - ERROR("Could not open OpenType font file: %s", name); - case CID_OPEN_ERROR_NOT_SFNT_FONT: - ERROR("Could not open SFNT font file: %s", name); - case CID_OPEN_ERROR_NO_CFF_TABLE: - ERROR("Not a CFF/OpenType font: %s", name); - case CID_OPEN_ERROR_CANNOT_OPEN_CFF_FONT: - ERROR("Could not open CFF font: %s", name); - case CID_OPEN_ERROR_NOT_CIDFONT: - ERROR("Not a CIDFont: %s", name); - case CID_OPEN_ERROR_IS_CIDFONT: - ERROR("Should not be a CIDFont: %s", name); - default: - break; - } -} - -static void -CIDFontInfo_init (CIDType0Info *info) -{ - memset(info, 0, sizeof(CIDType0Info)); -} - -static void -CIDFontInfo_close (CIDType0Info *info) -{ - if (info->cffont) - cff_close(info->cffont); - - if (info->sfont) - sfnt_close(info->sfont); - - if (info->fp) - DPXFCLOSE(info->fp); - - CIDFontInfo_init(info); -} - -static CIDType0Error -CIDFont_type0_try_open (const char *name, - int index, - int required_cid, - CIDType0Info *info) -{ - ULONG offset = 0; - int is_cid; - - CIDFontInfo_init(info); - - info->fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT); - if (!info->fp) { - info->fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT); - if (!info->fp) - return CID_OPEN_ERROR_CANNOT_OPEN_FILE; - } - - info->sfont = sfnt_open(info->fp); - if (!info->sfont) - return CID_OPEN_ERROR_NOT_SFNT_FONT; - - if (info->sfont->type == SFNT_TYPE_TTC) - offset = ttc_read_offset(info->sfont, index); - - if ((info->sfont->type != SFNT_TYPE_TTC && - info->sfont->type != SFNT_TYPE_POSTSCRIPT) || - sfnt_read_table_directory(info->sfont, offset) < 0 || - (offset = sfnt_find_table_pos(info->sfont, "CFF ")) == 0) { - CIDFontInfo_close(info); - return CID_OPEN_ERROR_NO_CFF_TABLE; - } - - info->cffont = cff_open(info->sfont->stream, offset, 0); - if (!info->cffont) - return CID_OPEN_ERROR_CANNOT_OPEN_CFF_FONT; - - is_cid = info->cffont->flag & FONTTYPE_CIDFONT; - if (required_cid != is_cid) { - CIDFontInfo_close(info); - return required_cid ? CID_OPEN_ERROR_NOT_CIDFONT - : CID_OPEN_ERROR_IS_CIDFONT; - } - - return CID_OPEN_ERROR_NO_ERROR; -} - static void -CIDFont_type0_add_CIDSet(CIDFont *font, char *used_chars, card16 last_cid) { +CIDFont_type0_add_CIDSet (pdf_font *font, char *used_chars, card16 last_cid) { /* * CIDSet: * Length of CIDSet stream is not clear. Must be 8192 bytes long? @@ -604,55 +474,91 @@ CIDFont_type0_add_CIDSet(CIDFont *font, char *used_chars, card16 last_cid) { pdf_release_obj(cidset); } -void -CIDFont_type0_dofont (CIDFont *font) +int +CIDFont_type0_dofont (pdf_font *font) { - cff_font *cffont; - cff_index *charstrings, *idx; - cff_charsets *charset = NULL; - cff_fdselect *fdselect = NULL; - int charstring_len, max_len; - int destlen = 0; - int size, offset = 0; - card8 *data; - card16 num_glyphs = 0, gid; - int cid; - card16 cs_count, last_cid = 0; - int fd, prev_fd; - char *used_chars; + FILE *fp; + sfnt *sfont; + cff_font *cffont; + cff_index *charstrings, *idx; + cff_charsets *charset = NULL; + cff_fdselect *fdselect = NULL; + int charstring_len, max_len; + int destlen = 0; + int size, offset = 0; + card8 *data; + card16 num_glyphs = 0, gid; + int cid; + card16 cs_count, last_cid = 0; + int fd, prev_fd; + char *used_chars; unsigned char *CIDToGIDMap = NULL; - CIDType0Error error; - CIDType0Info info; ASSERT(font); - if (!font->indirect) - return; + if (!font->reference) + return 0; - pdf_add_dict(font->fontdict, + pdf_add_dict(font->resource, pdf_new_name("FontDescriptor"), pdf_ref_obj (font->descriptor)); - if (CIDFont_is_BaseFont(font)) - return; - else if (!CIDFont_get_embedding(font) && - (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) { + if (font->flags & PDF_FONT_FLAG_BASEFONT) { + return 0; + } else if (!font->cid.options.embed && + (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH)) { /* No metrics needed. */ - pdf_add_dict(font->fontdict, + pdf_add_dict(font->resource, pdf_new_name("DW"), pdf_new_number(1000.0)); - return; + return 0; } - used_chars = CIDFont_type0_get_used_chars(font); + used_chars = font->usedchars; - error = CIDFont_type0_try_open(font->ident, CIDFont_get_opt_index(font), - 1, &info); - if (error != CID_OPEN_ERROR_NO_ERROR) { - CIDType0Error_Show(error, font->ident); - return; + fp = DPXFOPEN(font->filename, DPX_RES_TYPE_OTFONT); + if (!fp) { + fp = DPXFOPEN(font->filename, DPX_RES_TYPE_TTFONT); + if (!fp) { + WARN("Could not open file: %s", font->filename); + return -1; + } + } + + sfont = sfnt_open(fp); + if (!sfont) { + WARN("Failed to read font file: %s", font->filename); + DPXFCLOSE(fp); + return -1; + } + + if (sfont->type == SFNT_TYPE_TTC) + offset = ttc_read_offset(sfont, font->index); + + if ((sfont->type != SFNT_TYPE_TTC && + sfont->type != SFNT_TYPE_POSTSCRIPT) || + sfnt_read_table_directory(sfont, offset) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + WARN("Not a CFF/OpenType font: %s", font->filename); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } + + cffont = cff_open(sfont->stream, offset, 0); + if (!cffont) { + WARN("Failed to read CFF font data: %s", font->filename); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } - cffont = info.cffont; + if (!(cffont->flag & FONTTYPE_CIDFONT)) { + WARN("Unexpected type (CIDFont expected): %s", font->filename); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } cff_read_charsets(cffont); @@ -672,7 +578,7 @@ CIDFont_type0_dofont (CIDFont *font) if (is_used_char2(used_chars, cid)) { gid = cff_charsets_lookup(cffont, (card16)cid); if (cid != 0 && gid == 0) { - WARN("Glyph for CID %u missing in font \"%s\".", (CID) cid, font->ident); + WARN("Glyph for CID %u missing in font \"%s\".", (CID) cid, font->filename); used_chars[cid/8] &= ~(1 << (7 - (cid % 8))); continue; } @@ -688,19 +594,20 @@ CIDFont_type0_dofont (CIDFont *font) * DW, W, DW2 and W2: * Those values are obtained from OpenType table (not TFM). */ - if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) { - pdf_add_dict(font->fontdict, + if (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH) { + pdf_add_dict(font->resource, pdf_new_name("DW"), pdf_new_number(1000.0)); } else { - add_CIDMetrics(info.sfont, font->fontdict, CIDToGIDMap, last_cid, - ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1)); + add_CIDMetrics(sfont, font->resource, CIDToGIDMap, last_cid, + font->cid.usedchars_v ? 1 : 0); } - if (!CIDFont_get_embedding(font)) { + if (!font->cid.options.embed) { RELEASE(CIDToGIDMap); - CIDFontInfo_close(&info); - - return; + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return 0; } /* @@ -719,7 +626,11 @@ CIDFont_type0_dofont (CIDFont *font) offset = cff_tell(cffont); if ((cs_count = idx->count) < 2) { - ERROR("No valid charstring data found."); + WARN("No valid charstring data found: %s", font->filename); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } /* New Charsets data */ @@ -753,8 +664,19 @@ CIDFont_type0_dofont (CIDFont *font) gid_org = (CIDToGIDMap[2*cid] << 8)|(CIDToGIDMap[2*cid+1]); if ((size = (idx->offset)[gid_org+1] - (idx->offset)[gid_org]) - > CS_STR_LEN_MAX) - ERROR("Charstring too long: gid=%u", gid_org); + > CS_STR_LEN_MAX) { + WARN("Charstring too long: %s (gid=%u)", font->filename, gid_org); + RELEASE(data); + RELEASE(charstrings); + RELEASE(fdselect); + RELEASE(charset); + cff_release_index(idx); + RELEASE(CIDToGIDMap); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } if (charstring_len + CS_STR_LEN_MAX >= max_len) { max_len = charstring_len + 2 * CS_STR_LEN_MAX; charstrings->data = RENEW(charstrings->data, max_len, card8); @@ -779,8 +701,19 @@ CIDFont_type0_dofont (CIDFont *font) } gid++; } - if (gid != num_glyphs) - ERROR("Unexpeced error: ?????"); + if (gid != num_glyphs) { + WARN("Unexpeced error: %s", font->filename); + RELEASE(data); + RELEASE(charstrings); + RELEASE(fdselect); + RELEASE(charset); + cff_release_index(idx); + RELEASE(CIDToGIDMap); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } RELEASE(data); cff_release_index(idx); @@ -814,117 +747,158 @@ CIDFont_type0_dofont (CIDFont *font) destlen = write_fontfile(font, cffont); - CIDFontInfo_close(&info); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); if (dpx_conf.verbose_level > 1) MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, destlen); - CIDFont_type0_add_CIDSet(font, used_chars, last_cid); + if (pdf_check_version(2, 0) >= 0) { + CIDFont_type0_add_CIDSet(font, used_chars, last_cid); + } + + return 0; } int -CIDFont_type0_open (CIDFont *font, const char *name, - CIDSysInfo *cmap_csi, cid_opt *opt, - int expected_flag) +CIDFont_type0_open_from_t1 (pdf_font *font, const char *name, int index, cid_opt *opt) { - CIDSysInfo *csi; + CIDSysInfo csi; char *fontname; - sfnt *sfont = NULL; cff_font *cffont; FILE *fp = NULL; - ULONG offset = 0; - int is_cid_font = 0; - int expect_cid_font = expected_flag == 0; - int expect_type1_font = expected_flag & CIDFONT_FLAG_TYPE1; - dpx_res_type expect_file_type = - expect_type1_font ? DPX_RES_TYPE_T1FONT : DPX_RES_TYPE_OTFONT; ASSERT(font); - if (expect_type1_font) { - if (cmap_csi && - (strcmp(cmap_csi->registry, "Adobe") != 0 || - strcmp(cmap_csi->ordering, "Identity") != 0)) { - return -1; - } + fp = DPXFOPEN(name, DPX_RES_TYPE_T1FONT); + if (!fp) + return -1; + + cffont = t1_load_font(NULL, 1, fp); + if (!cffont) { + DPXFCLOSE(fp); + return -1; } - fp = DPXFOPEN(name, expect_file_type); - if (!expect_type1_font) { - if (!fp) { - fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT); - if (!fp) return -1; - } + { + char *shortname; + int fontname_len = 8; - sfont = sfnt_open(fp); - if (!sfont) { - ERROR("Not a CFF/OpenType font: %s", name); - } + shortname = cff_get_name(cffont); + if (!shortname) { + WARN("No valid FontName found: %s", name); + cff_close(cffont); + DPXFCLOSE(fp); + } + /* + * Mangled name requires more 7 bytes. + */ + fontname = NEW(strlen(shortname) + fontname_len, char); + memset(fontname, 0, strlen(shortname) + fontname_len); + strcpy(fontname, shortname); + RELEASE(shortname); + } - if (sfont->type == SFNT_TYPE_TTC) - offset = ttc_read_offset(sfont, opt->index); + csi.registry = NEW(strlen("Adobe") + 1, char); + strcpy(csi.registry, "Adobe"); + csi.ordering = NEW(strlen("Identity") + 1, char); + strcpy(csi.ordering, "Identity"); + csi.supplement = 0; + if (opt->style != FONT_STYLE_NONE) { + WARN(",Bold, ,Italic, ... not supported for this type of font..."); + opt->style = FONT_STYLE_NONE; + } - if ((sfont->type != SFNT_TYPE_TTC && sfont->type != SFNT_TYPE_POSTSCRIPT) || - sfnt_read_table_directory(sfont, offset) < 0 || - (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { - sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); - return -1; - } + font->fontname = fontname; + font->subtype = PDF_FONT_FONTTYPE_CIDTYPE0; + font->cid.csi = csi; + font->flags |= CIDFONT_FLAG_TYPE1; - cffont = cff_open(sfont->stream, offset, 0); - if (!cffont) { - ERROR("Cannot read CFF font data"); - } + font->resource = pdf_new_dict(); + pdf_add_dict(font->resource, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->resource, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType0")); - is_cid_font = cffont->flag & FONTTYPE_CIDFONT; - if (expect_cid_font != is_cid_font) { - cff_close(cffont); - sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); - return -1; - } - } else { - if (!fp) - return -1; + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; - cffont = t1_load_font(NULL, 1, fp); - if (!cffont) { - DPXFCLOSE(fp); - return -1; - } + font->descriptor = pdf_new_dict(); + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->resource, + pdf_new_name("BaseFont"), + pdf_new_name(fontname)); + { + pdf_obj *csi_dict = pdf_new_dict(); + pdf_add_dict(csi_dict, + pdf_new_name("Registry"), + pdf_new_string(csi.registry, strlen(csi.registry))); + pdf_add_dict(csi_dict, + pdf_new_name("Ordering"), + pdf_new_string(csi.ordering, strlen(csi.ordering))); + pdf_add_dict(csi_dict, + pdf_new_name("Supplement"), + pdf_new_number(csi.supplement)); + pdf_add_dict(font->resource, pdf_new_name("CIDSystemInfo"), csi_dict); + } + + return 0; +} + +int +CIDFont_type0_open (pdf_font *font, const char *name, int index, cid_opt *opt) +{ + CIDSysInfo csi; + char *fontname; + sfnt *sfont = NULL; + cff_font *cffont; + FILE *fp = NULL; + ULONG offset = 0; + + ASSERT(font); + + fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT); + if (!fp) { + fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT); + if (!fp) return -1; + } + + sfont = sfnt_open(fp); + if (!sfont) { DPXFCLOSE(fp); + return -1; } - csi = NEW(1, CIDSysInfo); - if (is_cid_font) { - csi->registry = - cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 0)); - csi->ordering = - cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 1)); - csi->supplement = (int)cff_dict_get(cffont->topdict, "ROS", 2); - } else { - csi->registry = NEW(strlen("Adobe") + 1, char); - strcpy(csi->registry, "Adobe"); - csi->ordering = NEW(strlen("Identity") + 1, char); - strcpy(csi->ordering, "Identity"); - csi->supplement = 0; - } - - if (!expect_type1_font && cmap_csi) { - if (strcmp(csi->registry, cmap_csi->registry) != 0 || - strcmp(csi->ordering, cmap_csi->ordering) != 0) { - MESG("\nCharacter collection mismatched:\n"); - MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement); - MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement); - ERROR("Inconsistent CMap specified for this font."); - } - if (csi->supplement < cmap_csi->supplement) { - WARN("CMap have higher supplement number."); - WARN("Some characters may not be displayed or printed."); - } + if (sfont->type == SFNT_TYPE_TTC) + offset = ttc_read_offset(sfont, index); + + if ((sfont->type != SFNT_TYPE_TTC && sfont->type != SFNT_TYPE_POSTSCRIPT) || + sfnt_read_table_directory(sfont, offset) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } + + cffont = cff_open(sfont->stream, offset, 0); + if (!cffont) { + WARN("Cannot read CFF font data"); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } + + if (!(cffont->flag & FONTTYPE_CIDFONT)) { + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } { @@ -932,26 +906,33 @@ CIDFont_type0_open (CIDFont *font, const char *name, int fontname_len = 8; shortname = cff_get_name(cffont); - if (!shortname) - ERROR("No valid FontName found."); + if (!shortname) { + WARN("No valid FontName found."); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } /* * Mangled name requires more 7 bytes. * Style requires more 11 bytes. */ - if (is_cid_font) - fontname_len += 11; + fontname_len += 11; fontname = NEW(strlen(shortname) + fontname_len, char); memset(fontname, 0, strlen(shortname) + fontname_len); strcpy(fontname, shortname); RELEASE(shortname); } + csi.registry = cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 0)); + csi.ordering = cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 1)); + csi.supplement = (int)cff_dict_get(cffont->topdict, "ROS", 2); + cff_close(cffont); - if (is_cid_font) { - if (opt->embed && opt->style != FONT_STYLE_NONE) { - WARN("Embedding disabled due to style option for %s.", name); - opt->embed = 0; - } + if (opt->embed && opt->style != FONT_STYLE_NONE) { + WARN("Embedding disabled due to style option for %s.", name); + opt->embed = 0; + switch (opt->style) { case FONT_STYLE_BOLD: strcat(fontname, ",Bold"); @@ -963,112 +944,282 @@ CIDFont_type0_open (CIDFont *font, const char *name, strcat(fontname, ",BoldItalic"); break; } - } else if (expect_type1_font) { - if (opt->style != FONT_STYLE_NONE) { - WARN(",Bold, ,Italic, ... not supported for this type of font..."); - opt->style = FONT_STYLE_NONE; - } - } else { - opt->embed = 1; + } + + /* getting font info. from TrueType tables */ + font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name); + if (!font->descriptor) { + WARN("Could not obtain necessary font info: %s", name); + RELEASE(fontname); + RELEASE(csi.registry); + RELEASE(csi.ordering); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } font->fontname = fontname; - font->subtype = CIDFONT_TYPE0; - font->csi = csi; - font->flags |= expected_flag; + font->subtype = PDF_FONT_FONTTYPE_CIDTYPE0; + font->cid.csi = csi; - font->fontdict = pdf_new_dict(); - pdf_add_dict(font->fontdict, + font->resource = pdf_new_dict(); + pdf_add_dict(font->resource, pdf_new_name("Type"), pdf_new_name("Font")); - pdf_add_dict(font->fontdict, + pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("CIDFontType0")); - if (expect_type1_font || opt->embed) { + if (opt->embed) { memmove(fontname + 7, fontname, strlen(fontname) + 1); pdf_font_make_uniqueTag(fontname); fontname[6] = '+'; } - if (expect_type1_font) { - font->descriptor = pdf_new_dict(); - } else { - /* getting font info. from TrueType tables */ - if ((font->descriptor - = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name)) == NULL) - ERROR("Could not obtain necessary font info."); - } - pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(fontname)); - pdf_add_dict(font->fontdict, + pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(fontname)); { pdf_obj *csi_dict = pdf_new_dict(); pdf_add_dict(csi_dict, pdf_new_name("Registry"), - pdf_new_string(csi->registry, strlen(csi->registry))); + pdf_new_string(csi.registry, strlen(csi.registry))); pdf_add_dict(csi_dict, pdf_new_name("Ordering"), - pdf_new_string(csi->ordering, strlen(csi->ordering))); + pdf_new_string(csi.ordering, strlen(csi.ordering))); pdf_add_dict(csi_dict, pdf_new_name("Supplement"), - pdf_new_number(csi->supplement)); - pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict); + pdf_new_number(csi.supplement)); + pdf_add_dict(font->resource, pdf_new_name("CIDSystemInfo"), csi_dict); + } + pdf_add_dict(font->resource, + pdf_new_name("DW"), + pdf_new_number(1000)); /* not sure */ + + sfnt_close(sfont); + DPXFCLOSE(fp); + + return 0; +} + +int +CIDFont_type0_open_from_t1c (pdf_font *font, const char *name, int index, cid_opt *opt) +{ + CIDSysInfo csi; + char *fontname; + sfnt *sfont = NULL; + cff_font *cffont; + FILE *fp = NULL; + ULONG offset = 0; + + ASSERT(font); + + fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT); + if (!fp) { + fp = DPXFOPEN(name, DPX_RES_TYPE_TTFONT); + if (!fp) return -1; + } + + sfont = sfnt_open(fp); + if (!sfont) { + WARN("Not a CFF/OpenType font: %s", name); + DPXFCLOSE(fp); + } + + if (sfont->type == SFNT_TYPE_TTC) + offset = ttc_read_offset(sfont, index); + + if ((sfont->type != SFNT_TYPE_TTC && sfont->type != SFNT_TYPE_POSTSCRIPT) || + sfnt_read_table_directory(sfont, offset) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } - if (is_cid_font) { - pdf_add_dict(font->fontdict, - pdf_new_name("DW"), - pdf_new_number(1000)); /* not sure */ + + cffont = cff_open(sfont->stream, offset, 0); + if (!cffont) { + WARN("Cannot read CFF font data: %s", name); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } - if (!expect_type1_font) { + if (cffont->flag & FONTTYPE_CIDFONT) { + cff_close(cffont); sfnt_close(sfont); - if (fp) + DPXFCLOSE(fp); + return -1; + } + + { + char *shortname; + int fontname_len = 8; + + shortname = cff_get_name(cffont); + if (!shortname) { + WARN("No valid FontName found: %s", name); + cff_close(cffont); + sfnt_close(sfont); DPXFCLOSE(fp); + return -1; + } + /* + * Mangled name requires more 7 bytes. + */ + fontname = NEW(strlen(shortname) + fontname_len, char); + memset(fontname, 0, strlen(shortname) + fontname_len); + strcpy(fontname, shortname); + RELEASE(shortname); + } + csi.registry = NEW(strlen("Adobe") + 1, char); + strcpy(csi.registry, "Adobe"); + csi.ordering = NEW(strlen("Identity") + 1, char); + strcpy(csi.ordering, "Identity"); + csi.supplement = 0; + + cff_close(cffont); + + opt->embed = 1; + /* getting font info. from TrueType tables */ + font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name); + if (!font->descriptor) { + WARN("Could not obtain necessary font info: %s", name); + RELEASE(fontname); + RELEASE(csi.registry); + RELEASE(csi.ordering); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } else if (!opt->embed) { + WARN("Can’t embed font due to font license: %s", name); + RELEASE(fontname); + RELEASE(csi.registry); + RELEASE(csi.ordering); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } + + font->fontname = fontname; + font->subtype = PDF_FONT_FONTTYPE_CIDTYPE0; + font->cid.csi = csi; + font->flags |= CIDFONT_FLAG_TYPE1C; + + font->resource = pdf_new_dict(); + pdf_add_dict(font->resource, + pdf_new_name("Type"), + pdf_new_name("Font")); + pdf_add_dict(font->resource, + pdf_new_name("Subtype"), + pdf_new_name("CIDFontType0")); + + if (opt->embed) { + memmove(fontname + 7, fontname, strlen(fontname) + 1); + pdf_font_make_uniqueTag(fontname); + fontname[6] = '+'; } + pdf_add_dict(font->descriptor, + pdf_new_name("FontName"), + pdf_new_name(fontname)); + pdf_add_dict(font->resource, + pdf_new_name("BaseFont"), + pdf_new_name(fontname)); + { + pdf_obj *csi_dict = pdf_new_dict(); + pdf_add_dict(csi_dict, + pdf_new_name("Registry"), + pdf_new_string(csi.registry, strlen(csi.registry))); + pdf_add_dict(csi_dict, + pdf_new_name("Ordering"), + pdf_new_string(csi.ordering, strlen(csi.ordering))); + pdf_add_dict(csi_dict, + pdf_new_name("Supplement"), + pdf_new_number(csi.supplement)); + pdf_add_dict(font->resource, pdf_new_name("CIDSystemInfo"), csi_dict); + } + + sfnt_close(sfont); + DPXFCLOSE(fp); + return 0; } -void -CIDFont_type0_t1cdofont (CIDFont *font) +int +CIDFont_type0_t1cdofont (pdf_font *font) { + FILE *fp; + sfnt *sfont; cff_font *cffont; cff_index *charstrings, *idx; - int charstring_len, max_len; - int destlen = 0; - int size, offset = 0; - card8 *data; - card16 num_glyphs, gid, last_cid; - int i, cid; - char *used_chars; - double default_width, nominal_width; - CIDType0Error error; - CIDType0Info info; + int charstring_len, max_len; + int destlen = 0; + int size, offset = 0; + card8 *data; + card16 num_glyphs, gid, last_cid; + int i, cid; + char *used_chars; + double default_width, nominal_width; ASSERT(font); - if (!font->indirect) - return; + if (!font->reference) + return 0; - pdf_add_dict(font->fontdict, + pdf_add_dict(font->resource, pdf_new_name("FontDescriptor"), pdf_ref_obj (font->descriptor)); - used_chars = CIDFont_type0_get_used_chars(font); + used_chars = font->usedchars; - error = CIDFont_type0_try_open(font->ident, CIDFont_get_opt_index(font), - 0, &info); - if (error != CID_OPEN_ERROR_NO_ERROR) { - CIDType0Error_Show(error, font->ident); - return; + fp = DPXFOPEN(font->filename, DPX_RES_TYPE_OTFONT); + if (!fp) { + fp = DPXFOPEN(font->filename, DPX_RES_TYPE_TTFONT); + if (!fp) { + WARN("Could not open file: %s", font->filename); + return -1; + } + } + + sfont = sfnt_open(fp); + if (!sfont) { + WARN("Failed to read font data: %s", font->filename); + DPXFCLOSE(fp); + return -1; + } + + if (sfont->type == SFNT_TYPE_TTC) + offset = ttc_read_offset(sfont, font->index); + + if ((sfont->type != SFNT_TYPE_TTC && + sfont->type != SFNT_TYPE_POSTSCRIPT) || + sfnt_read_table_directory(sfont, offset) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + WARN("Not a CFF/OpenType font: %s", font->filename); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } + + cffont = cff_open(sfont->stream, offset, 0); + if (!cffont) { + WARN("Failed to read CFF font data: %s", font->filename); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } - cffont = info.cffont; + if (cffont->flag & FONTTYPE_CIDFONT) { + WARN("Unxpected type (CIDFont) found: %s", font->filename); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } cff_read_private(cffont); cff_read_subrs (cffont); @@ -1166,8 +1317,14 @@ CIDFont_type0_t1cdofont (CIDFont *font) /* offset is now absolute offset ... bad */ offset = cff_tell(cffont); - if (idx->count < 2) - ERROR("No valid charstring data found."); + if (idx->count < 2) { + WARN("No valid charstring data found: %s", font->filename); + cff_release_index(idx); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } /* New CharStrings INDEX */ charstrings = cff_new_index((card16)(num_glyphs+1)); @@ -1182,8 +1339,16 @@ CIDFont_type0_t1cdofont (CIDFont *font) continue; if ((size = (idx->offset)[cid+1] - (idx->offset)[cid]) - > CS_STR_LEN_MAX) - ERROR("Charstring too long: gid=%u", cid); + > CS_STR_LEN_MAX) { + WARN("Charstring too long:%s (gid=%u)", font->filename, cid); + RELEASE(data); + cff_release_index(charstrings); + cff_release_index(idx); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } if (charstring_len + CS_STR_LEN_MAX >= max_len) { max_len = charstring_len + 2 * CS_STR_LEN_MAX; charstrings->data = RENEW(charstrings->data, max_len, card8); @@ -1198,8 +1363,16 @@ CIDFont_type0_t1cdofont (CIDFont *font) default_width, nominal_width, NULL); gid++; } - if (gid != num_glyphs) - ERROR("Unexpeced error: ?????"); + if (gid != num_glyphs) { + WARN("Unexpeced error: %s", font->filename); + RELEASE(data); + cff_release_index(charstrings); + cff_release_index(idx); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } RELEASE(data); cff_release_index(idx); @@ -1253,26 +1426,32 @@ CIDFont_type0_t1cdofont (CIDFont *font) CIDToGIDMap[2*cid+1] = cid & 0xff; } } - add_CIDMetrics(info.sfont, font->fontdict, CIDToGIDMap, last_cid, - ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1)); + add_CIDMetrics(sfont, font->resource, CIDToGIDMap, last_cid, + font->cid.usedchars_v ? 1 : 0); RELEASE(CIDToGIDMap); } - CIDFontInfo_close(&info); + cff_close(cffont); + sfnt_close(sfont); + DPXFCLOSE(fp); if (dpx_conf.verbose_level > 1) MESG("[%u glyphs][%ld bytes]", num_glyphs, destlen); - CIDFont_type0_add_CIDSet(font, used_chars, last_cid); + if (pdf_check_version(2, 0) >= 0) { + CIDFont_type0_add_CIDSet(font, used_chars, last_cid); + } + + return 0; } static int load_base_CMap (const char *font_name, int wmode, cff_font *cffont) { - int cmap_id = -1; - CMap *cmap; - char *cmap_name; - card16 gid; + int cmap_id = -1; + CMap *cmap; + char *cmap_name; + card16 gid; unsigned char range_min[4] = {0x00, 0x00, 0x00, 0x00}; unsigned char range_max[4] = {0x7f, 0xff, 0xff, 0xff}; @@ -1384,7 +1563,7 @@ t1_load_UnicodeCMap (const char *font_name, cff_close(cffont); if (cmap_id < 0) { - ERROR("Failed to create Unicode charmap for font \"%s\".", font_name); + WARN("Failed to create Unicode charmap for font \"%s\".", font_name); return -1; } @@ -1404,15 +1583,15 @@ static pdf_obj * create_ToUnicode_stream (cff_font *cffont, const char *font_name, const char *used_glyphs) { - pdf_obj *stream = NULL; - CMap *cmap; - CID cid; - card16 gid; - int glyph_count, total_fail_count; - char *cmap_name; + pdf_obj *stream = NULL; + CMap *cmap; + CID cid; + card16 gid; + int glyph_count, total_fail_count; + char *cmap_name; #define WBUF_SIZE 1024 - unsigned char wbuf[WBUF_SIZE]; - unsigned char *p, *endptr; + unsigned char wbuf[WBUF_SIZE]; + unsigned char *p, *endptr; static unsigned char range_min[2] = {0x00, 0x00}; static unsigned char range_max[2] = {0xff, 0xff}; @@ -1438,14 +1617,14 @@ create_ToUnicode_stream (cff_font *cffont, endptr = wbuf + WBUF_SIZE; for (cid = 1; cid < cffont->num_glyphs; cid++) { /* Skip .notdef */ if (is_used_char2(used_glyphs, cid)) { - char *glyph; - int32_t len; - int fail_count; + char *glyph; + int32_t len; + int fail_count; wbuf[0] = (cid >> 8) & 0xff; wbuf[1] = (cid & 0xff); - p = wbuf + 2; + p = wbuf + 2; gid = cff_charsets_lookup_inverse(cffont, cid); if (gid == 0) continue; @@ -1476,6 +1655,36 @@ create_ToUnicode_stream (cff_font *cffont, return stream; } +pdf_obj * +CIDFont_type0_t1create_ToUnicode_stream (const char *filename, const char *fontname, const char *used_chars) +{ + pdf_obj *ref = NULL; + pdf_obj *tounicode; + cff_font *cffont; + FILE *fp; + + ASSERT(filename); + ASSERT(fontname); + ASSERT(used_chars); + + fp = DPXFOPEN(filename, DPX_RES_TYPE_T1FONT); + if (!fp) { + return NULL; + } + + cffont = t1_load_font(NULL, 1, fp); + if (cffont) { + tounicode = create_ToUnicode_stream(cffont, fontname, used_chars); + if (tounicode) { + ref = pdf_ref_obj(tounicode); + pdf_release_obj(tounicode); + } + } + DPXFCLOSE(fp); + + return ref; +} + /* Duplicate from type1.c */ #define TYPE1_NAME_LEN_MAX 127 @@ -1489,9 +1698,8 @@ create_ToUnicode_stream (cff_font *cffont, #define FONT_FLAG_SMALLCAP (1 << 17) /* Small-cap font */ #define FONT_FLAG_FORCEBOLD (1 << 18) /* Force bold at small text sizes */ -/* pdf_font --> CIDFont */ static void -get_font_attr (CIDFont *font, cff_font *cffont) +get_font_attr (pdf_font *font, cff_font *cffont) { double capheight, ascent, descent; double italicangle, stemv; @@ -1630,7 +1838,7 @@ get_font_attr (CIDFont *font, cff_font *cffont) } static void -add_metrics (CIDFont *font, cff_font *cffont, +add_metrics (pdf_font *font, cff_font *cffont, unsigned char *CIDToGIDMap, double *widths, double default_width, CID last_cid) { @@ -1638,7 +1846,7 @@ add_metrics (CIDFont *font, cff_font *cffont, double val; card16 cid, gid; char *used_chars; - int i, parent_id; + int i; /* * The original FontBBox of the font is preserved, instead @@ -1647,23 +1855,17 @@ add_metrics (CIDFont *font, cff_font *cffont, * much as possible. */ if (!cff_dict_known(cffont->topdict, "FontBBox")) { - ERROR("No FontBBox?"); - } - tmp = pdf_new_array(); - for (i = 0; i < 4; i++) { - val = cff_dict_get(cffont->topdict, "FontBBox", i); - pdf_add_array(tmp, pdf_new_number(ROUND(val, 1.0))); + WARN("No FontBBox found: %s", font->filename); + } else { + tmp = pdf_new_array(); + for (i = 0; i < 4; i++) { + val = cff_dict_get(cffont->topdict, "FontBBox", i); + pdf_add_array(tmp, pdf_new_number(ROUND(val, 1.0))); + } + pdf_add_dict(font->descriptor, pdf_new_name("FontBBox"), tmp); } - pdf_add_dict(font->descriptor, pdf_new_name("FontBBox"), tmp); - if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 && - (parent_id = CIDFont_get_parent_id(font, 1)) < 0) - ERROR("No parent Type 0 font !"); - - used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); - if (!used_chars) { - ERROR("Unexpected error: Font not actually used???"); - } + used_chars = font->usedchars; /* FIXME: * This writes "CID CID width". @@ -1681,83 +1883,54 @@ add_metrics (CIDFont *font, cff_font *cffont, } } } - pdf_add_dict(font->fontdict, + pdf_add_dict(font->resource, pdf_new_name("DW"), pdf_new_number(default_width)); if (pdf_array_length(tmp) > 0) { - pdf_add_dict(font->fontdict, pdf_new_name("W"), pdf_ref_obj(tmp)); + pdf_add_dict(font->resource, pdf_new_name("W"), pdf_ref_obj(tmp)); } pdf_release_obj(tmp); } -void -CIDFont_type0_t1dofont (CIDFont *font) +int +CIDFont_type0_t1dofont (pdf_font *font) { - cff_font *cffont; - double defaultwidth, nominalwidth; - int num_glyphs = 0; - FILE *fp; - int i, offset; - char *used_chars = NULL; - card16 last_cid, gid, cid; + cff_font *cffont; + double defaultwidth, nominalwidth; + int num_glyphs = 0; + FILE *fp; + int i, offset; + char *used_chars = NULL; + card16 last_cid, gid, cid; unsigned char *CIDToGIDMap; ASSERT(font); - if (!font->indirect) { - return; + if (!font->reference) { + return 0; } - pdf_add_dict(font->fontdict, + pdf_add_dict(font->resource, pdf_new_name("FontDescriptor"), pdf_ref_obj (font->descriptor)); - fp = DPXFOPEN(font->ident, DPX_RES_TYPE_T1FONT); + fp = DPXFOPEN(font->filename, DPX_RES_TYPE_T1FONT); if (!fp) { - ERROR("Type1: Could not open Type1 font."); + WARN("Type1: Could not open Type1 font."); + return -1; } cffont = t1_load_font(NULL, 0, fp); - if (!cffont) - ERROR("Could not read Type 1 font..."); + if (!cffont) { + WARN("Could not read Type 1 font..."); + DPXFCLOSE(fp); + return -1; + } DPXFCLOSE(fp); - if (!font->fontname) - ERROR("Fontname undefined..."); - - { - Type0Font *hparent, *vparent; - pdf_obj *tounicode; - int vparent_id, hparent_id; - - hparent_id = CIDFont_get_parent_id(font, 0); - vparent_id = CIDFont_get_parent_id(font, 1); - if (hparent_id < 0 && vparent_id < 0) - ERROR("No parent Type 0 font !"); - - /* usedchars is same for h and v */ - if (hparent_id < 0) - hparent = NULL; - else { - hparent = Type0Font_cache_get(hparent_id); - used_chars = Type0Font_get_usedchars(hparent); - } - if (vparent_id < 0) - vparent = NULL; - else { - vparent = Type0Font_cache_get(vparent_id); - used_chars = Type0Font_get_usedchars(vparent); - } - if (!used_chars) - ERROR("Unexpected error: Font not actually used???"); + ASSERT(font->fontname); + ASSERT(font->usedchars); - tounicode = create_ToUnicode_stream(cffont, font->fontname, used_chars); - - if (hparent) - Type0Font_set_ToUnicode(hparent, pdf_ref_obj(tounicode)); - if (vparent) - Type0Font_set_ToUnicode(vparent, pdf_ref_obj(tounicode)); - pdf_release_obj(tounicode); - } + used_chars = font->usedchars; cff_set_name(cffont, font->fontname); @@ -1877,7 +2050,12 @@ CIDFont_type0_t1dofont (CIDFont *font) cffont->subrs[0], defaultwidth, nominalwidth, &gm); cstring->offset[gid+1] = offset + 1; if (gm.use_seac) { - ERROR("This font using the \"seac\" command for accented characters..."); + WARN("The \"seac\" command for an accented character found: %s", font->filename); + RELEASE(widths); + cff_release_index(cstring); + RELEASE(CIDToGIDMap); + cff_close(cffont); + return -1; } widths[gid] = gm.wx; if (gm.wx >= 0.0 && gm.wx <= 1000.0) { @@ -1929,5 +2107,9 @@ CIDFont_type0_t1dofont (CIDFont *font) cff_close(cffont); - CIDFont_type0_add_CIDSet(font, used_chars, last_cid); + if (pdf_check_version(2, 0) >= 0) { + CIDFont_type0_add_CIDSet(font, used_chars, last_cid); + } + + return 0; } diff --git a/Build/source/texk/dvipdfm-x/cidtype0.h b/Build/source/texk/dvipdfm-x/cidtype0.h index 513a90c6013..c4faa24486c 100644 --- a/Build/source/texk/dvipdfm-x/cidtype0.h +++ b/Build/source/texk/dvipdfm-x/cidtype0.h @@ -21,20 +21,18 @@ #ifndef _CIDTYPE0_H_ #define _CIDTYPE0_H_ -#include "cid.h" -#include "cid_p.h" -#include "fontmap.h" +#include "pdffont.h" -extern void CIDFont_type0_set_flags (int flags); - -extern int CIDFont_type0_open (CIDFont *font, const char *name, - CIDSysInfo *cmap_csi, cid_opt *opt, - int expected_flag); -extern void CIDFont_type0_dofont (CIDFont *font); +extern int CIDFont_type0_open (pdf_font *font, const char *name, int index, cid_opt *opt); +extern int CIDFont_type0_dofont (pdf_font *font); /* Type1 --> CFF CIDFont */ extern int t1_load_UnicodeCMap (const char *font_name, const char *otl_tags, int wmode); -extern void CIDFont_type0_t1dofont (CIDFont *font); -extern void CIDFont_type0_t1cdofont (CIDFont *font); +extern int CIDFont_type0_open_from_t1 (pdf_font *font, const char *name, int index, cid_opt *opt); +extern int CIDFont_type0_open_from_t1c (pdf_font *font, const char *name, int index, cid_opt *opt); +extern int CIDFont_type0_t1dofont (pdf_font *font); +extern int CIDFont_type0_t1cdofont (pdf_font *font); + +extern pdf_obj *CIDFont_type0_t1create_ToUnicode_stream (const char *filename, const char *fontname, const char *used_chars); #endif /* _CIDTYPE0_H_ */ diff --git a/Build/source/texk/dvipdfm-x/cidtype2.c b/Build/source/texk/dvipdfm-x/cidtype2.c index 8ee698b3991..f6913d1673f 100644 --- a/Build/source/texk/dvipdfm-x/cidtype2.c +++ b/Build/source/texk/dvipdfm-x/cidtype2.c @@ -55,17 +55,8 @@ #include "cmap.h" #include "type0.h" #include "cid.h" -#include "cid_p.h" #include "cidtype2.h" -static int opt_flags = 0; - -void -CIDFont_type2_set_flags (int32_t flags) -{ - opt_flags = flags; -} - /* * PDF viewer applications use following tables (CIDFontType 2) * @@ -98,7 +89,7 @@ static struct {"prep", 0}, {NULL, 0} }; -static void +static int validate_name (char *fontname, int len) { int i, count; @@ -137,8 +128,11 @@ validate_name (char *fontname, int len) } if (len < 1) { - ERROR("No valid character found in fontname string."); + WARN("No valid character found in fontname string."); + return -1; } + + return 0; } /* @@ -179,12 +173,10 @@ find_tocode_cmap (const char *reg, const char *ord, int select) const char *append; if (!reg || !ord || - select < 0 || select > KNOWN_ENCODINGS_MAX) - ERROR("Character set unknown."); - - if (!strcmp(ord, "UCS") && - select <= WIN_UCS_INDEX_MAX) + select < 0 || select > KNOWN_ENCODINGS_MAX) { + WARN("Character set unknown."); return NULL; + } for (i = 0; cmap_id < 0 && i < 5; i++) { append = known_encodings[select].pdfnames[i]; @@ -205,7 +197,7 @@ find_tocode_cmap (const char *reg, const char *ord, int select) MESG(" %s-%s-%s", reg, ord, append); } WARN("Please check if this file exists."); - ERROR("Cannot continue..."); + return NULL; } return CMap_cache_get(cmap_id); @@ -220,7 +212,7 @@ find_tocode_cmap (const char *reg, const char *ord, int select) static void add_TTCIDHMetrics (pdf_obj *fontdict, struct tt_glyphs *g, - char *used_chars, unsigned char *cidtogidmap, unsigned short last_cid) + char *used_chars, unsigned char *cidtogidmap, unsigned short last_cid) { int cid, start = 0, prev = 0; pdf_obj *w_array, *an_array = NULL; @@ -246,23 +238,23 @@ add_TTCIDHMetrics (pdf_obj *fontdict, struct tt_glyphs *g, width = PDFUNIT((g->gd)[idx].advw); if (width == dw) { if (an_array) { - pdf_add_array(w_array, pdf_new_number(start)); - pdf_add_array(w_array, an_array); - an_array = NULL; - empty = 0; + pdf_add_array(w_array, pdf_new_number(start)); + pdf_add_array(w_array, an_array); + an_array = NULL; + empty = 0; } } else { if (cid != prev + 1) { - if (an_array) { - pdf_add_array(w_array, pdf_new_number(start)); - pdf_add_array(w_array, an_array); - an_array = NULL; - empty = 0; - } + if (an_array) { + pdf_add_array(w_array, pdf_new_number(start)); + pdf_add_array(w_array, an_array); + an_array = NULL; + empty = 0; + } } if (an_array == NULL) { - an_array = pdf_new_array(); - start = cid; + an_array = pdf_new_array(); + start = cid; } pdf_add_array(an_array, pdf_new_number(width)); prev = cid; @@ -275,13 +267,9 @@ add_TTCIDHMetrics (pdf_obj *fontdict, struct tt_glyphs *g, empty = 0; } - pdf_add_dict(fontdict, - pdf_new_name("DW"), - pdf_new_number(dw)); + pdf_add_dict(fontdict, pdf_new_name("DW"), pdf_new_number(dw)); if (!empty) { - pdf_add_dict(fontdict, - pdf_new_name("W"), - pdf_ref_obj(w_array)); + pdf_add_dict(fontdict, pdf_new_name("W"), pdf_ref_obj(w_array)); } pdf_release_obj(w_array); @@ -290,7 +278,7 @@ add_TTCIDHMetrics (pdf_obj *fontdict, struct tt_glyphs *g, static void add_TTCIDVMetrics (pdf_obj *fontdict, struct tt_glyphs *g, - char *used_chars, unsigned short last_cid) + char *used_chars, unsigned short last_cid) { pdf_obj *w2_array, *an_array = NULL; int cid; @@ -484,30 +472,30 @@ cid_to_code (CMap *cmap, CID cid) /* #define NO_GHOSTSCRIPT_BUG 1 */ -void -CIDFont_type2_dofont (CIDFont *font) +int +CIDFont_type2_dofont (pdf_font *font) { - pdf_obj *fontfile; - sfnt *sfont; - char *h_used_chars, *v_used_chars, *used_chars; + pdf_obj *fontfile; + sfnt *sfont; + char *h_used_chars, *v_used_chars, *used_chars; struct tt_glyphs *glyphs; - CMap *cmap = NULL; - tt_cmap *ttcmap = NULL; - ULONG offset = 0; - CID cid, last_cid; - unsigned char *cidtogidmap; - USHORT num_glyphs; - int i, glyph_ordering = 0, unicode_cmap = 0; - FILE *fp = NULL; - - if (!font->indirect) - return; + CMap *cmap = NULL; + tt_cmap *ttcmap = NULL; + ULONG offset = 0; + CID cid, last_cid; + unsigned char *cidtogidmap; + USHORT num_glyphs; + int i, glyph_ordering = 0, unicode_cmap = 0; + FILE *fp = NULL; + + if (!font->reference) + return 0; - pdf_add_dict(font->fontdict, - pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor)); + pdf_add_dict(font->resource, + pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor)); - if (CIDFont_is_BaseFont(font)) - return; + if (font->flags & PDF_FONT_FLAG_BASEFONT) + return 0; /* * CIDSystemInfo comes here since Supplement can be increased. @@ -517,65 +505,84 @@ CIDFont_type2_dofont (CIDFont *font) tmp = pdf_new_dict (); pdf_add_dict(tmp, - pdf_new_name("Registry"), - pdf_new_string(font->csi->registry, strlen(font->csi->registry))); + pdf_new_name("Registry"), + pdf_new_string(font->cid.csi.registry, strlen(font->cid.csi.registry))); pdf_add_dict(tmp, - pdf_new_name("Ordering"), - pdf_new_string(font->csi->ordering, strlen(font->csi->ordering))); + pdf_new_name("Ordering"), + pdf_new_string(font->cid.csi.ordering, strlen(font->cid.csi.ordering))); pdf_add_dict(tmp, - pdf_new_name("Supplement"), - pdf_new_number(font->csi->supplement)); - pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), tmp); + pdf_new_name("Supplement"), + pdf_new_number(font->cid.csi.supplement)); + pdf_add_dict(font->resource, pdf_new_name("CIDSystemInfo"), tmp); } /* Quick exit for non-embedded & fixed-pitch font. */ - if (!CIDFont_get_embedding(font) && - (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) { - pdf_add_dict(font->fontdict, - pdf_new_name("DW"), pdf_new_number(1000.0)); - return; + if (!font->cid.options.embed && + (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH)) { + pdf_add_dict(font->resource, pdf_new_name("DW"), pdf_new_number(1000.0)); + return 0; } - fp = DPXFOPEN(font->ident, DPX_RES_TYPE_TTFONT); + fp = DPXFOPEN(font->filename, DPX_RES_TYPE_TTFONT); if (!fp) { - fp = DPXFOPEN(font->ident, DPX_RES_TYPE_DFONT); - if (!fp) ERROR("Could not open TTF/dfont file: %s", font->ident); - sfont = dfont_open(fp, font->options->index); + fp = DPXFOPEN(font->filename, DPX_RES_TYPE_DFONT); + if (!fp) { + WARN("Could not open TTF/dfont file: %s", font->filename); + return -1; + } + sfont = dfont_open(fp, font->index); } else { sfont = sfnt_open(fp); } if (!sfont) { - ERROR("Could not open TTF file: %s", font->ident); + WARN("Could not open TTF file: %s", font->filename); + DPXFCLOSE(fp); + return -1; } switch (sfont->type) { case SFNT_TYPE_TTC: - offset = ttc_read_offset(sfont, font->options->index); - if (offset == 0) - ERROR("Invalid TTC index in %s.", font->ident); + offset = ttc_read_offset(sfont, font->index); + if (offset == 0) { + WARN("Invalid TTC index in %s.", font->filename); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } break; case SFNT_TYPE_TRUETYPE: - if (font->options->index > 0) - ERROR("Found TrueType font file while expecting TTC file (%s).", font->ident); + if (font->index > 0) { + WARN("Found TrueType font file while expecting TTC file (%s).", font->filename); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } offset = 0; break; case SFNT_TYPE_DFONT: offset = sfont->offset; break; default: - ERROR("Not a TrueType/TTC font (%s)?", font->ident); + WARN("Not a TrueType/TTC font (%s)?", font->filename); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; break; } - if (sfnt_read_table_directory(sfont, offset) < 0) - ERROR("Could not read TrueType table directory (%s).", font->ident); + if (sfnt_read_table_directory(sfont, offset) < 0) { + WARN("Could not read TrueType table directory (%s).", font->filename); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } /* * Adobe-Identity means font's internal glyph ordering here. */ - if (!strcmp(font->csi->registry, "Adobe") && - !strcmp(font->csi->ordering, "Identity")) { + if (!strcmp(font->cid.csi.registry, "Adobe") && + !strcmp(font->cid.csi.ordering, "Identity")) { glyph_ordering = 1; } else { glyph_ordering = 0; @@ -594,27 +601,35 @@ CIDFont_type2_dofont (CIDFont *font) */ for (i = 0; i <= KNOWN_ENCODINGS_MAX; i++) { ttcmap = tt_cmap_read(sfont, - known_encodings[i].platform, - known_encodings[i].encoding); + known_encodings[i].platform, + known_encodings[i].encoding); if (ttcmap) - break; + break; } if (!ttcmap) { - WARN("No usable TrueType cmap table found for font \"%s\".", font->ident); + WARN("No usable TrueType cmap table found for font \"%s\".", font->filename); WARN("CID character collection for this font is set to \"%s-%s\"", - font->csi->registry, font->csi->ordering); - ERROR("Cannot continue without this..."); + font->cid.csi.registry, font->cid.csi.ordering); + WARN("Cannot continue without this..."); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } else if (i <= WIN_UCS_INDEX_MAX) { unicode_cmap = 1; } else { unicode_cmap = 0; } - /* - * NULL is returned if CMap is Identity CMap. - */ - cmap = find_tocode_cmap(font->csi->registry, - font->csi->ordering, i); + if (!strcmp(font->cid.csi.ordering, "UCS") && i <= WIN_UCS_INDEX_MAX) { + cmap = NULL; + } else { + cmap = find_tocode_cmap(font->cid.csi.registry, font->cid.csi.ordering, i); + if (!cmap) { + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } + } } glyphs = tt_build_init(); @@ -623,19 +638,12 @@ CIDFont_type2_dofont (CIDFont *font) num_glyphs = 1; /* .notdef */ used_chars = h_used_chars = v_used_chars = NULL; { - Type0Font *parent; - int parent_id, c; + int c; - if ((parent_id = CIDFont_get_parent_id(font, 0)) >= 0) { - parent = Type0Font_cache_get(parent_id); - h_used_chars = Type0Font_get_usedchars(parent); - } - if ((parent_id = CIDFont_get_parent_id(font, 1)) >= 0) { - parent = Type0Font_cache_get(parent_id); - v_used_chars = Type0Font_get_usedchars(parent); - } - if (!h_used_chars && !v_used_chars) - ERROR("Unexpected error."); + h_used_chars = font->usedchars; + v_used_chars = font->cid.usedchars_v; + + ASSERT(h_used_chars || v_used_chars); /* * Quick check of max CID. @@ -643,30 +651,28 @@ CIDFont_type2_dofont (CIDFont *font) c = 0; for (i = 8191; i >= 0; i--) { if (h_used_chars && h_used_chars[i] != 0) { - last_cid = i * 8 + 7; - c = h_used_chars[i]; - break; + last_cid = i * 8 + 7; + c = h_used_chars[i]; + break; } } for (i = 8191; i >= 0; i--) { if (v_used_chars && v_used_chars[i] != 0) { - if (i * 8 + 7 >= last_cid) { - c = (i * 8 + 7 > last_cid) ? (v_used_chars[i]) : (c | v_used_chars[i]); - last_cid = i * 8 + 7; - break; - } + if (i * 8 + 7 >= last_cid) { + c = (i * 8 + 7 > last_cid) ? (v_used_chars[i]) : (c | v_used_chars[i]); + last_cid = i * 8 + 7; + break; + } } } if (last_cid > 0) { for (i = 0; i < 8; i++) { - if ((c >> i) & 1) - break; - last_cid--; + if ((c >> i) & 1) + break; + last_cid--; } } - if (last_cid >= 0xFFFFu) { - ERROR("CID count > 65535"); - } + ASSERT(last_cid < 0xFFFFu); } #ifndef NO_GHOSTSCRIPT_BUG @@ -691,32 +697,31 @@ CIDFont_type2_dofont (CIDFont *font) unsigned short gid; if (!is_used_char2(h_used_chars, cid)) - continue; + continue; if (glyph_ordering) { - gid = cid; - code = cid; + gid = cid; + code = cid; } else { - code = cid_to_code(cmap, cid); - gid = tt_cmap_lookup(ttcmap, code); + code = cid_to_code(cmap, cid); + gid = tt_cmap_lookup(ttcmap, code); #ifdef FIX_CJK_UNIOCDE_SYMBOLS - if (gid == 0 && unicode_cmap) { - int alt_code; - - alt_code = fix_CJK_symbols((unsigned short)code); - if (alt_code != code) { - gid = tt_cmap_lookup(ttcmap, alt_code); - if (gid != 0) { - WARN("Unicode char U+%04x replaced with U+%04x.", - code, alt_code); - } - } - } + if (gid == 0 && unicode_cmap) { + int alt_code; + + alt_code = fix_CJK_symbols((unsigned short)code); + if (alt_code != code) { + gid = tt_cmap_lookup(ttcmap, alt_code); + if (gid != 0) { + WARN("Unicode char U+%04x replaced with U+%04x.", code, alt_code); + } + } + } #endif /* FIX_CJK_UNIOCDE_SYMBOLS */ } if (gid == 0) { - WARN("Glyph missing in font. (CID=%u, code=0x%04x)", cid, code); + WARN("Glyph missing in font. (CID=%u, code=0x%04x)", cid, code); } /* TODO: duplicated glyph */ @@ -745,18 +750,16 @@ CIDFont_type2_dofont (CIDFont *font) gsub_list = NULL; } else { gsub_list = otl_gsub_new(); - if (otl_gsub_add_feat(gsub_list, - "*", "*", "vrt2", sfont) < 0) { - if (otl_gsub_add_feat(gsub_list, - "*", "*", "vert", sfont) < 0) { - WARN("GSUB feature vrt2/vert not found."); - otl_gsub_release(gsub_list); - gsub_list = NULL; - } else { - otl_gsub_select(gsub_list, "*", "*", "vert"); - } + if (otl_gsub_add_feat(gsub_list, "*", "*", "vrt2", sfont) < 0) { + if (otl_gsub_add_feat(gsub_list, "*", "*", "vert", sfont) < 0) { + WARN("GSUB feature vrt2/vert not found."); + otl_gsub_release(gsub_list); + gsub_list = NULL; + } else { + otl_gsub_select(gsub_list, "*", "*", "vert"); + } } else { - otl_gsub_select(gsub_list, "*", "*", "vrt2"); + otl_gsub_select(gsub_list, "*", "*", "vrt2"); } } @@ -765,41 +768,40 @@ CIDFont_type2_dofont (CIDFont *font) unsigned short gid; if (!is_used_char2(v_used_chars, cid)) - continue; + continue; /* There may be conflict of horizontal and vertical glyphs * when font is used with /UCS. However, we simply ignore * that... */ if (h_used_chars && is_used_char2(h_used_chars, cid)) { - continue; + continue; } if (glyph_ordering) { - gid = cid; - code = cid; + gid = cid; + code = cid; } else { - code = cid_to_code(cmap, cid); - gid = tt_cmap_lookup(ttcmap, code); + code = cid_to_code(cmap, cid); + gid = tt_cmap_lookup(ttcmap, code); #ifdef FIX_CJK_UNIOCDE_SYMBOLS - if (gid == 0 && unicode_cmap) { - int alt_code; - - alt_code = fix_CJK_symbols((unsigned short)code); - if (alt_code != code) { - gid = tt_cmap_lookup(ttcmap, alt_code); - if (gid != 0) { - WARN("Unicode char U+%04x replaced with U+%04x.", - code, alt_code); - } - } - } + if (gid == 0 && unicode_cmap) { + int alt_code; + + alt_code = fix_CJK_symbols((unsigned short)code); + if (alt_code != code) { + gid = tt_cmap_lookup(ttcmap, alt_code); + if (gid != 0) { + WARN("Unicode char U+%04x replaced with U+%04x.", code, alt_code); + } + } + } #endif /* FIX_CJK_UNIOCDE_SYMBOLS */ } if (gid == 0) { - WARN("Glyph missing in font. (CID=%u, code=0x%04x)", cid, code); + WARN("Glyph missing in font. (CID=%u, code=0x%04x)", cid, code); } else if (gsub_list) { - otl_gsub_apply(gsub_list, &gid); + otl_gsub_apply(gsub_list, &gid); } #ifndef NO_GHOSTSCRIPT_BUG @@ -811,7 +813,7 @@ CIDFont_type2_dofont (CIDFont *font) #endif /* !NO_GHOSTSCRIPT_BUG */ if (used_chars) /* merge vertical used_chars to horizontal */ - add_to_used_chars2(used_chars, cid); + add_to_used_chars2(used_chars, cid); num_glyphs++; } @@ -823,31 +825,41 @@ CIDFont_type2_dofont (CIDFont *font) used_chars = v_used_chars; } - if (!used_chars) - ERROR("Unexpected error."); + ASSERT(used_chars); tt_cmap_release(ttcmap); - if (CIDFont_get_embedding(font)) { - if (tt_build_tables(sfont, glyphs) < 0) - ERROR("Could not created FontFile stream."); + if (font->cid.options.embed) { + if (tt_build_tables(sfont, glyphs) < 0) { + WARN("Could not created FontFile stream."); + if (cidtogidmap) + RELEASE(cidtogidmap); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } if (dpx_conf.verbose_level > 1) MESG("[%u glyphs (Max CID: %u)]", glyphs->num_glyphs, last_cid); } else { - if (tt_get_metrics(sfont, glyphs) < 0) - ERROR("Reading glyph metrics failed..."); + if (tt_get_metrics(sfont, glyphs) < 0) { + WARN("Reading glyph metrics failed..."); + if (cidtogidmap) + RELEASE(cidtogidmap); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } } /* * DW, W, DW2, and W2 */ - if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) { - pdf_add_dict(font->fontdict, - pdf_new_name("DW"), pdf_new_number(1000.0)); + if (opt_flags_cidfont & CIDFONT_FORCE_FIXEDPITCH) { + pdf_add_dict(font->resource, pdf_new_name("DW"), pdf_new_number(1000.0)); } else { - add_TTCIDHMetrics(font->fontdict, glyphs, used_chars, cidtogidmap, last_cid); + add_TTCIDHMetrics(font->resource, glyphs, used_chars, cidtogidmap, last_cid); if (v_used_chars) - add_TTCIDVMetrics(font->fontdict, glyphs, used_chars, last_cid); + add_TTCIDVMetrics(font->resource, glyphs, used_chars, last_cid); } /* CIDSet @@ -873,14 +885,13 @@ CIDFont_type2_dofont (CIDFont *font) tt_build_finish(glyphs); /* Finish here if not embedded. */ - if (!CIDFont_get_embedding(font)) { + if (!font->cid.options.embed) { if (cidtogidmap) RELEASE(cidtogidmap); sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); + DPXFCLOSE(fp); - return; + return 0; } /* Create font file */ @@ -888,7 +899,12 @@ CIDFont_type2_dofont (CIDFont *font) if (sfnt_require_table(sfont, required_table[i].name, required_table[i].must_exist) < 0) { - ERROR("Some required TrueType table (%s) does not exist.", required_table[i].name); + WARN("Some required TrueType table (%s) does not exist.", required_table[i].name); + if (cidtogidmap) + RELEASE(cidtogidmap); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } } @@ -898,19 +914,19 @@ CIDFont_type2_dofont (CIDFont *font) fontfile = sfnt_create_FontFile_stream(sfont); sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); - - if (!fontfile) - ERROR("Could not created FontFile stream for \"%s\".", font->ident); + DPXFCLOSE(fp); + if (!fontfile) { + WARN("Could not created FontFile stream for \"%s\".", font->filename); + if (cidtogidmap) + RELEASE(cidtogidmap); + return -1; + } if (dpx_conf.verbose_level > 1) { MESG("[%ld bytes]", pdf_stream_length(fontfile)); } - pdf_add_dict(font->descriptor, - pdf_new_name("FontFile2"), - pdf_ref_obj (fontfile)); + pdf_add_dict(font->descriptor, pdf_new_name("FontFile2"), pdf_ref_obj (fontfile)); pdf_release_obj(fontfile); /* @@ -920,32 +936,28 @@ CIDFont_type2_dofont (CIDFont *font) * for Type 2 CIDFonts with embedded font programs. */ if (!cidtogidmap) { - pdf_add_dict(font->fontdict, - pdf_new_name("CIDToGIDMap"), - pdf_new_name("Identity")); + pdf_add_dict(font->resource, pdf_new_name("CIDToGIDMap"), pdf_new_name("Identity")); } else { pdf_obj *c2gmstream; c2gmstream = pdf_new_stream(STREAM_COMPRESS); pdf_add_stream(c2gmstream, cidtogidmap, (last_cid + 1) * 2); - pdf_add_dict(font->fontdict, - pdf_new_name("CIDToGIDMap"), - pdf_ref_obj (c2gmstream)); + pdf_add_dict(font->resource, pdf_new_name("CIDToGIDMap"), pdf_ref_obj (c2gmstream)); pdf_release_obj(c2gmstream); RELEASE(cidtogidmap); } - return; + return 0; } int -CIDFont_type2_open (CIDFont *font, const char *name, - CIDSysInfo *cmap_csi, cid_opt *opt) +CIDFont_type2_open (pdf_font *font, const char *name, int index, cid_opt *opt) { + int error; char *fontname; sfnt *sfont; ULONG offset = 0; - FILE *fp = NULL; + FILE *fp = NULL; ASSERT(font && opt); @@ -953,7 +965,7 @@ CIDFont_type2_open (CIDFont *font, const char *name, if (!fp) { fp = DPXFOPEN(name, DPX_RES_TYPE_DFONT); if (!fp) return -1; - sfont = dfont_open(fp, opt->index); + sfont = dfont_open(fp, index); } else { sfont = sfnt_open(fp); } @@ -965,11 +977,15 @@ CIDFont_type2_open (CIDFont *font, const char *name, switch (sfont->type) { case SFNT_TYPE_TTC: - offset = ttc_read_offset(sfont, opt->index); + offset = ttc_read_offset(sfont, index); break; case SFNT_TYPE_TRUETYPE: - if (opt->index > 0) - ERROR("Invalid TTC index (not TTC font): %s", name); + if (index > 0) { + WARN("Invalid TTC index (not TTC font): %s", name); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } offset = 0; break; case SFNT_TYPE_DFONT: @@ -977,20 +993,21 @@ CIDFont_type2_open (CIDFont *font, const char *name, break; default: sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); + DPXFCLOSE(fp); return -1; } if (sfnt_read_table_directory(sfont, offset) < 0) { - ERROR("Reading TrueType table directory failed."); + WARN("Reading TrueType table directory failed: %s", name); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } /* Ignore TrueType Collection with CFF table. */ if (sfont->type == SFNT_TYPE_TTC && sfnt_find_table_pos(sfont, "CFF ")) { sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); + DPXFCLOSE(fp); return -1; } @@ -1006,7 +1023,13 @@ CIDFont_type2_open (CIDFont *font, const char *name, strncpy(shortname, name, PDF_NAME_LEN_MAX); namelen = strlen(shortname); } - validate_name(shortname, namelen); /* for SJIS, UTF-16, ... string */ + error = validate_name(shortname, namelen); /* for SJIS, UTF-16, ... string */ + if (error) { + RELEASE(shortname); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; + } /* * Strlen works, after validate_named string. * Mangled name requires more 7 bytes. @@ -1036,55 +1059,25 @@ CIDFont_type2_open (CIDFont *font, const char *name, * CIDSystemInfo is determined from CMap or from map record option. */ font->fontname = fontname; - font->subtype = CIDFONT_TYPE2; - font->csi = NEW(1, CIDSysInfo); - if (opt->csi) { - if (cmap_csi) { - if (strcmp(opt->csi->registry, cmap_csi->registry) || - strcmp(opt->csi->ordering, cmap_csi->ordering)) { - WARN("CID character collection mismatched:\n"); - MESG("\tFont: %s-%s-%d\n", - opt->csi->registry, opt->csi->ordering, opt->csi->supplement); - MESG("\tCMap: %s-%s-%d\n", - cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement); - ERROR("Incompatible CMap specified for this font."); - } - if (opt->csi->supplement < cmap_csi->supplement) { - WARN("Supplement value in CIDSystemInfo increased."); - WARN("Some characters may not shown."); - opt->csi->supplement = cmap_csi->supplement; - } - } - font->csi->registry = NEW(strlen(opt->csi->registry)+1, char); - strcpy(font->csi->registry, opt->csi->registry); - font->csi->ordering = NEW(strlen(opt->csi->ordering)+1, char); - strcpy(font->csi->ordering, opt->csi->ordering); - font->csi->supplement = opt->csi->supplement; - } else if (cmap_csi) { - font->csi->registry = NEW(strlen(cmap_csi->registry)+1, char); - strcpy(font->csi->registry, cmap_csi->registry); - font->csi->ordering = NEW(strlen(cmap_csi->ordering)+1, char); - strcpy(font->csi->ordering, cmap_csi->ordering); - font->csi->supplement = cmap_csi->supplement; - } else { /* This means font's internal glyph ordering. */ - font->csi->registry = NEW(strlen("Adobe")+1, char); - strcpy(font->csi->registry, "Adobe"); - font->csi->ordering = NEW(strlen("Identity")+1, char); - strcpy(font->csi->ordering, "Identity"); - font->csi->supplement = 0; + font->subtype = PDF_FONT_FONTTYPE_CIDTYPE2; + if (opt->csi.registry && opt->csi.ordering) { + font->cid.csi.registry = NEW(strlen(opt->csi.registry)+1, char); + strcpy(font->cid.csi.registry, opt->csi.registry); + font->cid.csi.ordering = NEW(strlen(opt->csi.ordering)+1, char); + strcpy(font->cid.csi.ordering, opt->csi.ordering); + font->cid.csi.supplement = opt->csi.supplement; } - font->fontdict = pdf_new_dict(); - pdf_add_dict(font->fontdict, - pdf_new_name("Type"), - pdf_new_name("Font")); - pdf_add_dict(font->fontdict, - pdf_new_name("Subtype"), - pdf_new_name("CIDFontType2")); + font->resource = pdf_new_dict(); + pdf_add_dict(font->resource, pdf_new_name("Type"), pdf_new_name("Font")); + pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("CIDFontType2")); font->descriptor = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0, name); if (!font->descriptor) { - ERROR("Could not obtain necessary font info."); + WARN("Could not obtain necessary font info: %s", name); + sfnt_close(sfont); + DPXFCLOSE(fp); + return -1; } if (opt->embed) { @@ -1093,12 +1086,8 @@ CIDFont_type2_open (CIDFont *font, const char *name, fontname[6] = '+'; } - pdf_add_dict(font->descriptor, - pdf_new_name("FontName"), - pdf_new_name(fontname)); - pdf_add_dict(font->fontdict, - pdf_new_name("BaseFont"), - pdf_new_name(fontname)); + pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(fontname)); + pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(fontname)); sfnt_close(sfont); if (fp) diff --git a/Build/source/texk/dvipdfm-x/cidtype2.h b/Build/source/texk/dvipdfm-x/cidtype2.h index 764767127af..70ab71e6d67 100644 --- a/Build/source/texk/dvipdfm-x/cidtype2.h +++ b/Build/source/texk/dvipdfm-x/cidtype2.h @@ -21,13 +21,9 @@ #ifndef _CIDTYPE2_H_ #define _CIDTYPE2_H_ -#include "cid.h" -#include "cid_p.h" +#include "pdffont.h" -extern void CIDFont_type2_set_flags (int flags); - -extern int CIDFont_type2_open (CIDFont *font, const char *name, - CIDSysInfo *cmap_csi, cid_opt *opt); -extern void CIDFont_type2_dofont (CIDFont *font); +extern int CIDFont_type2_open (pdf_font *font, const char *name, int index, cid_opt *opt); +extern int CIDFont_type2_dofont (pdf_font *font); #endif /* _CIDTYPE2_H_ */ diff --git a/Build/source/texk/dvipdfm-x/configure b/Build/source/texk/dvipdfm-x/configure index 96006213388..816697a5ef5 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) 20200906. +# Generated by GNU Autoconf 2.69 for dvipdfm-x (TeX Live) 20200922. # # Report bugs to <dvipdfmx@tug.org>. # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='dvipdfm-x (TeX Live)' PACKAGE_TARNAME='dvipdfm-x--tex-live-' -PACKAGE_VERSION='20200906' -PACKAGE_STRING='dvipdfm-x (TeX Live) 20200906' +PACKAGE_VERSION='20200922' +PACKAGE_STRING='dvipdfm-x (TeX Live) 20200922' PACKAGE_BUGREPORT='dvipdfmx@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) 20200906 to adapt to many kinds of systems. +\`configure' configures dvipdfm-x (TeX Live) 20200922 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) 20200906:";; + short | recursive ) echo "Configuration of dvipdfm-x (TeX Live) 20200922:";; 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 20200906 +dvipdfm-x (TeX Live) configure 20200922 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 20200906, which was +It was created by dvipdfm-x (TeX Live) $as_me 20200922, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -8077,7 +8077,7 @@ fi # Define the identity of the package. PACKAGE='dvipdfm-x--tex-live-' - VERSION='20200906' + VERSION='20200922' cat >>confdefs.h <<_ACEOF @@ -14746,7 +14746,7 @@ Usage: $0 [OPTIONS] Report bugs to <bug-libtool@gnu.org>." lt_cl_version="\ -dvipdfm-x (TeX Live) config.lt 20200906 +dvipdfm-x (TeX Live) config.lt 20200922 configured by $0, generated by GNU Autoconf 2.69. Copyright (C) 2011 Free Software Foundation, Inc. @@ -16636,7 +16636,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 20200906, which was +This file was extended by dvipdfm-x (TeX Live) $as_me 20200922, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16706,7 +16706,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 20200906 +dvipdfm-x (TeX Live) config.status 20200922 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 38bc50dddc0..b428d0b25c4 100644 --- a/Build/source/texk/dvipdfm-x/configure.ac +++ b/Build/source/texk/dvipdfm-x/configure.ac @@ -8,7 +8,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)], [20200906], [dvipdfmx@tug.org]) +AC_INIT([dvipdfm-x (TeX Live)], [20200922], [dvipdfmx@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/dpxutil.c b/Build/source/texk/dvipdfm-x/dpxutil.c index 4bcf28ad699..379fb515058 100644 --- a/Build/source/texk/dvipdfm-x/dpxutil.c +++ b/Build/source/texk/dvipdfm-x/dpxutil.c @@ -370,6 +370,8 @@ dpx_stack_roll (dpx_stack *stack, int n, int j) if (n == 1) return; j = j % n; + if (j < 0) + j = n + j; while (j-- > 0) { int m = n; stack_elem *elem, *prev, *top; diff --git a/Build/source/texk/dvipdfm-x/pdfdev.c b/Build/source/texk/dvipdfm-x/pdfdev.c index b3bec533cba..dc56050c3ee 100644 --- a/Build/source/texk/dvipdfm-x/pdfdev.c +++ b/Build/source/texk/dvipdfm-x/pdfdev.c @@ -176,7 +176,7 @@ struct dev_font { /* Needs to be big enough to hold name "Fxxx" * where xxx is number of largest font */ - char short_name[7]; /* Resource name */ + char short_name[16]; /* Resource name */ int used_on_this_page; char *tex_name; /* String identifier of this font */ @@ -196,9 +196,6 @@ struct dev_font { int font_id; int enc_id; - /* if >= 0, index of a dev_font that really has the resource and used_chars */ - int real_font_index; - pdf_obj *resource; char *used_chars; @@ -255,7 +252,6 @@ struct pdf_dev { struct dev_font *fonts; int num_dev_fonts; int max_dev_fonts; - int num_phys_fonts; char format_buffer[FORMAT_BUF_SIZE+1]; }; @@ -856,7 +852,6 @@ static int pdf_dev_set_font (pdf_dev *p, int font_id) { struct dev_font *font; - struct dev_font *real_font; int text_rotate; double font_scale; int len; @@ -870,11 +865,6 @@ pdf_dev_set_font (pdf_dev *p, int font_id) font = GET_FONT(p, font_id); ASSERT(font); /* Caller should check font_id. */ - if (font->real_font_index >= 0) - real_font = GET_FONT(p, font->real_font_index); - else - real_font = font; - p->text_state.is_mb = (font->format == PDF_FONTTYPE_COMPOSITE) ? 1 : 0; vert_font = font->wmode ? 1 : 0; @@ -894,20 +884,20 @@ pdf_dev_set_font (pdf_dev *p, int font_id) p->text_state.matrix.extend = font->extend; p->text_state.matrix.rotate = text_rotate; - if (!real_font->resource) { - real_font->resource = pdf_get_font_reference(real_font->font_id); - real_font->used_chars = pdf_get_font_usedchars(real_font->font_id); + if (!font->resource) { + font->resource = pdf_get_font_reference(font->font_id); + font->used_chars = pdf_get_font_usedchars(font->font_id); } - if (!real_font->used_on_this_page) { + if (!font->used_on_this_page) { pdf_doc_add_page_resource("Font", - real_font->short_name, - pdf_link_obj(real_font->resource)); - real_font->used_on_this_page = 1; + font->short_name, + pdf_link_obj(font->resource)); + font->used_on_this_page = 1; } font_scale = (double) font->sptsize * p->unit.dvi2pts; - len = sprintf(p->format_buffer, " /%s", real_font->short_name); /* space not necessary. */ + len = sprintf(p->format_buffer, " /%s", font->short_name); /* space not necessary. */ p->format_buffer[len++] = ' '; len += p_dtoa(font_scale, MIN(p->unit.precision+1, DEV_PRECISION_MAX), p->format_buffer+len); @@ -1057,7 +1047,6 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos, { pdf_dev *p = current_device(); struct dev_font *font; - struct dev_font *real_font; const unsigned char *str_ptr; /* Pointer to the reencoded string. */ int length, i, len = 0; spt_t kern, delh, delv; @@ -1078,11 +1067,6 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos, return; } - if (font->real_font_index >= 0) - real_font = GET_FONT(p, font->real_font_index); - else - real_font = font; - text_xorigin = p->text_state.ref_x; text_yorigin = p->text_state.ref_y; @@ -1094,16 +1078,16 @@ pdf_dev_set_string (spt_t xpos, spt_t ypos, ERROR("Error in converting input string..."); return; } - if (real_font->used_chars != NULL) { + if (font->used_chars != NULL) { for (i = 0; i < length; i += 2) { unsigned short cid = (str_ptr[i] << 8) | str_ptr[i + 1]; - add_to_used_chars2(real_font->used_chars, cid); + add_to_used_chars2(font->used_chars, cid); } } } else { - if (real_font->used_chars != NULL) { + if (font->used_chars != NULL) { for (i = 0; i < length; i++) - real_font->used_chars[str_ptr[i]] = 1; + font->used_chars[str_ptr[i]] = 1; } } @@ -1408,11 +1392,9 @@ pdf_dev_locate_font (const char *font_name, spt_t ptsize) } for (i = 0; i < p->num_dev_fonts; i++) { - if (strcmp(font_name, p->fonts[i].tex_name) == 0) { - if (ptsize == p->fonts[i].sptsize) - return i; /* found a dev_font that matches the request */ - if (p->fonts[i].format != PDF_FONTTYPE_BITMAP) - break; /* new dev_font will share pdf resource with /i/ */ + if (!strcmp(font_name, p->fonts[i].tex_name) && + ptsize == p->fonts[i].sptsize) { + return i; /* found a dev_font that matches the request */ } } @@ -1433,22 +1415,15 @@ pdf_dev_locate_font (const char *font_name, spt_t ptsize) if (dpx_conf.verbose_level > 1) print_fontmap(font_name, mrec); - font->font_id = pdf_font_findresource(font_name, ptsize * p->unit.dvi2pts, mrec); - if (font->font_id < 0) - return -1; - - /* We found device font here. */ - if (i < p->num_dev_fonts) { - font->real_font_index = i; - strcpy(font->short_name, p->fonts[i].short_name); - } - else { - font->real_font_index = -1; - font->short_name[0] = 'F'; - p_itoa(p->num_phys_fonts + 1, &font->short_name[1]); /* NULL terminated here */ - p->num_phys_fonts++; + font->font_id = pdf_font_findresource(font_name, ptsize * p->unit.dvi2pts); + if (font->font_id < 0) { + font->font_id = pdf_font_load_font(font_name, ptsize * p->unit.dvi2pts, mrec); + if (font->font_id < 0) + return -1; } + pdf_font_resource_name(font->font_id, font->short_name); + font->used_on_this_page = 0; font->tex_name = NEW(strlen(font_name) + 1, char); diff --git a/Build/source/texk/dvipdfm-x/pdfdraw.c b/Build/source/texk/dvipdfm-x/pdfdraw.c index 9fc71638bc0..66549e193b1 100644 --- a/Build/source/texk/dvipdfm-x/pdfdraw.c +++ b/Build/source/texk/dvipdfm-x/pdfdraw.c @@ -63,10 +63,12 @@ inversematrix (pdf_tmatrix *W, const pdf_tmatrix *M) return -1; /* result is undefined. */ } - W->a = (M->d) / det; W->b = -(M->b) / det; - W->c = -(M->c) / det; W->d = (M->a) / det; - W->e = (M->c) * (M->f) - (M->d) * (M->e); - W->f = (M->b) * (M->e) - (M->a) * (M->f); + W->a = (M->d) / det; W->b = -(M->b) / det; + W->c = -(M->c) / det; W->d = (M->a) / det; + W->e = (M->c) * (M->f) - (M->d) * (M->e); + W->f = (M->b) * (M->e) - (M->a) * (M->f); + W->e /= det; + W->f /= det; return 0; } @@ -134,7 +136,6 @@ pdf_coord__transform (pdf_coord *p, const pdf_tmatrix *M) return 0; } -#if 0 static /* __inline__ */ int pdf_coord__itransform (pdf_coord *p, const pdf_tmatrix *M) { @@ -152,7 +153,6 @@ pdf_coord__itransform (pdf_coord *p, const pdf_tmatrix *M) return 0; } -#endif static /* __inline__ */ int pdf_coord__dtransform (pdf_coord *p, const pdf_tmatrix *M) @@ -1759,7 +1759,6 @@ pdf_dev_transform (pdf_coord *p, const pdf_tmatrix *M) return; } -#if 0 void pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M) { @@ -1773,7 +1772,6 @@ pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M) return; } -#endif int pdf_dev_arc (double c_x , double c_y, double r, diff --git a/Build/source/texk/dvipdfm-x/pdfdraw.h b/Build/source/texk/dvipdfm-x/pdfdraw.h index b2a32b1e722..cf4588cdbd9 100644 --- a/Build/source/texk/dvipdfm-x/pdfdraw.h +++ b/Build/source/texk/dvipdfm-x/pdfdraw.h @@ -115,9 +115,7 @@ extern int pdf_dev_concat (const pdf_tmatrix *M); extern void pdf_dev_dtransform (pdf_coord *p, const pdf_tmatrix *M); extern void pdf_dev_idtransform (pdf_coord *p, const pdf_tmatrix *M); extern void pdf_dev_transform (pdf_coord *p, const pdf_tmatrix *M); -#if 0 extern void pdf_dev_itransform (pdf_coord *p, const pdf_tmatrix *M); -#endif extern int pdf_dev_gsave (void); extern int pdf_dev_grestore (void); diff --git a/Build/source/texk/dvipdfm-x/pdffont.c b/Build/source/texk/dvipdfm-x/pdffont.c index 5e38733d3c8..cc05c2e1ac9 100644 --- a/Build/source/texk/dvipdfm-x/pdffont.c +++ b/Build/source/texk/dvipdfm-x/pdffont.c @@ -47,9 +47,9 @@ #include "pkfont.h" +#include "cidtype0.h" #include "type0.h" #include "tt_cmap.h" -#include "cidtype0.h" #include "pdffont.h" @@ -66,16 +66,6 @@ pdf_font_make_uniqueTag (char *tag) { int i; char ch; - static char first = 1; - - if (first) { - time_t current_time; - current_time = dpx_util_get_unique_time_if_given(); - if (current_time == INVALID_EPOCH_VALUE) - current_time = time(NULL); - srand(current_time); - first = 0; - } for (i = 0; i < 6; i++) { ch = rand() % 26; @@ -84,58 +74,25 @@ pdf_font_make_uniqueTag (char *tag) tag[6] = '\0'; } - -struct pdf_font -{ - char *ident; - int subtype; - - char *map_name; - - int encoding_id; /* encoding or CMap */ - - /* - * If subtype is Type0, it simply points font_id - * of Type0 font. Type0 and simple font is not - * unified yet. - */ - int font_id; - - /* For simple font */ - uint32_t index; - char *fontname; - char uniqueID[7]; - - /* - * PDF font resource objects - */ - pdf_obj *reference; - pdf_obj *resource; - pdf_obj *descriptor; - - /* - * Font format specific data - */ - char *usedchars; - int flags; - - /* PK font */ - double point_size; - double design_size; -}; +static void +init_CIDSysInfo (CIDSysInfo *csi) { + csi->registry = NULL; + csi->ordering = NULL; + csi->supplement = 0; +} static void pdf_init_font_struct (pdf_font *font) { ASSERT(font); - font->ident = NULL; - font->map_name = NULL; - font->subtype = -1; - font->font_id = -1; /* Type0 ID */ - font->fontname = NULL; + font->ident = NULL; + font->filename = NULL; + font->subtype = -1; + font->font_id = -1; + font->fontname = NULL; memset(font->uniqueID, 0, 7); - font->index = 0; + font->index = 0; font->encoding_id = -1; @@ -149,6 +106,16 @@ pdf_init_font_struct (pdf_font *font) font->usedchars = NULL; font->flags = 0; + font->type0.descendant = -1; + font->type0.wmode = 0; + + init_CIDSysInfo(&font->cid.csi); + font->cid.usedchars_v = NULL; + font->cid.options.embed = 0; + font->cid.options.style = FONT_STYLE_NONE; + font->cid.options.stemv = 0; + init_CIDSysInfo(&font->cid.options.csi); + return; } @@ -157,37 +124,39 @@ pdf_flush_font (pdf_font *font) { char *fontname, *uniqueTag; - if (!font) { + if (!font) + return; + if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) || (font->flags & PDF_FONT_FLAG_IS_REENCODE)) { return; } if (font->resource && font->reference) { - if (font->subtype != PDF_FONT_FONTTYPE_TYPE3) { - if (pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) { - pdf_add_dict(font->resource, - pdf_new_name("BaseFont"), pdf_new_name(font->fontname)); - if (font->descriptor) { - pdf_add_dict(font->descriptor, - pdf_new_name("FontName"), pdf_new_name(font->fontname)); - } + switch (font->subtype) { + case PDF_FONT_FONTTYPE_TYPE3: + case PDF_FONT_FONTTYPE_TYPE0: + break; + case PDF_FONT_FONTTYPE_CIDTYPE0: + case PDF_FONT_FONTTYPE_CIDTYPE2: + break; + default: + if (font->flags & PDF_FONT_FLAG_NOEMBED) { + pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(font->fontname)); + if (font->descriptor) { + pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(font->fontname)); + } } else { - if (!font->fontname) { - ERROR("Undefined in fontname... (%s)", font->ident); - } - fontname = NEW(7+strlen(font->fontname)+1, char); - uniqueTag = pdf_font_get_uniqueTag(font); - sprintf(fontname, "%6s+%s", uniqueTag, font->fontname); - pdf_add_dict(font->resource, - pdf_new_name("BaseFont"), pdf_new_name(fontname)); - if (font->descriptor) { - pdf_add_dict(font->descriptor, - pdf_new_name("FontName"), pdf_new_name(fontname)); - } - RELEASE(fontname); + ASSERT(font->fontname); + fontname = NEW(7+strlen(font->fontname)+1, char); + uniqueTag = pdf_font_get_uniqueTag(font); + sprintf(fontname, "%6s+%s", uniqueTag, font->fontname); + pdf_add_dict(font->resource, pdf_new_name("BaseFont"), pdf_new_name(fontname)); + if (font->descriptor) { + pdf_add_dict(font->descriptor, pdf_new_name("FontName"), pdf_new_name(fontname)); + } + RELEASE(fontname); } if (font->descriptor) { - pdf_add_dict(font->resource, - pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor)); + pdf_add_dict(font->resource, pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor)); } } } @@ -209,28 +178,42 @@ pdf_flush_font (pdf_font *font) static void pdf_clean_font_struct (pdf_font *font) { - if (font) { - if (font->ident) - RELEASE(font->ident); - if (font->map_name) - RELEASE(font->map_name); - if (font->fontname) - RELEASE(font->fontname); - if (font->usedchars) - RELEASE(font->usedchars); - - if (font->reference) - ERROR("pdf_font>> Object not flushed."); - if (font->resource) - ERROR("pdf_font> Object not flushed."); - if (font->descriptor) - ERROR("pdf_font>> Object not flushed."); - - font->ident = NULL; - font->map_name = NULL; - font->fontname = NULL; - font->usedchars = NULL; + if (!font) + return; + + if (font->resource) + WARN("font \"%s\" not properly released?", font->ident); + + if (font->ident) + RELEASE(font->ident); + if (font->filename) + RELEASE(font->filename); + if (font->fontname) + RELEASE(font->fontname); + if (font->usedchars) { + if (!(font->flags & PDF_FONT_FLAG_USEDCHAR_SHARED)) + RELEASE(font->usedchars); } + if (font->cid.csi.registry) + RELEASE(font->cid.csi.registry); + if (font->cid.csi.ordering) + RELEASE(font->cid.csi.ordering); + if (font->cid.options.csi.registry) + RELEASE(font->cid.options.csi.registry); + if (font->cid.options.csi.ordering) + RELEASE(font->cid.options.csi.ordering); + if (font->cid.usedchars_v) + RELEASE(font->cid.usedchars_v); + + font->ident = NULL; + font->filename = NULL; + font->fontname = NULL; + font->usedchars = NULL; + font->cid.csi.registry = NULL; + font->cid.csi.ordering = NULL; + font->cid.options.csi.registry = NULL; + font->cid.options.csi.ordering = NULL; + font->cid.usedchars_v = NULL; return; } @@ -255,11 +238,18 @@ pdf_init_fonts (void) CMap_cache_init(); pdf_init_encodings(); - Type0Font_cache_init(); - font_cache.count = 0; font_cache.capacity = CACHE_ALLOC_SIZE; font_cache.fonts = NEW(font_cache.capacity, pdf_font); + + { + time_t current_time; + + current_time = dpx_util_get_unique_time_if_given(); + if (current_time == INVALID_EPOCH_VALUE) + current_time = time(NULL); + srand(current_time); + } } #define CHECK_ID(n) do {\ @@ -267,8 +257,41 @@ pdf_init_fonts (void) ERROR("Invalid font ID: %d", (n));\ }\ } while (0) -#define GET_FONT(n) (&(font_cache.fonts[(n)])) +static pdf_font * +GET_FONT (int font_id) +{ + pdf_font *font = NULL; + + if (font_id >= 0 && font_id < font_cache.count) { + font = &font_cache.fonts[font_id]; + if (font->flags & PDF_FONT_FLAG_IS_ALIAS) { + font = &font_cache.fonts[font->font_id]; + } + } + + return font; +} + +pdf_font * +pdf_get_font_data (int font_id) +{ + CHECK_ID(font_id); + + return &font_cache.fonts[font_id]; +} + +char * +pdf_get_font_ident (int font_id) +{ + pdf_font *font; + + CHECK_ID(font_id); + + font = &font_cache.fonts[font_id]; + + return font->ident; +} pdf_obj * pdf_get_font_reference (int font_id) @@ -278,20 +301,42 @@ pdf_get_font_reference (int font_id) CHECK_ID(font_id); font = GET_FONT(font_id); + if (font->flags & PDF_FONT_FLAG_IS_REENCODE) { + font = GET_FONT(font->font_id); + } + if (!font->reference) { + font->reference = pdf_ref_obj(pdf_font_get_resource(font)); + } if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) { - Type0Font *t0font; + if (!pdf_lookup_dict(font->resource, "DescendantFonts")) { + pdf_obj *array; - t0font = Type0Font_cache_get(font->font_id); - return Type0Font_get_resource(t0font); - } else { - if (!font->reference) { - font->reference = pdf_ref_obj(pdf_font_get_resource(font)); + array = pdf_new_array(); + pdf_add_array(array, pdf_get_font_reference(font->type0.descendant)); + pdf_add_dict(font->resource, pdf_new_name("DescendantFonts"), array); } } return pdf_link_obj(font->reference); } +pdf_obj * +pdf_get_font_resource (int font_id) +{ + pdf_font *font; + + CHECK_ID(font_id); + + font = GET_FONT(font_id); + if (font->flags & PDF_FONT_FLAG_IS_REENCODE) { + font = GET_FONT(font->font_id); + } + if (!font->resource) + font->resource = pdf_new_dict(); + + return font->resource; /* FIXME */ +} + char * pdf_get_font_usedchars (int font_id) { @@ -300,18 +345,17 @@ pdf_get_font_usedchars (int font_id) CHECK_ID(font_id); font = GET_FONT(font_id); - if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) { - Type0Font *t0font; - - t0font = Type0Font_cache_get(font->font_id); - return Type0Font_get_usedchars(t0font); - } else { + if (font->flags & PDF_FONT_FLAG_IS_REENCODE) { + font = GET_FONT(font->font_id); + } + if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) { if (!font->usedchars) { font->usedchars = NEW(256, char); memset(font->usedchars, 0, 256 * sizeof(char)); } - return font->usedchars; } + + return font->usedchars; } int @@ -322,11 +366,11 @@ pdf_get_font_wmode (int font_id) CHECK_ID(font_id); font = GET_FONT(font_id); + if (font->flags & PDF_FONT_FLAG_IS_REENCODE) { + font = GET_FONT(font->font_id); + } if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) { - Type0Font *t0font; - - t0font = Type0Font_cache_get(font->font_id); - return Type0Font_get_wmode(t0font); + return font->type0.wmode; } else { return 0; } @@ -340,13 +384,15 @@ pdf_get_font_subtype (int font_id) CHECK_ID(font_id); font = GET_FONT(font_id); + if (font->flags & PDF_FONT_FLAG_IS_REENCODE) { + font = GET_FONT(font->font_id); + } return font->subtype; } -#if 0 -char * -pdf_get_font_fontname (int font_id) +int +pdf_get_font_encoding (int font_id) { pdf_font *font; @@ -354,20 +400,28 @@ pdf_get_font_fontname (int font_id) font = GET_FONT(font_id); - return font->fontname; + return font->encoding_id; } -#endif /* 0 */ int -pdf_get_font_encoding (int font_id) +pdf_font_resource_name (int font_id, char *buff) { + int len; pdf_font *font; CHECK_ID(font_id); + font = &font_cache.fonts[font_id]; + if (font->flags & PDF_FONT_FLAG_IS_ALIAS) { + font_id = font->font_id; + } font = GET_FONT(font_id); + if (font->flags & PDF_FONT_FLAG_IS_REENCODE) { + font_id = font->font_id; + } + len = sprintf(buff, "F%d", font_id); - return font->encoding_id; + return len; } /* The rule for ToUnicode creation is: @@ -381,10 +435,9 @@ pdf_get_font_encoding (int font_id) static int try_load_ToUnicode_CMap (pdf_font *font) { - pdf_obj *fontdict; pdf_obj *tounicode; const char *cmap_name = NULL; - fontmap_rec *mrec; /* Be sure fontmap is still alive here */ + fontmap_rec *mrec = NULL; /* Be sure fontmap is still alive here */ ASSERT(font); @@ -394,29 +447,32 @@ try_load_ToUnicode_CMap (pdf_font *font) if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) return 0; - ASSERT(font->map_name); + ASSERT(font->ident); - mrec = pdf_lookup_fontmap_record(font->map_name); - if (MREC_HAS_TOUNICODE(mrec)) + mrec = pdf_lookup_fontmap_record(font->ident); + if (MREC_HAS_TOUNICODE(mrec)) { cmap_name = mrec->opt.tounicode; - else { - cmap_name = font->map_name; + } else { + cmap_name = font->ident; } - - fontdict = pdf_font_get_resource(font); tounicode = pdf_load_ToUnicode_stream(cmap_name); - if (!tounicode && MREC_HAS_TOUNICODE(mrec)) - WARN("Failed to read ToUnicode mapping \"%s\"...", mrec->opt.tounicode); - else if (tounicode) { - if (pdf_obj_typeof(tounicode) != PDF_STREAM) + + if (!tounicode) { + if (MREC_HAS_TOUNICODE(mrec)) { + WARN("Failed to read ToUnicode mapping \"%s\"...", mrec->opt.tounicode); + } + } else { + if (pdf_obj_typeof(tounicode) != PDF_STREAM) { ERROR("Object returned by pdf_load_ToUnicode_stream() not stream object! (This must be bug)"); - else if (pdf_stream_length(tounicode) > 0) { + } else if (pdf_stream_length(tounicode) > 0) { + pdf_obj *fontdict = pdf_font_get_resource(font); + pdf_add_dict(fontdict, pdf_new_name("ToUnicode"), pdf_ref_obj (tounicode)); /* _FIXME_ */ if (dpx_conf.verbose_level > 0) MESG("pdf_font>> ToUnicode CMap \"%s\" attached to font id=\"%s\".\n", - cmap_name, font->map_name); + cmap_name, font->ident); } pdf_release_obj(tounicode); } @@ -429,91 +485,133 @@ pdf_close_fonts (void) { int font_id; - for (font_id = 0; - font_id < font_cache.count; font_id++) { + for (font_id = 0; font_id < font_cache.count; font_id++) { pdf_font *font; - font = GET_FONT(font_id); + font = &font_cache.fonts[font_id]; + if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) || + (font->flags & PDF_FONT_FLAG_IS_REENCODE)) { + continue; + } + if (font->subtype == PDF_FONT_FONTTYPE_CIDTYPE0 || + font->subtype == PDF_FONT_FONTTYPE_CIDTYPE2) + continue; if (dpx_conf.verbose_level > 0) { if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) { - MESG("(%s", pdf_font_get_ident(font)); - if (dpx_conf.verbose_level > 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 (dpx_conf.verbose_level > 1) { - MESG("[%s]", pdf_font_get_fontname(font)); - } - if (dpx_conf.verbose_level > 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", font->filename); + if (dpx_conf.verbose_level > 2 && + !(font->flags & PDF_FONT_FLAG_NOEMBED)) { + MESG("[%s+%s]", pdf_font_get_uniqueTag(font), font->fontname); + } else if (dpx_conf.verbose_level > 1) { + MESG("[%s]", font->fontname); + } + if (dpx_conf.verbose_level > 1) { + if (font->encoding_id >= 0) { + MESG("[%s]", pdf_encoding_get_name(font->encoding_id)); + } else { + MESG("[built-in]"); + } + } } } /* Must come before load_xxx */ try_load_ToUnicode_CMap(font); - /* Type 0 is handled separately... */ switch (font->subtype) { case PDF_FONT_FONTTYPE_TYPE1: if (dpx_conf.verbose_level > 0) - MESG("[Type1]"); - if (!pdf_font_get_flag(font, PDF_FONT_FLAG_BASEFONT)) - pdf_font_load_type1(font); + MESG("[Type1]"); + if (!(font->flags & PDF_FONT_FLAG_BASEFONT)) + pdf_font_load_type1(font); break; case PDF_FONT_FONTTYPE_TYPE1C: if (dpx_conf.verbose_level > 0) - MESG("[Type1C]"); + MESG("[Type1C]"); pdf_font_load_type1c(font); break; case PDF_FONT_FONTTYPE_TRUETYPE: if (dpx_conf.verbose_level > 0) - MESG("[TrueType]"); + MESG("[TrueType]"); pdf_font_load_truetype(font); break; case PDF_FONT_FONTTYPE_TYPE3: if (dpx_conf.verbose_level > 0) - MESG("[Type3/PK]"); + MESG("[Type3/PK]"); pdf_font_load_pkfont (font); break; case PDF_FONT_FONTTYPE_TYPE0: - break; - default: - ERROR("Unknown font type: %d", font->subtype); + if (dpx_conf.verbose_level > 0) + MESG("[Type0]"); + pdf_font_load_type0(font); break; } - if (font->encoding_id >= 0 && font->subtype != PDF_FONT_FONTTYPE_TYPE0) - pdf_encoding_add_usedchars(font->encoding_id, font->usedchars); + if (font->encoding_id >= 0) { + if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) { + pdf_encoding_add_usedchars(font->encoding_id, font->usedchars); + } + } if (dpx_conf.verbose_level > 0) { - if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) - MESG(")"); + if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) { + MESG(")"); + } } } pdf_encoding_complete(); + /* Order is important... */ + for (font_id = 0; font_id < font_cache.count; font_id++) { + pdf_font *font = &font_cache.fonts[font_id]; + + if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) || + (font->flags & PDF_FONT_FLAG_IS_REENCODE)) { + continue; + } + + switch (font->subtype) { + case PDF_FONT_FONTTYPE_CIDTYPE0: + case PDF_FONT_FONTTYPE_CIDTYPE2: + pdf_font_load_cidfont(font); + break; + } + } for (font_id = 0; font_id < font_cache.count; font_id++) { - pdf_font *font = GET_FONT(font_id); + pdf_font *font; + + font = &font_cache.fonts[font_id]; - if (font->encoding_id >= 0 && font->subtype != PDF_FONT_FONTTYPE_TYPE0) { + if ((font->flags & PDF_FONT_FLAG_IS_ALIAS) || + (font->flags & PDF_FONT_FLAG_IS_REENCODE)) { + pdf_clean_font_struct(font); + continue; + } + + if (font->encoding_id >= 0 && + font->subtype != PDF_FONT_FONTTYPE_TYPE0 && + font->subtype != PDF_FONT_FONTTYPE_CIDTYPE0 && + font->subtype != PDF_FONT_FONTTYPE_CIDTYPE2) { pdf_obj *enc_obj = pdf_get_encoding_obj(font->encoding_id); 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)); + if (enc_obj) { + if (font->subtype == PDF_FONT_FONTTYPE_TRUETYPE) { + if (pdf_encoding_is_predefined(font->encoding_id) && PDF_OBJ_NAMETYPE(enc_obj)) { + pdf_add_dict(font->resource, + pdf_new_name("Encoding"), pdf_link_obj(enc_obj)); + } + } else { + pdf_add_dict(font->resource, + pdf_new_name("Encoding"), + PDF_OBJ_NAMETYPE(enc_obj) ? pdf_link_obj(enc_obj) : pdf_ref_obj(enc_obj)); + } + } /* For built-in encoding, each font loader create ToUnicode CMap. */ if (!pdf_lookup_dict(font->resource, "ToUnicode")) { tounicode = pdf_encoding_get_tounicode(font->encoding_id); @@ -529,17 +627,15 @@ pdf_close_fonts (void) pdf_new_name("Encoding"), pdf_new_name("MacRomanEncoding")); } - pdf_flush_font(font); pdf_clean_font_struct(font); } + RELEASE(font_cache.fonts); font_cache.fonts = NULL; font_cache.count = 0; font_cache.capacity = 0; - Type0Font_cache_close(); - CMap_cache_close(); pdf_close_encodings(); @@ -549,19 +645,148 @@ pdf_close_fonts (void) } int -pdf_font_findresource (const char *tex_name, - double font_scale, fontmap_rec *mrec) +pdf_font_findresource (const char *ident, double scale) +{ + int font_id, found = 0; + + for (font_id = 0; font_id < font_cache.count; font_id++) { + pdf_font *font; + + font = &font_cache.fonts[font_id]; + switch (font->subtype) { + case PDF_FONT_FONTTYPE_TYPE1: + case PDF_FONT_FONTTYPE_TYPE1C: + case PDF_FONT_FONTTYPE_TRUETYPE: + case PDF_FONT_FONTTYPE_TYPE0: + if (!strcmp(ident, font->ident)) { + found = 1; + } + 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(ident, font->ident) && scale == font->point_size) { + found = 1; + } + break; + } + + if (found) { + if (dpx_conf.verbose_level > 0) { + MESG("\npdf_font>> Font \"%s\" (enc_id=%d) found at id=%d.\n", font->ident, font->encoding_id, font_id); + } + break; + } + } + + return found ? font_id : -1; +} + +#if 1 +static void +compat_set_mapchar (int cmap_id, fontmap_rec *mrec) +{ + 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); + + 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 (dpx_conf.verbose_level > 0) { + 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; + } + + return; +} +#endif + +static int +create_font_alias (const char *ident, int font_id) +{ + int this_id; + pdf_font *font, *src; + + if (font_id < 0 || font_id >= font_cache.count) + return -1; + + src = &font_cache.fonts[font_id]; + + this_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 = &font_cache.fonts[this_id]; + pdf_init_font_struct(font); + + font->ident = NEW(strlen(ident) + 1, char); + strcpy(font->ident, ident); + font->font_id = font_id; + font->subtype = src->subtype; + font->encoding_id = src->encoding_id; + + font->flags |= PDF_FONT_FLAG_IS_ALIAS; + + font_cache.count++; + + return this_id; +} + +static int +create_font_reencoded (const char *ident, int font_id, int cmap_id) +{ + int this_id; + pdf_font *font; + + if (font_cache.count + 1 >= font_cache.capacity) { + font_cache.capacity += CACHE_ALLOC_SIZE; + font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font); + } + + this_id = font_cache.count; + font = &font_cache.fonts[this_id]; + pdf_init_font_struct(font); + font->ident = NEW(strlen(ident) + 1, char); + strcpy(font->ident, ident); + font->font_id = font_id; + font->subtype = PDF_FONT_FONTTYPE_TYPE0; + font->encoding_id = cmap_id; + font->flags |= PDF_FONT_FLAG_IS_REENCODE; + font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED; + font_cache.count++; + + return this_id; +} + +int +pdf_font_load_font (const char *ident, double font_scale, fontmap_rec *mrec) { - int font_id = -1; - pdf_font *font; - int encoding_id = -1, cmap_id = -1; - const char *fontname; + int font_id = -1; + pdf_font *font; + int encoding_id = -1, cmap_id = -1; + const char *fontname; /* * Get appropriate info from map file. (PK fonts at two different * point sizes would be looked up twice unecessarily.) */ - fontname = mrec ? mrec->font_name : tex_name; + fontname = mrec ? mrec->font_name : ident; /* 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 @@ -580,253 +805,218 @@ pdf_font_findresource (const char *tex_name, 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 < 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)) { + 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)); + } + } else if (!strstr(mrec->enc_name, ".enc") || strstr(mrec->enc_name, ".cmap")) { cmap_id = CMap_cache_find(mrec->enc_name); +#if 1 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 (dpx_conf.verbose_level > 0) { - 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..."); + compat_set_mapchar(cmap_id, mrec); } +#endif } 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); } } - if (mrec && cmap_id >= 0) { - /* - * Composite Font - */ - int type0_id, found = 0; - type0_id = Type0Font_cache_find(mrec->font_name, cmap_id, &mrec->opt); - if (type0_id < 0) { + if (mrec && mrec->enc_name) { + if (cmap_id < 0 && encoding_id < 0) { + WARN("Could not read encoding file: %s", mrec->enc_name); return -1; } + } - for (font_id = 0; - 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 (dpx_conf.verbose_level > 0) { - MESG("\npdf_font>> Type0 font \"%s\" (cmap_id=%d) found at font_id=%d.\n", - mrec->font_name, cmap_id, font_id); - } - break; + if (mrec && cmap_id >= 0) { + /* Composite font */ + CMap *cmap; + CIDSysInfo *csi; + int wmode, cid_id; + + cmap = CMap_cache_get(cmap_id); + csi = CMap_is_Identity(cmap) ? NULL : CMap_get_CIDSysInfo(cmap); + wmode = CMap_get_wmode(cmap); + + cid_id = pdf_font_cidfont_lookup_cache(font_cache.fonts, font_cache.count, mrec->font_name, csi, &mrec->opt); + if (cid_id >= 0) { + for (font_id = 0; font_id < font_cache.count; font_id++) { + font = &font_cache.fonts[font_id]; + if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) + continue; + if (font->type0.wmode == wmode && font->type0.descendant == cid_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); + if (font_id >= 0 && font_id < font_cache.count) { + font = &font_cache.fonts[font_id]; + if (font->encoding_id == cmap_id) { + if (dpx_conf.verbose_level > 0) { + MESG("\npdf_font>> Type0 font \"%s\" cmap_id=<%s,%d> found at font_id=<%s,%d>.\n", + mrec->font_name, mrec->enc_name, cmap_id, pdf_get_font_ident(font_id), font_id); + } + if (!strcmp(ident, font->ident)) { + return font_id; + } else { + return create_font_alias(ident, font_id); + } + } else { + if (dpx_conf.verbose_level > 0) { + MESG("\npdf_font>> Type0 font \"%s\" cmap_id=<%s,%d> found at font_id=<%s,%d>. (re-encoded)\n", + mrec->font_name, mrec->enc_name, cmap_id, pdf_get_font_ident(font_id), font_id); + } + return create_font_reencoded(ident, font_id, cmap_id); + } } - font = GET_FONT(font_id); - pdf_init_font_struct(font); + } - font->font_id = type0_id; - font->subtype = PDF_FONT_FONTTYPE_TYPE0; - font->encoding_id = cmap_id; + /* plus one for CIDFont */ + if (font_cache.count + 1 >= font_cache.capacity) { + font_cache.capacity += CACHE_ALLOC_SIZE; + font_cache.fonts = RENEW(font_cache.fonts, font_cache.capacity, pdf_font); + } - font_cache.count++; + if (cid_id < 0) { + pdf_font *cidfont; - if (dpx_conf.verbose_level > 0) { - 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); + cid_id = font_cache.count; + cidfont = &font_cache.fonts[cid_id]; + pdf_init_font_struct(cidfont); + if (pdf_font_open_cidfont(cidfont, fontname, csi, &mrec->opt) < 0) { + pdf_clean_font_struct(cidfont); + return -1; } + font_cache.count++; + } + font_id = font_cache.count; + font = &font_cache.fonts[font_id]; + pdf_init_font_struct(font); + if (pdf_font_open_type0(font, cid_id, wmode) < 0) { + pdf_clean_font_struct(font); + return -1; + } + font->ident = NEW(strlen(ident) + 1, char); + strcpy(font->ident, ident); + font->subtype = PDF_FONT_FONTTYPE_TYPE0; + font->encoding_id = cmap_id; + + font_cache.count++; + if (dpx_conf.verbose_level > 0) { + MESG("\n"); + MESG("pdf_font>> Type0 font \"%s\" ", fontname); + MESG("cmap_id=<%s,%d> ", mrec->enc_name, font->encoding_id); + MESG("font_id=<%s,%d>.", ident, font_id); + MESG("\n"); } } else { - /* - * Simple Font - always embed. - */ - int found = 0; - - for (font_id = 0; - font_id < font_cache.count; font_id++) { - font = GET_FONT(font_id); + /* Simple Font - always embed. */ + for (font_id = 0; font_id < font_cache.count; font_id++) { + font = &font_cache.fonts[font_id]; + if (font->flags & PDF_FONT_FLAG_IS_ALIAS) + continue; 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) { - if (mrec && mrec->opt.index == font->index) - found = 1; - } - break; + /* 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->filename) && encoding_id == font->encoding_id && + (!mrec || mrec->opt.index == font->index)) { + if (dpx_conf.verbose_level > 0) { + MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", fontname, encoding_id, font_id); + } + if (!strcmp(ident, font->ident)) { + return font_id; + } else { + return create_font_alias(ident, font_id); + } + } + 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; - case PDF_FONT_FONTTYPE_TYPE0: - break; - default: - ERROR("Unknown font type: %d", font->subtype); - break; - } - - if (found) { - if (dpx_conf.verbose_level > 0) { - MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", - fontname, encoding_id, font_id); - } - 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->filename) && font_scale == font->point_size) { + if (dpx_conf.verbose_level > 0) { + MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n", fontname, encoding_id, font_id); + } + if (!strcmp(ident, font->ident)) { + return font_id; + } else { + return create_font_alias(ident, font_id); + } + } + break; } } + 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); + } - 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 = GET_FONT(font_id); - - pdf_init_font_struct(font); - - font->point_size = font_scale; - font->encoding_id = encoding_id; - font->ident = NEW(strlen(fontname) + 1, char); - strcpy(font->ident, fontname); - font->map_name = NEW(strlen(tex_name) + 1, char); - strcpy(font->map_name, 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; - } else if (pdf_font_open_type1c(font) >= 0) { - font->subtype = PDF_FONT_FONTTYPE_TYPE1C; - } else if (pdf_font_open_truetype(font) >= 0) { - font->subtype = PDF_FONT_FONTTYPE_TRUETYPE; - } else if (pdf_font_open_pkfont(font) >= 0) { - font->subtype = PDF_FONT_FONTTYPE_TYPE3; - } else { - pdf_clean_font_struct(font); - return -1; - } + font = &font_cache.fonts[font_id]; + pdf_init_font_struct(font); + + font->ident = NEW(strlen(ident) + 1, char); + strcpy(font->ident, ident); + font->encoding_id = encoding_id; + font->filename = NEW(strlen(fontname) + 1, char); + strcpy(font->filename, fontname); + font->index = (mrec && mrec->opt.index) ? mrec->opt.index : 0; + font->flags |= (mrec && (mrec->opt.flags & FONTMAP_OPT_NOEMBED)) ? PDF_FONT_FLAG_NOEMBED : 0; + if (pdf_font_open_type1(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) { + font->subtype = PDF_FONT_FONTTYPE_TYPE1; + } else if (pdf_font_open_type1c(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) { + font->subtype = PDF_FONT_FONTTYPE_TYPE1C; + } else if (pdf_font_open_truetype(font, font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1) >= 0) { + font->subtype = PDF_FONT_FONTTYPE_TRUETYPE; + } else if (pdf_font_open_pkfont(font,font->filename, font->index, font->encoding_id, (font->flags & PDF_FONT_FLAG_NOEMBED) ? 0 : 1, font->point_size) >= 0) { + font->subtype = PDF_FONT_FONTTYPE_TYPE3; + } else { + pdf_clean_font_struct(font); + return -1; + } - font_cache.count++; + font_cache.count++; - if (dpx_conf.verbose_level > 0) { - 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); - } + if (dpx_conf.verbose_level > 0) { + MESG("\n"); + MESG("pdf_font>> Simple font \"%s\" ", fontname); + MESG("enc_id=<%s,%d> ", (mrec && mrec->enc_name) ? mrec->enc_name : "builtin", font->encoding_id); + MESG("font_id=<%s,%d>.", ident, font_id); + MESG("\n"); } } return font_id; } -int -pdf_font_is_in_use (pdf_font *font) -{ - ASSERT(font); - - return ((font->reference) ? 1 : 0); -} - -uint32_t -pdf_font_get_index (pdf_font *font) -{ - ASSERT(font); - - return font->index; -} - -char * -pdf_font_get_ident (pdf_font *font) -{ - ASSERT(font); - - return font->ident; -} - -char * -pdf_font_get_mapname (pdf_font *font) -{ - ASSERT(font); - - return font->map_name; -} - -char * -pdf_font_get_fontname (pdf_font *font) -{ - ASSERT(font); - - return font->fontname; -} - pdf_obj * pdf_font_get_resource (pdf_font *font) { @@ -834,21 +1024,17 @@ pdf_font_get_resource (pdf_font *font) if (!font->resource) { font->resource = pdf_new_dict(); - pdf_add_dict(font->resource, - pdf_new_name("Type"), pdf_new_name("Font")); + pdf_add_dict(font->resource, pdf_new_name("Type"), pdf_new_name("Font")); switch (font->subtype) { case PDF_FONT_FONTTYPE_TYPE1: case PDF_FONT_FONTTYPE_TYPE1C: - pdf_add_dict(font->resource, - pdf_new_name("Subtype"), pdf_new_name("Type1")); + pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("Type1")); break; case PDF_FONT_FONTTYPE_TYPE3: - pdf_add_dict(font->resource, - pdf_new_name("Subtype"), pdf_new_name("Type3")); + pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("Type3")); break; case PDF_FONT_FONTTYPE_TRUETYPE: - pdf_add_dict(font->resource, - pdf_new_name("Subtype"), pdf_new_name("TrueType")); + pdf_add_dict(font->resource, pdf_new_name("Subtype"), pdf_new_name("TrueType")); break; default: break; @@ -863,71 +1049,17 @@ pdf_font_get_descriptor (pdf_font *font) { ASSERT(font); - if (!font->descriptor) { + if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) { + return NULL; + } else if (!font->descriptor) { font->descriptor = pdf_new_dict(); - pdf_add_dict(font->descriptor, - pdf_new_name("Type"), pdf_new_name("FontDescriptor")); + pdf_add_dict(font->descriptor, pdf_new_name("Type"), pdf_new_name("FontDescriptor")); } return font->descriptor; } char * -pdf_font_get_usedchars (pdf_font *font) -{ - ASSERT(font); - - return font->usedchars; -} - -int -pdf_font_get_encoding (pdf_font *font) -{ - ASSERT(font); - - return font->encoding_id; -} - -int -pdf_font_get_flag (pdf_font *font, int mask) -{ - ASSERT(font); - - return ((font->flags & mask) ? 1 : 0); -} - -#if 0 -int -pdf_font_get_flags (pdf_font *font) -{ - ASSERT(font); - - return font->flags; -} -#endif /* 0 */ - -double -pdf_font_get_param (pdf_font *font, int param_type) -{ - double param = 0.0; - - ASSERT(font); - - switch (param_type) { - case PDF_FONT_PARAM_DESIGN_SIZE: - param = font->design_size; - break; - case PDF_FONT_PARAM_POINT_SIZE: - param = font->point_size; - break; - default: - break; - } - - return param; -} - -char * pdf_font_get_uniqueTag (pdf_font *font) { ASSERT(font); @@ -939,41 +1071,51 @@ pdf_font_get_uniqueTag (pdf_font *font) return font->uniqueID; } -int -pdf_font_set_fontname (pdf_font *font, const char *fontname) -{ - ASSERT(font && fontname); - - if (strlen(fontname) > PDF_NAME_LEN_MAX) { - ERROR("Unexpected error..."); - return -1; - } - if (font->fontname) { - RELEASE(font->fontname); - } - font->fontname = NEW(strlen(fontname)+1, char); - strcpy(font->fontname, fontname); - - return 0; -} - -int -pdf_font_set_subtype (pdf_font *font, int subtype) -{ - ASSERT(font); - - font->subtype = subtype; +/* + * Please don’t use TFM widths for the /Widths + * entry of the font dictionary. + * + * PDF 32000-1:2008 (p.255) + * + * These widths shall be consistent with the + * actual widths given in the font program. + */ - return 0; -} +#include "tfm.h" int -pdf_font_set_flags (pdf_font *font, int flags) +pdf_check_tfm_widths (const char *ident, double *widths, int firstchar, int lastchar, const char *usedchars) { - ASSERT(font); + int error = 0; + int tfm_id, code, count = 0; + double sum = 0.0; + double tolerance = 1.0; + int override = 0; /* Don't set to 1! */ + + tfm_id = tfm_open(ident, 0); + if (tfm_id < 0) + return 0; + for (code = firstchar; code <= lastchar; code++) { + if (usedchars[code]) { + double width, diff; + + width = 1000. * tfm_get_width(tfm_id, code); + diff = widths[code] - width; + diff = diff < 0 ? -diff : diff; + if (override) { + widths[code] = width; + } else if (diff > tolerance) { + if (dpx_conf.verbose_level > 0) { + WARN("Intolerable difference in glyph width: font=%s, char=%d", ident, code); + WARN("font: %g vs. tfm: %g", widths[code], width); + } + sum += diff; + } + count++; + } + } - font->flags |= flags; + error = sum > 0.5 * count * tolerance ? -1 : 0; - return 0; + return override ? 0 : error; } - diff --git a/Build/source/texk/dvipdfm-x/pdffont.h b/Build/source/texk/dvipdfm-x/pdffont.h index 65ba9d6fda0..7d20f39eb1e 100644 --- a/Build/source/texk/dvipdfm-x/pdffont.h +++ b/Build/source/texk/dvipdfm-x/pdffont.h @@ -33,66 +33,132 @@ #define PDF_FONT_FONTTYPE_TRUETYPE 3 #define PDF_FONT_FONTTYPE_TYPE0 4 +#define PDF_FONT_FONTTYPE_CIDTYPE0 5 +#define PDF_FONT_FONTTYPE_CIDTYPE2 6 extern void pdf_font_set_dpi (int font_dpi); -#define PDF_FONT_FLAG_NOEMBED (1 << 0) -#define PDF_FONT_FLAG_COMPOSITE (1 << 1) -#define PDF_FONT_FLAG_BASEFONT (1 << 2) +#define PDF_FONT_FLAG_NOEMBED (1 << 0) +#define PDF_FONT_FLAG_COMPOSITE (1 << 1) +#define PDF_FONT_FLAG_BASEFONT (1 << 2) +#define PDF_FONT_FLAG_USEDCHAR_SHARED (1 << 3) +#define PDF_FONT_FLAG_IS_ALIAS (1 << 4) +#define PDF_FONT_FLAG_IS_REENCODE (1 << 5) +#define PDF_FONT_FLAG_ACCFONT (1 << 6) +#define PDF_FONT_FLAG_UCSFONT (1 << 7) + +/* FIXME */ +/* Converted from Type 1 */ +#define CIDFONT_FLAG_TYPE1 (1 << 8) +#define CIDFONT_FLAG_TYPE1C (1 << 9) +#define CIDFONT_FLAG_TRUETYPE (1 << 10) #define PDF_FONT_PARAM_DESIGN_SIZE 1 #define PDF_FONT_PARAM_POINT_SIZE 2 +#include "fontmap.h" +#define FONT_STYLE_NONE FONTMAP_STYLE_NONE +#define FONT_STYLE_BOLD FONTMAP_STYLE_BOLD +#define FONT_STYLE_ITALIC FONTMAP_STYLE_ITALIC +#define FONT_STYLE_BOLDITALIC FONTMAP_STYLE_BOLDITALIC + +typedef struct { + char *registry; + char *ordering; + int supplement; +} CIDSysInfo; + +typedef struct +{ + CIDSysInfo csi; + int style; + int embed; + int stemv; +} cid_opt; + +struct pdf_font +{ + char *ident; /* map name */ + int font_id; /* ID of this font */ + int subtype; + + char *filename; + + int encoding_id; /* encoding or CMap */ + + uint32_t index; + char *fontname; + char uniqueID[7]; + + /* + * PDF font resource objects + */ + pdf_obj *reference; + pdf_obj *resource; + pdf_obj *descriptor; + + /* + * Font format specific data + */ + char *usedchars; + int flags; + + /* PK font */ + double point_size; + double design_size; + + /* Type0 font */ + struct { + int descendant; /* Only single descendant is allowed. */ + int wmode; + } type0; + + /* CIDFont */ + struct { + CIDSysInfo csi; /* Character collection */ + cid_opt options; /* Options from map record */ + char *usedchars_v; + } cid; +}; + typedef struct pdf_font pdf_font; /* pdf_open_document() call them. */ extern void pdf_init_fonts (void); extern void pdf_close_fonts (void); -/* font_name is used when mrec is NULL. +/* tex_name is used when mrec is NULL. * font_scale (point size) used by PK font. * It might be necessary if dvipdfmx supports font format with * various optical sizes supported in the future. */ -extern int pdf_font_findresource (const char *font_name, - double font_scale, fontmap_rec *mrec); +extern int pdf_font_findresource (const char *tex_name, double font_scale); +extern int pdf_font_load_font (const char *tex_name, double font_scale, fontmap_rec *mrec); -extern int pdf_get_font_subtype (int font_id); -extern pdf_obj *pdf_get_font_reference (int font_id); -extern char *pdf_get_font_usedchars (int font_id); +extern pdf_font *pdf_get_font_data (int font_id); -#if 0 -extern char *pdf_get_font_fontname (int font_id); /* without unique tag */ -#endif /* 0 */ -extern int pdf_get_font_encoding (int font_id); -extern int pdf_get_font_wmode (int font_id); +extern char *pdf_get_font_ident (int font_id); +extern int pdf_get_font_subtype (int font_id); +extern pdf_obj *pdf_get_font_reference (int font_id); +extern pdf_obj *pdf_get_font_resource (int font_id); +extern char *pdf_get_font_usedchars (int font_id); -/* Each font drivers use the followings. */ -extern int pdf_font_is_in_use (pdf_font *font); +extern int pdf_get_font_encoding (int font_id); +extern int pdf_get_font_wmode (int font_id); -extern char *pdf_font_get_ident (pdf_font *font); -extern char *pdf_font_get_mapname (pdf_font *font); -extern char *pdf_font_get_fontname (pdf_font *font); /* without unique tag */ -extern char *pdf_font_get_uniqueTag (pdf_font *font); +extern int pdf_font_resource_name (int font_id, char *buf); -extern pdf_obj *pdf_font_get_resource (pdf_font *font); -extern pdf_obj *pdf_font_get_descriptor (pdf_font *font); -extern char *pdf_font_get_usedchars (pdf_font *font); -extern int pdf_font_get_encoding (pdf_font *font); +extern char *pdf_font_get_uniqueTag (pdf_font *font); -extern int pdf_font_get_flag (pdf_font *font, int mask); -#if 0 -extern int pdf_font_get_flags (pdf_font *font); -#endif /* 0 */ -extern double pdf_font_get_param (pdf_font *font, int type); +extern pdf_obj *pdf_font_get_resource (pdf_font *font); +extern pdf_obj *pdf_font_get_descriptor (pdf_font *font); -extern uint32_t pdf_font_get_index (pdf_font *font); +extern void pdf_font_make_uniqueTag (char *tag); -extern int pdf_font_set_fontname (pdf_font *font, const char *fontname); -extern int pdf_font_set_flags (pdf_font *font, int flags); -extern int pdf_font_set_subtype (pdf_font *font, int subtype); +#define add_to_used_chars2(b,c) {(b)[(c)/8] |= (1 << (7-((c)%8)));} +#define is_used_char2(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8)))) -extern void pdf_font_make_uniqueTag (char *tag); +extern int pdf_check_tfm_widths (const char *ident, double *widths, int firstchar, int lastchar, const char *usedchars); #endif /* _PDFFONT_H_ */ diff --git a/Build/source/texk/dvipdfm-x/pkfont.c b/Build/source/texk/dvipdfm-x/pkfont.c index 9eb00f28c0c..1e4173bd397 100644 --- a/Build/source/texk/dvipdfm-x/pkfont.c +++ b/Build/source/texk/dvipdfm-x/pkfont.c @@ -98,20 +98,19 @@ dpx_open_pk_font_at (const char *ident, unsigned dpi) int -pdf_font_open_pkfont (pdf_font *font) +pdf_font_open_pkfont (pdf_font *font, const char *ident, int index, int encoding_id, int embedding, double point_size) { - char *ident; - double point_size; - int encoding_id; unsigned dpi; FILE *fp; - ident = pdf_font_get_ident(font); - point_size = pdf_font_get_param(font, PDF_FONT_PARAM_POINT_SIZE); - encoding_id = pdf_font_get_encoding(font); - if (!ident || point_size <= 0.0) return -1; + if (!embedding) { + WARN("Ignoring no-embed option for PK font: %s", ident); + } + if (index != 0) { + WARN("Ignoring font index option for PK font: %s", ident); + } dpi = truedpi(ident, point_size, base_dpi); fp = dpx_open_pk_font_at(ident, dpi); @@ -122,7 +121,8 @@ pdf_font_open_pkfont (pdf_font *font) /* Type 3 fonts doesn't have FontName. * FontFamily is recommended for PDF 1.5. */ - pdf_font_set_fontname(font, ident); + font->fontname = NEW(strlen(ident)+1, char); + strcpy(font->fontname, ident); if (encoding_id >= 0) { pdf_encoding_used_by_type3(encoding_id); @@ -502,15 +502,14 @@ pdf_font_load_pkfont (pdf_font *font) #endif /* ENABLE_GLYPHENC */ int error = 0; - if (!pdf_font_is_in_use(font)) { + if (!font->reference) return 0; - } - ident = pdf_font_get_ident(font); - point_size = pdf_font_get_param(font, PDF_FONT_PARAM_POINT_SIZE); - usedchars = pdf_font_get_usedchars(font); + ident = font->filename; + point_size = font->point_size; + usedchars = font->usedchars; #if ENABLE_GLYPHENC - encoding_id = pdf_font_get_encoding(font); + encoding_id = font->encoding_id; if (encoding_id < 0) enc_vec = NULL; else { diff --git a/Build/source/texk/dvipdfm-x/pkfont.h b/Build/source/texk/dvipdfm-x/pkfont.h index c06929c6565..f65fdfa24e4 100644 --- a/Build/source/texk/dvipdfm-x/pkfont.h +++ b/Build/source/texk/dvipdfm-x/pkfont.h @@ -25,7 +25,7 @@ #include "pdffont.h" -extern int pdf_font_open_pkfont (pdf_font *font); +extern int pdf_font_open_pkfont (pdf_font *font, const char *ident, int index, int encoding_id, int embedding, double point_size); extern int pdf_font_load_pkfont (pdf_font *font); extern void PKFont_set_dpi(int dpi); diff --git a/Build/source/texk/dvipdfm-x/truetype.c b/Build/source/texk/dvipdfm-x/truetype.c index dd10bb6be8a..d9ba0ed6325 100644 --- a/Build/source/texk/dvipdfm-x/truetype.c +++ b/Build/source/texk/dvipdfm-x/truetype.c @@ -51,35 +51,27 @@ #include "truetype.h" -#include "tfm.h" - /* Modifying this has no effect :P */ #ifdef ENABLE_NOEMBED # undef ENABLE_NOEMBED #endif int -pdf_font_open_truetype (pdf_font *font) +pdf_font_open_truetype (pdf_font *font, const char *ident, int index, int encoding_id, int embedding) { - char *ident; - int index, encoding_id; pdf_obj *fontdict, *descriptor; sfnt *sfont; - int embedding = 1; /* Must be embedded. */ FILE *fp = NULL; int length, error = 0; - ASSERT( font ); - - ident = pdf_font_get_ident(font); - index = pdf_font_get_index(font); - - ASSERT( ident ); + ASSERT(font); + ASSERT(ident); fp = DPXFOPEN(ident, DPX_RES_TYPE_TTFONT); if (!fp) { fp = DPXFOPEN(ident, DPX_RES_TYPE_DFONT); - if (!fp) return -1; + if (!fp) + return -1; sfont = dfont_open(fp, index); } else { sfont = sfnt_open(fp); @@ -94,13 +86,17 @@ pdf_font_open_truetype (pdf_font *font) if (sfont->type == SFNT_TYPE_TTC) { ULONG offset; + offset = ttc_read_offset(sfont, index); - if (offset == 0) ERROR("Invalid TTC index in %s.", ident); - error = sfnt_read_table_directory(sfont, offset); + if (offset == 0) { + WARN("Invalid TTC index in %s.", ident); + error = -1; + } else { + error = sfnt_read_table_directory(sfont, offset); + } } else { error = sfnt_read_table_directory(sfont, sfont->offset); } - if (error) { sfnt_close(sfont); if (fp) @@ -111,19 +107,22 @@ pdf_font_open_truetype (pdf_font *font) /* Reading fontdict before checking fonttype conflicts with PKFONT * because pdf_font_get_resource() always makes a dictionary. */ - encoding_id = pdf_font_get_encoding(font); - fontdict = pdf_font_get_resource(font); - descriptor = pdf_font_get_descriptor(font); -#ifdef ENABLE_NOEMBED - embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; + fontdict = pdf_font_get_resource(font); + descriptor = pdf_font_get_descriptor(font); +#ifndef ENABLE_NOEMBED + if (!embedding) { + WARN("No-embed option not supported for TrueType font: %s", ident); + embedding = 1; + font->flags &= ~PDF_FONT_FLAG_NOEMBED; + } #endif /* ENABLE_NOEMBED */ ASSERT( fontdict && descriptor ); { - char fontname[256]; - int n; - pdf_obj *tmp; + char fontname[256]; + int n; + pdf_obj *tmp; memset(fontname, 0, 256); length = tt_get_ps_fontname(sfont, fontname, 255); @@ -137,30 +136,38 @@ pdf_font_open_truetype (pdf_font *font) memmove(fontname + n, fontname + n + 1, length - n - 1); } } - if (strlen(fontname) == 0) - ERROR("Can't find valid fontname for \"%s\".", ident); - pdf_font_set_fontname(font, fontname); - - tmp = tt_get_fontdesc(sfont, &embedding, -1, 1, fontname); - if (!tmp) { - ERROR("Could not obtain necessary font info."); - sfnt_close(sfont); - if (fp) - DPXFCLOSE(fp); - return -1; + if (strlen(fontname) == 0) { + WARN("Can't find valid fontname for \"%s\".", ident); + error = -1; + } else { + font->fontname = NEW(strlen(fontname)+1, char); + strcpy(font->fontname, fontname); + tmp = tt_get_fontdesc(sfont, &embedding, -1, 1, fontname); + if (!tmp) { + WARN("Could not obtain necessary font info: %s", ident); + error = -1; + } else { + ASSERT(pdf_obj_typeof(tmp) == PDF_DICT); + pdf_merge_dict(descriptor, tmp); + pdf_release_obj(tmp); + } } - ASSERT(pdf_obj_typeof(tmp) == PDF_DICT); - - pdf_merge_dict(descriptor, tmp); - pdf_release_obj(tmp); + } + if (error) { + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; } if (!embedding) { - if (encoding_id >= 0 && - !pdf_encoding_is_predefined(encoding_id)) { - ERROR("Custom encoding not allowed for non-embedded TrueType font."); - sfnt_close(sfont); - return -1; +#ifndef ENABLE_NOEMBED + WARN("Font file=\"%s\" can't be embedded due to liscence restrictions.", ident); + error = -1; +#else + if (encoding_id >= 0 && !pdf_encoding_is_predefined(encoding_id)) { + WARN("Custom encoding not allowed for non-embedded TrueType font: %s", ident); + error = -1; } else { /* There are basically no guarantee for font substitution * can work with "symblic" fonts. At least all glyphs @@ -170,13 +177,10 @@ pdf_font_open_truetype (pdf_font *font) * only to predefined encodings for this reason. Note that * "builtin" encoding means "MacRoman" here. */ - pdf_obj *tmp; - int flags; + pdf_obj *tmp; + int flags; -#ifndef ENABLE_NOEMBED - ERROR("Font file=\"%s\" can't be embedded due to liscence restrictions.", ident); -#endif /* ENABLE_NOEMBED */ - pdf_font_set_flags(font, PDF_FONT_FLAG_NOEMBED); + font->flags |= PDF_FONT_FLAG_NOEMBED; tmp = pdf_lookup_dict(descriptor, "Flags"); if (tmp && pdf_obj_typeof(tmp) == PDF_NUMBER) { flags = (int) pdf_number_value(tmp); @@ -185,18 +189,22 @@ pdf_font_open_truetype (pdf_font *font) pdf_add_dict(descriptor, pdf_new_name("Flags"), pdf_new_number(flags)); } } +#endif /* ENABLE_NOEMBED */ } sfnt_close(sfont); if (fp) DPXFCLOSE(fp); - pdf_add_dict(fontdict, - pdf_new_name("Type"), pdf_new_name("Font")); - pdf_add_dict(fontdict, - pdf_new_name("Subtype"), pdf_new_name("TrueType")); + if (!error) { + pdf_add_dict(fontdict, + pdf_new_name("Type"), pdf_new_name("Font")); + pdf_add_dict(fontdict, + pdf_new_name("Subtype"), pdf_new_name("TrueType")); + font->subtype = PDF_FONT_FONTTYPE_TRUETYPE; + } - return 0; + return error; } /* @@ -226,14 +234,13 @@ static void do_widths (pdf_font *font, double *widths) { pdf_obj *fontdict; - pdf_obj *tmparray; - int code, firstchar, lastchar, tfm_id; + pdf_obj *array; + int code, firstchar, lastchar; char *usedchars; - fontdict = pdf_font_get_resource (font); - usedchars = pdf_font_get_usedchars (font); + fontdict = font->resource; + usedchars = font->usedchars; - tmparray = pdf_new_array(); for (firstchar = 255, lastchar = 0, code = 0; code < 256; code++) { if (usedchars[code]) { if (code < firstchar) firstchar = code; @@ -242,29 +249,23 @@ do_widths (pdf_font *font, double *widths) } if (firstchar > lastchar) { WARN("No glyphs actually used???"); - pdf_release_obj(tmparray); return; } - tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + + pdf_check_tfm_widths(font->ident, widths, firstchar, lastchar, usedchars); + + array = pdf_new_array(); for (code = firstchar; code <= lastchar; code++) { if (usedchars[code]) { - double width; - if (tfm_id < 0) /* tfm is not found */ - width = widths[code]; - else - width = 1000. * tfm_get_width(tfm_id, code); - pdf_add_array(tmparray, - pdf_new_number(ROUND(width, 0.1))); + pdf_add_array(array, pdf_new_number(ROUND(widths[code], 0.1))); } else { - pdf_add_array(tmparray, pdf_new_number(0.0)); + pdf_add_array(array, pdf_new_number(0.0)); } } - - if (pdf_array_length(tmparray) > 0) { - pdf_add_dict(fontdict, - pdf_new_name("Widths"), pdf_ref_obj(tmparray)); + if (pdf_array_length(array) > 0) { + pdf_add_dict(fontdict, pdf_new_name("Widths"), pdf_ref_obj(array)); } - pdf_release_obj(tmparray); + pdf_release_obj(array); pdf_add_dict(fontdict, pdf_new_name("FirstChar"), pdf_new_number(firstchar)); @@ -327,7 +328,7 @@ do_builtin_encoding (pdf_font *font, const char *usedchars, sfnt *sfont) gid = tt_cmap_lookup(ttcm, code); if (gid == 0) { WARN("Glyph for character code=0x%02x missing in font font-file=\"%s\".", - code, pdf_font_get_ident(font)); + code, font->filename); idx = 0; } else { idx = tt_find_glyph(glyphs, gid); @@ -785,8 +786,7 @@ do_custom_encoding (pdf_font *font, error = setup_glyph_mapper(&gm, sfont); if (error) { - WARN("No post table nor Unicode cmap found in font: %s", - pdf_font_get_ident(font)); + WARN("No post table nor Unicode cmap found in font: %s", font->filename); WARN(">> I can't find glyphs without this!"); return -1; } @@ -811,7 +811,7 @@ do_custom_encoding (pdf_font *font, if (!encoding[code] || !strcmp(encoding[code], ".notdef")) { WARN("Character code=\"0x%02X\" mapped to \".notdef\" glyph used in font font-file=\"%s\"", - code, pdf_font_get_ident(font)); + code, font->filename); WARN(">> Maybe incorrect encoding specified?"); idx = 0; } else { @@ -826,7 +826,7 @@ do_custom_encoding (pdf_font *font, */ if (error) { WARN("Glyph \"%s\" not available in font \"%s\".", - encoding[code], pdf_font_get_ident(font)); + encoding[code], font->filename); } else { if (dpx_conf.verbose_level > 1) MESG("truetype>> Glyph glyph-name=\"%s\" found at glyph-id=\"%u\".\n", encoding[code], gid); @@ -871,21 +871,21 @@ do_custom_encoding (pdf_font *font, int pdf_font_load_truetype (pdf_font *font) { - pdf_obj *descriptor = pdf_font_get_descriptor(font); - char *ident = pdf_font_get_ident(font); - int encoding_id = pdf_font_get_encoding(font); - char *usedchars = pdf_font_get_usedchars(font); + pdf_obj *descriptor = font->descriptor; + char *ident = font->filename; + int encoding_id = font->encoding_id; + char *usedchars = font->usedchars; #ifdef ENABLE_NOEMBED - int embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; + int embedding = font->flags & PDF_FONT_FLAG_NOEMBED ? 0 : 1; #endif /* ENABLE_NOEMBED */ - int index = pdf_font_get_index(font); + int index = font->index; char **enc_vec; pdf_obj *fontfile; FILE *fp = NULL; sfnt *sfont; int i, error = 0; - if (!pdf_font_is_in_use(font)) + if (!font->reference) return 0; fp = DPXFOPEN(ident, DPX_RES_TYPE_TTFONT); diff --git a/Build/source/texk/dvipdfm-x/truetype.h b/Build/source/texk/dvipdfm-x/truetype.h index 525caa5843d..fa5464c1834 100644 --- a/Build/source/texk/dvipdfm-x/truetype.h +++ b/Build/source/texk/dvipdfm-x/truetype.h @@ -25,7 +25,7 @@ #include "pdffont.h" -extern int pdf_font_open_truetype (pdf_font *font); +extern int pdf_font_open_truetype (pdf_font *font, const char *ident, int index, int encoding_id, int embedding); extern int pdf_font_load_truetype (pdf_font *font); #endif /* _TRUETYPE_H_ */ diff --git a/Build/source/texk/dvipdfm-x/type0.c b/Build/source/texk/dvipdfm-x/type0.c index 29c64bbd375..06699112945 100644 --- a/Build/source/texk/dvipdfm-x/type0.c +++ b/Build/source/texk/dvipdfm-x/type0.c @@ -42,103 +42,14 @@ #include "fontmap.h" #include "cmap.h" +#include "cidtype0.h" #include "cid.h" #include "type0.h" -#define TYPE0FONT_DEBUG_STR "Type0" -#define TYPE0FONT_DEBUG 3 - static pdf_obj *pdf_read_ToUnicode_file (const char *cmap_name); -/* - * used_chars: - * - * Single bit is used for each CIDs since used_chars can be reused as a - * stream content of CIDSet by doing so. See, cid.h for add_to_used() and - * is_used(). - */ - -static char * -new_used_chars2(void) -{ - char *used_chars; - - used_chars = NEW(8192, char); - memset(used_chars, 0, 8192); - - return used_chars; -} - -#define FLAG_NONE 0 -#define FLAG_USED_CHARS_SHARED (1 << 0) - -struct Type0Font { - char *fontname; /* BaseFont */ - char *encoding; /* "Identity-H" or "Identity-V" (not ID) */ - char *used_chars; /* Used chars (CIDs) */ - - /* - * Type0 only - */ - CIDFont *descendant; /* Only single descendant is allowed. */ - int flags; - int wmode; - int cmap_id; - - /* - * PDF Font Resource - */ - pdf_obj *indirect; - pdf_obj *fontdict; - pdf_obj *descriptor; /* MUST BE NULL */ -}; - -static void -Type0Font_init_font_struct (Type0Font *font) -{ - ASSERT(font); - - font->fontname = NULL; - font->fontdict = NULL; - font->indirect = NULL; - font->descriptor = NULL; - font->encoding = NULL; - font->used_chars = NULL; - font->descendant = NULL; - font->wmode = -1; - font->cmap_id = -1; - font->flags = FLAG_NONE; - - return; -} - -static void -Type0Font_clean (Type0Font *font) -{ - if (font) { - if (font->fontdict) - ERROR("%s: Object not flushed.", TYPE0FONT_DEBUG_STR); - if (font->indirect) - ERROR("%s: Object not flushed.", TYPE0FONT_DEBUG_STR); - if (font->descriptor) - ERROR("%s: FontDescriptor unexpected for Type0 font.", TYPE0FONT_DEBUG_STR); - if (!(font->flags & FLAG_USED_CHARS_SHARED) && font->used_chars) - RELEASE(font->used_chars); - if (font->encoding) - RELEASE(font->encoding); - if (font->fontname) - RELEASE(font->fontname); - font->fontdict = NULL; - font->indirect = NULL; - font->descriptor = NULL; - font->used_chars = NULL; - font->encoding = NULL; - font->fontname = NULL; - } -} - /* PLEASE FIX THIS */ #include "tt_cmap.h" @@ -147,7 +58,8 @@ Type0Font_clean (Type0Font *font) * 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) { +try_load_ToUnicode_file (char *cmap_base) +{ pdf_obj *tounicode; char *cmap_name; @@ -160,22 +72,14 @@ Type0Font_try_load_ToUnicode_stream(Type0Font *font, char *cmap_base) { } RELEASE(cmap_name); - if (!tounicode) { - CIDFont *cidfont = font->descendant; - tounicode = otf_create_ToUnicode_stream(CIDFont_get_ident(cidfont), - CIDFont_get_opt_index(cidfont), - CIDFont_get_fontname(cidfont), - Type0Font_get_usedchars(font)); - } - return tounicode; } static void -Type0Font_attach_ToUnicode_stream (Type0Font *font) +Type0Font_attach_ToUnicode_stream (pdf_font *font) { pdf_obj *tounicode; - CIDFont *cidfont; + pdf_font *cidfont = pdf_get_font_data(font->type0.descendant); CIDSysInfo *csi; char *fontname; @@ -187,12 +91,7 @@ Type0Font_attach_ToUnicode_stream (Type0Font *font) * ordering CID-keyed fonts. External resource must be loaded for * others. */ - - cidfont = font->descendant; - if (!cidfont) { - ERROR("%s: No descendant CID-keyed font.", TYPE0FONT_DEBUG_STR); - return; - } + ASSERT(cidfont); if (CIDFont_is_ACCFont(cidfont)) { /* No need to embed ToUnicode */ @@ -201,58 +100,52 @@ Type0Font_attach_ToUnicode_stream (Type0Font *font) /* * Old version of dvipdfmx mistakenly used Adobe-Identity as Unicode. */ + /* ref returned */ tounicode = pdf_read_ToUnicode_file("Adobe-Identity-UCS2"); if (!tounicode) { /* This should work */ - tounicode = pdf_new_name("Identity-H"); + tounicode = pdf_new_name("Identity-H"); } - pdf_add_dict(font->fontdict, pdf_new_name("ToUnicode"), tounicode); + pdf_add_dict(font->resource, pdf_new_name("ToUnicode"), tounicode); return; } tounicode = NULL; - csi = CIDFont_get_CIDSysInfo(cidfont); - fontname = CIDFont_get_fontname(cidfont); - if (CIDFont_get_embedding(cidfont)) { + csi = &cidfont->cid.csi; + fontname = cidfont->fontname; + if (cidfont->cid.options.embed) { fontname += 7; /* FIXME: Skip pseudo unique tag... */ } - if (!strcmp(csi->registry, "Adobe") && !strcmp(csi->ordering, "Identity")) { - switch (CIDFont_get_subtype(cidfont)) { - case CIDFONT_TYPE2: - /* PLEASE FIX THIS */ - { - tounicode = otf_create_ToUnicode_stream(CIDFont_get_ident(cidfont), - CIDFont_get_opt_index(cidfont), - CIDFont_get_fontname(cidfont), - Type0Font_get_usedchars(font)); - } - break; - default: - if (CIDFont_get_flag(cidfont, CIDFONT_FLAG_TYPE1C)) { - tounicode = otf_create_ToUnicode_stream(CIDFont_get_ident(cidfont), - CIDFont_get_opt_index(cidfont), - CIDFont_get_fontname(cidfont), - Type0Font_get_usedchars(font)); - } else if (CIDFont_get_flag(cidfont, CIDFONT_FLAG_TYPE1)) { - /* FIXME: handled on very different timing. - * Font loader will create ToUnicode and set. - */ - return; - } else { - tounicode = Type0Font_try_load_ToUnicode_stream(font, fontname); + switch (cidfont->subtype) { + case PDF_FONT_FONTTYPE_CIDTYPE2: + if (!strcmp(csi->registry, "Adobe") && !strcmp(csi->ordering, "Identity")) { + tounicode = otf_create_ToUnicode_stream(cidfont->ident, cidfont->index, + cidfont->fontname, font->usedchars); + } else { + char *cmap_base = NEW(strlen(csi->registry) + strlen(csi->ordering) + 2, char); + sprintf(cmap_base, "%s-%s", csi->registry, csi->ordering); + tounicode = try_load_ToUnicode_file(cmap_base); + RELEASE(cmap_base); + /* In this case glyphs are re-ordered hance otf_create... won't work */ + } + break; + default: + if (cidfont->flags & CIDFONT_FLAG_TYPE1C) { + tounicode = otf_create_ToUnicode_stream(cidfont->ident, cidfont->index, + cidfont->fontname, font->usedchars); + } else if (cidfont->flags & CIDFONT_FLAG_TYPE1) { + tounicode = CIDFont_type0_t1create_ToUnicode_stream(cidfont->ident, cidfont->fontname, font->usedchars); + } else { + tounicode = try_load_ToUnicode_file(fontname); + if (!tounicode) { + tounicode = otf_create_ToUnicode_stream(cidfont->ident, cidfont->index, + cidfont->fontname, font->usedchars); } - break; } - } else { - char *cmap_base = NEW(strlen(csi->registry) + strlen(csi->ordering) + 2, char); - sprintf(cmap_base, "%s-%s", csi->registry, csi->ordering); - tounicode = Type0Font_try_load_ToUnicode_stream(font, cmap_base); - RELEASE(cmap_base); } if (tounicode) { - pdf_add_dict(font->fontdict, - pdf_new_name("ToUnicode"), tounicode); + pdf_add_dict(font->resource, pdf_new_name("ToUnicode"), tounicode); } else { #if defined(LIBDPX) if (dpx_conf.verbose_level > 0) @@ -266,215 +159,31 @@ Type0Font_attach_ToUnicode_stream (Type0Font *font) } void -Type0Font_set_ToUnicode (Type0Font *font, pdf_obj *cmap_ref) -{ - ASSERT(font); - - pdf_add_dict(font->fontdict, - pdf_new_name("ToUnicode"), cmap_ref); -} - -static void -Type0Font_dofont (Type0Font *font) +pdf_font_load_type0 (pdf_font *font) { - if (!font || !font->indirect) + if (!font || !font->reference) return; /* FIXME: Should move to pdffont.c */ - if (!pdf_lookup_dict(font->fontdict, "ToUnicode")) { + if (!pdf_lookup_dict(font->resource, "ToUnicode")) { Type0Font_attach_ToUnicode_stream(font); } } -static void -Type0Font_flush (Type0Font *font) -{ - if (font) { - if (font->fontdict) - pdf_release_obj(font->fontdict); - font->fontdict = NULL; - if (font->indirect) - pdf_release_obj(font->indirect); - font->indirect = NULL; - if (font->descriptor) - ERROR("%s: FontDescriptor unexpected for Type0 font.", TYPE0FONT_DEBUG_STR); - font->descriptor = NULL; - } -} - int -Type0Font_get_wmode (Type0Font *font) +pdf_font_open_type0 (pdf_font *font, int cid_id, int wmode) { - ASSERT(font); - - return font->wmode; -} - -#if 0 -char * -Type0Font_get_encoding (Type0Font *font) -{ - ASSERT(font); - - return font->encoding; -} -#endif - -char * -Type0Font_get_usedchars (Type0Font *font) -{ - ASSERT(font); - - return font->used_chars; -} - -pdf_obj * -Type0Font_get_resource (Type0Font *font) -{ - ASSERT(font); - - /* - * This looks somewhat strange. - */ - if (!font->indirect) { - pdf_obj *array; - - array = pdf_new_array(); - pdf_add_array(array, CIDFont_get_resource(font->descendant)); - pdf_add_dict(font->fontdict, pdf_new_name("DescendantFonts"), array); - font->indirect = pdf_ref_obj(font->fontdict); - } - - return pdf_link_obj(font->indirect); -} - -/******************************** CACHE ********************************/ - -#define CHECK_ID(n) do {\ - if ((n) < 0 || (n) >= __cache.count)\ - ERROR("%s: Invalid ID %d", TYPE0FONT_DEBUG_STR, (n));\ -} while (0) - -#define CACHE_ALLOC_SIZE 16u - -static struct font_cache { - int count; - int capacity; - Type0Font *fonts; -} __cache = { - 0, 0, NULL -}; - -void -Type0Font_cache_init (void) -{ - if (__cache.fonts) - ERROR("%s: Already initialized.", TYPE0FONT_DEBUG_STR); - __cache.count = 0; - __cache.capacity = 0; - __cache.fonts = NULL; -} - -Type0Font * -Type0Font_cache_get (int id) -{ - CHECK_ID(id); - - return &__cache.fonts[id]; -} - -int -Type0Font_cache_find (const char *map_name, int cmap_id, fontmap_opt *fmap_opt) -{ - int font_id = -1; - Type0Font *font; - CIDFont *cidfont; - CMap *cmap; + pdf_font *cidfont; CIDSysInfo *csi; char *fontname = NULL; - int cid_id = -1, parent_id = -1, wmode = 0; - - if (!map_name || cmap_id < 0 || pdf_check_version(1, 2) < 0) - return -1; - - /* - * Encoding is Identity-H or Identity-V according as thier WMode value. - * - * We do not use match against the map_name since fonts (TrueType) covers - * characters across multiple character collection (eg, Adobe-Japan1 and - * Adobe-Japan2) must be splited into multiple CID-keyed fonts. - */ - - cmap = CMap_cache_get(cmap_id); - csi = (CMap_is_Identity(cmap)) ? NULL : CMap_get_CIDSysInfo(cmap) ; - - cid_id = CIDFont_cache_find(map_name, csi, fmap_opt); if (cid_id < 0) return -1; - /* - * The descendant CID-keyed font has already been registerd. - * If CID-keyed font with ID = cid_id is new font, then create new parent - * Type 0 font. Otherwise, there already exists parent Type 0 font and - * then we find him and return his ID. We must check against their WMode. - */ - - cidfont = CIDFont_cache_get(cid_id); - wmode = CMap_get_wmode(cmap); - - /* Does CID-keyed font already have parent ? */ - parent_id = CIDFont_get_parent_id(cidfont, wmode); - if (parent_id >= 0) - return parent_id; /* If so, we don't need new one. */ - - /* - * CIDFont does not have parent or his parent's WMode does not matched with - * wmode. Create new Type0 font. - */ - - if (__cache.count >= __cache.capacity) { - __cache.capacity += CACHE_ALLOC_SIZE; - __cache.fonts = RENEW(__cache.fonts, __cache.capacity, struct Type0Font); - } - font_id = __cache.count; - font = &__cache.fonts[font_id]; - - Type0Font_init_font_struct(font); - - /* - * All CJK double-byte characters are mapped so that resulting - * character codes coincide with CIDs of given character collection. - * So, the Encoding is always Identity-H for horizontal fonts or - * Identity-V for vertical fonts. - */ - if (wmode) { - font->encoding = NEW(strlen("Identity-V")+1, char); - strcpy(font->encoding, "Identity-V"); - } else { - font->encoding = NEW(strlen("Identity-H")+1, char); - strcpy(font->encoding, "Identity-H"); - } - font->wmode = wmode; - font->cmap_id = cmap_id; + cidfont = pdf_get_font_data(cid_id); - /* - * Now we start font dictionary. - */ - font->fontdict = pdf_new_dict(); - pdf_add_dict(font->fontdict, pdf_new_name ("Type"), pdf_new_name ("Font")); - pdf_add_dict(font->fontdict, pdf_new_name ("Subtype"), pdf_new_name ("Type0")); - - /* - * Type0 font does not have FontDescriptor because it is not a simple font. - * Instead, DescendantFonts appears here. - * - * Up to PDF version 1.5, Type0 font must have single descendant font which - * is a CID-keyed font. Future PDF spec. will allow multiple desecendant - * fonts. - */ - font->descendant = cidfont; - CIDFont_attach_parent(cidfont, font_id, wmode); + font->type0.wmode = wmode; + font->type0.descendant = cid_id; /* * PostScript Font name: @@ -482,96 +191,48 @@ Type0Font_cache_find (const char *map_name, int cmap_id, fontmap_opt *fmap_opt) * Type0 font's fontname is usually descendant CID-keyed font's font name * appended by -ENCODING. */ - fontname = CIDFont_get_fontname(cidfont); + fontname = cidfont->fontname; if (dpx_conf.verbose_level > 0) { - if (CIDFont_get_embedding(cidfont) && strlen(fontname) > 7) + if (cidfont->cid.options.embed && strlen(fontname) > 7) MESG("(CID:%s)", fontname+7); /* skip XXXXXX+ */ else MESG("(CID:%s)", fontname); } - /* - * The difference between CID-keyed font and TrueType font appears here. - * - * Glyph substitution for vertical writing is done in CMap mapping process - * for CID-keyed fonts. But we must rely on OpenType layout table in the - * case of TrueType fonts. So, we must use different used_chars for each - * horizontal and vertical fonts in that case. - * - * In most PDF file, encoding name is not appended to fontname for Type0 - * fonts having CIDFontType 2 font as their descendant. - */ - - font->used_chars = NULL; - font->flags = FLAG_NONE; - - switch (CIDFont_get_subtype(cidfont)) { - case CIDFONT_TYPE0: - font->fontname = NEW(strlen(fontname)+strlen(font->encoding)+2, char); - sprintf(font->fontname, "%s-%s", fontname, font->encoding); - pdf_add_dict(font->fontdict, - pdf_new_name("BaseFont"), pdf_new_name(font->fontname)); - /* - * Need used_chars to write W, W2. + switch (cidfont->subtype) { + case PDF_FONT_FONTTYPE_CIDTYPE0: + font->fontname = NEW(strlen(fontname)+strlen("Identity-V")+2, char); + sprintf(font->fontname, "%s-%s", fontname, wmode ? "Identity-V" : "Identity-H"); + font->usedchars = CIDFont_get_usedchars(cidfont); + font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED; + break; + case PDF_FONT_FONTTYPE_CIDTYPE2: + font->fontname = NEW(strlen(fontname)+1, char); + strcpy(font->fontname, fontname); + /* Adobe-Identity here means use GID as CID directly. No need to use GSUB for finding + * vertical glyphs hence separate used_chars for H and V instances are not needed. */ - if ((parent_id = CIDFont_get_parent_id(cidfont, wmode ? 0 : 1)) < 0) { - font->used_chars = new_used_chars2(); + csi = &cidfont->cid.csi; + if (!csi || (!strcmp(csi->registry, "Adobe") && !strcmp(csi->ordering, "Identity"))) { + font->usedchars = CIDFont_get_usedchars(cidfont); + font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED; } else { - /* Don't allocate new one. */ - font->used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id)); - font->flags |= FLAG_USED_CHARS_SHARED; + font->usedchars = wmode ? CIDFont_get_usedchars_v(cidfont) : CIDFont_get_usedchars(cidfont); + font->flags |= PDF_FONT_FLAG_USEDCHAR_SHARED; } break; - case CIDFONT_TYPE2: - /* - * TrueType: - * - * Use different used_chars for H and V. - */ - pdf_add_dict(font->fontdict, - pdf_new_name("BaseFont"), pdf_new_name(fontname)); - font->used_chars = new_used_chars2(); - break; - default: - ERROR("Unrecognized CIDFont Type"); - break; } - pdf_add_dict(font->fontdict, - pdf_new_name("Encoding"), pdf_new_name(font->encoding)); + font->resource = pdf_new_dict(); + pdf_add_dict(font->resource, pdf_new_name ("Type"), pdf_new_name ("Font")); + pdf_add_dict(font->resource, pdf_new_name ("Subtype"), pdf_new_name ("Type0")); + pdf_add_dict(font->resource, + pdf_new_name("BaseFont"), pdf_new_name(font->fontname)); + pdf_add_dict(font->resource, + pdf_new_name("Encoding"), pdf_new_name(wmode ? "Identity-V" : "Identity-H")); - __cache.count++; - - return font_id; -} - -void -Type0Font_cache_close (void) -{ - int font_id; - - /* - * This need to be fixed. - * - * CIDFont_cache_close() before Type0Font_release because of used_chars. - * ToUnicode support want descendant CIDFont's CSI and fontname. - */ - if (__cache.fonts) { - for (font_id = 0; font_id < __cache.count; font_id++) - Type0Font_dofont(&__cache.fonts[font_id]); - } - CIDFont_cache_close(); - if (__cache.fonts) { - for (font_id = 0; font_id < __cache.count; font_id++) { - Type0Font_flush(&__cache.fonts[font_id]); - Type0Font_clean(&__cache.fonts[font_id]); - } - RELEASE(__cache.fonts); - } - __cache.fonts = NULL; - __cache.count = 0; - __cache.capacity = 0; + return 0; } /******************************** COMPAT ********************************/ diff --git a/Build/source/texk/dvipdfm-x/type0.h b/Build/source/texk/dvipdfm-x/type0.h index 34a47d85c40..330ba532d53 100644 --- a/Build/source/texk/dvipdfm-x/type0.h +++ b/Build/source/texk/dvipdfm-x/type0.h @@ -21,30 +21,9 @@ #ifndef _TYPE0_H_ #define _TYPE0_H_ -#include "pdfobj.h" +#include "pdffont.h" -#define add_to_used_chars2(b,c) {(b)[(c)/8] |= (1 << (7-((c)%8)));} -#define is_used_char2(b,c) (((b)[(c)/8]) & (1 << (7-((c)%8)))) - -typedef struct Type0Font Type0Font; - -extern int Type0Font_get_wmode (Type0Font *font); -#if 0 -extern char *Type0Font_get_encoding (Type0Font *font); -#endif -extern char *Type0Font_get_usedchars (Type0Font *font); - -extern pdf_obj *Type0Font_get_resource (Type0Font *font); - -extern void Type0Font_set_ToUnicode (Type0Font *font, pdf_obj *cmap_ref); - -#include "fontmap.h" - -/******************************** CACHE ********************************/ - -extern void Type0Font_cache_init (void); -extern Type0Font *Type0Font_cache_get (int id); -extern int Type0Font_cache_find (const char *map_name, int cmap_id, fontmap_opt *fmap_opt); -extern void Type0Font_cache_close (void); +extern void pdf_font_load_type0 (pdf_font *font); +extern int pdf_font_open_type0 (pdf_font *font, int cid_id, int wmode); #endif /* _TYPE0_H_ */ diff --git a/Build/source/texk/dvipdfm-x/type1.c b/Build/source/texk/dvipdfm-x/type1.c index 277f4c57d31..525f38bb2f9 100644 --- a/Build/source/texk/dvipdfm-x/type1.c +++ b/Build/source/texk/dvipdfm-x/type1.c @@ -56,8 +56,6 @@ #include "type1.h" -#include "tfm.h" - #define FONT_FLAG_FIXEDPITCH (1 << 0) /* Fixed-width font */ #define FONT_FLAG_SERIF (1 << 1) /* Serif font */ #define FONT_FLAG_SYMBOLIC (1 << 2) /* Symbolic font */ @@ -89,34 +87,42 @@ is_basefont (const char *name) } int -pdf_font_open_type1 (pdf_font *font) +pdf_font_open_type1 (pdf_font *font, const char *ident, int index, int encoding_id, int embedding) { - char *ident; FILE *fp; char fontname[PDF_NAME_LEN_MAX+1]; ASSERT(font); + ASSERT(ident); - ident = pdf_font_get_ident(font); + if (index != 0) { + WARN("Ignoring non-zero font index: %s", ident); + } if (is_basefont(ident)) { - pdf_font_set_fontname(font, ident); - pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1); - pdf_font_set_flags (font, - (PDF_FONT_FLAG_NOEMBED|PDF_FONT_FLAG_BASEFONT)); + font->fontname = NEW(strlen(ident)+1, char); + strcpy(font->fontname, ident); + font->subtype = PDF_FONT_FONTTYPE_TYPE1; + font->flags |= PDF_FONT_FLAG_NOEMBED; + font->flags |= PDF_FONT_FLAG_BASEFONT; } else { fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT); if (!fp) return -1; + if (!embedding) { + WARN("Ignoring no-embed option for Type1 font: %s", ident); + font->flags &= ~PDF_FONT_FLAG_NOEMBED; + } memset(fontname, 0, PDF_NAME_LEN_MAX+1); if (!is_pfb(fp) || t1_get_fontname(fp, fontname) < 0) { ERROR("Failed to read Type 1 font \"%s\".", ident); } DPXFCLOSE(fp); - pdf_font_set_fontname(font, fontname); - pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1); + font->fontname = NEW(strlen(fontname)+1, char); + strcpy(font->fontname, fontname); + font->subtype = PDF_FONT_FONTTYPE_TYPE1; } return 0; @@ -242,7 +248,7 @@ get_font_attr (pdf_font *font, cff_font *cffont) flags |= FONT_FLAG_FIXEDPITCH; } - fontname = pdf_font_get_fontname (font); + fontname = font->fontname; descriptor = pdf_font_get_descriptor(font); if (fontname && !strstr(fontname, "Sans")) { @@ -271,16 +277,17 @@ static void add_metrics (pdf_font *font, cff_font *cffont, char **enc_vec, double *widths, int num_glyphs) { pdf_obj *fontdict, *descriptor; - pdf_obj *tmp_array; + pdf_obj *array; int code, firstchar, lastchar; double val; - int i, tfm_id; + int i; char *usedchars; - double scaling; + double scaling = 1.0; + double norm_widths[256]; fontdict = pdf_font_get_resource (font); descriptor = pdf_font_get_descriptor(font); - usedchars = pdf_font_get_usedchars (font); + usedchars = font->usedchars; /* * The original FontBBox of the font is preserved, instead @@ -296,82 +303,56 @@ add_metrics (pdf_font *font, cff_font *cffont, char **enc_vec, double *widths, i * to the default scaling of 1000:1, not relative to the scaling * given by the font matrix. */ - if (cff_dict_known(cffont->topdict, "FontMatrix")) + if (cff_dict_known(cffont->topdict, "FontMatrix")) { scaling = 1000*cff_dict_get(cffont->topdict, "FontMatrix", 0); - else + } else { scaling = 1; + } - tmp_array = pdf_new_array(); + array = pdf_new_array(); for (i = 0; i < 4; i++) { val = cff_dict_get(cffont->topdict, "FontBBox", i); - pdf_add_array(tmp_array, pdf_new_number(ROUND(val, 1.0))); + pdf_add_array(array, pdf_new_number(ROUND(val, 1.0))); } - pdf_add_dict(descriptor, pdf_new_name("FontBBox"), tmp_array); + pdf_add_dict(descriptor, pdf_new_name("FontBBox"), pdf_link_obj(array)); + pdf_release_obj(array); - tmp_array = pdf_new_array(); + array = pdf_new_array(); if (num_glyphs <= 1) { /* This must be an error. */ firstchar = lastchar = 0; - pdf_add_array(tmp_array, pdf_new_number(0.0)); + pdf_add_array(array, pdf_new_number(0.0)); } else { for (firstchar = 255, lastchar = 0, code = 0; code < 256; code++) { if (usedchars[code]) { if (code < firstchar) firstchar = code; if (code > lastchar) lastchar = code; + norm_widths[code] = scaling * widths[cff_glyph_lookup(cffont, enc_vec[code])]; } } if (firstchar > lastchar) { WARN("No glyphs actually used???"); - pdf_release_obj(tmp_array); + pdf_release_obj(array); return; } -#if !defined(LIBDPX) - /* PLEASE FIX THIS - * It's wrong to use TFM width here... We should warn if TFM width - * and actual glyph width are different. - */ -#endif /* !LIBDPX */ - tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + + pdf_check_tfm_widths(font->ident, norm_widths, firstchar, lastchar, usedchars); + for (code = firstchar; code <= lastchar; code++) { if (usedchars[code]) { - double width; - if (tfm_id < 0) /* tfm is not found */ - width = scaling * widths[cff_glyph_lookup(cffont, enc_vec[code])]; -#if defined(LIBDPX) - else -#else - else { - double diff; -#endif /* LIBDPX */ - width = 1000.0 * tfm_get_width(tfm_id, code); -#if !defined(LIBDPX) - diff = width - - scaling * widths[cff_glyph_lookup(cffont, enc_vec[code])]; - if (fabs(diff) > 1.0) { - WARN("Glyph width mismatch for TFM and font (%s)", - pdf_font_get_mapname(font)); - WARN("TFM: %g vs. Type1 font: %g", - width, widths[cff_glyph_lookup(cffont, enc_vec[code])]); - } - } -#endif /* !LIBDPX */ - pdf_add_array(tmp_array, - pdf_new_number(ROUND(width, 0.1))); + pdf_add_array(array, pdf_new_number(ROUND(norm_widths[code], 0.1))); } else { - pdf_add_array(tmp_array, pdf_new_number(0.0)); + pdf_add_array(array, pdf_new_number(0.0)); } } } - if (pdf_array_length(tmp_array) > 0) { - pdf_add_dict(fontdict, - pdf_new_name("Widths"), pdf_ref_obj(tmp_array)); + if (pdf_array_length(array) > 0) { + pdf_add_dict(fontdict, pdf_new_name("Widths"), pdf_ref_obj(array)); } - pdf_release_obj(tmp_array); + pdf_release_obj(array); - pdf_add_dict(fontdict, - pdf_new_name("FirstChar"), pdf_new_number(firstchar)); - pdf_add_dict(fontdict, - pdf_new_name("LastChar"), pdf_new_number(lastchar)); + pdf_add_dict(fontdict, pdf_new_name("FirstChar"), pdf_new_number(firstchar)); + pdf_add_dict(fontdict, pdf_new_name("LastChar"), pdf_new_number(lastchar)); return; } @@ -528,21 +509,19 @@ pdf_font_load_type1 (pdf_font *font) ASSERT(font); - if (!pdf_font_is_in_use(font)) { + if (!font->reference) return 0; - } - encoding_id = pdf_font_get_encoding (font); - fontdict = pdf_font_get_resource (font); + fontdict = pdf_font_get_resource(font); + encoding_id = font->encoding_id; + usedchars = font->usedchars; + ident = font->filename; + fontname = font->fontname; + uniqueTag = pdf_font_get_uniqueTag(font); - pdf_font_get_descriptor(font); - usedchars = pdf_font_get_usedchars (font); - ident = pdf_font_get_ident (font); - fontname = pdf_font_get_fontname (font); - uniqueTag = pdf_font_get_uniqueTag (font); - if (!usedchars || !ident || !fontname) { - ERROR("Type1: Unexpected error."); - } + ASSERT(usedchars); + ASSERT(ident); + ASSERT(fontname); fp = DPXFOPEN(ident, DPX_RES_TYPE_T1FONT); if (!fp) { diff --git a/Build/source/texk/dvipdfm-x/type1.h b/Build/source/texk/dvipdfm-x/type1.h index 9af389fcc77..112eb3b2489 100644 --- a/Build/source/texk/dvipdfm-x/type1.h +++ b/Build/source/texk/dvipdfm-x/type1.h @@ -25,7 +25,7 @@ #include "pdffont.h" -extern int pdf_font_open_type1 (pdf_font *font); +extern int pdf_font_open_type1 (pdf_font *font, const char *ident, int index, int encoding_id, int embedding); extern int pdf_font_load_type1 (pdf_font *font); #endif /* _TYPE1_H_ */ diff --git a/Build/source/texk/dvipdfm-x/type1c.c b/Build/source/texk/dvipdfm-x/type1c.c index d90d43e7d25..692a56be786 100644 --- a/Build/source/texk/dvipdfm-x/type1c.c +++ b/Build/source/texk/dvipdfm-x/type1c.c @@ -62,44 +62,52 @@ #include "type1c.h" -#include "tfm.h" - int -pdf_font_open_type1c (pdf_font *font) +pdf_font_open_type1c (pdf_font *font, const char *ident, int index, int encoding_id, int embedding) { char *fontname; - char *ident; FILE *fp = NULL; sfnt *sfont; cff_font *cffont; pdf_obj *descriptor, *tmp; - unsigned offset = 0; - int encoding_id, embedding; + ULONG offset = 0; ASSERT(font); - - ident = pdf_font_get_ident (font); - encoding_id = pdf_font_get_encoding(font); + ASSERT(ident); fp = DPXFOPEN(ident, DPX_RES_TYPE_OTFONT); if (!fp) + fp = DPXFOPEN(ident, DPX_RES_TYPE_TTFONT); + if (!fp) return -1; sfont = sfnt_open(fp); - if (!sfont || - sfont->type != SFNT_TYPE_POSTSCRIPT || - sfnt_read_table_directory(sfont, 0) < 0) { - ERROR("Not a CFF/OpenType font (9)?"); + if (!sfont) { + if (fp) + DPXFCLOSE(fp); + return -1; } - offset = sfnt_find_table_pos(sfont, "CFF "); - if (offset < 1) { - ERROR("No \"CFF \" table found; not a CFF/OpenType font (or variable font?) (10)?"); + if (sfont->type == SFNT_TYPE_TTC) { + offset = ttc_read_offset(sfont, index); + } + + if ((sfont->type != SFNT_TYPE_TTC && sfont->type != SFNT_TYPE_POSTSCRIPT) || + sfnt_read_table_directory(sfont, offset) < 0 || + (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) { + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; } cffont = cff_open(sfont->stream, offset, 0); if (!cffont) { - ERROR("Could not read CFF font data"); + WARN("Could not read CFF font data: %s", ident); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; } if (cffont->flag & FONTTYPE_CIDFONT) { @@ -112,13 +120,22 @@ pdf_font_open_type1c (pdf_font *font) fontname = cff_get_name(cffont); if (!fontname) { - ERROR("No valid FontName found in CFF/OpenType font."); + WARN("No valid FontName found in CFF/OpenType font: %s", ident); + cff_close (cffont); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; } - pdf_font_set_fontname(font, fontname); - RELEASE(fontname); + font->fontname = fontname; cff_close(cffont); + if (!embedding) { + WARN("Ignoring no-embed option for Type1C font: %s", ident); + embedding = 1; + font->flags &= ~PDF_FONT_FLAG_NOEMBED; + } /* * Font like AdobePiStd does not have meaningful built-in encoding. * Some software generate CFF/OpenType font with incorrect encoding. @@ -129,9 +146,8 @@ pdf_font_open_type1c (pdf_font *font) WARN("If you find text is not encoded properly in the generated PDF file,"); WARN("please specify appropriate \".enc\" file in your fontmap."); } - pdf_font_set_subtype (font, PDF_FONT_FONTTYPE_TYPE1C); + font->subtype = PDF_FONT_FONTTYPE_TYPE1C; - embedding = pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED) ? 0 : 1; descriptor = pdf_font_get_descriptor(font); /* * Create font descriptor from OpenType tables. @@ -145,7 +161,11 @@ pdf_font_open_type1c (pdf_font *font) pdf_merge_dict (descriptor, tmp); /* copy */ pdf_release_obj(tmp); if (!embedding) { /* tt_get_fontdesc may have changed this */ - pdf_font_set_flags(font, PDF_FONT_FLAG_NOEMBED); + WARN("Font embedding disallowed for \"%s\"", ident); + sfnt_close(sfont); + if (fp) + DPXFCLOSE(fp); + return -1; } sfnt_close(sfont); @@ -156,79 +176,63 @@ pdf_font_open_type1c (pdf_font *font) } static void -add_SimpleMetrics (pdf_font *font, cff_font *cffont, - double *widths, card16 num_glyphs) +add_SimpleMetrics (pdf_font *font, cff_font *cffont, double *widths, card16 num_glyphs) { pdf_obj *fontdict; - int code, firstchar, lastchar, tfm_id; + int code, firstchar, lastchar; char *usedchars; - pdf_obj *tmp_array; - double scaling; + pdf_obj *array; + double scaling = 1.0; fontdict = pdf_font_get_resource(font); - usedchars = pdf_font_get_usedchars(font); + usedchars = font->usedchars; /* The widhts array in the font dictionary must be given relative * to the default scaling of 1000:1, not relative to the scaling * given by the font matrix. */ - if (cff_dict_known(cffont->topdict, "FontMatrix")) - scaling = 1000*cff_dict_get(cffont->topdict, "FontMatrix", 0); - else - scaling = 1; + if (cff_dict_known(cffont->topdict, "FontMatrix")) { + scaling = 1000.0 * cff_dict_get(cffont->topdict, "FontMatrix", 0); + } else { + scaling = 1.0; + } - tmp_array = pdf_new_array(); + array = pdf_new_array(); if (num_glyphs <= 1) { /* This should be error. */ firstchar = lastchar = 0; - pdf_add_array(tmp_array, pdf_new_number(0.0)); + pdf_add_array(array, pdf_new_number(0.0)); } else { firstchar = 255; lastchar = 0; for (code = 0; code < 256; code++) { if (usedchars[code]) { - if (code < firstchar) firstchar = code; - if (code > lastchar) lastchar = code; + if (code < firstchar) firstchar = code; + if (code > lastchar) lastchar = code; + widths[code] *= scaling; } } if (firstchar > lastchar) { ERROR("No glyphs used at all!"); - pdf_release_obj(tmp_array); return; } - tfm_id = tfm_open(pdf_font_get_mapname(font), 0); + pdf_check_tfm_widths(font->ident, widths, firstchar, lastchar, usedchars); + for (code = firstchar; code <= lastchar; code++) { if (usedchars[code]) { - double width; - if (tfm_id < 0) /* tfm is not found */ - width = scaling * widths[code]; - else { - double diff; - width = 1000. * tfm_get_width(tfm_id, code); - diff = width - scaling * widths[code]; - if (fabs(diff) > 1.) { - WARN("Glyph width mismatch for TFM and font (%s)", - pdf_font_get_mapname(font)); - WARN("TFM: %g vs. CFF font: %g", width, widths[code]); - } - pdf_add_array(tmp_array, - pdf_new_number(ROUND(width, 0.1))); - } + pdf_add_array(array, pdf_new_number(ROUND(widths[code], 0.1))); } else { - pdf_add_array(tmp_array, pdf_new_number(0.0)); + pdf_add_array(array, pdf_new_number(0.0)); } } } - if (pdf_array_length(tmp_array) > 0) { - pdf_add_dict(fontdict, - pdf_new_name("Widths"), pdf_ref_obj(tmp_array)); + if (pdf_array_length(array) > 0) { + pdf_add_dict(fontdict, pdf_new_name("Widths"), pdf_ref_obj(array)); } - pdf_release_obj(tmp_array); + pdf_release_obj(array); - pdf_add_dict(fontdict, - pdf_new_name("FirstChar"), pdf_new_number(firstchar)); - pdf_add_dict(fontdict, - pdf_new_name("LastChar"), pdf_new_number(lastchar)); + pdf_add_dict(fontdict, pdf_new_name("FirstChar"), pdf_new_number(firstchar)); + pdf_add_dict(fontdict, pdf_new_name("LastChar"), pdf_new_number(lastchar)); return; } @@ -261,26 +265,25 @@ pdf_font_load_type1c (pdf_font *font) ASSERT(font); - if (!pdf_font_is_in_use(font)) { + if (!font->reference) return 0; - } - if (pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) { + if (font->flags & PDF_FONT_FLAG_NOEMBED) { ERROR("Only embedded font supported for CFF/OpenType font."); } - usedchars = pdf_font_get_usedchars (font); - fontname = pdf_font_get_fontname (font); - ident = pdf_font_get_ident (font); + usedchars = font->usedchars; + fontname = font->fontname; + ident = font->filename; uniqueTag = pdf_font_get_uniqueTag (font); - if (!usedchars || - !fontname || !ident) { - ERROR("Unexpected error...."); - } + + ASSERT(usedchars); + ASSERT(fontname); + ASSERT(ident); fontdict = pdf_font_get_resource (font); descriptor = pdf_font_get_descriptor(font); - encoding_id = pdf_font_get_encoding (font); + encoding_id = font->encoding_id; fp = DPXFOPEN(ident, DPX_RES_TYPE_OTFONT); if (!fp) { @@ -341,23 +344,21 @@ pdf_font_load_type1c (pdf_font *font) enc_vec = NEW(256, char *); for (code = 0; code < 256; code++) { if (usedchars[code]) { - card16 gid; - - gid = cff_encoding_lookup(cffont, code); - enc_vec[code] = cff_get_string(cffont, - cff_charsets_lookup_inverse(cffont, gid)); + card16 gid; + + gid = cff_encoding_lookup(cffont, code); + enc_vec[code] = cff_get_string(cffont, cff_charsets_lookup_inverse(cffont, gid)); } else { - enc_vec[code] = NULL; + enc_vec[code] = NULL; } } if (!pdf_lookup_dict(fontdict, "ToUnicode")) { - tounicode = pdf_create_ToUnicode_CMap(fullname, - enc_vec, usedchars); + tounicode = pdf_create_ToUnicode_CMap(fullname, enc_vec, usedchars); if (tounicode) { - pdf_add_dict(fontdict, + pdf_add_dict(fontdict, pdf_new_name("ToUnicode"), pdf_ref_obj (tounicode)); - pdf_release_obj(tounicode); + pdf_release_obj(tounicode); } } } @@ -409,8 +410,7 @@ pdf_font_load_type1c (pdf_font *font) double stemv; stemv = cff_dict_get(cffont->private[0], "StdVW", 0); - pdf_add_dict(descriptor, - pdf_new_name("StemV"), pdf_new_number(stemv)); + pdf_add_dict(descriptor, pdf_new_name("StemV"), pdf_new_number(stemv)); } /* diff --git a/Build/source/texk/dvipdfm-x/type1c.h b/Build/source/texk/dvipdfm-x/type1c.h index dd2ac00f04d..bf81149e7cb 100644 --- a/Build/source/texk/dvipdfm-x/type1c.h +++ b/Build/source/texk/dvipdfm-x/type1c.h @@ -25,7 +25,7 @@ #include "pdffont.h" -extern int pdf_font_open_type1c (pdf_font *font); +extern int pdf_font_open_type1c (pdf_font *font, const char *ident, int index, int encoding_id, int embedding); extern int pdf_font_load_type1c (pdf_font *font); #endif /* _TYPE1C_H_ */ |