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)
|
static inline bool is_subr_op (OpCode op)
|
||||||
{
|
{
|
||||||
switch (op)
|
switch (op)
|
||||||
|
@ -301,7 +320,6 @@ struct CSInterpreter : Interpreter<ENV>
|
||||||
{
|
{
|
||||||
inline bool interpret (PARAM& param)
|
inline bool interpret (PARAM& param)
|
||||||
{
|
{
|
||||||
param.init ();
|
|
||||||
Interpreter<ENV> &super = *this;
|
Interpreter<ENV> &super = *this;
|
||||||
super.env.set_endchar (false);
|
super.env.set_endchar (false);
|
||||||
|
|
||||||
|
|
|
@ -252,13 +252,21 @@ struct CFFPrivateDict_OpSerializer : OpSerializer
|
||||||
const bool flatten_subrs;
|
const bool flatten_subrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FlattenParam
|
||||||
|
{
|
||||||
|
ByteStrBuff &flatStr;
|
||||||
|
bool drop_hints;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename ACCESSOR, typename ENV, typename OPSET>
|
template <typename ACCESSOR, typename ENV, typename OPSET>
|
||||||
struct SubrFlattener
|
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_),
|
: acc (acc_),
|
||||||
glyphs (glyphs_)
|
glyphs (glyphs_),
|
||||||
|
drop_hints (drop_hints_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline bool flatten (ByteStrBuffArray &flat_charstrings)
|
inline bool flatten (ByteStrBuffArray &flat_charstrings)
|
||||||
|
@ -272,9 +280,10 @@ struct SubrFlattener
|
||||||
hb_codepoint_t glyph = glyphs[i];
|
hb_codepoint_t glyph = glyphs[i];
|
||||||
const ByteStr str = (*acc.charStrings)[glyph];
|
const ByteStr str = (*acc.charStrings)[glyph];
|
||||||
unsigned int fd = acc.fdSelect->get_fd (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);
|
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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -282,6 +291,7 @@ struct SubrFlattener
|
||||||
|
|
||||||
const ACCESSOR &acc;
|
const ACCESSOR &acc;
|
||||||
const hb_vector_t<hb_codepoint_t> &glyphs;
|
const hb_vector_t<hb_codepoint_t> &glyphs;
|
||||||
|
bool drop_hints;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SubrRefMaps
|
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;
|
return false;
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case OpCode_hintmask:
|
case OpCode_hintmask:
|
||||||
case OpCode_cntrmask:
|
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;
|
return false;
|
||||||
for (int i = -env.hintmask_size; i < 0; i++)
|
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;
|
return false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!CSOPSET::is_subr_op (op) &&
|
if (!CSOPSET::is_subr_op (op) &&
|
||||||
!CSOPSET::is_arg_op (op))
|
!CSOPSET::is_arg_op (op))
|
||||||
return flatStr.encode_op (op);
|
return param.flatStr.encode_op (op);
|
||||||
}
|
}
|
||||||
return true;
|
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++)
|
for (unsigned int i = 0; i < env.argStack.size; i++)
|
||||||
flatStr.encode_num (env.argStack.elements[i]);
|
param.flatStr.encode_num (env.argStack.elements[i]);
|
||||||
SUPER::flush_stack (env, flatStr);
|
SUPER::flush_stack (env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef CFF1CSOpSet<CFF1CSOpSet_Flatten, ByteStrBuff> SUPER;
|
typedef CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam> SUPER;
|
||||||
typedef CSOpSet<CFF1CSOpSet_Flatten, CFF1CSInterpEnv, ByteStrBuff> CSOPSET;
|
typedef CSOpSet<CFF1CSOpSet_Flatten, CFF1CSInterpEnv, FlattenParam> CSOPSET;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CFF1CSOpSet_SubsetSubrs : CFF1CSOpSet<CFF1CSOpSet_SubsetSubrs, SubrRefMapPair>
|
struct CFF1CSOpSet_SubsetSubrs : CFF1CSOpSet<CFF1CSOpSet_SubsetSubrs, SubrRefMapPair>
|
||||||
|
@ -226,7 +236,8 @@ struct cff_subset_plan {
|
||||||
if (flatten_subrs)
|
if (flatten_subrs)
|
||||||
{
|
{
|
||||||
/* Flatten global & local 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))
|
if (!flattener.flatten (flat_charstrings))
|
||||||
return false;
|
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;
|
return false;
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case OpCode_hintmask:
|
case OpCode_hintmask:
|
||||||
case OpCode_cntrmask:
|
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;
|
return false;
|
||||||
for (int i = -env.hintmask_size; i < 0; i++)
|
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;
|
return false;
|
||||||
break;
|
break;
|
||||||
case OpCode_return:
|
case OpCode_return:
|
||||||
|
@ -98,33 +108,33 @@ struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, ByteStrBuff>
|
||||||
default:
|
default:
|
||||||
if (!CSOPSET::is_subr_op (op) &&
|
if (!CSOPSET::is_subr_op (op) &&
|
||||||
!CSOPSET::is_arg_op (op))
|
!CSOPSET::is_arg_op (op))
|
||||||
return flatStr.encode_op (op);
|
return param.flatStr.encode_op (op);
|
||||||
}
|
}
|
||||||
return true;
|
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;
|
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;
|
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++)
|
for (unsigned int i = 0; i < env.argStack.size; i++)
|
||||||
flatStr.encode_num (env.argStack.elements[i]);
|
param.flatStr.encode_num (env.argStack.elements[i]);
|
||||||
SUPER::flush_stack (env, flatStr);
|
SUPER::flush_stack (env, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef CFF2CSOpSet<CFF2CSOpSet_Flatten, ByteStrBuff> SUPER;
|
typedef CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam> SUPER;
|
||||||
typedef CSOpSet<CFF2CSOpSet_Flatten, CFF2CSInterpEnv, ByteStrBuff> CSOPSET;
|
typedef CSOpSet<CFF2CSOpSet_Flatten, CFF2CSInterpEnv, FlattenParam> CSOPSET;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CFF2CSOpSet_SubsetSubrs : CFF2CSOpSet<CFF2CSOpSet_SubsetSubrs, SubrRefMapPair>
|
struct CFF2CSOpSet_SubsetSubrs : CFF2CSOpSet<CFF2CSOpSet_SubsetSubrs, SubrRefMapPair>
|
||||||
|
@ -200,7 +210,8 @@ struct cff2_subset_plan {
|
||||||
if (flatten_subrs)
|
if (flatten_subrs)
|
||||||
{
|
{
|
||||||
/* Flatten global & local 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))
|
if (!flattener.flatten (flat_charstrings))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue