sylware / charfbuzz (public) (License: LGPLv3) (since 2019-09-09) (hash sha1)
partial C implementation of harfbuzz C API for roman scripts
List of commits:
Subject Hash Author Date (UTC)
0.9.30 API 21d9751191f219964c1259f595ae1fe597798ecf Sylvain BERTRAND 2015-12-22 03:56:17
make cleanup and some bash-ism removal c3c7c886bca4c42f3c55169dbba1234f4889431d Sylvain BERTRAND 2015-03-27 01:23:07
compatible with busybox ab23689d96ea773aef950ac6876deb23c98edf54 MihailZenkov 2014-02-05 22:05:22
build system fixes 3ab23b119cbf12638ba80c5c1fb74dfdcc0db4b5 Sylvain BERTRAND 2013-12-01 23:31:59
Initial commit 6b51dc44275fcd132e0cbeec5a9eb79ca532b201 Sylvain BERTRAND 2013-10-16 01:42:30
Commit 21d9751191f219964c1259f595ae1fe597798ecf - 0.9.30 API
Author: Sylvain BERTRAND
Author date (UTC): 2015-12-22 03:56
Committer name: Sylvain BERTRAND
Committer date (UTC): 2015-12-22 03:56
Parent(s): c3c7c886bca4c42f3c55169dbba1234f4889431d
Signer:
Signing key:
Signing status: N
Tree: 2eb3ce145ef1389642e90c1e372d12ebbc5669d8
File Lines added Lines deleted
ABBREVIATIONS 8 7
FIXME 1 1
README 5 1
harfbuzz.pc.in 1 1
hb-atomic-private.h 31 27
hb-blob-private.h 1 2
hb-blob.c 145 155
hb-blob.h 15 16
hb-buffer-private.h 28 29
hb-buffer.c 320 331
hb-buffer.h 107 52
hb-common.c 96 83
hb-common.h 46 25
hb-coretext.h 17 3
hb-face-private.h 24 27
hb-face.c 144 142
hb-face.h 17 17
hb-fallback-shape.c 89 75
hb-font-private.h 76 78
hb-font.c 858 911
hb-font.h 76 71
hb-ft.c 72 66
hb-ft.h 72 8
hb-glib.c 89 95
hb-glib.h 6 3
hb-gobject-structs.h 31 21
hb-graphite2.h 2 2
hb-icu.h 3 3
hb-open-file-private.h 46 53
hb-open-file.c 89 74
hb-ot-font.h 15 10
hb-ot-layout.c 96 93
hb-ot-layout.h 42 34
hb-ot-shape.h 15 11
hb-ot-tag.c 19 22
hb-ot-tag.h 4 4
hb-ot.h 2 8
hb-private.h 55 26
hb-set.h 29 26
hb-shape-plan-private.h 30 30
hb-shape-plan.c 398 363
hb-shape-plan.h 9 9
hb-shape.c 213 26
hb-shape.h 5 8
hb-shaper-private.h 13 15
hb-shaper.c 77 56
hb-unicode-private.h 35 35
hb-unicode.c 217 194
hb-unicode.h 59 34
hb-uniscribe.h 2 5
hb-utf-private.c 198 173
hb-utf-private.h 23 48
hb-version.h.in 8 8
hb.h 4 0
make 18 13
File ABBREVIATIONS changed (mode: 100644) (index 1a0b33b..9381999)
1 chk check
2 cnt count
1 chk CHecK
2 cnt CouNT
3 3 fnt FoNT fnt FoNT
4 4 ft FreeType ft FreeType
5 5 hdr HeaDeR hdr HeaDeR
6 idx index
7 len length
6 idx InDeX
7 len LENgth
8 lib LIBrary
8 9 of(s) offset(s) of(s) offset(s)
9 10 ot OpenType ot OpenType
10 rec record
11 tbl(s) table(s)
11 rec RECord
12 tbl(s) TaBLe(s)
12 13 ttc TrueType Collection ttc TrueType Collection
13 ver version
14 ver VERsion
File FIXME changed (mode: 100644) (index 8bbabe4..b5b8344)
1 Lifetime of reference counted objets does not seem to be synchronised properly. Races can occure on heavy loaded CPUs.
1 Lifetime of reference counted objets does not seem to be synchronised properly. Races would occur on heavy loaded CPUs.
File README changed (mode: 100644) (index 8a85692..9c28271)
1 This is a *partial* C99 port of harfbuzz.
1 This is a *partial* C90ish port of harfbuzz
2 2
3 3 How to build and install? See output from $./make --help How to build and install? See output from $./make --help
4
5 The build system is insanely... simple with a sub-low technical cost.
6
7 Maybe adding international stuff with libindi/libthai/fribidi/etc?
File harfbuzz.pc.in changed (mode: 100644) (index 7f27bbb..bc171ca)
1 1 prefix=%prefix% prefix=%prefix%
2 exec_prefix=%exec_prefix%
2 exec_prefix=${prefix}
3 3 libdir=%libdir% libdir=%libdir%
4 4 includedir=%includedir% includedir=%includedir%
5 5
File hb-atomic-private.h changed (mode: 100644) (index 2931cca..833e0c5)
2 2 #define HB_ATOMIC_PRIVATE_H #define HB_ATOMIC_PRIVATE_H
3 3 #ifdef __GNUC__ #ifdef __GNUC__
4 4 #define atomic_int32_t int32_t #define atomic_int32_t int32_t
5 static HB_UNUSED atomic_int32_t hb_atomic_int32_add(atomic_int32_t *p,
6 atomic_int32_t val)
5 static HB_UNUSED atomic_int32_t hb_atomic_int32_add(atomic_int32_t * p,
6 atomic_int32_t val)
7 7 { {
8 return __atomic_add_fetch(p, val, __ATOMIC_SEQ_CST);
8 return __atomic_add_fetch(p, val, __ATOMIC_SEQ_CST);
9 9 } }
10 10
11 static HB_UNUSED atomic_int32_t hb_atomic_int32_get(atomic_int32_t *p)
11 static HB_UNUSED atomic_int32_t hb_atomic_int32_get(atomic_int32_t * p)
12 12 { {
13 atomic_int32_t r;
14 __atomic_load(p, &r, __ATOMIC_SEQ_CST);
15 return r;
13 atomic_int32_t r;
14 __atomic_load(p, &r, __ATOMIC_SEQ_CST);
15 return r;
16 16 } }
17 17
18 static HB_UNUSED void hb_atomic_int32_set(atomic_int32_t *p,
19 atomic_int32_t v)
18 static HB_UNUSED void hb_atomic_int32_set(atomic_int32_t * p, atomic_int32_t v)
20 19 { {
21 __atomic_store(p, &v, __ATOMIC_SEQ_CST);
20 __atomic_store(p, &v, __ATOMIC_SEQ_CST);
22 21 } }
23 22
24 23 static HB_UNUSED void *hb_atomic_ptr_get(void *P) static HB_UNUSED void *hb_atomic_ptr_get(void *P)
25 24 { {
26 void **P_real = (void**)P;
27 void *ret;
28 __atomic_load(P_real, &ret, __ATOMIC_SEQ_CST);
29 return ret;
25 void **P_real;
26 void *ret;
27
28 P_real = (void **)P;
29 __atomic_load(P_real, &ret, __ATOMIC_SEQ_CST);
30 return ret;
30 31 } }
31 32
32 33 static HB_UNUSED hb_bool_t hb_atomic_ptr_cmpexch(void *ptr, static HB_UNUSED hb_bool_t hb_atomic_ptr_cmpexch(void *ptr,
33 void *expected,
34 void *desired)
34 void *expected, void *desired)
35 35 { {
36 void **ptr_real = (void**)ptr;
37 void **expected_real = (void**)expected;
38 void **desired_real =(void**)desired;
39 return __atomic_compare_exchange(ptr_real,
40 expected_real,
41 desired_real,
42 FALSE,
43 __ATOMIC_SEQ_CST,
44 __ATOMIC_SEQ_CST);
36 void **ptr_real;
37 void **expected_real;
38 void **desired_real;
39
40 ptr_real = (void **)ptr;
41 expected_real = (void **)expected;
42 desired_real = (void **)desired;
43
44 return __atomic_compare_exchange(ptr_real,
45 expected_real,
46 desired_real,
47 FALSE,
48 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
45 49 } }
46 #else//__GNUC__
47 # error "missing definitions of atomic operations"
50 #else/*__GNUC__*/
51 #error "missing definitions of atomic operations"
48 52 #endif #endif
49 53 #endif #endif
File hb-blob-private.h changed (mode: 100644) (index ee63054..154fbbb)
1 1 #ifndef HB_BLOB_PRIVATE_H #ifndef HB_BLOB_PRIVATE_H
2 2 #define HB_BLOB_PRIVATE_H #define HB_BLOB_PRIVATE_H
3 struct ot_fnt_file *
4 hb_blob_lock_instance(hb_blob_t *blob);
3 struct ot_fnt_file *hb_blob_lock_instance(hb_blob_t *blob);
5 4 #endif #endif
File hb-blob.c changed (mode: 100644) (index 607f12b..6cc7939)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 */
4 5 #include <stdlib.h> #include <stdlib.h>
5 6 #include <unistd.h> #include <unistd.h>
6 7 #include <sys/mman.h> #include <sys/mman.h>
 
13 14 #include "hb-blob-private.h" #include "hb-blob-private.h"
14 15
15 16 struct hb_blob_t { struct hb_blob_t {
16 atomic_int32_t ref_cnt;
17 hb_bool_t immutable;
17 atomic_int32_t ref_cnt;
18 hb_bool_t immutable;
18 19
19 const char *data;
20 unsigned length;
21 hb_memory_mode_t mode;
20 const char *data;
21 unsigned length;
22 hb_memory_mode_t mode;
22 23
23 void *user_data;
24 hb_destroy_func_t destroy;
24 void *user_data;
25 hb_destroy_func_t destroy;
25 26 }; };
26 27
28 /*XXX:should go in lib "global init"*/
27 29 static hb_blob_t hb_blob_nil = { static hb_blob_t hb_blob_nil = {
28 REF_CNT_INVALID_VAL,//ref_cnt
29 TRUE,//immutable
30 NULL,//data
31 0,//length
32 HB_MEMORY_MODE_READONLY,//mode
33 NULL,//user_data
34 NULL//destroy
35 };
36
37 hb_blob_t *
38 hb_blob_get_empty(void)
30 REF_CNT_INVALID_VAL, /*ref_cnt */
31 TRUE, /*immutable */
32 NULL, /*data */
33 0, /*length */
34 HB_MEMORY_MODE_READONLY, /*mode */
35 NULL, /*user_data */
36 NULL /*destroy */
37 };
38
39 hb_blob_t *hb_blob_get_empty(void)
39 40 { {
40 return &hb_blob_nil;
41 return &hb_blob_nil;
41 42 } }
42 43
43 hb_blob_t *
44 hb_blob_reference(hb_blob_t *blob)
44 hb_blob_t *hb_blob_reference(hb_blob_t * blob)
45 45 { {
46 if (hb_atomic_int32_get(&blob->ref_cnt) != REF_CNT_INVALID_VAL)
47 hb_atomic_int32_add(&blob->ref_cnt, 1);
48 return blob;
46 if (hb_atomic_int32_get(&blob->ref_cnt) != REF_CNT_INVALID_VAL)
47 hb_atomic_int32_add(&blob->ref_cnt, 1);
48 return blob;
49 49 } }
50 50
51 void
52 hb_blob_make_immutable(hb_blob_t *blob)
51 void hb_blob_make_immutable(hb_blob_t * blob)
53 52 { {
54 if (hb_atomic_int32_get(&blob->ref_cnt) == REF_CNT_INVALID_VAL)
55 return;
56 blob->immutable = TRUE;
53 if (hb_atomic_int32_get(&blob->ref_cnt) == REF_CNT_INVALID_VAL)
54 return;
55 blob->immutable = TRUE;
57 56 } }
58 57
59 unsigned
60 hb_blob_get_length(hb_blob_t *blob)
58 unsigned hb_blob_get_length(hb_blob_t * blob)
61 59 { {
62 return blob->length;
60 return blob->length;
63 61 } }
64 62
65 const char *
66 hb_blob_get_data(hb_blob_t *blob, unsigned *length)
63 const char *hb_blob_get_data(hb_blob_t * blob, unsigned *length)
67 64 { {
68 if (length)
69 *length = blob->length;
70 return blob->data;
65 if (length)
66 *length = blob->length;
67 return blob->data;
71 68 } }
72 69
73 static hb_bool_t
74 try_make_writable_inplace_unix(hb_blob_t *blob)
70 static hb_bool_t try_make_writable_inplace_unix(hb_blob_t * blob)
75 71 { {
76 uintptr_t pagesize = -1, mask, length;
77 const char *addr;
72 uintptr_t pagesize, mask, length;
73 const char *addr;
78 74
79 pagesize = (uintptr_t)sysconf(_SC_PAGESIZE);
75 pagesize = (uintptr_t) sysconf(_SC_PAGESIZE);
80 76
81 if ((uintptr_t) -1L == pagesize)
82 return FALSE;
77 if ((uintptr_t) - 1L == pagesize)
78 return FALSE;
83 79
84 mask = ~(pagesize-1);
85 addr = (const char*)(((uintptr_t)blob->data) & mask);
86 length = (const char*)(((uintptr_t)blob->data + blob->length + pagesize-1)
87 & mask) - addr;
88 if (-1 == mprotect((void*)addr, length, PROT_READ | PROT_WRITE))
89 return FALSE;
80 mask = ~(pagesize - 1);
81 addr = (const char *)(((uintptr_t) blob->data) & mask);
82 length =
83 (const char
84 *)(((uintptr_t) blob->data + blob->length + pagesize - 1)
85 & mask) - addr;
86 if (-1 == mprotect((void *)addr, length, PROT_READ | PROT_WRITE))
87 return FALSE;
90 88
91 blob->mode = HB_MEMORY_MODE_WRITABLE;
92 return TRUE;
89 blob->mode = HB_MEMORY_MODE_WRITABLE;
90 return TRUE;
93 91 } }
94 92
95 static hb_bool_t
96 try_writable_inplace(hb_blob_t *blob)
93 static hb_bool_t try_writable_inplace(hb_blob_t * blob)
97 94 { {
98 if (try_make_writable_inplace_unix(blob))
99 return TRUE;
95 if (try_make_writable_inplace_unix(blob))
96 return TRUE;
100 97
101 //Failed to make writable inplace, mark that
102 blob->mode = HB_MEMORY_MODE_READONLY;
103 return FALSE;
98 /*Failed to make writable inplace, mark that */
99 blob->mode = HB_MEMORY_MODE_READONLY;
100 return FALSE;
104 101 } }
105 102
106 static void
107 hb_blob_destroy_user_data(hb_blob_t *blob)
103 static void hb_blob_destroy_user_data(hb_blob_t * blob)
108 104 { {
109 if (blob->destroy) {
110 blob->destroy(blob->user_data);
111 blob->user_data = NULL;
112 blob->destroy = NULL;
113 }
105 if (blob->destroy) {
106 blob->destroy(blob->user_data);
107 blob->user_data = NULL;
108 blob->destroy = NULL;
109 }
114 110 } }
115 111
116 static hb_bool_t
117 try_writable(hb_blob_t *blob)
112 static hb_bool_t try_writable(hb_blob_t * blob)
118 113 { {
119 if (blob->immutable)
120 return FALSE;
114 char *new_data;
121 115
122 if (blob->mode == HB_MEMORY_MODE_WRITABLE)
123 return TRUE;
116 if (blob->immutable)
117 return FALSE;
124 118
125 if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
126 && try_writable_inplace(blob))
127 return TRUE;
119 if (blob->mode == HB_MEMORY_MODE_WRITABLE)
120 return TRUE;
128 121
129 if (blob->mode == HB_MEMORY_MODE_WRITABLE)
130 return TRUE;
122 if (blob->mode == HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE
123 && try_writable_inplace(blob))
124 return TRUE;
131 125
132 char *new_data;
126 if (blob->mode == HB_MEMORY_MODE_WRITABLE)
127 return TRUE;
133 128
134 new_data = malloc(blob->length);
135 if (!new_data)
136 return FALSE;
129 new_data = malloc(blob->length);
130 if (!new_data)
131 return FALSE;
137 132
138 memcpy(new_data, blob->data, blob->length);
139 hb_blob_destroy_user_data(blob);
140 blob->mode = HB_MEMORY_MODE_WRITABLE;
141 blob->data = new_data;
142 blob->user_data = new_data;
143 blob->destroy = free;
144 return TRUE;
133 memcpy(new_data, blob->data, blob->length);
134 hb_blob_destroy_user_data(blob);
135 blob->mode = HB_MEMORY_MODE_WRITABLE;
136 blob->data = new_data;
137 blob->user_data = new_data;
138 blob->destroy = free;
139 return TRUE;
145 140 } }
146 141
147 void
148 hb_blob_destroy(hb_blob_t *blob)
142 void hb_blob_destroy(hb_blob_t * blob)
149 143 { {
150 if (!blob)
151 return;
152 if (hb_atomic_int32_get(&blob->ref_cnt) == REF_CNT_INVALID_VAL)
153 return;
154 hb_atomic_int32_add(&blob->ref_cnt, -1);
155 if (hb_atomic_int32_get(&blob->ref_cnt) > 0)
156 return;
157 hb_atomic_int32_set(&blob->ref_cnt, REF_CNT_INVALID_VAL);
158
159 hb_blob_destroy_user_data(blob);
160 free (blob);
144 if (!blob)
145 return;
146 if (hb_atomic_int32_get(&blob->ref_cnt) == REF_CNT_INVALID_VAL)
147 return;
148 hb_atomic_int32_add(&blob->ref_cnt, -1);
149 if (hb_atomic_int32_get(&blob->ref_cnt) > 0)
150 return;
151 hb_atomic_int32_set(&blob->ref_cnt, REF_CNT_INVALID_VAL);
152
153 hb_blob_destroy_user_data(blob);
154 free(blob);
161 155 } }
162 156
163 hb_blob_t *
164 hb_blob_create_sub_blob(hb_blob_t *parent,
165 unsigned offset,
166 unsigned length)
157 hb_blob_t *hb_blob_create_sub_blob(hb_blob_t * parent,
158 unsigned offset, unsigned length)
167 159 { {
168 hb_blob_t *blob;
160 hb_blob_t *blob;
169 161
170 if (!length || offset >= parent->length)
171 return hb_blob_get_empty();
162 if (!length || offset >= parent->length)
163 return hb_blob_get_empty();
172 164
173 hb_blob_make_immutable(parent);
165 hb_blob_make_immutable(parent);
174 166
175 blob = hb_blob_create(parent->data + offset,
176 MIN(length, parent->length - offset),
177 HB_MEMORY_MODE_READONLY,
178 hb_blob_reference(parent),
179 (hb_destroy_func_t)hb_blob_destroy);
180 return blob;
167 blob = hb_blob_create(parent->data + offset,
168 MIN(length, parent->length - offset),
169 HB_MEMORY_MODE_READONLY,
170 hb_blob_reference(parent),
171 (hb_destroy_func_t) hb_blob_destroy);
172 return blob;
181 173 } }
182 174
183 hb_blob_t *
184 hb_blob_create(const char *data,
185 unsigned length,
186 hb_memory_mode_t mode,
187 void *user_data,
188 hb_destroy_func_t destroy)
175 hb_blob_t *hb_blob_create(const char *data, unsigned length,
176 hb_memory_mode_t mode, void *user_data,
177 hb_destroy_func_t destroy)
189 178 { {
190 hb_blob_t *blob = calloc(1, sizeof(*blob));
191 if (!length || !blob) {
192 if (blob)
193 free(blob);
194 if (destroy)
195 destroy(user_data);
196 return hb_blob_get_empty();
197 }
198 hb_atomic_int32_set(&blob->ref_cnt, 1);
199 blob->immutable = FALSE;
200
201 blob->data = data;
202 blob->length = length;
203 blob->mode = mode;
204
205 blob->user_data = user_data;
206 blob->destroy = destroy;
207
208 if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
209 blob->mode = HB_MEMORY_MODE_READONLY;
210 if (!try_writable(blob)) {
211 hb_blob_destroy(blob);
212 return hb_blob_get_empty();
213 }
214 }
215 return blob;
179 hb_blob_t *blob = calloc(1, sizeof(*blob));
180 if (!length || !blob) {
181 if (blob)
182 free(blob);
183 if (destroy)
184 destroy(user_data);
185 return hb_blob_get_empty();
186 }
187 hb_atomic_int32_set(&blob->ref_cnt, 1);
188 blob->immutable = FALSE;
189
190 blob->data = data;
191 blob->length = length;
192 blob->mode = mode;
193
194 blob->user_data = user_data;
195 blob->destroy = destroy;
196
197 if (blob->mode == HB_MEMORY_MODE_DUPLICATE) {
198 blob->mode = HB_MEMORY_MODE_READONLY;
199 if (!try_writable(blob)) {
200 hb_blob_destroy(blob);
201 return hb_blob_get_empty();
202 }
203 }
204 return blob;
216 205 } }
217 206
218 struct ot_fnt_file *
219 hb_blob_lock_instance(hb_blob_t *blob)
207 struct ot_fnt_file *hb_blob_lock_instance(hb_blob_t * blob)
220 208 { {
221 hb_blob_make_immutable (blob);
222 const char *base = hb_blob_get_data(blob, NULL);
223 return (struct ot_fnt_file*)base;
209 const char *base;
210
211 hb_blob_make_immutable(blob);
212 base = hb_blob_get_data(blob, NULL);
213 return (struct ot_fnt_file *)base;
224 214 } }
File hb-blob.h changed (mode: 100644) (index d3d0f41..ef3fc98)
... ... HB_BEGIN_DECLS
47 47 * - Use MODE_READONLY otherse, unless you really really * - Use MODE_READONLY otherse, unless you really really
48 48 * really know what you are doing, * really know what you are doing,
49 49 * *
50 * - MODE_WRITABLE is appropriate if you relaly made a
50 * - MODE_WRITABLE is appropriate if you really made a
51 51 * copy of data solely for the purpose of passing to * copy of data solely for the purpose of passing to
52 52 * HarfBuzz and doing that just once (no reuse!), * HarfBuzz and doing that just once (no reuse!),
53 53 * *
54 54 * - If the font is mmap()ed, it's ok to use * - If the font is mmap()ed, it's ok to use
55 * READONLY_MAY_MAKE_WRITABLE, however, there were
56 * design problems with that mode, so HarfBuzz do not
57 * really use it anymore. If not sure, use MODE_READONLY.
55 * READONLY_MAY_MAKE_WRITABLE, however, using that mode
56 * correctly is very tricky. Use MODE_READONLY instead.
58 57 */ */
59 58 typedef enum { typedef enum {
60 59 HB_MEMORY_MODE_DUPLICATE, HB_MEMORY_MODE_DUPLICATE,
 
... ... typedef enum {
65 64
66 65 typedef struct hb_blob_t hb_blob_t; typedef struct hb_blob_t hb_blob_t;
67 66
68 hb_blob_t *
67 HB_EXTERN hb_blob_t *
69 68 hb_blob_create (const char *data, hb_blob_create (const char *data,
70 69 unsigned int length, unsigned int length,
71 70 hb_memory_mode_t mode, hb_memory_mode_t mode,
 
... ... hb_blob_create (const char *data,
78 77 * modify the parent data as that data may be * modify the parent data as that data may be
79 78 * shared among multiple sub-blobs. * shared among multiple sub-blobs.
80 79 */ */
81 hb_blob_t *
80 HB_EXTERN hb_blob_t *
82 81 hb_blob_create_sub_blob (hb_blob_t *parent, hb_blob_create_sub_blob (hb_blob_t *parent,
83 82 unsigned int offset, unsigned int offset,
84 83 unsigned int length); unsigned int length);
85 84
86 hb_blob_t *
85 HB_EXTERN hb_blob_t *
87 86 hb_blob_get_empty (void); hb_blob_get_empty (void);
88 87
89 hb_blob_t *
88 HB_EXTERN hb_blob_t *
90 89 hb_blob_reference (hb_blob_t *blob); hb_blob_reference (hb_blob_t *blob);
91 90
92 void
91 HB_EXTERN void
93 92 hb_blob_destroy (hb_blob_t *blob); hb_blob_destroy (hb_blob_t *blob);
94 93
95 hb_bool_t
94 HB_EXTERN hb_bool_t
96 95 hb_blob_set_user_data (hb_blob_t *blob, hb_blob_set_user_data (hb_blob_t *blob,
97 96 hb_user_data_key_t *key, hb_user_data_key_t *key,
98 97 void * data, void * data,
 
... ... hb_blob_set_user_data (hb_blob_t *blob,
100 99 hb_bool_t replace); hb_bool_t replace);
101 100
102 101
103 void *
102 HB_EXTERN void *
104 103 hb_blob_get_user_data (hb_blob_t *blob, hb_blob_get_user_data (hb_blob_t *blob,
105 104 hb_user_data_key_t *key); hb_user_data_key_t *key);
106 105
107 106
108 void
107 HB_EXTERN void
109 108 hb_blob_make_immutable (hb_blob_t *blob); hb_blob_make_immutable (hb_blob_t *blob);
110 109
111 hb_bool_t
110 HB_EXTERN hb_bool_t
112 111 hb_blob_is_immutable (hb_blob_t *blob); hb_blob_is_immutable (hb_blob_t *blob);
113 112
114 113
115 unsigned int
114 HB_EXTERN unsigned int
116 115 hb_blob_get_length (hb_blob_t *blob); hb_blob_get_length (hb_blob_t *blob);
117 116
118 const char *
117 HB_EXTERN const char *
119 118 hb_blob_get_data (hb_blob_t *blob, unsigned int *length); hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
120 119
121 char *
120 HB_EXTERN char *
122 121 hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length); hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length);
123 122
124 123
File hb-buffer-private.h changed (mode: 100644) (index 0455193..3b93b65)
1 1 #ifndef HB_BUFFER_PRIVATE_H #ifndef HB_BUFFER_PRIVATE_H
2 2 #define HB_BUFFER_PRIVATE_H #define HB_BUFFER_PRIVATE_H
3 3 struct hb_buffer_t { struct hb_buffer_t {
4 atomic_int32_t ref_cnt;
5 hb_unicode_funcs_t *unicode;//Unicode functions
6 hb_segment_properties_t props;//Script, language, direction
7 hb_buffer_flags_t flags;//BOT / EOT / etc.
4 atomic_int32_t ref_cnt;
5 hb_unicode_funcs_t *unicode; /*Unicode functions */
6 hb_segment_properties_t props; /*Script, language, direction */
7 hb_buffer_flags_t flags; /*BOT / EOT / etc. */
8 8
9 //Buffer contents
9 /*Buffer contents */
10 10
11 hb_buffer_content_type_t content_type;
11 hb_buffer_content_type_t content_type;
12 12
13 hb_bool_t in_error;//Allocation failed
14 hb_bool_t have_output;//Whether we have an output buffer going on
15 hb_bool_t have_positions;//Whether we have positions
13 hb_bool_t in_error; /*Allocation failed */
14 hb_bool_t have_output; /*Whether we have an output buffer going on */
15 hb_bool_t have_positions; /*Whether we have positions */
16 16
17 unsigned idx;//Cursor into ->info and ->pos arrays
18 unsigned len;//Length of ->info and ->pos arrays
19 unsigned out_len;//Length of ->out array if have_output
17 unsigned idx; /*Cursor into ->info and ->pos arrays */
18 unsigned len; /*Length of ->info and ->pos arrays */
19 unsigned out_len; /*Length of ->out array if have_output */
20 20
21 unsigned allocated;//Length of allocated arrays
22 hb_glyph_info_t *info;
23 hb_glyph_info_t *out_info;
24 hb_glyph_position_t *pos;
21 unsigned allocated; /*Length of allocated arrays */
22 hb_glyph_info_t *info;
23 hb_glyph_info_t *out_info;
24 hb_glyph_position_t *pos;
25 25
26 unsigned serial;
26 unsigned serial;
27 27
28 //These reflect current allocations of the bytes in glyph_info_t's var1 and
29 //var2.
30 uint8_t allocated_var_bytes[8];
31 const char *allocated_var_owner[8];
28 /*These reflect current allocations of the bytes in glyph_info_t's var1 and
29 var2. */
30 uint8_t allocated_var_bytes[8];
31 const char *allocated_var_owner[8];
32 32
33 //Text before / after the main buffer contents.
34 //Always in Unicode, and ordered outward.
35 //Index 0 is for "pre-context", 1 for "post-context".
36 #define HB_BUFFER_CONTEXT_LENGTH 5
37 hb_codepoint_t context[2][HB_BUFFER_CONTEXT_LENGTH];
38 unsigned context_len[2];
33 /*Text before / after the main buffer contents.
34 Always in Unicode, and ordered outward.
35 Index 0 is for "pre-context", 1 for "post-context". */
36 #define HB_BUFFER_CONTEXT_LENGTH 5
37 hb_codepoint_t context[2][HB_BUFFER_CONTEXT_LENGTH];
38 unsigned context_len[2];
39 39 }; };
40 40
41 void
42 hb_buffer_clear_positions(hb_buffer_t *buffer);
41 void hb_buffer_clear_positions(hb_buffer_t * buffer);
43 42 #endif #endif
File hb-buffer.c changed (mode: 100644) (index a3b6dec..24118c0)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <string.h> #include <string.h>
5 7 #include <stdlib.h> #include <stdlib.h>
6 8 #include <assert.h> #include <assert.h>
 
12 14 #include "hb-unicode-private.h" #include "hb-unicode-private.h"
13 15 #include "hb-utf-private.h" #include "hb-utf-private.h"
14 16
15 hb_bool_t
16 hb_segment_properties_equal(const hb_segment_properties_t *a,
17 const hb_segment_properties_t *b)
17 hb_bool_t hb_segment_properties_equal(const hb_segment_properties_t * a,
18 const hb_segment_properties_t * b)
18 19 { {
19 return a->direction == b->direction &&
20 a->script == b->script &&
21 a->language == b->language &&
22 a->reserved1 == b->reserved1 &&
23 a->reserved2 == b->reserved2;
20 return a->direction == b->direction &&
21 a->script == b->script &&
22 a->language == b->language &&
23 a->reserved1 == b->reserved1 && a->reserved2 == b->reserved2;
24 24 } }
25 25
26 unsigned
27 hb_buffer_get_length(hb_buffer_t *buffer)
26 unsigned hb_buffer_get_length(hb_buffer_t * buffer)
28 27 { {
29 return buffer->len;
28 return buffer->len;
30 29 } }
31 30
32 hb_glyph_info_t *
33 hb_buffer_get_glyph_infos(hb_buffer_t *buffer, unsigned *length)
31 hb_glyph_info_t *hb_buffer_get_glyph_infos(hb_buffer_t * buffer,
32 unsigned *length)
34 33 { {
35 if (length)
36 *length = buffer->len;
37 return buffer->info;
34 if (length)
35 *length = buffer->len;
36 return buffer->info;
38 37 } }
39 38
40 hb_glyph_position_t *
41 hb_buffer_get_glyph_positions(hb_buffer_t *buffer, unsigned *length)
39 hb_glyph_position_t *hb_buffer_get_glyph_positions(hb_buffer_t * buffer,
40 unsigned *length)
42 41 { {
43 if (!buffer->have_positions)
44 hb_buffer_clear_positions(buffer);
42 if (!buffer->have_positions)
43 hb_buffer_clear_positions(buffer);
45 44
46 if (length)
47 *length = buffer->len;
48 return buffer->pos;
45 if (length)
46 *length = buffer->len;
47 return buffer->pos;
49 48 } }
50 49
51 void
52 hb_buffer_set_unicode_funcs(hb_buffer_t *buffer,
53 hb_unicode_funcs_t *unicode_funcs)
50 void hb_buffer_set_unicode_funcs(hb_buffer_t * buffer,
51 hb_unicode_funcs_t * unicode_funcs)
54 52 { {
55 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
56 return;
53 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
54 return;
57 55
58 if (!unicode_funcs)
59 unicode_funcs = hb_unicode_funcs_get_default();
56 if (!unicode_funcs)
57 unicode_funcs = hb_unicode_funcs_get_default();
60 58
61 hb_unicode_funcs_reference(unicode_funcs);
62 hb_unicode_funcs_destroy(buffer->unicode);
63 buffer->unicode = unicode_funcs;
59 hb_unicode_funcs_reference(unicode_funcs);
60 hb_unicode_funcs_destroy(buffer->unicode);
61 buffer->unicode = unicode_funcs;
64 62 } }
65 63
66 static void
67 hb_buffer_reverse_range(hb_buffer_t *buffer,
68 unsigned start,
69 unsigned end)
64 void hb_buffer_reverse_range(hb_buffer_t * buffer, unsigned start, unsigned end)
70 65 { {
71 unsigned i, j;
66 unsigned i, j;
72 67
73 if (start == end - 1)
74 return;
68 if (start == end - 1)
69 return;
75 70
76 for (i = start, j = end - 1; i < j; i++, j--) {
77 hb_glyph_info_t t;
71 for (i = start, j = end - 1; i < j; i++, j--) {
72 hb_glyph_info_t t;
78 73
79 t = buffer->info[i];
80 buffer->info[i] = buffer->info[j];
81 buffer->info[j] = t;
82 }
74 t = buffer->info[i];
75 buffer->info[i] = buffer->info[j];
76 buffer->info[j] = t;
77 }
83 78
84 if (buffer->pos) {
85 for (i = start, j = end - 1; i < j; i++, j--) {
86 hb_glyph_position_t t;
79 if (buffer->pos) {
80 for (i = start, j = end - 1; i < j; i++, j--) {
81 hb_glyph_position_t t;
87 82
88 t = buffer->pos[i];
89 buffer->pos[i] = buffer->pos[j];
90 buffer->pos[j] = t;
91 }
92 }
83 t = buffer->pos[i];
84 buffer->pos[i] = buffer->pos[j];
85 buffer->pos[j] = t;
86 }
87 }
93 88 } }
94 89
95 void
96 hb_buffer_reverse(hb_buffer_t *buffer)
90 void hb_buffer_reverse(hb_buffer_t * buffer)
97 91 { {
98 if (!buffer->len)
99 return;
92 if (!buffer->len)
93 return;
100 94
101 hb_buffer_reverse_range(buffer, 0, buffer->len);
95 hb_buffer_reverse_range(buffer, 0, buffer->len);
102 96 } }
103 97
104 void
105 hb_buffer_set_direction(hb_buffer_t *buffer,
106 hb_direction_t direction)
107
98 void hb_buffer_set_direction(hb_buffer_t * buffer, hb_direction_t direction)
108 99 { {
109 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
110 return;
100 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
101 return;
111 102
112 buffer->props.direction = direction;
103 buffer->props.direction = direction;
113 104 } }
114 105
115 void
116 hb_buffer_clear_positions(hb_buffer_t *buffer)
106 void hb_buffer_clear_positions(hb_buffer_t * buffer)
117 107 { {
118 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
119 return;
108 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
109 return;
120 110
121 buffer->have_output = FALSE;
122 buffer->have_positions = TRUE;
111 buffer->have_output = FALSE;
112 buffer->have_positions = TRUE;
123 113
124 buffer->out_len = 0;
125 buffer->out_info = buffer->info;
114 buffer->out_len = 0;
115 buffer->out_info = buffer->info;
126 116
127 memset(buffer->pos, 0, sizeof(buffer->pos[0]) * buffer->len);
117 memset(buffer->pos, 0, sizeof(buffer->pos[0]) * buffer->len);
128 118 } }
129 119
120 /*XXX:should go in lib "global init"*/
130 121 static hb_buffer_t hb_buffer_nil = { static hb_buffer_t hb_buffer_nil = {
131 REF_CNT_INVALID_VAL,//ref_cnt
132 &_hb_unicode_funcs_nil,//unicode
133 HB_SEGMENT_PROPERTIES_DEFAULT,
134 HB_BUFFER_FLAG_DEFAULT,
135
136 HB_BUFFER_CONTENT_TYPE_INVALID,
137 FALSE,//in_error
138 FALSE,//have_output
139 FALSE//have_positions
140
141 //Zero is good enough for everything else.
122 REF_CNT_INVALID_VAL, /*ref_cnt */
123 &_hb_unicode_funcs_nil, /*unicode */
124 HB_SEGMENT_PROPERTIES_DEFAULT,
125 HB_BUFFER_FLAG_DEFAULT,
126
127 HB_BUFFER_CONTENT_TYPE_INVALID,
128 FALSE, /*in_error */
129 FALSE, /*have_output */
130 FALSE /*have_positions */
131 /*Zero is good enough for everything else. */
142 132 }; };
143 133
144 hb_buffer_t *
145 hb_buffer_get_empty(void)
134 hb_buffer_t *hb_buffer_get_empty(void)
146 135 { {
147 return &hb_buffer_nil;
136 return &hb_buffer_nil;
148 137 } }
149 138
150 void
151 hb_buffer_clear(hb_buffer_t *buffer)
139 void hb_buffer_clear(hb_buffer_t * buffer)
152 140 { {
153 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
154 return;
141 hb_segment_properties_t default_props;
142
143 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
144 return;
145
146 /*XXX:default_props = HB_SEGMENT_PROPERTIES_DEFAULT;*/
147 HB_SEGMENT_PROPERTIES_DEFAULT_INIT(default_props);
155 148
156 hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
157 buffer->props = default_props;
158 buffer->flags = HB_BUFFER_FLAG_DEFAULT;
149 buffer->props = default_props;
150 buffer->flags = HB_BUFFER_FLAG_DEFAULT;
159 151
160 buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
161 buffer->in_error = FALSE;
162 buffer->have_output = FALSE;
163 buffer->have_positions = FALSE;
152 buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
153 buffer->in_error = FALSE;
154 buffer->have_output = FALSE;
155 buffer->have_positions = FALSE;
164 156
165 buffer->idx = 0;
166 buffer->len = 0;
167 buffer->out_len = 0;
168 buffer->out_info = buffer->info;
157 buffer->idx = 0;
158 buffer->len = 0;
159 buffer->out_len = 0;
160 buffer->out_info = buffer->info;
169 161
170 buffer->serial = 0;
171 memset(buffer->allocated_var_bytes, 0, sizeof(buffer->allocated_var_bytes));
172 memset(buffer->allocated_var_owner, 0, sizeof(buffer->allocated_var_owner));
162 buffer->serial = 0;
163 memset(buffer->allocated_var_bytes, 0,
164 sizeof(buffer->allocated_var_bytes));
165 memset(buffer->allocated_var_owner, 0,
166 sizeof(buffer->allocated_var_owner));
173 167
174 memset(buffer->context, 0, sizeof(buffer->context));
175 memset(buffer->context_len, 0, sizeof(buffer->context_len));
168 memset(buffer->context, 0, sizeof(buffer->context));
169 memset(buffer->context_len, 0, sizeof(buffer->context_len));
176 170 } }
177 171
178 void
179 hb_buffer_reset(hb_buffer_t *buffer)
172 void hb_buffer_reset(hb_buffer_t * buffer)
180 173 { {
181 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
182 return;
174 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
175 return;
183 176
184 hb_unicode_funcs_destroy(buffer->unicode);
185 buffer->unicode = hb_unicode_funcs_get_default();
177 hb_unicode_funcs_destroy(buffer->unicode);
178 buffer->unicode = hb_unicode_funcs_get_default();
186 179
187 hb_buffer_clear(buffer);
180 hb_buffer_clear(buffer);
188 181 } }
189 182
190 void
191 hb_buffer_destroy(hb_buffer_t *buffer)
183 void hb_buffer_destroy(hb_buffer_t * buffer)
192 184 { {
193 if (!buffer)
194 return;
195 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
196 return;
197 hb_atomic_int32_add(&buffer->ref_cnt, -1);
198 if (hb_atomic_int32_get(&buffer->ref_cnt) > 0)
199 return;
200 hb_atomic_int32_set(&buffer->ref_cnt, REF_CNT_INVALID_VAL);
201
202 hb_unicode_funcs_destroy(buffer->unicode);
203
204 free(buffer->info);
205 free(buffer->pos);
206 free(buffer);
185 if (!buffer)
186 return;
187 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
188 return;
189 hb_atomic_int32_add(&buffer->ref_cnt, -1);
190 if (hb_atomic_int32_get(&buffer->ref_cnt) > 0)
191 return;
192 hb_atomic_int32_set(&buffer->ref_cnt, REF_CNT_INVALID_VAL);
193
194 hb_unicode_funcs_destroy(buffer->unicode);
195
196 free(buffer->info);
197 free(buffer->pos);
198 free(buffer);
207 199 } }
208 200
209 hb_buffer_t *
210 hb_buffer_create(void)
201 hb_buffer_t *hb_buffer_create(void)
211 202 { {
212 hb_buffer_t *buffer = calloc(1, sizeof(*buffer));
213 if (!buffer)
214 return hb_buffer_get_empty();
203 hb_buffer_t *buffer = calloc(1, sizeof(*buffer));
204 if (!buffer)
205 return hb_buffer_get_empty();
215 206
216 hb_atomic_int32_set(&buffer->ref_cnt, 1);
217 buffer->unicode = hb_unicode_funcs_get_empty();
207 hb_atomic_int32_set(&buffer->ref_cnt, 1);
208 buffer->unicode = hb_unicode_funcs_get_empty();
218 209
219 hb_buffer_reset(buffer);
220 return buffer;
210 hb_buffer_reset(buffer);
211 return buffer;
221 212 } }
222 213
223 void
224 hb_buffer_set_script(hb_buffer_t *buffer,
225 hb_script_t script)
214 void hb_buffer_set_script(hb_buffer_t * buffer, hb_script_t script)
226 215 { {
227 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
228 return;
216 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
217 return;
229 218
230 buffer->props.script = script;
219 buffer->props.script = script;
231 220 } }
232 221
233 //Here is how the buffer works internally:
234 //
235 //There are two info pointers: info and out_info. They always have
236 //the same allocated size, but different lengths.
237 //
238 //As an optimization, both info and out_info may point to the
239 //same piece of memory, which is owned by info. This remains the
240 //case as long as out_len doesn't exceed i at any time.
241 //In that case, swap_buffers() is no-op and the glyph operations operate
242 //mostly in-place.
243 //
244 //As soon as out_info gets longer than info, out_info is moved over
245 //to an alternate buffer (which we reuse the pos buffer for!), and its
246 //current contents (out_len entries) are copied to the new place.
247 //This should all remain transparent to the user. swap_buffers() then
248 //switches info and out_info.
249
250 static hb_bool_t
251 enlarge(hb_buffer_t *buffer, unsigned int size)
222 /*
223 Here is how the buffer works internally:
224
225 There are two info pointers: info and out_info. They always have
226 the same allocated size, but different lengths.
227
228 As an optimization, both info and out_info may point to the
229 same piece of memory, which is owned by info. This remains the
230 case as long as out_len doesn't exceed i at any time.
231 In that case, swap_buffers() is no-op and the glyph operations operate
232 mostly in-place.
233
234 As soon as out_info gets longer than info, out_info is moved over
235 to an alternate buffer (which we reuse the pos buffer for!), and its
236 current contents (out_len entries) are copied to the new place.
237 This should all remain transparent to the user. swap_buffers() then
238 switches info and out_info.
239 */
240
241 static hb_bool_t enlarge(hb_buffer_t * buffer, unsigned int size)
252 242 { {
253 if (buffer->in_error)
254 return FALSE;
243 unsigned new_allocated;
244 hb_glyph_position_t *new_pos;
245 hb_glyph_info_t *new_info;
246 hb_bool_t separate_out;
247
248 if (buffer->in_error)
249 return FALSE;
255 250
256 unsigned int new_allocated = buffer->allocated;
257 hb_glyph_position_t *new_pos = NULL;
258 hb_glyph_info_t *new_info = NULL;
259 hb_bool_t separate_out = buffer->out_info != buffer->info;
251 new_allocated = buffer->allocated;
252 new_pos = NULL;
253 new_info = NULL;
254 separate_out = buffer->out_info != buffer->info;
260 255
261 if (hb_unsigned_int_mul_overflows(size, sizeof(buffer->info[0])))
262 goto done;
256 if (hb_unsigned_int_mul_overflows(size, sizeof(buffer->info[0])))
257 goto done;
263 258
264 while (size >= new_allocated)
265 new_allocated += (new_allocated >> 1) + 32;
259 while (size >= new_allocated)
260 new_allocated += (new_allocated >> 1) + 32;
266 261
267 //ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0]));
268 if (hb_unsigned_int_mul_overflows(new_allocated, sizeof(buffer->info[0])))
269 goto done;
262 /*ASSERT_STATIC (sizeof (info[0]) == sizeof (pos[0])); */
263 if (hb_unsigned_int_mul_overflows
264 (new_allocated, sizeof(buffer->info[0])))
265 goto done;
270 266
271 new_pos = (hb_glyph_position_t*)realloc(buffer->pos, new_allocated
272 * sizeof(buffer->pos[0]));
273 new_info = (hb_glyph_info_t*)realloc(buffer->info, new_allocated
274 * sizeof(buffer->info[0]));
267 new_pos = (hb_glyph_position_t *) realloc(buffer->pos, new_allocated
268 * sizeof(buffer->pos[0]));
269 new_info = (hb_glyph_info_t *) realloc(buffer->info, new_allocated
270 * sizeof(buffer->info[0]));
275 271
276 272 done: done:
277 if (!new_pos || !new_info)
278 buffer->in_error = TRUE;
273 if (!new_pos || !new_info)
274 buffer->in_error = TRUE;
279 275
280 if (new_pos)
281 buffer->pos = new_pos;
276 if (new_pos)
277 buffer->pos = new_pos;
282 278
283 if (new_info)
284 buffer->info = new_info;
279 if (new_info)
280 buffer->info = new_info;
285 281
286 buffer->out_info = separate_out ? (hb_glyph_info_t*)buffer->pos
287 : buffer->info;
288 if (!buffer->in_error)
289 buffer->allocated = new_allocated;
290 return !buffer->in_error;
282 buffer->out_info = separate_out ? (hb_glyph_info_t *) buffer->pos
283 : buffer->info;
284 if (!buffer->in_error)
285 buffer->allocated = new_allocated;
286 return !buffer->in_error;
291 287 } }
292 288
293 static hb_bool_t
294 ensure(hb_buffer_t *buffer, unsigned int size)
289 static hb_bool_t ensure(hb_buffer_t * buffer, unsigned int size)
295 290 { {
296 return (size < buffer->allocated) ? TRUE : enlarge(buffer, size);
291 return (size < buffer->allocated) ? TRUE : enlarge(buffer, size);
297 292 } }
298 293
299 static void
300 clear_context(hb_buffer_t *buffer, unsigned int side)
294 static void clear_context(hb_buffer_t * buffer, unsigned int side)
301 295 { {
302 buffer->context_len[side] = 0;
296 buffer->context_len[side] = 0;
303 297 } }
304 298
305 static void
306 add(hb_buffer_t *buffer, hb_codepoint_t codepoint, unsigned int cluster)
299 static void add(hb_buffer_t * buffer, hb_codepoint_t codepoint,
300 unsigned int cluster)
307 301 { {
308 hb_glyph_info_t *glyph;
302 hb_glyph_info_t *glyph;
309 303
310 if (!ensure(buffer, buffer->len + 1)) return;
304 if (!ensure(buffer, buffer->len + 1))
305 return;
311 306
312 glyph = &buffer->info[buffer->len];
307 glyph = &buffer->info[buffer->len];
313 308
314 memset(glyph, 0, sizeof(*glyph));
315 glyph->codepoint = codepoint;
316 glyph->mask = 1;
317 glyph->cluster = cluster;
309 memset(glyph, 0, sizeof(*glyph));
310 glyph->codepoint = codepoint;
311 glyph->mask = 1;
312 glyph->cluster = cluster;
318 313
319 buffer->len++;
314 buffer->len++;
320 315 } }
321 316
322 317 struct utf { struct utf {
323 unsigned bytes_n;
324 unsigned (*len)(void *text);
325 void *(*ptr_offset)(void *text, unsigned offset);
326 void *(*prev)(void *text, void *start, hb_codepoint_t *unicode);
327 unsigned (*diff)(void *a, void *b);
328 void *(*next)(void *text, void *end, hb_codepoint_t *unicode);
318 unsigned bytes_n;
319 unsigned (*len) (void *text);
320 void *(*ptr_offset) (void *text, unsigned offset);
321 void *(*prev) (void *text, void *start, hb_codepoint_t * unicode);
322 unsigned (*diff) (void *a, void *b);
323 void *(*next) (void *text, void *end, hb_codepoint_t * unicode);
329 324 }; };
330 325
326 /*XXX:should go in lib "global init"*/
331 327 static struct utf utf8 = { static struct utf utf8 = {
332 sizeof(uint8_t),
333 hb_utf_strlen_utf8,
334 hb_utf_ptr_offset_utf8,
335 hb_utf_prev_utf8,
336 hb_utf_diff_utf8,
337 hb_utf_next_utf8
328 sizeof(uint8_t),
329 hb_utf_strlen_utf8,
330 hb_utf_ptr_offset_utf8,
331 hb_utf_prev_utf8,
332 hb_utf_diff_utf8,
333 hb_utf_next_utf8
338 334 }; };
339 335
336 /*XXX:should go in lib "global init"*/
340 337 static HB_UNUSED struct utf utf16 = { static HB_UNUSED struct utf utf16 = {
341 sizeof(uint16_t),
342 hb_utf_strlen_utf16,
343 hb_utf_ptr_offset_utf16,
344 hb_utf_prev_utf16,
345 hb_utf_diff_utf16,
346 hb_utf_next_utf16
338 sizeof(uint16_t),
339 hb_utf_strlen_utf16,
340 hb_utf_ptr_offset_utf16,
341 hb_utf_prev_utf16,
342 hb_utf_diff_utf16,
343 hb_utf_next_utf16
347 344 }; };
348 345
346 /*XXX:should go in lib "global init"*/
349 347 static HB_UNUSED struct utf utf32 = { static HB_UNUSED struct utf utf32 = {
350 sizeof(uint32_t),
351 hb_utf_strlen_utf32,
352 hb_utf_ptr_offset_utf32,
353 hb_utf_prev_utf32,
354 hb_utf_diff_utf32,
355 hb_utf_next_utf32
348 sizeof(uint32_t),
349 hb_utf_strlen_utf32,
350 hb_utf_ptr_offset_utf32,
351 hb_utf_prev_utf32,
352 hb_utf_diff_utf32,
353 hb_utf_next_utf32
356 354 }; };
357 355
358 //to unroll the original c++, could have used a macro
359 //ASSEMBLY:maybe worth to be unrolled to fine tuned assembly
360 static void
361 hb_buffer_add_utf(hb_buffer_t *buffer,
362 struct utf *utf,
363 void *text,
364 int text_length,
365 unsigned item_offset,
366 int item_length)
356 /*to unroll the original c++, could have used a macro
357 ASSEMBLY:maybe worth to be unrolled to fine tuned assembly*/
358 static void hb_buffer_add_utf(hb_buffer_t * buffer, struct utf *utf, void *text,
359 int text_length, unsigned item_offset,
360 int item_length)
367 361 { {
368 assert(buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
369 (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
370
371 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
372 return;
373
374 if (text_length == -1)
375 text_length = utf->len(text);
376
377 if (item_length == -1)
378 item_length = text_length - item_offset;
379
380 ensure(buffer, buffer->len + item_length * utf->bytes_n / 4);
381
382 //If buffer is empty and pre-context provided, install it.
383 //This check is written this way, to make sure people can
384 //provide pre-context in one add_utf() call, then provide
385 //text in a follow-up call. See:
386 //
387 //https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13
388 if (!buffer->len && item_offset > 0) {
389 //Add pre-context
390 clear_context(buffer, 0);
391 void *prev = utf->ptr_offset(text, item_offset);
392 void *start = text;
393 while (start < prev && buffer->context_len[0] < HB_BUFFER_CONTEXT_LENGTH) {
394 hb_codepoint_t u;
395 prev = utf->prev(prev, start, &u);
396 buffer->context[0][buffer->context_len[0]++] = u;
397 }
398 }
399
400 void *next = utf->ptr_offset(text, item_offset);
401 void *end = utf->ptr_offset(next, item_length);
402 while (next < end) {
403 hb_codepoint_t u;
404 void *old_next = next;
405 next = utf->next(next, end, &u);
406 add(buffer, u, utf->diff(old_next, text));
407 }
408
409 //Add post-context
410 clear_context(buffer, 1);
411 end = utf->ptr_offset(text, text_length);
412 end = text + text_length;
413 while (next < end && buffer->context_len[1] < HB_BUFFER_CONTEXT_LENGTH) {
414 hb_codepoint_t u;
415 next = utf->next(next, end, &u);
416 buffer->context[1][buffer->context_len[1]++] = u;
417 }
418
419 buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
362 void *next;
363 void *end;
364
365 assert(buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
366 (!buffer->len
367 && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
368
369 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
370 return;
371
372 if (text_length == -1)
373 text_length = utf->len(text);
374
375 if (item_length == -1)
376 item_length = text_length - item_offset;
377
378 ensure(buffer, buffer->len + item_length * utf->bytes_n / 4);
379
380 /*If buffer is empty and pre-context provided, install it.
381 This check is written this way, to make sure people can
382 provide pre-context in one add_utf() call, then provide
383 text in a follow-up call. See:
384
385 https://bugzilla.mozilla.org/show_bug.cgi?id=801410#c13 */
386 if (!buffer->len && item_offset > 0) {
387 void *prev;
388 void *start;
389
390 /*Add pre-context */
391 clear_context(buffer, 0);
392 prev = utf->ptr_offset(text, item_offset);
393 start = text;
394 while (start < prev
395 && buffer->context_len[0] < HB_BUFFER_CONTEXT_LENGTH) {
396 hb_codepoint_t u;
397 prev = utf->prev(prev, start, &u);
398 buffer->context[0][buffer->context_len[0]++] = u;
399 }
400 }
401
402 next = utf->ptr_offset(text, item_offset);
403 end = utf->ptr_offset(next, item_length);
404 while (next < end) {
405 hb_codepoint_t u;
406 void *old_next;
407
408 old_next = next;
409 next = utf->next(next, end, &u);
410 add(buffer, u, utf->diff(old_next, text));
411 }
412
413 /*Add post-context */
414 clear_context(buffer, 1);
415 end = utf->ptr_offset(text, text_length);
416 while (next < end && buffer->context_len[1] < HB_BUFFER_CONTEXT_LENGTH) {
417 hb_codepoint_t u;
418
419 next = utf->next(next, end, &u);
420 buffer->context[1][buffer->context_len[1]++] = u;
421 }
422
423 buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
420 424 } }
421 425
422 void
423 hb_buffer_add_utf8(hb_buffer_t *buffer,
424 const char *text,
425 int text_length,
426 unsigned int item_offset,
427 int item_length)
426 void hb_buffer_add_utf8(hb_buffer_t * buffer, const char *text, int text_length,
427 unsigned int item_offset, int item_length)
428 428 { {
429 hb_buffer_add_utf(buffer,
430 &utf8,
431 (void*)text,
432 text_length,
433 item_offset,
434 item_length);
429 hb_buffer_add_utf(buffer, &utf8, (void *)text, text_length, item_offset,
430 item_length);
435 431 } }
436 432
437 void
438 hb_buffer_set_flags(hb_buffer_t *buffer,
439 hb_buffer_flags_t flags)
433 void hb_buffer_set_flags(hb_buffer_t * buffer, hb_buffer_flags_t flags)
440 434 { {
441 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
442 return;
435 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
436 return;
443 437
444 buffer->flags = flags;
438 buffer->flags = flags;
445 439 } }
446 440
447 void
448 hb_buffer_set_language(hb_buffer_t *buffer,
449 hb_language_t language)
441 void hb_buffer_set_language(hb_buffer_t * buffer, hb_language_t language)
450 442 { {
451 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
452 return;
443 if (hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
444 return;
453 445
454 buffer->props.language = language;
446 buffer->props.language = language;
455 447 } }
456 448
457 hb_direction_t
458 hb_buffer_get_direction(hb_buffer_t *buffer)
449 hb_direction_t hb_buffer_get_direction(hb_buffer_t * buffer)
459 450 { {
460 return buffer->props.direction;
451 return buffer->props.direction;
461 452 } }
462 453
463 void
464 hb_buffer_add(hb_buffer_t *buffer,
465 hb_codepoint_t codepoint,
466 unsigned int cluster)
454 void hb_buffer_add(hb_buffer_t * buffer, hb_codepoint_t codepoint,
455 unsigned int cluster)
467 456 { {
468 add(buffer, codepoint, cluster);
469 clear_context(buffer, 1);
457 add(buffer, codepoint, cluster);
458 clear_context(buffer, 1);
470 459 } }
File hb-buffer.h changed (mode: 100644) (index 87c4ce5..d3a2512)
... ... typedef struct hb_segment_properties_t {
77 77 NULL, \ NULL, \
78 78 NULL} NULL}
79 79
80 hb_bool_t
80 HB_EXTERN hb_bool_t
81 81 hb_segment_properties_equal (const hb_segment_properties_t *a, hb_segment_properties_equal (const hb_segment_properties_t *a,
82 82 const hb_segment_properties_t *b); const hb_segment_properties_t *b);
83 83
84 unsigned int
84 HB_EXTERN unsigned int
85 85 hb_segment_properties_hash (const hb_segment_properties_t *p); hb_segment_properties_hash (const hb_segment_properties_t *p);
86 86
87 87
 
... ... hb_segment_properties_hash (const hb_segment_properties_t *p);
92 92
93 93 typedef struct hb_buffer_t hb_buffer_t; typedef struct hb_buffer_t hb_buffer_t;
94 94
95 hb_buffer_t *
95 HB_EXTERN hb_buffer_t *
96 96 hb_buffer_create (void); hb_buffer_create (void);
97 97
98 hb_buffer_t *
98 HB_EXTERN hb_buffer_t *
99 99 hb_buffer_get_empty (void); hb_buffer_get_empty (void);
100 100
101 hb_buffer_t *
101 HB_EXTERN hb_buffer_t *
102 102 hb_buffer_reference (hb_buffer_t *buffer); hb_buffer_reference (hb_buffer_t *buffer);
103 103
104 void
104 HB_EXTERN void
105 105 hb_buffer_destroy (hb_buffer_t *buffer); hb_buffer_destroy (hb_buffer_t *buffer);
106 106
107 hb_bool_t
107 HB_EXTERN hb_bool_t
108 108 hb_buffer_set_user_data (hb_buffer_t *buffer, hb_buffer_set_user_data (hb_buffer_t *buffer,
109 109 hb_user_data_key_t *key, hb_user_data_key_t *key,
110 110 void * data, void * data,
111 111 hb_destroy_func_t destroy, hb_destroy_func_t destroy,
112 112 hb_bool_t replace); hb_bool_t replace);
113 113
114 void *
114 HB_EXTERN void *
115 115 hb_buffer_get_user_data (hb_buffer_t *buffer, hb_buffer_get_user_data (hb_buffer_t *buffer,
116 116 hb_user_data_key_t *key); hb_user_data_key_t *key);
117 117
 
... ... typedef enum {
122 122 HB_BUFFER_CONTENT_TYPE_GLYPHS HB_BUFFER_CONTENT_TYPE_GLYPHS
123 123 } hb_buffer_content_type_t; } hb_buffer_content_type_t;
124 124
125 void
125 HB_EXTERN void
126 126 hb_buffer_set_content_type (hb_buffer_t *buffer, hb_buffer_set_content_type (hb_buffer_t *buffer,
127 127 hb_buffer_content_type_t content_type); hb_buffer_content_type_t content_type);
128 128
129 hb_buffer_content_type_t
129 HB_EXTERN hb_buffer_content_type_t
130 130 hb_buffer_get_content_type (hb_buffer_t *buffer); hb_buffer_get_content_type (hb_buffer_t *buffer);
131 131
132 132
133 void
133 HB_EXTERN void
134 134 hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
135 135 hb_unicode_funcs_t *unicode_funcs); hb_unicode_funcs_t *unicode_funcs);
136 136
137 hb_unicode_funcs_t *
137 HB_EXTERN hb_unicode_funcs_t *
138 138 hb_buffer_get_unicode_funcs (hb_buffer_t *buffer); hb_buffer_get_unicode_funcs (hb_buffer_t *buffer);
139 139
140 void
140 HB_EXTERN void
141 141 hb_buffer_set_direction (hb_buffer_t *buffer, hb_buffer_set_direction (hb_buffer_t *buffer,
142 142 hb_direction_t direction); hb_direction_t direction);
143 143
144 hb_direction_t
144 HB_EXTERN hb_direction_t
145 145 hb_buffer_get_direction (hb_buffer_t *buffer); hb_buffer_get_direction (hb_buffer_t *buffer);
146 146
147 void
147 HB_EXTERN void
148 148 hb_buffer_set_script (hb_buffer_t *buffer, hb_buffer_set_script (hb_buffer_t *buffer,
149 149 hb_script_t script); hb_script_t script);
150 150
151 hb_script_t
151 HB_EXTERN hb_script_t
152 152 hb_buffer_get_script (hb_buffer_t *buffer); hb_buffer_get_script (hb_buffer_t *buffer);
153 153
154 void
154 HB_EXTERN void
155 155 hb_buffer_set_language (hb_buffer_t *buffer, hb_buffer_set_language (hb_buffer_t *buffer,
156 156 hb_language_t language); hb_language_t language);
157 157
158 158
159 hb_language_t
159 HB_EXTERN hb_language_t
160 160 hb_buffer_get_language (hb_buffer_t *buffer); hb_buffer_get_language (hb_buffer_t *buffer);
161 161
162 void
162 HB_EXTERN void
163 163 hb_buffer_set_segment_properties (hb_buffer_t *buffer, hb_buffer_set_segment_properties (hb_buffer_t *buffer,
164 164 const hb_segment_properties_t *props); const hb_segment_properties_t *props);
165 165
166 void
166 HB_EXTERN void
167 167 hb_buffer_get_segment_properties (hb_buffer_t *buffer, hb_buffer_get_segment_properties (hb_buffer_t *buffer,
168 168 hb_segment_properties_t *props); hb_segment_properties_t *props);
169 169
170 void
170 HB_EXTERN void
171 171 hb_buffer_guess_segment_properties (hb_buffer_t *buffer); hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
172 172
173 173
174 /*
175 * Since: 0.9.20
176 */
174 177 typedef enum { /*< flags >*/ typedef enum { /*< flags >*/
175 HB_BUFFER_FLAG_DEFAULT = 0x00000000,
176 HB_BUFFER_FLAG_BOT = 0x00000001, /* Beginning-of-text */
177 HB_BUFFER_FLAG_EOT = 0x00000002, /* End-of-text */
178 HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004
178 HB_BUFFER_FLAG_DEFAULT = 0x00000000u,
179 HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */
180 HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */
181 HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u
179 182 } hb_buffer_flags_t; } hb_buffer_flags_t;
180 183
181 void
184 HB_EXTERN void
182 185 hb_buffer_set_flags (hb_buffer_t *buffer, hb_buffer_set_flags (hb_buffer_t *buffer,
183 186 hb_buffer_flags_t flags); hb_buffer_flags_t flags);
184 187
185 hb_buffer_flags_t
188 HB_EXTERN hb_buffer_flags_t
186 189 hb_buffer_get_flags (hb_buffer_t *buffer); hb_buffer_get_flags (hb_buffer_t *buffer);
187 190
191 /*
192 * Since: 0.9.42
193 */
194 typedef enum {
195 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0,
196 HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1,
197 HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2,
198 HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES
199 } hb_buffer_cluster_level_t;
200
201 HB_EXTERN void
202 hb_buffer_set_cluster_level (hb_buffer_t *buffer,
203 hb_buffer_cluster_level_t cluster_level);
204
205 HB_EXTERN hb_buffer_cluster_level_t
206 hb_buffer_get_cluster_level (hb_buffer_t *buffer);
207
208 #define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu
209
210 /* Sets codepoint used to replace invalid UTF-8/16/32 entries.
211 * Default is 0xFFFDu. */
212 HB_EXTERN void
213 hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer,
214 hb_codepoint_t replacement);
215
216 HB_EXTERN hb_codepoint_t
217 hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer);
218
188 219
189 220 /* Resets the buffer. Afterwards it's as if it was just created, /* Resets the buffer. Afterwards it's as if it was just created,
190 221 * except that it has a larger buffer allocated perhaps... */ * except that it has a larger buffer allocated perhaps... */
191 void
222 HB_EXTERN void
192 223 hb_buffer_reset (hb_buffer_t *buffer); hb_buffer_reset (hb_buffer_t *buffer);
193 224
194 /* Like reset, but does NOT clear unicode_funcs. */
195 void
225 /* Like reset, but does NOT clear unicode_funcs and replacement_codepoint. */
226 HB_EXTERN void
196 227 hb_buffer_clear_contents (hb_buffer_t *buffer); hb_buffer_clear_contents (hb_buffer_t *buffer);
197 228
198 229 /* Returns false if allocation failed */ /* Returns false if allocation failed */
199 hb_bool_t
230 HB_EXTERN hb_bool_t
200 231 hb_buffer_pre_allocate (hb_buffer_t *buffer, hb_buffer_pre_allocate (hb_buffer_t *buffer,
201 232 unsigned int size); unsigned int size);
202 233
203 234
204 235 /* Returns false if allocation has failed before */ /* Returns false if allocation has failed before */
205 hb_bool_t
236 HB_EXTERN hb_bool_t
206 237 hb_buffer_allocation_successful (hb_buffer_t *buffer); hb_buffer_allocation_successful (hb_buffer_t *buffer);
207 238
208 void
239 HB_EXTERN void
209 240 hb_buffer_reverse (hb_buffer_t *buffer); hb_buffer_reverse (hb_buffer_t *buffer);
210 241
211 void
242 HB_EXTERN void
243 hb_buffer_reverse_range (hb_buffer_t *buffer,
244 unsigned int start, unsigned int end);
245
246 HB_EXTERN void
212 247 hb_buffer_reverse_clusters (hb_buffer_t *buffer); hb_buffer_reverse_clusters (hb_buffer_t *buffer);
213 248
214 249
215 250 /* Filling the buffer in */ /* Filling the buffer in */
216 251
217 void
252 HB_EXTERN void
218 253 hb_buffer_add (hb_buffer_t *buffer, hb_buffer_add (hb_buffer_t *buffer,
219 254 hb_codepoint_t codepoint, hb_codepoint_t codepoint,
220 255 unsigned int cluster); unsigned int cluster);
221 256
222 void
257 HB_EXTERN void
223 258 hb_buffer_add_utf8 (hb_buffer_t *buffer, hb_buffer_add_utf8 (hb_buffer_t *buffer,
224 259 const char *text, const char *text,
225 260 int text_length, int text_length,
226 261 unsigned int item_offset, unsigned int item_offset,
227 262 int item_length); int item_length);
228 263
229 void
264 HB_EXTERN void
230 265 hb_buffer_add_utf16 (hb_buffer_t *buffer, hb_buffer_add_utf16 (hb_buffer_t *buffer,
231 266 const uint16_t *text, const uint16_t *text,
232 267 int text_length, int text_length,
233 268 unsigned int item_offset, unsigned int item_offset,
234 269 int item_length); int item_length);
235 270
236 void
271 HB_EXTERN void
237 272 hb_buffer_add_utf32 (hb_buffer_t *buffer, hb_buffer_add_utf32 (hb_buffer_t *buffer,
238 273 const uint32_t *text, const uint32_t *text,
239 274 int text_length, int text_length,
240 275 unsigned int item_offset, unsigned int item_offset,
241 276 int item_length); int item_length);
242 277
278 /* Allows only access to first 256 Unicode codepoints. */
279 HB_EXTERN void
280 hb_buffer_add_latin1 (hb_buffer_t *buffer,
281 const uint8_t *text,
282 int text_length,
283 unsigned int item_offset,
284 int item_length);
285
286 /* Like add_utf32 but does NOT check for invalid Unicode codepoints. */
287 HB_EXTERN void
288 hb_buffer_add_codepoints (hb_buffer_t *buffer,
289 const hb_codepoint_t *text,
290 int text_length,
291 unsigned int item_offset,
292 int item_length);
293
243 294
244 295 /* Clears any new items added at the end */ /* Clears any new items added at the end */
245 hb_bool_t
296 HB_EXTERN hb_bool_t
246 297 hb_buffer_set_length (hb_buffer_t *buffer, hb_buffer_set_length (hb_buffer_t *buffer,
247 298 unsigned int length); unsigned int length);
248 299
249 300 /* Return value valid as long as buffer not modified */ /* Return value valid as long as buffer not modified */
250 unsigned int
301 HB_EXTERN unsigned int
251 302 hb_buffer_get_length (hb_buffer_t *buffer); hb_buffer_get_length (hb_buffer_t *buffer);
252 303
253 304 /* Getting glyphs out of the buffer */ /* Getting glyphs out of the buffer */
254 305
255 306 /* Return value valid as long as buffer not modified */ /* Return value valid as long as buffer not modified */
256 hb_glyph_info_t *
307 HB_EXTERN hb_glyph_info_t *
257 308 hb_buffer_get_glyph_infos (hb_buffer_t *buffer, hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
258 309 unsigned int *length); unsigned int *length);
259 310
260 311 /* Return value valid as long as buffer not modified */ /* Return value valid as long as buffer not modified */
261 hb_glyph_position_t *
312 HB_EXTERN hb_glyph_position_t *
262 313 hb_buffer_get_glyph_positions (hb_buffer_t *buffer, hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
263 314 unsigned int *length); unsigned int *length);
264 315
 
... ... hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
266 317 /* Reorders a glyph buffer to have canonical in-cluster glyph order / position. /* Reorders a glyph buffer to have canonical in-cluster glyph order / position.
267 318 * The resulting clusters should behave identical to pre-reordering clusters. * The resulting clusters should behave identical to pre-reordering clusters.
268 319 * NOTE: This has nothing to do with Unicode normalization. */ * NOTE: This has nothing to do with Unicode normalization. */
269 void
320 HB_EXTERN void
270 321 hb_buffer_normalize_glyphs (hb_buffer_t *buffer); hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
271 322
272 323
 
... ... hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
274 325 * Serialize * Serialize
275 326 */ */
276 327
328 /*
329 * Since: 0.9.20
330 */
277 331 typedef enum { /*< flags >*/ typedef enum { /*< flags >*/
278 HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000,
279 HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001,
280 HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002,
281 HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004
332 HB_BUFFER_SERIALIZE_FLAG_DEFAULT = 0x00000000u,
333 HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u,
334 HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u,
335 HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u,
336 HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u
282 337 } hb_buffer_serialize_flags_t; } hb_buffer_serialize_flags_t;
283 338
284 339 typedef enum { typedef enum {
 
... ... typedef enum {
288 343 } hb_buffer_serialize_format_t; } hb_buffer_serialize_format_t;
289 344
290 345 /* len=-1 means str is NUL-terminated. */ /* len=-1 means str is NUL-terminated. */
291 hb_buffer_serialize_format_t
346 HB_EXTERN hb_buffer_serialize_format_t
292 347 hb_buffer_serialize_format_from_string (const char *str, int len); hb_buffer_serialize_format_from_string (const char *str, int len);
293 348
294 const char *
349 HB_EXTERN const char *
295 350 hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format); hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format);
296 351
297 const char **
352 HB_EXTERN const char **
298 353 hb_buffer_serialize_list_formats (void); hb_buffer_serialize_list_formats (void);
299 354
300 355 /* Returns number of items, starting at start, that were serialized. */ /* Returns number of items, starting at start, that were serialized. */
301 unsigned int
356 HB_EXTERN unsigned int
302 357 hb_buffer_serialize_glyphs (hb_buffer_t *buffer, hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
303 358 unsigned int start, unsigned int start,
304 359 unsigned int end, unsigned int end,
 
... ... hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
309 364 hb_buffer_serialize_format_t format, hb_buffer_serialize_format_t format,
310 365 hb_buffer_serialize_flags_t flags); hb_buffer_serialize_flags_t flags);
311 366
312 hb_bool_t
367 HB_EXTERN hb_bool_t
313 368 hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
314 369 const char *buf, const char *buf,
315 370 int buf_len, /* -1 means nul-terminated */ int buf_len, /* -1 means nul-terminated */
File hb-common.c changed (mode: 100644) (index f5141f5..92b54db)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #define _GNU_SOURCE #define _GNU_SOURCE
5 7 #include <string.h> #include <string.h>
6 8 #include <stdlib.h> #include <stdlib.h>
 
9 11 #include "hb-private.h" #include "hb-private.h"
10 12 #include "hb-atomic-private.h" #include "hb-atomic-private.h"
11 13
12 //this is actually hb_language_t type
14 /*this is actually hb_language_t type*/
13 15 struct hb_language_impl_t { struct hb_language_impl_t {
14 const char s[1];
16 const char s[1];
15 17 }; };
16 18
19 /*XXX:should go in lib "global init"*/
17 20 static const char canon_map[256] = { static const char canon_map[256] = {
18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
21 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
22 '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
23 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
24 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
25 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
22 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
24 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
25 '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
26 'n', 'o',
27 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
28 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
29 'o',
30 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
26 31 }; };
27 32
28 static hb_bool_t
29 lang_equal(hb_language_t v1,
30 const void *v2)
33 static hb_bool_t lang_equal(hb_language_t v1, const void *v2)
31 34 { {
32 const unsigned char *p1 = (const unsigned char*)v1;
33 const unsigned char *p2 = (const unsigned char*)v2;
35 const unsigned char *p1;
36 const unsigned char *p2;
34 37
35 while (*p1 && *p1 == canon_map[*p2])
36 p1++, p2++;
37 return *p1 == canon_map[*p2];
38 p1 = (const unsigned char *)v1;
39 p2 = (const unsigned char *)v2;
40
41 while (*p1 && *p1 == canon_map[*p2])
42 p1++, p2++;
43 return *p1 == canon_map[*p2];
38 44 } }
39 45
40 46 struct hb_language_item_t { struct hb_language_item_t {
41
42 struct hb_language_item_t *next;
43 hb_language_t lang;
47 struct hb_language_item_t *next;
48 hb_language_t lang;
44 49 }; };
45 50
46 static hb_language_t
47 lang_assign(const char *s)
51 static hb_language_t lang_assign(const char *s)
48 52 { {
49 hb_language_t lang = (hb_language_t)strdup(s);
50 for (unsigned char *p = (unsigned char *)lang; *p; p++)
51 *p = canon_map[*p];
52 return lang;
53 unsigned char *p;
54
55 hb_language_t lang = (hb_language_t) strdup(s);
56 for (p = (unsigned char *)lang; *p; p++)
57 *p = canon_map[*p];
58 return lang;
53 59 } }
54 60
55 /* Thread-safe lock-free language list */
61 /*Thread-safe lock-free language list*/
56 62
57 63 static struct hb_language_item_t *lang_items; static struct hb_language_item_t *lang_items;
58 64
59 static struct hb_language_item_t *
60 language_item_find_or_insert(const char *key)
65 static struct hb_language_item_t *language_item_find_or_insert(const char *key)
61 66 { {
62 struct hb_language_item_t *first_lang_item = hb_atomic_ptr_get(&lang_items);
63
64 while (1) {
65 for (struct hb_language_item_t *lang_item = first_lang_item; lang_item;
66 lang_item = lang_item->next)
67 if (lang_equal(lang_item->lang, key))
68 return lang_item;
69
70 //Not found; allocate one.
71 struct hb_language_item_t *lang_item = calloc(1, sizeof(*lang_item));
72 if (!lang_item)
73 return NULL;
74 lang_item->next = first_lang_item;
75 lang_item->lang = lang_assign(key);
76
77 if (hb_atomic_ptr_cmpexch(&lang_items, &first_lang_item, &lang_item))
78 return lang_item;
79 free (lang_item);
80 }
67 struct hb_language_item_t *first_lang_item =
68 hb_atomic_ptr_get(&lang_items);
69
70 while (1) {
71 struct hb_language_item_t *lang_item;
72
73 for (lang_item = first_lang_item; lang_item;
74 lang_item = lang_item->next)
75 if (lang_equal(lang_item->lang, key))
76 return lang_item;
77
78 /*Not found; allocate one. */
79 lang_item = calloc(1, sizeof(*lang_item));
80 if (!lang_item)
81 return NULL;
82 lang_item->next = first_lang_item;
83 lang_item->lang = lang_assign(key);
84
85 if (hb_atomic_ptr_cmpexch
86 (&lang_items, &first_lang_item, &lang_item))
87 return lang_item;
88 free(lang_item);
89 }
81 90 } }
82 91
83 hb_language_t
84 hb_language_from_string(const char *str, int len)
92 hb_language_t hb_language_from_string(const char *str, int len)
85 93 { {
86 if (!str || !len || !*str)
87 return HB_LANGUAGE_INVALID;
94 struct hb_language_item_t *item;
95
96 if (!str || !len || !*str)
97 return HB_LANGUAGE_INVALID;
88 98
89 if (len >= 0) {
90 char strbuf[64];
91 len = MIN(len, (int)sizeof(strbuf) - 1);
92 str = (char*)memcpy(strbuf, str, len);
93 strbuf[len] = '\0';
94 }
99 if (len >= 0) {
100 char strbuf[64];
95 101
96 struct hb_language_item_t *item = language_item_find_or_insert(str);
102 len = MIN(len, (int)sizeof(strbuf) - 1);
103 str = (char *)memcpy(strbuf, str, len);
104 strbuf[len] = '\0';
105 }
97 106
98 return item ? item->lang : HB_LANGUAGE_INVALID;
107 item = language_item_find_or_insert(str);
108 return item ? item->lang : HB_LANGUAGE_INVALID;
109 }
110
111 hb_tag_t hb_tag_from_string(const char *str, int len)
112 {
113 char tag[4];
114 unsigned i;
115
116 if (!str || !len || !*str)
117 return HB_TAG_NONE;
118
119 if (len < 0 || len > 4)
120 len = 4;
121 for (i = 0; i < (unsigned)len && str[i]; ++i)
122 tag[i] = str[i];
123 for (; i < 4; ++i)
124 tag[i] = ' ';
125 return HB_TAG_CHAR4(tag);
99 126 } }
100 127
101 hb_tag_t
102 hb_tag_from_string(const char *str, int len)
128 const char *hb_language_to_string(hb_language_t language)
103 129 { {
104 char tag[4];
105 unsigned i;
106
107 if (!str || !len || !*str)
108 return HB_TAG_NONE;
109
110 if (len < 0 || len > 4)
111 len = 4;
112 for (i = 0; i < (unsigned)len && str[i]; ++i)
113 tag[i] = str[i];
114 for (; i < 4; ++i)
115 tag[i] = ' ';
116 return HB_TAG_CHAR4(tag);
130 /*This is actually NULL-safe! */
131 return language->s;
117 132 } }
118 133
119 const char *
120 hb_language_to_string(hb_language_t language)
134 hb_bool_t hb_version_atleast(unsigned int major,unsigned int minor,unsigned int micro)
121 135 { {
122 //This is actually NULL-safe!
123 return language->s;
136 return HB_VERSION_ATLEAST(major,minor,micro);
124 137 } }
File hb-common.h changed (mode: 100644) (index 40c1887..af17d78)
... ... typedef union _hb_var_int_t {
90 90
91 91 typedef uint32_t hb_tag_t; typedef uint32_t hb_tag_t;
92 92
93 #define HB_TAG(a,b,c,d) ((hb_tag_t)((((uint8_t)(a))<<24)|(((uint8_t)(b))<<16)|(((uint8_t)(c))<<8)|((uint8_t)(d))))
93 #define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
94 94 #define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag)) #define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
95 95
96 96 #define HB_TAG_NONE HB_TAG(0,0,0,0) #define HB_TAG_NONE HB_TAG(0,0,0,0)
97 #define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
98 #define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff)
97 99
98 100 /* len=-1 means str is NUL-terminated. */ /* len=-1 means str is NUL-terminated. */
99 hb_tag_t
101 HB_EXTERN hb_tag_t
100 102 hb_tag_from_string (const char *str, int len); hb_tag_from_string (const char *str, int len);
101 103
102 104 /* buf should have 4 bytes. */ /* buf should have 4 bytes. */
103 void
105 HB_EXTERN void
104 106 hb_tag_to_string (hb_tag_t tag, char *buf); hb_tag_to_string (hb_tag_t tag, char *buf);
105 107
106 108
 
... ... typedef enum {
115 117 } hb_direction_t; } hb_direction_t;
116 118
117 119 /* len=-1 means str is NUL-terminated */ /* len=-1 means str is NUL-terminated */
118 hb_direction_t
120 HB_EXTERN hb_direction_t
119 121 hb_direction_from_string (const char *str, int len); hb_direction_from_string (const char *str, int len);
120 122
121 const char *
123 HB_EXTERN const char *
122 124 hb_direction_to_string (hb_direction_t direction); hb_direction_to_string (hb_direction_t direction);
123 125
126 #define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
127 /* Direction must be valid for the following */
124 128 #define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4) #define HB_DIRECTION_IS_HORIZONTAL(dir) ((((unsigned int) (dir)) & ~1U) == 4)
125 129 #define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6) #define HB_DIRECTION_IS_VERTICAL(dir) ((((unsigned int) (dir)) & ~1U) == 6)
126 130 #define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4) #define HB_DIRECTION_IS_FORWARD(dir) ((((unsigned int) (dir)) & ~2U) == 4)
127 131 #define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5) #define HB_DIRECTION_IS_BACKWARD(dir) ((((unsigned int) (dir)) & ~2U) == 5)
128 #define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4)
129 #define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1)) /* Direction must be valid */
132 #define HB_DIRECTION_REVERSE(dir) ((hb_direction_t) (((unsigned int) (dir)) ^ 1))
130 133
131 134
132 135 /* hb_language_t */ /* hb_language_t */
 
... ... hb_direction_to_string (hb_direction_t direction);
134 137 typedef const struct hb_language_impl_t *hb_language_t; typedef const struct hb_language_impl_t *hb_language_t;
135 138
136 139 /* len=-1 means str is NUL-terminated */ /* len=-1 means str is NUL-terminated */
137 hb_language_t
140 HB_EXTERN hb_language_t
138 141 hb_language_from_string (const char *str, int len); hb_language_from_string (const char *str, int len);
139 142
140 const char *
143 HB_EXTERN const char *
141 144 hb_language_to_string (hb_language_t language); hb_language_to_string (hb_language_t language);
142 145
143 146 #define HB_LANGUAGE_INVALID ((hb_language_t) NULL) #define HB_LANGUAGE_INVALID ((hb_language_t) NULL)
144 147
145 hb_language_t
148 HB_EXTERN hb_language_t
146 149 hb_language_get_default (void); hb_language_get_default (void);
147 150
148 151
 
... ... typedef enum
269 272 /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'),
270 273 /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'),
271 274
272 /* No script set. */
273 /*---*/ HB_SCRIPT_INVALID = HB_TAG_NONE
274 } hb_script_t;
275
276 /* These are moved out of hb_script_t because glib-mkenums chokes otherwise. */
277 #if 0
275 /*
276 * Since: 0.9.30
277 */
278 278 /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'),
279 279 /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'),
280 280 /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'),
 
... ... typedef enum
286 286 /*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'), /*7.0*/ HB_SCRIPT_MAHAJANI = HB_TAG ('M','a','h','j'),
287 287 /*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'), /*7.0*/ HB_SCRIPT_MANICHAEAN = HB_TAG ('M','a','n','i'),
288 288 /*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'), /*7.0*/ HB_SCRIPT_MENDE_KIKAKUI = HB_TAG ('M','e','n','d'),
289 /*7.0*/ HB_SCRIPT_MODI = ???
289 /*7.0*/ HB_SCRIPT_MODI = HB_TAG ('M','o','d','i'),
290 290 /*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'), /*7.0*/ HB_SCRIPT_MRO = HB_TAG ('M','r','o','o'),
291 291 /*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'), /*7.0*/ HB_SCRIPT_NABATAEAN = HB_TAG ('N','b','a','t'),
292 292 /*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'), /*7.0*/ HB_SCRIPT_OLD_NORTH_ARABIAN = HB_TAG ('N','a','r','b'),
293 293 /*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'), /*7.0*/ HB_SCRIPT_OLD_PERMIC = HB_TAG ('P','e','r','m'),
294 294 /*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'), /*7.0*/ HB_SCRIPT_PAHAWH_HMONG = HB_TAG ('H','m','n','g'),
295 295 /*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'), /*7.0*/ HB_SCRIPT_PALMYRENE = HB_TAG ('P','a','l','m'),
296 /*7.0*/ HB_SCRIPT_PAU_CIN_HAU = ???
296 /*7.0*/ HB_SCRIPT_PAU_CIN_HAU = HB_TAG ('P','a','u','c'),
297 297 /*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'), /*7.0*/ HB_SCRIPT_PSALTER_PAHLAVI = HB_TAG ('P','h','l','p'),
298 /*7.0*/ HB_SCRIPT_SIDDHAM = ???
298 /*7.0*/ HB_SCRIPT_SIDDHAM = HB_TAG ('S','i','d','d'),
299 299 /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'),
300 300 /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'),
301 #endif
301
302 /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'),
303 /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'),
304 /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'),
305 /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'),
306 /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'),
307 /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'),
308
309 /* No script set. */
310 HB_SCRIPT_INVALID = HB_TAG_NONE,
311
312 /* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
313 * without risking undefined behavior. Include both a signed and unsigned max,
314 * since technically enums are int, and indeed, hb_script_t ends up being signed.
315 * See this thread for technicalities:
316 *
317 * http://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
318 */
319 _HB_SCRIPT_MAX_VALUE = HB_TAG_MAX, /*< skip >*/
320 _HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/
321
322 } hb_script_t;
302 323
303 324
304 325 /* Script functions */ /* Script functions */
305 326
306 hb_script_t
327 HB_EXTERN hb_script_t
307 328 hb_script_from_iso15924_tag (hb_tag_t tag); hb_script_from_iso15924_tag (hb_tag_t tag);
308 329
309 /* suger for tag_from_string() then script_from_iso15924_tag */
330 /* sugar for tag_from_string() then script_from_iso15924_tag */
310 331 /* len=-1 means s is NUL-terminated */ /* len=-1 means s is NUL-terminated */
311 hb_script_t
332 HB_EXTERN hb_script_t
312 333 hb_script_from_string (const char *s, int len); hb_script_from_string (const char *s, int len);
313 334
314 hb_tag_t
335 HB_EXTERN hb_tag_t
315 336 hb_script_to_iso15924_tag (hb_script_t script); hb_script_to_iso15924_tag (hb_script_t script);
316 337
317 hb_direction_t
338 HB_EXTERN hb_direction_t
318 339 hb_script_get_horizontal_direction (hb_script_t script); hb_script_get_horizontal_direction (hb_script_t script);
319 340
320 341
File hb-coretext.h changed (mode: 100644) (index c4954fa..82066e4)
29 29
30 30 #include "hb.h" #include "hb.h"
31 31
32 #include <ApplicationServices/ApplicationServices.h>
32 #include <TargetConditionals.h>
33 #if TARGET_OS_IPHONE
34 # include <CoreText/CoreText.h>
35 # include <CoreGraphics/CoreGraphics.h>
36 #else
37 # include <ApplicationServices/ApplicationServices.h>
38 #endif
33 39
34 40 HB_BEGIN_DECLS HB_BEGIN_DECLS
35 41
36 42
37 CGFontRef
43 #define HB_CORETEXT_TAG_MORT HB_TAG('m','o','r','t')
44 #define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x')
45
46
47 HB_EXTERN hb_face_t *
48 hb_coretext_face_create (CGFontRef cg_font);
49
50
51 HB_EXTERN CGFontRef
38 52 hb_coretext_face_get_cg_font (hb_face_t *face); hb_coretext_face_get_cg_font (hb_face_t *face);
39 53
40 CTFontRef
54 HB_EXTERN CTFontRef
41 55 hb_coretext_font_get_ct_font (hb_font_t *font); hb_coretext_font_get_ct_font (hb_font_t *font);
42 56
43 57
File hb-face-private.h changed (mode: 100644) (index 3ea9861..5e43e30)
1 1 #ifndef HB_FACE_PRIVATE_H #ifndef HB_FACE_PRIVATE_H
2 2 #define HB_FACE_PRIVATE_H #define HB_FACE_PRIVATE_H
3 3 struct plan_node_t { struct plan_node_t {
4 hb_shape_plan_t *shape_plan;
5 struct plan_node_t *next;
4 hb_shape_plan_t *shape_plan;
5 struct plan_node_t *next;
6 6 }; };
7 7
8 8 struct hb_face_t { struct hb_face_t {
9 atomic_int32_t ref_cnt;
10 hb_bool_t immutable;
11 FT_Face ft_face;
12 void *user_data;
13 hb_destroy_func_t destroy;
14 struct hb_shaper_data_t shaper_data;
15 struct plan_node_t *shape_plans;
16 unsigned upem;
17 unsigned num_glyphs;
18 unsigned index;
19 hb_reference_table_func_t reference_table_func;
9 atomic_int32_t ref_cnt;
10 hb_bool_t immutable;
11 FT_Face ft_face;
12 void *user_data;
13 hb_destroy_func_t destroy;
14 struct hb_shaper_data_t shaper_data;
15 struct plan_node_t *shape_plans;
16 unsigned upem;
17 unsigned num_glyphs;
18 unsigned index;
19 hb_reference_table_func_t reference_table_func;
20 20 }; };
21 21
22 22 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
23 23 struct hb_graphite2_shaper_face_data_t; struct hb_graphite2_shaper_face_data_t;
24 struct hb_graphite2_shaper_face_data_t *
25 hb_graphite2_shaper_face_data_create(hb_face_t *face);
26 void
27 hb_graphite2_shaper_face_data_destroy(
28 struct hb_graphite2_shaper_face_data *data);
24 struct hb_graphite2_shaper_face_data_t
25 *hb_graphite2_shaper_face_data_create(hb_face_t * face);
26 void hb_graphite2_shaper_face_data_destroy(struct hb_graphite2_shaper_face_data
27 *data);
29 28 #endif #endif
30 29 #ifdef HAVE_OT #ifdef HAVE_OT
31 30 struct hb_ot_shaper_face_data_t; struct hb_ot_shaper_face_data_t;
32 struct hb_ot_shaper_face_data_t *
33 hb_ot_shaper_face_data_create(hb_face_t *face);
34 void
35 hb_ot_shaper_face_data_destroy(struct hb_ot_shaper_face_data_t *data);
31 struct hb_ot_shaper_face_data_t *hb_ot_shaper_face_data_create(hb_face_t *
32 face);
33 void hb_ot_shaper_face_data_destroy(struct hb_ot_shaper_face_data_t *data);
36 34 #endif #endif
37 35 struct hb_fallback_shaper_face_data_t; struct hb_fallback_shaper_face_data_t;
38 struct hb_fallback_shaper_face_data_t *
39 hb_fallback_shaper_face_data_create(hb_face_t *face);
40 void
41 hb_fallback_shaper_face_data_destroy(
42 struct hb_fallback_shaper_face_data_t *data);
36 struct hb_fallback_shaper_face_data_t
37 *hb_fallback_shaper_face_data_create(hb_face_t * face);
38 void hb_fallback_shaper_face_data_destroy(struct hb_fallback_shaper_face_data_t
39 *data);
43 40 #endif #endif
File hb-face.c changed (mode: 100644) (index 4489a99..770d81b)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <stdlib.h> #include <stdlib.h>
5 7
6 8 #include <ft2build.h> #include <ft2build.h>
 
15 17 #include "hb-blob-private.h" #include "hb-blob-private.h"
16 18 #include "hb-open-file-private.h" #include "hb-open-file-private.h"
17 19
18 void
19 hb_face_make_immutable(hb_face_t *face)
20 void hb_face_make_immutable(hb_face_t * face)
20 21 { {
21 if (hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
22 return;
22 if (hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
23 return;
23 24
24 face->immutable = TRUE;
25 face->immutable = TRUE;
25 26 } }
26 27
27 hb_face_t *
28 hb_face_reference(hb_face_t *face)
28 hb_face_t *hb_face_reference(hb_face_t * face)
29 29 { {
30 if (hb_atomic_int32_get(&face->ref_cnt) != REF_CNT_INVALID_VAL)
31 hb_atomic_int32_add(&face->ref_cnt, 1);
32 return face;
30 if (hb_atomic_int32_get(&face->ref_cnt) != REF_CNT_INVALID_VAL)
31 hb_atomic_int32_add(&face->ref_cnt, 1);
32 return face;
33 33 } }
34 34
35 /*XXX:should go in lib "global init"*/
35 36 static hb_face_t hb_face_nil = { static hb_face_t hb_face_nil = {
36 REF_CNT_INVALID_VAL,//ref_cnt
37 TRUE,//immutable
38 NULL,//ft_face
39 NULL,//user_data
40 NULL,//destroy
41 {
37 REF_CNT_INVALID_VAL, /*ref_cnt */
38 TRUE, /*immutable */
39 NULL, /*ft_face */
40 NULL, /*user_data */
41 NULL, /*destroy */
42 {
42 43 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
43 HB_SHAPER_DATA_INVALID,
44 HB_SHAPER_DATA_INVALID,
44 45 #endif #endif
45 46 #ifdef HAVE_OT #ifdef HAVE_OT
46 HB_SHAPER_DATA_INVALID,
47 HB_SHAPER_DATA_INVALID,
47 48 #endif #endif
48 HB_SHAPER_DATA_INVALID//fallback
49 },
50 NULL,//shape_plans
51 0,//upem
52 0,//num_glyphs
53 0,//index
54 NULL//reference_table_func
49 HB_SHAPER_DATA_INVALID /*fallback */
50 },
51 NULL, /*shape_plans */
52 0, /*upem */
53 0, /*num_glyphs */
54 0, /*index */
55 NULL /*reference_table_func */
55 56 }; };
56 57
57 hb_face_t *
58 hb_face_get_empty(void)
58 hb_face_t *hb_face_get_empty(void)
59 59 { {
60 return &hb_face_nil;
60 return &hb_face_nil;
61 61 } }
62 62
63 void
64 hb_face_set_index(hb_face_t *face, unsigned index)
63 void hb_face_set_index(hb_face_t * face, unsigned index)
65 64 { {
66 if (hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
67 return;
65 if (hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
66 return;
68 67
69 face->index = index;
68 face->index = index;
70 69 } }
71 70
72 void
73 hb_face_set_upem(hb_face_t *face,
74 unsigned upem)
71 void hb_face_set_upem(hb_face_t * face, unsigned upem)
75 72 { {
76 if (hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
77 return;
73 if (hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
74 return;
78 75
79 face->upem = upem;
76 face->upem = upem;
80 77 } }
81 78
82 hb_face_t *
83 hb_face_create_for_tables(hb_reference_table_func_t reference_table_func,
84 void *user_data,
85 hb_destroy_func_t destroy)
79 hb_face_t *hb_face_create_for_tables(hb_reference_table_func_t
80 reference_table_func, void *user_data,
81 hb_destroy_func_t destroy)
86 82 { {
87 hb_face_t *face = calloc(1, sizeof(*face));
88 if (!reference_table_func || !face) {
89 if (face)
90 free(face);
91 if (destroy)
92 destroy(user_data);
93 return hb_face_get_empty();
94 }
95 hb_atomic_int32_set(&face->ref_cnt, 1);
96
97 face->reference_table_func = reference_table_func;
98 face->user_data = user_data;
99 face->destroy = destroy;
100
101 face->upem = 0;
102 face->num_glyphs = (unsigned)-1;
103 return face;
83 hb_face_t *face;
84
85 face = calloc(1, sizeof(*face));
86 if (!reference_table_func || !face) {
87 if (face)
88 free(face);
89 if (destroy)
90 destroy(user_data);
91 return hb_face_get_empty();
92 }
93 hb_atomic_int32_set(&face->ref_cnt, 1);
94
95 face->reference_table_func = reference_table_func;
96 face->user_data = user_data;
97 face->destroy = destroy;
98
99 face->upem = 0;
100 face->num_glyphs = (unsigned)-1;
101 return face;
104 102 } }
105 103
106 104 typedef struct hb_face_for_data_closure_t { typedef struct hb_face_for_data_closure_t {
107 hb_blob_t *blob;
108 unsigned index;
105 hb_blob_t *blob;
106 unsigned index;
109 107 } hb_face_for_data_closure_t; } hb_face_for_data_closure_t;
110 108
111 static hb_face_for_data_closure_t *
112 hb_face_for_data_closure_create(hb_blob_t *blob, unsigned index)
109 static hb_face_for_data_closure_t *hb_face_for_data_closure_create(hb_blob_t *
110 blob,
111 unsigned
112 index)
113 113 { {
114 hb_face_for_data_closure_t *closure;
114 hb_face_for_data_closure_t *closure;
115 115
116 closure = malloc(sizeof(*closure));
117 if (!closure)
118 return NULL;
116 closure = malloc(sizeof(*closure));
117 if (!closure)
118 return NULL;
119 119
120 closure->blob = blob;
121 closure->index = index;
122 return closure;
120 closure->blob = blob;
121 closure->index = index;
122 return closure;
123 123 } }
124 124
125 static void
126 hb_face_for_data_closure_destroy(hb_face_for_data_closure_t *closure)
125 static void hb_face_for_data_closure_destroy(hb_face_for_data_closure_t *
126 closure)
127 127 { {
128 hb_blob_destroy(closure->blob);
129 free(closure);
128 hb_blob_destroy(closure->blob);
129 free(closure);
130 130 } }
131 131
132 static hb_blob_t *
133 hb_face_for_data_reference_table(hb_face_t *face HB_UNUSED,
134 hb_tag_t tag,
135 void *user_data)
132 static hb_blob_t *hb_face_for_data_reference_table(hb_face_t * face HB_UNUSED,
133 hb_tag_t tag,
134 void *user_data)
136 135 { {
137 hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *)user_data;
138
139 if (tag == HB_TAG_NONE)
140 return hb_blob_reference(data->blob);
141
142 //XXX:carefull, we don't use a "null" object like original code
143 //be NULL pointers
144 struct ot_fnt_file *ot_fnt_file = hb_blob_lock_instance(data->blob);
145 struct ot_fnt_face *ot_fnt_face = ot_fnt_file_get_face(ot_fnt_file,
146 data->index);
147 struct ot_tbl *ot_tbl = ot_fnt_face_get_tbl_by_tag(ot_fnt_face, tag);
148
149 //XXX:without "null" object return the empty blob
150 if (!ot_tbl)
151 return hb_blob_get_empty();
152 hb_blob_t *blob = hb_blob_create_sub_blob(data->blob, ot_tbl->of,
153 ot_tbl->len);
154 return blob;
136 hb_face_for_data_closure_t *data;
137 struct ot_fnt_file *ot_fnt_file;
138 struct ot_fnt_face *ot_fnt_face;
139 struct ot_tbl *ot_tbl;
140 hb_blob_t *blob;
141
142 data = (hb_face_for_data_closure_t *) user_data;
143 if (tag == HB_TAG_NONE)
144 return hb_blob_reference(data->blob);
145
146 /*XXX:carefull, we don't use a "null" object like original code
147 be NULL pointers */
148 ot_fnt_file = hb_blob_lock_instance(data->blob);
149 ot_fnt_face = ot_fnt_file_get_face(ot_fnt_file, data->index);
150 ot_tbl = ot_fnt_face_get_tbl_by_tag(ot_fnt_face, tag);
151
152 /*XXX:without "null" object return the empty blob */
153 if (!ot_tbl)
154 return hb_blob_get_empty();
155 blob = hb_blob_create_sub_blob(data->blob, ot_tbl->of, ot_tbl->len);
156 return blob;
155 157 } }
156 158
157 hb_face_t *
158 hb_face_create(hb_blob_t *blob,
159 unsigned index)
159 hb_face_t *hb_face_create(hb_blob_t * blob, unsigned index)
160 160 { {
161 hb_face_t *face;
161 hb_face_t *face;
162 hb_face_for_data_closure_t *closure;
162 163
163 if (!blob || !hb_blob_get_length(blob))
164 return hb_face_get_empty();
164 if (!blob || !hb_blob_get_length(blob))
165 return hb_face_get_empty();
165 166
166 hb_face_for_data_closure_t *closure = hb_face_for_data_closure_create(
167 hb_blob_reference(blob), index);
167 closure =
168 hb_face_for_data_closure_create(hb_blob_reference(blob), index);
168 169
169 if (!closure)
170 return hb_face_get_empty();
170 if (!closure)
171 return hb_face_get_empty();
171 172
172 face = hb_face_create_for_tables(
173 hb_face_for_data_reference_table,
174 closure,
175 (hb_destroy_func_t)hb_face_for_data_closure_destroy);
173 face =
174 hb_face_create_for_tables(hb_face_for_data_reference_table, closure,
175 (hb_destroy_func_t)
176 hb_face_for_data_closure_destroy);
176 177
177 hb_face_set_index(face, index);
178 return face;
178 hb_face_set_index(face, index);
179 return face;
179 180 } }
180 181
181 void
182 hb_face_destroy(hb_face_t *face)
182 void hb_face_destroy(hb_face_t * face)
183 183 { {
184 if (!face)
185 return;
186 if (hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
187 return;
188 hb_atomic_int32_add(&face->ref_cnt, -1);
189 if (hb_atomic_int32_get(&face->ref_cnt) > 0)
190 return;
191 hb_atomic_int32_set(&face->ref_cnt, REF_CNT_INVALID_VAL);
184 if (!face)
185 return;
186 if (hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
187 return;
188 hb_atomic_int32_add(&face->ref_cnt, -1);
189 if (hb_atomic_int32_get(&face->ref_cnt) > 0)
190 return;
191 hb_atomic_int32_set(&face->ref_cnt, REF_CNT_INVALID_VAL);
192 192
193 193 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
194 if (face->shaper_data.graphite2
195 && face->shaper_data.graphite2 != HB_SHAPER_DATA_INVALID
196 && face->shaper_data.graphite2 != HB_SHAPER_DATA_SUCCEEDED)
197 hb_graphite2_shaper_face_data_destroy(face->shaper_data.graphite2);
194 if (face->shaper_data.graphite2
195 && face->shaper_data.graphite2 != HB_SHAPER_DATA_INVALID
196 && face->shaper_data.graphite2 != HB_SHAPER_DATA_SUCCEEDED)
197 hb_graphite2_shaper_face_data_destroy(face->shaper_data.
198 graphite2);
198 199 #endif #endif
199 200 #ifdef HAVE_OT #ifdef HAVE_OT
200 if (face->shaper_data.ot
201 && face->shaper_data.ot != HB_SHAPER_DATA_INVALID
202 && face->shaper_data.ot != HB_SHAPER_DATA_SUCCEEDED)
203 hb_ot_shaper_face_data_destroy(face->shaper_data.ot);
201 if (face->shaper_data.ot
202 && face->shaper_data.ot != HB_SHAPER_DATA_INVALID
203 && face->shaper_data.ot != HB_SHAPER_DATA_SUCCEEDED)
204 hb_ot_shaper_face_data_destroy(face->shaper_data.ot);
204 205 #endif #endif
205 if (face->shaper_data.fallback
206 && face->shaper_data.fallback != HB_SHAPER_DATA_INVALID
207 && face->shaper_data.fallback != HB_SHAPER_DATA_SUCCEEDED)
208 hb_fallback_shaper_face_data_destroy(face->shaper_data.fallback);
209
210 if (face->destroy)
211 face->destroy(face->user_data);
212 free(face);
206 if (face->shaper_data.fallback
207 && face->shaper_data.fallback != HB_SHAPER_DATA_INVALID
208 && face->shaper_data.fallback != HB_SHAPER_DATA_SUCCEEDED)
209 hb_fallback_shaper_face_data_destroy(face->shaper_data.
210 fallback);
211
212 if (face->destroy)
213 face->destroy(face->user_data);
214 free(face);
213 215 } }
File hb-face.h changed (mode: 100644) (index f682c46..91237b7)
... ... HB_BEGIN_DECLS
43 43
44 44 typedef struct hb_face_t hb_face_t; typedef struct hb_face_t hb_face_t;
45 45
46 hb_face_t *
46 HB_EXTERN hb_face_t *
47 47 hb_face_create (hb_blob_t *blob, hb_face_create (hb_blob_t *blob,
48 48 unsigned int index); unsigned int index);
49 49
50 50 typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data);
51 51
52 52 /* calls destroy() when not needing user_data anymore */ /* calls destroy() when not needing user_data anymore */
53 hb_face_t *
53 HB_EXTERN hb_face_t *
54 54 hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
55 55 void *user_data, void *user_data,
56 56 hb_destroy_func_t destroy); hb_destroy_func_t destroy);
57 57
58 hb_face_t *
58 HB_EXTERN hb_face_t *
59 59 hb_face_get_empty (void); hb_face_get_empty (void);
60 60
61 hb_face_t *
61 HB_EXTERN hb_face_t *
62 62 hb_face_reference (hb_face_t *face); hb_face_reference (hb_face_t *face);
63 63
64 void
64 HB_EXTERN void
65 65 hb_face_destroy (hb_face_t *face); hb_face_destroy (hb_face_t *face);
66 66
67 hb_bool_t
67 HB_EXTERN hb_bool_t
68 68 hb_face_set_user_data (hb_face_t *face, hb_face_set_user_data (hb_face_t *face,
69 69 hb_user_data_key_t *key, hb_user_data_key_t *key,
70 70 void * data, void * data,
 
... ... hb_face_set_user_data (hb_face_t *face,
72 72 hb_bool_t replace); hb_bool_t replace);
73 73
74 74
75 void *
75 HB_EXTERN void *
76 76 hb_face_get_user_data (hb_face_t *face, hb_face_get_user_data (hb_face_t *face,
77 77 hb_user_data_key_t *key); hb_user_data_key_t *key);
78 78
79 void
79 HB_EXTERN void
80 80 hb_face_make_immutable (hb_face_t *face); hb_face_make_immutable (hb_face_t *face);
81 81
82 hb_bool_t
82 HB_EXTERN hb_bool_t
83 83 hb_face_is_immutable (hb_face_t *face); hb_face_is_immutable (hb_face_t *face);
84 84
85 85
86 hb_blob_t *
86 HB_EXTERN hb_blob_t *
87 87 hb_face_reference_table (hb_face_t *face, hb_face_reference_table (hb_face_t *face,
88 88 hb_tag_t tag); hb_tag_t tag);
89 89
90 hb_blob_t *
90 HB_EXTERN hb_blob_t *
91 91 hb_face_reference_blob (hb_face_t *face); hb_face_reference_blob (hb_face_t *face);
92 92
93 void
93 HB_EXTERN void
94 94 hb_face_set_index (hb_face_t *face, hb_face_set_index (hb_face_t *face,
95 95 unsigned int index); unsigned int index);
96 96
97 unsigned int
97 HB_EXTERN unsigned int
98 98 hb_face_get_index (hb_face_t *face); hb_face_get_index (hb_face_t *face);
99 99
100 void
100 HB_EXTERN void
101 101 hb_face_set_upem (hb_face_t *face, hb_face_set_upem (hb_face_t *face,
102 102 unsigned int upem); unsigned int upem);
103 103
104 unsigned int
104 HB_EXTERN unsigned int
105 105 hb_face_get_upem (hb_face_t *face); hb_face_get_upem (hb_face_t *face);
106 106
107 void
107 HB_EXTERN void
108 108 hb_face_set_glyph_count (hb_face_t *face, hb_face_set_glyph_count (hb_face_t *face,
109 109 unsigned int glyph_count); unsigned int glyph_count);
110 110
111 unsigned int
111 HB_EXTERN unsigned int
112 112 hb_face_get_glyph_count (hb_face_t *face); hb_face_get_glyph_count (hb_face_t *face);
113 113
114 114
File hb-fallback-shape.c changed (mode: 100644) (index f027e1e..cdc0ae9)
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
1 6 #include "hb.h" #include "hb.h"
2 7 #include "hb-private.h" #include "hb-private.h"
3 8 #include "hb-atomic-private.h" #include "hb-atomic-private.h"
4 9 #include "hb-buffer-private.h" #include "hb-buffer-private.h"
5 // C99 port from c++ is protected by a GNU Lesser GPLv3
6 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
7 // <sylware@legeek.net>
8 10 #include "hb-shaper-private.h" #include "hb-shaper-private.h"
9 11 #include "hb-font-private.h" #include "hb-font-private.h"
10 12 #include "hb-unicode-private.h" #include "hb-unicode-private.h"
11 13
12 //------------------------------------------------------------------------------
13 //shaper face data
14 struct hb_fallback_shaper_face_data_t {};
14 /*----------------------------------------------------------------------------*/
15 /*shaper face data*/
16 struct hb_fallback_shaper_face_data_t {
17 long empty;
18 };
15 19
16 struct hb_fallback_shaper_face_data_t *
17 hb_fallback_shaper_face_data_create(hb_face_t *face HB_UNUSED)
20 struct hb_fallback_shaper_face_data_t
21 *hb_fallback_shaper_face_data_create(hb_face_t * face HB_UNUSED)
18 22 { {
19 return HB_SHAPER_DATA_SUCCEEDED;
23 return HB_SHAPER_DATA_SUCCEEDED;
20 24 } }
21 25
22 26 void void
23 hb_fallback_shaper_face_data_destroy(
24 struct hb_fallback_shaper_face_data_t *data HB_UNUSED)
27 hb_fallback_shaper_face_data_destroy(struct hb_fallback_shaper_face_data_t *data
28 HB_UNUSED)
25 29 { {
26 30 } }
27 //------------------------------------------------------------------------------
28 31
32 /*----------------------------------------------------------------------------*/
29 33
30 //------------------------------------------------------------------------------
31 //shaper font data
32 struct hb_fallback_shaper_font_data_t {};
34 /*----------------------------------------------------------------------------*/
35 /*shaper font data*/
36 struct hb_fallback_shaper_font_data_t {
37 long empty;
38 };
33 39
34 struct hb_fallback_shaper_font_data_t *
35 hb_fallback_shaper_font_data_create(hb_font_t *font HB_UNUSED)
40 struct hb_fallback_shaper_font_data_t
41 *hb_fallback_shaper_font_data_create(hb_font_t * font HB_UNUSED)
36 42 { {
37 return HB_SHAPER_DATA_SUCCEEDED;
43 return HB_SHAPER_DATA_SUCCEEDED;
38 44 } }
39 45
40 void
41 hb_fallback_shaper_font_data_destroy(
42 struct hb_fallback_shaper_font_data_t *data HB_UNUSED)
46 void hb_fallback_shaper_font_data_destroy(struct hb_fallback_shaper_font_data_t
47 *data HB_UNUSED)
43 48 { {
44 49 } }
45 //------------------------------------------------------------------------------
46 50
51 /*----------------------------------------------------------------------------*/
47 52
48 //------------------------------------------------------------------------------
49 //shaper shape_plan data
50 struct hb_fallback_shaper_shape_plan_data_t {};
53 /*----------------------------------------------------------------------------*/
54 /*shaper shape_plan data*/
55 struct hb_fallback_shaper_shape_plan_data_t {
56 long empty;
57 };
51 58
52 struct hb_fallback_shaper_shape_plan_data_t *
53 hb_fallback_shaper_shape_plan_data_create(
54 hb_shape_plan_t *shape_plan HB_UNUSED,
55 const hb_feature_t *user_features HB_UNUSED,
56 unsigned num_user_features HB_UNUSED)
59 struct hb_fallback_shaper_shape_plan_data_t
60 *hb_fallback_shaper_shape_plan_data_create(hb_shape_plan_t *
61 shape_plan HB_UNUSED,
62 const hb_feature_t *
63 user_features HB_UNUSED,
64 unsigned num_user_features HB_UNUSED)
57 65 { {
58 return HB_SHAPER_DATA_SUCCEEDED;
66 return HB_SHAPER_DATA_SUCCEEDED;
59 67 } }
60 68
61 void
62 hb_fallback_shaper_shape_plan_data_destroy(
63 struct hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
69 void hb_fallback_shaper_shape_plan_data_destroy(struct
70 hb_fallback_shaper_shape_plan_data_t
71 *data HB_UNUSED)
64 72 { {
65 73 } }
66 //------------------------------------------------------------------------------
67 74
75 /*----------------------------------------------------------------------------*/
68 76
69 //shaper
70 hb_bool_t
71 hb_fallback_shape(hb_shape_plan_t *shape_plan HB_UNUSED,
72 hb_font_t *font,
73 hb_buffer_t *buffer,
74 const hb_feature_t *features HB_UNUSED,
75 unsigned num_features HB_UNUSED)
77 /*shaper*/
78 hb_bool_t hb_fallback_shape(hb_shape_plan_t * shape_plan HB_UNUSED,
79 hb_font_t * font, hb_buffer_t * buffer,
80 const hb_feature_t * features HB_UNUSED,
81 unsigned num_features HB_UNUSED)
76 82 { {
77 hb_codepoint_t space;
78 hb_font_get_glyph(font, ' ', 0, &space);
79
80 hb_buffer_clear_positions(buffer);
81
82 unsigned count = buffer->len;
83
84 for (unsigned i = 0; i < count; i++) {
85 if (hb_unicode_is_default_ignorable(buffer->info[i].codepoint)) {
86 buffer->info[i].codepoint = space;
87 buffer->pos[i].x_advance = 0;
88 buffer->pos[i].y_advance = 0;
89 continue;
90 }
91 hb_font_get_glyph(font,
92 buffer->info[i].codepoint,
93 0,
94 &buffer->info[i].codepoint);
95 hb_font_get_glyph_advance_for_direction(font,
96 buffer->info[i].codepoint,
97 buffer->props.direction,
98 &buffer->pos[i].x_advance,
99 &buffer->pos[i].y_advance);
100 hb_font_subtract_glyph_origin_for_direction(font,
101 buffer->info[i].codepoint,
102 buffer->props.direction,
103 &buffer->pos[i].x_offset,
104 &buffer->pos[i].y_offset);
105 }
106
107 if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
108 hb_buffer_reverse(buffer);
109 return TRUE;
83 hb_codepoint_t space;
84 unsigned count;
85 unsigned i;
86
87 hb_font_get_glyph(font, ' ', 0, &space);
88
89 hb_buffer_clear_positions(buffer);
90
91 count = buffer->len;
92
93 for (i = 0; i < count; ++i) {
94 if (hb_unicode_is_default_ignorable(buffer->info[i].codepoint)) {
95 buffer->info[i].codepoint = space;
96 buffer->pos[i].x_advance = 0;
97 buffer->pos[i].y_advance = 0;
98 continue;
99 }
100 hb_font_get_glyph(font, buffer->info[i].codepoint, 0,
101 &buffer->info[i].codepoint);
102 hb_font_get_glyph_advance_for_direction(font,
103 buffer->
104 info[i].codepoint,
105 buffer->props.direction,
106 &buffer->
107 pos[i].x_advance,
108 &buffer->
109 pos[i].y_advance);
110 hb_font_subtract_glyph_origin_for_direction(font,
111 buffer->
112 info[i].codepoint,
113 buffer->
114 props.direction,
115 &buffer->
116 pos[i].x_offset,
117 &buffer->
118 pos[i].y_offset);
119 }
120
121 if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
122 hb_buffer_reverse(buffer);
123 return TRUE;
110 124 } }
File hb-font-private.h changed (mode: 100644) (index 172e69a..dce2474)
1 1 #ifndef HB_FONT_PRIVATE #ifndef HB_FONT_PRIVATE
2 2 #define HB_FONT_PRIVATE #define HB_FONT_PRIVATE
3 3 struct hb_font_funcs_t { struct hb_font_funcs_t {
4 atomic_int32_t ref_cnt;
5 hb_bool_t immutable;
4 atomic_int32_t ref_cnt;
5 hb_bool_t immutable;
6 6
7 //Don't access these directly. Call hb_font_get_*() instead.
8 struct {
9 hb_font_get_glyph_func_t glyph;
10 hb_font_get_glyph_h_advance_func_t glyph_h_advance;
11 hb_font_get_glyph_v_advance_func_t glyph_v_advance;
12 hb_font_get_glyph_h_origin_func_t glyph_h_origin;
13 hb_font_get_glyph_v_origin_func_t glyph_v_origin;
14 hb_font_get_glyph_h_kerning_func_t glyph_h_kerning;
15 hb_font_get_glyph_v_kerning_func_t glyph_v_kerning;
16 hb_font_get_glyph_extents_func_t glyph_extents;
17 hb_font_get_glyph_contour_point_func_t glyph_contour_point;
18 hb_font_get_glyph_name_func_t glyph_name;
19 hb_font_get_glyph_from_name_func_t glyph_from_name;
20 } get;
7 /*Don't access these directly. Call hb_font_get_*() instead. */
8 struct {
9 hb_font_get_glyph_func_t glyph;
10 hb_font_get_glyph_h_advance_func_t glyph_h_advance;
11 hb_font_get_glyph_v_advance_func_t glyph_v_advance;
12 hb_font_get_glyph_h_origin_func_t glyph_h_origin;
13 hb_font_get_glyph_v_origin_func_t glyph_v_origin;
14 hb_font_get_glyph_h_kerning_func_t glyph_h_kerning;
15 hb_font_get_glyph_v_kerning_func_t glyph_v_kerning;
16 hb_font_get_glyph_extents_func_t glyph_extents;
17 hb_font_get_glyph_contour_point_func_t glyph_contour_point;
18 hb_font_get_glyph_name_func_t glyph_name;
19 hb_font_get_glyph_from_name_func_t glyph_from_name;
20 } get;
21 21
22 struct {
23 void *glyph;
24 void *glyph_h_advance;
25 void *glyph_v_advance;
26 void *glyph_h_origin;
27 void *glyph_v_origin;
28 void *glyph_h_kerning;
29 void *glyph_v_kerning;
30 void *glyph_extents;
31 void *glyph_contour_point;
32 void *glyph_name;
33 void *glyph_from_name;
34 } user_data;
22 struct {
23 void *glyph;
24 void *glyph_h_advance;
25 void *glyph_v_advance;
26 void *glyph_h_origin;
27 void *glyph_v_origin;
28 void *glyph_h_kerning;
29 void *glyph_v_kerning;
30 void *glyph_extents;
31 void *glyph_contour_point;
32 void *glyph_name;
33 void *glyph_from_name;
34 } user_data;
35 35
36 struct {
37 hb_destroy_func_t glyph;
38 hb_destroy_func_t glyph_h_advance;
39 hb_destroy_func_t glyph_v_advance;
40 hb_destroy_func_t glyph_h_origin;
41 hb_destroy_func_t glyph_v_origin;
42 hb_destroy_func_t glyph_h_kerning;
43 hb_destroy_func_t glyph_v_kerning;
44 hb_destroy_func_t glyph_extents;
45 hb_destroy_func_t glyph_contour_point;
46 hb_destroy_func_t glyph_name;
47 hb_destroy_func_t glyph_from_name;
48 } destroy;
36 struct {
37 hb_destroy_func_t glyph;
38 hb_destroy_func_t glyph_h_advance;
39 hb_destroy_func_t glyph_v_advance;
40 hb_destroy_func_t glyph_h_origin;
41 hb_destroy_func_t glyph_v_origin;
42 hb_destroy_func_t glyph_h_kerning;
43 hb_destroy_func_t glyph_v_kerning;
44 hb_destroy_func_t glyph_extents;
45 hb_destroy_func_t glyph_contour_point;
46 hb_destroy_func_t glyph_name;
47 hb_destroy_func_t glyph_from_name;
48 } destroy;
49 49 }; };
50 50
51 51 struct hb_font_t { struct hb_font_t {
52 atomic_int32_t ref_cnt;
53 hb_bool_t immutable;
54 hb_font_t *parent;
55 hb_face_t *face;
56 int x_scale;
57 int y_scale;
58 unsigned int x_ppem;
59 unsigned int y_ppem;
60 hb_font_funcs_t *klass;
61 void *user_data;
62 hb_destroy_func_t destroy;
63 struct hb_shaper_data_t shaper_data;
52 atomic_int32_t ref_cnt;
53 hb_bool_t immutable;
54 hb_font_t *parent;
55 hb_face_t *face;
56 int x_scale;
57 int y_scale;
58 unsigned int x_ppem;
59 unsigned int y_ppem;
60 hb_font_funcs_t *klass;
61 void *user_data;
62 hb_destroy_func_t destroy;
63 struct hb_shaper_data_t shaper_data;
64 64 }; };
65 65
66 void
67 hb_font_get_glyph_advance_for_direction(hb_font_t *font,
68 hb_codepoint_t glyph,
69 hb_direction_t direction,
70 hb_position_t *x, hb_position_t *y);
71 void
72 hb_font_subtract_glyph_origin_for_direction(hb_font_t *font,
73 hb_codepoint_t glyph,
74 hb_direction_t direction,
75 hb_position_t *x, hb_position_t *y);
66 void hb_font_get_glyph_advance_for_direction(hb_font_t * font,
67 hb_codepoint_t glyph,
68 hb_direction_t direction,
69 hb_position_t * x,
70 hb_position_t * y);
71 void hb_font_subtract_glyph_origin_for_direction(hb_font_t * font,
72 hb_codepoint_t glyph,
73 hb_direction_t direction,
74 hb_position_t * x,
75 hb_position_t * y);
76 76
77 77 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
78 78 struct hb_graphite2_shaper_font_data_t; struct hb_graphite2_shaper_font_data_t;
79 struct hb_graphite2_shaper_font_data_t *
80 hb_graphite2_shaper_font_data_create(hb_font_t *font);
81 void
82 hb_graphite2_shaper_font_data_destroy(
83 struct hb_graphite2_shaper_font_data_t *data);
79 struct hb_graphite2_shaper_font_data_t
80 *hb_graphite2_shaper_font_data_create(hb_font_t * font);
81 void hb_graphite2_shaper_font_data_destroy(struct
82 hb_graphite2_shaper_font_data_t
83 *data);
84 84 #endif #endif
85 85 #ifdef HAVE_OT #ifdef HAVE_OT
86 86 struct hb_ot_shaper_font_data_t; struct hb_ot_shaper_font_data_t;
87 struct hb_ot_shaper_font_data_t *
88 hb_ot_shaper_font_data_create(hb_font_t *font);
89 void
90 hb_ot_shaper_font_data_destroy(struct hb_ot_shaper_font_data_t *data);
87 struct hb_ot_shaper_font_data_t *hb_ot_shaper_font_data_create(hb_font_t *
88 font);
89 void hb_ot_shaper_font_data_destroy(struct hb_ot_shaper_font_data_t *data);
91 90 #endif #endif
92 91 struct hb_fallback_shaper_font_data_t; struct hb_fallback_shaper_font_data_t;
93 struct hb_fallback_shaper_font_data_t *
94 hb_fallback_shaper_font_data_create(hb_font_t *font);
95 void
96 hb_fallback_shaper_font_data_destroy(
97 struct hb_fallback_shaper_font_data_t *data);
92 struct hb_fallback_shaper_font_data_t
93 *hb_fallback_shaper_font_data_create(hb_font_t * font);
94 void hb_fallback_shaper_font_data_destroy(struct hb_fallback_shaper_font_data_t
95 *data);
98 96 #endif #endif
File hb-font.c changed (mode: 100644) (index ba271fa..80df40b)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <stdlib.h> #include <stdlib.h>
5 7 #include <string.h> #include <string.h>
6 8
 
14 16 #include "hb-face-private.h" #include "hb-face-private.h"
15 17 #include "hb-font-private.h" #include "hb-font-private.h"
16 18
17 void
18 hb_font_destroy(hb_font_t *font)
19 void hb_font_destroy(hb_font_t * font)
19 20 { {
20 if (!font)
21 return;
22 if (hb_atomic_int32_get(&font->ref_cnt) == REF_CNT_INVALID_VAL)
23 return;
24 hb_atomic_int32_add(&font->ref_cnt, -1);
25 if (hb_atomic_int32_get(&font->ref_cnt) > 0)
26 return;
27 hb_atomic_int32_set(&font->ref_cnt, REF_CNT_INVALID_VAL);
21 if (!font)
22 return;
23 if (hb_atomic_int32_get(&font->ref_cnt) == REF_CNT_INVALID_VAL)
24 return;
25 hb_atomic_int32_add(&font->ref_cnt, -1);
26 if (hb_atomic_int32_get(&font->ref_cnt) > 0)
27 return;
28 hb_atomic_int32_set(&font->ref_cnt, REF_CNT_INVALID_VAL);
28 29
29 30 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
30 if (font->shaper_data.graphite2
31 && font->shaper_data.graphite2 != HB_SHAPER_DATA_INVALID
32 && font->shaper_data.graphite2 != HB_SHAPER_DATA_SUCCEEDED)
33 hb_graphite2_shaper_font_data_destroy(font->shaper_data.graphite2);
31 if (font->shaper_data.graphite2
32 && font->shaper_data.graphite2 != HB_SHAPER_DATA_INVALID
33 && font->shaper_data.graphite2 != HB_SHAPER_DATA_SUCCEEDED)
34 hb_graphite2_shaper_font_data_destroy(font->shaper_data.
35 graphite2);
34 36 #endif #endif
35 37 #ifdef HAVE_OT #ifdef HAVE_OT
36 if (font->shaper_data.ot
37 && font->shaper_data.ot != HB_SHAPER_DATA_INVALID
38 && font->shaper_data.ot != HB_SHAPER_DATA_SUCCEEDED)
39 hb_ot_shaper_font_data_destroy(font->shaper_data.ot);
38 if (font->shaper_data.ot
39 && font->shaper_data.ot != HB_SHAPER_DATA_INVALID
40 && font->shaper_data.ot != HB_SHAPER_DATA_SUCCEEDED)
41 hb_ot_shaper_font_data_destroy(font->shaper_data.ot);
40 42 #endif #endif
41 if (font->shaper_data.fallback
42 && font->shaper_data.fallback != HB_SHAPER_DATA_INVALID
43 && font->shaper_data.fallback != HB_SHAPER_DATA_SUCCEEDED)
44 hb_fallback_shaper_font_data_destroy(font->shaper_data.fallback);
43 if (font->shaper_data.fallback
44 && font->shaper_data.fallback != HB_SHAPER_DATA_INVALID
45 && font->shaper_data.fallback != HB_SHAPER_DATA_SUCCEEDED)
46 hb_fallback_shaper_font_data_destroy(font->shaper_data.
47 fallback);
45 48
46 if (font->destroy)
47 font->destroy(font->user_data);
49 if (font->destroy)
50 font->destroy(font->user_data);
48 51
49 hb_font_destroy(font->parent);
50 hb_face_destroy(font->face);
51 hb_font_funcs_destroy(font->klass);
52 free(font);
52 hb_font_destroy(font->parent);
53 hb_face_destroy(font->face);
54 hb_font_funcs_destroy(font->klass);
55 free(font);
53 56 } }
54 57
55 hb_bool_t
56 hb_font_get_glyph(hb_font_t *font,
57 hb_codepoint_t unicode,
58 hb_codepoint_t variation_selector,
59 hb_codepoint_t *glyph)
58 hb_bool_t hb_font_get_glyph(hb_font_t * font, hb_codepoint_t unicode,
59 hb_codepoint_t variation_selector,
60 hb_codepoint_t * glyph)
60 61 { {
61 *glyph = 0;
62 return font->klass->get.glyph(font,
63 font->user_data,
64 unicode,
65 variation_selector,
66 glyph,
67 font->klass->user_data.glyph);
62 *glyph = 0;
63 return font->klass->get.glyph(font, font->user_data, unicode,
64 variation_selector, glyph,
65 font->klass->user_data.glyph);
68 66 } }
69 67
70 //Convert from parent-font user-space to our user-space
71 hb_position_t
72 hb_font_parent_scale_x_distance(hb_font_t *font,
73 hb_position_t v)
68 /*Convert from parent-font user-space to our user-space*/
69 hb_position_t hb_font_parent_scale_x_distance(hb_font_t * font, hb_position_t v)
74 70 { {
75 if (font->parent && font->parent->x_scale != font->x_scale)
76 return v * (int64_t) font->x_scale / font->parent->x_scale;
77 return v;
71 if (font->parent && font->parent->x_scale != font->x_scale)
72 return v * (int64_t) font->x_scale / font->parent->x_scale;
73 return v;
78 74 } }
79 75
80 hb_position_t
81 hb_font_parent_scale_y_distance(hb_font_t *font,
82 hb_position_t v)
76 hb_position_t hb_font_parent_scale_y_distance(hb_font_t * font, hb_position_t v)
83 77 { {
84 if (font->parent && font->parent->y_scale != font->y_scale)
85 return v * (int64_t) font->y_scale / font->parent->y_scale;
86 return v;
78 if (font->parent && font->parent->y_scale != font->y_scale)
79 return v * (int64_t) font->y_scale / font->parent->y_scale;
80 return v;
87 81 } }
88 82
89 hb_position_t
90 hb_font_parent_scale_x_position(hb_font_t *font,
91 hb_position_t v)
83 hb_position_t hb_font_parent_scale_x_position(hb_font_t * font, hb_position_t v)
92 84 { {
93 return hb_font_parent_scale_x_distance(font, v);
85 return hb_font_parent_scale_x_distance(font, v);
94 86 } }
95 87
96 hb_position_t
97 hb_font_parent_scale_y_position(hb_font_t *font,
98 hb_position_t v)
88 hb_position_t hb_font_parent_scale_y_position(hb_font_t * font, hb_position_t v)
99 89 { {
100 return hb_font_parent_scale_y_distance(font, v);
90 return hb_font_parent_scale_y_distance(font, v);
101 91 } }
102 92
103 void
104 hb_font_parent_scale_position(hb_font_t *font,
105 hb_position_t *x,
106 hb_position_t *y)
93 void hb_font_parent_scale_position(hb_font_t * font, hb_position_t * x,
94 hb_position_t * y)
107 95 { {
108 *x = hb_font_parent_scale_x_position(font, *x);
109 *y = hb_font_parent_scale_y_position(font, *y);
96 *x = hb_font_parent_scale_x_position(font, *x);
97 *y = hb_font_parent_scale_y_position(font, *y);
110 98 } }
111 99
112 void
113 hb_font_parent_scale_distance(hb_font_t *font,
114 hb_position_t *x,
115 hb_position_t *y)
100 void hb_font_parent_scale_distance(hb_font_t * font, hb_position_t * x,
101 hb_position_t * y)
116 102 { {
117 *x = hb_font_parent_scale_x_distance(font, *x);
118 *y = hb_font_parent_scale_y_distance(font, *y);
103 *x = hb_font_parent_scale_x_distance(font, *x);
104 *y = hb_font_parent_scale_y_distance(font, *y);
119 105 } }
120 106
121 hb_position_t
122 hb_font_get_glyph_h_advance(hb_font_t *font,
123 hb_codepoint_t glyph)
107 hb_position_t hb_font_get_glyph_h_advance(hb_font_t * font,
108 hb_codepoint_t glyph)
124 109 { {
125 return font->klass->get.glyph_h_advance(
126 font,
127 font->user_data,
128 glyph,
129 font->klass->user_data.glyph_h_advance);
110 return font->klass->get.glyph_h_advance(font, font->user_data, glyph,
111 font->klass->user_data.
112 glyph_h_advance);
130 113 } }
131 114
132
133 hb_position_t
134 hb_font_get_glyph_v_advance(hb_font_t *font,
135 hb_codepoint_t glyph)
115 hb_position_t hb_font_get_glyph_v_advance(hb_font_t * font,
116 hb_codepoint_t glyph)
136 117 { {
137 return font->klass->get.glyph_v_advance(
138 font,
139 font->user_data,
140 glyph,
141 font->klass->user_data.glyph_v_advance);
118 return font->klass->get.glyph_v_advance(font, font->user_data, glyph,
119 font->klass->user_data.
120 glyph_v_advance);
142 121 } }
143 122
144 hb_bool_t
145 hb_font_get_glyph_h_origin(hb_font_t *font,
146 hb_codepoint_t glyph,
147 hb_position_t *x,
148 hb_position_t *y)
123 hb_bool_t hb_font_get_glyph_h_origin(hb_font_t * font, hb_codepoint_t glyph,
124 hb_position_t * x, hb_position_t * y)
149 125 { {
150 *x = *y = 0;
151 return font->klass->get.glyph_h_origin(font,
152 font->user_data,
153 glyph,
154 x, y,
155 font->klass->user_data.glyph_h_origin);
126 *x = *y = 0;
127 return font->klass->get.glyph_h_origin(font, font->user_data, glyph, x,
128 y,
129 font->klass->user_data.
130 glyph_h_origin);
156 131 } }
157 132
158 hb_bool_t
159 hb_font_get_glyph_v_origin(hb_font_t *font,
160 hb_codepoint_t glyph,
161 hb_position_t *x,
162 hb_position_t *y)
133 hb_bool_t hb_font_get_glyph_v_origin(hb_font_t * font, hb_codepoint_t glyph,
134 hb_position_t * x, hb_position_t * y)
163 135 { {
164 *x = *y = 0;
165 return font->klass->get.glyph_v_origin(font,
166 font->user_data,
167 glyph,
168 x, y,
169 font->klass->user_data.glyph_v_origin);
136 *x = *y = 0;
137 return font->klass->get.glyph_v_origin(font, font->user_data, glyph, x,
138 y,
139 font->klass->user_data.
140 glyph_v_origin);
170 141 } }
171 142
172 hb_position_t
173 hb_font_get_glyph_h_kerning(hb_font_t *font,
174 hb_codepoint_t left_glyph,
175 hb_codepoint_t right_glyph)
143 hb_position_t hb_font_get_glyph_h_kerning(hb_font_t * font,
144 hb_codepoint_t left_glyph,
145 hb_codepoint_t right_glyph)
176 146 { {
177 return font->klass->get.glyph_h_kerning(
178 font,
179 font->user_data,
180 left_glyph,
181 right_glyph,
182 font->klass->user_data.glyph_h_kerning);
147 return font->klass->get.glyph_h_kerning(font, font->user_data,
148 left_glyph, right_glyph,
149 font->klass->user_data.
150 glyph_h_kerning);
183 151 } }
184 152
185 hb_position_t
186 hb_font_get_glyph_v_kerning(hb_font_t *font,
187 hb_codepoint_t top_glyph,
188 hb_codepoint_t bottom_glyph)
153 hb_position_t hb_font_get_glyph_v_kerning(hb_font_t * font,
154 hb_codepoint_t top_glyph,
155 hb_codepoint_t bottom_glyph)
189 156 { {
190 return font->klass->get.glyph_v_kerning(
191 font,
192 font->user_data,
193 top_glyph,
194 bottom_glyph,
195 font->klass->user_data.glyph_v_kerning);
196 }
197
198 hb_bool_t
199 hb_font_get_glyph_extents(hb_font_t *font,
200 hb_codepoint_t glyph,
201 hb_glyph_extents_t *extents)
202 {
203 memset(extents, 0, sizeof(*extents));
204 return font->klass->get.glyph_extents(font,
205 font->user_data,
206 glyph,
207 extents,
208 font->klass->user_data.glyph_extents);
209 }
210
211 hb_bool_t
212 hb_font_get_glyph_contour_point(hb_font_t *font,
213 hb_codepoint_t glyph,
214 unsigned int point_index,
215 hb_position_t *x,
216 hb_position_t *y)
217 {
218 *x = *y = 0;
219 return font->klass->get.glyph_contour_point(
220 font,
221 font->user_data,
222 glyph, point_index,
223 x, y,
224 font->klass->user_data.glyph_contour_point);
225 }
226
227 hb_bool_t
228 hb_font_get_glyph_name(hb_font_t *font,
229 hb_codepoint_t glyph,
230 char *name,
231 unsigned int size)
232 {
233 if (size) *name = '\0';
234 return font->klass->get.glyph_name(font,
235 font->user_data,
236 glyph,
237 name,
238 size,
239 font->klass->user_data.glyph_name);
240 }
241
242 hb_bool_t
243 hb_font_get_glyph_from_name(hb_font_t *font,
244 const char *name,
245 int len,//-1 means nul-terminated
246 hb_codepoint_t *glyph)
247 {
248 *glyph = 0;
249 if (len == -1) len = strlen(name);
250 return font->klass->get.glyph_from_name(
251 font,
252 font->user_data,
253 name,
254 len,
255 glyph,
256 font->klass->user_data.glyph_from_name);
257 }
258
259 static hb_bool_t
260 hb_font_get_glyph_nil(hb_font_t *font,
261 void *font_data HB_UNUSED,
262 hb_codepoint_t unicode,
263 hb_codepoint_t variation_selector,
264 hb_codepoint_t *glyph,
265 void *user_data HB_UNUSED)
266 {
267 if (font->parent)
268 return hb_font_get_glyph(font->parent,
269 unicode,
270 variation_selector,
271 glyph);
272
273 *glyph = 0;
274 return FALSE;
275 }
276
277 static hb_position_t
278 hb_font_get_glyph_h_advance_nil(hb_font_t *font,
279 void *font_data HB_UNUSED,
280 hb_codepoint_t glyph,
281 void *user_data HB_UNUSED)
282 {
283 if (font->parent)
284 return hb_font_parent_scale_x_distance(font, hb_font_get_glyph_h_advance(
285 font->parent,
286 glyph));
287 return font->x_scale;
288 }
289
290 static hb_position_t
291 hb_font_get_glyph_v_advance_nil(hb_font_t *font,
292 void *font_data HB_UNUSED,
293 hb_codepoint_t glyph,
294 void *user_data HB_UNUSED)
295 {
296 if (font->parent)
297 return hb_font_parent_scale_y_distance(font, hb_font_get_glyph_v_advance(
298 font->parent,
299 glyph));
300 return font->y_scale;
301 }
302
303 static hb_bool_t
304 hb_font_get_glyph_h_origin_nil(hb_font_t *font,
305 void *font_data HB_UNUSED,
306 hb_codepoint_t glyph,
307 hb_position_t *x,
308 hb_position_t *y,
309 void *user_data HB_UNUSED)
310 {
311 if (font->parent) {
312 hb_bool_t ret = hb_font_get_glyph_h_origin(font->parent, glyph, x, y);
313 if (ret)
314 hb_font_parent_scale_position(font, x, y);
315 return ret;
316 }
317
318 *x = *y = 0;
319 return FALSE;
320 }
321
322 static hb_bool_t
323 hb_font_get_glyph_v_origin_nil(hb_font_t *font,
324 void *font_data HB_UNUSED,
325 hb_codepoint_t glyph,
326 hb_position_t *x,
327 hb_position_t *y,
328 void *user_data HB_UNUSED)
329 {
330 if (font->parent) {
331 hb_bool_t ret = hb_font_get_glyph_v_origin(font->parent, glyph, x, y);
332 if (ret)
333 hb_font_parent_scale_position(font, x, y);
334 return ret;
335 }
336
337 *x = *y = 0;
338 return FALSE;
339 }
340
341 static hb_position_t
342 hb_font_get_glyph_h_kerning_nil(hb_font_t *font,
343 void *font_data HB_UNUSED,
344 hb_codepoint_t left_glyph,
345 hb_codepoint_t right_glyph,
346 void *user_data HB_UNUSED)
347 {
348 if (font->parent)
349 return hb_font_parent_scale_x_distance(font, hb_font_get_glyph_h_kerning(
350 font->parent,
351 left_glyph,
352 right_glyph));
353 return 0;
354 }
355
356 static hb_position_t
357 hb_font_get_glyph_v_kerning_nil(hb_font_t *font,
358 void *font_data HB_UNUSED,
359 hb_codepoint_t top_glyph,
360 hb_codepoint_t bottom_glyph,
361 void *user_data HB_UNUSED)
362 {
363 if (font->parent)
364 return hb_font_parent_scale_y_distance(font, hb_font_get_glyph_v_kerning(
365 font->parent,
366 top_glyph,
367 bottom_glyph));
368 return 0;
369 }
370
371 static hb_bool_t
372 hb_font_get_glyph_extents_nil(hb_font_t *font,
373 void *font_data HB_UNUSED,
374 hb_codepoint_t glyph,
375 hb_glyph_extents_t *extents,
376 void *user_data HB_UNUSED)
377 {
378 if (font->parent) {
379 hb_bool_t ret = hb_font_get_glyph_extents(font->parent, glyph, extents);
380 if (ret) {
381 hb_font_parent_scale_position(font,
382 &extents->x_bearing,
383 &extents->y_bearing);
384 hb_font_parent_scale_distance(font, &extents->width, &extents->height);
385 }
386 return ret;
387 }
388
389 memset(extents, 0, sizeof(*extents));
390 return FALSE;
391 }
392
393 static hb_bool_t
394 hb_font_get_glyph_contour_point_nil(hb_font_t *font,
395 void *font_data HB_UNUSED,
396 hb_codepoint_t glyph,
397 unsigned int point_index,
398 hb_position_t *x,
399 hb_position_t *y,
400 void *user_data HB_UNUSED)
401 {
402 if (font->parent) {
403 hb_bool_t ret = hb_font_get_glyph_contour_point(font->parent,
404 glyph,
405 point_index,
406 x, y);
407 if (ret)
408 hb_font_parent_scale_position(font, x, y);
409 return ret;
410 }
411
412 *x = *y = 0;
413 return FALSE;
414 }
415
416 static hb_bool_t
417 hb_font_get_glyph_name_nil(hb_font_t *font,
418 void *font_data HB_UNUSED,
419 hb_codepoint_t glyph,
420 char *name, unsigned int size,
421 void *user_data HB_UNUSED)
422 {
423 if (font->parent)
424 return hb_font_get_glyph_name(font->parent, glyph, name, size);
425
426 if (size) *name = '\0';
427 return FALSE;
428 }
429
430 static hb_bool_t
431 hb_font_get_glyph_from_name_nil(hb_font_t *font,
432 void *font_data HB_UNUSED,
433 const char *name,
434 int len,//-1 means nul-terminated
435 hb_codepoint_t *glyph,
436 void *user_data HB_UNUSED)
437 {
438 if (font->parent)
439 return hb_font_get_glyph_from_name(font->parent, name, len, glyph);
440
441 *glyph = 0;
442 return FALSE;
443 }
444
445 //A bit higher-level, and with fallback
446
447 void
448 hb_font_get_glyph_advance_for_direction(hb_font_t *font,
449 hb_codepoint_t glyph,
450 hb_direction_t direction,
451 hb_position_t *x, hb_position_t *y)
452 {
453 if (HB_DIRECTION_IS_HORIZONTAL(direction)) {
454 *x = hb_font_get_glyph_h_advance(font, glyph);
455 *y = 0;
456 } else {
457 *x = 0;
458 *y = hb_font_get_glyph_v_advance(font, glyph);
459 }
460 }
461
462 //Internal only
463 static void
464 hb_font_guess_v_origin_minus_h_origin(hb_font_t *font,
465 hb_codepoint_t glyph,
466 hb_position_t *x, hb_position_t *y)
157 return font->klass->get.glyph_v_kerning(font, font->user_data,
158 top_glyph, bottom_glyph,
159 font->klass->user_data.
160 glyph_v_kerning);
161 }
162
163 hb_bool_t hb_font_get_glyph_extents(hb_font_t * font, hb_codepoint_t glyph,
164 hb_glyph_extents_t * extents)
467 165 { {
468 *x = hb_font_get_glyph_h_advance(font, glyph) / 2;
166 memset(extents, 0, sizeof(*extents));
167 return font->klass->get.glyph_extents(font, font->user_data, glyph,
168 extents,
169 font->klass->user_data.
170 glyph_extents);
171 }
469 172
470 //TODO:use font_metics.ascent
471 *y = font->y_scale;
173 hb_bool_t hb_font_get_glyph_contour_point(hb_font_t * font,
174 hb_codepoint_t glyph,
175 unsigned int point_index,
176 hb_position_t * x, hb_position_t * y)
177 {
178 *x = *y = 0;
179 return font->klass->get.glyph_contour_point(font, font->user_data,
180 glyph, point_index, x, y,
181 font->klass->user_data.
182 glyph_contour_point);
472 183 } }
473 184
474 void
475 hb_font_get_glyph_origin_for_direction(hb_font_t *font,
476 hb_codepoint_t glyph,
477 hb_direction_t direction,
478 hb_position_t *x, hb_position_t *y)
185 hb_bool_t hb_font_get_glyph_name(hb_font_t * font, hb_codepoint_t glyph,
186 char *name, unsigned int size)
479 187 { {
480 if (HB_DIRECTION_IS_HORIZONTAL(direction)) {
481 if (!hb_font_get_glyph_h_origin(font, glyph, x, y)
482 && hb_font_get_glyph_v_origin(font, glyph, x, y)) {
483 hb_position_t dx, dy;
484 hb_font_guess_v_origin_minus_h_origin(font, glyph, &dx, &dy);
485 *x -= dx; *y -= dy;
486 }
487 } else {
488 if (!hb_font_get_glyph_v_origin(font, glyph, x, y)
489 && hb_font_get_glyph_h_origin(font, glyph, x, y)) {
490 hb_position_t dx, dy;
491 hb_font_guess_v_origin_minus_h_origin(font, glyph, &dx, &dy);
492 *x += dx; *y += dy;
493 }
494 }
188 if (size)
189 *name = '\0';
190 return font->klass->get.glyph_name(font, font->user_data, glyph, name,
191 size,
192 font->klass->user_data.glyph_name);
495 193 } }
496 194
497 void
498 hb_font_subtract_glyph_origin_for_direction(hb_font_t *font,
499 hb_codepoint_t glyph,
500 hb_direction_t direction,
501 hb_position_t *x, hb_position_t *y)
195 hb_bool_t hb_font_get_glyph_from_name(hb_font_t * font, const char *name,
196 int len /*-1 means nul-terminated*/ ,
197 hb_codepoint_t * glyph)
502 198 { {
503 hb_position_t origin_x, origin_y;
199 *glyph = 0;
200 if (len == -1)
201 len = strlen(name);
202 return font->klass->get.glyph_from_name(font, font->user_data, name,
203 len, glyph,
204 font->klass->user_data.
205 glyph_from_name);
206 }
504 207
505 hb_font_get_glyph_origin_for_direction(font, glyph, direction, &origin_x,
506 &origin_y);
208 static hb_bool_t hb_font_get_glyph_nil(hb_font_t * font,
209 void *font_data HB_UNUSED,
210 hb_codepoint_t unicode,
211 hb_codepoint_t variation_selector,
212 hb_codepoint_t * glyph,
213 void *user_data HB_UNUSED)
214 {
215 if (font->parent)
216 return hb_font_get_glyph(font->parent, unicode,
217 variation_selector, glyph);
507 218
508 *x -= origin_x;
509 *y -= origin_y;
219 *glyph = 0;
220 return FALSE;
510 221 } }
511 222
223 static hb_position_t hb_font_get_glyph_h_advance_nil(hb_font_t * font,
224 void *font_data HB_UNUSED,
225 hb_codepoint_t glyph,
226 void *user_data HB_UNUSED)
227 {
228 if (font->parent)
229 return hb_font_parent_scale_x_distance(font,
230 hb_font_get_glyph_h_advance
231 (font->parent, glyph));
232 return font->x_scale;
233 }
234
235 static hb_position_t hb_font_get_glyph_v_advance_nil(hb_font_t * font,
236 void *font_data HB_UNUSED,
237 hb_codepoint_t glyph,
238 void *user_data HB_UNUSED)
239 {
240 if (font->parent)
241 return hb_font_parent_scale_y_distance(font,
242 hb_font_get_glyph_v_advance
243 (font->parent, glyph));
244 return font->y_scale;
245 }
246
247 static hb_bool_t hb_font_get_glyph_h_origin_nil(hb_font_t * font,
248 void *font_data HB_UNUSED,
249 hb_codepoint_t glyph,
250 hb_position_t * x,
251 hb_position_t * y,
252 void *user_data HB_UNUSED)
253 {
254 if (font->parent) {
255 hb_bool_t ret;
256
257 ret = hb_font_get_glyph_h_origin(font->parent, glyph, x, y);
258 if (ret)
259 hb_font_parent_scale_position(font, x, y);
260 return ret;
261 }
262
263 *x = *y = 0;
264 return FALSE;
265 }
266
267 static hb_bool_t hb_font_get_glyph_v_origin_nil(hb_font_t * font,
268 void *font_data HB_UNUSED,
269 hb_codepoint_t glyph,
270 hb_position_t * x,
271 hb_position_t * y,
272 void *user_data HB_UNUSED)
273 {
274 if (font->parent) {
275 hb_bool_t ret;
276
277 ret = hb_font_get_glyph_v_origin(font->parent, glyph, x, y);
278 if (ret)
279 hb_font_parent_scale_position(font, x, y);
280 return ret;
281 }
282
283 *x = *y = 0;
284 return FALSE;
285 }
286
287 static hb_position_t hb_font_get_glyph_h_kerning_nil(hb_font_t * font,
288 void *font_data HB_UNUSED,
289 hb_codepoint_t left_glyph,
290 hb_codepoint_t right_glyph,
291 void *user_data HB_UNUSED)
292 {
293 if (font->parent)
294 return hb_font_parent_scale_x_distance(font,
295 hb_font_get_glyph_h_kerning
296 (font->parent,
297 left_glyph,
298 right_glyph));
299 return 0;
300 }
301
302 static hb_position_t hb_font_get_glyph_v_kerning_nil(hb_font_t * font,
303 void *font_data HB_UNUSED,
304 hb_codepoint_t top_glyph,
305 hb_codepoint_t
306 bottom_glyph,
307 void *user_data HB_UNUSED)
308 {
309 if (font->parent)
310 return hb_font_parent_scale_y_distance(font,
311 hb_font_get_glyph_v_kerning
312 (font->parent, top_glyph,
313 bottom_glyph));
314 return 0;
315 }
316
317 static hb_bool_t hb_font_get_glyph_extents_nil(hb_font_t * font,
318 void *font_data HB_UNUSED,
319 hb_codepoint_t glyph,
320 hb_glyph_extents_t * extents,
321 void *user_data HB_UNUSED)
322 {
323 if (font->parent) {
324 hb_bool_t ret;
325
326 ret = hb_font_get_glyph_extents(font->parent, glyph, extents);
327 if (ret) {
328 hb_font_parent_scale_position(font, &extents->x_bearing,
329 &extents->y_bearing);
330 hb_font_parent_scale_distance(font, &extents->width,
331 &extents->height);
332 }
333 return ret;
334 }
335
336 memset(extents, 0, sizeof(*extents));
337 return FALSE;
338 }
339
340 static hb_bool_t hb_font_get_glyph_contour_point_nil(hb_font_t * font,
341 void *font_data HB_UNUSED,
342 hb_codepoint_t glyph,
343 unsigned int point_index,
344 hb_position_t * x,
345 hb_position_t * y,
346 void *user_data HB_UNUSED)
347 {
348 if (font->parent) {
349 hb_bool_t ret;
350
351 ret =
352 hb_font_get_glyph_contour_point(font->parent, glyph,
353 point_index, x, y);
354 if (ret)
355 hb_font_parent_scale_position(font, x, y);
356 return ret;
357 }
358
359 *x = *y = 0;
360 return FALSE;
361 }
362
363 static hb_bool_t hb_font_get_glyph_name_nil(hb_font_t * font,
364 void *font_data HB_UNUSED,
365 hb_codepoint_t glyph, char *name,
366 unsigned int size,
367 void *user_data HB_UNUSED)
368 {
369 if (font->parent)
370 return hb_font_get_glyph_name(font->parent, glyph, name, size);
371
372 if (size)
373 *name = '\0';
374 return FALSE;
375 }
376
377 static hb_bool_t hb_font_get_glyph_from_name_nil(hb_font_t * font,
378 void *font_data HB_UNUSED,
379 const char *name,
380 int len
381 /*-1 means nul-terminated*/ ,
382 hb_codepoint_t * glyph,
383 void *user_data HB_UNUSED)
384 {
385 if (font->parent)
386 return hb_font_get_glyph_from_name(font->parent, name, len,
387 glyph);
388
389 *glyph = 0;
390 return FALSE;
391 }
392
393 /*A bit higher-level, and with fallback*/
394
395 void hb_font_get_glyph_advance_for_direction(hb_font_t * font,
396 hb_codepoint_t glyph,
397 hb_direction_t direction,
398 hb_position_t * x,
399 hb_position_t * y)
400 {
401 if (HB_DIRECTION_IS_HORIZONTAL(direction)) {
402 *x = hb_font_get_glyph_h_advance(font, glyph);
403 *y = 0;
404 } else {
405 *x = 0;
406 *y = hb_font_get_glyph_v_advance(font, glyph);
407 }
408 }
409
410 /*Internal only*/
411 static void
412 hb_font_guess_v_origin_minus_h_origin(hb_font_t * font, hb_codepoint_t glyph,
413 hb_position_t * x, hb_position_t * y)
414 {
415 *x = hb_font_get_glyph_h_advance(font, glyph) / 2;
416
417 /*TODO:use font_metics.ascent */
418 *y = font->y_scale;
419 }
420
421 void hb_font_get_glyph_origin_for_direction(hb_font_t * font,
422 hb_codepoint_t glyph,
423 hb_direction_t direction,
424 hb_position_t * x,
425 hb_position_t * y)
426 {
427 if (HB_DIRECTION_IS_HORIZONTAL(direction)) {
428 if (!hb_font_get_glyph_h_origin(font, glyph, x, y)
429 && hb_font_get_glyph_v_origin(font, glyph, x, y)) {
430 hb_position_t dx, dy;
431 hb_font_guess_v_origin_minus_h_origin(font, glyph, &dx,
432 &dy);
433 *x -= dx;
434 *y -= dy;
435 }
436 } else {
437 if (!hb_font_get_glyph_v_origin(font, glyph, x, y)
438 && hb_font_get_glyph_h_origin(font, glyph, x, y)) {
439 hb_position_t dx, dy;
440 hb_font_guess_v_origin_minus_h_origin(font, glyph, &dx,
441 &dy);
442 *x += dx;
443 *y += dy;
444 }
445 }
446 }
447
448 void hb_font_subtract_glyph_origin_for_direction(hb_font_t * font,
449 hb_codepoint_t glyph,
450 hb_direction_t direction,
451 hb_position_t * x,
452 hb_position_t * y)
453 {
454 hb_position_t origin_x, origin_y;
455
456 hb_font_get_glyph_origin_for_direction(font, glyph, direction,
457 &origin_x, &origin_y);
458
459 *x -= origin_x;
460 *y -= origin_y;
461 }
462
463 /*XXX:should go in lib "global init"*/
512 464 static hb_font_funcs_t hb_font_funcs_nil = { static hb_font_funcs_t hb_font_funcs_nil = {
513 REF_CNT_INVALID_VAL,//ref_cnt
514 TRUE,//immutable
515 {//get
516 hb_font_get_glyph_nil,
517 hb_font_get_glyph_h_advance_nil,
518 hb_font_get_glyph_v_advance_nil,
519 hb_font_get_glyph_h_origin_nil,
520 hb_font_get_glyph_v_origin_nil,
521 hb_font_get_glyph_h_kerning_nil,
522 hb_font_get_glyph_v_kerning_nil,
523 hb_font_get_glyph_extents_nil,
524 hb_font_get_glyph_contour_point_nil,
525 hb_font_get_glyph_name_nil,
526 hb_font_get_glyph_from_name_nil,
527 },
528 {//user_data
529 NULL,//glyph
530 NULL,//glyph_h_advance
531 NULL,//glyph_v_advance
532 NULL,//glyph_h_origin
533 NULL,//glyph_v_origin
534 NULL,//glyph_h_kerning
535 NULL,//glyph_v_kerning
536 NULL,//glyph_extents
537 NULL,//glyph_contour_po
538 NULL,//glyph_name
539 NULL,//glyph_from_name
540 },
541 {//destroy
542 NULL,//glyph
543 NULL,//glyph_h_advance
544 NULL,//glyph_v_advance
545 NULL,//glyph_h_origin
546 NULL,//glyph_v_origin
547 NULL,//glyph_h_kerning
548 NULL,//glyph_v_kerning
549 NULL,//glyph_extents
550 NULL,//glyph_contour_po
551 NULL,//glyph_name
552 NULL,//glyph_from_name
553 }
465 REF_CNT_INVALID_VAL, /*ref_cnt */
466 TRUE, /*immutable */
467 { /*get */
468 hb_font_get_glyph_nil,
469 hb_font_get_glyph_h_advance_nil,
470 hb_font_get_glyph_v_advance_nil,
471 hb_font_get_glyph_h_origin_nil,
472 hb_font_get_glyph_v_origin_nil,
473 hb_font_get_glyph_h_kerning_nil,
474 hb_font_get_glyph_v_kerning_nil,
475 hb_font_get_glyph_extents_nil,
476 hb_font_get_glyph_contour_point_nil,
477 hb_font_get_glyph_name_nil,
478 hb_font_get_glyph_from_name_nil,
479 },
480 { /*user_data */
481 NULL, /*glyph */
482 NULL, /*glyph_h_advance */
483 NULL, /*glyph_v_advance */
484 NULL, /*glyph_h_origin */
485 NULL, /*glyph_v_origin */
486 NULL, /*glyph_h_kerning */
487 NULL, /*glyph_v_kerning */
488 NULL, /*glyph_extents */
489 NULL, /*glyph_contour_po */
490 NULL, /*glyph_name */
491 NULL, /*glyph_from_name */
492 },
493 { /*destroy */
494 NULL, /*glyph */
495 NULL, /*glyph_h_advance */
496 NULL, /*glyph_v_advance */
497 NULL, /*glyph_h_origin */
498 NULL, /*glyph_v_origin */
499 NULL, /*glyph_h_kerning */
500 NULL, /*glyph_v_kerning */
501 NULL, /*glyph_extents */
502 NULL, /*glyph_contour_po */
503 NULL, /*glyph_name */
504 NULL, /*glyph_from_name */
505 }
554 506 }; };
555 507
508 /*XXX:should go in lib "global init"*/
556 509 static hb_font_t hb_font_nil = { static hb_font_t hb_font_nil = {
557 REF_CNT_INVALID_VAL,//ref_cnt
558 TRUE,//immutable
559 NULL,//parent
560 NULL,//face
561 0,//x_scale
562 0,//y_scale
563 0,//x_ppem
564 0,//y_ppem
565 NULL,//klass
566 NULL,//user_data
567 NULL,//destroy
568 {
510 REF_CNT_INVALID_VAL, /*ref_cnt */
511 TRUE, /*immutable */
512 NULL, /*parent */
513 NULL, /*face */
514 0, /*x_scale */
515 0, /*y_scale */
516 0, /*x_ppem */
517 0, /*y_ppem */
518 NULL, /*klass */
519 NULL, /*user_data */
520 NULL, /*destroy */
521 {
569 522 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
570 HB_SHAPER_DATA_INVALID,
523 HB_SHAPER_DATA_INVALID,
571 524 #endif #endif
572 525 #ifdef HAVE_OT #ifdef HAVE_OT
573 HB_SHAPER_DATA_INVALID,
526 HB_SHAPER_DATA_INVALID,
574 527 #endif #endif
575 HB_SHAPER_DATA_INVALID//fallback
576 },
528 HB_SHAPER_DATA_INVALID /*fallback */
529 },
577 530 }; };
578 531
579 hb_font_funcs_t *
580 hb_font_funcs_get_empty(void)
581 {
582 return &hb_font_funcs_nil;
583 }
584
585 hb_font_t *
586 hb_font_get_empty(void)
587 {
588 return &hb_font_nil;
589 }
590
591 void
592 hb_font_funcs_destroy(hb_font_funcs_t *ffuncs)
593 {
594 if (!ffuncs)
595 return;
596 if (hb_atomic_int32_get(&ffuncs->ref_cnt) == REF_CNT_INVALID_VAL)
597 return;
598 hb_atomic_int32_add(&ffuncs->ref_cnt, -1);
599 if (hb_atomic_int32_get(&ffuncs->ref_cnt) > 0)
600 return;
601 hb_atomic_int32_set(&ffuncs->ref_cnt, REF_CNT_INVALID_VAL);
602
603 if (ffuncs->destroy.glyph)
604 ffuncs->destroy.glyph(ffuncs->user_data.glyph);
605 if (ffuncs->destroy.glyph_h_advance)
606 ffuncs->destroy.glyph_h_advance(ffuncs->user_data.glyph_h_advance);
607 if (ffuncs->destroy.glyph_v_advance)
608 ffuncs->destroy.glyph_v_advance(ffuncs->user_data.glyph_v_advance);
609 if (ffuncs->destroy.glyph_h_origin)
610 ffuncs->destroy.glyph_h_origin(ffuncs->user_data.glyph_h_origin);
611 if (ffuncs->destroy.glyph_v_origin)
612 ffuncs->destroy.glyph_v_origin(ffuncs->user_data.glyph_v_origin);
613 if (ffuncs->destroy.glyph_h_kerning)
614 ffuncs->destroy.glyph_h_kerning(ffuncs->user_data.glyph_h_kerning);
615 if (ffuncs->destroy.glyph_v_kerning)
616 ffuncs->destroy.glyph_v_kerning(ffuncs->user_data.glyph_v_kerning);
617 if (ffuncs->destroy.glyph_extents)
618 ffuncs->destroy.glyph_extents(ffuncs->user_data.glyph_extents);
619 if (ffuncs->destroy.glyph_contour_point)
620 ffuncs->destroy.glyph_contour_point(ffuncs->user_data.glyph_contour_point);
621 if (ffuncs->destroy.glyph_name)
622 ffuncs->destroy.glyph_name(ffuncs->user_data.glyph_name);
623 if (ffuncs->destroy.glyph_from_name)
624 ffuncs->destroy.glyph_from_name(ffuncs->user_data.glyph_from_name);
625
626 free(ffuncs);
627 }
628
629 hb_font_t *
630 hb_font_create(hb_face_t *face)
631 {
632 if (!face)
633 face = hb_face_get_empty();
634
635 if (face->ref_cnt == REF_CNT_INVALID_VAL)
636 return hb_font_get_empty();
637
638 hb_font_t *font = calloc(1, sizeof(*font));
639 if (!font)
640 return hb_font_get_empty();
641
642 hb_atomic_int32_set(&font->ref_cnt, 1);
643 hb_face_make_immutable(face);
644 font->face = hb_face_reference(face);
645 font->klass = hb_font_funcs_get_empty();
646 return font;
647 }
648
649 void
650 hb_font_funcs_set_glyph_func(hb_font_funcs_t *ffuncs,
651 hb_font_get_glyph_func_t func,
652 void *user_data,
653 hb_destroy_func_t destroy)
654 {
655 if (ffuncs->immutable) {
656 if (destroy)
657 destroy(user_data);
658 return;
659 }
660
661 if (ffuncs->destroy.glyph)
662 ffuncs->destroy.glyph(ffuncs->user_data.glyph);
663
664 if (func) {
665 ffuncs->get.glyph = func;
666 ffuncs->user_data.glyph = user_data;
667 ffuncs->destroy.glyph = destroy;
668 } else {
669 ffuncs->get.glyph = hb_font_get_glyph_nil;
670 ffuncs->user_data.glyph = NULL;
671 ffuncs->destroy.glyph = NULL;
672 }
673 }
674
675 void
676 hb_font_funcs_set_glyph_h_advance_func(hb_font_funcs_t *ffuncs,
677 hb_font_get_glyph_h_advance_func_t func,
678 void *user_data,
679 hb_destroy_func_t destroy)
680 {
681 if (ffuncs->immutable) {
682 if (destroy)
683 destroy(user_data);
684 return;
685 }
686
687 if (ffuncs->destroy.glyph_h_advance)
688 ffuncs->destroy.glyph_h_advance(ffuncs->user_data.glyph_h_advance);
689
690 if (func) {
691 ffuncs->get.glyph_h_advance = func;
692 ffuncs->user_data.glyph_h_advance = user_data;
693 ffuncs->destroy.glyph_h_advance = destroy;
694 } else {
695 ffuncs->get.glyph_h_advance = hb_font_get_glyph_h_advance_nil;
696 ffuncs->user_data.glyph_h_advance = NULL;
697 ffuncs->destroy.glyph_h_advance = NULL;
698 }
699 }
700
701 void
702 hb_font_funcs_set_glyph_v_advance_func(hb_font_funcs_t *ffuncs,
703 hb_font_get_glyph_v_advance_func_t func,
704 void *user_data,
705 hb_destroy_func_t destroy)
706 {
707 if (ffuncs->immutable) {
708 if (destroy)
709 destroy(user_data);
710 return;
711 }
712
713 if (ffuncs->destroy.glyph_v_advance)
714 ffuncs->destroy.glyph_v_advance(ffuncs->user_data.glyph_v_advance);
715
716 if (func) {
717 ffuncs->get.glyph_v_advance = func;
718 ffuncs->user_data.glyph_v_advance = user_data;
719 ffuncs->destroy.glyph_v_advance = destroy;
720 } else {
721 ffuncs->get.glyph_v_advance = hb_font_get_glyph_v_advance_nil;
722 ffuncs->user_data.glyph_v_advance = NULL;
723 ffuncs->destroy.glyph_v_advance = NULL;
724 }
725 }
726
727 void
728 hb_font_funcs_set_glyph_h_origin_func(hb_font_funcs_t *ffuncs,
729 hb_font_get_glyph_h_origin_func_t func,
730 void *user_data,
731 hb_destroy_func_t destroy)
732 {
733 if (ffuncs->immutable) {
734 if (destroy)
735 destroy(user_data);
736 return;
737 }
738
739 if (ffuncs->destroy.glyph_h_origin)
740 ffuncs->destroy.glyph_h_origin(ffuncs->user_data.glyph_h_origin);
741
742 if (func) {
743 ffuncs->get.glyph_h_origin = func;
744 ffuncs->user_data.glyph_h_origin = user_data;
745 ffuncs->destroy.glyph_h_origin = destroy;
746 } else {
747 ffuncs->get.glyph_h_origin = hb_font_get_glyph_h_origin_nil;
748 ffuncs->user_data.glyph_h_origin = NULL;
749 ffuncs->destroy.glyph_h_origin = NULL;
750 }
751 }
752
753 void
754 hb_font_funcs_set_glyph_v_origin_func(hb_font_funcs_t *ffuncs,
755 hb_font_get_glyph_v_origin_func_t func,
756 void *user_data,
757 hb_destroy_func_t destroy)
758 {
759 if (ffuncs->immutable) {
760 if (destroy)
761 destroy(user_data);
762 return;
763 }
764
765 if (ffuncs->destroy.glyph_v_origin)
766 ffuncs->destroy.glyph_v_origin(ffuncs->user_data.glyph_v_origin);
767
768 if (func) {
769 ffuncs->get.glyph_v_origin = func;
770 ffuncs->user_data.glyph_v_origin = user_data;
771 ffuncs->destroy.glyph_v_origin = destroy;
772 } else {
773 ffuncs->get.glyph_v_origin = hb_font_get_glyph_v_origin_nil;
774 ffuncs->user_data.glyph_v_origin = NULL;
775 ffuncs->destroy.glyph_v_origin = NULL;
776 }
777 }
778
779 void
780 hb_font_funcs_set_glyph_h_kerning_func(hb_font_funcs_t *ffuncs,
781 hb_font_get_glyph_h_kerning_func_t func,
782 void *user_data,
783 hb_destroy_func_t destroy)
784 {
785 if (ffuncs->immutable) {
786 if (destroy)
787 destroy(user_data);
788 return;
789 }
790
791 if (ffuncs->destroy.glyph_h_kerning)
792 ffuncs->destroy.glyph_h_kerning(ffuncs->user_data.glyph_h_kerning);
793
794 if (func) {
795 ffuncs->get.glyph_h_kerning = func;
796 ffuncs->user_data.glyph_h_kerning = user_data;
797 ffuncs->destroy.glyph_h_kerning = destroy;
798 } else {
799 ffuncs->get.glyph_h_kerning = hb_font_get_glyph_h_kerning_nil;
800 ffuncs->user_data.glyph_h_kerning = NULL;
801 ffuncs->destroy.glyph_h_kerning = NULL;
802 }
803 }
804
805 void
806 hb_font_funcs_set_glyph_v_kerning_func(hb_font_funcs_t *ffuncs,
807 hb_font_get_glyph_v_kerning_func_t func,
808 void *user_data,
809 hb_destroy_func_t destroy)
810 {
811 if (ffuncs->immutable) {
812 if (destroy)
813 destroy(user_data);
814 return;
815 }
816
817 if (ffuncs->destroy.glyph_v_kerning)
818 ffuncs->destroy.glyph_v_kerning(ffuncs->user_data.glyph_v_kerning);
819
820 if (func) {
821 ffuncs->get.glyph_v_kerning = func;
822 ffuncs->user_data.glyph_v_kerning = user_data;
823 ffuncs->destroy.glyph_v_kerning = destroy;
824 } else {
825 ffuncs->get.glyph_v_kerning = hb_font_get_glyph_v_kerning_nil;
826 ffuncs->user_data.glyph_v_kerning = NULL;
827 ffuncs->destroy.glyph_v_kerning = NULL;
828 }
829 }
830
831 void
832 hb_font_funcs_set_glyph_extents_func(hb_font_funcs_t *ffuncs,
833 hb_font_get_glyph_extents_func_t func,
834 void *user_data,
835 hb_destroy_func_t destroy)
836 {
837 if (ffuncs->immutable) {
838 if (destroy)
839 destroy(user_data);
840 return;
841 }
842
843 if (ffuncs->destroy.glyph_extents)
844 ffuncs->destroy.glyph_extents(ffuncs->user_data.glyph_extents);
845
846 if (func) {
847 ffuncs->get.glyph_extents = func;
848 ffuncs->user_data.glyph_extents = user_data;
849 ffuncs->destroy.glyph_extents = destroy;
850 } else {
851 ffuncs->get.glyph_extents = hb_font_get_glyph_extents_nil;
852 ffuncs->user_data.glyph_extents = NULL;
853 ffuncs->destroy.glyph_extents = NULL;
854 }
855 }
856
857 void
858 hb_font_funcs_set_glyph_contour_point_func(
859 hb_font_funcs_t *ffuncs,
860 hb_font_get_glyph_contour_point_func_t func,
861 void *user_data,
862 hb_destroy_func_t destroy)
863 {
864 if (ffuncs->immutable) {
865 if (destroy)
866 destroy(user_data);
867 return;
868 }
869
870 if (ffuncs->destroy.glyph_contour_point)
871 ffuncs->destroy.glyph_contour_point(ffuncs->user_data.glyph_contour_point);
872
873 if (func) {
874 ffuncs->get.glyph_contour_point = func;
875 ffuncs->user_data.glyph_contour_point = user_data;
876 ffuncs->destroy.glyph_contour_point = destroy;
877 } else {
878 ffuncs->get.glyph_contour_point = hb_font_get_glyph_contour_point_nil;
879 ffuncs->user_data.glyph_contour_point = NULL;
880 ffuncs->destroy.glyph_contour_point = NULL;
881 }
882 }
883
884 void
885 hb_font_funcs_set_glyph_name_func(hb_font_funcs_t *ffuncs,
886 hb_font_get_glyph_name_func_t func,
887 void *user_data,
888 hb_destroy_func_t destroy)
889 {
890 if (ffuncs->immutable) {
891 if (destroy)
892 destroy(user_data);
893 return;
894 }
895
896 if (ffuncs->destroy.glyph_name)
897 ffuncs->destroy.glyph_name(ffuncs->user_data.glyph_name);
898
899 if (func) {
900 ffuncs->get.glyph_name = func;
901 ffuncs->user_data.glyph_name = user_data;
902 ffuncs->destroy.glyph_name = destroy;
903 } else {
904 ffuncs->get.glyph_name = hb_font_get_glyph_name_nil;
905 ffuncs->user_data.glyph_name = NULL;
906 ffuncs->destroy.glyph_name = NULL;
907 }
908 }
909
910 void
911 hb_font_funcs_set_glyph_from_name_func(hb_font_funcs_t *ffuncs,
912 hb_font_get_glyph_from_name_func_t func,
913 void *user_data,
914 hb_destroy_func_t destroy)
915 {
916 if (ffuncs->immutable) {
917 if (destroy)
918 destroy(user_data);
919 return;
920 }
921
922 if (ffuncs->destroy.glyph_from_name)
923 ffuncs->destroy.glyph_from_name(ffuncs->user_data.glyph_from_name);
924
925 if (func) {
926 ffuncs->get.glyph_from_name = func;
927 ffuncs->user_data.glyph_from_name = user_data;
928 ffuncs->destroy.glyph_from_name = destroy;
929 } else {
930 ffuncs->get.glyph_from_name = hb_font_get_glyph_from_name_nil;
931 ffuncs->user_data.glyph_from_name = NULL;
932 ffuncs->destroy.glyph_from_name = NULL;
933 }
934 }
935
936 hb_font_funcs_t *
937 hb_font_funcs_create(void)
938 {
939 hb_font_funcs_t *ffuncs = calloc(1, sizeof(*ffuncs));
940 if (!ffuncs)
941 return hb_font_funcs_get_empty();
942 hb_atomic_int32_set(&ffuncs->ref_cnt, 1);
943
944 ffuncs->get = hb_font_funcs_nil.get;
945 return ffuncs;
946 }
947
948 void
949 hb_font_set_funcs(hb_font_t *font,
950 hb_font_funcs_t *klass,
951 void *font_data,
952 hb_destroy_func_t destroy)
953 {
954 if (font->immutable) {
955 if (destroy)
956 destroy(font_data);
957 return;
958 }
959
960 if (font->destroy)
961 font->destroy(font->user_data);
962
963 if (!klass)
964 klass = hb_font_funcs_get_empty();
965
966 hb_font_funcs_reference(klass);
967 hb_font_funcs_destroy(font->klass);
968 font->klass = klass;
969 font->user_data = font_data;
970 font->destroy = destroy;
971 }
532 hb_font_funcs_t *hb_font_funcs_get_empty(void)
533 {
534 return &hb_font_funcs_nil;
535 }
536
537 hb_font_t *hb_font_get_empty(void)
538 {
539 return &hb_font_nil;
540 }
541
542 void hb_font_funcs_destroy(hb_font_funcs_t * ffuncs)
543 {
544 if (!ffuncs)
545 return;
546 if (hb_atomic_int32_get(&ffuncs->ref_cnt) == REF_CNT_INVALID_VAL)
547 return;
548 hb_atomic_int32_add(&ffuncs->ref_cnt, -1);
549 if (hb_atomic_int32_get(&ffuncs->ref_cnt) > 0)
550 return;
551 hb_atomic_int32_set(&ffuncs->ref_cnt, REF_CNT_INVALID_VAL);
552
553 if (ffuncs->destroy.glyph)
554 ffuncs->destroy.glyph(ffuncs->user_data.glyph);
555 if (ffuncs->destroy.glyph_h_advance)
556 ffuncs->destroy.glyph_h_advance(ffuncs->user_data.
557 glyph_h_advance);
558 if (ffuncs->destroy.glyph_v_advance)
559 ffuncs->destroy.glyph_v_advance(ffuncs->user_data.
560 glyph_v_advance);
561 if (ffuncs->destroy.glyph_h_origin)
562 ffuncs->destroy.glyph_h_origin(ffuncs->user_data.
563 glyph_h_origin);
564 if (ffuncs->destroy.glyph_v_origin)
565 ffuncs->destroy.glyph_v_origin(ffuncs->user_data.
566 glyph_v_origin);
567 if (ffuncs->destroy.glyph_h_kerning)
568 ffuncs->destroy.glyph_h_kerning(ffuncs->user_data.
569 glyph_h_kerning);
570 if (ffuncs->destroy.glyph_v_kerning)
571 ffuncs->destroy.glyph_v_kerning(ffuncs->user_data.
572 glyph_v_kerning);
573 if (ffuncs->destroy.glyph_extents)
574 ffuncs->destroy.glyph_extents(ffuncs->user_data.glyph_extents);
575 if (ffuncs->destroy.glyph_contour_point)
576 ffuncs->destroy.glyph_contour_point(ffuncs->user_data.
577 glyph_contour_point);
578 if (ffuncs->destroy.glyph_name)
579 ffuncs->destroy.glyph_name(ffuncs->user_data.glyph_name);
580 if (ffuncs->destroy.glyph_from_name)
581 ffuncs->destroy.glyph_from_name(ffuncs->user_data.
582 glyph_from_name);
583
584 free(ffuncs);
585 }
586
587 hb_font_t *hb_font_create(hb_face_t * face)
588 {
589 hb_font_t *font;
590
591 if (!face)
592 face = hb_face_get_empty();
593
594 if (face->ref_cnt == REF_CNT_INVALID_VAL)
595 return hb_font_get_empty();
596
597 font = calloc(1, sizeof(*font));
598 if (!font)
599 return hb_font_get_empty();
600
601 hb_atomic_int32_set(&font->ref_cnt, 1);
602 hb_face_make_immutable(face);
603 font->face = hb_face_reference(face);
604 font->klass = hb_font_funcs_get_empty();
605 return font;
606 }
607
608 void hb_font_funcs_set_glyph_func(hb_font_funcs_t * ffuncs,
609 hb_font_get_glyph_func_t func,
610 void *user_data, hb_destroy_func_t destroy)
611 {
612 if (ffuncs->immutable) {
613 if (destroy)
614 destroy(user_data);
615 return;
616 }
617
618 if (ffuncs->destroy.glyph)
619 ffuncs->destroy.glyph(ffuncs->user_data.glyph);
620
621 if (func) {
622 ffuncs->get.glyph = func;
623 ffuncs->user_data.glyph = user_data;
624 ffuncs->destroy.glyph = destroy;
625 } else {
626 ffuncs->get.glyph = hb_font_get_glyph_nil;
627 ffuncs->user_data.glyph = NULL;
628 ffuncs->destroy.glyph = NULL;
629 }
630 }
631
632 void hb_font_funcs_set_glyph_h_advance_func(hb_font_funcs_t * ffuncs,
633 hb_font_get_glyph_h_advance_func_t
634 func, void *user_data,
635 hb_destroy_func_t destroy)
636 {
637 if (ffuncs->immutable) {
638 if (destroy)
639 destroy(user_data);
640 return;
641 }
642
643 if (ffuncs->destroy.glyph_h_advance)
644 ffuncs->destroy.glyph_h_advance(ffuncs->user_data.
645 glyph_h_advance);
646
647 if (func) {
648 ffuncs->get.glyph_h_advance = func;
649 ffuncs->user_data.glyph_h_advance = user_data;
650 ffuncs->destroy.glyph_h_advance = destroy;
651 } else {
652 ffuncs->get.glyph_h_advance = hb_font_get_glyph_h_advance_nil;
653 ffuncs->user_data.glyph_h_advance = NULL;
654 ffuncs->destroy.glyph_h_advance = NULL;
655 }
656 }
657
658 void hb_font_funcs_set_glyph_v_advance_func(hb_font_funcs_t * ffuncs,
659 hb_font_get_glyph_v_advance_func_t
660 func, void *user_data,
661 hb_destroy_func_t destroy)
662 {
663 if (ffuncs->immutable) {
664 if (destroy)
665 destroy(user_data);
666 return;
667 }
668
669 if (ffuncs->destroy.glyph_v_advance)
670 ffuncs->destroy.glyph_v_advance(ffuncs->user_data.
671 glyph_v_advance);
672
673 if (func) {
674 ffuncs->get.glyph_v_advance = func;
675 ffuncs->user_data.glyph_v_advance = user_data;
676 ffuncs->destroy.glyph_v_advance = destroy;
677 } else {
678 ffuncs->get.glyph_v_advance = hb_font_get_glyph_v_advance_nil;
679 ffuncs->user_data.glyph_v_advance = NULL;
680 ffuncs->destroy.glyph_v_advance = NULL;
681 }
682 }
683
684 void hb_font_funcs_set_glyph_h_origin_func(hb_font_funcs_t * ffuncs,
685 hb_font_get_glyph_h_origin_func_t
686 func, void *user_data,
687 hb_destroy_func_t destroy)
688 {
689 if (ffuncs->immutable) {
690 if (destroy)
691 destroy(user_data);
692 return;
693 }
694
695 if (ffuncs->destroy.glyph_h_origin)
696 ffuncs->destroy.glyph_h_origin(ffuncs->user_data.
697 glyph_h_origin);
698
699 if (func) {
700 ffuncs->get.glyph_h_origin = func;
701 ffuncs->user_data.glyph_h_origin = user_data;
702 ffuncs->destroy.glyph_h_origin = destroy;
703 } else {
704 ffuncs->get.glyph_h_origin = hb_font_get_glyph_h_origin_nil;
705 ffuncs->user_data.glyph_h_origin = NULL;
706 ffuncs->destroy.glyph_h_origin = NULL;
707 }
708 }
709
710 void hb_font_funcs_set_glyph_v_origin_func(hb_font_funcs_t * ffuncs,
711 hb_font_get_glyph_v_origin_func_t
712 func, void *user_data,
713 hb_destroy_func_t destroy)
714 {
715 if (ffuncs->immutable) {
716 if (destroy)
717 destroy(user_data);
718 return;
719 }
720
721 if (ffuncs->destroy.glyph_v_origin)
722 ffuncs->destroy.glyph_v_origin(ffuncs->user_data.
723 glyph_v_origin);
724
725 if (func) {
726 ffuncs->get.glyph_v_origin = func;
727 ffuncs->user_data.glyph_v_origin = user_data;
728 ffuncs->destroy.glyph_v_origin = destroy;
729 } else {
730 ffuncs->get.glyph_v_origin = hb_font_get_glyph_v_origin_nil;
731 ffuncs->user_data.glyph_v_origin = NULL;
732 ffuncs->destroy.glyph_v_origin = NULL;
733 }
734 }
735
736 void hb_font_funcs_set_glyph_h_kerning_func(hb_font_funcs_t * ffuncs,
737 hb_font_get_glyph_h_kerning_func_t
738 func, void *user_data,
739 hb_destroy_func_t destroy)
740 {
741 if (ffuncs->immutable) {
742 if (destroy)
743 destroy(user_data);
744 return;
745 }
746
747 if (ffuncs->destroy.glyph_h_kerning)
748 ffuncs->destroy.glyph_h_kerning(ffuncs->user_data.
749 glyph_h_kerning);
750
751 if (func) {
752 ffuncs->get.glyph_h_kerning = func;
753 ffuncs->user_data.glyph_h_kerning = user_data;
754 ffuncs->destroy.glyph_h_kerning = destroy;
755 } else {
756 ffuncs->get.glyph_h_kerning = hb_font_get_glyph_h_kerning_nil;
757 ffuncs->user_data.glyph_h_kerning = NULL;
758 ffuncs->destroy.glyph_h_kerning = NULL;
759 }
760 }
761
762 void hb_font_funcs_set_glyph_v_kerning_func(hb_font_funcs_t * ffuncs,
763 hb_font_get_glyph_v_kerning_func_t
764 func, void *user_data,
765 hb_destroy_func_t destroy)
766 {
767 if (ffuncs->immutable) {
768 if (destroy)
769 destroy(user_data);
770 return;
771 }
772
773 if (ffuncs->destroy.glyph_v_kerning)
774 ffuncs->destroy.glyph_v_kerning(ffuncs->user_data.
775 glyph_v_kerning);
776
777 if (func) {
778 ffuncs->get.glyph_v_kerning = func;
779 ffuncs->user_data.glyph_v_kerning = user_data;
780 ffuncs->destroy.glyph_v_kerning = destroy;
781 } else {
782 ffuncs->get.glyph_v_kerning = hb_font_get_glyph_v_kerning_nil;
783 ffuncs->user_data.glyph_v_kerning = NULL;
784 ffuncs->destroy.glyph_v_kerning = NULL;
785 }
786 }
787
788 void hb_font_funcs_set_glyph_extents_func(hb_font_funcs_t * ffuncs,
789 hb_font_get_glyph_extents_func_t func,
790 void *user_data,
791 hb_destroy_func_t destroy)
792 {
793 if (ffuncs->immutable) {
794 if (destroy)
795 destroy(user_data);
796 return;
797 }
798
799 if (ffuncs->destroy.glyph_extents)
800 ffuncs->destroy.glyph_extents(ffuncs->user_data.glyph_extents);
801
802 if (func) {
803 ffuncs->get.glyph_extents = func;
804 ffuncs->user_data.glyph_extents = user_data;
805 ffuncs->destroy.glyph_extents = destroy;
806 } else {
807 ffuncs->get.glyph_extents = hb_font_get_glyph_extents_nil;
808 ffuncs->user_data.glyph_extents = NULL;
809 ffuncs->destroy.glyph_extents = NULL;
810 }
811 }
812
813 void hb_font_funcs_set_glyph_contour_point_func(hb_font_funcs_t * ffuncs,
814 hb_font_get_glyph_contour_point_func_t
815 func, void *user_data,
816 hb_destroy_func_t destroy)
817 {
818 if (ffuncs->immutable) {
819 if (destroy)
820 destroy(user_data);
821 return;
822 }
823
824 if (ffuncs->destroy.glyph_contour_point)
825 ffuncs->destroy.glyph_contour_point(ffuncs->user_data.
826 glyph_contour_point);
827
828 if (func) {
829 ffuncs->get.glyph_contour_point = func;
830 ffuncs->user_data.glyph_contour_point = user_data;
831 ffuncs->destroy.glyph_contour_point = destroy;
832 } else {
833 ffuncs->get.glyph_contour_point =
834 hb_font_get_glyph_contour_point_nil;
835 ffuncs->user_data.glyph_contour_point = NULL;
836 ffuncs->destroy.glyph_contour_point = NULL;
837 }
838 }
839
840 void hb_font_funcs_set_glyph_name_func(hb_font_funcs_t * ffuncs,
841 hb_font_get_glyph_name_func_t func,
842 void *user_data,
843 hb_destroy_func_t destroy)
844 {
845 if (ffuncs->immutable) {
846 if (destroy)
847 destroy(user_data);
848 return;
849 }
850
851 if (ffuncs->destroy.glyph_name)
852 ffuncs->destroy.glyph_name(ffuncs->user_data.glyph_name);
853
854 if (func) {
855 ffuncs->get.glyph_name = func;
856 ffuncs->user_data.glyph_name = user_data;
857 ffuncs->destroy.glyph_name = destroy;
858 } else {
859 ffuncs->get.glyph_name = hb_font_get_glyph_name_nil;
860 ffuncs->user_data.glyph_name = NULL;
861 ffuncs->destroy.glyph_name = NULL;
862 }
863 }
864
865 void hb_font_funcs_set_glyph_from_name_func(hb_font_funcs_t * ffuncs,
866 hb_font_get_glyph_from_name_func_t
867 func, void *user_data,
868 hb_destroy_func_t destroy)
869 {
870 if (ffuncs->immutable) {
871 if (destroy)
872 destroy(user_data);
873 return;
874 }
875
876 if (ffuncs->destroy.glyph_from_name)
877 ffuncs->destroy.glyph_from_name(ffuncs->user_data.
878 glyph_from_name);
972 879
973 hb_font_funcs_t *
974 hb_font_funcs_reference(hb_font_funcs_t *ffuncs)
975 {
976 if (hb_atomic_int32_get(&ffuncs->ref_cnt) != REF_CNT_INVALID_VAL)
977 hb_atomic_int32_add(&ffuncs->ref_cnt, 1);
978 return ffuncs;
880 if (func) {
881 ffuncs->get.glyph_from_name = func;
882 ffuncs->user_data.glyph_from_name = user_data;
883 ffuncs->destroy.glyph_from_name = destroy;
884 } else {
885 ffuncs->get.glyph_from_name = hb_font_get_glyph_from_name_nil;
886 ffuncs->user_data.glyph_from_name = NULL;
887 ffuncs->destroy.glyph_from_name = NULL;
888 }
889 }
890
891 hb_font_funcs_t *hb_font_funcs_create(void)
892 {
893 hb_font_funcs_t *ffuncs;
894
895 ffuncs = calloc(1, sizeof(*ffuncs));
896 if (!ffuncs)
897 return hb_font_funcs_get_empty();
898 hb_atomic_int32_set(&ffuncs->ref_cnt, 1);
899
900 ffuncs->get = hb_font_funcs_nil.get;
901 return ffuncs;
902 }
903
904 void hb_font_set_funcs(hb_font_t * font, hb_font_funcs_t * klass,
905 void *font_data, hb_destroy_func_t destroy)
906 {
907 if (font->immutable) {
908 if (destroy)
909 destroy(font_data);
910 return;
911 }
912
913 if (font->destroy)
914 font->destroy(font->user_data);
915
916 if (!klass)
917 klass = hb_font_funcs_get_empty();
918
919 hb_font_funcs_reference(klass);
920 hb_font_funcs_destroy(font->klass);
921 font->klass = klass;
922 font->user_data = font_data;
923 font->destroy = destroy;
924 }
925
926 hb_font_funcs_t *hb_font_funcs_reference(hb_font_funcs_t * ffuncs)
927 {
928 if (hb_atomic_int32_get(&ffuncs->ref_cnt) != REF_CNT_INVALID_VAL)
929 hb_atomic_int32_add(&ffuncs->ref_cnt, 1);
930 return ffuncs;
979 931 } }
980 932
981 void
982 hb_font_set_scale(hb_font_t *font,
983 int x_scale,
984 int y_scale)
933 void hb_font_set_scale(hb_font_t * font, int x_scale, int y_scale)
985 934 { {
986 if (font->immutable)
987 return;
935 if (font->immutable)
936 return;
988 937
989 font->x_scale = x_scale;
990 font->y_scale = y_scale;
938 font->x_scale = x_scale;
939 font->y_scale = y_scale;
991 940 } }
992 941
993 void
994 hb_font_set_ppem(hb_font_t *font,
995 unsigned int x_ppem,
996 unsigned int y_ppem)
942 void hb_font_set_ppem(hb_font_t * font, unsigned int x_ppem,
943 unsigned int y_ppem)
997 944 { {
998 if (font->immutable)
999 return;
945 if (font->immutable)
946 return;
1000 947
1001 font->x_ppem = x_ppem;
1002 font->y_ppem = y_ppem;
948 font->x_ppem = x_ppem;
949 font->y_ppem = y_ppem;
1003 950 } }
File hb-font.h changed (mode: 100644) (index 7273db4..c3165e1)
... ... typedef struct hb_font_t hb_font_t;
46 46
47 47 typedef struct hb_font_funcs_t hb_font_funcs_t; typedef struct hb_font_funcs_t hb_font_funcs_t;
48 48
49 hb_font_funcs_t *
49 HB_EXTERN hb_font_funcs_t *
50 50 hb_font_funcs_create (void); hb_font_funcs_create (void);
51 51
52 hb_font_funcs_t *
52 HB_EXTERN hb_font_funcs_t *
53 53 hb_font_funcs_get_empty (void); hb_font_funcs_get_empty (void);
54 54
55 hb_font_funcs_t *
55 HB_EXTERN hb_font_funcs_t *
56 56 hb_font_funcs_reference (hb_font_funcs_t *ffuncs); hb_font_funcs_reference (hb_font_funcs_t *ffuncs);
57 57
58 void
58 HB_EXTERN void
59 59 hb_font_funcs_destroy (hb_font_funcs_t *ffuncs); hb_font_funcs_destroy (hb_font_funcs_t *ffuncs);
60 60
61 hb_bool_t
61 HB_EXTERN hb_bool_t
62 62 hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
63 63 hb_user_data_key_t *key, hb_user_data_key_t *key,
64 64 void * data, void * data,
 
... ... hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
66 66 hb_bool_t replace); hb_bool_t replace);
67 67
68 68
69 void *
69 HB_EXTERN void *
70 70 hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
71 71 hb_user_data_key_t *key); hb_user_data_key_t *key);
72 72
73 73
74 void
74 HB_EXTERN void
75 75 hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs); hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs);
76 76
77 hb_bool_t
77 HB_EXTERN hb_bool_t
78 78 hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs);
79 79
80 80
81 81 /* glyph extents */ /* glyph extents */
82 82
83 /* Note that height is negative in coordinate systems that grow up. */
83 84 typedef struct hb_glyph_extents_t typedef struct hb_glyph_extents_t
84 85 { {
85 hb_position_t x_bearing;
86 hb_position_t y_bearing;
87 hb_position_t width;
88 hb_position_t height;
86 hb_position_t x_bearing; /* left side of glyph from origin. */
87 hb_position_t y_bearing; /* top side of glyph from origin. */
88 hb_position_t width; /* distance from left to right side. */
89 hb_position_t height; /* distance from top to bottom side. */
89 90 } hb_glyph_extents_t; } hb_glyph_extents_t;
90 91
91 92
 
... ... typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
148 149 * *
149 150 * *
150 151 * *
151 * Since: 1.0
152 * Since: 0.9.2
152 153 **/ **/
153 void
154 HB_EXTERN void
154 155 hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
155 156 hb_font_get_glyph_func_t func, hb_font_get_glyph_func_t func,
156 157 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
164 165 * *
165 166 * *
166 167 * *
167 * Since: 1.0
168 * Since: 0.9.2
168 169 **/ **/
169 void
170 HB_EXTERN void
170 171 hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
171 172 hb_font_get_glyph_h_advance_func_t func, hb_font_get_glyph_h_advance_func_t func,
172 173 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
180 181 * *
181 182 * *
182 183 * *
183 * Since: 1.0
184 * Since: 0.9.2
184 185 **/ **/
185 void
186 HB_EXTERN void
186 187 hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
187 188 hb_font_get_glyph_v_advance_func_t func, hb_font_get_glyph_v_advance_func_t func,
188 189 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
196 197 * *
197 198 * *
198 199 * *
199 * Since: 1.0
200 * Since: 0.9.2
200 201 **/ **/
201 void
202 HB_EXTERN void
202 203 hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
203 204 hb_font_get_glyph_h_origin_func_t func, hb_font_get_glyph_h_origin_func_t func,
204 205 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
212 213 * *
213 214 * *
214 215 * *
215 * Since: 1.0
216 * Since: 0.9.2
216 217 **/ **/
217 void
218 HB_EXTERN void
218 219 hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
219 220 hb_font_get_glyph_v_origin_func_t func, hb_font_get_glyph_v_origin_func_t func,
220 221 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
228 229 * *
229 230 * *
230 231 * *
231 * Since: 1.0
232 * Since: 0.9.2
232 233 **/ **/
233 void
234 HB_EXTERN void
234 235 hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
235 236 hb_font_get_glyph_h_kerning_func_t func, hb_font_get_glyph_h_kerning_func_t func,
236 237 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
244 245 * *
245 246 * *
246 247 * *
247 * Since: 1.0
248 * Since: 0.9.2
248 249 **/ **/
249 void
250 HB_EXTERN void
250 251 hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
251 252 hb_font_get_glyph_v_kerning_func_t func, hb_font_get_glyph_v_kerning_func_t func,
252 253 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
260 261 * *
261 262 * *
262 263 * *
263 * Since: 1.0
264 * Since: 0.9.2
264 265 **/ **/
265 void
266 HB_EXTERN void
266 267 hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
267 268 hb_font_get_glyph_extents_func_t func, hb_font_get_glyph_extents_func_t func,
268 269 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
276 277 * *
277 278 * *
278 279 * *
279 * Since: 1.0
280 * Since: 0.9.2
280 281 **/ **/
281 void
282 HB_EXTERN void
282 283 hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
283 284 hb_font_get_glyph_contour_point_func_t func, hb_font_get_glyph_contour_point_func_t func,
284 285 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
292 293 * *
293 294 * *
294 295 * *
295 * Since: 1.0
296 * Since: 0.9.2
296 297 **/ **/
297 void
298 HB_EXTERN void
298 299 hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
299 300 hb_font_get_glyph_name_func_t func, hb_font_get_glyph_name_func_t func,
300 301 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
308 309 * *
309 310 * *
310 311 * *
311 * Since: 1.0
312 * Since: 0.9.2
312 313 **/ **/
313 void
314 HB_EXTERN void
314 315 hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
315 316 hb_font_get_glyph_from_name_func_t func, hb_font_get_glyph_from_name_func_t func,
316 317 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
318 319
319 320 /* func dispatch */ /* func dispatch */
320 321
321 hb_bool_t
322 HB_EXTERN hb_bool_t
322 323 hb_font_get_glyph (hb_font_t *font, hb_font_get_glyph (hb_font_t *font,
323 324 hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t unicode, hb_codepoint_t variation_selector,
324 325 hb_codepoint_t *glyph); hb_codepoint_t *glyph);
325 326
326 hb_position_t
327 HB_EXTERN hb_position_t
327 328 hb_font_get_glyph_h_advance (hb_font_t *font, hb_font_get_glyph_h_advance (hb_font_t *font,
328 329 hb_codepoint_t glyph); hb_codepoint_t glyph);
329 hb_position_t
330 HB_EXTERN hb_position_t
330 331 hb_font_get_glyph_v_advance (hb_font_t *font, hb_font_get_glyph_v_advance (hb_font_t *font,
331 332 hb_codepoint_t glyph); hb_codepoint_t glyph);
332 333
333 hb_bool_t
334 HB_EXTERN hb_bool_t
334 335 hb_font_get_glyph_h_origin (hb_font_t *font, hb_font_get_glyph_h_origin (hb_font_t *font,
335 336 hb_codepoint_t glyph, hb_codepoint_t glyph,
336 337 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
337 hb_bool_t
338 HB_EXTERN hb_bool_t
338 339 hb_font_get_glyph_v_origin (hb_font_t *font, hb_font_get_glyph_v_origin (hb_font_t *font,
339 340 hb_codepoint_t glyph, hb_codepoint_t glyph,
340 341 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
341 342
342 hb_position_t
343 HB_EXTERN hb_position_t
343 344 hb_font_get_glyph_h_kerning (hb_font_t *font, hb_font_get_glyph_h_kerning (hb_font_t *font,
344 345 hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
345 hb_position_t
346 HB_EXTERN hb_position_t
346 347 hb_font_get_glyph_v_kerning (hb_font_t *font, hb_font_get_glyph_v_kerning (hb_font_t *font,
347 348 hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph); hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
348 349
349 hb_bool_t
350 HB_EXTERN hb_bool_t
350 351 hb_font_get_glyph_extents (hb_font_t *font, hb_font_get_glyph_extents (hb_font_t *font,
351 352 hb_codepoint_t glyph, hb_codepoint_t glyph,
352 353 hb_glyph_extents_t *extents); hb_glyph_extents_t *extents);
353 354
354 hb_bool_t
355 HB_EXTERN hb_bool_t
355 356 hb_font_get_glyph_contour_point (hb_font_t *font, hb_font_get_glyph_contour_point (hb_font_t *font,
356 357 hb_codepoint_t glyph, unsigned int point_index, hb_codepoint_t glyph, unsigned int point_index,
357 358 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
358 359
359 hb_bool_t
360 HB_EXTERN hb_bool_t
360 361 hb_font_get_glyph_name (hb_font_t *font, hb_font_get_glyph_name (hb_font_t *font,
361 362 hb_codepoint_t glyph, hb_codepoint_t glyph,
362 363 char *name, unsigned int size); char *name, unsigned int size);
363 hb_bool_t
364 HB_EXTERN hb_bool_t
364 365 hb_font_get_glyph_from_name (hb_font_t *font, hb_font_get_glyph_from_name (hb_font_t *font,
365 366 const char *name, int len, /* -1 means nul-terminated */ const char *name, int len, /* -1 means nul-terminated */
366 367 hb_codepoint_t *glyph); hb_codepoint_t *glyph);
 
... ... hb_font_get_glyph_from_name (hb_font_t *font,
368 369
369 370 /* high-level funcs, with fallback */ /* high-level funcs, with fallback */
370 371
371 void
372 HB_EXTERN void
372 373 hb_font_get_glyph_advance_for_direction (hb_font_t *font, hb_font_get_glyph_advance_for_direction (hb_font_t *font,
373 374 hb_codepoint_t glyph, hb_codepoint_t glyph,
374 375 hb_direction_t direction, hb_direction_t direction,
375 376 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
376 void
377 HB_EXTERN void
377 378 hb_font_get_glyph_origin_for_direction (hb_font_t *font, hb_font_get_glyph_origin_for_direction (hb_font_t *font,
378 379 hb_codepoint_t glyph, hb_codepoint_t glyph,
379 380 hb_direction_t direction, hb_direction_t direction,
380 381 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
381 void
382 HB_EXTERN void
382 383 hb_font_add_glyph_origin_for_direction (hb_font_t *font, hb_font_add_glyph_origin_for_direction (hb_font_t *font,
383 384 hb_codepoint_t glyph, hb_codepoint_t glyph,
384 385 hb_direction_t direction, hb_direction_t direction,
385 386 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
386 void
387 HB_EXTERN void
387 388 hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
388 389 hb_codepoint_t glyph, hb_codepoint_t glyph,
389 390 hb_direction_t direction, hb_direction_t direction,
390 391 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
391 392
392 void
393 HB_EXTERN void
393 394 hb_font_get_glyph_kerning_for_direction (hb_font_t *font, hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
394 395 hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
395 396 hb_direction_t direction, hb_direction_t direction,
396 397 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
397 398
398 hb_bool_t
399 HB_EXTERN hb_bool_t
399 400 hb_font_get_glyph_extents_for_origin (hb_font_t *font, hb_font_get_glyph_extents_for_origin (hb_font_t *font,
400 401 hb_codepoint_t glyph, hb_codepoint_t glyph,
401 402 hb_direction_t direction, hb_direction_t direction,
402 403 hb_glyph_extents_t *extents); hb_glyph_extents_t *extents);
403 404
404 hb_bool_t
405 HB_EXTERN hb_bool_t
405 406 hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
406 407 hb_codepoint_t glyph, unsigned int point_index, hb_codepoint_t glyph, unsigned int point_index,
407 408 hb_direction_t direction, hb_direction_t direction,
408 409 hb_position_t *x, hb_position_t *y); hb_position_t *x, hb_position_t *y);
409 410
410 411 /* Generates gidDDD if glyph has no name. */ /* Generates gidDDD if glyph has no name. */
411 void
412 HB_EXTERN void
412 413 hb_font_glyph_to_string (hb_font_t *font, hb_font_glyph_to_string (hb_font_t *font,
413 414 hb_codepoint_t glyph, hb_codepoint_t glyph,
414 415 char *s, unsigned int size); char *s, unsigned int size);
415 416 /* Parses gidDDD and uniUUUU strings automatically. */ /* Parses gidDDD and uniUUUU strings automatically. */
416 hb_bool_t
417 HB_EXTERN hb_bool_t
417 418 hb_font_glyph_from_string (hb_font_t *font, hb_font_glyph_from_string (hb_font_t *font,
418 419 const char *s, int len, /* -1 means nul-terminated */ const char *s, int len, /* -1 means nul-terminated */
419 420 hb_codepoint_t *glyph); hb_codepoint_t *glyph);
 
... ... hb_font_glyph_from_string (hb_font_t *font,
425 426
426 427 /* Fonts are very light-weight objects */ /* Fonts are very light-weight objects */
427 428
428 hb_font_t *
429 HB_EXTERN hb_font_t *
429 430 hb_font_create (hb_face_t *face); hb_font_create (hb_face_t *face);
430 431
431 hb_font_t *
432 HB_EXTERN hb_font_t *
432 433 hb_font_create_sub_font (hb_font_t *parent); hb_font_create_sub_font (hb_font_t *parent);
433 434
434 hb_font_t *
435 HB_EXTERN hb_font_t *
435 436 hb_font_get_empty (void); hb_font_get_empty (void);
436 437
437 hb_font_t *
438 HB_EXTERN hb_font_t *
438 439 hb_font_reference (hb_font_t *font); hb_font_reference (hb_font_t *font);
439 440
440 void
441 HB_EXTERN void
441 442 hb_font_destroy (hb_font_t *font); hb_font_destroy (hb_font_t *font);
442 443
443 hb_bool_t
444 HB_EXTERN hb_bool_t
444 445 hb_font_set_user_data (hb_font_t *font, hb_font_set_user_data (hb_font_t *font,
445 446 hb_user_data_key_t *key, hb_user_data_key_t *key,
446 447 void * data, void * data,
 
... ... hb_font_set_user_data (hb_font_t *font,
448 449 hb_bool_t replace); hb_bool_t replace);
449 450
450 451
451 void *
452 HB_EXTERN void *
452 453 hb_font_get_user_data (hb_font_t *font, hb_font_get_user_data (hb_font_t *font,
453 454 hb_user_data_key_t *key); hb_user_data_key_t *key);
454 455
455 void
456 HB_EXTERN void
456 457 hb_font_make_immutable (hb_font_t *font); hb_font_make_immutable (hb_font_t *font);
457 458
458 hb_bool_t
459 HB_EXTERN hb_bool_t
459 460 hb_font_is_immutable (hb_font_t *font); hb_font_is_immutable (hb_font_t *font);
460 461
461 hb_font_t *
462 HB_EXTERN void
463 hb_font_set_parent (hb_font_t *font,
464 hb_font_t *parent);
465
466 HB_EXTERN hb_font_t *
462 467 hb_font_get_parent (hb_font_t *font); hb_font_get_parent (hb_font_t *font);
463 468
464 hb_face_t *
469 HB_EXTERN hb_face_t *
465 470 hb_font_get_face (hb_font_t *font); hb_font_get_face (hb_font_t *font);
466 471
467 472
468 void
473 HB_EXTERN void
469 474 hb_font_set_funcs (hb_font_t *font, hb_font_set_funcs (hb_font_t *font,
470 475 hb_font_funcs_t *klass, hb_font_funcs_t *klass,
471 476 void *font_data, void *font_data,
472 477 hb_destroy_func_t destroy); hb_destroy_func_t destroy);
473 478
474 479 /* Be *very* careful with this function! */ /* Be *very* careful with this function! */
475 void
480 HB_EXTERN void
476 481 hb_font_set_funcs_data (hb_font_t *font, hb_font_set_funcs_data (hb_font_t *font,
477 482 void *font_data, void *font_data,
478 483 hb_destroy_func_t destroy); hb_destroy_func_t destroy);
479 484
480 485
481 void
486 HB_EXTERN void
482 487 hb_font_set_scale (hb_font_t *font, hb_font_set_scale (hb_font_t *font,
483 488 int x_scale, int x_scale,
484 489 int y_scale); int y_scale);
485 490
486 void
491 HB_EXTERN void
487 492 hb_font_get_scale (hb_font_t *font, hb_font_get_scale (hb_font_t *font,
488 493 int *x_scale, int *x_scale,
489 494 int *y_scale); int *y_scale);
 
... ... hb_font_get_scale (hb_font_t *font,
491 496 /* /*
492 497 * A zero value means "no hinting in that direction" * A zero value means "no hinting in that direction"
493 498 */ */
494 void
499 HB_EXTERN void
495 500 hb_font_set_ppem (hb_font_t *font, hb_font_set_ppem (hb_font_t *font,
496 501 unsigned int x_ppem, unsigned int x_ppem,
497 502 unsigned int y_ppem); unsigned int y_ppem);
498 503
499 void
504 HB_EXTERN void
500 505 hb_font_get_ppem (hb_font_t *font, hb_font_get_ppem (hb_font_t *font,
501 506 unsigned int *x_ppem, unsigned int *x_ppem,
502 507 unsigned int *y_ppem); unsigned int *y_ppem);
File hb-ft.c changed (mode: 100644) (index bb44c03..551d6e4)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <stdlib.h> #include <stdlib.h>
5 7
6 8 #include <ft2build.h> #include <ft2build.h>
 
14 16 #include "hb-shaper-private.h" #include "hb-shaper-private.h"
15 17 #include "hb-face-private.h" #include "hb-face-private.h"
16 18
17 static hb_blob_t *
18 reference_table(hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
19 static hb_blob_t *reference_table(hb_face_t * face HB_UNUSED, hb_tag_t tag,
20 void *user_data)
19 21 { {
20 FT_Face ft_face = (FT_Face)user_data;
21 FT_Byte *buffer;
22 FT_ULong length = 0;
23 FT_Error error;
24
25 //Note: FreeType like HarfBuzz uses the NONE tag for fetching the entire blob
26
27 error = FT_Load_Sfnt_Table(ft_face, tag, 0, NULL, &length);
28 if (error)
29 return NULL;
30
31 buffer = (FT_Byte*)malloc(length);
32 if (buffer == NULL)
33 return NULL;
34
35 error = FT_Load_Sfnt_Table(ft_face, tag, 0, buffer, &length);
36 if (error)
37 return NULL;
38
39 return hb_blob_create((const char*)buffer,
40 length,
41 HB_MEMORY_MODE_WRITABLE,
42 buffer,
43 free);
22 FT_Face ft_face;
23 FT_Byte *buffer;
24 FT_ULong length;
25 FT_Error error;
26
27 ft_face = (FT_Face) user_data;
28 length = 0;
29
30 /*Note: FreeType like HarfBuzz uses the NONE tag for fetching the
31 entire blob */
32
33 error = FT_Load_Sfnt_Table(ft_face, tag, 0, NULL, &length);
34 if (error)
35 return NULL;
36
37 buffer = (FT_Byte *) malloc(length);
38 if (buffer == NULL)
39 return NULL;
40
41 error = FT_Load_Sfnt_Table(ft_face, tag, 0, buffer, &length);
42 if (error)
43 return NULL;
44
45 return hb_blob_create((const char *)buffer, length,
46 HB_MEMORY_MODE_WRITABLE, buffer, free);
44 47 } }
45 48
46 hb_face_t *
47 hb_ft_face_create(FT_Face ft_face, hb_destroy_func_t destroy)
49 hb_face_t *hb_ft_face_create(FT_Face ft_face, hb_destroy_func_t destroy)
48 50 { {
49 hb_face_t *face;
50
51 if (ft_face->stream->read == NULL) {
52 hb_blob_t *blob;
53
54 blob = hb_blob_create((const char*)ft_face->stream->base,
55 (unsigned)ft_face->stream->size,
56 //TODO: We assume that it's mmap()'ed, but FreeType
57 //code suggests that there are cases we reach here
58 //but font is not mmapped. For example, when mmap()
59 //fails. No idea how to deal with it better here.
60 HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
61 ft_face, destroy);
62 face = hb_face_create(blob, ft_face->face_index);
63 hb_blob_destroy(blob);
64 } else {
65 face = hb_face_create_for_tables(reference_table, ft_face, destroy);
66 }
67
68 hb_face_set_index(face, ft_face->face_index);
69 hb_face_set_upem(face, ft_face->units_per_EM);
70 return face;
51 hb_face_t *face;
52
53 if (ft_face->stream->read == NULL) {
54 hb_blob_t *blob;
55
56 /*TODO: We assume that it's mmap()'ed, but FreeType
57 code suggests that there are cases we reach here
58 but font is not mmapped. For example, when mmap()
59 fails. No idea how to deal with it better here.*/
60 blob =
61 hb_blob_create((const char *)ft_face->stream->base,
62 (unsigned)ft_face->stream->size,
63 HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
64 ft_face, destroy);
65 face = hb_face_create(blob, ft_face->face_index);
66 hb_blob_destroy(blob);
67 } else {
68 face =
69 hb_face_create_for_tables(reference_table, ft_face,
70 destroy);
71 }
72
73 hb_face_set_index(face, ft_face->face_index);
74 hb_face_set_upem(face, ft_face->units_per_EM);
75 return face;
71 76 } }
72 77
73 static void
74 hb_ft_face_finalize(FT_Face ft_face)
78 static void hb_ft_face_finalize(FT_Face ft_face)
75 79 { {
76 hb_face_destroy((hb_face_t*)ft_face->generic.data);
80 hb_face_destroy((hb_face_t *) ft_face->generic.data);
77 81 } }
78 82
79 hb_face_t *
80 hb_ft_face_create_cached(FT_Face ft_face)
83 hb_face_t *hb_ft_face_create_cached(FT_Face ft_face)
81 84 { {
82 if (!ft_face->generic.data || ft_face->generic.finalizer != (FT_Generic_Finalizer)hb_ft_face_finalize) {
83 if (ft_face->generic.finalizer)
84 ft_face->generic.finalizer(ft_face);
85
86 ft_face->generic.data = hb_ft_face_create(ft_face, NULL);
87 ft_face->generic.finalizer = (FT_Generic_Finalizer)hb_ft_face_finalize;
88 }
89 return hb_face_reference((hb_face_t*)ft_face->generic.data);
85 if (!ft_face->generic.data
86 || ft_face->generic.finalizer !=
87 (FT_Generic_Finalizer) hb_ft_face_finalize) {
88 if (ft_face->generic.finalizer)
89 ft_face->generic.finalizer(ft_face);
90
91 ft_face->generic.data = hb_ft_face_create(ft_face, NULL);
92 ft_face->generic.finalizer =
93 (FT_Generic_Finalizer) hb_ft_face_finalize;
94 }
95 return hb_face_reference((hb_face_t *) ft_face->generic.data);
90 96 } }
File hb-ft.h changed (mode: 100644) (index 696251e..dc8ef85)
1 1 /* /*
2 2 * Copyright © 2009 Red Hat, Inc. * Copyright © 2009 Red Hat, Inc.
3 * Copyright © 2015 Google, Inc.
3 4 * *
4 5 * This is part of HarfBuzz, a text shaping library. * This is part of HarfBuzz, a text shaping library.
5 6 * *
 
22 23 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 24 * *
24 25 * Red Hat Author(s): Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
26 * Google Author(s): Behdad Esfahbod
25 27 */ */
26 28
27 29 #ifndef HB_FT_H #ifndef HB_FT_H
 
34 36
35 37 HB_BEGIN_DECLS HB_BEGIN_DECLS
36 38
37 /* Note: FreeType is not thread-safe. Hence, these functions are not either. */
39 /*
40 * Note: FreeType is not thread-safe.
41 * Hence, these functions are not either.
42 */
38 43
39 hb_face_t *
44 /*
45 * hb-face from ft-face.
46 */
47
48 /* This one creates a new hb-face for given ft-face.
49 * When the returned hb-face is destroyed, the destroy
50 * callback is called (if not NULL), with the ft-face passed
51 * to it.
52 *
53 * The client is responsible to make sure that ft-face is
54 * destroyed after hb-face is destroyed.
55 *
56 * Most often you don't want this function. You should use either
57 * hb_ft_face_create_cached(), or hb_ft_face_create_referenced().
58 * In particular, if you are going to pass NULL as destroy, you
59 * probably should use (the more recent) hb_ft_face_create_referenced()
60 * instead.
61 */
62 HB_EXTERN hb_face_t *
40 63 hb_ft_face_create (FT_Face ft_face, hb_ft_face_create (FT_Face ft_face,
41 64 hb_destroy_func_t destroy); hb_destroy_func_t destroy);
42 65
43 hb_face_t *
66 /* This version is like hb_ft_face_create(), except that it caches
67 * the hb-face using the generic pointer of the ft-face. This means
68 * that subsequent calls to this function with the same ft-face will
69 * return the same hb-face (correctly referenced).
70 *
71 * Client is still responsible for making sure that ft-face is destroyed
72 * after hb-face is.
73 */
74 HB_EXTERN hb_face_t *
44 75 hb_ft_face_create_cached (FT_Face ft_face); hb_ft_face_create_cached (FT_Face ft_face);
45 76
46 hb_font_t *
77 /* This version is like hb_ft_face_create(), except that it calls
78 * FT_Reference_Face() on ft-face, as such keeping ft-face alive
79 * as long as the hb-face is.
80 *
81 * This is the most convenient version to use. Use it unless you have
82 * very good reasons not to.
83 */
84 HB_EXTERN hb_face_t *
85 hb_ft_face_create_referenced (FT_Face ft_face);
86
87
88 /*
89 * hb-font from ft-face.
90 */
91
92 /*
93 * Note:
94 *
95 * Set face size on ft-face before creating hb-font from it.
96 * Otherwise hb-ft would NOT pick up the font size correctly.
97 */
98
99 /* See notes on hb_ft_face_create(). Same issues re lifecycle-management
100 * apply here. Use hb_ft_font_create_referenced() if you can. */
101 HB_EXTERN hb_font_t *
47 102 hb_ft_font_create (FT_Face ft_face, hb_ft_font_create (FT_Face ft_face,
48 103 hb_destroy_func_t destroy); hb_destroy_func_t destroy);
49 104
105 /* See notes on hb_ft_face_create_referenced() re lifecycle-management
106 * issues. */
107 HB_EXTERN hb_font_t *
108 hb_ft_font_create_referenced (FT_Face ft_face);
109
110 HB_EXTERN FT_Face
111 hb_ft_font_get_face (hb_font_t *font);
112
113 HB_EXTERN void
114 hb_ft_font_set_load_flags (hb_font_t *font, int load_flags);
50 115
116 HB_EXTERN int
117 hb_ft_font_get_load_flags (hb_font_t *font);
51 118
52 119 /* Makes an hb_font_t use FreeType internally to implement font functions. */ /* Makes an hb_font_t use FreeType internally to implement font functions. */
53 void
120 HB_EXTERN void
54 121 hb_ft_font_set_funcs (hb_font_t *font); hb_ft_font_set_funcs (hb_font_t *font);
55 122
56 FT_Face
57 hb_ft_font_get_face (hb_font_t *font);
58
59 123
60 124 HB_END_DECLS HB_END_DECLS
61 125
File hb-glib.c changed (mode: 100644) (index 91eaa70..96582d1)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include "hb.h" #include "hb.h"
5 7 #include "hb-private.h" #include "hb-private.h"
6 8 #include "hb-atomic-private.h" #include "hb-atomic-private.h"
7 9 #include "hb-glib.h" #include "hb-glib.h"
8 10 #include "hb-unicode-private.h" #include "hb-unicode-private.h"
9 11
10 GUnicodeScript
11 hb_glib_script_from_script(hb_script_t script)
12 GUnicodeScript hb_glib_script_from_script(hb_script_t script)
12 13 { {
13 return g_unicode_script_from_iso15924(script);
14 return g_unicode_script_from_iso15924(script);
14 15 } }
15 16
16 hb_script_t
17 hb_glib_script_to_script(GUnicodeScript script)
17 hb_script_t hb_glib_script_to_script(GUnicodeScript script)
18 18 { {
19 return (hb_script_t)g_unicode_script_to_iso15924(script);
19 return (hb_script_t) g_unicode_script_to_iso15924(script);
20 20 } }
21 21
22 22 static hb_unicode_combining_class_t static hb_unicode_combining_class_t
23 hb_glib_unicode_combining_class(hb_unicode_funcs_t *ufuncs HB_UNUSED,
24 hb_codepoint_t unicode,
25 void *user_data HB_UNUSED)
26
23 hb_glib_unicode_combining_class(hb_unicode_funcs_t * ufuncs HB_UNUSED,
24 hb_codepoint_t unicode,
25 void *user_data HB_UNUSED)
27 26 { {
28 return (hb_unicode_combining_class_t)g_unichar_combining_class(unicode);
27 return (hb_unicode_combining_class_t)
28 g_unichar_combining_class(unicode);
29 29 } }
30 30
31 static unsigned int
32 hb_glib_unicode_eastasian_width(hb_unicode_funcs_t *ufuncs HB_UNUSED,
33 hb_codepoint_t unicode,
34 void *user_data HB_UNUSED)
31 static unsigned int hb_glib_unicode_eastasian_width(hb_unicode_funcs_t *
32 ufuncs HB_UNUSED,
33 hb_codepoint_t unicode,
34 void *user_data HB_UNUSED)
35 35 { {
36 return g_unichar_iswide(unicode) ? 2 : 1;
36 return g_unichar_iswide(unicode) ? 2 : 1;
37 37 } }
38 38
39 39 static hb_unicode_general_category_t static hb_unicode_general_category_t
40 hb_glib_unicode_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED,
41 hb_codepoint_t unicode,
42 void *user_data HB_UNUSED)
43
40 hb_glib_unicode_general_category(hb_unicode_funcs_t * ufuncs HB_UNUSED,
41 hb_codepoint_t unicode,
42 void *user_data HB_UNUSED)
44 43 { {
45 //hb_unicode_general_category_t and GUnicodeType are identical
46 return (hb_unicode_general_category_t)g_unichar_type(unicode);
44 /*hb_unicode_general_category_t and GUnicodeType are identical */
45 return (hb_unicode_general_category_t) g_unichar_type(unicode);
47 46 } }
48 47
49 static hb_codepoint_t
50 hb_glib_unicode_mirroring(hb_unicode_funcs_t *ufuncs HB_UNUSED,
51 hb_codepoint_t unicode,
52 void *user_data HB_UNUSED)
48 static hb_codepoint_t hb_glib_unicode_mirroring(hb_unicode_funcs_t *
49 ufuncs HB_UNUSED,
50 hb_codepoint_t unicode,
51 void *user_data HB_UNUSED)
53 52 { {
54 g_unichar_get_mirror_char(unicode, &unicode);
55 return unicode;
53 g_unichar_get_mirror_char(unicode, &unicode);
54 return unicode;
56 55 } }
57 56
58 static hb_script_t
59 hb_glib_unicode_script(hb_unicode_funcs_t *ufuncs HB_UNUSED,
60 hb_codepoint_t unicode,
61 void *user_data HB_UNUSED)
57 static hb_script_t hb_glib_unicode_script(hb_unicode_funcs_t * ufuncs HB_UNUSED,
58 hb_codepoint_t unicode,
59 void *user_data HB_UNUSED)
62 60 { {
63 return hb_glib_script_to_script(g_unichar_get_script(unicode));
61 return hb_glib_script_to_script(g_unichar_get_script(unicode));
64 62 } }
65 63
66 static hb_bool_t
67 hb_glib_unicode_compose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
68 hb_codepoint_t a,
69 hb_codepoint_t b,
70 hb_codepoint_t *ab,
71 void *user_data HB_UNUSED)
64 static hb_bool_t hb_glib_unicode_compose(hb_unicode_funcs_t * ufuncs HB_UNUSED,
65 hb_codepoint_t a, hb_codepoint_t b,
66 hb_codepoint_t * ab,
67 void *user_data HB_UNUSED)
72 68 { {
73 return g_unichar_compose(a, b, ab);
69 return g_unichar_compose(a, b, ab);
74 70 } }
75 71
76 static hb_bool_t
77 hb_glib_unicode_decompose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
78 hb_codepoint_t ab,
79 hb_codepoint_t *a,
80 hb_codepoint_t *b,
81 void *user_data HB_UNUSED)
72 static hb_bool_t hb_glib_unicode_decompose(hb_unicode_funcs_t *
73 ufuncs HB_UNUSED, hb_codepoint_t ab,
74 hb_codepoint_t * a,
75 hb_codepoint_t * b,
76 void *user_data HB_UNUSED)
82 77 { {
83 return g_unichar_decompose(ab, a, b);
78 return g_unichar_decompose(ab, a, b);
84 79 } }
85 80
86 static unsigned int
87 hb_glib_unicode_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
88 hb_codepoint_t u,
89 hb_codepoint_t *decomposed,
90 void *user_data HB_UNUSED)
81 static unsigned int hb_glib_unicode_decompose_compatibility(hb_unicode_funcs_t *
82 ufuncs HB_UNUSED,
83 hb_codepoint_t u,
84 hb_codepoint_t *
85 decomposed,
86 void *user_data
87 HB_UNUSED)
91 88 { {
92 return g_unichar_fully_decompose(u,
93 TRUE,
94 decomposed,
95 HB_UNICODE_MAX_DECOMPOSITION_LEN);
89 return g_unichar_fully_decompose(u, TRUE, decomposed,
90 HB_UNICODE_MAX_DECOMPOSITION_LEN);
96 91 } }
97 92
93 /*XXX:should go in lib "global init"*/
98 94 static hb_unicode_funcs_t hb_glib_unicode_funcs = { static hb_unicode_funcs_t hb_glib_unicode_funcs = {
99 REF_CNT_INVALID_VAL,//ref_cnt
100 NULL,//parent
101 TRUE,//immutable
102 {//func
103 hb_glib_unicode_combining_class,
104 hb_glib_unicode_eastasian_width,
105 hb_glib_unicode_general_category,
106 hb_glib_unicode_mirroring,
107 hb_glib_unicode_script,
108 hb_glib_unicode_compose,
109 hb_glib_unicode_decompose,
110 hb_glib_unicode_decompose_compatibility
111 },
112 {//user_data
113 NULL,//combining_class
114 NULL,//eastasian_width
115 NULL,//general_category
116 NULL,//mirroring
117 NULL,//script
118 NULL,//compose
119 NULL,//decompose
120 NULL//decompose_compatibility
121 },
122 {//destroy
123 NULL,//combining_class
124 NULL,//eastasian_width
125 NULL,//general_category
126 NULL,//mirroring
127 NULL,//script
128 NULL,//compose
129 NULL,//decompose
130 NULL//decompose_compatibility
131 }
95 REF_CNT_INVALID_VAL, /*ref_cnt */
96 NULL, /*parent */
97 TRUE, /*immutable */
98 { /*func */
99 hb_glib_unicode_combining_class,
100 hb_glib_unicode_eastasian_width,
101 hb_glib_unicode_general_category,
102 hb_glib_unicode_mirroring,
103 hb_glib_unicode_script,
104 hb_glib_unicode_compose,
105 hb_glib_unicode_decompose,
106 hb_glib_unicode_decompose_compatibility},
107 { /*user_data */
108 NULL, /*combining_class */
109 NULL, /*eastasian_width */
110 NULL, /*general_category */
111 NULL, /*mirroring */
112 NULL, /*script */
113 NULL, /*compose */
114 NULL, /*decompose */
115 NULL /*decompose_compatibility */
116 },
117 { /*destroy */
118 NULL, /*combining_class */
119 NULL, /*eastasian_width */
120 NULL, /*general_category */
121 NULL, /*mirroring */
122 NULL, /*script */
123 NULL, /*compose */
124 NULL, /*decompose */
125 NULL /*decompose_compatibility */
126 }
132 127 }; };
133 128
134 hb_unicode_funcs_t *
135 hb_glib_get_unicode_funcs(void)
129 hb_unicode_funcs_t *hb_glib_get_unicode_funcs(void)
136 130 { {
137 return &hb_glib_unicode_funcs;
131 return &hb_glib_unicode_funcs;
138 132 } }
File hb-glib.h changed (mode: 100644) (index 63a9d33..12c3e3b)
36 36 HB_BEGIN_DECLS HB_BEGIN_DECLS
37 37
38 38
39 hb_script_t
39 HB_EXTERN hb_script_t
40 40 hb_glib_script_to_script (GUnicodeScript script); hb_glib_script_to_script (GUnicodeScript script);
41 41
42 GUnicodeScript
42 HB_EXTERN GUnicodeScript
43 43 hb_glib_script_from_script (hb_script_t script); hb_glib_script_from_script (hb_script_t script);
44 44
45 45
46 hb_unicode_funcs_t *
46 HB_EXTERN hb_unicode_funcs_t *
47 47 hb_glib_get_unicode_funcs (void); hb_glib_get_unicode_funcs (void);
48 48
49 HB_EXTERN hb_blob_t *
50 hb_glib_blob_create (GBytes *gbytes);
51
49 52
50 53 HB_END_DECLS HB_END_DECLS
51 54
File hb-gobject-structs.h changed (mode: 100644) (index 4a88d56..0ea3b12)
... ... HB_BEGIN_DECLS
40 40
41 41 /* Object types */ /* Object types */
42 42
43 GType hb_gobject_blob_get_type (void);
43 /**
44 * Since: 0.9.2
45 **/
46 HB_EXTERN GType hb_gobject_blob_get_type (void);
44 47 #define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ()) #define HB_GOBJECT_TYPE_BLOB (hb_gobject_blob_get_type ())
45 48
46 GType hb_gobject_buffer_get_type (void);
49 /**
50 * Since: 0.9.2
51 **/
52 HB_EXTERN GType hb_gobject_buffer_get_type (void);
47 53 #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ()) #define HB_GOBJECT_TYPE_BUFFER (hb_gobject_buffer_get_type ())
48 54
49 GType hb_gobject_face_get_type (void);
55 /**
56 * Since: 0.9.2
57 **/
58 HB_EXTERN GType hb_gobject_face_get_type (void);
50 59 #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ()) #define HB_GOBJECT_TYPE_FACE (hb_gobject_face_get_type ())
51 60
52 GType hb_gobject_font_get_type (void);
61 /**
62 * Since: 0.9.2
63 **/
64 HB_EXTERN GType hb_gobject_font_get_type (void);
53 65 #define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ()) #define HB_GOBJECT_TYPE_FONT (hb_gobject_font_get_type ())
54 66
55 GType hb_gobject_font_funcs_get_type (void);
67 /**
68 * Since: 0.9.2
69 **/
70 HB_EXTERN GType hb_gobject_font_funcs_get_type (void);
56 71 #define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ()) #define HB_GOBJECT_TYPE_FONT_FUNCS (hb_gobject_font_funcs_get_type ())
57 72
58 GType hb_gobject_set_get_type (void);
73 HB_EXTERN GType hb_gobject_set_get_type (void);
59 74 #define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ()) #define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ())
60 75
61 GType hb_gobject_shape_plan_get_type (void);
76 HB_EXTERN GType hb_gobject_shape_plan_get_type (void);
62 77 #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ()) #define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ())
63 78
64 GType hb_gobject_unicode_funcs_get_type (void);
79 /**
80 * Since: 0.9.2
81 **/
82 HB_EXTERN GType hb_gobject_unicode_funcs_get_type (void);
65 83 #define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ()) #define HB_GOBJECT_TYPE_UNICODE_FUNCS (hb_gobject_unicode_funcs_get_type ())
66 84
67 85 /* Value types */ /* Value types */
68 86
69 GType hb_gobject_feature_get_type (void);
87 HB_EXTERN GType hb_gobject_feature_get_type (void);
70 88 #define HB_GOBJECT_TYPE_FEATURE (hb_gobject_feature_get_type ()) #define HB_GOBJECT_TYPE_FEATURE (hb_gobject_feature_get_type ())
71 89
72 GType hb_gobject_glyph_info_get_type (void);
90 HB_EXTERN GType hb_gobject_glyph_info_get_type (void);
73 91 #define HB_GOBJECT_TYPE_GLYPH_INFO (hb_gobject_glyph_info_get_type ()) #define HB_GOBJECT_TYPE_GLYPH_INFO (hb_gobject_glyph_info_get_type ())
74 92
75 GType hb_gobject_glyph_position_get_type (void);
93 HB_EXTERN GType hb_gobject_glyph_position_get_type (void);
76 94 #define HB_GOBJECT_TYPE_GLYPH_POSITION (hb_gobject_glyph_position_get_type ()) #define HB_GOBJECT_TYPE_GLYPH_POSITION (hb_gobject_glyph_position_get_type ())
77 95
78 GType hb_gobject_segment_properties_get_type (void);
96 HB_EXTERN GType hb_gobject_segment_properties_get_type (void);
79 97 #define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ()) #define HB_GOBJECT_TYPE_SEGMENT_PROPERTIES (hb_gobject_segment_properties_get_type ())
80 98
81 GType hb_gobject_user_data_key_get_type (void);
99 HB_EXTERN GType hb_gobject_user_data_key_get_type (void);
82 100 #define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ()) #define HB_GOBJECT_TYPE_USER_DATA_KEY (hb_gobject_user_data_key_get_type ())
83 101
84 /* Currently gobject-introspection doesn't understand that hb_language_t
85 * can be passed by-value. As such we box it up. May remove in the
86 * future.
87 *
88 * https://bugzilla.gnome.org/show_bug.cgi?id=707656
89 */
90 GType hb_gobject_language_get_type (void);
91 #define HB_GOBJECT_TYPE_LANGUAGE (hb_gobject_language_get_type ())
92 102
93 103 HB_END_DECLS HB_END_DECLS
94 104
File hb-graphite2.h changed (mode: 100644) (index 3eae54a..122c3e4)
... ... HB_BEGIN_DECLS
36 36 #define HB_GRAPHITE2_TAG_SILF HB_TAG('S','i','l','f') #define HB_GRAPHITE2_TAG_SILF HB_TAG('S','i','l','f')
37 37
38 38
39 gr_face *
39 HB_EXTERN gr_face *
40 40 hb_graphite2_face_get_gr_face (hb_face_t *face); hb_graphite2_face_get_gr_face (hb_face_t *face);
41 41
42 gr_font *
42 HB_EXTERN gr_font *
43 43 hb_graphite2_font_get_gr_font (hb_font_t *font); hb_graphite2_font_get_gr_font (hb_font_t *font);
44 44
45 45
File hb-icu.h changed (mode: 100644) (index f2f35f0..2db6a7b)
36 36 HB_BEGIN_DECLS HB_BEGIN_DECLS
37 37
38 38
39 hb_script_t
39 HB_EXTERN hb_script_t
40 40 hb_icu_script_to_script (UScriptCode script); hb_icu_script_to_script (UScriptCode script);
41 41
42 UScriptCode
42 HB_EXTERN UScriptCode
43 43 hb_icu_script_from_script (hb_script_t script); hb_icu_script_from_script (hb_script_t script);
44 44
45 45
46 hb_unicode_funcs_t *
46 HB_EXTERN hb_unicode_funcs_t *
47 47 hb_icu_get_unicode_funcs (void); hb_icu_get_unicode_funcs (void);
48 48
49 49
File hb-open-file-private.h changed (mode: 100644) (index 7172c28..3e45145)
1 1 #ifndef HB_OPEN_FILE_PRIVATE_H #ifndef HB_OPEN_FILE_PRIVATE_H
2 2 #define HB_OPEN_FILE_PRIVATE_H #define HB_OPEN_FILE_PRIVATE_H
3 3
4 // Organization of an OpenType Font
5 // note: structs are supposely properly aligned to avoid the use of packing
6
4 /*Organization of an OpenType Font
5 note: structs are supposely properly aligned to avoid the use of packing*/
7 6
8 7 #define IDX_NOT_FOUND 0xffff #define IDX_NOT_FOUND 0xffff
9 8
10 struct tbl_rec
11 {
12 uint32_t tag; //4-byte identifier
13 uint32_t chk_sum;//Check sum for this table
14 uint32_t of; //Offset from beginning of TrueType font file
15 uint32_t len; //Length of this table
9 struct tbl_rec {
10 uint32_t tag; /*4-byte identifier */
11 uint32_t chk_sum; /*Check sum for this table */
12 uint32_t of; /*Offset from beginning of TrueType font file */
13 uint32_t len; /*Length of this table */
16 14 }; };
17 15 #define ot_tbl tbl_rec #define ot_tbl tbl_rec
18 16
19 struct ot_fnt_face
20 {
21 uint32_t sfnt_ver; //'\0\001\0\00' if TrueType / 'OTTO' if CFF
22 uint16_t tbls_n; //Number of tables
23 uint16_t search_range; //(Maximum power of 2 <= tbls_n) * 16
24 uint16_t entry_selector;//Log2(maximum power of 2 <= tbls_n)
25 uint16_t range_shift; //tbls_n * 16 - search_range
26 struct tbl_rec tbls[1]; //tbl_rec entries. tbls_n items.
17 struct ot_fnt_face {
18 uint32_t sfnt_ver; /*'\0\001\0\00' if TrueType / 'OTTO' if CFF& */
19 uint16_t tbls_n; /*Number of tables */
20 uint16_t search_range; /*(Maximum power of 2 <= tbls_n) * 16 */
21 uint16_t entry_selector; /*Log2(maximum power of 2 <= tbls_n) */
22 uint16_t range_shift; /*tbls_n * 16 - search_range */
23 struct tbl_rec tbls[1]; /*tbl_rec entries. tbls_n items. */
27 24 }; };
28 25 #define of_tbl ot_fnt_face #define of_tbl ot_fnt_face
29 26
30 struct fixed_ver
31 {
32 uint16_t major;
33 uint16_t minor;
27 struct fixed_ver {
28 uint16_t major;
29 uint16_t minor;
34 30 }; };
35 31
36 struct ttc_hdr_ver1
37 {
38 uint32_t ttc_tag; //TrueType Collection ID string: 'ttcf'
39 struct fixed_ver ver; //Version of the TTC Header (1.0), 0x00010000
40 uint32_t of_tbls_ofs[1];//Array of offsets to the OffsetTable for each
41 //font from the beginning of the file
32 struct ttc_hdr_ver1 {
33 uint32_t ttc_tag; /*TrueType Collection ID string: 'ttcf' */
34 struct fixed_ver ver; /*Version of the TTC Header (1.0), 0x00010000 */
35 uint32_t of_tbls_ofs[1]; /*Array of offsets to the OffsetTable for each */
36 /*font from the beginning of the file */
42 37 }; };
43 38
44 struct ttc_hdr
45 {
46 union {
47 struct {
48 uint32_t ttc_tag; //TrueType Collection ID string: 'ttcf'
49 struct fixed_ver ver;//Version of the TTC Header (1.0 or 2.0),
50 //* 0x00010000 or 0x00020000 */
51 } hdr;
52 struct ttc_hdr_ver1 ver1;
53 } u;
39 struct ttc_hdr {
40 union {
41 struct {
42 uint32_t ttc_tag; /*TrueType Collection ID string: 'ttcf' */
43 struct fixed_ver ver; /*Version of the TTC Header (1.0 or 2.0), */
44 /* 0x00010000 or 0x00020000 */
45 } hdr;
46 struct ttc_hdr_ver1 ver1;
47 } u;
54 48 }; };
55 49
56 //OpenType with Postscript outlines
50 /*OpenType with Postscript outlines*/
57 51 #define CFF_TAG HB_TAG('O','T','T','O') #define CFF_TAG HB_TAG('O','T','T','O')
58 //OpenType with TrueType outlines
52 /*OpenType with TrueType outlines*/
59 53 #define TRUETYPE_TAG HB_TAG( 0 , 1 , 0 , 0 ) #define TRUETYPE_TAG HB_TAG( 0 , 1 , 0 , 0 )
60 //TrueType Collection
54 /*TrueType Collection*/
61 55 #define TTC_TAG HB_TAG('t','t','c','f') #define TTC_TAG HB_TAG('t','t','c','f')
62 //Obsolete Apple TrueType
56 /*Obsolete Apple TrueType*/
63 57 #define TRUE_TAG HB_TAG('t','r','u','e') #define TRUE_TAG HB_TAG('t','r','u','e')
64 //Obsolete Apple Type1 font in SFNT container
58 /*Obsolete Apple Type1 font in SFNT container*/
65 59 #define TYP1_TAG HB_TAG('t','y','p','1') #define TYP1_TAG HB_TAG('t','y','p','1')
66 60
67 struct ot_fnt_file
68 {
69 union {
70 uint32_t tag;
71 struct ot_fnt_face fnt_face;
72 struct ttc_hdr ttc_hdr;
73 } u;
61 struct ot_fnt_file {
62 union {
63 uint32_t tag;
64 struct ot_fnt_face fnt_face;
65 struct ttc_hdr ttc_hdr;
66 } u;
74 67 }; };
75 68
76 struct ot_fnt_face *
77 ot_fnt_file_get_face(struct ot_fnt_file *ot_fnt_file, unsigned i);
69 struct ot_fnt_face *ot_fnt_file_get_face(struct ot_fnt_file *ot_fnt_file,
70 unsigned i);
78 71
79 struct tbl_rec *
80 ot_fnt_face_get_tbl_by_tag(struct ot_fnt_face *ot_fnt_face, hb_tag_t tag);
72 struct tbl_rec *ot_fnt_face_get_tbl_by_tag(struct ot_fnt_face *ot_fnt_face,
73 hb_tag_t tag);
81 74 #endif #endif
File hb-open-file.c changed (mode: 100644) (index c4079ce..18b8970)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
6 /*XXX:have to go*/
4 7 #define _GNU_SOURCE #define _GNU_SOURCE
5 8 #include <endian.h> #include <endian.h>
6 9 #include <stdint.h> #include <stdint.h>
 
10 13 #include "hb-private.h" #include "hb-private.h"
11 14 #include "hb-open-file-private.h" #include "hb-open-file-private.h"
12 15
13 static struct ot_fnt_face *
14 ttc_hdr_ver1_get_face(struct ttc_hdr_ver1 *ttc_hdr_ver1, unsigned i)
16 static struct ot_fnt_face *ttc_hdr_ver1_get_face(struct ttc_hdr_ver1
17 *ttc_hdr_ver1, unsigned i)
15 18 { {
16 if (!ttc_hdr_ver1)
17 return NULL;
19 uint32_t of;
20 uint8_t *base; /*the beginning of the file */
18 21
19 uint32_t of = be32toh(ttc_hdr_ver1->of_tbls_ofs[i]);
20 uint8_t *base = (uint8_t*)ttc_hdr_ver1;//the beginning of the file
21 return (struct ot_fnt_face*)(base + of);
22 if (!ttc_hdr_ver1)
23 return NULL;
24
25 of = be32toh(ttc_hdr_ver1->of_tbls_ofs[i]);
26 base = (uint8_t *) ttc_hdr_ver1;
27 return (struct ot_fnt_face *)(base + of);
22 28 } }
23 29
24 static struct ot_fnt_face *
25 ttc_hdr_get_face(struct ttc_hdr *ttc_hdr, unsigned i)
30 static struct ot_fnt_face *ttc_hdr_get_face(struct ttc_hdr *ttc_hdr, unsigned i)
26 31 { {
27 if (!ttc_hdr)
28 return NULL;
29
30 switch (ttc_hdr->u.hdr.ver.major) {
31 case 2://version 2 is compatible with version 1
32 case 1: return ttc_hdr_ver1_get_face(&ttc_hdr->u.ver1, i);
33 default:return NULL;
34 }
32 if (!ttc_hdr)
33 return NULL;
34
35 switch (ttc_hdr->u.hdr.ver.major) {
36 case 2: /*version 2 is compatible with version 1 */
37 case 1:
38 return ttc_hdr_ver1_get_face(&ttc_hdr->u.ver1, i);
39 default:
40 return NULL;
41 }
35 42 } }
36 43
37 struct ot_fnt_face *
38 ot_fnt_file_get_face(struct ot_fnt_file *ot_fnt_file, unsigned i)
44 struct ot_fnt_face *ot_fnt_file_get_face(struct ot_fnt_file *ot_fnt_file,
45 unsigned i)
39 46 { {
40 if (!ot_fnt_file)
41 return NULL;
42
43 uint32_t tag = be32toh(ot_fnt_file->u.tag);
44
45 switch (tag) {
46 //Note: for non-collection SFNT data we ignore index. This is because
47 //Apple dfont container is a container of SFNT's. So each SFNT is a
48 //non-TTC, but the index is more than zero.
49 case CFF_TAG://All the non-collection tags
50 case TRUE_TAG:
51 case TYP1_TAG:
52 case TRUETYPE_TAG:
53 return &ot_fnt_file->u.fnt_face;
54 case TTC_TAG:
55 return ttc_hdr_get_face(&ot_fnt_file->u.ttc_hdr, i);
56 default:
57 return NULL;
58 }
47 uint32_t tag;
48
49 if (!ot_fnt_file)
50 return NULL;
51
52 tag = be32toh(ot_fnt_file->u.tag);
53
54 switch (tag) {
55 /*Note: for non-collection SFNT data we ignore index. This is because
56 Apple dfont container is a container of SFNT's. So each SFNT is a
57 non-TTC, but the index is more than zero. */
58 case CFF_TAG: /*All the non-collection tags */
59 case TRUE_TAG:
60 case TYP1_TAG:
61 case TRUETYPE_TAG:
62 return &ot_fnt_file->u.fnt_face;
63 case TTC_TAG:
64 return ttc_hdr_get_face(&ot_fnt_file->u.ttc_hdr, i);
65 default:
66 return NULL;
67 }
59 68 } }
60 69
61 static struct tbl_rec *
62 ot_fnt_face_get_tbl(struct ot_fnt_face *ot_fnt_face, unsigned i)
70 static struct tbl_rec *ot_fnt_face_get_tbl(struct ot_fnt_face *ot_fnt_face,
71 unsigned i)
63 72 { {
64 //XXX:check is useless in known code paths
65 if (!ot_fnt_face)
66 return NULL;
73 /*XXX:check is useless in known code paths */
74 if (!ot_fnt_face)
75 return NULL;
67 76
68 if (i >= ot_fnt_face->tbls_n)
69 return NULL;//XXX:original code use a "null" object
70 return &ot_fnt_face->tbls[i];
77 if (i >= ot_fnt_face->tbls_n)
78 return NULL; /*XXX:original code use a "null" object */
79 return &ot_fnt_face->tbls[i];
71 80 } }
72 81
73 static hb_bool_t
74 ot_fnt_face_find_tbl_idx(struct ot_fnt_face *ot_fnt_face,
75 hb_tag_t tag,
76 unsigned *tbl_idx)
82 static hb_bool_t ot_fnt_face_find_tbl_idx(struct ot_fnt_face *ot_fnt_face,
83 hb_tag_t tag, unsigned *tbl_idx)
77 84 { {
78 //XXX:check is useless in known code paths
79 if (!ot_fnt_face)
80 return FALSE;
81
82 unsigned cnt = ot_fnt_face->tbls_n;
83 for (unsigned i = 0; i < cnt; ++i) {
84 uint32_t tbl_tag = be32toh(ot_fnt_face->tbls[i].tag);
85 if (tag == tbl_tag) {
86 if (tbl_idx) *tbl_idx = i;
87 return TRUE;
88 }
89 }
90 if (tbl_idx) *tbl_idx = IDX_NOT_FOUND;
91 return FALSE;
85 unsigned cnt;
86 unsigned i;
87
88 /*XXX:check is useless in known code paths */
89 if (!ot_fnt_face)
90 return FALSE;
91
92 cnt = ot_fnt_face->tbls_n;
93 for (i = 0; i < cnt; ++i) {
94 uint32_t tbl_tag;
95
96 tbl_tag = be32toh(ot_fnt_face->tbls[i].tag);
97 if (tag == tbl_tag) {
98 if (tbl_idx)
99 *tbl_idx = i;
100 return TRUE;
101 }
102 }
103 if (tbl_idx)
104 *tbl_idx = IDX_NOT_FOUND;
105 return FALSE;
92 106 } }
93 107
94 struct tbl_rec *
95 ot_fnt_face_get_tbl_by_tag(struct ot_fnt_face *ot_fnt_face, hb_tag_t tag)
108 struct tbl_rec *ot_fnt_face_get_tbl_by_tag(struct ot_fnt_face *ot_fnt_face,
109 hb_tag_t tag)
96 110 { {
97 if (!ot_fnt_face)
98 return NULL;
111 unsigned tbl_idx;
112
113 if (!ot_fnt_face)
114 return NULL;
99 115
100 unsigned tbl_idx;
101 ot_fnt_face_find_tbl_idx(ot_fnt_face, tag, &tbl_idx);
102 return ot_fnt_face_get_tbl(ot_fnt_face, tbl_idx);
116 ot_fnt_face_find_tbl_idx(ot_fnt_face, tag, &tbl_idx);
117 return ot_fnt_face_get_tbl(ot_fnt_face, tbl_idx);
103 118 } }
File hb-ot-font.h copied from file hb-gobject.h (similarity 79%) (mode: 100644) (index ea1bd25..80eaa54)
1 1 /* /*
2 * Copyright © 2011 Google, Inc.
2 * Copyright © 2014 Google, Inc.
3 3 * *
4 4 * This is part of HarfBuzz, a text shaping library. * This is part of HarfBuzz, a text shaping library.
5 5 * *
 
21 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23 23 * *
24 * Google Author(s): Behdad Esfahbod
24 * Google Author(s): Behdad Esfahbod, Roozbeh Pournader
25 25 */ */
26 26
27 #ifndef HB_GOBJECT_H
28 #define HB_GOBJECT_H
29 #define HB_GOBJECT_H_IN
27 #ifndef HB_OT_H_IN
28 #error "Include <hb-ot.h> instead."
29 #endif
30 30
31 #include "hb.h"
31 #ifndef HB_OT_FONT_H
32 #define HB_OT_FONT_H
32 33
33 #include "hb-gobject-enums.h"
34 #include "hb-gobject-structs.h"
34 #include "hb.h"
35 35
36 36 HB_BEGIN_DECLS HB_BEGIN_DECLS
37
38
39 HB_EXTERN void
40 hb_ot_font_set_funcs (hb_font_t *font);
41
42
37 43 HB_END_DECLS HB_END_DECLS
38 44
39 #undef HB_GOBJECT_H_IN
40 #endif /* HB_GOBJECT_H */
45 #endif /* HB_OT_FONT_H */
File hb-ot-layout.c changed (mode: 100644) (index ecfd5b1..91122b5)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include "hb.h" #include "hb.h"
5 7 #include "hb-private.h" #include "hb-private.h"
6 8 #include "hb-ot-face-private.h" #include "hb-ot-face-private.h"
7 9
8 hb_bool_t
9 hb_ot_layout_table_find_script (hb_face_t *face,
10 hb_tag_t table_tag,
11 hb_tag_t script_tag,
12 unsigned int *script_index)
10 hb_bool_t hb_ot_layout_table_find_script(hb_face_t * face, hb_tag_t table_tag,
11 hb_tag_t script_tag,
12 unsigned int *script_index)
13 13 { {
14 (void)face;
15 (void)table_tag;
16 (void)script_tag;
17 (void)script_index;
18 return FALSE;
14 (void)face;
15 (void)table_tag;
16 (void)script_tag;
17 (void)script_index;
18 return FALSE;
19 19 } }
20 20
21 unsigned int
22 hb_ot_layout_language_get_feature_tags (hb_face_t *face,
23 hb_tag_t table_tag,
24 unsigned int script_index,
25 unsigned int language_index,
26 unsigned int start_offset,
27 unsigned int *feature_count /* IN/OUT */,
28 hb_tag_t *feature_tags /* OUT */)
21 unsigned int hb_ot_layout_language_get_feature_tags(hb_face_t * face,
22 hb_tag_t table_tag,
23 unsigned int script_index,
24 unsigned int language_index,
25 unsigned int start_offset,
26 unsigned int *feature_count
27 /* IN/OUT */ ,
28 hb_tag_t *
29 feature_tags /* OUT */)
29 30 { {
30 (void)face;
31 (void)table_tag;
32 (void)script_index;
33 (void)language_index;
34 (void)start_offset;
35 (void)feature_count;
36 (void)feature_tags;
37 return 0;
31 (void)face;
32 (void)table_tag;
33 (void)script_index;
34 (void)language_index;
35 (void)start_offset;
36 (void)feature_count;
37 (void)feature_tags;
38 return 0;
38 39 } }
39 40
40 hb_bool_t
41 hb_ot_layout_language_find_feature (hb_face_t *face,
42 hb_tag_t table_tag,
43 unsigned int script_index,
44 unsigned int language_index,
45 hb_tag_t feature_tag,
46 unsigned int *feature_index)
41 hb_bool_t hb_ot_layout_language_find_feature(hb_face_t * face,
42 hb_tag_t table_tag,
43 unsigned int script_index,
44 unsigned int language_index,
45 hb_tag_t feature_tag,
46 unsigned int *feature_index)
47 47 { {
48 (void)face;
49 (void)table_tag;
50 (void)script_index;
51 (void)language_index;
52 (void)feature_tag;
53 (void)feature_index;
54 return FALSE;
48 (void)face;
49 (void)table_tag;
50 (void)script_index;
51 (void)language_index;
52 (void)feature_tag;
53 (void)feature_index;
54 return FALSE;
55 55 } }
56 56
57 unsigned int
58 hb_ot_layout_script_get_language_tags (hb_face_t *face,
59 hb_tag_t table_tag,
60 unsigned int script_index,
61 unsigned int start_offset,
62 unsigned int *language_count /* IN/OUT */,
63 hb_tag_t *language_tags /* OUT */)
57 unsigned int hb_ot_layout_script_get_language_tags(hb_face_t * face,
58 hb_tag_t table_tag,
59 unsigned int script_index,
60 unsigned int start_offset,
61 unsigned int *language_count
62 /* IN/OUT */ ,
63 hb_tag_t *
64 language_tags /* OUT */)
64 65 { {
65 (void)face;
66 (void)table_tag;
67 (void)script_index;
68 (void)start_offset;
69 (void)language_count;
70 (void)language_tags;
71 return 0;
66 (void)face;
67 (void)table_tag;
68 (void)script_index;
69 (void)start_offset;
70 (void)language_count;
71 (void)language_tags;
72 return 0;
72 73 } }
73 74
74 unsigned int
75 hb_ot_layout_table_get_script_tags (hb_face_t *face,
76 hb_tag_t table_tag,
77 unsigned int start_offset,
78 unsigned int *script_count /* IN/OUT */,
79 hb_tag_t *script_tags /* OUT */)
75 unsigned int hb_ot_layout_table_get_script_tags(hb_face_t * face,
76 hb_tag_t table_tag,
77 unsigned int start_offset,
78 unsigned int *script_count
79 /* IN/OUT */ ,
80 hb_tag_t *
81 script_tags /* OUT */)
80 82 { {
81 (void)face;
82 (void)table_tag;
83 (void)start_offset;
84 (void)script_count;
85 (void)script_tags;
86 return 0;
83 (void)face;
84 (void)table_tag;
85 (void)start_offset;
86 (void)script_count;
87 (void)script_tags;
88 return 0;
87 89 } }
88 90
89 hb_bool_t
90 hb_ot_layout_script_find_language (hb_face_t *face,
91 hb_tag_t table_tag,
92 unsigned int script_index,
93 hb_tag_t language_tag,
94 unsigned int *language_index)
91 hb_bool_t hb_ot_layout_script_find_language(hb_face_t * face,
92 hb_tag_t table_tag,
93 unsigned int script_index,
94 hb_tag_t language_tag,
95 unsigned int *language_index)
95 96 { {
96 (void)face;
97 (void)table_tag;
98 (void)script_index;
99 (void)language_tag;
100 (void)language_index;
101 return FALSE;
97 (void)face;
98 (void)table_tag;
99 (void)script_index;
100 (void)language_tag;
101 (void)language_index;
102 return FALSE;
102 103 } }
103 104
104 hb_bool_t
105 hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
106 hb_tag_t table_tag,
107 unsigned int script_index,
108 unsigned int language_index,
109 unsigned int *feature_index)
105 hb_bool_t hb_ot_layout_language_get_required_feature_index(hb_face_t * face,
106 hb_tag_t table_tag,
107 unsigned int
108 script_index,
109 unsigned int
110 language_index,
111 unsigned int
112 *feature_index)
110 113 { {
111 (void)face;
112 (void)table_tag;
113 (void)script_index;
114 (void)language_index;
115 (void)feature_index;
116 return FALSE;
114 (void)face;
115 (void)table_tag;
116 (void)script_index;
117 (void)language_index;
118 (void)feature_index;
119 return FALSE;
117 120 } }
File hb-ot-layout.h changed (mode: 100644) (index d2a314c..eb23d45)
... ... HB_BEGIN_DECLS
48 48 * GDEF * GDEF
49 49 */ */
50 50
51 hb_bool_t
51 HB_EXTERN hb_bool_t
52 52 hb_ot_layout_has_glyph_classes (hb_face_t *face); hb_ot_layout_has_glyph_classes (hb_face_t *face);
53 53
54 54 typedef enum { typedef enum {
 
... ... typedef enum {
59 59 HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 4 HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 4
60 60 } hb_ot_layout_glyph_class_t; } hb_ot_layout_glyph_class_t;
61 61
62 hb_ot_layout_glyph_class_t
62 HB_EXTERN hb_ot_layout_glyph_class_t
63 63 hb_ot_layout_get_glyph_class (hb_face_t *face, hb_ot_layout_get_glyph_class (hb_face_t *face,
64 64 hb_codepoint_t glyph); hb_codepoint_t glyph);
65 65
66 void
66 HB_EXTERN void
67 67 hb_ot_layout_get_glyphs_in_class (hb_face_t *face, hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
68 68 hb_ot_layout_glyph_class_t klass, hb_ot_layout_glyph_class_t klass,
69 69 hb_set_t *glyphs /* OUT */); hb_set_t *glyphs /* OUT */);
 
... ... hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
71 71
72 72 /* Not that useful. Provides list of attach points for a glyph that a /* Not that useful. Provides list of attach points for a glyph that a
73 73 * client may want to cache */ * client may want to cache */
74 unsigned int
74 HB_EXTERN unsigned int
75 75 hb_ot_layout_get_attach_points (hb_face_t *face, hb_ot_layout_get_attach_points (hb_face_t *face,
76 76 hb_codepoint_t glyph, hb_codepoint_t glyph,
77 77 unsigned int start_offset, unsigned int start_offset,
 
... ... hb_ot_layout_get_attach_points (hb_face_t *face,
79 79 unsigned int *point_array /* OUT */); unsigned int *point_array /* OUT */);
80 80
81 81 /* Ligature caret positions */ /* Ligature caret positions */
82 unsigned int
82 HB_EXTERN unsigned int
83 83 hb_ot_layout_get_ligature_carets (hb_font_t *font, hb_ot_layout_get_ligature_carets (hb_font_t *font,
84 84 hb_direction_t direction, hb_direction_t direction,
85 85 hb_codepoint_t glyph, hb_codepoint_t glyph,
 
... ... hb_ot_layout_get_ligature_carets (hb_font_t *font,
92 92 * GSUB/GPOS feature query and enumeration interface * GSUB/GPOS feature query and enumeration interface
93 93 */ */
94 94
95 #define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF)
96 #define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF)
97 #define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF)
95 #define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu
96 #define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu
97 #define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu
98 98
99 unsigned int
99 HB_EXTERN unsigned int
100 100 hb_ot_layout_table_get_script_tags (hb_face_t *face, hb_ot_layout_table_get_script_tags (hb_face_t *face,
101 101 hb_tag_t table_tag, hb_tag_t table_tag,
102 102 unsigned int start_offset, unsigned int start_offset,
103 103 unsigned int *script_count /* IN/OUT */, unsigned int *script_count /* IN/OUT */,
104 104 hb_tag_t *script_tags /* OUT */); hb_tag_t *script_tags /* OUT */);
105 105
106 hb_bool_t
106 HB_EXTERN hb_bool_t
107 107 hb_ot_layout_table_find_script (hb_face_t *face, hb_ot_layout_table_find_script (hb_face_t *face,
108 108 hb_tag_t table_tag, hb_tag_t table_tag,
109 109 hb_tag_t script_tag, hb_tag_t script_tag,
110 110 unsigned int *script_index); unsigned int *script_index);
111 111
112 112 /* Like find_script, but takes zero-terminated array of scripts to test */ /* Like find_script, but takes zero-terminated array of scripts to test */
113 hb_bool_t
113 HB_EXTERN hb_bool_t
114 114 hb_ot_layout_table_choose_script (hb_face_t *face, hb_ot_layout_table_choose_script (hb_face_t *face,
115 115 hb_tag_t table_tag, hb_tag_t table_tag,
116 116 const hb_tag_t *script_tags, const hb_tag_t *script_tags,
117 117 unsigned int *script_index, unsigned int *script_index,
118 118 hb_tag_t *chosen_script); hb_tag_t *chosen_script);
119 119
120 unsigned int
120 HB_EXTERN unsigned int
121 121 hb_ot_layout_table_get_feature_tags (hb_face_t *face, hb_ot_layout_table_get_feature_tags (hb_face_t *face,
122 122 hb_tag_t table_tag, hb_tag_t table_tag,
123 123 unsigned int start_offset, unsigned int start_offset,
124 124 unsigned int *feature_count /* IN/OUT */, unsigned int *feature_count /* IN/OUT */,
125 125 hb_tag_t *feature_tags /* OUT */); hb_tag_t *feature_tags /* OUT */);
126 126
127 unsigned int
127 HB_EXTERN unsigned int
128 128 hb_ot_layout_script_get_language_tags (hb_face_t *face, hb_ot_layout_script_get_language_tags (hb_face_t *face,
129 129 hb_tag_t table_tag, hb_tag_t table_tag,
130 130 unsigned int script_index, unsigned int script_index,
 
... ... hb_ot_layout_script_get_language_tags (hb_face_t *face,
132 132 unsigned int *language_count /* IN/OUT */, unsigned int *language_count /* IN/OUT */,
133 133 hb_tag_t *language_tags /* OUT */); hb_tag_t *language_tags /* OUT */);
134 134
135 hb_bool_t
135 HB_EXTERN hb_bool_t
136 136 hb_ot_layout_script_find_language (hb_face_t *face, hb_ot_layout_script_find_language (hb_face_t *face,
137 137 hb_tag_t table_tag, hb_tag_t table_tag,
138 138 unsigned int script_index, unsigned int script_index,
139 139 hb_tag_t language_tag, hb_tag_t language_tag,
140 140 unsigned int *language_index); unsigned int *language_index);
141 141
142 hb_bool_t
142 HB_EXTERN hb_bool_t
143 143 hb_ot_layout_language_get_required_feature_index (hb_face_t *face, hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
144 144 hb_tag_t table_tag, hb_tag_t table_tag,
145 145 unsigned int script_index, unsigned int script_index,
146 146 unsigned int language_index, unsigned int language_index,
147 147 unsigned int *feature_index); unsigned int *feature_index);
148 148
149 unsigned int
149 HB_EXTERN hb_bool_t
150 hb_ot_layout_language_get_required_feature (hb_face_t *face,
151 hb_tag_t table_tag,
152 unsigned int script_index,
153 unsigned int language_index,
154 unsigned int *feature_index,
155 hb_tag_t *feature_tag);
156
157 HB_EXTERN unsigned int
150 158 hb_ot_layout_language_get_feature_indexes (hb_face_t *face, hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
151 159 hb_tag_t table_tag, hb_tag_t table_tag,
152 160 unsigned int script_index, unsigned int script_index,
 
... ... hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
155 163 unsigned int *feature_count /* IN/OUT */, unsigned int *feature_count /* IN/OUT */,
156 164 unsigned int *feature_indexes /* OUT */); unsigned int *feature_indexes /* OUT */);
157 165
158 unsigned int
166 HB_EXTERN unsigned int
159 167 hb_ot_layout_language_get_feature_tags (hb_face_t *face, hb_ot_layout_language_get_feature_tags (hb_face_t *face,
160 168 hb_tag_t table_tag, hb_tag_t table_tag,
161 169 unsigned int script_index, unsigned int script_index,
 
... ... hb_ot_layout_language_get_feature_tags (hb_face_t *face,
164 172 unsigned int *feature_count /* IN/OUT */, unsigned int *feature_count /* IN/OUT */,
165 173 hb_tag_t *feature_tags /* OUT */); hb_tag_t *feature_tags /* OUT */);
166 174
167 hb_bool_t
175 HB_EXTERN hb_bool_t
168 176 hb_ot_layout_language_find_feature (hb_face_t *face, hb_ot_layout_language_find_feature (hb_face_t *face,
169 177 hb_tag_t table_tag, hb_tag_t table_tag,
170 178 unsigned int script_index, unsigned int script_index,
 
... ... hb_ot_layout_language_find_feature (hb_face_t *face,
172 180 hb_tag_t feature_tag, hb_tag_t feature_tag,
173 181 unsigned int *feature_index); unsigned int *feature_index);
174 182
175 unsigned int
183 HB_EXTERN unsigned int
176 184 hb_ot_layout_feature_get_lookups (hb_face_t *face, hb_ot_layout_feature_get_lookups (hb_face_t *face,
177 185 hb_tag_t table_tag, hb_tag_t table_tag,
178 186 unsigned int feature_index, unsigned int feature_index,
 
... ... hb_ot_layout_feature_get_lookups (hb_face_t *face,
180 188 unsigned int *lookup_count /* IN/OUT */, unsigned int *lookup_count /* IN/OUT */,
181 189 unsigned int *lookup_indexes /* OUT */); unsigned int *lookup_indexes /* OUT */);
182 190
183 void
191 HB_EXTERN unsigned int
192 hb_ot_layout_table_get_lookup_count (hb_face_t *face,
193 hb_tag_t table_tag);
194
195
196 HB_EXTERN void
184 197 hb_ot_layout_collect_lookups (hb_face_t *face, hb_ot_layout_collect_lookups (hb_face_t *face,
185 198 hb_tag_t table_tag, hb_tag_t table_tag,
186 199 const hb_tag_t *scripts, const hb_tag_t *scripts,
 
... ... hb_ot_layout_collect_lookups (hb_face_t *face,
188 201 const hb_tag_t *features, const hb_tag_t *features,
189 202 hb_set_t *lookup_indexes /* OUT */); hb_set_t *lookup_indexes /* OUT */);
190 203
191 void
192 hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
193 hb_tag_t table_tag,
194 hb_set_t *lookup_indexes /* OUT */);
195
196 void
204 HB_EXTERN void
197 205 hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
198 206 hb_tag_t table_tag, hb_tag_t table_tag,
199 207 unsigned int lookup_index, unsigned int lookup_index,
 
... ... typedef hb_bool_t
220 228 const hb_ot_layout_glyph_sequence_t *sequence, const hb_ot_layout_glyph_sequence_t *sequence,
221 229 void *user_data); void *user_data);
222 230
223 void
231 HB_EXTERN void
224 232 Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face, Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face,
225 233 hb_tag_t table_tag, hb_tag_t table_tag,
226 234 unsigned int lookup_index, unsigned int lookup_index,
 
... ... Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face,
233 241 * GSUB * GSUB
234 242 */ */
235 243
236 hb_bool_t
244 HB_EXTERN hb_bool_t
237 245 hb_ot_layout_has_substitution (hb_face_t *face); hb_ot_layout_has_substitution (hb_face_t *face);
238 246
239 hb_bool_t
247 HB_EXTERN hb_bool_t
240 248 hb_ot_layout_lookup_would_substitute (hb_face_t *face, hb_ot_layout_lookup_would_substitute (hb_face_t *face,
241 249 unsigned int lookup_index, unsigned int lookup_index,
242 250 const hb_codepoint_t *glyphs, const hb_codepoint_t *glyphs,
243 251 unsigned int glyphs_length, unsigned int glyphs_length,
244 252 hb_bool_t zero_context); hb_bool_t zero_context);
245 253
246 void
254 HB_EXTERN void
247 255 hb_ot_layout_lookup_substitute_closure (hb_face_t *face, hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
248 256 unsigned int lookup_index, unsigned int lookup_index,
249 257 hb_set_t *glyphs hb_set_t *glyphs
 
... ... hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
251 259
252 260 #ifdef HB_NOT_IMPLEMENTED #ifdef HB_NOT_IMPLEMENTED
253 261 /* Note: You better have GDEF when using this API, or marks won't do much. */ /* Note: You better have GDEF when using this API, or marks won't do much. */
254 hb_bool_t
262 HB_EXTERN hb_bool_t
255 263 Xhb_ot_layout_lookup_substitute (hb_font_t *font, Xhb_ot_layout_lookup_substitute (hb_font_t *font,
256 264 unsigned int lookup_index, unsigned int lookup_index,
257 265 const hb_ot_layout_glyph_sequence_t *sequence, const hb_ot_layout_glyph_sequence_t *sequence,
 
... ... Xhb_ot_layout_lookup_substitute (hb_font_t *font,
266 274 * GPOS * GPOS
267 275 */ */
268 276
269 hb_bool_t
277 HB_EXTERN hb_bool_t
270 278 hb_ot_layout_has_positioning (hb_face_t *face); hb_ot_layout_has_positioning (hb_face_t *face);
271 279
272 280 #ifdef HB_NOT_IMPLEMENTED #ifdef HB_NOT_IMPLEMENTED
273 281 /* Note: You better have GDEF when using this API, or marks won't do much. */ /* Note: You better have GDEF when using this API, or marks won't do much. */
274 hb_bool_t
282 HB_EXTERN hb_bool_t
275 283 Xhb_ot_layout_lookup_position (hb_font_t *font, Xhb_ot_layout_lookup_position (hb_font_t *font,
276 284 unsigned int lookup_index, unsigned int lookup_index,
277 285 const hb_ot_layout_glyph_sequence_t *sequence, const hb_ot_layout_glyph_sequence_t *sequence,
 
... ... Xhb_ot_layout_lookup_position (hb_font_t *font,
280 288
281 289 /* Optical 'size' feature info. Returns true if found. /* Optical 'size' feature info. Returns true if found.
282 290 * http://www.microsoft.com/typography/otspec/features_pt.htm#size */ * http://www.microsoft.com/typography/otspec/features_pt.htm#size */
283 hb_bool_t
291 HB_EXTERN hb_bool_t
284 292 hb_ot_layout_get_size_params (hb_face_t *face, hb_ot_layout_get_size_params (hb_face_t *face,
285 293 unsigned int *design_size, /* OUT. May be NULL */ unsigned int *design_size, /* OUT. May be NULL */
286 294 unsigned int *subfamily_id, /* OUT. May be NULL */ unsigned int *subfamily_id, /* OUT. May be NULL */
File hb-ot-shape.h copied from file hb-ot.h (similarity 77%) (mode: 100644) (index 8073906..7b1bcc0)
1 1 /* /*
2 * Copyright © 2009 Red Hat, Inc.
2 * Copyright © 2013 Red Hat, Inc.
3 3 * *
4 4 * This is part of HarfBuzz, a text shaping library. * This is part of HarfBuzz, a text shaping library.
5 5 * *
 
24 24 * Red Hat Author(s): Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
25 25 */ */
26 26
27 #ifndef HB_OT_H
28 #define HB_OT_H
29 #define HB_OT_H_IN
27 #ifndef HB_OT_H_IN
28 #error "Include <hb-ot.h> instead."
29 #endif
30 30
31 #include "hb.h"
31 #ifndef HB_OT_SHAPE_H
32 #define HB_OT_SHAPE_H
32 33
33 #include "hb-ot-layout.h"
34 #include "hb-ot-tag.h"
34 #include "hb.h"
35 35
36 36 HB_BEGIN_DECLS HB_BEGIN_DECLS
37 37
38 /* TODO remove */
39 void
38 /* TODO port to shape-plan / set. */
39 HB_EXTERN void
40 40 hb_ot_shape_glyphs_closure (hb_font_t *font, hb_ot_shape_glyphs_closure (hb_font_t *font,
41 41 hb_buffer_t *buffer, hb_buffer_t *buffer,
42 42 const hb_feature_t *features, const hb_feature_t *features,
43 43 unsigned int num_features, unsigned int num_features,
44 44 hb_set_t *glyphs); hb_set_t *glyphs);
45 45
46 HB_EXTERN void
47 hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
48 hb_tag_t table_tag,
49 hb_set_t *lookup_indexes /* OUT */);
50
46 51 HB_END_DECLS HB_END_DECLS
47 52
48 #undef HB_OT_H_IN
49 #endif /* HB_OT_H */
53 #endif /* HB_OT_SHAPE_H */
File hb-ot-tag.c changed (mode: 100644) (index 42faaca..bfa3d45)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 *Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <stddef.h> #include <stddef.h>
5 7
6 8 #include "hb.h" #include "hb.h"
7 9 #include "hb-private.h" #include "hb-private.h"
8 10 #include "hb-ot.h" #include "hb-ot.h"
9 11
10 hb_script_t
11 hb_ot_tag_to_script (hb_tag_t tag)
12 hb_script_t hb_ot_tag_to_script(hb_tag_t tag)
12 13 { {
13 (void)tag;
14 return HB_SCRIPT_INVALID;
14 (void)tag;
15 return HB_SCRIPT_INVALID;
15 16 } }
16 17
17 hb_language_t
18 hb_ot_tag_to_language (hb_tag_t tag)
18 hb_language_t hb_ot_tag_to_language(hb_tag_t tag)
19 19 { {
20 (void)tag;
21 return HB_LANGUAGE_INVALID;
20 (void)tag;
21 return HB_LANGUAGE_INVALID;
22 22 } }
23 23
24 hb_tag_t
25 hb_ot_tag_from_language (hb_language_t language)
24 hb_tag_t hb_ot_tag_from_language(hb_language_t language)
26 25 { {
27 (void)language;
28 return HB_OT_TAG_DEFAULT_LANGUAGE;
26 (void)language;
27 return HB_OT_TAG_DEFAULT_LANGUAGE;
29 28 } }
30 29
31 void
32 hb_ot_tags_from_script (hb_script_t script,
33 hb_tag_t *script_tag_1,
34 hb_tag_t *script_tag_2)
30 void hb_ot_tags_from_script(hb_script_t script, hb_tag_t * script_tag_1,
31 hb_tag_t * script_tag_2)
35 32 { {
36 (void)script;
37 (void)script_tag_1;
38 (void)script_tag_2;
33 (void)script;
34 (void)script_tag_1;
35 (void)script_tag_2;
39 36 } }
File hb-ot-tag.h changed (mode: 100644) (index 1bf12ab..54fb747)
... ... HB_BEGIN_DECLS
39 39 #define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') #define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T')
40 40 #define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') #define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't')
41 41
42 void
42 HB_EXTERN void
43 43 hb_ot_tags_from_script (hb_script_t script, hb_ot_tags_from_script (hb_script_t script,
44 44 hb_tag_t *script_tag_1, hb_tag_t *script_tag_1,
45 45 hb_tag_t *script_tag_2); hb_tag_t *script_tag_2);
46 46
47 hb_script_t
47 HB_EXTERN hb_script_t
48 48 hb_ot_tag_to_script (hb_tag_t tag); hb_ot_tag_to_script (hb_tag_t tag);
49 49
50 hb_tag_t
50 HB_EXTERN hb_tag_t
51 51 hb_ot_tag_from_language (hb_language_t language); hb_ot_tag_from_language (hb_language_t language);
52 52
53 hb_language_t
53 HB_EXTERN hb_language_t
54 54 hb_ot_tag_to_language (hb_tag_t tag); hb_ot_tag_to_language (hb_tag_t tag);
55 55
56 56
File hb-ot.h changed (mode: 100644) (index 8073906..47c92a5)
30 30
31 31 #include "hb.h" #include "hb.h"
32 32
33 #include "hb-ot-font.h"
33 34 #include "hb-ot-layout.h" #include "hb-ot-layout.h"
34 35 #include "hb-ot-tag.h" #include "hb-ot-tag.h"
36 #include "hb-ot-shape.h"
35 37
36 38 HB_BEGIN_DECLS HB_BEGIN_DECLS
37 39
38 /* TODO remove */
39 void
40 hb_ot_shape_glyphs_closure (hb_font_t *font,
41 hb_buffer_t *buffer,
42 const hb_feature_t *features,
43 unsigned int num_features,
44 hb_set_t *glyphs);
45
46 40 HB_END_DECLS HB_END_DECLS
47 41
48 42 #undef HB_OT_H_IN #undef HB_OT_H_IN
File hb-private.h changed (mode: 100644) (index ae4bc85..827e6c9)
1 1 #ifndef HB_PRIVATE_H #ifndef HB_PRIVATE_H
2 2 #define HB_PRIVATE_H #define HB_PRIVATE_H
3 3 #if __GNUC__ >= 4 #if __GNUC__ >= 4
4 # define HB_UNUSED __attribute__((unused))
4 #define HB_UNUSED __attribute__((unused))
5 5 #else #else
6 # define HB_UNUSED
6 #define HB_UNUSED
7 7 #endif #endif
8 8
9 9 #ifdef __GNUC__ #ifdef __GNUC__
10 # define HB_INTERNAL __attribute__((__visibility__("hidden")))
10 #define HB_INTERNAL __attribute__((__visibility__("hidden")))
11 #define INLINE __inline__
11 12 #else #else
12 # define HB_INTERNAL
13 #define HB_INTERNAL
14 #define INLINE
13 15 #endif #endif
14 16
15 17 #define HB_DEBUG 0 #define HB_DEBUG 0
 
23 25 #undef ARRAY_LENGTH #undef ARRAY_LENGTH
24 26 #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0])) #define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
25 27
26 static inline hb_bool_t
27 hb_unsigned_int_mul_overflows(unsigned int count, unsigned int size)
28 static INLINE hb_bool_t hb_unsigned_int_mul_overflows(unsigned int count,
29 unsigned int size)
28 30 { {
29 return (size > 0) && (count >= ((unsigned int) -1) / size);
31 return (size > 0) && (count >= ((unsigned int)-1) / size);
30 32 } }
31 33
32 static inline hb_bool_t
33 hb_codepoint_in_range(hb_codepoint_t u, hb_codepoint_t lo, hb_codepoint_t hi)
34 static INLINE hb_bool_t hb_codepoint_in_range(hb_codepoint_t u,
35 hb_codepoint_t lo,
36 hb_codepoint_t hi)
34 37 { {
35 if ( ((lo^hi) & lo) == 0 &&
36 ((lo^hi) & hi) == (lo^hi) &&
37 ((lo^hi) & ((lo^hi) + 1)) == 0 )
38 return (u & ~(lo^hi)) == lo;
39 else
40 return lo <= u && u <= hi;
38 if (((lo ^ hi) & lo) == 0 &&
39 ((lo ^ hi) & hi) == (lo ^ hi) && ((lo ^ hi) & ((lo ^ hi) + 1)) == 0)
40 return (u & ~(lo ^ hi)) == lo;
41 else
42 return lo <= u && u <= hi;
41 43 } }
42 44
43 static inline hb_bool_t
44 hb_codepoint_in_ranges(hb_codepoint_t u, hb_codepoint_t lo1, hb_codepoint_t hi1,
45 hb_codepoint_t lo2, hb_codepoint_t hi2,
46 hb_codepoint_t lo3, hb_codepoint_t hi3)
45 static INLINE hb_bool_t hb_codepoint_in_ranges(hb_codepoint_t u,
46 hb_codepoint_t lo1,
47 hb_codepoint_t hi1,
48 hb_codepoint_t lo2,
49 hb_codepoint_t hi2,
50 hb_codepoint_t lo3,
51 hb_codepoint_t hi3)
47 52 { {
48 return hb_codepoint_in_range(u, lo1, hi1)
49 || hb_codepoint_in_range(u, lo2, hi2)
50 || hb_codepoint_in_range(u, lo3, hi3);
53 return hb_codepoint_in_range(u, lo1, hi1)
54 || hb_codepoint_in_range(u, lo2, hi2)
55 || hb_codepoint_in_range(u, lo3, hi3);
51 56 } }
52 57
53 #define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \
54 ((const char *) s)[1], \
55 ((const char *) s)[2], \
56 ((const char *) s)[3]))
58 /* ASCII tag/character handling */
59
60 static INLINE hb_bool_t ISALPHA (unsigned char c)
61 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); }
62 static INLINE hb_bool_t ISALNUM (unsigned char c)
63 { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); }
64 static INLINE hb_bool_t ISSPACE (unsigned char c)
65 { return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; }
66 static INLINE unsigned char TOUPPER (unsigned char c)
67 { return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; }
68 static INLINE unsigned char TOLOWER (unsigned char c)
69 { return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
70
71 #define HB_TAG_CHAR4(s) (HB_TAG(((const char *)s)[0], \
72 ((const char *)s)[1], \
73 ((const char *)s)[2], \
74 ((const char *)s)[3]))
75
76 /*
77 XXX:must be in sync with the "official" harfbuzz API
78 HB_SEGMENT_PROPERTIES_DEFAULT in hb-buffer.h
79 */
80 #define HB_SEGMENT_PROPERTIES_DEFAULT_INIT(x) \
81 (x).direction=HB_DIRECTION_INVALID; \
82 (x).script=HB_SCRIPT_INVALID; \
83 (x).language=HB_LANGUAGE_INVALID; \
84 (x).reserved1=NULL; \
85 (x).reserved2=NULL;
57 86 #endif #endif
File hb-set.h changed (mode: 100644) (index bafdae9..2164c1a)
36 36 HB_BEGIN_DECLS HB_BEGIN_DECLS
37 37
38 38
39 /*
40 * Since: 0.9.21
41 */
39 42 #define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1) #define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
40 43
41 44 typedef struct hb_set_t hb_set_t; typedef struct hb_set_t hb_set_t;
42 45
43 46
44 hb_set_t *
47 HB_EXTERN hb_set_t *
45 48 hb_set_create (void); hb_set_create (void);
46 49
47 hb_set_t *
50 HB_EXTERN hb_set_t *
48 51 hb_set_get_empty (void); hb_set_get_empty (void);
49 52
50 hb_set_t *
53 HB_EXTERN hb_set_t *
51 54 hb_set_reference (hb_set_t *set); hb_set_reference (hb_set_t *set);
52 55
53 void
56 HB_EXTERN void
54 57 hb_set_destroy (hb_set_t *set); hb_set_destroy (hb_set_t *set);
55 58
56 hb_bool_t
59 HB_EXTERN hb_bool_t
57 60 hb_set_set_user_data (hb_set_t *set, hb_set_set_user_data (hb_set_t *set,
58 61 hb_user_data_key_t *key, hb_user_data_key_t *key,
59 62 void * data, void * data,
60 63 hb_destroy_func_t destroy, hb_destroy_func_t destroy,
61 64 hb_bool_t replace); hb_bool_t replace);
62 65
63 void *
66 HB_EXTERN void *
64 67 hb_set_get_user_data (hb_set_t *set, hb_set_get_user_data (hb_set_t *set,
65 68 hb_user_data_key_t *key); hb_user_data_key_t *key);
66 69
67 70
68 71 /* Returns false if allocation has failed before */ /* Returns false if allocation has failed before */
69 hb_bool_t
72 HB_EXTERN hb_bool_t
70 73 hb_set_allocation_successful (const hb_set_t *set); hb_set_allocation_successful (const hb_set_t *set);
71 74
72 void
75 HB_EXTERN void
73 76 hb_set_clear (hb_set_t *set); hb_set_clear (hb_set_t *set);
74 77
75 hb_bool_t
78 HB_EXTERN hb_bool_t
76 79 hb_set_is_empty (const hb_set_t *set); hb_set_is_empty (const hb_set_t *set);
77 80
78 hb_bool_t
81 HB_EXTERN hb_bool_t
79 82 hb_set_has (const hb_set_t *set, hb_set_has (const hb_set_t *set,
80 83 hb_codepoint_t codepoint); hb_codepoint_t codepoint);
81 84
82 85 /* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1 /* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1
83 86 * which we will use as a sentinel. */ * which we will use as a sentinel. */
84 void
87 HB_EXTERN void
85 88 hb_set_add (hb_set_t *set, hb_set_add (hb_set_t *set,
86 89 hb_codepoint_t codepoint); hb_codepoint_t codepoint);
87 90
88 void
91 HB_EXTERN void
89 92 hb_set_add_range (hb_set_t *set, hb_set_add_range (hb_set_t *set,
90 93 hb_codepoint_t first, hb_codepoint_t first,
91 94 hb_codepoint_t last); hb_codepoint_t last);
92 95
93 void
96 HB_EXTERN void
94 97 hb_set_del (hb_set_t *set, hb_set_del (hb_set_t *set,
95 98 hb_codepoint_t codepoint); hb_codepoint_t codepoint);
96 99
97 void
100 HB_EXTERN void
98 101 hb_set_del_range (hb_set_t *set, hb_set_del_range (hb_set_t *set,
99 102 hb_codepoint_t first, hb_codepoint_t first,
100 103 hb_codepoint_t last); hb_codepoint_t last);
101 104
102 hb_bool_t
105 HB_EXTERN hb_bool_t
103 106 hb_set_is_equal (const hb_set_t *set, hb_set_is_equal (const hb_set_t *set,
104 107 const hb_set_t *other); const hb_set_t *other);
105 108
106 void
109 HB_EXTERN void
107 110 hb_set_set (hb_set_t *set, hb_set_set (hb_set_t *set,
108 111 const hb_set_t *other); const hb_set_t *other);
109 112
110 void
113 HB_EXTERN void
111 114 hb_set_union (hb_set_t *set, hb_set_union (hb_set_t *set,
112 115 const hb_set_t *other); const hb_set_t *other);
113 116
114 void
117 HB_EXTERN void
115 118 hb_set_intersect (hb_set_t *set, hb_set_intersect (hb_set_t *set,
116 119 const hb_set_t *other); const hb_set_t *other);
117 120
118 void
121 HB_EXTERN void
119 122 hb_set_subtract (hb_set_t *set, hb_set_subtract (hb_set_t *set,
120 123 const hb_set_t *other); const hb_set_t *other);
121 124
122 void
125 HB_EXTERN void
123 126 hb_set_symmetric_difference (hb_set_t *set, hb_set_symmetric_difference (hb_set_t *set,
124 127 const hb_set_t *other); const hb_set_t *other);
125 128
126 void
129 HB_EXTERN void
127 130 hb_set_invert (hb_set_t *set); hb_set_invert (hb_set_t *set);
128 131
129 unsigned int
132 HB_EXTERN unsigned int
130 133 hb_set_get_population (const hb_set_t *set); hb_set_get_population (const hb_set_t *set);
131 134
132 135 /* Returns -1 if set empty. */ /* Returns -1 if set empty. */
133 hb_codepoint_t
136 HB_EXTERN hb_codepoint_t
134 137 hb_set_get_min (const hb_set_t *set); hb_set_get_min (const hb_set_t *set);
135 138
136 139 /* Returns -1 if set empty. */ /* Returns -1 if set empty. */
137 hb_codepoint_t
140 HB_EXTERN hb_codepoint_t
138 141 hb_set_get_max (const hb_set_t *set); hb_set_get_max (const hb_set_t *set);
139 142
140 143 /* Pass -1 in to get started. */ /* Pass -1 in to get started. */
141 hb_bool_t
144 HB_EXTERN hb_bool_t
142 145 hb_set_next (const hb_set_t *set, hb_set_next (const hb_set_t *set,
143 146 hb_codepoint_t *codepoint); hb_codepoint_t *codepoint);
144 147
145 148 /* Pass -1 for first and last to get started. */ /* Pass -1 for first and last to get started. */
146 hb_bool_t
149 HB_EXTERN hb_bool_t
147 150 hb_set_next_range (const hb_set_t *set, hb_set_next_range (const hb_set_t *set,
148 151 hb_codepoint_t *first, hb_codepoint_t *first,
149 152 hb_codepoint_t *last); hb_codepoint_t *last);
File hb-shape-plan-private.h changed (mode: 100644) (index 1a90aed..62ff962)
1 1 #ifndef HB_SHAPE_PLAN_PRIVATE_H #ifndef HB_SHAPE_PLAN_PRIVATE_H
2 2 #define HB_SHAPE_PLAN_PRIVATE_H #define HB_SHAPE_PLAN_PRIVATE_H
3 struct hb_shape_plan_t
4 {
5 atomic_int32_t ref_cnt;
3 struct hb_shape_plan_t {
4 atomic_int32_t ref_cnt;
6 5
7 hb_bool_t default_shaper_list;
8 hb_face_t *face;
9 hb_segment_properties_t props;
6 hb_bool_t default_shaper_list;
7 hb_face_t *face;
8 hb_segment_properties_t props;
10 9
11 hb_shape_func_t *shaper_func;
12 char *shaper_name;
10 hb_shape_func_t *shaper_func;
11 char *shaper_name;
13 12
14 struct hb_shaper_data_t shaper_data;
13 struct hb_shaper_data_t shaper_data;
15 14 }; };
16 15
17 16 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
18 17 struct hb_graphite2_shaper_shape_plan_data_t; struct hb_graphite2_shaper_shape_plan_data_t;
19 struct hb_graphite2_shaper_shape_plan_data_t *
20 hb_graphite2_shaper_shape_plan_data_create(hb_shape_plan_t *shape_plan,
21 const hb_feature_t *user_features,
22 unsigned num_user_features);
23 void
24 hb_graphite2_shaper_shape_plan_data_destroy(
25 struct hb_graphite2_shaper_shape_plan_data_t *data);
18 struct hb_graphite2_shaper_shape_plan_data_t
19 *hb_graphite2_shaper_shape_plan_data_create(hb_shape_plan_t * shape_plan,
20 const hb_feature_t *
21 user_features,
22 unsigned num_user_features);
23 void hb_graphite2_shaper_shape_plan_data_destroy(struct
24 hb_graphite2_shaper_shape_plan_data_t
25 *data);
26 26 #endif #endif
27 27 #ifdef HAVE_OT #ifdef HAVE_OT
28 28 struct hb_ot_shaper_shape_plan_data_t; struct hb_ot_shaper_shape_plan_data_t;
29 struct hb_ot_shaper_shape_plan_data_t *
30 hb_ot_shaper_shape_plan_data_create(hb_shape_plan_t *shape_plan,
31 const hb_feature_t *user_features,
32 unsigned num_user_features);
33 void
34 hb_ot_shaper_shape_plan_data_destroy(
35 struct hb_ot_shaper_shape_plan_data_t *data);
29 struct hb_ot_shaper_shape_plan_data_t
30 *hb_ot_shaper_shape_plan_data_create(hb_shape_plan_t * shape_plan,
31 const hb_feature_t * user_features,
32 unsigned num_user_features);
33 void hb_ot_shaper_shape_plan_data_destroy(struct hb_ot_shaper_shape_plan_data_t
34 *data);
36 35 #endif #endif
37 36 struct hb_fallback_shaper_shape_plan_data_t; struct hb_fallback_shaper_shape_plan_data_t;
38 struct hb_fallback_shaper_shape_plan_data_t *
39 hb_fallback_shaper_shape_plan_data_create(hb_shape_plan_t *shape_plan,
40 const hb_feature_t *user_features,
41 unsigned num_user_features);
42 void
43 hb_fallback_shaper_shape_plan_data_destroy(
44 struct hb_fallback_shaper_shape_plan_data_t *data);
37 struct hb_fallback_shaper_shape_plan_data_t
38 *hb_fallback_shaper_shape_plan_data_create(hb_shape_plan_t * shape_plan,
39 const hb_feature_t *
40 user_features,
41 unsigned num_user_features);
42 void hb_fallback_shaper_shape_plan_data_destroy(struct
43 hb_fallback_shaper_shape_plan_data_t
44 *data);
45 45 #endif #endif
File hb-shape-plan.c changed (mode: 100644) (index 929804a..11f405c)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <stddef.h> #include <stddef.h>
5 7 #include <assert.h> #include <assert.h>
6 8
 
16 18 #include "hb-font-private.h" #include "hb-font-private.h"
17 19 #include "hb-shape-plan-private.h" #include "hb-shape-plan-private.h"
18 20
21 /*XXX:should go in lib "global init"*/
19 22 static hb_shape_plan_t hb_shape_plan_nil = { static hb_shape_plan_t hb_shape_plan_nil = {
20 REF_CNT_INVALID_VAL,
21 TRUE,//default_shaper_list
22 NULL,//face
23 HB_SEGMENT_PROPERTIES_DEFAULT,//props
24 NULL,//shaper_func
25 NULL,//shaper_name
26 {
23 REF_CNT_INVALID_VAL,
24 TRUE, /*default_shaper_list */
25 NULL, /*face */
26 HB_SEGMENT_PROPERTIES_DEFAULT, /*props */
27 NULL, /*shaper_func */
28 NULL, /*shaper_name */
29 {
27 30 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
28 HB_SHAPER_DATA_INVALID,
31 HB_SHAPER_DATA_INVALID,
29 32 #endif #endif
30 33 #ifdef HAVE_OT #ifdef HAVE_OT
31 HB_SHAPER_DATA_INVALID,
34 HB_SHAPER_DATA_INVALID,
32 35 #endif #endif
33 HB_SHAPER_DATA_INVALID//fallback
34 }
36 HB_SHAPER_DATA_INVALID /*fallback */
37 }
35 38 }; };
36 39
37 //TODO no user-feature caching for now.
38 struct hb_shape_plan_proposal_t
39 {
40 const hb_segment_properties_t props;
41 const char * const *shaper_list;
42 hb_shape_func_t *shaper_func;
40 /*TODO no user-feature caching for now.*/
41 struct hb_shape_plan_proposal_t {
42 const hb_segment_properties_t props;
43 const char *const *shaper_list;
44 hb_shape_func_t *shaper_func;
43 45 }; };
44 46
45 hb_shape_plan_t *
46 hb_shape_plan_get_empty(void)
47 hb_shape_plan_t *hb_shape_plan_get_empty(void)
47 48 { {
48 return &hb_shape_plan_nil;
49 return &hb_shape_plan_nil;
49 50 } }
50 51
51 52 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
52 static inline hb_bool_t
53 hb_graphite2_shaper_face_data_ensure(hb_face_t *face)
53 static INLINE hb_bool_t hb_graphite2_shaper_face_data_ensure(hb_face_t * face)
54 54 { {
55 while (1) {
56 struct hb_graphite2_shaper_face_data_t *data = hb_atomic_ptr_get(
57 &face->shaper_data.graphite2);
58 if (data)
59 return !HB_SHAPER_DATA_IS_INVALID(data);
55 while (1) {
56 struct hb_graphite2_shaper_face_data_t *data;
57 void *expected;
58
59 data = hb_atomic_ptr_get(&face->shaper_data.graphite2);
60 if (data)
61 return !HB_SHAPER_DATA_IS_INVALID(data);
60 62
61 if (!data)
62 data = hb_graphite2_shaper_face_data_create(face);
63 if (!data)
64 data = hb_graphite2_shaper_face_data_create(face);
63 65
64 if (!data)
65 data = HB_SHAPER_DATA_INVALID;
66 if (!data)
67 data = HB_SHAPER_DATA_INVALID;
66 68
67 void *expected = NULL;
68 if (hb_atomic_ptr_cmpexch(&face->shaper_data.graphite2, &expected, &data))
69 return !HB_SHAPER_DATA_IS_INVALID(data);
69 expected = NULL;
70 if (hb_atomic_ptr_cmpexch
71 (&face->shaper_data.graphite2, &expected, &data))
72 return !HB_SHAPER_DATA_IS_INVALID(data);
70 73
71 if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED)
72 hb_graphite2_shaper_face_data_destroy(data);
73 }
74 if (data != HB_SHAPER_DATA_INVALID
75 && data != HB_SHAPER_DATA_SUCCEEDED)
76 hb_graphite2_shaper_face_data_destroy(data);
77 }
74 78 } }
75 79
76 static inline hb_bool_t
77 hb_graphite2_shaper_font_data_ensure(hb_font_t *font)
80 static INLINE hb_bool_t hb_graphite2_shaper_font_data_ensure(hb_font_t * font)
78 81 { {
79 while (1) {
80 struct hb_graphite2_shaper_font_data_t *data = hb_atomic_ptr_get(
81 &font->shaper_data.graphite2);
82 if (data)
83 return !HB_SHAPER_DATA_IS_INVALID(data);
82 while (1) {
83 struct hb_graphite2_shaper_font_data_t *data;
84 void *expected;
85
86 data = hb_atomic_ptr_get(&font->shaper_data.graphite2);
87 if (data)
88 return !HB_SHAPER_DATA_IS_INVALID(data);
84 89
85 if (!data)
86 data = hb_graphite2_shaper_font_data_create(font);
90 if (!data)
91 data = hb_graphite2_shaper_font_data_create(font);
87 92
88 if (!data)
89 data = HB_SHAPER_DATA_INVALID;
93 if (!data)
94 data = HB_SHAPER_DATA_INVALID;
90 95
91 void *expected = NULL;
92 if (hb_atomic_ptr_cmpexch(&font->shaper_data.graphite2, &expected, &data))
93 return !HB_SHAPER_DATA_IS_INVALID(data);
96 expected = NULL;
97 if (hb_atomic_ptr_cmpexch
98 (&font->shaper_data.graphite2, &expected, &data))
99 return !HB_SHAPER_DATA_IS_INVALID(data);
94 100
95 if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED)
96 hb_graphite2_shaper_font_data_destroy(data);
97 }
101 if (data != HB_SHAPER_DATA_INVALID
102 && data != HB_SHAPER_DATA_SUCCEEDED)
103 hb_graphite2_shaper_font_data_destroy(data);
104 }
98 105 } }
99 106 #endif #endif
100 107
101 108 #ifdef HAVE_OT #ifdef HAVE_OT
102 static inline hb_bool_t
103 hb_ot_shaper_face_data_ensure(hb_face_t *face)
109 static INLINE hb_bool_t hb_ot_shaper_face_data_ensure(hb_face_t * face)
104 110 { {
105 while (1) {
106 struct hb_ot_shaper_face_data_t *data = hb_atomic_ptr_get(
107 &face->shaper_data.ot);
108 if (data)
109 return !HB_SHAPER_DATA_IS_INVALID(data);
111 while (1) {
112 struct hb_ot_shaper_face_data_t *data;
113 void *expected;
110 114
111 if (!data)
112 data = hb_ot_shaper_face_data_create(face);
115 data = hb_atomic_ptr_get(&face->shaper_data.ot);
116 if (data)
117 return !HB_SHAPER_DATA_IS_INVALID(data);
113 118
114 if (!data)
115 data = HB_SHAPER_DATA_INVALID;
119 if (!data)
120 data = hb_ot_shaper_face_data_create(face);
116 121
117 void *expected = NULL;
118 if (hb_atomic_ptr_cmpexch(&face->shaper_data.ot, &expected, &data))
119 return !HB_SHAPER_DATA_IS_INVALID(data);
122 if (!data)
123 data = HB_SHAPER_DATA_INVALID;
120 124
121 if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED)
122 hb_ot_shaper_face_data_destroy(data);
123 }
125 expected = NULL;
126 if (hb_atomic_ptr_cmpexch
127 (&face->shaper_data.ot, &expected, &data))
128 return !HB_SHAPER_DATA_IS_INVALID(data);
129
130 if (data != HB_SHAPER_DATA_INVALID
131 && data != HB_SHAPER_DATA_SUCCEEDED)
132 hb_ot_shaper_face_data_destroy(data);
133 }
124 134 } }
125 135
126 static inline hb_bool_t
127 hb_ot_shaper_font_data_ensure(hb_font_t *font)
136 static INLINE hb_bool_t hb_ot_shaper_font_data_ensure(hb_font_t * font)
128 137 { {
129 while (1) {
130 struct hb_ot_shaper_font_data_t *data = hb_atomic_ptr_get(
131 &font->shaper_data.ot);
132 if (data)
133 return !HB_SHAPER_DATA_IS_INVALID(data);
138 while (1) {
139 struct hb_ot_shaper_font_data_t *data;
140 void *expected;
141
142 data = hb_atomic_ptr_get(&font->shaper_data.ot);
143 if (data)
144 return !HB_SHAPER_DATA_IS_INVALID(data);
134 145
135 if (!data)
136 data = hb_ot_shaper_font_data_create(font);
146 if (!data)
147 data = hb_ot_shaper_font_data_create(font);
137 148
138 if (!data)
139 data = HB_SHAPER_DATA_INVALID;
149 if (!data)
150 data = HB_SHAPER_DATA_INVALID;
140 151
141 void *expected = NULL;
142 if (hb_atomic_ptr_cmpexch(&font->shaper_data.ot, &expected, &data))
143 return !HB_SHAPER_DATA_IS_INVALID(data);
152 expected = NULL;
153 if (hb_atomic_ptr_cmpexch
154 (&font->shaper_data.ot, &expected, &data))
155 return !HB_SHAPER_DATA_IS_INVALID(data);
144 156
145 if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED)
146 hb_ot_shaper_font_data_destroy(data);
147 }
157 if (data != HB_SHAPER_DATA_INVALID
158 && data != HB_SHAPER_DATA_SUCCEEDED)
159 hb_ot_shaper_font_data_destroy(data);
160 }
148 161 } }
149 162 #endif #endif
150 163
151 static inline hb_bool_t
152 hb_fallback_shaper_face_data_ensure(hb_face_t *face)
164 static INLINE hb_bool_t hb_fallback_shaper_face_data_ensure(hb_face_t * face)
153 165 { {
154 while (1) {
155 struct hb_fallback_shaper_face_data_t *data = hb_atomic_ptr_get(
156 &face->shaper_data.fallback);
157 if (data)
158 return !HB_SHAPER_DATA_IS_INVALID(data);
166 while (1) {
167 struct hb_fallback_shaper_face_data_t *data;
168 void *expected;
159 169
160 if (!data)
161 data = hb_fallback_shaper_face_data_create(face);
170 data = hb_atomic_ptr_get(&face->shaper_data.fallback);
171 if (data)
172 return !HB_SHAPER_DATA_IS_INVALID(data);
162 173
163 if (!data)
164 data = HB_SHAPER_DATA_INVALID;
174 if (!data)
175 data = hb_fallback_shaper_face_data_create(face);
165 176
166 void *expected = NULL;
167 if (hb_atomic_ptr_cmpexch(&face->shaper_data.fallback, &expected, &data))
168 return !HB_SHAPER_DATA_IS_INVALID(data);
177 if (!data)
178 data = HB_SHAPER_DATA_INVALID;
169 179
170 if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED)
171 hb_fallback_shaper_face_data_destroy(data);
172 }
180 expected = NULL;
181 if (hb_atomic_ptr_cmpexch
182 (&face->shaper_data.fallback, &expected, &data))
183 return !HB_SHAPER_DATA_IS_INVALID(data);
184
185 if (data != HB_SHAPER_DATA_INVALID
186 && data != HB_SHAPER_DATA_SUCCEEDED)
187 hb_fallback_shaper_face_data_destroy(data);
188 }
173 189 } }
174 190
175 static inline hb_bool_t
176 hb_fallback_shaper_font_data_ensure(hb_font_t *font)
191 static INLINE hb_bool_t hb_fallback_shaper_font_data_ensure(hb_font_t * font)
177 192 { {
178 while (1) {
179 struct hb_fallback_shaper_font_data_t *data = hb_atomic_ptr_get(
180 &font->shaper_data.fallback);
181 if (data)
182 return !HB_SHAPER_DATA_IS_INVALID(data);
193 while (1) {
194 struct hb_fallback_shaper_font_data_t *data;
195 void *expected;
196
197 data = hb_atomic_ptr_get(&font->shaper_data.fallback);
198 if (data)
199 return !HB_SHAPER_DATA_IS_INVALID(data);
183 200
184 if (!data)
185 data = hb_fallback_shaper_font_data_create(font);
201 if (!data)
202 data = hb_fallback_shaper_font_data_create(font);
186 203
187 if (!data)
188 data = HB_SHAPER_DATA_INVALID;
204 if (!data)
205 data = HB_SHAPER_DATA_INVALID;
189 206
190 void *expected = NULL;
191 if (hb_atomic_ptr_cmpexch(&font->shaper_data.fallback, &expected, &data))
192 return !HB_SHAPER_DATA_IS_INVALID(data);
207 expected = NULL;
208 if (hb_atomic_ptr_cmpexch
209 (&font->shaper_data.fallback, &expected, &data))
210 return !HB_SHAPER_DATA_IS_INVALID(data);
193 211
194 if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED)
195 hb_fallback_shaper_font_data_destroy(data);
196 }
212 if (data != HB_SHAPER_DATA_INVALID
213 && data != HB_SHAPER_DATA_SUCCEEDED)
214 hb_fallback_shaper_font_data_destroy(data);
215 }
197 216 } }
198 217
199 static void
200 hb_shape_plan_plan(hb_shape_plan_t *shape_plan,
201 const hb_feature_t *user_features,
202 unsigned num_user_features,
203 const char * const *shaper_list)
218 static void hb_shape_plan_plan(hb_shape_plan_t * shape_plan,
219 const hb_feature_t * user_features,
220 unsigned num_user_features,
221 const char *const *shaper_list)
204 222 { {
205 struct hb_shaper_pair_t *shapers = hb_shapers_get();
223 struct hb_shaper_pair_t *shapers;
224 unsigned i;
206 225
207 if (!shaper_list) {
208 for (unsigned i = 0; i < HB_SHAPERS_COUNT; ++i)
209 if (0)
210 ;
226 shapers = hb_shapers_get();
227 if (!shaper_list) {
228 for (i = 0; i < HB_SHAPERS_COUNT; ++i)
229 if (0) ;
211 230 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
212 else if (shapers[i].func == hb_graphite2_shape) {
213 if (hb_graphite2_shaper_face_data_ensure(shape_plan->face)) {
214 shape_plan->shaper_data.graphite2 =
215 hb_graphite2_shaper_shape_plan_data_create(shape_plan,
216 user_features,
217 num_user_features);
218 shape_plan->shaper_func = hb_graphite2_shape;
219 shape_plan->shaper_name ="graphite2";
220 return;
221 }
222 }
231 else if (shapers[i].func == hb_graphite2_shape) {
232 if (hb_graphite2_shaper_face_data_ensure
233 (shape_plan->face)) {
234 shape_plan->shaper_data.graphite2 =
235 hb_graphite2_shaper_shape_plan_data_create
236 (shape_plan, user_features,
237 num_user_features);
238 shape_plan->shaper_func =
239 hb_graphite2_shape;
240 shape_plan->shaper_name = "graphite2";
241 return;
242 }
243 }
223 244 #endif #endif
224 245 #ifdef HAVE_OT #ifdef HAVE_OT
225 else if (shapers[i].func == hb_ot_shape) {
226 if (hb_ot_shaper_face_data_ensure(shape_plan->face)) {
227 shape_plan->shaper_data.ot = hb_ot_shaper_shape_plan_data_create(
228 shape_plan,
229 user_features,
230 num_user_features);
231 shape_plan->shaper_func = hb_ot_shape;
232 shape_plan->shaper_name ="ot";
233 return;
234 }
235 }
246 else if (shapers[i].func == hb_ot_shape) {
247 if (hb_ot_shaper_face_data_ensure
248 (shape_plan->face)) {
249 shape_plan->shaper_data.ot =
250 hb_ot_shaper_shape_plan_data_create
251 (shape_plan, user_features,
252 num_user_features);
253 shape_plan->shaper_func = hb_ot_shape;
254 shape_plan->shaper_name = "ot";
255 return;
256 }
257 }
236 258 #endif #endif
237 else if (shapers[i].func == hb_fallback_shape) {
238 if (hb_fallback_shaper_face_data_ensure(shape_plan->face)) {
239 shape_plan->shaper_data.fallback =
240 hb_fallback_shaper_shape_plan_data_create(shape_plan,
241 user_features,
242 num_user_features);
243 shape_plan->shaper_func = hb_fallback_shape;
244 shape_plan->shaper_name = "fallback";
245 return;
246 }
247 }
248 } else {
249 for (; *shaper_list; ++shaper_list)
250 if (0)
251 ;
259 else if (shapers[i].func == hb_fallback_shape) {
260 if (hb_fallback_shaper_face_data_ensure
261 (shape_plan->face)) {
262 shape_plan->shaper_data.fallback =
263 hb_fallback_shaper_shape_plan_data_create
264 (shape_plan, user_features,
265 num_user_features);
266 shape_plan->shaper_func =
267 hb_fallback_shape;
268 shape_plan->shaper_name = "fallback";
269 return;
270 }
271 }
272 } else {
273 for (; *shaper_list; ++shaper_list)
274 if (0) ;
252 275 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
253 else if (0 == strcmp(*shaper_list, "graphite2")) {
254 if (hb_graphite2_shaper_face_data_ensure(shape_plan->face)) {
255 shape_plan->shaper_data.graphite2 =
256 hb_graphite2_shaper_shape_plan_data_create(shape_plan,
257 user_features,
258 num_user_features);
259 shape_plan->shaper_func = hb_graphite2_shape;
260 shape_plan->shaper_name = "graphite2";
261 return;
262 }
263 }
276 else if (0 == strcmp(*shaper_list, "graphite2")) {
277 if (hb_graphite2_shaper_face_data_ensure
278 (shape_plan->face)) {
279 shape_plan->shaper_data.graphite2 =
280 hb_graphite2_shaper_shape_plan_data_create
281 (shape_plan, user_features,
282 num_user_features);
283 shape_plan->shaper_func =
284 hb_graphite2_shape;
285 shape_plan->shaper_name = "graphite2";
286 return;
287 }
288 }
264 289 #endif #endif
265 290 #ifdef HAVE_OT #ifdef HAVE_OT
266 else if (0 == strcmp(*shaper_list, "ot")) {
267 if (hb_ot_shaper_face_data_ensure(shape_plan->face)) {
268 shape_plan->shaper_data.ot = hb_ot_shaper_shape_plan_data_create(
269 shape_plan,
270 user_features,
271 num_user_features);
272 shape_plan->shaper_func = hb_ot_shape;
273 shape_plan->shaper_name = "ot";
274 return;
275 }
276 }
291 else if (0 == strcmp(*shaper_list, "ot")) {
292 if (hb_ot_shaper_face_data_ensure
293 (shape_plan->face)) {
294 shape_plan->shaper_data.ot =
295 hb_ot_shaper_shape_plan_data_create
296 (shape_plan, user_features,
297 num_user_features);
298 shape_plan->shaper_func = hb_ot_shape;
299 shape_plan->shaper_name = "ot";
300 return;
301 }
302 }
277 303 #endif #endif
278 else if (0 == strcmp(*shaper_list, "fallback")) {
279 if (hb_fallback_shaper_face_data_ensure(shape_plan->face)) {
280 shape_plan->shaper_data.fallback =
281 hb_fallback_shaper_shape_plan_data_create(shape_plan,
282 user_features,
283 num_user_features);
284 shape_plan->shaper_func = hb_fallback_shape;
285 shape_plan->shaper_name = "fallback";
286 return;
287 }
288 }
289 }
304 else if (0 == strcmp(*shaper_list, "fallback")) {
305 if (hb_fallback_shaper_face_data_ensure
306 (shape_plan->face)) {
307 shape_plan->shaper_data.fallback =
308 hb_fallback_shaper_shape_plan_data_create
309 (shape_plan, user_features,
310 num_user_features);
311 shape_plan->shaper_func =
312 hb_fallback_shape;
313 shape_plan->shaper_name = "fallback";
314 return;
315 }
316 }
317 }
290 318 } }
291 319
292 hb_shape_plan_t *
293 hb_shape_plan_create(hb_face_t *face,
294 const hb_segment_properties_t *props,
295 const hb_feature_t *user_features,
296 unsigned int num_user_features,
297 const char * const *shaper_list)
320 hb_shape_plan_t *hb_shape_plan_create(hb_face_t * face,
321 const hb_segment_properties_t * props,
322 const hb_feature_t * user_features,
323 unsigned int num_user_features,
324 const char *const *shaper_list)
298 325 { {
299 assert(props->direction != HB_DIRECTION_INVALID);
326 hb_shape_plan_t *shape_plan;
300 327
301 if (!face)
302 face = hb_face_get_empty();
328 assert(props->direction != HB_DIRECTION_INVALID);
303 329
304 if (!props || hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
305 return hb_shape_plan_get_empty();
330 if (!face)
331 face = hb_face_get_empty();
306 332
307 hb_shape_plan_t *shape_plan = calloc(1, sizeof(*shape_plan));
308 if (!shape_plan)
309 return hb_shape_plan_get_empty();
310 hb_atomic_int32_set(&shape_plan->ref_cnt, 1);
333 if (!props
334 || hb_atomic_int32_get(&face->ref_cnt) == REF_CNT_INVALID_VAL)
335 return hb_shape_plan_get_empty();
311 336
312 shape_plan->default_shaper_list = shaper_list == NULL;
313 hb_face_make_immutable(face);
314 shape_plan->face = hb_face_reference(face);
315 shape_plan->props = *props;
337 shape_plan = calloc(1, sizeof(*shape_plan));
338 if (!shape_plan)
339 return hb_shape_plan_get_empty();
340 hb_atomic_int32_set(&shape_plan->ref_cnt, 1);
316 341
317 hb_shape_plan_plan(shape_plan, user_features, num_user_features, shaper_list);
318 return shape_plan;
342 shape_plan->default_shaper_list = shaper_list == NULL;
343 hb_face_make_immutable(face);
344 shape_plan->face = hb_face_reference(face);
345 shape_plan->props = *props;
346
347 hb_shape_plan_plan(shape_plan, user_features, num_user_features,
348 shaper_list);
349 return shape_plan;
319 350 } }
320 351
321 static hb_bool_t
322 hb_shape_plan_matches(hb_shape_plan_t *shape_plan,
323 struct hb_shape_plan_proposal_t *proposal)
352 static hb_bool_t hb_shape_plan_matches(hb_shape_plan_t * shape_plan,
353 struct hb_shape_plan_proposal_t
354 *proposal)
324 355 { {
325 return hb_segment_properties_equal(&shape_plan->props, &proposal->props) &&
326 ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
327 (shape_plan->shaper_func == proposal->shaper_func));
356 return hb_segment_properties_equal(&shape_plan->props, &proposal->props)
357 &&
358 ((shape_plan->default_shaper_list && proposal->shaper_list == NULL)
359 || (shape_plan->shaper_func == proposal->shaper_func));
328 360 } }
329 361
330 hb_shape_plan_t *
331 hb_shape_plan_reference(hb_shape_plan_t *shape_plan)
362 hb_shape_plan_t *hb_shape_plan_reference(hb_shape_plan_t * shape_plan)
332 363 { {
333 if (hb_atomic_int32_get(&shape_plan->ref_cnt) != REF_CNT_INVALID_VAL)
334 hb_atomic_int32_add(&shape_plan->ref_cnt, 1);
335 return shape_plan;
364 if (hb_atomic_int32_get(&shape_plan->ref_cnt) != REF_CNT_INVALID_VAL)
365 hb_atomic_int32_add(&shape_plan->ref_cnt, 1);
366 return shape_plan;
336 367 } }
337 368
338 void
339 hb_shape_plan_destroy(hb_shape_plan_t *shape_plan)
369 void hb_shape_plan_destroy(hb_shape_plan_t * shape_plan)
340 370 { {
341 if (!shape_plan)
342 return;
343 if (hb_atomic_int32_get(&shape_plan->ref_cnt) == REF_CNT_INVALID_VAL)
344 return;
345 hb_atomic_int32_add(&shape_plan->ref_cnt, -1);
346 if (hb_atomic_int32_get(&shape_plan->ref_cnt) > 0)
347 return;
348 hb_atomic_int32_set(&shape_plan->ref_cnt, REF_CNT_INVALID_VAL);
371 if (!shape_plan)
372 return;
373 if (hb_atomic_int32_get(&shape_plan->ref_cnt) == REF_CNT_INVALID_VAL)
374 return;
375 hb_atomic_int32_add(&shape_plan->ref_cnt, -1);
376 if (hb_atomic_int32_get(&shape_plan->ref_cnt) > 0)
377 return;
378 hb_atomic_int32_set(&shape_plan->ref_cnt, REF_CNT_INVALID_VAL);
349 379
350 380 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
351 if (shape_plan->shaper_data.graphite2 &&
352 shape_plan->shaper_data.graphite2 != HB_SHAPER_DATA_INVALID &&
353 shape_plan->shaper_data.graphite2 != HB_SHAPER_DATA_SUCCEEDED)
354 hb_graphite2_shaper_shape_plan_data_destroy(
355 shape_plan->shaper_data.graphite2);
381 if (shape_plan->shaper_data.graphite2
382 && shape_plan->shaper_data.graphite2 != HB_SHAPER_DATA_INVALID
383 && shape_plan->shaper_data.graphite2 != HB_SHAPER_DATA_SUCCEEDED)
384 hb_graphite2_shaper_shape_plan_data_destroy
385 (shape_plan->shaper_data.graphite2);
356 386 #endif #endif
357 387 #ifdef HAVE_OT #ifdef HAVE_OT
358 if (shape_plan->shaper_data.ot &&
359 shape_plan->shaper_data.ot != HB_SHAPER_DATA_INVALID &&
360 shape_plan->shaper_data.ot != HB_SHAPER_DATA_SUCCEEDED)
361 hb_ot_shaper_shape_plan_data_destroy(shape_plan->shaper_data.ot);
388 if (shape_plan->shaper_data.ot
389 && shape_plan->shaper_data.ot != HB_SHAPER_DATA_INVALID
390 && shape_plan->shaper_data.ot != HB_SHAPER_DATA_SUCCEEDED)
391 hb_ot_shaper_shape_plan_data_destroy(shape_plan->shaper_data.
392 ot);
362 393 #endif #endif
363 if (shape_plan->shaper_data.fallback &&
364 shape_plan->shaper_data.fallback != HB_SHAPER_DATA_INVALID &&
365 shape_plan->shaper_data.fallback != HB_SHAPER_DATA_SUCCEEDED)
366 hb_fallback_shaper_shape_plan_data_destroy(
367 shape_plan->shaper_data.fallback);
368
369 hb_face_destroy(shape_plan->face);
370 free(shape_plan);
394 if (shape_plan->shaper_data.fallback
395 && shape_plan->shaper_data.fallback != HB_SHAPER_DATA_INVALID
396 && shape_plan->shaper_data.fallback != HB_SHAPER_DATA_SUCCEEDED)
397 hb_fallback_shaper_shape_plan_data_destroy
398 (shape_plan->shaper_data.fallback);
399
400 hb_face_destroy(shape_plan->face);
401 free(shape_plan);
371 402 } }
372 403
373 hb_shape_plan_t *
374 hb_shape_plan_create_cached(hb_face_t *face,
375 const hb_segment_properties_t *props,
376 const hb_feature_t *user_features,
377 unsigned int num_user_features,
378 const char * const *shaper_list)
404 hb_shape_plan_t *hb_shape_plan_create_cached(hb_face_t * face,
405 const hb_segment_properties_t *
406 props,
407 const hb_feature_t * user_features,
408 unsigned int num_user_features,
409 const char *const *shaper_list)
379 410 { {
380 if (num_user_features)
381 return hb_shape_plan_create(face, props, user_features, num_user_features,
382 shaper_list);
383
384 struct hb_shape_plan_proposal_t proposal = {
385 *props,
386 shaper_list,
387 NULL
388 };
389
390 if (shaper_list) {
391 //Choose shaper. Adapted from hb_shape_plan_plan().
392 for (const char * const *shaper_item = shaper_list; *shaper_item;
393 shaper_item++)
394 if (0)
395 ;
411 struct hb_shape_plan_proposal_t proposal;
412 const char *const *shaper_item;
413 struct plan_node_t *cached_plan_nodes;
414 hb_shape_plan_t *shape_plan;
415
416 if (num_user_features)
417 return hb_shape_plan_create(face, props, user_features,
418 num_user_features, shaper_list);
419
420 /*XXX:proposal.props = *props;*/
421 memcpy((void*)&proposal.props,(void*)props,sizeof(proposal.props));
422 proposal.shaper_list = shaper_list;
423 proposal.shaper_func = NULL;
424
425 if (shaper_list) {
426 /*Choose shaper. Adapted from hb_shape_plan_plan(). */
427 for (shaper_item = shaper_list; *shaper_item; shaper_item++)
428 if (0) ;
396 429 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
397 else if (0 == strcmp(*shaper_item, "graphite2")) {
398 if (hb_graphite2_shaper_face_data_ensure(face))
399 proposal.shaper_func = hb_graphite2_shape;
400 }
430 else if (0 == strcmp(*shaper_item, "graphite2")) {
431 if (hb_graphite2_shaper_face_data_ensure(face))
432 proposal.shaper_func =
433 hb_graphite2_shape;
434 }
401 435 #endif #endif
402 436 #ifdef HAVE_OT #ifdef HAVE_OT
403 else if (0 == strcmp(*shaper_item, "ot")) {
404 if (hb_ot_shaper_face_data_ensure(face))
405 proposal.shaper_func = hb_ot_shape;
406 }
437 else if (0 == strcmp(*shaper_item, "ot")) {
438 if (hb_ot_shaper_face_data_ensure(face))
439 proposal.shaper_func = hb_ot_shape;
440 }
407 441 #endif #endif
408 else if (0 == strcmp(*shaper_item, "fallback")) {
409 if (hb_fallback_shaper_face_data_ensure(face))
410 proposal.shaper_func = hb_fallback_shape;
411 }
412
413 if (!proposal.shaper_list)
414 return hb_shape_plan_get_empty();
415 }
416
417 struct plan_node_t *cached_plan_nodes = hb_atomic_ptr_get(&face->shape_plans);
418 hb_shape_plan_t *shape_plan;
419 while (1) {
420 for (struct plan_node_t *node = cached_plan_nodes; node; node = node->next)
421 if (hb_shape_plan_matches(node->shape_plan, &proposal))
422 return hb_shape_plan_reference(node->shape_plan);
423
424 //Not found.
425
426 shape_plan = hb_shape_plan_create(face, props, user_features,
427 num_user_features, shaper_list);
428
429 struct plan_node_t *node = calloc(1, sizeof(*node));
430 if (!node)
431 return shape_plan;
432
433 node->shape_plan = shape_plan;
434 node->next = cached_plan_nodes;
435
436 if (hb_atomic_ptr_cmpexch(&face->shape_plans, &cached_plan_nodes, &node))
437 break;
438
439 hb_shape_plan_destroy(shape_plan);
440 free(node);
441 }
442
443 //Release our reference on face.
444 hb_face_destroy(face);
445 return hb_shape_plan_reference(shape_plan);
442 else if (0 == strcmp(*shaper_item, "fallback")) {
443 if (hb_fallback_shaper_face_data_ensure(face))
444 proposal.shaper_func =
445 hb_fallback_shape;
446 }
447
448 if (!proposal.shaper_list)
449 return hb_shape_plan_get_empty();
450 }
451
452 cached_plan_nodes = hb_atomic_ptr_get(&face->shape_plans);
453 while (1) {
454 struct plan_node_t *node;
455
456 for (node = cached_plan_nodes; node; node = node->next)
457 if (hb_shape_plan_matches(node->shape_plan, &proposal))
458 return
459 hb_shape_plan_reference(node->shape_plan);
460
461 /*Not found. */
462
463 shape_plan =
464 hb_shape_plan_create(face, props, user_features,
465 num_user_features, shaper_list);
466 node = calloc(1, sizeof(*node));
467 if (!node)
468 return shape_plan;
469
470 node->shape_plan = shape_plan;
471 node->next = cached_plan_nodes;
472
473 if (hb_atomic_ptr_cmpexch
474 (&face->shape_plans, &cached_plan_nodes, &node))
475 break;
476
477 hb_shape_plan_destroy(shape_plan);
478 free(node);
479 }
480
481 /*Release our reference on face. */
482 hb_face_destroy(face);
483 return hb_shape_plan_reference(shape_plan);
446 484 } }
447 485
448 hb_bool_t
449 hb_shape_plan_execute(hb_shape_plan_t *shape_plan,
450 hb_font_t *font,
451 hb_buffer_t *buffer,
452 const hb_feature_t *features,
453 unsigned num_features)
486 hb_bool_t hb_shape_plan_execute(hb_shape_plan_t * shape_plan, hb_font_t * font,
487 hb_buffer_t * buffer,
488 const hb_feature_t * features,
489 unsigned num_features)
454 490 { {
455 if (hb_atomic_int32_get(&shape_plan->ref_cnt) == REF_CNT_INVALID_VAL
456 || hb_atomic_int32_get(&font->ref_cnt) == REF_CNT_INVALID_VAL
457 || hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
458 return FALSE;
491 if (hb_atomic_int32_get(&shape_plan->ref_cnt) == REF_CNT_INVALID_VAL
492 || hb_atomic_int32_get(&font->ref_cnt) == REF_CNT_INVALID_VAL
493 || hb_atomic_int32_get(&buffer->ref_cnt) == REF_CNT_INVALID_VAL)
494 return FALSE;
459 495
460 assert(shape_plan->face == font->face);
461 assert(hb_segment_properties_equal(&shape_plan->props, &buffer->props));
496 assert(shape_plan->face == font->face);
497 assert(hb_segment_properties_equal(&shape_plan->props, &buffer->props));
462 498
463 if (0)
464 ;
499 if (0) ;
465 500 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
466 else if (shape_plan->shaper_func == hb_graphite2_shape)
467 return shape_plan->shaper_data.graphite2
468 && hb_graphite2_shaper_font_data_ensure(font)
469 && hb_graphite2_shape(shape_plan, font, buffer, features,
470 num_features);
501 else if (shape_plan->shaper_func == hb_graphite2_shape)
502 return shape_plan->shaper_data.graphite2
503 && hb_graphite2_shaper_font_data_ensure(font)
504 && hb_graphite2_shape(shape_plan, font, buffer, features,
505 num_features);
471 506 #endif #endif
472 507 #ifdef HAVE_OT #ifdef HAVE_OT
473 else if (shape_plan->shaper_func == hb_ot_shape)
474 return shape_plan->shaper_data.ot
475 && hb_ot_shaper_font_data_ensure(font)
476 && hb_ot_shape(shape_plan, font, buffer, features, num_features);
508 else if (shape_plan->shaper_func == hb_ot_shape)
509 return shape_plan->shaper_data.ot
510 && hb_ot_shaper_font_data_ensure(font)
511 && hb_ot_shape(shape_plan, font, buffer, features,
512 num_features);
477 513 #endif #endif
478 else if (shape_plan->shaper_func == hb_fallback_shape)
479 return shape_plan->shaper_data.fallback
480 && hb_fallback_shaper_font_data_ensure(font)
481 && hb_fallback_shape(shape_plan, font, buffer, features,
482 num_features);
483 return FALSE;
514 else if (shape_plan->shaper_func == hb_fallback_shape)
515 return shape_plan->shaper_data.fallback
516 && hb_fallback_shaper_font_data_ensure(font)
517 && hb_fallback_shape(shape_plan, font, buffer, features,
518 num_features);
519 return FALSE;
484 520 } }
485
File hb-shape-plan.h changed (mode: 100644) (index 8f54552..aa5e0c7)
... ... HB_BEGIN_DECLS
38 38
39 39 typedef struct hb_shape_plan_t hb_shape_plan_t; typedef struct hb_shape_plan_t hb_shape_plan_t;
40 40
41 hb_shape_plan_t *
41 HB_EXTERN hb_shape_plan_t *
42 42 hb_shape_plan_create (hb_face_t *face, hb_shape_plan_create (hb_face_t *face,
43 43 const hb_segment_properties_t *props, const hb_segment_properties_t *props,
44 44 const hb_feature_t *user_features, const hb_feature_t *user_features,
45 45 unsigned int num_user_features, unsigned int num_user_features,
46 46 const char * const *shaper_list); const char * const *shaper_list);
47 47
48 hb_shape_plan_t *
48 HB_EXTERN hb_shape_plan_t *
49 49 hb_shape_plan_create_cached (hb_face_t *face, hb_shape_plan_create_cached (hb_face_t *face,
50 50 const hb_segment_properties_t *props, const hb_segment_properties_t *props,
51 51 const hb_feature_t *user_features, const hb_feature_t *user_features,
52 52 unsigned int num_user_features, unsigned int num_user_features,
53 53 const char * const *shaper_list); const char * const *shaper_list);
54 54
55 hb_shape_plan_t *
55 HB_EXTERN hb_shape_plan_t *
56 56 hb_shape_plan_get_empty (void); hb_shape_plan_get_empty (void);
57 57
58 hb_shape_plan_t *
58 HB_EXTERN hb_shape_plan_t *
59 59 hb_shape_plan_reference (hb_shape_plan_t *shape_plan); hb_shape_plan_reference (hb_shape_plan_t *shape_plan);
60 60
61 void
61 HB_EXTERN void
62 62 hb_shape_plan_destroy (hb_shape_plan_t *shape_plan); hb_shape_plan_destroy (hb_shape_plan_t *shape_plan);
63 63
64 hb_bool_t
64 HB_EXTERN hb_bool_t
65 65 hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
66 66 hb_user_data_key_t *key, hb_user_data_key_t *key,
67 67 void * data, void * data,
68 68 hb_destroy_func_t destroy, hb_destroy_func_t destroy,
69 69 hb_bool_t replace); hb_bool_t replace);
70 70
71 void *
71 HB_EXTERN void *
72 72 hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
73 73 hb_user_data_key_t *key); hb_user_data_key_t *key);
74 74
75 75
76 hb_bool_t
76 HB_EXTERN hb_bool_t
77 77 hb_shape_plan_execute (hb_shape_plan_t *shape_plan, hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
78 78 hb_font_t *font, hb_font_t *font,
79 79 hb_buffer_t *buffer, hb_buffer_t *buffer,
80 80 const hb_feature_t *features, const hb_feature_t *features,
81 81 unsigned int num_features); unsigned int num_features);
82 82
83 const char *
83 HB_EXTERN const char *
84 84 hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan); hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan);
85 85
86 86
File hb-shape.c changed (mode: 100644) (index 1ff445b..00628cd)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <stddef.h> #include <stddef.h>
5 7 #include <assert.h> #include <assert.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include <errno.h>
6 11
7 12 #include "hb.h" #include "hb.h"
8 13 #include "hb-private.h" #include "hb-private.h"
 
12 17 #include "hb-shape-plan-private.h" #include "hb-shape-plan-private.h"
13 18 #include "hb-font-private.h" #include "hb-font-private.h"
14 19
15 hb_bool_t
16 hb_shape_full(hb_font_t *font,
17 hb_buffer_t *buffer,
18 const hb_feature_t *features,
19 unsigned num_features,
20 const char * const *shaper_list)
20 hb_bool_t hb_shape_full(hb_font_t * font, hb_buffer_t * buffer,
21 const hb_feature_t * features, unsigned num_features,
22 const char *const *shaper_list)
21 23 { {
22 if (!buffer->len)
23 return TRUE;
24 hb_shape_plan_t *shape_plan;
25 hb_bool_t res;
24 26
25 assert(buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
27 if (!buffer->len)
28 return TRUE;
26 29
27 hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached(font->face,
28 &buffer->props, features, num_features, shaper_list);
30 assert(buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
29 31
30 hb_bool_t res = hb_shape_plan_execute(shape_plan, font, buffer, features,
31 num_features);
32 hb_shape_plan_destroy(shape_plan);
32 shape_plan =
33 hb_shape_plan_create_cached(font->face, &buffer->props, features,
34 num_features, shaper_list);
35 res =
36 hb_shape_plan_execute(shape_plan, font, buffer, features,
37 num_features);
38 hb_shape_plan_destroy(shape_plan);
33 39
34 if (res)
35 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
36 return res;
40 if (res)
41 buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
42 return res;
37 43 } }
38 44
39 void
40 hb_shape(hb_font_t *font,
41 hb_buffer_t *buffer,
42 const hb_feature_t *features,
43 unsigned num_features)
45 void hb_shape(hb_font_t * font, hb_buffer_t * buffer,
46 const hb_feature_t * features, unsigned num_features)
44 47 { {
45 hb_shape_full(font, buffer, features, num_features, NULL);
48 hb_shape_full(font, buffer, features, num_features, NULL);
49 }
50
51 static hb_bool_t parse_space(const char **pp, const char *end)
52 {
53 while (*pp < end && ISSPACE(**pp))
54 (*pp)++;
55 return TRUE;
56 }
57
58 static hb_bool_t parse_char(const char **pp, const char *end, char c)
59 {
60 parse_space(pp, end);
61
62 if (*pp == end || **pp != c)
63 return FALSE;
64
65 (*pp)++;
66 return TRUE;
67 }
68
69 static hb_bool_t parse_feature_value_prefix(const char **pp, const char *end,
70 hb_feature_t * feature)
71 {
72 if (parse_char(pp, end, '-'))
73 feature->value = 0;
74 else {
75 parse_char(pp, end, '+');
76 feature->value = 1;
77 }
78 return TRUE;
79 }
80
81 static hb_bool_t parse_feature_tag(const char **pp, const char *end,
82 hb_feature_t * feature)
83 {
84 char quote;
85 const char *p;
86
87 parse_space(pp, end);
88
89 quote = 0;
90
91 if (*pp < end && (**pp == '\'' || **pp == '"')) {
92 quote = **pp;
93 (*pp)++;
94 }
95
96 p = *pp;
97 while (*pp < end && ISALNUM(**pp))
98 (*pp)++;
99
100 if (p == *pp || *pp - p > 4)
101 return FALSE;
102
103 feature->tag = hb_tag_from_string(p, *pp - p);
104
105 if (quote) {
106 /*CSS expects exactly four bytes. And we only allow
107 quotations for CSS compatibility. So, enforce the length. */
108 if (*pp - p != 4)
109 return FALSE;
110 if (*pp == end || **pp != quote)
111 return FALSE;
112 (*pp)++;
113 }
114
115 return TRUE;
116 }
117
118 static hb_bool_t parse_uint(const char **pp, const char *end, unsigned int *pv)
119 {
120 char buf[32];
121 unsigned int len;
122 char *p;
123 char *pend;
124 unsigned int v;
125
126 len = MIN(ARRAY_LENGTH(buf) - 1, (unsigned int)(end - *pp));
127 strncpy(buf, *pp, len);
128 buf[len] = '\0';
129
130 p = buf;
131 pend = p;
132
133 /* Intentionally use strtol instead of strtoul, such that
134 * -1 turns into "big number"... */
135 errno = 0;
136 v = strtol(p, &pend, 0);
137 if (errno || p == pend)
138 return FALSE;
139
140 *pv = v;
141 *pp += pend - p;
142 return TRUE;
143 }
144
145 static hb_bool_t parse_feature_indices(const char **pp, const char *end,
146 hb_feature_t * feature)
147 {
148 hb_bool_t has_start;
149
150 parse_space(pp, end);
151
152 feature->start = 0;
153 feature->end = (unsigned int)-1;
154
155 if (!parse_char(pp, end, '['))
156 return TRUE;
157
158 has_start = parse_uint(pp, end, &feature->start);
159
160 if (parse_char(pp, end, ':')) {
161 parse_uint(pp, end, &feature->end);
162 } else {
163 if (has_start)
164 feature->end = feature->start + 1;
165 }
166
167 return parse_char(pp, end, ']');
168 }
169
170 static hb_bool_t parse_bool(const char **pp, const char *end, unsigned int *pv)
171 {
172 const char *p;
173
174 parse_space(pp, end);
175
176 p = *pp;
177 while (*pp < end && ISALPHA(**pp))
178 (*pp)++;
179
180 /* CSS allows on/off as aliases 1/0. */
181 if (*pp - p == 2 || 0 == strncmp(p, "on", 2))
182 *pv = 1;
183 else if (*pp - p == 3 || 0 == strncmp(p, "off", 2))
184 *pv = 0;
185 else
186 return FALSE;
187
188 return TRUE;
189 }
190
191 static hb_bool_t parse_feature_value_postfix(const char **pp, const char *end,
192 hb_feature_t * feature)
193 {
194 hb_bool_t had_equal;
195 hb_bool_t had_value;
196
197 had_equal = parse_char(pp, end, '=');
198 had_value = parse_uint(pp, end, &feature->value)
199 || parse_bool(pp, end, &feature->value);
200 /* CSS doesn't use equal-sign between tag and value.
201 * If there was an equal-sign, then there *must* be a value.
202 * A value without an eqaul-sign is ok, but not required. */
203 return !had_equal || had_value;
204 }
205
206 static hb_bool_t parse_one_feature(const char **pp, const char *end,
207 hb_feature_t * feature)
208 {
209 return parse_feature_value_prefix(pp, end, feature)
210 && parse_feature_tag(pp, end, feature)
211 && parse_feature_indices(pp, end, feature)
212 && parse_feature_value_postfix(pp, end, feature)
213 && parse_space(pp, end) && *pp == end;
214 }
215
216 hb_bool_t hb_feature_from_string(const char *str, int len,
217 hb_feature_t * feature)
218 {
219 hb_feature_t feat;
220
221 if (len < 0)
222 len = strlen(str);
223
224 if (parse_one_feature(&str, str + len, &feat)) {
225 if (feature)
226 *feature = feat;
227 return TRUE;
228 }
229
230 if (feature)
231 memset(feature, 0, sizeof(*feature));
232 return FALSE;
46 233 } }
File hb-shape.h changed (mode: 100644) (index 10a35cb..53bb845)
... ... typedef struct hb_feature_t {
47 47 unsigned int end; unsigned int end;
48 48 } hb_feature_t; } hb_feature_t;
49 49
50 /* len=-1 means str is NUL-terminated */
51 hb_bool_t
50 HB_EXTERN hb_bool_t
52 51 hb_feature_from_string (const char *str, int len, hb_feature_from_string (const char *str, int len,
53 52 hb_feature_t *feature); hb_feature_t *feature);
54 53
55 /* Something like 128 bytes is more than enough.
56 * nul-terminates. */
57 void
54 HB_EXTERN void
58 55 hb_feature_to_string (hb_feature_t *feature, hb_feature_to_string (hb_feature_t *feature,
59 56 char *buf, unsigned int size); char *buf, unsigned int size);
60 57
61 58
62 void
59 HB_EXTERN void
63 60 hb_shape (hb_font_t *font, hb_shape (hb_font_t *font,
64 61 hb_buffer_t *buffer, hb_buffer_t *buffer,
65 62 const hb_feature_t *features, const hb_feature_t *features,
66 63 unsigned int num_features); unsigned int num_features);
67 64
68 hb_bool_t
65 HB_EXTERN hb_bool_t
69 66 hb_shape_full (hb_font_t *font, hb_shape_full (hb_font_t *font,
70 67 hb_buffer_t *buffer, hb_buffer_t *buffer,
71 68 const hb_feature_t *features, const hb_feature_t *features,
72 69 unsigned int num_features, unsigned int num_features,
73 70 const char * const *shaper_list); const char * const *shaper_list);
74 71
75 const char **
72 HB_EXTERN const char **
76 73 hb_shape_list_shapers (void); hb_shape_list_shapers (void);
77 74
78 75
File hb-shaper-private.h changed (mode: 100644) (index 78e3fe4..ee80e45)
1 1 #ifndef HB_SHAPER_PRIVATE_H #ifndef HB_SHAPER_PRIVATE_H
2 2 #define HB_SHAPER_PRIVATE_H #define HB_SHAPER_PRIVATE_H
3 //Means: succeeded, but don't need to keep any data.
3 /*Means: succeeded, but don't need to keep any data.*/
4 4 #define HB_SHAPER_DATA_SUCCEEDED ((void*)+1) #define HB_SHAPER_DATA_SUCCEEDED ((void*)+1)
5 //Means: tried but failed to create.
5 /*Means: tried but failed to create.*/
6 6 #define HB_SHAPER_DATA_INVALID ((void*)-1) #define HB_SHAPER_DATA_INVALID ((void*)-1)
7 7
8 typedef hb_bool_t hb_shape_func_t(hb_shape_plan_t *shape_plan,
9 hb_font_t *font,
10 hb_buffer_t *buffer,
11 const hb_feature_t *features,
12 unsigned num_features);
8 typedef hb_bool_t hb_shape_func_t(hb_shape_plan_t * shape_plan,
9 hb_font_t * font, hb_buffer_t * buffer,
10 const hb_feature_t * features,
11 unsigned num_features);
13 12 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
14 13 hb_shape_func_t hb_graphite2_shape; hb_shape_func_t hb_graphite2_shape;
15 14 #endif #endif
 
... ... hb_shape_func_t hb_ot_shape;
19 18 hb_shape_func_t hb_fallback_shape; hb_shape_func_t hb_fallback_shape;
20 19
21 20 struct hb_shaper_pair_t { struct hb_shaper_pair_t {
22 char name[16];
23 hb_shape_func_t *func;
21 char name[16];
22 hb_shape_func_t *func;
24 23 }; };
25 24
26 //For embedding in face / font / ...
25 /*For embedding in face / font / ...*/
27 26 struct hb_shaper_data_t { struct hb_shaper_data_t {
28 27 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
29 void *graphite2;
28 void *graphite2;
30 29 #endif #endif
31 30 #ifdef HAVE_OT #ifdef HAVE_OT
32 void *ot;
31 void *ot;
33 32 #endif #endif
34 void *fallback;
33 void *fallback;
35 34 }; };
36 35
37 36 #define HB_SHAPERS_COUNT (sizeof(struct hb_shaper_data_t)/sizeof(void *)) #define HB_SHAPERS_COUNT (sizeof(struct hb_shaper_data_t)/sizeof(void *))
38 37 #define HB_SHAPER_DATA_IS_INVALID(data) ((void*)(data) == HB_SHAPER_DATA_INVALID) #define HB_SHAPER_DATA_IS_INVALID(data) ((void*)(data) == HB_SHAPER_DATA_INVALID)
39 38
40 struct hb_shaper_pair_t *
41 hb_shapers_get(void);
39 struct hb_shaper_pair_t *hb_shapers_get(void);
42 40 #endif #endif
File hb-shaper.c changed (mode: 100644) (index d1c8f97..8073a7c)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <string.h> #include <string.h>
5 7 #include <stdlib.h> #include <stdlib.h>
6 8
 
9 11 #include "hb-atomic-private.h" #include "hb-atomic-private.h"
10 12 #include "hb-shaper-private.h" #include "hb-shaper-private.h"
11 13
14 /*XXX:should go in lib "global init*/
12 15 static struct hb_shaper_pair_t all_shapers[] = { static struct hb_shaper_pair_t all_shapers[] = {
13 16 #ifdef HAVE_GRAPHITE2 #ifdef HAVE_GRAPHITE2
14 {"graphite2", hb_graphite2_shape},
17 {"graphite2", hb_graphite2_shape},
15 18 #endif #endif
16 19 #ifdef HAVE_OT #ifdef HAVE_OT
17 {"ot", hb_ot_shape},
20 {"ot", hb_ot_shape},
18 21 #endif #endif
19 {"fallback", hb_fallback_shape}
22 {"fallback", hb_fallback_shape}
20 23 }; };
21 24
22 //Thread-safe, lock-free, shapers
25 /*Thread-safe, lock-free, shapers*/
23 26
27 /*XXX:should go in lib "global init*/
24 28 static struct hb_shaper_pair_t *static_shapers = NULL; static struct hb_shaper_pair_t *static_shapers = NULL;
25 29
26 struct hb_shaper_pair_t *
27 hb_shapers_get(void)
30 struct hb_shaper_pair_t *hb_shapers_get(void)
28 31 { {
29 while (1) {
30 struct hb_shaper_pair_t *shapers = hb_atomic_ptr_get(&static_shapers);
31 if (shapers)
32 return shapers;
32 while (1) {
33 struct hb_shaper_pair_t *shapers;
34 char *env;
35 unsigned i;
36 char *end, *p;
37 unsigned j;
38 void *expected;
33 39
34 char *env = getenv("HB_SHAPER_LIST");
35 if (!env || !*env) {
36 void *expected = NULL;
37 void *desired = &all_shapers[0];
38 hb_atomic_ptr_cmpexch(&static_shapers, &expected, &desired);
39 return all_shapers;
40 }
40 shapers = hb_atomic_ptr_get(&static_shapers);
41 if (shapers)
42 return shapers;
41 43
42 //Not found; allocate one
43 shapers = malloc(sizeof(all_shapers));
44 if (!shapers) {
45 void *expected = NULL;
46 void *desired = &all_shapers[0];
47 hb_atomic_ptr_cmpexch(&static_shapers, &expected, &desired);
48 return all_shapers;
49 }
44 env = getenv("HB_SHAPER_LIST");
45 if (!env || !*env) {
46 void *expected;
47 void *desired;
50 48
51 memcpy(shapers, all_shapers, sizeof(all_shapers));
49 expected = NULL;
50 desired = &all_shapers[0];
51 hb_atomic_ptr_cmpexch(&static_shapers, &expected,
52 &desired);
53 return all_shapers;
54 }
52 55
53 //Reorder shaper list to prefer requested shapers.
54 unsigned i = 0;
55 char *end, *p = env;
56 for (;;) {
57 end = strchr(p, ',');
58 if (!end)
59 end = p + strlen(p);
56 /*Not found; allocate one */
57 shapers = malloc(sizeof(all_shapers));
58 if (!shapers) {
59 void *expected;
60 void *desired;
60 61
61 for (unsigned j = i; j < ARRAY_LENGTH(all_shapers); ++j)
62 if (end - p == (int)strlen(shapers[j].name) &&
63 0 == strncmp(shapers[j].name, p, end - p)) {
64 //Reorder this shaper to position i
65 struct hb_shaper_pair_t t = shapers[j];
66 memmove(&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
67 shapers[i] = t;
68 i++;
69 }
62 expected = NULL;
63 desired = &all_shapers[0];
64 hb_atomic_ptr_cmpexch(&static_shapers, &expected,
65 &desired);
66 return all_shapers;
67 }
70 68
71 if (!*end)
72 break;
73 else
74 p = end + 1;
75 }
69 memcpy(shapers, all_shapers, sizeof(all_shapers));
76 70
77 void *expected = NULL;
78 if (hb_atomic_ptr_cmpexch(&static_shapers, &expected, &shapers)) {
79 return shapers;
80 }
81 free(shapers);
82 }
71 /*Reorder shaper list to prefer requested shapers. */
72 i = 0;
73 p = env;
74 for (;;) {
75 end = strchr(p, ',');
76 if (!end)
77 end = p + strlen(p);
78
79 for (j = i; j < ARRAY_LENGTH(all_shapers); ++j)
80 if (end - p == (int)strlen(shapers[j].name)
81 && 0 == strncmp(shapers[j].name, p,
82 end - p)) {
83 struct hb_shaper_pair_t t;
84 /*Reorder this shaper to position i */
85 t = shapers[j];
86 memmove(&shapers[i + 1], &shapers[i],
87 sizeof(shapers[i]) * (j - i));
88 shapers[i] = t;
89 i++;
90 }
91
92 if (!*end)
93 break;
94 else
95 p = end + 1;
96 }
97
98 expected = NULL;
99 if (hb_atomic_ptr_cmpexch(&static_shapers, &expected, &shapers)) {
100 return shapers;
101 }
102 free(shapers);
103 }
83 104 } }
File hb-unicode-private.h changed (mode: 100644) (index 8629390..276c97e)
3 3 extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil; extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil;
4 4
5 5 struct hb_unicode_funcs_t { struct hb_unicode_funcs_t {
6 atomic_int32_t ref_cnt;
7 hb_unicode_funcs_t *parent;
8 hb_bool_t immutable;
6 atomic_int32_t ref_cnt;
7 hb_unicode_funcs_t *parent;
8 hb_bool_t immutable;
9 9
10 struct {
11 hb_unicode_combining_class_func_t combining_class;
12 hb_unicode_eastasian_width_func_t eastasian_width;
13 hb_unicode_general_category_func_t general_category;
14 hb_unicode_mirroring_func_t mirroring;
15 hb_unicode_script_func_t script;
16 hb_unicode_compose_func_t compose;
17 hb_unicode_decompose_func_t decompose;
18 hb_unicode_decompose_compatibility_func_t decompose_compatibility;
19 } func;
10 struct {
11 hb_unicode_combining_class_func_t combining_class;
12 hb_unicode_eastasian_width_func_t eastasian_width;
13 hb_unicode_general_category_func_t general_category;
14 hb_unicode_mirroring_func_t mirroring;
15 hb_unicode_script_func_t script;
16 hb_unicode_compose_func_t compose;
17 hb_unicode_decompose_func_t decompose;
18 hb_unicode_decompose_compatibility_func_t
19 decompose_compatibility;
20 } func;
20 21
21 struct {
22 void *combining_class;
23 void *eastasian_width;
24 void *general_category;
25 void *mirroring;
26 void *script;
27 void *compose;
28 void *decompose;
29 void *decompose_compatibility;
30 } user_data;
22 struct {
23 void *combining_class;
24 void *eastasian_width;
25 void *general_category;
26 void *mirroring;
27 void *script;
28 void *compose;
29 void *decompose;
30 void *decompose_compatibility;
31 } user_data;
31 32
32 struct {
33 hb_destroy_func_t combining_class;
34 hb_destroy_func_t eastasian_width;
35 hb_destroy_func_t general_category;
36 hb_destroy_func_t mirroring;
37 hb_destroy_func_t script;
38 hb_destroy_func_t compose;
39 hb_destroy_func_t decompose;
40 hb_destroy_func_t decompose_compatibility;
41 } destroy;
33 struct {
34 hb_destroy_func_t combining_class;
35 hb_destroy_func_t eastasian_width;
36 hb_destroy_func_t general_category;
37 hb_destroy_func_t mirroring;
38 hb_destroy_func_t script;
39 hb_destroy_func_t compose;
40 hb_destroy_func_t decompose;
41 hb_destroy_func_t decompose_compatibility;
42 } destroy;
42 43 }; };
43 hb_bool_t
44 hb_unicode_is_default_ignorable(hb_codepoint_t ch);
44 hb_bool_t hb_unicode_is_default_ignorable(hb_codepoint_t ch);
45 45 #endif #endif
File hb-unicode.c changed (mode: 100644) (index 462ddc1..53862e6)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <stdlib.h> #include <stdlib.h>
5 7
6 8 #include "hb.h" #include "hb.h"
 
9 11 #include "hb-unicode-private.h" #include "hb-unicode-private.h"
10 12
11 13 static hb_unicode_combining_class_t static hb_unicode_combining_class_t
12 hb_unicode_combining_class_nil(hb_unicode_funcs_t *ufuncs HB_UNUSED,
13 hb_codepoint_t unicode HB_UNUSED,
14 void *user_data HB_UNUSED)
14 hb_unicode_combining_class_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
15 hb_codepoint_t unicode HB_UNUSED,
16 void *user_data HB_UNUSED)
15 17 { {
16 return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
18 return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
17 19 } }
18 20
19 static unsigned int
20 hb_unicode_eastasian_width_nil(hb_unicode_funcs_t *ufuncs HB_UNUSED,
21 hb_codepoint_t unicode HB_UNUSED,
22 void *user_data HB_UNUSED)
21 static unsigned int hb_unicode_eastasian_width_nil(hb_unicode_funcs_t *
22 ufuncs HB_UNUSED,
23 hb_codepoint_t unicode
24 HB_UNUSED,
25 void *user_data HB_UNUSED)
23 26 { {
24 return 1;
27 return 1;
25 28 } }
26 29
27 30 static hb_unicode_general_category_t static hb_unicode_general_category_t
28 hb_unicode_general_category_nil(hb_unicode_funcs_t *ufuncs HB_UNUSED,
29 hb_codepoint_t unicode HB_UNUSED,
30 void *user_data HB_UNUSED)
31 hb_unicode_general_category_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
32 hb_codepoint_t unicode HB_UNUSED,
33 void *user_data HB_UNUSED)
31 34 { {
32 return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
35 return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
33 36 } }
34 37
35 static hb_codepoint_t
36 hb_unicode_mirroring_nil(hb_unicode_funcs_t *ufuncs HB_UNUSED,
37 hb_codepoint_t unicode HB_UNUSED,
38 void *user_data HB_UNUSED)
38 static hb_codepoint_t hb_unicode_mirroring_nil(hb_unicode_funcs_t *
39 ufuncs HB_UNUSED,
40 hb_codepoint_t unicode HB_UNUSED,
41 void *user_data HB_UNUSED)
39 42 { {
40 return unicode;
43 return unicode;
41 44 } }
42 45
43 static hb_script_t
44 hb_unicode_script_nil(hb_unicode_funcs_t *ufuncs HB_UNUSED,
45 hb_codepoint_t unicode HB_UNUSED,
46 void *user_data HB_UNUSED)
46 static hb_script_t hb_unicode_script_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
47 hb_codepoint_t unicode HB_UNUSED,
48 void *user_data HB_UNUSED)
47 49 { {
48 return HB_SCRIPT_UNKNOWN;
50 return HB_SCRIPT_UNKNOWN;
49 51 } }
50 52
51 static hb_bool_t
52 hb_unicode_compose_nil(hb_unicode_funcs_t *ufuncs HB_UNUSED,
53 hb_codepoint_t a HB_UNUSED,
54 hb_codepoint_t b HB_UNUSED,
55 hb_codepoint_t *ab HB_UNUSED,
56 void *user_data HB_UNUSED)
53 static hb_bool_t hb_unicode_compose_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
54 hb_codepoint_t a HB_UNUSED,
55 hb_codepoint_t b HB_UNUSED,
56 hb_codepoint_t * ab HB_UNUSED,
57 void *user_data HB_UNUSED)
57 58 { {
58 return FALSE;
59 return FALSE;
59 60 } }
60 61
61 static hb_bool_t
62 hb_unicode_decompose_nil(hb_unicode_funcs_t *ufuncs HB_UNUSED,
63 hb_codepoint_t ab HB_UNUSED,
64 hb_codepoint_t *a HB_UNUSED,
65 hb_codepoint_t *b HB_UNUSED,
66 void *user_data HB_UNUSED)
62 static hb_bool_t hb_unicode_decompose_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,
63 hb_codepoint_t ab HB_UNUSED,
64 hb_codepoint_t * a HB_UNUSED,
65 hb_codepoint_t * b HB_UNUSED,
66 void *user_data HB_UNUSED)
67 67 { {
68 return FALSE;
68 return FALSE;
69 69 } }
70 70
71 static unsigned int
72 hb_unicode_decompose_compatibility_nil(hb_unicode_funcs_t *ufuncs HB_UNUSED,
73 hb_codepoint_t u HB_UNUSED,
74 hb_codepoint_t *decomposed HB_UNUSED,
75 void *user_data HB_UNUSED)
71 static unsigned int hb_unicode_decompose_compatibility_nil(hb_unicode_funcs_t *
72 ufuncs HB_UNUSED,
73 hb_codepoint_t u
74 HB_UNUSED,
75 hb_codepoint_t *
76 decomposed HB_UNUSED,
77 void *user_data
78 HB_UNUSED)
76 79 { {
77 return 0;
80 return 0;
78 81 } }
79 82
80 //must be public
83 /*must be public*/
81 84 hb_unicode_funcs_t _hb_unicode_funcs_nil = { hb_unicode_funcs_t _hb_unicode_funcs_nil = {
82 REF_CNT_INVALID_VAL,//ref_cnt
83 NULL,//parent
84 TRUE,//immutable
85 {//func
86 hb_unicode_combining_class_nil,
87 hb_unicode_eastasian_width_nil,
88 hb_unicode_general_category_nil,
89 hb_unicode_mirroring_nil,
90 hb_unicode_script_nil,
91 hb_unicode_compose_nil,
92 hb_unicode_decompose_nil,
93 hb_unicode_decompose_compatibility_nil
94 },
95 {//user_data
96 NULL,//combining_class
97 NULL,//eastasian_width
98 NULL,//general_category
99 NULL,//mirroring
100 NULL,//script
101 NULL,//compose
102 NULL,//decompose
103 NULL//decompose_compatibility
104 },
105 {//destroy
106 NULL,//combining_class
107 NULL,//eastasian_width
108 NULL,//general_category
109 NULL,//mirroring
110 NULL,//script
111 NULL,//compose
112 NULL,//decompose
113 NULL//decompose_compatibility
114 }
85 REF_CNT_INVALID_VAL, /*ref_cnt */
86 NULL, /*parent */
87 TRUE, /*immutable */
88 { /*func */
89 hb_unicode_combining_class_nil,
90 hb_unicode_eastasian_width_nil,
91 hb_unicode_general_category_nil,
92 hb_unicode_mirroring_nil,
93 hb_unicode_script_nil,
94 hb_unicode_compose_nil,
95 hb_unicode_decompose_nil,
96 hb_unicode_decompose_compatibility_nil}
97 ,
98 { /*user_data */
99 NULL, /*combining_class */
100 NULL, /*eastasian_width */
101 NULL, /*general_category */
102 NULL, /*mirroring */
103 NULL, /*script */
104 NULL, /*compose */
105 NULL, /*decompose */
106 NULL /*decompose_compatibility */
107 }
108 ,
109 { /*destroy */
110 NULL, /*combining_class */
111 NULL, /*eastasian_width */
112 NULL, /*general_category */
113 NULL, /*mirroring */
114 NULL, /*script */
115 NULL, /*compose */
116 NULL, /*decompose */
117 NULL /*decompose_compatibility */
118 }
115 119 }; };
116 120
117 //Default_Ignorable codepoints:
118 //
119 //Note that as of Oct 2012 (Unicode 6.2), U+180E MONGOLIAN VOWEL SEPARATOR
120 //is NOT Default_Ignorable, but it really behaves in a way that it should
121 //be. That has been reported to the Unicode Technical Committee for
122 //consideration. As such, we include it here, since Uniscribe removes it.
123 //It *is* in Unicode 6.3 however. U+061C ARABIC LETTER MARK from Unicode
124 //6.3 is also added manually. The new Unicode 6.3 bidi formatting
125 //characters are encoded in a block that was Default_Ignorable already.
126 //
127 //Note: While U+115F and U+1160 are Default_Ignorable, we do NOT want to
128 //hide them, as the way Uniscribe has implemented them is with regular
129 //spacing glyphs, and that's the way fonts are made to work. As such,
130 //we make exceptions for those two.
131 //
132 //Gathered from:
133 //http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on
134 //
135 //Last updated to the page with the following versions:
136 //Version 3.6; ICU version: 50.0.1.0; Unicode version: 6.1.0.0
137 //
138 //4,167 Code Points
139 //
140 //[\u00AD\u034F\u115F\u1160\u17B4\u17B5\u180B-\u180D\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8\U0001D173-\U0001D17A\U000E0000-\U000E0FFF]
141 //
142 //00AD ;SOFT HYPHEN
143 //034F ;COMBINING GRAPHEME JOINER
144 //#115F ;HANGUL CHOSEONG FILLER
145 //#1160 ;HANGUL JUNGSEONG FILLER
146 //17B4 ;KHMER VOWEL INHERENT AQ
147 //17B5 ;KHMER VOWEL INHERENT AA
148 //180B..180D ;MONGOLIAN FREE VARIATION SELECTOR THREE
149 //200B..200F ;RIGHT-TO-LEFT MARK
150 //202A..202E ;RIGHT-TO-LEFT OVERRIDE
151 //2060..206F ;NOMINAL DIGIT SHAPES
152 //3164 ;HANGUL FILLER
153 //FE00..FE0F ;VARIATION SELECTOR-16
154 //FEFF ;ZERO WIDTH NO-BREAK SPACE
155 //FFA0 ;HALFWIDTH HANGUL FILLER
156 //FFF0..FFF8 ;<unassigned-FFF8>
157 //1D173..1D17A ;MUSICAL SYMBOL END PHRASE
158 //E0000..E0FFF ;<unassigned-E0FFF>
159
160 hb_bool_t
161 hb_unicode_is_default_ignorable(hb_codepoint_t ch)
121 /*
122 Default_Ignorable codepoints:
123
124 Note that as of Oct 2012 (Unicode 6.2), U+180E MONGOLIAN VOWEL SEPARATOR
125 is NOT Default_Ignorable, but it really behaves in a way that it should
126 be. That has been reported to the Unicode Technical Committee for
127 consideration. As such, we include it here, since Uniscribe removes it.
128 It *is* in Unicode 6.3 however. U+061C ARABIC LETTER MARK from Unicode
129 6.3 is also added manually. The new Unicode 6.3 bidi formatting
130 characters are encoded in a block that was Default_Ignorable already.
131
132 Note: While U+115F and U+1160 are Default_Ignorable, we do NOT want to
133 hide them, as the way Uniscribe has implemented them is with regular
134 spacing glyphs, and that's the way fonts are made to work. As such,
135 we make exceptions for those two.
136
137 Gathered from:
138 http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:DI:]&abb=on&ucd=on&esc=on
139
140 Last updated to the page with the following versions:
141 Version 3.6; ICU version: 50.0.1.0; Unicode version: 6.1.0.0
142
143 4,167 Code Points
144
145 [\u00AD\u034F\u115F\u1160\u17B4\u17B5\u180B-\u180D\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8\U0001D173-\U0001D17A\U000E0000-\U000E0FFF]
146
147 00AD ;SOFT HYPHEN
148 034F ;COMBINING GRAPHEME JOINER
149 #115F ;HANGUL CHOSEONG FILLER
150 #1160 ;HANGUL JUNGSEONG FILLER
151 17B4 ;KHMER VOWEL INHERENT AQ
152 17B5 ;KHMER VOWEL INHERENT AA
153 180B..180D ;MONGOLIAN FREE VARIATION SELECTOR THREE
154 200B..200F ;RIGHT-TO-LEFT MARK
155 202A..202E ;RIGHT-TO-LEFT OVERRIDE
156 2060..206F ;NOMINAL DIGIT SHAPES
157 3164 ;HANGUL FILLER
158 FE00..FE0F ;VARIATION SELECTOR-16
159 FEFF ;ZERO WIDTH NO-BREAK SPACE
160 FFA0 ;HALFWIDTH HANGUL FILLER
161 FFF0..FFF8 ;<unassigned-FFF8>
162 1D173..1D17A ;MUSICAL SYMBOL END PHRASE
163 E0000..E0FFF ;<unassigned-E0FFF>
164 */
165
166 hb_bool_t hb_unicode_is_default_ignorable(hb_codepoint_t ch)
162 167 { {
163 hb_codepoint_t plane = ch >> 16;
164 if (plane == 0) {
165 //BMP
166 hb_codepoint_t page = ch >> 8;
167 switch (page) {
168 case 0x00: return ch == 0x00AD;
169 case 0x03: return ch == 0x034F;
170 case 0x06: return ch == 0x061C;
171 case 0x17: return hb_codepoint_in_range(ch, 0x17B4, 0x17B5);
172 case 0x18: return hb_codepoint_in_range(ch, 0x180B, 0x180E);
173 case 0x20: return hb_codepoint_in_ranges(ch, 0x200B, 0x200F,
174 0x202A, 0x202E,
175 0x2060, 0x206F);
176 case 0x31: return ch == 0x3164;
177 case 0xFE: return hb_codepoint_in_range(ch, 0xFE00, 0xFE0F) || ch == 0xFEFF;
178 case 0xFF: return hb_codepoint_in_range(ch, 0xFFF0, 0xFFF8) || ch == 0xFFA0;
179 default: return FALSE;
180 }
181 } else {
182 //Other planes
183 switch (plane) {
184 case 0x01: return hb_codepoint_in_range(ch, 0x0001D173, 0x0001D17A);
185 case 0x0E: return hb_codepoint_in_range(ch, 0x000E0000, 0x000E0FFF);
186 default: return FALSE;
187 }
188 }
168 hb_codepoint_t plane;
169
170 plane = ch >> 16;
171 if (plane == 0) {
172 hb_codepoint_t page;
173 /*BMP*/ page = ch >> 8;
174 switch (page) {
175 case 0x00:
176 return ch == 0x00AD;
177 case 0x03:
178 return ch == 0x034F;
179 case 0x06:
180 return ch == 0x061C;
181 case 0x17:
182 return hb_codepoint_in_range(ch, 0x17B4, 0x17B5);
183 case 0x18:
184 return hb_codepoint_in_range(ch, 0x180B, 0x180E);
185 case 0x20:
186 return hb_codepoint_in_ranges(ch, 0x200B, 0x200F,
187 0x202A, 0x202E, 0x2060,
188 0x206F);
189 case 0x31:
190 return ch == 0x3164;
191 case 0xFE:
192 return hb_codepoint_in_range(ch, 0xFE00, 0xFE0F)
193 || ch == 0xFEFF;
194 case 0xFF:
195 return hb_codepoint_in_range(ch, 0xFFF0, 0xFFF8)
196 || ch == 0xFFA0;
197 default:
198 return FALSE;
199 }
200 } else {
201 /*Other planes */
202 switch (plane) {
203 case 0x01:
204 return hb_codepoint_in_range(ch, 0x0001D173,
205 0x0001D17A);
206 case 0x0E:
207 return hb_codepoint_in_range(ch, 0x000E0000,
208 0x000E0FFF);
209 default:
210 return FALSE;
211 }
212 }
189 213 } }
190 214
191 hb_unicode_funcs_t *
192 hb_unicode_funcs_get_empty(void)
215 hb_unicode_funcs_t *hb_unicode_funcs_get_empty(void)
193 216 { {
194 return &_hb_unicode_funcs_nil;
217 return &_hb_unicode_funcs_nil;
195 218 } }
196 219
197 hb_unicode_funcs_t *
198 hb_unicode_funcs_reference(hb_unicode_funcs_t *ufuncs)
220 hb_unicode_funcs_t *hb_unicode_funcs_reference(hb_unicode_funcs_t * ufuncs)
199 221 { {
200 if (hb_atomic_int32_get(&ufuncs->ref_cnt) != REF_CNT_INVALID_VAL)
201 hb_atomic_int32_add(&ufuncs->ref_cnt, 1);
202 return ufuncs;
222 if (hb_atomic_int32_get(&ufuncs->ref_cnt) != REF_CNT_INVALID_VAL)
223 hb_atomic_int32_add(&ufuncs->ref_cnt, 1);
224 return ufuncs;
203 225 } }
204 226
205 227 extern hb_unicode_funcs_t *hb_glib_get_unicode_funcs(void); extern hb_unicode_funcs_t *hb_glib_get_unicode_funcs(void);
206 228 extern hb_unicode_funcs_t *hb_nil_get_unicode_funcs(void); extern hb_unicode_funcs_t *hb_nil_get_unicode_funcs(void);
207 229
208 hb_unicode_funcs_t *
209 hb_unicode_funcs_get_default(void)
230 hb_unicode_funcs_t *hb_unicode_funcs_get_default(void)
210 231 { {
211 232 #ifdef HAVE_GLIB #ifdef HAVE_GLIB
212 return hb_glib_get_unicode_funcs();
233 return hb_glib_get_unicode_funcs();
213 234 #else #else
214 return hb_unicode_funcs_get_empty();
235 return hb_unicode_funcs_get_empty();
215 236 #endif #endif
216 237 } }
217 238
218 void
219 hb_unicode_funcs_destroy(hb_unicode_funcs_t *ufuncs)
239 void hb_unicode_funcs_destroy(hb_unicode_funcs_t * ufuncs)
220 240 { {
221 if (!ufuncs)
222 return;
223 if (hb_atomic_int32_get(&ufuncs->ref_cnt) == REF_CNT_INVALID_VAL)
224 return;
225 hb_atomic_int32_add(&ufuncs->ref_cnt, -1);
226 if (hb_atomic_int32_get(&ufuncs->ref_cnt) > 0)
227 return;
228 hb_atomic_int32_set(&ufuncs->ref_cnt, REF_CNT_INVALID_VAL);
229
230 if (ufuncs->destroy.combining_class)
231 ufuncs->destroy.combining_class(ufuncs->user_data.combining_class);
232 if (ufuncs->destroy.eastasian_width)
233 ufuncs->destroy.eastasian_width(ufuncs->user_data.eastasian_width);
234 if (ufuncs->destroy.general_category)
235 ufuncs->destroy.general_category(ufuncs->user_data.general_category);
236 if (ufuncs->destroy.mirroring)
237 ufuncs->destroy.mirroring(ufuncs->user_data.mirroring);
238 if (ufuncs->destroy.script)
239 ufuncs->destroy.script(ufuncs->user_data.script);
240 if (ufuncs->destroy.compose)
241 ufuncs->destroy.compose(ufuncs->user_data.compose);
242 if (ufuncs->destroy.decompose)
243 ufuncs->destroy.decompose(ufuncs->user_data.decompose);
244 if (ufuncs->destroy.decompose_compatibility)
245 ufuncs->destroy.decompose_compatibility(
246 ufuncs->user_data.decompose_compatibility);
247
248 hb_unicode_funcs_destroy(ufuncs->parent);
249 free (ufuncs);
241 if (!ufuncs)
242 return;
243 if (hb_atomic_int32_get(&ufuncs->ref_cnt) == REF_CNT_INVALID_VAL)
244 return;
245 hb_atomic_int32_add(&ufuncs->ref_cnt, -1);
246 if (hb_atomic_int32_get(&ufuncs->ref_cnt) > 0)
247 return;
248 hb_atomic_int32_set(&ufuncs->ref_cnt, REF_CNT_INVALID_VAL);
249
250 if (ufuncs->destroy.combining_class)
251 ufuncs->destroy.combining_class(ufuncs->user_data.
252 combining_class);
253 if (ufuncs->destroy.eastasian_width)
254 ufuncs->destroy.eastasian_width(ufuncs->user_data.
255 eastasian_width);
256 if (ufuncs->destroy.general_category)
257 ufuncs->destroy.general_category(ufuncs->user_data.
258 general_category);
259 if (ufuncs->destroy.mirroring)
260 ufuncs->destroy.mirroring(ufuncs->user_data.mirroring);
261 if (ufuncs->destroy.script)
262 ufuncs->destroy.script(ufuncs->user_data.script);
263 if (ufuncs->destroy.compose)
264 ufuncs->destroy.compose(ufuncs->user_data.compose);
265 if (ufuncs->destroy.decompose)
266 ufuncs->destroy.decompose(ufuncs->user_data.decompose);
267 if (ufuncs->destroy.decompose_compatibility)
268 ufuncs->destroy.decompose_compatibility(ufuncs->user_data.
269 decompose_compatibility);
270
271 hb_unicode_funcs_destroy(ufuncs->parent);
272 free(ufuncs);
250 273 } }
File hb-unicode.h changed (mode: 100644) (index 1c4e097..33b68aa)
... ... typedef struct hb_unicode_funcs_t hb_unicode_funcs_t;
174 174 /* /*
175 175 * just give me the best implementation you've got there. * just give me the best implementation you've got there.
176 176 */ */
177 hb_unicode_funcs_t *
177 HB_EXTERN hb_unicode_funcs_t *
178 178 hb_unicode_funcs_get_default (void); hb_unicode_funcs_get_default (void);
179 179
180 180
181 hb_unicode_funcs_t *
181 HB_EXTERN hb_unicode_funcs_t *
182 182 hb_unicode_funcs_create (hb_unicode_funcs_t *parent); hb_unicode_funcs_create (hb_unicode_funcs_t *parent);
183 183
184 hb_unicode_funcs_t *
184 HB_EXTERN hb_unicode_funcs_t *
185 185 hb_unicode_funcs_get_empty (void); hb_unicode_funcs_get_empty (void);
186 186
187 hb_unicode_funcs_t *
187 HB_EXTERN hb_unicode_funcs_t *
188 188 hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs); hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs);
189 189
190 void
190 HB_EXTERN void
191 191 hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs); hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
192 192
193 hb_bool_t
193 HB_EXTERN hb_bool_t
194 194 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
195 195 hb_user_data_key_t *key, hb_user_data_key_t *key,
196 196 void * data, void * data,
 
... ... hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
198 198 hb_bool_t replace); hb_bool_t replace);
199 199
200 200
201 void *
201 HB_EXTERN void *
202 202 hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
203 203 hb_user_data_key_t *key); hb_user_data_key_t *key);
204 204
205 205
206 void
206 HB_EXTERN void
207 207 hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs); hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs);
208 208
209 hb_bool_t
209 HB_EXTERN hb_bool_t
210 210 hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs); hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs);
211 211
212 hb_unicode_funcs_t *
212 HB_EXTERN hb_unicode_funcs_t *
213 213 hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs); hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
214 214
215 215
 
... ... typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_
283 283 * *
284 284 * *
285 285 * *
286 * Since: 1.0
286 * Since: 0.9.2
287 287 **/ **/
288 void
288 HB_EXTERN void
289 289 hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
290 290 hb_unicode_combining_class_func_t func, hb_unicode_combining_class_func_t func,
291 291 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
299 299 * *
300 300 * *
301 301 * *
302 * Since: 1.0
302 * Since: 0.9.2
303 303 **/ **/
304 void
304 HB_EXTERN void
305 305 hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
306 306 hb_unicode_eastasian_width_func_t func, hb_unicode_eastasian_width_func_t func,
307 307 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
315 315 * *
316 316 * *
317 317 * *
318 * Since: 1.0
318 * Since: 0.9.2
319 319 **/ **/
320 void
320 HB_EXTERN void
321 321 hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
322 322 hb_unicode_general_category_func_t func, hb_unicode_general_category_func_t func,
323 323 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
331 331 * *
332 332 * *
333 333 * *
334 * Since: 1.0
334 * Since: 0.9.2
335 335 **/ **/
336 void
336 HB_EXTERN void
337 337 hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
338 338 hb_unicode_mirroring_func_t func, hb_unicode_mirroring_func_t func,
339 339 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
347 347 * *
348 348 * *
349 349 * *
350 * Since: 1.0
350 * Since: 0.9.2
351 351 **/ **/
352 void
352 HB_EXTERN void
353 353 hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
354 354 hb_unicode_script_func_t func, hb_unicode_script_func_t func,
355 355 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
363 363 * *
364 364 * *
365 365 * *
366 * Since: 1.0
366 * Since: 0.9.2
367 367 **/ **/
368 void
368 HB_EXTERN void
369 369 hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
370 370 hb_unicode_compose_func_t func, hb_unicode_compose_func_t func,
371 371 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
379 379 * *
380 380 * *
381 381 * *
382 * Since: 1.0
382 * Since: 0.9.2
383 383 **/ **/
384 void
384 HB_EXTERN void
385 385 hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
386 386 hb_unicode_decompose_func_t func, hb_unicode_decompose_func_t func,
387 387 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
 
... ... hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
395 395 * *
396 396 * *
397 397 * *
398 * Since: 1.0
398 * Since: 0.9.2
399 399 **/ **/
400 void
400 HB_EXTERN void
401 401 hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
402 402 hb_unicode_decompose_compatibility_func_t func, hb_unicode_decompose_compatibility_func_t func,
403 403 void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
404 404
405 405 /* accessors */ /* accessors */
406 406
407 hb_unicode_combining_class_t
407 /**
408 * Since: 0.9.2
409 **/
410 HB_EXTERN hb_unicode_combining_class_t
408 411 hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
409 412 hb_codepoint_t unicode); hb_codepoint_t unicode);
410 413
411 unsigned int
414 /**
415 * Since: 0.9.2
416 **/
417 HB_EXTERN unsigned int
412 418 hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
413 419 hb_codepoint_t unicode); hb_codepoint_t unicode);
414 420
415 hb_unicode_general_category_t
421 /**
422 * Since: 0.9.2
423 **/
424 HB_EXTERN hb_unicode_general_category_t
416 425 hb_unicode_general_category (hb_unicode_funcs_t *ufuncs, hb_unicode_general_category (hb_unicode_funcs_t *ufuncs,
417 426 hb_codepoint_t unicode); hb_codepoint_t unicode);
418 427
419 hb_codepoint_t
428 /**
429 * Since: 0.9.2
430 **/
431 HB_EXTERN hb_codepoint_t
420 432 hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs, hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs,
421 433 hb_codepoint_t unicode); hb_codepoint_t unicode);
422 434
423 hb_script_t
435 /**
436 * Since: 0.9.2
437 **/
438 HB_EXTERN hb_script_t
424 439 hb_unicode_script (hb_unicode_funcs_t *ufuncs, hb_unicode_script (hb_unicode_funcs_t *ufuncs,
425 440 hb_codepoint_t unicode); hb_codepoint_t unicode);
426 441
427 hb_bool_t
442 /**
443 * Since: 0.9.2
444 **/
445 HB_EXTERN hb_bool_t
428 446 hb_unicode_compose (hb_unicode_funcs_t *ufuncs, hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
429 447 hb_codepoint_t a, hb_codepoint_t a,
430 448 hb_codepoint_t b, hb_codepoint_t b,
431 449 hb_codepoint_t *ab); hb_codepoint_t *ab);
432 hb_bool_t
450
451 /**
452 * Since: 0.9.2
453 **/
454 HB_EXTERN hb_bool_t
433 455 hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
434 456 hb_codepoint_t ab, hb_codepoint_t ab,
435 457 hb_codepoint_t *a, hb_codepoint_t *a,
436 458 hb_codepoint_t *b); hb_codepoint_t *b);
437 459
438 unsigned int
460 /**
461 * Since: 0.9.2
462 **/
463 HB_EXTERN unsigned int
439 464 hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
440 465 hb_codepoint_t u, hb_codepoint_t u,
441 466 hb_codepoint_t *decomposed); hb_codepoint_t *decomposed);
File hb-uniscribe.h changed (mode: 100644) (index 51887c8..4e4ef99)
29 29
30 30 #include "hb.h" #include "hb.h"
31 31
32 #ifndef _WIN32_WINNT
33 #define _WIN32_WINNT 0x0600
34 #endif
35 32 #include <windows.h> #include <windows.h>
36 33
37 34 HB_BEGIN_DECLS HB_BEGIN_DECLS
38 35
39 36
40 LOGFONTW *
37 HB_EXTERN LOGFONTW *
41 38 hb_uniscribe_font_get_logfontw (hb_font_t *font); hb_uniscribe_font_get_logfontw (hb_font_t *font);
42 39
43 HFONT
40 HB_EXTERN HFONT
44 41 hb_uniscribe_font_get_hfont (hb_font_t *font); hb_uniscribe_font_get_hfont (hb_font_t *font);
45 42
46 43
File hb-utf-private.c changed (mode: 100644) (index 97eb779..319e112)
1 // C99 port from c++ is protected by a GNU Lesser GPLv3
2 // Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
3 // <sylware@legeek.net>
1 /*
2 Port from c++ is protected by a GNU Lesser GPLv3
3 Copyright © 2013 Sylvain BERTRAND <sylvain.bertrand@gmail.com>
4 <sylware@legeek.net>
5 */
4 6 #include <string.h> #include <string.h>
5 7 #include <stdint.h> #include <stdint.h>
6 8
7 9 #include "hb.h" #include "hb.h"
8 10 #include "hb-private.h" #include "hb-private.h"
9 11
10 //------------------------------------------------------------------------------
11 //utf8
12 /*----------------------------------------------------------------------------*/
13 /*utf8*/
12 14 #define HB_UTF8_COMPUTE(Char, Mask, Len) \ #define HB_UTF8_COMPUTE(Char, Mask, Len) \
13 15 if (Char < 128) { Len = 1; Mask = 0x7f; } \ if (Char < 128) { Len = 1; Mask = 0x7f; } \
14 16 else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \ else if ((Char & 0xe0) == 0xc0) { Len = 2; Mask = 0x1f; } \
 
16 18 else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \ else if ((Char & 0xf8) == 0xf0) { Len = 4; Mask = 0x07; } \
17 19 else Len = 0; else Len = 0;
18 20
19 void *
20 hb_utf_next_utf8(void *text,
21 void *end,
22 hb_codepoint_t *unicode)
21 void *hb_utf_next_utf8(void *text, void *end, hb_codepoint_t * unicode)
23 22 { {
24 uint8_t *text_utf8 = text;
25 uint8_t *end_utf8 = end;
26 hb_codepoint_t c = *text_utf8, mask;
27 unsigned len;
28
29 //TODO check for overlong sequences?
30
31 HB_UTF8_COMPUTE (c, mask, len);
32 if (!len || (unsigned) (end_utf8 - text_utf8) < len) {
33 *unicode = -1;
34 return text_utf8 + 1;
35 } else {
36 hb_codepoint_t result;
37 unsigned i;
38 result = c & mask;
39 for (i = 1; i < len; i++) {
40 if ((text_utf8[i] & 0xc0) != 0x80) {
41 *unicode = -1;
42 return text_utf8 + 1;
43 }
44 result <<= 6;
45 result |= (text_utf8[i] & 0x3f);
46 }
47 *unicode = result;
48 return text_utf8 + len;
49 }
23 uint8_t *text_utf8;
24 uint8_t *end_utf8;
25 hb_codepoint_t c, mask;
26 unsigned len;
27
28 text_utf8 = text;
29 end_utf8 = end;
30 c = *text_utf8;
31
32 /*TODO check for overlong sequences? */
33
34 HB_UTF8_COMPUTE(c, mask, len);
35 if (!len || (unsigned)(end_utf8 - text_utf8) < len) {
36 *unicode = -1;
37 return text_utf8 + 1;
38 } else {
39 hb_codepoint_t result;
40 unsigned i;
41
42 result = c & mask;
43 for (i = 1; i < len; i++) {
44 if ((text_utf8[i] & 0xc0) != 0x80) {
45 *unicode = -1;
46 return text_utf8 + 1;
47 }
48 result <<= 6;
49 result |= (text_utf8[i] & 0x3f);
50 }
51 *unicode = result;
52 return text_utf8 + len;
53 }
50 54 } }
51 55
52 void *
53 hb_utf_prev_utf8(void *text,
54 void *start,
55 hb_codepoint_t *unicode)
56 void *hb_utf_prev_utf8(void *text, void *start, hb_codepoint_t * unicode)
56 57 { {
57 uint8_t *text_utf8 = text;
58 uint8_t *start_utf8 = start;
59
60 uint8_t *end = text_utf8--;
61 while (start_utf8 < text_utf8 && (*text_utf8 & 0xc0) == 0x80
62 && end - text_utf8 < 4)
63 text_utf8--;
64
65 hb_codepoint_t c = *text_utf8, mask;
66 unsigned len;
67
68 //TODO check for overlong sequences?
69
70 HB_UTF8_COMPUTE(c, mask, len);
71 if (!len || (unsigned)(end - text_utf8) != len) {
72 *unicode = -1;
73 return end - 1;
74 } else {
75 hb_codepoint_t result;
76 unsigned i;
77 result = c & mask;
78 for (i = 1; i < len; i++) {
79 result <<= 6;
80 result |= (text_utf8[i] & 0x3f);
81 }
82 *unicode = result;
83 return text_utf8;
84 }
58 uint8_t *text_utf8;
59 uint8_t *start_utf8;
60 uint8_t *end;
61 hb_codepoint_t c, mask;
62 unsigned len;
63
64 text_utf8 = text;
65 start_utf8 = start;
66
67 end = text_utf8--;
68 while (start_utf8 < text_utf8 && (*text_utf8 & 0xc0) == 0x80
69 && end - text_utf8 < 4)
70 text_utf8--;
71
72 c = *text_utf8;
73
74 /*TODO check for overlong sequences? */
75
76 HB_UTF8_COMPUTE(c, mask, len);
77 if (!len || (unsigned)(end - text_utf8) != len) {
78 *unicode = -1;
79 return end - 1;
80 } else {
81 hb_codepoint_t result;
82 unsigned i;
83
84 result = c & mask;
85 for (i = 1; i < len; i++) {
86 result <<= 6;
87 result |= (text_utf8[i] & 0x3f);
88 }
89 *unicode = result;
90 return text_utf8;
91 }
85 92 } }
86 93
87 void *
88 hb_utf_ptr_offset_utf8(void *text, unsigned offset)
94 void *hb_utf_ptr_offset_utf8(void *text, unsigned offset)
89 95 { {
90 uint8_t *text_utf8 = text;
91 return text_utf8 + offset;
96 uint8_t *text_utf8;
97
98 text_utf8 = text;
99 return text_utf8 + offset;
92 100 } }
93
94 unsigned
95 hb_utf_strlen_utf8(void *text)
101
102 unsigned hb_utf_strlen_utf8(void *text)
96 103 { {
97 return strlen(text);
104 return strlen(text);
98 105 } }
99 106
100 unsigned
101 hb_utf_diff_utf8(void *a, void *b)
107 unsigned hb_utf_diff_utf8(void *a, void *b)
102 108 { {
103 uint8_t *a_utf8 = a;
104 uint8_t *b_utf8 = b;
105 return a_utf8 - b_utf8;
109 uint8_t *a_utf8;
110 uint8_t *b_utf8;
111
112 a_utf8 = a;
113 b_utf8 = b;
114 return a_utf8 - b_utf8;
106 115 } }
107 116
108 //------------------------------------------------------------------------------
109 //utf16
110 void *
111 hb_utf_next_utf16(void *text,
112 void *end,
113 hb_codepoint_t *unicode)
117 /*----------------------------------------------------------------------------*/
118 /*utf16*/
119 void *hb_utf_next_utf16(void *text, void *end, hb_codepoint_t * unicode)
114 120 { {
115 uint16_t *text_utf16 = text;
116 uint16_t *end_utf16 = end;
117
118 hb_codepoint_t c = *text_utf16++;
119
120 if (hb_codepoint_in_range(c, 0xd800, 0xdbff)) {
121 //high surrogate
122 hb_codepoint_t l;
123 if (text_utf16 < end_utf16 && ((l = *text_utf16),
124 hb_codepoint_in_range(l, 0xdc00, 0xdfff))) {
125 //low surrogate
126 *unicode = (c << 10) + l - ((0xd800 << 10) - 0x10000 + 0xdc00);
127 text_utf16++;
128 } else
129 *unicode = -1;
130 } else
131 *unicode = c;
132 return text_utf16;
121 uint16_t *text_utf16;
122 uint16_t *end_utf16;
123 hb_codepoint_t c;
124
125 text_utf16 = text;
126 end_utf16 = end;
127 c = *text_utf16++;
128
129 if (hb_codepoint_in_range(c, 0xd800, 0xdbff)) {
130 /*high surrogate */
131 hb_codepoint_t l;
132 if (text_utf16 < end_utf16
133 && ((l = *text_utf16),
134 hb_codepoint_in_range(l, 0xdc00, 0xdfff))) {
135 /*low surrogate */
136 *unicode =
137 (c << 10) + l - ((0xd800 << 10) - 0x10000 + 0xdc00);
138 text_utf16++;
139 } else
140 *unicode = -1;
141 } else
142 *unicode = c;
143 return text_utf16;
133 144 } }
134 145
135 void *
136 hb_utf_prev_utf16(void *text,
137 void *start,
138 hb_codepoint_t *unicode)
146 void *hb_utf_prev_utf16(void *text, void *start, hb_codepoint_t * unicode)
139 147 { {
140 uint16_t *text_utf16 = text;
141 uint16_t *start_utf16 = start;
142 hb_codepoint_t c = *--text_utf16;
143
144 if (hb_codepoint_in_range(c, 0xdc00, 0xdfff)) {
145 //low surrogate
146 hb_codepoint_t h;
147 if (start_utf16 < text_utf16
148 && ((h = *(text_utf16 - 1)), hb_codepoint_in_range(h, 0xd800, 0xdbff))) {
149 //high surrogate
150 *unicode = (h << 10) + c - ((0xd800 << 10) - 0x10000 + 0xdc00);
151 text_utf16--;
152 } else
153 *unicode = -1;
154 } else
155 *unicode = c;
156 return text_utf16;
148 uint16_t *text_utf16;
149 uint16_t *start_utf16;
150 hb_codepoint_t c;
151
152 text_utf16 = text;
153 start_utf16 = start;
154 c = *--text_utf16;
155
156 if (hb_codepoint_in_range(c, 0xdc00, 0xdfff)) {
157 /*low surrogate */
158 hb_codepoint_t h;
159 if (start_utf16 < text_utf16
160 && ((h = *(text_utf16 - 1)),
161 hb_codepoint_in_range(h, 0xd800, 0xdbff))) {
162 /*high surrogate */
163 *unicode =
164 (h << 10) + c - ((0xd800 << 10) - 0x10000 + 0xdc00);
165 text_utf16--;
166 } else
167 *unicode = -1;
168 } else
169 *unicode = c;
170 return text_utf16;
157 171 } }
158 172
159 void *
160 hb_utf_ptr_offset_utf16(void *text, unsigned offset)
173 void *hb_utf_ptr_offset_utf16(void *text, unsigned offset)
161 174 { {
162 uint16_t *text_utf16 = text;
163 return text_utf16 + offset;
175 uint16_t *text_utf16;
176
177 text_utf16 = text;
178 return text_utf16 + offset;
164 179 } }
165 180
166 unsigned
167 hb_utf_strlen_utf16(void *text)
181 unsigned hb_utf_strlen_utf16(void *text)
168 182 { {
169 uint16_t *text_utf16 = text;
170
171 unsigned l = 0;
172 while (*text_utf16++) l++;
173 return l;
183 uint16_t *text_utf16;
184 unsigned l;
185
186 text_utf16 = text;
187 l = 0;
188 while (*text_utf16++)
189 l++;
190 return l;
174 191 } }
175 192
176 unsigned
177 hb_utf_diff_utf16(void *a, void *b)
193 unsigned hb_utf_diff_utf16(void *a, void *b)
178 194 { {
179 uint16_t *a_utf16 = a;
180 uint16_t *b_utf16 = b;
181 return a_utf16 - b_utf16;
195 uint16_t *a_utf16;
196 uint16_t *b_utf16;
197
198 a_utf16 = a;
199 b_utf16 = b;
200 return a_utf16 - b_utf16;
182 201 } }
183 //------------------------------------------------------------------------------
184 //utf32
185 void *
186 hb_utf_next_utf32(void *text,
187 void *end HB_UNUSED,
188 hb_codepoint_t *unicode)
202
203 /*----------------------------------------------------------------------------*/
204 /*utf32*/
205 void *hb_utf_next_utf32(void *text, void *end HB_UNUSED,
206 hb_codepoint_t * unicode)
189 207 { {
190 uint32_t *text_utf32 = text;
191 *unicode = *text_utf32++;
192 return text_utf32;
208 uint32_t *text_utf32;
209
210 text_utf32 = text;
211 *unicode = *text_utf32++;
212 return text_utf32;
193 213 } }
194 214
195 void *
196 hb_utf_prev_utf32(void *text,
197 void *start HB_UNUSED,
198 hb_codepoint_t *unicode)
215 void *hb_utf_prev_utf32(void *text, void *start HB_UNUSED,
216 hb_codepoint_t * unicode)
199 217 { {
200 uint32_t *text_utf32 = text;
201 *unicode = *--text_utf32;
202 return text_utf32;
218 uint32_t *text_utf32;
219
220 text_utf32 = text;
221 *unicode = *--text_utf32;
222 return text_utf32;
203 223 } }
204 224
205 void *
206 hb_utf_ptr_offset_utf32(void *text, unsigned offset)
225 void *hb_utf_ptr_offset_utf32(void *text, unsigned offset)
207 226 { {
208 uint32_t *text_utf32 = text;
209 return text_utf32 + offset;
227 uint32_t *text_utf32;
228
229 text_utf32 = text;
230 return text_utf32 + offset;
210 231 } }
211 232
212 unsigned
213 hb_utf_strlen_utf32(void *text)
233 unsigned hb_utf_strlen_utf32(void *text)
214 234 { {
215 uint32_t *text_utf32 = text;
216
217 unsigned l = 0;
218 while (*text_utf32++) l++;
219 return l;
235 uint32_t *text_utf32;
236 unsigned l;
237
238 text_utf32 = text;
239 l = 0;
240 while (*text_utf32++)
241 l++;
242 return l;
220 243 } }
221 244
222 unsigned
223 hb_utf_diff_utf32(void *a, void *b)
245 unsigned hb_utf_diff_utf32(void *a, void *b)
224 246 { {
225 uint32_t *a_utf32 = a;
226 uint32_t *b_utf32 = b;
227 return a_utf32 - b_utf32;
247 uint32_t *a_utf32;
248 uint32_t *b_utf32;
249
250 a_utf32 = a;
251 b_utf32 = b;
252 return a_utf32 - b_utf32;
228 253 } }
File hb-utf-private.h changed (mode: 100644) (index 636ce35..dca4a18)
1 1 #ifndef HB_UTF_PRIVATE_H #ifndef HB_UTF_PRIVATE_H
2 2 #define HB_UTF_PRIVATE_H #define HB_UTF_PRIVATE_H
3 //------------------------------------------------------------------------------
4 //utf8
5 void *
6 hb_utf_next_utf8(void *text,
7 void *end,
8 hb_codepoint_t *unicode);
9 void *
10 hb_utf_prev_utf8(void *text,
11 void *start,
12 hb_codepoint_t *unicode);
13 void *
14 hb_utf_ptr_offset_utf8(void *text, unsigned offset);
15 unsigned
16 hb_utf_strlen_utf8(void *text);
17 unsigned
18 hb_utf_diff_utf8(void *a, void *b);
3 /*----------------------------------------------------------------------------*/
4 /*utf8*/
5 void *hb_utf_next_utf8(void *text, void *end, hb_codepoint_t * unicode);
6 void *hb_utf_prev_utf8(void *text, void *start, hb_codepoint_t * unicode);
7 void *hb_utf_ptr_offset_utf8(void *text, unsigned offset);
8 unsigned hb_utf_strlen_utf8(void *text);
9 unsigned hb_utf_diff_utf8(void *a, void *b);
19 10
20 //------------------------------------------------------------------------------
21 //utf16
22 void *
23 hb_utf_next_utf16(void *text,
24 void *end,
25 hb_codepoint_t *unicode);
26 void *
27 hb_utf_prev_utf16(void *text,
28 void *start,
29 hb_codepoint_t *unicode);
30 void *
31 hb_utf_ptr_offset_utf16(void *text, unsigned offset);
32 unsigned
33 hb_utf_strlen_utf16(void *text);
34 unsigned
35 hb_utf_diff_utf16(void *a, void *b);
11 /*----------------------------------------------------------------------------*/
12 /*utf16*/
13 void *hb_utf_next_utf16(void *text, void *end, hb_codepoint_t * unicode);
14 void *hb_utf_prev_utf16(void *text, void *start, hb_codepoint_t * unicode);
15 void *hb_utf_ptr_offset_utf16(void *text, unsigned offset);
16 unsigned hb_utf_strlen_utf16(void *text);
17 unsigned hb_utf_diff_utf16(void *a, void *b);
36 18
37 //------------------------------------------------------------------------------
38 //utf32
39 void *
40 hb_utf_next_utf32(void *text,
41 void *end HB_UNUSED,
42 hb_codepoint_t *unicode);
43 void *
44 hb_utf_prev_utf32(void *text,
45 void *start HB_UNUSED,
46 hb_codepoint_t *unicode);
47 void *
48 hb_utf_ptr_offset_utf32(void *text, unsigned offset);
49 unsigned
50 hb_utf_strlen_utf32(void *text);
51 unsigned
52 hb_utf_diff_utf32(void *a, void *b);
19 /*----------------------------------------------------------------------------*/
20 /*utf32*/
21 void *hb_utf_next_utf32(void *text, void *end HB_UNUSED,
22 hb_codepoint_t * unicode);
23 void *hb_utf_prev_utf32(void *text, void *start HB_UNUSED,
24 hb_codepoint_t * unicode);
25 void *hb_utf_ptr_offset_utf32(void *text, unsigned offset);
26 unsigned hb_utf_strlen_utf32(void *text);
27 unsigned hb_utf_diff_utf32(void *a, void *b);
53 28 #endif #endif
File hb-version.h.in changed (mode: 100644) (index 43634f9..0ffd889)
... ... HB_BEGIN_DECLS
42 42
43 43 #define HB_VERSION_STRING "@HB_VERSION@" #define HB_VERSION_STRING "@HB_VERSION@"
44 44
45 #define HB_VERSION_CHECK(major,minor,micro) \
46 ((major)*10000+(minor)*100+(micro) >= \
45 #define HB_VERSION_ATLEAST(major,minor,micro) \
46 ((major)*10000+(minor)*100+(micro) <= \
47 47 HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO)
48 48
49 49
50 void
50 HB_EXTERN void
51 51 hb_version (unsigned int *major, hb_version (unsigned int *major,
52 52 unsigned int *minor, unsigned int *minor,
53 53 unsigned int *micro); unsigned int *micro);
54 54
55 const char *
55 HB_EXTERN const char *
56 56 hb_version_string (void); hb_version_string (void);
57 57
58 hb_bool_t
59 hb_version_check (unsigned int major,
60 unsigned int minor,
61 unsigned int micro);
58 HB_EXTERN hb_bool_t
59 hb_version_atleast (unsigned int major,
60 unsigned int minor,
61 unsigned int micro);
62 62
63 63
64 64 HB_END_DECLS HB_END_DECLS
File hb.h changed (mode: 100644) (index c5a938a..7402034)
28 28 #define HB_H #define HB_H
29 29 #define HB_H_IN #define HB_H_IN
30 30
31 #ifndef HB_EXTERN
32 #define HB_EXTERN extern
33 #endif
34
31 35 #include "hb-blob.h" #include "hb-blob.h"
32 36 #include "hb-buffer.h" #include "hb-buffer.h"
33 37 #include "hb-common.h" #include "hb-common.h"
File make changed (mode: 100755) (index 01bff5e..93ec1ea)
... ... export LC_ALL
8 8
9 9 major=0 major=0
10 10 minor=9 minor=9
11 micro=20
11 micro=30
12 12 slib_file_name=libharfbuzz.so.$major.$minor.$micro slib_file_name=libharfbuzz.so.$major.$minor.$micro
13 13 slib_soname=libharfbuzz.so.$major slib_soname=libharfbuzz.so.$major
14 14
15 15 api_hdrs=' api_hdrs='
16 hb.h
17 16 hb-blob.h hb-blob.h
18 17 hb-buffer.h hb-buffer.h
19 18 hb-common.h hb-common.h
19 hb-coretext.h
20 20 hb-deprecated.h hb-deprecated.h
21 21 hb-face.h hb-face.h
22 22 hb-font.h hb-font.h
23 hb-set.h
24 hb-shape.h
25 hb-shape-plan.h
26 hb-unicode.h
27 23 hb-ft.h hb-ft.h
28 hb-graphite2.h
29 hb-coretext.h
30 hb-uniscribe.h
31 hb-icu.h
32 24 hb-glib.h hb-glib.h
33 25 hb-gobject.h hb-gobject.h
34 26 hb-gobject-structs.h hb-gobject-structs.h
27 hb-graphite2.h
28 hb.h
29 hb-icu.h
30 hb-ot-font.h
35 31 hb-ot.h hb-ot.h
36 32 hb-ot-layout.h hb-ot-layout.h
33 hb-ot-shape.h
37 34 hb-ot-tag.h hb-ot-tag.h
35 hb-set.h
36 hb-shape.h
37 hb-shape-plan.h
38 hb-unicode.h
39 hb-uniscribe.h
38 40 ' '
39 41
40 42 srcs=' srcs='
 
... ... CMDLINE_SET="
128 130 " "
129 131
130 132 #path defaults #path defaults
131 prefix_default=''
133 prefix_default='/usr/local'
132 134 incdir_default='$prefix/include' incdir_default='$prefix/include'
133 135 libdir_default='$prefix/lib' libdir_default='$prefix/lib'
134 136 pkg_config_sysroot='' pkg_config_sysroot=''
135 137
136 138 #command lin set defaults #command lin set defaults
137 slib_cc_default='gcc -Wall -Wextra -Wno-missing-field-initializers -c -fPIC -fpic -O0 -std=c99'
139 #for your information: harbuzz C API is shit when enabling c90 pedantic compilation
140 slib_cc_default='gcc -Wall -Wextra -Wno-missing-field-initializers -c -fpic -O0 -std=c90'
138 141 slib_ccld_default="gcc -shared -Wl,-soname=$slib_soname" slib_ccld_default="gcc -shared -Wl,-soname=$slib_soname"
139 142 ln_s_default='ln -sf' ln_s_default='ln -sf'
140 143
 
... ... $(pkg-config --cflags glib-2.0)
202 205
203 206 #generate the version header file #generate the version header file
204 207 sed -e " sed -e "
205 s/@HB_VERSION_MAJOR@/$major)/
208 s/@HB_VERSION_MAJOR@/$major/
206 209 s/@HB_VERSION_MINOR@/$minor/ s/@HB_VERSION_MINOR@/$minor/
207 210 s/@HB_VERSION_MICRO@/$micro/ s/@HB_VERSION_MICRO@/$micro/
208 211 s/@HB_VERSION@/$major.$minor.$micro/ s/@HB_VERSION@/$major.$minor.$micro/
 
... ... eval "e_libdir=$libdir"
214 217
215 218 #generate the pkg-config file #generate the pkg-config file
216 219 sed -e " sed -e "
220 s:%prefix%:$prefix:
221 s:%exec_prefix%:$prefix:
217 222 s:%libdir%:$e_libdir: s:%libdir%:$e_libdir:
218 223 s:%includedir%:$e_incdir: s:%includedir%:$e_incdir:
219 224 s:%VERSION%:$major.$minor.$micro: s:%VERSION%:$major.$minor.$micro:
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/sylware/charfbuzz

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/sylware/charfbuzz

Clone this repository using git:
git clone git://git.rocketgit.com/user/sylware/charfbuzz

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main