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