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>
|
||||
struct Stack
|
||||
{
|
||||
inline void init (void) { size = 0; }
|
||||
inline void init (void) { count = 0; }
|
||||
inline void fini (void) { }
|
||||
|
||||
inline void push (const ELEM &v)
|
||||
{
|
||||
if (likely (size < kSizeLimit))
|
||||
elements[size++] = v;
|
||||
if (likely (count < kSizeLimit))
|
||||
elements[count++] = v;
|
||||
}
|
||||
|
||||
inline const ELEM& pop (void)
|
||||
{
|
||||
if (likely (size > 0))
|
||||
return elements[--size];
|
||||
if (likely (count > 0))
|
||||
return elements[--count];
|
||||
else
|
||||
return Null(ELEM);
|
||||
}
|
||||
|
||||
inline void unpop (void)
|
||||
{
|
||||
if (likely (size < kSizeLimit))
|
||||
size++;
|
||||
if (likely (count < kSizeLimit))
|
||||
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_underflow (unsigned int count=1) const { return (count <= size); }
|
||||
inline bool check_overflow (unsigned int n=1) const { return (n <= kSizeLimit) && (n + count <= kSizeLimit); }
|
||||
inline bool check_underflow (unsigned int n=1) const { return (n <= count); }
|
||||
|
||||
inline unsigned int get_size (void) const { return size; }
|
||||
inline bool is_empty (void) const { return size == 0; }
|
||||
inline unsigned int get_count (void) const { return count; }
|
||||
inline bool is_empty (void) const { return count == 0; }
|
||||
|
||||
static const unsigned int kSizeLimit = LIMIT;
|
||||
|
||||
unsigned int size;
|
||||
unsigned int count;
|
||||
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)
|
||||
{
|
||||
if (even && unlikely ((this->size & 1) != 0))
|
||||
if (even && unlikely ((this->count & 1) != 0))
|
||||
return false;
|
||||
|
||||
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 ();
|
||||
Number *n = vec.push ();
|
||||
n->set_real (val);
|
||||
@ -564,6 +564,17 @@ struct InterpEnv
|
||||
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;
|
||||
ArgStack argStack;
|
||||
};
|
||||
@ -604,7 +615,7 @@ struct OpSet
|
||||
env.argStack.push_int ((int)op - 139);
|
||||
} else {
|
||||
/* invalid unknown operator */
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -64,7 +64,6 @@ struct CSInterpEnv : InterpEnv
|
||||
{
|
||||
InterpEnv::init (str);
|
||||
|
||||
stack_cleared = false;
|
||||
seen_moveto = true;
|
||||
seen_hintmask = false;
|
||||
hstem_count = 0;
|
||||
@ -121,25 +120,17 @@ struct CSInterpEnv : InterpEnv
|
||||
{
|
||||
if (!seen_hintmask)
|
||||
{
|
||||
vstem_count += argStack.size / 2;
|
||||
vstem_count += argStack.get_count() / 2;
|
||||
hintmask_size = (hstem_count + vstem_count + 7) >> 3;
|
||||
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 bool is_endchar (void) const { return endchar_flag; }
|
||||
inline bool is_stack_cleared (void) const { return stack_cleared; }
|
||||
|
||||
public:
|
||||
bool endchar_flag;
|
||||
bool stack_cleared;
|
||||
bool seen_moveto;
|
||||
bool seen_hintmask;
|
||||
|
||||
@ -162,7 +153,8 @@ struct CSOpSet : OpSet
|
||||
return env.returnFromSubr ();
|
||||
case OpCode_endchar:
|
||||
env.set_endchar (true);
|
||||
return true;
|
||||
OPSET::flush_op (op, env, param);
|
||||
break;
|
||||
|
||||
case OpCode_fixedcs:
|
||||
return env.argStack.push_fixed_from_substr (env.substr);
|
||||
@ -175,19 +167,15 @@ struct CSOpSet : OpSet
|
||||
|
||||
case OpCode_hstem:
|
||||
case OpCode_hstemhm:
|
||||
OPSET::process_hstem (env, param);
|
||||
OPSET::process_hstem (op, env, param);
|
||||
break;
|
||||
case OpCode_vstem:
|
||||
case OpCode_vstemhm:
|
||||
OPSET::process_vstem (env, param);
|
||||
OPSET::process_vstem (op, env, param);
|
||||
break;
|
||||
case OpCode_hintmask:
|
||||
case OpCode_cntrmask:
|
||||
env.determine_hintmask_size ();
|
||||
OPSET::flush_stack (env, param);
|
||||
if (unlikely (!env.substr.avail (env.hintmask_size)))
|
||||
return false;
|
||||
env.substr.inc (env.hintmask_size);
|
||||
OPSET::process_hintmask (op, env, param);
|
||||
break;
|
||||
|
||||
case OpCode_vmoveto:
|
||||
@ -196,7 +184,7 @@ struct CSOpSet : OpSet
|
||||
case OpCode_vlineto:
|
||||
case OpCode_rmoveto:
|
||||
case OpCode_hmoveto:
|
||||
OPSET::process_moveto (env, param);
|
||||
OPSET::process_moveto (op, env, param);
|
||||
break;
|
||||
case OpCode_rrcurveto:
|
||||
case OpCode_rcurveline:
|
||||
@ -205,11 +193,14 @@ struct CSOpSet : OpSet
|
||||
case OpCode_hhcurveto:
|
||||
case OpCode_vhcurveto:
|
||||
case OpCode_hvcurveto:
|
||||
OPSET::process_path (op, env, param);
|
||||
break;
|
||||
|
||||
case OpCode_hflex:
|
||||
case OpCode_flex:
|
||||
case OpCode_hflex1:
|
||||
case OpCode_flex1:
|
||||
OPSET::flush_stack (env, param);
|
||||
OPSET::process_flex (op, env, param);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -218,87 +209,76 @@ struct CSOpSet : OpSet
|
||||
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;
|
||||
OPSET::flush_stack (env, param);
|
||||
env.hstem_count += env.argStack.count / 2;
|
||||
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;
|
||||
OPSET::flush_stack (env, param);
|
||||
env.vstem_count += env.argStack.count / 2;
|
||||
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)
|
||||
{
|
||||
env.determine_hintmask_size ();
|
||||
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 bool is_arg_op (OpCode op)
|
||||
static inline void flush_args_and_op (OpCode op, ENV &env, PARAM& param)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
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);
|
||||
}
|
||||
OPSET::flush_n_args_and_op (op, env.argStack.count, env, param);
|
||||
}
|
||||
|
||||
/* hint operators (excluding hint/counter mask) */
|
||||
static inline bool is_hint_op (OpCode op)
|
||||
static inline void flush_n_args_and_op (OpCode op, unsigned int n, ENV &env, PARAM& param)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case OpCode_hstem:
|
||||
case OpCode_vstem:
|
||||
case OpCode_hstemhm:
|
||||
case OpCode_vstemhm:
|
||||
case OpCode_hflex:
|
||||
case OpCode_flex:
|
||||
case OpCode_hflex1:
|
||||
case OpCode_flex1:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
OPSET::flush_n_args (n, env, param);
|
||||
OPSET::flush_op (op, env, param);
|
||||
}
|
||||
|
||||
static inline void flush_args (ENV &env, PARAM& param)
|
||||
{
|
||||
OPSET::flush_n_args (env.argStack.count, env, param);
|
||||
}
|
||||
|
||||
static inline void flush_n_args (unsigned int n, ENV &env, PARAM& param)
|
||||
{
|
||||
env.pop_n_args (n);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -169,12 +169,12 @@ struct TopDictOpSet : DictOpSet
|
||||
case OpCode_CharStrings:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.charStringsOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
case OpCode_FDArray:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.FDArrayOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
default:
|
||||
return DictOpSet::process_op (op, env);
|
||||
|
@ -51,7 +51,7 @@ struct CFF1CSInterpEnv : CSInterpEnv<CFF1Subrs>
|
||||
{
|
||||
if (!processed_width)
|
||||
{
|
||||
if ((this->argStack.size & 1) != 0)
|
||||
if ((this->argStack.count & 1) != 0)
|
||||
{
|
||||
width = this->argStack.elements[0];
|
||||
has_width = true;
|
||||
@ -163,8 +163,8 @@ struct CFF1CSOpSet : CSOpSet<OPSET, CFF1CSInterpEnv, PARAM>
|
||||
if (unlikely (!env.argStack.check_pop_num (n1))) return false;
|
||||
int i = n1.to_int ();
|
||||
if (i < 0) i = 0;
|
||||
if (unlikely (i >= env.argStack.size || !env.argStack.check_overflow (1))) return false;
|
||||
env.argStack.push (env.argStack.elements[env.argStack.size - i - 1]);
|
||||
if (unlikely (i >= env.argStack.count || !env.argStack.check_overflow (1))) return false;
|
||||
env.argStack.push (env.argStack.elements[env.argStack.count - i - 1]);
|
||||
}
|
||||
break;
|
||||
case OpCode_roll:
|
||||
@ -172,13 +172,13 @@ struct CFF1CSOpSet : CSOpSet<OPSET, CFF1CSInterpEnv, PARAM>
|
||||
if (unlikely (!env.argStack.check_pop_num2 (n1, n2))) return false;
|
||||
int n = n1.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 (j < 0)
|
||||
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;
|
||||
env.argStack.reverse_range (top - j + 1, top);
|
||||
env.argStack.reverse_range (bot, top - j);
|
||||
@ -194,10 +194,10 @@ struct CFF1CSOpSet : CSOpSet<OPSET, CFF1CSInterpEnv, PARAM>
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void flush_stack (CFF1CSInterpEnv &env, PARAM& param)
|
||||
static inline void flush_args (CFF1CSInterpEnv &env, PARAM& param)
|
||||
{
|
||||
env.check_width ();
|
||||
SUPER::flush_stack (env, param);
|
||||
SUPER::flush_args (env, param);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -54,13 +54,11 @@ struct CFF2CSInterpEnv : CSInterpEnv<CFF2Subrs>
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool process_vsindex (void)
|
||||
inline void process_vsindex (void)
|
||||
{
|
||||
unsigned int index;
|
||||
if (unlikely (!argStack.check_pop_uint (index)))
|
||||
return false;
|
||||
set_ivs (index);
|
||||
return true;
|
||||
if (likely (argStack.check_pop_uint (index)))
|
||||
set_ivs (argStack.check_pop_uint (index));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
case OpCode_vsindexcs:
|
||||
return OPSET::process_vsindex (env, param);
|
||||
OPSET::process_vsindex (env, param);
|
||||
break;
|
||||
|
||||
default:
|
||||
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)
|
||||
{
|
||||
// XXX: TODO leave default values?
|
||||
OPSET::flush_stack (env, param);
|
||||
OPSET::flush_args (env, param);
|
||||
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_XUID:
|
||||
case OpCode_BaseFontBlend:
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
case OpCode_CIDCount:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.cidCount)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
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[0])))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
case OpCode_Encoding:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.EncodingOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
case OpCode_charset:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.CharsetOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
case OpCode_FDSelect:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.FDSelectOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
case OpCode_Private:
|
||||
@ -477,7 +477,7 @@ struct CFF1TopDictOpSet : TopDictOpSet
|
||||
return false;
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -517,14 +517,14 @@ struct CFF1FontDictOpSet : DictOpSet
|
||||
case OpCode_FontName:
|
||||
case OpCode_FontMatrix:
|
||||
case OpCode_PaintType:
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
case OpCode_Private:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.offset)))
|
||||
return false;
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -602,12 +602,12 @@ struct CFF1PrivateDictOpSet : DictOpSet
|
||||
case OpCode_nominalWidthX:
|
||||
if (unlikely (!env.argStack.check_pop_num (val.single_val)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
case OpCode_Subrs:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -644,13 +644,13 @@ struct CFF1PrivateDictOpSet_Subset : DictOpSet
|
||||
case OpCode_initialRandomSeed:
|
||||
case OpCode_defaultWidthX:
|
||||
case OpCode_nominalWidthX:
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
case OpCode_Subrs:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -183,19 +183,19 @@ struct CFF2TopDictOpSet : TopDictOpSet
|
||||
DictVal val;
|
||||
val.init ();
|
||||
dictval.pushVal (op, env.substr);
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
}
|
||||
break;
|
||||
|
||||
case OpCode_vstore:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.vstoreOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
case OpCode_FDSelect:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.FDSelectOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -236,7 +236,7 @@ struct CFF2FontDictOpSet : DictOpSet
|
||||
return false;
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.privateDictInfo.size)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -301,7 +301,7 @@ struct CFF2PrivateDictOpSet : DictOpSet
|
||||
case OpCode_LanguageGroup:
|
||||
if (unlikely (!env.argStack.check_pop_num (val.single_val)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
case OpCode_BlueValues:
|
||||
case OpCode_OtherBlues:
|
||||
@ -311,12 +311,12 @@ struct CFF2PrivateDictOpSet : DictOpSet
|
||||
case OpCode_StemSnapV:
|
||||
if (unlikely (!env.argStack.check_pop_delta (val.multi_val)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
case OpCode_Subrs:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
case OpCode_vsindexdict:
|
||||
case OpCode_blenddict:
|
||||
@ -353,17 +353,17 @@ struct CFF2PrivateDictOpSet_Subset : DictOpSet
|
||||
case OpCode_StemSnapV:
|
||||
case OpCode_LanguageGroup:
|
||||
case OpCode_ExpansionFactor:
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
case OpCode_blenddict:
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
return true;
|
||||
|
||||
case OpCode_Subrs:
|
||||
if (unlikely (!env.argStack.check_pop_uint (dictval.subrsOffset)))
|
||||
return false;
|
||||
env.argStack.clear ();
|
||||
env.clear_args ();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -106,43 +106,50 @@ struct CFF1TopDict_OpSerializer : CFFTopDict_OpSerializer
|
||||
|
||||
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)
|
||||
{
|
||||
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_stack ();
|
||||
return true;
|
||||
env.clear_args ();
|
||||
return;
|
||||
}
|
||||
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;
|
||||
/* NO BREAK */
|
||||
|
||||
default:
|
||||
if (!CSOPSET::is_subr_op (op) &&
|
||||
!CSOPSET::is_arg_op (op))
|
||||
return param.flatStr.encode_op (op);
|
||||
SUPER::flush_args_and_op (op, env, param);
|
||||
break;
|
||||
}
|
||||
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]);
|
||||
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:
|
||||
|
@ -77,59 +77,54 @@ struct CFF2TopDict_OpSerializer : CFFTopDict_OpSerializer
|
||||
|
||||
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)
|
||||
{
|
||||
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_endchar:
|
||||
/* dummy opcodes in CFF2. ignore */
|
||||
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:
|
||||
if (!CSOPSET::is_subr_op (op) &&
|
||||
!CSOPSET::is_arg_op (op))
|
||||
return param.flatStr.encode_op (op);
|
||||
SUPER::flush_args_and_op (op, env, param);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
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++)
|
||||
for (unsigned int i = env.argStack.count - n; i < env.argStack.count; 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:
|
||||
|
Loading…
Reference in New Issue
Block a user