summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/xsrc/agl.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdfm-x/xsrc/agl.c')
-rw-r--r--Build/source/texk/dvipdfm-x/xsrc/agl.c826
1 files changed, 0 insertions, 826 deletions
diff --git a/Build/source/texk/dvipdfm-x/xsrc/agl.c b/Build/source/texk/dvipdfm-x/xsrc/agl.c
deleted file mode 100644
index d5a4edd7730..00000000000
--- a/Build/source/texk/dvipdfm-x/xsrc/agl.c
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
-
- This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
-
- Copyright (C) 2007-2012 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.
-*/
-
-/*
- * References:
- *
- * Unicode and Glyph Names, ver. 2.3., Adobe Solution Network
- * http://partners.adobe.com/asn/tech/type/unicodegn.jsp
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <ctype.h>
-
-#include "system.h"
-#include "mem.h"
-#include "error.h"
-
-#include "mfileio.h"
-#include "pdfparse.h"
-
-/* Hash */
-#include "dpxutil.h"
-
-#include "dpxfile.h"
-
-#include "unicode.h"
-
-#include "agl.h"
-
-static int verbose = 0;
-
-void
-agl_set_verbose (void)
-{
- verbose++;
-}
-
-static agl_name *
-agl_new_name (void)
-{
- agl_name *agln;
-
- agln = NEW(1, agl_name);
- agln->name = NULL;
- agln->suffix = NULL;
- agln->n_components = 0;
- agln->alternate = NULL;
- agln->is_predef = 0;
-
- return agln;
-}
-
-static void
-agl_release_name (agl_name *agln)
-{
- agl_name *next;
-
- while (agln) {
- next = agln->alternate;
- if (agln->name)
- RELEASE(agln->name);
- if (agln->suffix)
- RELEASE(agln->suffix);
- agln->name = NULL;
- RELEASE(agln);
- agln = next;
- }
-}
-
-char *
-agl_chop_suffix (const char *glyphname, char **suffix)
-{
- char *name, *p;
- int len;
-
- ASSERT(glyphname && suffix);
-
- p = strchr(glyphname, '.');
- if (p) {
- len = strlen(glyphname) - strlen(p);
- if (len < 1) {
- name = NULL;
- *suffix = NEW(strlen(glyphname), char);
- strcpy(*suffix, glyphname+1);
- } else {
- p++;
- name = NEW(len + 1, char);
- strncpy(name, glyphname, len);
- name[len] = '\0';
- if (p[0] == '\0') {
- *suffix = NULL;
- } else {
- *suffix = NEW(strlen(p) + 1, char);
- strcpy(*suffix, p);
- }
- }
- } else {
- name = NEW(strlen(glyphname) + 1, char);
- strcpy(name, glyphname);
- *suffix = NULL;
- }
-
- return name;
-}
-
-static const char * const modifiers[] = {
- "acute", "breve", "caron", "cedilla", "circumflex",
- "dieresis", "dotaccent", "grave", "hungarumlaut",
- "macron", "ogonek", "ring", "tilde", "commaaccent",
- "slash",
-
- /* The following entries are not accent nor something
- * but PS font may have those "small" version...
- */
- "ampersand", "exclam", "exclamdown",
- "question","questiondown",
- NULL
-};
-
-static int
-skip_capital (const char **p, const char *endptr)
-{
- long slen = 0, len;
-
- len = (long) (endptr - (*p));
-
- if (len >= 2 &&
- ((**p == 'A' && *(*p+1) == 'E') ||
- (**p == 'O' && *(*p+1) == 'E'))) {
- *p += 2;
- slen = 2;
- } else if (len >= 3 &&
- **p == 'E' &&
- *(*p+1) == 't' &&
- *(*p+2) == 'h') {
- *p += 3;
- slen = 3;
- } else if (len >= 5 &&
- **p == 'T' &&
- *(*p+1) == 'h' &&
- *(*p+2) == 'o' &&
- *(*p+3) == 'r' &&
- *(*p+4) == 'n') {
- *p += 5;
- slen = 5;
- } else if (len >= 1 &&
- **p >= 'A' && **p <= 'Z') {
- *p += 1;
- slen = 1;
- }
-
- return slen;
-}
-
-static int
-skip_modifier (const char **p, const char *endptr)
-{
- long slen = 0, len;
- int i;
-
- len = (long) (endptr - (*p));
-
- for (i = 0; modifiers[i] != NULL; i++) {
- if ((len >= strlen(modifiers[i]) &&
- !memcmp(*p, modifiers[i], len))) {
- slen = strlen(modifiers[i]);
- *p += slen;
- break;
- }
- }
-
- return slen;
-}
-
-static int
-is_smallcap (const char *glyphname)
-{
- long len, slen;
- const char *p, *endptr;
-
- if (!glyphname)
- return 0;
-
- p = glyphname;
- len = strlen(glyphname);
- if (len < 6 ||
- strcmp(p + len - 5, "small"))
- return 0;
-
- endptr = p + len - 5;
-
- len -= 5;
- slen = skip_modifier(&p, endptr);
- if (slen == len)
- return 1; /* Acutesmall, Gravesmall, etc */
- else if (slen > 0) { /* ??? */
- return 0;
- }
-
- len -= skip_capital(&p, endptr);
- if (len == 0) {
- return 1; /* Asmall, AEsmall, etc */
- }
-
- while (len > 0) { /* allow multiple accent */
- slen = skip_modifier(&p, endptr);
- if (slen == 0)
- return 0;
- len -= slen;
- }
-
- return 1;
-}
-
-#define SUFFIX_LIST_MAX 16
-#define AGL_VAR_SMCP_IDX 0
-static struct {
- const char *key;
- const char *otl_tag;
- const char *suffixes[SUFFIX_LIST_MAX];
-} var_list[] = {
- {"small" , "smcp", {"sc", NULL}},
- {"swash" , "swsh", {NULL}},
- {"superior" , "sups", {NULL}},
- {"inferior" , "sinf", {NULL}},
- {"numerator" , "numr", {NULL}},
- {"denominator" , "dnom", {NULL}},
- {"oldstyle" , "onum", {NULL}},
-
- /* The following only used by TeX, there are no
- * corresponding OTL feat. tag.
- */
- {"display" , NULL, {NULL}},
- {"text" , NULL, {NULL}},
- {"big" , NULL, {NULL}},
- {"bigg" , NULL, {NULL}},
- {"Big" , NULL, {NULL}},
- {"Bigg" , NULL, {NULL}},
- {NULL, NULL, {NULL}}
-};
-
-const char *
-agl_suffix_to_otltag (const char *suffix)
-{
- int i, j;
-
- for (i = 0; var_list[i].key; i++) {
- for (j = 0; var_list[i].suffixes[j]; j++) {
- if (!strcmp(suffix, var_list[i].suffixes[j]))
- return var_list[i].otl_tag;
- }
- if (!strcmp(suffix, var_list[i].key))
- return var_list[i].otl_tag;
- if (var_list[i].otl_tag &&
- !strcmp(suffix, var_list[i].otl_tag))
- return var_list[i].otl_tag;
- }
-
- return NULL;
-}
-
-static int
-agl_guess_name (const char *glyphname)
-{
- int i, len;
-
- if (is_smallcap(glyphname))
- return AGL_VAR_SMCP_IDX;
-
- len = strlen(glyphname);
- for (i = 1; var_list[i].key != NULL; i++) {
- if (len > strlen(var_list[i].key) &&
- !strcmp(glyphname+len-strlen(var_list[i].key), var_list[i].key)
- ) {
- return i;
- }
- }
-
- return -1;
-}
-
-static agl_name *
-agl_normalized_name (char *glyphname)
-{
- agl_name *agln;
- char *suffix;
- int i, n;
-
- if (!glyphname)
- return NULL;
-
- agln = agl_new_name();
- suffix = strchr(glyphname, '.');
- if (suffix) {
- n = strlen(glyphname) - strlen(suffix);
- if (suffix[1] != '\0') {
- agln->suffix = NEW(strlen(suffix), char);
- strcpy(agln->suffix, suffix+1);
- }
- agln->name = NEW(n+1, char);
- memcpy(agln->name, glyphname, n);
- agln->name[n] = '\0';
- } else if (is_smallcap(glyphname)) {
- n = strlen(glyphname) - 5;
- agln->suffix = NEW(3, char);
- strcpy(agln->suffix, "sc");
- agln->name = NEW(n+1, char);
- for (i = 0; i < n; i++) {
- agln->name[i] = isupper(glyphname[i]) ?
- (glyphname[i] + 32) : glyphname[i];
- }
- agln->name[n] = '\0';
- } else {
- int var_idx;
-
-#define SET_STRING(p,s) do {\
- (p) = NEW(strlen((s))+1, char);\
- strcpy((p),(s));\
-} while (0)
- var_idx = agl_guess_name(glyphname);
- if (var_idx < 0 ||
- !var_list[var_idx].key) {
- n = strlen(glyphname);
- } else {
- n = strlen(glyphname) - strlen(var_list[var_idx].key);
- if (var_list[var_idx].suffixes[0])
- SET_STRING(agln->suffix, var_list[var_idx].suffixes[0]);
- else {
- SET_STRING(agln->suffix, var_list[var_idx].key);
- }
- }
- agln->name = NEW(n+1, char);
- memcpy(agln->name, glyphname, n);
- agln->name[n] = '\0';
- }
-
- return agln;
-}
-
-static struct ht_table aglmap;
-
-static void CDECL
-hval_free (void *hval)
-{
- agl_release_name((struct agl_name *) hval);
-}
-
-void
-agl_init_map (void)
-{
- ht_init_table(&aglmap, hval_free);
- agl_load_listfile(AGL_EXTRA_LISTFILE, 0);
- if (agl_load_listfile(AGL_PREDEF_LISTFILE, 1) < 0) {
- WARN("Failed to load AGL file \"%s\"...", AGL_PREDEF_LISTFILE);
- }
- if (agl_load_listfile(AGL_DEFAULT_LISTFILE, 0) < 0) {
- WARN("Failed to load AGL file \"%s\"...", AGL_DEFAULT_LISTFILE);
- }
-}
-
-void
-agl_close_map (void)
-{
- ht_clear_table(&aglmap);
-}
-
-#define WBUF_SIZE 1024
-
-int
-agl_load_listfile (const char *filename, int is_predef)
-{
- int count = 0;
- const char *p, *endptr;
- char *nextptr;
- char wbuf[WBUF_SIZE];
- FILE *fp;
-
- if (!filename)
- return -1;
-
- fp = DPXFOPEN(filename, DPX_RES_TYPE_AGL);
- if (!fp) {
- return -1;
- }
-
- if (verbose)
- MESG("<AGL:%s", filename);
-
- while ((p = mfgets(wbuf, WBUF_SIZE, fp)) != NULL) {
- agl_name *agln, *duplicate;
- char *name;
- int n_unicodes, i;
- long unicodes[AGL_MAX_UNICODES];
-
- endptr = p + strlen(p);
- skip_white(&p, endptr);
-
- /* Need table version check. */
- if (!p || p[0] == '#' || p >= endptr)
- continue;
- nextptr = strchr(p, ';');
- if (!nextptr || nextptr == p)
- continue;
-
- name = parse_ident(&p, nextptr);
-
- skip_white(&p, endptr);
- if (!name || p[0] != ';') {
- WARN("Invalid AGL entry: %s", wbuf);
- if (name)
- RELEASE(name);
- continue;
- }
-
- p++;
- skip_white(&p, endptr);
-
- n_unicodes = 0;
- while (p < endptr &&
- ((p[0] >= '0' && p[0] <= '9') ||
- (p[0] >= 'A' && p[0] <= 'F'))
- ) {
-
- if (n_unicodes >= AGL_MAX_UNICODES) {
- WARN("Too many Unicode values");
- break;
- }
- unicodes[n_unicodes++] = strtol(p, &nextptr, 16);
-
- p = nextptr;
- skip_white(&p, endptr);
- }
-
- if (n_unicodes == 0) {
- WARN("AGL entry ignored (no mapping): %s", wbuf);
- RELEASE(name);
- continue;
- }
-
- agln = agl_normalized_name(name);
- agln->is_predef = is_predef;
- agln->n_components = n_unicodes;
- for (i = 0; i < n_unicodes; i++) {
- agln->unicodes[i] = unicodes[i];
- }
-
- duplicate = ht_lookup_table(&aglmap, name, strlen(name));
- if (!duplicate)
- ht_append_table(&aglmap, name, strlen(name), agln);
- else {
- while (duplicate->alternate)
- duplicate = duplicate->alternate;
- duplicate->alternate = agln;
- }
-
- if (verbose > 3) {
- if (agln->suffix)
- MESG("agl: %s [%s.%s] -->", name, agln->name, agln->suffix);
- else
- MESG("agl: %s [%s] -->", name, agln->name);
- for (i = 0; i < agln->n_components; i++) {
- if (agln->unicodes[i] > 0xffff) {
- MESG(" U+%06X", agln->unicodes[i]);
- } else {
- MESG(" U+%04X", agln->unicodes[i]);
- }
- }
- MESG("\n");
- }
-
- RELEASE(name);
- count++;
- }
- DPXFCLOSE(fp);
-
- if (verbose)
- MESG(">");
-
- return count;
-}
-
-agl_name *
-agl_lookup_list (const char *glyphname)
-{
- agl_name *agln;
-
- if (!glyphname)
- return NULL;
-
- agln = ht_lookup_table(&aglmap, glyphname, strlen(glyphname));
-
- return agln;
-}
-
-int
-agl_name_is_unicode (const char *glyphname)
-{
- char c, *suffix;
- int i, len;
-
- if (!glyphname)
- return 0;
-
- suffix = strchr(glyphname, '.');
- len = (int) (suffix ? suffix - glyphname : strlen(glyphname));
- /*
- * uni02ac is invalid glyph name and mapped to th empty string.
- */
- if (len >= 7 && (len - 3) % 4 == 0 &&
- !strncmp(glyphname, "uni", 3)) {
- c = glyphname[3];
- /*
- * Check if the 4th character is uppercase hexadecimal digit.
- * "union" should not be treated as Unicode glyph name.
- */
- if (isdigit(c) || (c >= 'A' && c <= 'F'))
- return 1;
- else
- return 0;
- } else if (len <= 7 && len >= 5 &&
- glyphname[0] == 'u') {
- for (i = 1; i < len - 1; i++) {
- c = glyphname[i];
- if (!isdigit(c) && (c < 'A' || c > 'F'))
- return 0;
- }
- return 1;
- }
-
- return 0;
-}
-
-long
-agl_name_convert_unicode (const char *glyphname)
-{
- long ucv = -1;
- const char *p;
-
- if (!agl_name_is_unicode(glyphname))
- return -1;
-
- if (strlen(glyphname) > 7 && *(glyphname+7) != '.') {
- WARN("Mapping to multiple Unicode characters not supported.");
- return -1;
- }
-
- if (glyphname[1] == 'n')
- p = glyphname + 3;
- else
- p = glyphname + 1;
- ucv = 0;
- while (*p != '\0' && *p != '.') {
- if (!isdigit(*p) && (*p < 'A' || *p > 'F')) {
- WARN("Invalid char %c in Unicode glyph name %s.", *p, glyphname);
- return -1;
- }
- ucv <<= 4;
- ucv += isdigit(*p) ? *p - '0' : *p - 'A' + 10;
- p++;
- }
-
- if (!UC_is_valid(ucv)) {
- if (ucv < 0x10000) {
- WARN("Invalid Unicode code value U+%04X.", ucv);
- } else {
- WARN("Invalid Unicode code value U+%06X.", ucv);
- }
- ucv = -1;
- }
-
- return ucv;
-}
-
-
-
-static long
-xtol (const char *start, int len)
-{
- long v = 0;
-
- while (len-- > 0) {
- v <<= 4;
- if (isdigit(*start)) {
- v += *start - '0';
- } else if (*start >= 'A' && *start <= 'F') {
- v += *start - 'A' + 10;
- } else {
- return -1;
- }
- start++;
- }
-
- return v;
-}
-
-#define IS_PUA(u) (((u) >= 0x00E000L && (u) <= 0x00F8FFL) || \
- ((u) >= 0x0F0000L && (u) <= 0x0FFFFDL) || \
- ((u) >= 0x100000L && (u) <= 0x10FFFDL) \
-)
-
-static long
-put_unicode_glyph (const char *name,
- unsigned char **dstpp, unsigned char *limptr)
-{
- const char *p;
- long len = 0, ucv;
-
- p = name;
- ucv = 0;
-
- if (p[1] != 'n') {
- p += 1;
- ucv = xtol(p, strlen(p));
- len += UC_sput_UTF16BE (ucv, dstpp, limptr);
- } else {
- p += 3;
- while (*p != '\0') {
- ucv = xtol(p, 4);
- len += UC_sput_UTF16BE (ucv, dstpp, limptr);
- p += 4;
- }
- }
-
- return len;
-}
-
-long
-agl_sput_UTF16BE (const char *glyphstr,
- unsigned char **dstpp, unsigned char *limptr,
- int *fail_count)
-{
- long len = 0;
- int count = 0;
- const char *p, *endptr;
-
- ASSERT(glyphstr && dstpp);
-
- p = glyphstr;
- endptr = strchr(p, '.');
- if (!endptr)
- endptr = p + strlen(p);
-
- while (p < endptr) {
- char *name;
- const char *delim;
- long sub_len;
- int i;
- agl_name *agln0, *agln1 = NULL;
-
- delim = strchr(p, '_');
- if (delim == p) {
- /*
- * Glyph names starting with a underscore or two subsequent
- * underscore in glyph name not allowed?
- */
- WARN("Invalid glyph name component in \"%s\".", glyphstr);
- count++;
- if (fail_count)
- *fail_count = count;
- return len; /* Cannot continue */
- } else if (!delim || delim > endptr) {
- delim = endptr;
- }
- sub_len = (long) (delim - p);
-
- name = NEW(sub_len+1, char);
- memcpy(name, p, sub_len);
- name[sub_len] = '\0';
-
- if (agl_name_is_unicode(name)) {
- sub_len = put_unicode_glyph(name, dstpp, limptr);
- if (sub_len > 0)
- len += sub_len;
- else {
- count++;
- }
- } else {
- agln1 = agl_lookup_list(name);
- if (!agln1 || (agln1->n_components == 1 &&
- IS_PUA(agln1->unicodes[0]))) {
- agln0 = agl_normalized_name(name);
- if (agln0) {
- if (verbose > 1 && agln0->suffix) {
- WARN("agl: fix %s --> %s.%s",
- name, agln0->name, agln0->suffix);
- }
- agln1 = agl_lookup_list(agln0->name);
- agl_release_name(agln0);
- }
- }
- if (agln1) {
- for (i = 0; i < agln1->n_components; i++) {
- len += UC_sput_UTF16BE (agln1->unicodes[i], dstpp, limptr);
- }
- } else {
- if (verbose) {
- WARN("No Unicode mapping for glyph name \"%s\" found.", name);
- }
- count++;
- }
- }
- RELEASE(name);
- p = delim + 1;
- }
-
- if (fail_count)
- *fail_count = count;
- return len;
-}
-
-int
-agl_get_unicodes (const char *glyphstr,
- long *unicodes, int max_unicodes)
-{
- int count = 0;
- const char *p, *endptr;
-
- p = glyphstr;
- endptr = strchr(p, '.');
- if (!endptr)
- endptr = p + strlen(p);
-
- while (p < endptr) {
- char *name;
- const char *delim;
- long sub_len;
- int i;
- agl_name *agln0, *agln1 = NULL;
-
- delim = strchr(p, '_');
- if (delim == p) {
- /*
- * Glyph names starting with a underscore or two subsequent
- * underscore in glyph name not allowed?
- */
- WARN("Invalid glyph name component in \"%s\".", glyphstr);
- return -1; /* Cannot continue */
- } else if (!delim || delim > endptr) {
- delim = endptr;
- }
- sub_len = (long) (delim - p);
-
- name = NEW(sub_len+1, char);
- memcpy(name, p, sub_len);
- name[sub_len] = '\0';
-
- if (agl_name_is_unicode(name)) {
- p = name;
- if (p[1] != 'n') { /* uXXXXXXXX */
- if (count >= max_unicodes) {
- RELEASE(name);
- return -1;
- }
- p++;
- unicodes[count++] = xtol(p, strlen(p));
- } else {
- p += 3;
- while (*p != '\0') {
- if (count >= max_unicodes) {
- RELEASE(name);
- return -1;
- }
- unicodes[count++] = xtol(p, 4);
- p += 4;
- }
- }
- } else {
- agln1 = agl_lookup_list(name);
- if (!agln1 || (agln1->n_components == 1 &&
- IS_PUA(agln1->unicodes[0]))) {
- agln0 = agl_normalized_name(name);
- if (agln0) {
- if (verbose > 1 && agln0->suffix) {
- WARN("agl: fix %s --> %s.%s",
- name, agln0->name, agln0->suffix);
- }
- agln1 = agl_lookup_list(agln0->name);
- agl_release_name(agln0);
- }
- }
- if (agln1) {
- if (count + agln1->n_components > max_unicodes) {
- RELEASE(name);
- return -1;
- }
- for (i = 0; i < agln1->n_components; i++) {
- unicodes[count++] = agln1->unicodes[i];
- }
- } else {
- if (verbose > 1)
- WARN("No Unicode mapping for glyph name \"%s\" found.", name);
- RELEASE(name);
- return -1;
- }
- }
- RELEASE(name);
- p = delim + 1;
- }
-
- return count;
-}