• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2009  Red Hat, Inc.
3  * Copyright © 2011  Codethink Limited
4  * Copyright © 2010,2011,2012  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 hb_unicode_combining_class_t
hb_unicode_combining_class_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,hb_codepoint_t unicode HB_UNUSED,void * user_data HB_UNUSED)42 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   return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
47 }
48 
49 static unsigned int
hb_unicode_eastasian_width_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,hb_codepoint_t unicode HB_UNUSED,void * user_data HB_UNUSED)50 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   return 1;
55 }
56 
57 static hb_unicode_general_category_t
hb_unicode_general_category_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,hb_codepoint_t unicode HB_UNUSED,void * user_data HB_UNUSED)58 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   return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
63 }
64 
65 static hb_codepoint_t
hb_unicode_mirroring_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,hb_codepoint_t unicode HB_UNUSED,void * user_data HB_UNUSED)66 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   return unicode;
71 }
72 
73 static hb_script_t
hb_unicode_script_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,hb_codepoint_t unicode HB_UNUSED,void * user_data HB_UNUSED)74 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   return HB_SCRIPT_UNKNOWN;
79 }
80 
81 static hb_bool_t
hb_unicode_compose_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,hb_codepoint_t a HB_UNUSED,hb_codepoint_t b HB_UNUSED,hb_codepoint_t * ab HB_UNUSED,void * user_data HB_UNUSED)82 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   return false;
89 }
90 
91 static hb_bool_t
hb_unicode_decompose_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,hb_codepoint_t ab HB_UNUSED,hb_codepoint_t * a HB_UNUSED,hb_codepoint_t * b HB_UNUSED,void * user_data HB_UNUSED)92 hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
93 			  hb_codepoint_t      ab        HB_UNUSED,
94 			  hb_codepoint_t     *a         HB_UNUSED,
95 			  hb_codepoint_t     *b         HB_UNUSED,
96 			  void               *user_data HB_UNUSED)
97 {
98   return false;
99 }
100 
101 
102 static unsigned int
hb_unicode_decompose_compatibility_nil(hb_unicode_funcs_t * ufuncs HB_UNUSED,hb_codepoint_t u HB_UNUSED,hb_codepoint_t * decomposed HB_UNUSED,void * user_data HB_UNUSED)103 hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs     HB_UNUSED,
104 					hb_codepoint_t      u          HB_UNUSED,
105 					hb_codepoint_t     *decomposed HB_UNUSED,
106 					void               *user_data  HB_UNUSED)
107 {
108   return 0;
109 }
110 
111 
112 #define HB_UNICODE_FUNCS_IMPLEMENT_SET \
113   HB_UNICODE_FUNCS_IMPLEMENT (glib) \
114   HB_UNICODE_FUNCS_IMPLEMENT (icu) \
115   HB_UNICODE_FUNCS_IMPLEMENT (ucdn) \
116   HB_UNICODE_FUNCS_IMPLEMENT (nil) \
117   /* ^--- Add new callbacks before nil */
118 
119 #define hb_nil_get_unicode_funcs hb_unicode_funcs_get_empty
120 
121 /* Prototype them all */
122 #define HB_UNICODE_FUNCS_IMPLEMENT(set) \
123 extern "C" hb_unicode_funcs_t *hb_##set##_get_unicode_funcs (void);
124 HB_UNICODE_FUNCS_IMPLEMENT_SET
125 #undef HB_UNICODE_FUNCS_IMPLEMENT
126 
127 
128 hb_unicode_funcs_t *
hb_unicode_funcs_get_default(void)129 hb_unicode_funcs_get_default (void)
130 {
131 #define HB_UNICODE_FUNCS_IMPLEMENT(set) \
132   return hb_##set##_get_unicode_funcs ();
133 
134 #ifdef HAVE_GLIB
135   HB_UNICODE_FUNCS_IMPLEMENT(glib)
136 #elif defined(HAVE_ICU)
137   HB_UNICODE_FUNCS_IMPLEMENT(icu)
138 #elif defined(HAVE_UCDN)
139   HB_UNICODE_FUNCS_IMPLEMENT(ucdn)
140 #else
141 #define HB_UNICODE_FUNCS_NIL 1
142   HB_UNICODE_FUNCS_IMPLEMENT(nil)
143 #endif
144 
145 #undef HB_UNICODE_FUNCS_IMPLEMENT
146 }
147 
148 #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
149 #pragma message("Could not find any Unicode functions implementation, you have to provide your own.")
150 #pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS.")
151 #endif
152 
153 hb_unicode_funcs_t *
hb_unicode_funcs_create(hb_unicode_funcs_t * parent)154 hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
155 {
156   hb_unicode_funcs_t *ufuncs;
157 
158   if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
159     return hb_unicode_funcs_get_empty ();
160 
161   if (!parent)
162     parent = hb_unicode_funcs_get_empty ();
163 
164   hb_unicode_funcs_make_immutable (parent);
165   ufuncs->parent = hb_unicode_funcs_reference (parent);
166 
167   ufuncs->func = parent->func;
168 
169   /* We can safely copy user_data from parent since we hold a reference
170    * onto it and it's immutable.  We should not copy the destroy notifiers
171    * though. */
172   ufuncs->user_data = parent->user_data;
173 
174   return ufuncs;
175 }
176 
177 
178 const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
179   HB_OBJECT_HEADER_STATIC,
180 
181   NULL, /* parent */
182   true, /* immutable */
183   {
184 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
185     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
186 #undef HB_UNICODE_FUNC_IMPLEMENT
187   }
188 };
189 
190 hb_unicode_funcs_t *
hb_unicode_funcs_get_empty(void)191 hb_unicode_funcs_get_empty (void)
192 {
193   return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
194 }
195 
196 hb_unicode_funcs_t *
hb_unicode_funcs_reference(hb_unicode_funcs_t * ufuncs)197 hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
198 {
199   return hb_object_reference (ufuncs);
200 }
201 
202 void
hb_unicode_funcs_destroy(hb_unicode_funcs_t * ufuncs)203 hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
204 {
205   if (!hb_object_destroy (ufuncs)) return;
206 
207 #define HB_UNICODE_FUNC_IMPLEMENT(name) \
208   if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
209     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
210 #undef HB_UNICODE_FUNC_IMPLEMENT
211 
212   hb_unicode_funcs_destroy (ufuncs->parent);
213 
214   free (ufuncs);
215 }
216 
217 hb_bool_t
hb_unicode_funcs_set_user_data(hb_unicode_funcs_t * ufuncs,hb_user_data_key_t * key,void * data,hb_destroy_func_t destroy,hb_bool_t replace)218 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
219 			        hb_user_data_key_t *key,
220 			        void *              data,
221 			        hb_destroy_func_t   destroy,
222 				hb_bool_t           replace)
223 {
224   return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
225 }
226 
227 void *
hb_unicode_funcs_get_user_data(hb_unicode_funcs_t * ufuncs,hb_user_data_key_t * key)228 hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
229 			        hb_user_data_key_t *key)
230 {
231   return hb_object_get_user_data (ufuncs, key);
232 }
233 
234 
235 void
hb_unicode_funcs_make_immutable(hb_unicode_funcs_t * ufuncs)236 hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
237 {
238   if (hb_object_is_inert (ufuncs))
239     return;
240 
241   ufuncs->immutable = true;
242 }
243 
244 hb_bool_t
hb_unicode_funcs_is_immutable(hb_unicode_funcs_t * ufuncs)245 hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
246 {
247   return ufuncs->immutable;
248 }
249 
250 hb_unicode_funcs_t *
hb_unicode_funcs_get_parent(hb_unicode_funcs_t * ufuncs)251 hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
252 {
253   return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
254 }
255 
256 
257 #define HB_UNICODE_FUNC_IMPLEMENT(name)						\
258 										\
259 void										\
260 hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
261 				    hb_unicode_##name##_func_t	    func,	\
262 				    void			   *user_data,	\
263 				    hb_destroy_func_t		    destroy)	\
264 {										\
265   if (ufuncs->immutable)							\
266     return;									\
267 										\
268   if (ufuncs->destroy.name)							\
269     ufuncs->destroy.name (ufuncs->user_data.name);				\
270 										\
271   if (func) {									\
272     ufuncs->func.name = func;							\
273     ufuncs->user_data.name = user_data;						\
274     ufuncs->destroy.name = destroy;						\
275   } else {									\
276     ufuncs->func.name = ufuncs->parent->func.name;				\
277     ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
278     ufuncs->destroy.name = NULL;						\
279   }										\
280 }
281 
282 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
283 #undef HB_UNICODE_FUNC_IMPLEMENT
284 
285 
286 #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)				\
287 										\
288 return_type									\
289 hb_unicode_##name (hb_unicode_funcs_t *ufuncs,					\
290 		   hb_codepoint_t      unicode)					\
291 {										\
292   return ufuncs->name (unicode);						\
293 }
294 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
295 #undef HB_UNICODE_FUNC_IMPLEMENT
296 
297 hb_bool_t
hb_unicode_compose(hb_unicode_funcs_t * ufuncs,hb_codepoint_t a,hb_codepoint_t b,hb_codepoint_t * ab)298 hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
299 		    hb_codepoint_t      a,
300 		    hb_codepoint_t      b,
301 		    hb_codepoint_t     *ab)
302 {
303   return ufuncs->compose (a, b, ab);
304 }
305 
306 hb_bool_t
hb_unicode_decompose(hb_unicode_funcs_t * ufuncs,hb_codepoint_t ab,hb_codepoint_t * a,hb_codepoint_t * b)307 hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
308 		      hb_codepoint_t      ab,
309 		      hb_codepoint_t     *a,
310 		      hb_codepoint_t     *b)
311 {
312   return ufuncs->decompose (ab, a, b);
313 }
314 
315 unsigned int
hb_unicode_decompose_compatibility(hb_unicode_funcs_t * ufuncs,hb_codepoint_t u,hb_codepoint_t * decomposed)316 hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
317 				    hb_codepoint_t      u,
318 				    hb_codepoint_t     *decomposed)
319 {
320   return ufuncs->decompose_compatibility (u, decomposed);
321 }
322 
323 
324 /* See hb-unicode-private.hh for details. */
325 const uint8_t
326 _hb_modified_combining_class[256] =
327 {
328   0, /* HB_UNICODE_COMBINING_CLASS_NOT_REORDERED */
329   1, /* HB_UNICODE_COMBINING_CLASS_OVERLAY */
330   2, 3, 4, 5, 6,
331   7, /* HB_UNICODE_COMBINING_CLASS_NUKTA */
332   8, /* HB_UNICODE_COMBINING_CLASS_KANA_VOICING */
333   9, /* HB_UNICODE_COMBINING_CLASS_VIRAMA */
334 
335   /* Hebrew */
336   HB_MODIFIED_COMBINING_CLASS_CCC10,
337   HB_MODIFIED_COMBINING_CLASS_CCC11,
338   HB_MODIFIED_COMBINING_CLASS_CCC12,
339   HB_MODIFIED_COMBINING_CLASS_CCC13,
340   HB_MODIFIED_COMBINING_CLASS_CCC14,
341   HB_MODIFIED_COMBINING_CLASS_CCC15,
342   HB_MODIFIED_COMBINING_CLASS_CCC16,
343   HB_MODIFIED_COMBINING_CLASS_CCC17,
344   HB_MODIFIED_COMBINING_CLASS_CCC18,
345   HB_MODIFIED_COMBINING_CLASS_CCC19,
346   HB_MODIFIED_COMBINING_CLASS_CCC20,
347   HB_MODIFIED_COMBINING_CLASS_CCC21,
348   HB_MODIFIED_COMBINING_CLASS_CCC22,
349   HB_MODIFIED_COMBINING_CLASS_CCC23,
350   HB_MODIFIED_COMBINING_CLASS_CCC24,
351   HB_MODIFIED_COMBINING_CLASS_CCC25,
352   HB_MODIFIED_COMBINING_CLASS_CCC26,
353 
354   /* Arabic */
355   HB_MODIFIED_COMBINING_CLASS_CCC27,
356   HB_MODIFIED_COMBINING_CLASS_CCC28,
357   HB_MODIFIED_COMBINING_CLASS_CCC29,
358   HB_MODIFIED_COMBINING_CLASS_CCC30,
359   HB_MODIFIED_COMBINING_CLASS_CCC31,
360   HB_MODIFIED_COMBINING_CLASS_CCC32,
361   HB_MODIFIED_COMBINING_CLASS_CCC33,
362   HB_MODIFIED_COMBINING_CLASS_CCC34,
363   HB_MODIFIED_COMBINING_CLASS_CCC35,
364 
365   /* Syriac */
366   HB_MODIFIED_COMBINING_CLASS_CCC36,
367 
368   37, 38, 39,
369   40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
370   60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
371   80, 81, 82, 83,
372 
373   /* Telugu */
374   HB_MODIFIED_COMBINING_CLASS_CCC84,
375   85, 86, 87, 88, 89, 90,
376   HB_MODIFIED_COMBINING_CLASS_CCC91,
377   92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
378 
379   /* Thai */
380   HB_MODIFIED_COMBINING_CLASS_CCC103,
381   104, 105, 106,
382   HB_MODIFIED_COMBINING_CLASS_CCC107,
383   108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
384 
385   /* Lao */
386   HB_MODIFIED_COMBINING_CLASS_CCC118,
387   119, 120, 121,
388   HB_MODIFIED_COMBINING_CLASS_CCC122,
389   123, 124, 125, 126, 127, 128,
390 
391   /* Tibetan */
392   HB_MODIFIED_COMBINING_CLASS_CCC129,
393   HB_MODIFIED_COMBINING_CLASS_CCC130,
394   131,
395   HB_MODIFIED_COMBINING_CLASS_CCC132,
396   133, 134, 135, 136, 137, 138, 139,
397 
398 
399   140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
400   150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
401   160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
402   170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
403   180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
404   190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
405 
406   200, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT */
407   201,
408   202, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW */
409   203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
410   214, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE */
411   215,
412   216, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT */
413   217,
414   218, /* HB_UNICODE_COMBINING_CLASS_BELOW_LEFT */
415   219,
416   220, /* HB_UNICODE_COMBINING_CLASS_BELOW */
417   221,
418   222, /* HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT */
419   223,
420   224, /* HB_UNICODE_COMBINING_CLASS_LEFT */
421   225,
422   226, /* HB_UNICODE_COMBINING_CLASS_RIGHT */
423   227,
424   228, /* HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT */
425   229,
426   230, /* HB_UNICODE_COMBINING_CLASS_ABOVE */
427   231,
428   232, /* HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT */
429   233, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW */
430   234, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE */
431   235, 236, 237, 238, 239,
432   240, /* HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT */
433   241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
434   255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
435 };
436