1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
|
// -*- related-file-name: "../../libefont/t1interp.cc" -*-
#ifndef EFONT_T1INTERP_HH
#define EFONT_T1INTERP_HH
#include <efont/t1cs.hh>
#include <lcdf/point.hh>
#include <stdio.h>
namespace Efont {
class CharstringInterp { public:
CharstringInterp();
CharstringInterp(const Vector<double> &weight_vec);
virtual ~CharstringInterp() { }
int error() const { return _error; }
int error_data() const { return _error_data; }
static String error_string(int error, int error_data);
inline String error_string() const;
bool careful() const { return _careful; }
void set_careful(bool c) { _careful = c; }
bool done() const { return _done; }
void set_done() { _done = true; }
int size() const { return _sp; }
double &at(unsigned i) { return _s[i]; }
double &top(unsigned i = 0) { return _s[_sp - i - 1]; }
double pop(unsigned n = 1) { _sp -= n; return _s[_sp]; }
inline void push(double);
void clear() { _sp = 0; }
int ps_size() const { return _ps_sp; }
double ps_at(unsigned i) const { return _ps_s[i]; }
double ps_pop() { return _ps_s[--_ps_sp]; }
inline void ps_push(double);
void ps_clear() { _ps_sp = 0; }
int subr_depth() const { return _subr_depth; }
inline double &vec(Vector<double> *, int);
const Vector<double> &weight_vector() const { return _weight_vector; }
Vector<double> *scratch_vector() { return &_scratch_vector; }
const CharstringProgram *program() const { return _program; }
inline Charstring *get_subr(int) const;
inline Charstring *get_gsubr(int) const;
inline Charstring *get_xsubr(bool g, int) const;
inline Charstring *get_glyph(PermString) const;
bool interpret(const CharstringProgram *, const Charstring *);
inline bool interpret(const CharstringContext &);
//virtual void init(const CharstringProgram *);
bool error(int c) { return error(c, 0); }
virtual bool error(int, int);
virtual bool number(double);
bool arith_command(int);
bool vector_command(int);
bool blend_command();
bool callsubr_command();
bool callgsubr_command();
inline bool callxsubr_command(bool g);
bool mm_command(int, int);
bool itc_command(int, int);
const Point &left_sidebearing() const { return _lsb; }
const Point ¤tpoint() const { return _cp; }
void set_state_path() { _state = S_PATH; }
virtual bool callothersubr_command(int, int);
virtual bool type1_command(int);
virtual bool type2_command(int, const uint8_t *, int *);
virtual void act_sidebearing(int cmd, const Point &lsb);
virtual void act_width(int cmd, const Point &width);
virtual void act_default_width(int cmd);
virtual void act_nominal_width_delta(int cmd, double delta);
virtual void act_seac(int cmd, double asb, double adx, double ady, int bchar, int achar);
virtual void act_line(int cmd, const Point &p0, const Point &p1);
virtual void act_curve(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3);
virtual void act_closepath(int cmd);
virtual void act_flex(int cmd, const Point &p0, const Point &p1, const Point &p2, const Point &p3_4, const Point &p5, const Point &p6, const Point &p7, double flex_depth);
virtual void act_hstem(int cmd, double y, double dy);
virtual void act_vstem(int cmd, double x, double dx);
virtual void act_hstem3(int cmd, double y0, double dy0, double y1, double dy1, double y2, double dy2);
virtual void act_vstem3(int cmd, double x0, double dx0, double x1, double dx1, double x2, double dx2);
virtual void act_hintmask(int cmd, const uint8_t *data, int nhints);
typedef Charstring Cs;
enum Errors {
errOK = 0,
errInternal = -1,
errRunoff = -2,
errUnimplemented = -3,
errOverflow = -4,
errUnderflow = -5,
errVector = -6,
errValue = -7,
errSubr = -8,
errGlyph = -9,
errCurrentPoint = -10,
errFlex = -11,
errMultipleMaster = -12,
errOpenStroke = -13,
errLateSidebearing = -14,
errOthersubr = -15,
errOrdering = -16,
errHintmask = -17,
errSubrDepth = -18,
errLastError = -18
};
enum { STACK_SIZE = 48, PS_STACK_SIZE = 24, MAX_SUBR_DEPTH = 10,
SCRATCH_SIZE = 32 };
private:
int _error;
int _error_data;
bool _done;
bool _careful;
double _s[STACK_SIZE];
int _sp;
double _ps_s[PS_STACK_SIZE];
int _ps_sp;
int _subr_depth;
Vector<double> _weight_vector;
Vector<double> _scratch_vector;
Point _lsb;
Point _cp;
Point _seac_origin;
const CharstringProgram *_program;
enum State {
S_INITIAL, S_SEAC, S_SBW, S_HSTEM, S_VSTEM, S_HINTMASK, S_IPATH, S_PATH
};
State _state;
bool _flex;
// for processing Type 2 charstrings
int _t2nhints;
static double double_for_error;
void initialize();
inline void ensure_weight_vector();
void fetch_weight_vector();
bool roll_command();
int type2_handle_width(int, bool);
inline void actp_rmoveto(int, double, double);
inline void actp_rlineto(int, double, double);
void actp_rrcurveto(int, double, double, double, double, double, double);
void actp_rrflex(int, double, double, double, double, double, double, double, double, double, double, double, double, double);
};
inline String CharstringInterp::error_string() const
{
return error_string(_error, _error_data);
}
inline void CharstringInterp::push(double d)
{
if (_sp < STACK_SIZE)
_s[_sp++] = d;
else
error(errOverflow);
}
inline void CharstringInterp::ps_push(double d)
{
if (_ps_sp < PS_STACK_SIZE)
_ps_s[_ps_sp++] = d;
else
error(errOverflow);
}
inline double &CharstringInterp::vec(Vector<double> *v, int i)
{
if (i < 0 || i >= v->size()) {
error(errVector);
return double_for_error;
} else
return v->at_u(i);
}
inline Charstring *CharstringInterp::get_subr(int n) const
{
return _program ? _program->subr(n) : 0;
}
inline Charstring *CharstringInterp::get_gsubr(int n) const
{
return _program ? _program->gsubr(n) : 0;
}
inline Charstring *CharstringInterp::get_xsubr(bool g, int n) const
{
return _program ? _program->xsubr(g, n) : 0;
}
inline Charstring *CharstringInterp::get_glyph(PermString n) const
{
return _program ? _program->glyph(n) : 0;
}
inline void CharstringInterp::ensure_weight_vector()
{
if (!_weight_vector.size())
fetch_weight_vector();
}
inline bool CharstringInterp::callxsubr_command(bool g)
{
return (g ? callgsubr_command() : callsubr_command());
}
inline bool CharstringInterp::interpret(const CharstringContext &g)
{
return interpret(g.program, g.cs);
}
}
#endif
|