2 * Copyright © 2009 Red Hat, Inc.
3 * Copyright © 2011 Codethink Limited
4 * Copyright © 2010,2011,2012 Google, Inc.
6 * This is part of HarfBuzz, a text shaping library.
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.
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
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.
26 * Red Hat Author(s): Behdad Esfahbod
27 * Codethink Author(s): Ryan Lortie
28 * Google Author(s): Behdad Esfahbod
33 #include "hb-unicode.hh"
39 * @short_description: Unicode character property access
42 * Unicode functions are used to access Unicode character properties.
43 * Client can pass its own Unicode functions to HarfBuzz, or access
44 * the built-in Unicode functions that come with HarfBuzz.
46 * With the Unicode functions, one can query variour Unicode character
47 * properties, such as General Category, Script, Combining Class, etc.
55 static hb_unicode_combining_class_t
56 hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
57 hb_codepoint_t unicode HB_UNUSED,
58 void *user_data HB_UNUSED)
60 return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
63 #ifndef HB_DISABLE_DEPRECATED
65 hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
66 hb_codepoint_t unicode HB_UNUSED,
67 void *user_data HB_UNUSED)
73 static hb_unicode_general_category_t
74 hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
75 hb_codepoint_t unicode HB_UNUSED,
76 void *user_data HB_UNUSED)
78 return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
82 hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
83 hb_codepoint_t unicode,
84 void *user_data HB_UNUSED)
90 hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
91 hb_codepoint_t unicode HB_UNUSED,
92 void *user_data HB_UNUSED)
94 return HB_SCRIPT_UNKNOWN;
98 hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
99 hb_codepoint_t a HB_UNUSED,
100 hb_codepoint_t b HB_UNUSED,
101 hb_codepoint_t *ab HB_UNUSED,
102 void *user_data HB_UNUSED)
108 hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
109 hb_codepoint_t ab HB_UNUSED,
110 hb_codepoint_t *a HB_UNUSED,
111 hb_codepoint_t *b HB_UNUSED,
112 void *user_data HB_UNUSED)
118 #ifndef HB_DISABLE_DEPRECATED
120 hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
121 hb_codepoint_t u HB_UNUSED,
122 hb_codepoint_t *decomposed HB_UNUSED,
123 void *user_data HB_UNUSED)
129 #if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_GLIB)
132 #if !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
137 hb_unicode_funcs_get_default ()
139 #if !defined(HB_NO_UNICODE_FUNCS) && !defined(HB_NO_UCD)
140 return hb_ucd_get_unicode_funcs ();
141 #elif !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_GLIB)
142 return hb_glib_get_unicode_funcs ();
143 #elif !defined(HB_NO_UNICODE_FUNCS) && defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN)
144 return hb_icu_get_unicode_funcs ();
146 #define HB_UNICODE_FUNCS_NIL 1
147 return hb_unicode_funcs_get_empty ();
151 #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
152 #error "Could not find any Unicode functions implementation, you have to provide your own"
153 #error "Consider building hb-ucd.cc. If you absolutely want to build without any, check the code."
157 * hb_unicode_funcs_create: (Xconstructor)
158 * @parent: (nullable):
162 * Return value: (transfer full):
167 hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
169 hb_unicode_funcs_t *ufuncs;
171 if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
172 return hb_unicode_funcs_get_empty ();
175 parent = hb_unicode_funcs_get_empty ();
177 hb_unicode_funcs_make_immutable (parent);
178 ufuncs->parent = hb_unicode_funcs_reference (parent);
180 ufuncs->func = parent->func;
182 /* We can safely copy user_data from parent since we hold a reference
183 * onto it and it's immutable. We should not copy the destroy notifiers
185 ufuncs->user_data = parent->user_data;
191 DEFINE_NULL_INSTANCE (hb_unicode_funcs_t) =
193 HB_OBJECT_HEADER_STATIC,
195 nullptr, /* parent */
197 #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
198 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
199 #undef HB_UNICODE_FUNC_IMPLEMENT
204 * hb_unicode_funcs_get_empty:
208 * Return value: (transfer full):
213 hb_unicode_funcs_get_empty ()
215 return const_cast<hb_unicode_funcs_t *> (&Null (hb_unicode_funcs_t));
219 * hb_unicode_funcs_reference: (skip)
220 * @ufuncs: Unicode functions.
224 * Return value: (transfer full):
229 hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
231 return hb_object_reference (ufuncs);
235 * hb_unicode_funcs_destroy: (skip)
236 * @ufuncs: Unicode functions.
243 hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
245 if (!hb_object_destroy (ufuncs)) return;
247 #define HB_UNICODE_FUNC_IMPLEMENT(name) \
248 if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
249 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
250 #undef HB_UNICODE_FUNC_IMPLEMENT
252 hb_unicode_funcs_destroy (ufuncs->parent);
258 * hb_unicode_funcs_set_user_data: (skip)
259 * @ufuncs: Unicode functions.
272 hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
273 hb_user_data_key_t *key,
275 hb_destroy_func_t destroy,
278 return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
282 * hb_unicode_funcs_get_user_data: (skip)
283 * @ufuncs: Unicode functions.
288 * Return value: (transfer none):
293 hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
294 hb_user_data_key_t *key)
296 return hb_object_get_user_data (ufuncs, key);
301 * hb_unicode_funcs_make_immutable:
302 * @ufuncs: Unicode functions.
309 hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
311 if (hb_object_is_immutable (ufuncs))
314 hb_object_make_immutable (ufuncs);
318 * hb_unicode_funcs_is_immutable:
319 * @ufuncs: Unicode functions.
328 hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
330 return hb_object_is_immutable (ufuncs);
334 * hb_unicode_funcs_get_parent:
335 * @ufuncs: Unicode functions.
344 hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
346 return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
350 #define HB_UNICODE_FUNC_IMPLEMENT(name) \
353 hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
354 hb_unicode_##name##_func_t func, \
356 hb_destroy_func_t destroy) \
358 if (hb_object_is_immutable (ufuncs)) \
361 if (ufuncs->destroy.name) \
362 ufuncs->destroy.name (ufuncs->user_data.name); \
365 ufuncs->func.name = func; \
366 ufuncs->user_data.name = user_data; \
367 ufuncs->destroy.name = destroy; \
369 ufuncs->func.name = ufuncs->parent->func.name; \
370 ufuncs->user_data.name = ufuncs->parent->user_data.name; \
371 ufuncs->destroy.name = nullptr; \
375 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
376 #undef HB_UNICODE_FUNC_IMPLEMENT
379 #define HB_UNICODE_FUNC_IMPLEMENT(return_type, name) \
382 hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \
383 hb_codepoint_t unicode) \
385 return ufuncs->name (unicode); \
387 HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
388 #undef HB_UNICODE_FUNC_IMPLEMENT
391 * hb_unicode_compose:
392 * @ufuncs: Unicode functions.
404 hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
409 return ufuncs->compose (a, b, ab);
413 * hb_unicode_decompose:
414 * @ufuncs: Unicode functions.
426 hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
431 return ufuncs->decompose (ab, a, b);
434 #ifndef HB_DISABLE_DEPRECATED
436 * hb_unicode_decompose_compatibility:
437 * @ufuncs: Unicode functions.
439 * @decomposed: (out):
449 hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
451 hb_codepoint_t *decomposed)
453 return ufuncs->decompose_compatibility (u, decomposed);
458 #ifndef HB_NO_OT_SHAPE
459 /* See hb-unicode.hh for details. */
461 _hb_modified_combining_class[256] =
463 0, /* HB_UNICODE_COMBINING_CLASS_NOT_REORDERED */
464 1, /* HB_UNICODE_COMBINING_CLASS_OVERLAY */
466 7, /* HB_UNICODE_COMBINING_CLASS_NUKTA */
467 8, /* HB_UNICODE_COMBINING_CLASS_KANA_VOICING */
468 9, /* HB_UNICODE_COMBINING_CLASS_VIRAMA */
471 HB_MODIFIED_COMBINING_CLASS_CCC10,
472 HB_MODIFIED_COMBINING_CLASS_CCC11,
473 HB_MODIFIED_COMBINING_CLASS_CCC12,
474 HB_MODIFIED_COMBINING_CLASS_CCC13,
475 HB_MODIFIED_COMBINING_CLASS_CCC14,
476 HB_MODIFIED_COMBINING_CLASS_CCC15,
477 HB_MODIFIED_COMBINING_CLASS_CCC16,
478 HB_MODIFIED_COMBINING_CLASS_CCC17,
479 HB_MODIFIED_COMBINING_CLASS_CCC18,
480 HB_MODIFIED_COMBINING_CLASS_CCC19,
481 HB_MODIFIED_COMBINING_CLASS_CCC20,
482 HB_MODIFIED_COMBINING_CLASS_CCC21,
483 HB_MODIFIED_COMBINING_CLASS_CCC22,
484 HB_MODIFIED_COMBINING_CLASS_CCC23,
485 HB_MODIFIED_COMBINING_CLASS_CCC24,
486 HB_MODIFIED_COMBINING_CLASS_CCC25,
487 HB_MODIFIED_COMBINING_CLASS_CCC26,
490 HB_MODIFIED_COMBINING_CLASS_CCC27,
491 HB_MODIFIED_COMBINING_CLASS_CCC28,
492 HB_MODIFIED_COMBINING_CLASS_CCC29,
493 HB_MODIFIED_COMBINING_CLASS_CCC30,
494 HB_MODIFIED_COMBINING_CLASS_CCC31,
495 HB_MODIFIED_COMBINING_CLASS_CCC32,
496 HB_MODIFIED_COMBINING_CLASS_CCC33,
497 HB_MODIFIED_COMBINING_CLASS_CCC34,
498 HB_MODIFIED_COMBINING_CLASS_CCC35,
501 HB_MODIFIED_COMBINING_CLASS_CCC36,
504 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
505 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
509 HB_MODIFIED_COMBINING_CLASS_CCC84,
510 85, 86, 87, 88, 89, 90,
511 HB_MODIFIED_COMBINING_CLASS_CCC91,
512 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
515 HB_MODIFIED_COMBINING_CLASS_CCC103,
517 HB_MODIFIED_COMBINING_CLASS_CCC107,
518 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
521 HB_MODIFIED_COMBINING_CLASS_CCC118,
523 HB_MODIFIED_COMBINING_CLASS_CCC122,
524 123, 124, 125, 126, 127, 128,
527 HB_MODIFIED_COMBINING_CLASS_CCC129,
528 HB_MODIFIED_COMBINING_CLASS_CCC130,
530 HB_MODIFIED_COMBINING_CLASS_CCC132,
531 133, 134, 135, 136, 137, 138, 139,
534 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
535 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
536 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,
537 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
538 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,
539 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
541 200, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT */
543 202, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW */
544 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
545 214, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE */
547 216, /* HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT */
549 218, /* HB_UNICODE_COMBINING_CLASS_BELOW_LEFT */
551 220, /* HB_UNICODE_COMBINING_CLASS_BELOW */
553 222, /* HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT */
555 224, /* HB_UNICODE_COMBINING_CLASS_LEFT */
557 226, /* HB_UNICODE_COMBINING_CLASS_RIGHT */
559 228, /* HB_UNICODE_COMBINING_CLASS_ABOVE_LEFT */
561 230, /* HB_UNICODE_COMBINING_CLASS_ABOVE */
563 232, /* HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT */
564 233, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW */
565 234, /* HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE */
566 235, 236, 237, 238, 239,
567 240, /* HB_UNICODE_COMBINING_CLASS_IOTA_SUBSCRIPT */
568 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254,
569 255, /* HB_UNICODE_COMBINING_CLASS_INVALID */
577 #ifndef HB_NO_EMOJI_SEQUENCES
579 #include "hb-unicode-emoji-table.hh"
582 _hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp)
584 return _hb_emoji_is_Extended_Pictographic (cp);