summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfmx/dvipdfmx-20110305/src/t1_load.c
diff options
context:
space:
mode:
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.c1211
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;
-}