fixed char widths & standard Encoding in subset CFF

also merged flush_n_args to flush_args into one
takes start index of the arguments on stack instead of count
This commit is contained in:
Michiharu Ariza 2018-09-18 17:24:30 -07:00
parent bf4eb2e4cf
commit ebeccf3e63
5 changed files with 35 additions and 32 deletions

View File

@ -220,7 +220,7 @@ struct CSOpSet : OpSet<ARG>
return env.returnFromSubr (); return env.returnFromSubr ();
case OpCode_endchar: case OpCode_endchar:
env.set_endchar (true); env.set_endchar (true);
OPSET::flush_op (op, env, param); OPSET::flush_args_and_op (op, env, param);
break; break;
case OpCode_fixedcs: case OpCode_fixedcs:
@ -352,25 +352,15 @@ struct CSOpSet : OpSet<ARG>
OPSET::flush_args_and_op (op, env, param); OPSET::flush_args_and_op (op, env, param);
} }
static inline void flush_args_and_op (OpCode op, ENV &env, PARAM& param) static inline void flush_args_and_op (OpCode op, ENV &env, PARAM& param, unsigned int start_arg = 0)
{ {
OPSET::flush_n_args_and_op (op, env.argStack.get_count (), env, param); OPSET::flush_args (env, param, start_arg);
}
static inline void flush_n_args_and_op (OpCode op, unsigned int n, ENV &env, PARAM& param)
{
OPSET::flush_n_args (n, env, param);
OPSET::flush_op (op, env, param); OPSET::flush_op (op, env, param);
} }
static inline void flush_args (ENV &env, PARAM& param) static inline void flush_args (ENV &env, PARAM& param, unsigned int start_arg = 0)
{ {
OPSET::flush_n_args (env.argStack.get_count (), env, param); env.pop_n_args (env.argStack.get_count () - start_arg);
}
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_op (OpCode op, ENV &env, PARAM& param)

View File

@ -48,17 +48,20 @@ struct CFF1CSInterpEnv : CSInterpEnv<Number, CFF1Subrs>
bool check_transient_array_index (unsigned int i) const bool check_transient_array_index (unsigned int i) const
{ return i < kTransientArraySize; } { return i < kTransientArraySize; }
inline void check_width (void) inline unsigned int check_width (void)
{ {
unsigned int arg_start = 0;
if (!processed_width) if (!processed_width)
{ {
if ((SUPER::argStack.get_count () & 1) != 0) if ((SUPER::argStack.get_count () & 1) != 0)
{ {
width = SUPER::argStack[0]; width = SUPER::argStack[0];
has_width = true; has_width = true;
arg_start = 1;
} }
processed_width = true; processed_width = true;
} }
return arg_start;
} }
bool processed_width; bool processed_width;
@ -198,10 +201,10 @@ struct CFF1CSOpSet : CSOpSet<Number, OPSET, CFF1CSInterpEnv, PARAM, PATH>
return true; return true;
} }
static inline void flush_args (CFF1CSInterpEnv &env, PARAM& param) static inline void flush_args (CFF1CSInterpEnv &env, PARAM& param, unsigned int start_arg = 0)
{ {
env.check_width (); start_arg = env.check_width ();
SUPER::flush_args (env, param); SUPER::flush_args (env, param, start_arg);
} }
private: private:

View File

@ -168,7 +168,7 @@ struct CFF2CSOpSet : CSOpSet<BlendArg, OPSET, CFF2CSInterpEnv, PARAM, PATH>
static inline void process_vsindex (CFF2CSInterpEnv &env, PARAM& param) static inline void process_vsindex (CFF2CSInterpEnv &env, PARAM& param)
{ {
env.process_vsindex (); env.process_vsindex ();
OPSET::flush_n_args_and_op (OpCode_vsindexcs, 1, env, param); OPSET::flush_args_and_op (OpCode_vsindexcs, env, param, env.argStack.get_count ()-1);
} }
private: private:

View File

@ -270,8 +270,12 @@ struct CFF1FontDict_OpSerializer : CFFFontDict_OpSerializer
struct CFF1CSOpSet_Flatten : CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam> struct CFF1CSOpSet_Flatten : CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam>
{ {
static inline void flush_args_and_op (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param) static inline void flush_args_and_op (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param, unsigned int start_arg = 0)
{ {
start_arg = env.check_width ();
if ((start_arg > 0) && likely (param.flatStr.len == 0))
flush_width (env, param);
switch (op) switch (op)
{ {
case OpCode_hstem: case OpCode_hstem:
@ -292,16 +296,16 @@ struct CFF1CSOpSet_Flatten : CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam>
/* NO BREAK */ /* NO BREAK */
default: default:
SUPER::flush_args_and_op (op, env, param); SUPER::flush_args_and_op (op, env, param, start_arg);
break; break;
} }
} }
static inline void flush_n_args (unsigned int n, CFF1CSInterpEnv &env, FlattenParam& param) static inline void flush_args (CFF1CSInterpEnv &env, FlattenParam& param, unsigned int start_arg = 0)
{ {
for (unsigned int i = env.argStack.get_count () - n; i < env.argStack.get_count (); i++) for (unsigned int i = start_arg; i < env.argStack.get_count (); i++)
param.flatStr.encode_num (env.argStack[i]); param.flatStr.encode_num (env.argStack[i]);
SUPER::flush_n_args (n, env, param); SUPER::flush_args (env, param, start_arg);
} }
static inline void flush_op (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param) static inline void flush_op (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param)
@ -309,6 +313,12 @@ struct CFF1CSOpSet_Flatten : CFF1CSOpSet<CFF1CSOpSet_Flatten, FlattenParam>
param.flatStr.encode_op (op); param.flatStr.encode_op (op);
} }
static inline void flush_width (CFF1CSInterpEnv &env, FlattenParam& param)
{
assert (env.has_width);
param.flatStr.encode_num (env.width);
}
static inline void flush_hintmask (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param) static inline void flush_hintmask (OpCode op, CFF1CSInterpEnv &env, FlattenParam& param)
{ {
SUPER::flush_hintmask (op, env, param); SUPER::flush_hintmask (op, env, param);
@ -527,7 +537,7 @@ struct cff_subset_plan {
} }
subset_charset = gid_renum || !acc.is_predef_charset (); subset_charset = gid_renum || !acc.is_predef_charset ();
subset_encoding = !acc.is_CID() && (gid_renum || !acc.is_predef_encoding ()); subset_encoding = !acc.is_CID() && !acc.is_predef_encoding ();
/* CFF header */ /* CFF header */
final_size += OT::cff1::static_size; final_size += OT::cff1::static_size;

View File

@ -77,7 +77,7 @@ struct CFF2TopDict_OpSerializer : CFFTopDict_OpSerializer<>
struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam> struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam>
{ {
static inline void flush_args_and_op (OpCode op, CFF2CSInterpEnv &env, FlattenParam& param) static inline void flush_args_and_op (OpCode op, CFF2CSInterpEnv &env, FlattenParam& param, unsigned int start_arg = 0)
{ {
switch (op) switch (op)
{ {
@ -104,19 +104,19 @@ struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam>
/* NO BREAK */ /* NO BREAK */
default: default:
SUPER::flush_args_and_op (op, env, param); SUPER::flush_args_and_op (op, env, param, start_arg);
break; break;
} }
} }
static inline void flush_n_args (unsigned int n, CFF2CSInterpEnv &env, FlattenParam& param) static inline void flush_args (CFF2CSInterpEnv &env, FlattenParam& param, unsigned int start_arg = 0)
{ {
for (unsigned int i = env.argStack.get_count () - n; i < env.argStack.get_count ();) for (unsigned int i = start_arg; i < env.argStack.get_count ();)
{ {
const BlendArg &arg = env.argStack[i]; const BlendArg &arg = env.argStack[i];
if (arg.blended ()) if (arg.blended ())
{ {
assert ((arg.numValues > 0) && (n >= arg.numValues)); assert ((arg.numValues > 0) && (env.argStack.get_count () - start_arg >= arg.numValues));
flatten_blends (arg, i, env, param); flatten_blends (arg, i, env, param);
i += arg.numValues; i += arg.numValues;
} }
@ -126,7 +126,7 @@ struct CFF2CSOpSet_Flatten : CFF2CSOpSet<CFF2CSOpSet_Flatten, FlattenParam>
i++; i++;
} }
} }
SUPER::flush_n_args (n, env, param); SUPER::flush_args (env, param, start_arg);
} }
static inline void flatten_blends (const BlendArg &arg, unsigned int i, CFF2CSInterpEnv &env, FlattenParam& param) static inline void flatten_blends (const BlendArg &arg, unsigned int i, CFF2CSInterpEnv &env, FlattenParam& param)