xref: /aosp_15_r20/external/harfbuzz_ng/src/hb-cff-interp-cs-common.hh (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker  * Copyright © 2018 Adobe Inc.
3*2d1272b8SAndroid Build Coastguard Worker  *
4*2d1272b8SAndroid Build Coastguard Worker  *  This is part of HarfBuzz, a text shaping library.
5*2d1272b8SAndroid Build Coastguard Worker  *
6*2d1272b8SAndroid Build Coastguard Worker  * Permission is hereby granted, without written agreement and without
7*2d1272b8SAndroid Build Coastguard Worker  * license or royalty fees, to use, copy, modify, and distribute this
8*2d1272b8SAndroid Build Coastguard Worker  * software and its documentation for any purpose, provided that the
9*2d1272b8SAndroid Build Coastguard Worker  * above copyright notice and the following two paragraphs appear in
10*2d1272b8SAndroid Build Coastguard Worker  * all copies of this software.
11*2d1272b8SAndroid Build Coastguard Worker  *
12*2d1272b8SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13*2d1272b8SAndroid Build Coastguard Worker  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14*2d1272b8SAndroid Build Coastguard Worker  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15*2d1272b8SAndroid Build Coastguard Worker  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16*2d1272b8SAndroid Build Coastguard Worker  * DAMAGE.
17*2d1272b8SAndroid Build Coastguard Worker  *
18*2d1272b8SAndroid Build Coastguard Worker  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19*2d1272b8SAndroid Build Coastguard Worker  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20*2d1272b8SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21*2d1272b8SAndroid Build Coastguard Worker  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22*2d1272b8SAndroid Build Coastguard Worker  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23*2d1272b8SAndroid Build Coastguard Worker  *
24*2d1272b8SAndroid Build Coastguard Worker  * Adobe Author(s): Michiharu Ariza
25*2d1272b8SAndroid Build Coastguard Worker  */
26*2d1272b8SAndroid Build Coastguard Worker #ifndef HB_CFF_INTERP_CS_COMMON_HH
27*2d1272b8SAndroid Build Coastguard Worker #define HB_CFF_INTERP_CS_COMMON_HH
28*2d1272b8SAndroid Build Coastguard Worker 
29*2d1272b8SAndroid Build Coastguard Worker #include "hb.hh"
30*2d1272b8SAndroid Build Coastguard Worker #include "hb-cff-interp-common.hh"
31*2d1272b8SAndroid Build Coastguard Worker 
32*2d1272b8SAndroid Build Coastguard Worker namespace CFF {
33*2d1272b8SAndroid Build Coastguard Worker 
34*2d1272b8SAndroid Build Coastguard Worker using namespace OT;
35*2d1272b8SAndroid Build Coastguard Worker 
36*2d1272b8SAndroid Build Coastguard Worker enum cs_type_t {
37*2d1272b8SAndroid Build Coastguard Worker   CSType_CharString,
38*2d1272b8SAndroid Build Coastguard Worker   CSType_GlobalSubr,
39*2d1272b8SAndroid Build Coastguard Worker   CSType_LocalSubr
40*2d1272b8SAndroid Build Coastguard Worker };
41*2d1272b8SAndroid Build Coastguard Worker 
42*2d1272b8SAndroid Build Coastguard Worker struct call_context_t
43*2d1272b8SAndroid Build Coastguard Worker {
initCFF::call_context_t44*2d1272b8SAndroid Build Coastguard Worker   void init (const byte_str_ref_t substr_=byte_str_ref_t (), cs_type_t type_=CSType_CharString, unsigned int subr_num_=0)
45*2d1272b8SAndroid Build Coastguard Worker   {
46*2d1272b8SAndroid Build Coastguard Worker     str_ref = substr_;
47*2d1272b8SAndroid Build Coastguard Worker     type = type_;
48*2d1272b8SAndroid Build Coastguard Worker     subr_num = subr_num_;
49*2d1272b8SAndroid Build Coastguard Worker   }
50*2d1272b8SAndroid Build Coastguard Worker 
finiCFF::call_context_t51*2d1272b8SAndroid Build Coastguard Worker   void fini () {}
52*2d1272b8SAndroid Build Coastguard Worker 
53*2d1272b8SAndroid Build Coastguard Worker   byte_str_ref_t  str_ref;
54*2d1272b8SAndroid Build Coastguard Worker   cs_type_t	  type;
55*2d1272b8SAndroid Build Coastguard Worker   unsigned int    subr_num;
56*2d1272b8SAndroid Build Coastguard Worker };
57*2d1272b8SAndroid Build Coastguard Worker 
58*2d1272b8SAndroid Build Coastguard Worker /* call stack */
59*2d1272b8SAndroid Build Coastguard Worker const unsigned int kMaxCallLimit = 10;
60*2d1272b8SAndroid Build Coastguard Worker struct call_stack_t : cff_stack_t<call_context_t, kMaxCallLimit> {};
61*2d1272b8SAndroid Build Coastguard Worker 
62*2d1272b8SAndroid Build Coastguard Worker template <typename SUBRS>
63*2d1272b8SAndroid Build Coastguard Worker struct biased_subrs_t
64*2d1272b8SAndroid Build Coastguard Worker {
initCFF::biased_subrs_t65*2d1272b8SAndroid Build Coastguard Worker   void init (const SUBRS *subrs_)
66*2d1272b8SAndroid Build Coastguard Worker   {
67*2d1272b8SAndroid Build Coastguard Worker     subrs = subrs_;
68*2d1272b8SAndroid Build Coastguard Worker     unsigned int  nSubrs = get_count ();
69*2d1272b8SAndroid Build Coastguard Worker     if (nSubrs < 1240)
70*2d1272b8SAndroid Build Coastguard Worker       bias = 107;
71*2d1272b8SAndroid Build Coastguard Worker     else if (nSubrs < 33900)
72*2d1272b8SAndroid Build Coastguard Worker       bias = 1131;
73*2d1272b8SAndroid Build Coastguard Worker     else
74*2d1272b8SAndroid Build Coastguard Worker       bias = 32768;
75*2d1272b8SAndroid Build Coastguard Worker   }
76*2d1272b8SAndroid Build Coastguard Worker 
finiCFF::biased_subrs_t77*2d1272b8SAndroid Build Coastguard Worker   void fini () {}
78*2d1272b8SAndroid Build Coastguard Worker 
get_countCFF::biased_subrs_t79*2d1272b8SAndroid Build Coastguard Worker   unsigned int get_count () const { return subrs ? subrs->count : 0; }
get_biasCFF::biased_subrs_t80*2d1272b8SAndroid Build Coastguard Worker   unsigned int get_bias () const  { return bias; }
81*2d1272b8SAndroid Build Coastguard Worker 
operator []CFF::biased_subrs_t82*2d1272b8SAndroid Build Coastguard Worker   hb_ubytes_t operator [] (unsigned int index) const
83*2d1272b8SAndroid Build Coastguard Worker   {
84*2d1272b8SAndroid Build Coastguard Worker     if (unlikely (!subrs || index >= subrs->count))
85*2d1272b8SAndroid Build Coastguard Worker       return hb_ubytes_t ();
86*2d1272b8SAndroid Build Coastguard Worker     else
87*2d1272b8SAndroid Build Coastguard Worker       return (*subrs)[index];
88*2d1272b8SAndroid Build Coastguard Worker   }
89*2d1272b8SAndroid Build Coastguard Worker 
90*2d1272b8SAndroid Build Coastguard Worker   protected:
91*2d1272b8SAndroid Build Coastguard Worker   unsigned int  bias;
92*2d1272b8SAndroid Build Coastguard Worker   const SUBRS   *subrs;
93*2d1272b8SAndroid Build Coastguard Worker };
94*2d1272b8SAndroid Build Coastguard Worker 
95*2d1272b8SAndroid Build Coastguard Worker struct point_t
96*2d1272b8SAndroid Build Coastguard Worker {
set_intCFF::point_t97*2d1272b8SAndroid Build Coastguard Worker   void set_int (int _x, int _y)
98*2d1272b8SAndroid Build Coastguard Worker   {
99*2d1272b8SAndroid Build Coastguard Worker     x.set_int (_x);
100*2d1272b8SAndroid Build Coastguard Worker     y.set_int (_y);
101*2d1272b8SAndroid Build Coastguard Worker   }
102*2d1272b8SAndroid Build Coastguard Worker 
move_xCFF::point_t103*2d1272b8SAndroid Build Coastguard Worker   void move_x (const number_t &dx) { x += dx; }
move_yCFF::point_t104*2d1272b8SAndroid Build Coastguard Worker   void move_y (const number_t &dy) { y += dy; }
moveCFF::point_t105*2d1272b8SAndroid Build Coastguard Worker   void move (const number_t &dx, const number_t &dy) { move_x (dx); move_y (dy); }
moveCFF::point_t106*2d1272b8SAndroid Build Coastguard Worker   void move (const point_t &d) { move_x (d.x); move_y (d.y); }
107*2d1272b8SAndroid Build Coastguard Worker 
108*2d1272b8SAndroid Build Coastguard Worker   number_t  x;
109*2d1272b8SAndroid Build Coastguard Worker   number_t  y;
110*2d1272b8SAndroid Build Coastguard Worker };
111*2d1272b8SAndroid Build Coastguard Worker 
112*2d1272b8SAndroid Build Coastguard Worker template <typename ARG, typename SUBRS>
113*2d1272b8SAndroid Build Coastguard Worker struct cs_interp_env_t : interp_env_t<ARG>
114*2d1272b8SAndroid Build Coastguard Worker {
cs_interp_env_tCFF::cs_interp_env_t115*2d1272b8SAndroid Build Coastguard Worker   cs_interp_env_t (const hb_ubytes_t &str, const SUBRS *globalSubrs_, const SUBRS *localSubrs_) :
116*2d1272b8SAndroid Build Coastguard Worker     interp_env_t<ARG> (str)
117*2d1272b8SAndroid Build Coastguard Worker   {
118*2d1272b8SAndroid Build Coastguard Worker     context.init (str, CSType_CharString);
119*2d1272b8SAndroid Build Coastguard Worker     seen_moveto = true;
120*2d1272b8SAndroid Build Coastguard Worker     seen_hintmask = false;
121*2d1272b8SAndroid Build Coastguard Worker     hstem_count = 0;
122*2d1272b8SAndroid Build Coastguard Worker     vstem_count = 0;
123*2d1272b8SAndroid Build Coastguard Worker     hintmask_size = 0;
124*2d1272b8SAndroid Build Coastguard Worker     pt.set_int (0, 0);
125*2d1272b8SAndroid Build Coastguard Worker     globalSubrs.init (globalSubrs_);
126*2d1272b8SAndroid Build Coastguard Worker     localSubrs.init (localSubrs_);
127*2d1272b8SAndroid Build Coastguard Worker   }
~cs_interp_env_tCFF::cs_interp_env_t128*2d1272b8SAndroid Build Coastguard Worker   ~cs_interp_env_t ()
129*2d1272b8SAndroid Build Coastguard Worker   {
130*2d1272b8SAndroid Build Coastguard Worker     globalSubrs.fini ();
131*2d1272b8SAndroid Build Coastguard Worker     localSubrs.fini ();
132*2d1272b8SAndroid Build Coastguard Worker   }
133*2d1272b8SAndroid Build Coastguard Worker 
in_errorCFF::cs_interp_env_t134*2d1272b8SAndroid Build Coastguard Worker   bool in_error () const
135*2d1272b8SAndroid Build Coastguard Worker   {
136*2d1272b8SAndroid Build Coastguard Worker     return callStack.in_error () || SUPER::in_error ();
137*2d1272b8SAndroid Build Coastguard Worker   }
138*2d1272b8SAndroid Build Coastguard Worker 
pop_subr_numCFF::cs_interp_env_t139*2d1272b8SAndroid Build Coastguard Worker   bool pop_subr_num (const biased_subrs_t<SUBRS>& biasedSubrs, unsigned int &subr_num)
140*2d1272b8SAndroid Build Coastguard Worker   {
141*2d1272b8SAndroid Build Coastguard Worker     subr_num = 0;
142*2d1272b8SAndroid Build Coastguard Worker     int n = SUPER::argStack.pop_int ();
143*2d1272b8SAndroid Build Coastguard Worker     n += biasedSubrs.get_bias ();
144*2d1272b8SAndroid Build Coastguard Worker     if (unlikely ((n < 0) || ((unsigned int)n >= biasedSubrs.get_count ())))
145*2d1272b8SAndroid Build Coastguard Worker       return false;
146*2d1272b8SAndroid Build Coastguard Worker 
147*2d1272b8SAndroid Build Coastguard Worker     subr_num = (unsigned int)n;
148*2d1272b8SAndroid Build Coastguard Worker     return true;
149*2d1272b8SAndroid Build Coastguard Worker   }
150*2d1272b8SAndroid Build Coastguard Worker 
call_subrCFF::cs_interp_env_t151*2d1272b8SAndroid Build Coastguard Worker   void call_subr (const biased_subrs_t<SUBRS>& biasedSubrs, cs_type_t type)
152*2d1272b8SAndroid Build Coastguard Worker   {
153*2d1272b8SAndroid Build Coastguard Worker     unsigned int subr_num = 0;
154*2d1272b8SAndroid Build Coastguard Worker 
155*2d1272b8SAndroid Build Coastguard Worker     if (unlikely (!pop_subr_num (biasedSubrs, subr_num)
156*2d1272b8SAndroid Build Coastguard Worker 		 || callStack.get_count () >= kMaxCallLimit))
157*2d1272b8SAndroid Build Coastguard Worker     {
158*2d1272b8SAndroid Build Coastguard Worker       SUPER::set_error ();
159*2d1272b8SAndroid Build Coastguard Worker       return;
160*2d1272b8SAndroid Build Coastguard Worker     }
161*2d1272b8SAndroid Build Coastguard Worker     context.str_ref = SUPER::str_ref;
162*2d1272b8SAndroid Build Coastguard Worker     callStack.push (context);
163*2d1272b8SAndroid Build Coastguard Worker 
164*2d1272b8SAndroid Build Coastguard Worker     context.init ( biasedSubrs[subr_num], type, subr_num);
165*2d1272b8SAndroid Build Coastguard Worker     SUPER::str_ref = context.str_ref;
166*2d1272b8SAndroid Build Coastguard Worker   }
167*2d1272b8SAndroid Build Coastguard Worker 
return_from_subrCFF::cs_interp_env_t168*2d1272b8SAndroid Build Coastguard Worker   void return_from_subr ()
169*2d1272b8SAndroid Build Coastguard Worker   {
170*2d1272b8SAndroid Build Coastguard Worker     if (unlikely (SUPER::str_ref.in_error ()))
171*2d1272b8SAndroid Build Coastguard Worker       SUPER::set_error ();
172*2d1272b8SAndroid Build Coastguard Worker     context = callStack.pop ();
173*2d1272b8SAndroid Build Coastguard Worker     SUPER::str_ref = context.str_ref;
174*2d1272b8SAndroid Build Coastguard Worker   }
175*2d1272b8SAndroid Build Coastguard Worker 
determine_hintmask_sizeCFF::cs_interp_env_t176*2d1272b8SAndroid Build Coastguard Worker   void determine_hintmask_size ()
177*2d1272b8SAndroid Build Coastguard Worker   {
178*2d1272b8SAndroid Build Coastguard Worker     if (!seen_hintmask)
179*2d1272b8SAndroid Build Coastguard Worker     {
180*2d1272b8SAndroid Build Coastguard Worker       vstem_count += SUPER::argStack.get_count() / 2;
181*2d1272b8SAndroid Build Coastguard Worker       hintmask_size = (hstem_count + vstem_count + 7) >> 3;
182*2d1272b8SAndroid Build Coastguard Worker       seen_hintmask = true;
183*2d1272b8SAndroid Build Coastguard Worker     }
184*2d1272b8SAndroid Build Coastguard Worker   }
185*2d1272b8SAndroid Build Coastguard Worker 
set_endcharCFF::cs_interp_env_t186*2d1272b8SAndroid Build Coastguard Worker   void set_endchar (bool endchar_flag_) { endchar_flag = endchar_flag_; }
is_endcharCFF::cs_interp_env_t187*2d1272b8SAndroid Build Coastguard Worker   bool is_endchar () const { return endchar_flag; }
188*2d1272b8SAndroid Build Coastguard Worker 
get_xCFF::cs_interp_env_t189*2d1272b8SAndroid Build Coastguard Worker   const number_t &get_x () const { return pt.x; }
get_yCFF::cs_interp_env_t190*2d1272b8SAndroid Build Coastguard Worker   const number_t &get_y () const { return pt.y; }
get_ptCFF::cs_interp_env_t191*2d1272b8SAndroid Build Coastguard Worker   const point_t &get_pt () const { return pt; }
192*2d1272b8SAndroid Build Coastguard Worker 
movetoCFF::cs_interp_env_t193*2d1272b8SAndroid Build Coastguard Worker   void moveto (const point_t &pt_ ) { pt = pt_; }
194*2d1272b8SAndroid Build Coastguard Worker 
195*2d1272b8SAndroid Build Coastguard Worker   public:
196*2d1272b8SAndroid Build Coastguard Worker   call_context_t   context;
197*2d1272b8SAndroid Build Coastguard Worker   bool	  endchar_flag;
198*2d1272b8SAndroid Build Coastguard Worker   bool	  seen_moveto;
199*2d1272b8SAndroid Build Coastguard Worker   bool	  seen_hintmask;
200*2d1272b8SAndroid Build Coastguard Worker 
201*2d1272b8SAndroid Build Coastguard Worker   unsigned int  hstem_count;
202*2d1272b8SAndroid Build Coastguard Worker   unsigned int  vstem_count;
203*2d1272b8SAndroid Build Coastguard Worker   unsigned int  hintmask_size;
204*2d1272b8SAndroid Build Coastguard Worker   call_stack_t	callStack;
205*2d1272b8SAndroid Build Coastguard Worker   biased_subrs_t<SUBRS>   globalSubrs;
206*2d1272b8SAndroid Build Coastguard Worker   biased_subrs_t<SUBRS>   localSubrs;
207*2d1272b8SAndroid Build Coastguard Worker 
208*2d1272b8SAndroid Build Coastguard Worker   private:
209*2d1272b8SAndroid Build Coastguard Worker   point_t	 pt;
210*2d1272b8SAndroid Build Coastguard Worker 
211*2d1272b8SAndroid Build Coastguard Worker   typedef interp_env_t<ARG> SUPER;
212*2d1272b8SAndroid Build Coastguard Worker };
213*2d1272b8SAndroid Build Coastguard Worker 
214*2d1272b8SAndroid Build Coastguard Worker template <typename ENV, typename PARAM>
215*2d1272b8SAndroid Build Coastguard Worker struct path_procs_null_t
216*2d1272b8SAndroid Build Coastguard Worker {
rmovetoCFF::path_procs_null_t217*2d1272b8SAndroid Build Coastguard Worker   static void rmoveto (ENV &env, PARAM& param) {}
hmovetoCFF::path_procs_null_t218*2d1272b8SAndroid Build Coastguard Worker   static void hmoveto (ENV &env, PARAM& param) {}
vmovetoCFF::path_procs_null_t219*2d1272b8SAndroid Build Coastguard Worker   static void vmoveto (ENV &env, PARAM& param) {}
rlinetoCFF::path_procs_null_t220*2d1272b8SAndroid Build Coastguard Worker   static void rlineto (ENV &env, PARAM& param) {}
hlinetoCFF::path_procs_null_t221*2d1272b8SAndroid Build Coastguard Worker   static void hlineto (ENV &env, PARAM& param) {}
vlinetoCFF::path_procs_null_t222*2d1272b8SAndroid Build Coastguard Worker   static void vlineto (ENV &env, PARAM& param) {}
rrcurvetoCFF::path_procs_null_t223*2d1272b8SAndroid Build Coastguard Worker   static void rrcurveto (ENV &env, PARAM& param) {}
rcurvelineCFF::path_procs_null_t224*2d1272b8SAndroid Build Coastguard Worker   static void rcurveline (ENV &env, PARAM& param) {}
rlinecurveCFF::path_procs_null_t225*2d1272b8SAndroid Build Coastguard Worker   static void rlinecurve (ENV &env, PARAM& param) {}
vvcurvetoCFF::path_procs_null_t226*2d1272b8SAndroid Build Coastguard Worker   static void vvcurveto (ENV &env, PARAM& param) {}
hhcurvetoCFF::path_procs_null_t227*2d1272b8SAndroid Build Coastguard Worker   static void hhcurveto (ENV &env, PARAM& param) {}
vhcurvetoCFF::path_procs_null_t228*2d1272b8SAndroid Build Coastguard Worker   static void vhcurveto (ENV &env, PARAM& param) {}
hvcurvetoCFF::path_procs_null_t229*2d1272b8SAndroid Build Coastguard Worker   static void hvcurveto (ENV &env, PARAM& param) {}
movetoCFF::path_procs_null_t230*2d1272b8SAndroid Build Coastguard Worker   static void moveto (ENV &env, PARAM& param, const point_t &pt) {}
lineCFF::path_procs_null_t231*2d1272b8SAndroid Build Coastguard Worker   static void line (ENV &env, PARAM& param, const point_t &pt1) {}
curveCFF::path_procs_null_t232*2d1272b8SAndroid Build Coastguard Worker   static void curve (ENV &env, PARAM& param, const point_t &pt1, const point_t &pt2, const point_t &pt3) {}
hflexCFF::path_procs_null_t233*2d1272b8SAndroid Build Coastguard Worker   static void hflex (ENV &env, PARAM& param) {}
flexCFF::path_procs_null_t234*2d1272b8SAndroid Build Coastguard Worker   static void flex (ENV &env, PARAM& param) {}
hflex1CFF::path_procs_null_t235*2d1272b8SAndroid Build Coastguard Worker   static void hflex1 (ENV &env, PARAM& param) {}
flex1CFF::path_procs_null_t236*2d1272b8SAndroid Build Coastguard Worker   static void flex1 (ENV &env, PARAM& param) {}
237*2d1272b8SAndroid Build Coastguard Worker };
238*2d1272b8SAndroid Build Coastguard Worker 
239*2d1272b8SAndroid Build Coastguard Worker template <typename ARG, typename OPSET, typename ENV, typename PARAM, typename PATH=path_procs_null_t<ENV, PARAM>>
240*2d1272b8SAndroid Build Coastguard Worker struct cs_opset_t : opset_t<ARG>
241*2d1272b8SAndroid Build Coastguard Worker {
process_opCFF::cs_opset_t242*2d1272b8SAndroid Build Coastguard Worker   static void process_op (op_code_t op, ENV &env, PARAM& param)
243*2d1272b8SAndroid Build Coastguard Worker   {
244*2d1272b8SAndroid Build Coastguard Worker     switch (op) {
245*2d1272b8SAndroid Build Coastguard Worker 
246*2d1272b8SAndroid Build Coastguard Worker       case OpCode_return:
247*2d1272b8SAndroid Build Coastguard Worker 	env.return_from_subr ();
248*2d1272b8SAndroid Build Coastguard Worker 	break;
249*2d1272b8SAndroid Build Coastguard Worker       case OpCode_endchar:
250*2d1272b8SAndroid Build Coastguard Worker 	OPSET::check_width (op, env, param);
251*2d1272b8SAndroid Build Coastguard Worker 	env.set_endchar (true);
252*2d1272b8SAndroid Build Coastguard Worker 	OPSET::flush_args_and_op (op, env, param);
253*2d1272b8SAndroid Build Coastguard Worker 	break;
254*2d1272b8SAndroid Build Coastguard Worker 
255*2d1272b8SAndroid Build Coastguard Worker       case OpCode_fixedcs:
256*2d1272b8SAndroid Build Coastguard Worker 	env.argStack.push_fixed_from_substr (env.str_ref);
257*2d1272b8SAndroid Build Coastguard Worker 	break;
258*2d1272b8SAndroid Build Coastguard Worker 
259*2d1272b8SAndroid Build Coastguard Worker       case OpCode_callsubr:
260*2d1272b8SAndroid Build Coastguard Worker 	env.call_subr (env.localSubrs, CSType_LocalSubr);
261*2d1272b8SAndroid Build Coastguard Worker 	break;
262*2d1272b8SAndroid Build Coastguard Worker 
263*2d1272b8SAndroid Build Coastguard Worker       case OpCode_callgsubr:
264*2d1272b8SAndroid Build Coastguard Worker 	env.call_subr (env.globalSubrs, CSType_GlobalSubr);
265*2d1272b8SAndroid Build Coastguard Worker 	break;
266*2d1272b8SAndroid Build Coastguard Worker 
267*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hstem:
268*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hstemhm:
269*2d1272b8SAndroid Build Coastguard Worker 	OPSET::check_width (op, env, param);
270*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_hstem (op, env, param);
271*2d1272b8SAndroid Build Coastguard Worker 	break;
272*2d1272b8SAndroid Build Coastguard Worker       case OpCode_vstem:
273*2d1272b8SAndroid Build Coastguard Worker       case OpCode_vstemhm:
274*2d1272b8SAndroid Build Coastguard Worker 	OPSET::check_width (op, env, param);
275*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_vstem (op, env, param);
276*2d1272b8SAndroid Build Coastguard Worker 	break;
277*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hintmask:
278*2d1272b8SAndroid Build Coastguard Worker       case OpCode_cntrmask:
279*2d1272b8SAndroid Build Coastguard Worker 	OPSET::check_width (op, env, param);
280*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_hintmask (op, env, param);
281*2d1272b8SAndroid Build Coastguard Worker 	break;
282*2d1272b8SAndroid Build Coastguard Worker       case OpCode_rmoveto:
283*2d1272b8SAndroid Build Coastguard Worker 	OPSET::check_width (op, env, param);
284*2d1272b8SAndroid Build Coastguard Worker 	PATH::rmoveto (env, param);
285*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_post_move (op, env, param);
286*2d1272b8SAndroid Build Coastguard Worker 	break;
287*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hmoveto:
288*2d1272b8SAndroid Build Coastguard Worker 	OPSET::check_width (op, env, param);
289*2d1272b8SAndroid Build Coastguard Worker 	PATH::hmoveto (env, param);
290*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_post_move (op, env, param);
291*2d1272b8SAndroid Build Coastguard Worker 	break;
292*2d1272b8SAndroid Build Coastguard Worker       case OpCode_vmoveto:
293*2d1272b8SAndroid Build Coastguard Worker 	OPSET::check_width (op, env, param);
294*2d1272b8SAndroid Build Coastguard Worker 	PATH::vmoveto (env, param);
295*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_post_move (op, env, param);
296*2d1272b8SAndroid Build Coastguard Worker 	break;
297*2d1272b8SAndroid Build Coastguard Worker       case OpCode_rlineto:
298*2d1272b8SAndroid Build Coastguard Worker 	PATH::rlineto (env, param);
299*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
300*2d1272b8SAndroid Build Coastguard Worker 	break;
301*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hlineto:
302*2d1272b8SAndroid Build Coastguard Worker 	PATH::hlineto (env, param);
303*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
304*2d1272b8SAndroid Build Coastguard Worker 	break;
305*2d1272b8SAndroid Build Coastguard Worker       case OpCode_vlineto:
306*2d1272b8SAndroid Build Coastguard Worker 	PATH::vlineto (env, param);
307*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
308*2d1272b8SAndroid Build Coastguard Worker 	break;
309*2d1272b8SAndroid Build Coastguard Worker       case OpCode_rrcurveto:
310*2d1272b8SAndroid Build Coastguard Worker 	PATH::rrcurveto (env, param);
311*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
312*2d1272b8SAndroid Build Coastguard Worker 	break;
313*2d1272b8SAndroid Build Coastguard Worker       case OpCode_rcurveline:
314*2d1272b8SAndroid Build Coastguard Worker 	PATH::rcurveline (env, param);
315*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
316*2d1272b8SAndroid Build Coastguard Worker 	break;
317*2d1272b8SAndroid Build Coastguard Worker       case OpCode_rlinecurve:
318*2d1272b8SAndroid Build Coastguard Worker 	PATH::rlinecurve (env, param);
319*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
320*2d1272b8SAndroid Build Coastguard Worker 	break;
321*2d1272b8SAndroid Build Coastguard Worker       case OpCode_vvcurveto:
322*2d1272b8SAndroid Build Coastguard Worker 	PATH::vvcurveto (env, param);
323*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
324*2d1272b8SAndroid Build Coastguard Worker 	break;
325*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hhcurveto:
326*2d1272b8SAndroid Build Coastguard Worker 	PATH::hhcurveto (env, param);
327*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
328*2d1272b8SAndroid Build Coastguard Worker 	break;
329*2d1272b8SAndroid Build Coastguard Worker       case OpCode_vhcurveto:
330*2d1272b8SAndroid Build Coastguard Worker 	PATH::vhcurveto (env, param);
331*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
332*2d1272b8SAndroid Build Coastguard Worker 	break;
333*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hvcurveto:
334*2d1272b8SAndroid Build Coastguard Worker 	PATH::hvcurveto (env, param);
335*2d1272b8SAndroid Build Coastguard Worker 	process_post_path (op, env, param);
336*2d1272b8SAndroid Build Coastguard Worker 	break;
337*2d1272b8SAndroid Build Coastguard Worker 
338*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hflex:
339*2d1272b8SAndroid Build Coastguard Worker 	PATH::hflex (env, param);
340*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_post_flex (op, env, param);
341*2d1272b8SAndroid Build Coastguard Worker 	break;
342*2d1272b8SAndroid Build Coastguard Worker 
343*2d1272b8SAndroid Build Coastguard Worker       case OpCode_flex:
344*2d1272b8SAndroid Build Coastguard Worker 	PATH::flex (env, param);
345*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_post_flex (op, env, param);
346*2d1272b8SAndroid Build Coastguard Worker 	break;
347*2d1272b8SAndroid Build Coastguard Worker 
348*2d1272b8SAndroid Build Coastguard Worker       case OpCode_hflex1:
349*2d1272b8SAndroid Build Coastguard Worker 	PATH::hflex1 (env, param);
350*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_post_flex (op, env, param);
351*2d1272b8SAndroid Build Coastguard Worker 	break;
352*2d1272b8SAndroid Build Coastguard Worker 
353*2d1272b8SAndroid Build Coastguard Worker       case OpCode_flex1:
354*2d1272b8SAndroid Build Coastguard Worker 	PATH::flex1 (env, param);
355*2d1272b8SAndroid Build Coastguard Worker 	OPSET::process_post_flex (op, env, param);
356*2d1272b8SAndroid Build Coastguard Worker 	break;
357*2d1272b8SAndroid Build Coastguard Worker 
358*2d1272b8SAndroid Build Coastguard Worker       default:
359*2d1272b8SAndroid Build Coastguard Worker 	SUPER::process_op (op, env);
360*2d1272b8SAndroid Build Coastguard Worker 	break;
361*2d1272b8SAndroid Build Coastguard Worker     }
362*2d1272b8SAndroid Build Coastguard Worker   }
363*2d1272b8SAndroid Build Coastguard Worker 
process_hstemCFF::cs_opset_t364*2d1272b8SAndroid Build Coastguard Worker   static void process_hstem (op_code_t op, ENV &env, PARAM& param)
365*2d1272b8SAndroid Build Coastguard Worker   {
366*2d1272b8SAndroid Build Coastguard Worker     env.hstem_count += env.argStack.get_count () / 2;
367*2d1272b8SAndroid Build Coastguard Worker     OPSET::flush_args_and_op (op, env, param);
368*2d1272b8SAndroid Build Coastguard Worker   }
369*2d1272b8SAndroid Build Coastguard Worker 
process_vstemCFF::cs_opset_t370*2d1272b8SAndroid Build Coastguard Worker   static void process_vstem (op_code_t op, ENV &env, PARAM& param)
371*2d1272b8SAndroid Build Coastguard Worker   {
372*2d1272b8SAndroid Build Coastguard Worker     env.vstem_count += env.argStack.get_count () / 2;
373*2d1272b8SAndroid Build Coastguard Worker     OPSET::flush_args_and_op (op, env, param);
374*2d1272b8SAndroid Build Coastguard Worker   }
375*2d1272b8SAndroid Build Coastguard Worker 
process_hintmaskCFF::cs_opset_t376*2d1272b8SAndroid Build Coastguard Worker   static void process_hintmask (op_code_t op, ENV &env, PARAM& param)
377*2d1272b8SAndroid Build Coastguard Worker   {
378*2d1272b8SAndroid Build Coastguard Worker     env.determine_hintmask_size ();
379*2d1272b8SAndroid Build Coastguard Worker     if (likely (env.str_ref.avail (env.hintmask_size)))
380*2d1272b8SAndroid Build Coastguard Worker     {
381*2d1272b8SAndroid Build Coastguard Worker       OPSET::flush_hintmask (op, env, param);
382*2d1272b8SAndroid Build Coastguard Worker       env.str_ref.inc (env.hintmask_size);
383*2d1272b8SAndroid Build Coastguard Worker     }
384*2d1272b8SAndroid Build Coastguard Worker   }
385*2d1272b8SAndroid Build Coastguard Worker 
process_post_flexCFF::cs_opset_t386*2d1272b8SAndroid Build Coastguard Worker   static void process_post_flex (op_code_t op, ENV &env, PARAM& param)
387*2d1272b8SAndroid Build Coastguard Worker   {
388*2d1272b8SAndroid Build Coastguard Worker     OPSET::flush_args_and_op (op, env, param);
389*2d1272b8SAndroid Build Coastguard Worker   }
390*2d1272b8SAndroid Build Coastguard Worker 
check_widthCFF::cs_opset_t391*2d1272b8SAndroid Build Coastguard Worker   static void check_width (op_code_t op, ENV &env, PARAM& param)
392*2d1272b8SAndroid Build Coastguard Worker   {}
393*2d1272b8SAndroid Build Coastguard Worker 
process_post_moveCFF::cs_opset_t394*2d1272b8SAndroid Build Coastguard Worker   static void process_post_move (op_code_t op, ENV &env, PARAM& param)
395*2d1272b8SAndroid Build Coastguard Worker   {
396*2d1272b8SAndroid Build Coastguard Worker     if (!env.seen_moveto)
397*2d1272b8SAndroid Build Coastguard Worker     {
398*2d1272b8SAndroid Build Coastguard Worker       env.determine_hintmask_size ();
399*2d1272b8SAndroid Build Coastguard Worker       env.seen_moveto = true;
400*2d1272b8SAndroid Build Coastguard Worker     }
401*2d1272b8SAndroid Build Coastguard Worker     OPSET::flush_args_and_op (op, env, param);
402*2d1272b8SAndroid Build Coastguard Worker   }
403*2d1272b8SAndroid Build Coastguard Worker 
process_post_pathCFF::cs_opset_t404*2d1272b8SAndroid Build Coastguard Worker   static void process_post_path (op_code_t op, ENV &env, PARAM& param)
405*2d1272b8SAndroid Build Coastguard Worker   {
406*2d1272b8SAndroid Build Coastguard Worker     OPSET::flush_args_and_op (op, env, param);
407*2d1272b8SAndroid Build Coastguard Worker   }
408*2d1272b8SAndroid Build Coastguard Worker 
flush_args_and_opCFF::cs_opset_t409*2d1272b8SAndroid Build Coastguard Worker   static void flush_args_and_op (op_code_t op, ENV &env, PARAM& param)
410*2d1272b8SAndroid Build Coastguard Worker   {
411*2d1272b8SAndroid Build Coastguard Worker     OPSET::flush_args (env, param);
412*2d1272b8SAndroid Build Coastguard Worker     OPSET::flush_op (op, env, param);
413*2d1272b8SAndroid Build Coastguard Worker   }
414*2d1272b8SAndroid Build Coastguard Worker 
flush_argsCFF::cs_opset_t415*2d1272b8SAndroid Build Coastguard Worker   static void flush_args (ENV &env, PARAM& param)
416*2d1272b8SAndroid Build Coastguard Worker   {
417*2d1272b8SAndroid Build Coastguard Worker     env.pop_n_args (env.argStack.get_count ());
418*2d1272b8SAndroid Build Coastguard Worker   }
419*2d1272b8SAndroid Build Coastguard Worker 
flush_opCFF::cs_opset_t420*2d1272b8SAndroid Build Coastguard Worker   static void flush_op (op_code_t op, ENV &env, PARAM& param)
421*2d1272b8SAndroid Build Coastguard Worker   {
422*2d1272b8SAndroid Build Coastguard Worker   }
423*2d1272b8SAndroid Build Coastguard Worker 
flush_hintmaskCFF::cs_opset_t424*2d1272b8SAndroid Build Coastguard Worker   static void flush_hintmask (op_code_t op, ENV &env, PARAM& param)
425*2d1272b8SAndroid Build Coastguard Worker   {
426*2d1272b8SAndroid Build Coastguard Worker     OPSET::flush_args_and_op (op, env, param);
427*2d1272b8SAndroid Build Coastguard Worker   }
428*2d1272b8SAndroid Build Coastguard Worker 
is_number_opCFF::cs_opset_t429*2d1272b8SAndroid Build Coastguard Worker   static bool is_number_op (op_code_t op)
430*2d1272b8SAndroid Build Coastguard Worker   {
431*2d1272b8SAndroid Build Coastguard Worker     switch (op)
432*2d1272b8SAndroid Build Coastguard Worker     {
433*2d1272b8SAndroid Build Coastguard Worker       case OpCode_shortint:
434*2d1272b8SAndroid Build Coastguard Worker       case OpCode_fixedcs:
435*2d1272b8SAndroid Build Coastguard Worker       case OpCode_TwoBytePosInt0: case OpCode_TwoBytePosInt1:
436*2d1272b8SAndroid Build Coastguard Worker       case OpCode_TwoBytePosInt2: case OpCode_TwoBytePosInt3:
437*2d1272b8SAndroid Build Coastguard Worker       case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1:
438*2d1272b8SAndroid Build Coastguard Worker       case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3:
439*2d1272b8SAndroid Build Coastguard Worker 	return true;
440*2d1272b8SAndroid Build Coastguard Worker 
441*2d1272b8SAndroid Build Coastguard Worker       default:
442*2d1272b8SAndroid Build Coastguard Worker 	/* 1-byte integer */
443*2d1272b8SAndroid Build Coastguard Worker 	return (OpCode_OneByteIntFirst <= op) && (op <= OpCode_OneByteIntLast);
444*2d1272b8SAndroid Build Coastguard Worker     }
445*2d1272b8SAndroid Build Coastguard Worker   }
446*2d1272b8SAndroid Build Coastguard Worker 
447*2d1272b8SAndroid Build Coastguard Worker   protected:
448*2d1272b8SAndroid Build Coastguard Worker   typedef opset_t<ARG>  SUPER;
449*2d1272b8SAndroid Build Coastguard Worker };
450*2d1272b8SAndroid Build Coastguard Worker 
451*2d1272b8SAndroid Build Coastguard Worker template <typename PATH, typename ENV, typename PARAM>
452*2d1272b8SAndroid Build Coastguard Worker struct path_procs_t
453*2d1272b8SAndroid Build Coastguard Worker {
rmovetoCFF::path_procs_t454*2d1272b8SAndroid Build Coastguard Worker   static void rmoveto (ENV &env, PARAM& param)
455*2d1272b8SAndroid Build Coastguard Worker   {
456*2d1272b8SAndroid Build Coastguard Worker     point_t pt1 = env.get_pt ();
457*2d1272b8SAndroid Build Coastguard Worker     const number_t &dy = env.pop_arg ();
458*2d1272b8SAndroid Build Coastguard Worker     const number_t &dx = env.pop_arg ();
459*2d1272b8SAndroid Build Coastguard Worker     pt1.move (dx, dy);
460*2d1272b8SAndroid Build Coastguard Worker     PATH::moveto (env, param, pt1);
461*2d1272b8SAndroid Build Coastguard Worker   }
462*2d1272b8SAndroid Build Coastguard Worker 
hmovetoCFF::path_procs_t463*2d1272b8SAndroid Build Coastguard Worker   static void hmoveto (ENV &env, PARAM& param)
464*2d1272b8SAndroid Build Coastguard Worker   {
465*2d1272b8SAndroid Build Coastguard Worker     point_t pt1 = env.get_pt ();
466*2d1272b8SAndroid Build Coastguard Worker     pt1.move_x (env.pop_arg ());
467*2d1272b8SAndroid Build Coastguard Worker     PATH::moveto (env, param, pt1);
468*2d1272b8SAndroid Build Coastguard Worker   }
469*2d1272b8SAndroid Build Coastguard Worker 
vmovetoCFF::path_procs_t470*2d1272b8SAndroid Build Coastguard Worker   static void vmoveto (ENV &env, PARAM& param)
471*2d1272b8SAndroid Build Coastguard Worker   {
472*2d1272b8SAndroid Build Coastguard Worker     point_t pt1 = env.get_pt ();
473*2d1272b8SAndroid Build Coastguard Worker     pt1.move_y (env.pop_arg ());
474*2d1272b8SAndroid Build Coastguard Worker     PATH::moveto (env, param, pt1);
475*2d1272b8SAndroid Build Coastguard Worker   }
476*2d1272b8SAndroid Build Coastguard Worker 
rlinetoCFF::path_procs_t477*2d1272b8SAndroid Build Coastguard Worker   static void rlineto (ENV &env, PARAM& param)
478*2d1272b8SAndroid Build Coastguard Worker   {
479*2d1272b8SAndroid Build Coastguard Worker     for (unsigned int i = 0; i + 2 <= env.argStack.get_count (); i += 2)
480*2d1272b8SAndroid Build Coastguard Worker     {
481*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
482*2d1272b8SAndroid Build Coastguard Worker       pt1.move (env.eval_arg (i), env.eval_arg (i+1));
483*2d1272b8SAndroid Build Coastguard Worker       PATH::line (env, param, pt1);
484*2d1272b8SAndroid Build Coastguard Worker     }
485*2d1272b8SAndroid Build Coastguard Worker   }
486*2d1272b8SAndroid Build Coastguard Worker 
hlinetoCFF::path_procs_t487*2d1272b8SAndroid Build Coastguard Worker   static void hlineto (ENV &env, PARAM& param)
488*2d1272b8SAndroid Build Coastguard Worker   {
489*2d1272b8SAndroid Build Coastguard Worker     point_t pt1;
490*2d1272b8SAndroid Build Coastguard Worker     unsigned int i = 0;
491*2d1272b8SAndroid Build Coastguard Worker     for (; i + 2 <= env.argStack.get_count (); i += 2)
492*2d1272b8SAndroid Build Coastguard Worker     {
493*2d1272b8SAndroid Build Coastguard Worker       pt1 = env.get_pt ();
494*2d1272b8SAndroid Build Coastguard Worker       pt1.move_x (env.eval_arg (i));
495*2d1272b8SAndroid Build Coastguard Worker       PATH::line (env, param, pt1);
496*2d1272b8SAndroid Build Coastguard Worker       pt1.move_y (env.eval_arg (i+1));
497*2d1272b8SAndroid Build Coastguard Worker       PATH::line (env, param, pt1);
498*2d1272b8SAndroid Build Coastguard Worker     }
499*2d1272b8SAndroid Build Coastguard Worker     if (i < env.argStack.get_count ())
500*2d1272b8SAndroid Build Coastguard Worker     {
501*2d1272b8SAndroid Build Coastguard Worker       pt1 = env.get_pt ();
502*2d1272b8SAndroid Build Coastguard Worker       pt1.move_x (env.eval_arg (i));
503*2d1272b8SAndroid Build Coastguard Worker       PATH::line (env, param, pt1);
504*2d1272b8SAndroid Build Coastguard Worker     }
505*2d1272b8SAndroid Build Coastguard Worker   }
506*2d1272b8SAndroid Build Coastguard Worker 
vlinetoCFF::path_procs_t507*2d1272b8SAndroid Build Coastguard Worker   static void vlineto (ENV &env, PARAM& param)
508*2d1272b8SAndroid Build Coastguard Worker   {
509*2d1272b8SAndroid Build Coastguard Worker     point_t pt1;
510*2d1272b8SAndroid Build Coastguard Worker     unsigned int i = 0;
511*2d1272b8SAndroid Build Coastguard Worker     for (; i + 2 <= env.argStack.get_count (); i += 2)
512*2d1272b8SAndroid Build Coastguard Worker     {
513*2d1272b8SAndroid Build Coastguard Worker       pt1 = env.get_pt ();
514*2d1272b8SAndroid Build Coastguard Worker       pt1.move_y (env.eval_arg (i));
515*2d1272b8SAndroid Build Coastguard Worker       PATH::line (env, param, pt1);
516*2d1272b8SAndroid Build Coastguard Worker       pt1.move_x (env.eval_arg (i+1));
517*2d1272b8SAndroid Build Coastguard Worker       PATH::line (env, param, pt1);
518*2d1272b8SAndroid Build Coastguard Worker     }
519*2d1272b8SAndroid Build Coastguard Worker     if (i < env.argStack.get_count ())
520*2d1272b8SAndroid Build Coastguard Worker     {
521*2d1272b8SAndroid Build Coastguard Worker       pt1 = env.get_pt ();
522*2d1272b8SAndroid Build Coastguard Worker       pt1.move_y (env.eval_arg (i));
523*2d1272b8SAndroid Build Coastguard Worker       PATH::line (env, param, pt1);
524*2d1272b8SAndroid Build Coastguard Worker     }
525*2d1272b8SAndroid Build Coastguard Worker   }
526*2d1272b8SAndroid Build Coastguard Worker 
rrcurvetoCFF::path_procs_t527*2d1272b8SAndroid Build Coastguard Worker   static void rrcurveto (ENV &env, PARAM& param)
528*2d1272b8SAndroid Build Coastguard Worker   {
529*2d1272b8SAndroid Build Coastguard Worker     for (unsigned int i = 0; i + 6 <= env.argStack.get_count (); i += 6)
530*2d1272b8SAndroid Build Coastguard Worker     {
531*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
532*2d1272b8SAndroid Build Coastguard Worker       pt1.move (env.eval_arg (i), env.eval_arg (i+1));
533*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
534*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (i+2), env.eval_arg (i+3));
535*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
536*2d1272b8SAndroid Build Coastguard Worker       pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
537*2d1272b8SAndroid Build Coastguard Worker       PATH::curve (env, param, pt1, pt2, pt3);
538*2d1272b8SAndroid Build Coastguard Worker     }
539*2d1272b8SAndroid Build Coastguard Worker   }
540*2d1272b8SAndroid Build Coastguard Worker 
rcurvelineCFF::path_procs_t541*2d1272b8SAndroid Build Coastguard Worker   static void rcurveline (ENV &env, PARAM& param)
542*2d1272b8SAndroid Build Coastguard Worker   {
543*2d1272b8SAndroid Build Coastguard Worker     unsigned int arg_count = env.argStack.get_count ();
544*2d1272b8SAndroid Build Coastguard Worker     if (unlikely (arg_count < 8))
545*2d1272b8SAndroid Build Coastguard Worker       return;
546*2d1272b8SAndroid Build Coastguard Worker 
547*2d1272b8SAndroid Build Coastguard Worker     unsigned int i = 0;
548*2d1272b8SAndroid Build Coastguard Worker     unsigned int curve_limit = arg_count - 2;
549*2d1272b8SAndroid Build Coastguard Worker     for (; i + 6 <= curve_limit; i += 6)
550*2d1272b8SAndroid Build Coastguard Worker     {
551*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
552*2d1272b8SAndroid Build Coastguard Worker       pt1.move (env.eval_arg (i), env.eval_arg (i+1));
553*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
554*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (i+2), env.eval_arg (i+3));
555*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
556*2d1272b8SAndroid Build Coastguard Worker       pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
557*2d1272b8SAndroid Build Coastguard Worker       PATH::curve (env, param, pt1, pt2, pt3);
558*2d1272b8SAndroid Build Coastguard Worker     }
559*2d1272b8SAndroid Build Coastguard Worker 
560*2d1272b8SAndroid Build Coastguard Worker     point_t pt1 = env.get_pt ();
561*2d1272b8SAndroid Build Coastguard Worker     pt1.move (env.eval_arg (i), env.eval_arg (i+1));
562*2d1272b8SAndroid Build Coastguard Worker     PATH::line (env, param, pt1);
563*2d1272b8SAndroid Build Coastguard Worker   }
564*2d1272b8SAndroid Build Coastguard Worker 
rlinecurveCFF::path_procs_t565*2d1272b8SAndroid Build Coastguard Worker   static void rlinecurve (ENV &env, PARAM& param)
566*2d1272b8SAndroid Build Coastguard Worker   {
567*2d1272b8SAndroid Build Coastguard Worker     unsigned int arg_count = env.argStack.get_count ();
568*2d1272b8SAndroid Build Coastguard Worker     if (unlikely (arg_count < 8))
569*2d1272b8SAndroid Build Coastguard Worker       return;
570*2d1272b8SAndroid Build Coastguard Worker 
571*2d1272b8SAndroid Build Coastguard Worker     unsigned int i = 0;
572*2d1272b8SAndroid Build Coastguard Worker     unsigned int line_limit = arg_count - 6;
573*2d1272b8SAndroid Build Coastguard Worker     for (; i + 2 <= line_limit; i += 2)
574*2d1272b8SAndroid Build Coastguard Worker     {
575*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
576*2d1272b8SAndroid Build Coastguard Worker       pt1.move (env.eval_arg (i), env.eval_arg (i+1));
577*2d1272b8SAndroid Build Coastguard Worker       PATH::line (env, param, pt1);
578*2d1272b8SAndroid Build Coastguard Worker     }
579*2d1272b8SAndroid Build Coastguard Worker 
580*2d1272b8SAndroid Build Coastguard Worker     point_t pt1 = env.get_pt ();
581*2d1272b8SAndroid Build Coastguard Worker     pt1.move (env.eval_arg (i), env.eval_arg (i+1));
582*2d1272b8SAndroid Build Coastguard Worker     point_t pt2 = pt1;
583*2d1272b8SAndroid Build Coastguard Worker     pt2.move (env.eval_arg (i+2), env.eval_arg (i+3));
584*2d1272b8SAndroid Build Coastguard Worker     point_t pt3 = pt2;
585*2d1272b8SAndroid Build Coastguard Worker     pt3.move (env.eval_arg (i+4), env.eval_arg (i+5));
586*2d1272b8SAndroid Build Coastguard Worker     PATH::curve (env, param, pt1, pt2, pt3);
587*2d1272b8SAndroid Build Coastguard Worker   }
588*2d1272b8SAndroid Build Coastguard Worker 
vvcurvetoCFF::path_procs_t589*2d1272b8SAndroid Build Coastguard Worker   static void vvcurveto (ENV &env, PARAM& param)
590*2d1272b8SAndroid Build Coastguard Worker   {
591*2d1272b8SAndroid Build Coastguard Worker     unsigned int i = 0;
592*2d1272b8SAndroid Build Coastguard Worker     point_t pt1 = env.get_pt ();
593*2d1272b8SAndroid Build Coastguard Worker     if ((env.argStack.get_count () & 1) != 0)
594*2d1272b8SAndroid Build Coastguard Worker       pt1.move_x (env.eval_arg (i++));
595*2d1272b8SAndroid Build Coastguard Worker     for (; i + 4 <= env.argStack.get_count (); i += 4)
596*2d1272b8SAndroid Build Coastguard Worker     {
597*2d1272b8SAndroid Build Coastguard Worker       pt1.move_y (env.eval_arg (i));
598*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
599*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
600*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
601*2d1272b8SAndroid Build Coastguard Worker       pt3.move_y (env.eval_arg (i+3));
602*2d1272b8SAndroid Build Coastguard Worker       PATH::curve (env, param, pt1, pt2, pt3);
603*2d1272b8SAndroid Build Coastguard Worker       pt1 = env.get_pt ();
604*2d1272b8SAndroid Build Coastguard Worker     }
605*2d1272b8SAndroid Build Coastguard Worker   }
606*2d1272b8SAndroid Build Coastguard Worker 
hhcurvetoCFF::path_procs_t607*2d1272b8SAndroid Build Coastguard Worker   static void hhcurveto (ENV &env, PARAM& param)
608*2d1272b8SAndroid Build Coastguard Worker   {
609*2d1272b8SAndroid Build Coastguard Worker     unsigned int i = 0;
610*2d1272b8SAndroid Build Coastguard Worker     point_t pt1 = env.get_pt ();
611*2d1272b8SAndroid Build Coastguard Worker     if ((env.argStack.get_count () & 1) != 0)
612*2d1272b8SAndroid Build Coastguard Worker       pt1.move_y (env.eval_arg (i++));
613*2d1272b8SAndroid Build Coastguard Worker     for (; i + 4 <= env.argStack.get_count (); i += 4)
614*2d1272b8SAndroid Build Coastguard Worker     {
615*2d1272b8SAndroid Build Coastguard Worker       pt1.move_x (env.eval_arg (i));
616*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
617*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
618*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
619*2d1272b8SAndroid Build Coastguard Worker       pt3.move_x (env.eval_arg (i+3));
620*2d1272b8SAndroid Build Coastguard Worker       PATH::curve (env, param, pt1, pt2, pt3);
621*2d1272b8SAndroid Build Coastguard Worker       pt1 = env.get_pt ();
622*2d1272b8SAndroid Build Coastguard Worker     }
623*2d1272b8SAndroid Build Coastguard Worker   }
624*2d1272b8SAndroid Build Coastguard Worker 
vhcurvetoCFF::path_procs_t625*2d1272b8SAndroid Build Coastguard Worker   static void vhcurveto (ENV &env, PARAM& param)
626*2d1272b8SAndroid Build Coastguard Worker   {
627*2d1272b8SAndroid Build Coastguard Worker     point_t pt1, pt2, pt3;
628*2d1272b8SAndroid Build Coastguard Worker     unsigned int i = 0;
629*2d1272b8SAndroid Build Coastguard Worker     if ((env.argStack.get_count () % 8) >= 4)
630*2d1272b8SAndroid Build Coastguard Worker     {
631*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
632*2d1272b8SAndroid Build Coastguard Worker       pt1.move_y (env.eval_arg (i));
633*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
634*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
635*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
636*2d1272b8SAndroid Build Coastguard Worker       pt3.move_x (env.eval_arg (i+3));
637*2d1272b8SAndroid Build Coastguard Worker       i += 4;
638*2d1272b8SAndroid Build Coastguard Worker 
639*2d1272b8SAndroid Build Coastguard Worker       for (; i + 8 <= env.argStack.get_count (); i += 8)
640*2d1272b8SAndroid Build Coastguard Worker       {
641*2d1272b8SAndroid Build Coastguard Worker 	PATH::curve (env, param, pt1, pt2, pt3);
642*2d1272b8SAndroid Build Coastguard Worker 	pt1 = env.get_pt ();
643*2d1272b8SAndroid Build Coastguard Worker 	pt1.move_x (env.eval_arg (i));
644*2d1272b8SAndroid Build Coastguard Worker 	pt2 = pt1;
645*2d1272b8SAndroid Build Coastguard Worker 	pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
646*2d1272b8SAndroid Build Coastguard Worker 	pt3 = pt2;
647*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_y (env.eval_arg (i+3));
648*2d1272b8SAndroid Build Coastguard Worker 	PATH::curve (env, param, pt1, pt2, pt3);
649*2d1272b8SAndroid Build Coastguard Worker 
650*2d1272b8SAndroid Build Coastguard Worker 	pt1 = pt3;
651*2d1272b8SAndroid Build Coastguard Worker 	pt1.move_y (env.eval_arg (i+4));
652*2d1272b8SAndroid Build Coastguard Worker 	pt2 = pt1;
653*2d1272b8SAndroid Build Coastguard Worker 	pt2.move (env.eval_arg (i+5), env.eval_arg (i+6));
654*2d1272b8SAndroid Build Coastguard Worker 	pt3 = pt2;
655*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_x (env.eval_arg (i+7));
656*2d1272b8SAndroid Build Coastguard Worker       }
657*2d1272b8SAndroid Build Coastguard Worker       if (i < env.argStack.get_count ())
658*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_y (env.eval_arg (i));
659*2d1272b8SAndroid Build Coastguard Worker       PATH::curve (env, param, pt1, pt2, pt3);
660*2d1272b8SAndroid Build Coastguard Worker     }
661*2d1272b8SAndroid Build Coastguard Worker     else
662*2d1272b8SAndroid Build Coastguard Worker     {
663*2d1272b8SAndroid Build Coastguard Worker       for (; i + 8 <= env.argStack.get_count (); i += 8)
664*2d1272b8SAndroid Build Coastguard Worker       {
665*2d1272b8SAndroid Build Coastguard Worker 	pt1 = env.get_pt ();
666*2d1272b8SAndroid Build Coastguard Worker 	pt1.move_y (env.eval_arg (i));
667*2d1272b8SAndroid Build Coastguard Worker 	pt2 = pt1;
668*2d1272b8SAndroid Build Coastguard Worker 	pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
669*2d1272b8SAndroid Build Coastguard Worker 	pt3 = pt2;
670*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_x (env.eval_arg (i+3));
671*2d1272b8SAndroid Build Coastguard Worker 	PATH::curve (env, param, pt1, pt2, pt3);
672*2d1272b8SAndroid Build Coastguard Worker 
673*2d1272b8SAndroid Build Coastguard Worker 	pt1 = pt3;
674*2d1272b8SAndroid Build Coastguard Worker 	pt1.move_x (env.eval_arg (i+4));
675*2d1272b8SAndroid Build Coastguard Worker 	pt2 = pt1;
676*2d1272b8SAndroid Build Coastguard Worker 	pt2.move (env.eval_arg (i+5), env.eval_arg (i+6));
677*2d1272b8SAndroid Build Coastguard Worker 	pt3 = pt2;
678*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_y (env.eval_arg (i+7));
679*2d1272b8SAndroid Build Coastguard Worker 	if ((env.argStack.get_count () - i < 16) && ((env.argStack.get_count () & 1) != 0))
680*2d1272b8SAndroid Build Coastguard Worker 	  pt3.move_x (env.eval_arg (i+8));
681*2d1272b8SAndroid Build Coastguard Worker 	PATH::curve (env, param, pt1, pt2, pt3);
682*2d1272b8SAndroid Build Coastguard Worker       }
683*2d1272b8SAndroid Build Coastguard Worker     }
684*2d1272b8SAndroid Build Coastguard Worker   }
685*2d1272b8SAndroid Build Coastguard Worker 
hvcurvetoCFF::path_procs_t686*2d1272b8SAndroid Build Coastguard Worker   static void hvcurveto (ENV &env, PARAM& param)
687*2d1272b8SAndroid Build Coastguard Worker   {
688*2d1272b8SAndroid Build Coastguard Worker     point_t pt1, pt2, pt3;
689*2d1272b8SAndroid Build Coastguard Worker     unsigned int i = 0;
690*2d1272b8SAndroid Build Coastguard Worker     if ((env.argStack.get_count () % 8) >= 4)
691*2d1272b8SAndroid Build Coastguard Worker     {
692*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
693*2d1272b8SAndroid Build Coastguard Worker       pt1.move_x (env.eval_arg (i));
694*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
695*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
696*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
697*2d1272b8SAndroid Build Coastguard Worker       pt3.move_y (env.eval_arg (i+3));
698*2d1272b8SAndroid Build Coastguard Worker       i += 4;
699*2d1272b8SAndroid Build Coastguard Worker 
700*2d1272b8SAndroid Build Coastguard Worker       for (; i + 8 <= env.argStack.get_count (); i += 8)
701*2d1272b8SAndroid Build Coastguard Worker       {
702*2d1272b8SAndroid Build Coastguard Worker 	PATH::curve (env, param, pt1, pt2, pt3);
703*2d1272b8SAndroid Build Coastguard Worker 	pt1 = env.get_pt ();
704*2d1272b8SAndroid Build Coastguard Worker 	pt1.move_y (env.eval_arg (i));
705*2d1272b8SAndroid Build Coastguard Worker 	pt2 = pt1;
706*2d1272b8SAndroid Build Coastguard Worker 	pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
707*2d1272b8SAndroid Build Coastguard Worker 	pt3 = pt2;
708*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_x (env.eval_arg (i+3));
709*2d1272b8SAndroid Build Coastguard Worker 	PATH::curve (env, param, pt1, pt2, pt3);
710*2d1272b8SAndroid Build Coastguard Worker 
711*2d1272b8SAndroid Build Coastguard Worker 	pt1 = pt3;
712*2d1272b8SAndroid Build Coastguard Worker 	pt1.move_x (env.eval_arg (i+4));
713*2d1272b8SAndroid Build Coastguard Worker 	pt2 = pt1;
714*2d1272b8SAndroid Build Coastguard Worker 	pt2.move (env.eval_arg (i+5), env.eval_arg (i+6));
715*2d1272b8SAndroid Build Coastguard Worker 	pt3 = pt2;
716*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_y (env.eval_arg (i+7));
717*2d1272b8SAndroid Build Coastguard Worker       }
718*2d1272b8SAndroid Build Coastguard Worker       if (i < env.argStack.get_count ())
719*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_x (env.eval_arg (i));
720*2d1272b8SAndroid Build Coastguard Worker       PATH::curve (env, param, pt1, pt2, pt3);
721*2d1272b8SAndroid Build Coastguard Worker     }
722*2d1272b8SAndroid Build Coastguard Worker     else
723*2d1272b8SAndroid Build Coastguard Worker     {
724*2d1272b8SAndroid Build Coastguard Worker       for (; i + 8 <= env.argStack.get_count (); i += 8)
725*2d1272b8SAndroid Build Coastguard Worker       {
726*2d1272b8SAndroid Build Coastguard Worker 	pt1 = env.get_pt ();
727*2d1272b8SAndroid Build Coastguard Worker 	pt1.move_x (env.eval_arg (i));
728*2d1272b8SAndroid Build Coastguard Worker 	pt2 = pt1;
729*2d1272b8SAndroid Build Coastguard Worker 	pt2.move (env.eval_arg (i+1), env.eval_arg (i+2));
730*2d1272b8SAndroid Build Coastguard Worker 	pt3 = pt2;
731*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_y (env.eval_arg (i+3));
732*2d1272b8SAndroid Build Coastguard Worker 	PATH::curve (env, param, pt1, pt2, pt3);
733*2d1272b8SAndroid Build Coastguard Worker 
734*2d1272b8SAndroid Build Coastguard Worker 	pt1 = pt3;
735*2d1272b8SAndroid Build Coastguard Worker 	pt1.move_y (env.eval_arg (i+4));
736*2d1272b8SAndroid Build Coastguard Worker 	pt2 = pt1;
737*2d1272b8SAndroid Build Coastguard Worker 	pt2.move (env.eval_arg (i+5), env.eval_arg (i+6));
738*2d1272b8SAndroid Build Coastguard Worker 	pt3 = pt2;
739*2d1272b8SAndroid Build Coastguard Worker 	pt3.move_x (env.eval_arg (i+7));
740*2d1272b8SAndroid Build Coastguard Worker 	if ((env.argStack.get_count () - i < 16) && ((env.argStack.get_count () & 1) != 0))
741*2d1272b8SAndroid Build Coastguard Worker 	  pt3.move_y (env.eval_arg (i+8));
742*2d1272b8SAndroid Build Coastguard Worker 	PATH::curve (env, param, pt1, pt2, pt3);
743*2d1272b8SAndroid Build Coastguard Worker       }
744*2d1272b8SAndroid Build Coastguard Worker     }
745*2d1272b8SAndroid Build Coastguard Worker   }
746*2d1272b8SAndroid Build Coastguard Worker 
747*2d1272b8SAndroid Build Coastguard Worker   /* default actions to be overridden */
movetoCFF::path_procs_t748*2d1272b8SAndroid Build Coastguard Worker   static void moveto (ENV &env, PARAM& param, const point_t &pt)
749*2d1272b8SAndroid Build Coastguard Worker   { env.moveto (pt); }
750*2d1272b8SAndroid Build Coastguard Worker 
lineCFF::path_procs_t751*2d1272b8SAndroid Build Coastguard Worker   static void line (ENV &env, PARAM& param, const point_t &pt1)
752*2d1272b8SAndroid Build Coastguard Worker   { PATH::moveto (env, param, pt1); }
753*2d1272b8SAndroid Build Coastguard Worker 
curveCFF::path_procs_t754*2d1272b8SAndroid Build Coastguard Worker   static void curve (ENV &env, PARAM& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
755*2d1272b8SAndroid Build Coastguard Worker   { PATH::moveto (env, param, pt3); }
756*2d1272b8SAndroid Build Coastguard Worker 
hflexCFF::path_procs_t757*2d1272b8SAndroid Build Coastguard Worker   static void hflex (ENV &env, PARAM& param)
758*2d1272b8SAndroid Build Coastguard Worker   {
759*2d1272b8SAndroid Build Coastguard Worker     if (likely (env.argStack.get_count () == 7))
760*2d1272b8SAndroid Build Coastguard Worker     {
761*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
762*2d1272b8SAndroid Build Coastguard Worker       pt1.move_x (env.eval_arg (0));
763*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
764*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (1), env.eval_arg (2));
765*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
766*2d1272b8SAndroid Build Coastguard Worker       pt3.move_x (env.eval_arg (3));
767*2d1272b8SAndroid Build Coastguard Worker       point_t pt4 = pt3;
768*2d1272b8SAndroid Build Coastguard Worker       pt4.move_x (env.eval_arg (4));
769*2d1272b8SAndroid Build Coastguard Worker       point_t pt5 = pt4;
770*2d1272b8SAndroid Build Coastguard Worker       pt5.move_x (env.eval_arg (5));
771*2d1272b8SAndroid Build Coastguard Worker       pt5.y = pt1.y;
772*2d1272b8SAndroid Build Coastguard Worker       point_t pt6 = pt5;
773*2d1272b8SAndroid Build Coastguard Worker       pt6.move_x (env.eval_arg (6));
774*2d1272b8SAndroid Build Coastguard Worker 
775*2d1272b8SAndroid Build Coastguard Worker       curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6);
776*2d1272b8SAndroid Build Coastguard Worker     }
777*2d1272b8SAndroid Build Coastguard Worker     else
778*2d1272b8SAndroid Build Coastguard Worker       env.set_error ();
779*2d1272b8SAndroid Build Coastguard Worker   }
780*2d1272b8SAndroid Build Coastguard Worker 
flexCFF::path_procs_t781*2d1272b8SAndroid Build Coastguard Worker   static void flex (ENV &env, PARAM& param)
782*2d1272b8SAndroid Build Coastguard Worker   {
783*2d1272b8SAndroid Build Coastguard Worker     if (likely (env.argStack.get_count () == 13))
784*2d1272b8SAndroid Build Coastguard Worker     {
785*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
786*2d1272b8SAndroid Build Coastguard Worker       pt1.move (env.eval_arg (0), env.eval_arg (1));
787*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
788*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (2), env.eval_arg (3));
789*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
790*2d1272b8SAndroid Build Coastguard Worker       pt3.move (env.eval_arg (4), env.eval_arg (5));
791*2d1272b8SAndroid Build Coastguard Worker       point_t pt4 = pt3;
792*2d1272b8SAndroid Build Coastguard Worker       pt4.move (env.eval_arg (6), env.eval_arg (7));
793*2d1272b8SAndroid Build Coastguard Worker       point_t pt5 = pt4;
794*2d1272b8SAndroid Build Coastguard Worker       pt5.move (env.eval_arg (8), env.eval_arg (9));
795*2d1272b8SAndroid Build Coastguard Worker       point_t pt6 = pt5;
796*2d1272b8SAndroid Build Coastguard Worker       pt6.move (env.eval_arg (10), env.eval_arg (11));
797*2d1272b8SAndroid Build Coastguard Worker 
798*2d1272b8SAndroid Build Coastguard Worker       curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6);
799*2d1272b8SAndroid Build Coastguard Worker     }
800*2d1272b8SAndroid Build Coastguard Worker     else
801*2d1272b8SAndroid Build Coastguard Worker       env.set_error ();
802*2d1272b8SAndroid Build Coastguard Worker   }
803*2d1272b8SAndroid Build Coastguard Worker 
hflex1CFF::path_procs_t804*2d1272b8SAndroid Build Coastguard Worker   static void hflex1 (ENV &env, PARAM& param)
805*2d1272b8SAndroid Build Coastguard Worker   {
806*2d1272b8SAndroid Build Coastguard Worker     if (likely (env.argStack.get_count () == 9))
807*2d1272b8SAndroid Build Coastguard Worker     {
808*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
809*2d1272b8SAndroid Build Coastguard Worker       pt1.move (env.eval_arg (0), env.eval_arg (1));
810*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
811*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (2), env.eval_arg (3));
812*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
813*2d1272b8SAndroid Build Coastguard Worker       pt3.move_x (env.eval_arg (4));
814*2d1272b8SAndroid Build Coastguard Worker       point_t pt4 = pt3;
815*2d1272b8SAndroid Build Coastguard Worker       pt4.move_x (env.eval_arg (5));
816*2d1272b8SAndroid Build Coastguard Worker       point_t pt5 = pt4;
817*2d1272b8SAndroid Build Coastguard Worker       pt5.move (env.eval_arg (6), env.eval_arg (7));
818*2d1272b8SAndroid Build Coastguard Worker       point_t pt6 = pt5;
819*2d1272b8SAndroid Build Coastguard Worker       pt6.move_x (env.eval_arg (8));
820*2d1272b8SAndroid Build Coastguard Worker       pt6.y = env.get_pt ().y;
821*2d1272b8SAndroid Build Coastguard Worker 
822*2d1272b8SAndroid Build Coastguard Worker       curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6);
823*2d1272b8SAndroid Build Coastguard Worker     }
824*2d1272b8SAndroid Build Coastguard Worker     else
825*2d1272b8SAndroid Build Coastguard Worker       env.set_error ();
826*2d1272b8SAndroid Build Coastguard Worker   }
827*2d1272b8SAndroid Build Coastguard Worker 
flex1CFF::path_procs_t828*2d1272b8SAndroid Build Coastguard Worker   static void flex1 (ENV &env, PARAM& param)
829*2d1272b8SAndroid Build Coastguard Worker   {
830*2d1272b8SAndroid Build Coastguard Worker     if (likely (env.argStack.get_count () == 11))
831*2d1272b8SAndroid Build Coastguard Worker     {
832*2d1272b8SAndroid Build Coastguard Worker       point_t d;
833*2d1272b8SAndroid Build Coastguard Worker       for (unsigned int i = 0; i < 10; i += 2)
834*2d1272b8SAndroid Build Coastguard Worker 	d.move (env.eval_arg (i), env.eval_arg (i+1));
835*2d1272b8SAndroid Build Coastguard Worker 
836*2d1272b8SAndroid Build Coastguard Worker       point_t pt1 = env.get_pt ();
837*2d1272b8SAndroid Build Coastguard Worker       pt1.move (env.eval_arg (0), env.eval_arg (1));
838*2d1272b8SAndroid Build Coastguard Worker       point_t pt2 = pt1;
839*2d1272b8SAndroid Build Coastguard Worker       pt2.move (env.eval_arg (2), env.eval_arg (3));
840*2d1272b8SAndroid Build Coastguard Worker       point_t pt3 = pt2;
841*2d1272b8SAndroid Build Coastguard Worker       pt3.move (env.eval_arg (4), env.eval_arg (5));
842*2d1272b8SAndroid Build Coastguard Worker       point_t pt4 = pt3;
843*2d1272b8SAndroid Build Coastguard Worker       pt4.move (env.eval_arg (6), env.eval_arg (7));
844*2d1272b8SAndroid Build Coastguard Worker       point_t pt5 = pt4;
845*2d1272b8SAndroid Build Coastguard Worker       pt5.move (env.eval_arg (8), env.eval_arg (9));
846*2d1272b8SAndroid Build Coastguard Worker       point_t pt6 = pt5;
847*2d1272b8SAndroid Build Coastguard Worker 
848*2d1272b8SAndroid Build Coastguard Worker       if (fabs (d.x.to_real ()) > fabs (d.y.to_real ()))
849*2d1272b8SAndroid Build Coastguard Worker       {
850*2d1272b8SAndroid Build Coastguard Worker 	pt6.move_x (env.eval_arg (10));
851*2d1272b8SAndroid Build Coastguard Worker 	pt6.y = env.get_pt ().y;
852*2d1272b8SAndroid Build Coastguard Worker       }
853*2d1272b8SAndroid Build Coastguard Worker       else
854*2d1272b8SAndroid Build Coastguard Worker       {
855*2d1272b8SAndroid Build Coastguard Worker 	pt6.x = env.get_pt ().x;
856*2d1272b8SAndroid Build Coastguard Worker 	pt6.move_y (env.eval_arg (10));
857*2d1272b8SAndroid Build Coastguard Worker       }
858*2d1272b8SAndroid Build Coastguard Worker 
859*2d1272b8SAndroid Build Coastguard Worker       curve2 (env, param, pt1, pt2, pt3, pt4, pt5, pt6);
860*2d1272b8SAndroid Build Coastguard Worker     }
861*2d1272b8SAndroid Build Coastguard Worker     else
862*2d1272b8SAndroid Build Coastguard Worker       env.set_error ();
863*2d1272b8SAndroid Build Coastguard Worker   }
864*2d1272b8SAndroid Build Coastguard Worker 
865*2d1272b8SAndroid Build Coastguard Worker   protected:
curve2CFF::path_procs_t866*2d1272b8SAndroid Build Coastguard Worker   static void curve2 (ENV &env, PARAM& param,
867*2d1272b8SAndroid Build Coastguard Worker 		      const point_t &pt1, const point_t &pt2, const point_t &pt3,
868*2d1272b8SAndroid Build Coastguard Worker 		      const point_t &pt4, const point_t &pt5, const point_t &pt6)
869*2d1272b8SAndroid Build Coastguard Worker   {
870*2d1272b8SAndroid Build Coastguard Worker     PATH::curve (env, param, pt1, pt2, pt3);
871*2d1272b8SAndroid Build Coastguard Worker     PATH::curve (env, param, pt4, pt5, pt6);
872*2d1272b8SAndroid Build Coastguard Worker   }
873*2d1272b8SAndroid Build Coastguard Worker };
874*2d1272b8SAndroid Build Coastguard Worker 
875*2d1272b8SAndroid Build Coastguard Worker template <typename ENV, typename OPSET, typename PARAM>
876*2d1272b8SAndroid Build Coastguard Worker struct cs_interpreter_t : interpreter_t<ENV>
877*2d1272b8SAndroid Build Coastguard Worker {
cs_interpreter_tCFF::cs_interpreter_t878*2d1272b8SAndroid Build Coastguard Worker   cs_interpreter_t (ENV& env_) : interpreter_t<ENV> (env_) {}
879*2d1272b8SAndroid Build Coastguard Worker 
interpretCFF::cs_interpreter_t880*2d1272b8SAndroid Build Coastguard Worker   bool interpret (PARAM& param)
881*2d1272b8SAndroid Build Coastguard Worker   {
882*2d1272b8SAndroid Build Coastguard Worker     SUPER::env.set_endchar (false);
883*2d1272b8SAndroid Build Coastguard Worker 
884*2d1272b8SAndroid Build Coastguard Worker     unsigned max_ops = HB_CFF_MAX_OPS;
885*2d1272b8SAndroid Build Coastguard Worker     for (;;) {
886*2d1272b8SAndroid Build Coastguard Worker       OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
887*2d1272b8SAndroid Build Coastguard Worker       if (unlikely (SUPER::env.in_error () || !--max_ops))
888*2d1272b8SAndroid Build Coastguard Worker       {
889*2d1272b8SAndroid Build Coastguard Worker 	SUPER::env.set_error ();
890*2d1272b8SAndroid Build Coastguard Worker 	return false;
891*2d1272b8SAndroid Build Coastguard Worker       }
892*2d1272b8SAndroid Build Coastguard Worker       if (SUPER::env.is_endchar ())
893*2d1272b8SAndroid Build Coastguard Worker 	break;
894*2d1272b8SAndroid Build Coastguard Worker     }
895*2d1272b8SAndroid Build Coastguard Worker 
896*2d1272b8SAndroid Build Coastguard Worker     return true;
897*2d1272b8SAndroid Build Coastguard Worker   }
898*2d1272b8SAndroid Build Coastguard Worker 
899*2d1272b8SAndroid Build Coastguard Worker   private:
900*2d1272b8SAndroid Build Coastguard Worker   typedef interpreter_t<ENV> SUPER;
901*2d1272b8SAndroid Build Coastguard Worker };
902*2d1272b8SAndroid Build Coastguard Worker 
903*2d1272b8SAndroid Build Coastguard Worker } /* namespace CFF */
904*2d1272b8SAndroid Build Coastguard Worker 
905*2d1272b8SAndroid Build Coastguard Worker #endif /* HB_CFF_INTERP_CS_COMMON_HH */
906