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