src/java.desktop/share/native/libfontmanager/harfbuzz/hb-private.hh
changeset 48274 51772bf1fb0c
parent 47216 71c04702a3d5
child 50352 25db2c8f3cf8
equal deleted inserted replaced
48273:e2065f7505eb 48274:51772bf1fb0c
    42 
    42 
    43 #include <stdlib.h>
    43 #include <stdlib.h>
    44 #include <stddef.h>
    44 #include <stddef.h>
    45 #include <string.h>
    45 #include <string.h>
    46 #include <assert.h>
    46 #include <assert.h>
    47 
    47 #include <errno.h>
    48 /* We only use these two for debug output.  However, the debug code is
       
    49  * always seen by the compiler (and optimized out in non-debug builds.
       
    50  * If including these becomes a problem, we can start thinking about
       
    51  * someway around that. */
       
    52 #include <stdio.h>
    48 #include <stdio.h>
    53 #include <errno.h>
       
    54 #include <stdarg.h>
    49 #include <stdarg.h>
    55 
    50 
       
    51 
       
    52 #define HB_PASTE1(a,b) a##b
       
    53 #define HB_PASTE(a,b) HB_PASTE1(a,b)
    56 
    54 
    57 /* Compile-time custom allocator support. */
    55 /* Compile-time custom allocator support. */
    58 
    56 
    59 #if defined(hb_malloc_impl) \
    57 #if defined(hb_malloc_impl) \
    60  && defined(hb_calloc_impl) \
    58  && defined(hb_calloc_impl) \
    72 
    70 
    73 
    71 
    74 /* Compiler attributes */
    72 /* Compiler attributes */
    75 
    73 
    76 
    74 
    77 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
    75 #if __cplusplus < 201103L
    78 #define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
    76 
    79 #define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
    77 #ifndef nullptr
    80 #define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
    78 #define nullptr NULL
       
    79 #endif
       
    80 
       
    81 // Static assertions
       
    82 #ifndef static_assert
       
    83 #define static_assert(e, msg) \
       
    84         HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
       
    85 #endif // static_assert
       
    86 
       
    87 #endif // __cplusplus < 201103L
       
    88 
       
    89 #define _GNU_SOURCE 1
       
    90 
       
    91 #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
       
    92 #define likely(expr) (__builtin_expect (!!(expr), 1))
       
    93 #define unlikely(expr) (__builtin_expect (!!(expr), 0))
    81 #else
    94 #else
    82 #define likely(expr) (expr)
    95 #define likely(expr) (expr)
    83 #define unlikely(expr) (expr)
    96 #define unlikely(expr) (expr)
    84 #endif
    97 #endif
    85 
    98 
   166 #    define STRICT 1
   179 #    define STRICT 1
   167 #  endif
   180 #  endif
   168 
   181 
   169 #  if defined(_WIN32_WCE)
   182 #  if defined(_WIN32_WCE)
   170      /* Some things not defined on Windows CE. */
   183      /* Some things not defined on Windows CE. */
   171 #    define strdup _strdup
       
   172 #    define vsnprintf _vsnprintf
   184 #    define vsnprintf _vsnprintf
   173 #    define getenv(Name) NULL
   185 #    define getenv(Name) nullptr
   174 #    if _WIN32_WCE < 0x800
   186 #    if _WIN32_WCE < 0x800
   175 #      define setlocale(Category, Locale) "C"
   187 #      define setlocale(Category, Locale) "C"
   176 static int errno = 0; /* Use something better? */
   188 static int errno = 0; /* Use something better? */
   177 #    endif
   189 #    endif
   178 #  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
   190 #  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
   179 #    define getenv(Name) NULL
   191 #    define getenv(Name) nullptr
   180 #  endif
   192 #  endif
   181 #  if defined(_MSC_VER) && _MSC_VER < 1900
   193 #  if defined(_MSC_VER) && _MSC_VER < 1900
   182 #    define snprintf _snprintf
   194 #    define snprintf _snprintf
   183 #  elif defined(_MSC_VER) && _MSC_VER >= 1900
       
   184 #    /* Covers VC++ Error for strdup being a deprecated POSIX name and to instead use _strdup instead */
       
   185 #    define strdup _strdup
       
   186 #  endif
   195 #  endif
   187 #endif
   196 #endif
   188 
   197 
   189 #if HAVE_ATEXIT
   198 #if HAVE_ATEXIT
   190 /* atexit() is only safe to be called from shared libraries on certain
   199 /* atexit() is only safe to be called from shared libraries on certain
   212 #  endif
   221 #  endif
   213 #endif
   222 #endif
   214 
   223 
   215 /* Basics */
   224 /* Basics */
   216 
   225 
   217 
       
   218 #ifndef NULL
       
   219 # define NULL ((void *) 0)
       
   220 #endif
       
   221 
       
   222 #undef MIN
   226 #undef MIN
   223 template <typename Type>
   227 template <typename Type>
   224 static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
   228 static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
   225 
   229 
   226 #undef MAX
   230 #undef MAX
   238 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
   242 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
   239 
   243 
   240 #define HB_STMT_START do
   244 #define HB_STMT_START do
   241 #define HB_STMT_END   while (0)
   245 #define HB_STMT_END   while (0)
   242 
   246 
   243 #define _ASSERT_STATIC1(_line, _cond)   HB_UNUSED typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
   247 template <unsigned int cond> class hb_assert_constant_t;
   244 #define _ASSERT_STATIC0(_line, _cond)   _ASSERT_STATIC1 (_line, (_cond))
   248 template <> class hb_assert_constant_t<1> {};
   245 #define ASSERT_STATIC(_cond)            _ASSERT_STATIC0 (__LINE__, (_cond))
       
   246 
       
   247 template <unsigned int cond> class hb_assert_constant_t {};
       
   248 
   249 
   249 #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>))
   250 #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>))
   250 
   251 
   251 #define _PASTE1(a,b) a##b
       
   252 #define PASTE(a,b) _PASTE1(a,b)
       
   253 
       
   254 /* Lets assert int types.  Saves trouble down the road. */
   252 /* Lets assert int types.  Saves trouble down the road. */
   255 
   253 
   256 ASSERT_STATIC (sizeof (int8_t) == 1);
   254 static_assert ((sizeof (int8_t) == 1), "");
   257 ASSERT_STATIC (sizeof (uint8_t) == 1);
   255 static_assert ((sizeof (uint8_t) == 1), "");
   258 ASSERT_STATIC (sizeof (int16_t) == 2);
   256 static_assert ((sizeof (int16_t) == 2), "");
   259 ASSERT_STATIC (sizeof (uint16_t) == 2);
   257 static_assert ((sizeof (uint16_t) == 2), "");
   260 ASSERT_STATIC (sizeof (int32_t) == 4);
   258 static_assert ((sizeof (int32_t) == 4), "");
   261 ASSERT_STATIC (sizeof (uint32_t) == 4);
   259 static_assert ((sizeof (uint32_t) == 4), "");
   262 ASSERT_STATIC (sizeof (int64_t) == 8);
   260 static_assert ((sizeof (int64_t) == 8), "");
   263 ASSERT_STATIC (sizeof (uint64_t) == 8);
   261 static_assert ((sizeof (uint64_t) == 8), "");
   264 
   262 
   265 ASSERT_STATIC (sizeof (hb_codepoint_t) == 4);
   263 static_assert ((sizeof (hb_codepoint_t) == 4), "");
   266 ASSERT_STATIC (sizeof (hb_position_t) == 4);
   264 static_assert ((sizeof (hb_position_t) == 4), "");
   267 ASSERT_STATIC (sizeof (hb_mask_t) == 4);
   265 static_assert ((sizeof (hb_mask_t) == 4), "");
   268 ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
   266 static_assert ((sizeof (hb_var_int_t) == 4), "");
   269 
   267 
   270 
   268 
   271 /* We like our types POD */
   269 /* We like our types POD */
   272 
   270 
   273 #define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
   271 #define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
   298 /* Misc */
   296 /* Misc */
   299 
   297 
   300 /* Void! */
   298 /* Void! */
   301 struct _hb_void_t {};
   299 struct _hb_void_t {};
   302 typedef const _hb_void_t *hb_void_t;
   300 typedef const _hb_void_t *hb_void_t;
   303 #define HB_VOID ((const _hb_void_t *) NULL)
   301 #define HB_VOID ((const _hb_void_t *) nullptr)
   304 
   302 
   305 /* Return the number of 1 bits in mask. */
   303 /* Return the number of 1 bits in mask. */
   306 static inline HB_CONST_FUNC unsigned int
   304 static inline HB_CONST_FUNC unsigned int
   307 _hb_popcount32 (uint32_t mask)
   305 _hb_popcount32 (uint32_t mask)
   308 {
   306 {
   314   y = (mask >> 1) &033333333333;
   312   y = (mask >> 1) &033333333333;
   315   y = mask - y - ((y >>1) & 033333333333);
   313   y = mask - y - ((y >>1) & 033333333333);
   316   return (((y + (y >> 3)) & 030707070707) % 077);
   314   return (((y + (y >> 3)) & 030707070707) % 077);
   317 #endif
   315 #endif
   318 }
   316 }
       
   317 static inline HB_CONST_FUNC unsigned int
       
   318 _hb_popcount64 (uint64_t mask)
       
   319 {
       
   320 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
       
   321   if (sizeof (long) >= sizeof (mask))
       
   322     return __builtin_popcountl (mask);
       
   323 #endif
       
   324   return _hb_popcount32 (mask & 0xFFFFFFFF) + _hb_popcount32 (mask >> 32);
       
   325 }
       
   326 template <typename T> static inline unsigned int _hb_popcount (T mask);
       
   327 template <> inline unsigned int _hb_popcount<uint32_t> (uint32_t mask) { return _hb_popcount32 (mask); }
       
   328 template <> inline unsigned int _hb_popcount<uint64_t> (uint64_t mask) { return _hb_popcount64 (mask); }
   319 
   329 
   320 /* Returns the number of bits needed to store number */
   330 /* Returns the number of bits needed to store number */
   321 static inline HB_CONST_FUNC unsigned int
   331 static inline HB_CONST_FUNC unsigned int
   322 _hb_bit_storage (unsigned int number)
   332 _hb_bit_storage (unsigned int number)
   323 {
   333 {
   355 {
   365 {
   356   return (size > 0) && (count >= ((unsigned int) -1) / size);
   366   return (size > 0) && (count >= ((unsigned int) -1) / size);
   357 }
   367 }
   358 
   368 
   359 
   369 
   360 /* Type of bsearch() / qsort() compare function */
       
   361 typedef int (*hb_compare_func_t) (const void *, const void *);
       
   362 
       
   363 
       
   364 
       
   365 
   370 
   366 /* arrays and maps */
   371 /* arrays and maps */
   367 
   372 
   368 
   373 
   369 #define HB_PREALLOCED_ARRAY_INIT {0, 0, NULL}
   374 #define HB_PREALLOCED_ARRAY_INIT {0, 0, nullptr}
   370 template <typename Type, unsigned int StaticSize=16>
   375 template <typename Type, unsigned int StaticSize=16>
   371 struct hb_prealloced_array_t
   376 struct hb_prealloced_array_t
   372 {
   377 {
   373   unsigned int len;
   378   unsigned int len;
   374   unsigned int allocated;
   379   unsigned int allocated;
   375   Type *array;
   380   Type *array;
   376   Type static_array[StaticSize];
   381   Type static_array[StaticSize];
   377 
   382 
   378   void init (void) { memset (this, 0, sizeof (*this)); }
   383   void init (void)
       
   384   {
       
   385     len = 0;
       
   386     allocated = ARRAY_LENGTH (static_array);
       
   387     array = static_array;
       
   388   }
   379 
   389 
   380   inline Type& operator [] (unsigned int i) { return array[i]; }
   390   inline Type& operator [] (unsigned int i) { return array[i]; }
   381   inline const Type& operator [] (unsigned int i) const { return array[i]; }
   391   inline const Type& operator [] (unsigned int i) const { return array[i]; }
   382 
   392 
   383   inline Type *push (void)
   393   inline Type *push (void)
   384   {
   394   {
   385     if (!array) {
   395     if (unlikely (!resize (len + 1)))
   386       array = static_array;
   396       return nullptr;
   387       allocated = ARRAY_LENGTH (static_array);
   397 
       
   398     return &array[len - 1];
       
   399   }
       
   400 
       
   401   inline bool resize (unsigned int size)
       
   402   {
       
   403     if (unlikely (size > allocated))
       
   404     {
       
   405       /* Need to reallocate */
       
   406 
       
   407       unsigned int new_allocated = allocated;
       
   408       while (size >= new_allocated)
       
   409         new_allocated += (new_allocated >> 1) + 8;
       
   410 
       
   411       Type *new_array = nullptr;
       
   412 
       
   413       if (array == static_array) {
       
   414         new_array = (Type *) calloc (new_allocated, sizeof (Type));
       
   415         if (new_array)
       
   416           memcpy (new_array, array, len * sizeof (Type));
       
   417       } else {
       
   418         bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
       
   419         if (likely (!overflows)) {
       
   420           new_array = (Type *) realloc (array, new_allocated * sizeof (Type));
       
   421         }
       
   422       }
       
   423 
       
   424       if (unlikely (!new_array))
       
   425         return false;
       
   426 
       
   427       array = new_array;
       
   428       allocated = new_allocated;
   388     }
   429     }
   389     if (likely (len < allocated))
   430 
   390       return &array[len++];
   431     len = size;
   391 
   432     return true;
   392     /* Need to reallocate */
       
   393     unsigned int new_allocated = allocated + (allocated >> 1) + 8;
       
   394     Type *new_array = NULL;
       
   395 
       
   396     if (array == static_array) {
       
   397       new_array = (Type *) calloc (new_allocated, sizeof (Type));
       
   398       if (new_array)
       
   399         memcpy (new_array, array, len * sizeof (Type));
       
   400     } else {
       
   401       bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type));
       
   402       if (likely (!overflows)) {
       
   403         new_array = (Type *) realloc (array, new_allocated * sizeof (Type));
       
   404       }
       
   405     }
       
   406 
       
   407     if (unlikely (!new_array))
       
   408       return NULL;
       
   409 
       
   410     array = new_array;
       
   411     allocated = new_allocated;
       
   412     return &array[len++];
       
   413   }
   433   }
   414 
   434 
   415   inline void pop (void)
   435   inline void pop (void)
   416   {
   436   {
   417     len--;
   437     len--;
   436   template <typename T>
   456   template <typename T>
   437   inline Type *find (T v) {
   457   inline Type *find (T v) {
   438     for (unsigned int i = 0; i < len; i++)
   458     for (unsigned int i = 0; i < len; i++)
   439       if (array[i] == v)
   459       if (array[i] == v)
   440         return &array[i];
   460         return &array[i];
   441     return NULL;
   461     return nullptr;
   442   }
   462   }
   443   template <typename T>
   463   template <typename T>
   444   inline const Type *find (T v) const {
   464   inline const Type *find (T v) const {
   445     for (unsigned int i = 0; i < len; i++)
   465     for (unsigned int i = 0; i < len; i++)
   446       if (array[i] == v)
   466       if (array[i] == v)
   447         return &array[i];
   467         return &array[i];
   448     return NULL;
   468     return nullptr;
   449   }
   469   }
   450 
   470 
   451   inline void qsort (void)
   471   inline void qsort (void)
   452   {
   472   {
   453     ::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
   473     ::qsort (array, len, sizeof (Type), Type::cmp);
   454   }
   474   }
   455 
   475 
   456   inline void qsort (unsigned int start, unsigned int end)
   476   inline void qsort (unsigned int start, unsigned int end)
   457   {
   477   {
   458     ::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
   478     ::qsort (array + start, end - start, sizeof (Type), Type::cmp);
   459   }
   479   }
   460 
   480 
   461   template <typename T>
   481   template <typename T>
   462   inline Type *bsearch (T *key)
   482   inline Type *bsearch (T *x)
   463   {
   483   {
   464     return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
   484     unsigned int i;
       
   485     return bfind (x, &i) ? &array[i] : nullptr;
   465   }
   486   }
   466   template <typename T>
   487   template <typename T>
   467   inline const Type *bsearch (T *key) const
   488   inline const Type *bsearch (T *x) const
   468   {
   489   {
   469     return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
   490     unsigned int i;
       
   491     return bfind (x, &i) ? &array[i] : nullptr;
       
   492   }
       
   493   template <typename T>
       
   494   inline bool bfind (T *x, unsigned int *i) const
       
   495   {
       
   496     int min = 0, max = (int) this->len - 1;
       
   497     while (min <= max)
       
   498     {
       
   499       int mid = (min + max) / 2;
       
   500       int c = this->array[mid].cmp (x);
       
   501       if (c < 0)
       
   502         max = mid - 1;
       
   503       else if (c > 0)
       
   504         min = mid + 1;
       
   505       else
       
   506       {
       
   507         *i = mid;
       
   508         return true;
       
   509       }
       
   510     }
       
   511     if (max < 0 || (max < (int) this->len && this->array[max].cmp (x) > 0))
       
   512       max++;
       
   513     *i = max;
       
   514     return false;
   470   }
   515   }
   471 
   516 
   472   inline void finish (void)
   517   inline void finish (void)
   473   {
   518   {
   474     if (array != static_array)
   519     if (array != static_array)
   475       free (array);
   520       free (array);
   476     array = NULL;
   521     array = nullptr;
   477     allocated = len = 0;
   522     allocated = len = 0;
   478   }
   523   }
   479 };
   524 };
   480 
   525 
   481 template <typename Type>
   526 template <typename Type>
   488 
   533 
   489 #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
   534 #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
   490 template <typename item_t, typename lock_t>
   535 template <typename item_t, typename lock_t>
   491 struct hb_lockable_set_t
   536 struct hb_lockable_set_t
   492 {
   537 {
   493   hb_prealloced_array_t <item_t, 2> items;
   538   hb_prealloced_array_t <item_t, 1> items;
   494 
   539 
   495   inline void init (void) { items.init (); }
   540   inline void init (void) { items.init (); }
   496 
   541 
   497   template <typename T>
   542   template <typename T>
   498   inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
   543   inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
   505         *item = v;
   550         *item = v;
   506         l.unlock ();
   551         l.unlock ();
   507         old.finish ();
   552         old.finish ();
   508       }
   553       }
   509       else {
   554       else {
   510         item = NULL;
   555         item = nullptr;
   511         l.unlock ();
   556         l.unlock ();
   512       }
   557       }
   513     } else {
   558     } else {
   514       item = items.push ();
   559       item = items.push ();
   515       if (likely (item))
   560       if (likely (item))
   593 static inline unsigned char TOUPPER (unsigned char c)
   638 static inline unsigned char TOUPPER (unsigned char c)
   594 { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
   639 { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
   595 static inline unsigned char TOLOWER (unsigned char c)
   640 static inline unsigned char TOLOWER (unsigned char c)
   596 { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
   641 { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
   597 
   642 
   598 #define HB_TAG_CHAR4(s)   (HB_TAG(((const char *) s)[0], \
       
   599                                   ((const char *) s)[1], \
       
   600                                   ((const char *) s)[2], \
       
   601                                   ((const char *) s)[3]))
       
   602 
       
   603 
       
   604 /* C++ helpers */
       
   605 
       
   606 /* Makes class uncopyable.  Use in private: section. */
       
   607 #define NO_COPY(T) \
       
   608   T (const T &o); \
       
   609   T &operator = (const T &o)
       
   610 
       
   611 
       
   612 /* Debug */
       
   613 
       
   614 
   643 
   615 /* HB_NDEBUG disables some sanity checks that are very safe to disable and
   644 /* HB_NDEBUG disables some sanity checks that are very safe to disable and
   616  * should be disabled in production systems.  If NDEBUG is defined, enable
   645  * should be disabled in production systems.  If NDEBUG is defined, enable
   617  * HB_NDEBUG; but if it's desirable that normal assert()s (which are very
   646  * HB_NDEBUG; but if it's desirable that normal assert()s (which are very
   618  * light-weight) to be enabled, then HB_DEBUG can be defined to disable
   647  * light-weight) to be enabled, then HB_DEBUG can be defined to disable
   619  * the costlier checks. */
   648  * the costlier checks. */
   620 #ifdef NDEBUG
   649 #ifdef NDEBUG
   621 #define HB_NDEBUG
   650 #define HB_NDEBUG
   622 #endif
   651 #endif
   623 
   652 
   624 #ifndef HB_DEBUG
       
   625 #define HB_DEBUG 0
       
   626 #endif
       
   627 
       
   628 static inline bool
       
   629 _hb_debug (unsigned int level,
       
   630            unsigned int max_level)
       
   631 {
       
   632   return level < max_level;
       
   633 }
       
   634 
       
   635 #define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
       
   636 #define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
       
   637 
       
   638 static inline void
       
   639 _hb_print_func (const char *func)
       
   640 {
       
   641   if (func)
       
   642   {
       
   643     unsigned int func_len = strlen (func);
       
   644     /* Skip "static" */
       
   645     if (0 == strncmp (func, "static ", 7))
       
   646       func += 7;
       
   647     /* Skip "typename" */
       
   648     if (0 == strncmp (func, "typename ", 9))
       
   649       func += 9;
       
   650     /* Skip return type */
       
   651     const char *space = strchr (func, ' ');
       
   652     if (space)
       
   653       func = space + 1;
       
   654     /* Skip parameter list */
       
   655     const char *paren = strchr (func, '(');
       
   656     if (paren)
       
   657       func_len = paren - func;
       
   658     fprintf (stderr, "%.*s", func_len, func);
       
   659   }
       
   660 }
       
   661 
       
   662 template <int max_level> static inline void
       
   663 _hb_debug_msg_va (const char *what,
       
   664                   const void *obj,
       
   665                   const char *func,
       
   666                   bool indented,
       
   667                   unsigned int level,
       
   668                   int level_dir,
       
   669                   const char *message,
       
   670                   va_list ap) HB_PRINTF_FUNC(7, 0);
       
   671 template <int max_level> static inline void
       
   672 _hb_debug_msg_va (const char *what,
       
   673                   const void *obj,
       
   674                   const char *func,
       
   675                   bool indented,
       
   676                   unsigned int level,
       
   677                   int level_dir,
       
   678                   const char *message,
       
   679                   va_list ap)
       
   680 {
       
   681   if (!_hb_debug (level, max_level))
       
   682     return;
       
   683 
       
   684   fprintf (stderr, "%-10s", what ? what : "");
       
   685 
       
   686   if (obj)
       
   687     fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj);
       
   688   else
       
   689     fprintf (stderr, " %*s  ", (unsigned int) (2 * sizeof (void *)), "");
       
   690 
       
   691   if (indented) {
       
   692 #define VBAR    "\342\224\202"  /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
       
   693 #define VRBAR   "\342\224\234"  /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
       
   694 #define DLBAR   "\342\225\256"  /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */
       
   695 #define ULBAR   "\342\225\257"  /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */
       
   696 #define LBAR    "\342\225\264"  /* U+2574 BOX DRAWINGS LIGHT LEFT */
       
   697     static const char bars[] =
       
   698       VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
       
   699       VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
       
   700       VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
       
   701       VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
       
   702       VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
       
   703     fprintf (stderr, "%2u %s" VRBAR "%s",
       
   704              level,
       
   705              bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
       
   706              level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
       
   707   } else
       
   708     fprintf (stderr, "   " VRBAR LBAR);
       
   709 
       
   710   _hb_print_func (func);
       
   711 
       
   712   if (message)
       
   713   {
       
   714     fprintf (stderr, ": ");
       
   715     vfprintf (stderr, message, ap);
       
   716   }
       
   717 
       
   718   fprintf (stderr, "\n");
       
   719 }
       
   720 template <> inline void
       
   721 _hb_debug_msg_va<0> (const char *what HB_UNUSED,
       
   722                      const void *obj HB_UNUSED,
       
   723                      const char *func HB_UNUSED,
       
   724                      bool indented HB_UNUSED,
       
   725                      unsigned int level HB_UNUSED,
       
   726                      int level_dir HB_UNUSED,
       
   727                      const char *message HB_UNUSED,
       
   728                      va_list ap HB_UNUSED) {}
       
   729 
       
   730 template <int max_level> static inline void
       
   731 _hb_debug_msg (const char *what,
       
   732                const void *obj,
       
   733                const char *func,
       
   734                bool indented,
       
   735                unsigned int level,
       
   736                int level_dir,
       
   737                const char *message,
       
   738                ...) HB_PRINTF_FUNC(7, 8);
       
   739 template <int max_level> static inline void
       
   740 _hb_debug_msg (const char *what,
       
   741                const void *obj,
       
   742                const char *func,
       
   743                bool indented,
       
   744                unsigned int level,
       
   745                int level_dir,
       
   746                const char *message,
       
   747                ...)
       
   748 {
       
   749   va_list ap;
       
   750   va_start (ap, message);
       
   751   _hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap);
       
   752   va_end (ap);
       
   753 }
       
   754 template <> inline void
       
   755 _hb_debug_msg<0> (const char *what HB_UNUSED,
       
   756                   const void *obj HB_UNUSED,
       
   757                   const char *func HB_UNUSED,
       
   758                   bool indented HB_UNUSED,
       
   759                   unsigned int level HB_UNUSED,
       
   760                   int level_dir HB_UNUSED,
       
   761                   const char *message HB_UNUSED,
       
   762                   ...) HB_PRINTF_FUNC(7, 8);
       
   763 template <> inline void
       
   764 _hb_debug_msg<0> (const char *what HB_UNUSED,
       
   765                   const void *obj HB_UNUSED,
       
   766                   const char *func HB_UNUSED,
       
   767                   bool indented HB_UNUSED,
       
   768                   unsigned int level HB_UNUSED,
       
   769                   int level_dir HB_UNUSED,
       
   770                   const char *message HB_UNUSED,
       
   771                   ...) {}
       
   772 
       
   773 #define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...)       _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL,    true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
       
   774 #define DEBUG_MSG(WHAT, OBJ, ...)                               _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), NULL,    false, 0, 0, __VA_ARGS__)
       
   775 #define DEBUG_MSG_FUNC(WHAT, OBJ, ...)                          _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
       
   776 
       
   777 
       
   778 /*
       
   779  * Printer
       
   780  */
       
   781 
       
   782 template <typename T>
       
   783 struct hb_printer_t {
       
   784   const char *print (const T&) { return "something"; }
       
   785 };
       
   786 
       
   787 template <>
       
   788 struct hb_printer_t<bool> {
       
   789   const char *print (bool v) { return v ? "true" : "false"; }
       
   790 };
       
   791 
       
   792 template <>
       
   793 struct hb_printer_t<hb_void_t> {
       
   794   const char *print (hb_void_t) { return ""; }
       
   795 };
       
   796 
       
   797 
       
   798 /*
       
   799  * Trace
       
   800  */
       
   801 
       
   802 template <typename T>
       
   803 static inline void _hb_warn_no_return (bool returned)
       
   804 {
       
   805   if (unlikely (!returned)) {
       
   806     fprintf (stderr, "OUCH, returned with no call to return_trace().  This is a bug, please report.\n");
       
   807   }
       
   808 }
       
   809 template <>
       
   810 /*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
       
   811 {}
       
   812 
       
   813 template <int max_level, typename ret_t>
       
   814 struct hb_auto_trace_t {
       
   815   explicit inline hb_auto_trace_t (unsigned int *plevel_,
       
   816                                    const char *what_,
       
   817                                    const void *obj_,
       
   818                                    const char *func,
       
   819                                    const char *message,
       
   820                                    ...) : plevel (plevel_), what (what_), obj (obj_), returned (false)
       
   821   {
       
   822     if (plevel) ++*plevel;
       
   823 
       
   824     va_list ap;
       
   825     va_start (ap, message);
       
   826     _hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
       
   827     va_end (ap);
       
   828   }
       
   829   inline ~hb_auto_trace_t (void)
       
   830   {
       
   831     _hb_warn_no_return<ret_t> (returned);
       
   832     if (!returned) {
       
   833       _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " ");
       
   834     }
       
   835     if (plevel) --*plevel;
       
   836   }
       
   837 
       
   838   inline ret_t ret (ret_t v, unsigned int line = 0)
       
   839   {
       
   840     if (unlikely (returned)) {
       
   841       fprintf (stderr, "OUCH, double calls to return_trace().  This is a bug, please report.\n");
       
   842       return v;
       
   843     }
       
   844 
       
   845     _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
       
   846                               "return %s (line %d)",
       
   847                               hb_printer_t<ret_t>().print (v), line);
       
   848     if (plevel) --*plevel;
       
   849     plevel = NULL;
       
   850     returned = true;
       
   851     return v;
       
   852   }
       
   853 
       
   854   private:
       
   855   unsigned int *plevel;
       
   856   const char *what;
       
   857   const void *obj;
       
   858   bool returned;
       
   859 };
       
   860 template <typename ret_t> /* Optimize when tracing is disabled */
       
   861 struct hb_auto_trace_t<0, ret_t> {
       
   862   explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED,
       
   863                                    const char *what HB_UNUSED,
       
   864                                    const void *obj HB_UNUSED,
       
   865                                    const char *func HB_UNUSED,
       
   866                                    const char *message HB_UNUSED,
       
   867                                    ...) {}
       
   868 
       
   869   inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
       
   870 };
       
   871 
       
   872 #define return_trace(RET) return trace.ret (RET, __LINE__)
       
   873 
   653 
   874 /* Misc */
   654 /* Misc */
   875 
   655 
   876 template <typename T> class hb_assert_unsigned_t;
   656 template <typename T> class hb_assert_unsigned_t;
   877 template <> class hb_assert_unsigned_t<unsigned char> {};
   657 template <> class hb_assert_unsigned_t<unsigned char> {};
   885   /* The sizeof() is here to force template instantiation.
   665   /* The sizeof() is here to force template instantiation.
   886    * I'm sure there are better ways to do this but can't think of
   666    * I'm sure there are better ways to do this but can't think of
   887    * one right now.  Declaring a variable won't work as HB_UNUSED
   667    * one right now.  Declaring a variable won't work as HB_UNUSED
   888    * is unusable on some platforms and unused types are less likely
   668    * is unusable on some platforms and unused types are less likely
   889    * to generate a warning than unused variables. */
   669    * to generate a warning than unused variables. */
   890   ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);
   670   static_assert ((sizeof (hb_assert_unsigned_t<T>) >= 0), "");
   891 
   671 
   892   /* The casts below are important as if T is smaller than int,
   672   /* The casts below are important as if T is smaller than int,
   893    * the subtract results will become a signed int! */
   673    * the subtract results will become a signed int! */
   894   return (T)(u - lo) <= (T)(hi - lo);
   674   return (T)(u - lo) <= (T)(hi - lo);
   895 }
   675 }
   930         }
   710         }
   931 
   711 
   932 
   712 
   933 /* Useful for set-operations on small enums.
   713 /* Useful for set-operations on small enums.
   934  * For example, for testing "x ∈ {x1, x2, x3}" use:
   714  * For example, for testing "x ∈ {x1, x2, x3}" use:
   935  * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
   715  * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
   936  */
   716  */
   937 #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x)))
   717 #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned int)(x) < 32) + (1U << (unsigned int)(x)))
   938 #define FLAG_SAFE(x) (1U << (x))
   718 #define FLAG_UNSAFE(x) ((unsigned int)(x) < 32 ? (1U << (unsigned int)(x)) : 0)
   939 #define FLAG_UNSAFE(x) ((x) < 32 ? FLAG_SAFE(x) : 0)
       
   940 #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
   719 #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
   941 
   720 
   942 
   721 
   943 template <typename T, typename T2> static inline void
   722 template <typename T, typename T2> static inline void
   944 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
   723 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
   966 }
   745 }
   967 
   746 
   968 template <typename T> static inline void
   747 template <typename T> static inline void
   969 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
   748 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
   970 {
   749 {
   971   hb_stable_sort (array, len, compar, (int *) NULL);
   750   hb_stable_sort (array, len, compar, (int *) nullptr);
   972 }
   751 }
   973 
   752 
   974 static inline hb_bool_t
   753 static inline hb_bool_t
   975 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
   754 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
   976 {
   755 {
   988   *out = v;
   767   *out = v;
   989   return true;
   768   return true;
   990 }
   769 }
   991 
   770 
   992 
   771 
       
   772 /* Vectorization */
       
   773 
       
   774 struct HbOpOr
       
   775 {
       
   776   static const bool passthru_left = true;
       
   777   static const bool passthru_right = true;
       
   778   template <typename T> static void process (T &o, const T &a, const T &b) { o = a | b; }
       
   779 };
       
   780 struct HbOpAnd
       
   781 {
       
   782   static const bool passthru_left = false;
       
   783   static const bool passthru_right = false;
       
   784   template <typename T> static void process (T &o, const T &a, const T &b) { o = a & b; }
       
   785 };
       
   786 struct HbOpMinus
       
   787 {
       
   788   static const bool passthru_left = true;
       
   789   static const bool passthru_right = false;
       
   790   template <typename T> static void process (T &o, const T &a, const T &b) { o = a & ~b; }
       
   791 };
       
   792 struct HbOpXor
       
   793 {
       
   794   static const bool passthru_left = true;
       
   795   static const bool passthru_right = true;
       
   796   template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; }
       
   797 };
       
   798 
       
   799 /* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))). */
       
   800 template <typename elt_t, unsigned int byte_size>
       
   801 struct hb_vector_size_t
       
   802 {
       
   803   elt_t& operator [] (unsigned int i) { return v[i]; }
       
   804   const elt_t& operator [] (unsigned int i) const { return v[i]; }
       
   805 
       
   806   template <class Op>
       
   807   inline hb_vector_size_t process (const hb_vector_size_t &o) const
       
   808   {
       
   809     hb_vector_size_t r;
       
   810     for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
       
   811       Op::process (r.v[i], v[i], o.v[i]);
       
   812     return r;
       
   813   }
       
   814   inline hb_vector_size_t operator | (const hb_vector_size_t &o) const
       
   815   { return process<HbOpOr> (o); }
       
   816   inline hb_vector_size_t operator & (const hb_vector_size_t &o) const
       
   817   { return process<HbOpAnd> (o); }
       
   818   inline hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
       
   819   { return process<HbOpXor> (o); }
       
   820   inline hb_vector_size_t operator ~ () const
       
   821   {
       
   822     hb_vector_size_t r;
       
   823     for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
       
   824       r.v[i] = ~v[i];
       
   825     return r;
       
   826   }
       
   827 
       
   828   private:
       
   829   static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
       
   830   elt_t v[byte_size / sizeof (elt_t)];
       
   831 };
       
   832 
       
   833 /* The `vector_size' attribute was introduced in gcc 3.1. */
       
   834 #if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
       
   835 #define HAVE_VECTOR_SIZE 1
       
   836 #endif
       
   837 
       
   838 
   993 /* Global runtime options. */
   839 /* Global runtime options. */
   994 
   840 
   995 struct hb_options_t
   841 struct hb_options_t
   996 {
   842 {
   997   unsigned int initialized : 1;
   843   unsigned int initialized : 1;
  1000 
   846 
  1001 union hb_options_union_t {
   847 union hb_options_union_t {
  1002   unsigned int i;
   848   unsigned int i;
  1003   hb_options_t opts;
   849   hb_options_t opts;
  1004 };
   850 };
  1005 ASSERT_STATIC (sizeof (int) == sizeof (hb_options_union_t));
   851 static_assert ((sizeof (int) == sizeof (hb_options_union_t)), "");
  1006 
   852 
  1007 HB_INTERNAL void
   853 HB_INTERNAL void
  1008 _hb_options_init (void);
   854 _hb_options_init (void);
  1009 
   855 
  1010 extern HB_INTERNAL hb_options_union_t _hb_options;
   856 extern HB_INTERNAL hb_options_union_t _hb_options;
  1019 }
   865 }
  1020 
   866 
  1021 /* Size signifying variable-sized array */
   867 /* Size signifying variable-sized array */
  1022 #define VAR 1
   868 #define VAR 1
  1023 
   869 
       
   870 
       
   871 /* String type. */
       
   872 
       
   873 struct hb_string_t
       
   874 {
       
   875   inline hb_string_t (void) : bytes (nullptr), len (0) {}
       
   876   inline hb_string_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
       
   877 
       
   878   inline int cmp (const hb_string_t &a) const
       
   879   {
       
   880     if (len != a.len)
       
   881       return (int) a.len - (int) len;
       
   882 
       
   883     return memcmp (a.bytes, bytes, len);
       
   884   }
       
   885   static inline int cmp (const void *pa, const void *pb)
       
   886   {
       
   887     hb_string_t *a = (hb_string_t *) pa;
       
   888     hb_string_t *b = (hb_string_t *) pb;
       
   889     return b->cmp (*a);
       
   890   }
       
   891 
       
   892   const char *bytes;
       
   893   unsigned int len;
       
   894 };
       
   895 
       
   896 
  1024 #endif /* HB_PRIVATE_HH */
   897 #endif /* HB_PRIVATE_HH */