Added drop_hints to SubrFlattener
diff --git a/src/hb-cff-interp-cs-common.hh b/src/hb-cff-interp-cs-common.hh
index 9e22b1e..a07ca0d 100644
--- a/src/hb-cff-interp-cs-common.hh
+++ b/src/hb-cff-interp-cs-common.hh
@@ -282,6 +282,25 @@
}
}
+ /* hint operators (excluding hint/counter mask) */
+ static inline bool is_hint_op (OpCode op)
+ {
+ 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;
+ }
+ }
+
static inline bool is_subr_op (OpCode op)
{
switch (op)
@@ -301,7 +320,6 @@
{
inline bool interpret (PARAM& param)
{
- param.init ();
Interpreter<ENV> &super = *this;
super.env.set_endchar (false);
diff --git a/src/hb-subset-cff-common.hh b/src/hb-subset-cff-common.hh
index f7294cc..56d7a57 100644
--- a/src/hb-subset-cff-common.hh
+++ b/src/hb-subset-cff-common.hh
@@ -252,13 +252,21 @@
const bool flatten_subrs;
};
+struct FlattenParam
+{
+ ByteStrBuff &flatStr;
+ bool drop_hints;
+};
template <typename ACCESSOR, typename ENV, typename OPSET>
struct SubrFlattener
{
- inline SubrFlattener (const ACCESSOR &acc_, const hb_vector_t<hb_codepoint_t> &glyphs_)
+ inline SubrFlattener (const ACCESSOR &acc_,
+ const hb_vector_t<hb_codepoint_t> &glyphs_,
+ bool drop_hints_)
: acc (acc_),
- glyphs (glyphs_)
+ glyphs (glyphs_),
+ drop_hints (drop_hints_)
{}
inline bool flatten (ByteStrBuffArray &flat_charstrings)
@@ -272,9 +280,10 @@
hb_codepoint_t glyph = glyphs[i];
const ByteStr str = (*acc.charStrings)[glyph];
unsigned int fd = acc.fdSelect->get_fd (glyph);
- CSInterpreter<ENV, OPSET, ByteStrBuff> interp;
+ CSInterpreter<ENV, OPSET, FlattenParam> interp;
interp.env.init (str, *acc.globalSubrs, *acc.privateDicts[fd].localSubrs);
- if (unlikely (!interp.interpret (flat_charstrings[i])))
+ FlattenParam param = { flat_charstrings[i], drop_hints };
+ if (unlikely (!interp.interpret (param)))
return false;
}
return true;
@@ -282,6 +291,7 @@
const ACCESSOR &acc;
const hb_vector_t<hb_codepoint_t> &glyphs;
+ bool drop_hints;
};
struct SubrRefMaps
diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc
index 769eb5e..2685934 100644
--- a/src/hb-subset-cff1.cc
+++ b/src/hb-subset-cff1.cc
@@ -104,40 +104,50 @@
}
};
-struct CFF1CSOpSet_Flatten : CFF1CSOpSet<CFF1CSOpSet_Flatten, ByteStrBuff>
+struct CFF1CSOpSet_Flatten : CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam>
{
- static inline bool process_op (OpCode op, CFF1CSInterpEnv &env, ByteStrBuff& flatStr)
+ static inline bool process_op (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param)
{
- if (unlikely (!SUPER::process_op (op, env, flatStr)))
+ 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 (unlikely (!flatStr.encode_op (op)))
+ 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 (!flatStr.encode_byte (env.substr[i])))
+ if (unlikely (!param.flatStr.encode_byte (env.substr[i])))
return false;
break;
default:
if (!CSOPSET::is_subr_op (op) &&
!CSOPSET::is_arg_op (op))
- return flatStr.encode_op (op);
+ return param.flatStr.encode_op (op);
}
return true;
}
- static inline void flush_stack (CFF1CSInterpEnv &env, ByteStrBuff& flatStr)
+ static inline void flush_stack (CFF1CSInterpEnv &env, FlattenParam& param)
{
for (unsigned int i = 0; i < env.argStack.size; i++)
- flatStr.encode_num (env.argStack.elements[i]);
- SUPER::flush_stack (env, flatStr);
+ param.flatStr.encode_num (env.argStack.elements[i]);
+ SUPER::flush_stack (env, param);
}
private:
- typedef CFF1CSOpSet<CFF1CSOpSet_Flatten, ByteStrBuff> SUPER;
- typedef CSOpSet<CFF1CSOpSet_Flatten, CFF1CSInterpEnv, ByteStrBuff> CSOPSET;
+ typedef CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam> SUPER;
+ typedef CSOpSet<CFF1CSOpSet_Flatten, CFF1CSInterpEnv, FlattenParam> CSOPSET;
};
struct CFF1CSOpSet_SubsetSubrs : CFF1CSOpSet<CFF1CSOpSet_SubsetSubrs, SubrRefMapPair>
@@ -226,7 +236,8 @@
if (flatten_subrs)
{
/* Flatten global & local subrs */
- SubrFlattener<const OT::cff1::accelerator_subset_t, CFF1CSInterpEnv, CFF1CSOpSet_Flatten> flattener(acc, plan->glyphs);
+ SubrFlattener<const OT::cff1::accelerator_subset_t, CFF1CSInterpEnv, CFF1CSOpSet_Flatten>
+ flattener(acc, plan->glyphs, plan->drop_hints);
if (!flattener.flatten (flat_charstrings))
return false;
diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc
index 59535e6..0edca28 100644
--- a/src/hb-subset-cff2.cc
+++ b/src/hb-subset-cff2.cc
@@ -75,20 +75,30 @@
}
};
-struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, ByteStrBuff>
+struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam>
{
- static inline bool process_op (OpCode op, CFF2CSInterpEnv &env, ByteStrBuff& flatStr)
+ static inline bool process_op (OpCode op, CFF2CSInterpEnv &env, FlattenParam& param)
{
- if (unlikely (!SUPER::process_op (op, env, flatStr)))
+ 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 (unlikely (!flatStr.encode_op (op)))
+ 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 (!flatStr.encode_byte (env.substr[i])))
+ if (unlikely (!param.flatStr.encode_byte (env.substr[i])))
return false;
break;
case OpCode_return:
@@ -98,33 +108,33 @@
default:
if (!CSOPSET::is_subr_op (op) &&
!CSOPSET::is_arg_op (op))
- return flatStr.encode_op (op);
+ return param.flatStr.encode_op (op);
}
return true;
}
- static inline bool process_blend (CFF2CSInterpEnv &env, ByteStrBuff& flatStr)
+ static inline bool process_blend (CFF2CSInterpEnv &env, FlattenParam& param)
{
- flush_stack (env, flatStr);
+ flush_stack (env, param);
return true;
}
- static inline bool process_vsindex (CFF2CSInterpEnv &env, ByteStrBuff& flatStr)
+ static inline bool process_vsindex (CFF2CSInterpEnv &env, FlattenParam& param)
{
- flush_stack (env, flatStr);
+ flush_stack (env, param);
return true;
}
- static inline void flush_stack (CFF2CSInterpEnv &env, ByteStrBuff& flatStr)
+ static inline void flush_stack (CFF2CSInterpEnv &env, FlattenParam& param)
{
for (unsigned int i = 0; i < env.argStack.size; i++)
- flatStr.encode_num (env.argStack.elements[i]);
- SUPER::flush_stack (env, flatStr);
+ param.flatStr.encode_num (env.argStack.elements[i]);
+ SUPER::flush_stack (env, param);
}
private:
- typedef CFF2CSOpSet<CFF2CSOpSet_Flatten, ByteStrBuff> SUPER;
- typedef CSOpSet<CFF2CSOpSet_Flatten, CFF2CSInterpEnv, ByteStrBuff> CSOPSET;
+ typedef CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam> SUPER;
+ typedef CSOpSet<CFF2CSOpSet_Flatten, CFF2CSInterpEnv, FlattenParam> CSOPSET;
};
struct CFF2CSOpSet_SubsetSubrs : CFF2CSOpSet<CFF2CSOpSet_SubsetSubrs, SubrRefMapPair>
@@ -200,7 +210,8 @@
if (flatten_subrs)
{
/* Flatten global & local subrs */
- SubrFlattener<const OT::cff2::accelerator_subset_t, CFF2CSInterpEnv, CFF2CSOpSet_Flatten> flattener(acc, plan->glyphs);
+ SubrFlattener<const OT::cff2::accelerator_subset_t, CFF2CSInterpEnv, CFF2CSOpSet_Flatten>
+ flattener(acc, plan->glyphs, plan->drop_hints);
if (!flattener.flatten (flat_charstrings))
return false;