Back to index

texmacs  1.0.7.15
Defines | Functions | Variables
t1_load.c File Reference
#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"

Go to the source code of this file.

Defines

#define T1_EEKEY   55665u
#define T1_CHARKEY   4330u
#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)
#define CFF_GLYPH_MAX   CFF_SID_MAX
#define CHECK_ARGN_EQ(n)
#define CHECK_ARGN_GE(n)
#define MAX_ARGS   127
#define TYPE1_NAME_LEN_MAX   127
#define PFB_SEG_TYPE_ASCII   1
#define PFB_SEG_TYPE_BINARY   2

Functions

static void t1_decrypt (unsigned short key, unsigned char *dst, const unsigned char *src, long skip, long len)
static char * get_next_key (unsigned char **start, unsigned char *end)
static int seek_operator (unsigned char **start, unsigned char *end, const char *op)
static int parse_svalue (unsigned char **start, unsigned char *end, char **value)
static int parse_bvalue (unsigned char **start, unsigned char *end, double *value)
static int parse_nvalue (unsigned char **start, unsigned char *end, double *value, int max)
static int parse_encoding (char **enc_vec, unsigned char **start, unsigned char *end, int mode)
static int parse_subrs (cff_font *font, unsigned char **start, unsigned char *end, int lenIV, int mode)
static int parse_charstrings (cff_font *font, unsigned char **start, unsigned char *end, int lenIV, int mode)
static int parse_part2 (cff_font *font, unsigned char **start, unsigned char *end, int mode)
static long parse_part1 (cff_font *font, char **enc_vec, unsigned char **start, unsigned char *end, int mode)
int is_pfb (FILE *fp)
static unsigned char * get_pfb_segment (FILE *fp, int expected_type, long *length)
char * t1_get_standard_glyph (int code)
int t1_get_fontname (FILE *fp, char *fontname)
static void init_cff_font (cff_font *cff)
cff_fontt1_load_font (char **enc_vec, int mode, FILE *fp)

Variables

static const char *const StandardEncoding [256]
static const char *const ISOLatin1Encoding [256]

Define Documentation

#define CFF_GLYPH_MAX   CFF_SID_MAX

Definition at line 438 of file t1_load.c.

#define CHECK_ARGN_EQ (   n)
Value:
if (argn != (n)) {\
  WARN("%d values expected but only %d read.", (n), argn);\
  RELEASE(key);\
  return -1;\
}

Definition at line 761 of file t1_load.c.

#define CHECK_ARGN_GE (   n)
Value:
if (argn < (n)) {\
  WARN("%d values expected but only %d read.", (n), argn);\
  RELEASE(key);\
  return -1;\
}

Definition at line 766 of file t1_load.c.

#define MATCH_NAME (   t,
  n 
)    ((t) && PST_NAMETYPE((t)) && !strncmp(pst_data_ptr((t)),(n),strlen((n))))

Definition at line 94 of file t1_load.c.

#define MATCH_OP (   t,
  n 
)    ((t) && PST_UNKNOWNTYPE((t)) && !strncmp(pst_data_ptr((t)),(n),strlen((n))))

Definition at line 95 of file t1_load.c.

#define MAX_ARGS   127

Definition at line 772 of file t1_load.c.

#define PFB_SEG_TYPE_ASCII   1

Definition at line 1014 of file t1_load.c.

#define PFB_SEG_TYPE_BINARY   2

Definition at line 1015 of file t1_load.c.

#define RELEASE_TOK (   t)
Value:
if ((t) != NULL) {\
  pst_release_obj((t));\
  (t) = NULL;\
}

Definition at line 97 of file t1_load.c.

#define T1_CHARKEY   4330u

Definition at line 58 of file t1_load.c.

#define T1_EEKEY   55665u

Definition at line 57 of file t1_load.c.

#define TYPE1_NAME_LEN_MAX   127

Definition at line 846 of file t1_load.c.


Function Documentation

static char* get_next_key ( unsigned char **  start,
unsigned char *  end 
) [static]

Definition at line 103 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned char* get_pfb_segment ( FILE *  fp,
int  expected_type,
long *  length 
) [static]

Definition at line 1018 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_cff_font ( cff_font cff) [static]

Definition at line 1127 of file t1_load.c.

{
  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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int is_pfb ( FILE *  fp)

Definition at line 977 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_bvalue ( unsigned char **  start,
unsigned char *  end,
double *  value 
) [static]

Definition at line 162 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_charstrings ( cff_font font,
unsigned char **  start,
unsigned char *  end,
int  lenIV,
int  mode 
) [static]

Definition at line 596 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_encoding ( char **  enc_vec,
unsigned char **  start,
unsigned char *  end,
int  mode 
) [static]

Definition at line 328 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_nvalue ( unsigned char **  start,
unsigned char *  end,
double *  value,
int  max 
) [static]

Definition at line 181 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long parse_part1 ( cff_font font,
char **  enc_vec,
unsigned char **  start,
unsigned char *  end,
int  mode 
) [static]

Definition at line 850 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_part2 ( cff_font font,
unsigned char **  start,
unsigned char *  end,
int  mode 
) [static]

Definition at line 774 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_subrs ( cff_font font,
unsigned char **  start,
unsigned char *  end,
int  lenIV,
int  mode 
) [static]

Definition at line 442 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int parse_svalue ( unsigned char **  start,
unsigned char *  end,
char **  value 
) [static]

Definition at line 143 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int seek_operator ( unsigned char **  start,
unsigned char *  end,
const char *  op 
) [static]

Definition at line 122 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void t1_decrypt ( unsigned short  key,
unsigned char *  dst,
const unsigned char *  src,
long  skip,
long  len 
) [static]

Definition at line 79 of file t1_load.c.

{
  len -= skip;
  while (skip--)
    key = (key + *src++) * 52845u + 22719u;
  while (len--) {
    unsigned char c = *src++;
    *dst++ = (c ^ (key >> 8));
    key = (key + c) * 52845u + 22719u;
  }
}

Here is the caller graph for this function:

int t1_get_fontname ( FILE *  fp,
char *  fontname 
)

Definition at line 1086 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* t1_get_standard_glyph ( int  code)

Definition at line 1077 of file t1_load.c.

{
  if (!StandardEncoding[code])
    return NULL;

  return (char *) StandardEncoding[code];
}

Here is the caller graph for this function:

cff_font* t1_load_font ( char **  enc_vec,
int  mode,
FILE *  fp 
)

Definition at line 1161 of file t1_load.c.

{
  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;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const char* const ISOLatin1Encoding[256] [static]

Definition at line 270 of file t1_load.c.

const char* const StandardEncoding[256] [static]

Definition at line 215 of file t1_load.c.