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

29 30
#ifndef HB_HH
#define HB_HH
B
Behdad Esfahbod 已提交
31

B
Behdad Esfahbod 已提交
32

B
Behdad Esfahbod 已提交
33
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC
B
Minor  
Behdad Esfahbod 已提交
34
#ifdef _MSC_VER
35 36
#pragma warning( disable: 4068 ) /* Unknown pragma */
#endif
37
#if defined(__GNUC__) || defined(__clang__)
B
Behdad Esfahbod 已提交
38
/* Rules:
B
Behdad Esfahbod 已提交
39 40 41 42
 *
 * - All pragmas are declared GCC even if they are clang ones.  Otherwise GCC
 *   nags, even though we instruct it to ignore -Wunknown-pragmas. ¯\_(ツ)_/¯
 *
B
Behdad Esfahbod 已提交
43
 * - Within each category, keep sorted.
B
Behdad Esfahbod 已提交
44
 *
B
Behdad Esfahbod 已提交
45 46
 * - Warnings whose scope can be expanded in future compiler versions shall
 *   be declared as "warning".  Otherwise, either ignored or error.
B
Behdad Esfahbod 已提交
47
 */
B
Behdad Esfahbod 已提交
48

B
Behdad Esfahbod 已提交
49
/* Setup.  Don't sort order within this category. */
B
Behdad Esfahbod 已提交
50
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
B
Behdad Esfahbod 已提交
51 52
#pragma GCC diagnostic warning "-Wall"
#pragma GCC diagnostic warning "-Wextra"
B
Behdad Esfahbod 已提交
53 54
#endif
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
B
Behdad Esfahbod 已提交
55 56 57
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#pragma GCC diagnostic ignored "-Wunknown-warning-option"
B
Behdad Esfahbod 已提交
58 59
#endif
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
B
Behdad Esfahbod 已提交
60
//#pragma GCC diagnostic warning "-Weverything"
B
Behdad Esfahbod 已提交
61
#endif
B
Behdad Esfahbod 已提交
62

B
Behdad Esfahbod 已提交
63
/* Error.  Should never happen. */
B
Behdad Esfahbod 已提交
64
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR
B
Behdad Esfahbod 已提交
65 66
#pragma GCC diagnostic error   "-Wc++11-narrowing"
#pragma GCC diagnostic error   "-Wcast-align"
67
#pragma GCC diagnostic error   "-Wcast-function-type"
68
#pragma GCC diagnostic error   "-Wdelete-non-virtual-dtor"
B
Behdad Esfahbod 已提交
69
#pragma GCC diagnostic error   "-Wdouble-promotion"
B
Behdad Esfahbod 已提交
70 71 72
#pragma GCC diagnostic error   "-Wformat-security"
#pragma GCC diagnostic error   "-Wimplicit-function-declaration"
#pragma GCC diagnostic error   "-Winit-self"
73
#pragma GCC diagnostic error   "-Winjected-class-name"
B
Behdad Esfahbod 已提交
74 75 76 77 78 79 80
#pragma GCC diagnostic error   "-Wmissing-braces"
#pragma GCC diagnostic error   "-Wmissing-declarations"
#pragma GCC diagnostic error   "-Wmissing-prototypes"
#pragma GCC diagnostic error   "-Wnested-externs"
#pragma GCC diagnostic error   "-Wold-style-definition"
#pragma GCC diagnostic error   "-Wpointer-arith"
#pragma GCC diagnostic error   "-Wredundant-decls"
81
#pragma GCC diagnostic error   "-Wreorder"
82
#pragma GCC diagnostic error   "-Wsign-compare"
B
Behdad Esfahbod 已提交
83 84 85 86 87 88 89 90 91
#pragma GCC diagnostic error   "-Wstrict-prototypes"
#pragma GCC diagnostic error   "-Wstring-conversion"
#pragma GCC diagnostic error   "-Wswitch-enum"
#pragma GCC diagnostic error   "-Wtautological-overlap-compare"
#pragma GCC diagnostic error   "-Wunneeded-internal-declaration"
#pragma GCC diagnostic error   "-Wunused"
#pragma GCC diagnostic error   "-Wunused-local-typedefs"
#pragma GCC diagnostic error   "-Wunused-value"
#pragma GCC diagnostic error   "-Wunused-variable"
92
#pragma GCC diagnostic error   "-Wvla"
B
Behdad Esfahbod 已提交
93
#pragma GCC diagnostic error   "-Wwrite-strings"
B
Behdad Esfahbod 已提交
94
#endif
B
Behdad Esfahbod 已提交
95

B
Behdad Esfahbod 已提交
96
/* Warning.  To be investigated if happens. */
B
Behdad Esfahbod 已提交
97
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_WARNING
B
Behdad Esfahbod 已提交
98
#pragma GCC diagnostic warning "-Wbuiltin-macro-redefined"
B
Behdad Esfahbod 已提交
99
#pragma GCC diagnostic warning "-Wdeprecated"
B
Behdad Esfahbod 已提交
100 101 102 103
#pragma GCC diagnostic warning "-Wdisabled-optimization"
#pragma GCC diagnostic warning "-Wformat=2"
#pragma GCC diagnostic warning "-Wignored-pragma-optimize"
#pragma GCC diagnostic warning "-Wlogical-op"
104
#pragma GCC diagnostic warning "-Wmaybe-uninitialized"
B
Behdad Esfahbod 已提交
105 106
#pragma GCC diagnostic warning "-Wmissing-format-attribute"
#pragma GCC diagnostic warning "-Wundef"
B
Behdad Esfahbod 已提交
107
#endif
B
Behdad Esfahbod 已提交
108

B
Behdad Esfahbod 已提交
109
/* Ignored currently, but should be fixed at some point. */
B
Behdad Esfahbod 已提交
110
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
B
Behdad Esfahbod 已提交
111 112 113 114 115
#pragma GCC diagnostic ignored "-Wconversion"			// TODO fix
#pragma GCC diagnostic ignored "-Wformat-signedness"		// TODO fix
#pragma GCC diagnostic ignored "-Wshadow"			// TODO fix
#pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations"	// TODO fix
#pragma GCC diagnostic ignored "-Wunused-parameter"		// TODO fix
B
Behdad Esfahbod 已提交
116
#endif
B
Behdad Esfahbod 已提交
117

B
Behdad Esfahbod 已提交
118
/* Ignored intentionally. */
B
Behdad Esfahbod 已提交
119
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_IGNORED
B
Behdad Esfahbod 已提交
120 121 122 123 124 125 126
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#pragma GCC diagnostic ignored "-Wformat-zero-length"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#pragma GCC diagnostic ignored "-Wpacked" // Erratic impl in clang
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#pragma GCC diagnostic ignored "-Wtype-limits"
127
#pragma GCC diagnostic ignored "-Wc++11-compat" // only gcc raises it
B
Behdad Esfahbod 已提交
128
#endif
129 130

#endif
B
Behdad Esfahbod 已提交
131 132
#endif

B
Behdad Esfahbod 已提交
133 134 135

#include "hb-config.hh"

B
Behdad Esfahbod 已提交
136

137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
/*
 * Following added based on what AC_USE_SYSTEM_EXTENSIONS adds to
 * config.h.in.  Copied here for the convenience of those embedding
 * HarfBuzz and not using our build system.
 */
/* Enable extensions on AIX 3, Interix.  */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them.  */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris.  */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop.  */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris.  */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif

163 164 165 166
#if defined (_MSC_VER) && defined (HB_DLL_EXPORT)
#define HB_EXTERN __declspec (dllexport) extern
#endif

167 168
#include "hb.h"
#define HB_H_IN
B
Minor  
Behdad Esfahbod 已提交
169
#include "hb-ot.h"
170
#define HB_OT_H_IN
171 172
#include "hb-aat.h"
#define HB_AAT_H_IN
173

B
Behdad Esfahbod 已提交
174
#include <limits.h>
175
#include <math.h>
B
Behdad Esfahbod 已提交
176
#include <stdlib.h>
177
#include <stddef.h>
B
Behdad Esfahbod 已提交
178 179
#include <string.h>
#include <assert.h>
180
#include <errno.h>
181
#include <stdio.h>
182
#include <stdarg.h>
B
Behdad Esfahbod 已提交
183

184
#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
185 186
#include <intrin.h>
#endif
B
Behdad Esfahbod 已提交
187

B
Behdad Esfahbod 已提交
188 189 190
#define HB_PASTE1(a,b) a##b
#define HB_PASTE(a,b) HB_PASTE1(a,b)

B
Behdad Esfahbod 已提交
191

192 193 194 195 196 197
/* Compile-time custom allocator support. */

#if defined(hb_malloc_impl) \
 && defined(hb_calloc_impl) \
 && defined(hb_realloc_impl) \
 && defined(hb_free_impl)
198 199 200 201
extern "C" void* hb_malloc_impl(size_t size);
extern "C" void* hb_calloc_impl(size_t nmemb, size_t size);
extern "C" void* hb_realloc_impl(void *ptr, size_t size);
extern "C" void  hb_free_impl(void *ptr);
202 203 204 205
#define malloc hb_malloc_impl
#define calloc hb_calloc_impl
#define realloc hb_realloc_impl
#define free hb_free_impl
B
Behdad Esfahbod 已提交
206

B
Minor  
Behdad Esfahbod 已提交
207
#ifdef hb_memalign_impl
B
Behdad Esfahbod 已提交
208 209 210 211 212 213
extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
#define posix_memalign hb_memalign_impl
#else
#undef HAVE_POSIX_MEMALIGN
#endif

214 215 216
#endif


B
Behdad Esfahbod 已提交
217 218
/*
 * Compiler attributes
B
Minor  
Behdad Esfahbod 已提交
219
 */
220

221 222 223
#if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
#define likely(expr) (__builtin_expect (!!(expr), 1))
#define unlikely(expr) (__builtin_expect (!!(expr), 0))
B
Behdad Esfahbod 已提交
224 225 226
#else
#define likely(expr) (expr)
#define unlikely(expr) (expr)
B
Behdad Esfahbod 已提交
227 228
#endif

229
#if !defined(__GNUC__) && !defined(__clang__)
B
Behdad Esfahbod 已提交
230 231 232 233
#undef __attribute__
#define __attribute__(x)
#endif

234
#if defined(__GNUC__) && (__GNUC__ >= 3)
B
Behdad Esfahbod 已提交
235 236 237 238 239 240 241 242
#define HB_PURE_FUNC	__attribute__((pure))
#define HB_CONST_FUNC	__attribute__((const))
#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx)))
#else
#define HB_PURE_FUNC
#define HB_CONST_FUNC
#define HB_PRINTF_FUNC(format_idx, arg_idx)
#endif
243
#if defined(__GNUC__) && (__GNUC__ >= 4)
B
Behdad Esfahbod 已提交
244
#define HB_UNUSED	__attribute__((unused))
245 246
#elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
#define HB_UNUSED __pragma(warning(suppress: 4100 4101))
B
Behdad Esfahbod 已提交
247 248 249 250 251
#else
#define HB_UNUSED
#endif

#ifndef HB_INTERNAL
B
Behdad Esfahbod 已提交
252
# if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC)
B
Behdad Esfahbod 已提交
253
#  define HB_INTERNAL __attribute__((__visibility__("hidden")))
B
Behdad Esfahbod 已提交
254
# elif defined(__MINGW32__)
255 256 257 258
   /* We use -export-symbols on mingw32, since it does not support visibility attributes. */
#  define HB_INTERNAL
# elif defined (_MSC_VER) && defined (HB_DLL_EXPORT)
   /* We do not try to export internal symbols on Visual Studio */
B
Behdad Esfahbod 已提交
259 260
#  define HB_INTERNAL
#else
B
Behdad Esfahbod 已提交
261
#  define HB_INTERNAL
262
#  define HB_NO_VISIBILITY 1
B
Behdad Esfahbod 已提交
263 264 265
# endif
#endif

B
Behdad Esfahbod 已提交
266 267 268 269 270 271 272
/* https://github.com/harfbuzz/harfbuzz/issues/1651 */
#if defined(__clang__) && __clang_major__ < 10
#define static_const static
#else
#define static_const static const
#endif

273
#if defined(__GNUC__) && (__GNUC__ >= 3)
B
Behdad Esfahbod 已提交
274 275 276 277 278 279
#define HB_FUNC __PRETTY_FUNCTION__
#elif defined(_MSC_VER)
#define HB_FUNC __FUNCSIG__
#else
#define HB_FUNC __func__
#endif
B
Behdad Esfahbod 已提交
280

P
prrace 已提交
281
#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140)
282 283 284 285
/* https://github.com/harfbuzz/harfbuzz/issues/630 */
#define __restrict
#endif

B
Behdad Esfahbod 已提交
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
/*
 * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
 * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
 * cases that fall through without a break or return statement. HB_FALLTHROUGH
 * is only needed on cases that have code:
 *
 * switch (foo) {
 *   case 1: // These cases have no code. No fallthrough annotations are needed.
 *   case 2:
 *   case 3:
 *     foo = 4; // This case has code, so a fallthrough annotation is needed:
 *     HB_FALLTHROUGH;
 *   default:
 *     return foo;
 * }
 */
#if defined(__clang__) && __cplusplus >= 201103L
   /* clang's fallthrough annotations are only available starting in C++11. */
#  define HB_FALLTHROUGH [[clang::fallthrough]]
305
#elif defined(__GNUC__) && (__GNUC__ >= 7)
306 307
   /* GNU fallthrough attribute is available from GCC7 */
#  define HB_FALLTHROUGH __attribute__((fallthrough))
B
Behdad Esfahbod 已提交
308 309 310 311 312 313 314 315 316 317 318
#elif defined(_MSC_VER)
   /*
    * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
    * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
    */
#  include <sal.h>
#  define HB_FALLTHROUGH __fallthrough
#else
#  define HB_FALLTHROUGH /* FALLTHROUGH */
#endif

B
Minor  
Behdad Esfahbod 已提交
319
#ifdef __clang__
320 321 322 323 324 325 326 327
/* Disable certain sanitizer errors. */
/* https://github.com/harfbuzz/harfbuzz/issues/1247 */
#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
#else
#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
#endif


K
Ken Brown 已提交
328
#ifdef _WIN32
329 330 331 332 333 334 335
   /* We need Windows Vista for both Uniscribe backend and for
    * MemoryBarrier.  We don't support compiling on Windows XP,
    * though we run on it fine. */
#  if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
#    undef _WIN32_WINNT
#  endif
#  ifndef _WIN32_WINNT
336 337 338
#    if !defined(WINAPI_FAMILY) || !(WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
#      define _WIN32_WINNT 0x0600
#    endif
339
#  endif
340 341 342 343 344 345
#  ifndef WIN32_LEAN_AND_MEAN
#    define WIN32_LEAN_AND_MEAN 1
#  endif
#  ifndef STRICT
#    define STRICT 1
#  endif
B
Minor  
Behdad Esfahbod 已提交
346

K
Konstantin Ritt 已提交
347 348
#  if defined(_WIN32_WCE)
     /* Some things not defined on Windows CE. */
K
Konstantin Ritt 已提交
349
#    define vsnprintf _vsnprintf
350 351 352
#    ifndef HB_NO_GETENV
#      define HB_NO_GETENV
#    endif
K
Konstantin Ritt 已提交
353 354
#    if _WIN32_WCE < 0x800
#      define setlocale(Category, Locale) "C"
355
static int errno = 0; /* Use something better? */
K
Konstantin Ritt 已提交
356
#    endif
K
Konstantin Ritt 已提交
357
#  elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
358 359 360
#    ifndef HB_NO_GETENV
#      define HB_NO_GETENV
#    endif
K
Konstantin Ritt 已提交
361
#  endif
362
#  if defined(_MSC_VER) && _MSC_VER < 1900
K
Konstantin Ritt 已提交
363 364
#    define snprintf _snprintf
#  endif
365 366
#endif

367 368 369 370
#ifdef HB_NO_GETENV
#define getenv(Name) nullptr
#endif

371
#if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT)
372 373 374 375 376 377 378 379 380 381
/* atexit() is only safe to be called from shared libraries on certain
 * platforms.  Whitelist.
 * https://bugs.freedesktop.org/show_bug.cgi?id=82246 */
#  if defined(__linux) && defined(__GLIBC_PREREQ)
#    if __GLIBC_PREREQ(2,3)
/* From atexit() manpage, it's safe with glibc 2.2.3 on Linux. */
#      define HB_USE_ATEXIT 1
#    endif
#  elif defined(_MSC_VER) || defined(__MINGW32__)
/* For MSVC:
382 383
 * https://msdn.microsoft.com/en-us/library/tze57ck3.aspx
 * https://msdn.microsoft.com/en-us/library/zk17ww08.aspx
384 385 386
 * mingw32 headers say atexit is safe to use in shared libraries.
 */
#    define HB_USE_ATEXIT 1
387 388 389
#  elif defined(__ANDROID__)
/* This is available since Android NKD r8 or r8b:
 * https://issuetracker.google.com/code/p/android/issues/detail?id=6455
390 391
 */
#    define HB_USE_ATEXIT 1
392 393 394 395 396 397
#  elif defined(__APPLE__)
/* For macOS and related platforms, the atexit man page indicates
 * that it will be invoked when the library is unloaded, not only
 * at application exit.
 */
#    define HB_USE_ATEXIT 1
398 399
#  endif
#endif
B
Behdad Esfahbod 已提交
400 401 402
#ifdef HB_NO_ATEXIT
#  undef HB_USE_ATEXIT
#endif
403 404 405
#ifndef HB_USE_ATEXIT
#  define HB_USE_ATEXIT 0
#endif
B
Minor  
Behdad Esfahbod 已提交
406

407 408
#define HB_STMT_START do
#define HB_STMT_END   while (0)
B
Behdad Esfahbod 已提交
409

B
Minor  
Behdad Esfahbod 已提交
410
/* Static-assert as expression. */
411 412
template <unsigned int cond> class hb_assert_constant_t;
template <> class hb_assert_constant_t<1> {};
413
#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>))
B
Behdad Esfahbod 已提交
414

B
Behdad Esfahbod 已提交
415
/* Lets assert int types.  Saves trouble down the road. */
416 417 418 419 420 421 422 423 424 425 426 427
static_assert ((sizeof (int8_t) == 1), "");
static_assert ((sizeof (uint8_t) == 1), "");
static_assert ((sizeof (int16_t) == 2), "");
static_assert ((sizeof (uint16_t) == 2), "");
static_assert ((sizeof (int32_t) == 4), "");
static_assert ((sizeof (uint32_t) == 4), "");
static_assert ((sizeof (int64_t) == 8), "");
static_assert ((sizeof (uint64_t) == 8), "");
static_assert ((sizeof (hb_codepoint_t) == 4), "");
static_assert ((sizeof (hb_position_t) == 4), "");
static_assert ((sizeof (hb_mask_t) == 4), "");
static_assert ((sizeof (hb_var_int_t) == 4), "");
B
Behdad Esfahbod 已提交
428

B
Behdad Esfahbod 已提交
429
#define HB_DELETE_COPY_ASSIGN(TypeName) \
B
Behdad Esfahbod 已提交
430 431
  TypeName(const TypeName&) = delete; \
  void operator=(const TypeName&) = delete
B
Behdad Esfahbod 已提交
432
#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \
B
Behdad Esfahbod 已提交
433 434 435
  TypeName() = delete; \
  TypeName(const TypeName&) = delete; \
  void operator=(const TypeName&) = delete
B
Behdad Esfahbod 已提交
436

437 438 439 440 441 442 443 444 445 446 447 448

/*
 * Compiler-assisted vectorization parameters.
 */

/*
 * Disable vectorization for now.  To correctly use them, we should
 * use posix_memalign() to allocate in hb_vector_t.  Otherwise, can
 * cause misaligned access.
 *
 * https://bugs.chromium.org/p/chromium/issues/detail?id=860184
 */
B
Minor  
Behdad Esfahbod 已提交
449
#ifndef HB_VECTOR_SIZE
450 451 452 453
#  define HB_VECTOR_SIZE 0
#endif

/* The `vector_size' attribute was introduced in gcc 3.1. */
B
Minor  
Behdad Esfahbod 已提交
454
#ifndef HB_VECTOR_SIZE
455 456 457 458 459 460
#  if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
#    define HB_VECTOR_SIZE 128
#  else
#    define HB_VECTOR_SIZE 0
#  endif
#endif
461 462
static_assert (0 == (HB_VECTOR_SIZE & (HB_VECTOR_SIZE - 1)), "HB_VECTOR_SIZE is not power of 2.");
static_assert (0 == (HB_VECTOR_SIZE % 64), "HB_VECTOR_SIZE is not multiple of 64.");
463 464 465 466 467 468 469
#if HB_VECTOR_SIZE
typedef uint64_t hb_vector_size_impl_t __attribute__((vector_size (HB_VECTOR_SIZE / 8)));
#else
typedef uint64_t hb_vector_size_impl_t;
#endif


B
Behdad Esfahbod 已提交
470 471 472 473 474 475
/* HB_NDEBUG disables some sanity checks that are very safe to disable and
 * should be disabled in production systems.  If NDEBUG is defined, enable
 * HB_NDEBUG; but if it's desirable that normal assert()s (which are very
 * light-weight) to be enabled, then HB_DEBUG can be defined to disable
 * the costlier checks. */
#ifdef NDEBUG
B
Minor  
Behdad Esfahbod 已提交
476
#define HB_NDEBUG 1
B
Behdad Esfahbod 已提交
477 478
#endif

479

B
Behdad Esfahbod 已提交
480
/* Flags */
B
Minor  
Behdad Esfahbod 已提交
481

B
Behdad Esfahbod 已提交
482
/* Enable bitwise ops on enums marked as flags_t */
483 484
/* To my surprise, looks like the function resolver is happy to silently cast
 * one enum to another...  So this doesn't provide the type-checking that I
B
Behdad Esfahbod 已提交
485 486
 * originally had in mind... :(.
 *
487
 * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163
B
Behdad Esfahbod 已提交
488 489 490 491
 */
#ifdef _MSC_VER
# pragma warning(disable:4200)
# pragma warning(disable:4800)
C
Chun-wei Fan 已提交
492
#endif
B
Behdad Esfahbod 已提交
493 494 495 496 497 498 499 500 501
#define HB_MARK_AS_FLAG_T(T) \
	extern "C++" { \
	  static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
	  static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
	  static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
	  static inline T operator ~ (T r) { return T (~(unsigned int) r); } \
	  static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
	  static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
	  static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
B
Behdad Esfahbod 已提交
502 503
	} \
	static_assert (true, "")
B
Behdad Esfahbod 已提交
504

B
Behdad Esfahbod 已提交
505 506
/* Useful for set-operations on small enums.
 * For example, for testing "x ∈ {x1, x2, x3}" use:
B
Behdad Esfahbod 已提交
507
 * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
B
Behdad Esfahbod 已提交
508
 */
B
Minor  
Behdad Esfahbod 已提交
509 510
#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x)))
#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0)
511
#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
B
Minor  
Behdad Esfahbod 已提交
512 513
#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x)))
#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0)
B
Minor  
Behdad Esfahbod 已提交
514

B
Minor  
Behdad Esfahbod 已提交
515

S
Steven R. Loomis 已提交
516 517
/* Size signifying variable-sized array */
#define VAR 1
518

B
Behdad Esfahbod 已提交
519

520 521
/* fallback for round() */
static inline double
522
_hb_round (double x)
523 524 525 526 527 528
{
  if (x >= 0)
    return floor (x + 0.5);
  else
    return ceil (x - 0.5);
}
529
#if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND)
530
#define round(x) _hb_round(x)
531 532 533
#endif


B
Behdad Esfahbod 已提交
534 535 536 537
/* fallback for posix_memalign() */
static inline int
_hb_memalign(void **memptr, size_t alignment, size_t size)
{
538
  if (unlikely (0 != (alignment & (alignment - 1)) ||
B
Behdad Esfahbod 已提交
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
		!alignment ||
		0 != (alignment & (sizeof (void *) - 1))))
    return EINVAL;

  char *p = (char *) malloc (size + alignment - 1);
  if (unlikely (!p))
    return ENOMEM;

  size_t off = (size_t) p & (alignment - 1);
  if (off)
    p += alignment - off;

  *memptr = (void *) p;

  return 0;
}
#if !defined(posix_memalign) && !defined(HAVE_POSIX_MEMALIGN)
#define posix_memalign _hb_memalign
#endif


B
Behdad Esfahbod 已提交
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
/*
 * Big-endian integers.  Here because fundamental.
 */

template <typename Type, int Bytes> struct BEInt;

template <typename Type>
struct BEInt<Type, 1>
{
  public:
  BEInt<Type, 1>& operator = (Type V)
  {
    v = V;
    return *this;
  }
  operator Type () const { return v; }
  private: uint8_t v;
};
template <typename Type>
struct BEInt<Type, 2>
{
  public:
  BEInt<Type, 2>& operator = (Type V)
  {
    v[0] = (V >>  8) & 0xFF;
    v[1] = (V      ) & 0xFF;
    return *this;
  }
  operator Type () const
  {
#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \
    defined(__BYTE_ORDER) && \
    (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN)
    /* Spoon-feed the compiler a big-endian integer with alignment 1.
     * https://github.com/harfbuzz/harfbuzz/pull/1398 */
    struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
#if __BYTE_ORDER == __LITTLE_ENDIAN
    return __builtin_bswap16 (((packed_uint16_t *) this)->v);
#else /* __BYTE_ORDER == __BIG_ENDIAN */
    return ((packed_uint16_t *) this)->v;
#endif
#endif
    return (v[0] <<  8)
         + (v[1]      );
  }
  private: uint8_t v[2];
};
template <typename Type>
struct BEInt<Type, 3>
{
  public:
  BEInt<Type, 3>& operator = (Type V)
  {
    v[0] = (V >> 16) & 0xFF;
    v[1] = (V >>  8) & 0xFF;
    v[2] = (V      ) & 0xFF;
    return *this;
  }
  operator Type () const
  {
    return (v[0] << 16)
         + (v[1] <<  8)
         + (v[2]      );
  }
  private: uint8_t v[3];
};
template <typename Type>
struct BEInt<Type, 4>
{
  public:
  BEInt<Type, 4>& operator = (Type V)
  {
    v[0] = (V >> 24) & 0xFF;
    v[1] = (V >> 16) & 0xFF;
    v[2] = (V >>  8) & 0xFF;
    v[3] = (V      ) & 0xFF;
    return *this;
  }
  operator Type () const
  {
    return (v[0] << 24)
         + (v[1] << 16)
         + (v[2] <<  8)
         + (v[3]      );
  }
  private: uint8_t v[4];
};


649 650 651 652 653 654 655 656
/*
 * For lack of a better place, put Zawgyi script hack here.
 * https://github.com/harfbuzz/harfbuzz/issues/1162
 */

#define HB_SCRIPT_MYANMAR_ZAWGYI	((hb_script_t) HB_TAG ('Q','a','a','g'))


657 658 659
/* Headers we include for everyone.  Keep topologically sorted by dependency.
 * They express dependency amongst themselves, but no other file should include
 * them directly.*/
660
#include "hb-meta.hh"
661
#include "hb-mutex.hh"
B
Behdad Esfahbod 已提交
662
#include "hb-atomic.hh"	// Requires: hb-meta
B
Behdad Esfahbod 已提交
663
#include "hb-null.hh"	// Requires: hb-meta
B
Behdad Esfahbod 已提交
664
#include "hb-algs.hh"	// Requires: hb-meta hb-null
665
#include "hb-iter.hh"	// Requires: hb-algs hb-meta
B
Behdad Esfahbod 已提交
666 667
#include "hb-debug.hh"	// Requires: hb-algs hb-atomic
#include "hb-array.hh"	// Requires: hb-algs hb-iter hb-null
668 669
#include "hb-vector.hh"	// Requires: hb-array hb-null
#include "hb-object.hh"	// Requires: hb-atomic hb-mutex hb-vector
B
Behdad Esfahbod 已提交
670

671
#endif /* HB_HH */