summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2017-04-15 20:19:40 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2017-04-15 20:19:40 +0000
commit8650bb5cde687a8830d8edec629705ba8e462980 (patch)
treef078a81989c211e261aa93c2715712733e9b445b
parentabbde7a337e5fe45d76b545f95c9697c5a149a14 (diff)
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
-rw-r--r--Build/source/texk/dvipdfm-x/ChangeLog9
-rw-r--r--Build/source/texk/dvipdfm-x/fontmap.c13
-rw-r--r--Build/source/texk/dvipdfm-x/pdffont.c4
-rw-r--r--Build/source/texk/dvipdfm-x/tt_cmap.c622
-rw-r--r--Build/source/texk/dvipdfm-x/tt_gsub.c175
-rw-r--r--Build/source/texk/dvipdfm-x/tt_gsub.h6
6 files changed, 236 insertions, 593 deletions
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 <shunsaku.hirata74@gmail.com>
+
+ * 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 <kakuto@fuk.kindai.ac.jp>
* 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,