Imported Upstream version 1.8.1
[platform/upstream/harfbuzz.git] / src / hb-open-type-private.hh
1 /*
2  * Copyright © 2007,2008,2009,2010  Red Hat, Inc.
3  * Copyright © 2012  Google, Inc.
4  *
5  *  This is part of HarfBuzz, a text shaping library.
6  *
7  * Permission is hereby granted, without written agreement and without
8  * license or royalty fees, to use, copy, modify, and distribute this
9  * software and its documentation for any purpose, provided that the
10  * above copyright notice and the following two paragraphs appear in
11  * all copies of this software.
12  *
13  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
15  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
16  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
17  * DAMAGE.
18  *
19  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
20  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
22  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
23  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
24  *
25  * Red Hat Author(s): Behdad Esfahbod
26  * Google Author(s): Behdad Esfahbod
27  */
28
29 #ifndef HB_OPEN_TYPE_PRIVATE_HH
30 #define HB_OPEN_TYPE_PRIVATE_HH
31
32 #include "hb-private.hh"
33 #include "hb-debug.hh"
34 #include "hb-blob-private.hh"
35 #include "hb-face-private.hh"
36
37
38 namespace OT {
39
40
41
42 /*
43  * Casts
44  */
45
46 /* Cast to struct T, reference to reference */
47 template<typename Type, typename TObject>
48 static inline const Type& CastR(const TObject &X)
49 { return reinterpret_cast<const Type&> (X); }
50 template<typename Type, typename TObject>
51 static inline Type& CastR(TObject &X)
52 { return reinterpret_cast<Type&> (X); }
53
54 /* Cast to struct T, pointer to pointer */
55 template<typename Type, typename TObject>
56 static inline const Type* CastP(const TObject *X)
57 { return reinterpret_cast<const Type*> (X); }
58 template<typename Type, typename TObject>
59 static inline Type* CastP(TObject *X)
60 { return reinterpret_cast<Type*> (X); }
61
62 /* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory
63  * location pointed to by P plus Ofs bytes. */
64 template<typename Type>
65 static inline const Type& StructAtOffset(const void *P, unsigned int offset)
66 { return * reinterpret_cast<const Type*> ((const char *) P + offset); }
67 template<typename Type>
68 static inline Type& StructAtOffset(void *P, unsigned int offset)
69 { return * reinterpret_cast<Type*> ((char *) P + offset); }
70
71 /* StructAfter<T>(X) returns the struct T& that is placed after X.
72  * Works with X of variable size also.  X must implement get_size() */
73 template<typename Type, typename TObject>
74 static inline const Type& StructAfter(const TObject &X)
75 { return StructAtOffset<Type>(&X, X.get_size()); }
76 template<typename Type, typename TObject>
77 static inline Type& StructAfter(TObject &X)
78 { return StructAtOffset<Type>(&X, X.get_size()); }
79
80
81
82 /*
83  * Size checking
84  */
85
86 /* Check _assertion in a method environment */
87 #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
88   inline void _instance_assertion_on_line_##_line (void) const \
89   { \
90     static_assert ((_assertion), ""); \
91     ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
92   }
93 # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
94 # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
95
96 /* Check that _code compiles in a method environment */
97 #define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
98   inline void _compiles_assertion_on_line_##_line (void) const \
99   { _code; }
100 # define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
101 # define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
102
103
104 #define DEFINE_SIZE_STATIC(size) \
105   DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
106   static const unsigned int static_size = (size); \
107   static const unsigned int min_size = (size); \
108   inline unsigned int get_size (void) const { return (size); }
109
110 #define DEFINE_SIZE_UNION(size, _member) \
111   DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \
112   static const unsigned int min_size = (size)
113
114 #define DEFINE_SIZE_MIN(size) \
115   DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
116   static const unsigned int min_size = (size)
117
118 #define DEFINE_SIZE_ARRAY(size, array) \
119   DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
120   DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
121   static const unsigned int min_size = (size)
122
123 #define DEFINE_SIZE_ARRAY2(size, array1, array2) \
124   DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
125   DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
126   static const unsigned int min_size = (size)
127
128
129
130 /*
131  * Dispatch
132  */
133
134 template <typename Context, typename Return, unsigned int MaxDebugDepth>
135 struct hb_dispatch_context_t
136 {
137   static const unsigned int max_debug_depth = MaxDebugDepth;
138   typedef Return return_t;
139   template <typename T, typename F>
140   inline bool may_dispatch (const T *obj, const F *format) { return true; }
141   static return_t no_dispatch_return_value (void) { return Context::default_return_value (); }
142 };
143
144
145 /*
146  * Sanitize
147  */
148
149 /* This limits sanitizing time on really broken fonts. */
150 #ifndef HB_SANITIZE_MAX_EDITS
151 #define HB_SANITIZE_MAX_EDITS 32
152 #endif
153 #ifndef HB_SANITIZE_MAX_OPS_FACTOR
154 #define HB_SANITIZE_MAX_OPS_FACTOR 8
155 #endif
156 #ifndef HB_SANITIZE_MAX_OPS_MIN
157 #define HB_SANITIZE_MAX_OPS_MIN 16384
158 #endif
159
160 struct hb_sanitize_context_t :
161        hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
162 {
163   inline hb_sanitize_context_t (void) :
164         debug_depth (0),
165         start (nullptr), end (nullptr),
166         writable (false), edit_count (0), max_ops (0),
167         blob (nullptr),
168         num_glyphs (0) {}
169
170   inline const char *get_name (void) { return "SANITIZE"; }
171   template <typename T, typename F>
172   inline bool may_dispatch (const T *obj, const F *format)
173   { return format->sanitize (this); }
174   template <typename T>
175   inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
176   static return_t default_return_value (void) { return true; }
177   static return_t no_dispatch_return_value (void) { return false; }
178   bool stop_sublookup_iteration (const return_t r) const { return !r; }
179
180   inline void init (hb_blob_t *b)
181   {
182     this->blob = hb_blob_reference (b);
183     this->writable = false;
184   }
185
186   inline void start_processing (void)
187   {
188     this->start = hb_blob_get_data (this->blob, nullptr);
189     this->end = this->start + this->blob->length;
190     assert (this->start <= this->end); /* Must not overflow. */
191     this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
192                          (unsigned) HB_SANITIZE_MAX_OPS_MIN);
193     this->edit_count = 0;
194     this->debug_depth = 0;
195
196     DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
197                      "start [%p..%p] (%lu bytes)",
198                      this->start, this->end,
199                      (unsigned long) (this->end - this->start));
200   }
201
202   inline void end_processing (void)
203   {
204     DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1,
205                      "end [%p..%p] %u edit requests",
206                      this->start, this->end, this->edit_count);
207
208     hb_blob_destroy (this->blob);
209     this->blob = nullptr;
210     this->start = this->end = nullptr;
211   }
212
213   inline bool check_range (const void *base, unsigned int len) const
214   {
215     const char *p = (const char *) base;
216     bool ok = this->max_ops-- > 0 &&
217               this->start <= p &&
218               p <= this->end &&
219               (unsigned int) (this->end - p) >= len;
220
221     DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
222        "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s",
223        p, p + len, len,
224        this->start, this->end,
225        ok ? "OK" : "OUT-OF-RANGE");
226
227     return likely (ok);
228   }
229
230   inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const
231   {
232     const char *p = (const char *) base;
233     bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
234     unsigned int array_size = record_size * len;
235     bool ok = !overflows && this->check_range (base, array_size);
236
237     DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
238        "check_array [%p..%p] (%d*%d=%d bytes) in [%p..%p] -> %s",
239        p, p + (record_size * len), record_size, len, (unsigned int) array_size,
240        this->start, this->end,
241        overflows ? "OVERFLOWS" : ok ? "OK" : "OUT-OF-RANGE");
242
243     return likely (ok);
244   }
245
246   template <typename Type>
247   inline bool check_struct (const Type *obj) const
248   {
249     return likely (this->check_range (obj, obj->min_size));
250   }
251
252   inline bool may_edit (const void *base, unsigned int len)
253   {
254     if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
255       return false;
256
257     const char *p = (const char *) base;
258     this->edit_count++;
259
260     DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
261        "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
262        this->edit_count,
263        p, p + len, len,
264        this->start, this->end,
265        this->writable ? "GRANTED" : "DENIED");
266
267     return this->writable;
268   }
269
270   template <typename Type, typename ValueType>
271   inline bool try_set (const Type *obj, const ValueType &v) {
272     if (this->may_edit (obj, obj->static_size)) {
273       const_cast<Type *> (obj)->set (v);
274       return true;
275     }
276     return false;
277   }
278
279   mutable unsigned int debug_depth;
280   const char *start, *end;
281   bool writable;
282   unsigned int edit_count;
283   mutable int max_ops;
284   hb_blob_t *blob;
285   unsigned int num_glyphs;
286 };
287
288
289
290 /* Template to sanitize an object. */
291 template <typename Type>
292 struct Sanitizer
293 {
294   inline Sanitizer (void) {}
295
296   inline hb_blob_t *sanitize (hb_blob_t *blob) {
297     bool sane;
298
299     /* TODO is_sane() stuff */
300
301     c->init (blob);
302
303   retry:
304     DEBUG_MSG_FUNC (SANITIZE, c->start, "start");
305
306     c->start_processing ();
307
308     if (unlikely (!c->start)) {
309       c->end_processing ();
310       return blob;
311     }
312
313     Type *t = CastP<Type> (const_cast<char *> (c->start));
314
315     sane = t->sanitize (c);
316     if (sane) {
317       if (c->edit_count) {
318         DEBUG_MSG_FUNC (SANITIZE, c->start, "passed first round with %d edits; going for second round", c->edit_count);
319
320         /* sanitize again to ensure no toe-stepping */
321         c->edit_count = 0;
322         sane = t->sanitize (c);
323         if (c->edit_count) {
324           DEBUG_MSG_FUNC (SANITIZE, c->start, "requested %d edits in second round; FAILLING", c->edit_count);
325           sane = false;
326         }
327       }
328     } else {
329       unsigned int edit_count = c->edit_count;
330       if (edit_count && !c->writable) {
331         c->start = hb_blob_get_data_writable (blob, nullptr);
332         c->end = c->start + blob->length;
333
334         if (c->start) {
335           c->writable = true;
336           /* ok, we made it writable by relocating.  try again */
337           DEBUG_MSG_FUNC (SANITIZE, c->start, "retry");
338           goto retry;
339         }
340       }
341     }
342
343     c->end_processing ();
344
345     DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED");
346     if (sane)
347     {
348       blob->lock ();
349       return blob;
350     }
351     else
352     {
353       hb_blob_destroy (blob);
354       return hb_blob_get_empty ();
355     }
356   }
357
358   inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; }
359
360   private:
361   hb_sanitize_context_t c[1];
362 };
363
364
365
366 /*
367  * Serialize
368  */
369
370
371 struct hb_serialize_context_t
372 {
373   inline hb_serialize_context_t (void *start_, unsigned int size)
374   {
375     this->start = (char *) start_;
376     this->end = this->start + size;
377
378     this->ran_out_of_room = false;
379     this->head = this->start;
380     this->debug_depth = 0;
381   }
382
383   template <typename Type>
384   inline Type *start_serialize (void)
385   {
386     DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
387                      "start [%p..%p] (%lu bytes)",
388                      this->start, this->end,
389                      (unsigned long) (this->end - this->start));
390
391     return start_embed<Type> ();
392   }
393
394   inline void end_serialize (void)
395   {
396     DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, -1,
397                      "end [%p..%p] serialized %d bytes; %s",
398                      this->start, this->end,
399                      (int) (this->head - this->start),
400                      this->ran_out_of_room ? "RAN OUT OF ROOM" : "did not ran out of room");
401
402   }
403
404   template <typename Type>
405   inline Type *copy (void)
406   {
407     assert (!this->ran_out_of_room);
408     unsigned int len = this->head - this->start;
409     void *p = malloc (len);
410     if (p)
411       memcpy (p, this->start, len);
412     return reinterpret_cast<Type *> (p);
413   }
414
415   template <typename Type>
416   inline Type *allocate_size (unsigned int size)
417   {
418     if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
419       this->ran_out_of_room = true;
420       return nullptr;
421     }
422     memset (this->head, 0, size);
423     char *ret = this->head;
424     this->head += size;
425     return reinterpret_cast<Type *> (ret);
426   }
427
428   template <typename Type>
429   inline Type *allocate_min (void)
430   {
431     return this->allocate_size<Type> (Type::min_size);
432   }
433
434   template <typename Type>
435   inline Type *start_embed (void)
436   {
437     Type *ret = reinterpret_cast<Type *> (this->head);
438     return ret;
439   }
440
441   template <typename Type>
442   inline Type *embed (const Type &obj)
443   {
444     unsigned int size = obj.get_size ();
445     Type *ret = this->allocate_size<Type> (size);
446     if (unlikely (!ret)) return nullptr;
447     memcpy (ret, obj, size);
448     return ret;
449   }
450
451   template <typename Type>
452   inline Type *extend_min (Type &obj)
453   {
454     unsigned int size = obj.min_size;
455     assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
456     if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
457     return reinterpret_cast<Type *> (&obj);
458   }
459
460   template <typename Type>
461   inline Type *extend (Type &obj)
462   {
463     unsigned int size = obj.get_size ();
464     assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
465     if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
466     return reinterpret_cast<Type *> (&obj);
467   }
468
469   inline void truncate (void *new_head)
470   {
471     assert (this->start < new_head && new_head <= this->head);
472     this->head = (char *) new_head;
473   }
474
475   unsigned int debug_depth;
476   char *start, *end, *head;
477   bool ran_out_of_room;
478 };
479
480 template <typename Type>
481 struct Supplier
482 {
483   inline Supplier (const Type *array, unsigned int len_, unsigned int stride_=sizeof(Type))
484   {
485     head = array;
486     len = len_;
487     stride = stride_;
488   }
489   inline const Type operator [] (unsigned int i) const
490   {
491     if (unlikely (i >= len)) return Type ();
492     return * (const Type *) (const void *) ((const char *) head + stride * i);
493   }
494
495   inline Supplier<Type> & operator += (unsigned int count)
496   {
497     if (unlikely (count > len))
498       count = len;
499     len -= count;
500     head = (const Type *) (const void *) ((const char *) head + stride * count);
501     return *this;
502   }
503
504   private:
505   inline Supplier (const Supplier<Type> &); /* Disallow copy */
506   inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
507
508   unsigned int len;
509   unsigned int stride;
510   const Type *head;
511 };
512
513
514 /*
515  *
516  * The OpenType Font File: Data Types
517  */
518
519
520 /* "The following data types are used in the OpenType font file.
521  *  All OpenType fonts use Motorola-style byte ordering (Big Endian):" */
522
523 /*
524  * Int types
525  */
526
527
528 template <typename Type, int Bytes> struct BEInt;
529
530 template <typename Type>
531 struct BEInt<Type, 1>
532 {
533   public:
534   inline void set (Type V)
535   {
536     v = V;
537   }
538   inline operator Type (void) const
539   {
540     return v;
541   }
542   private: uint8_t v;
543 };
544 template <typename Type>
545 struct BEInt<Type, 2>
546 {
547   public:
548   inline void set (Type V)
549   {
550     v[0] = (V >>  8) & 0xFF;
551     v[1] = (V      ) & 0xFF;
552   }
553   inline operator Type (void) const
554   {
555     return (v[0] <<  8)
556          + (v[1]      );
557   }
558   private: uint8_t v[2];
559 };
560 template <typename Type>
561 struct BEInt<Type, 3>
562 {
563   public:
564   inline void set (Type V)
565   {
566     v[0] = (V >> 16) & 0xFF;
567     v[1] = (V >>  8) & 0xFF;
568     v[2] = (V      ) & 0xFF;
569   }
570   inline operator Type (void) const
571   {
572     return (v[0] << 16)
573          + (v[1] <<  8)
574          + (v[2]      );
575   }
576   private: uint8_t v[3];
577 };
578 template <typename Type>
579 struct BEInt<Type, 4>
580 {
581   public:
582   inline void set (Type V)
583   {
584     v[0] = (V >> 24) & 0xFF;
585     v[1] = (V >> 16) & 0xFF;
586     v[2] = (V >>  8) & 0xFF;
587     v[3] = (V      ) & 0xFF;
588   }
589   inline operator Type (void) const
590   {
591     return (v[0] << 24)
592          + (v[1] << 16)
593          + (v[2] <<  8)
594          + (v[3]      );
595   }
596   private: uint8_t v[4];
597 };
598
599 /* Integer types in big-endian order and no alignment requirement */
600 template <typename Type, unsigned int Size>
601 struct IntType
602 {
603   inline void set (Type i) { v.set (i); }
604   inline operator Type(void) const { return v; }
605   inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
606   inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
607   static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
608   template <typename Type2>
609   inline int cmp (Type2 a) const
610   {
611     Type b = v;
612     if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int))
613       return (int) a - (int) b;
614     else
615       return a < b ? -1 : a == b ? 0 : +1;
616   }
617   inline bool sanitize (hb_sanitize_context_t *c) const
618   {
619     TRACE_SANITIZE (this);
620     return_trace (likely (c->check_struct (this)));
621   }
622   protected:
623   BEInt<Type, Size> v;
624   public:
625   DEFINE_SIZE_STATIC (Size);
626 };
627
628 typedef IntType<uint8_t,  1> HBUINT8;   /* 8-bit unsigned integer. */
629 typedef IntType<int8_t,   1> HBINT8;    /* 8-bit signed integer. */
630 typedef IntType<uint16_t, 2> HBUINT16;  /* 16-bit unsigned integer. */
631 typedef IntType<int16_t,  2> HBINT16;   /* 16-bit signed integer. */
632 typedef IntType<uint32_t, 4> HBUINT32;  /* 32-bit unsigned integer. */
633 typedef IntType<int32_t,  4> HBINT32;   /* 32-bit signed integer. */
634 typedef IntType<uint32_t, 3> HBUINT24;  /* 24-bit unsigned integer. */
635
636 /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
637 typedef HBINT16 FWORD;
638
639 /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
640 typedef HBUINT16 UFWORD;
641
642 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
643 struct F2DOT14 : HBINT16
644 {
645   // 16384 means 1<<14
646   inline float to_float (void) const { return ((int32_t) v) / 16384.f; }
647   inline void set_float (float f) { v.set (round (f * 16384.f)); }
648   public:
649   DEFINE_SIZE_STATIC (2);
650 };
651
652 /* 32-bit signed fixed-point number (16.16). */
653 struct Fixed : HBINT32
654 {
655   // 65536 means 1<<16
656   inline float to_float (void) const { return ((int32_t) v) / 65536.f; }
657   inline void set_float (float f) { v.set (round (f * 65536.f)); }
658   public:
659   DEFINE_SIZE_STATIC (4);
660 };
661
662 /* Date represented in number of seconds since 12:00 midnight, January 1,
663  * 1904. The value is represented as a signed 64-bit integer. */
664 struct LONGDATETIME
665 {
666   inline bool sanitize (hb_sanitize_context_t *c) const
667   {
668     TRACE_SANITIZE (this);
669     return_trace (likely (c->check_struct (this)));
670   }
671   protected:
672   HBINT32 major;
673   HBUINT32 minor;
674   public:
675   DEFINE_SIZE_STATIC (8);
676 };
677
678 /* Array of four uint8s (length = 32 bits) used to identify a script, language
679  * system, feature, or baseline */
680 struct Tag : HBUINT32
681 {
682   /* What the char* converters return is NOT nul-terminated.  Print using "%.4s" */
683   inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
684   inline operator char* (void) { return reinterpret_cast<char *> (&this->v); }
685   public:
686   DEFINE_SIZE_STATIC (4);
687 };
688 DEFINE_NULL_DATA (OT, Tag, "    ");
689
690 /* Glyph index number, same as uint16 (length = 16 bits) */
691 typedef HBUINT16 GlyphID;
692
693 /* Name-table index, same as uint16 (length = 16 bits) */
694 typedef HBUINT16 NameID;
695
696 /* Script/language-system/feature index */
697 struct Index : HBUINT16 {
698   static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
699 };
700 DEFINE_NULL_DATA (OT, Index, "\xff\xff");
701
702 /* Offset, Null offset = 0 */
703 template <typename Type>
704 struct Offset : Type
705 {
706   inline bool is_null (void) const { return 0 == *this; }
707
708   inline void *serialize (hb_serialize_context_t *c, const void *base)
709   {
710     void *t = c->start_embed<void> ();
711     this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
712     return t;
713   }
714
715   public:
716   DEFINE_SIZE_STATIC (sizeof(Type));
717 };
718
719 typedef Offset<HBUINT16> Offset16;
720 typedef Offset<HBUINT32> Offset32;
721
722
723 /* CheckSum */
724 struct CheckSum : HBUINT32
725 {
726   /* This is reference implementation from the spec. */
727   static inline uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length)
728   {
729     uint32_t Sum = 0L;
730     assert (0 == (Length & 3));
731     const HBUINT32 *EndPtr = Table + Length / HBUINT32::static_size;
732
733     while (Table < EndPtr)
734       Sum += *Table++;
735     return Sum;
736   }
737
738   /* Note: data should be 4byte aligned and have 4byte padding at the end. */
739   inline void set_for_data (const void *data, unsigned int length)
740   { set (CalcTableChecksum ((const HBUINT32 *) data, length)); }
741
742   public:
743   DEFINE_SIZE_STATIC (4);
744 };
745
746
747 /*
748  * Version Numbers
749  */
750
751 template <typename FixedType=HBUINT16>
752 struct FixedVersion
753 {
754   inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; }
755
756   inline bool sanitize (hb_sanitize_context_t *c) const
757   {
758     TRACE_SANITIZE (this);
759     return_trace (c->check_struct (this));
760   }
761
762   FixedType major;
763   FixedType minor;
764   public:
765   DEFINE_SIZE_STATIC (2 * sizeof(FixedType));
766 };
767
768
769
770 /*
771  * Template subclasses of Offset that do the dereferencing.
772  * Use: (base+offset)
773  */
774
775 template <typename Type, typename OffsetType=HBUINT16>
776 struct OffsetTo : Offset<OffsetType>
777 {
778   inline const Type& operator () (const void *base) const
779   {
780     unsigned int offset = *this;
781     if (unlikely (!offset)) return Null(Type);
782     return StructAtOffset<const Type> (base, offset);
783   }
784   inline Type& operator () (void *base) const
785   {
786     unsigned int offset = *this;
787     if (unlikely (!offset)) return Crap(Type);
788     return StructAtOffset<Type> (base, offset);
789   }
790
791   inline Type& serialize (hb_serialize_context_t *c, const void *base)
792   {
793     return * (Type *) Offset<OffsetType>::serialize (c, base);
794   }
795
796   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
797   {
798     TRACE_SANITIZE (this);
799     if (unlikely (!c->check_struct (this))) return_trace (false);
800     unsigned int offset = *this;
801     if (unlikely (!offset)) return_trace (true);
802     if (unlikely (!c->check_range (base, offset))) return_trace (false);
803     const Type &obj = StructAtOffset<Type> (base, offset);
804     return_trace (likely (obj.sanitize (c)) || neuter (c));
805   }
806   template <typename T>
807   inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
808   {
809     TRACE_SANITIZE (this);
810     if (unlikely (!c->check_struct (this))) return_trace (false);
811     unsigned int offset = *this;
812     if (unlikely (!offset)) return_trace (true);
813     if (unlikely (!c->check_range (base, offset))) return_trace (false);
814     const Type &obj = StructAtOffset<Type> (base, offset);
815     return_trace (likely (obj.sanitize (c, user_data)) || neuter (c));
816   }
817
818   /* Set the offset to Null */
819   inline bool neuter (hb_sanitize_context_t *c) const {
820     return c->try_set (this, 0);
821   }
822   DEFINE_SIZE_STATIC (sizeof(OffsetType));
823 };
824 template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {};
825 template <typename Base, typename OffsetType, typename Type>
826 static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
827 template <typename Base, typename OffsetType, typename Type>
828 static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); }
829
830
831 /*
832  * Array Types
833  */
834
835
836 /* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */
837 template <typename Type>
838 struct UnsizedArrayOf
839 {
840   inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
841   inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
842
843   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
844   {
845     TRACE_SANITIZE (this);
846     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
847
848     /* Note: for structs that do not reference other structs,
849      * we do not need to call their sanitize() as we already did
850      * a bound check on the aggregate array size.  We just include
851      * a small unreachable expression to make sure the structs
852      * pointed to do have a simple sanitize(), ie. they do not
853      * reference other structs via offsets.
854      */
855     (void) (false && arrayZ[0].sanitize (c));
856
857     return_trace (true);
858   }
859   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const
860   {
861     TRACE_SANITIZE (this);
862     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
863     for (unsigned int i = 0; i < count; i++)
864       if (unlikely (!arrayZ[i].sanitize (c, base)))
865         return_trace (false);
866     return_trace (true);
867   }
868   template <typename T>
869   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const
870   {
871     TRACE_SANITIZE (this);
872     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
873     for (unsigned int i = 0; i < count; i++)
874       if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
875         return_trace (false);
876     return_trace (true);
877   }
878
879   inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
880   {
881     TRACE_SANITIZE (this);
882     return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count));
883   }
884
885   public:
886   Type  arrayZ[VAR];
887   public:
888   DEFINE_SIZE_ARRAY (0, arrayZ);
889 };
890
891 /* Unsized array of offset's */
892 template <typename Type, typename OffsetType>
893 struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {};
894
895 /* Unsized array of offsets relative to the beginning of the array itself. */
896 template <typename Type, typename OffsetType>
897 struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType>
898 {
899   inline const Type& operator [] (unsigned int i) const
900   {
901     return this+this->arrayZ[i];
902   }
903
904   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
905   {
906     TRACE_SANITIZE (this);
907     return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this)));
908   }
909   template <typename T>
910   inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const
911   {
912     TRACE_SANITIZE (this);
913     return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data)));
914   }
915 };
916
917
918 /* An array with a number of elements. */
919 template <typename Type, typename LenType=HBUINT16>
920 struct ArrayOf
921 {
922   const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
923   {
924     unsigned int count = len;
925     if (unlikely (start_offset > count))
926       count = 0;
927     else
928       count -= start_offset;
929     count = MIN (count, *pcount);
930     *pcount = count;
931     return arrayZ + start_offset;
932   }
933
934   inline const Type& operator [] (unsigned int i) const
935   {
936     if (unlikely (i >= len)) return Null(Type);
937     return arrayZ[i];
938   }
939   inline Type& operator [] (unsigned int i)
940   {
941     if (unlikely (i >= len)) return Crap(Type);
942     return arrayZ[i];
943   }
944   inline unsigned int get_size (void) const
945   { return len.static_size + len * Type::static_size; }
946
947   inline bool serialize (hb_serialize_context_t *c,
948                          unsigned int items_len)
949   {
950     TRACE_SERIALIZE (this);
951     if (unlikely (!c->extend_min (*this))) return_trace (false);
952     len.set (items_len); /* TODO(serialize) Overflow? */
953     if (unlikely (!c->extend (*this))) return_trace (false);
954     return_trace (true);
955   }
956
957   inline bool serialize (hb_serialize_context_t *c,
958                          Supplier<Type> &items,
959                          unsigned int items_len)
960   {
961     TRACE_SERIALIZE (this);
962     if (unlikely (!serialize (c, items_len))) return_trace (false);
963     for (unsigned int i = 0; i < items_len; i++)
964       arrayZ[i] = items[i];
965     items += items_len;
966     return_trace (true);
967   }
968
969   inline bool sanitize (hb_sanitize_context_t *c) const
970   {
971     TRACE_SANITIZE (this);
972     if (unlikely (!sanitize_shallow (c))) return_trace (false);
973
974     /* Note: for structs that do not reference other structs,
975      * we do not need to call their sanitize() as we already did
976      * a bound check on the aggregate array size.  We just include
977      * a small unreachable expression to make sure the structs
978      * pointed to do have a simple sanitize(), ie. they do not
979      * reference other structs via offsets.
980      */
981     (void) (false && arrayZ[0].sanitize (c));
982
983     return_trace (true);
984   }
985   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
986   {
987     TRACE_SANITIZE (this);
988     if (unlikely (!sanitize_shallow (c))) return_trace (false);
989     unsigned int count = len;
990     for (unsigned int i = 0; i < count; i++)
991       if (unlikely (!arrayZ[i].sanitize (c, base)))
992         return_trace (false);
993     return_trace (true);
994   }
995   template <typename T>
996   inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
997   {
998     TRACE_SANITIZE (this);
999     if (unlikely (!sanitize_shallow (c))) return_trace (false);
1000     unsigned int count = len;
1001     for (unsigned int i = 0; i < count; i++)
1002       if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
1003         return_trace (false);
1004     return_trace (true);
1005   }
1006
1007   template <typename SearchType>
1008   inline int lsearch (const SearchType &x) const
1009   {
1010     unsigned int count = len;
1011     for (unsigned int i = 0; i < count; i++)
1012       if (!this->arrayZ[i].cmp (x))
1013         return i;
1014     return -1;
1015   }
1016
1017   inline void qsort (void)
1018   {
1019     ::qsort (arrayZ, len, sizeof (Type), Type::cmp);
1020   }
1021
1022   private:
1023   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
1024   {
1025     TRACE_SANITIZE (this);
1026     return_trace (len.sanitize (c) && c->check_array (arrayZ, Type::static_size, len));
1027   }
1028
1029   public:
1030   LenType len;
1031   Type arrayZ[VAR];
1032   public:
1033   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
1034 };
1035 template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
1036
1037 /* Array of Offset's */
1038 template <typename Type, typename OffsetType=HBUINT16>
1039 struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {};
1040
1041 /* Array of offsets relative to the beginning of the array itself. */
1042 template <typename Type>
1043 struct OffsetListOf : OffsetArrayOf<Type>
1044 {
1045   inline const Type& operator [] (unsigned int i) const
1046   {
1047     if (unlikely (i >= this->len)) return Null(Type);
1048     return this+this->arrayZ[i];
1049   }
1050   inline const Type& operator [] (unsigned int i)
1051   {
1052     if (unlikely (i >= this->len)) return Crap(Type);
1053     return this+this->arrayZ[i];
1054   }
1055
1056   inline bool sanitize (hb_sanitize_context_t *c) const
1057   {
1058     TRACE_SANITIZE (this);
1059     return_trace (OffsetArrayOf<Type>::sanitize (c, this));
1060   }
1061   template <typename T>
1062   inline bool sanitize (hb_sanitize_context_t *c, T user_data) const
1063   {
1064     TRACE_SANITIZE (this);
1065     return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data));
1066   }
1067 };
1068
1069
1070 /* An array starting at second element. */
1071 template <typename Type, typename LenType=HBUINT16>
1072 struct HeadlessArrayOf
1073 {
1074   inline const Type& operator [] (unsigned int i) const
1075   {
1076     if (unlikely (i >= len || !i)) return Null(Type);
1077     return arrayZ[i-1];
1078   }
1079   inline Type& operator [] (unsigned int i)
1080   {
1081     if (unlikely (i >= len || !i)) return Crap(Type);
1082     return arrayZ[i-1];
1083   }
1084   inline unsigned int get_size (void) const
1085   { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
1086
1087   inline bool serialize (hb_serialize_context_t *c,
1088                          Supplier<Type> &items,
1089                          unsigned int items_len)
1090   {
1091     TRACE_SERIALIZE (this);
1092     if (unlikely (!c->extend_min (*this))) return_trace (false);
1093     len.set (items_len); /* TODO(serialize) Overflow? */
1094     if (unlikely (!items_len)) return_trace (true);
1095     if (unlikely (!c->extend (*this))) return_trace (false);
1096     for (unsigned int i = 0; i < items_len - 1; i++)
1097       arrayZ[i] = items[i];
1098     items += items_len - 1;
1099     return_trace (true);
1100   }
1101
1102   inline bool sanitize (hb_sanitize_context_t *c) const
1103   {
1104     TRACE_SANITIZE (this);
1105     if (unlikely (!sanitize_shallow (c))) return_trace (false);
1106
1107     /* Note: for structs that do not reference other structs,
1108      * we do not need to call their sanitize() as we already did
1109      * a bound check on the aggregate array size.  We just include
1110      * a small unreachable expression to make sure the structs
1111      * pointed to do have a simple sanitize(), ie. they do not
1112      * reference other structs via offsets.
1113      */
1114     (void) (false && arrayZ[0].sanitize (c));
1115
1116     return_trace (true);
1117   }
1118
1119   private:
1120   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
1121   {
1122     TRACE_SANITIZE (this);
1123     return_trace (len.sanitize (c) &&
1124                   (!len || c->check_array (arrayZ, Type::static_size, len - 1)));
1125   }
1126
1127   public:
1128   LenType len;
1129   Type arrayZ[VAR];
1130   public:
1131   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
1132 };
1133
1134
1135 /*
1136  * An array with sorted elements.  Supports binary searching.
1137  */
1138 template <typename Type, typename LenType=HBUINT16>
1139 struct SortedArrayOf : ArrayOf<Type, LenType>
1140 {
1141   template <typename SearchType>
1142   inline int bsearch (const SearchType &x) const
1143   {
1144     /* Hand-coded bsearch here since this is in the hot inner loop. */
1145     const Type *arr = this->arrayZ;
1146     int min = 0, max = (int) this->len - 1;
1147     while (min <= max)
1148     {
1149       int mid = (min + max) / 2;
1150       int c = arr[mid].cmp (x);
1151       if (c < 0)
1152         max = mid - 1;
1153       else if (c > 0)
1154         min = mid + 1;
1155       else
1156         return mid;
1157     }
1158     return -1;
1159   }
1160 };
1161
1162 /*
1163  * Binary-search arrays
1164  */
1165
1166 struct BinSearchHeader
1167 {
1168   inline operator uint32_t (void) const { return len; }
1169
1170   inline bool sanitize (hb_sanitize_context_t *c) const
1171   {
1172     TRACE_SANITIZE (this);
1173     return_trace (c->check_struct (this));
1174   }
1175
1176   inline void set (unsigned int v)
1177   {
1178     len.set (v);
1179     assert (len == v);
1180     entrySelector.set (MAX (1u, _hb_bit_storage (v)) - 1);
1181     searchRange.set (16 * (1u << entrySelector));
1182     rangeShift.set (v * 16 > searchRange
1183                     ? 16 * v - searchRange
1184                     : 0);
1185   }
1186
1187   protected:
1188   HBUINT16      len;
1189   HBUINT16      searchRange;
1190   HBUINT16      entrySelector;
1191   HBUINT16      rangeShift;
1192
1193   public:
1194   DEFINE_SIZE_STATIC (8);
1195 };
1196
1197 template <typename Type>
1198 struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
1199
1200
1201 /* Lazy struct and blob loaders. */
1202
1203 /* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
1204 template <typename T>
1205 struct hb_lazy_loader_t
1206 {
1207   inline void init (hb_face_t *face_)
1208   {
1209     face = face_;
1210     instance = nullptr;
1211   }
1212
1213   inline void fini (void)
1214   {
1215     if (instance && instance != &Null(T))
1216     {
1217       instance->fini();
1218       free (instance);
1219     }
1220   }
1221
1222   inline const T* get (void) const
1223   {
1224   retry:
1225     T *p = (T *) hb_atomic_ptr_get (&instance);
1226     if (unlikely (!p))
1227     {
1228       p = (T *) calloc (1, sizeof (T));
1229       if (unlikely (!p))
1230         p = const_cast<T *> (&Null(T));
1231       else
1232         p->init (face);
1233       if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
1234       {
1235         if (p != &Null(T))
1236           p->fini ();
1237         goto retry;
1238       }
1239     }
1240     return p;
1241   }
1242
1243   inline const T* operator-> (void) const
1244   {
1245     return get ();
1246   }
1247
1248   private:
1249   hb_face_t *face;
1250   T *instance;
1251 };
1252
1253 /* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
1254 template <typename T>
1255 struct hb_table_lazy_loader_t
1256 {
1257   inline void init (hb_face_t *face_)
1258   {
1259     face = face_;
1260     blob = nullptr;
1261   }
1262
1263   inline void fini (void)
1264   {
1265     hb_blob_destroy (blob);
1266   }
1267
1268   inline const T* get (void) const
1269   {
1270   retry:
1271     hb_blob_t *blob_ = (hb_blob_t *) hb_atomic_ptr_get (&blob);
1272     if (unlikely (!blob_))
1273     {
1274       blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
1275       if (!hb_atomic_ptr_cmpexch (&blob, nullptr, blob_))
1276       {
1277         hb_blob_destroy (blob_);
1278         goto retry;
1279       }
1280       blob = blob_;
1281     }
1282     return blob_->as<T> ();
1283   }
1284
1285   inline const T* operator-> (void) const
1286   {
1287     return get();
1288   }
1289
1290   private:
1291   hb_face_t *face;
1292   mutable hb_blob_t *blob;
1293 };
1294
1295
1296 } /* namespace OT */
1297
1298
1299 #endif /* HB_OPEN_TYPE_PRIVATE_HH */