From 8650bb5cde687a8830d8edec629705ba8e462980 Mon Sep 17 00:00:00 2001 From: Akira Kakuto Date: Sat, 15 Apr 2017 20:19:40 +0000 Subject: dvipdfm-x: Final patch for TL 2017 by the author, S. Hirata git-svn-id: svn://tug.org/texlive/trunk@43807 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/dvipdfm-x/ChangeLog | 9 + Build/source/texk/dvipdfm-x/fontmap.c | 13 +- Build/source/texk/dvipdfm-x/pdffont.c | 4 - Build/source/texk/dvipdfm-x/tt_cmap.c | 622 +++------------------------------- Build/source/texk/dvipdfm-x/tt_gsub.c | 175 +++++++++- Build/source/texk/dvipdfm-x/tt_gsub.h | 6 + 6 files changed, 236 insertions(+), 593 deletions(-) (limited to 'Build/source/texk/dvipdfm-x') diff --git a/Build/source/texk/dvipdfm-x/ChangeLog b/Build/source/texk/dvipdfm-x/ChangeLog index 73f833656a3..9bb2cffbd33 100644 --- a/Build/source/texk/dvipdfm-x/ChangeLog +++ b/Build/source/texk/dvipdfm-x/ChangeLog @@ -1,3 +1,12 @@ +2017-04-15 Shunsaku Hirata + + * fontmap.c, tt_cmap.c, tt_gsub.c, tt_gsub.h, pdffont.c: Removed + undocumented OpenType Layout GSUB support. Added simplified version of + OpenType Layout GSUB support. Fontmap option "-l otl_tags" enables + OpenType GSUB features specified by otl_tags, where otl_tags is a ":" + separated list of OpenType Layout feature tags + (or strings of script.language.feature form). + 2017-04-12 Akira Kakuto * dvipdfmx.c: Fix a bug in static const char *optstrig. diff --git a/Build/source/texk/dvipdfm-x/fontmap.c b/Build/source/texk/dvipdfm-x/fontmap.c index 0f3b4657d41..3ee569c1ac0 100644 --- a/Build/source/texk/dvipdfm-x/fontmap.c +++ b/Build/source/texk/dvipdfm-x/fontmap.c @@ -71,7 +71,7 @@ pdf_init_fontmap_record (fontmap_rec *mrec) mrec->opt.design_size = -1.0; mrec->opt.tounicode = NULL; - mrec->opt.otl_tags = NULL; /* deactivated */ + mrec->opt.otl_tags = NULL; mrec->opt.index = 0; mrec->opt.charcoll = NULL; mrec->opt.style = FONTMAP_STYLE_NONE; @@ -453,6 +453,17 @@ fontmap_parse_mapdef_dpm (fontmap_rec *mrec, RELEASE(q); break; + /* 2017.4.15 back again */ + case 'l': + q = parse_string_value(&p, endptr); + if (q) + mrec->opt.otl_tags = q; + else { + WARN("Missing string value for option 'l'."); + return -1; + } + break; + /* Omega uses both single-byte and double-byte set_char command * even for double-byte OFMs. This confuses CMap decoder. */ diff --git a/Build/source/texk/dvipdfm-x/pdffont.c b/Build/source/texk/dvipdfm-x/pdffont.c index 8346f00af8e..6c1ffb5b8e5 100644 --- a/Build/source/texk/dvipdfm-x/pdffont.c +++ b/Build/source/texk/dvipdfm-x/pdffont.c @@ -50,7 +50,6 @@ #include "type0.h" #include "tt_cmap.h" #include "cidtype0.h" -#include "otl_conf.h" #include "pdffont.h" @@ -67,7 +66,6 @@ pdf_font_set_verbose (void) CIDFont_set_verbose (); pdf_encoding_set_verbose(); agl_set_verbose(); - otl_conf_set_verbose(); otf_cmap_set_verbose (); } @@ -308,7 +306,6 @@ pdf_init_fonts (void) ASSERT(font_cache.fonts == NULL); agl_init_map(); - otl_init_conf(); CMap_cache_init(); pdf_init_encodings(); @@ -600,7 +597,6 @@ pdf_close_fonts (void) CMap_cache_close(); pdf_close_encodings(); - otl_close_conf(); agl_close_map (); /* After encoding */ return; diff --git a/Build/source/texk/dvipdfm-x/tt_cmap.c b/Build/source/texk/dvipdfm-x/tt_cmap.c index b356ed4de44..5f4f99ec741 100644 --- a/Build/source/texk/dvipdfm-x/tt_cmap.c +++ b/Build/source/texk/dvipdfm-x/tt_cmap.c @@ -45,12 +45,9 @@ #include "unicode.h" #include "agl.h" -#include "pdfparse.h" -#include "pdfresource.h" -#include "otl_conf.h" +#include "pdfresource.h" #include "dpxfile.h" - /* Hash */ #include "dpxutil.h" @@ -612,7 +609,8 @@ static unsigned char lrange_max[4] = {0x7f, 0xff, 0xff, 0xff}; static void load_cmap4 (struct cmap4 *map, - unsigned char *GIDToCIDMap, otl_gsub *gsub_list, CMap *cmap) + unsigned char *GIDToCIDMap, + otl_gsub *gsub_vert, otl_gsub *gsub_list, CMap *cmap) { USHORT c0, c1, gid, cid; USHORT j, d, segCount; @@ -637,7 +635,9 @@ load_cmap4 (struct cmap4 *map, } if (gid != 0 && gid != 0xffff) { if (gsub_list) - otl_gsub_apply(gsub_list, &gid); + otl_gsub_apply_chain(gsub_list, &gid); + if (gsub_vert) + otl_gsub_apply(gsub_vert, &gid); if (GIDToCIDMap) { cid = ((GIDToCIDMap[2*gid] << 8)|GIDToCIDMap[2*gid+1]); if (cid == 0) @@ -659,7 +659,8 @@ load_cmap4 (struct cmap4 *map, static void load_cmap12 (struct cmap12 *map, - unsigned char *GIDToCIDMap, otl_gsub *gsub_list, CMap *cmap) + unsigned char *GIDToCIDMap, + otl_gsub *gsub_vert, otl_gsub *gsub_list, CMap *cmap) { ULONG i, ch; /* LONG ? */ USHORT gid, cid; @@ -671,7 +672,9 @@ load_cmap12 (struct cmap12 *map, int d = ch - map->groups[i].startCharCode; gid = (USHORT) ((map->groups[i].startGlyphID + d) & 0xffff); if (gsub_list) - otl_gsub_apply(gsub_list, &gid); + otl_gsub_apply_chain(gsub_list, &gid); + if (gsub_vert) + otl_gsub_apply(gsub_vert, &gid); if (GIDToCIDMap) { cid = ((GIDToCIDMap[2*gid] << 8)|GIDToCIDMap[2*gid+1]); if (cid == 0) @@ -1304,300 +1307,10 @@ otf_create_ToUnicode_stream (const char *font_name, return cmap_ref; } -/* Must be smaller than (WBUF_SIZE-2)/8 */ -#define MAX_UNICODES 16 - -struct gent -{ - USHORT gid; - int32_t ucv; /* assigned PUA unicode */ - - int num_unicodes; - int32_t unicodes[MAX_UNICODES]; -}; - -static void -create_cmaps (CMap *cmap, CMap *tounicode, - struct ht_table *unencoded, unsigned char *GIDToCIDMap) -{ - struct ht_iter iter; - - ASSERT(cmap && unencoded); - - if (ht_set_iter(unencoded, &iter) < 0) - return; - - CMap_set_silent(1); /* many warnings without this... */ - - do { - struct gent *glyph; - unsigned char *ucv; - int i, len; - unsigned char *p, *endptr; - CID cid; - - glyph = (struct gent *) ht_iter_getval(&iter); - ucv = (unsigned char *) ht_iter_getkey(&iter, &len); - - if (GIDToCIDMap) { - cid = ((GIDToCIDMap[2 * glyph->gid] << 8)|GIDToCIDMap[2 * glyph->gid + 1]); - if (cid == 0) - WARN("Glyph gid=%u does not have corresponding CID.", glyph->gid); - } else { - cid = glyph->gid; - } - - CMap_add_cidchar(cmap, ucv, 4, cid); - - if (tounicode) { - wbuf[0] = (cid >> 8) & 0xff; - wbuf[1] = cid & 0xff; - p = wbuf + 2; - endptr = wbuf + WBUF_SIZE; - len = 0; - for (i = 0; i < glyph->num_unicodes; i++) { - len += UC_UTF16BE_encode_char(glyph->unicodes[i], &p, endptr); - } - CMap_add_bfchar(tounicode, wbuf, 2, wbuf + 2, len); - } - } while (ht_iter_next(&iter) >= 0); - - CMap_set_silent(0); - - ht_clear_iter(&iter); -} - -static void -add_glyph (struct ht_table *unencoded, - USHORT gid, int32_t ucv, int num_unicodes, int32_t *unicodes) -{ - struct gent *glyph; - int i; - - ASSERT(unencoded); - - if (gid == 0 || num_unicodes < 1) { - return; - } - - wbuf[0] = (ucv >> 24) & 0xff; - wbuf[1] = (ucv >> 16) & 0xff; - wbuf[2] = (ucv >> 8) & 0xff; - wbuf[3] = ucv & 0xff; - - glyph = NEW(1, struct gent); - glyph->gid = gid; - glyph->num_unicodes = num_unicodes; - for (i = 0; - i < num_unicodes && i < MAX_UNICODES; i++) { - glyph->unicodes[i] = unicodes[i]; - } - - ht_append_table(unencoded, wbuf, 4, glyph); -} - -/* This seriously affects speed... */ -static struct gent * -find_glyph (struct ht_table *unencoded, int32_t ucv) -{ - ASSERT(unencoded); - - wbuf[0] = (ucv >> 24) & 0xff; - wbuf[1] = (ucv >> 16) & 0xff; - wbuf[2] = (ucv >> 8) & 0xff; - wbuf[3] = ucv & 0xff; - - return (struct gent *) ht_lookup_table(unencoded, wbuf, 4); -} - -static void -handle_subst (pdf_obj *dst_obj, pdf_obj *src_obj, int flag, - otl_gsub *gsub_list, tt_cmap *ttcmap, - struct ht_table *unencoded) -{ - pdf_obj *tmp; - int32_t i, j, src_size, dst_size; - int32_t src, dst; - int32_t src_start, src_end, dst_start, dst_end; - - src_size = pdf_array_length(src_obj); - dst_size = pdf_array_length(dst_obj); - - dst_start = dst_end = -1; dst = 0; - src_start = src_end = -1; src = 0; - for (i = 0, j = 0; - i < src_size && j < dst_size; i++) { - USHORT gid; - int rv; - struct gent *glyph; - - tmp = pdf_get_array(src_obj, i); - if (PDF_OBJ_ARRAYTYPE(tmp)) { - src_start = (int32_t) pdf_number_value(pdf_get_array(tmp, 0)); - src_end = (int32_t) pdf_number_value(pdf_get_array(tmp, 1)); - } else { - src_start = src_end = (int32_t) pdf_number_value(tmp); - } - for (src = src_start; src <= src_end; src++) { - glyph = find_glyph(unencoded, src); - if (glyph) - gid = glyph->gid; - else { - gid = tt_cmap_lookup(ttcmap, src); - } - dst++; - if (dst > dst_end) { - tmp = pdf_get_array(dst_obj, j++); - if (PDF_OBJ_ARRAYTYPE(tmp)) { - dst_start = (int32_t) pdf_number_value(pdf_get_array(tmp, 0)); - dst_end = (int32_t) pdf_number_value(pdf_get_array(tmp, 1)); - } else { - dst_start = dst_end = (int32_t) pdf_number_value(tmp); - } - dst = dst_start; - } - if (gid == 0) { - if (flag == 'r' || flag == 'p') { - if (src < 0x10000) { - WARN("Font does not have glyph for U+%04X.", src); - } else { - WARN("Font does not have glyph for U+%06X.", src); - } - } - if (flag == 'r') { - ERROR("Missing glyph found..."); - } - continue; - } - rv = otl_gsub_apply(gsub_list, &gid); - if (rv < 0) { - if (flag == 'p' || flag == 'r') { - if (src < 0x10000) { - WARN("No substituted glyph for U+%04X.", src); - } else { - WARN("No substituted glyph for U+%06X.", src); - } - } - if (flag == 'r') { - ERROR("Missing glyph found..."); - } - continue; - } - - if (glyph) { - glyph->gid = gid; - } else { - add_glyph(unencoded, gid, dst, 1, &src); - } - - if (verbose > VERBOSE_LEVEL_MIN) { - if (dst < 0x10000) { - MESG("otf_cmap>> Substituted glyph gid=%u assigned to U+%04X\n", - gid, dst); - } else { - MESG("otf_cmap>> Substituted glyph gid=%u assigned to U+%06X\n", - gid, dst); - } - } - - } - } - - if (dst < dst_end || src < src_end || - i < src_size || j < dst_size) { - WARN("Number of glyphs in left-side and right-side not equal..."); - WARN("Please check .otl file..."); - } -} - -static void -handle_assign (pdf_obj *dst, pdf_obj *src, int flag, - otl_gsub *gsub_list, tt_cmap *ttcmap, - struct ht_table *unencoded) -{ - int32_t unicodes[MAX_UNICODES], ucv; - int i, n_unicodes, rv; - USHORT gid_in[MAX_UNICODES], lig; - - n_unicodes = pdf_array_length(src); /* FIXME */ - ucv = (int32_t) pdf_number_value(pdf_get_array(dst, 0)); /* FIXME */ - if (!UC_is_valid(ucv)) { - if (flag == 'r' || flag == 'p') { - if (ucv < 0x10000) { - WARN("Invalid Unicode in: %04X", ucv); - } else { - WARN("Invalid Unicode in: %06X", ucv); - } - } - if (flag == 'r') { - ERROR("Invalid Unicode code specified."); - } - return; - } - - if (verbose > VERBOSE_LEVEL_MIN) { - MESG("otf_cmap>> Ligature component:"); - } - - for (i = 0; i < n_unicodes; i++) { - unicodes[i] = - (int32_t) pdf_number_value(pdf_get_array(src, i)); - gid_in[i] = tt_cmap_lookup(ttcmap, unicodes[i]); - - if (verbose > VERBOSE_LEVEL_MIN) { - if (unicodes[i] < 0x10000) { - MESG(" U+%04X (gid=%u)", unicodes[i], gid_in[i]); - } else { - MESG(" U+%06X (gid=%u)", unicodes[i], gid_in[i]); - } - } - - if (gid_in[i] == 0) { - if (flag == 'r' || flag == 'p') { - if (unicodes[i] < 0x10000) { - WARN("Unicode char U+%04X not exist in font...", unicodes[i]); - } else { - WARN("Unicode char U+%06X not exist in font...", unicodes[i]); - } - } - if (flag == 'r') { - ERROR("Missing glyph found..."); - } - return; - } - - } - - if (verbose > VERBOSE_LEVEL_MIN) { - MESG("\n"); - } - - rv = otl_gsub_apply_lig(gsub_list, - gid_in, (USHORT)n_unicodes, &lig); - if (rv < 0) { - if (flag == 'p') - WARN("No ligature found..."); - else if (flag == 'r') - ERROR("No ligature found..."); - return; - } - - add_glyph(unencoded, lig, ucv, n_unicodes, unicodes); - - if (verbose > VERBOSE_LEVEL_MIN) { - if (ucv < 0x10000) { - MESG("otf_cmap>> Ligature glyph gid=%u assigned to U+%04X\n", lig, ucv); - } else { - MESG("otf_cmap>> Ligature glyph gid=%u assigned to U+%06X\n", lig, ucv); - } - } - - return; -} - static int load_base_CMap (const char *cmap_name, int wmode, - CIDSysInfo *csi, unsigned char *GIDToCIDMap, otl_gsub *gsub_list, + CIDSysInfo *csi, unsigned char *GIDToCIDMap, + otl_gsub *gsub_vert, otl_gsub *gsub_list, tt_cmap *ttcmap) { int cmap_id; @@ -1619,9 +1332,9 @@ load_base_CMap (const char *cmap_name, int wmode, } if (ttcmap->format == 12) { - load_cmap12(ttcmap->map, GIDToCIDMap, gsub_list, cmap); + load_cmap12(ttcmap->map, GIDToCIDMap, gsub_vert, gsub_list, cmap); } else if (ttcmap->format == 4) { - load_cmap4(ttcmap->map, GIDToCIDMap, gsub_list, cmap); + load_cmap4(ttcmap->map, GIDToCIDMap, gsub_vert, gsub_list, cmap); } cmap_id = CMap_cache_add(cmap); @@ -1630,156 +1343,18 @@ load_base_CMap (const char *cmap_name, int wmode, return cmap_id; } -static void -load_gsub (pdf_obj *conf, otl_gsub *gsub_list, sfnt *sfont) -{ - pdf_obj *rule; - char *script, *language, *feature; - int i, size; - - rule = otl_conf_get_rule(conf); - if (!rule) - return; - - script = otl_conf_get_script (conf); - language = otl_conf_get_language(conf); - - size = pdf_array_length(rule); - for (i = 0; i < size; i += 2) { - pdf_obj *tmp, *commands; - int flag; - int j, num_comms; - - tmp = pdf_get_array(rule, i); - flag = (int) pdf_number_value(tmp); - - commands = pdf_get_array(rule, i+1); - num_comms = pdf_array_length(commands); - - /* (assign|substitute) tag dst src */ - for (j = 0 ; j < num_comms; j += 4) { - tmp = pdf_get_array(commands, 1); - if (PDF_OBJ_STRINGTYPE(tmp)) { - feature = pdf_string_value(tmp); - if (otl_gsub_add_feat(gsub_list, - script, language, feature, sfont) < 0) { - if (flag == 'p') - WARN("No OTL feature matches \"%s.%s.%s\" found.", - script, language, feature); - else if (flag == 'r') - ERROR("No OTL feature matches \"%s.%s.%s\" found.", - script, language, feature); - } - } - - } - } - -} - -static void -handle_gsub (pdf_obj *conf, - tt_cmap *ttcmap, otl_gsub *gsub_list, - struct ht_table *unencoded) -{ - pdf_obj *rule; - char *script, *language, *feature; - int i, size; - - if (!conf) - return; - - rule = otl_conf_get_rule(conf); - if (!rule) { - return; - } - - if (!PDF_OBJ_ARRAYTYPE(rule)) { - WARN("Not arraytype?"); - return; - } - script = otl_conf_get_script (conf); - language = otl_conf_get_language(conf); - - size = pdf_array_length(rule); - for (i = 0; i < size; i += 2) { - pdf_obj *tmp, *commands; - int j, num_comms; - int flag; - - tmp = pdf_get_array(rule, i); - flag = (int) pdf_number_value(tmp); - - commands = pdf_get_array (rule, i+1); - num_comms = pdf_array_length(commands); - - for (j = 0; j < num_comms; j += 4) { - pdf_obj *operator; - pdf_obj *src, *dst, *feat; - int rv; - - /* (assing|substitute) tag dst src */ - operator = pdf_get_array(commands, j); - - feat = pdf_get_array(commands, j+1); - if (PDF_OBJ_STRINGTYPE(feat)) - feature = pdf_string_value(feat); - else - feature = NULL; - - dst = pdf_get_array(commands, j+2); - src = pdf_get_array(commands, j+3); - - rv = otl_gsub_select(gsub_list, script, language, feature); - if (rv < 0) { - if (flag == 'p') { - WARN("No GSUB feature %s.%s.%s loaded...", - script, language, feature); - } else if (flag == 'r') { - ERROR("No GSUB feature %s.%s.%s loaded...", - script, language, feature); - } - } else { - - if (verbose > VERBOSE_LEVEL_MIN) { - MESG("otf_cmap>> %s:\n", pdf_name_value(operator)); - } - - if (!strcmp(pdf_name_value(operator), "assign")) { - handle_assign(dst, src, flag, - gsub_list, ttcmap, unencoded); - } else if (!strcmp(pdf_name_value(operator), "substitute")) { - handle_subst(dst, src, flag, - gsub_list, ttcmap, unencoded); - } - } - - } - - } - -} - -static inline void -hval_free (void *hval) -{ - RELEASE(hval); -} - int otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC font */ const char *otl_tags, int wmode) { int cmap_id = -1; - int tounicode_id = -1, is_cidfont = 0; + int is_cidfont = 0; sfnt *sfont; ULONG offset = 0; char *base_name = NULL, *cmap_name = NULL; - char *tounicode_name = NULL; FILE *fp = NULL; - otl_gsub *gsub_list = NULL; + otl_gsub *gsub_vert = NULL, *gsub_list = NULL; tt_cmap *ttcmap; - CMap *cmap, *base, *tounicode = NULL; CIDSysInfo csi = {NULL, NULL, 0}; unsigned char *GIDToCIDMap = NULL; @@ -1851,28 +1426,17 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon is_cidfont = 0; } - if (is_cidfont) { - tounicode_name = NULL; - } else { - tounicode_name = NEW(strlen(map_name)+strlen("-UTF16")+5, char); - sprintf(tounicode_name, "%s,%03d-UTF16", map_name, ttc_index); - } - if (verbose > VERBOSE_LEVEL_MIN) { MESG("\n"); MESG("otf_cmap>> Unicode charmap for font=\"%s\" layout=\"%s\"\n", map_name, (otl_tags ? otl_tags : "none")); } - cmap_id = CMap_cache_find(cmap_name); if (cmap_id >= 0) { RELEASE(cmap_name); RELEASE(base_name); if (GIDToCIDMap) RELEASE(GIDToCIDMap); - if (tounicode_name) - RELEASE(tounicode_name); - sfnt_close(sfont); DPXFCLOSE(fp); @@ -1897,37 +1461,47 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon } } if (wmode == 1) { - 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) { + gsub_vert = otl_gsub_new(); + if (otl_gsub_add_feat(gsub_vert, "*", "*", "vrt2", sfont) < 0) { + if (otl_gsub_add_feat(gsub_vert, "*", "*", "vert", sfont) < 0) { WARN("GSUB feature vrt2/vert not found."); - otl_gsub_release(gsub_list); - gsub_list = NULL; + otl_gsub_release(gsub_vert); + gsub_vert = NULL; } else { - otl_gsub_select(gsub_list, "*", "*", "vert"); + otl_gsub_select(gsub_vert, "*", "*", "vert"); } } else { - otl_gsub_select(gsub_list, "*", "*", "vrt2"); + otl_gsub_select(gsub_vert, "*", "*", "vrt2"); + } + } else { + gsub_vert = NULL; + } + if (otl_tags) { + gsub_list = otl_gsub_new(); + if (otl_gsub_add_feat_list(gsub_list, otl_tags, sfont) < 0) { + WARN("Readin GSUB feature table(s) failed for \"%s\"", otl_tags); + } else { + otl_gsub_set_chain(gsub_list, otl_tags); } } else { gsub_list = NULL; } cmap_id = load_base_CMap(base_name, wmode, (is_cidfont ? &csi : NULL), GIDToCIDMap, - gsub_list, ttcmap); + gsub_vert, gsub_list, ttcmap); if (cmap_id < 0) ERROR("Failed to read OpenType/TrueType cmap table."); + if (gsub_vert) + otl_gsub_release(gsub_vert); + gsub_vert = NULL; if (gsub_list) otl_gsub_release(gsub_list); gsub_list = NULL; - if (!otl_tags) { RELEASE(cmap_name); RELEASE(base_name); if (GIDToCIDMap) RELEASE(GIDToCIDMap); - if (tounicode_name) - RELEASE(tounicode_name); if (is_cidfont) { if (csi.registry) RELEASE(csi.registry); @@ -1938,125 +1512,5 @@ otf_load_Unicode_CMap (const char *map_name, int ttc_index, /* 0 for non-TTC fon sfnt_close(sfont); DPXFCLOSE(fp); - return cmap_id; - } - - base = CMap_cache_get(cmap_id); - - cmap = CMap_new(); - CMap_set_name (cmap, cmap_name); - CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID); - CMap_set_wmode(cmap, wmode); - /* CMap_add_codespacerange(cmap, lrange_min, lrange_max, 4); */ - CMap_set_usecmap(cmap, base); - CMap_add_cidchar(cmap, lrange_max, 4, 0); /* FIXME */ - - if (is_cidfont) { - CMap_set_CIDSysInfo(cmap, &csi); - if (csi.registry) - RELEASE(csi.registry); - if (csi.ordering) - RELEASE(csi.ordering); - } else { - CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY); - } - - gsub_list = otl_gsub_new(); - - { - struct ht_table unencoded; - char *conf_name, *opt_tag; - pdf_obj *conf, *opt_conf; - - conf_name = NEW(strlen(otl_tags)+1, char); - memset (conf_name, 0, strlen(otl_tags)+1); - opt_tag = strchr(otl_tags, ':'); - if (opt_tag) { - opt_tag++; - strncpy(conf_name, otl_tags, - strlen(otl_tags) - strlen(opt_tag) - 1); - } else { - strcpy(conf_name, otl_tags); - } - - if (verbose > VERBOSE_LEVEL_MIN) { - MESG("otf_cmap>> Read layout config. \"%s\"\n", conf_name); - } - - conf = otl_find_conf(conf_name); - if (!conf) - ERROR("Layout file \"%s\" not found...", conf_name); - - load_gsub(conf, gsub_list, sfont); - if (opt_tag) { - if (verbose > VERBOSE_LEVEL_MIN) { - MESG("otf_cmap>> Layout option \"%s\" enabled\n", opt_tag); - } - opt_conf = otl_conf_find_opt(conf, opt_tag); - if (!opt_conf) - ERROR("There is no option \"%s\" in \"%s\".", - opt_tag, conf_name); - load_gsub(opt_conf, gsub_list, sfont); - } - - ht_init_table(&unencoded, hval_free); - - handle_gsub(conf, ttcmap, gsub_list, &unencoded); - if (opt_tag) { - opt_conf = otl_conf_find_opt(conf, opt_tag); - if (!opt_conf) - ERROR("There is no option \"%s\" in \"%s\".", - opt_tag, conf_name); - handle_gsub(opt_conf, ttcmap, gsub_list, &unencoded); - } - if (is_cidfont) { - tounicode_id = -1; - tounicode = NULL; - } else { - tounicode_id = CMap_cache_find(tounicode_name); - if (tounicode_id >= 0) - tounicode = CMap_cache_get(tounicode_id); - else { - tounicode = CMap_new(); - CMap_set_name (tounicode, tounicode_name); - CMap_set_type (tounicode, CMAP_TYPE_TO_UNICODE); - CMap_set_wmode(tounicode, 0); - CMap_add_codespacerange(tounicode, srange_min, srange_max, 2); - CMap_set_CIDSysInfo(tounicode, &CSI_UNICODE); - /* FIXME */ - CMap_add_bfchar(tounicode, srange_min, 2, srange_max, 2); - } - } - create_cmaps(cmap, tounicode, &unencoded, GIDToCIDMap); - - ht_clear_table(&unencoded); - RELEASE(conf_name); - } - - cmap_id = CMap_cache_add(cmap); - if (!is_cidfont && tounicode_id < 0) /* New */ - CMap_cache_add(tounicode); - - tt_cmap_release(ttcmap); - if (gsub_list) - otl_gsub_release(gsub_list); - - if (verbose > VERBOSE_LEVEL_MIN) { - MESG("otf_cmap>> Overwrite CMap \"%s\" by \"%s\" with usecmap\n", - base_name, cmap_name); - } - - if (GIDToCIDMap) - RELEASE(GIDToCIDMap); - if (base_name) - RELEASE(base_name); - if (cmap_name) - RELEASE(cmap_name); - if (tounicode_name) - RELEASE(tounicode_name); - - sfnt_close(sfont); - DPXFCLOSE(fp); - return cmap_id; } diff --git a/Build/source/texk/dvipdfm-x/tt_gsub.c b/Build/source/texk/dvipdfm-x/tt_gsub.c index 3151e9ed9f7..86d5e8c0e5e 100644 --- a/Build/source/texk/dvipdfm-x/tt_gsub.c +++ b/Build/source/texk/dvipdfm-x/tt_gsub.c @@ -1269,10 +1269,16 @@ otl_gsub_apply_ligature (struct otl_gsub_subtab *subtab, } #define GSUB_LIST_MAX 32 +struct gsub_entry { + int index; + struct gsub_entry *next; +}; + struct otl_gsub { int num_gsubs; int select; + struct gsub_entry *first; struct otl_gsub_tab gsubs[GSUB_LIST_MAX]; }; @@ -1284,10 +1290,21 @@ otl_gsub_new (void) gsub_list = NEW(1, struct otl_gsub); gsub_list->num_gsubs = 0; gsub_list->select = -1; + gsub_list->first = NULL; return (otl_gsub *) gsub_list; } +static void +clear_chain (otl_gsub *gsub_list) { + struct gsub_entry *entry, *next; + for (entry = gsub_list->first; entry != NULL; entry = next) { + next = entry->next; + RELEASE(entry); + } + gsub_list->first = NULL; +} + int otl_gsub_add_feat (otl_gsub *gsub_list, const char *script, @@ -1342,6 +1359,56 @@ otl_gsub_add_feat (otl_gsub *gsub_list, return retval; } +static const char * +scan_otl_tag (const char *otl_tags, const char *endptr, + char *script, char *language, char *feature) +{ + const char *p, *period; + + ASSERT(script && language && feature); + ASSERT(otl_tags < endptr); + + if (!otl_tags) + return NULL; + + memset(script, ' ', 4); script[4] = 0; + memset(language, ' ', 4); language[4] = 0; + memset(feature, ' ', 4); feature[4] = 0; + + /* First parse otl_tags variable */ + p = otl_tags; + period = strchr(p, '.'); + if (period && period < endptr) { + /* Format scrp.lang.feat */ + if (period < p + 5) { + strncpy(script, p, period - p); + } else { + WARN("Invalid OTL script tag found: %s", p); + } + p = period + 1; + period = strchr(p, '.'); + if (period && period < endptr) { + /* Now lang part */ + if (period < p + 5) { + strncpy(language, p, period - p); + } else { + WARN("Invalid OTL lanuage tag found: %s", p); + } + p = period + 1; + } + } else { + strcpy(script, "*"); + strcpy(language, "*"); + } + /* Finally feature */ + if (p < endptr) { + strncpy(feature, p, endptr - p); + p = endptr; + } + + return p; +} + void otl_gsub_release (otl_gsub *gsub_list) { @@ -1381,7 +1448,7 @@ otl_gsub_release (otl_gsub *gsub_list) } RELEASE(gsub->subtables); } - + clear_chain(gsub_list); RELEASE(gsub_list); } @@ -1487,7 +1554,7 @@ otl_gsub_apply_lig (otl_gsub *gsub_list, } int -otl_gsub_select (otl_gsub *gsub_list, +gsub_find (otl_gsub *gsub_list, const char *script, const char *language, const char *feature) @@ -1500,14 +1567,114 @@ otl_gsub_select (otl_gsub *gsub_list, if (!strcmp(gsub->script, script) && !strcmp(gsub->language, language) && !strcmp(gsub->feature, feature)) { - gsub_list->select = i; return i; } } - gsub_list->select = -1; + return -1; +} + +int +otl_gsub_select (otl_gsub *gsub_list, + const char *script, + const char *language, + const char *feature) +{ + gsub_list->select = gsub_find(gsub_list, script, language, feature); + return gsub_list->select; +} + +int +otl_gsub_set_chain (otl_gsub *gsub_list, const char *otl_tags) { + struct gsub_entry *prev = NULL; + const char *p, *nextptr, *endptr; + char script[5], language[5], feature[5]; + int idx; + + clear_chain(gsub_list); + + endptr = otl_tags + strlen(otl_tags); + for (p = otl_tags; p < endptr; p = nextptr) { + nextptr = strchr(p, ':'); + if (!nextptr) + nextptr = endptr; + scan_otl_tag(p, nextptr, script, language, feature); + idx = gsub_find(gsub_list, script, language, feature); + if (idx >= 0 && idx <= gsub_list->num_gsubs) { + struct gsub_entry *entry; + entry = NEW(1, struct gsub_entry); + if (prev) + prev->next = entry; + entry->index = idx; + prev = entry; + } + nextptr++; + } + if (prev) + prev->next = NULL; + gsub_list->first = prev; + + return 0; +} + +int +otl_gsub_add_feat_list (otl_gsub *gsub_list, const char *otl_tags, sfnt *sfont) +{ + const char *p, *nextptr, *endptr; + char script[5], language[5], feature[5]; + int idx; + if (!gsub_list || !otl_tags || !sfont) return -1; + + clear_chain(gsub_list); + endptr = otl_tags + strlen(otl_tags); + for (p = otl_tags; p < endptr; p = nextptr) { + nextptr = strchr(p, ':'); + if (!nextptr) + nextptr = endptr; + scan_otl_tag(p, nextptr, script, language, feature); + idx = gsub_find(gsub_list, script, language, feature); + if (idx < 0) { + otl_gsub_add_feat(gsub_list, script, language, feature, sfont); + } + nextptr++; + } + + return 0; +} + +int +otl_gsub_apply_chain (otl_gsub *gsub_list, USHORT *gid) { + int retval = -1; + struct otl_gsub_tab *gsub; + struct otl_gsub_subtab *subtab; + struct gsub_entry *entry; + int i, idx; + + if (!gsub_list || !gid) + return retval; + + for (entry = gsub_list->first; + entry != NULL; entry = entry->next) { + idx = entry->index; + if (idx < 0 || idx >= gsub_list->num_gsubs) + continue; + gsub = &(gsub_list->gsubs[idx]); + for (i = 0, retval = -1; + retval < 0 && i < gsub->num_subtables; i++) { + subtab = &(gsub->subtables[i]); + switch ((int) subtab->LookupType){ + case OTL_GSUB_TYPE_SINGLE: + retval = otl_gsub_apply_single(subtab, gid); + break; + default: + break; + } + } + } + + return retval; } #if 0 diff --git a/Build/source/texk/dvipdfm-x/tt_gsub.h b/Build/source/texk/dvipdfm-x/tt_gsub.h index c7c16226f1d..80ff6cb44b6 100644 --- a/Build/source/texk/dvipdfm-x/tt_gsub.h +++ b/Build/source/texk/dvipdfm-x/tt_gsub.h @@ -55,6 +55,12 @@ extern int otl_gsub_apply_lig (otl_gsub *gsub_list, USHORT *gid_in, USHORT num_gids, USHORT *gid_out); +/* Handle a list of OTL features */ +extern int otl_gsub_add_feat_list (otl_gsub *gsub_list, + const char *otl_tags, sfnt *sfont); +extern int otl_gsub_set_chain (otl_gsub *gsub_list, const char *otl_tags); +extern int otl_gsub_apply_chain (otl_gsub *gsub_list, USHORT *gid); + #if 0 extern int otl_gsub_dump (otl_gsub *gsub_list, const char *script, -- cgit v1.2.3