Added drop_hints to SubrFlattener
This commit is contained in:
parent
9fd08cc238
commit
8c5e03b541
|
@ -282,6 +282,25 @@ struct CSOpSet : OpSet
|
|||
}
|
||||
}
|
||||
|
||||
/* 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 @@ struct CSInterpreter : Interpreter<ENV>
|
|||
{
|
||||
inline bool interpret (PARAM& param)
|
||||
{
|
||||
param.init ();
|
||||
Interpreter<ENV> &super = *this;
|
||||
super.env.set_endchar (false);
|
||||
|
||||
|
|
|
@ -252,13 +252,21 @@ struct CFFPrivateDict_OpSerializer : OpSerializer
|
|||
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 @@ struct SubrFlattener
|
|||
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 @@ struct SubrFlattener
|
|||
|
||||
const ACCESSOR &acc;
|
||||
const hb_vector_t<hb_codepoint_t> &glyphs;
|
||||
bool drop_hints;
|
||||
};
|
||||
|
||||
struct SubrRefMaps
|
||||
|
|
|
@ -104,40 +104,50 @@ struct CFF1TopDict_OpSerializer : CFFTopDict_OpSerializer
|
|||
}
|
||||
};
|
||||
|
||||
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 @@ struct cff_subset_plan {
|
|||
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;
|
||||
|
||||
|
|
|
@ -75,20 +75,30 @@ struct CFF2TopDict_OpSerializer : CFFTopDict_OpSerializer
|
|||
}
|
||||
};
|
||||
|
||||
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 @@ struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, ByteStrBuff>
|
|||
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 @@ struct cff2_subset_plan {
|
|||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue