diff options
Diffstat (limited to 'Build/source/texk/dvipdfmx/dvipdfmx-20110305/src/t1_load.c')
-rw-r--r-- | Build/source/texk/dvipdfmx/dvipdfmx-20110305/src/t1_load.c | 1211 |
1 files changed, 0 insertions, 1211 deletions
diff --git a/Build/source/texk/dvipdfmx/dvipdfmx-20110305/src/t1_load.c b/Build/source/texk/dvipdfmx/dvipdfmx-20110305/src/t1_load.c deleted file mode 100644 index 2ba439bdaa7..00000000000 --- a/Build/source/texk/dvipdfmx/dvipdfmx-20110305/src/t1_load.c +++ /dev/null @@ -1,1211 +0,0 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/t1_load.c,v 1.14 2011/03/06 03:14:15 chofchof Exp $ - - This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. - - Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, - the dvipdfmx project team <dvipdfmx@project.ktug.or.kr> - - 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. -*/ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <math.h> - -#include "system.h" -#include "mfileio.h" -#include "mem.h" -#include "error.h" -#include "numbers.h" - -#include "pdfobj.h" -#include "pdffont.h" - -#include "pdfencoding.h" -#include "unicode.h" - -#include "dpxutil.h" - -#include "pst_obj.h" -#include "pst.h" - -#include "cff_limits.h" -#include "cff_types.h" -#include "cff_dict.h" -#include "cff.h" - -#include "t1_load.h" - -/* Migrated from t1crypt */ -#define T1_EEKEY 55665u -#define T1_CHARKEY 4330u - -#if 0 -/* We no longer need encryption. */ -static unsigned short r = T1_EEKEY, c1 = 52845, c2 = 22719; - -static unsigned char t1_encrypt (unsigned char plain) -{ - unsigned char cipher; - cipher = (plain ^ (r >> 8)); - r = (cipher + r) * c1 + c2; - return cipher; -} - -static void t1_crypt_init (unsigned short key) -{ - r = key; -} -#endif /* 0 */ - -static void -t1_decrypt (unsigned short key, - unsigned char *dst, const unsigned char *src, - long skip, long len) -{ - len -= skip; - while (skip--) - key = (key + *src++) * 52845u + 22719u; - while (len--) { - unsigned char c = *src++; - *dst++ = (c ^ (key >> 8)); - key = (key + c) * 52845u + 22719u; - } -} -/* T1CRYPT */ - -#define MATCH_NAME(t,n) ((t) && PST_NAMETYPE((t)) && !strncmp(pst_data_ptr((t)),(n),strlen((n)))) -#define MATCH_OP(t,n) ((t) && PST_UNKNOWNTYPE((t)) && !strncmp(pst_data_ptr((t)),(n),strlen((n)))) - -#define RELEASE_TOK(t) if ((t) != NULL) {\ - pst_release_obj((t));\ - (t) = NULL;\ -} - -static char * -get_next_key (unsigned char **start, unsigned char *end) -{ - char *key = NULL; - pst_obj *tok; - - while (*start < end && - (tok = pst_get_token(start, end)) != NULL) { - if (PST_NAMETYPE(tok)) { - key = (char *) pst_getSV(tok); - RELEASE_TOK(tok); - break; - } - RELEASE_TOK(tok); - } - - return key; -} - -static int -seek_operator (unsigned char **start, unsigned char *end, const char *op) -{ - pst_obj *tok = NULL; - - while (*start < end && - (tok = pst_get_token(start, end)) != NULL) { - if (MATCH_OP(tok, op)) { - break; - } - RELEASE_TOK(tok); - } - - if (tok == NULL) - return -1; - RELEASE_TOK(tok); - - return 0; -} - - -static int -parse_svalue (unsigned char **start, unsigned char *end, char **value) -{ - pst_obj *tok; - - tok = pst_get_token(start, end); - if (tok == NULL) - return -1; - else if (PST_NAMETYPE(tok) || PST_STRINGTYPE(tok)) - *value = (char *) pst_getSV(tok); - else { - RELEASE_TOK(tok); - return -1; - } - RELEASE_TOK(tok); - - return 1; -} - -static int -parse_bvalue (unsigned char **start, unsigned char *end, double *value) -{ - pst_obj *tok; - - tok = pst_get_token(start, end); - if (tok == NULL) - return -1; - else if (PST_BOOLEANTYPE(tok)) - *value = (double) pst_getIV(tok); - else { - RELEASE_TOK(tok); - return -1; - } - RELEASE_TOK(tok); - - return 1; -} - -static int -parse_nvalue (unsigned char **start, unsigned char *end, double *value, int max) -{ - int argn = 0; - pst_obj *tok; - - tok = pst_get_token(start, end); - if (tok == NULL) - return -1; - /* - * All array elements must be numeric token. (ATM compatible) - */ - if (PST_NUMBERTYPE(tok) && max > 0) { - value[0] = (double) pst_getRV(tok); - argn = 1; - } else if (PST_MARKTYPE(tok)) { - /* It does not distinguish '[' and '{'... */ - RELEASE_TOK(tok); - while (*start < end && - (tok = pst_get_token(start, end)) != NULL && - PST_NUMBERTYPE(tok) && argn < max) { - value[argn++] = (double) pst_getRV(tok); - RELEASE_TOK(tok); - } - if (tok == NULL) - return -1; - if (!MATCH_OP(tok, "]") && !MATCH_OP(tok, "}")) { - argn = -1; - } - } - RELEASE_TOK(tok); - - return argn; -} - -static const char *const StandardEncoding[256] = { - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", "space", "exclam", "quotedbl", - "numbersign", "dollar", "percent", "ampersand", "quoteright", - "parenleft", "parenright", "asterisk", "plus", "comma", - "hyphen", "period", "slash", "zero", "one", - "two", "three", "four", "five", "six", - "seven", "eight", "nine", "colon", "semicolon", - "less", "equal", "greater", "question", "at", - "A", "B", "C", "D", "E", - "F", "G", "H", "I", "J", - "K", "L", "M", "N", "O", - "P", "Q", "R", "S", "T", - "U", "V", "W", "X", "Y", - "Z", "bracketleft", "backslash", "bracketright", "asciicircum", - "underscore", "quoteleft", "a", "b", "c", - "d", "e", "f", "g", "h", - "i", "j", "k", "l", "m", - "n", "o", "p", "q", "r", - "s", "t", "u", "v", "w", - "x", "y", "z", "braceleft", "bar", - "braceright", "asciitilde", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", "exclamdown", "cent", "sterling", "fraction", - "yen", "florin", "section", "currency", "quotesingle", - "quotedblleft", "guillemotleft", "guilsinglleft", "guilsinglright", "fi", - "fl", ".notdef", "endash", "dagger", "daggerdbl", - "periodcentered", ".notdef", "paragraph", "bullet", "quotesinglbase", - "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", - ".notdef", "questiondown", ".notdef", "grave", "acute", - "circumflex", "tilde", "macron", "breve", "dotaccent", - "dieresis", ".notdef", "ring", "cedilla", ".notdef", - "hungarumlaut", "ogonek", "caron", "emdash", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - "AE", ".notdef", "ordfeminine", ".notdef", ".notdef", - ".notdef", ".notdef", "Lslash", "Oslash", "OE", - "ordmasculine", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", "ae", ".notdef", ".notdef", ".notdef", - "dotlessi", ".notdef", ".notdef", "lslash", "oslash", - "oe", "germandbls", ".notdef", ".notdef", ".notdef", - ".notdef" -}; - -static const char *const ISOLatin1Encoding[256] = { - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", "space", "exclam", "quotedbl", - "numbersign", "dollar", "percent", "ampersand", "quotesingle", - "parenleft", "parenright", "asterisk", "plus", "comma", - "hyphen", "period", "slash", "zero", "one", - "two", "three", "four", "five", "six", - "seven", "eight", "nine", "colon", "semicolon", - "less", "equal", "greater", "question", "at", - "A", "B", "C", "D", "E", - "F", "G", "H", "I", "J", - "K", "L", "M", "N", "O", - "P", "Q", "R", "S", "T", - "U", "V", "W", "X", "Y", - "Z", "bracketleft", "backslash", "bracketright", "asciicircum", - "underscore", "grave", "a", "b", "c", - "d", "e", "f", "g", "h", - "i", "j", "k", "l", "m", - "n", "o", "p", "q", "r", - "s", "t", "u", "v", "w", - "x", "y", "z", "braceleft", "bar", - "braceright", "asciitilde", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", ".notdef", - ".notdef", ".notdef", ".notdef", ".notdef", "dotlessi", - "quoteleft", "quoteright", "circumflex", "tilde", "macron", - "breve", "dotaccent", "dieresis", ".notdef", "ring", - "cedilla", ".notdef", "hungarumlaut", "ogonek", "caron", - "space", "exclamdown", "cent", "sterling", "currency", - "yen", "brokenbar", "section", "dieresis", "copyright", - "ordfeminine", "guillemotleft", "logicalnot", "hyphen", - "registered", - "macron", "degree", "plusminus", "twosuperior", "threesuperior", - "acute", "mu", "paragraph", "periodcentered", "cedilla", - "onesuperior", "ordmasculine", "guillemotright", "onequarter", - "onehalf", - "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex", - "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", - "Egrave", "Eacute", "Ecircumflex", "Edieresis", "Igrave", - "Iacute", "Icircumflex", "Idieresis", "Eth", "Ntilde", - "Ograve", "Oacute", "Ocircumflex", "Otilde", "Odieresis", - "multiply", "Oslash", "Ugrave", "Uacute", "Ucircumflex", - "Udieresis", "Yacute", "Thorn", "germandbls", "agrave", - "aacute", "acircumflex", "atilde", "adieresis", "aring", - "ae", "ccedilla", "egrave", "eacute", "ecircumflex", - "edieresis", "igrave", "iacute", "icircumflex", "idieresis", - "eth", "ntilde", "ograve", "oacute", "ocircumflex", - "otilde", "odieresis", "divide", "oslash", "ugrave", - "uacute", "ucircumflex", "udieresis", "yacute", "thorn", - "ydieresis" -}; - -static int -parse_encoding (char **enc_vec, unsigned char **start, unsigned char *end, int mode) -{ - pst_obj *tok; - int code; - - /* - * StandardEncoding def - * or - * ISOLatin1Encoding def - * or - * 0 1 255 {1 index exch /.notdef put } for - * dup int name put - * ... - * [readonly] def - */ - tok = pst_get_token(start, end); - if (MATCH_OP(tok, "StandardEncoding")) { - RELEASE_TOK(tok); - if (enc_vec) { - for (code = 0; code < 256; code++) { - if (StandardEncoding[code] && - strcmp(StandardEncoding[code], ".notdef") != 0) { - enc_vec[code] = NEW(strlen(StandardEncoding[code])+1, char); - strcpy(enc_vec[code], StandardEncoding[code]); - } else { - enc_vec[code] = NULL; - } - } - } - } else if (MATCH_OP(tok, "ISOLatin1Encoding")) { - RELEASE_TOK(tok); - if (enc_vec) { - for (code = 0; code < 256; code++) { - if (ISOLatin1Encoding[code] && - strcmp(ISOLatin1Encoding[code], ".notdef") != 0) { - enc_vec[code] = NEW(strlen(ISOLatin1Encoding[code])+1, char); - strcpy(enc_vec[code], ISOLatin1Encoding[code]); - } else { - enc_vec[code] = NULL; - } - } - } - } else if (MATCH_OP(tok, "ExpertEncoding")) { - RELEASE_TOK(tok); - if (enc_vec) { - WARN("ExpertEncoding not supported."); - RELEASE_TOK(tok); - return -1; - } - /* - * Not supported yet. - */ - } else { - RELEASE_TOK(tok); - seek_operator(start, end, "array"); - /* - * Pick all seaquences that matches "dup n /Name put" until - * occurrence of "def" or "readonly". - */ - while (*start < end && - (tok = pst_get_token(start, end)) != NULL) { - if (MATCH_OP(tok, "def") || MATCH_OP(tok, "readonly")) { - RELEASE_TOK(tok); - break; - } else if (!MATCH_OP(tok, "dup")) { - RELEASE_TOK(tok); - continue; - } - RELEASE_TOK(tok); - - tok = pst_get_token(start, end); - if (!tok || !PST_INTEGERTYPE(tok) || - (code = pst_getIV(tok)) > 255 || code < 0) { - RELEASE_TOK(tok); - continue; - } - RELEASE_TOK(tok); - - tok = pst_get_token(start, end); - if (!tok || !PST_NAMETYPE(tok)) { - RELEASE_TOK(tok); - continue; - } - if (enc_vec) { - if (enc_vec[code]) - RELEASE(enc_vec[code]); - enc_vec[code] = (char *) pst_getSV(tok); - } - RELEASE_TOK(tok); - - tok = pst_get_token(start, end); - if (!MATCH_OP(tok, "put")) { - if (enc_vec[code]) { - RELEASE(enc_vec[code]); - enc_vec[code] = NULL; - } - RELEASE_TOK(tok); - continue; - } - RELEASE_TOK(tok); - } - } - - return 0; -} - -#ifndef CS_STR_LEN_MAX -#define CS_STR_LEN_MAX 65536UL -#endif -#ifndef CFF_GLYPH_MAX -#define CFF_GLYPH_MAX CFF_SID_MAX -#endif - -static int -parse_subrs (cff_font *font, - unsigned char **start, unsigned char *end, int lenIV, int mode) -{ - cff_index *subrs; - pst_obj *tok; - long i, count, offset, max_size; - long *offsets, *lengths; - card8 *data; - - tok = pst_get_token(start, end); - if (!PST_INTEGERTYPE(tok) || pst_getIV(tok) < 0) { - WARN("Parsing Subrs failed."); - RELEASE_TOK(tok); - return -1; - } - - count = pst_getIV(tok); - RELEASE_TOK(tok); - - if (count == 0) { - font->subrs[0] = NULL; - return 0; - } - - tok = pst_get_token(start, end); - if (!MATCH_OP(tok, "array")) { - RELEASE_TOK(tok); - return -1; - } - RELEASE_TOK(tok); - - if (mode != 1) { - max_size = CS_STR_LEN_MAX; - data = NEW(max_size, card8); - offsets = NEW(count, long); - lengths = NEW(count, long); - memset(offsets, 0, sizeof(long)*count); - memset(lengths, 0, sizeof(long)*count); - } else { - max_size = 0; - data = NULL; - offsets = NULL; - lengths = NULL; - } - - offset = 0; - /* dup subr# n-bytes RD n-binary-bytes NP */ - for (i = 0; i < count;) { - long idx, len; - - tok = pst_get_token(start, end); - if (!tok) { - if (data) RELEASE(data); - if (offsets) RELEASE(offsets); - if (lengths) RELEASE(lengths); - return -1; - } else if (MATCH_OP(tok, "ND") || - MATCH_OP(tok, "|-") || MATCH_OP(tok, "def")) { - RELEASE_TOK(tok); - break; - } else if (!MATCH_OP(tok, "dup")) { - RELEASE_TOK(tok); - continue; - } - RELEASE_TOK(tok); - - /* Found "dup" */ - tok = pst_get_token(start, end); - if (!PST_INTEGERTYPE(tok) || pst_getIV(tok) < 0 || - pst_getIV(tok) >= count) { - RELEASE_TOK(tok); - if (data) RELEASE(data); - if (offsets) RELEASE(offsets); - if (lengths) RELEASE(lengths); - return -1; - } - idx = pst_getIV(tok); - RELEASE_TOK(tok); - - tok = pst_get_token(start, end); - if (!PST_INTEGERTYPE(tok) || pst_getIV(tok) < 0 || - pst_getIV(tok) > CS_STR_LEN_MAX) { - RELEASE_TOK(tok); - return -1; - } - len = pst_getIV(tok); - RELEASE_TOK(tok); - - tok = pst_get_token(start, end); - if (!MATCH_OP(tok, "RD") && !MATCH_OP(tok, "-|") && - seek_operator(start, end, "readstring") < 0) { - RELEASE_TOK(tok); - if (data) RELEASE(data); - if (offsets) RELEASE(offsets); - if (lengths) RELEASE(lengths); - return -1; - } - RELEASE_TOK(tok); - - *start += 1; - if (*start + len >= end) { - if (data) RELEASE(data); - if (offsets) RELEASE(offsets); - if (lengths) RELEASE(lengths); - return -1; - } - if (mode != 1) { - if (offset + len >= max_size) { - max_size += CS_STR_LEN_MAX; - data = RENEW(data, max_size, card8); - } - if (lenIV >= 0) { - t1_decrypt(T1_CHARKEY, data+offset, *start, lenIV, len); - offsets[idx] = offset; - offset += (lengths[idx] = len - lenIV); - } else if (len > 0) { - offsets[idx] = offset; - lengths[idx] = len; - memcpy(&data[offset], *start, len); - offset += len; - } - } - *start += len; - i++; - } - - if (mode != 1) { - if (font->subrs[0] == NULL) { - subrs = font->subrs[0] = cff_new_index(count); - subrs->data = NEW(offset, card8); - offset = 0; - for (i = 0; i < count; i++) { - subrs->offset[i] = offset + 1; - if (lengths[i] > 0) { - memcpy(subrs->data + offset, data + offsets[i], lengths[i]); - offset += lengths[i]; - } - } - subrs->offset[count] = offset + 1; - } else { - /* Adobe's OPO_____.PFB and OPBO____.PFB have two /Subrs dicts, - * and also have /CharStrings not followed by dicts. - * Simply ignores those data. By ChoF on 2009/04/08. */ - WARN("Already found /Subrs; ignores the other /Subrs dicts."); - } - RELEASE(data); - RELEASE(offsets); - RELEASE(lengths); - } - - return 0; -} - -static int -parse_charstrings (cff_font *font, - unsigned char **start, unsigned char *end, int lenIV, int mode) -{ - cff_index *charstrings; - cff_charsets *charset; - pst_obj *tok; - long i, count, have_notdef; - long max_size, offset; - - /* /CharStrings n dict dup begin - * /GlyphName n-bytes RD -n-binary-bytes- ND - * ... - * end - * - stack - ... /CharStrings dict - */ - tok = pst_get_token(start, end); - if (!PST_INTEGERTYPE(tok) || - pst_getIV(tok) < 0 || pst_getIV(tok) > CFF_GLYPH_MAX) { - unsigned char *s = pst_getSV(tok); - WARN("Ignores non dict \"/CharStrings %s ...\"", s); - RELEASE(s); - RELEASE_TOK(tok); - return 0; - } - count = pst_getIV(tok); - RELEASE_TOK(tok); - - if (mode != 1) { - charstrings = cff_new_index(count); - max_size = CS_STR_LEN_MAX; - charstrings->data = NEW(max_size, card8); - } else { - charstrings = NULL; - max_size = 0; - } - font->cstrings = charstrings; - - charset = font->charsets = NEW(1, cff_charsets); - charset->format = 0; - charset->num_entries = count-1; - charset->data.glyphs = NEW(count-1, s_SID); - memset(charset->data.glyphs, 0, sizeof(s_SID)*(count-1)); - - offset = 0; - have_notdef = 0; /* .notdef must be at gid = 0 in CFF */ - - seek_operator(start, end, "begin"); - for (i = 0; i < count; i++) { - char *glyph_name; - long len, gid, j; - - /* BUG-20061126 (by ChoF): - * Some fonts (e.g., belleek/blsy.pfb) does not have the correct number - * of glyphs. Modify the codes even to work with these broken fonts. - */ - tok = pst_get_token(start, end); - glyph_name = (char *)pst_getSV(tok); - - if (PST_NAMETYPE(tok)) { - RELEASE_TOK(tok); - if (!glyph_name) { - return -1; - } else if (!strcmp(glyph_name, ".notdef")) { - gid = 0; - have_notdef = 1; - } else if (have_notdef) { - gid = i; - } else if (i == count - 1) { - WARN("No .notdef glyph???"); - return -1; - } else { - gid = i+1; - } - } else if (PST_UNKNOWNTYPE(tok) && !strcmp(glyph_name, "end")) { - RELEASE_TOK(tok); - break; - } else { - RELEASE_TOK(tok); - return -1; - } - - if (gid > 0) - charset->data.glyphs[gid-1] = cff_add_string(font, glyph_name, 0); - /* - * We don't care about duplicate strings here since - * later a subset font of this font will be generated. - */ - - RELEASE(glyph_name); - - tok = pst_get_token(start, end); - if (!PST_INTEGERTYPE(tok) || - pst_getIV(tok) < 0 || pst_getIV(tok) > CS_STR_LEN_MAX) { - RELEASE_TOK(tok); - return -1; - } - len = pst_getIV(tok); - RELEASE_TOK(tok); - - tok = pst_get_token(start, end); - if (!MATCH_OP(tok, "RD") && - !MATCH_OP(tok, "-|") && - seek_operator(start, end, "readstring") < 0) { - RELEASE_TOK(tok); - return -1; - } - RELEASE_TOK(tok); - - if (*start + len + 1 >= end) { - return -1; - } - if (mode != 1) { - if (offset + len >= max_size) { - max_size += MAX(len, CS_STR_LEN_MAX); - charstrings->data = RENEW(charstrings->data, max_size, card8); - } - if (gid == 0) { - if (lenIV >= 0) { - memmove(charstrings->data + len - lenIV, charstrings->data, offset); - for (j = 1; j <= i; j++) { - charstrings->offset[j] += len - lenIV; - } - } else { - memmove(charstrings->data + len, charstrings->data, offset); - for (j = 1; j <= i; j++) { - charstrings->offset[j] += len; - } - } - } - } - - *start += 1; - if (mode != 1) { - if (lenIV >= 0) { - long offs = gid ? offset : 0; - charstrings->offset[gid] = offs + 1; /* start at 1 */ - t1_decrypt(T1_CHARKEY, charstrings->data+offs, *start, lenIV, len); - offset += len - lenIV; - } else { - if (gid == 0) { - charstrings->offset[gid] = 1; - memcpy(&charstrings->data[0], *start, len); - } else { - charstrings->offset[gid] = offset + 1; - memcpy(&charstrings->data[offset], *start, len); - } - offset += len; - } - } - *start += len; - - tok = pst_get_token(start, end); - if (!MATCH_OP(tok, "ND") && !MATCH_OP(tok, "|-")) { - RELEASE_TOK(tok); - return -1; - } - RELEASE_TOK(tok); - } - if (mode != 1) - charstrings->offset[count] = offset + 1; - font->num_glyphs = count; - - return 0; -} - -#define CHECK_ARGN_EQ(n) if (argn != (n)) {\ - WARN("%d values expected but only %d read.", (n), argn);\ - RELEASE(key);\ - return -1;\ -} -#define CHECK_ARGN_GE(n) if (argn < (n)) {\ - WARN("%d values expected but only %d read.", (n), argn);\ - RELEASE(key);\ - return -1;\ -} - -#define MAX_ARGS 127 -static int -parse_part2 (cff_font *font, unsigned char **start, unsigned char *end, int mode) -{ - char *key; - double argv[MAX_ARGS]; - int argn, lenIV = 4; - - while (*start < end && - (key = get_next_key(start, end)) != NULL) { - if (!strcmp(key, "Subrs")) { - /* levIV must appear before Subrs */ - if (parse_subrs(font, start, end, lenIV, mode) < 0) { - RELEASE(key); - return -1; - } - } else if (!strcmp(key, "CharStrings")) { - if (parse_charstrings(font, start, end, lenIV, mode) < 0) { - RELEASE(key); - return -1; - } - } else if (!strcmp(key, "lenIV")) { - argn = parse_nvalue(start, end, argv, 1); - CHECK_ARGN_EQ(1); - lenIV = (int) argv[0]; - } else if (!strcmp(key, "BlueValues") || - !strcmp(key, "OtherBlues") || - !strcmp(key, "FamilyBlues") || - !strcmp(key, "FamilyOtherBlues") || - !strcmp(key, "StemSnapH") || - !strcmp(key, "StemSnapV")) { - /* - * Operand values are delta in CFF font dictionary encoding. - */ - argn = parse_nvalue(start, end, argv, MAX_ARGS); - CHECK_ARGN_GE(0); - cff_dict_add(font->private[0], key, argn); - while (argn-- > 0) { - cff_dict_set(font->private[0], key, argn, - (argn == 0) ? argv[argn] : argv[argn] - argv[argn-1]); - } - } else if (!strcmp(key, "StdHW") || - !strcmp(key, "StdVW") || - !strcmp(key, "BlueScale") || - !strcmp(key, "BlueShift") || - !strcmp(key, "BlueFuzz") || - !strcmp(key, "LanguageGroup") || - !strcmp(key, "ExpansionFactor")) { - /* - * Value of StdHW and StdVW is described as an array in the - * Type 1 Font Specification but is a number in CFF format. - */ - argn = parse_nvalue(start, end, argv, 1); - CHECK_ARGN_EQ(1); - cff_dict_add(font->private[0], key, 1); - cff_dict_set(font->private[0], key, 0, argv[0]); - } else if (!strcmp(key, "ForceBold")) { - argn = parse_bvalue(start, end, &(argv[0])); - CHECK_ARGN_EQ(1); - if (argv[0] != 0) { - cff_dict_add(font->private[0], key, 1); - cff_dict_set(font->private[0], key, 0, 1); - } - } - /* - * MinFeature, RndStemUp, UniqueID, Password ignored. - */ - RELEASE(key); - } - - return 0; -} - -#ifndef TYPE1_NAME_LEN_MAX -#define TYPE1_NAME_LEN_MAX 127 -#endif - -static long -parse_part1 (cff_font *font, char **enc_vec, - unsigned char **start, unsigned char *end, int mode) -{ - char *key, *strval; - double argv[MAX_ARGS]; - int argn; /* Macro CHECK_ARGN_XX assume 'argn' is used. */ - - /* - * We skip PostScript code inserted before the beginning of - * font dictionary so that parser will not be confused with - * it. See LMRoman10-Regular (lmr10.pfb) for example. - */ - if (seek_operator(start, end, "begin") < 0) - return -1; - - while (*start < end && - (key = get_next_key(start, end)) != NULL) { - if (!strcmp(key, "Encoding")) { - if (parse_encoding(enc_vec, start, end, mode) < 0) { - RELEASE(key); - return -1; - } - } else if (!strcmp(key, "FontName")) { - argn = parse_svalue(start, end, &strval); - CHECK_ARGN_EQ(1); - if (strlen(strval) > TYPE1_NAME_LEN_MAX) { - WARN("FontName too long: %s (%d bytes)", strval, strlen(strval)); - strval[TYPE1_NAME_LEN_MAX] = '\0'; - } - cff_set_name(font, strval); - RELEASE(strval); - } else if (!strcmp(key, "FontType")) { - argn = parse_nvalue(start, end, argv, 1); - CHECK_ARGN_EQ(1); - if (argv[0] != 1.0) { - WARN("FontType %d not supported.", (int) argv[0]); - RELEASE(key); - return -1; - } -#if 0 - /* DISABLED: - * - * Subsetted font shouldn't have UniqueID. - */ - } else if (!strcmp(key, "UniqueID")) { - argn = parse_nvalue(start, end, argv, 1); - CHECK_ARGN_EQ(1); - cff_dict_add(font->topdict, key, 1); - cff_dict_set(font->topdict, key, 0, argv[0]); -#endif - } else if (!strcmp(key, "ItalicAngle") || - !strcmp(key, "StrokeWidth") || - !strcmp(key, "PaintType")) { - argn = parse_nvalue(start, end, argv, 1); - CHECK_ARGN_EQ(1); - if (argv[0] != 0.0) { -#if 0 - /* - * Positive value in Bitstream CharterBT-Italic ??? - */ - if (!strcmp(key, "ItalicAngle") && argv[0] > 0) { - WARN("Positive ItalicAngle value: %g", argv[0]); - argv[0] *= -1; - } -#endif - cff_dict_add(font->topdict, key, 1); - cff_dict_set(font->topdict, key, 0, argv[0]); - } - } else if (!strcmp(key, "UnderLinePosition") || - !strcmp(key, "UnderLineThickness")) { - argn = parse_nvalue(start, end, argv, 1); - CHECK_ARGN_EQ(1); - cff_dict_add(font->topdict, key, 1); - cff_dict_set(font->topdict, key, 0, argv[0]); - } else if (!strcmp(key, "FontBBox")) { - argn = parse_nvalue(start, end, argv, 4); - CHECK_ARGN_EQ(4); - cff_dict_add(font->topdict, key, 4); - while (argn-- > 0) { - cff_dict_set(font->topdict, key, argn, argv[argn]); - } - } else if (!strcmp(key, "FontMatrix")) { - argn = parse_nvalue(start, end, argv, 6); - CHECK_ARGN_EQ(6); - if (argv[0] != 0.001 || argv[1] != 0.0 || argv[2] != 0.0 || - argv[3] != 0.001 || argv[4] != 0.0 || argv[5] != 0.0) { - cff_dict_add(font->topdict, key, 6); - while (argn-- > 0) { - cff_dict_set(font->topdict, key, argn, argv[argn]); - } - } - } else if (!strcmp(key, "version") || !strcmp(key, "Notice") || - !strcmp(key, "FullName") || !strcmp(key, "FamilyName") || - !strcmp(key, "Weight") || !strcmp(key, "Copyright")) { - /* - * FontInfo - */ - argn = parse_svalue(start, end, &strval); - CHECK_ARGN_EQ(1); - { - s_SID sid; - - cff_dict_add(font->topdict, key, 1); - if ((sid = cff_get_sid(font, strval)) == CFF_STRING_NOTDEF) - sid = cff_add_string(font, strval, 0); /* FIXME */ - /* - * We don't care about duplicate strings here since - * later a subset font of this font will be generated. - */ - cff_dict_set(font->topdict, key, 0, sid); - } - RELEASE(strval); - } else if (!strcmp(key, "IsFixedPitch")) { - argn = parse_bvalue(start, end, &(argv[0])); - CHECK_ARGN_EQ(1); - if (argv[0] != 0.0) { - cff_dict_add(font->private[0], key, 1); - cff_dict_set(font->private[0], key, 0, 1); - } - } - RELEASE(key); - } - - return 0; -} - -int -is_pfb (FILE *fp) -{ - char sig[15]; - int i, ch; - - rewind(fp); - if ((ch = fgetc(fp)) != 128 || - (ch = fgetc (fp)) < 0 || ch > 3) { - return 0; - } - for (i = 0; i < 4; i++) { - if ((ch = fgetc(fp)) < 0) { - return 0; - } - } - for (i = 0; i < 14; i++) { - if ((ch = fgetc(fp)) < 0) { - return 0; - } - sig[i] = (char) ch; - } - if (!memcmp(sig, "%!PS-AdobeFont", 14) || - !memcmp(sig, "%!FontType1", 11)) { - return 1; - } else if (!memcmp(sig, "%!PS", 4)) { - sig[14] = '\0'; - WARN("Ambiguous PostScript resource type: %s", sig); - return 1; - } else { - WARN("Not a PFB font file?"); - return 0; - } - - return 0; -} - - -#define PFB_SEG_TYPE_ASCII 1 -#define PFB_SEG_TYPE_BINARY 2 - -static unsigned char * -get_pfb_segment (FILE *fp, int expected_type, long *length) -{ - unsigned char *buffer; - long bytesread; - - buffer = NULL; bytesread = 0; - for (;;) { - int ch; - - ch = fgetc(fp); - if (ch < 0) { - break; - } else if (ch != 128) { - ERROR("Not a pfb file?"); - } - ch = fgetc(fp); - if (ch < 0 || ch != expected_type) { - seek_relative(fp, -2); - break; - } - { - long slen, rlen; - int i; - - slen = 0; - for (i = 0; i < 4; i++) { - if ((ch = fgetc(fp)) < 0) { - if (buffer) - RELEASE(buffer); - return NULL; - } - slen = slen + (ch << (8*i)); - } - buffer = RENEW(buffer, bytesread + slen, unsigned char); - while (slen > 0) { - rlen = fread(buffer + bytesread, sizeof(unsigned char), slen, fp); - if (rlen < 0) { - if (buffer) - RELEASE(buffer); - return NULL; - } - slen -= rlen; - bytesread += rlen; - } - } - } - if (bytesread == 0) { - ERROR("PFB segment length zero?"); - } - - buffer = RENEW(buffer, bytesread+1, unsigned char); - buffer[bytesread] = 0; - - if (length) - *length = bytesread; - return buffer; -} - -const char * -t1_get_standard_glyph (int code) -{ - if (!StandardEncoding[code]) - return NULL; - - return StandardEncoding[code]; -} - -int -t1_get_fontname (FILE *fp, char *fontname) -{ - unsigned char *buffer, *start, *end; - long length; - char *key; - int fn_found = 0; - - rewind(fp); - buffer = get_pfb_segment(fp, PFB_SEG_TYPE_ASCII, &length); - if (buffer == NULL || length == 0) - ERROR("Reading PFB (ASCII part) file failed."); - start = buffer; - end = buffer + length; - - if (seek_operator(&start, end, "begin") < 0) { - RELEASE(buffer); - return -1; - } - - while (!fn_found && start < end && - (key = get_next_key(&start, end)) != NULL) { - if (!strcmp(key, "FontName")) { - char *strval; - if (parse_svalue(&start, end, &strval) == 1) { - if (strlen(strval) > TYPE1_NAME_LEN_MAX) { - WARN("FontName \"%s\" too long. (%d bytes)", strval, strlen(strval)); - strval[TYPE1_NAME_LEN_MAX] = '\0'; - } - strcpy(fontname, strval); - RELEASE(strval); - fn_found = 1; - } - } - RELEASE(key); - } - RELEASE(buffer); - - return 0; -} - -static void -init_cff_font (cff_font *cff) -{ - cff->stream = NULL; - cff->filter = 0; - cff->fontname = NULL; - cff->index = 0; - cff->flag = FONTTYPE_FONT; - - cff->header.major = 1; - cff->header.minor = 0; - cff->header.hdr_size = 4; - cff->header.offsize = 4; - cff->name = cff_new_index(1); - cff->topdict = cff_new_dict(); - cff->string = NULL; - cff->gsubr = cff_new_index(0); /* No Global Subr */ - cff->encoding = NULL; - cff->charsets = NULL; - cff->fdselect = NULL; - cff->cstrings = NULL; - cff->fdarray = NULL; - cff->private = NEW(1, cff_dict *); - cff->private[0] = cff_new_dict(); - cff->subrs = NEW(1, cff_index *); - cff->subrs[0] = NULL; - - cff->offset = 0; - cff->gsubr_offset = 0; - cff->num_glyphs = 0; - cff->num_fds = 1; - cff->_string = cff_new_index(0); -} - -cff_font * -t1_load_font (char **enc_vec, int mode, FILE *fp) -{ - long length; - cff_font *cff; - unsigned char *buffer, *start, *end; - - rewind(fp); - /* ASCII section */ - buffer = get_pfb_segment(fp, PFB_SEG_TYPE_ASCII, &length); - if (buffer == NULL || length == 0) { - ERROR("Reading PFB (ASCII part) file failed."); - return NULL; - } - - cff = NEW(1, cff_font); - init_cff_font(cff); - - start = buffer; end = buffer + length; - if (parse_part1(cff, enc_vec, &start, end, mode) < 0) { - cff_close(cff); - RELEASE(buffer); - ERROR("Reading PFB (ASCII part) file failed."); - return NULL; - } - RELEASE(buffer); - - /* Binary section */ - buffer = get_pfb_segment(fp, PFB_SEG_TYPE_BINARY, &length); - if (buffer == NULL || length == 0) { - cff_close(cff); - RELEASE(buffer); - ERROR("Reading PFB (BINARY part) file failed."); - return NULL; - } else { - t1_decrypt(T1_EEKEY, buffer, buffer, 0, length); - } - start = buffer + 4; end = buffer + length; - if (parse_part2(cff, &start, end, mode) < 0) { - cff_close(cff); - RELEASE(buffer); - ERROR("Reading PFB (BINARY part) file failed."); - return NULL; - } - RELEASE(buffer); - - cff_update_string(cff); - - /* Remaining section ignored. */ - - return cff; -} |