Back to index

texmacs  1.0.7.15
Classes | Defines | Typedefs | Functions | Variables
t1_char.c File Reference
#include <string.h>
#include <math.h>
#include "system.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_char.h"

Go to the source code of this file.

Classes

struct  t1_cpath
struct  t1_stem
struct  t1_stemgroup
struct  t1_chardesc
struct  t1_chardesc.sbw
struct  t1_chardesc.bbox
struct  t1_chardesc.seac

Defines

#define CS_OP_NOSUPPORT   -4
#define CS_BUFFER_ERROR   -3
#define CS_STACK_ERROR   -2
#define CS_PARSE_ERROR   -1
#define CS_PARSE_OK   0
#define CS_PARSE_END   1
#define CS_SUBR_RETURN   2
#define CS_CHAR_END   3
#define DST_NEED(a, b)   {if ((a) < (b)) { status = CS_BUFFER_ERROR ; return ; }}
#define SRC_NEED(a, b)   {if ((a) < (b)) { status = CS_PARSE_ERROR ; return ; }}
#define NEED(a, b)   {if ((a) < (b)) { status = CS_STACK_ERROR ; return ; }}
#define T1_CS_PHASE_INIT   0
#define T1_CS_PHASE_HINT   1
#define T1_CS_PHASE_PATH   2
#define T1_CS_PHASE_FLEX   3
#define CS_STEM_GROUP_MAX   CS_STEM_ZONE_MAX
#define PS_ARG_STACK_MAX   (CS_STEM_ZONE_MAX*2+2)
#define HSTEM   0
#define VSTEM   1
#define T1_CS_FLAG_NONE   0
#define T1_CS_FLAG_USE_HINTMASK   (1 << 0)
#define T1_CS_FLAG_USE_CNTRMASK   (1 << 1)
#define T1_CS_FLAG_USE_SEAC   (1 << 2)
#define CS_HINT_DECL   -1
#define CS_FLEX_CTRL   -2
#define CS_CNTR_CTRL   -3
#define cs_hstem   1
#define cs_vstem   3
#define cs_vmoveto   4
#define cs_rlineto   5
#define cs_hlineto   6
#define cs_vlineto   7
#define cs_rrcurveto   8
#define cs_closepath   9
#define cs_callsubr   10
#define cs_return   11
#define cs_escape   12
#define cs_hsbw   13
#define cs_endchar   14
#define cs_hstemhm   18
#define cs_hintmask   19
#define cs_cntrmask   20
#define cs_rmoveto   21
#define cs_hmoveto   22
#define cs_vstemhm   23
#define cs_rcurveline   24
#define cs_rlinecurve   25
#define cs_vvcurveto   26
#define cs_hhcurveto   27
#define cs_callgsubr   29
#define cs_vhcurveto   30
#define cs_hvcurveto   31
#define cs_dotsection   0
#define cs_vstem3   1
#define cs_hstem3   2
#define cs_and   3
#define cs_or   4
#define cs_not   5
#define cs_seac   6
#define cs_sbw   7
#define cs_abs   9
#define cs_add   10
#define cs_sub   11
#define cs_div   12
#define cs_neg   14
#define cs_eq   15
#define cs_callothersubr   16
#define cs_pop   17
#define cs_drop   18
#define cs_put   20
#define cs_get   21
#define cs_ifelse   22
#define cs_random   23
#define cs_mul   24
#define cs_sqrt   26
#define cs_dup   27
#define cs_exch   28
#define cs_index   29
#define cs_roll   30
#define cs_setcurrentpoint   33
#define cs_hflex   34
#define cs_flex   35
#define cs_hflex1   36
#define cs_flex1   37
#define IS_PATH_OPERATOR(o)
#define SORT_STEMS(cd)   qsort((cd)->stems,(cd)->num_stems,sizeof(t1_stem),stem_compare)
#define LIMITCHECK(n)
#define CHECKSTACK(n)
#define CLEARSTACK()
#define ADD_PATH(p, t, n)   add_charpath((p),(t),&(cs_arg_stack[cs_stack_top-(n)]),(n))
#define UPDATE_BBOX(b, x, y)
#define TRY_COMPACT   (prev && cur && ((prev->num_args + cur->num_args) <= CS_ARG_STACK_MAX))
#define RESET_STATE()
#define CHECK_BUFFER(n)
#define CHECK_STATUS()

Typedefs

typedef struct t1_cpath t1_cpath

Functions

static int CDECL stem_compare (const void *v1, const void *v2)
static int get_stem (t1_chardesc *cd, int stem_id)
static int add_stem (t1_chardesc *cd, double pos, double del, int dir)
static void copy_args (double *args1, double *args2, int count)
static void add_charpath (t1_chardesc *cd, int type, double *argv, int argn)
static void init_charpath (t1_chardesc *cd)
static void release_charpath (t1_chardesc *cd)
static void do_operator1 (t1_chardesc *cd, card8 **data, card8 *endptr)
static void do_othersubr0 (t1_chardesc *cd)
static void do_othersubr1 (t1_chardesc *cd)
static void do_othersubr2 (t1_chardesc *cd)
static void do_othersubr3 (t1_chardesc *cd)
static void do_othersubr12 (t1_chardesc *cd)
static void do_othersubr13 (t1_chardesc *cd)
static void do_callothersubr (t1_chardesc *cd)
static void do_operator2 (t1_chardesc *cd, card8 **data, card8 *endptr)
static void put_numbers (double *argv, int argn, card8 **dest, card8 *limit)
static void get_integer (card8 **data, card8 *endptr)
static void get_longint (card8 **data, card8 *endptr)
static void t1char_build_charpath (t1_chardesc *cd, card8 **data, card8 *endptr, cff_index *subrs)
static void do_postproc (t1_chardesc *cd)
int t1char_get_metrics (card8 *src, long srclen, cff_index *subrs, t1_ginfo *ginfo)
static long t1char_encode_charpath (t1_chardesc *cd, double default_width, double nominal_width, card8 *dst, card8 *endptr)
long t1char_convert_charstring (card8 *dst, long dstlen, card8 *src, long srclen, cff_index *subrs, double default_width, double nominal_width, t1_ginfo *ginfo)

Variables

static int status = CS_PARSE_ERROR
static int phase = -1
static int nest = -1
static int cs_stack_top = 0
static int ps_stack_top = 0
static double cs_arg_stack [CS_ARG_STACK_MAX+1]
static double ps_arg_stack [PS_ARG_STACK_MAX]

Class Documentation

struct t1_cpath

Definition at line 99 of file t1_char.c.

Collaboration diagram for t1_cpath:
Class Members
double args
struct t1_cpath * next
int num_args
int type
struct t1_stem

Definition at line 108 of file t1_char.c.

Class Members
double del
int dir
int id
double pos
struct t1_stemgroup

Definition at line 114 of file t1_char.c.

Class Members
int num_stems
double stems
struct t1_chardesc

Definition at line 124 of file t1_char.c.

Collaboration diagram for t1_chardesc:
Class Members
struct t1_chardesc bbox
t1_cpath * charpath
int flags
t1_cpath * lastpath
int num_stems
struct t1_chardesc sbw
struct t1_chardesc seac
t1_stem stems
struct t1_chardesc.sbw

Definition at line 126 of file t1_char.c.

Class Members
double sbx
double sby
double wx
double wy
struct t1_chardesc.bbox

Definition at line 129 of file t1_char.c.

Class Members
double llx
double lly
double urx
double ury
struct t1_chardesc.seac

Definition at line 132 of file t1_char.c.

Class Members
card8 achar
double adx
double ady
double asb
card8 bchar

Define Documentation

#define ADD_PATH (   p,
  t,
  n 
)    add_charpath((p),(t),&(cs_arg_stack[cs_stack_top-(n)]),(n))

Definition at line 421 of file t1_char.c.

#define CHECK_BUFFER (   n)
Value:
if (dst+(n) >= endptr) {\
  ERROR("Buffer overflow.");\
}

Definition at line 1360 of file t1_char.c.

#define CHECK_STATUS ( )
Value:
if (status != CS_PARSE_OK) {\
  ERROR("Charstring encoder error: %d", status);\
}

Definition at line 1363 of file t1_char.c.

#define CHECKSTACK (   n)
Value:
do {\
                           if (cs_stack_top < (n)) {\
                             status = CS_STACK_ERROR;\
                             return;\
                           }\
                      } while (0)

Definition at line 349 of file t1_char.c.

#define CLEARSTACK ( )
Value:
do {\
                           cs_stack_top = 0;\
                      } while (0)

Definition at line 355 of file t1_char.c.

#define cs_abs   9

Definition at line 211 of file t1_char.c.

#define cs_add   10

Definition at line 212 of file t1_char.c.

#define cs_and   3

Definition at line 205 of file t1_char.c.

#define CS_BUFFER_ERROR   -3

Definition at line 61 of file t1_char.c.

#define cs_callgsubr   29

Definition at line 191 of file t1_char.c.

#define cs_callothersubr   16

Definition at line 218 of file t1_char.c.

#define cs_callsubr   10

Definition at line 172 of file t1_char.c.

#define CS_CHAR_END   3

Definition at line 67 of file t1_char.c.

#define cs_closepath   9

Definition at line 171 of file t1_char.c.

#define CS_CNTR_CTRL   -3

Definition at line 151 of file t1_char.c.

#define cs_cntrmask   20

Definition at line 182 of file t1_char.c.

#define cs_div   12

Definition at line 214 of file t1_char.c.

#define cs_dotsection   0

Definition at line 202 of file t1_char.c.

#define cs_drop   18

Definition at line 220 of file t1_char.c.

#define cs_dup   27

Definition at line 229 of file t1_char.c.

#define cs_endchar   14

Definition at line 176 of file t1_char.c.

#define cs_eq   15

Definition at line 217 of file t1_char.c.

#define cs_escape   12

Definition at line 174 of file t1_char.c.

#define cs_exch   28

Definition at line 230 of file t1_char.c.

#define cs_flex   35

Definition at line 237 of file t1_char.c.

#define cs_flex1   37

Definition at line 239 of file t1_char.c.

#define CS_FLEX_CTRL   -2

Definition at line 150 of file t1_char.c.

#define cs_get   21

Definition at line 223 of file t1_char.c.

#define cs_hflex   34

Definition at line 236 of file t1_char.c.

#define cs_hflex1   36

Definition at line 238 of file t1_char.c.

#define cs_hhcurveto   27

Definition at line 189 of file t1_char.c.

#define CS_HINT_DECL   -1

Definition at line 149 of file t1_char.c.

#define cs_hintmask   19

Definition at line 181 of file t1_char.c.

#define cs_hlineto   6

Definition at line 168 of file t1_char.c.

#define cs_hmoveto   22

Definition at line 184 of file t1_char.c.

#define cs_hsbw   13

Definition at line 175 of file t1_char.c.

#define cs_hstem   1

Definition at line 163 of file t1_char.c.

#define cs_hstem3   2

Definition at line 204 of file t1_char.c.

#define cs_hstemhm   18

Definition at line 180 of file t1_char.c.

#define cs_hvcurveto   31

Definition at line 193 of file t1_char.c.

#define cs_ifelse   22

Definition at line 224 of file t1_char.c.

#define cs_index   29

Definition at line 231 of file t1_char.c.

#define cs_mul   24

Definition at line 226 of file t1_char.c.

#define cs_neg   14

Definition at line 216 of file t1_char.c.

#define cs_not   5

Definition at line 207 of file t1_char.c.

#define CS_OP_NOSUPPORT   -4

Definition at line 60 of file t1_char.c.

#define cs_or   4

Definition at line 206 of file t1_char.c.

#define CS_PARSE_END   1

Definition at line 65 of file t1_char.c.

#define CS_PARSE_ERROR   -1

Definition at line 63 of file t1_char.c.

#define CS_PARSE_OK   0

Definition at line 64 of file t1_char.c.

#define cs_pop   17

Definition at line 219 of file t1_char.c.

#define cs_put   20

Definition at line 222 of file t1_char.c.

#define cs_random   23

Definition at line 225 of file t1_char.c.

#define cs_rcurveline   24

Definition at line 186 of file t1_char.c.

#define cs_return   11

Definition at line 173 of file t1_char.c.

#define cs_rlinecurve   25

Definition at line 187 of file t1_char.c.

#define cs_rlineto   5

Definition at line 167 of file t1_char.c.

#define cs_rmoveto   21

Definition at line 183 of file t1_char.c.

#define cs_roll   30

Definition at line 232 of file t1_char.c.

#define cs_rrcurveto   8

Definition at line 170 of file t1_char.c.

#define cs_sbw   7

Definition at line 209 of file t1_char.c.

#define cs_seac   6

Definition at line 208 of file t1_char.c.

#define cs_setcurrentpoint   33

Definition at line 235 of file t1_char.c.

#define cs_sqrt   26

Definition at line 228 of file t1_char.c.

#define CS_STACK_ERROR   -2

Definition at line 62 of file t1_char.c.

Definition at line 87 of file t1_char.c.

#define cs_sub   11

Definition at line 213 of file t1_char.c.

#define CS_SUBR_RETURN   2

Definition at line 66 of file t1_char.c.

#define cs_vhcurveto   30

Definition at line 192 of file t1_char.c.

#define cs_vlineto   7

Definition at line 169 of file t1_char.c.

#define cs_vmoveto   4

Definition at line 166 of file t1_char.c.

#define cs_vstem   3

Definition at line 165 of file t1_char.c.

#define cs_vstem3   1

Definition at line 203 of file t1_char.c.

#define cs_vstemhm   23

Definition at line 185 of file t1_char.c.

#define cs_vvcurveto   26

Definition at line 188 of file t1_char.c.

#define DST_NEED (   a,
 
)    {if ((a) < (b)) { status = CS_BUFFER_ERROR ; return ; }}

Definition at line 71 of file t1_char.c.

#define HSTEM   0

Definition at line 106 of file t1_char.c.

#define IS_PATH_OPERATOR (   o)
Value:
(((o) >= cs_vmoveto && (o) <= cs_closepath) || \
                             ((o) >= cs_rmoveto && (o) <= cs_hvcurveto && \
                              (o) != cs_vstemhm && (o) != cs_callgsubr && (o) != 28)\
                            )

Definition at line 241 of file t1_char.c.

#define LIMITCHECK (   n)
Value:
do {\
                           if (cs_stack_top+(n) > CS_ARG_STACK_MAX) {\
                             status = CS_STACK_ERROR;\
                             return;\
                           }\
                      } while (0)

Definition at line 343 of file t1_char.c.

#define NEED (   a,
 
)    {if ((a) < (b)) { status = CS_STACK_ERROR ; return ; }}

Definition at line 73 of file t1_char.c.

#define PS_ARG_STACK_MAX   (CS_STEM_ZONE_MAX*2+2)

Definition at line 96 of file t1_char.c.

#define RESET_STATE ( )
Value:
do {\
  status = CS_PARSE_OK;\
  phase  = T1_CS_PHASE_INIT;\
  nest   = 0;\
  ps_stack_top = 0;\
} while (0)

Definition at line 1318 of file t1_char.c.

#define SORT_STEMS (   cd)    qsort((cd)->stems,(cd)->num_stems,sizeof(t1_stem),stem_compare)

Definition at line 288 of file t1_char.c.

#define SRC_NEED (   a,
 
)    {if ((a) < (b)) { status = CS_PARSE_ERROR ; return ; }}

Definition at line 72 of file t1_char.c.

#define T1_CS_FLAG_NONE   0

Definition at line 119 of file t1_char.c.

#define T1_CS_FLAG_USE_CNTRMASK   (1 << 1)

Definition at line 121 of file t1_char.c.

#define T1_CS_FLAG_USE_HINTMASK   (1 << 0)

Definition at line 120 of file t1_char.c.

#define T1_CS_FLAG_USE_SEAC   (1 << 2)

Definition at line 122 of file t1_char.c.

#define T1_CS_PHASE_FLEX   3

Definition at line 78 of file t1_char.c.

#define T1_CS_PHASE_HINT   1

Definition at line 76 of file t1_char.c.

#define T1_CS_PHASE_INIT   0

Definition at line 75 of file t1_char.c.

#define T1_CS_PHASE_PATH   2

Definition at line 77 of file t1_char.c.

#define TRY_COMPACT   (prev && cur && ((prev->num_args + cur->num_args) <= CS_ARG_STACK_MAX))
#define UPDATE_BBOX (   b,
  x,
  y 
)
Value:
do {\
  if ((b).llx > (x)) (b).llx = (x);\
  if ((b).urx < (x)) (b).urx = (x);\
  if ((b).lly > (y)) (b).lly = (y);\
  if ((b).ury < (y)) (b).ury = (y);\
} while (0)
#define VSTEM   1

Definition at line 107 of file t1_char.c.


Typedef Documentation

typedef struct t1_cpath t1_cpath

Function Documentation

static void add_charpath ( t1_chardesc cd,
int  type,
double *  argv,
int  argn 
) [static]

Definition at line 364 of file t1_char.c.

{
  t1_cpath *p;

  ASSERT(cd);
  ASSERT(argn <= CS_ARG_STACK_MAX);

  p = NEW(1, t1_cpath);
  p->type     = type;
  p->num_args = argn;
  p->next     = NULL;

  while (argn-- > 0)
    p->args[argn] = argv[argn];

  if (!cd->charpath)
    cd->charpath = p;
  if (cd->lastpath)
    cd->lastpath->next = p;
  cd->lastpath = p;

  if (type >= 0 &&
      phase != T1_CS_PHASE_FLEX && IS_PATH_OPERATOR(type))
    phase = T1_CS_PHASE_PATH;
}

Here is the caller graph for this function:

static int add_stem ( t1_chardesc cd,
double  pos,
double  del,
int  dir 
) [static]

Definition at line 304 of file t1_char.c.

{
  int i;

  ASSERT(cd);

  pos += (dir == HSTEM) ? cd->sbw.sby : cd->sbw.sbx;
  for (i = 0; i < cd->num_stems; i++) {
    if (cd->stems[i].dir == dir &&
       cd->stems[i].pos == pos &&
       cd->stems[i].del == del)
      break;
  }
  if (i == cd->num_stems) {
    if (cd->num_stems == CS_STEM_ZONE_MAX)
      return -1;
    cd->stems[i].dir = dir;
    cd->stems[i].pos = pos;
    cd->stems[i].del = del;
    cd->stems[i].id  = cd->num_stems;
    (cd->num_stems)++;
  }

  return cd->stems[i].id;
}

Here is the caller graph for this function:

static void copy_args ( double *  args1,
double *  args2,
int  count 
) [static]

Definition at line 332 of file t1_char.c.

{
  while (count-- > 0) {
    *args1 = *args2;
    args1++; args2++;
  }
}

Here is the caller graph for this function:

static void do_callothersubr ( t1_chardesc cd) [static]

Definition at line 773 of file t1_char.c.

{
  int argn, subrno;

  CHECKSTACK(2);
  subrno = (int) cs_arg_stack[--cs_stack_top];
  argn   = (int) cs_arg_stack[--cs_stack_top];

  CHECKSTACK(argn);
  if (ps_stack_top+argn > PS_ARG_STACK_MAX) {
    status = CS_PARSE_ERROR;
    return;
  }
  while (argn-- > 0)
    ps_arg_stack[ps_stack_top++] = cs_arg_stack[--cs_stack_top];

  switch (subrno) {
  case 0:  do_othersubr0(cd) ; break;
  case 1:  do_othersubr1(cd) ; break;
  case 2:  do_othersubr2(cd) ; break;
  case 3:  do_othersubr3(cd) ; break;
  case 12: do_othersubr12(cd); break;
  case 13: do_othersubr13(cd); break;
  default:
    ERROR("Unknown othersubr #%ld.", subrno);
    break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_operator1 ( t1_chardesc cd,
card8 **  data,
card8 endptr 
) [static]

Definition at line 427 of file t1_char.c.

{
  card8 op = **data;

  *data += 1;

  switch (op) {
  case cs_closepath:
    /*
     * From T1 spec.:
     *  Note that, unlike the closepath command in the PostScript language,
     *  this command does not reposition the current point. Any subsequent
     *  rmoveto must be relative to the current point in force before the
     *  Type 1 font format closepath command was given.
     */
    /* noop */
    CLEARSTACK();
    break;
  case cs_hsbw:
    CHECKSTACK(2);
    cd->sbw.wx  = cs_arg_stack[--cs_stack_top];
    cd->sbw.wy  = 0;
    cd->sbw.sbx = cs_arg_stack[--cs_stack_top];
    cd->sbw.sby = 0;
    CLEARSTACK();
    /* hsbw does NOT set currentpoint. */
    break;
  case cs_hstem:
  case cs_vstem:
    CHECKSTACK(2);
    {
      int stem_id;
      stem_id = add_stem(cd,
                      cs_arg_stack[cs_stack_top-2],
                      cs_arg_stack[cs_stack_top-1],
                      ((op == cs_hstem) ? HSTEM : VSTEM));
      if (stem_id < 0) {
       WARN("Too many hints...");
       status = CS_PARSE_ERROR;
       return;
      }
      /* Put stem_id onto the stack... */
      cs_arg_stack[cs_stack_top++] = stem_id;
      ADD_PATH(cd, CS_HINT_DECL, 1);
    }
    CLEARSTACK();
    break;
  case cs_rmoveto:
    /*
     * Reference point is (0, 0) in Type 2 charstring.
     */
    CHECKSTACK(2);
    {
      if (phase < T1_CS_PHASE_PATH) {
       cs_arg_stack[cs_stack_top-2] += cd->sbw.sbx;
       cs_arg_stack[cs_stack_top-1] += cd->sbw.sby;
      }
      ADD_PATH(cd, op, 2);
    }
    CLEARSTACK();
    break;
  case cs_hmoveto:
  case cs_vmoveto:
    CHECKSTACK(1);
    {
      int argn = 1;
      if (phase < T1_CS_PHASE_PATH) {
       /*
        * The reference point for the first moveto operator is diferrent
        * between Type 1 charstring and Type 2 charstring. We compensate it.
        */
       if (op == cs_hmoveto) {
         cs_arg_stack[cs_stack_top-1] += cd->sbw.sbx;
         if (cd->sbw.sby != 0.0) {
           cs_arg_stack[cs_stack_top++] = cd->sbw.sby;
           argn = 2;
           op = cs_rmoveto;
         }
       } else {
         cs_arg_stack[cs_stack_top-1] += cd->sbw.sby;
         if (cd->sbw.sbx != 0.0) {
           cs_arg_stack[cs_stack_top]   = cs_arg_stack[cs_stack_top-1];
           cs_arg_stack[cs_stack_top-1] = cd->sbw.sbx;
           cs_stack_top++;
           argn = 2;
           op = cs_rmoveto;
         }
       }
      }
      ADD_PATH(cd, op, argn);
    }
    CLEARSTACK();
    break;
  case cs_endchar:
    status = CS_CHAR_END;
    CLEARSTACK();
    break;
  /* above oprators are candidate for first stack-clearing operator */
  case cs_rlineto:
    CHECKSTACK(2);
    ADD_PATH(cd, op, 2);
    CLEARSTACK();
    break;
  case cs_hlineto:
  case cs_vlineto:
    CHECKSTACK(1);
    ADD_PATH(cd, op, 1);
    CLEARSTACK();
    break;
  case cs_rrcurveto:
    CHECKSTACK(6);
    ADD_PATH(cd, op, 6);
    CLEARSTACK();
    break;
  case cs_vhcurveto:
  case cs_hvcurveto:
    CHECKSTACK(4);
    ADD_PATH(cd, op, 4);
    CLEARSTACK();
    break;
    /* all operotors above are stack-clearing operator */
    /* no output */
  case cs_return:
    break;
  case cs_callsubr:
    ERROR("Unexpected callsubr.");
    break;
  default:
    /* no-op ? */
    WARN("Unknown charstring operator: 0x%02x", op);
    status = CS_PARSE_ERROR;
    break;
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_operator2 ( t1_chardesc cd,
card8 **  data,
card8 endptr 
) [static]

Definition at line 806 of file t1_char.c.

{
  card8 op;

  *data += 1;

  SRC_NEED(endptr, *data + 1);

  op = **data;
  *data += 1;

  switch(op) {
  case cs_sbw:
    CHECKSTACK(4);
    cd->sbw.wy  = cs_arg_stack[--cs_stack_top];
    cd->sbw.wx  = cs_arg_stack[--cs_stack_top];
    cd->sbw.sby = cs_arg_stack[--cs_stack_top];
    cd->sbw.sbx = cs_arg_stack[--cs_stack_top];
    CLEARSTACK();
    break;
  case cs_hstem3:
  case cs_vstem3:
    /*
     * TODO:
     *  The counter control can be used for hstem3 and vstem3
     *  operator if LanguageGroup is not equal to 1.
     */
    CHECKSTACK(6);
    {
      int i;
      for (i = 2; i >= 0; i--) {
       int stem_id;
       stem_id = add_stem(cd,
                        cs_arg_stack[cs_stack_top-2*i-2],
                        cs_arg_stack[cs_stack_top-2*i-1],
                        ((op == cs_hstem3) ? HSTEM : VSTEM));
       if (stem_id < 0) {
         WARN("Too many hints...");
         status = CS_PARSE_ERROR;
         return;
       }
       /* Put stem_id onto the stack... */
       cs_arg_stack[cs_stack_top++] = stem_id;
       ADD_PATH(cd, CS_HINT_DECL, 1);
       cs_stack_top--;
      }
    }
    CLEARSTACK();
    break;
  case cs_setcurrentpoint:
    CHECKSTACK(2);
    /* noop */
    CLEARSTACK();
    break;
    /* all operator above are stack-clearing */
  case cs_pop:
    /*
     * Transfer a operand from PS interpreter operand stack to BuildChar
     * operand stack.
     */
    if (ps_stack_top < 1) {
      status = CS_PARSE_ERROR;
      return;
    }
    LIMITCHECK(1);
    cs_arg_stack[cs_stack_top++] = ps_arg_stack[--ps_stack_top];
    break;
  case cs_dotsection:
#if 0
    /*
     * If the hint replacement feature is used in the font, the
     * "dotsection" operator exist only for compatibility to older
     * (more than 10 years old) Type 1 font rasterizer which can't
     * perform hint replacement. In this case, we silently ignore
     * the "dotsection" operator.
     *
     * The following code will wrongly warn about "dotsection" when
     * the charstring only contains dot (e.g., "bullet") where the
     * hint replacement is not necessary.
     *
     * Adobe ATM renderers always treat this operator as a no-op.
     * (See, Adobe Technical Note #5177, Appendix C)
     */
    if (!(cd->flags & T1_CS_FLAG_USE_HINTMASK)) {
      if (__verbose > 1)
       WARN("Obsolete Type 1 charstring operator \"dotsection\" not supported.");
    }
#endif
    /* noop */
    break;
  case cs_div: /* TODO: check overflow */
    CHECKSTACK(2);
    cs_arg_stack[cs_stack_top-2] /= cs_arg_stack[cs_stack_top-1];
    cs_stack_top--;
    break;
  case cs_callothersubr:
    do_callothersubr(cd);
    break;
  case cs_seac:
    CHECKSTACK(5);
    cd->flags |= T1_CS_FLAG_USE_SEAC;
    cd->seac.achar = (card8) cs_arg_stack[--cs_stack_top];
    cd->seac.bchar = (card8) cs_arg_stack[--cs_stack_top];
    cd->seac.ady   = cs_arg_stack[--cs_stack_top];
    cd->seac.adx   = cs_arg_stack[--cs_stack_top];
    /* We must compensate the difference of the glyph origin. */
    cd->seac.ady += cd->sbw.sby;
    cd->seac.adx += cd->sbw.sbx - cs_arg_stack[--cs_stack_top];
    CLEARSTACK();
    break;
  default:
    /* no-op ? */
    WARN("Unknown charstring operator: 0x0c%02x", op);
    status = CS_PARSE_ERROR;
    break;
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_othersubr0 ( t1_chardesc cd) [static]

Definition at line 589 of file t1_char.c.

{
  t1_cpath *flex, *cur, *next;

  if (ps_stack_top < 1) {
    status = CS_PARSE_ERROR;
    return;
  }

  /* Seek first CS_FLEX_CTRL mark */
  for (cur = cd->charpath; cur != NULL && cur->type != CS_FLEX_CTRL; cur = cur->next);
  flex = cur;
  {
    int i;
    cur = cur->next;
    for (i = 1; i < 7; i++) {
      if (cur == NULL || cur->type != CS_FLEX_CTRL ||
         cur->num_args != 2) {
       status = CS_PARSE_ERROR;
       return;
      }
      if (i == 1) {
       flex->args[0] += cur->args[0];
       flex->args[1] += cur->args[1];
      } else {
       copy_args(&(flex->args[2*i-2]), cur->args, 2);
      }
      next = cur->next;
      RELEASE(cur);
      cur = next;
    }
  }
  if (cur != NULL) {
    status = CS_PARSE_ERROR;
    return;
  }
  /*
   * Now 'flex' have all six control points, the first pair is relative
   * from starting point.
   */
  flex->type = cs_flex;
  flex->args[12] = ps_arg_stack[--ps_stack_top]; /* flex depth */
  flex->num_args = 13;
  flex->next   = NULL;
  cd->lastpath = flex;

  phase = T1_CS_PHASE_PATH;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_othersubr1 ( t1_chardesc cd) [static]

Definition at line 640 of file t1_char.c.

Here is the caller graph for this function:

static void do_othersubr12 ( t1_chardesc cd) [static]

Definition at line 684 of file t1_char.c.

{
  /* Othersubr12 call must immediately follow the hsbw or sbw. */
  if (phase != T1_CS_PHASE_INIT) {
    status = CS_PARSE_ERROR;
    return;
  }
  /* noop */
}

Here is the caller graph for this function:

static void do_othersubr13 ( t1_chardesc cd) [static]

Definition at line 695 of file t1_char.c.

{
  t1_stemgroup stemgroups[CS_STEM_GROUP_MAX];
  int num_hgroups, num_vgroups, n, stem_id;
  double pos, del;

  /* After #12 callothersubr or hsbw or sbw. */
  if (phase != T1_CS_PHASE_INIT) {
    status = CS_PARSE_ERROR;
    return;
  }
  for (n = 0; n < CS_STEM_GROUP_MAX; n++) {
    stemgroups[n].num_stems = 0;
  }

  num_hgroups = (int) ps_arg_stack[--ps_stack_top];
  if (num_hgroups < 0 || num_hgroups > CS_STEM_GROUP_MAX) {
    status = CS_PARSE_ERROR;
    return;
  }
  n = 0; pos = 0.0;
  while (ps_stack_top >= 2 && n < num_hgroups) {
    /* add_stem() add sidebearing */
    pos += ps_arg_stack[--ps_stack_top];
    del  = ps_arg_stack[--ps_stack_top];
    stem_id = add_stem(cd,
                     (del < 0.0) ? pos + del : pos,
                     (del < 0.0) ? -del : del,
                     HSTEM);
    stemgroups[n].stems[stemgroups[n].num_stems] = stem_id;
    stemgroups[n].num_stems += 1;
    pos += del;
    if (del < 0.0) {
      pos = 0.0;
      n++;
    }
  }
  if (n != num_hgroups) {
    status = CS_STACK_ERROR;
    return;
  }

  num_vgroups = (int) ps_arg_stack[--ps_stack_top];
  if (num_vgroups < 0 || num_vgroups > CS_STEM_GROUP_MAX) {
    status = CS_PARSE_ERROR;
    return;
  }
  n = 0; pos = 0.0;
  while (ps_stack_top >= 2 && n < num_vgroups) {
    /* add_stem() add sidebearing */
    pos += ps_arg_stack[--ps_stack_top];
    del  = ps_arg_stack[--ps_stack_top];
    stem_id = add_stem(cd,
                     (del < 0.0) ? pos + del : pos,
                     (del < 0.0) ? -del : del,
                     VSTEM);
    stemgroups[n].stems[stemgroups[n].num_stems] = stem_id;
    stemgroups[n].num_stems += 1;
    pos += del;
    if (del < 0.0) {
      pos = 0.0;
      n++;
    }
  }
  if (n != num_vgroups) {
    status = CS_STACK_ERROR;
    return;
  }

  for (n = 0; n < MAX(num_hgroups, num_vgroups); n++) {
    add_charpath(cd, cs_cntrmask,
               stemgroups[n].stems, stemgroups[n].num_stems);
  }

  cd->flags |= T1_CS_FLAG_USE_CNTRMASK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_othersubr2 ( t1_chardesc cd) [static]

Definition at line 647 of file t1_char.c.

{
  if (phase != T1_CS_PHASE_FLEX || !cd->lastpath) {
    status = CS_PARSE_ERROR;
    return;
  }

  switch (cd->lastpath->type) {
  case cs_rmoveto:
    break;
  case cs_hmoveto:
    cd->lastpath->num_args = 2;
    cd->lastpath->args[1] = 0.0;
    break;
  case cs_vmoveto:
    cd->lastpath->num_args = 2;
    cd->lastpath->args[1] = cd->lastpath->args[0];
    cd->lastpath->args[0] = 0.0;
    break;
  default:
    status = CS_PARSE_ERROR;
    return;
  }
  cd->lastpath->type = CS_FLEX_CTRL;
}

Here is the caller graph for this function:

static void do_othersubr3 ( t1_chardesc cd) [static]

Definition at line 678 of file t1_char.c.

Here is the caller graph for this function:

static void do_postproc ( t1_chardesc cd) [static]

Definition at line 1123 of file t1_char.c.

{
  int i;
  t1_cpath *cur, *prev, *next;
  double x, y;

  if (!cd->charpath)
    return;

  /* Set dummy large value. */
  cd->bbox.llx = cd->bbox.lly =  100000.0;
  cd->bbox.urx = cd->bbox.ury = -100000.0;

  cur  = cd->charpath;
  prev = NULL;
  x = y = 0.0;

#define UPDATE_BBOX(b,x,y) do {\
  if ((b).llx > (x)) (b).llx = (x);\
  if ((b).urx < (x)) (b).urx = (x);\
  if ((b).lly > (y)) (b).lly = (y);\
  if ((b).ury < (y)) (b).ury = (y);\
} while (0)
#define TRY_COMPACT (prev && cur && ((prev->num_args + cur->num_args) <= CS_ARG_STACK_MAX))

  while (cur != NULL) {
    next = cur->next;
    switch (cur->type) {
    case cs_rmoveto:
      x += cur->args[0]; y += cur->args[1];
      UPDATE_BBOX(cd->bbox, x, y);
      break;
    case cs_rlineto:
      x += cur->args[0]; y += cur->args[1];
      UPDATE_BBOX(cd->bbox, x, y);
      if (TRY_COMPACT) {
       if (prev->type == cs_rlineto) {
         copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
         prev->num_args += cur->num_args;
         prev->next = next;
         RELEASE(cur); cur = NULL;
       } else if (prev->type == cs_rrcurveto) {
         copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
         prev->num_args += cur->num_args;
         prev->type = cs_rcurveline;
         prev->next = next;
         RELEASE(cur); cur = NULL;
       }
      }
      break;
    case cs_hmoveto:
      x += cur->args[0];
      UPDATE_BBOX(cd->bbox, x, y);
      break;
    case cs_hlineto:
      x += cur->args[0];
      UPDATE_BBOX(cd->bbox, x, y);
      if (TRY_COMPACT) {
       if ((prev->type == cs_vlineto && (prev->num_args % 2) == 1) ||
           (prev->type == cs_hlineto && (prev->num_args % 2) == 0)) {
         copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
         prev->num_args += cur->num_args;
         prev->next = next;
         RELEASE(cur); cur = NULL;
       }
      }
      break;
    case cs_vmoveto:
      y += cur->args[0];
      UPDATE_BBOX(cd->bbox, x, y);
      break;
    case cs_vlineto:
      y += cur->args[0];
      UPDATE_BBOX(cd->bbox, x, y);
      if (TRY_COMPACT) {
       if ((prev->type == cs_hlineto && (prev->num_args % 2) == 1) ||
           (prev->type == cs_vlineto && (prev->num_args % 2) == 0)) {
         copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
         prev->num_args += cur->num_args;
         prev->next = next;
         RELEASE(cur); cur = NULL;
       }
      }
      break;
    case cs_rrcurveto:
      for (i = 0; i < 3; i++) {
       x += cur->args[2*i]; y += cur->args[2*i+1];
       UPDATE_BBOX(cd->bbox, x, y);
      }
      if (TRY_COMPACT) {
       if (prev->type == cs_rrcurveto) {
         copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
         prev->num_args += cur->num_args;
         prev->next = next;
         RELEASE(cur); cur = NULL;
       } else if (prev->type == cs_rlineto) {
         copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
         prev->num_args += cur->num_args;
         prev->type = cs_rlinecurve;
         prev->next = next;
         RELEASE(cur); cur = NULL;
       }
      }
      break;
    case cs_vhcurveto:
      y += cur->args[0];
      UPDATE_BBOX(cd->bbox, x, y);
      x += cur->args[1]; y += cur->args[2];
      UPDATE_BBOX(cd->bbox, x, y);
      x += cur->args[3];
      UPDATE_BBOX(cd->bbox, x, y);
      if (TRY_COMPACT) {
       if ((prev->type == cs_hvcurveto && ((prev->num_args / 4) % 2) == 1) ||
           (prev->type == cs_vhcurveto && ((prev->num_args / 4) % 2) == 0)) {
         copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
         prev->num_args += cur->num_args;
         prev->next = next;
         RELEASE(cur); cur = NULL;
       }
      }
      break;
    case cs_hvcurveto:
      x += cur->args[0];
      UPDATE_BBOX(cd->bbox, x, y);
      x += cur->args[1]; y += cur->args[2];
      UPDATE_BBOX(cd->bbox, x, y);
      y += cur->args[3];
      UPDATE_BBOX(cd->bbox, x, y);
      if (TRY_COMPACT) {
       if ((prev->type == cs_vhcurveto && ((prev->num_args / 4) % 2) == 1) ||
           (prev->type == cs_hvcurveto && ((prev->num_args / 4) % 2) == 0)) {
         copy_args(prev->args+prev->num_args, cur->args, cur->num_args);
         prev->num_args += cur->num_args;
         prev->next = next;
         RELEASE(cur); cur = NULL;
       }
      }
      break;
    case cs_flex:
      for (i = 0; i < 6; i++) {
       x += cur->args[2*i]; y += cur->args[2*1+1];
       UPDATE_BBOX(cd->bbox, x, y);
      }
      if (cur->args[12] == 50.0) {
       if (cur->args[1] == 0.0 && cur->args[11] == 0.0 &&
           cur->args[5] == 0.0 && cur->args[7] == 0.0 &&
           cur->args[3] + cur->args[9] == 0.0) {
         /* cur->args[0] = cur->args[0];  dx1 */
         cur->args[1] = cur->args[2];  /* dx2 */
         cur->args[2] = cur->args[3];  /* dy2 */
         cur->args[3] = cur->args[4];  /* dx3 */
         cur->args[4] = cur->args[6];  /* dx4 */
         cur->args[5] = cur->args[8];  /* dx5 */
         cur->args[6] = cur->args[10]; /* dx6 */
         cur->num_args = 7;
         cur->type = cs_hflex;
       } else if (cur->args[5] == 0.0 && cur->args[7] == 0.0 &&
                 (cur->args[1] + cur->args[3] +
                  cur->args[9] + cur->args[11]) == 0) {
         /* cur->args[0] = cur->args[0];  dx1 */
         /* cur->args[1] = cur->args[1];  dy1 */
         /* cur->args[2] = cur->args[2];  dx2 */
         /* cur->args[3] = cur->args[3];  dy2 */
         /* cur->args[4] = cur->args[4];  dx3 */
         cur->args[5] = cur->args[6];  /* dx4 */
         cur->args[6] = cur->args[8];  /* dx5 */
         cur->args[7] = cur->args[9];  /* dy5 */
         cur->args[8] = cur->args[10]; /* dx6 */
         cur->num_args = 9;
         cur->type = cs_hflex1;
       }
      }
      break;
    case CS_HINT_DECL:
    case cs_cntrmask:
      /* noop */
      break;
    default:
      ERROR("Unexpected Type 2 charstring command %d.", cur->type);
      break;
    }
    if (cur != NULL)
      prev = cur;
    cur = next;
  }

  /* Had no path. Fix lower-left point. */
  if (cd->bbox.llx > cd->bbox.urx)
    cd->bbox.llx = cd->bbox.urx = cd->sbw.wx;
  if (cd->bbox.lly > cd->bbox.ury)
    cd->bbox.lly = cd->bbox.ury = cd->sbw.wy;

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_integer ( card8 **  data,
card8 endptr 
) [static]

Definition at line 991 of file t1_char.c.

{
  long result = 0;
  card8 b0 = **data, b1, b2;

  *data += 1;

  if (b0 == 28) { /* shortint */
    SRC_NEED(endptr, *data + 2);
    b1 = **data;
    b2 = *(*data+1);
    result = b1*256+b2;
    if (result > 0x7fff)
      result -= 0x10000L;
    *data += 2;
  } else if (b0 >= 32 && b0 <= 246) { /* int (1) */
    result = b0 - 139;
  } else if (b0 >= 247 && b0 <= 250) { /* int (2) */
    SRC_NEED(endptr, *data + 1);
    b1 = **data;
    result = (b0-247)*256+b1+108;
    *data += 1;
  } else if (b0 >= 251 && b0 <= 254) {
    SRC_NEED(endptr, *data + 1);
    b1 = **data;
    result = -(b0-251)*256-b1-108;
    *data += 1;
  } else {
    status = CS_PARSE_ERROR;
    return;
  }

  LIMITCHECK(1);
  cs_arg_stack[cs_stack_top++] = (double) result;

  return;
}

Here is the caller graph for this function:

static void get_longint ( card8 **  data,
card8 endptr 
) [static]

Definition at line 1031 of file t1_char.c.

{
  long result = 0;
  int  i;

  *data += 1;
  SRC_NEED(endptr, *data + 4);
  result = **data;
  if (result >= 0x80L)
    result -= 0x100L;
  *data += 1;
  for (i = 1; i < 4; i++) {
    result = result*256 + (**data);
    *data += 1;
  }

  LIMITCHECK(1);
  cs_arg_stack[cs_stack_top++] = (double) result;

  return;
}

Here is the caller graph for this function:

static int get_stem ( t1_chardesc cd,
int  stem_id 
) [static]

Definition at line 291 of file t1_char.c.

{
  int i;

  for (i = 0; i < cd->num_stems; i++) {
    if (cd->stems[i].id == stem_id)
      break;
  }

  return ((i < cd->num_stems) ? i : -1);
}

Here is the caller graph for this function:

static void init_charpath ( t1_chardesc cd) [static]

Definition at line 391 of file t1_char.c.

{
  cd->flags = T1_CS_FLAG_NONE;
  cd->num_stems = 0;
  cd->sbw.wx  = cd->sbw.wy  = 0.0;
  cd->sbw.sbx = cd->sbw.sby = 0.0;
  cd->bbox.llx = cd->bbox.lly = cd->bbox.urx = cd->bbox.ury = 0.0;
  cd->charpath = cd->lastpath = NULL;
}

Here is the caller graph for this function:

static void put_numbers ( double *  argv,
int  argn,
card8 **  dest,
card8 limit 
) [static]

Definition at line 937 of file t1_char.c.

{
  int i;

  for (i = 0; i < argn; i++) {
    double value;
    long   ivalue;
    value  = argv[i];
    /* Nearest integer value */
    ivalue = (long) floor(value+0.5);
    if (value >= 0x8000L || value <= (-0x8000L - 1)) {
      /*
       * This number cannot be represented as a single operand.
       * We must use `a b mul ...' or `a c div' to represent large values.
       */
      ERROR("Argument value too large. (This is bug)");
    } else if (fabs(value - ivalue) > 3.0e-5) {
      /* 16.16-bit signed fixed value  */
      DST_NEED(limit, *dest + 5);
      *(*dest)++ = 255;
      ivalue = (long) floor(value); /* mantissa */
      *(*dest)++ = (ivalue >> 8) & 0xff;
      *(*dest)++ = ivalue & 0xff;
      ivalue = (long)((value - ivalue) * 0x10000l); /* fraction */
      *(*dest)++ = (ivalue >> 8) & 0xff;
      *(*dest)++ = ivalue & 0xff;
      /* Everything else are integers. */
    } else if (ivalue >= -107 && ivalue <= 107) {
      DST_NEED(limit, *dest + 1);
      *(*dest)++ = ivalue + 139;
    } else if (ivalue >= 108 && ivalue <= 1131) {
      DST_NEED(limit, *dest + 2);
      ivalue = 0xf700u + ivalue - 108;
      *(*dest)++ = (ivalue >> 8) & 0xff;
      *(*dest)++ = ivalue & 0xff;
    } else if (ivalue >= -1131 && ivalue <= -108) {
      DST_NEED(limit, *dest + 2);
      ivalue = 0xfb00u - ivalue - 108;
      *(*dest)++ = (ivalue >> 8) & 0xff;
      *(*dest)++ = ivalue & 0xff;
    } else if (ivalue >= -32768 && ivalue <= 32767) { /* shortint */
      DST_NEED(limit, *dest + 3);
      *(*dest)++ = 28;
      *(*dest)++ = (ivalue >> 8) & 0xff;
      *(*dest)++ = (ivalue) & 0xff;
    } else { /* Shouldn't come here */
      ERROR("Unexpected error.");
    }
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void release_charpath ( t1_chardesc cd) [static]

Definition at line 402 of file t1_char.c.

{
  t1_cpath *curr, *next;

  ASSERT(cd);

  curr = cd->charpath;
  while (curr != NULL) {
    next = curr->next;
    RELEASE(curr);
    curr = next;
  }

  cd->charpath = cd->lastpath = NULL;
}

Here is the caller graph for this function:

static int CDECL stem_compare ( const void *  v1,
const void *  v2 
) [static]

Definition at line 265 of file t1_char.c.

{
  int cmp = 0;
  t1_stem *s1, *s2;

  s1 = (t1_stem *) v1;
  s2 = (t1_stem *) v2;
  if (s1->dir == s2->dir) {
    if (s1->pos == s2->pos) {
      if (s1->del == s2->del)
       cmp = 0;
      else
       cmp = (s1->del < s2->del) ? -1 : 1;
    } else {
      cmp = (s1->pos < s2->pos) ? -1 : 1;
    }
  } else {
    cmp = (s1->dir == HSTEM) ? -1 : 1;
  }

  return cmp;
}
static void t1char_build_charpath ( t1_chardesc cd,
card8 **  data,
card8 endptr,
cff_index subrs 
) [static]

Definition at line 1061 of file t1_char.c.

{
  card8 b0 = 0, *subr;
  long len;

  if (nest > CS_SUBR_NEST_MAX)
    ERROR("Subroutine nested too deeply.");

  nest++;
  while (*data < endptr && status == CS_PARSE_OK) {
    b0 = **data;
    if (b0 == 255) {
      get_longint(data, endptr); /* Type 1 */
    } else if (b0 == cs_return) {
      status = CS_SUBR_RETURN;
    } else if (b0 == cs_callsubr) {
      if (cs_stack_top < 1) {
       status = CS_STACK_ERROR;
      } else {
       int idx;

       idx = cs_arg_stack[--cs_stack_top];
       if (!subrs || idx >= subrs->count)
         ERROR("Invalid Subr#.");
       subr = subrs->data + subrs->offset[idx] - 1;
       len  = subrs->offset[idx+1] - subrs->offset[idx];
       t1char_build_charpath(cd, &subr, subr+len, subrs);
       *data += 1;
      }
    } else if (b0 == cs_escape) {
      do_operator2(cd, data, endptr);
    } else if (b0 < 32 && b0 != 28) { /* 19, 20 need mask */
      do_operator1(cd, data, endptr);
    } else if ((b0 <= 22 && b0 >= 27) || b0 == 31) { /* reserved */
      status = CS_PARSE_ERROR; /* not an error ? */
    } else { /* integer */
      get_integer(data, endptr);
    }
  }

  if (status == CS_SUBR_RETURN) {
    status = CS_PARSE_OK;
  } else if (status == CS_CHAR_END && *data < endptr) {
    if (!(*data == endptr - 1 && **data == cs_return))
      WARN("Garbage after endchar. (%ld bytes)", (long) (endptr - *data));
  } else if (status < CS_PARSE_OK) { /* error */
    ERROR("Parsing charstring failed: (status=%d, stack=%d)", status, cs_stack_top);
  }

  nest--;

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

long t1char_convert_charstring ( card8 dst,
long  dstlen,
card8 src,
long  srclen,
cff_index subrs,
double  default_width,
double  nominal_width,
t1_ginfo ginfo 
)

Definition at line 1550 of file t1_char.c.

{
  long length;
  t1_chardesc t1char, *cd;

  cd = &t1char;
  init_charpath(cd);
  RESET_STATE();
  CLEARSTACK();
  t1char_build_charpath(cd, &src, src+srclen, subrs);
  if (cs_stack_top != 0 || ps_stack_top != 0)
    WARN("Stack not empty. (%d, %d)", cs_stack_top, ps_stack_top);
  do_postproc(cd);
  SORT_STEMS(cd);

  length = t1char_encode_charpath(cd, default_width, nominal_width, dst, dst+dstlen);

  if (ginfo) {
    ginfo->wx = cd->sbw.wx;
    ginfo->wy = cd->sbw.wy;
    ginfo->bbox.llx = cd->bbox.llx;
    ginfo->bbox.lly = cd->bbox.lly;
    ginfo->bbox.urx = cd->bbox.urx;
    ginfo->bbox.ury = cd->bbox.ury;
    if (cd->flags & T1_CS_FLAG_USE_SEAC) {
      ginfo->use_seac = 1;
      ginfo->seac.adx = cd->seac.adx;
      ginfo->seac.ady = cd->seac.ady;
      ginfo->seac.bchar = cd->seac.bchar;
      ginfo->seac.achar = cd->seac.achar;
    } else {
      ginfo->use_seac = 0;
    }
  }
  release_charpath(cd);

  return length;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long t1char_encode_charpath ( t1_chardesc cd,
double  default_width,
double  nominal_width,
card8 dst,
card8 endptr 
) [static]

Definition at line 1371 of file t1_char.c.

{
  card8    *save;
  t1_cpath *curr;

  ASSERT(cd);

  save = dst;
  curr = cd->charpath;

  RESET_STATE();
  CLEARSTACK(); 
  /*
   * Advance Width
   */
  if (cd->sbw.wx != default_width) {
    double wx = cd->sbw.wx - nominal_width;
    put_numbers(&wx, 1, &dst, endptr);
    CHECK_STATUS();
  }
  /*
   * Hint Declaration
   */
  {
    int num_hstems = 0, num_vstems = 0;
    int i, reset = 1;
    double stem[2];

    for (i = 0; i < cd->num_stems && cd->stems[i].dir == HSTEM; i++) {
      num_hstems++;
      stem[0] = (reset ?
               (cd->stems[i].pos) :
               (cd->stems[i].pos - (cd->stems[i-1].pos + cd->stems[i-1].del)));
      stem[1] = cd->stems[i].del;
      put_numbers(stem, 2, &dst, endptr);
      CHECK_STATUS();
      reset = 0;
      if (2*num_hstems == CS_ARG_STACK_MAX) {
       CHECK_BUFFER(1);
       *dst++ = (card8) ((cd->flags & T1_CS_FLAG_USE_HINTMASK) ? cs_hstemhm : cs_hstem);
       reset = 1;
      }
    }
    if (reset == 0) {
      CHECK_BUFFER(1);
      *dst++ = (card8) ((cd->flags & T1_CS_FLAG_USE_HINTMASK) ? cs_hstemhm : cs_hstem);
    }
    reset = 1;
    if (cd->num_stems - num_hstems > 0) {
      for (i = num_hstems; i < cd->num_stems; i++) {
       num_vstems++;
       stem[0] = (reset ?
                 (cd->stems[i].pos) :
                 (cd->stems[i].pos - (cd->stems[i-1].pos + cd->stems[i-1].del)));
       stem[1] = cd->stems[i].del;
       put_numbers(stem, 2, &dst, endptr);
       CHECK_STATUS();
       reset = 0;
       if (2*num_vstems == CS_ARG_STACK_MAX) {
         CHECK_BUFFER(1);
         *dst++ = (card8) ((cd->flags & T1_CS_FLAG_USE_HINTMASK) ? cs_vstemhm : cs_vstem);
         reset = 1;
       }
      }
      if (reset == 0) {
       CHECK_BUFFER(1);
       if ((cd->flags & T1_CS_FLAG_USE_HINTMASK) ||
           (cd->flags & T1_CS_FLAG_USE_CNTRMASK)) {
         /*
          * The vstem hint operator can be ommited if hstem and vstem hints
          * are both declared at the beginning of a charstring, and is
          * followed directly by the hintmask or cntrmask operators.
          */
         if (curr->type != CS_HINT_DECL &&
             curr->type != cs_cntrmask) {
           *dst++ = (card8) cs_vstemhm;
         }
       } else {
         *dst++ = (card8) cs_vstem;
       }
      }
    }
  }
  /*
   * Path Construction and Hint Replacement
   */
  while (curr != NULL && curr->type != cs_endchar) {
    switch (curr->type) {
    case CS_HINT_DECL:
      {
       card8 hintmask[(CS_STEM_ZONE_MAX+7)/8];

       memset(hintmask, 0, (cd->num_stems+7)/8);
       while (curr != NULL && curr->type == CS_HINT_DECL) {
         int stem_idx;

         stem_idx = get_stem(cd, (int) curr->args[0]);
         ASSERT(stem_idx < cd->num_stems);
         hintmask[stem_idx/8] |= (1 << (7 - (stem_idx % 8)));
         curr = curr->next;
       }
       if (cd->flags & T1_CS_FLAG_USE_HINTMASK) {
         CHECK_BUFFER((cd->num_stems+7)/8 + 1);
         *dst++ = (card8) cs_hintmask;
         memcpy(dst, hintmask, (cd->num_stems+7)/8);
         dst += (cd->num_stems+7)/8;
       }
      }
      break;
    case cs_cntrmask:
      {
       card8 cntrmask[(CS_STEM_ZONE_MAX+7)/8];
       int   stem_idx, i;

       memset(cntrmask, 0, (cd->num_stems+7)/8);
       for (i = 0; i < curr->num_args; i++) {
         stem_idx = get_stem(cd, (int) curr->args[i]);
         ASSERT(stem_idx < cd->num_stems);
         cntrmask[stem_idx/8] |= (1 << (7 - (stem_idx % 8)));
       }
       CHECK_BUFFER((cd->num_stems+7)/8 + 1);
       *dst++ = (card8) cs_cntrmask;
       memcpy(dst, cntrmask, (cd->num_stems+7)/8);
       dst += (cd->num_stems+7)/8;
       curr = curr->next;
      }
      break;
    case cs_rmoveto: case cs_hmoveto: case cs_vmoveto:
    case cs_rlineto: case cs_hlineto: case cs_vlineto:
    case cs_rrcurveto:  case cs_hvcurveto: case cs_vhcurveto:
    case cs_rlinecurve: case cs_rcurveline:
      {
       put_numbers(curr->args, curr->num_args, &dst, endptr);
       CHECK_STATUS();
       CHECK_BUFFER(1);
       *dst++ = (card8) curr->type;
       curr = curr->next;
      }
      break;
    case cs_flex: case cs_hflex:
    case cs_hflex1:
      {
       put_numbers(curr->args, curr->num_args, &dst, endptr);
       CHECK_STATUS();
       CHECK_BUFFER(2);
       *dst++ = (card8) cs_escape;
       *dst++ = (card8) curr->type;
       curr = curr->next;
      }
      break;
    default:
      ERROR("Unknown Type 2 charstring command: %d", curr->type);
      break;
    }
  }

  /*
   * (adx ady bchar achar) endchar
   */
  if (cd->flags & T1_CS_FLAG_USE_SEAC) {
    double seac[4];
    seac[0] = cd->seac.adx;
    seac[1] = cd->seac.ady;
    seac[2] = cd->seac.bchar;
    seac[3] = cd->seac.achar;
    put_numbers(seac, 4, &dst, endptr);
    CHECK_STATUS();
    CHECK_BUFFER(2);
    WARN("Obsolete four arguments of \"endchar\" will be used for Type 1 \"seac\" operator.");
  }
  CHECK_BUFFER(1);
  *dst++ = (card8) cs_endchar;

  return (long) (dst - save);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int t1char_get_metrics ( card8 src,
long  srclen,
cff_index subrs,
t1_ginfo ginfo 
)

Definition at line 1326 of file t1_char.c.

{
  t1_chardesc t1char, *cd;

  cd = &t1char;
  init_charpath(cd);
  RESET_STATE();
  CLEARSTACK();
  t1char_build_charpath(cd, &src, src+srclen, subrs);
  if (cs_stack_top != 0 || ps_stack_top != 0)
    WARN("Stack not empty. (%d, %d)", cs_stack_top, ps_stack_top);
  do_postproc(cd);
  if (ginfo) {
    ginfo->wx = cd->sbw.wx;
    ginfo->wy = cd->sbw.wy;
    ginfo->bbox.llx = cd->bbox.llx;
    ginfo->bbox.lly = cd->bbox.lly;
    ginfo->bbox.urx = cd->bbox.urx;
    ginfo->bbox.ury = cd->bbox.ury;
    if (cd->flags & T1_CS_FLAG_USE_SEAC) {
      ginfo->use_seac = 1;
      ginfo->seac.adx = cd->seac.adx;
      ginfo->seac.ady = cd->seac.ady;
      ginfo->seac.bchar = cd->seac.bchar;
      ginfo->seac.achar = cd->seac.achar;
    } else {
      ginfo->use_seac = 0;
    }
  }
  release_charpath(cd);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

double cs_arg_stack[CS_ARG_STACK_MAX+1] [static]

Definition at line 146 of file t1_char.c.

int cs_stack_top = 0 [static]

Definition at line 142 of file t1_char.c.

int nest = -1 [static]

Definition at line 81 of file t1_char.c.

int phase = -1 [static]

Definition at line 80 of file t1_char.c.

double ps_arg_stack[PS_ARG_STACK_MAX] [static]

Definition at line 147 of file t1_char.c.

int ps_stack_top = 0 [static]

Definition at line 143 of file t1_char.c.

int status = CS_PARSE_ERROR [static]

Definition at line 69 of file t1_char.c.