diff options
Diffstat (limited to 'Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc')
-rw-r--r-- | Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc | 1377 |
1 files changed, 0 insertions, 1377 deletions
diff --git a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc b/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc deleted file mode 100644 index 59200f0981b..00000000000 --- a/Build/source/texk/lcdf-typetools/lcdf-typetools-src/libefont/t1interp.cc +++ /dev/null @@ -1,1377 +0,0 @@ -// -*- related-file-name: "../include/efont/t1interp.hh" -*- - -/* t1interp.{cc,hh} -- Type 1/2 charstring interpretation - * - * Copyright (c) 1998-2019 Eddie Kohler - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <efont/t1interp.hh> -#include <stdio.h> -#include <stdlib.h> -#include <math.h> - -#ifdef WIN32 -# define random() rand() -#endif - -#define CHECK_STACK(numargs) do { if (size() < numargs) return error(errUnderflow, cmd); } while (0) -#define CHECK_STATE() do { if (_state < S_IPATH) return error(errOrdering, cmd); } while (0) -#define CHECK_PATH_START() do { _state = S_PATH; } while (0) -#define CHECK_PATH_END() do { if (_state == S_PATH) { act_closepath(cmd); } _state = S_IPATH; } while (0) - -#ifndef static_assert -# define static_assert(c, msg) switch ((int) (c)) case 0: case (c): -#endif - -namespace Efont { - -static const char * const error_formats[] = { - "charstring OK", // errOK - "charstring internal error in '%C'", // errInternal - "charstring commands past end", // errRunoff - "charstring command '%C' unimplemented", // errUnimplemented - "charstring stack overflow", // errOverflow - "charstring stack underflow in '%C'", // errUnderflow - "charstring bad vector operation in '%C'", // errVector - "charstring bad value in '%C'", // errValue - "charstring bad subroutine number %d", // errSubr - "charstring bad glyph number '%d'", // errGlyph - "charstring no current point in '%C'", // errCurrentPoint - "charstring flex error", // errFlex - "charstring multiple master error in '%C'", // errMultipleMaster - "charstring open stroke", // errOpenStroke - "charstring late sidebearing command '%C'", // errLateSidebearing - "charstring bad othersubr number %d", // errOthersubr - "charstring ordering constraints violated at '%C'", // errOrdering - "charstring inappropriate hintmask", // errHintmask - "charstring subrs nested too deep at '%d'" // errSubrDepth -}; - -double CharstringInterp::double_for_error; - - -CharstringInterp::CharstringInterp() - : _error(errOK), _careful(false), _sp(0), _ps_sp(0), - _scratch_vector(SCRATCH_SIZE, 0), _program(0) -{ -} - -CharstringInterp::CharstringInterp(const Vector<double> &weight_vector) - : _error(errOK), _careful(false), _sp(0), _ps_sp(0), - _weight_vector(weight_vector), - _scratch_vector(SCRATCH_SIZE, 0), _program(0) -{ -} - -void -CharstringInterp::initialize() -{ - clear(); - ps_clear(); - _lsb = _cp = _seac_origin = Point(0, 0); - _state = S_INITIAL; - _flex = false; - _t2nhints = 0; - _subr_depth = 0; - _done = false; - _error = errOK; -} - -bool -CharstringInterp::interpret(const CharstringProgram *program, const Charstring *cs) -{ - if (cs) { - initialize(); - _program = program; - cs->process(*this); - return _error == errOK; - } else - return error(errGlyph, 0); -} - -bool -CharstringInterp::error(int err, int error_data) -{ - _error = err; - _error_data = error_data; - return false; -} - -String -CharstringInterp::error_string(int error, int error_data) -{ - static_assert(-errLastError == (sizeof(error_formats) / sizeof(error_formats[0])) - 1, - "errLastError defined incorrectly"); - if (error >= 0) - return error_formats[0]; - else if (error < errLastError) - return "charstring unknown error number " + String(error); - String format = error_formats[-error]; - int percent = format.find_left('%'); - if (percent >= 0 && format[percent + 1] == 'C') - return format.substring(0, percent) + Charstring::command_name(error_data) + format.substring(percent + 2); - else if (percent >= 0 && format[percent + 1] == 'd') - return format.substring(0, percent) + String(error_data) + format.substring(percent + 2); - else - return format; -} - -bool -CharstringInterp::number(double v) -{ - push(v); - return true; -} - -void -CharstringInterp::fetch_weight_vector() -{ - if (_program) - if (Vector<double> *wv = _program->mm_vector(CharstringProgram::VEC_WEIGHT, false)) - _weight_vector = *wv; -} - -bool -CharstringInterp::vector_command(int cmd) -{ - CharstringProgram::VectorType which_vector; - int vectoroff, offset, num, i; - Vector<double> *v = 0; - - switch (cmd) { - - case Cs::cPut: - CHECK_STACK(2); - offset = (int)top(0); - vec(&_scratch_vector, offset) = top(1); - pop(2); - break; - - case Cs::cGet: - CHECK_STACK(1); - offset = (int)top(); - top() = vec(&_scratch_vector, offset); - break; - - case Cs::cStore: - CHECK_STACK(4); - which_vector = (CharstringProgram::VectorType)((int)top(3)); - vectoroff = (int)top(2); - offset = (int)top(1); - num = (int)top(0); - pop(4); - - if (!_program) - return error(errVector, cmd); - v = _program->mm_vector(which_vector, true); - if (!v) - return error(errVector, cmd); - - for (i = 0; i < num; i++, offset++, vectoroff++) - vec(v, vectoroff) = vec(&_scratch_vector, offset); - // erase our weight vector if the global weight vector has changed - if (which_vector == CharstringProgram::VEC_WEIGHT) - _weight_vector.clear(); - break; - - case Cs::cLoad: - CHECK_STACK(3); - which_vector = (CharstringProgram::VectorType)((int)top(2)); - offset = (int)top(1); - num = (int)top(0); - pop(3); - - if (!_program) - return error(errVector, cmd); - v = _program->mm_vector(which_vector, false); - // use our weight vector if appropriate - if (!v && which_vector == CharstringProgram::VEC_WEIGHT && _weight_vector.size()) - v = &_weight_vector; - if (!v) - return error(errVector, cmd); - - for (i = 0; i < num; i++, offset++) - vec(&_scratch_vector, offset) = vec(v, i); - break; - - default: - return error(errUnimplemented, cmd); - - } - - return true; -} - -bool -CharstringInterp::blend_command() -{ - const int cmd = Cs::cBlend; - CHECK_STACK(1); - int nargs = (int)pop(); - - ensure_weight_vector(); - if (!_weight_vector.size()) - return error(errVector, cmd); - - int nmasters = _weight_vector.size(); - CHECK_STACK(nargs * nmasters); - - int base = _sp - nargs * nmasters; - int off = base + nargs; - for (int j = 0; j < nargs; j++) { - double &val = _s[base + j]; - for (int i = 1; i < nmasters; i++, off++) - val += _weight_vector.at_u(i) * _s[off]; - } - - pop(nargs * (nmasters - 1)); - return true; -} - -bool -CharstringInterp::roll_command() -{ - const int cmd = Cs::cRoll; - CHECK_STACK(2); - int amount = (int)pop(); - int n = (int)pop(); - if (n <= 0) - return error(errValue, cmd); - CHECK_STACK(n); - - int base = _sp - n; - while (amount < 0) - amount += n; - - int i; - double copy_stack[STACK_SIZE]; - for (i = 0; i < n; i++) - copy_stack[i] = _s[ base + (i+amount) % n ]; - for (i = 0; i < n; i++) - _s[base + i] = copy_stack[i]; - - return true; -} - -bool -CharstringInterp::arith_command(int cmd) -{ - int i; - double d; - - switch (cmd) { - - case Cs::cBlend: - return blend_command(); - - case Cs::cAbs: - CHECK_STACK(1); - if (top() < 0) - top() = -top(); - break; - - case Cs::cAdd: - CHECK_STACK(1); - d = pop(); - top() += d; - break; - - case Cs::cSub: - CHECK_STACK(1); - d = pop(); - top() -= d; - break; - - case Cs::cDiv: - CHECK_STACK(2); - d = pop(); - top() /= d; - break; - - case Cs::cNeg: - CHECK_STACK(1); - top() = -top(); - break; - - case Cs::cRandom: { - double d; - do { - d = random() / ((double)RAND_MAX); - } while (d == 0); - push(d); - break; - } - - case Cs::cMul: - CHECK_STACK(2); - d = pop(); - top() *= d; - break; - - case Cs::cSqrt: - CHECK_STACK(1); - if (top() < 0) - return error(errValue, cmd); - top() = sqrt(top()); - break; - - case Cs::cDrop: - CHECK_STACK(1); - pop(); - break; - - case Cs::cExch: - CHECK_STACK(2); - d = top(0); - top(0) = top(1); - top(1) = d; - break; - - case Cs::cIndex: - CHECK_STACK(1); - i = (int)top(); - if (i < 0) - return error(errValue, cmd); - CHECK_STACK(i + 2); - top() = top(i+1); - break; - - case Cs::cRoll: - return roll_command(); - - case Cs::cDup: - CHECK_STACK(1); - push(top()); - break; - - case Cs::cAnd: - CHECK_STACK(2); - d = pop(); - top() = (top() != 0) && (d != 0); - break; - - case Cs::cOr: - CHECK_STACK(2); - d = pop(); - top() = (top() != 0) || (d != 0); - break; - - case Cs::cNot: - CHECK_STACK(1); - top() = (top() == 0); - break; - - case Cs::cEq: - CHECK_STACK(2); - d = pop(); - top() = (top() == d); - break; - - case Cs::cIfelse: - CHECK_STACK(4); - if (top(1) > top(0)) - top(3) = top(2); - pop(3); - break; - - case Cs::cPop: - if (ps_size() < 1) - return error(errUnderflow, cmd); - push(ps_pop()); - break; - - case 15: - // this command is found with no explanation in JansonText-Roman - CHECK_STACK(2); - pop(2); - return true; - - default: - return error(errUnimplemented, cmd); - - } - - return true; -} - -bool -CharstringInterp::callsubr_command() -{ - const int cmd = Cs::cCallsubr; - CHECK_STACK(1); - int which = (int)pop(); - - Charstring *subr_cs = get_subr(which); - if (!subr_cs) - return error(errSubr, which); - - if (_subr_depth >= MAX_SUBR_DEPTH) - return error(errSubrDepth, which); - _subr_depth++; - - subr_cs->process(*this); - - _subr_depth--; - if (_error != errOK) - return false; - return !done(); -} - -bool -CharstringInterp::callgsubr_command() -{ - const int cmd = Cs::cCallgsubr; - CHECK_STACK(1); - int which = (int)pop(); - - Charstring *subr_cs = get_gsubr(which); - if (!subr_cs) - return error(errSubr, which); - - if (_subr_depth >= MAX_SUBR_DEPTH) - return error(errSubrDepth, which); - _subr_depth++; - - subr_cs->process(*this); - - _subr_depth--; - if (_error != errOK) - return false; - return !done(); -} - -bool -CharstringInterp::mm_command(int command, int on_stack) -{ - ensure_weight_vector(); - if (!_weight_vector.size()) - return error(errVector, command); - - int nargs; - switch (command) { - case Cs::othcMM1: nargs = 1; break; - case Cs::othcMM2: nargs = 2; break; - case Cs::othcMM3: nargs = 3; break; - case Cs::othcMM4: nargs = 4; break; - case Cs::othcMM6: nargs = 6; break; - default: return error(errInternal, command); - } - - int nmasters = _weight_vector.size(); - if (size() < nargs * nmasters - || on_stack != nargs * nmasters) - return error(errMultipleMaster, command); - - int base = size() - on_stack; - - int off = base + nargs; - for (int j = 0; j < nargs; j++) { - double &val = at(base + j); - for (int i = 1; i < nmasters; i++, off++) - val += _weight_vector.at_u(i) * at(off); - } - - for (int i = nargs - 1; i >= 0; i--) - ps_push(at(base + i)); - - pop(on_stack); - return true; -} - -bool -CharstringInterp::itc_command(int command, int on_stack) -{ - ensure_weight_vector(); - if (!_weight_vector.size()) - return error(errVector, command); - - int base = size() - on_stack; - switch (command) { - - case Cs::othcITC_load: { - if (on_stack != 1) - return error(errOthersubr, command); - int offset = (int)at(base); - for (int i = 0; i < _weight_vector.size(); i++) - vec(&_scratch_vector, offset+i) = _weight_vector.at_u(i); - break; - } - - case Cs::othcITC_put: { - if (on_stack != 2) - return error(errOthersubr, command); - int offset = (int)at(base+1); - vec(&_scratch_vector, offset) = at(base); - break; - } - - case Cs::othcITC_get: { - if (on_stack != 1) - return error(errOthersubr, command); - int offset = (int)at(base); - ps_push(vec(&_scratch_vector, offset)); - break; - } - - case Cs::othcITC_add: { - if (on_stack != 2) - return error(errOthersubr, command); - ps_push(at(base) + at(base+1)); - break; - } - - case Cs::othcITC_sub: { - if (on_stack != 2) - return error(errOthersubr, command); - ps_push(at(base) - at(base+1)); - break; - } - - case Cs::othcITC_mul: { - if (on_stack != 2) - return error(errOthersubr, command); - ps_push(at(base) * at(base+1)); - break; - } - - case Cs::othcITC_div: { - if (on_stack != 2) - return error(errOthersubr, command); - ps_push(at(base) / at(base+1)); - break; - } - - case Cs::othcITC_ifelse: { - if (on_stack != 4) - return error(errOthersubr, command); - if (at(base+2) <= at(base+3)) - ps_push(at(base)); - else - ps_push(at(base+1)); - break; - } - - default: - return error(errOthersubr, command); - - } - - pop(on_stack); - return true; -} - - -inline void -CharstringInterp::actp_rmoveto(int /*cmd*/, double dx, double dy) -{ - _cp.shift(dx, dy); -} - -inline void -CharstringInterp::actp_rlineto(int cmd, double dx, double dy) -{ - Point p0(_cp); - _cp.shift(dx, dy); - act_line(cmd, p0, _cp); -} - -void -CharstringInterp::actp_rrcurveto(int cmd, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3) -{ - Point p0(_cp); - Point p1(p0, dx1, dy1); - Point p2(p1, dx2, dy2); - _cp = p2.shifted(dx3, dy3); - act_curve(cmd, p0, p1, p2, _cp); -} - -void -CharstringInterp::actp_rrflex(int cmd, double dx1, double dy1, double dx2, double dy2, double dx3, double dy3, double dx4, double dy4, double dx5, double dy5, double dx6, double dy6, double flex_depth) -{ - Point p0(_cp); - Point p1(p0, dx1, dy1); - Point p2(p1, dx2, dy2); - Point p3_4(p2, dx3, dy3); - Point p5(p3_4, dx4, dy4); - Point p6(p5, dx5, dy5); - _cp = p6.shifted(dx6, dy6); - act_flex(cmd, p0, p1, p2, p3_4, p5, p6, _cp, flex_depth); -} - - -bool -CharstringInterp::callothersubr_command(int othersubrnum, int n) -{ - switch (othersubrnum) { - - case Cs::othcFlexend: - if (n != 3) - goto unknown; - if (!_flex || ps_size() != 16) - return error(errFlex); - CHECK_PATH_START(); - act_flex(Cs::cCallothersubr, Point(ps_at(0), ps_at(1)), - Point(ps_at(4), ps_at(5)), Point(ps_at(6), ps_at(7)), - Point(ps_at(8), ps_at(9)), Point(ps_at(10), ps_at(11)), - Point(ps_at(12), ps_at(13)), Point(ps_at(14), ps_at(15)), - top(2)); - ps_clear(); - ps_push(top(0)); - ps_push(top(1)); - _flex = false; - _state = S_PATH; - break; - - case Cs::othcFlexbegin: - if (n != 0) - goto unknown; - if (_flex) - return error(errFlex); - ps_clear(); - ps_push(_cp.x); - ps_push(_cp.y); - _flex = true; - _state = S_IPATH; - break; - - case Cs::othcFlexmiddle: - if (n != 0) - goto unknown; - if (!_flex) - return error(errFlex); - ps_push(_cp.x); - ps_push(_cp.y); - break; - - case Cs::othcReplacehints: - if (n != 1) - goto unknown; - ps_clear(); - ps_push(top()); - break; - - case Cs::othcMM1: - case Cs::othcMM2: - case Cs::othcMM3: - case Cs::othcMM4: - case Cs::othcMM6: - return mm_command(othersubrnum, n); - - case Cs::othcITC_load: - case Cs::othcITC_add: - case Cs::othcITC_sub: - case Cs::othcITC_mul: - case Cs::othcITC_div: - case Cs::othcITC_put: - case Cs::othcITC_get: - case Cs::othcITC_unknown: - case Cs::othcITC_ifelse: - case Cs::othcITC_random: - return itc_command(othersubrnum, n); - - default: // unknown - unknown: - ps_clear(); - for (int i = 0; i < n; i++) - ps_push(top(i)); - break; - - } - - pop(n); - return true; -} - -bool -CharstringInterp::type1_command(int cmd) -{ - switch (cmd) { - - case Cs::cReturn: - return false; - - case Cs::cHsbw: - CHECK_STACK(2); - if (_state > S_SEAC && _careful) - return error(errOrdering, cmd); - else { - _lsb = _cp = _seac_origin.shifted(at(0), 0); - if (_state == S_INITIAL) { - act_sidebearing(cmd, _lsb); - act_width(cmd, Point(at(1), 0)); - } - if (_state <= S_SEAC) - _state = S_SBW; - } - break; - - case Cs::cSbw: - CHECK_STACK(4); - if (_state > S_SEAC && _careful) - return error(errOrdering, cmd); - else { - _lsb = _cp = _seac_origin.shifted(at(0), at(1)); - if (_state == S_INITIAL) { - act_sidebearing(cmd, _lsb); - act_width(cmd, Point(at(2), at(3))); - } - if (_state <= S_SEAC) - _state = S_SBW; - } - break; - - case Cs::cSeac: - CHECK_STACK(5); - if (_state > S_SBW) - return error(errOrdering, cmd); - act_seac(cmd, at(0), at(1), at(2), (int)at(3), (int)at(4)); - clear(); - return false; - - case Cs::cCallsubr: - return callsubr_command(); - - case Cs::cCallothersubr: { - CHECK_STACK(2); - int othersubrnum = (int)top(0); - int n = (int)top(1); - pop(2); - if (othersubrnum < 0 || size() < n) - return error(errOthersubr, cmd); - return callothersubr_command(othersubrnum, n); - } - - case Cs::cPut: - case Cs::cGet: - case Cs::cStore: - case Cs::cLoad: - return vector_command(cmd); - - case Cs::cBlend: - case Cs::cAbs: - case Cs::cAdd: - case Cs::cSub: - case Cs::cDiv: - case Cs::cNeg: - case Cs::cRandom: - case Cs::cMul: - case Cs::cSqrt: - case Cs::cDrop: - case Cs::cExch: - case Cs::cIndex: - case Cs::cRoll: - case Cs::cDup: - case Cs::cAnd: - case Cs::cOr: - case Cs::cNot: - case Cs::cEq: - case Cs::cIfelse: - case Cs::cPop: - return arith_command(cmd); - - case Cs::cHlineto: - CHECK_STACK(1); - CHECK_PATH_START(); - actp_rlineto(cmd, at(0), 0); - break; - - case Cs::cHmoveto: - CHECK_STACK(1); - CHECK_PATH_END(); - actp_rmoveto(cmd, at(0), 0); - break; - - case Cs::cHvcurveto: - CHECK_STACK(4); - CHECK_PATH_START(); - actp_rrcurveto(cmd, at(0), 0, at(1), at(2), 0, at(3)); - break; - - case Cs::cRlineto: - CHECK_STACK(2); - CHECK_PATH_START(); - actp_rlineto(cmd, at(0), at(1)); - break; - - case Cs::cRmoveto: - CHECK_STACK(2); - CHECK_PATH_END(); - actp_rmoveto(cmd, at(0), at(1)); - break; - - case Cs::cRrcurveto: - CHECK_STACK(6); - CHECK_PATH_START(); - actp_rrcurveto(cmd, at(0), at(1), at(2), at(3), at(4), at(5)); - break; - - case Cs::cVhcurveto: - CHECK_STACK(4); - CHECK_PATH_START(); - actp_rrcurveto(cmd, 0, at(0), at(1), at(2), at(3), 0); - break; - - case Cs::cVlineto: - CHECK_STACK(1); - CHECK_PATH_START(); - actp_rlineto(cmd, 0, at(0)); - break; - - case Cs::cVmoveto: - CHECK_STACK(1); - CHECK_PATH_END(); - actp_rmoveto(cmd, 0, at(0)); - break; - - case Cs::cDotsection: - break; - - case Cs::cHstem: - CHECK_STACK(2); - act_hstem(cmd, _lsb.y + at(0), at(1)); - break; - - case Cs::cHstem3: - CHECK_STACK(6); - act_hstem3(cmd, _lsb.y + at(0), at(1), _lsb.y + at(2), at(3), _lsb.y + at(4), at(5)); - break; - - case Cs::cVstem: - CHECK_STACK(2); - act_vstem(cmd, _lsb.x + at(0), at(1)); - break; - - case Cs::cVstem3: - CHECK_STACK(6); - act_vstem3(cmd, _lsb.x + at(0), at(1), _lsb.x + at(2), at(3), _lsb.x + at(4), at(5)); - break; - - case Cs::cSetcurrentpoint: - CHECK_STACK(2); - _cp = Point(at(0), at(1)); - break; - - case Cs::cClosepath: - CHECK_PATH_END(); - break; - - case Cs::cEndchar: - CHECK_PATH_END(); - set_done(); - return false; - - case Cs::cError: - default: - return error(errUnimplemented, cmd); - - } - - clear(); - return error() >= 0; -} - - -#undef DEBUG_TYPE2 - -int -CharstringInterp::type2_handle_width(int cmd, bool have_width) -{ - _cp = _lsb = _seac_origin; - if (_state != S_INITIAL) - /* ignore width */; - else if (have_width) - act_nominal_width_delta(cmd, at(0)); - else - act_default_width(cmd); - return (have_width ? 1 : 0); -} - -bool -CharstringInterp::type2_command(int cmd, const uint8_t *data, int *left) -{ - int bottom = 0; - -#ifdef DEBUG_TYPE2 - fprintf(stderr, "%s [%d/%d]\n", Charstring::command_name(cmd).c_str(), _t2nhints, size()); -#endif - - switch (cmd) { - - case Cs::cHstem: - case Cs::cHstemhm: - CHECK_STACK(2); - if (_state <= S_SEAC) - bottom = type2_handle_width(cmd, (size() % 2) == 1); - if (_state > S_HSTEM) - return error(errOrdering, cmd); - _state = S_HSTEM; - for (double pos = 0; bottom + 1 < size(); bottom += 2) { - _t2nhints++; - act_hstem(cmd, pos + at(bottom), at(bottom + 1)); - pos += at(bottom) + at(bottom + 1); - } - break; - - case Cs::cVstem: - case Cs::cVstemhm: - CHECK_STACK(2); - if (_state <= S_SEAC) - bottom = type2_handle_width(cmd, (size() % 2) == 1); - if (_state > S_VSTEM) - return error(errOrdering, cmd); - _state = S_VSTEM; - for (double pos = 0; bottom + 1 < size(); bottom += 2) { - _t2nhints++; - act_vstem(cmd, pos + at(bottom), at(bottom + 1)); - pos += at(bottom) + at(bottom + 1); - } - break; - - case Cs::cHintmask: - case Cs::cCntrmask: - if (_state <= S_SEAC && size() >= 1) { - bottom = type2_handle_width(cmd, (size() % 2) == 1); - for (double pos = 0; bottom + 1 < size(); bottom += 2) { - _t2nhints++; - act_hstem(cmd, pos + at(bottom), at(bottom + 1)); - pos += at(bottom) + at(bottom + 1); - } - } - if ((_state == S_HSTEM || _state == S_VSTEM) && size() >= 2) - for (double pos = 0; bottom + 1 < size(); bottom += 2) { - _t2nhints++; - act_vstem(cmd, pos + at(bottom), at(bottom + 1)); - pos += at(bottom) + at(bottom + 1); - } - if (_state < S_HINTMASK) - _state = S_HINTMASK; - if (_t2nhints == 0) - return error(errHintmask, cmd); - if (!data || !left) - return error(errInternal, cmd); - if (((_t2nhints - 1) >> 3) + 1 > *left) - return error(errRunoff, cmd); - act_hintmask(cmd, data, _t2nhints); - *left -= ((_t2nhints - 1) >> 3) + 1; - break; - - case Cs::cRmoveto: - CHECK_STACK(2); - if (_state <= S_SEAC) - bottom = type2_handle_width(cmd, size() > 2); - CHECK_PATH_END(); - actp_rmoveto(cmd, at(bottom), at(bottom + 1)); -#if DEBUG_TYPE2 - bottom += 2; -#endif - break; - - case Cs::cHmoveto: - CHECK_STACK(1); - if (_state <= S_SEAC) - bottom = type2_handle_width(cmd, size() > 1); - CHECK_PATH_END(); - actp_rmoveto(cmd, at(bottom), 0); -#if DEBUG_TYPE2 - bottom++; -#endif - break; - - case Cs::cVmoveto: - CHECK_STACK(1); - if (_state <= S_SEAC) - bottom = type2_handle_width(cmd, size() > 1); - CHECK_PATH_END(); - actp_rmoveto(cmd, 0, at(bottom)); -#if DEBUG_TYPE2 - bottom++; -#endif - break; - - case Cs::cRlineto: - CHECK_STACK(2); - CHECK_STATE(); - CHECK_PATH_START(); - for (; bottom + 1 < size(); bottom += 2) - actp_rlineto(cmd, at(bottom), at(bottom + 1)); - break; - - case Cs::cHlineto: - CHECK_STACK(1); - CHECK_STATE(); - CHECK_PATH_START(); - while (bottom < size()) { - actp_rlineto(cmd, at(bottom++), 0); - if (bottom < size()) - actp_rlineto(cmd, 0, at(bottom++)); - } - break; - - case Cs::cVlineto: - CHECK_STACK(1); - CHECK_STATE(); - CHECK_PATH_START(); - while (bottom < size()) { - actp_rlineto(cmd, 0, at(bottom++)); - if (bottom < size()) - actp_rlineto(cmd, at(bottom++), 0); - } - break; - - case Cs::cRrcurveto: - CHECK_STACK(6); - CHECK_STATE(); - CHECK_PATH_START(); - for (; bottom + 5 < size(); bottom += 6) - actp_rrcurveto(cmd, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), at(bottom + 4), at(bottom + 5)); - break; - - case Cs::cHhcurveto: - CHECK_STACK(4); - CHECK_STATE(); - CHECK_PATH_START(); - if (size() % 2 == 1) { - actp_rrcurveto(cmd, at(bottom + 1), at(bottom), at(bottom + 2), at(bottom + 3), at(bottom + 4), 0); - bottom += 5; - } - for (; bottom + 3 < size(); bottom += 4) - actp_rrcurveto(cmd, at(bottom), 0, at(bottom + 1), at(bottom + 2), at(bottom + 3), 0); - break; - - case Cs::cHvcurveto: - CHECK_STACK(4); - CHECK_STATE(); - CHECK_PATH_START(); - while (bottom + 3 < size()) { - double dx3 = (bottom + 5 == size() ? at(bottom + 4) : 0); - actp_rrcurveto(cmd, at(bottom), 0, at(bottom + 1), at(bottom + 2), dx3, at(bottom + 3)); - bottom += 4; - if (bottom + 3 < size()) { - double dy3 = (bottom + 5 == size() ? at(bottom + 4) : 0); - actp_rrcurveto(cmd, 0, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), dy3); - bottom += 4; - } - } -#if DEBUG_TYPE2 - if (bottom + 1 == size()) - bottom++; -#endif - break; - - case Cs::cRcurveline: - CHECK_STACK(8); - CHECK_STATE(); - CHECK_PATH_START(); - for (; bottom + 7 < size(); bottom += 6) - actp_rrcurveto(cmd, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), at(bottom + 4), at(bottom + 5)); - actp_rlineto(cmd, at(bottom), at(bottom + 1)); -#if DEBUG_TYPE2 - bottom += 2; -#endif - break; - - case Cs::cRlinecurve: - CHECK_STACK(8); - CHECK_STATE(); - CHECK_PATH_START(); - for (; bottom + 7 < size(); bottom += 2) - actp_rlineto(cmd, at(bottom), at(bottom + 1)); - actp_rrcurveto(cmd, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), at(bottom + 4), at(bottom + 5)); -#if DEBUG_TYPE2 - bottom += 6; -#endif - break; - - case Cs::cVhcurveto: - CHECK_STACK(4); - CHECK_STATE(); - CHECK_PATH_START(); - while (bottom + 3 < size()) { - double dy3 = (bottom + 5 == size() ? at(bottom + 4) : 0); - actp_rrcurveto(cmd, 0, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), dy3); - bottom += 4; - if (bottom + 3 < size()) { - double dx3 = (bottom + 5 == size() ? at(bottom + 4) : 0); - actp_rrcurveto(cmd, at(bottom), 0, at(bottom + 1), at(bottom + 2), dx3, at(bottom + 3)); - bottom += 4; - } - } -#if DEBUG_TYPE2 - if (bottom + 1 == size()) - bottom++; -#endif - break; - - case Cs::cVvcurveto: - CHECK_STACK(4); - CHECK_STATE(); - CHECK_PATH_START(); - if (size() % 2 == 1) { - actp_rrcurveto(cmd, at(bottom), at(bottom + 1), at(bottom + 2), at(bottom + 3), 0, at(bottom + 4)); - bottom += 5; - } - for (; bottom + 3 < size(); bottom += 4) - actp_rrcurveto(cmd, 0, at(bottom), at(bottom + 1), at(bottom + 2), 0, at(bottom + 3)); - break; - - case Cs::cFlex: - CHECK_STACK(13); - CHECK_STATE(); - CHECK_PATH_START(); - assert(bottom == 0); - actp_rrflex(cmd, - at(0), at(1), at(2), at(3), at(4), at(5), - at(6), at(7), at(8), at(9), at(10), at(11), - at(12)); -#if DEBUG_TYPE2 - bottom += 13; -#endif - break; - - case Cs::cHflex: - CHECK_STACK(7); - CHECK_STATE(); - CHECK_PATH_START(); - assert(bottom == 0); - actp_rrflex(cmd, - at(0), 0, at(1), at(2), at(3), 0, - at(4), 0, at(5), -at(2), at(6), 0, - 50); -#if DEBUG_TYPE2 - bottom += 7; -#endif - break; - - case Cs::cHflex1: - CHECK_STACK(9); - CHECK_STATE(); - CHECK_PATH_START(); - assert(bottom == 0); - actp_rrflex(cmd, - at(0), at(1), at(2), at(3), at(4), 0, - at(5), 0, at(6), at(7), at(8), -(at(1) + at(3) + at(7)), - 50); -#if DEBUG_TYPE2 - bottom += 9; -#endif - break; - - case Cs::cFlex1: { - CHECK_STACK(11); - CHECK_STATE(); - CHECK_PATH_START(); - assert(bottom == 0); - double dx = at(0) + at(2) + at(4) + at(6) + at(8); - double dy = at(1) + at(3) + at(5) + at(7) + at(9); - if (fabs(dx) > fabs(dy)) - actp_rrflex(cmd, - at(0), at(1), at(2), at(3), at(4), at(5), - at(6), at(7), at(8), at(9), at(10), -dy, - 50); - else - actp_rrflex(cmd, - at(0), at(1), at(2), at(3), at(4), at(5), - at(6), at(7), at(8), at(9), -dx, at(10), - 50); - break; -#if DEBUG_TYPE2 - bottom += 11; -#endif - } - - case Cs::cEndchar: - if (_state <= S_SEAC) - bottom = type2_handle_width(cmd, size() > 0 && size() != 4); - if (bottom + 3 < size() && _state == S_INITIAL) - act_seac(cmd, 0, at(bottom), at(bottom + 1), (int)at(bottom + 2), (int)at(bottom + 3)); - CHECK_PATH_END(); - set_done(); - clear(); - return false; - - case Cs::cReturn: - return false; - - case Cs::cCallsubr: - return callsubr_command(); - - case Cs::cCallgsubr: - return callgsubr_command(); - - case Cs::cPut: - case Cs::cGet: - case Cs::cStore: - case Cs::cLoad: - return vector_command(cmd); - - case Cs::cBlend: - case Cs::cAbs: - case Cs::cAdd: - case Cs::cSub: - case Cs::cDiv: - case Cs::cNeg: - case Cs::cRandom: - case Cs::cMul: - case Cs::cSqrt: - case Cs::cDrop: - case Cs::cExch: - case Cs::cIndex: - case Cs::cRoll: - case Cs::cDup: - case Cs::cAnd: - case Cs::cOr: - case Cs::cNot: - case Cs::cEq: - case Cs::cIfelse: - case Cs::cPop: - return arith_command(cmd); - - case Cs::cDotsection: - break; - - case Cs::cError: - default: - return error(errUnimplemented, cmd); - - } - -#if DEBUG_TYPE2 - if (bottom != size()) - fprintf(stderr, "[left %d on stack] ", size() - bottom); -#endif - - clear(); - return error() >= 0; -} - - -void -CharstringInterp::act_sidebearing(int, const Point &) -{ - /* do nothing */ -} - -void -CharstringInterp::act_width(int, const Point &) -{ - /* do nothing */ -} - -void -CharstringInterp::act_default_width(int cmd) -{ - double d = (_program ? _program->global_width_x(false) : UNKDOUBLE); - if (KNOWN(d)) - act_width(cmd, Point(d, 0)); -} - -void -CharstringInterp::act_nominal_width_delta(int cmd, double delta) -{ - double d = (_program ? _program->global_width_x(true) : UNKDOUBLE); - if (KNOWN(d)) - act_width(cmd, Point(d + delta, 0)); -} - -void -CharstringInterp::act_seac(int cmd, double asb, double adx, double ady, int bchar, int achar) -{ - Charstring *acs = 0, *bcs = 0; - if (achar < 0 || achar >= 256 || bchar < 0 || bchar >= 256 - || !_program || _program->parent_program() - || !(acs = get_glyph(Charstring::standard_encoding[achar])) - || !(bcs = get_glyph(Charstring::standard_encoding[bchar]))) { - error(errGlyph, cmd); - return; - } - - Point apos = Point(adx + _lsb.x - asb, ady + _lsb.y); - Point save_lsb = _lsb; - Point save_seac_origin = _seac_origin; - - CharstringInterp::initialize(); - _seac_origin = apos; - _state = S_SEAC; - acs->process(*this); - if (error() == errOK) { - CharstringInterp::initialize(); - _seac_origin = save_seac_origin; - _state = S_SEAC; - bcs->process(*this); - } - - _lsb = save_lsb; -} - -void -CharstringInterp::act_line(int cmd, const Point &p0, const Point &p1) -{ - act_curve(cmd, p0, p0, p1, p1); -} - -void -CharstringInterp::act_curve(int cmd, const Point &, const Point &, const Point &, const Point &) -{ - error(errUnimplemented, cmd); -} - -void -CharstringInterp::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) -{ - (void) flex_depth; - act_curve(cmd, p0, p1, p2, p3_4); - act_curve(cmd, p3_4, p5, p6, p7); -} - -void -CharstringInterp::act_closepath(int) -{ - /* do nothing */ -} - -void -CharstringInterp::act_hstem(int, double, double) -{ - /* do nothing */ -} - -void -CharstringInterp::act_vstem(int, double, double) -{ - /* do nothing */ -} - -void -CharstringInterp::act_hstem3(int cmd, double y0, double dy0, double y1, double dy1, double y2, double dy2) -{ - act_hstem(cmd, y0, dy0); - act_hstem(cmd, y1, dy1); - act_hstem(cmd, y2, dy2); -} - -void -CharstringInterp::act_vstem3(int cmd, double x0, double dx0, double x1, double dx1, double x2, double dx2) -{ - act_vstem(cmd, x0, dx0); - act_vstem(cmd, x1, dx1); - act_vstem(cmd, x2, dx2); -} - -void -CharstringInterp::act_hintmask(int, const uint8_t *, int) -{ - /* do nothing */ -} - -} |