< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-private.hh

Print this page




  27  */
  28 
  29 #ifndef HB_PRIVATE_HH
  30 #define HB_PRIVATE_HH
  31 
  32 #ifdef HAVE_CONFIG_H
  33 #include "config.h"
  34 #endif
  35 
  36 #include "hb.h"
  37 #define HB_H_IN
  38 #ifdef HAVE_OT
  39 #include "hb-ot.h"
  40 #define HB_OT_H_IN
  41 #endif
  42 
  43 #include <stdlib.h>
  44 #include <stddef.h>
  45 #include <string.h>
  46 #include <assert.h>
  47 
  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>
  53 #include <errno.h>

  54 #include <stdarg.h>
  55 
  56 



  57 /* Compile-time custom allocator support. */
  58 
  59 #if defined(hb_malloc_impl) \
  60  && defined(hb_calloc_impl) \
  61  && defined(hb_realloc_impl) \
  62  && defined(hb_free_impl)
  63 extern "C" void* hb_malloc_impl(size_t size);
  64 extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
  65 extern "C" void* hb_realloc_impl(void *ptr, size_t size);
  66 extern "C" void  hb_free_impl(void *ptr);
  67 #define malloc hb_malloc_impl
  68 #define calloc hb_calloc_impl
  69 #define realloc hb_realloc_impl
  70 #define free hb_free_impl
  71 #endif
  72 
  73 
  74 /* Compiler attributes */
  75 
  76 
  77 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
  78 #define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0)
  79 #define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
  80 #define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))















  81 #else
  82 #define likely(expr) (expr)
  83 #define unlikely(expr) (expr)
  84 #endif
  85 
  86 #if !defined(__GNUC__) && !defined(__clang__)
  87 #undef __attribute__
  88 #define __attribute__(x)
  89 #endif
  90 
  91 #if __GNUC__ >= 3
  92 #define HB_PURE_FUNC    __attribute__((pure))
  93 #define HB_CONST_FUNC   __attribute__((const))
  94 #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
  95 #else
  96 #define HB_PURE_FUNC
  97 #define HB_CONST_FUNC
  98 #define HB_PRINTF_FUNC(format_idx, arg_idx)
  99 #endif
 100 #if __GNUC__ >= 4


 151 
 152 #if defined(_WIN32) || defined(__CYGWIN__)
 153    /* We need Windows Vista for both Uniscribe backend and for
 154     * MemoryBarrier.  We don't support compiling on Windows XP,
 155     * though we run on it fine. */
 156 #  if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
 157 #    undef _WIN32_WINNT
 158 #  endif
 159 #  ifndef _WIN32_WINNT
 160 #    define _WIN32_WINNT 0x0600
 161 #  endif
 162 #  ifndef WIN32_LEAN_AND_MEAN
 163 #    define WIN32_LEAN_AND_MEAN 1
 164 #  endif
 165 #  ifndef STRICT
 166 #    define STRICT 1
 167 #  endif
 168 
 169 #  if defined(_WIN32_WCE)
 170      /* Some things not defined on Windows CE. */
 171 #    define strdup _strdup
 172 #    define vsnprintf _vsnprintf
 173 #    define getenv(Name) NULL
 174 #    if _WIN32_WCE < 0x800
 175 #      define setlocale(Category, Locale) "C"
 176 static int errno = 0; /* Use something better? */
 177 #    endif
 178 #  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
 179 #    define getenv(Name) NULL
 180 #  endif
 181 #  if defined(_MSC_VER) && _MSC_VER < 1900
 182 #    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
 187 #endif
 188 
 189 #if HAVE_ATEXIT
 190 /* atexit() is only safe to be called from shared libraries on certain
 191  * platforms.  Whitelist.
 192  * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
 193 #  if defined(__linux) && defined(__GLIBC_PREREQ)
 194 #    if __GLIBC_PREREQ(2,3)
 195 /* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
 196 #      define HB_USE_ATEXIT 1
 197 #    endif
 198 #  elif defined(_MSC_VER) || defined(__MINGW32__)
 199 /* For MSVC:
 200  * http://msdn.microsoft.com/en-ca/library/tze57ck3.aspx
 201  * http://msdn.microsoft.com/en-ca/library/zk17ww08.aspx
 202  * mingw32 headers say atexit is safe to use in shared libraries.
 203  */
 204 #    define HB_USE_ATEXIT 1
 205 #  elif defined(__ANDROID__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
 206 /* This was fixed in Android NKD r8 or r8b:
 207  * https://code.google.com/p/android/issues/detail?id=6455
 208  * which introduced GCC 4.6:
 209  * https://developer.android.com/tools/sdk/ndk/index.html
 210  */
 211 #    define HB_USE_ATEXIT 1
 212 #  endif
 213 #endif
 214 
 215 /* Basics */
 216 
 217 
 218 #ifndef NULL
 219 # define NULL ((void *) 0)
 220 #endif
 221 
 222 #undef MIN
 223 template <typename Type>
 224 static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
 225 
 226 #undef MAX
 227 template <typename Type>
 228 static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
 229 
 230 static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
 231 { return (a + (b - 1)) / b; }
 232 
 233 
 234 #undef  ARRAY_LENGTH
 235 template <typename Type, unsigned int n>
 236 static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
 237 /* A const version, but does not detect erratically being called on pointers. */
 238 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
 239 
 240 #define HB_STMT_START do
 241 #define HB_STMT_END   while (0)
 242 
 243 #define _ASSERT_STATIC1(_line, _cond)   HB_UNUSED typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
 244 #define _ASSERT_STATIC0(_line, _cond)   _ASSERT_STATIC1 (_line, (_cond))
 245 #define ASSERT_STATIC(_cond)            _ASSERT_STATIC0 (__LINE__, (_cond))
 246 
 247 template <unsigned int cond> class hb_assert_constant_t {};
 248 
 249 #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>))
 250 
 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. */
 255 
 256 ASSERT_STATIC (sizeof (int8_t) == 1);
 257 ASSERT_STATIC (sizeof (uint8_t) == 1);
 258 ASSERT_STATIC (sizeof (int16_t) == 2);
 259 ASSERT_STATIC (sizeof (uint16_t) == 2);
 260 ASSERT_STATIC (sizeof (int32_t) == 4);
 261 ASSERT_STATIC (sizeof (uint32_t) == 4);
 262 ASSERT_STATIC (sizeof (int64_t) == 8);
 263 ASSERT_STATIC (sizeof (uint64_t) == 8);
 264 
 265 ASSERT_STATIC (sizeof (hb_codepoint_t) == 4);
 266 ASSERT_STATIC (sizeof (hb_position_t) == 4);
 267 ASSERT_STATIC (sizeof (hb_mask_t) == 4);
 268 ASSERT_STATIC (sizeof (hb_var_int_t) == 4);
 269 
 270 
 271 /* We like our types POD */
 272 
 273 #define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
 274 #define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type)
 275 #define ASSERT_TYPE_POD(_type)          _ASSERT_TYPE_POD0 (__LINE__, _type)
 276 
 277 #ifdef __GNUC__
 278 # define _ASSERT_INSTANCE_POD1(_line, _instance) \
 279         HB_STMT_START { \
 280                 typedef __typeof__(_instance) _type_##_line; \
 281                 _ASSERT_TYPE_POD1 (_line, _type_##_line); \
 282         } HB_STMT_END
 283 #else
 284 # define _ASSERT_INSTANCE_POD1(_line, _instance)        typedef int _assertion_on_line_##_line##_not_tested
 285 #endif
 286 # define _ASSERT_INSTANCE_POD0(_line, _instance)        _ASSERT_INSTANCE_POD1 (_line, _instance)
 287 # define ASSERT_INSTANCE_POD(_instance)                 _ASSERT_INSTANCE_POD0 (__LINE__, _instance)
 288 
 289 /* Check _assertion in a method environment */
 290 #define _ASSERT_POD1(_line) \
 291         HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \
 292         { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
 293 # define _ASSERT_POD0(_line)    _ASSERT_POD1 (_line)
 294 # define ASSERT_POD()           _ASSERT_POD0 (__LINE__)
 295 
 296 
 297 
 298 /* Misc */
 299 
 300 /* Void! */
 301 struct _hb_void_t {};
 302 typedef const _hb_void_t *hb_void_t;
 303 #define HB_VOID ((const _hb_void_t *) NULL)
 304 
 305 /* Return the number of 1 bits in mask. */
 306 static inline HB_CONST_FUNC unsigned int
 307 _hb_popcount32 (uint32_t mask)
 308 {
 309 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
 310   return __builtin_popcount (mask);
 311 #else
 312   /* "HACKMEM 169" */
 313   uint32_t y;
 314   y = (mask >> 1) &033333333333;
 315   y = mask - y - ((y >>1) & 033333333333);
 316   return (((y + (y >> 3)) & 030707070707) % 077);
 317 #endif
 318 }












 319 
 320 /* Returns the number of bits needed to store number */
 321 static inline HB_CONST_FUNC unsigned int
 322 _hb_bit_storage (unsigned int number)
 323 {
 324 #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
 325   return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0;
 326 #else
 327   unsigned int n_bits = 0;
 328   while (number) {
 329     n_bits++;
 330     number >>= 1;
 331   }
 332   return n_bits;
 333 #endif
 334 }
 335 
 336 /* Returns the number of zero bits in the least significant side of number */
 337 static inline HB_CONST_FUNC unsigned int
 338 _hb_ctz (unsigned int number)


 340 #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
 341   return likely (number) ? __builtin_ctz (number) : 0;
 342 #else
 343   unsigned int n_bits = 0;
 344   if (unlikely (!number)) return 0;
 345   while (!(number & 1)) {
 346     n_bits++;
 347     number >>= 1;
 348   }
 349   return n_bits;
 350 #endif
 351 }
 352 
 353 static inline bool
 354 _hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
 355 {
 356   return (size > 0) && (count >= ((unsigned int) -1) / size);
 357 }
 358 
 359 
 360 /* Type of bsearch() / qsort() compare function */
 361 typedef int (*hb_compare_func_t) (const void *, const void *);
 362 
 363 
 364 
 365 
 366 /* arrays and maps */
 367 
 368 
 369 #define HB_PREALLOCED_ARRAY_INIT {0, 0, NULL}
 370 template <typename Type, unsigned int StaticSize=16>
 371 struct hb_prealloced_array_t
 372 {
 373   unsigned int len;
 374   unsigned int allocated;
 375   Type *array;
 376   Type static_array[StaticSize];
 377 
 378   void init (void) { memset (this, 0, sizeof (*this)); }





 379 
 380   inline Type& operator [] (unsigned int i) { return array[i]; }
 381   inline const Type& operator [] (unsigned int i) const { return array[i]; }
 382 
 383   inline Type *push (void)
 384   {
 385     if (!array) {
 386       array = static_array;
 387       allocated = ARRAY_LENGTH (static_array);

 388     }
 389     if (likely (len < allocated))
 390       return &array[len++];
 391 




 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   }
 414 
 415   inline void pop (void)
 416   {
 417     len--;
 418   }
 419 
 420   inline void remove (unsigned int i)
 421   {
 422      if (unlikely (i >= len))
 423        return;
 424      memmove (static_cast<void *> (&array[i]),
 425               static_cast<void *> (&array[i + 1]),
 426               (len - i - 1) * sizeof (Type));
 427      len--;
 428   }
 429 
 430   inline void shrink (unsigned int l)
 431   {
 432      if (l < len)
 433        len = l;
 434   }
 435 
 436   template <typename T>
 437   inline Type *find (T v) {
 438     for (unsigned int i = 0; i < len; i++)
 439       if (array[i] == v)
 440         return &array[i];
 441     return NULL;
 442   }
 443   template <typename T>
 444   inline const Type *find (T v) const {
 445     for (unsigned int i = 0; i < len; i++)
 446       if (array[i] == v)
 447         return &array[i];
 448     return NULL;
 449   }
 450 
 451   inline void qsort (void)
 452   {
 453     ::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
 454   }
 455 
 456   inline void qsort (unsigned int start, unsigned int end)
 457   {
 458     ::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
 459   }
 460 
 461   template <typename T>
 462   inline Type *bsearch (T *key)
 463   {
 464     return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);

 465   }
 466   template <typename T>
 467   inline const Type *bsearch (T *key) const
 468   {
 469     return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
























 470   }
 471 
 472   inline void finish (void)
 473   {
 474     if (array != static_array)
 475       free (array);
 476     array = NULL;
 477     allocated = len = 0;
 478   }
 479 };
 480 
 481 template <typename Type>
 482 struct hb_auto_array_t : hb_prealloced_array_t <Type>
 483 {
 484   hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); }
 485   ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); }
 486 };
 487 
 488 
 489 #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
 490 template <typename item_t, typename lock_t>
 491 struct hb_lockable_set_t
 492 {
 493   hb_prealloced_array_t <item_t, 2> items;
 494 
 495   inline void init (void) { items.init (); }
 496 
 497   template <typename T>
 498   inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
 499   {
 500     l.lock ();
 501     item_t *item = items.find (v);
 502     if (item) {
 503       if (replace) {
 504         item_t old = *item;
 505         *item = v;
 506         l.unlock ();
 507         old.finish ();
 508       }
 509       else {
 510         item = NULL;
 511         l.unlock ();
 512       }
 513     } else {
 514       item = items.push ();
 515       if (likely (item))
 516         *item = v;
 517       l.unlock ();
 518     }
 519     return item;
 520   }
 521 
 522   template <typename T>
 523   inline void remove (T v, lock_t &l)
 524   {
 525     l.lock ();
 526     item_t *item = items.find (v);
 527     if (item) {
 528       item_t old = *item;
 529       *item = items[items.len - 1];
 530       items.pop ();


 578     items.finish ();
 579     l.unlock ();
 580   }
 581 
 582 };
 583 
 584 
 585 /* ASCII tag/character handling */
 586 
 587 static inline bool ISALPHA (unsigned char c)
 588 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
 589 static inline bool ISALNUM (unsigned char c)
 590 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
 591 static inline bool ISSPACE (unsigned char c)
 592 { return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
 593 static inline unsigned char TOUPPER (unsigned char c)
 594 { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
 595 static inline unsigned char TOLOWER (unsigned char c)
 596 { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
 597 
 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 
 615 /* 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
 617  * 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
 619  * the costlier checks. */
 620 #ifdef NDEBUG
 621 #define HB_NDEBUG
 622 #endif
 623 
 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 
 874 /* Misc */
 875 
 876 template <typename T> class hb_assert_unsigned_t;
 877 template <> class hb_assert_unsigned_t<unsigned char> {};
 878 template <> class hb_assert_unsigned_t<unsigned short> {};
 879 template <> class hb_assert_unsigned_t<unsigned int> {};
 880 template <> class hb_assert_unsigned_t<unsigned long> {};
 881 
 882 template <typename T> static inline bool
 883 hb_in_range (T u, T lo, T hi)
 884 {
 885   /* The sizeof() is here to force template instantiation.
 886    * 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
 888    * is unusable on some platforms and unused types are less likely
 889    * to generate a warning than unused variables. */
 890   ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);
 891 
 892   /* The casts below are important as if T is smaller than int,
 893    * the subtract results will become a signed int! */
 894   return (T)(u - lo) <= (T)(hi - lo);
 895 }
 896 
 897 template <typename T> static inline bool
 898 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
 899 {
 900   return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
 901 }
 902 
 903 template <typename T> static inline bool
 904 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
 905 {
 906   return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
 907 }
 908 
 909 
 910 /* Enable bitwise ops on enums marked as flags_t */


 915  * For MSVC warnings, see: https://github.com/behdad/harfbuzz/pull/163
 916  */
 917 #ifdef _MSC_VER
 918 # pragma warning(disable:4200)
 919 # pragma warning(disable:4800)
 920 #endif
 921 #define HB_MARK_AS_FLAG_T(T) \
 922         extern "C++" { \
 923           static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
 924           static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
 925           static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
 926           static inline T operator ~ (T r) { return T (~(unsigned int) r); } \
 927           static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
 928           static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
 929           static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
 930         }
 931 
 932 
 933 /* Useful for set-operations on small enums.
 934  * For example, for testing "x ∈ {x1, x2, x3}" use:
 935  * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
 936  */
 937 #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x)))
 938 #define FLAG_SAFE(x) (1U << (x))
 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))
 941 
 942 
 943 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)
 945 {
 946   for (unsigned int i = 1; i < len; i++)
 947   {
 948     unsigned int j = i;
 949     while (j && compar (&array[j - 1], &array[i]) > 0)
 950       j--;
 951     if (i == j)
 952       continue;
 953     /* Move item i to occupy place for item j, shift what's in between. */
 954     {
 955       T t = array[i];
 956       memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
 957       array[j] = t;
 958     }
 959     if (array2)
 960     {
 961       T2 t = array2[i];
 962       memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2));
 963       array2[j] = t;
 964     }
 965   }
 966 }
 967 
 968 template <typename T> static inline void
 969 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
 970 {
 971   hb_stable_sort (array, len, compar, (int *) NULL);
 972 }
 973 
 974 static inline hb_bool_t
 975 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
 976 {
 977   /* Pain because we don't know whether s is nul-terminated. */
 978   char buf[64];
 979   len = MIN (ARRAY_LENGTH (buf) - 1, len);
 980   strncpy (buf, s, len);
 981   buf[len] = '\0';
 982 
 983   char *end;
 984   errno = 0;
 985   unsigned long v = strtoul (buf, &end, base);
 986   if (errno) return false;
 987   if (*end) return false;
 988   *out = v;
 989   return true;
 990 }
 991 
 992 



































































 993 /* Global runtime options. */
 994 
 995 struct hb_options_t
 996 {
 997   unsigned int initialized : 1;
 998   unsigned int uniscribe_bug_compatible : 1;
 999 };
1000 
1001 union hb_options_union_t {
1002   unsigned int i;
1003   hb_options_t opts;
1004 };
1005 ASSERT_STATIC (sizeof (int) == sizeof (hb_options_union_t));
1006 
1007 HB_INTERNAL void
1008 _hb_options_init (void);
1009 
1010 extern HB_INTERNAL hb_options_union_t _hb_options;
1011 
1012 static inline hb_options_t
1013 hb_options (void)
1014 {
1015   if (unlikely (!_hb_options.i))
1016     _hb_options_init ();
1017 
1018   return _hb_options.opts;
1019 }
1020 
1021 /* Size signifying variable-sized array */
1022 #define VAR 1



























1023 
1024 #endif /* HB_PRIVATE_HH */


  27  */
  28 
  29 #ifndef HB_PRIVATE_HH
  30 #define HB_PRIVATE_HH
  31 
  32 #ifdef HAVE_CONFIG_H
  33 #include "config.h"
  34 #endif
  35 
  36 #include "hb.h"
  37 #define HB_H_IN
  38 #ifdef HAVE_OT
  39 #include "hb-ot.h"
  40 #define HB_OT_H_IN
  41 #endif
  42 
  43 #include <stdlib.h>
  44 #include <stddef.h>
  45 #include <string.h>
  46 #include <assert.h>






  47 #include <errno.h>
  48 #include <stdio.h>
  49 #include <stdarg.h>
  50 
  51 
  52 #define HB_PASTE1(a,b) a##b
  53 #define HB_PASTE(a,b) HB_PASTE1(a,b)
  54 
  55 /* Compile-time custom allocator support. */
  56 
  57 #if defined(hb_malloc_impl) \
  58  && defined(hb_calloc_impl) \
  59  && defined(hb_realloc_impl) \
  60  && defined(hb_free_impl)
  61 extern "C" void* hb_malloc_impl(size_t size);
  62 extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
  63 extern "C" void* hb_realloc_impl(void *ptr, size_t size);
  64 extern "C" void  hb_free_impl(void *ptr);
  65 #define malloc hb_malloc_impl
  66 #define calloc hb_calloc_impl
  67 #define realloc hb_realloc_impl
  68 #define free hb_free_impl
  69 #endif
  70 
  71 
  72 /* Compiler attributes */
  73 
  74 
  75 #if __cplusplus < 201103L
  76 
  77 #ifndef nullptr
  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))
  94 #else
  95 #define likely(expr) (expr)
  96 #define unlikely(expr) (expr)
  97 #endif
  98 
  99 #if !defined(__GNUC__) && !defined(__clang__)
 100 #undef __attribute__
 101 #define __attribute__(x)
 102 #endif
 103 
 104 #if __GNUC__ >= 3
 105 #define HB_PURE_FUNC    __attribute__((pure))
 106 #define HB_CONST_FUNC   __attribute__((const))
 107 #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
 108 #else
 109 #define HB_PURE_FUNC
 110 #define HB_CONST_FUNC
 111 #define HB_PRINTF_FUNC(format_idx, arg_idx)
 112 #endif
 113 #if __GNUC__ >= 4


 164 
 165 #if defined(_WIN32) || defined(__CYGWIN__)
 166    /* We need Windows Vista for both Uniscribe backend and for
 167     * MemoryBarrier.  We don't support compiling on Windows XP,
 168     * though we run on it fine. */
 169 #  if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
 170 #    undef _WIN32_WINNT
 171 #  endif
 172 #  ifndef _WIN32_WINNT
 173 #    define _WIN32_WINNT 0x0600
 174 #  endif
 175 #  ifndef WIN32_LEAN_AND_MEAN
 176 #    define WIN32_LEAN_AND_MEAN 1
 177 #  endif
 178 #  ifndef STRICT
 179 #    define STRICT 1
 180 #  endif
 181 
 182 #  if defined(_WIN32_WCE)
 183      /* Some things not defined on Windows CE. */

 184 #    define vsnprintf _vsnprintf
 185 #    define getenv(Name) nullptr
 186 #    if _WIN32_WCE < 0x800
 187 #      define setlocale(Category, Locale) "C"
 188 static int errno = 0; /* Use something better? */
 189 #    endif
 190 #  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
 191 #    define getenv(Name) nullptr
 192 #  endif
 193 #  if defined(_MSC_VER) && _MSC_VER < 1900
 194 #    define snprintf _snprintf



 195 #  endif
 196 #endif
 197 
 198 #if HAVE_ATEXIT
 199 /* atexit() is only safe to be called from shared libraries on certain
 200  * platforms.  Whitelist.
 201  * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
 202 #  if defined(__linux) && defined(__GLIBC_PREREQ)
 203 #    if __GLIBC_PREREQ(2,3)
 204 /* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
 205 #      define HB_USE_ATEXIT 1
 206 #    endif
 207 #  elif defined(_MSC_VER) || defined(__MINGW32__)
 208 /* For MSVC:
 209  * http://msdn.microsoft.com/en-ca/library/tze57ck3.aspx
 210  * http://msdn.microsoft.com/en-ca/library/zk17ww08.aspx
 211  * mingw32 headers say atexit is safe to use in shared libraries.
 212  */
 213 #    define HB_USE_ATEXIT 1
 214 #  elif defined(__ANDROID__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
 215 /* This was fixed in Android NKD r8 or r8b:
 216  * https://code.google.com/p/android/issues/detail?id=6455
 217  * which introduced GCC 4.6:
 218  * https://developer.android.com/tools/sdk/ndk/index.html
 219  */
 220 #    define HB_USE_ATEXIT 1
 221 #  endif
 222 #endif
 223 
 224 /* Basics */
 225 





 226 #undef MIN
 227 template <typename Type>
 228 static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
 229 
 230 #undef MAX
 231 template <typename Type>
 232 static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
 233 
 234 static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
 235 { return (a + (b - 1)) / b; }
 236 
 237 
 238 #undef  ARRAY_LENGTH
 239 template <typename Type, unsigned int n>
 240 static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
 241 /* A const version, but does not detect erratically being called on pointers. */
 242 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
 243 
 244 #define HB_STMT_START do
 245 #define HB_STMT_END   while (0)
 246 
 247 template <unsigned int cond> class hb_assert_constant_t;
 248 template <> class hb_assert_constant_t<1> {};



 249 
 250 #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>))
 251 



 252 /* Lets assert int types.  Saves trouble down the road. */
 253 
 254 static_assert ((sizeof (int8_t) == 1), "");
 255 static_assert ((sizeof (uint8_t) == 1), "");
 256 static_assert ((sizeof (int16_t) == 2), "");
 257 static_assert ((sizeof (uint16_t) == 2), "");
 258 static_assert ((sizeof (int32_t) == 4), "");
 259 static_assert ((sizeof (uint32_t) == 4), "");
 260 static_assert ((sizeof (int64_t) == 8), "");
 261 static_assert ((sizeof (uint64_t) == 8), "");
 262 
 263 static_assert ((sizeof (hb_codepoint_t) == 4), "");
 264 static_assert ((sizeof (hb_position_t) == 4), "");
 265 static_assert ((sizeof (hb_mask_t) == 4), "");
 266 static_assert ((sizeof (hb_var_int_t) == 4), "");
 267 
 268 
 269 /* We like our types POD */
 270 
 271 #define _ASSERT_TYPE_POD1(_line, _type) union _type_##_type##_on_line_##_line##_is_not_POD { _type instance; }
 272 #define _ASSERT_TYPE_POD0(_line, _type) _ASSERT_TYPE_POD1 (_line, _type)
 273 #define ASSERT_TYPE_POD(_type)          _ASSERT_TYPE_POD0 (__LINE__, _type)
 274 
 275 #ifdef __GNUC__
 276 # define _ASSERT_INSTANCE_POD1(_line, _instance) \
 277         HB_STMT_START { \
 278                 typedef __typeof__(_instance) _type_##_line; \
 279                 _ASSERT_TYPE_POD1 (_line, _type_##_line); \
 280         } HB_STMT_END
 281 #else
 282 # define _ASSERT_INSTANCE_POD1(_line, _instance)        typedef int _assertion_on_line_##_line##_not_tested
 283 #endif
 284 # define _ASSERT_INSTANCE_POD0(_line, _instance)        _ASSERT_INSTANCE_POD1 (_line, _instance)
 285 # define ASSERT_INSTANCE_POD(_instance)                 _ASSERT_INSTANCE_POD0 (__LINE__, _instance)
 286 
 287 /* Check _assertion in a method environment */
 288 #define _ASSERT_POD1(_line) \
 289         HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \
 290         { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ }
 291 # define _ASSERT_POD0(_line)    _ASSERT_POD1 (_line)
 292 # define ASSERT_POD()           _ASSERT_POD0 (__LINE__)
 293 
 294 
 295 
 296 /* Misc */
 297 
 298 /* Void! */
 299 struct _hb_void_t {};
 300 typedef const _hb_void_t *hb_void_t;
 301 #define HB_VOID ((const _hb_void_t *) nullptr)
 302 
 303 /* Return the number of 1 bits in mask. */
 304 static inline HB_CONST_FUNC unsigned int
 305 _hb_popcount32 (uint32_t mask)
 306 {
 307 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
 308   return __builtin_popcount (mask);
 309 #else
 310   /* "HACKMEM 169" */
 311   uint32_t y;
 312   y = (mask >> 1) &033333333333;
 313   y = mask - y - ((y >>1) & 033333333333);
 314   return (((y + (y >> 3)) & 030707070707) % 077);
 315 #endif
 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); }
 329 
 330 /* Returns the number of bits needed to store number */
 331 static inline HB_CONST_FUNC unsigned int
 332 _hb_bit_storage (unsigned int number)
 333 {
 334 #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
 335   return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0;
 336 #else
 337   unsigned int n_bits = 0;
 338   while (number) {
 339     n_bits++;
 340     number >>= 1;
 341   }
 342   return n_bits;
 343 #endif
 344 }
 345 
 346 /* Returns the number of zero bits in the least significant side of number */
 347 static inline HB_CONST_FUNC unsigned int
 348 _hb_ctz (unsigned int number)


 350 #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
 351   return likely (number) ? __builtin_ctz (number) : 0;
 352 #else
 353   unsigned int n_bits = 0;
 354   if (unlikely (!number)) return 0;
 355   while (!(number & 1)) {
 356     n_bits++;
 357     number >>= 1;
 358   }
 359   return n_bits;
 360 #endif
 361 }
 362 
 363 static inline bool
 364 _hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
 365 {
 366   return (size > 0) && (count >= ((unsigned int) -1) / size);
 367 }
 368 
 369 





 370 
 371 /* arrays and maps */
 372 
 373 
 374 #define HB_PREALLOCED_ARRAY_INIT {0, 0, nullptr}
 375 template <typename Type, unsigned int StaticSize=16>
 376 struct hb_prealloced_array_t
 377 {
 378   unsigned int len;
 379   unsigned int allocated;
 380   Type *array;
 381   Type static_array[StaticSize];
 382 
 383   void init (void)
 384   {
 385     len = 0;
 386     allocated = ARRAY_LENGTH (static_array);
 387     array = static_array;
 388   }
 389 
 390   inline Type& operator [] (unsigned int i) { return array[i]; }
 391   inline const Type& operator [] (unsigned int i) const { return array[i]; }
 392 
 393   inline Type *push (void)
 394   {
 395     if (unlikely (!resize (len + 1)))
 396       return nullptr;
 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;
 429     }
 430 
 431     len = size;
 432     return true;
 433   }
 434 
 435   inline void pop (void)
 436   {
 437     len--;
 438   }
 439 
 440   inline void remove (unsigned int i)
 441   {
 442      if (unlikely (i >= len))
 443        return;
 444      memmove (static_cast<void *> (&array[i]),
 445               static_cast<void *> (&array[i + 1]),
 446               (len - i - 1) * sizeof (Type));
 447      len--;
 448   }
 449 
 450   inline void shrink (unsigned int l)
 451   {
 452      if (l < len)
 453        len = l;
 454   }
 455 
 456   template <typename T>
 457   inline Type *find (T v) {
 458     for (unsigned int i = 0; i < len; i++)
 459       if (array[i] == v)
 460         return &array[i];
 461     return nullptr;
 462   }
 463   template <typename T>
 464   inline const Type *find (T v) const {
 465     for (unsigned int i = 0; i < len; i++)
 466       if (array[i] == v)
 467         return &array[i];
 468     return nullptr;
 469   }
 470 
 471   inline void qsort (void)
 472   {
 473     ::qsort (array, len, sizeof (Type), Type::cmp);
 474   }
 475 
 476   inline void qsort (unsigned int start, unsigned int end)
 477   {
 478     ::qsort (array + start, end - start, sizeof (Type), Type::cmp);
 479   }
 480 
 481   template <typename T>
 482   inline Type *bsearch (T *x)
 483   {
 484     unsigned int i;
 485     return bfind (x, &i) ? &array[i] : nullptr;
 486   }
 487   template <typename T>
 488   inline const Type *bsearch (T *x) const
 489   {
 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;
 515   }
 516 
 517   inline void finish (void)
 518   {
 519     if (array != static_array)
 520       free (array);
 521     array = nullptr;
 522     allocated = len = 0;
 523   }
 524 };
 525 
 526 template <typename Type>
 527 struct hb_auto_array_t : hb_prealloced_array_t <Type>
 528 {
 529   hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); }
 530   ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); }
 531 };
 532 
 533 
 534 #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT}
 535 template <typename item_t, typename lock_t>
 536 struct hb_lockable_set_t
 537 {
 538   hb_prealloced_array_t <item_t, 1> items;
 539 
 540   inline void init (void) { items.init (); }
 541 
 542   template <typename T>
 543   inline item_t *replace_or_insert (T v, lock_t &l, bool replace)
 544   {
 545     l.lock ();
 546     item_t *item = items.find (v);
 547     if (item) {
 548       if (replace) {
 549         item_t old = *item;
 550         *item = v;
 551         l.unlock ();
 552         old.finish ();
 553       }
 554       else {
 555         item = nullptr;
 556         l.unlock ();
 557       }
 558     } else {
 559       item = items.push ();
 560       if (likely (item))
 561         *item = v;
 562       l.unlock ();
 563     }
 564     return item;
 565   }
 566 
 567   template <typename T>
 568   inline void remove (T v, lock_t &l)
 569   {
 570     l.lock ();
 571     item_t *item = items.find (v);
 572     if (item) {
 573       item_t old = *item;
 574       *item = items[items.len - 1];
 575       items.pop ();


 623     items.finish ();
 624     l.unlock ();
 625   }
 626 
 627 };
 628 
 629 
 630 /* ASCII tag/character handling */
 631 
 632 static inline bool ISALPHA (unsigned char c)
 633 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
 634 static inline bool ISALNUM (unsigned char c)
 635 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
 636 static inline bool ISSPACE (unsigned char c)
 637 { return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
 638 static inline unsigned char TOUPPER (unsigned char c)
 639 { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
 640 static inline unsigned char TOLOWER (unsigned char c)
 641 { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
 642 
















 643 
 644 /* HB_NDEBUG disables some sanity checks that are very safe to disable and
 645  * should be disabled in production systems.  If NDEBUG is defined, enable
 646  * HB_NDEBUG; but if it's desirable that normal assert()s (which are very
 647  * light-weight) to be enabled, then HB_DEBUG can be defined to disable
 648  * the costlier checks. */
 649 #ifdef NDEBUG
 650 #define HB_NDEBUG
 651 #endif
 652 

























































































































































































































































 653 
 654 /* Misc */
 655 
 656 template <typename T> class hb_assert_unsigned_t;
 657 template <> class hb_assert_unsigned_t<unsigned char> {};
 658 template <> class hb_assert_unsigned_t<unsigned short> {};
 659 template <> class hb_assert_unsigned_t<unsigned int> {};
 660 template <> class hb_assert_unsigned_t<unsigned long> {};
 661 
 662 template <typename T> static inline bool
 663 hb_in_range (T u, T lo, T hi)
 664 {
 665   /* The sizeof() is here to force template instantiation.
 666    * I'm sure there are better ways to do this but can't think of
 667    * one right now.  Declaring a variable won't work as HB_UNUSED
 668    * is unusable on some platforms and unused types are less likely
 669    * to generate a warning than unused variables. */
 670   static_assert ((sizeof (hb_assert_unsigned_t<T>) >= 0), "");
 671 
 672   /* The casts below are important as if T is smaller than int,
 673    * the subtract results will become a signed int! */
 674   return (T)(u - lo) <= (T)(hi - lo);
 675 }
 676 
 677 template <typename T> static inline bool
 678 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2)
 679 {
 680   return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2);
 681 }
 682 
 683 template <typename T> static inline bool
 684 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
 685 {
 686   return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3);
 687 }
 688 
 689 
 690 /* Enable bitwise ops on enums marked as flags_t */


 695  * For MSVC warnings, see: https://github.com/behdad/harfbuzz/pull/163
 696  */
 697 #ifdef _MSC_VER
 698 # pragma warning(disable:4200)
 699 # pragma warning(disable:4800)
 700 #endif
 701 #define HB_MARK_AS_FLAG_T(T) \
 702         extern "C++" { \
 703           static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
 704           static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
 705           static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
 706           static inline T operator ~ (T r) { return T (~(unsigned int) r); } \
 707           static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
 708           static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
 709           static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
 710         }
 711 
 712 
 713 /* Useful for set-operations on small enums.
 714  * For example, for testing "x ∈ {x1, x2, x3}" use:
 715  * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
 716  */
 717 #define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned int)(x) < 32) + (1U << (unsigned int)(x)))
 718 #define FLAG_UNSAFE(x) ((unsigned int)(x) < 32 ? (1U << (unsigned int)(x)) : 0)

 719 #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
 720 
 721 
 722 template <typename T, typename T2> static inline void
 723 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
 724 {
 725   for (unsigned int i = 1; i < len; i++)
 726   {
 727     unsigned int j = i;
 728     while (j && compar (&array[j - 1], &array[i]) > 0)
 729       j--;
 730     if (i == j)
 731       continue;
 732     /* Move item i to occupy place for item j, shift what's in between. */
 733     {
 734       T t = array[i];
 735       memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
 736       array[j] = t;
 737     }
 738     if (array2)
 739     {
 740       T2 t = array2[i];
 741       memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2));
 742       array2[j] = t;
 743     }
 744   }
 745 }
 746 
 747 template <typename T> static inline void
 748 hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
 749 {
 750   hb_stable_sort (array, len, compar, (int *) nullptr);
 751 }
 752 
 753 static inline hb_bool_t
 754 hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
 755 {
 756   /* Pain because we don't know whether s is nul-terminated. */
 757   char buf[64];
 758   len = MIN (ARRAY_LENGTH (buf) - 1, len);
 759   strncpy (buf, s, len);
 760   buf[len] = '\0';
 761 
 762   char *end;
 763   errno = 0;
 764   unsigned long v = strtoul (buf, &end, base);
 765   if (errno) return false;
 766   if (*end) return false;
 767   *out = v;
 768   return true;
 769 }
 770 
 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 
 839 /* Global runtime options. */
 840 
 841 struct hb_options_t
 842 {
 843   unsigned int initialized : 1;
 844   unsigned int uniscribe_bug_compatible : 1;
 845 };
 846 
 847 union hb_options_union_t {
 848   unsigned int i;
 849   hb_options_t opts;
 850 };
 851 static_assert ((sizeof (int) == sizeof (hb_options_union_t)), "");
 852 
 853 HB_INTERNAL void
 854 _hb_options_init (void);
 855 
 856 extern HB_INTERNAL hb_options_union_t _hb_options;
 857 
 858 static inline hb_options_t
 859 hb_options (void)
 860 {
 861   if (unlikely (!_hb_options.i))
 862     _hb_options_init ();
 863 
 864   return _hb_options.opts;
 865 }
 866 
 867 /* Size signifying variable-sized array */
 868 #define VAR 1
 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 
 897 #endif /* HB_PRIVATE_HH */
< prev index next >