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-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-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-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-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 |
} |
} |