drop hints from CFF1 charstrings
renamed confusing Stack.size to Stack.count
This commit is contained in:
parent
8c5e03b541
commit
968168bf0e
@ -379,40 +379,40 @@ inline float parse_bcd (SubByteStr& substr, float& v)
|
|||||||
template <typename ELEM, int LIMIT>
|
template <typename ELEM, int LIMIT>
|
||||||
struct Stack
|
struct Stack
|
||||||
{
|
{
|
||||||
inline void init (void) { size = 0; }
|
inline void init (void) { count = 0; }
|
||||||
inline void fini (void) { }
|
inline void fini (void) { }
|
||||||
|
|
||||||
inline void push (const ELEM &v)
|
inline void push (const ELEM &v)
|
||||||
{
|
{
|
||||||
if (likely (size < kSizeLimit))
|
if (likely (count < kSizeLimit))
|
||||||
elements[size++] = v;
|
elements[count++] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const ELEM& pop (void)
|
inline const ELEM& pop (void)
|
||||||
{
|
{
|
||||||
if (likely (size > 0))
|
if (likely (count > 0))
|
||||||
return elements[--size];
|
return elements[--count];
|
||||||
else
|
else
|
||||||
return Null(ELEM);
|
return Null(ELEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void unpop (void)
|
inline void unpop (void)
|
||||||
{
|
{
|
||||||
if (likely (size < kSizeLimit))
|
if (likely (count < kSizeLimit))
|
||||||
size++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clear (void) { size = 0; }
|
inline void clear (void) { count = 0; }
|
||||||
|
|
||||||
inline bool check_overflow (unsigned int count=1) const { return (count <= kSizeLimit) && (count + size <= kSizeLimit); }
|
inline bool check_overflow (unsigned int n=1) const { return (n <= kSizeLimit) && (n + count <= kSizeLimit); }
|
||||||
inline bool check_underflow (unsigned int count=1) const { return (count <= size); }
|
inline bool check_underflow (unsigned int n=1) const { return (n <= count); }
|
||||||
|
|
||||||
inline unsigned int get_size (void) const { return size; }
|
inline unsigned int get_count (void) const { return count; }
|
||||||
inline bool is_empty (void) const { return size == 0; }
|
inline bool is_empty (void) const { return count == 0; }
|
||||||
|
|
||||||
static const unsigned int kSizeLimit = LIMIT;
|
static const unsigned int kSizeLimit = LIMIT;
|
||||||
|
|
||||||
unsigned int size;
|
unsigned int count;
|
||||||
ELEM elements[kSizeLimit];
|
ELEM elements[kSizeLimit];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -469,11 +469,11 @@ struct ArgStack : Stack<Number, 513>
|
|||||||
|
|
||||||
inline bool check_pop_delta (hb_vector_t<Number>& vec, bool even=false)
|
inline bool check_pop_delta (hb_vector_t<Number>& vec, bool even=false)
|
||||||
{
|
{
|
||||||
if (even && unlikely ((this->size & 1) != 0))
|
if (even && unlikely ((this->count & 1) != 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
float val = 0.0f;
|
float val = 0.0f;
|
||||||
for (unsigned int i = 0; i < size; i++) {
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
val += elements[i].to_real ();
|
val += elements[i].to_real ();
|
||||||
Number *n = vec.push ();
|
Number *n = vec.push ();
|
||||||
n->set_real (val);
|
n->set_real (val);
|
||||||
@ -564,6 +564,17 @@ struct InterpEnv
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void pop_n_args (unsigned int n)
|
||||||
|
{
|
||||||
|
assert (n <= argStack.count);
|
||||||
|
argStack.count -= n;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void clear_args (void)
|
||||||
|
{
|
||||||
|
pop_n_args (argStack.count);
|
||||||
|
}
|
||||||
|
|
||||||
SubByteStr substr;
|
SubByteStr substr;
|
||||||
ArgStack argStack;
|
ArgStack argStack;
|
||||||
};
|
};
|
||||||
@ -604,7 +615,7 @@ struct OpSet
|
|||||||
env.argStack.push_int ((int)op - 139);
|
env.argStack.push_int ((int)op - 139);
|
||||||
} else {
|
} else {
|
||||||
/* invalid unknown operator */
|
/* invalid unknown operator */
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -64,7 +64,6 @@ struct CSInterpEnv : InterpEnv
|
|||||||
{
|
{
|
||||||
InterpEnv::init (str);
|
InterpEnv::init (str);
|
||||||
|
|
||||||
stack_cleared = false;
|
|
||||||
seen_moveto = true;
|
seen_moveto = true;
|
||||||
seen_hintmask = false;
|
seen_hintmask = false;
|
||||||
hstem_count = 0;
|
hstem_count = 0;
|
||||||
@ -121,25 +120,17 @@ struct CSInterpEnv : InterpEnv
|
|||||||
{
|
{
|
||||||
if (!seen_hintmask)
|
if (!seen_hintmask)
|
||||||
{
|
{
|
||||||
vstem_count += argStack.size / 2;
|
vstem_count += argStack.get_count() / 2;
|
||||||
hintmask_size = (hstem_count + vstem_count + 7) >> 3;
|
hintmask_size = (hstem_count + vstem_count + 7) >> 3;
|
||||||
seen_hintmask = true;
|
seen_hintmask = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clear_stack (void)
|
|
||||||
{
|
|
||||||
stack_cleared = true;
|
|
||||||
argStack.clear ();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set_endchar (bool endchar_flag_) { endchar_flag = endchar_flag_; }
|
inline void set_endchar (bool endchar_flag_) { endchar_flag = endchar_flag_; }
|
||||||
inline bool is_endchar (void) const { return endchar_flag; }
|
inline bool is_endchar (void) const { return endchar_flag; }
|
||||||
inline bool is_stack_cleared (void) const { return stack_cleared; }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool endchar_flag;
|
bool endchar_flag;
|
||||||
bool stack_cleared;
|
|
||||||
bool seen_moveto;
|
bool seen_moveto;
|
||||||
bool seen_hintmask;
|
bool seen_hintmask;
|
||||||
|
|
||||||
@ -162,7 +153,8 @@ struct CSOpSet : OpSet
|
|||||||
return env.returnFromSubr ();
|
return env.returnFromSubr ();
|
||||||
case OpCode_endchar:
|
case OpCode_endchar:
|
||||||
env.set_endchar (true);
|
env.set_endchar (true);
|
||||||
return true;
|
OPSET::flush_op (op, env, param);
|
||||||
|
break;
|
||||||
|
|
||||||
case OpCode_fixedcs:
|
case OpCode_fixedcs:
|
||||||
return env.argStack.push_fixed_from_substr (env.substr);
|
return env.argStack.push_fixed_from_substr (env.substr);
|
||||||
@ -175,19 +167,15 @@ struct CSOpSet : OpSet
|
|||||||
|
|
||||||
case OpCode_hstem:
|
case OpCode_hstem:
|
||||||
case OpCode_hstemhm:
|
case OpCode_hstemhm:
|
||||||
OPSET::process_hstem (env, param);
|
OPSET::process_hstem (op, env, param);
|
||||||
break;
|
break;
|
||||||
case OpCode_vstem:
|
case OpCode_vstem:
|
||||||
case OpCode_vstemhm:
|
case OpCode_vstemhm:
|
||||||
OPSET::process_vstem (env, param);
|
OPSET::process_vstem (op, env, param);
|
||||||
break;
|
break;
|
||||||
case OpCode_hintmask:
|
case OpCode_hintmask:
|
||||||
case OpCode_cntrmask:
|
case OpCode_cntrmask:
|
||||||
env.determine_hintmask_size ();
|
OPSET::process_hintmask (op, env, param);
|
||||||
OPSET::flush_stack (env, param);
|
|
||||||
if (unlikely (!env.substr.avail (env.hintmask_size)))
|
|
||||||
return false;
|
|
||||||
env.substr.inc (env.hintmask_size);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_vmoveto:
|
case OpCode_vmoveto:
|
||||||
@ -196,7 +184,7 @@ struct CSOpSet : OpSet
|
|||||||
case OpCode_vlineto:
|
case OpCode_vlineto:
|
||||||
case OpCode_rmoveto:
|
case OpCode_rmoveto:
|
||||||
case OpCode_hmoveto:
|
case OpCode_hmoveto:
|
||||||
OPSET::process_moveto (env, param);
|
OPSET::process_moveto (op, env, param);
|
||||||
break;
|
break;
|
||||||
case OpCode_rrcurveto:
|
case OpCode_rrcurveto:
|
||||||
case OpCode_rcurveline:
|
case OpCode_rcurveline:
|
||||||
@ -205,11 +193,14 @@ struct CSOpSet : OpSet
|
|||||||
case OpCode_hhcurveto:
|
case OpCode_hhcurveto:
|
||||||
case OpCode_vhcurveto:
|
case OpCode_vhcurveto:
|
||||||
case OpCode_hvcurveto:
|
case OpCode_hvcurveto:
|
||||||
|
OPSET::process_path (op, env, param);
|
||||||
|
break;
|
||||||
|
|
||||||
case OpCode_hflex:
|
case OpCode_hflex:
|
||||||
case OpCode_flex:
|
case OpCode_flex:
|
||||||
case OpCode_hflex1:
|
case OpCode_hflex1:
|
||||||
case OpCode_flex1:
|
case OpCode_flex1:
|
||||||
OPSET::flush_stack (env, param);
|
OPSET::process_flex (op, env, param);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -218,87 +209,76 @@ struct CSOpSet : OpSet
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void process_hstem (ENV &env, PARAM& param)
|
static inline void process_hstem (OpCode op, ENV &env, PARAM& param)
|
||||||
{
|
{
|
||||||
env.hstem_count += env.argStack.size / 2;
|
env.hstem_count += env.argStack.count / 2;
|
||||||
OPSET::flush_stack (env, param);
|
OPSET::flush_args_and_op (op, env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void process_vstem (ENV &env, PARAM& param)
|
static inline void process_vstem (OpCode op, ENV &env, PARAM& param)
|
||||||
{
|
{
|
||||||
env.vstem_count += env.argStack.size / 2;
|
env.vstem_count += env.argStack.count / 2;
|
||||||
OPSET::flush_stack (env, param);
|
OPSET::flush_args_and_op (op, env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void process_moveto (ENV &env, PARAM& param)
|
static inline void process_hintmask (OpCode op, ENV &env, PARAM& param)
|
||||||
|
{
|
||||||
|
env.determine_hintmask_size ();
|
||||||
|
if (likely (env.substr.avail (env.hintmask_size)))
|
||||||
|
{
|
||||||
|
OPSET::flush_hintmask (op, env, param);
|
||||||
|
env.substr.inc (env.hintmask_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void process_flex (OpCode op, ENV &env, PARAM& param)
|
||||||
|
{
|
||||||
|
OPSET::flush_args_and_op (op, env, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void process_moveto (OpCode op, ENV &env, PARAM& param)
|
||||||
{
|
{
|
||||||
if (!env.seen_moveto)
|
if (!env.seen_moveto)
|
||||||
{
|
{
|
||||||
env.determine_hintmask_size ();
|
env.determine_hintmask_size ();
|
||||||
env.seen_moveto = true;
|
env.seen_moveto = true;
|
||||||
}
|
}
|
||||||
OPSET::flush_stack (env, param);
|
OPSET::flush_args_and_op (op, env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flush_stack (ENV &env, PARAM& param)
|
static inline void process_path (OpCode op, ENV &env, PARAM& param)
|
||||||
{
|
{
|
||||||
env.clear_stack ();
|
OPSET::flush_args_and_op (op, env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* numeric / logical / arithmetic operators */
|
static inline void flush_args_and_op (OpCode op, ENV &env, PARAM& param)
|
||||||
static inline bool is_arg_op (OpCode op)
|
|
||||||
{
|
{
|
||||||
switch (op)
|
OPSET::flush_n_args_and_op (op, env.argStack.count, env, param);
|
||||||
{
|
|
||||||
case OpCode_shortint:
|
|
||||||
case OpCode_TwoBytePosInt0: case OpCode_TwoBytePosInt1:
|
|
||||||
case OpCode_TwoBytePosInt2: case OpCode_TwoBytePosInt3:
|
|
||||||
case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1:
|
|
||||||
case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3:
|
|
||||||
case OpCode_fixedcs:
|
|
||||||
case OpCode_and:
|
|
||||||
case OpCode_or:
|
|
||||||
case OpCode_not:
|
|
||||||
case OpCode_abs:
|
|
||||||
case OpCode_add:
|
|
||||||
case OpCode_sub:
|
|
||||||
case OpCode_div:
|
|
||||||
case OpCode_neg:
|
|
||||||
case OpCode_eq:
|
|
||||||
case OpCode_drop:
|
|
||||||
case OpCode_put:
|
|
||||||
case OpCode_get:
|
|
||||||
case OpCode_ifelse:
|
|
||||||
case OpCode_random:
|
|
||||||
case OpCode_mul:
|
|
||||||
case OpCode_sqrt:
|
|
||||||
case OpCode_dup:
|
|
||||||
case OpCode_exch:
|
|
||||||
case OpCode_index:
|
|
||||||
case OpCode_roll:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return (OpCode_OneByteIntFirst <= op) && (op <= OpCode_OneByteIntLast);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hint operators (excluding hint/counter mask) */
|
static inline void flush_n_args_and_op (OpCode op, unsigned int n, ENV &env, PARAM& param)
|
||||||
static inline bool is_hint_op (OpCode op)
|
|
||||||
{
|
{
|
||||||
switch (op)
|
OPSET::flush_n_args (n, env, param);
|
||||||
{
|
OPSET::flush_op (op, env, param);
|
||||||
case OpCode_hstem:
|
}
|
||||||
case OpCode_vstem:
|
|
||||||
case OpCode_hstemhm:
|
static inline void flush_args (ENV &env, PARAM& param)
|
||||||
case OpCode_vstemhm:
|
{
|
||||||
case OpCode_hflex:
|
OPSET::flush_n_args (env.argStack.count, env, param);
|
||||||
case OpCode_flex:
|
}
|
||||||
case OpCode_hflex1:
|
|
||||||
case OpCode_flex1:
|
static inline void flush_n_args (unsigned int n, ENV &env, PARAM& param)
|
||||||
return true;
|
{
|
||||||
default:
|
env.pop_n_args (n);
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
static inline void flush_op (OpCode op, ENV &env, PARAM& param)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void flush_hintmask (OpCode op, ENV &env, PARAM& param)
|
||||||
|
{
|
||||||
|
OPSET::flush_args_and_op (op, env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_subr_op (OpCode op)
|
static inline bool is_subr_op (OpCode op)
|
||||||
|
@ -169,12 +169,12 @@ struct TopDictOpSet : DictOpSet
|
|||||||
case OpCode_CharStrings:
|
case OpCode_CharStrings:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.charStringsOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.charStringsOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
case OpCode_FDArray:
|
case OpCode_FDArray:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.FDArrayOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.FDArrayOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return DictOpSet::process_op (op, env);
|
return DictOpSet::process_op (op, env);
|
||||||
|
@ -51,7 +51,7 @@ struct CFF1CSInterpEnv : CSInterpEnv<CFF1Subrs>
|
|||||||
{
|
{
|
||||||
if (!processed_width)
|
if (!processed_width)
|
||||||
{
|
{
|
||||||
if ((this->argStack.size & 1) != 0)
|
if ((this->argStack.count & 1) != 0)
|
||||||
{
|
{
|
||||||
width = this->argStack.elements[0];
|
width = this->argStack.elements[0];
|
||||||
has_width = true;
|
has_width = true;
|
||||||
@ -163,8 +163,8 @@ struct CFF1CSOpSet : CSOpSet<OPSET, CFF1CSInterpEnv, PARAM>
|
|||||||
if (unlikely (!env.argStack.check_pop_num (n1))) return false;
|
if (unlikely (!env.argStack.check_pop_num (n1))) return false;
|
||||||
int i = n1.to_int ();
|
int i = n1.to_int ();
|
||||||
if (i < 0) i = 0;
|
if (i < 0) i = 0;
|
||||||
if (unlikely (i >= env.argStack.size || !env.argStack.check_overflow (1))) return false;
|
if (unlikely (i >= env.argStack.count || !env.argStack.check_overflow (1))) return false;
|
||||||
env.argStack.push (env.argStack.elements[env.argStack.size - i - 1]);
|
env.argStack.push (env.argStack.elements[env.argStack.count - i - 1]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OpCode_roll:
|
case OpCode_roll:
|
||||||
@ -172,13 +172,13 @@ struct CFF1CSOpSet : CSOpSet<OPSET, CFF1CSInterpEnv, PARAM>
|
|||||||
if (unlikely (!env.argStack.check_pop_num2 (n1, n2))) return false;
|
if (unlikely (!env.argStack.check_pop_num2 (n1, n2))) return false;
|
||||||
int n = n1.to_int ();
|
int n = n1.to_int ();
|
||||||
int j = n2.to_int ();
|
int j = n2.to_int ();
|
||||||
if (unlikely (n < 0 || n > env.argStack.size)) return false;
|
if (unlikely (n < 0 || n > env.argStack.count)) return false;
|
||||||
if (likely (n > 0))
|
if (likely (n > 0))
|
||||||
{
|
{
|
||||||
if (j < 0)
|
if (j < 0)
|
||||||
j = n - (-j % n);
|
j = n - (-j % n);
|
||||||
j %= n;
|
j %= n;
|
||||||
unsigned int top = env.argStack.size - 1;
|
unsigned int top = env.argStack.count - 1;
|
||||||
unsigned int bot = top - n + 1;
|
unsigned int bot = top - n + 1;
|
||||||
env.argStack.reverse_range (top - j + 1, top);
|
env.argStack.reverse_range (top - j + 1, top);
|
||||||
env.argStack.reverse_range (bot, top - j);
|
env.argStack.reverse_range (bot, top - j);
|
||||||
@ -194,10 +194,10 @@ struct CFF1CSOpSet : CSOpSet<OPSET, CFF1CSInterpEnv, PARAM>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flush_stack (CFF1CSInterpEnv &env, PARAM& param)
|
static inline void flush_args (CFF1CSInterpEnv &env, PARAM& param)
|
||||||
{
|
{
|
||||||
env.check_width ();
|
env.check_width ();
|
||||||
SUPER::flush_stack (env, param);
|
SUPER::flush_args (env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -54,13 +54,11 @@ struct CFF2CSInterpEnv : CSInterpEnv<CFF2Subrs>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool process_vsindex (void)
|
inline void process_vsindex (void)
|
||||||
{
|
{
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
if (unlikely (!argStack.check_pop_uint (index)))
|
if (likely (argStack.check_pop_uint (index)))
|
||||||
return false;
|
set_ivs (argStack.check_pop_uint (index));
|
||||||
set_ivs (index);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int get_ivs (void) const { return ivs; }
|
inline unsigned int get_ivs (void) const { return ivs; }
|
||||||
@ -81,7 +79,8 @@ struct CFF2CSOpSet : CSOpSet<OPSET, CFF2CSInterpEnv, PARAM>
|
|||||||
return OPSET::process_blend (env, param);
|
return OPSET::process_blend (env, param);
|
||||||
|
|
||||||
case OpCode_vsindexcs:
|
case OpCode_vsindexcs:
|
||||||
return OPSET::process_vsindex (env, param);
|
OPSET::process_vsindex (env, param);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
typedef CSOpSet<OPSET, CFF2CSInterpEnv, PARAM> SUPER;
|
typedef CSOpSet<OPSET, CFF2CSInterpEnv, PARAM> SUPER;
|
||||||
@ -95,13 +94,14 @@ struct CFF2CSOpSet : CSOpSet<OPSET, CFF2CSInterpEnv, PARAM>
|
|||||||
static inline bool process_blend (CFF2CSInterpEnv &env, PARAM& param)
|
static inline bool process_blend (CFF2CSInterpEnv &env, PARAM& param)
|
||||||
{
|
{
|
||||||
// XXX: TODO leave default values?
|
// XXX: TODO leave default values?
|
||||||
OPSET::flush_stack (env, param);
|
OPSET::flush_args (env, param);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool process_vsindex (CFF2CSInterpEnv &env, PARAM& param)
|
static inline void process_vsindex (CFF2CSInterpEnv &env, PARAM& param)
|
||||||
{
|
{
|
||||||
return env.process_vsindex ();
|
env.process_vsindex ();
|
||||||
|
OPSET::flush_n_args_and_op (OpCode_vsindexcs, 1, env, param);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -437,13 +437,13 @@ struct CFF1TopDictOpSet : TopDictOpSet
|
|||||||
case OpCode_FontBBox:
|
case OpCode_FontBBox:
|
||||||
case OpCode_XUID:
|
case OpCode_XUID:
|
||||||
case OpCode_BaseFontBlend:
|
case OpCode_BaseFontBlend:
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_CIDCount:
|
case OpCode_CIDCount:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.cidCount)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.cidCount)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_ROS:
|
case OpCode_ROS:
|
||||||
@ -451,25 +451,25 @@ struct CFF1TopDictOpSet : TopDictOpSet
|
|||||||
!env.argStack.check_pop_uint (dictval.ros[1]) ||
|
!env.argStack.check_pop_uint (dictval.ros[1]) ||
|
||||||
!env.argStack.check_pop_uint (dictval.ros[0])))
|
!env.argStack.check_pop_uint (dictval.ros[0])))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_Encoding:
|
case OpCode_Encoding:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.EncodingOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.EncodingOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_charset:
|
case OpCode_charset:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.CharsetOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.CharsetOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_FDSelect:
|
case OpCode_FDSelect:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.FDSelectOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.FDSelectOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_Private:
|
case OpCode_Private:
|
||||||
@ -477,7 +477,7 @@ struct CFF1TopDictOpSet : TopDictOpSet
|
|||||||
return false;
|
return false;
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -517,14 +517,14 @@ struct CFF1FontDictOpSet : DictOpSet
|
|||||||
case OpCode_FontName:
|
case OpCode_FontName:
|
||||||
case OpCode_FontMatrix:
|
case OpCode_FontMatrix:
|
||||||
case OpCode_PaintType:
|
case OpCode_PaintType:
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
case OpCode_Private:
|
case OpCode_Private:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.offset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.offset)))
|
||||||
return false;
|
return false;
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -602,12 +602,12 @@ struct CFF1PrivateDictOpSet : DictOpSet
|
|||||||
case OpCode_nominalWidthX:
|
case OpCode_nominalWidthX:
|
||||||
if (unlikely (!env.argStack.check_pop_num (val.single_val)))
|
if (unlikely (!env.argStack.check_pop_num (val.single_val)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
case OpCode_Subrs:
|
case OpCode_Subrs:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -644,13 +644,13 @@ struct CFF1PrivateDictOpSet_Subset : DictOpSet
|
|||||||
case OpCode_initialRandomSeed:
|
case OpCode_initialRandomSeed:
|
||||||
case OpCode_defaultWidthX:
|
case OpCode_defaultWidthX:
|
||||||
case OpCode_nominalWidthX:
|
case OpCode_nominalWidthX:
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_Subrs:
|
case OpCode_Subrs:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -183,19 +183,19 @@ struct CFF2TopDictOpSet : TopDictOpSet
|
|||||||
DictVal val;
|
DictVal val;
|
||||||
val.init ();
|
val.init ();
|
||||||
dictval.pushVal (op, env.substr);
|
dictval.pushVal (op, env.substr);
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_vstore:
|
case OpCode_vstore:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.vstoreOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.vstoreOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
case OpCode_FDSelect:
|
case OpCode_FDSelect:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.FDSelectOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.FDSelectOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -236,7 +236,7 @@ struct CFF2FontDictOpSet : DictOpSet
|
|||||||
return false;
|
return false;
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -301,7 +301,7 @@ struct CFF2PrivateDictOpSet : DictOpSet
|
|||||||
case OpCode_LanguageGroup:
|
case OpCode_LanguageGroup:
|
||||||
if (unlikely (!env.argStack.check_pop_num (val.single_val)))
|
if (unlikely (!env.argStack.check_pop_num (val.single_val)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
case OpCode_BlueValues:
|
case OpCode_BlueValues:
|
||||||
case OpCode_OtherBlues:
|
case OpCode_OtherBlues:
|
||||||
@ -311,12 +311,12 @@ struct CFF2PrivateDictOpSet : DictOpSet
|
|||||||
case OpCode_StemSnapV:
|
case OpCode_StemSnapV:
|
||||||
if (unlikely (!env.argStack.check_pop_delta (val.multi_val)))
|
if (unlikely (!env.argStack.check_pop_delta (val.multi_val)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
case OpCode_Subrs:
|
case OpCode_Subrs:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
case OpCode_vsindexdict:
|
case OpCode_vsindexdict:
|
||||||
case OpCode_blenddict:
|
case OpCode_blenddict:
|
||||||
@ -353,17 +353,17 @@ struct CFF2PrivateDictOpSet_Subset : DictOpSet
|
|||||||
case OpCode_StemSnapV:
|
case OpCode_StemSnapV:
|
||||||
case OpCode_LanguageGroup:
|
case OpCode_LanguageGroup:
|
||||||
case OpCode_ExpansionFactor:
|
case OpCode_ExpansionFactor:
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCode_blenddict:
|
case OpCode_blenddict:
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OpCode_Subrs:
|
case OpCode_Subrs:
|
||||||
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
||||||
return false;
|
return false;
|
||||||
env.argStack.clear ();
|
env.clear_args ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -106,43 +106,50 @@ struct CFF1TopDict_OpSerializer : CFFTopDict_OpSerializer
|
|||||||
|
|
||||||
struct CFF1CSOpSet_Flatten : CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam>
|
struct CFF1CSOpSet_Flatten : CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam>
|
||||||
{
|
{
|
||||||
static inline bool process_op (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param)
|
static inline void flush_args_and_op (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param)
|
||||||
{
|
{
|
||||||
if (param.drop_hints && CSOPSET::is_hint_op (op))
|
|
||||||
{
|
|
||||||
env.clear_stack ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (unlikely (!SUPER::process_op (op, env, param)))
|
|
||||||
return false;
|
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
|
case OpCode_hstem:
|
||||||
|
case OpCode_hstemhm:
|
||||||
|
case OpCode_vstem:
|
||||||
|
case OpCode_vstemhm:
|
||||||
case OpCode_hintmask:
|
case OpCode_hintmask:
|
||||||
case OpCode_cntrmask:
|
case OpCode_cntrmask:
|
||||||
|
case OpCode_hflex:
|
||||||
|
case OpCode_flex:
|
||||||
|
case OpCode_hflex1:
|
||||||
|
case OpCode_flex1:
|
||||||
if (param.drop_hints)
|
if (param.drop_hints)
|
||||||
{
|
{
|
||||||
env.clear_stack ();
|
env.clear_args ();
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
if (unlikely (!param.flatStr.encode_op (op)))
|
/* NO BREAK */
|
||||||
return false;
|
|
||||||
for (int i = -env.hintmask_size; i < 0; i++)
|
|
||||||
if (unlikely (!param.flatStr.encode_byte (env.substr[i])))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
if (!CSOPSET::is_subr_op (op) &&
|
SUPER::flush_args_and_op (op, env, param);
|
||||||
!CSOPSET::is_arg_op (op))
|
break;
|
||||||
return param.flatStr.encode_op (op);
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void flush_stack (CFF1CSInterpEnv &env, FlattenParam& param)
|
static inline void flush_n_args (unsigned int n, CFF1CSInterpEnv &env, FlattenParam& param)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < env.argStack.size; i++)
|
for (unsigned int i = env.argStack.count - n; i < env.argStack.count; i++)
|
||||||
param.flatStr.encode_num (env.argStack.elements[i]);
|
param.flatStr.encode_num (env.argStack.elements[i]);
|
||||||
SUPER::flush_stack (env, param);
|
SUPER::flush_n_args (n, env, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void flush_op (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param)
|
||||||
|
{
|
||||||
|
param.flatStr.encode_op (op);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void flush_hintmask (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param)
|
||||||
|
{
|
||||||
|
SUPER::flush_hintmask (op, env, param);
|
||||||
|
for (unsigned int i = 0; i < env.hintmask_size; i++)
|
||||||
|
param.flatStr.encode_byte (env.substr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -77,59 +77,54 @@ struct CFF2TopDict_OpSerializer : CFFTopDict_OpSerializer
|
|||||||
|
|
||||||
struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam>
|
struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam>
|
||||||
{
|
{
|
||||||
static inline bool process_op (OpCode op, CFF2CSInterpEnv &env, FlattenParam& param)
|
static inline bool process_blend (CFF2CSInterpEnv &env, FlattenParam& param)
|
||||||
|
{
|
||||||
|
flush_args (env, param);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void flush_args_and_op (OpCode op, CFF2CSInterpEnv &env, FlattenParam& param)
|
||||||
{
|
{
|
||||||
if (param.drop_hints && CSOPSET::is_hint_op (op))
|
|
||||||
{
|
|
||||||
env.clear_stack ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (unlikely (!SUPER::process_op (op, env, param)))
|
|
||||||
return false;
|
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case OpCode_hintmask:
|
|
||||||
case OpCode_cntrmask:
|
|
||||||
if (param.drop_hints)
|
|
||||||
{
|
|
||||||
env.clear_stack ();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (unlikely (!param.flatStr.encode_op (op)))
|
|
||||||
return false;
|
|
||||||
for (int i = -env.hintmask_size; i < 0; i++)
|
|
||||||
if (unlikely (!param.flatStr.encode_byte (env.substr[i])))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case OpCode_return:
|
case OpCode_return:
|
||||||
case OpCode_endchar:
|
case OpCode_endchar:
|
||||||
/* dummy opcodes in CFF2. ignore */
|
/* dummy opcodes in CFF2. ignore */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OpCode_hstem:
|
||||||
|
case OpCode_hstemhm:
|
||||||
|
case OpCode_vstem:
|
||||||
|
case OpCode_vstemhm:
|
||||||
|
case OpCode_hintmask:
|
||||||
|
case OpCode_cntrmask:
|
||||||
|
case OpCode_hflex:
|
||||||
|
case OpCode_flex:
|
||||||
|
case OpCode_hflex1:
|
||||||
|
case OpCode_flex1:
|
||||||
|
if (param.drop_hints)
|
||||||
|
{
|
||||||
|
env.clear_args ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* NO BREAK */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!CSOPSET::is_subr_op (op) &&
|
SUPER::flush_args_and_op (op, env, param);
|
||||||
!CSOPSET::is_arg_op (op))
|
break;
|
||||||
return param.flatStr.encode_op (op);
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool process_blend (CFF2CSInterpEnv &env, FlattenParam& param)
|
static inline void flush_n_args (unsigned int n, CFF2CSInterpEnv &env, FlattenParam& param)
|
||||||
{
|
{
|
||||||
flush_stack (env, param);
|
for (unsigned int i = env.argStack.count - n; i < env.argStack.count; i++)
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool process_vsindex (CFF2CSInterpEnv &env, FlattenParam& param)
|
|
||||||
{
|
|
||||||
flush_stack (env, param);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void flush_stack (CFF2CSInterpEnv &env, FlattenParam& param)
|
|
||||||
{
|
|
||||||
for (unsigned int i = 0; i < env.argStack.size; i++)
|
|
||||||
param.flatStr.encode_num (env.argStack.elements[i]);
|
param.flatStr.encode_num (env.argStack.elements[i]);
|
||||||
SUPER::flush_stack (env, param);
|
SUPER::flush_n_args (n, env, param);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void flush_op (OpCode op, CFF2CSInterpEnv &env, FlattenParam& param)
|
||||||
|
{
|
||||||
|
param.flatStr.encode_op (op);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user