src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh
changeset 50826 f5b95be8b6e2
parent 50352 25db2c8f3cf8
child 51000 7c8841474f57
equal deleted inserted replaced
50825:aa0a35b071fb 50826:f5b95be8b6e2
    29 #ifndef HB_OPEN_TYPE_PRIVATE_HH
    29 #ifndef HB_OPEN_TYPE_PRIVATE_HH
    30 #define HB_OPEN_TYPE_PRIVATE_HH
    30 #define HB_OPEN_TYPE_PRIVATE_HH
    31 
    31 
    32 #include "hb-private.hh"
    32 #include "hb-private.hh"
    33 #include "hb-debug.hh"
    33 #include "hb-debug.hh"
       
    34 #include "hb-blob-private.hh"
    34 #include "hb-face-private.hh"
    35 #include "hb-face-private.hh"
    35 
    36 
    36 
    37 
    37 namespace OT {
    38 namespace OT {
    38 
    39 
   122 #define DEFINE_SIZE_ARRAY2(size, array1, array2) \
   123 #define DEFINE_SIZE_ARRAY2(size, array1, array2) \
   123   DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
   124   DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
   124   DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
   125   DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
   125   static const unsigned int min_size = (size)
   126   static const unsigned int min_size = (size)
   126 
   127 
   127 
       
   128 
       
   129 /*
       
   130  * Null objects
       
   131  */
       
   132 
       
   133 /* Global nul-content Null pool.  Enlarge as necessary. */
       
   134 
       
   135 #define HB_NULL_POOL_SIZE 264
       
   136 static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
       
   137 
       
   138 #ifdef HB_NO_VISIBILITY
       
   139 static
       
   140 #else
       
   141 extern HB_INTERNAL
       
   142 #endif
       
   143 const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)]
       
   144 #ifdef HB_NO_VISIBILITY
       
   145 = {}
       
   146 #endif
       
   147 ;
       
   148 
       
   149 /* Generic nul-content Null objects. */
       
   150 template <typename Type>
       
   151 static inline const Type& Null (void) {
       
   152   static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
       
   153   return *CastP<Type> (_hb_NullPool);
       
   154 }
       
   155 
       
   156 /* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
       
   157 #define DEFINE_NULL_DATA(Type, data) \
       
   158 static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
       
   159 template <> \
       
   160 /*static*/ inline const Type& Null<Type> (void) { \
       
   161   return *CastP<Type> (_Null##Type); \
       
   162 } /* The following line really exists such that we end in a place needing semicolon */ \
       
   163 static_assert (Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small.  Enlarge.")
       
   164 
       
   165 /* Accessor macro. */
       
   166 #define Null(Type) Null<Type>()
       
   167 
   128 
   168 
   129 
   169 /*
   130 /*
   170  * Dispatch
   131  * Dispatch
   171  */
   132  */
   223   }
   184   }
   224 
   185 
   225   inline void start_processing (void)
   186   inline void start_processing (void)
   226   {
   187   {
   227     this->start = hb_blob_get_data (this->blob, nullptr);
   188     this->start = hb_blob_get_data (this->blob, nullptr);
   228     this->end = this->start + hb_blob_get_length (this->blob);
   189     this->end = this->start + this->blob->length;
   229     assert (this->start <= this->end); /* Must not overflow. */
   190     assert (this->start <= this->end); /* Must not overflow. */
   230     this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
   191     this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
   231                          (unsigned) HB_SANITIZE_MAX_OPS_MIN);
   192                          (unsigned) HB_SANITIZE_MAX_OPS_MIN);
   232     this->edit_count = 0;
   193     this->edit_count = 0;
   233     this->debug_depth = 0;
   194     this->debug_depth = 0;
   286   inline bool check_struct (const Type *obj) const
   247   inline bool check_struct (const Type *obj) const
   287   {
   248   {
   288     return likely (this->check_range (obj, obj->min_size));
   249     return likely (this->check_range (obj, obj->min_size));
   289   }
   250   }
   290 
   251 
   291   inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED)
   252   inline bool may_edit (const void *base, unsigned int len)
   292   {
   253   {
   293     if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
   254     if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
   294       return false;
   255       return false;
   295 
   256 
   296     const char *p = (const char *) base;
   257     const char *p = (const char *) base;
   366       }
   327       }
   367     } else {
   328     } else {
   368       unsigned int edit_count = c->edit_count;
   329       unsigned int edit_count = c->edit_count;
   369       if (edit_count && !c->writable) {
   330       if (edit_count && !c->writable) {
   370         c->start = hb_blob_get_data_writable (blob, nullptr);
   331         c->start = hb_blob_get_data_writable (blob, nullptr);
   371         c->end = c->start + hb_blob_get_length (blob);
   332         c->end = c->start + blob->length;
   372 
   333 
   373         if (c->start) {
   334         if (c->start) {
   374           c->writable = true;
   335           c->writable = true;
   375           /* ok, we made it writable by relocating.  try again */
   336           /* ok, we made it writable by relocating.  try again */
   376           DEBUG_MSG_FUNC (SANITIZE, c->start, "retry");
   337           DEBUG_MSG_FUNC (SANITIZE, c->start, "retry");
   381 
   342 
   382     c->end_processing ();
   343     c->end_processing ();
   383 
   344 
   384     DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED");
   345     DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED");
   385     if (sane)
   346     if (sane)
       
   347     {
       
   348       blob->lock ();
   386       return blob;
   349       return blob;
   387     else {
   350     }
       
   351     else
       
   352     {
   388       hb_blob_destroy (blob);
   353       hb_blob_destroy (blob);
   389       return hb_blob_get_empty ();
   354       return hb_blob_get_empty ();
   390     }
   355     }
   391   }
       
   392 
       
   393   static const Type* lock_instance (hb_blob_t *blob) {
       
   394     hb_blob_make_immutable (blob);
       
   395     const char *base = hb_blob_get_data (blob, nullptr);
       
   396     return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
       
   397   }
   356   }
   398 
   357 
   399   inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; }
   358   inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; }
   400 
   359 
   401   private:
   360   private:
   670 typedef IntType<int8_t,   1> HBINT8;    /* 8-bit signed integer. */
   629 typedef IntType<int8_t,   1> HBINT8;    /* 8-bit signed integer. */
   671 typedef IntType<uint16_t, 2> HBUINT16;  /* 16-bit unsigned integer. */
   630 typedef IntType<uint16_t, 2> HBUINT16;  /* 16-bit unsigned integer. */
   672 typedef IntType<int16_t,  2> HBINT16;   /* 16-bit signed integer. */
   631 typedef IntType<int16_t,  2> HBINT16;   /* 16-bit signed integer. */
   673 typedef IntType<uint32_t, 4> HBUINT32;  /* 32-bit unsigned integer. */
   632 typedef IntType<uint32_t, 4> HBUINT32;  /* 32-bit unsigned integer. */
   674 typedef IntType<int32_t,  4> HBINT32;   /* 32-bit signed integer. */
   633 typedef IntType<int32_t,  4> HBINT32;   /* 32-bit signed integer. */
   675 typedef IntType<uint32_t, 3> UINT24;    /* 24-bit unsigned integer. */
   634 typedef IntType<uint32_t, 3> HBUINT24;  /* 24-bit unsigned integer. */
   676 
   635 
   677 /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
   636 /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
   678 typedef HBINT16 FWORD;
   637 typedef HBINT16 FWORD;
   679 
   638 
   680 /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
   639 /* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
   681 typedef HBUINT16 UFWORD;
   640 typedef HBUINT16 UFWORD;
   682 
   641 
   683 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
   642 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
   684 struct F2DOT14 : HBINT16
   643 struct F2DOT14 : HBINT16
   685 {
   644 {
   686   //inline float to_float (void) const { return ???; }
   645   // 16384 means 1<<14
   687   //inline void set_float (float f) { v.set (f * ???); }
   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)); }
   688   public:
   648   public:
   689   DEFINE_SIZE_STATIC (2);
   649   DEFINE_SIZE_STATIC (2);
   690 };
   650 };
   691 
   651 
   692 /* 32-bit signed fixed-point number (16.16). */
   652 /* 32-bit signed fixed-point number (16.16). */
   693 struct Fixed: HBINT32
   653 struct Fixed : HBINT32
   694 {
   654 {
   695   inline float to_float (void) const { return ((int32_t) v) / 65536.0; }
   655   // 65536 means 1<<16
   696   inline void set_float (float f) { v.set (round (f * 65536.0)); }
   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)); }
   697   public:
   658   public:
   698   DEFINE_SIZE_STATIC (4);
   659   DEFINE_SIZE_STATIC (4);
   699 };
   660 };
   700 
   661 
   701 /* Date represented in number of seconds since 12:00 midnight, January 1,
   662 /* Date represented in number of seconds since 12:00 midnight, January 1,
   722   inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
   683   inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
   723   inline operator char* (void) { return reinterpret_cast<char *> (&this->v); }
   684   inline operator char* (void) { return reinterpret_cast<char *> (&this->v); }
   724   public:
   685   public:
   725   DEFINE_SIZE_STATIC (4);
   686   DEFINE_SIZE_STATIC (4);
   726 };
   687 };
   727 DEFINE_NULL_DATA (Tag, "    ");
   688 DEFINE_NULL_DATA (OT, Tag, "    ");
   728 
   689 
   729 /* Glyph index number, same as uint16 (length = 16 bits) */
   690 /* Glyph index number, same as uint16 (length = 16 bits) */
   730 typedef HBUINT16 GlyphID;
   691 typedef HBUINT16 GlyphID;
       
   692 
       
   693 /* Name-table index, same as uint16 (length = 16 bits) */
       
   694 typedef HBUINT16 NameID;
   731 
   695 
   732 /* Script/language-system/feature index */
   696 /* Script/language-system/feature index */
   733 struct Index : HBUINT16 {
   697 struct Index : HBUINT16 {
   734   static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
   698   static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
   735 };
   699 };
   736 DEFINE_NULL_DATA (Index, "\xff\xff");
   700 DEFINE_NULL_DATA (OT, Index, "\xff\xff");
   737 
   701 
   738 /* Offset, Null offset = 0 */
   702 /* Offset, Null offset = 0 */
   739 template <typename Type>
   703 template <typename Type>
   740 struct Offset : Type
   704 struct Offset : Type
   741 {
   705 {
   813 {
   777 {
   814   inline const Type& operator () (const void *base) const
   778   inline const Type& operator () (const void *base) const
   815   {
   779   {
   816     unsigned int offset = *this;
   780     unsigned int offset = *this;
   817     if (unlikely (!offset)) return Null(Type);
   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);
   818     return StructAtOffset<Type> (base, offset);
   788     return StructAtOffset<Type> (base, offset);
   819   }
   789   }
   820 
   790 
   821   inline Type& serialize (hb_serialize_context_t *c, const void *base)
   791   inline Type& serialize (hb_serialize_context_t *c, const void *base)
   822   {
   792   {
   859 
   829 
   860 
   830 
   861 /*
   831 /*
   862  * Array Types
   832  * Array Types
   863  */
   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 
   864 
   917 
   865 /* An array with a number of elements. */
   918 /* An array with a number of elements. */
   866 template <typename Type, typename LenType=HBUINT16>
   919 template <typename Type, typename LenType=HBUINT16>
   867 struct ArrayOf
   920 struct ArrayOf
   868 {
   921 {
   873       count = 0;
   926       count = 0;
   874     else
   927     else
   875       count -= start_offset;
   928       count -= start_offset;
   876     count = MIN (count, *pcount);
   929     count = MIN (count, *pcount);
   877     *pcount = count;
   930     *pcount = count;
   878     return array + start_offset;
   931     return arrayZ + start_offset;
   879   }
   932   }
   880 
   933 
   881   inline const Type& operator [] (unsigned int i) const
   934   inline const Type& operator [] (unsigned int i) const
   882   {
   935   {
   883     if (unlikely (i >= len)) return Null(Type);
   936     if (unlikely (i >= len)) return Null(Type);
   884     return array[i];
   937     return arrayZ[i];
   885   }
   938   }
   886   inline Type& operator [] (unsigned int i)
   939   inline Type& operator [] (unsigned int i)
   887   {
   940   {
   888     return array[i];
   941     if (unlikely (i >= len)) return Crap(Type);
       
   942     return arrayZ[i];
   889   }
   943   }
   890   inline unsigned int get_size (void) const
   944   inline unsigned int get_size (void) const
   891   { return len.static_size + len * Type::static_size; }
   945   { return len.static_size + len * Type::static_size; }
   892 
   946 
   893   inline bool serialize (hb_serialize_context_t *c,
   947   inline bool serialize (hb_serialize_context_t *c,
   905                          unsigned int items_len)
   959                          unsigned int items_len)
   906   {
   960   {
   907     TRACE_SERIALIZE (this);
   961     TRACE_SERIALIZE (this);
   908     if (unlikely (!serialize (c, items_len))) return_trace (false);
   962     if (unlikely (!serialize (c, items_len))) return_trace (false);
   909     for (unsigned int i = 0; i < items_len; i++)
   963     for (unsigned int i = 0; i < items_len; i++)
   910       array[i] = items[i];
   964       arrayZ[i] = items[i];
   911     items += items_len;
   965     items += items_len;
   912     return_trace (true);
   966     return_trace (true);
   913   }
   967   }
   914 
   968 
   915   inline bool sanitize (hb_sanitize_context_t *c) const
   969   inline bool sanitize (hb_sanitize_context_t *c) const
   922      * a bound check on the aggregate array size.  We just include
   976      * a bound check on the aggregate array size.  We just include
   923      * a small unreachable expression to make sure the structs
   977      * a small unreachable expression to make sure the structs
   924      * pointed to do have a simple sanitize(), ie. they do not
   978      * pointed to do have a simple sanitize(), ie. they do not
   925      * reference other structs via offsets.
   979      * reference other structs via offsets.
   926      */
   980      */
   927     (void) (false && array[0].sanitize (c));
   981     (void) (false && arrayZ[0].sanitize (c));
   928 
   982 
   929     return_trace (true);
   983     return_trace (true);
   930   }
   984   }
   931   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
   985   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
   932   {
   986   {
   933     TRACE_SANITIZE (this);
   987     TRACE_SANITIZE (this);
   934     if (unlikely (!sanitize_shallow (c))) return_trace (false);
   988     if (unlikely (!sanitize_shallow (c))) return_trace (false);
   935     unsigned int count = len;
   989     unsigned int count = len;
   936     for (unsigned int i = 0; i < count; i++)
   990     for (unsigned int i = 0; i < count; i++)
   937       if (unlikely (!array[i].sanitize (c, base)))
   991       if (unlikely (!arrayZ[i].sanitize (c, base)))
   938         return_trace (false);
   992         return_trace (false);
   939     return_trace (true);
   993     return_trace (true);
   940   }
   994   }
   941   template <typename T>
   995   template <typename T>
   942   inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
   996   inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
   943   {
   997   {
   944     TRACE_SANITIZE (this);
   998     TRACE_SANITIZE (this);
   945     if (unlikely (!sanitize_shallow (c))) return_trace (false);
   999     if (unlikely (!sanitize_shallow (c))) return_trace (false);
   946     unsigned int count = len;
  1000     unsigned int count = len;
   947     for (unsigned int i = 0; i < count; i++)
  1001     for (unsigned int i = 0; i < count; i++)
   948       if (unlikely (!array[i].sanitize (c, base, user_data)))
  1002       if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
   949         return_trace (false);
  1003         return_trace (false);
   950     return_trace (true);
  1004     return_trace (true);
   951   }
  1005   }
   952 
  1006 
   953   template <typename SearchType>
  1007   template <typename SearchType>
   954   inline int lsearch (const SearchType &x) const
  1008   inline int lsearch (const SearchType &x) const
   955   {
  1009   {
   956     unsigned int count = len;
  1010     unsigned int count = len;
   957     for (unsigned int i = 0; i < count; i++)
  1011     for (unsigned int i = 0; i < count; i++)
   958       if (!this->array[i].cmp (x))
  1012       if (!this->arrayZ[i].cmp (x))
   959         return i;
  1013         return i;
   960     return -1;
  1014     return -1;
   961   }
  1015   }
   962 
  1016 
   963   inline void qsort (void)
  1017   inline void qsort (void)
   964   {
  1018   {
   965     ::qsort (array, len, sizeof (Type), Type::cmp);
  1019     ::qsort (arrayZ, len, sizeof (Type), Type::cmp);
   966   }
  1020   }
   967 
  1021 
   968   private:
  1022   private:
   969   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
  1023   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
   970   {
  1024   {
   971     TRACE_SANITIZE (this);
  1025     TRACE_SANITIZE (this);
   972     return_trace (len.sanitize (c) && c->check_array (array, Type::static_size, len));
  1026     return_trace (len.sanitize (c) && c->check_array (arrayZ, Type::static_size, len));
   973   }
  1027   }
   974 
  1028 
   975   public:
  1029   public:
   976   LenType len;
  1030   LenType len;
   977   Type array[VAR];
  1031   Type arrayZ[VAR];
   978   public:
  1032   public:
   979   DEFINE_SIZE_ARRAY (sizeof (LenType), array);
  1033   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
   980 };
  1034 };
   981 template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
  1035 template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
   982 
  1036 
   983 /* Array of Offset's */
  1037 /* Array of Offset's */
   984 template <typename Type, typename OffsetType=HBUINT16>
  1038 template <typename Type, typename OffsetType=HBUINT16>
   989 struct OffsetListOf : OffsetArrayOf<Type>
  1043 struct OffsetListOf : OffsetArrayOf<Type>
   990 {
  1044 {
   991   inline const Type& operator [] (unsigned int i) const
  1045   inline const Type& operator [] (unsigned int i) const
   992   {
  1046   {
   993     if (unlikely (i >= this->len)) return Null(Type);
  1047     if (unlikely (i >= this->len)) return Null(Type);
   994     return this+this->array[i];
  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];
   995   }
  1054   }
   996 
  1055 
   997   inline bool sanitize (hb_sanitize_context_t *c) const
  1056   inline bool sanitize (hb_sanitize_context_t *c) const
   998   {
  1057   {
   999     TRACE_SANITIZE (this);
  1058     TRACE_SANITIZE (this);
  1013 struct HeadlessArrayOf
  1072 struct HeadlessArrayOf
  1014 {
  1073 {
  1015   inline const Type& operator [] (unsigned int i) const
  1074   inline const Type& operator [] (unsigned int i) const
  1016   {
  1075   {
  1017     if (unlikely (i >= len || !i)) return Null(Type);
  1076     if (unlikely (i >= len || !i)) return Null(Type);
  1018     return array[i-1];
  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];
  1019   }
  1083   }
  1020   inline unsigned int get_size (void) const
  1084   inline unsigned int get_size (void) const
  1021   { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
  1085   { return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
  1022 
  1086 
  1023   inline bool serialize (hb_serialize_context_t *c,
  1087   inline bool serialize (hb_serialize_context_t *c,
  1028     if (unlikely (!c->extend_min (*this))) return_trace (false);
  1092     if (unlikely (!c->extend_min (*this))) return_trace (false);
  1029     len.set (items_len); /* TODO(serialize) Overflow? */
  1093     len.set (items_len); /* TODO(serialize) Overflow? */
  1030     if (unlikely (!items_len)) return_trace (true);
  1094     if (unlikely (!items_len)) return_trace (true);
  1031     if (unlikely (!c->extend (*this))) return_trace (false);
  1095     if (unlikely (!c->extend (*this))) return_trace (false);
  1032     for (unsigned int i = 0; i < items_len - 1; i++)
  1096     for (unsigned int i = 0; i < items_len - 1; i++)
  1033       array[i] = items[i];
  1097       arrayZ[i] = items[i];
  1034     items += items_len - 1;
  1098     items += items_len - 1;
  1035     return_trace (true);
  1099     return_trace (true);
  1036   }
  1100   }
  1037 
  1101 
  1038   inline bool sanitize (hb_sanitize_context_t *c) const
  1102   inline bool sanitize (hb_sanitize_context_t *c) const
  1045      * a bound check on the aggregate array size.  We just include
  1109      * a bound check on the aggregate array size.  We just include
  1046      * a small unreachable expression to make sure the structs
  1110      * a small unreachable expression to make sure the structs
  1047      * pointed to do have a simple sanitize(), ie. they do not
  1111      * pointed to do have a simple sanitize(), ie. they do not
  1048      * reference other structs via offsets.
  1112      * reference other structs via offsets.
  1049      */
  1113      */
  1050     (void) (false && array[0].sanitize (c));
  1114     (void) (false && arrayZ[0].sanitize (c));
  1051 
  1115 
  1052     return_trace (true);
  1116     return_trace (true);
  1053   }
  1117   }
  1054 
  1118 
  1055   private:
  1119   private:
  1056   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
  1120   inline bool sanitize_shallow (hb_sanitize_context_t *c) const
  1057   {
  1121   {
  1058     TRACE_SANITIZE (this);
  1122     TRACE_SANITIZE (this);
  1059     return_trace (len.sanitize (c) &&
  1123     return_trace (len.sanitize (c) &&
  1060                   (!len || c->check_array (array, Type::static_size, len - 1)));
  1124                   (!len || c->check_array (arrayZ, Type::static_size, len - 1)));
  1061   }
  1125   }
  1062 
  1126 
  1063   public:
  1127   public:
  1064   LenType len;
  1128   LenType len;
  1065   Type array[VAR];
  1129   Type arrayZ[VAR];
  1066   public:
  1130   public:
  1067   DEFINE_SIZE_ARRAY (sizeof (LenType), array);
  1131   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
  1068 };
  1132 };
  1069 
  1133 
  1070 
  1134 
  1071 /*
  1135 /*
  1072  * An array with sorted elements.  Supports binary searching.
  1136  * An array with sorted elements.  Supports binary searching.
  1076 {
  1140 {
  1077   template <typename SearchType>
  1141   template <typename SearchType>
  1078   inline int bsearch (const SearchType &x) const
  1142   inline int bsearch (const SearchType &x) const
  1079   {
  1143   {
  1080     /* Hand-coded bsearch here since this is in the hot inner loop. */
  1144     /* Hand-coded bsearch here since this is in the hot inner loop. */
  1081     const Type *arr = this->array;
  1145     const Type *arr = this->arrayZ;
  1082     int min = 0, max = (int) this->len - 1;
  1146     int min = 0, max = (int) this->len - 1;
  1083     while (min <= max)
  1147     while (min <= max)
  1084     {
  1148     {
  1085       int mid = (min + max) / 2;
  1149       int mid = (min + max) / 2;
  1086       int c = arr[mid].cmp (x);
  1150       int c = arr[mid].cmp (x);
  1111 
  1175 
  1112   inline void set (unsigned int v)
  1176   inline void set (unsigned int v)
  1113   {
  1177   {
  1114     len.set (v);
  1178     len.set (v);
  1115     assert (len == v);
  1179     assert (len == v);
  1116     entrySelectorZ.set (MAX (1u, _hb_bit_storage (v)) - 1);
  1180     entrySelector.set (MAX (1u, _hb_bit_storage (v)) - 1);
  1117     searchRangeZ.set (16 * (1u << entrySelectorZ));
  1181     searchRange.set (16 * (1u << entrySelector));
  1118     rangeShiftZ.set (v * 16 > searchRangeZ
  1182     rangeShift.set (v * 16 > searchRange
  1119                      ? 16 * v - searchRangeZ
  1183                     ? 16 * v - searchRange
  1120                      : 0);
  1184                     : 0);
  1121   }
  1185   }
  1122 
  1186 
  1123   protected:
  1187   protected:
  1124   HBUINT16      len;
  1188   HBUINT16      len;
  1125   HBUINT16      searchRangeZ;
  1189   HBUINT16      searchRange;
  1126   HBUINT16      entrySelectorZ;
  1190   HBUINT16      entrySelector;
  1127   HBUINT16      rangeShiftZ;
  1191   HBUINT16      rangeShift;
  1128 
  1192 
  1129   public:
  1193   public:
  1130   DEFINE_SIZE_STATIC (8);
  1194   DEFINE_SIZE_STATIC (8);
  1131 };
  1195 };
  1132 
  1196 
  1134 struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
  1198 struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
  1135 
  1199 
  1136 
  1200 
  1137 /* Lazy struct and blob loaders. */
  1201 /* Lazy struct and blob loaders. */
  1138 
  1202 
  1139 /* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
  1203 /* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
  1140 template <typename T>
  1204 template <typename T>
  1141 struct hb_lazy_loader_t
  1205 struct hb_lazy_loader_t
  1142 {
  1206 {
  1143   inline void init (hb_face_t *face_)
  1207   inline void init (hb_face_t *face_)
  1144   {
  1208   {
  1146     instance = nullptr;
  1210     instance = nullptr;
  1147   }
  1211   }
  1148 
  1212 
  1149   inline void fini (void)
  1213   inline void fini (void)
  1150   {
  1214   {
  1151     if (instance && instance != &OT::Null(T))
  1215     if (instance && instance != &Null(T))
  1152     {
  1216     {
  1153       instance->fini();
  1217       instance->fini();
  1154       free (instance);
  1218       free (instance);
  1155     }
  1219     }
  1156   }
  1220   }
  1161     T *p = (T *) hb_atomic_ptr_get (&instance);
  1225     T *p = (T *) hb_atomic_ptr_get (&instance);
  1162     if (unlikely (!p))
  1226     if (unlikely (!p))
  1163     {
  1227     {
  1164       p = (T *) calloc (1, sizeof (T));
  1228       p = (T *) calloc (1, sizeof (T));
  1165       if (unlikely (!p))
  1229       if (unlikely (!p))
  1166         p = const_cast<T *> (&OT::Null(T));
  1230         p = const_cast<T *> (&Null(T));
  1167       else
  1231       else
  1168         p->init (face);
  1232         p->init (face);
  1169       if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
  1233       if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
  1170       {
  1234       {
  1171         if (p != &OT::Null(T))
  1235         if (p != &Null(T))
  1172           p->fini ();
  1236           p->fini ();
  1173         goto retry;
  1237         goto retry;
  1174       }
  1238       }
  1175     }
  1239     }
  1176     return p;
  1240     return p;
  1184   private:
  1248   private:
  1185   hb_face_t *face;
  1249   hb_face_t *face;
  1186   T *instance;
  1250   T *instance;
  1187 };
  1251 };
  1188 
  1252 
  1189 /* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
  1253 /* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
  1190 template <typename T>
  1254 template <typename T>
  1191 struct hb_lazy_table_loader_t
  1255 struct hb_table_lazy_loader_t
  1192 {
  1256 {
  1193   inline void init (hb_face_t *face_)
  1257   inline void init (hb_face_t *face_)
  1194   {
  1258   {
  1195     face = face_;
  1259     face = face_;
  1196     blob = nullptr;
  1260     blob = nullptr;
  1197     instance = nullptr;
       
  1198   }
  1261   }
  1199 
  1262 
  1200   inline void fini (void)
  1263   inline void fini (void)
  1201   {
  1264   {
  1202     hb_blob_destroy (blob);
  1265     hb_blob_destroy (blob);
  1203   }
  1266   }
  1204 
  1267 
  1205   inline const T* get (void) const
  1268   inline const T* get (void) const
  1206   {
  1269   {
  1207   retry:
  1270   retry:
  1208     T *p = (T *) hb_atomic_ptr_get (&instance);
  1271     hb_blob_t *blob_ = (hb_blob_t *) hb_atomic_ptr_get (&blob);
  1209     if (unlikely (!p))
  1272     if (unlikely (!blob_))
  1210     {
  1273     {
  1211       hb_blob_t *blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
  1274       blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
  1212       p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_));
  1275       if (!hb_atomic_ptr_cmpexch (&blob, nullptr, blob_))
  1213       if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p))
       
  1214       {
  1276       {
  1215         hb_blob_destroy (blob_);
  1277         hb_blob_destroy (blob_);
  1216         goto retry;
  1278         goto retry;
  1217       }
  1279       }
  1218       blob = blob_;
  1280       blob = blob_;
  1219     }
  1281     }
  1220     return p;
  1282     return blob_->as<T> ();
  1221   }
  1283   }
  1222 
  1284 
  1223   inline const T* operator-> (void) const
  1285   inline const T* operator-> (void) const
  1224   {
  1286   {
  1225     return get();
  1287     return get();
  1226   }
  1288   }
  1227 
  1289 
       
  1290   private:
  1228   hb_face_t *face;
  1291   hb_face_t *face;
  1229   mutable hb_blob_t *blob;
  1292   mutable hb_blob_t *blob;
  1230   private:
       
  1231   mutable T *instance;
       
  1232 };
  1293 };
  1233 
  1294 
  1234 
  1295 
  1235 } /* namespace OT */
  1296 } /* namespace OT */
  1236 
  1297