1 : /*
2 : * Copyright © 2009 Red Hat, Inc.
3 : * Copyright © 2011 Codethink Limited
4 : * Copyright © 2010,2011 Google, Inc.
5 : *
6 : * This is part of HarfBuzz, a text shaping library.
7 : *
8 : * Permission is hereby granted, without written agreement and without
9 : * license or royalty fees, to use, copy, modify, and distribute this
10 : * software and its documentation for any purpose, provided that the
11 : * above copyright notice and the following two paragraphs appear in
12 : * all copies of this software.
13 : *
14 : * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
15 : * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
16 : * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
17 : * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
18 : * DAMAGE.
19 : *
20 : * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
21 : * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 : * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
23 : * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
24 : * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
25 : *
26 : * Red Hat Author(s): Behdad Esfahbod
27 : * Codethink Author(s): Ryan Lortie
28 : * Google Author(s): Behdad Esfahbod
29 : */
30 :
31 : #include "hb-private.hh"
32 :
33 : #include "hb-unicode-private.hh"
34 :
35 :
36 :
37 : /*
38 : * hb_unicode_funcs_t
39 : */
40 :
41 : static unsigned int
42 0 : hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
43 : hb_codepoint_t unicode HB_UNUSED,
44 : void *user_data HB_UNUSED)
45 : {
46 0 : return 0;
47 : }
48 :
49 : static unsigned int
50 0 : hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
51 : hb_codepoint_t unicode HB_UNUSED,
52 : void *user_data HB_UNUSED)
53 : {
54 0 : return 1;
55 : }
56 :
57 : static hb_unicode_general_category_t
58 0 : hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
59 : hb_codepoint_t unicode HB_UNUSED,
60 : void *user_data HB_UNUSED)
61 : {
62 0 : return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
63 : }
64 :
65 : static hb_codepoint_t
66 0 : hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
67 : hb_codepoint_t unicode HB_UNUSED,
68 : void *user_data HB_UNUSED)
69 : {
70 0 : return unicode;
71 : }
72 :
73 : static hb_script_t
74 0 : hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
75 : hb_codepoint_t unicode HB_UNUSED,
76 : void *user_data HB_UNUSED)
77 : {
78 0 : return HB_SCRIPT_UNKNOWN;
79 : }
80 :
81 : static hb_bool_t
82 0 : hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
83 : hb_codepoint_t a HB_UNUSED,
84 : hb_codepoint_t b HB_UNUSED,
85 : hb_codepoint_t *ab HB_UNUSED,
86 : void *user_data HB_UNUSED)
87 : {
88 : /* TODO handle Hangul jamo here? */
89 0 : return FALSE;
90 : }
91 :
92 : static hb_bool_t
93 0 : hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
94 : hb_codepoint_t ab HB_UNUSED,
95 : hb_codepoint_t *a HB_UNUSED,
96 : hb_codepoint_t *b HB_UNUSED,
97 : void *user_data HB_UNUSED)
98 : {
99 : /* TODO handle Hangul jamo here? */
100 0 : return FALSE;
101 : }
102 :
103 :
104 : hb_unicode_funcs_t _hb_unicode_funcs_nil = {
105 : HB_OBJECT_HEADER_STATIC,
106 :
107 : NULL, /* parent */
108 : TRUE, /* immutable */
109 : {
110 : #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
111 : HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
112 : #undef HB_UNICODE_FUNC_IMPLEMENT
113 : }
114 1464 : };
115 :
116 :
117 : hb_unicode_funcs_t *
118 0 : hb_unicode_funcs_get_default (void)
119 : {
120 0 : return &_hb_unicode_funcs_default;
121 : }
122 :
123 : hb_unicode_funcs_t *
124 0 : hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
125 : {
126 : hb_unicode_funcs_t *ufuncs;
127 :
128 0 : if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
129 0 : return &_hb_unicode_funcs_nil;
130 :
131 0 : if (!parent)
132 0 : parent = &_hb_unicode_funcs_nil;
133 :
134 0 : hb_unicode_funcs_make_immutable (parent);
135 0 : ufuncs->parent = hb_unicode_funcs_reference (parent);
136 :
137 0 : ufuncs->func = parent->func;
138 :
139 : /* We can safely copy user_data from parent since we hold a reference
140 : * onto it and it's immutable. We should not copy the destroy notifiers
141 : * though. */
142 0 : ufuncs->user_data = parent->user_data;
143 :
144 0 : return ufuncs;
145 : }
146 :
147 : hb_unicode_funcs_t *
148 0 : hb_unicode_funcs_get_empty (void)
149 : {
150 0 : return &_hb_unicode_funcs_nil;
151 : }
152 :
153 : hb_unicode_funcs_t *
154 0 : hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
155 : {
156 0 : return hb_object_reference (ufuncs);
157 : }
158 :
159 : void
160 0 : hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
161 : {
162 0 : if (!hb_object_destroy (ufuncs)) return;
163 :
164 : #define HB_UNICODE_FUNC_IMPLEMENT(name) \
165 : if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
166 0 : HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
167 : #undef HB_UNICODE_FUNC_IMPLEMENT
168 :
169 0 : hb_unicode_funcs_destroy (ufuncs->parent);
170 :
171 0 : free (ufuncs);
172 : }
173 :
174 : hb_bool_t
175 0 : hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
176 : hb_user_data_key_t *key,
177 : void * data,
178 : hb_destroy_func_t destroy,
179 : hb_bool_t replace)
180 : {
181 0 : return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
182 : }
183 :
184 : void *
185 0 : hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
186 : hb_user_data_key_t *key)
187 : {
188 0 : return hb_object_get_user_data (ufuncs, key);
189 : }
190 :
191 :
192 : void
193 0 : hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
194 : {
195 0 : if (hb_object_is_inert (ufuncs))
196 0 : return;
197 :
198 0 : ufuncs->immutable = TRUE;
199 : }
200 :
201 : hb_bool_t
202 0 : hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
203 : {
204 0 : return ufuncs->immutable;
205 : }
206 :
207 : hb_unicode_funcs_t *
208 0 : hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
209 : {
210 0 : return ufuncs->parent ? ufuncs->parent : &_hb_unicode_funcs_nil;
211 : }
212 :
213 :
214 : #define HB_UNICODE_FUNC_IMPLEMENT(name) \
215 : \
216 : void \
217 : hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
218 : hb_unicode_##name##_func_t func, \
219 : void *user_data, \
220 : hb_destroy_func_t destroy) \
221 : { \
222 : if (ufuncs->immutable) \
223 : return; \
224 : \
225 : if (ufuncs->destroy.name) \
226 : ufuncs->destroy.name (ufuncs->user_data.name); \
227 : \
228 : if (func) { \
229 : ufuncs->func.name = func; \
230 : ufuncs->user_data.name = user_data; \
231 : ufuncs->destroy.name = destroy; \
232 : } else { \
233 : ufuncs->func.name = ufuncs->parent->func.name; \
234 : ufuncs->user_data.name = ufuncs->parent->user_data.name; \
235 : ufuncs->destroy.name = NULL; \
236 : } \
237 : }
238 :
239 0 : HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
240 : #undef HB_UNICODE_FUNC_IMPLEMENT
241 :
242 :
243 : #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \
244 : \
245 : return_type \
246 : hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \
247 : hb_codepoint_t unicode) \
248 : { \
249 : return ufuncs->func.name (ufuncs, unicode, ufuncs->user_data.name); \
250 : }
251 0 : HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
252 : #undef HB_UNICODE_FUNC_IMPLEMENT
253 :
254 : hb_bool_t
255 0 : hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
256 : hb_codepoint_t a,
257 : hb_codepoint_t b,
258 : hb_codepoint_t *ab)
259 : {
260 0 : *ab = 0;
261 0 : return ufuncs->func.compose (ufuncs, a, b, ab, ufuncs->user_data.compose);
262 : }
263 :
264 : hb_bool_t
265 0 : hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
266 : hb_codepoint_t ab,
267 : hb_codepoint_t *a,
268 : hb_codepoint_t *b)
269 : {
270 0 : *a = ab; *b = 0;
271 0 : return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose);
272 4392 : }
273 :
|