hb-cff-interp-common.hh 20.8 KB
Newer Older
M
Michiharu Ariza 已提交
1
/*
M
Michiharu Ariza 已提交
2
 * Copyright © 2018 Adobe Inc.
M
Michiharu Ariza 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Adobe Author(s): Michiharu Ariza
 */
M
Michiharu Ariza 已提交
26 27
#ifndef HB_CFF_INTERP_COMMON_HH
#define HB_CFF_INTERP_COMMON_HH
M
Michiharu Ariza 已提交
28 29 30 31 32

namespace CFF {

using namespace OT;

M
Michiharu Ariza 已提交
33
typedef unsigned int op_code_t;
B
Behdad Esfahbod 已提交
34 35


36 37 38
/* === Dict operators === */

/* One byte operators (0-31) */
B
Behdad Esfahbod 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
#define OpCode_version		  0 /* CFF Top */
#define OpCode_Notice		  1 /* CFF Top */
#define OpCode_FullName		  2 /* CFF Top */
#define OpCode_FamilyName	  3 /* CFF Top */
#define OpCode_Weight		  4 /* CFF Top */
#define OpCode_FontBBox		  5 /* CFF Top */
#define OpCode_BlueValues	  6 /* CFF Private, CFF2 Private */
#define OpCode_OtherBlues	  7 /* CFF Private, CFF2 Private */
#define OpCode_FamilyBlues	  8 /* CFF Private, CFF2 Private */
#define OpCode_FamilyOtherBlues	  9 /* CFF Private, CFF2 Private */
#define OpCode_StdHW		 10 /* CFF Private, CFF2 Private */
#define OpCode_StdVW		 11 /* CFF Private, CFF2 Private */
#define OpCode_escape		 12 /* All. Shared with CS */
#define OpCode_UniqueID		 13 /* CFF Top */
#define OpCode_XUID		 14 /* CFF Top */
#define OpCode_charset		 15 /* CFF Top (0) */
#define OpCode_Encoding		 16 /* CFF Top (0) */
#define OpCode_CharStrings	 17 /* CFF Top, CFF2 Top */
#define OpCode_Private		 18 /* CFF Top, CFF2 FD */
#define OpCode_Subrs		 19 /* CFF Private, CFF2 Private */
#define OpCode_defaultWidthX	 20 /* CFF Private (0) */
#define OpCode_nominalWidthX	 21 /* CFF Private (0) */
#define OpCode_vsindexdict	 22 /* CFF2 Private/CS */
#define OpCode_blenddict	 23 /* CFF2 Private/CS */
#define OpCode_vstore		 24 /* CFF2 Top */
#define OpCode_reserved25	 25
#define OpCode_reserved26	 26
#define OpCode_reserved27	 27
67 68

/* Numbers */
B
Behdad Esfahbod 已提交
69 70 71 72
#define OpCode_shortint		 28 /* 16-bit integer, All */
#define OpCode_longintdict	 29 /* 32-bit integer, All */
#define OpCode_BCD		 30 /* Real number, CFF2 Top/FD */
#define OpCode_reserved31	 31
73 74

/* 1-byte integers */
B
Behdad Esfahbod 已提交
75 76
#define OpCode_OneByteIntFirst	 32 /* All. beginning of the range of first byte ints */
#define OpCode_OneByteIntLast	246 /* All. ending of the range of first byte int */
77 78

/* 2-byte integers */
B
Behdad Esfahbod 已提交
79 80 81 82
#define OpCode_TwoBytePosInt0	247 /* All. first byte of two byte positive int (+108 to +1131) */
#define OpCode_TwoBytePosInt1	248
#define OpCode_TwoBytePosInt2	249
#define OpCode_TwoBytePosInt3	250
83

B
Behdad Esfahbod 已提交
84 85 86 87
#define OpCode_TwoByteNegInt0	251 /* All. first byte of two byte negative int (-1131 to -108) */
#define OpCode_TwoByteNegInt1	252
#define OpCode_TwoByteNegInt2	253
#define OpCode_TwoByteNegInt3	254
88 89

/* Two byte escape operators 12, (0-41) */
B
Behdad Esfahbod 已提交
90
#define OpCode_ESC_Base		256
M
Michiharu Ariza 已提交
91
#define Make_OpCode_ESC(byte2)	((op_code_t)(OpCode_ESC_Base + (byte2)))
M
Michiharu Ariza 已提交
92

M
Michiharu Ariza 已提交
93 94 95
inline op_code_t Unmake_OpCode_ESC (op_code_t op)  { return (op_code_t)(op - OpCode_ESC_Base); }
inline bool Is_OpCode_ESC (op_code_t op) { return op >= OpCode_ESC_Base; }
inline unsigned int OpCode_Size (op_code_t op) { return Is_OpCode_ESC (op) ? 2: 1; }
B
Behdad Esfahbod 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172

#define OpCode_Copyright	Make_OpCode_ESC(0) /* CFF Top */
#define OpCode_isFixedPitch	Make_OpCode_ESC(1) /* CFF Top (false) */
#define OpCode_ItalicAngle	Make_OpCode_ESC(2) /* CFF Top (0) */
#define OpCode_UnderlinePosition Make_OpCode_ESC(3) /* CFF Top (-100) */
#define OpCode_UnderlineThickness Make_OpCode_ESC(4) /* CFF Top (50) */
#define OpCode_PaintType	Make_OpCode_ESC(5) /* CFF Top (0) */
#define OpCode_CharstringType	Make_OpCode_ESC(6) /* CFF Top (2) */
#define OpCode_FontMatrix	Make_OpCode_ESC(7) /* CFF Top, CFF2 Top (.001 0 0 .001 0 0)*/
#define OpCode_StrokeWidth	Make_OpCode_ESC(8) /* CFF Top (0) */
#define OpCode_BlueScale	Make_OpCode_ESC(9) /* CFF Private, CFF2 Private (0.039625) */
#define OpCode_BlueShift	Make_OpCode_ESC(10) /* CFF Private, CFF2 Private (7) */
#define OpCode_BlueFuzz		Make_OpCode_ESC(11) /* CFF Private, CFF2 Private (1) */
#define OpCode_StemSnapH	Make_OpCode_ESC(12) /* CFF Private, CFF2 Private */
#define OpCode_StemSnapV	Make_OpCode_ESC(13) /* CFF Private, CFF2 Private */
#define OpCode_ForceBold	Make_OpCode_ESC(14) /* CFF Private (false) */
#define OpCode_reservedESC15	Make_OpCode_ESC(15)
#define OpCode_reservedESC16	Make_OpCode_ESC(16)
#define OpCode_LanguageGroup	Make_OpCode_ESC(17) /* CFF Private, CFF2 Private (0) */
#define OpCode_ExpansionFactor	Make_OpCode_ESC(18) /* CFF Private, CFF2 Private (0.06) */
#define OpCode_initialRandomSeed Make_OpCode_ESC(19) /* CFF Private (0) */
#define OpCode_SyntheticBase	Make_OpCode_ESC(20) /* CFF Top */
#define OpCode_PostScript	Make_OpCode_ESC(21) /* CFF Top */
#define OpCode_BaseFontName	Make_OpCode_ESC(22) /* CFF Top */
#define OpCode_BaseFontBlend	Make_OpCode_ESC(23) /* CFF Top */
#define OpCode_reservedESC24	Make_OpCode_ESC(24)
#define OpCode_reservedESC25	Make_OpCode_ESC(25)
#define OpCode_reservedESC26	Make_OpCode_ESC(26)
#define OpCode_reservedESC27	Make_OpCode_ESC(27)
#define OpCode_reservedESC28	Make_OpCode_ESC(28)
#define OpCode_reservedESC29	Make_OpCode_ESC(29)
#define OpCode_ROS		Make_OpCode_ESC(30) /* CFF Top_CID */
#define OpCode_CIDFontVersion	Make_OpCode_ESC(31) /* CFF Top_CID (0) */
#define OpCode_CIDFontRevision	Make_OpCode_ESC(32) /* CFF Top_CID (0) */
#define OpCode_CIDFontType	Make_OpCode_ESC(33) /* CFF Top_CID (0) */
#define OpCode_CIDCount		Make_OpCode_ESC(34) /* CFF Top_CID (8720) */
#define OpCode_UIDBase		Make_OpCode_ESC(35) /* CFF Top_CID */
#define OpCode_FDArray		Make_OpCode_ESC(36) /* CFF Top_CID, CFF2 Top */
#define OpCode_FDSelect		Make_OpCode_ESC(37) /* CFF Top_CID, CFF2 Top */
#define OpCode_FontName		Make_OpCode_ESC(38) /* CFF Top_CID */


/* === CharString operators === */

#define OpCode_hstem		  1 /* CFF, CFF2 */
#define OpCode_Reserved2	  2
#define OpCode_vstem		  3 /* CFF, CFF2 */
#define OpCode_vmoveto		  4 /* CFF, CFF2 */
#define OpCode_rlineto		  5 /* CFF, CFF2 */
#define OpCode_hlineto		  6 /* CFF, CFF2 */
#define OpCode_vlineto		  7 /* CFF, CFF2 */
#define OpCode_rrcurveto	  8 /* CFF, CFF2 */
#define OpCode_Reserved9	  9
#define OpCode_callsubr		 10 /* CFF, CFF2 */
#define OpCode_return		 11 /* CFF */
//#define OpCode_escape		 12 /* CFF, CFF2 */
#define OpCode_Reserved13	 13
#define OpCode_endchar		 14 /* CFF */
#define OpCode_vsindexcs	 15 /* CFF2 */
#define OpCode_blendcs		 16 /* CFF2 */
#define OpCode_Reserved17	 17
#define OpCode_hstemhm		 18 /* CFF, CFF2 */
#define OpCode_hintmask		 19 /* CFF, CFF2 */
#define OpCode_cntrmask		 20 /* CFF, CFF2 */
#define OpCode_rmoveto		 21 /* CFF, CFF2 */
#define OpCode_hmoveto		 22 /* CFF, CFF2 */
#define OpCode_vstemhm		 23 /* CFF, CFF2 */
#define OpCode_rcurveline	 24 /* CFF, CFF2 */
#define OpCode_rlinecurve	 25 /* CFF, CFF2 */
#define OpCode_vvcurveto	 26 /* CFF, CFF2 */
#define OpCode_hhcurveto	 27 /* CFF, CFF2 */
//#define OpCode_shortint	 28 /* CFF, CFF2 */
#define OpCode_callgsubr	 29 /* CFF, CFF2 */
#define OpCode_vhcurveto	 30 /* CFF, CFF2 */
#define OpCode_hvcurveto	 31 /* CFF, CFF2 */

#define OpCode_fixedcs		255 /* 32-bit fixed */
173 174

/* Two byte escape operators 12, (0-41) */
B
Behdad Esfahbod 已提交
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
#define OpCode_dotsection	Make_OpCode_ESC(0) /* CFF (obsoleted) */
#define OpCode_ReservedESC1	Make_OpCode_ESC(1)
#define OpCode_ReservedESC2	Make_OpCode_ESC(2)
#define OpCode_and		Make_OpCode_ESC(3) /* CFF */
#define OpCode_or		Make_OpCode_ESC(4) /* CFF */
#define OpCode_not		Make_OpCode_ESC(5) /* CFF */
#define OpCode_ReservedESC6	Make_OpCode_ESC(6)
#define OpCode_ReservedESC7	Make_OpCode_ESC(7)
#define OpCode_ReservedESC8	Make_OpCode_ESC(8)
#define OpCode_abs		Make_OpCode_ESC(9) /* CFF */
#define OpCode_add		Make_OpCode_ESC(10) /* CFF */
#define OpCode_sub		Make_OpCode_ESC(11) /* CFF */
#define OpCode_div		Make_OpCode_ESC(12) /* CFF */
#define OpCode_ReservedESC13	Make_OpCode_ESC(13)
#define OpCode_neg		Make_OpCode_ESC(14) /* CFF */
#define OpCode_eq		Make_OpCode_ESC(15) /* CFF */
#define OpCode_ReservedESC16	Make_OpCode_ESC(16)
#define OpCode_ReservedESC17	Make_OpCode_ESC(17)
#define OpCode_drop		Make_OpCode_ESC(18) /* CFF */
#define OpCode_ReservedESC19	Make_OpCode_ESC(19)
#define OpCode_put		Make_OpCode_ESC(20) /* CFF */
#define OpCode_get		Make_OpCode_ESC(21) /* CFF */
#define OpCode_ifelse		Make_OpCode_ESC(22) /* CFF */
#define OpCode_random		Make_OpCode_ESC(23) /* CFF */
#define OpCode_mul		Make_OpCode_ESC(24) /* CFF */
//#define OpCode_reservedESC25	Make_OpCode_ESC(25)
#define OpCode_sqrt		Make_OpCode_ESC(26) /* CFF */
#define OpCode_dup		Make_OpCode_ESC(27) /* CFF */
#define OpCode_exch		Make_OpCode_ESC(28) /* CFF */
#define OpCode_index		Make_OpCode_ESC(29) /* CFF */
#define OpCode_roll		Make_OpCode_ESC(30) /* CFF */
#define OpCode_reservedESC31	Make_OpCode_ESC(31)
#define OpCode_reservedESC32	Make_OpCode_ESC(32)
#define OpCode_reservedESC33	Make_OpCode_ESC(33)
#define OpCode_hflex		Make_OpCode_ESC(34) /* CFF, CFF2 */
#define OpCode_flex		Make_OpCode_ESC(35) /* CFF, CFF2 */
#define OpCode_hflex1		Make_OpCode_ESC(36) /* CFF, CFF2 */
#define OpCode_flex1		Make_OpCode_ESC(37) /* CFF, CFF2 */


#define OpCode_Invalid		0xFFFFu

217

M
Michiharu Ariza 已提交
218
struct number_t
M
Michiharu Ariza 已提交
219
{
220 221
  void init () { set_real (0.0); }
  void fini () {}
M
Michiharu Ariza 已提交
222

223
  void set_int (int v)       { value = (double) v; }
224 225
  int to_int () const        { return (int) value; }

226
  void set_fixed (int32_t v) { value = v / 65536.0; }
227 228
  int32_t to_fixed () const  { return (int32_t) (value * 65536.0); }

229
  void set_real (double v)   { value = v; }
230
  double to_real () const    { return value; }
231

232 233
  int ceil () const          { return (int) ::ceil (value); }
  int floor () const         { return (int) ::floor (value); }
234

235
  bool in_int_range () const
236
  { return ((double) (int16_t) to_int () == value); }
237

238 239 240 241
  bool operator >  (const number_t &n) const { return value > n.to_real (); }
  bool operator <  (const number_t &n) const { return n > *this; }
  bool operator >= (const number_t &n) const { return !(*this < n); }
  bool operator <= (const number_t &n) const { return !(*this > n); }
242

M
Michiharu Ariza 已提交
243
  const number_t &operator += (const number_t &n)
244
  {
245
    set_real (to_real () + n.to_real ());
M
Michiharu Ariza 已提交
246

247 248 249
    return *this;
  }

250
  protected:
251
  double	value;
M
Michiharu Ariza 已提交
252 253 254 255 256 257 258
};

/* byte string */
struct UnsizedByteStr : UnsizedArrayOf <HBUINT8>
{
  // encode 2-byte int (Dict/CharString) or 4-byte int (Dict)
  template <typename INTTYPE, int minVal, int maxVal>
M
Michiharu Ariza 已提交
259
  static bool serialize_int (hb_serialize_context_t *c, op_code_t intOp, int value)
M
Michiharu Ariza 已提交
260 261 262 263 264 265 266 267
  {
    TRACE_SERIALIZE (this);

    if (unlikely ((value < minVal || value > maxVal)))
      return_trace (false);

    HBUINT8 *p = c->allocate_size<HBUINT8> (1);
    if (unlikely (p == nullptr)) return_trace (false);
268
    *p = intOp;
M
Michiharu Ariza 已提交
269 270 271

    INTTYPE *ip = c->allocate_size<INTTYPE> (INTTYPE::static_size);
    if (unlikely (ip == nullptr)) return_trace (false);
272
    *ip = (unsigned int) value;
M
Michiharu Ariza 已提交
273 274 275

    return_trace (true);
  }
B
Behdad Esfahbod 已提交
276

277
  static bool serialize_int4 (hb_serialize_context_t *c, int value)
M
Michiharu Ariza 已提交
278
  { return serialize_int<HBUINT32, 0, 0x7FFFFFFF> (c, OpCode_longintdict, value); }
B
Behdad Esfahbod 已提交
279

280
  static bool serialize_int2 (hb_serialize_context_t *c, int value)
M
Michiharu Ariza 已提交
281
  { return serialize_int<HBUINT16, 0, 0x7FFF> (c, OpCode_shortint, value); }
M
Michiharu Ariza 已提交
282 283 284 285

  /* Defining null_size allows a Null object may be created. Should be safe because:
   * A descendent struct Dict uses a Null pointer to indicate a missing table,
   * checked before access.
M
Michiharu Ariza 已提交
286
   * byte_str_t, a wrapper struct pairing a byte pointer along with its length, always
M
Michiharu Ariza 已提交
287 288 289 290
   * checks the length before access. A Null pointer is used as the initial pointer
   * along with zero length by the default ctor.
   */
  DEFINE_SIZE_MIN(0);
M
Michiharu Ariza 已提交
291 292
};

M
Michiharu Ariza 已提交
293 294
/* Holder of a section of byte string within a CFFIndex entry */
struct byte_str_t : hb_ubytes_t
M
Michiharu Ariza 已提交
295
{
M
Michiharu Ariza 已提交
296 297 298 299 300 301 302 303
  byte_str_t ()
    : hb_ubytes_t () {}
  byte_str_t (const UnsizedByteStr& s, unsigned int l)
    : hb_ubytes_t ((const unsigned char*)&s, l) {}
  byte_str_t (const unsigned char *s, unsigned int l)
    : hb_ubytes_t (s, l) {}
  byte_str_t (const hb_ubytes_t &ub)	/* conversion from hb_ubytes_t */
    : hb_ubytes_t (ub) {}
304

M
Michiharu Ariza 已提交
305
  /* sub-string */
M
Michiharu Ariza 已提交
306 307
  byte_str_t sub_str (unsigned int offset, unsigned int len_) const
  { return byte_str_t (hb_ubytes_t::sub_array (offset, len_)); }
M
Michiharu Ariza 已提交
308

309
  bool check_limit (unsigned int offset, unsigned int count) const
M
Michiharu Ariza 已提交
310
  { return (offset + count <= length); }
M
Michiharu Ariza 已提交
311 312
};

M
Michiharu Ariza 已提交
313 314
/* A byte string associated with the current offset and an error condition */
struct byte_str_ref_t
M
Michiharu Ariza 已提交
315
{
316
  byte_str_ref_t () { init (); }
317

318
  void init ()
319
  {
M
Michiharu Ariza 已提交
320
    str = byte_str_t ();
321
    offset = 0;
322
    error = false;
323 324
  }

325
  void fini () {}
M
Michiharu Ariza 已提交
326

M
Michiharu Ariza 已提交
327
  byte_str_ref_t (const byte_str_t &str_, unsigned int offset_ = 0)
328
    : str (str_), offset (offset_), error (false) {}
M
Michiharu Ariza 已提交
329

M
Michiharu Ariza 已提交
330
  void reset (const byte_str_t &str_, unsigned int offset_ = 0)
M
Michiharu Ariza 已提交
331 332 333
  {
    str = str_;
    offset = offset_;
334
    error = false;
M
Michiharu Ariza 已提交
335 336
  }

M
Michiharu Ariza 已提交
337
  const unsigned char& operator [] (int i) {
338
    if (unlikely ((unsigned int) (offset + i) >= str.length))
339 340
    {
      set_error ();
341
      return Null (unsigned char);
342
    }
343
    return str[offset + i];
M
Michiharu Ariza 已提交
344 345
  }

M
Michiharu Ariza 已提交
346 347 348 349 350
  /* Conversion to byte_str_t */
  operator byte_str_t () const { return str.sub_str (offset, str.length - offset); }

  byte_str_t sub_str (unsigned int offset_, unsigned int len_) const
  { return str.sub_str (offset_, len_); }
M
Michiharu Ariza 已提交
351

352
  bool avail (unsigned int count=1) const
353
  { return (!in_error () && str.check_limit (offset, count)); }
354
  void inc (unsigned int count=1)
355
  {
M
Michiharu Ariza 已提交
356
    if (likely (!in_error () && (offset <= str.length) && (offset + count <= str.length)))
357 358 359 360 361
    {
      offset += count;
    }
    else
    {
M
Michiharu Ariza 已提交
362
      offset = str.length;
363 364 365
      set_error ();
    }
  }
M
Michiharu Ariza 已提交
366

367 368
  void set_error ()      { error = true; }
  bool in_error () const { return error; }
369

M
Michiharu Ariza 已提交
370
  byte_str_t       str;
M
Michiharu Ariza 已提交
371
  unsigned int  offset; /* beginning of the sub-string within str */
372 373

  protected:
B
Behdad Esfahbod 已提交
374
  bool	  error;
M
Michiharu Ariza 已提交
375 376
};

M
Michiharu Ariza 已提交
377
typedef hb_vector_t<byte_str_t> byte_str_array_t;
378

M
Michiharu Ariza 已提交
379 380
/* stack */
template <typename ELEM, int LIMIT>
381
struct cff_stack_t
M
Michiharu Ariza 已提交
382
{
383
  void init ()
384
  {
385
    error = false;
386 387 388
    count = 0;
    elements.init ();
    elements.resize (kSizeLimit);
389
    for (unsigned int i = 0; i < elements.length; i++)
390 391
      elements[i].init ();
  }
392
  void fini () { elements.fini_deep (); }
M
Michiharu Ariza 已提交
393

394
  ELEM& operator [] (unsigned int i)
395 396 397 398
  {
    if (unlikely (i >= count)) set_error ();
    return elements[i];
  }
399

400
  void push (const ELEM &v)
M
Michiharu Ariza 已提交
401
  {
402
    if (likely (count < elements.length))
403
      elements[count++] = v;
404 405
    else
      set_error ();
M
Michiharu Ariza 已提交
406
  }
407
  ELEM &push ()
408
  {
409
    if (likely (count < elements.length))
410 411
      return elements[count++];
    else
412 413
    {
      set_error ();
414
      return Crap(ELEM);
415
    }
416 417
  }

418
  ELEM& pop ()
M
Michiharu Ariza 已提交
419
  {
420 421
    if (likely (count > 0))
      return elements[--count];
M
Michiharu Ariza 已提交
422
    else
423 424
    {
      set_error ();
M
Michiharu Ariza 已提交
425
      return Crap(ELEM);
426
    }
M
Michiharu Ariza 已提交
427
  }
428
  void pop (unsigned int n)
429 430 431
  {
    if (likely (count >= n))
      count -= n;
432 433
    else
      set_error ();
434 435
  }

436
  const ELEM& peek ()
437
  {
438
    if (unlikely (count < 0))
439 440
    {
      set_error ();
441
      return Null(ELEM);
442
    }
443
    return elements[count - 1];
444 445
  }

446
  void unpop ()
M
Michiharu Ariza 已提交
447
  {
448
    if (likely (count < elements.length))
449
      count++;
450 451
    else
      set_error ();
M
Michiharu Ariza 已提交
452 453
  }

454
  void clear () { count = 0; }
M
Michiharu Ariza 已提交
455

456 457
  bool in_error () const { return (error || elements.in_error ()); }
  void set_error ()      { error = true; }
M
Michiharu Ariza 已提交
458

459
  unsigned int get_count () const { return count; }
460
  bool is_empty () const          { return !count; }
M
Michiharu Ariza 已提交
461

462
  static constexpr unsigned kSizeLimit = LIMIT;
M
Michiharu Ariza 已提交
463

464
  protected:
465
  bool error;
466
  unsigned int count;
B
Behdad Esfahbod 已提交
467
  hb_vector_t<ELEM> elements;
M
Michiharu Ariza 已提交
468 469 470
};

/* argument stack */
M
Michiharu Ariza 已提交
471
template <typename ARG=number_t>
472
struct arg_stack_t : cff_stack_t<ARG, 513>
M
Michiharu Ariza 已提交
473
{
474
  void push_int (int v)
M
Michiharu Ariza 已提交
475
  {
476
    ARG &n = S::push ();
M
Michiharu Ariza 已提交
477
    n.set_int (v);
478 479
  }

480
  void push_fixed (int32_t v)
481 482 483
  {
    ARG &n = S::push ();
    n.set_fixed (v);
M
Michiharu Ariza 已提交
484 485
  }

486
  void push_real (double v)
M
Michiharu Ariza 已提交
487
  {
488
    ARG &n = S::push ();
M
Michiharu Ariza 已提交
489 490 491
    n.set_real (v);
  }

492
  ARG& pop_num () { return this->pop (); }
M
Michiharu Ariza 已提交
493

494
  int pop_int ()  { return this->pop ().to_int (); }
M
Michiharu Ariza 已提交
495

496
  unsigned int pop_uint ()
M
Michiharu Ariza 已提交
497
  {
498
    int i = pop_int ();
499 500 501 502 503
    if (unlikely (i < 0))
    {
      i = 0;
      S::set_error ();
    }
504
    return (unsigned) i;
M
Michiharu Ariza 已提交
505 506
  }

M
Michiharu Ariza 已提交
507
  void push_longint_from_substr (byte_str_ref_t& str_ref)
M
Michiharu Ariza 已提交
508
  {
M
Michiharu Ariza 已提交
509 510
    push_int ((str_ref[0] << 24) | (str_ref[1] << 16) | (str_ref[2] << 8) | (str_ref[3]));
    str_ref.inc (4);
M
Michiharu Ariza 已提交
511 512
  }

M
Michiharu Ariza 已提交
513
  bool push_fixed_from_substr (byte_str_ref_t& str_ref)
M
Michiharu Ariza 已提交
514
  {
M
Michiharu Ariza 已提交
515
    if (unlikely (!str_ref.avail (4)))
M
Michiharu Ariza 已提交
516
      return false;
M
Michiharu Ariza 已提交
517 518
    push_fixed ((int32_t)*(const HBUINT32*)&str_ref[0]);
    str_ref.inc (4);
M
Michiharu Ariza 已提交
519 520 521
    return true;
  }

522
  hb_array_t<const ARG> get_subarray (unsigned int start) const
523
  { return S::elements.sub_array (start); }
524

525
  private:
526
  typedef cff_stack_t<ARG, 513> S;
M
Michiharu Ariza 已提交
527 528 529
};

/* an operator prefixed by its operands in a byte string */
M
Michiharu Ariza 已提交
530
struct op_str_t
M
Michiharu Ariza 已提交
531
{
532 533
  void init () {}
  void fini () {}
534

M
Michiharu Ariza 已提交
535 536
  op_code_t  op;
  byte_str_t str;
M
Michiharu Ariza 已提交
537 538 539
};

/* base of OP_SERIALIZER */
M
Michiharu Ariza 已提交
540
struct op_serializer_t
M
Michiharu Ariza 已提交
541 542
{
  protected:
M
Michiharu Ariza 已提交
543
  bool copy_opstr (hb_serialize_context_t *c, const op_str_t& opstr) const
M
Michiharu Ariza 已提交
544 545 546
  {
    TRACE_SERIALIZE (this);

M
Michiharu Ariza 已提交
547
    HBUINT8 *d = c->allocate_size<HBUINT8> (opstr.str.length);
M
Michiharu Ariza 已提交
548
    if (unlikely (d == nullptr)) return_trace (false);
M
Michiharu Ariza 已提交
549
    memcpy (d, &opstr.str[0], opstr.str.length);
M
Michiharu Ariza 已提交
550 551 552 553
    return_trace (true);
  }
};

554
template <typename VAL>
M
Michiharu Ariza 已提交
555
struct parsed_values_t
556
{
557
  void init ()
558 559 560 561
  {
    opStart = 0;
    values.init ();
  }
562
  void fini () { values.fini_deep (); }
563

M
Michiharu Ariza 已提交
564
  void add_op (op_code_t op, const byte_str_ref_t& str_ref = byte_str_ref_t ())
565 566 567
  {
    VAL *val = values.push ();
    val->op = op;
M
Michiharu Ariza 已提交
568 569
    val->str = str_ref.str.sub_str (opStart, str_ref.offset - opStart);
    opStart = str_ref.offset;
570 571
  }

M
Michiharu Ariza 已提交
572
  void add_op (op_code_t op, const byte_str_ref_t& str_ref, const VAL &v)
573 574 575
  {
    VAL *val = values.push (v);
    val->op = op;
M
Michiharu Ariza 已提交
576 577
    val->str = str_ref.sub_str ( opStart, str_ref.offset - opStart);
    opStart = str_ref.offset;
578 579
  }

M
Michiharu Ariza 已提交
580
  bool has_op (op_code_t op) const
581 582 583 584 585 586
  {
    for (unsigned int i = 0; i < get_count (); i++)
      if (get_value (i).op == op) return true;
    return false;
  }

587
  unsigned get_count () const { return values.length; }
588
  const VAL &get_value (unsigned int i)   const { return values[i]; }
589
  const VAL &operator [] (unsigned int i) const { return get_value (i); }
590 591 592 593 594

  unsigned int       opStart;
  hb_vector_t<VAL>   values;
};

M
Michiharu Ariza 已提交
595 596
template <typename ARG=number_t>
struct interp_env_t
M
Michiharu Ariza 已提交
597
{
M
Michiharu Ariza 已提交
598
  void init (const byte_str_t &str_)
M
Michiharu Ariza 已提交
599
  {
M
Michiharu Ariza 已提交
600
    str_ref.reset (str_);
M
Michiharu Ariza 已提交
601
    argStack.init ();
602
    error = false;
M
Michiharu Ariza 已提交
603
  }
604
  void fini () { argStack.fini (); }
M
Michiharu Ariza 已提交
605

606
  bool in_error () const
M
Michiharu Ariza 已提交
607
  { return error || str_ref.in_error () || argStack.in_error (); }
608

609
  void set_error () { error = true; }
610

M
Michiharu Ariza 已提交
611
  op_code_t fetch_op ()
M
Michiharu Ariza 已提交
612
  {
M
Michiharu Ariza 已提交
613 614
    op_code_t  op = OpCode_Invalid;
    if (unlikely (!str_ref.avail ()))
615
      return OpCode_Invalid;
M
Michiharu Ariza 已提交
616
    op = (op_code_t)(unsigned char)str_ref[0];
M
Michiharu Ariza 已提交
617
    if (op == OpCode_escape) {
M
Michiharu Ariza 已提交
618
      if (unlikely (!str_ref.avail ()))
B
Behdad Esfahbod 已提交
619
	return OpCode_Invalid;
M
Michiharu Ariza 已提交
620 621
      op = Make_OpCode_ESC(str_ref[1]);
      str_ref.inc ();
M
Michiharu Ariza 已提交
622
    }
M
Michiharu Ariza 已提交
623
    str_ref.inc ();
624
    return op;
M
Michiharu Ariza 已提交
625
  }
M
Michiharu Ariza 已提交
626

627
  const ARG& eval_arg (unsigned int i) { return argStack[i]; }
M
Michiharu Ariza 已提交
628

629 630
  ARG& pop_arg () { return argStack.pop (); }
  void pop_n_args (unsigned int n) { argStack.pop (n); }
631

632
  void clear_args () { pop_n_args (argStack.get_count ()); }
633

634 635 636 637
  byte_str_ref_t
		str_ref;
  arg_stack_t<ARG>
		argStack;
638
  protected:
639
  bool		error;
M
Michiharu Ariza 已提交
640 641
};

M
Michiharu Ariza 已提交
642
typedef interp_env_t<> num_interp_env_t;
643

M
Michiharu Ariza 已提交
644 645
template <typename ARG=number_t>
struct opset_t
M
Michiharu Ariza 已提交
646
{
M
Michiharu Ariza 已提交
647
  static void process_op (op_code_t op, interp_env_t<ARG>& env)
M
Michiharu Ariza 已提交
648 649 650
  {
    switch (op) {
      case OpCode_shortint:
M
Michiharu Ariza 已提交
651 652
	env.argStack.push_int ((int16_t)((env.str_ref[0] << 8) | env.str_ref[1]));
	env.str_ref.inc (2);
B
Behdad Esfahbod 已提交
653
	break;
M
Michiharu Ariza 已提交
654 655 656

      case OpCode_TwoBytePosInt0: case OpCode_TwoBytePosInt1:
      case OpCode_TwoBytePosInt2: case OpCode_TwoBytePosInt3:
M
Michiharu Ariza 已提交
657 658
	env.argStack.push_int ((int16_t)((op - OpCode_TwoBytePosInt0) * 256 + env.str_ref[0] + 108));
	env.str_ref.inc ();
B
Behdad Esfahbod 已提交
659
	break;
B
Behdad Esfahbod 已提交
660

M
Michiharu Ariza 已提交
661 662
      case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1:
      case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3:
M
Michiharu Ariza 已提交
663
	env.argStack.push_int ((-(int16_t)(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108));
M
Michiharu Ariza 已提交
664
	env.str_ref.inc ();
B
Behdad Esfahbod 已提交
665
	break;
M
Michiharu Ariza 已提交
666 667

      default:
B
Behdad Esfahbod 已提交
668 669 670 671 672 673 674 675 676 677
	/* 1-byte integer */
	if (likely ((OpCode_OneByteIntFirst <= op) && (op <= OpCode_OneByteIntLast)))
	{
	  env.argStack.push_int ((int)op - 139);
	} else {
	  /* invalid unknown operator */
	  env.clear_args ();
	  env.set_error ();
	}
	break;
M
Michiharu Ariza 已提交
678 679 680 681 682
    }
  }
};

template <typename ENV>
683 684
struct interpreter_t
{
M
Michiharu Ariza 已提交
685
  ~interpreter_t() { fini (); }
M
Michiharu Ariza 已提交
686

687
  void fini () { env.fini (); }
M
Michiharu Ariza 已提交
688 689 690 691 692 693

  ENV env;
};

} /* namespace CFF */

M
Michiharu Ariza 已提交
694
#endif /* HB_CFF_INTERP_COMMON_HH */