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