From 8679d02b4b3f2f9147c4ea0319eb39851c4e40e6 Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Oct 2018 13:04:21 -0700 Subject: [PATCH] implement flex ops for glyph extents/subset also removed unused CSInterpEnv::move_[xy]_with_arg fixed bug a width being left over on argStack with CFF1 --- src/hb-cff-interp-cs-common.hh | 157 ++++++++++++++++++++++++++++----- src/hb-cff1-interp-cs.hh | 1 + src/hb-subset-cff1.cc | 4 - src/hb-subset-cff2.cc | 4 - 4 files changed, 138 insertions(+), 28 deletions(-) diff --git a/src/hb-cff-interp-cs-common.hh b/src/hb-cff-interp-cs-common.hh index 5d85c85c0..f22d753eb 100644 --- a/src/hb-cff-interp-cs-common.hh +++ b/src/hb-cff-interp-cs-common.hh @@ -152,24 +152,6 @@ struct CSInterpEnv : InterpEnv inline void moveto (const Point &pt_ ) { pt = pt_; } - inline unsigned int move_x_with_arg (unsigned int i) - { - pt.move_x (SUPER::eval_arg (i)); - return i + 1; - } - - inline unsigned int move_y_with_arg (unsigned int i) - { - pt.move_y (SUPER::eval_arg (i)); - return i + 1; - } - - inline unsigned int move_xy_with_arg (unsigned int i) - { - pt.move (SUPER::eval_arg (i), SUPER::eval_arg (i+1)); - return i + 2; - } - public: bool endchar_flag; bool seen_moveto; @@ -207,6 +189,10 @@ struct PathProcsNull static inline void moveto (ENV &env, PARAM& param, const Point &pt) {} static inline void line (ENV &env, PARAM& param, const Point &pt1) {} static inline void curve (ENV &env, PARAM& param, const Point &pt1, const Point &pt2, const Point &pt3) {} + static inline void hflex (ENV &env, PARAM& param) {} + static inline void flex (ENV &env, PARAM& param) {} + static inline void hflex1 (ENV &env, PARAM& param) {} + static inline void flex1 (ENV &env, PARAM& param) {} }; template > @@ -302,10 +288,23 @@ struct CSOpSet : OpSet break; case OpCode_hflex: + PATH::hflex (env, param); + OPSET::process_post_flex (op, env, param); + break; + case OpCode_flex: + PATH::flex (env, param); + OPSET::process_post_flex (op, env, param); + break; + case OpCode_hflex1: + PATH::hflex1 (env, param); + OPSET::process_post_flex (op, env, param); + break; + case OpCode_flex1: - OPSET::process_flex (op, env, param); + PATH::flex1 (env, param); + OPSET::process_post_flex (op, env, param); break; default: @@ -336,7 +335,7 @@ struct CSOpSet : OpSet } } - static inline void process_flex (OpCode op, ENV &env, PARAM& param) + static inline void process_post_flex (OpCode op, ENV &env, PARAM& param) { OPSET::flush_args_and_op (op, env, param); } @@ -680,6 +679,124 @@ struct PathProcs static inline void curve (ENV &env, PARAM& param, const Point &pt1, const Point &pt2, const Point &pt3) { PATH::moveto (env, param, pt3); } + + static inline void hflex (ENV &env, PARAM& param) + { + if (likely (env.argStack.get_count () == 7)) + { + Point pt1 = env.get_pt (); + pt1.move_x (env.eval_arg (0)); + Point pt2 = pt1; + pt2.move (env.eval_arg (1), env.eval_arg (2)); + Point pt3 = pt2; + pt3.move_x (env.eval_arg (3)); + Point pt4 = pt3; + pt4.move_x (env.eval_arg (4)); + Point pt5 = pt4; + pt5.move_x (env.eval_arg (5)); + pt5.y = pt1.y; + Point pt6 = pt5; + pt6.move_x (env.eval_arg (6)); + + curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6); + } + else + env.set_error (); + } + + static inline void flex (ENV &env, PARAM& param) + { + if (likely (env.argStack.get_count () == 13)) + { + Point pt1 = env.get_pt (); + pt1.move (env.eval_arg (0), env.eval_arg (1)); + Point pt2 = pt1; + pt2.move (env.eval_arg (2), env.eval_arg (3)); + Point pt3 = pt2; + pt3.move (env.eval_arg (4), env.eval_arg (5)); + Point pt4 = pt3; + pt4.move (env.eval_arg (6), env.eval_arg (7)); + Point pt5 = pt4; + pt5.move (env.eval_arg (8), env.eval_arg (9)); + Point pt6 = pt5; + pt6.move (env.eval_arg (10), env.eval_arg (11)); + + curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6); + } + else + env.set_error (); + } + + static inline void hflex1 (ENV &env, PARAM& param) + { + if (likely (env.argStack.get_count () == 9)) + { + Point pt1 = env.get_pt (); + pt1.move (env.eval_arg (0), env.eval_arg (1)); + Point pt2 = pt1; + pt2.move (env.eval_arg (2), env.eval_arg (3)); + Point pt3 = pt2; + pt3.move_x (env.eval_arg (4)); + Point pt4 = pt3; + pt4.move_x (env.eval_arg (5)); + Point pt5 = pt4; + pt5.move (env.eval_arg (6), env.eval_arg (7)); + Point pt6 = pt5; + pt6.move_x (env.eval_arg (8)); + pt6.y = env.get_pt ().y; + + curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6); + } + else + env.set_error (); + } + + static inline void flex1 (ENV &env, PARAM& param) + { + if (likely (env.argStack.get_count () == 11)) + { + Point d; + d.init (); + for (unsigned int i = 0; i < 10; i += 2) + d.move (env.eval_arg (i), env.eval_arg (i+1)); + + Point pt1 = env.get_pt (); + pt1.move (env.eval_arg (0), env.eval_arg (1)); + Point pt2 = pt1; + pt2.move (env.eval_arg (2), env.eval_arg (3)); + Point pt3 = pt2; + pt3.move (env.eval_arg (4), env.eval_arg (5)); + Point pt4 = pt3; + pt4.move (env.eval_arg (6), env.eval_arg (7)); + Point pt5 = pt4; + pt5.move (env.eval_arg (8), env.eval_arg (9)); + Point pt6 = pt5; + + if (fabs (d.x.to_real ()) > fabs (d.y.to_real ())) + { + pt6.move_x (env.eval_arg (10)); + pt6.y = env.get_pt ().y; + } + else + { + pt6.x = env.get_pt ().x; + pt6.move_y (env.eval_arg (10)); + } + + curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6); + } + else + env.set_error (); + } + + protected: + static inline void curve2 (ENV &env, PARAM& param, + const Point &pt1, const Point &pt2, const Point &pt3, + const Point &pt4, const Point &pt5, const Point &pt6) + { + PATH::curve (env, param, pt1, pt2, pt3); + PATH::curve (env, param, pt4, pt5, pt6); + } }; template diff --git a/src/hb-cff1-interp-cs.hh b/src/hb-cff1-interp-cs.hh index b41811484..33c8148d1 100644 --- a/src/hb-cff1-interp-cs.hh +++ b/src/hb-cff1-interp-cs.hh @@ -214,6 +214,7 @@ struct CFF1CSOpSet : CSOpSet { start_arg = env.check_width (); SUPER::flush_args (env, param, start_arg); + env.clear_args (); /* pop off width */ } private: diff --git a/src/hb-subset-cff1.cc b/src/hb-subset-cff1.cc index d2d65ed81..4216be45d 100644 --- a/src/hb-subset-cff1.cc +++ b/src/hb-subset-cff1.cc @@ -284,10 +284,6 @@ struct CFF1CSOpSet_Flatten : CFF1CSOpSet 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 (); diff --git a/src/hb-subset-cff2.cc b/src/hb-subset-cff2.cc index 0f4db1318..b30145cd7 100644 --- a/src/hb-subset-cff2.cc +++ b/src/hb-subset-cff2.cc @@ -92,10 +92,6 @@ struct CFF2CSOpSet_Flatten : CFF2CSOpSet 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 ();