Revert "Imported Upstream version 1.2.7"
[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 (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 *
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) && defined(HAVE_ICU_BUILTIN)
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 #ifdef _MSC_VER
150 #pragma message("Could not find any Unicode functions implementation, you have to provide your own")
151 #pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS")
152 #else
153 #warning "Could not find any Unicode functions implementation, you have to provide your own"
154 #warning "To suppress this warning, define HB_NO_UNICODE_FUNCS"
155 #endif
156 #endif
157
158 /**
159  * hb_unicode_funcs_create: (Xconstructor)
160  * @parent: (nullable):
161  *
162  * 
163  *
164  * Return value: (transfer full):
165  *
166  * Since: 1.0
167  **/
168 hb_unicode_funcs_t *
169 hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
170 {
171   hb_unicode_funcs_t *ufuncs;
172
173   if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
174     return hb_unicode_funcs_get_empty ();
175
176   if (!parent)
177     parent = hb_unicode_funcs_get_empty ();
178
179   hb_unicode_funcs_make_immutable (parent);
180   ufuncs->parent = hb_unicode_funcs_reference (parent);
181
182   ufuncs->func = parent->func;
183
184   /* We can safely copy user_data from parent since we hold a reference
185    * onto it and it's immutable.  We should not copy the destroy notifiers
186    * though. */
187   ufuncs->user_data = parent->user_data;
188
189   return ufuncs;
190 }
191
192
193 const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
194   HB_OBJECT_HEADER_STATIC,
195
196   NULL, /* parent */
197   true, /* immutable */
198   {
199 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
200     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
201 #undef HB_UNICODE_FUNC_IMPLEMENT
202   }
203 };
204
205 /**
206  * hb_unicode_funcs_get_empty:
207  *
208  * 
209  *
210  * Return value: (transfer full):
211  *
212  * Since: 1.0
213  **/
214 hb_unicode_funcs_t *
215 hb_unicode_funcs_get_empty (void)
216 {
217   return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
218 }
219
220 /**
221  * hb_unicode_funcs_reference: (skip)
222  * @ufuncs: Unicode functions.
223  *
224  * 
225  *
226  * Return value: (transfer full):
227  *
228  * Since: 1.0
229  **/
230 hb_unicode_funcs_t *
231 hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
232 {
233   return hb_object_reference (ufuncs);
234 }
235
236 /**
237  * hb_unicode_funcs_destroy: (skip)
238  * @ufuncs: Unicode functions.
239  *
240  * 
241  *
242  * Since: 1.0
243  **/
244 void
245 hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
246 {
247   if (!hb_object_destroy (ufuncs)) return;
248
249 #define HB_UNICODE_FUNC_IMPLEMENT(name) \
250   if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
251     HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
252 #undef HB_UNICODE_FUNC_IMPLEMENT
253
254   hb_unicode_funcs_destroy (ufuncs->parent);
255
256   free (ufuncs);
257 }
258
259 /**
260  * hb_unicode_funcs_set_user_data: (skip)
261  * @ufuncs: Unicode functions.
262  * @key: 
263  * @data: 
264  * @destroy: 
265  * @replace: 
266  *
267  * 
268  *
269  * Return value: 
270  *
271  * Since: 1.0
272  **/
273 hb_bool_t
274 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
275                                 hb_user_data_key_t *key,
276                                 void *              data,
277                                 hb_destroy_func_t   destroy,
278                                 hb_bool_t           replace)
279 {
280   return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
281 }
282
283 /**
284  * hb_unicode_funcs_get_user_data: (skip)
285  * @ufuncs: Unicode functions.
286  * @key: 
287  *
288  * 
289  *
290  * Return value: (transfer none):
291  *
292  * Since: 1.0
293  **/
294 void *
295 hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
296                                 hb_user_data_key_t *key)
297 {
298   return hb_object_get_user_data (ufuncs, key);
299 }
300
301
302 /**
303  * hb_unicode_funcs_make_immutable:
304  * @ufuncs: Unicode functions.
305  *
306  * 
307  *
308  * Since: 1.0
309  **/
310 void
311 hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
312 {
313   if (unlikely (hb_object_is_inert (ufuncs)))
314     return;
315
316   ufuncs->immutable = true;
317 }
318
319 /**
320  * hb_unicode_funcs_is_immutable:
321  * @ufuncs: Unicode functions.
322  *
323  * 
324  *
325  * Return value: 
326  *
327  * Since: 1.0
328  **/
329 hb_bool_t
330 hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
331 {
332   return ufuncs->immutable;
333 }
334
335 /**
336  * hb_unicode_funcs_get_parent:
337  * @ufuncs: Unicode functions.
338  *
339  * 
340  *
341  * Return value: 
342  *
343  * Since: 1.0
344  **/
345 hb_unicode_funcs_t *
346 hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
347 {
348   return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
349 }
350
351
352 #define HB_UNICODE_FUNC_IMPLEMENT(name)                                         \
353                                                                                 \
354 void                                                                            \
355 hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t             *ufuncs,     \
356                                     hb_unicode_##name##_func_t      func,       \
357                                     void                           *user_data,  \
358                                     hb_destroy_func_t               destroy)    \
359 {                                                                               \
360   if (ufuncs->immutable)                                                        \
361     return;                                                                     \
362                                                                                 \
363   if (ufuncs->destroy.name)                                                     \
364     ufuncs->destroy.name (ufuncs->user_data.name);                              \
365                                                                                 \
366   if (func) {                                                                   \
367     ufuncs->func.name = func;                                                   \
368     ufuncs->user_data.name = user_data;                                         \
369     ufuncs->destroy.name = destroy;                                             \
370   } else {                                                                      \
371     ufuncs->func.name = ufuncs->parent->func.name;                              \
372     ufuncs->user_data.name = ufuncs->parent->user_data.name;                    \
373     ufuncs->destroy.name = NULL;                                                \
374   }                                                                             \
375 }
376
377 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
378 #undef HB_UNICODE_FUNC_IMPLEMENT
379
380
381 #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)                            \
382                                                                                 \
383 return_type                                                                     \
384 hb_unicode_##name (hb_unicode_funcs_t *ufuncs,                                  \
385                    hb_codepoint_t      unicode)                                 \
386 {                                                                               \
387   return ufuncs->name (unicode);                                                \
388 }
389 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
390 #undef HB_UNICODE_FUNC_IMPLEMENT
391
392 /**
393  * hb_unicode_compose:
394  * @ufuncs: Unicode functions.
395  * @a: 
396  * @b: 
397  * @ab: (out):
398  *
399  * 
400  *
401  * Return value: 
402  *
403  * Since: 1.0
404  **/
405 hb_bool_t
406 hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
407                     hb_codepoint_t      a,
408                     hb_codepoint_t      b,
409                     hb_codepoint_t     *ab)
410 {
411   return ufuncs->compose (a, b, ab);
412 }
413
414 /**
415  * hb_unicode_decompose:
416  * @ufuncs: Unicode functions.
417  * @ab: 
418  * @a: (out):
419  * @b: (out):
420  *
421  * 
422  *
423  * Return value: 
424  *
425  * Since: 1.0
426  **/
427 hb_bool_t
428 hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
429                       hb_codepoint_t      ab,
430                       hb_codepoint_t     *a,
431                       hb_codepoint_t     *b)
432 {
433   return ufuncs->decompose (ab, a, b);
434 }
435
436 /**
437  * hb_unicode_decompose_compatibility:
438  * @ufuncs: Unicode functions.
439  * @u: 
440  * @decomposed: (out):
441  *
442  * 
443  *
444  * Return value: 
445  *
446  * Since: 1.0
447  **/
448 unsigned int
449 hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
450                                     hb_codepoint_t      u,
451                                     hb_codepoint_t     *decomposed)
452 {
453   return ufuncs->decompose_compatibility (u, decomposed);
454 }
455
456
457 /* See hb-unicode-private.hh for details. */
458 const uint8_t
459 _hb_modified_combining_class[256] =
460 {
461   0, /* HB_UNICODE_COMBINING_CLASS_NOT_REORDERED */
462   1, /* HB_UNICODE_COMBINING_CLASS_OVERLAY */
463   2, 3, 4, 5, 6,
464   7, /* HB_UNICODE_COMBINING_CLASS_NUKTA */
465   8, /* HB_UNICODE_COMBINING_CLASS_KANA_VOICING */
466   9, /* HB_UNICODE_COMBINING_CLASS_VIRAMA */
467
468   /* Hebrew */
469   HB_MODIFIED_COMBINING_CLASS_CCC10,
470   HB_MODIFIED_COMBINING_CLASS_CCC11,
471   HB_MODIFIED_COMBINING_CLASS_CCC12,
472   HB_MODIFIED_COMBINING_CLASS_CCC13,
473   HB_MODIFIED_COMBINING_CLASS_CCC14,
474   HB_MODIFIED_COMBINING_CLASS_CCC15,
475   HB_MODIFIED_COMBINING_CLASS_CCC16,
476   HB_MODIFIED_COMBINING_CLASS_CCC17,
477   HB_MODIFIED_COMBINING_CLASS_CCC18,
478   HB_MODIFIED_COMBINING_CLASS_CCC19,
479   HB_MODIFIED_COMBINING_CLASS_CCC20,
480   HB_MODIFIED_COMBINING_CLASS_CCC21,
481   HB_MODIFIED_COMBINING_CLASS_CCC22,
482   HB_MODIFIED_COMBINING_CLASS_CCC23,
483   HB_MODIFIED_COMBINING_CLASS_CCC24,
484   HB_MODIFIED_COMBINING_CLASS_CCC25,
485   HB_MODIFIED_COMBINING_CLASS_CCC26,
486
487   /* Arabic */
488   HB_MODIFIED_COMBINING_CLASS_CCC27,
489   HB_MODIFIED_COMBINING_CLASS_CCC28,
490   HB_MODIFIED_COMBINING_CLASS_CCC29,
491   HB_MODIFIED_COMBINING_CLASS_CCC30,
492   HB_MODIFIED_COMBINING_CLASS_CCC31,
493   HB_MODIFIED_COMBINING_CLASS_CCC32,
494   HB_MODIFIED_COMBINING_CLASS_CCC33,
495   HB_MODIFIED_COMBINING_CLASS_CCC34,
496   HB_MODIFIED_COMBINING_CLASS_CCC35,
497
498   /* Syriac */
499   HB_MODIFIED_COMBINING_CLASS_CCC36,
500
501   37, 38, 39,
502   40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
503   60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
504   80, 81, 82, 83,
505
506   /* Telugu */
507   HB_MODIFIED_COMBINING_CLASS_CCC84,
508   85, 86, 87, 88, 89, 90,
509   HB_MODIFIED_COMBINING_CLASS_CCC91,
510   92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
511
512   /* Thai */
513   HB_MODIFIED_COMBINING_CLASS_CCC103,
514   104, 105, 106,
515   HB_MODIFIED_COMBINING_CLASS_CCC107,
516   108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
517
518   /* Lao */
519   HB_MODIFIED_COMBINING_CLASS_CCC118,
520   119, 120, 121,
521   HB_MODIFIED_COMBINING_CLASS_CCC122,
522   123, 124, 125, 126, 127, 128,
523
524   /* Tibetan */
525   HB_MODIFIED_COMBINING_CLASS_CCC129,
526   HB_MODIFIED_COMBINING_CLASS_CCC130,
527   131,
528   HB_MODIFIED_COMBINING_CLASS_CCC132,
529   133, 134, 135, 136, 137, 138, 139,
530
531
532   140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
533   150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
534   160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
535   170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
536   180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
537   190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
538
539   200, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT */
540   201,
541   202, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW */
542   203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
543   214, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE */
544   215,
545   216, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT */
546   217,
547   218, /* HB_UNICODE_COMBINING_CLASS_BELOW_LEFT */
548   219,
549   220, /* HB_UNICODE_COMBINING_CLASS_BELOW */
550   221,
551   222, /* HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT */
552   223,
553   224, /* HB_UNICODE_COMBINING_CLASS_LEFT */
554   225,
555   226, /* HB_UNICODE_COMBINING_CLASS_RIGHT */
556   227,
557   228, /* HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT */
558   229,
559   230, /* HB_UNICODE_COMBINING_CLASS_ABOVE */
560   231,
561   232, /* HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT */
562   233, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW */
563   234, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE */
564   235, 236, 237, 238, 239,
565   240, /* HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT */
566   241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
567   255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
568 };