OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2007,2008,2009 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009 Red Hat, Inc. |
3 * Copyright © 2011,2012 Google, Inc. | 3 * Copyright © 2011,2012 Google, Inc. |
4 * | 4 * |
5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
6 * | 6 * |
7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 | 47 |
48 /* We only use these two for debug output. However, the debug code is | 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. | 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 | 50 * If including these becomes a problem, we can start thinking about |
51 * someway around that. */ | 51 * someway around that. */ |
52 #include <stdio.h> | 52 #include <stdio.h> |
53 #include <errno.h> | 53 #include <errno.h> |
54 #include <stdarg.h> | 54 #include <stdarg.h> |
55 | 55 |
56 | 56 |
| 57 /* Compiler attributes */ |
57 | 58 |
58 /* Essentials */ | 59 |
| 60 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) |
| 61 #define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) |
| 62 #define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) |
| 63 #define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) |
| 64 #else |
| 65 #define likely(expr) (expr) |
| 66 #define unlikely(expr) (expr) |
| 67 #endif |
| 68 |
| 69 #ifndef __GNUC__ |
| 70 #undef __attribute__ |
| 71 #define __attribute__(x) |
| 72 #endif |
| 73 |
| 74 #if __GNUC__ >= 3 |
| 75 #define HB_PURE_FUNC» __attribute__((pure)) |
| 76 #define HB_CONST_FUNC» __attribute__((const)) |
| 77 #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf_
_, format_idx, arg_idx))) |
| 78 #else |
| 79 #define HB_PURE_FUNC |
| 80 #define HB_CONST_FUNC |
| 81 #define HB_PRINTF_FUNC(format_idx, arg_idx) |
| 82 #endif |
| 83 #if __GNUC__ >= 4 |
| 84 #define HB_UNUSED» __attribute__((unused)) |
| 85 #else |
| 86 #define HB_UNUSED |
| 87 #endif |
| 88 |
| 89 #ifndef HB_INTERNAL |
| 90 # ifndef __MINGW32__ |
| 91 # define HB_INTERNAL __attribute__((__visibility__("hidden"))) |
| 92 # else |
| 93 # define HB_INTERNAL |
| 94 # endif |
| 95 #endif |
| 96 |
| 97 #if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) |
| 98 #define snprintf _snprintf |
| 99 #endif |
| 100 |
| 101 #ifdef _MSC_VER |
| 102 #undef inline |
| 103 #define inline __inline |
| 104 #endif |
| 105 |
| 106 #ifdef __STRICT_ANSI__ |
| 107 #undef inline |
| 108 #define inline __inline__ |
| 109 #endif |
| 110 |
| 111 #if __GNUC__ >= 3 |
| 112 #define HB_FUNC __PRETTY_FUNCTION__ |
| 113 #elif defined(_MSC_VER) |
| 114 #define HB_FUNC __FUNCSIG__ |
| 115 #else |
| 116 #define HB_FUNC __func__ |
| 117 #endif |
| 118 |
| 119 |
| 120 |
| 121 /* Basics */ |
| 122 |
59 | 123 |
60 #ifndef NULL | 124 #ifndef NULL |
61 # define NULL ((void *) 0) | 125 # define NULL ((void *) 0) |
62 #endif | 126 #endif |
63 | 127 |
64 | |
65 /* Void! */ | |
66 struct _hb_void_t {}; | |
67 typedef const _hb_void_t &hb_void_t; | |
68 #define HB_VOID (* (const _hb_void_t *) NULL) | |
69 | |
70 | |
71 /* Basics */ | |
72 | |
73 | |
74 #undef MIN | 128 #undef MIN |
75 template <typename Type> | 129 template <typename Type> |
76 static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } | 130 static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } |
77 | 131 |
78 #undef MAX | 132 #undef MAX |
79 template <typename Type> | 133 template <typename Type> |
80 static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; } | 134 static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; } |
81 | 135 |
82 static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b) | 136 static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b) |
83 { return (a + (b - 1)) / b; } | 137 { return (a + (b - 1)) / b; } |
84 | 138 |
85 | 139 |
86 #undef ARRAY_LENGTH | 140 #undef ARRAY_LENGTH |
87 template <typename Type, unsigned int n> | 141 template <typename Type, unsigned int n> |
88 static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } | 142 static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } |
89 /* A const version, but does not detect erratically being called on pointers. */ | 143 /* A const version, but does not detect erratically being called on pointers. */ |
90 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__
array[0]))) | 144 #define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__
array[0]))) |
91 | 145 |
92 #define HB_STMT_START do | 146 #define HB_STMT_START do |
93 #define HB_STMT_END while (0) | 147 #define HB_STMT_END while (0) |
94 | 148 |
95 #define _ASSERT_STATIC1(_line, _cond)» typedef int _static_assert_on_line_##_li
ne##_failed[(_cond)?1:-1] | 149 #define _ASSERT_STATIC1(_line, _cond)» HB_UNUSED typedef int _static_assert_on_
line_##_line##_failed[(_cond)?1:-1] |
96 #define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) | 150 #define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) |
97 #define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) | 151 #define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) |
98 | 152 |
99 #define ASSERT_STATIC_EXPR(_cond)((void) sizeof (char[(_cond) ? 1 : -1])) | 153 #define ASSERT_STATIC_EXPR(_cond)((void) sizeof (char[(_cond) ? 1 : -1])) |
100 #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1])) | 154 #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1])) |
101 | 155 |
102 #define _PASTE1(a,b) a##b | 156 #define _PASTE1(a,b) a##b |
103 #define PASTE(a,b) _PASTE1(a,b) | 157 #define PASTE(a,b) _PASTE1(a,b) |
104 | 158 |
105 /* Lets assert int types. Saves trouble down the road. */ | 159 /* Lets assert int types. Saves trouble down the road. */ |
(...skipping 26 matching lines...) Expand all Loading... |
132 _ASSERT_TYPE_POD1 (_line, _type_##_line); \ | 186 _ASSERT_TYPE_POD1 (_line, _type_##_line); \ |
133 } HB_STMT_END | 187 } HB_STMT_END |
134 #else | 188 #else |
135 # define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_o
n_line_##_line##_not_tested | 189 # define _ASSERT_INSTANCE_POD1(_line, _instance) typedef int _assertion_o
n_line_##_line##_not_tested |
136 #endif | 190 #endif |
137 # define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_
line, _instance) | 191 # define _ASSERT_INSTANCE_POD0(_line, _instance) _ASSERT_INSTANCE_POD1 (_
line, _instance) |
138 # define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (_
_LINE__, _instance) | 192 # define ASSERT_INSTANCE_POD(_instance) _ASSERT_INSTANCE_POD0 (_
_LINE__, _instance) |
139 | 193 |
140 /* Check _assertion in a method environment */ | 194 /* Check _assertion in a method environment */ |
141 #define _ASSERT_POD1(_line) \ | 195 #define _ASSERT_POD1(_line) \ |
142 » inline void _static_assertion_on_line_##_line (void) const \ | 196 » HB_UNUSED inline void _static_assertion_on_line_##_line (void) const \ |
143 { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ } | 197 { _ASSERT_INSTANCE_POD1 (_line, *this); /* Make sure it's POD. */ } |
144 # define _ASSERT_POD0(_line) _ASSERT_POD1 (_line) | 198 # define _ASSERT_POD0(_line) _ASSERT_POD1 (_line) |
145 # define ASSERT_POD() _ASSERT_POD0 (__LINE__) | 199 # define ASSERT_POD() _ASSERT_POD0 (__LINE__) |
146 | 200 |
147 | 201 |
148 | 202 |
149 /* Misc */ | 203 /* Misc */ |
150 | 204 |
151 | 205 /* Void! */ |
152 #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) | 206 struct _hb_void_t {}; |
153 #define _HB_BOOLEAN_EXPR(expr) ((expr) ? 1 : 0) | 207 typedef const _hb_void_t &hb_void_t; |
154 #define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1)) | 208 #define HB_VOID (* (const _hb_void_t *) NULL) |
155 #define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0)) | |
156 #else | |
157 #define likely(expr) (expr) | |
158 #define unlikely(expr) (expr) | |
159 #endif | |
160 | |
161 #ifndef __GNUC__ | |
162 #undef __attribute__ | |
163 #define __attribute__(x) | |
164 #endif | |
165 | |
166 #if __GNUC__ >= 3 | |
167 #define HB_PURE_FUNC» __attribute__((pure)) | |
168 #define HB_CONST_FUNC» __attribute__((const)) | |
169 #define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf_
_, format_idx, arg_idx))) | |
170 #else | |
171 #define HB_PURE_FUNC | |
172 #define HB_CONST_FUNC | |
173 #define HB_PRINTF_FUNC(format_idx, arg_idx) | |
174 #endif | |
175 #if __GNUC__ >= 4 | |
176 #define HB_UNUSED» __attribute__((unused)) | |
177 #else | |
178 #define HB_UNUSED | |
179 #endif | |
180 | |
181 #ifndef HB_INTERNAL | |
182 # ifndef __MINGW32__ | |
183 # define HB_INTERNAL __attribute__((__visibility__("hidden"))) | |
184 # else | |
185 # define HB_INTERNAL | |
186 # endif | |
187 #endif | |
188 | |
189 | |
190 #if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) | |
191 #define snprintf _snprintf | |
192 #endif | |
193 | |
194 #ifdef _MSC_VER | |
195 #undef inline | |
196 #define inline __inline | |
197 #endif | |
198 | |
199 #ifdef __STRICT_ANSI__ | |
200 #undef inline | |
201 #define inline __inline__ | |
202 #endif | |
203 | |
204 | |
205 #if __GNUC__ >= 3 | |
206 #define HB_FUNC __PRETTY_FUNCTION__ | |
207 #elif defined(_MSC_VER) | |
208 #define HB_FUNC __FUNCSIG__ | |
209 #else | |
210 #define HB_FUNC __func__ | |
211 #endif | |
212 | |
213 | 209 |
214 /* Return the number of 1 bits in mask. */ | 210 /* Return the number of 1 bits in mask. */ |
215 static inline HB_CONST_FUNC unsigned int | 211 static inline HB_CONST_FUNC unsigned int |
216 _hb_popcount32 (uint32_t mask) | 212 _hb_popcount32 (uint32_t mask) |
217 { | 213 { |
218 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) | 214 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) |
219 return __builtin_popcount (mask); | 215 return __builtin_popcount (mask); |
220 #else | 216 #else |
221 /* "HACKMEM 169" */ | 217 /* "HACKMEM 169" */ |
222 uint32_t y; | 218 uint32_t y; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 /* Type of bsearch() / qsort() compare function */ | 265 /* Type of bsearch() / qsort() compare function */ |
270 typedef int (*hb_compare_func_t) (const void *, const void *); | 266 typedef int (*hb_compare_func_t) (const void *, const void *); |
271 | 267 |
272 | 268 |
273 | 269 |
274 | 270 |
275 /* arrays and maps */ | 271 /* arrays and maps */ |
276 | 272 |
277 | 273 |
278 #define HB_PREALLOCED_ARRAY_INIT {0} | 274 #define HB_PREALLOCED_ARRAY_INIT {0} |
279 template <typename Type, unsigned int StaticSize> | 275 template <typename Type, unsigned int StaticSize=16> |
280 struct hb_prealloced_array_t | 276 struct hb_prealloced_array_t |
281 { | 277 { |
282 unsigned int len; | 278 unsigned int len; |
283 unsigned int allocated; | 279 unsigned int allocated; |
284 Type *array; | 280 Type *array; |
285 Type static_array[StaticSize]; | 281 Type static_array[StaticSize]; |
286 | 282 |
287 void init (void) { memset (this, 0, sizeof (*this)); } | 283 void init (void) { memset (this, 0, sizeof (*this)); } |
288 | 284 |
289 inline Type& operator [] (unsigned int i) { return array[i]; } | 285 inline Type& operator [] (unsigned int i) { return array[i]; } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 return NULL; | 346 return NULL; |
351 } | 347 } |
352 template <typename T> | 348 template <typename T> |
353 inline const Type *find (T v) const { | 349 inline const Type *find (T v) const { |
354 for (unsigned int i = 0; i < len; i++) | 350 for (unsigned int i = 0; i < len; i++) |
355 if (array[i] == v) | 351 if (array[i] == v) |
356 return &array[i]; | 352 return &array[i]; |
357 return NULL; | 353 return NULL; |
358 } | 354 } |
359 | 355 |
360 inline void sort (void) | 356 inline void qsort (void) |
361 { | 357 { |
362 qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); | 358 ::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp); |
363 } | 359 } |
364 | 360 |
365 inline void sort (unsigned int start, unsigned int end) | 361 inline void qsort (unsigned int start, unsigned int end) |
366 { | 362 { |
367 qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::
cmp); | 363 ::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type
::cmp); |
368 } | 364 } |
369 | 365 |
370 template <typename T> | 366 template <typename T> |
371 inline Type *bsearch (T *key) | 367 inline Type *bsearch (T *key) |
372 { | 368 { |
373 return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_
t) Type::cmp); | 369 return (Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare_func_
t) Type::cmp); |
374 } | 370 } |
375 template <typename T> | 371 template <typename T> |
376 inline const Type *bsearch (T *key) const | 372 inline const Type *bsearch (T *key) const |
377 { | 373 { |
378 return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare
_func_t) Type::cmp); | 374 return (const Type *) ::bsearch (key, array, len, sizeof (Type), (hb_compare
_func_t) Type::cmp); |
379 } | 375 } |
380 | 376 |
381 inline void finish (void) | 377 inline void finish (void) |
382 { | 378 { |
383 if (array != static_array) | 379 if (array != static_array) |
384 free (array); | 380 free (array); |
385 array = NULL; | 381 array = NULL; |
386 allocated = len = 0; | 382 allocated = len = 0; |
387 } | 383 } |
388 }; | 384 }; |
389 | 385 |
390 #define HB_AUTO_ARRAY_PREALLOCED 16 | |
391 template <typename Type> | 386 template <typename Type> |
392 struct hb_auto_array_t : hb_prealloced_array_t <Type, HB_AUTO_ARRAY_PREALLOCED> | 387 struct hb_auto_array_t : hb_prealloced_array_t <Type> |
393 { | 388 { |
394 hb_auto_array_t (void) { hb_prealloced_array_t<Type, HB_AUTO_ARRAY_PREALLOCED>
::init (); } | 389 hb_auto_array_t (void) { hb_prealloced_array_t<Type>::init (); } |
395 ~hb_auto_array_t (void) { hb_prealloced_array_t<Type, HB_AUTO_ARRAY_PREALLOCED
>::finish (); } | 390 ~hb_auto_array_t (void) { hb_prealloced_array_t<Type>::finish (); } |
396 }; | 391 }; |
397 | 392 |
398 | 393 |
399 #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT} | 394 #define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT} |
400 template <typename item_t, typename lock_t> | 395 template <typename item_t, typename lock_t> |
401 struct hb_lockable_set_t | 396 struct hb_lockable_set_t |
402 { | 397 { |
403 hb_prealloced_array_t <item_t, 2> items; | 398 hb_prealloced_array_t <item_t, 2> items; |
404 | 399 |
405 inline void init (void) { items.init (); } | 400 inline void init (void) { items.init (); } |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 */ | 713 */ |
719 | 714 |
720 template <typename T> | 715 template <typename T> |
721 static inline void _hb_warn_no_return (bool returned) | 716 static inline void _hb_warn_no_return (bool returned) |
722 { | 717 { |
723 if (unlikely (!returned)) { | 718 if (unlikely (!returned)) { |
724 fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bu
g, please report.\n"); | 719 fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bu
g, please report.\n"); |
725 } | 720 } |
726 } | 721 } |
727 template <> | 722 template <> |
728 inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED) | 723 /*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED) |
729 {} | 724 {} |
730 | 725 |
731 template <int max_level, typename ret_t> | 726 template <int max_level, typename ret_t> |
732 struct hb_auto_trace_t { | 727 struct hb_auto_trace_t { |
733 explicit inline hb_auto_trace_t (unsigned int *plevel_, | 728 explicit inline hb_auto_trace_t (unsigned int *plevel_, |
734 const char *what_, | 729 const char *what_, |
735 const void *obj_, | 730 const void *obj_, |
736 const char *func, | 731 const char *func, |
737 const char *message, | 732 const char *message, |
738 ...) : plevel (plevel_), what (what_), obj (o
bj_), returned (false) | 733 ...) : plevel (plevel_), what (what_), obj (o
bj_), returned (false) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 const char *message HB_UNUSED, | 779 const char *message HB_UNUSED, |
785 ...) {} | 780 ...) {} |
786 | 781 |
787 inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } | 782 inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } |
788 }; | 783 }; |
789 | 784 |
790 #define TRACE_RETURN(RET) trace.ret (RET, __LINE__) | 785 #define TRACE_RETURN(RET) trace.ret (RET, __LINE__) |
791 | 786 |
792 /* Misc */ | 787 /* Misc */ |
793 | 788 |
| 789 template <typename T> class hb_assert_unsigned_t; |
| 790 template <> class hb_assert_unsigned_t<unsigned char> {}; |
| 791 template <> class hb_assert_unsigned_t<unsigned short> {}; |
| 792 template <> class hb_assert_unsigned_t<unsigned int> {}; |
| 793 template <> class hb_assert_unsigned_t<unsigned long> {}; |
794 | 794 |
795 /* Pre-mature optimization: | |
796 * Checks for lo <= u <= hi but with an optimization if lo and hi | |
797 * are only different in a contiguous set of lower-most bits. | |
798 */ | |
799 template <typename T> static inline bool | 795 template <typename T> static inline bool |
800 hb_in_range (T u, T lo, T hi) | 796 hb_in_range (T u, T lo, T hi) |
801 { | 797 { |
802 if ( ((lo^hi) & lo) == 0 && | 798 /* The sizeof() is here to force template instantiation. |
803 ((lo^hi) & hi) == (lo^hi) && | 799 * I'm sure there are better ways to do this but can't think of |
804 ((lo^hi) & ((lo^hi) + 1)) == 0 ) | 800 * one right now. Declaring a variable won't work as HB_UNUSED |
805 return (u & ~(lo^hi)) == lo; | 801 * is unsable on some platforms and unused types are less likely |
806 else | 802 * to generate a warning than unused variables. */ |
807 return lo <= u && u <= hi; | 803 ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0); |
| 804 |
| 805 return (u - lo) <= (hi - lo); |
808 } | 806 } |
809 | 807 |
810 template <typename T> static inline bool | 808 template <typename T> static inline bool |
811 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) | 809 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) |
812 { | 810 { |
813 return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); | 811 return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); |
814 } | 812 } |
815 | 813 |
816 template <typename T> static inline bool | 814 template <typename T> static inline bool |
817 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) | 815 hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 hb_options (void) | 907 hb_options (void) |
910 { | 908 { |
911 if (unlikely (!_hb_options.i)) | 909 if (unlikely (!_hb_options.i)) |
912 _hb_options_init (); | 910 _hb_options_init (); |
913 | 911 |
914 return _hb_options.opts; | 912 return _hb_options.opts; |
915 } | 913 } |
916 | 914 |
917 | 915 |
918 #endif /* HB_PRIVATE_HH */ | 916 #endif /* HB_PRIVATE_HH */ |
OLD | NEW |