blob: 8a323decf0de1b2d2600104f5eb73aa69292f0a6 [file] [log] [blame]
Behdad Esfahbod64aef3a2008-01-23 16:14:38 -05001/*
Behdad Esfahbod6c786832009-05-25 03:22:19 -04002 * Copyright (C) 2007,2008,2009 Red Hat, Inc.
Behdad Esfahbod64aef3a2008-01-23 16:14:38 -05003 *
Behdad Esfahbodc755cb32010-04-22 00:11:43 -04004 * This is part of HarfBuzz, a text shaping library.
Behdad Esfahbod64aef3a2008-01-23 16:14:38 -05005 *
6 * Permission is hereby granted, without written agreement and without
7 * license or royalty fees, to use, copy, modify, and distribute this
8 * software and its documentation for any purpose, provided that the
9 * above copyright notice and the following two paragraphs appear in
10 * all copies of this software.
11 *
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16 * DAMAGE.
17 *
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 *
24 * Red Hat Author(s): Behdad Esfahbod
25 */
26
Behdad Esfahbod8dd1c8b2008-01-23 05:00:30 -050027#ifndef HB_PRIVATE_H
28#define HB_PRIVATE_H
Behdad Esfahbod5b3f7702006-12-28 06:42:37 -050029
Behdad Esfahboddf660282009-08-01 20:46:02 -040030#if HAVE_CONFIG_H
31#include "config.h"
32#endif
Behdad Esfahbod12360f72008-01-23 15:50:38 -050033
Behdad Esfahbodbc200452010-04-29 01:40:26 -040034#include "hb-common.h"
Behdad Esfahbodb28815c2009-08-04 22:35:36 -040035
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -040036#include <stdlib.h>
Behdad Esfahbodf0954d12009-07-30 15:33:57 -040037#include <string.h>
38#include <assert.h>
Behdad Esfahbod1d521512010-04-28 13:18:41 -040039
40/* We only use these two for debug output. However, the debug code is
41 * always seen by the compiler (and optimized out in non-debug builds.
42 * If including these becomes a problem, we can start thinking about
43 * someway around that. */
Behdad Esfahbod7acb3892009-08-05 15:20:34 -040044#include <stdio.h>
45#include <errno.h>
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -040046
Behdad Esfahbodbc200452010-04-29 01:40:26 -040047
48/* Essentials */
49
50#ifndef NULL
51# define NULL ((void *) 0)
52#endif
53
54#undef FALSE
55#define FALSE 0
56
57#undef TRUE
58#define TRUE 1
Behdad Esfahboddf660282009-08-01 20:46:02 -040059
Behdad Esfahboda794ebf2009-08-06 12:32:35 -040060
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -040061/* Basics */
62
63#undef MIN
64#define MIN(a,b) ((a) < (b) ? (a) : (b))
65
Behdad Esfahbod8a3511a2009-11-04 19:45:39 -050066#undef MAX
67#define MAX(a,b) ((a) > (b) ? (a) : (b))
68
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -040069#ifndef HB_INTERNAL
Behdad Esfahbod081819e2009-08-10 23:40:28 -040070# define HB_INTERNAL extern
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -040071#endif
72
Behdad Esfahbod45917532009-11-04 18:15:59 -050073#undef ARRAY_LENGTH
74#define ARRAY_LENGTH(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -040075
Behdad Esfahbod35a73832009-08-01 19:30:31 -040076#define HB_STMT_START do
77#define HB_STMT_END while (0)
Behdad Esfahbod5b3f7702006-12-28 06:42:37 -050078
Behdad Esfahbod303fe622008-01-23 00:20:48 -050079#define _ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1]
80#define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond))
81#define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond))
82
Behdad Esfahbodbc200452010-04-29 01:40:26 -040083
84/* Misc */
85
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -040086
Behdad Esfahboddf660282009-08-01 20:46:02 -040087#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
Behdad Esfahbod79512792009-11-03 20:27:05 -050088#define _HB_BOOLEAN_EXPR(expr) \
89 __extension__ ({ \
90 int _hb_boolean_var_; \
91 if (expr) \
92 _hb_boolean_var_ = 1; \
93 else \
94 _hb_boolean_var_ = 0; \
95 _hb_boolean_var_; \
96 })
Behdad Esfahbod64d3fc82010-05-03 22:51:19 -040097#define likely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 1))
98#define unlikely(expr) (__builtin_expect (_HB_BOOLEAN_EXPR(expr), 0))
Behdad Esfahboddf660282009-08-01 20:46:02 -040099#else
Behdad Esfahbod64d3fc82010-05-03 22:51:19 -0400100#define likely(expr) (expr)
101#define unlikely(expr) (expr)
Behdad Esfahboddf660282009-08-01 20:46:02 -0400102#endif
103
104#ifndef __GNUC__
105#undef __attribute__
106#define __attribute__(x)
107#endif
108
109#if __GNUC__ >= 3
Behdad Esfahbod33d13fd2010-04-29 13:56:44 -0400110#define HB_PURE_FUNC __attribute__((pure))
111#define HB_CONST_FUNC __attribute__((const))
Behdad Esfahboddf660282009-08-01 20:46:02 -0400112#else
Behdad Esfahbod33d13fd2010-04-29 13:56:44 -0400113#define HB_PURE_FUNC
114#define HB_CONST_FUNC
Behdad Esfahboddf660282009-08-01 20:46:02 -0400115#endif
Behdad Esfahbodbc7830e2010-02-17 15:14:57 -0500116#if __GNUC__ >= 4
Behdad Esfahbod33d13fd2010-04-29 13:56:44 -0400117#define HB_UNUSED __attribute__((unused))
Behdad Esfahbodbc7830e2010-02-17 15:14:57 -0500118#else
Behdad Esfahbod33d13fd2010-04-29 13:56:44 -0400119#define HB_UNUSED
Behdad Esfahbodbc7830e2010-02-17 15:14:57 -0500120#endif
Behdad Esfahboddf660282009-08-01 20:46:02 -0400121
122
123#if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER)
124#define snprintf _snprintf
125#endif
126
127#ifdef _MSC_VER
128#undef inline
129#define inline __inline
130#endif
131
132#ifdef __STRICT_ANSI__
133#undef inline
134#define inline __inline__
135#endif
136
137
Behdad Esfahbod7d3a1262010-04-29 13:54:01 -0400138#if __GNUC__ >= 3
139#define HB_FUNC __PRETTY_FUNCTION__
140#elif defined(_MSC_VER)
141#define HB_FUNC __FUNCSIG__
142#else
143#define HB_FUNC __func__
144#endif
145
146
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -0400147/* Return the number of 1 bits in mask.
148 *
149 * GCC 3.4 supports a "population count" builtin, which on many targets is
150 * implemented with a single instruction. There is a fallback definition
151 * in libgcc in case a target does not have one, which should be just as
152 * good as the open-coded solution below, (which is "HACKMEM 169").
153 */
Jeff Muizelaareaf29ed2010-05-03 22:27:56 -0400154static inline unsigned int
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -0400155_hb_popcount32 (uint32_t mask)
156{
157#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
158 return __builtin_popcount (mask);
159#else
Behdad Esfahbod9faee632009-08-06 10:24:49 -0400160 register uint32_t y;
Behdad Esfahbodc7d457a2009-05-21 12:46:29 -0400161
162 y = (mask >> 1) &033333333333;
163 y = mask - y - ((y >>1) & 033333333333);
164 return (((y + (y >> 3)) & 030707070707) % 077);
165#endif
166}
167
Behdad Esfahboddf660282009-08-01 20:46:02 -0400168
Behdad Esfahbod3c69bd42009-08-17 16:48:13 -0400169/* Multiplies a 16dot16 value by another value, then truncates the result */
Behdad Esfahbod06558d22010-04-19 02:34:10 -0400170#define _hb_16dot16_mul_round(A,B) (((int64_t) (A) * (B) + 0x8000) / 0x10000)
Behdad Esfahbod3c69bd42009-08-17 16:48:13 -0400171
Behdad Esfahbodf60f2162010-04-21 02:12:45 -0400172
173/* We need external help for these */
174
175#ifdef HAVE_GLIB
176
177#include <glib.h>
178
179typedef int hb_atomic_int_t;
180#define hb_atomic_int_fetch_and_add(AI, V) g_atomic_int_exchange_and_add (&(AI), V)
181#define hb_atomic_int_get(AI) g_atomic_int_get (&(AI))
182#define hb_atomic_int_set(AI, V) g_atomic_int_set (&(AI), V)
183
184typedef GStaticMutex hb_mutex_t;
185#define HB_MUTEX_INIT G_STATIC_MUTEX_INIT
186#define hb_mutex_init(M) g_static_mutex_init (&M)
187#define hb_mutex_lock(M) g_static_mutex_lock (&M)
188#define hb_mutex_trylock(M) g_static_mutex_trylock (&M)
189#define hb_mutex_unlock(M) g_static_mutex_unlock (&M)
190
191#else
192
193#ifdef _MSC_VER
194#pragma message(__LOC__"Could not find any system to define platform macros, library will NOT be thread-safe")
195#else
196#warning "Could not find any system to define platform macros, library will NOT be thread-safe"
197#endif
198
199typedef int hb_atomic_int_t;
200#define hb_atomic_int_fetch_and_add(AI, V) ((AI) += (V), (AI) - (V))
201#define hb_atomic_int_get(AI) (AI)
Behdad Esfahbodffff7dc2010-04-21 02:13:55 -0400202#define hb_atomic_int_set(AI, V) HB_STMT_START { (AI) = (V); } HB_STMT_END
Behdad Esfahbodf60f2162010-04-21 02:12:45 -0400203
204typedef int hb_mutex_t;
Behdad Esfahbodffff7dc2010-04-21 02:13:55 -0400205#define HB_MUTEX_INIT 0
206#define hb_mutex_init(M) HB_STMT_START { (M) = 0; } HB_STMT_END
207#define hb_mutex_lock(M) HB_STMT_START { (M) = 1; } HB_STMT_END
208#define hb_mutex_trylock(M) ((M) = 1, 1)
209#define hb_mutex_unlock(M) HB_STMT_START { (M) = 0; } HB_STMT_END
Behdad Esfahbodf60f2162010-04-21 02:12:45 -0400210
211#endif
212
213
214/* Big-endian handling */
215
Behdad Esfahbod7a52f282010-04-21 02:14:44 -0400216#define hb_be_uint16(v) ((uint16_t) ((((const uint8_t *)&(v))[0] << 8) + (((const uint8_t *)&(v))[1])))
Behdad Esfahbodf60f2162010-04-21 02:12:45 -0400217
Behdad Esfahbode032ed92010-04-21 03:11:46 -0400218#define hb_be_uint16_put(v,V) HB_STMT_START { v[0] = (V>>8); v[1] = (V); } HB_STMT_END
Behdad Esfahbod7a52f282010-04-21 02:14:44 -0400219#define hb_be_uint16_get(v) (uint16_t) ((v[0] << 8) + v[1])
220#define hb_be_uint16_cmp(a,b) (a[0] == b[0] && a[1] == b[1])
Behdad Esfahbodf60f2162010-04-21 02:12:45 -0400221
Behdad Esfahbode032ed92010-04-21 03:11:46 -0400222#define hb_be_uint32_put(v,V) HB_STMT_START { v[0] = (V>>24); v[1] = (V>>16); v[2] = (V>>8); v[3] = (V); } HB_STMT_END
Behdad Esfahbod7a52f282010-04-21 02:14:44 -0400223#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3])
224#define hb_be_uint32_cmp(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])
Behdad Esfahbodf60f2162010-04-21 02:12:45 -0400225
226
Behdad Esfahbodbc200452010-04-29 01:40:26 -0400227/* Debug */
228
229#ifndef HB_DEBUG
230#define HB_DEBUG 0
231#endif
232
Jeff Muizelaareaf29ed2010-05-03 22:27:56 -0400233static inline hb_bool_t /* always returns TRUE */
Behdad Esfahbodbc200452010-04-29 01:40:26 -0400234_hb_trace (const char *what,
235 const char *function,
236 const void *obj,
237 unsigned int depth,
238 unsigned int max_depth)
239{
240 if (depth < max_depth)
241 fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, depth, depth, function);
242 return TRUE;
243}
244
Behdad Esfahbodf60f2162010-04-21 02:12:45 -0400245
Behdad Esfahbodba8d94c2009-08-01 20:29:22 -0400246#include "hb-object-private.h"
247
Behdad Esfahbod8dd1c8b2008-01-23 05:00:30 -0500248#endif /* HB_PRIVATE_H */