From f4ac14944daa5778aa3cdb37113fbc5c774b40bf Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Sat, 7 Jan 2017 19:24:07 +0400 Subject: Update bundled HarfBuzz-NG copy to 1.4.1 Most important changes since 1.0: - New API. - Update to Unicode 9.0.0; add 6 more scripts. - Improved list of language tag mappings. - OpenType 1.8 Font Variations support. - Blacklist GDEF table of certain fonts. - Implement parsing of OpenType MATH table. - Implement CBDT/CBLC color font glyph extents. - Fix mark zeroing types of most shapers. - Allow GPOS cursive connection on marks, and fix the interaction with mark attachment. - Universal Shaping Engine fixes; update to latest draft from Microsoft. - Implement "shaping" of various Unicode space characters, even if the font does not support them. - Allow MultipleSubst to delete a glyph (matching Windows engine). - CoreText backend fixes and optimizations. - Optimizations and other improvements. [ChangeLog] Bundled HarfBuzz-NG copy updated to 1.4.1 Change-Id: Ie398fad8f6d3b98e3236f62a97caedc649511470 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh | 25 + src/3rdparty/harfbuzz-ng/src/hb-blob.cc | 1 - src/3rdparty/harfbuzz-ng/src/hb-blob.h | 24 +- src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh | 114 +- .../harfbuzz-ng/src/hb-buffer-serialize.cc | 88 +- src/3rdparty/harfbuzz-ng/src/hb-buffer.cc | 489 +++-- src/3rdparty/harfbuzz-ng/src/hb-buffer.h | 254 ++- src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh | 8 +- src/3rdparty/harfbuzz-ng/src/hb-common.cc | 52 +- src/3rdparty/harfbuzz-ng/src/hb-common.h | 59 +- src/3rdparty/harfbuzz-ng/src/hb-coretext.cc | 267 ++- src/3rdparty/harfbuzz-ng/src/hb-coretext.h | 6 +- src/3rdparty/harfbuzz-ng/src/hb-deprecated.h | 10 + src/3rdparty/harfbuzz-ng/src/hb-face.cc | 2 - src/3rdparty/harfbuzz-ng/src/hb-face.h | 34 +- src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc | 143 ++ src/3rdparty/harfbuzz-ng/src/hb-font-private.hh | 290 ++- src/3rdparty/harfbuzz-ng/src/hb-font.cc | 586 +++++- src/3rdparty/harfbuzz-ng/src/hb-font.h | 246 ++- .../harfbuzz-ng/src/hb-open-file-private.hh | 4 +- .../harfbuzz-ng/src/hb-open-type-private.hh | 45 +- src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh | 384 ++++ src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh | 125 +- src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc | 466 +++-- src/3rdparty/harfbuzz-ng/src/hb-ot-font.h | 2 +- src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh | 8 +- src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh | 8 +- src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh | 6 +- .../harfbuzz-ng/src/hb-ot-layout-common-private.hh | 551 +++++- .../harfbuzz-ng/src/hb-ot-layout-gdef-table.hh | 54 +- .../harfbuzz-ng/src/hb-ot-layout-gpos-table.hh | 253 +-- .../harfbuzz-ng/src/hb-ot-layout-gsub-table.hh | 87 +- .../src/hb-ot-layout-gsubgpos-private.hh | 91 +- .../harfbuzz-ng/src/hb-ot-layout-jstf-table.hh | 2 +- .../harfbuzz-ng/src/hb-ot-layout-math-table.hh | 722 +++++++ .../harfbuzz-ng/src/hb-ot-layout-private.hh | 208 +- src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc | 305 ++- src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h | 75 +- src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh | 37 +- src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc | 125 +- src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc | 272 +++ src/3rdparty/harfbuzz-ng/src/hb-ot-math.h | 209 ++ src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh | 2 +- src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh | 105 + src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh | 119 ++ .../src/hb-ot-shape-complex-arabic-table.hh | 56 +- .../src/hb-ot-shape-complex-arabic-win1256.hh | 323 ++++ .../harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc | 249 ++- .../harfbuzz-ng/src/hb-ot-shape-complex-default.cc | 4 +- .../harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc | 10 +- .../harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc | 16 +- .../src/hb-ot-shape-complex-indic-machine.hh | 2026 +++++++++----------- .../src/hb-ot-shape-complex-indic-private.hh | 45 +- .../src/hb-ot-shape-complex-indic-table.cc | 718 ++----- .../harfbuzz-ng/src/hb-ot-shape-complex-indic.cc | 151 +- .../harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc | 17 +- .../harfbuzz-ng/src/hb-ot-shape-complex-private.hh | 37 +- .../harfbuzz-ng/src/hb-ot-shape-complex-thai.cc | 9 +- .../harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc | 4 +- .../src/hb-ot-shape-complex-use-machine.hh | 588 +++--- .../src/hb-ot-shape-complex-use-private.hh | 1 - .../src/hb-ot-shape-complex-use-table.cc | 224 ++- .../harfbuzz-ng/src/hb-ot-shape-complex-use.cc | 99 +- .../src/hb-ot-shape-fallback-private.hh | 4 + .../harfbuzz-ng/src/hb-ot-shape-fallback.cc | 67 + .../harfbuzz-ng/src/hb-ot-shape-normalize.cc | 77 +- .../harfbuzz-ng/src/hb-ot-shape-private.hh | 6 +- src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc | 196 +- src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h | 4 +- src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc | 187 +- src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h | 8 +- src/3rdparty/harfbuzz-ng/src/hb-ot.h | 1 + src/3rdparty/harfbuzz-ng/src/hb-private.hh | 51 +- src/3rdparty/harfbuzz-ng/src/hb-set-private.hh | 4 +- src/3rdparty/harfbuzz-ng/src/hb-set.h | 52 +- .../harfbuzz-ng/src/hb-shape-plan-private.hh | 9 +- src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc | 107 +- src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h | 37 +- src/3rdparty/harfbuzz-ng/src/hb-shape.cc | 17 +- src/3rdparty/harfbuzz-ng/src/hb-shape.h | 10 +- src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh | 3 + src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh | 61 +- src/3rdparty/harfbuzz-ng/src/hb-unicode.cc | 6 +- src/3rdparty/harfbuzz-ng/src/hb-unicode.h | 71 +- src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh | 46 +- src/3rdparty/harfbuzz-ng/src/hb-version.h | 12 +- src/3rdparty/harfbuzz-ng/src/hb.h | 4 + 88 files changed, 8585 insertions(+), 3997 deletions(-) create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-layout-math-table.hh create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-math.h create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh create mode 100644 src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh (limited to 'src/3rdparty/harfbuzz-ng/src') diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh index 8179571ad2..100ba539e3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh @@ -119,6 +119,31 @@ typedef unsigned int hb_atomic_int_impl_t; #define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) +#elif !defined(HB_NO_MT) && defined(_AIX) && defined(__IBMCPP__) + +#include + + +static inline int hb_fetch_and_add(volatile int* AI, unsigned int V) { + __lwsync(); + int result = __fetch_and_add(AI, V); + __isync(); + return result; +} +static inline int hb_compare_and_swaplp(volatile long* P, long O, long N) { + __sync(); + int result = __compare_and_swaplp (P, &O, N); + __sync(); + return result; +} + +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) hb_fetch_and_add (&(AI), (V)) + +#define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N)) + #elif !defined(HB_NO_MT) #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc index a6870dc06e..fb48f03cab 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc @@ -104,7 +104,6 @@ hb_blob_create (const char *data, if (!length || length >= 1u << 31 || - data + length < data /* overflows */ || !(blob = hb_object_create ())) { if (destroy) destroy (user_data); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.h b/src/3rdparty/harfbuzz-ng/src/hb-blob.h index b2419abfd2..ef3fc98c05 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-blob.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.h @@ -64,7 +64,7 @@ typedef enum { typedef struct hb_blob_t hb_blob_t; -hb_blob_t * +HB_EXTERN hb_blob_t * hb_blob_create (const char *data, unsigned int length, hb_memory_mode_t mode, @@ -77,21 +77,21 @@ hb_blob_create (const char *data, * modify the parent data as that data may be * shared among multiple sub-blobs. */ -hb_blob_t * +HB_EXTERN hb_blob_t * hb_blob_create_sub_blob (hb_blob_t *parent, unsigned int offset, unsigned int length); -hb_blob_t * +HB_EXTERN hb_blob_t * hb_blob_get_empty (void); -hb_blob_t * +HB_EXTERN hb_blob_t * hb_blob_reference (hb_blob_t *blob); -void +HB_EXTERN void hb_blob_destroy (hb_blob_t *blob); -hb_bool_t +HB_EXTERN hb_bool_t hb_blob_set_user_data (hb_blob_t *blob, hb_user_data_key_t *key, void * data, @@ -99,25 +99,25 @@ hb_blob_set_user_data (hb_blob_t *blob, hb_bool_t replace); -void * +HB_EXTERN void * hb_blob_get_user_data (hb_blob_t *blob, hb_user_data_key_t *key); -void +HB_EXTERN void hb_blob_make_immutable (hb_blob_t *blob); -hb_bool_t +HB_EXTERN hb_bool_t hb_blob_is_immutable (hb_blob_t *blob); -unsigned int +HB_EXTERN unsigned int hb_blob_get_length (hb_blob_t *blob); -const char * +HB_EXTERN const char * hb_blob_get_data (hb_blob_t *blob, unsigned int *length); -char * +HB_EXTERN char * hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh index 7fed7386b0..bca308da2f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh @@ -35,9 +35,36 @@ #include "hb-unicode-private.hh" +#ifndef HB_BUFFER_MAX_EXPANSION_FACTOR +#define HB_BUFFER_MAX_EXPANSION_FACTOR 32 +#endif +#ifndef HB_BUFFER_MAX_LEN_MIN +#define HB_BUFFER_MAX_LEN_MIN 8192 +#endif +#ifndef HB_BUFFER_MAX_LEN_DEFAULT +#define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ +#endif + ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20); ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)); +HB_MARK_AS_FLAG_T (hb_buffer_flags_t); +HB_MARK_AS_FLAG_T (hb_buffer_serialize_flags_t); + +enum hb_buffer_scratch_flags_t { + HB_BUFFER_SCRATCH_FLAG_DEFAULT = 0x00000000u, + HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII = 0x00000001u, + HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES = 0x00000002u, + HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, + HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, + /* Reserved for complex shapers' internal use. */ + HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u, + HB_BUFFER_SCRATCH_FLAG_COMPLEX1 = 0x02000000u, + HB_BUFFER_SCRATCH_FLAG_COMPLEX2 = 0x04000000u, + HB_BUFFER_SCRATCH_FLAG_COMPLEX3 = 0x08000000u, +}; +HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t); + /* * hb_buffer_t @@ -52,6 +79,8 @@ struct hb_buffer_t { hb_buffer_flags_t flags; /* BOT / EOT / etc. */ hb_buffer_cluster_level_t cluster_level; hb_codepoint_t replacement; /* U+FFFD or something else. */ + hb_buffer_scratch_flags_t scratch_flags; /* Have space-flallback, etc. */ + unsigned int max_len; /* Maximum allowed len. */ /* Buffer contents */ hb_buffer_content_type_t content_type; @@ -76,17 +105,13 @@ struct hb_buffer_t { inline hb_glyph_position_t &cur_pos (unsigned int i = 0) { return pos[idx + i]; } inline hb_glyph_position_t cur_pos (unsigned int i = 0) const { return pos[idx + i]; } - inline hb_glyph_info_t &prev (void) { return out_info[out_len - 1]; } - inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; } + inline hb_glyph_info_t &prev (void) { return out_info[out_len ? out_len - 1 : 0]; } + inline hb_glyph_info_t prev (void) const { return out_info[out_len ? out_len - 1 : 0]; } inline bool has_separate_output (void) const { return info != out_info; } unsigned int serial; - /* These reflect current allocations of the bytes in glyph_info_t's var1 and var2. */ - uint8_t allocated_var_bytes[8]; - const char *allocated_var_owner[8]; - /* Text before / after the main buffer contents. * Always in Unicode, and ordered outward. * Index 0 is for "pre-context", 1 for "post-context". */ @@ -94,6 +119,52 @@ struct hb_buffer_t { hb_codepoint_t context[2][CONTEXT_LENGTH]; unsigned int context_len[2]; + /* Debugging API */ + hb_buffer_message_func_t message_func; + void *message_data; + hb_destroy_func_t message_destroy; + + /* Internal debugging. */ + /* The bits here reflect current allocations of the bytes in glyph_info_t's var1 and var2. */ +#ifndef HB_NDEBUG + uint8_t allocated_var_bits; +#endif + inline void allocate_var (unsigned int start, unsigned int count) + { +#ifndef HB_NDEBUG + unsigned int end = start + count; + assert (end <= 8); + unsigned int bits = (1u<func (offsetof (hb_glyph_info_t, var) - offsetof(hb_glyph_info_t, var1), \ - sizeof (b->info[0].var), owner) -#define HB_BUFFER_ALLOCATE_VAR(b, var) \ - HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var (), #var) -#define HB_BUFFER_DEALLOCATE_VAR(b, var) \ - HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var (), #var) -#define HB_BUFFER_ASSERT_VAR(b, var) \ - HB_BUFFER_XALLOCATE_VAR (b, assert_var, var (), #var) + sizeof (b->info[0].var)) +#define HB_BUFFER_ALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, allocate_var, var ()) +#define HB_BUFFER_DEALLOCATE_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, deallocate_var, var ()) +#define HB_BUFFER_ASSERT_VAR(b, var) HB_BUFFER_XALLOCATE_VAR (b, assert_var, var ()) #endif /* HB_BUFFER_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc index 7839cbc3f0..63a0f34669 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc @@ -36,11 +36,12 @@ static const char *serialize_formats[] = { /** * hb_buffer_serialize_list_formats: * - * + * Returns a list of supported buffer serialization formats. * * Return value: (transfer none): + * A string array of buffer serialization formats. Should not be freed. * - * Since: 0.9.2 + * Since: 0.9.7 **/ const char ** hb_buffer_serialize_list_formats (void) @@ -50,14 +51,17 @@ hb_buffer_serialize_list_formats (void) /** * hb_buffer_serialize_format_from_string: - * @str: - * @len: + * @str: (array length=len) (element-type uint8_t): a string to parse + * @len: length of @str, or -1 if string is %NULL terminated * - * + * Parses a string into an #hb_buffer_serialize_format_t. Does not check if + * @str is a valid buffer serialization format, use + * hb_buffer_serialize_list_formats() to get the list of supported formats. * * Return value: + * The parsed #hb_buffer_serialize_format_t. * - * Since: 0.9.2 + * Since: 0.9.7 **/ hb_buffer_serialize_format_t hb_buffer_serialize_format_from_string (const char *str, int len) @@ -68,13 +72,15 @@ hb_buffer_serialize_format_from_string (const char *str, int len) /** * hb_buffer_serialize_format_to_string: - * @format: + * @format: an #hb_buffer_serialize_format_t to convert. * - * + * Converts @format to the string corresponding it, or %NULL if it is not a valid + * #hb_buffer_serialize_format_t. * - * Return value: + * Return value: (transfer none): + * A %NULL terminated string corresponding to @format. Should not be freed. * - * Since: 0.9.2 + * Since: 0.9.7 **/ const char * hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) @@ -242,24 +248,51 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, return end - start; } -/* Returns number of items, starting at start, that were serialized. */ /** * hb_buffer_serialize_glyphs: - * @buffer: a buffer. - * @start: - * @end: - * @buf: (array length=buf_size): - * @buf_size: - * @buf_consumed: (out): - * @font: - * @format: - * @flags: + * @buffer: an #hb_buffer_t buffer. + * @start: the first item in @buffer to serialize. + * @end: the last item in @buffer to serialize. + * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to + * write serialized buffer into. + * @buf_size: the size of @buf. + * @buf_consumed: (out) (allow-none): if not %NULL, will be set to the number of byes written into @buf. + * @font: (allow-none): the #hb_font_t used to shape this buffer, needed to + * read glyph names and extents. If %NULL, and empty font will be used. + * @format: the #hb_buffer_serialize_format_t to use for formatting the output. + * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties + * to serialize. * - * + * Serializes @buffer into a textual representation of its glyph content, + * useful for showing the contents of the buffer, for example during debugging. + * There are currently two supported serialization formats: + * + * ## text + * A human-readable, plain text format. + * The serialized glyphs will look something like: + * + * ``` + * [uni0651=0@518,0+0|uni0628=0+1897] + * ``` + * - The serialized glyphs are delimited with `[` and `]`. + * - Glyphs are separated with `|` + * - Each glyph starts with glyph name, or glyph index if + * #HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES flag is set. Then, + * - If #HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS is not set, `=` then #hb_glyph_info_t.cluster. + * - If #HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS is not set, the #hb_glyph_position_t in the format: + * - If both #hb_glyph_position_t.x_offset and #hb_glyph_position_t.y_offset are not 0, `@x_offset,y_offset`. Then, + * - `+x_advance`, then `,y_advance` if #hb_glyph_position_t.y_advance is not 0. Then, + * - If #HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS is set, the + * #hb_glyph_extents_t in the format + * `<x_bearing,y_bearing,width,height>` + * + * ## json + * TODO. * * Return value: + * The number of serialized items. * - * Since: 0.9.2 + * Since: 0.9.7 **/ unsigned int hb_buffer_serialize_glyphs (hb_buffer_t *buffer, @@ -267,8 +300,8 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, unsigned int end, char *buf, unsigned int buf_size, - unsigned int *buf_consumed, /* May be NULL */ - hb_font_t *font, /* May be NULL */ + unsigned int *buf_consumed, + hb_font_t *font, hb_buffer_serialize_format_t format, hb_buffer_serialize_flags_t flags) { @@ -282,6 +315,9 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) || buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS); + if (!buffer->have_positions) + flags |= HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS; + if (unlikely (start == end)) return 0; @@ -355,7 +391,7 @@ parse_int (const char *pp, const char *end, int32_t *pv) /** * hb_buffer_deserialize_glyphs: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t buffer. * @buf: (array length=buf_len): * @buf_len: * @end_ptr: (out): @@ -366,7 +402,7 @@ parse_int (const char *pp, const char *end, int32_t *pv) * * Return value: * - * Since: 0.9.2 + * Since: 0.9.7 **/ hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc index 50710dd23e..3940a3dbf8 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc @@ -35,8 +35,26 @@ #define HB_DEBUG_BUFFER (HB_DEBUG+0) #endif +/** + * SECTION: hb-buffer + * @title: Buffers + * @short_description: Input and output buffers + * @include: hb.h + * + * Buffers serve dual role in HarfBuzz; they hold the input characters that are + * passed hb_shape(), and after shaping they hold the output glyphs. + **/ /** + * hb_segment_properties_equal: + * @a: first #hb_segment_properties_t to compare. + * @b: second #hb_segment_properties_t to compare. + * + * Checks the equality of two #hb_segment_properties_t's. + * + * Return value: + * %true if all properties of @a equal those of @b, false otherwise. + * * Since: 0.9.7 **/ hb_bool_t @@ -52,6 +70,14 @@ hb_segment_properties_equal (const hb_segment_properties_t *a, } /** + * hb_segment_properties_hash: + * @p: #hb_segment_properties_t to hash. + * + * Creates a hash representing @p. + * + * Return value: + * A hash of @p. + * * Since: 0.9.7 **/ unsigned int @@ -91,6 +117,11 @@ hb_buffer_t::enlarge (unsigned int size) { if (unlikely (in_error)) return false; + if (unlikely (size > max_len)) + { + in_error = true; + return false; + } unsigned int new_allocated = allocated; hb_glyph_position_t *new_pos = NULL; @@ -152,6 +183,12 @@ hb_buffer_t::shift_forward (unsigned int count) if (unlikely (!ensure (len + count))) return false; memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0])); + if (idx + count > len) + { + /* Under memory failure we might expose this area. At least + * clean it up. Oh well... */ + memset (info + len, 0, (idx + count - len) * sizeof (info[0])); + } len += count; idx += count; @@ -198,6 +235,7 @@ hb_buffer_t::clear (void) hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT; props = default_props; + scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; content_type = HB_BUFFER_CONTENT_TYPE_INVALID; in_error = false; @@ -210,11 +248,11 @@ hb_buffer_t::clear (void) out_info = info; serial = 0; - memset (allocated_var_bytes, 0, sizeof allocated_var_bytes); - memset (allocated_var_owner, 0, sizeof allocated_var_owner); memset (context, 0, sizeof context); memset (context_len, 0, sizeof context_len); + + deallocate_var_all (); } void @@ -375,6 +413,8 @@ hb_buffer_t::move_to (unsigned int i) idx = i; return true; } + if (unlikely (in_error)) + return false; assert (i <= out_len + (len - idx)); @@ -392,6 +432,8 @@ hb_buffer_t::move_to (unsigned int i) /* Tricky part: rewinding... */ unsigned int count = out_len - i; + /* This will blow in our face if memory allocation fails later + * in this same lookup... */ if (unlikely (idx < count && !shift_forward (count + 32))) return false; assert (idx >= count); @@ -627,82 +669,19 @@ hb_buffer_t::guess_segment_properties (void) } -static inline void -dump_var_allocation (const hb_buffer_t *buffer) -{ - char buf[80]; - for (unsigned int i = 0; i < 8; i++) - buf[i] = '0' + buffer->allocated_var_bytes[7 - i]; - buf[8] = '\0'; - DEBUG_MSG (BUFFER, buffer, - "Current var allocation: %s", - buf); -} - -void hb_buffer_t::allocate_var (unsigned int byte_i, unsigned int count, const char *owner) -{ - assert (byte_i < 8 && byte_i + count <= 8); - - if (DEBUG_ENABLED (BUFFER)) - dump_var_allocation (this); - DEBUG_MSG (BUFFER, this, - "Allocating var bytes %d..%d for %s", - byte_i, byte_i + count - 1, owner); - - for (unsigned int i = byte_i; i < byte_i + count; i++) { - assert (!allocated_var_bytes[i]); - allocated_var_bytes[i]++; - allocated_var_owner[i] = owner; - } -} - -void hb_buffer_t::deallocate_var (unsigned int byte_i, unsigned int count, const char *owner) -{ - if (DEBUG_ENABLED (BUFFER)) - dump_var_allocation (this); - - DEBUG_MSG (BUFFER, this, - "Deallocating var bytes %d..%d for %s", - byte_i, byte_i + count - 1, owner); - - assert (byte_i < 8 && byte_i + count <= 8); - for (unsigned int i = byte_i; i < byte_i + count; i++) { - assert (allocated_var_bytes[i]); - assert (0 == strcmp (allocated_var_owner[i], owner)); - allocated_var_bytes[i]--; - } -} - -void hb_buffer_t::assert_var (unsigned int byte_i, unsigned int count, const char *owner) -{ - if (DEBUG_ENABLED (BUFFER)) - dump_var_allocation (this); - - DEBUG_MSG (BUFFER, this, - "Asserting var bytes %d..%d for %s", - byte_i, byte_i + count - 1, owner); - - assert (byte_i < 8 && byte_i + count <= 8); - for (unsigned int i = byte_i; i < byte_i + count; i++) { - assert (allocated_var_bytes[i]); - assert (0 == strcmp (allocated_var_owner[i], owner)); - } -} - -void hb_buffer_t::deallocate_var_all (void) -{ - memset (allocated_var_bytes, 0, sizeof (allocated_var_bytes)); - memset (allocated_var_owner, 0, sizeof (allocated_var_owner)); -} - /* Public API */ /** * hb_buffer_create: (Xconstructor) * - * + * Creates a new #hb_buffer_t with all properties to defaults. * - * Return value: (transfer full) + * Return value: (transfer full): + * A newly allocated #hb_buffer_t with a reference count of 1. The initial + * reference count should be released with hb_buffer_destroy() when you are done + * using the #hb_buffer_t. This function never returns %NULL. If memory cannot + * be allocated, a special #hb_buffer_t object will be returned on which + * hb_buffer_allocation_successful() returns %false. * * Since: 0.9.2 **/ @@ -714,6 +693,8 @@ hb_buffer_create (void) if (!(buffer = hb_object_create ())) return hb_buffer_get_empty (); + buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT; + buffer->reset (); return buffer; @@ -738,6 +719,8 @@ hb_buffer_get_empty (void) HB_BUFFER_FLAG_DEFAULT, HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, + HB_BUFFER_SCRATCH_FLAG_DEFAULT, + HB_BUFFER_MAX_LEN_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, HB_SEGMENT_PROPERTIES_DEFAULT, @@ -753,11 +736,13 @@ hb_buffer_get_empty (void) /** * hb_buffer_reference: (skip) - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * Increases the reference count on @buffer by one. This prevents @buffer from + * being destroyed until a matching call to hb_buffer_destroy() is made. * * Return value: (transfer full): + * The referenced #hb_buffer_t. * * Since: 0.9.2 **/ @@ -769,9 +754,11 @@ hb_buffer_reference (hb_buffer_t *buffer) /** * hb_buffer_destroy: (skip) - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * Deallocate the @buffer. + * Decreases the reference count on @buffer by one. If the result is zero, then + * @buffer and all associated resources are freed. See hb_buffer_reference(). * * Since: 0.9.2 **/ @@ -784,13 +771,15 @@ hb_buffer_destroy (hb_buffer_t *buffer) free (buffer->info); free (buffer->pos); + if (buffer->message_destroy) + buffer->message_destroy (buffer->message_data); free (buffer); } /** * hb_buffer_set_user_data: (skip) - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * @key: * @data: * @destroy: @@ -814,7 +803,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer, /** * hb_buffer_get_user_data: (skip) - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * @key: * * @@ -833,10 +822,11 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, /** * hb_buffer_set_content_type: - * @buffer: a buffer. - * @content_type: + * @buffer: an #hb_buffer_t. + * @content_type: the type of buffer contents to set * - * + * Sets the type of @buffer contents, buffers are either empty, contain + * characters (before shaping) or glyphs (the result of shaping). * * Since: 0.9.5 **/ @@ -849,11 +839,12 @@ hb_buffer_set_content_type (hb_buffer_t *buffer, /** * hb_buffer_get_content_type: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * see hb_buffer_set_content_type(). * - * Return value: + * Return value: + * The type of @buffer contents. * * Since: 0.9.5 **/ @@ -866,7 +857,7 @@ hb_buffer_get_content_type (hb_buffer_t *buffer) /** * hb_buffer_set_unicode_funcs: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * @unicode_funcs: * * @@ -891,7 +882,7 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, /** * hb_buffer_get_unicode_funcs: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * * * @@ -907,10 +898,16 @@ hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) /** * hb_buffer_set_direction: - * @buffer: a buffer. - * @direction: + * @buffer: an #hb_buffer_t. + * @direction: the #hb_direction_t of the @buffer * - * + * Set the text flow direction of the buffer. No shaping can happen without + * setting @buffer direction, and it controls the visual direction for the + * output glyphs; for RTL direction the glyphs will be reversed. Many layout + * features depend on the proper setting of the direction, for example, + * reversing RTL text before shaping, then shaping with LTR direction is not + * the same as keeping the text in logical order and shaping with RTL + * direction. * * Since: 0.9.2 **/ @@ -927,11 +924,12 @@ hb_buffer_set_direction (hb_buffer_t *buffer, /** * hb_buffer_get_direction: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * See hb_buffer_set_direction() * - * Return value: + * Return value: + * The direction of the @buffer. * * Since: 0.9.2 **/ @@ -943,10 +941,18 @@ hb_buffer_get_direction (hb_buffer_t *buffer) /** * hb_buffer_set_script: - * @buffer: a buffer. - * @script: + * @buffer: an #hb_buffer_t. + * @script: an #hb_script_t to set. * - * + * Sets the script of @buffer to @script. + * + * Script is crucial for choosing the proper shaping behaviour for scripts that + * require it (e.g. Arabic) and the which OpenType features defined in the font + * to be applied. + * + * You can pass one of the predefined #hb_script_t values, or use + * hb_script_from_string() or hb_script_from_iso15924_tag() to get the + * corresponding script from an ISO 15924 script tag. * * Since: 0.9.2 **/ @@ -962,11 +968,12 @@ hb_buffer_set_script (hb_buffer_t *buffer, /** * hb_buffer_get_script: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * See hb_buffer_set_script(). * - * Return value: + * Return value: + * The #hb_script_t of the @buffer. * * Since: 0.9.2 **/ @@ -978,10 +985,18 @@ hb_buffer_get_script (hb_buffer_t *buffer) /** * hb_buffer_set_language: - * @buffer: a buffer. - * @language: + * @buffer: an #hb_buffer_t. + * @language: an hb_language_t to set. * - * + * Sets the language of @buffer to @language. + * + * Languages are crucial for selecting which OpenType feature to apply to the + * buffer which can result in applying language-specific behaviour. Languages + * are orthogonal to the scripts, and though they are related, they are + * different concepts and should not be confused with each other. + * + * Use hb_language_from_string() to convert from ISO 639 language codes to + * #hb_language_t. * * Since: 0.9.2 **/ @@ -997,11 +1012,12 @@ hb_buffer_set_language (hb_buffer_t *buffer, /** * hb_buffer_get_language: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * See hb_buffer_set_language(). * * Return value: (transfer none): + * The #hb_language_t of the buffer. Must not be freed by the caller. * * Since: 0.9.2 **/ @@ -1013,10 +1029,12 @@ hb_buffer_get_language (hb_buffer_t *buffer) /** * hb_buffer_set_segment_properties: - * @buffer: a buffer. - * @props: + * @buffer: an #hb_buffer_t. + * @props: an #hb_segment_properties_t to use. * - * + * Sets the segment properties of the buffer, a shortcut for calling + * hb_buffer_set_direction(), hb_buffer_set_script() and + * hb_buffer_set_language() individually. * * Since: 0.9.7 **/ @@ -1032,10 +1050,10 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer, /** * hb_buffer_get_segment_properties: - * @buffer: a buffer. - * @props: (out): + * @buffer: an #hb_buffer_t. + * @props: (out): the output #hb_segment_properties_t. * - * + * Sets @props to the #hb_segment_properties_t of @buffer. * * Since: 0.9.7 **/ @@ -1049,10 +1067,10 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer, /** * hb_buffer_set_flags: - * @buffer: a buffer. - * @flags: + * @buffer: an #hb_buffer_t. + * @flags: the buffer flags to set. * - * + * Sets @buffer flags to @flags. See #hb_buffer_flags_t. * * Since: 0.9.7 **/ @@ -1068,11 +1086,12 @@ hb_buffer_set_flags (hb_buffer_t *buffer, /** * hb_buffer_get_flags: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * See hb_buffer_set_flags(). * * Return value: + * The @buffer flags. * * Since: 0.9.7 **/ @@ -1084,7 +1103,7 @@ hb_buffer_get_flags (hb_buffer_t *buffer) /** * hb_buffer_set_cluster_level: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * @cluster_level: * * @@ -1103,7 +1122,7 @@ hb_buffer_set_cluster_level (hb_buffer_t *buffer, /** * hb_buffer_get_cluster_level: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * * * @@ -1120,10 +1139,13 @@ hb_buffer_get_cluster_level (hb_buffer_t *buffer) /** * hb_buffer_set_replacement_codepoint: - * @buffer: a buffer. - * @replacement: + * @buffer: an #hb_buffer_t. + * @replacement: the replacement #hb_codepoint_t * - * + * Sets the #hb_codepoint_t that replaces invalid entries for a given encoding + * when adding text to @buffer. + * + * Default is %HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT. * * Since: 0.9.31 **/ @@ -1139,11 +1161,12 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, /** * hb_buffer_get_replacement_codepoint: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * See hb_buffer_set_replacement_codepoint(). * * Return value: + * The @buffer replacement #hb_codepoint_t. * * Since: 0.9.31 **/ @@ -1156,9 +1179,10 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) /** * hb_buffer_reset: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * Resets the buffer to its initial status, as if it was just newly created + * with hb_buffer_create(). * * Since: 0.9.2 **/ @@ -1170,9 +1194,10 @@ hb_buffer_reset (hb_buffer_t *buffer) /** * hb_buffer_clear_contents: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * Similar to hb_buffer_reset(), but does not clear the Unicode functions and + * the replacement code point. * * Since: 0.9.11 **/ @@ -1184,12 +1209,13 @@ hb_buffer_clear_contents (hb_buffer_t *buffer) /** * hb_buffer_pre_allocate: - * @buffer: a buffer. - * @size: + * @buffer: an #hb_buffer_t. + * @size: number of items to pre allocate. * - * + * Pre allocates memory for @buffer to fit at least @size number of items. * - * Return value: + * Return value: + * %true if @buffer memory allocation succeeded, %false otherwise. * * Since: 0.9.2 **/ @@ -1201,11 +1227,12 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) /** * hb_buffer_allocation_successful: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * Check if allocating memory for the buffer succeeded. * - * Return value: + * Return value: + * %true if @buffer memory allocation succeeded, %false otherwise. * * Since: 0.9.2 **/ @@ -1217,11 +1244,18 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer) /** * hb_buffer_add: - * @buffer: a buffer. - * @codepoint: - * @cluster: + * @buffer: an #hb_buffer_t. + * @codepoint: a Unicode code point. + * @cluster: the cluster value of @codepoint. * - * + * Appends a character with the Unicode value of @codepoint to @buffer, and + * gives it the initial cluster value of @cluster. Clusters can be any thing + * the client wants, they are usually used to refer to the index of the + * character in the input text stream and are output in + * #hb_glyph_info_t.cluster field. + * + * This function does not check the validity of @codepoint, it is up to the + * caller to ensure it is a valid Unicode code point. * * Since: 0.9.7 **/ @@ -1236,12 +1270,14 @@ hb_buffer_add (hb_buffer_t *buffer, /** * hb_buffer_set_length: - * @buffer: a buffer. - * @length: + * @buffer: an #hb_buffer_t. + * @length: the new length of @buffer. * - * + * Similar to hb_buffer_pre_allocate(), but clears any new items added at the + * end. * * Return value: + * %true if @buffer memory allocation succeeded, %false otherwise. * * Since: 0.9.2 **/ @@ -1276,11 +1312,13 @@ hb_buffer_set_length (hb_buffer_t *buffer, /** * hb_buffer_get_length: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * * Returns the number of items in the buffer. * - * Return value: buffer length. + * Return value: + * The @buffer length. + * The value valid as long as buffer has not been modified. * * Since: 0.9.2 **/ @@ -1292,13 +1330,15 @@ hb_buffer_get_length (hb_buffer_t *buffer) /** * hb_buffer_get_glyph_infos: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * @length: (out): output array length. * - * Returns buffer glyph information array. Returned pointer - * is valid as long as buffer contents are not modified. + * Returns @buffer glyph information array. Returned pointer + * is valid as long as @buffer contents are not modified. * - * Return value: (transfer none) (array length=length): buffer glyph information array. + * Return value: (transfer none) (array length=length): + * The @buffer glyph information array. + * The value valid as long as buffer has not been modified. * * Since: 0.9.2 **/ @@ -1314,13 +1354,15 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer, /** * hb_buffer_get_glyph_positions: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * @length: (out): output length. * - * Returns buffer glyph position array. Returned pointer - * is valid as long as buffer contents are not modified. + * Returns @buffer glyph position array. Returned pointer + * is valid as long as @buffer contents are not modified. * - * Return value: (transfer none) (array length=length): buffer glyph position array. + * Return value: (transfer none) (array length=length): + * The @buffer glyph position array. + * The value valid as long as buffer has not been modified. * * Since: 0.9.2 **/ @@ -1339,7 +1381,7 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer, /** * hb_buffer_reverse: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * * Reverses buffer contents. * @@ -1353,7 +1395,7 @@ hb_buffer_reverse (hb_buffer_t *buffer) /** * hb_buffer_reverse_range: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * @start: start index. * @end: end index. * @@ -1370,7 +1412,7 @@ hb_buffer_reverse_range (hb_buffer_t *buffer, /** * hb_buffer_reverse_clusters: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * * Reverses buffer clusters. That is, the buffer contents are * reversed, then each cluster (consecutive items having the @@ -1386,7 +1428,7 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer) /** * hb_buffer_guess_segment_properties: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * * Sets unset buffer segment properties based on buffer Unicode * contents. If buffer is not empty, it must have content type @@ -1485,13 +1527,18 @@ hb_buffer_add_utf (hb_buffer_t *buffer, /** * hb_buffer_add_utf8: - * @buffer: a buffer. - * @text: (array length=text_length) (element-type uint8_t): - * @text_length: - * @item_offset: - * @item_length: + * @buffer: an #hb_buffer_t. + * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 + * characters to append. + * @text_length: the length of the @text, or -1 if it is %NULL terminated. + * @item_offset: the offset of the first character to add to the @buffer. + * @item_length: the number of characters to add to the @buffer, or -1 for the + * end of @text (assuming it is %NULL terminated). * - * + * See hb_buffer_add_codepoints(). + * + * Replaces invalid UTF-8 characters with the @buffer replacement code point, + * see hb_buffer_set_replacement_codepoint(). * * Since: 0.9.2 **/ @@ -1507,13 +1554,17 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer, /** * hb_buffer_add_utf16: - * @buffer: a buffer. - * @text: (array length=text_length): - * @text_length: - * @item_offset: - * @item_length: + * @buffer: an #hb_buffer_t. + * @text: (array length=text_length): an array of UTF-16 characters to append. + * @text_length: the length of the @text, or -1 if it is %NULL terminated. + * @item_offset: the offset of the first character to add to the @buffer. + * @item_length: the number of characters to add to the @buffer, or -1 for the + * end of @text (assuming it is %NULL terminated). * - * + * See hb_buffer_add_codepoints(). + * + * Replaces invalid UTF-16 characters with the @buffer replacement code point, + * see hb_buffer_set_replacement_codepoint(). * * Since: 0.9.2 **/ @@ -1529,13 +1580,17 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer, /** * hb_buffer_add_utf32: - * @buffer: a buffer. - * @text: (array length=text_length): - * @text_length: - * @item_offset: - * @item_length: + * @buffer: an #hb_buffer_t. + * @text: (array length=text_length): an array of UTF-32 characters to append. + * @text_length: the length of the @text, or -1 if it is %NULL terminated. + * @item_offset: the offset of the first character to add to the @buffer. + * @item_length: the number of characters to add to the @buffer, or -1 for the + * end of @text (assuming it is %NULL terminated). * - * + * See hb_buffer_add_codepoints(). + * + * Replaces invalid UTF-32 characters with the @buffer replacement code point, + * see hb_buffer_set_replacement_codepoint(). * * Since: 0.9.2 **/ @@ -1551,13 +1606,18 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, /** * hb_buffer_add_latin1: - * @buffer: a buffer. - * @text: (array length=text_length) (element-type uint8_t): - * @text_length: - * @item_offset: - * @item_length: + * @buffer: an #hb_buffer_t. + * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 + * characters to append. + * @text_length: the length of the @text, or -1 if it is %NULL terminated. + * @item_offset: the offset of the first character to add to the @buffer. + * @item_length: the number of characters to add to the @buffer, or -1 for the + * end of @text (assuming it is %NULL terminated). * - * + * Similar to hb_buffer_add_codepoints(), but allows only access to first 256 + * Unicode code points that can fit in 8-bit strings. + * + * Has nothing to do with non-Unicode Latin-1 encoding. * * Since: 0.9.39 **/ @@ -1573,13 +1633,25 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer, /** * hb_buffer_add_codepoints: - * @buffer: a buffer. - * @text: (array length=text_length): - * @text_length: - * @item_offset: - * @item_length: - * - * + * @buffer: a #hb_buffer_t to append characters to. + * @text: (array length=text_length): an array of Unicode code points to append. + * @text_length: the length of the @text, or -1 if it is %NULL terminated. + * @item_offset: the offset of the first code point to add to the @buffer. + * @item_length: the number of code points to add to the @buffer, or -1 for the + * end of @text (assuming it is %NULL terminated). + * + * Appends characters from @text array to @buffer. The @item_offset is the + * position of the first character from @text that will be appended, and + * @item_length is the number of character. When shaping part of a larger text + * (e.g. a run of text from a paragraph), instead of passing just the substring + * corresponding to the run, it is preferable to pass the whole + * paragraph and specify the run start and length as @item_offset and + * @item_length, respectively, to give HarfBuzz the full context to be able, + * for example, to do cross-run Arabic shaping or properly handle combining + * marks at stat of run. + * + * This function does not check the validity of @text, it is up to the caller + * to ensure it contains a valid Unicode code points. * * Since: 0.9.31 **/ @@ -1651,9 +1723,12 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, /** * hb_buffer_normalize_glyphs: - * @buffer: a buffer. + * @buffer: an #hb_buffer_t. * - * + * Reorders a glyph buffer to have canonical in-cluster glyph order / position. + * The resulting clusters should behave identical to pre-reordering clusters. + * + * This has nothing to do with Unicode normalization. * * Since: 0.9.2 **/ @@ -1699,3 +1774,45 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g } } } + +/* + * Debugging. + */ + +/** + * hb_buffer_set_message_func: + * @buffer: an #hb_buffer_t. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.1.3 + **/ +void +hb_buffer_set_message_func (hb_buffer_t *buffer, + hb_buffer_message_func_t func, + void *user_data, hb_destroy_func_t destroy) +{ + if (buffer->message_destroy) + buffer->message_destroy (buffer->message_data); + + if (func) { + buffer->message_func = func; + buffer->message_data = user_data; + buffer->message_destroy = destroy; + } else { + buffer->message_func = NULL; + buffer->message_data = NULL; + buffer->message_destroy = NULL; + } +} + +bool +hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap) +{ + char buf[100]; + vsnprintf (buf, sizeof (buf), fmt, ap); + return (bool) this->message_func (this, font, buf, this->message_data); +} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h index bb89dc3de7..bf289c19b3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h @@ -40,7 +40,27 @@ HB_BEGIN_DECLS - +/** + * hb_glyph_info_t: + * @codepoint: either a Unicode code point (before shaping) or a glyph index + * (after shaping). + * @mask: + * @cluster: the index of the character in the original text that corresponds + * to this #hb_glyph_info_t, or whatever the client passes to + * hb_buffer_add(). More than one #hb_glyph_info_t can have the same + * @cluster value, if they resulted from the same character (e.g. one + * to many glyph substitution), and when more than one character gets + * merged in the same glyph (e.g. many to one glyph substitution) the + * #hb_glyph_info_t will have the smallest cluster value of them. + * By default some characters are merged into the same cluster + * (e.g. combining marks have the same cluster as their bases) + * even if they are separate glyphs, hb_buffer_set_cluster_level() + * allow selecting more fine-grained cluster handling. + * + * The #hb_glyph_info_t is the structure that holds information about the + * glyphs and their relation to input text. + * + */ typedef struct hb_glyph_info_t { hb_codepoint_t codepoint; hb_mask_t mask; @@ -51,6 +71,22 @@ typedef struct hb_glyph_info_t { hb_var_int_t var2; } hb_glyph_info_t; +/** + * hb_glyph_position_t: + * @x_advance: how much the line advances after drawing this glyph when setting + * text in horizontal direction. + * @y_advance: how much the line advances after drawing this glyph when setting + * text in vertical direction. + * @x_offset: how much the glyph moves on the X-axis before drawing it, this + * should not affect how much the line advances. + * @y_offset: how much the glyph moves on the Y-axis before drawing it, this + * should not affect how much the line advances. + * + * The #hb_glyph_position_t is the structure that holds the positions of the + * glyph in both horizontal and vertical directions. All positions in + * #hb_glyph_position_t are relative to the current point. + * + */ typedef struct hb_glyph_position_t { hb_position_t x_advance; hb_position_t y_advance; @@ -61,7 +97,16 @@ typedef struct hb_glyph_position_t { hb_var_int_t var; } hb_glyph_position_t; - +/** + * hb_segment_properties_t: + * @direction: the #hb_direction_t of the buffer, see hb_buffer_set_direction(). + * @script: the #hb_script_t of the buffer, see hb_buffer_set_script(). + * @language: the #hb_language_t of the buffer, see hb_buffer_set_language(). + * + * The structure that holds various text properties of an #hb_buffer_t. Can be + * set and retrieved using hb_buffer_set_segment_properties() and + * hb_buffer_get_segment_properties(), respectively. + */ typedef struct hb_segment_properties_t { hb_direction_t direction; hb_script_t script; @@ -77,101 +122,125 @@ typedef struct hb_segment_properties_t { NULL, \ NULL} -hb_bool_t +HB_EXTERN hb_bool_t hb_segment_properties_equal (const hb_segment_properties_t *a, const hb_segment_properties_t *b); -unsigned int +HB_EXTERN unsigned int hb_segment_properties_hash (const hb_segment_properties_t *p); -/* - * hb_buffer_t +/** + * hb_buffer_t: + * + * The main structure holding the input text and its properties before shaping, + * and output glyphs and their information after shaping. */ typedef struct hb_buffer_t hb_buffer_t; -hb_buffer_t * +HB_EXTERN hb_buffer_t * hb_buffer_create (void); -hb_buffer_t * +HB_EXTERN hb_buffer_t * hb_buffer_get_empty (void); -hb_buffer_t * +HB_EXTERN hb_buffer_t * hb_buffer_reference (hb_buffer_t *buffer); -void +HB_EXTERN void hb_buffer_destroy (hb_buffer_t *buffer); -hb_bool_t +HB_EXTERN hb_bool_t hb_buffer_set_user_data (hb_buffer_t *buffer, hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy, hb_bool_t replace); -void * +HB_EXTERN void * hb_buffer_get_user_data (hb_buffer_t *buffer, hb_user_data_key_t *key); - +/** + * hb_buffer_content_type_t: + * @HB_BUFFER_CONTENT_TYPE_INVALID: Initial value for new buffer. + * @HB_BUFFER_CONTENT_TYPE_UNICODE: The buffer contains input characters (before shaping). + * @HB_BUFFER_CONTENT_TYPE_GLYPHS: The buffer contains output glyphs (after shaping). + */ typedef enum { HB_BUFFER_CONTENT_TYPE_INVALID = 0, HB_BUFFER_CONTENT_TYPE_UNICODE, HB_BUFFER_CONTENT_TYPE_GLYPHS } hb_buffer_content_type_t; -void +HB_EXTERN void hb_buffer_set_content_type (hb_buffer_t *buffer, hb_buffer_content_type_t content_type); -hb_buffer_content_type_t +HB_EXTERN hb_buffer_content_type_t hb_buffer_get_content_type (hb_buffer_t *buffer); -void +HB_EXTERN void hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, hb_unicode_funcs_t *unicode_funcs); -hb_unicode_funcs_t * +HB_EXTERN hb_unicode_funcs_t * hb_buffer_get_unicode_funcs (hb_buffer_t *buffer); -void +HB_EXTERN void hb_buffer_set_direction (hb_buffer_t *buffer, hb_direction_t direction); -hb_direction_t +HB_EXTERN hb_direction_t hb_buffer_get_direction (hb_buffer_t *buffer); -void +HB_EXTERN void hb_buffer_set_script (hb_buffer_t *buffer, hb_script_t script); -hb_script_t +HB_EXTERN hb_script_t hb_buffer_get_script (hb_buffer_t *buffer); -void +HB_EXTERN void hb_buffer_set_language (hb_buffer_t *buffer, hb_language_t language); -hb_language_t +HB_EXTERN hb_language_t hb_buffer_get_language (hb_buffer_t *buffer); -void +HB_EXTERN void hb_buffer_set_segment_properties (hb_buffer_t *buffer, const hb_segment_properties_t *props); -void +HB_EXTERN void hb_buffer_get_segment_properties (hb_buffer_t *buffer, hb_segment_properties_t *props); -void +HB_EXTERN void hb_buffer_guess_segment_properties (hb_buffer_t *buffer); -/* +/** + * hb_buffer_flags_t: + * @HB_BUFFER_FLAG_DEFAULT: the default buffer flag. + * @HB_BUFFER_FLAG_BOT: flag indicating that special handling of the beginning + * of text paragraph can be applied to this buffer. Should usually + * be set, unless you are passing to the buffer only part + * of the text without the full context. + * @HB_BUFFER_FLAG_EOT: flag indicating that special handling of the end of text + * paragraph can be applied to this buffer, similar to + * @HB_BUFFER_FLAG_EOT. + * @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES: + * flag indication that character with Default_Ignorable + * Unicode property should use the corresponding glyph + * from the font, instead of hiding them (currently done + * by replacing them with the space glyph and zeroing the + * advance width.) + * * Since: 0.9.20 */ typedef enum { /*< flags >*/ @@ -181,11 +250,11 @@ typedef enum { /*< flags >*/ HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u } hb_buffer_flags_t; -void +HB_EXTERN void hb_buffer_set_flags (hb_buffer_t *buffer, hb_buffer_flags_t flags); -hb_buffer_flags_t +HB_EXTERN hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer); /* @@ -198,93 +267,92 @@ typedef enum { HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES } hb_buffer_cluster_level_t; -void +HB_EXTERN void hb_buffer_set_cluster_level (hb_buffer_t *buffer, hb_buffer_cluster_level_t cluster_level); -hb_buffer_cluster_level_t +HB_EXTERN hb_buffer_cluster_level_t hb_buffer_get_cluster_level (hb_buffer_t *buffer); +/** + * HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT: + * + * The default code point for replacing invalid characters in a given encoding. + * Set to U+FFFD REPLACEMENT CHARACTER. + * + * Since: 0.9.31 + */ #define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu -/* Sets codepoint used to replace invalid UTF-8/16/32 entries. - * Default is 0xFFFDu. */ -void +HB_EXTERN void hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, hb_codepoint_t replacement); -hb_codepoint_t +HB_EXTERN hb_codepoint_t hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer); -/* Resets the buffer. Afterwards it's as if it was just created, - * except that it has a larger buffer allocated perhaps... */ -void +HB_EXTERN void hb_buffer_reset (hb_buffer_t *buffer); -/* Like reset, but does NOT clear unicode_funcs and replacement_codepoint. */ -void +HB_EXTERN void hb_buffer_clear_contents (hb_buffer_t *buffer); -/* Returns false if allocation failed */ -hb_bool_t +HB_EXTERN hb_bool_t hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size); -/* Returns false if allocation has failed before */ -hb_bool_t +HB_EXTERN hb_bool_t hb_buffer_allocation_successful (hb_buffer_t *buffer); -void +HB_EXTERN void hb_buffer_reverse (hb_buffer_t *buffer); -void +HB_EXTERN void hb_buffer_reverse_range (hb_buffer_t *buffer, unsigned int start, unsigned int end); -void +HB_EXTERN void hb_buffer_reverse_clusters (hb_buffer_t *buffer); /* Filling the buffer in */ -void +HB_EXTERN void hb_buffer_add (hb_buffer_t *buffer, hb_codepoint_t codepoint, unsigned int cluster); -void +HB_EXTERN void hb_buffer_add_utf8 (hb_buffer_t *buffer, const char *text, int text_length, unsigned int item_offset, int item_length); -void +HB_EXTERN void hb_buffer_add_utf16 (hb_buffer_t *buffer, const uint16_t *text, int text_length, unsigned int item_offset, int item_length); -void +HB_EXTERN void hb_buffer_add_utf32 (hb_buffer_t *buffer, const uint32_t *text, int text_length, unsigned int item_offset, int item_length); -/* Allows only access to first 256 Unicode codepoints. */ -void +HB_EXTERN void hb_buffer_add_latin1 (hb_buffer_t *buffer, const uint8_t *text, int text_length, unsigned int item_offset, int item_length); -/* Like add_utf32 but does NOT check for invalid Unicode codepoints. */ -void +HB_EXTERN void hb_buffer_add_codepoints (hb_buffer_t *buffer, const hb_codepoint_t *text, int text_length, @@ -292,32 +360,25 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer, int item_length); -/* Clears any new items added at the end */ -hb_bool_t +HB_EXTERN hb_bool_t hb_buffer_set_length (hb_buffer_t *buffer, unsigned int length); -/* Return value valid as long as buffer not modified */ -unsigned int +HB_EXTERN unsigned int hb_buffer_get_length (hb_buffer_t *buffer); /* Getting glyphs out of the buffer */ -/* Return value valid as long as buffer not modified */ -hb_glyph_info_t * +HB_EXTERN hb_glyph_info_t * hb_buffer_get_glyph_infos (hb_buffer_t *buffer, unsigned int *length); -/* Return value valid as long as buffer not modified */ -hb_glyph_position_t * +HB_EXTERN hb_glyph_position_t * hb_buffer_get_glyph_positions (hb_buffer_t *buffer, unsigned int *length); -/* Reorders a glyph buffer to have canonical in-cluster glyph order / position. - * The resulting clusters should behave identical to pre-reordering clusters. - * NOTE: This has nothing to do with Unicode normalization. */ -void +HB_EXTERN void hb_buffer_normalize_glyphs (hb_buffer_t *buffer); @@ -325,7 +386,16 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer); * Serialize */ -/* +/** + * hb_buffer_serialize_flags_t: + * @HB_BUFFER_SERIALIZE_FLAG_DEFAULT: serialize glyph names, clusters and positions. + * @HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS: do not serialize glyph cluster. + * @HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS: do not serialize glyph position information. + * @HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES: do no serialize glyph name. + * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents. + * + * Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs(). + * * Since: 0.9.20 */ typedef enum { /*< flags >*/ @@ -336,43 +406,67 @@ typedef enum { /*< flags >*/ HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u } hb_buffer_serialize_flags_t; +/** + * hb_buffer_serialize_format_t: + * @HB_BUFFER_SERIALIZE_FORMAT_TEXT: a human-readable, plain text format. + * @HB_BUFFER_SERIALIZE_FORMAT_JSON: a machine-readable JSON format. + * @HB_BUFFER_SERIALIZE_FORMAT_INVALID: invalid format. + * + * The buffer serialization and de-serialization format used in + * hb_buffer_serialize_glyphs() and hb_buffer_deserialize_glyphs(). + * + * Since: 0.9.2 + */ typedef enum { HB_BUFFER_SERIALIZE_FORMAT_TEXT = HB_TAG('T','E','X','T'), HB_BUFFER_SERIALIZE_FORMAT_JSON = HB_TAG('J','S','O','N'), HB_BUFFER_SERIALIZE_FORMAT_INVALID = HB_TAG_NONE } hb_buffer_serialize_format_t; -/* len=-1 means str is NUL-terminated. */ -hb_buffer_serialize_format_t +HB_EXTERN hb_buffer_serialize_format_t hb_buffer_serialize_format_from_string (const char *str, int len); -const char * +HB_EXTERN const char * hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format); -const char ** +HB_EXTERN const char ** hb_buffer_serialize_list_formats (void); -/* Returns number of items, starting at start, that were serialized. */ -unsigned int +HB_EXTERN unsigned int hb_buffer_serialize_glyphs (hb_buffer_t *buffer, unsigned int start, unsigned int end, char *buf, unsigned int buf_size, - unsigned int *buf_consumed, /* May be NULL */ - hb_font_t *font, /* May be NULL */ + unsigned int *buf_consumed, + hb_font_t *font, hb_buffer_serialize_format_t format, hb_buffer_serialize_flags_t flags); -hb_bool_t +HB_EXTERN hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, const char *buf, - int buf_len, /* -1 means nul-terminated */ - const char **end_ptr, /* May be NULL */ - hb_font_t *font, /* May be NULL */ + int buf_len, + const char **end_ptr, + hb_font_t *font, hb_buffer_serialize_format_t format); +/* + * Debugging. + */ + +typedef hb_bool_t (*hb_buffer_message_func_t) (hb_buffer_t *buffer, + hb_font_t *font, + const char *message, + void *user_data); + +HB_EXTERN void +hb_buffer_set_message_func (hb_buffer_t *buffer, + hb_buffer_message_func_t func, + void *user_data, hb_destroy_func_t destroy); + + HB_END_DECLS #endif /* HB_BUFFER_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh index 19b70b7e39..24957e1e96 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-cache-private.hh @@ -45,11 +45,11 @@ struct hb_cache_t inline bool get (unsigned int key, unsigned int *value) { - unsigned int k = key & ((1<> value_bits) != (key >> cache_bits)) return false; - *value = v & ((1<> key_bits) || (value >> value_bits))) return false; /* Overflows */ - unsigned int k = key & ((1<>cache_bits)< hb_cmap_cache_t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc index e67059d10b..3564e43557 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc @@ -88,7 +88,7 @@ hb_tag_from_string (const char *str, int len) /** * hb_tag_to_string: * @tag: - * @buf: (array fixed-size=4): + * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): * * * @@ -281,12 +281,15 @@ retry: /** * hb_language_from_string: - * @str: (array length=len) (element-type uint8_t): - * @len: + * @str: (array length=len) (element-type uint8_t): a string representing + * ISO 639 language code + * @len: length of the @str, or -1 if it is %NULL-terminated. * - * + * Converts @str representing an ISO 639 language code to the corresponding + * #hb_language_t. * * Return value: (transfer none): + * The #hb_language_t corresponding to the ISO 639 language code. * * Since: 0.9.2 **/ @@ -314,11 +317,13 @@ hb_language_from_string (const char *str, int len) /** * hb_language_to_string: - * @language: + * @language: an #hb_language_t to convert. * - * + * See hb_language_from_string(). * - * Return value: (transfer none): + * Return value: (transfer none): + * A %NULL-terminated string representing the @language. Must not be freed by + * the caller. * * Since: 0.9.2 **/ @@ -357,11 +362,12 @@ hb_language_get_default (void) /** * hb_script_from_iso15924_tag: - * @tag: + * @tag: an #hb_tag_t representing an ISO 15924 tag. * - * + * Converts an ISO 15924 script tag to a corresponding #hb_script_t. * * Return value: + * An #hb_script_t corresponding to the ISO 15924 tag. * * Since: 0.9.2 **/ @@ -401,28 +407,33 @@ hb_script_from_iso15924_tag (hb_tag_t tag) /** * hb_script_from_string: - * @s: (array length=len) (element-type uint8_t): - * @len: + * @str: (array length=len) (element-type uint8_t): a string representing an + * ISO 15924 tag. + * @len: length of the @str, or -1 if it is %NULL-terminated. * - * + * Converts a string @str representing an ISO 15924 script tag to a + * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then + * hb_script_from_iso15924_tag(). * * Return value: + * An #hb_script_t corresponding to the ISO 15924 tag. * * Since: 0.9.2 **/ hb_script_t -hb_script_from_string (const char *s, int len) +hb_script_from_string (const char *str, int len) { - return hb_script_from_iso15924_tag (hb_tag_from_string (s, len)); + return hb_script_from_iso15924_tag (hb_tag_from_string (str, len)); } /** * hb_script_to_iso15924_tag: - * @script: + * @script: an #hb_script_ to convert. * - * + * See hb_script_from_iso15924_tag(). * - * Return value: + * Return value: + * An #hb_tag_t representing an ISO 15924 script tag. * * Since: 0.9.2 **/ @@ -496,6 +507,9 @@ hb_script_get_horizontal_direction (hb_script_t script) /* Unicode-8.0 additions */ case HB_SCRIPT_OLD_HUNGARIAN: + /* Unicode-9.0 additions */ + case HB_SCRIPT_ADLAM: + return HB_DIRECTION_RTL; } @@ -521,7 +535,7 @@ hb_user_data_array_t::set (hb_user_data_key_t *key, } } hb_user_data_item_t item = {key, data, destroy}; - bool ret = !!items.replace_or_insert (item, lock, replace); + bool ret = !!items.replace_or_insert (item, lock, (bool) replace); return ret; } @@ -529,7 +543,7 @@ hb_user_data_array_t::set (hb_user_data_key_t *key, void * hb_user_data_array_t::get (hb_user_data_key_t *key) { - hb_user_data_item_t item = {NULL }; + hb_user_data_item_t item = {NULL, NULL, NULL}; return items.find (key, &item, lock) ? item.data : NULL; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h index c291dbbe94..2cbee76a8f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h @@ -98,16 +98,22 @@ typedef uint32_t hb_tag_t; #define HB_TAG_MAX_SIGNED HB_TAG(0x7f,0xff,0xff,0xff) /* len=-1 means str is NUL-terminated. */ -hb_tag_t +HB_EXTERN hb_tag_t hb_tag_from_string (const char *str, int len); /* buf should have 4 bytes. */ -void +HB_EXTERN void hb_tag_to_string (hb_tag_t tag, char *buf); -/* hb_direction_t */ - +/** + * hb_direction_t: + * @HB_DIRECTION_INVALID: Initial, unset direction. + * @HB_DIRECTION_LTR: Text is set horizontally from left to right. + * @HB_DIRECTION_RTL: Text is set horizontally from right to left. + * @HB_DIRECTION_TTB: Text is set vertically from top to bottom. + * @HB_DIRECTION_BTT: Text is set vertically from bottom to top. + */ typedef enum { HB_DIRECTION_INVALID = 0, HB_DIRECTION_LTR = 4, @@ -117,10 +123,10 @@ typedef enum { } hb_direction_t; /* len=-1 means str is NUL-terminated */ -hb_direction_t +HB_EXTERN hb_direction_t hb_direction_from_string (const char *str, int len); -const char * +HB_EXTERN const char * hb_direction_to_string (hb_direction_t direction); #define HB_DIRECTION_IS_VALID(dir) ((((unsigned int) (dir)) & ~3U) == 4) @@ -136,16 +142,15 @@ hb_direction_to_string (hb_direction_t direction); typedef const struct hb_language_impl_t *hb_language_t; -/* len=-1 means str is NUL-terminated */ -hb_language_t +HB_EXTERN hb_language_t hb_language_from_string (const char *str, int len); -const char * +HB_EXTERN const char * hb_language_to_string (hb_language_t language); #define HB_LANGUAGE_INVALID ((hb_language_t) NULL) -hb_language_t +HB_EXTERN hb_language_t hb_language_get_default (void); @@ -299,12 +304,22 @@ typedef enum /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), - /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), - /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), - /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), - /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), - /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), - /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), + /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), + /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), + /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), + /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), + /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), + /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), + + /* + * Since 1.3.0 + */ + /*9.0*/ HB_SCRIPT_ADLAM = HB_TAG ('A','d','l','m'), + /*9.0*/ HB_SCRIPT_BHAIKSUKI = HB_TAG ('B','h','k','s'), + /*9.0*/ HB_SCRIPT_MARCHEN = HB_TAG ('M','a','r','c'), + /*9.0*/ HB_SCRIPT_OSAGE = HB_TAG ('O','s','g','e'), + /*9.0*/ HB_SCRIPT_TANGUT = HB_TAG ('T','a','n','g'), + /*9.0*/ HB_SCRIPT_NEWA = HB_TAG ('N','e','w','a'), /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, @@ -324,18 +339,16 @@ typedef enum /* Script functions */ -hb_script_t +HB_EXTERN hb_script_t hb_script_from_iso15924_tag (hb_tag_t tag); -/* sugar for tag_from_string() then script_from_iso15924_tag */ -/* len=-1 means s is NUL-terminated */ -hb_script_t -hb_script_from_string (const char *s, int len); +HB_EXTERN hb_script_t +hb_script_from_string (const char *str, int len); -hb_tag_t +HB_EXTERN hb_tag_t hb_script_to_iso15924_tag (hb_script_t script); -hb_direction_t +HB_EXTERN hb_direction_t hb_script_get_horizontal_direction (hb_script_t script); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index 76c81e48f4..9865bbba41 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -27,7 +27,6 @@ */ #define HB_SHAPER coretext -#define hb_coretext_shaper_face_data_t CGFont #include "hb-shaper-impl-private.hh" #include "hb-coretext.h" @@ -91,6 +90,29 @@ HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font) * shaper face data */ +static CTFontDescriptorRef +get_last_resort_font_desc (void) +{ + // TODO Handle allocation failures? + CTFontDescriptorRef last_resort = CTFontDescriptorCreateWithNameAndSize (CFSTR("LastResort"), 0); + CFArrayRef cascade_list = CFArrayCreate (kCFAllocatorDefault, + (const void **) &last_resort, + 1, + &kCFTypeArrayCallBacks); + CFRelease (last_resort); + CFDictionaryRef attributes = CFDictionaryCreate (kCFAllocatorDefault, + (const void **) &kCTFontCascadeListAttribute, + (const void **) &cascade_list, + 1, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFRelease (cascade_list); + + CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); + CFRelease (attributes); + return font_desc; +} + static void release_data (void *info, const void *data, size_t size) { @@ -100,15 +122,14 @@ release_data (void *info, const void *data, size_t size) hb_blob_destroy ((hb_blob_t *) info); } -hb_coretext_shaper_face_data_t * -_hb_coretext_shaper_face_data_create (hb_face_t *face) +static CGFontRef +create_cg_font (hb_face_t *face) { - hb_coretext_shaper_face_data_t *data = NULL; - + CGFontRef cg_font = NULL; #if 0 if (face->destroy == (hb_destroy_func_t) CGFontRelease) { - data = CGFontRetain ((CGFontRef) face->user_data); + cg_font = CGFontRetain ((CGFontRef) face->user_data); } else { @@ -121,18 +142,119 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face) CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data); if (likely (provider)) { - data = CGFontCreateWithDataProvider (provider); + cg_font = CGFontCreateWithDataProvider (provider); + if (unlikely (!cg_font)) + DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); CGDataProviderRelease (provider); } } #else FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; - data = CGFontRetain (coreTextFontEngineData->cgFont); + cg_font = CGFontRetain (coreTextFontEngineData->cgFont); #endif + return cg_font; +} + +static CTFontRef +create_ct_font (CGFontRef cg_font, CGFloat font_size) +{ + CTFontRef ct_font = CTFontCreateWithGraphicsFont (cg_font, font_size, NULL, NULL); + if (unlikely (!ct_font)) { + DEBUG_MSG (CORETEXT, cg_font, "Font CTFontCreateWithGraphicsFont() failed"); + return NULL; + } + + /* crbug.com/576941 and crbug.com/625902 and the investigation in the latter + * bug indicate that the cascade list reconfiguration occasionally causes + * crashes in CoreText on OS X 10.9, thus let's skip this step on older + * operating system versions. Except for the emoji font, where _not_ + * reconfiguring the cascade list causes CoreText crashes. For details, see + * crbug.com/549610 */ + // 0x00070000 stands for "kCTVersionNumber10_10", see CoreText.h + if (&CTGetCoreTextVersion != NULL && CTGetCoreTextVersion() < 0x00070000) { + CFStringRef fontName = CTFontCopyPostScriptName (ct_font); + bool isEmojiFont = CFStringCompare (fontName, CFSTR("AppleColorEmoji"), 0) == kCFCompareEqualTo; + CFRelease (fontName); + if (!isEmojiFont) + return ct_font; + } + + CFURLRef original_url = (CFURLRef)CTFontCopyAttribute(ct_font, kCTFontURLAttribute); + + /* Create font copy with cascade list that has LastResort first; this speeds up CoreText + * font fallback which we don't need anyway. */ + { + CTFontDescriptorRef last_resort_font_desc = get_last_resort_font_desc (); + CTFontRef new_ct_font = CTFontCreateCopyWithAttributes (ct_font, 0.0, NULL, last_resort_font_desc); + CFRelease (last_resort_font_desc); + if (new_ct_font) + { + /* The CTFontCreateCopyWithAttributes call fails to stay on the same font + * when reconfiguring the cascade list and may switch to a different font + * when there are fonts that go by the same name, since the descriptor is + * just name and size. + * + * Avoid reconfiguring the cascade lists if the new font is outside the + * system locations that we cannot access from the sandboxed renderer + * process in Blink. This can be detected by the new file URL location + * that the newly found font points to. */ + CFURLRef new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute); + // Keep reconfigured font if URL cannot be retrieved (seems to be the case + // on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606 + if (!original_url || !new_url || CFEqual (original_url, new_url)) { + CFRelease (ct_font); + ct_font = new_ct_font; + } else { + CFRelease (new_ct_font); + DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed."); + } + if (new_url) + CFRelease (new_url); + } + else + DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed"); + } + + if (original_url) + CFRelease (original_url); + return ct_font; +} + +struct hb_coretext_shaper_face_data_t { + CGFontRef cg_font; + CTFontRef ct_font; +}; + +hb_coretext_shaper_face_data_t * +_hb_coretext_shaper_face_data_create (hb_face_t *face) +{ + hb_coretext_shaper_face_data_t *data = (hb_coretext_shaper_face_data_t *) calloc (1, sizeof (hb_coretext_shaper_face_data_t)); + if (unlikely (!data)) + return NULL; + + data->cg_font = create_cg_font (face); + if (unlikely (!data->cg_font)) + { + DEBUG_MSG (CORETEXT, face, "CGFont creation failed.."); + free (data); + return NULL; + } - if (unlikely (!data)) { - DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); + /* We use 36pt size instead of UPEM, because CoreText implements the 'trak' table, + * which can make the font too tight at large sizes. 36pt should be a good semi-neutral + * size. + * + * Since we always create CTFont at a fixed size, our CTFont lives in face_data + * instead of font_data. Which is good, because when people change scale on + * hb_font_t, we won't need to update our CTFont. */ + data->ct_font = create_ct_font (data->cg_font, 36.); + if (unlikely (!data->ct_font)) + { + DEBUG_MSG (CORETEXT, face, "CTFont creation failed."); + CFRelease (data->cg_font); + free (data); + return NULL; } return data; @@ -141,7 +263,9 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face) void _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data) { - CFRelease (data); + CFRelease (data->ct_font); + CFRelease (data->cg_font); + free (data); } /* @@ -152,7 +276,7 @@ hb_coretext_face_get_cg_font (hb_face_t *face) { if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL; hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - return face_data; + return face_data->cg_font; } @@ -160,56 +284,17 @@ hb_coretext_face_get_cg_font (hb_face_t *face) * shaper font data */ -struct hb_coretext_shaper_font_data_t { - CTFontRef ct_font; - CGFloat x_mult, y_mult; /* From CT space to HB space. */ -}; +struct hb_coretext_shaper_font_data_t {}; hb_coretext_shaper_font_data_t * -_hb_coretext_shaper_font_data_create (hb_font_t *font) +_hb_coretext_shaper_font_data_create (hb_font_t *font HB_UNUSED) { - if (unlikely (!hb_coretext_shaper_face_data_ensure (font->face))) return NULL; - - hb_coretext_shaper_font_data_t *data = (hb_coretext_shaper_font_data_t *) calloc (1, sizeof (hb_coretext_shaper_font_data_t)); - if (unlikely (!data)) - return NULL; - - hb_face_t *face = font->face; -#if 0 - hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - - /* Choose a CoreText font size and calculate multipliers to convert to HarfBuzz space. */ - /* TODO: use upem instead of 36? */ - CGFloat font_size = 36.; /* Default... */ - /* No idea if the following is even a good idea. */ - if (font->y_ppem) - font_size = font->y_ppem; - - if (font_size < 0) - font_size = -font_size; - data->x_mult = (CGFloat) font->x_scale / font_size; - data->y_mult = (CGFloat) font->y_scale / font_size; - data->ct_font = CTFontCreateWithGraphicsFont (face_data, font_size, NULL, NULL); -#else - data->x_mult = data->y_mult = (CGFloat) 64.0f; - FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; - CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; - data->ct_font = (CTFontRef) CFRetain (coreTextFontEngineData->ctFont); -#endif - if (unlikely (!data->ct_font)) { - DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); - free (data); - return NULL; - } - - return data; + return (hb_coretext_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; } void _hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data) { - CFRelease (data->ct_font); - free (data); } @@ -222,7 +307,9 @@ struct hb_coretext_shaper_shape_plan_data_t {}; hb_coretext_shaper_shape_plan_data_t * _hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED) + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) { return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; } @@ -235,9 +322,10 @@ _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_ CTFontRef hb_coretext_font_get_ct_font (hb_font_t *font) { - if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL; - hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); - return font_data->ct_font; + hb_face_t *face = font->face; + if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL; + hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); + return face_data->ct_font; } @@ -470,7 +558,10 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, { hb_face_t *face = font->face; hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); - hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font); + + CGFloat ct_font_size = CTFontGetSize (face_data->ct_font); + CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size; + CGFloat y_mult = (CGFloat) font->y_scale / ct_font_size; /* Attach marks to their bases, to match the 'ot' shaper. * Adapted from hb-ot-shape:hb_form_clusters(). @@ -479,6 +570,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, * B1 M1 B2 M2, and B1-B2 form a ligature, M2's cluster will * continue pointing to B2 even though B2 was merged into B1's * cluster... */ + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) { hb_unicode_funcs_t *unicode = buffer->unicode; unsigned int count = buffer->len; @@ -601,7 +693,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, CTFontDescriptorRef font_desc = CTFontDescriptorCreateWithAttributes (attributes); CFRelease (attributes); - range->font = CTFontCreateCopyWithAttributes (font_data->ct_font, 0.0, NULL, font_desc); + range->font = CTFontCreateCopyWithAttributes (face_data->ct_font, 0.0, NULL, font_desc); CFRelease (font_desc); } else @@ -662,7 +754,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan, pchars[chars_len++] = 0xFFFDu; else { pchars[chars_len++] = 0xD800u + ((c - 0x10000u) >> 10); - pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1 << 10) - 1)); + pchars[chars_len++] = 0xDC00u + ((c - 0x10000u) & ((1u << 10) - 1)); } } @@ -719,7 +811,6 @@ resize_and_retry: scratch += old_scratch_used; scratch_size -= old_scratch_used; } -retry: { string_ref = CFStringCreateWithCharactersNoCopy (NULL, pchars, chars_len, @@ -759,7 +850,7 @@ retry: CFRelease (lang); } CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), - kCTFontAttributeName, font_data->ct_font); + kCTFontAttributeName, face_data->ct_font); if (num_features) { @@ -844,8 +935,6 @@ retry: run_advance = -run_advance; DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); - CFRange range = CTRunGetStringRange (run); - /* CoreText does automatic font fallback (AKA "cascading") for characters * not supported by the requested font, and provides no way to turn it off, * so we must detect if the returned run uses a font other than the requested @@ -854,7 +943,7 @@ retry: */ CFDictionaryRef attributes = CTRunGetAttributes (run); CTFontRef run_ct_font = static_cast(CFDictionaryGetValue (attributes, kCTFontAttributeName)); - if (!CFEqual (run_ct_font, font_data->ct_font)) + if (!CFEqual (run_ct_font, face_data->ct_font)) { /* The run doesn't use our main font instance. We have to figure out * whether font fallback happened, or this is just CoreText giving us @@ -874,15 +963,11 @@ retry: * backend. * * However, even that wouldn't work if we were passed in the CGFont to - * begin with. - * - * Webkit uses a slightly different approach: it installs LastResort - * as fallback chain, and then checks PS name of used font against - * LastResort. That one is safe for any font except for LastResort, - * as opposed to ours, which can fail if we are using any uninstalled - * font that has the same name as an installed font. + * construct a hb_face to begin with. * * See: http://github.com/behdad/harfbuzz/pull/36 + * + * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098 */ bool matched = false; for (unsigned int i = 0; i < range_records.len; i++) @@ -896,13 +981,13 @@ retry: CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0); if (run_cg_font) { - matched = CFEqual (run_cg_font, face_data); + matched = CFEqual (run_cg_font, face_data->cg_font); CFRelease (run_cg_font); } } if (!matched) { - CFStringRef font_ps_name = CTFontCopyName (font_data->ct_font, kCTFontPostScriptNameKey); + CFStringRef font_ps_name = CTFontCopyName (face_data->ct_font, kCTFontPostScriptNameKey); CFStringRef run_ps_name = CTFontCopyName (run_ct_font, kCTFontPostScriptNameKey); CFComparisonResult result = CFStringCompare (run_ps_name, font_ps_name, 0); CFRelease (run_ps_name); @@ -912,6 +997,7 @@ retry: } if (!matched) { + CFRange range = CTRunGetStringRange (run); DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld", range.location, range.location + range.length); if (!buffer->ensure_inplace (buffer->len + range.length)) @@ -963,13 +1049,7 @@ retry: if (num_glyphs == 0) continue; - /* ### temporary fix for QTBUG-38113 */ - /* CoreText throws away the PDF token, while the OpenType backend will add a zero-advance - * glyph for this. We need to make sure the two produce the same output. */ - UniChar endGlyph = CFStringGetCharacterAtIndex (string_ref, range.location + range.length - 1); - bool endsWithPDF = endGlyph == 0x202c; - - if (!buffer->ensure_inplace (buffer->len + num_glyphs + (endsWithPDF ? 1 : 0))) + if (!buffer->ensure_inplace (buffer->len + num_glyphs)) goto resize_and_retry; hb_glyph_info_t *run_info = buffer->info + buffer->len; @@ -1027,7 +1107,6 @@ retry: positions = position_buf; } hb_glyph_info_t *info = run_info; - CGFloat x_mult = font_data->x_mult, y_mult = font_data->y_mult; if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) { hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult; @@ -1060,20 +1139,6 @@ retry: info++; } } - if (endsWithPDF) { - /* Ensure a zero-advance glyph the PDF token */ - if (unlikely (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))) { - memmove (run_info + 1, run_info, num_glyphs * sizeof (hb_glyph_info_t)); - info = run_info; - } - info->codepoint = 0xffff; - info->cluster = log_clusters[range.location + range.length - 1]; - info->mask = 0; - info->var1.u32 = 0; - info->var2.u32 = 0; - - buffer->len++; - } SCRATCH_RESTORE(); advances_so_far += run_advance; } @@ -1176,10 +1241,6 @@ fail: * AAT shaper */ -HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, face) -HB_SHAPER_DATA_ENSURE_DECLARE(coretext_aat, font) - - /* * shaper face data */ @@ -1240,7 +1301,9 @@ struct hb_coretext_aat_shaper_shape_plan_data_t {}; hb_coretext_aat_shaper_shape_plan_data_t * _hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, const hb_feature_t *user_features HB_UNUSED, - unsigned int num_user_features HB_UNUSED) + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) { return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h index 25267bc978..82066e4e0d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h @@ -44,14 +44,14 @@ HB_BEGIN_DECLS #define HB_CORETEXT_TAG_MORX HB_TAG('m','o','r','x') -hb_face_t * +HB_EXTERN hb_face_t * hb_coretext_face_create (CGFontRef cg_font); -CGFontRef +HB_EXTERN CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face); -CTFontRef +HB_EXTERN CTFontRef hb_coretext_font_get_ct_font (hb_font_t *font); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h index 30ae4b1caf..0398dfae60 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-deprecated.h @@ -44,6 +44,16 @@ HB_BEGIN_DECLS #define HB_BUFFER_FLAGS_DEFAULT HB_BUFFER_FLAG_DEFAULT #define HB_BUFFER_SERIALIZE_FLAGS_DEFAULT HB_BUFFER_SERIALIZE_FLAG_DEFAULT +typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t unicode, hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, + void *user_data); + +HB_EXTERN void +hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + #endif HB_END_DECLS diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc index 9effc41c88..6b563bc8f1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc @@ -35,8 +35,6 @@ #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" -#include "hb-cache-private.hh" - #include diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.h b/src/3rdparty/harfbuzz-ng/src/hb-face.h index f682c468de..91237b7085 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.h @@ -43,28 +43,28 @@ HB_BEGIN_DECLS typedef struct hb_face_t hb_face_t; -hb_face_t * +HB_EXTERN hb_face_t * hb_face_create (hb_blob_t *blob, unsigned int index); typedef hb_blob_t * (*hb_reference_table_func_t) (hb_face_t *face, hb_tag_t tag, void *user_data); /* calls destroy() when not needing user_data anymore */ -hb_face_t * +HB_EXTERN hb_face_t * hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, void *user_data, hb_destroy_func_t destroy); -hb_face_t * +HB_EXTERN hb_face_t * hb_face_get_empty (void); -hb_face_t * +HB_EXTERN hb_face_t * hb_face_reference (hb_face_t *face); -void +HB_EXTERN void hb_face_destroy (hb_face_t *face); -hb_bool_t +HB_EXTERN hb_bool_t hb_face_set_user_data (hb_face_t *face, hb_user_data_key_t *key, void * data, @@ -72,43 +72,43 @@ hb_face_set_user_data (hb_face_t *face, hb_bool_t replace); -void * +HB_EXTERN void * hb_face_get_user_data (hb_face_t *face, hb_user_data_key_t *key); -void +HB_EXTERN void hb_face_make_immutable (hb_face_t *face); -hb_bool_t +HB_EXTERN hb_bool_t hb_face_is_immutable (hb_face_t *face); -hb_blob_t * +HB_EXTERN hb_blob_t * hb_face_reference_table (hb_face_t *face, hb_tag_t tag); -hb_blob_t * +HB_EXTERN hb_blob_t * hb_face_reference_blob (hb_face_t *face); -void +HB_EXTERN void hb_face_set_index (hb_face_t *face, unsigned int index); -unsigned int +HB_EXTERN unsigned int hb_face_get_index (hb_face_t *face); -void +HB_EXTERN void hb_face_set_upem (hb_face_t *face, unsigned int upem); -unsigned int +HB_EXTERN unsigned int hb_face_get_upem (hb_face_t *face); -void +HB_EXTERN void hb_face_set_glyph_count (hb_face_t *face, unsigned int glyph_count); -unsigned int +HB_EXTERN unsigned int hb_face_get_glyph_count (hb_face_t *face); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc new file mode 100644 index 0000000000..ac6d4b00f5 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc @@ -0,0 +1,143 @@ +/* + * Copyright © 2011 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#define HB_SHAPER fallback +#include "hb-shaper-impl-private.hh" + + +/* + * shaper face data + */ + +struct hb_fallback_shaper_face_data_t {}; + +hb_fallback_shaper_face_data_t * +_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED) +{ + return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper font data + */ + +struct hb_fallback_shaper_font_data_t {}; + +hb_fallback_shaper_font_data_t * +_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED) +{ + return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper shape_plan data + */ + +struct hb_fallback_shaper_shape_plan_data_t {}; + +hb_fallback_shaper_shape_plan_data_t * +_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED, + const hb_feature_t *user_features HB_UNUSED, + unsigned int num_user_features HB_UNUSED, + const int *coords HB_UNUSED, + unsigned int num_coords HB_UNUSED) +{ + return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; +} + +void +_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED) +{ +} + + +/* + * shaper + */ + +hb_bool_t +_hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED, + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features HB_UNUSED, + unsigned int num_features HB_UNUSED) +{ + /* TODO + * + * - Apply fallback kern. + * - Handle Variation Selectors? + * - Apply normalization? + * + * This will make the fallback shaper into a dumb "TrueType" + * shaper which many people unfortunately still request. + */ + + hb_codepoint_t space; + bool has_space = (bool) font->get_nominal_glyph (' ', &space); + + buffer->clear_positions (); + + hb_direction_t direction = buffer->props.direction; + hb_unicode_funcs_t *unicode = buffer->unicode; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + for (unsigned int i = 0; i < count; i++) + { + if (has_space && unicode->is_default_ignorable (info[i].codepoint)) { + info[i].codepoint = space; + pos[i].x_advance = 0; + pos[i].y_advance = 0; + continue; + } + font->get_nominal_glyph (info[i].codepoint, &info[i].codepoint); + font->get_glyph_advance_for_direction (info[i].codepoint, + direction, + &pos[i].x_advance, + &pos[i].y_advance); + font->subtract_glyph_origin_for_direction (info[i].codepoint, + direction, + &pos[i].x_offset, + &pos[i].y_offset); + } + + if (HB_DIRECTION_IS_BACKWARD (direction)) + hb_buffer_reverse (buffer); + + return true; +} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh index c05499d4c2..53671d78d2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh @@ -42,7 +42,10 @@ */ #define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \ - HB_FONT_FUNC_IMPLEMENT (glyph) \ + HB_FONT_FUNC_IMPLEMENT (font_h_extents) \ + HB_FONT_FUNC_IMPLEMENT (font_v_extents) \ + HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \ + HB_FONT_FUNC_IMPLEMENT (variation_glyph) \ HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \ HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \ HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \ @@ -61,14 +64,6 @@ struct hb_font_funcs_t { hb_bool_t immutable; - /* Don't access these directly. Call hb_font_get_*() instead. */ - - struct { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_FONT_FUNC_IMPLEMENT - } get; - struct { #define HB_FONT_FUNC_IMPLEMENT(name) void *name; HB_FONT_FUNCS_IMPLEMENT_CALLBACKS @@ -80,6 +75,16 @@ struct hb_font_funcs_t { HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT } destroy; + + /* Don't access these directly. Call font->get_*() instead. */ + union get_t { + struct get_funcs_t { +#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name; + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + } f; + void (*array[VAR]) (void); + } get; }; @@ -103,6 +108,10 @@ struct hb_font_t { unsigned int x_ppem; unsigned int y_ppem; + /* Font variation coordinates. */ + unsigned int num_coords; + int *coords; + hb_font_funcs_t *klass; void *user_data; hb_destroy_func_t destroy; @@ -111,8 +120,14 @@ struct hb_font_t { /* Convert from font-space to user-space */ - inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); } - inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, this->y_scale); } + inline int dir_scale (hb_direction_t direction) + { return HB_DIRECTION_IS_VERTICAL(direction) ? y_scale : x_scale; } + inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, x_scale); } + inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); } + inline hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); } + inline hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); } + inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction) + { return em_scale (v, dir_scale (direction)); } /* Convert from parent-font user-space to our user-space */ inline hb_position_t parent_scale_x_distance (hb_position_t v) { @@ -144,95 +159,133 @@ struct hb_font_t { /* Public getters */ - inline hb_bool_t has_glyph (hb_codepoint_t unicode) + HB_INTERNAL bool has_func (unsigned int i); + + /* has_* ... */ +#define HB_FONT_FUNC_IMPLEMENT(name) \ + bool \ + has_##name##_func (void) \ + { \ + hb_font_funcs_t *funcs = this->klass; \ + unsigned int i = offsetof (hb_font_funcs_t::get_t::get_funcs_t, name) / sizeof (funcs->get.array[0]); \ + return has_func (i); \ + } + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + + inline hb_bool_t get_font_h_extents (hb_font_extents_t *extents) + { + memset (extents, 0, sizeof (*extents)); + return klass->get.f.font_h_extents (this, user_data, + extents, + klass->user_data.font_h_extents); + } + inline hb_bool_t get_font_v_extents (hb_font_extents_t *extents) + { + memset (extents, 0, sizeof (*extents)); + return klass->get.f.font_v_extents (this, user_data, + extents, + klass->user_data.font_v_extents); + } + + inline bool has_glyph (hb_codepoint_t unicode) { hb_codepoint_t glyph; - return get_glyph (unicode, 0, &glyph); + return get_nominal_glyph (unicode, &glyph); } - inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph) + inline hb_bool_t get_nominal_glyph (hb_codepoint_t unicode, + hb_codepoint_t *glyph) { *glyph = 0; - return klass->get.glyph (this, user_data, - unicode, variation_selector, glyph, - klass->user_data.glyph); + return klass->get.f.nominal_glyph (this, user_data, + unicode, glyph, + klass->user_data.nominal_glyph); + } + + inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, + hb_codepoint_t *glyph) + { + *glyph = 0; + return klass->get.f.variation_glyph (this, user_data, + unicode, variation_selector, glyph, + klass->user_data.variation_glyph); } inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) { - return klass->get.glyph_h_advance (this, user_data, - glyph, - klass->user_data.glyph_h_advance); + return klass->get.f.glyph_h_advance (this, user_data, + glyph, + klass->user_data.glyph_h_advance); } inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) { - return klass->get.glyph_v_advance (this, user_data, - glyph, - klass->user_data.glyph_v_advance); + return klass->get.f.glyph_v_advance (this, user_data, + glyph, + klass->user_data.glyph_v_advance); } inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { *x = *y = 0; - return klass->get.glyph_h_origin (this, user_data, - glyph, x, y, - klass->user_data.glyph_h_origin); + return klass->get.f.glyph_h_origin (this, user_data, + glyph, x, y, + klass->user_data.glyph_h_origin); } inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { *x = *y = 0; - return klass->get.glyph_v_origin (this, user_data, - glyph, x, y, - klass->user_data.glyph_v_origin); + return klass->get.f.glyph_v_origin (this, user_data, + glyph, x, y, + klass->user_data.glyph_v_origin); } inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) { - return klass->get.glyph_h_kerning (this, user_data, - left_glyph, right_glyph, - klass->user_data.glyph_h_kerning); + return klass->get.f.glyph_h_kerning (this, user_data, + left_glyph, right_glyph, + klass->user_data.glyph_h_kerning); } inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph) { - return klass->get.glyph_v_kerning (this, user_data, - top_glyph, bottom_glyph, - klass->user_data.glyph_v_kerning); + return klass->get.f.glyph_v_kerning (this, user_data, + top_glyph, bottom_glyph, + klass->user_data.glyph_v_kerning); } inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) { memset (extents, 0, sizeof (*extents)); - return klass->get.glyph_extents (this, user_data, - glyph, - extents, - klass->user_data.glyph_extents); + return klass->get.f.glyph_extents (this, user_data, + glyph, + extents, + klass->user_data.glyph_extents); } inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, hb_position_t *x, hb_position_t *y) { *x = *y = 0; - return klass->get.glyph_contour_point (this, user_data, - glyph, point_index, - x, y, - klass->user_data.glyph_contour_point); + return klass->get.f.glyph_contour_point (this, user_data, + glyph, point_index, + x, y, + klass->user_data.glyph_contour_point); } inline hb_bool_t get_glyph_name (hb_codepoint_t glyph, char *name, unsigned int size) { if (size) *name = '\0'; - return klass->get.glyph_name (this, user_data, - glyph, - name, size, - klass->user_data.glyph_name); + return klass->get.f.glyph_name (this, user_data, + glyph, + name, size, + klass->user_data.glyph_name); } inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */ @@ -240,15 +293,43 @@ struct hb_font_t { { *glyph = 0; if (len == -1) len = strlen (name); - return klass->get.glyph_from_name (this, user_data, - name, len, - glyph, - klass->user_data.glyph_from_name); + return klass->get.f.glyph_from_name (this, user_data, + name, len, + glyph, + klass->user_data.glyph_from_name); } /* A bit higher-level, and with fallback */ + inline void get_h_extents_with_fallback (hb_font_extents_t *extents) + { + if (!get_font_h_extents (extents)) + { + extents->ascender = y_scale * .8; + extents->descender = extents->ascender - y_scale; + extents->line_gap = 0; + } + } + inline void get_v_extents_with_fallback (hb_font_extents_t *extents) + { + if (!get_font_v_extents (extents)) + { + extents->ascender = x_scale / 2; + extents->descender = extents->ascender - x_scale; + extents->line_gap = 0; + } + } + + inline void get_extents_for_direction (hb_direction_t direction, + hb_font_extents_t *extents) + { + if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) + get_h_extents_with_fallback (extents); + else + get_v_extents_with_fallback (extents); + } + inline void get_glyph_advance_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) @@ -262,14 +343,38 @@ struct hb_font_t { } } - /* Internal only */ inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) { *x = get_glyph_h_advance (glyph) / 2; - /* TODO use font_metrics.ascent */ - *y = y_scale; + /* TODO cache this somehow?! */ + hb_font_extents_t extents; + get_h_extents_with_fallback (&extents); + *y = extents.ascender; + } + + inline void get_glyph_h_origin_with_fallback (hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y) + { + if (!get_glyph_h_origin (glyph, x, y) && + get_glyph_v_origin (glyph, x, y)) + { + hb_position_t dx, dy; + guess_v_origin_minus_h_origin (glyph, &dx, &dy); + *x -= dx; *y -= dy; + } + } + inline void get_glyph_v_origin_with_fallback (hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y) + { + if (!get_glyph_v_origin (glyph, x, y) && + get_glyph_h_origin (glyph, x, y)) + { + hb_position_t dx, dy; + guess_v_origin_minus_h_origin (glyph, &dx, &dy); + *x += dx; *y += dy; + } } inline void get_glyph_origin_for_direction (hb_codepoint_t glyph, @@ -277,27 +382,31 @@ struct hb_font_t { hb_position_t *x, hb_position_t *y) { if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) - { - if (!get_glyph_h_origin (glyph, x, y) && - get_glyph_v_origin (glyph, x, y)) - { - hb_position_t dx, dy; - guess_v_origin_minus_h_origin (glyph, &dx, &dy); - *x -= dx; *y -= dy; - } - } + get_glyph_h_origin_with_fallback (glyph, x, y); else - { - if (!get_glyph_v_origin (glyph, x, y) && - get_glyph_h_origin (glyph, x, y)) - { - hb_position_t dx, dy; - guess_v_origin_minus_h_origin (glyph, &dx, &dy); - *x += dx; *y += dy; - } - } + get_glyph_v_origin_with_fallback (glyph, x, y); } + inline void add_glyph_h_origin (hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y) + { + hb_position_t origin_x, origin_y; + + get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); + + *x += origin_x; + *y += origin_y; + } + inline void add_glyph_v_origin (hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y) + { + hb_position_t origin_x, origin_y; + + get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); + + *x += origin_x; + *y += origin_y; + } inline void add_glyph_origin_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) @@ -310,6 +419,26 @@ struct hb_font_t { *y += origin_y; } + inline void subtract_glyph_h_origin (hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y) + { + hb_position_t origin_x, origin_y; + + get_glyph_h_origin_with_fallback (glyph, &origin_x, &origin_y); + + *x -= origin_x; + *y -= origin_y; + } + inline void subtract_glyph_v_origin (hb_codepoint_t glyph, + hb_position_t *x, hb_position_t *y) + { + hb_position_t origin_x, origin_y; + + get_glyph_v_origin_with_fallback (glyph, &origin_x, &origin_y); + + *x -= origin_x; + *y -= origin_y; + } inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y) @@ -394,15 +523,24 @@ struct hb_font_t { hb_codepoint_t unichar; if (0 == strncmp (s, "uni", 3) && hb_codepoint_parse (s + 3, len - 3, 16, &unichar) && - get_glyph (unichar, 0, glyph)) + get_nominal_glyph (unichar, glyph)) return true; } return false; } - private: - inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); } + inline hb_position_t em_scale (int16_t v, int scale) + { + int upem = face->get_upem (); + int64_t scaled = v * (int64_t) scale; + scaled += scaled >= 0 ? upem/2 : -upem/2; /* Round. */ + return (hb_position_t) (scaled / upem); + } + inline hb_position_t em_scalef (float v, int scale) + { + return (hb_position_t) (v * scale / face->get_upem ()); + } }; #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc index 6a69cae313..2935c4b4fd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc @@ -35,8 +35,6 @@ #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" -#include "hb-cache-private.hh" - #include @@ -45,130 +43,246 @@ */ static hb_bool_t -hb_font_get_glyph_nil (hb_font_t *font, - void *font_data HB_UNUSED, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) +hb_font_get_font_h_extents_nil (hb_font_t *font, + void *font_data HB_UNUSED, + hb_font_extents_t *metrics, + void *user_data HB_UNUSED) { - if (font->parent) - return font->parent->get_glyph (unicode, variation_selector, glyph); + memset (metrics, 0, sizeof (*metrics)); + return false; +} +static hb_bool_t +hb_font_get_font_h_extents_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_font_extents_t *metrics, + void *user_data HB_UNUSED) +{ + hb_bool_t ret = font->parent->get_font_h_extents (metrics); + if (ret) { + metrics->ascender = font->parent_scale_y_distance (metrics->ascender); + metrics->descender = font->parent_scale_y_distance (metrics->descender); + metrics->line_gap = font->parent_scale_y_distance (metrics->line_gap); + } + return ret; +} +static hb_bool_t +hb_font_get_font_v_extents_nil (hb_font_t *font, + void *font_data HB_UNUSED, + hb_font_extents_t *metrics, + void *user_data HB_UNUSED) +{ + memset (metrics, 0, sizeof (*metrics)); + return false; +} +static hb_bool_t +hb_font_get_font_v_extents_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_font_extents_t *metrics, + void *user_data HB_UNUSED) +{ + hb_bool_t ret = font->parent->get_font_v_extents (metrics); + if (ret) { + metrics->ascender = font->parent_scale_x_distance (metrics->ascender); + metrics->descender = font->parent_scale_x_distance (metrics->descender); + metrics->line_gap = font->parent_scale_x_distance (metrics->line_gap); + } + return ret; +} + +static hb_bool_t +hb_font_get_nominal_glyph_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) +{ *glyph = 0; return false; } +static hb_bool_t +hb_font_get_nominal_glyph_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) +{ + return font->parent->get_nominal_glyph (unicode, glyph); +} + +static hb_bool_t +hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED, + void *font_data HB_UNUSED, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) +{ + *glyph = 0; + return false; +} +static hb_bool_t +hb_font_get_variation_glyph_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) +{ + return font->parent->get_variation_glyph (unicode, variation_selector, glyph); +} + static hb_position_t -hb_font_get_glyph_h_advance_nil (hb_font_t *font, +hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t glyph, void *user_data HB_UNUSED) { - if (font->parent) - return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); - return font->x_scale; } +static hb_position_t +hb_font_get_glyph_h_advance_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + void *user_data HB_UNUSED) +{ + return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph)); +} static hb_position_t -hb_font_get_glyph_v_advance_nil (hb_font_t *font, +hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t glyph, void *user_data HB_UNUSED) { - if (font->parent) - return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); - + /* TODO use font_extents.ascender+descender */ return font->y_scale; } +static hb_position_t +hb_font_get_glyph_v_advance_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + void *user_data HB_UNUSED) +{ + return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph)); +} static hb_bool_t -hb_font_get_glyph_h_origin_nil (hb_font_t *font, +hb_font_get_glyph_h_origin_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y, void *user_data HB_UNUSED) { - if (font->parent) { - hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); - if (ret) - font->parent_scale_position (x, y); - return ret; - } - *x = *y = 0; - return false; + return true; +} +static hb_bool_t +hb_font_get_glyph_h_origin_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) +{ + hb_bool_t ret = font->parent->get_glyph_h_origin (glyph, x, y); + if (ret) + font->parent_scale_position (x, y); + return ret; } static hb_bool_t -hb_font_get_glyph_v_origin_nil (hb_font_t *font, +hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y, void *user_data HB_UNUSED) { - if (font->parent) { - hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); - if (ret) - font->parent_scale_position (x, y); - return ret; - } - *x = *y = 0; return false; } +static hb_bool_t +hb_font_get_glyph_v_origin_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) +{ + hb_bool_t ret = font->parent->get_glyph_v_origin (glyph, x, y); + if (ret) + font->parent_scale_position (x, y); + return ret; +} static hb_position_t -hb_font_get_glyph_h_kerning_nil (hb_font_t *font, +hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t left_glyph, hb_codepoint_t right_glyph, void *user_data HB_UNUSED) { - if (font->parent) - return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); - return 0; } +static hb_position_t +hb_font_get_glyph_h_kerning_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t left_glyph, + hb_codepoint_t right_glyph, + void *user_data HB_UNUSED) +{ + return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph)); +} static hb_position_t -hb_font_get_glyph_v_kerning_nil (hb_font_t *font, +hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph, void *user_data HB_UNUSED) { - if (font->parent) - return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); - return 0; } +static hb_position_t +hb_font_get_glyph_v_kerning_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t top_glyph, + hb_codepoint_t bottom_glyph, + void *user_data HB_UNUSED) +{ + return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph)); +} static hb_bool_t -hb_font_get_glyph_extents_nil (hb_font_t *font, +hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t glyph, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - if (font->parent) { - hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); - if (ret) { - font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); - font->parent_scale_distance (&extents->width, &extents->height); - } - return ret; - } - memset (extents, 0, sizeof (*extents)); return false; } +static hb_bool_t +hb_font_get_glyph_extents_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + void *user_data HB_UNUSED) +{ + hb_bool_t ret = font->parent->get_glyph_extents (glyph, extents); + if (ret) { + font->parent_scale_position (&extents->x_bearing, &extents->y_bearing); + font->parent_scale_distance (&extents->width, &extents->height); + } + return ret; +} static hb_bool_t -hb_font_get_glyph_contour_point_nil (hb_font_t *font, +hb_font_get_glyph_contour_point_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t glyph, unsigned int point_index, @@ -176,45 +290,63 @@ hb_font_get_glyph_contour_point_nil (hb_font_t *font, hb_position_t *y, void *user_data HB_UNUSED) { - if (font->parent) { - hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); - if (ret) - font->parent_scale_position (x, y); - return ret; - } - *x = *y = 0; return false; } +static hb_bool_t +hb_font_get_glyph_contour_point_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + unsigned int point_index, + hb_position_t *x, + hb_position_t *y, + void *user_data HB_UNUSED) +{ + hb_bool_t ret = font->parent->get_glyph_contour_point (glyph, point_index, x, y); + if (ret) + font->parent_scale_position (x, y); + return ret; +} static hb_bool_t -hb_font_get_glyph_name_nil (hb_font_t *font, +hb_font_get_glyph_name_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, hb_codepoint_t glyph, char *name, unsigned int size, void *user_data HB_UNUSED) { - if (font->parent) - return font->parent->get_glyph_name (glyph, name, size); - if (size) *name = '\0'; return false; } +static hb_bool_t +hb_font_get_glyph_name_parent (hb_font_t *font, + void *font_data HB_UNUSED, + hb_codepoint_t glyph, + char *name, unsigned int size, + void *user_data HB_UNUSED) +{ + return font->parent->get_glyph_name (glyph, name, size); +} static hb_bool_t -hb_font_get_glyph_from_name_nil (hb_font_t *font, +hb_font_get_glyph_from_name_nil (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED, const char *name, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph, void *user_data HB_UNUSED) { - if (font->parent) - return font->parent->get_glyph_from_name (name, len, glyph); - *glyph = 0; return false; } - +static hb_bool_t +hb_font_get_glyph_from_name_parent (hb_font_t *font, + void *font_data HB_UNUSED, + const char *name, int len, /* -1 means nul-terminated */ + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) +{ + return font->parent->get_glyph_from_name (name, len, glyph); +} static const hb_font_funcs_t _hb_font_funcs_nil = { HB_OBJECT_HEADER_STATIC, @@ -222,9 +354,44 @@ static const hb_font_funcs_t _hb_font_funcs_nil = { true, /* immutable */ { +#define HB_FONT_FUNC_IMPLEMENT(name) NULL, + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + }, + { +#define HB_FONT_FUNC_IMPLEMENT(name) NULL, + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + }, + { + { #define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil, + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + } + } +}; +static const hb_font_funcs_t _hb_font_funcs_parent = { + HB_OBJECT_HEADER_STATIC, + + true, /* immutable */ + + { +#define HB_FONT_FUNC_IMPLEMENT(name) NULL, + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + }, + { +#define HB_FONT_FUNC_IMPLEMENT(name) NULL, HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT + }, + { + { +#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_parent, + HB_FONT_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_FONT_FUNC_IMPLEMENT + } } }; @@ -246,7 +413,7 @@ hb_font_funcs_create (void) if (!(ffuncs = hb_object_create ())) return hb_font_funcs_get_empty (); - ffuncs->get = _hb_font_funcs_nil.get; + ffuncs->get = _hb_font_funcs_parent.get; return ffuncs; } @@ -263,7 +430,7 @@ hb_font_funcs_create (void) hb_font_funcs_t * hb_font_funcs_get_empty (void) { - return const_cast (&_hb_font_funcs_nil); + return const_cast (&_hb_font_funcs_parent); } /** @@ -398,11 +565,11 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ ffuncs->destroy.name (ffuncs->user_data.name); \ \ if (func) { \ - ffuncs->get.name = func; \ + ffuncs->get.f.name = func; \ ffuncs->user_data.name = user_data; \ ffuncs->destroy.name = destroy; \ } else { \ - ffuncs->get.name = hb_font_get_##name##_nil; \ + ffuncs->get.f.name = hb_font_get_##name##_parent; \ ffuncs->user_data.name = NULL; \ ffuncs->destroy.name = NULL; \ } \ @@ -411,9 +578,52 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS #undef HB_FONT_FUNC_IMPLEMENT +bool +hb_font_t::has_func (unsigned int i) +{ + if (parent && parent != hb_font_get_empty () && parent->has_func (i)) + return true; + return this->klass->get.array[i] != _hb_font_funcs_parent.get.array[i]; +} /* Public getters */ +/** + * hb_font_get_h_extents: + * @font: a font. + * @extents: (out): + * + * + * + * Return value: + * + * Since: 1.1.3 + **/ +hb_bool_t +hb_font_get_h_extents (hb_font_t *font, + hb_font_extents_t *extents) +{ + return font->get_font_h_extents (extents); +} + +/** + * hb_font_get_v_extents: + * @font: a font. + * @extents: (out): + * + * + * + * Return value: + * + * Since: 1.1.3 + **/ +hb_bool_t +hb_font_get_v_extents (hb_font_t *font, + hb_font_extents_t *extents) +{ + return font->get_font_v_extents (extents); +} + /** * hb_font_get_glyph: * @font: a font. @@ -432,7 +642,50 @@ hb_font_get_glyph (hb_font_t *font, hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_codepoint_t *glyph) { - return font->get_glyph (unicode, variation_selector, glyph); + if (unlikely (variation_selector)) + return font->get_variation_glyph (unicode, variation_selector, glyph); + return font->get_nominal_glyph (unicode, glyph); +} + +/** + * hb_font_get_nominal_glyph: + * @font: a font. + * @unicode: + * @glyph: (out): + * + * + * + * Return value: + * + * Since: 1.2.3 + **/ +hb_bool_t +hb_font_get_nominal_glyph (hb_font_t *font, + hb_codepoint_t unicode, + hb_codepoint_t *glyph) +{ + return font->get_nominal_glyph (unicode, glyph); +} + +/** + * hb_font_get_variation_glyph: + * @font: a font. + * @unicode: + * @variation_selector: + * @glyph: (out): + * + * + * + * Return value: + * + * Since: 1.2.3 + **/ +hb_bool_t +hb_font_get_variation_glyph (hb_font_t *font, + hb_codepoint_t unicode, hb_codepoint_t variation_selector, + hb_codepoint_t *glyph) +{ + return font->get_variation_glyph (unicode, variation_selector, glyph); } /** @@ -638,6 +891,23 @@ hb_font_get_glyph_from_name (hb_font_t *font, /* A bit higher-level, and with fallback */ +/** + * hb_font_get_extents_for_direction: + * @font: a font. + * @direction: + * @extents: + * + * + * + * Since: 1.1.3 + **/ +void +hb_font_get_extents_for_direction (hb_font_t *font, + hb_direction_t direction, + hb_font_extents_t *extents) +{ + return font->get_extents_for_direction (direction, extents); +} /** * hb_font_get_glyph_advance_for_direction: * @font: a font. @@ -858,6 +1128,7 @@ hb_font_create (hb_face_t *face) return hb_font_get_empty (); hb_face_make_immutable (face); + font->parent = hb_font_get_empty (); font->face = hb_face_reference (face); font->klass = hb_font_funcs_get_empty (); @@ -894,6 +1165,8 @@ hb_font_create_sub_font (hb_font_t *parent) font->x_ppem = parent->x_ppem; font->y_ppem = parent->y_ppem; + /* TODO: copy variation coordinates. */ + return font; } @@ -917,12 +1190,15 @@ hb_font_get_empty (void) NULL, /* parent */ const_cast (&_hb_face_nil), - 0, /* x_scale */ - 0, /* y_scale */ + 1000, /* x_scale */ + 1000, /* y_scale */ 0, /* x_ppem */ 0, /* y_ppem */ + 0, /* num_coords */ + NULL, /* coords */ + const_cast (&_hb_font_funcs_nil), /* klass */ NULL, /* user_data */ NULL, /* destroy */ @@ -977,6 +1253,8 @@ hb_font_destroy (hb_font_t *font) hb_face_destroy (font->face); hb_font_funcs_destroy (font->klass); + free (font->coords); + free (font); } @@ -1264,3 +1542,157 @@ hb_font_get_ppem (hb_font_t *font, if (x_ppem) *x_ppem = font->x_ppem; if (y_ppem) *y_ppem = font->y_ppem; } + + +void +hb_font_set_var_coords_normalized (hb_font_t *font, + int *coords, /* XXX 2.14 normalized */ + unsigned int coords_length) +{ + if (font->immutable) + return; + + /* Skip tail zero entries. */ + while (coords_length && !coords[coords_length - 1]) + coords_length--; + + int *copy = coords_length ? (int *) calloc (coords_length, sizeof (coords[0])) : NULL; + if (unlikely (coords_length && !copy)) + return; + + free (font->coords); + + if (coords_length) + memcpy (copy, coords, coords_length * sizeof (coords[0])); + + font->coords = copy; + font->num_coords = coords_length; +} + + +#ifndef HB_DISABLE_DEPRECATED + +/* + * Deprecated get_glyph_func(): + */ + +struct hb_trampoline_closure_t +{ + void *user_data; + hb_destroy_func_t destroy; + unsigned int ref_count; +}; + +template +struct hb_trampoline_t +{ + hb_trampoline_closure_t closure; /* Must be first. */ + FuncType func; +}; + +template +static hb_trampoline_t * +trampoline_create (FuncType func, + void *user_data, + hb_destroy_func_t destroy) +{ + typedef hb_trampoline_t trampoline_t; + + trampoline_t *trampoline = (trampoline_t *) calloc (1, sizeof (trampoline_t)); + + if (unlikely (!trampoline)) + return NULL; + + trampoline->closure.user_data = user_data; + trampoline->closure.destroy = destroy; + trampoline->closure.ref_count = 1; + trampoline->func = func; + + return trampoline; +} + +static void +trampoline_reference (hb_trampoline_closure_t *closure) +{ + closure->ref_count++; +} + +static void +trampoline_destroy (void *user_data) +{ + hb_trampoline_closure_t *closure = (hb_trampoline_closure_t *) user_data; + + if (--closure->ref_count) + return; + + if (closure->destroy) + closure->destroy (closure->user_data); + free (closure); +} + +typedef hb_trampoline_t hb_font_get_glyph_trampoline_t; + +static hb_bool_t +hb_font_get_nominal_glyph_trampoline (hb_font_t *font, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void *user_data) +{ + hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; + return trampoline->func (font, font_data, unicode, 0, glyph, trampoline->closure.user_data); +} + +static hb_bool_t +hb_font_get_variation_glyph_trampoline (hb_font_t *font, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, + void *user_data) +{ + hb_font_get_glyph_trampoline_t *trampoline = (hb_font_get_glyph_trampoline_t *) user_data; + return trampoline->func (font, font_data, unicode, variation_selector, glyph, trampoline->closure.user_data); +} + +/** + * hb_font_funcs_set_glyph_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * Deprecated. Use hb_font_funcs_set_nominal_glyph_func() and + * hb_font_funcs_set_variation_glyph_func() instead. + * + * Since: 0.9.2 + * Deprecated: 1.2.3 + **/ +void +hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_get_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy) +{ + hb_font_get_glyph_trampoline_t *trampoline; + + trampoline = trampoline_create (func, user_data, destroy); + if (unlikely (!trampoline)) + { + if (destroy) + destroy (user_data); + return; + } + + hb_font_funcs_set_nominal_glyph_func (ffuncs, + hb_font_get_nominal_glyph_trampoline, + trampoline, + trampoline_destroy); + + trampoline_reference (&trampoline->closure); + hb_font_funcs_set_variation_glyph_func (ffuncs, + hb_font_get_variation_glyph_trampoline, + trampoline, + trampoline_destroy); +} + +#endif /* HB_DISABLE_DEPRECATED */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h index fb4a0eab5a..8813286726 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h @@ -46,19 +46,19 @@ typedef struct hb_font_t hb_font_t; typedef struct hb_font_funcs_t hb_font_funcs_t; -hb_font_funcs_t * +HB_EXTERN hb_font_funcs_t * hb_font_funcs_create (void); -hb_font_funcs_t * +HB_EXTERN hb_font_funcs_t * hb_font_funcs_get_empty (void); -hb_font_funcs_t * +HB_EXTERN hb_font_funcs_t * hb_font_funcs_reference (hb_font_funcs_t *ffuncs); -void +HB_EXTERN void hb_font_funcs_destroy (hb_font_funcs_t *ffuncs); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, hb_user_data_key_t *key, void * data, @@ -66,19 +66,37 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, hb_bool_t replace); -void * +HB_EXTERN void * hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, hb_user_data_key_t *key); -void +HB_EXTERN void hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); -/* glyph extents */ +/* font and glyph extents */ + +/* Note that typically ascender is positive and descender negative in coordinate systems that grow up. */ +typedef struct hb_font_extents_t +{ + hb_position_t ascender; /* typographic ascender. */ + hb_position_t descender; /* typographic descender. */ + hb_position_t line_gap; /* suggested line spacing gap. */ + /*< private >*/ + hb_position_t reserved9; + hb_position_t reserved8; + hb_position_t reserved7; + hb_position_t reserved6; + hb_position_t reserved5; + hb_position_t reserved4; + hb_position_t reserved3; + hb_position_t reserved2; + hb_position_t reserved1; +} hb_font_extents_t; /* Note that height is negative in coordinate systems that grow up. */ typedef struct hb_glyph_extents_t @@ -89,13 +107,23 @@ typedef struct hb_glyph_extents_t hb_position_t height; /* distance from top to bottom side. */ } hb_glyph_extents_t; - /* func types */ -typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data, - hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - void *user_data); +typedef hb_bool_t (*hb_font_get_font_extents_func_t) (hb_font_t *font, void *font_data, + hb_font_extents_t *metrics, + void *user_data); +typedef hb_font_get_font_extents_func_t hb_font_get_font_h_extents_func_t; +typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t; + + +typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void *user_data); +typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data, + hb_codepoint_t unicode, hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, + void *user_data); typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data, @@ -141,7 +169,39 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * /* func setters */ /** - * hb_font_funcs_set_glyph_func: + * hb_font_funcs_set_font_h_extents_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.1.2 + **/ +HB_EXTERN void +hb_font_funcs_set_font_h_extents_func (hb_font_funcs_t *ffuncs, + hb_font_get_font_h_extents_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_font_v_extents_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.1.2 + **/ +HB_EXTERN void +hb_font_funcs_set_font_v_extents_func (hb_font_funcs_t *ffuncs, + hb_font_get_font_v_extents_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_nominal_glyph_func: * @ffuncs: font functions. * @func: (closure user_data) (destroy destroy) (scope notified): * @user_data: @@ -149,12 +209,28 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * * * - * Since: 0.9.2 + * Since: 1.2.3 + **/ +HB_EXTERN void +hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_get_nominal_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); + +/** + * hb_font_funcs_set_variation_glyph_func: + * @ffuncs: font functions. + * @func: (closure user_data) (destroy destroy) (scope notified): + * @user_data: + * @destroy: + * + * + * + * Since: 1.2.3 **/ -void -hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, - hb_font_get_glyph_func_t func, - void *user_data, hb_destroy_func_t destroy); +HB_EXTERN void +hb_font_funcs_set_variation_glyph_func (hb_font_funcs_t *ffuncs, + hb_font_get_variation_glyph_func_t func, + void *user_data, hb_destroy_func_t destroy); /** * hb_font_funcs_set_glyph_h_advance_func: @@ -167,7 +243,7 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_h_advance_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -183,7 +259,7 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_v_advance_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -199,7 +275,7 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_h_origin_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -215,7 +291,7 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_v_origin_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -231,7 +307,7 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_h_kerning_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -247,7 +323,7 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_v_kerning_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -263,7 +339,7 @@ hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_extents_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -279,7 +355,7 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_contour_point_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -295,7 +371,7 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_name_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -311,57 +387,67 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, hb_font_get_glyph_from_name_func_t func, void *user_data, hb_destroy_func_t destroy); - /* func dispatch */ -hb_bool_t -hb_font_get_glyph (hb_font_t *font, - hb_codepoint_t unicode, hb_codepoint_t variation_selector, - hb_codepoint_t *glyph); +HB_EXTERN hb_bool_t +hb_font_get_h_extents (hb_font_t *font, + hb_font_extents_t *extents); +HB_EXTERN hb_bool_t +hb_font_get_v_extents (hb_font_t *font, + hb_font_extents_t *extents); + +HB_EXTERN hb_bool_t +hb_font_get_nominal_glyph (hb_font_t *font, + hb_codepoint_t unicode, + hb_codepoint_t *glyph); +HB_EXTERN hb_bool_t +hb_font_get_variation_glyph (hb_font_t *font, + hb_codepoint_t unicode, hb_codepoint_t variation_selector, + hb_codepoint_t *glyph); -hb_position_t +HB_EXTERN hb_position_t hb_font_get_glyph_h_advance (hb_font_t *font, hb_codepoint_t glyph); -hb_position_t +HB_EXTERN hb_position_t hb_font_get_glyph_v_advance (hb_font_t *font, hb_codepoint_t glyph); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_get_glyph_h_origin (hb_font_t *font, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_get_glyph_v_origin (hb_font_t *font, hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y); -hb_position_t +HB_EXTERN hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, hb_codepoint_t left_glyph, hb_codepoint_t right_glyph); -hb_position_t +HB_EXTERN hb_position_t hb_font_get_glyph_v_kerning (hb_font_t *font, hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_get_glyph_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_get_glyph_contour_point (hb_font_t *font, hb_codepoint_t glyph, unsigned int point_index, hb_position_t *x, hb_position_t *y); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_get_glyph_name (hb_font_t *font, hb_codepoint_t glyph, char *name, unsigned int size); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_get_glyph_from_name (hb_font_t *font, const char *name, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph); @@ -369,52 +455,63 @@ hb_font_get_glyph_from_name (hb_font_t *font, /* high-level funcs, with fallback */ -void +/* Calls either hb_font_get_nominal_glyph() if variation_selector is 0, + * otherwise callse hb_font_get_variation_glyph(). */ +HB_EXTERN hb_bool_t +hb_font_get_glyph (hb_font_t *font, + hb_codepoint_t unicode, hb_codepoint_t variation_selector, + hb_codepoint_t *glyph); + +HB_EXTERN void +hb_font_get_extents_for_direction (hb_font_t *font, + hb_direction_t direction, + hb_font_extents_t *extents); +HB_EXTERN void hb_font_get_glyph_advance_for_direction (hb_font_t *font, hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y); -void +HB_EXTERN void hb_font_get_glyph_origin_for_direction (hb_font_t *font, hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y); -void +HB_EXTERN void hb_font_add_glyph_origin_for_direction (hb_font_t *font, hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y); -void +HB_EXTERN void hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, hb_codepoint_t glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y); -void +HB_EXTERN void hb_font_get_glyph_kerning_for_direction (hb_font_t *font, hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, hb_direction_t direction, hb_position_t *x, hb_position_t *y); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_get_glyph_extents_for_origin (hb_font_t *font, hb_codepoint_t glyph, hb_direction_t direction, hb_glyph_extents_t *extents); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, hb_codepoint_t glyph, unsigned int point_index, hb_direction_t direction, hb_position_t *x, hb_position_t *y); /* Generates gidDDD if glyph has no name. */ -void +HB_EXTERN void hb_font_glyph_to_string (hb_font_t *font, hb_codepoint_t glyph, char *s, unsigned int size); /* Parses gidDDD and uniUUUU strings automatically. */ -hb_bool_t +HB_EXTERN hb_bool_t hb_font_glyph_from_string (hb_font_t *font, const char *s, int len, /* -1 means nul-terminated */ hb_codepoint_t *glyph); @@ -426,22 +523,22 @@ hb_font_glyph_from_string (hb_font_t *font, /* Fonts are very light-weight objects */ -hb_font_t * +HB_EXTERN hb_font_t * hb_font_create (hb_face_t *face); -hb_font_t * +HB_EXTERN hb_font_t * hb_font_create_sub_font (hb_font_t *parent); -hb_font_t * +HB_EXTERN hb_font_t * hb_font_get_empty (void); -hb_font_t * +HB_EXTERN hb_font_t * hb_font_reference (hb_font_t *font); -void +HB_EXTERN void hb_font_destroy (hb_font_t *font); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_set_user_data (hb_font_t *font, hb_user_data_key_t *key, void * data, @@ -449,46 +546,46 @@ hb_font_set_user_data (hb_font_t *font, hb_bool_t replace); -void * +HB_EXTERN void * hb_font_get_user_data (hb_font_t *font, hb_user_data_key_t *key); -void +HB_EXTERN void hb_font_make_immutable (hb_font_t *font); -hb_bool_t +HB_EXTERN hb_bool_t hb_font_is_immutable (hb_font_t *font); -void +HB_EXTERN void hb_font_set_parent (hb_font_t *font, hb_font_t *parent); -hb_font_t * +HB_EXTERN hb_font_t * hb_font_get_parent (hb_font_t *font); -hb_face_t * +HB_EXTERN hb_face_t * hb_font_get_face (hb_font_t *font); -void +HB_EXTERN void hb_font_set_funcs (hb_font_t *font, hb_font_funcs_t *klass, void *font_data, hb_destroy_func_t destroy); /* Be *very* careful with this function! */ -void +HB_EXTERN void hb_font_set_funcs_data (hb_font_t *font, void *font_data, hb_destroy_func_t destroy); -void +HB_EXTERN void hb_font_set_scale (hb_font_t *font, int x_scale, int y_scale); -void +HB_EXTERN void hb_font_get_scale (hb_font_t *font, int *x_scale, int *y_scale); @@ -496,17 +593,22 @@ hb_font_get_scale (hb_font_t *font, /* * A zero value means "no hinting in that direction" */ -void +HB_EXTERN void hb_font_set_ppem (hb_font_t *font, unsigned int x_ppem, unsigned int y_ppem); -void +HB_EXTERN void hb_font_get_ppem (hb_font_t *font, unsigned int *x_ppem, unsigned int *y_ppem); +HB_EXTERN void +hb_font_set_var_coords_normalized (hb_font_t *font, + int *coords, /* XXX 2.14 normalized */ + unsigned int coords_length); + HB_END_DECLS #endif /* HB_FONT_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh index 152230a0e5..5357ddcf5b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh @@ -140,7 +140,7 @@ struct TTCHeaderVersion1 protected: Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ - FixedVersion version; /* Version of the TTC Header (1.0), + FixedVersion<>version; /* Version of the TTC Header (1.0), * 0x00010000u */ ArrayOf, ULONG> table; /* Array of offsets to the OffsetTable for each font @@ -187,7 +187,7 @@ struct TTCHeader union { struct { Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ - FixedVersion version; /* Version of the TTC Header (1.0 or 2.0), + FixedVersion<>version; /* Version of the TTC Header (1.0 or 2.0), * 0x00010000u or 0x00020000u */ } header; TTCHeaderVersion1 version1; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh index f053502ded..2cc1fb20d2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh @@ -101,13 +101,11 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_STATIC(size) \ DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \ static const unsigned int static_size = (size); \ - static const unsigned int min_size = (size) - -/* Size signifying variable-sized array */ -#define VAR 1 + static const unsigned int min_size = (size); \ + inline unsigned int get_size (void) const { return (size); } #define DEFINE_SIZE_UNION(size, _member) \ - DEFINE_INSTANCE_ASSERTION (this->u._member.static_size == (size)); \ + DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \ static const unsigned int min_size = (size) #define DEFINE_SIZE_MIN(size) \ @@ -185,7 +183,7 @@ struct hb_dispatch_context_t /* This limits sanitizing time on really broken fonts. */ #ifndef HB_SANITIZE_MAX_EDITS -#define HB_SANITIZE_MAX_EDITS 100 +#define HB_SANITIZE_MAX_EDITS 32 #endif struct hb_sanitize_context_t : @@ -652,7 +650,9 @@ struct IntType DEFINE_SIZE_STATIC (Size); }; +typedef IntType CHAR; /* 8-bit signed integer. */ typedef IntType BYTE; /* 8-bit unsigned integer. */ +typedef IntType INT8; /* 8-bit signed integer. */ typedef IntType USHORT; /* 16-bit unsigned integer. */ typedef IntType SHORT; /* 16-bit signed integer. */ typedef IntType ULONG; /* 32-bit unsigned integer. */ @@ -665,6 +665,24 @@ typedef SHORT FWORD; /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ typedef USHORT UFWORD; +/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ +struct F2DOT14 : SHORT +{ + //inline float to_float (void) const { return ???; } + //inline void set_float (float f) { v.set (f * ???); } + public: + DEFINE_SIZE_STATIC (2); +}; + +/* 32-bit signed fixed-point number (16.16). */ +struct Fixed: LONG +{ + //inline float to_float (void) const { return ???; } + //inline void set_float (float f) { v.set (f * ???); } + public: + DEFINE_SIZE_STATIC (4); +}; + /* Date represented in number of seconds since 12:00 midnight, January 1, * 1904. The value is represented as a signed 64-bit integer. */ struct LONGDATETIME @@ -742,9 +760,10 @@ struct CheckSum : ULONG * Version Numbers */ +template struct FixedVersion { - inline uint32_t to_int (void) const { return (major << 16) + minor; } + inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; } inline bool sanitize (hb_sanitize_context_t *c) const { @@ -752,10 +771,10 @@ struct FixedVersion return_trace (c->check_struct (this)); } - USHORT major; - USHORT minor; + FixedType major; + FixedType minor; public: - DEFINE_SIZE_STATIC (4); + DEFINE_SIZE_STATIC (2 * sizeof(FixedType)); }; @@ -788,6 +807,7 @@ struct OffsetTo : Offset if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; if (unlikely (!offset)) return_trace (true); + if (unlikely (!c->check_range (base, offset))) return_trace (false); const Type &obj = StructAtOffset (base, offset); return_trace (likely (obj.sanitize (c)) || neuter (c)); } @@ -798,6 +818,7 @@ struct OffsetTo : Offset if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; if (unlikely (!offset)) return_trace (true); + if (unlikely (!c->check_range (base, offset))) return_trace (false); const Type &obj = StructAtOffset (base, offset); return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); } @@ -931,8 +952,8 @@ struct ArrayOf }; /* Array of Offset's */ -template -struct OffsetArrayOf : ArrayOf > {}; +template +struct OffsetArrayOf : ArrayOf > {}; /* Array of offsets relative to the beginning of the array itself. */ template diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh new file mode 100644 index 0000000000..52897abd3a --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cbdt-table.hh @@ -0,0 +1,384 @@ +/* + * Copyright © 2016 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Seigo Nonaka + */ + +#ifndef HB_OT_CBDT_TABLE_HH +#define HB_OT_CBDT_TABLE_HH + +#include "hb-open-type-private.hh" + +namespace OT { + +struct SmallGlyphMetrics +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + inline void get_extents (hb_glyph_extents_t *extents) const + { + extents->x_bearing = bearingX; + extents->y_bearing = bearingY; + extents->width = width; + extents->height = -height; + } + + BYTE height; + BYTE width; + CHAR bearingX; + CHAR bearingY; + BYTE advance; + + DEFINE_SIZE_STATIC(5); +}; + +struct BigGlyphMetrics : SmallGlyphMetrics +{ + CHAR vertBearingX; + CHAR vertBearingY; + BYTE vertAdvance; + + DEFINE_SIZE_STATIC(8); +}; + +struct SBitLineMetrics +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + CHAR ascender; + CHAR decender; + BYTE widthMax; + CHAR caretSlopeNumerator; + CHAR caretSlopeDenominator; + CHAR caretOffset; + CHAR minOriginSB; + CHAR minAdvanceSB; + CHAR maxBeforeBL; + CHAR minAfterBL; + CHAR padding1; + CHAR padding2; + + DEFINE_SIZE_STATIC(12); +}; + + +/* + * Index Subtables. + */ + +struct IndexSubtableHeader +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + USHORT indexFormat; + USHORT imageFormat; + ULONG imageDataOffset; + + DEFINE_SIZE_STATIC(8); +}; + +template +struct IndexSubtableFormat1Or3 +{ + inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1)); + } + + bool get_image_data (unsigned int idx, + unsigned int *offset, + unsigned int *length) const + { + if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx])) + return false; + + *offset = header.imageDataOffset + offsetArrayZ[idx]; + *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx]; + return true; + } + + IndexSubtableHeader header; + Offset offsetArrayZ[VAR]; + + DEFINE_SIZE_ARRAY(8, offsetArrayZ); +}; + +struct IndexSubtableFormat1 : IndexSubtableFormat1Or3 {}; +struct IndexSubtableFormat3 : IndexSubtableFormat1Or3 {}; + +struct IndexSubtable +{ + inline bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const + { + TRACE_SANITIZE (this); + if (!u.header.sanitize (c)) return_trace (false); + switch (u.header.indexFormat) { + case 1: return_trace (u.format1.sanitize (c, glyph_count)); + case 3: return_trace (u.format3.sanitize (c, glyph_count)); + default:return_trace (true); + } + } + + inline bool get_extents (hb_glyph_extents_t *extents) const + { + switch (u.header.indexFormat) { + case 2: case 5: /* TODO */ + case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */ + default:return (false); + } + } + + bool get_image_data (unsigned int idx, + unsigned int *offset, + unsigned int *length, + unsigned int *format) const + { + *format = u.header.imageFormat; + switch (u.header.indexFormat) { + case 1: return u.format1.get_image_data (idx, offset, length); + case 3: return u.format3.get_image_data (idx, offset, length); + default: return false; + } + } + + protected: + union { + IndexSubtableHeader header; + IndexSubtableFormat1 format1; + IndexSubtableFormat3 format3; + /* TODO: Format 2, 4, 5. */ + } u; + public: + DEFINE_SIZE_UNION (8, header); +}; + +struct IndexSubtableRecord +{ + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + firstGlyphIndex <= lastGlyphIndex && + offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1)); + } + + inline bool get_extents (hb_glyph_extents_t *extents) const + { + return (this+offsetToSubtable).get_extents (extents); + } + + bool get_image_data (unsigned int gid, + unsigned int *offset, + unsigned int *length, + unsigned int *format) const + { + if (gid < firstGlyphIndex || gid > lastGlyphIndex) + { + return false; + } + return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex, + offset, length, format); + } + + USHORT firstGlyphIndex; + USHORT lastGlyphIndex; + OffsetTo offsetToSubtable; + + DEFINE_SIZE_STATIC(8); +}; + +struct IndexSubtableArray +{ + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count))) + return_trace (false); + for (unsigned int i = 0; i < count; i++) + if (unlikely (!indexSubtablesZ[i].sanitize (c, this))) + return_trace (false); + return_trace (true); + } + + public: + const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const + { + for (unsigned int i = 0; i < numTables; ++i) + { + unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex; + unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex; + if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) { + return &indexSubtablesZ[i]; + } + } + return NULL; + } + + protected: + IndexSubtableRecord indexSubtablesZ[VAR]; + + public: + DEFINE_SIZE_ARRAY(0, indexSubtablesZ); +}; + +struct BitmapSizeTable +{ + friend struct CBLC; + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && + c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) && + horizontal.sanitize (c) && + vertical.sanitize (c)); + } + + const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const + { + return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables); + } + + protected: + OffsetTo indexSubtableArrayOffset; + ULONG indexTablesSize; + ULONG numberOfIndexSubtables; + ULONG colorRef; + SBitLineMetrics horizontal; + SBitLineMetrics vertical; + USHORT startGlyphIndex; + USHORT endGlyphIndex; + BYTE ppemX; + BYTE ppemY; + BYTE bitDepth; + CHAR flags; + +public: + DEFINE_SIZE_STATIC(48); +}; + + +/* + * Glyph Bitmap Data Formats. + */ + +struct GlyphBitmapDataFormat17 +{ + SmallGlyphMetrics glyphMetrics; + ULONG dataLen; + BYTE dataZ[VAR]; + + DEFINE_SIZE_ARRAY(9, dataZ); +}; + + +/* + * CBLC -- Color Bitmap Location Table + */ + +#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C') + +struct CBLC +{ + static const hb_tag_t tableTag = HB_OT_TAG_CBLC; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version.major == 2 || version.major == 3) && + sizeTables.sanitize (c, this)); + } + + public: + const IndexSubtableRecord *find_table (hb_codepoint_t glyph, + unsigned int *x_ppem, unsigned int *y_ppem) const + { + /* TODO: Make it possible to select strike. */ + + unsigned int count = sizeTables.len; + for (uint32_t i = 0; i < count; ++i) + { + unsigned int startGlyphIndex = sizeTables.array[i].startGlyphIndex; + unsigned int endGlyphIndex = sizeTables.array[i].endGlyphIndex; + if (startGlyphIndex <= glyph && glyph <= endGlyphIndex) + { + *x_ppem = sizeTables[i].ppemX; + *y_ppem = sizeTables[i].ppemY; + return sizeTables[i].find_table (glyph, this); + } + } + + return NULL; + } + + protected: + FixedVersion<>version; + ArrayOf sizeTables; + + public: + DEFINE_SIZE_ARRAY(8, sizeTables); +}; + +/* + * CBDT -- Color Bitmap Data Table + */ +#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T') + +struct CBDT +{ + static const hb_tag_t tableTag = HB_OT_TAG_CBDT; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version.major == 2 || version.major == 3)); + } + + protected: + FixedVersion<>version; + BYTE dataZ[VAR]; + + public: + DEFINE_SIZE_ARRAY(4, dataZ); +}; + +} /* namespace OT */ + +#endif /* HB_OT_CBDT_TABLE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh index c9161f0ef4..d7a94a1ef0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh @@ -69,61 +69,78 @@ struct CmapSubtableFormat0 struct CmapSubtableFormat4 { - inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const + struct accelerator_t { - unsigned int segCount; - const USHORT *endCount; - const USHORT *startCount; - const USHORT *idDelta; - const USHORT *idRangeOffset; - const USHORT *glyphIdArray; - unsigned int glyphIdArrayLength; + inline void init (const CmapSubtableFormat4 *subtable) + { + segCount = subtable->segCountX2 / 2; + endCount = subtable->values; + startCount = endCount + segCount + 1; + idDelta = startCount + segCount; + idRangeOffset = idDelta + segCount; + glyphIdArray = idRangeOffset + segCount; + glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2; + } - segCount = this->segCountX2 / 2; - endCount = this->values; - startCount = endCount + segCount + 1; - idDelta = startCount + segCount; - idRangeOffset = idDelta + segCount; - glyphIdArray = idRangeOffset + segCount; - glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2; - - /* Custom two-array bsearch. */ - int min = 0, max = (int) segCount - 1; - unsigned int i; - while (min <= max) + static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph) { - int mid = (min + max) / 2; - if (codepoint < startCount[mid]) - max = mid - 1; - else if (codepoint > endCount[mid]) - min = mid + 1; + const accelerator_t *thiz = (const accelerator_t *) obj; + + /* Custom two-array bsearch. */ + int min = 0, max = (int) thiz->segCount - 1; + const USHORT *startCount = thiz->startCount; + const USHORT *endCount = thiz->endCount; + unsigned int i; + while (min <= max) + { + int mid = (min + max) / 2; + if (codepoint < startCount[mid]) + max = mid - 1; + else if (codepoint > endCount[mid]) + min = mid + 1; + else + { + i = mid; + goto found; + } + } + return false; + + found: + hb_codepoint_t gid; + unsigned int rangeOffset = thiz->idRangeOffset[i]; + if (rangeOffset == 0) + gid = codepoint + thiz->idDelta[i]; else { - i = mid; - goto found; + /* Somebody has been smoking... */ + unsigned int index = rangeOffset / 2 + (codepoint - thiz->startCount[i]) + i - thiz->segCount; + if (unlikely (index >= thiz->glyphIdArrayLength)) + return false; + gid = thiz->glyphIdArray[index]; + if (unlikely (!gid)) + return false; + gid += thiz->idDelta[i]; } - } - return false; - - found: - hb_codepoint_t gid; - unsigned int rangeOffset = idRangeOffset[i]; - if (rangeOffset == 0) - gid = codepoint + idDelta[i]; - else - { - /* Somebody has been smoking... */ - unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount; - if (unlikely (index >= glyphIdArrayLength)) - return false; - gid = glyphIdArray[index]; - if (unlikely (!gid)) - return false; - gid += idDelta[i]; + + *glyph = gid & 0xFFFFu; + return true; } - *glyph = gid & 0xFFFFu; - return true; + const USHORT *endCount; + const USHORT *startCount; + const USHORT *idDelta; + const USHORT *idRangeOffset; + const USHORT *glyphIdArray; + unsigned int segCount; + unsigned int glyphIdArrayLength; + }; + + inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const + { + accelerator_t accel; + accel.init (this); + return accel.get_glyph_func (&accel, codepoint, glyph); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -388,7 +405,7 @@ struct CmapSubtableFormat14 } protected: - USHORT format; /* Format number is set to 0. */ + USHORT format; /* Format number is set to 14. */ ULONG lengthZ; /* Byte length of this subtable. */ SortedArrayOf record; /* Variation selector records; sorted @@ -416,16 +433,6 @@ struct CmapSubtable } } - inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph) const - { - switch (u.format) { - case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph); - default: return GLYPH_VARIANT_NOT_FOUND; - } - } - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -442,7 +449,7 @@ struct CmapSubtable } } - protected: + public: union { USHORT format; /* Format identifier */ CmapSubtableFormat0 format0; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc index 69d2503abb..5be055d344 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc @@ -31,10 +31,13 @@ #include "hb-font-private.hh" #include "hb-ot-cmap-table.hh" +#include "hb-ot-cbdt-table.hh" #include "hb-ot-glyf-table.hh" #include "hb-ot-head-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" +#include "hb-ot-os2-table.hh" +//#include "hb-ot-post-table.hh" struct hb_ot_face_metrics_accelerator_t @@ -42,24 +45,63 @@ struct hb_ot_face_metrics_accelerator_t unsigned int num_metrics; unsigned int num_advances; unsigned int default_advance; + unsigned short ascender; + unsigned short descender; + unsigned short line_gap; + bool has_font_extents; + const OT::_mtx *table; hb_blob_t *blob; inline void init (hb_face_t *face, - hb_tag_t _hea_tag, hb_tag_t _mtx_tag, - unsigned int default_advance_) + hb_tag_t _hea_tag, + hb_tag_t _mtx_tag, + hb_tag_t os2_tag, + unsigned int default_advance = 0) { - this->default_advance = default_advance_; - this->num_metrics = face->get_num_glyphs (); + this->default_advance = default_advance ? default_advance : face->get_upem (); + + bool got_font_extents = false; + if (os2_tag) + { + hb_blob_t *os2_blob = OT::Sanitizer::sanitize (face->reference_table (os2_tag)); + const OT::os2 *os2 = OT::Sanitizer::lock_instance (os2_blob); +#define USE_TYPO_METRICS (1u<<7) + if (0 != (os2->fsSelection & USE_TYPO_METRICS)) + { + this->ascender = os2->sTypoAscender; + this->descender = os2->sTypoDescender; + this->line_gap = os2->sTypoLineGap; + got_font_extents = (this->ascender | this->descender) != 0; + } + hb_blob_destroy (os2_blob); + } hb_blob_t *_hea_blob = OT::Sanitizer::sanitize (face->reference_table (_hea_tag)); const OT::_hea *_hea = OT::Sanitizer::lock_instance (_hea_blob); this->num_advances = _hea->numberOfLongMetrics; + if (!got_font_extents) + { + this->ascender = _hea->ascender; + this->descender = _hea->descender; + this->line_gap = _hea->lineGap; + got_font_extents = (this->ascender | this->descender) != 0; + } hb_blob_destroy (_hea_blob); + this->has_font_extents = got_font_extents; + this->blob = OT::Sanitizer::sanitize (face->reference_table (_mtx_tag)); - if (unlikely (!this->num_advances || - 2 * (this->num_advances + this->num_metrics) > hb_blob_get_length (this->blob))) + + /* Cap num_metrics() and num_advances() based on table length. */ + unsigned int len = hb_blob_get_length (this->blob); + if (unlikely (this->num_advances * 4 > len)) + this->num_advances = len / 4; + this->num_metrics = this->num_advances + (len - 4 * this->num_advances) / 2; + + /* We MUST set num_metrics to zero if num_advances is zero. + * Our get_advance() depends on that. */ + if (unlikely (!this->num_advances)) { this->num_metrics = this->num_advances = 0; hb_blob_destroy (this->blob); @@ -166,10 +208,133 @@ struct hb_ot_face_glyf_accelerator_t } }; +struct hb_ot_face_cbdt_accelerator_t +{ + hb_blob_t *cblc_blob; + hb_blob_t *cbdt_blob; + const OT::CBLC *cblc; + const OT::CBDT *cbdt; + + unsigned int cbdt_len; + float upem; + + inline void init (hb_face_t *face) + { + upem = face->get_upem(); + + cblc_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_CBLC)); + cbdt_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_CBDT)); + cbdt_len = hb_blob_get_length (cbdt_blob); + + if (hb_blob_get_length (cblc_blob) == 0) { + cblc = NULL; + cbdt = NULL; + return; /* Not a bitmap font. */ + } + cblc = OT::Sanitizer::lock_instance (cblc_blob); + cbdt = OT::Sanitizer::lock_instance (cbdt_blob); + + } + + inline void fini (void) + { + hb_blob_destroy (this->cblc_blob); + hb_blob_destroy (this->cbdt_blob); + } + + inline bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + { + unsigned int x_ppem = upem, y_ppem = upem; /* TODO Use font ppem if available. */ + + if (cblc == NULL) + return false; // Not a color bitmap font. + + const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); + if (subtable_record == NULL) + return false; + + if (subtable_record->get_extents (extents)) + return true; + + unsigned int image_offset = 0, image_length = 0, image_format = 0; + if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format)) + return false; + + { + /* TODO Move the following into CBDT struct when adding more formats. */ + + if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + return false; + + switch (image_format) + { + case 17: { + if (unlikely (image_length < OT::GlyphBitmapDataFormat17::min_size)) + return false; + + const OT::GlyphBitmapDataFormat17& glyphFormat17 = + OT::StructAtOffset (this->cbdt, image_offset); + glyphFormat17.glyphMetrics.get_extents (extents); + } + break; + default: + // TODO: Support other image formats. + return false; + } + } + + /* Convert to the font units. */ + extents->x_bearing *= upem / (float) x_ppem; + extents->y_bearing *= upem / (float) y_ppem; + extents->width *= upem / (float) x_ppem; + extents->height *= upem / (float) y_ppem; + + return true; + } +}; + +typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph); + +template +static inline bool get_glyph_from (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) +{ + const Type *typed_obj = (const Type *) obj; + return typed_obj->get_glyph (codepoint, glyph); +} + +template +static inline bool get_glyph_from_symbol (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph) +{ + const Type *typed_obj = (const Type *) obj; + if (likely (typed_obj->get_glyph (codepoint, glyph))) + return true; + + if (codepoint <= 0x00FFu) + { + /* For symbol-encoded OpenType fonts, we duplicate the + * U+F000..F0FF range at U+0000..U+00FF. That's what + * Windows seems to do, and that's hinted about at: + * http://www.microsoft.com/typography/otspec/recom.htm + * under "Non-Standard (Symbol) Fonts". */ + return typed_obj->get_glyph (0xF000u + codepoint, glyph); + } + + return false; +} + struct hb_ot_face_cmap_accelerator_t { - const OT::CmapSubtable *table; - const OT::CmapSubtable *uvs_table; + hb_cmap_get_glyph_func_t get_glyph_func; + const void *get_glyph_data; + OT::CmapSubtableFormat4::accelerator_t format4_accel; + + const OT::CmapSubtableFormat14 *uvs_table; hb_blob_t *blob; inline void init (hb_face_t *face) @@ -177,8 +342,9 @@ struct hb_ot_face_cmap_accelerator_t this->blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_cmap)); const OT::cmap *cmap = OT::Sanitizer::lock_instance (this->blob); const OT::CmapSubtable *subtable = NULL; - const OT::CmapSubtable *subtable_uvs = NULL; + const OT::CmapSubtableFormat14 *subtable_uvs = NULL; + bool symbol = false; /* 32-bit subtables. */ if (!subtable) subtable = cmap->find_subtable (3, 10); if (!subtable) subtable = cmap->find_subtable (0, 6); @@ -189,17 +355,42 @@ struct hb_ot_face_cmap_accelerator_t if (!subtable) subtable = cmap->find_subtable (0, 2); if (!subtable) subtable = cmap->find_subtable (0, 1); if (!subtable) subtable = cmap->find_subtable (0, 0); - if (!subtable) subtable = cmap->find_subtable (3, 0); + if (!subtable) + { + subtable = cmap->find_subtable (3, 0); + if (subtable) symbol = true; + } /* Meh. */ if (!subtable) subtable = &OT::Null(OT::CmapSubtable); /* UVS subtable. */ - if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5); + if (!subtable_uvs) + { + const OT::CmapSubtable *st = cmap->find_subtable (0, 5); + if (st && st->u.format == 14) + subtable_uvs = &st->u.format14; + } /* Meh. */ - if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable); + if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14); - this->table = subtable; this->uvs_table = subtable_uvs; + + this->get_glyph_data = subtable; + if (unlikely (symbol)) + this->get_glyph_func = get_glyph_from_symbol; + else + switch (subtable->u.format) { + /* Accelerate format 4 and format 12. */ + default: this->get_glyph_func = get_glyph_from; break; + case 12: this->get_glyph_func = get_glyph_from; break; + case 4: + { + this->format4_accel.init (&subtable->u.format4); + this->get_glyph_data = &this->format4_accel; + this->get_glyph_func = this->format4_accel.get_glyph_func; + } + break; + } } inline void fini (void) @@ -207,33 +398,78 @@ struct hb_ot_face_cmap_accelerator_t hb_blob_destroy (this->blob); } - inline bool get_glyph (hb_codepoint_t unicode, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph) const + inline bool get_nominal_glyph (hb_codepoint_t unicode, + hb_codepoint_t *glyph) const { - if (unlikely (variation_selector)) + return this->get_glyph_func (this->get_glyph_data, unicode, glyph); + } + + inline bool get_variation_glyph (hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph) const + { + switch (this->uvs_table->get_glyph_variant (unicode, + variation_selector, + glyph)) { - switch (this->uvs_table->get_glyph_variant (unicode, - variation_selector, - glyph)) - { - case OT::GLYPH_VARIANT_NOT_FOUND: return false; - case OT::GLYPH_VARIANT_FOUND: return true; - case OT::GLYPH_VARIANT_USE_DEFAULT: break; - } + case OT::GLYPH_VARIANT_NOT_FOUND: return false; + case OT::GLYPH_VARIANT_FOUND: return true; + case OT::GLYPH_VARIANT_USE_DEFAULT: break; } - return this->table->get_glyph (unicode, glyph); + return get_nominal_glyph (unicode, glyph); } }; +template +struct hb_lazy_loader_t +{ + inline void init (hb_face_t *face_) + { + face = face_; + instance = NULL; + } + + inline void fini (void) + { + if (instance && instance != &OT::Null(T)) + { + instance->fini(); + free (instance); + } + } + + inline const T* operator-> (void) const + { + retry: + T *p = (T *) hb_atomic_ptr_get (&instance); + if (unlikely (!p)) + { + p = (T *) calloc (1, sizeof (T)); + if (unlikely (!p)) + return &OT::Null(T); + p->init (face); + if (unlikely (!hb_atomic_ptr_cmpexch (const_cast(&instance), NULL, p))) + { + p->fini (); + goto retry; + } + } + return p; + } + + private: + hb_face_t *face; + T *instance; +}; struct hb_ot_font_t { hb_ot_face_cmap_accelerator_t cmap; hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; - hb_ot_face_glyf_accelerator_t glyf; + hb_lazy_loader_t glyf; + hb_lazy_loader_t cbdt; }; @@ -245,12 +481,12 @@ _hb_ot_font_create (hb_face_t *face) if (unlikely (!ot_font)) return NULL; - unsigned int upem = face->get_upem (); - ot_font->cmap.init (face); - ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1); - ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */ + ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_os2); + ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_TAG_NONE, + ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ ot_font->glyf.init (face); + ot_font->cbdt.init (face); return ot_font; } @@ -262,88 +498,54 @@ _hb_ot_font_destroy (hb_ot_font_t *ot_font) ot_font->h_metrics.fini (); ot_font->v_metrics.fini (); ot_font->glyf.fini (); + ot_font->cbdt.fini (); free (ot_font); } static hb_bool_t -hb_ot_get_glyph (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) +hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - return ot_font->cmap.get_glyph (unicode, variation_selector, glyph); + return ot_font->cmap.get_nominal_glyph (unicode, glyph); } -static hb_position_t -hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED, +static hb_bool_t +hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED, void *font_data, - hb_codepoint_t glyph, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - return font->em_scale_x (ot_font->h_metrics.get_advance (glyph)); + return ot_font->cmap.get_variation_glyph (unicode, variation_selector, glyph); } static hb_position_t -hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, +hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED, void *font_data, hb_codepoint_t glyph, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); -} - -static hb_bool_t -hb_ot_get_glyph_h_origin (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t glyph HB_UNUSED, - hb_position_t *x HB_UNUSED, - hb_position_t *y HB_UNUSED, - void *user_data HB_UNUSED) -{ - /* We always work in the horizontal coordinates. */ - return true; -} - -static hb_bool_t -hb_ot_get_glyph_v_origin (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) -{ - /* TODO */ - return false; + return font->em_scale_x (ot_font->h_metrics.get_advance (glyph)); } static hb_position_t -hb_ot_get_glyph_h_kerning (hb_font_t *font, +hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, void *font_data, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data HB_UNUSED) -{ - /* TODO */ - return 0; -} - -static hb_position_t -hb_ot_get_glyph_v_kerning (hb_font_t *font HB_UNUSED, - void *font_data HB_UNUSED, - hb_codepoint_t top_glyph HB_UNUSED, - hb_codepoint_t bottom_glyph HB_UNUSED, + hb_codepoint_t glyph, void *user_data HB_UNUSED) { - /* OpenType doesn't have vertical-kerning other than GPOS. */ - return 0; + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); } static hb_bool_t @@ -354,7 +556,9 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - bool ret = ot_font->glyf.get_extents (glyph, extents); + bool ret = ot_font->glyf->get_extents (glyph, extents); + if (!ret) + ret = ot_font->cbdt->get_extents (glyph, extents); extents->x_bearing = font->em_scale_x (extents->x_bearing); extents->y_bearing = font->em_scale_y (extents->y_bearing); extents->width = font->em_scale_x (extents->width); @@ -363,61 +567,85 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, } static hb_bool_t -hb_ot_get_glyph_contour_point (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, - unsigned int point_index, - hb_position_t *x, - hb_position_t *y, - void *user_data HB_UNUSED) +hb_ot_get_font_h_extents (hb_font_t *font HB_UNUSED, + void *font_data, + hb_font_extents_t *metrics, + void *user_data HB_UNUSED) { - /* TODO */ - return false; + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + metrics->ascender = font->em_scale_y (ot_font->h_metrics.ascender); + metrics->descender = font->em_scale_y (ot_font->h_metrics.descender); + metrics->line_gap = font->em_scale_y (ot_font->h_metrics.line_gap); + return ot_font->h_metrics.has_font_extents; } static hb_bool_t -hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED, - void *font_data, - hb_codepoint_t glyph, - char *name, unsigned int size, - void *user_data HB_UNUSED) +hb_ot_get_font_v_extents (hb_font_t *font HB_UNUSED, + void *font_data, + hb_font_extents_t *metrics, + void *user_data HB_UNUSED) { - /* TODO */ - return false; + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + metrics->ascender = font->em_scale_x (ot_font->v_metrics.ascender); + metrics->descender = font->em_scale_x (ot_font->v_metrics.descender); + metrics->line_gap = font->em_scale_x (ot_font->v_metrics.line_gap); + return ot_font->v_metrics.has_font_extents; } -static hb_bool_t -hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED, - void *font_data, - const char *name, int len, /* -1 means nul-terminated */ - hb_codepoint_t *glyph, - void *user_data HB_UNUSED) +static hb_font_funcs_t *static_ot_funcs = NULL; + +#ifdef HB_USE_ATEXIT +static +void free_static_ot_funcs (void) { - /* TODO */ - return false; + hb_font_funcs_destroy (static_ot_funcs); } - +#endif static hb_font_funcs_t * _hb_ot_get_font_funcs (void) { - static const hb_font_funcs_t ot_ffuncs = { - HB_OBJECT_HEADER_STATIC, - - true, /* immutable */ +retry: + hb_font_funcs_t *funcs = (hb_font_funcs_t *) hb_atomic_ptr_get (&static_ot_funcs); - { -#define HB_FONT_FUNC_IMPLEMENT(name) hb_ot_get_##name, - HB_FONT_FUNCS_IMPLEMENT_CALLBACKS -#undef HB_FONT_FUNC_IMPLEMENT + if (unlikely (!funcs)) + { + funcs = hb_font_funcs_create (); + + hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, NULL, NULL); + hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, NULL, NULL); + hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, NULL, NULL); + hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, NULL, NULL); + hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, NULL, NULL); + hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, NULL, NULL); + //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, NULL, NULL); + //hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, NULL, NULL); + //hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, NULL, NULL); TODO + //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, NULL, NULL); + hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, NULL, NULL); + //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, NULL, NULL); TODO + //hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, NULL, NULL); TODO + //hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, NULL, NULL); TODO + + hb_font_funcs_make_immutable (funcs); + + if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, NULL, funcs)) { + hb_font_funcs_destroy (funcs); + goto retry; } + +#ifdef HB_USE_ATEXIT + atexit (free_static_ot_funcs); /* First person registers atexit() callback. */ +#endif }; - return const_cast (&ot_ffuncs); + return funcs; } /** + * hb_ot_font_set_funcs: + * * Since: 0.9.28 **/ void diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h index b9947a16bc..80eaa54b1a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h @@ -36,7 +36,7 @@ HB_BEGIN_DECLS -void +HB_EXTERN void hb_ot_font_set_funcs (hb_font_t *font); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh index 9e5af6d10d..dc7aa8469a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh @@ -90,10 +90,10 @@ struct glyfGlyphHeader * greater than or equal to zero, * this is a simple glyph; if negative, * this is a composite glyph. */ - SHORT xMin; /* Minimum x for coordinate data. */ - SHORT yMin; /* Minimum y for coordinate data. */ - SHORT xMax; /* Maximum x for coordinate data. */ - SHORT yMax; /* Maximum y for coordinate data. */ + FWORD xMin; /* Minimum x for coordinate data. */ + FWORD yMin; /* Minimum y for coordinate data. */ + FWORD xMax; /* Maximum x for coordinate data. */ + FWORD yMax; /* Maximum y for coordinate data. */ DEFINE_SIZE_STATIC (10); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh index fc351cfb48..9c3e51eb08 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh @@ -55,13 +55,15 @@ struct head inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && + version.major == 1 && + magicNumber == 0x5F0F3CF5u); } protected: - FixedVersion version; /* Version of the head table--currently + FixedVersion<>version; /* Version of the head table--currently * 0x00010000u for version 1.0. */ - FixedVersion fontRevision; /* Set by font manufacturer. */ + FixedVersion<>fontRevision; /* Set by font manufacturer. */ ULONG checkSumAdjustment; /* To compute: set it to 0, sum the * entire font as ULONG, then store * 0xB1B0AFBAu - sum. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh index 24114534a7..c8e9536cf1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh @@ -56,7 +56,7 @@ struct _hea } public: - FixedVersion version; /* 0x00010000u for version 1.0. */ + FixedVersion<>version; /* 0x00010000u for version 1.0. */ FWORD ascender; /* Typographic ascent. */ FWORD descender; /* Typographic descent. */ FWORD lineGap; /* Typographic line gap. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index 49056e6769..a9606b3d27 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -44,8 +44,8 @@ namespace OT { struct LongMetric { - USHORT advance; /* Advance width/height. */ - SHORT lsb; /* Leading (left/top) side bearing. */ + UFWORD advance; /* Advance width/height. */ + FWORD lsb; /* Leading (left/top) side bearing. */ public: DEFINE_SIZE_STATIC (4); }; @@ -74,7 +74,7 @@ struct _mtx * be in the array, but that entry is * required. The last entry applies to * all subsequent glyphs. */ - SHORT leadingBearingX[VAR]; /* Here the advance is assumed + FWORD leadingBearingX[VAR]; /* Here the advance is assumed * to be the same as the advance * for the last entry above. The * number of entries in this array is diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh index ea61f5c1bd..62ca7a348e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh @@ -34,6 +34,14 @@ #include "hb-set-private.hh" +#ifndef HB_MAX_NESTING_LEVEL +#define HB_MAX_NESTING_LEVEL 6 +#endif +#ifndef HB_MAX_CONTEXT_LENGTH +#define HB_MAX_CONTEXT_LENGTH 64 +#endif + + namespace OT { @@ -44,8 +52,6 @@ namespace OT { #define NOT_COVERED ((unsigned int) -1) -#define MAX_NESTING_LEVEL 6 -#define MAX_CONTEXT_LENGTH 64 @@ -501,7 +507,7 @@ struct Feature { return this+featureParams; } inline bool sanitize (hb_sanitize_context_t *c, - const Record::sanitize_closure_t *closure) const + const Record::sanitize_closure_t *closure = NULL) const { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) @@ -539,6 +545,9 @@ struct Feature c->try_set (&featureParams, new_offset) && !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) return_trace (false); + + if (c->edit_count > 1) + c->edit_count--; /* This was a "legitimate" edit; don't contribute to error count. */ } return_trace (true); @@ -573,6 +582,11 @@ struct LookupFlag : USHORT DEFINE_SIZE_STATIC (2); }; +} /* namespace OT */ +/* This has to be outside the namespace. */ +HB_MARK_AS_FLAG_T (OT::LookupFlag::Flags); +namespace OT { + struct Lookup { inline unsigned int get_subtable_count (void) const { return subTable.len; } @@ -717,8 +731,8 @@ struct CoverageFormat1 inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; inline bool more (void) { return i < c->glyphArray.len; } inline void next (void) { i++; } - inline uint16_t get_glyph (void) { return c->glyphArray[i]; } - inline uint16_t get_coverage (void) { return i; } + inline hb_codepoint_t get_glyph (void) { return c->glyphArray[i]; } + inline unsigned int get_coverage (void) { return i; } private: const struct CoverageFormat1 *c; @@ -756,7 +770,11 @@ struct CoverageFormat2 TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - if (unlikely (!num_glyphs)) return_trace (true); + if (unlikely (!num_glyphs)) + { + rangeRecord.len.set (0); + return_trace (true); + } unsigned int num_ranges = 1; for (unsigned int i = 1; i < num_glyphs; i++) @@ -811,26 +829,33 @@ struct CoverageFormat2 public: /* Older compilers need this to be public. */ - struct Iter { - inline void init (const CoverageFormat2 &c_) { + struct Iter + { + inline void init (const CoverageFormat2 &c_) + { c = &c_; coverage = 0; i = 0; j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; } inline bool more (void) { return i < c->rangeRecord.len; } - inline void next (void) { - coverage++; - if (j == c->rangeRecord[i].end) { + inline void next (void) + { + if (j >= c->rangeRecord[i].end) + { i++; if (more ()) + { j = c->rangeRecord[i].start; + coverage = c->rangeRecord[i].value; + } return; } + coverage++; j++; } - inline uint16_t get_glyph (void) { return j; } - inline uint16_t get_coverage (void) { return coverage; } + inline hb_codepoint_t get_glyph (void) { return j; } + inline unsigned int get_coverage (void) { return coverage; } private: const struct CoverageFormat2 *c; @@ -939,14 +964,14 @@ struct Coverage default: break; } } - inline uint16_t get_glyph (void) { + inline hb_codepoint_t get_glyph (void) { switch (format) { case 1: return u.format1.get_glyph (); case 2: return u.format2.get_glyph (); default:return 0; } } - inline uint16_t get_coverage (void) { + inline unsigned int get_coverage (void) { switch (format) { case 1: return u.format1.get_coverage (); case 2: return u.format2.get_coverage (); @@ -1143,12 +1168,381 @@ struct ClassDef }; +/* + * Item Variation Store + */ + +struct VarRegionAxis +{ + inline float evaluate (int coord) const + { + int start = startCoord, peak = peakCoord, end = endCoord; + + /* TODO Move these to sanitize(). */ + if (unlikely (start > peak || peak > end)) + return 1.; + if (unlikely (start < 0 && end > 0 && peak != 0)) + return 1.; + + if (peak == 0 || coord == peak) + return 1.; + + if (coord <= start || end <= coord) + return 0.; + + /* Interpolate */ + if (coord < peak) + return float (coord - start) / (peak - start); + else + return float (end - coord) / (end - peak); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + /* TODO Handle invalid start/peak/end configs, so we don't + * have to do that at runtime. */ + } + + public: + F2DOT14 startCoord; + F2DOT14 peakCoord; + F2DOT14 endCoord; + public: + DEFINE_SIZE_STATIC (6); +}; + +struct VarRegionList +{ + inline float evaluate (unsigned int region_index, + int *coords, unsigned int coord_len) const + { + if (unlikely (region_index >= regionCount)) + return 0.; + + const VarRegionAxis *axes = axesZ + (region_index * axisCount); + + float v = 1.; + unsigned int count = MIN (coord_len, (unsigned int) axisCount); + for (unsigned int i = 0; i < count; i++) + { + float factor = axes[i].evaluate (coords[i]); + if (factor == 0.) + return 0.; + v *= factor; + } + return v; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_array (axesZ, axesZ[0].static_size, + (unsigned int) axisCount * (unsigned int) regionCount)); + } + + protected: + USHORT axisCount; + USHORT regionCount; + VarRegionAxis axesZ[VAR]; + public: + DEFINE_SIZE_ARRAY (4, axesZ); +}; + +struct VarData +{ + inline unsigned int get_row_size (void) const + { return shortCount + regionIndices.len; } + + inline unsigned int get_size (void) const + { return itemCount * get_row_size (); } + + inline float get_delta (unsigned int inner, + int *coords, unsigned int coord_count, + const VarRegionList ®ions) const + { + if (unlikely (inner >= itemCount)) + return 0.; + + unsigned int count = regionIndices.len; + unsigned int scount = shortCount; + + const BYTE *bytes = &StructAfter (regionIndices); + const BYTE *row = bytes + inner * (scount + count); + + float delta = 0.; + unsigned int i = 0; + + const SHORT *scursor = reinterpret_cast (row); + for (; i < scount; i++) + { + float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); + delta += scalar * *scursor++; + } + const INT8 *bcursor = reinterpret_cast (scursor); + for (; i < count; i++) + { + float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); + delta += scalar * *bcursor++; + } + + return delta; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + regionIndices.sanitize(c) && + shortCount <= regionIndices.len && + c->check_array (&StructAfter (regionIndices), + get_row_size (), itemCount)); + } + + protected: + USHORT itemCount; + USHORT shortCount; + ArrayOf regionIndices; + BYTE bytesX[VAR]; + public: + DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); +}; + +struct VariationStore +{ + inline float get_delta (unsigned int outer, unsigned int inner, + int *coords, unsigned int coord_count) const + { + if (unlikely (outer >= dataSets.len)) + return 0.; + + return (this+dataSets[outer]).get_delta (inner, + coords, coord_count, + this+regions); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + format == 1 && + regions.sanitize (c, this) && + dataSets.sanitize (c, this)); + } + + protected: + USHORT format; + OffsetTo regions; + OffsetArrayOf dataSets; + public: + DEFINE_SIZE_ARRAY (8, dataSets); +}; + +/* + * Feature Variations + */ + +struct ConditionFormat1 +{ + friend struct Condition; + + private: + inline bool evaluate (const int *coords, unsigned int coord_len) const + { + int coord = axisIndex < coord_len ? coords[axisIndex] : 0; + return filterRangeMinValue <= coord && coord <= filterRangeMaxValue; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + USHORT format; /* Format identifier--format = 1 */ + USHORT axisIndex; + F2DOT14 filterRangeMinValue; + F2DOT14 filterRangeMaxValue; + public: + DEFINE_SIZE_STATIC (8); +}; + +struct Condition +{ + inline bool evaluate (const int *coords, unsigned int coord_len) const + { + switch (u.format) { + case 1: return u.format1.evaluate (coords, coord_len); + default:return false; + } + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) { + case 1: return_trace (u.format1.sanitize (c)); + default:return_trace (true); + } + } + + protected: + union { + USHORT format; /* Format identifier */ + ConditionFormat1 format1; + } u; + public: + DEFINE_SIZE_UNION (2, format); +}; + +struct ConditionSet +{ + inline bool evaluate (const int *coords, unsigned int coord_len) const + { + unsigned int count = conditions.len; + for (unsigned int i = 0; i < count; i++) + if (!(this+conditions.array[i]).evaluate (coords, coord_len)) + return false; + return true; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (conditions.sanitize (c, this)); + } + + protected: + OffsetArrayOf conditions; + public: + DEFINE_SIZE_ARRAY (2, conditions); +}; + +struct FeatureTableSubstitutionRecord +{ + friend struct FeatureTableSubstitution; + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && feature.sanitize (c, base)); + } + + protected: + USHORT featureIndex; + OffsetTo feature; + public: + DEFINE_SIZE_STATIC (6); +}; + +struct FeatureTableSubstitution +{ + inline const Feature *find_substitute (unsigned int feature_index) const + { + unsigned int count = substitutions.len; + for (unsigned int i = 0; i < count; i++) + { + const FeatureTableSubstitutionRecord &record = substitutions.array[i]; + if (record.featureIndex == feature_index) + return &(this+record.feature); + } + return NULL; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + likely (version.major == 1) && + substitutions.sanitize (c, this)); + } + + protected: + FixedVersion<> version; /* Version--0x00010000u */ + ArrayOf + substitutions; + public: + DEFINE_SIZE_ARRAY (6, substitutions); +}; + +struct FeatureVariationRecord +{ + friend struct FeatureVariations; + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (conditions.sanitize (c, base) && + substitutions.sanitize (c, base)); + } + + protected: + OffsetTo + conditions; + OffsetTo + substitutions; + public: + DEFINE_SIZE_STATIC (8); +}; + +struct FeatureVariations +{ + static const unsigned int NOT_FOUND_INDEX = 0xFFFFFFFFu; + + inline bool find_index (const int *coords, unsigned int coord_len, + unsigned int *index) const + { + unsigned int count = varRecords.len; + for (unsigned int i = 0; i < count; i++) + { + const FeatureVariationRecord &record = varRecords.array[i]; + if ((this+record.conditions).evaluate (coords, coord_len)) + { + *index = i; + return true; + } + } + *index = NOT_FOUND_INDEX; + return false; + } + + inline const Feature *find_substitute (unsigned int variations_index, + unsigned int feature_index) const + { + const FeatureVariationRecord &record = varRecords[variations_index]; + return (this+record.substitutions).find_substitute (feature_index); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + likely (version.major == 1) && + varRecords.sanitize (c, this)); + } + + protected: + FixedVersion<> version; /* Version--0x00010000u */ + ArrayOf + varRecords; + public: + DEFINE_SIZE_ARRAY (8, varRecords); +}; + + /* * Device Tables */ -struct Device +struct HintingDevice { + friend struct Device; + + private: inline hb_position_t get_x_delta (hb_font_t *font) const { return get_delta (font->x_ppem, font->x_scale); } @@ -1156,6 +1550,21 @@ struct Device inline hb_position_t get_y_delta (hb_font_t *font) const { return get_delta (font->y_ppem, font->y_scale); } + inline unsigned int get_size (void) const + { + unsigned int f = deltaFormat; + if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; + return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); + } + + private: + inline int get_delta (unsigned int ppem, int scale) const { if (!ppem) return 0; @@ -1166,8 +1575,6 @@ struct Device return (int) (pixels * (int64_t) scale / ppem); } - - inline int get_delta_pixels (unsigned int ppem_size) const { unsigned int f = deltaFormat; @@ -1191,19 +1598,6 @@ struct Device return delta; } - inline unsigned int get_size (void) const - { - unsigned int f = deltaFormat; - if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size; - return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f))); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); - } - protected: USHORT startSize; /* Smallest size to correct--in ppem */ USHORT endSize; /* Largest size to correct--in ppem */ @@ -1217,6 +1611,101 @@ struct Device DEFINE_SIZE_ARRAY (6, deltaValue); }; +struct VariationDevice +{ + friend struct Device; + + private: + + inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store) const + { return font->em_scalef_x (get_delta (font, store)); } + + inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const + { return font->em_scalef_y (get_delta (font, store)); } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + private: + + inline float get_delta (hb_font_t *font, const VariationStore &store) const + { + return store.get_delta (outerIndex, innerIndex, font->coords, font->num_coords); + } + + protected: + USHORT outerIndex; + USHORT innerIndex; + USHORT deltaFormat; /* Format identifier for this table: 0x0x8000 */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct DeviceHeader +{ + protected: + USHORT reserved1; + USHORT reserved2; + public: + USHORT format; /* Format identifier */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct Device +{ + inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const + { + switch (u.b.format) + { + case 1: case 2: case 3: + return u.hinting.get_x_delta (font); + case 0x8000: + return u.variation.get_x_delta (font, store); + default: + return 0; + } + } + inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const + { + switch (u.b.format) + { + case 1: case 2: case 3: + return u.hinting.get_y_delta (font); + case 0x8000: + return u.variation.get_y_delta (font, store); + default: + return 0; + } + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.b.format.sanitize (c)) return_trace (false); + switch (u.b.format) { + case 1: case 2: case 3: + return_trace (u.hinting.sanitize (c)); + case 0x8000: + return_trace (u.variation.sanitize (c)); + default: + return_trace (true); + } + } + + protected: + union { + DeviceHeader b; + HintingDevice hinting; + VariationDevice variation; + } u; + public: + DEFINE_SIZE_UNION (6, b); +}; + } /* namespace OT */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh index bc36436be7..b70cbb7a38 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh @@ -97,7 +97,7 @@ struct CaretValueFormat1 friend struct CaretValue; private: - inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const + inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const { return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate); } @@ -146,11 +146,11 @@ struct CaretValueFormat3 { friend struct CaretValue; - inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id HB_UNUSED) const + inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, const VariationStore &var_store) const { return HB_DIRECTION_IS_HORIZONTAL (direction) ? - font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font) : - font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font); + font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) : + font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -172,12 +172,15 @@ struct CaretValueFormat3 struct CaretValue { - inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const + inline hb_position_t get_caret_value (hb_font_t *font, + hb_direction_t direction, + hb_codepoint_t glyph_id, + const VariationStore &var_store) const { switch (u.format) { - case 1: return u.format1.get_caret_value (font, direction, glyph_id); + case 1: return u.format1.get_caret_value (font, direction); case 2: return u.format2.get_caret_value (font, direction, glyph_id); - case 3: return u.format3.get_caret_value (font, direction, glyph_id); + case 3: return u.format3.get_caret_value (font, direction, var_store); default:return 0; } } @@ -210,6 +213,7 @@ struct LigGlyph inline unsigned int get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, + const VariationStore &var_store, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -218,7 +222,7 @@ struct LigGlyph const OffsetTo *array = carets.sub_array (start_offset, caret_count); unsigned int count = *caret_count; for (unsigned int i = 0; i < count; i++) - caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id); + caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store); } return carets.len; @@ -244,6 +248,7 @@ struct LigCaretList inline unsigned int get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, + const VariationStore &var_store, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const @@ -256,7 +261,7 @@ struct LigCaretList return 0; } const LigGlyph &lig_glyph = this+ligGlyph[index]; - return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); + return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -367,11 +372,17 @@ struct GDEF unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const - { return (this+ligCaretList).get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array); } + { return (this+ligCaretList).get_lig_carets (font, + direction, glyph_id, get_var_store(), + start_offset, caret_count, caret_array); } - inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef[0] != 0; } + inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef != 0; } inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const - { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); } + { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef).covers (set_index, glyph_id); } + + inline bool has_var_store (void) const { return version.to_int () >= 0x00010003u && varStore != 0; } + inline const VariationStore &get_var_store (void) const + { return version.to_int () >= 0x00010003u ? this+varStore : Null(VariationStore); } inline bool sanitize (hb_sanitize_context_t *c) const { @@ -382,10 +393,10 @@ struct GDEF attachList.sanitize (c, this) && ligCaretList.sanitize (c, this) && markAttachClassDef.sanitize (c, this) && - (version.to_int () < 0x00010002u || markGlyphSetsDef[0].sanitize (c, this))); + (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && + (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); } - /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing * glyph class and other bits, and high 8-bit gthe mark attachment type (if any). * Not to be confused with lookup_props which is very similar. */ @@ -409,8 +420,8 @@ struct GDEF protected: - FixedVersion version; /* Version of the GDEF table--currently - * 0x00010002u */ + FixedVersion<>version; /* Version of the GDEF table--currently + * 0x00010003u */ OffsetTo glyphClassDef; /* Offset to class definition table * for glyph type--from beginning of @@ -428,12 +439,17 @@ struct GDEF * mark attachment type--from beginning * of GDEF header (may be Null) */ OffsetTo - markGlyphSetsDef[VAR]; /* Offset to the table of mark set + markGlyphSetsDef; /* Offset to the table of mark set * definitions--from beginning of GDEF * header (may be NULL). Introduced - * in version 00010002. */ + * in version 0x00010002. */ + OffsetTo + varStore; /* Offset to the table of Item Variation + * Store--from beginning of GDEF + * header (may be NULL). Introduced + * in version 0x00010003. */ public: - DEFINE_SIZE_ARRAY (12, markGlyphSetsDef); + DEFINE_SIZE_MIN (12); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh index 568b5f63a9..952fd60fec 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh @@ -36,8 +36,17 @@ namespace OT { /* buffer **position** var allocations */ -#define attach_lookback() var.u16[0] /* number of glyphs to go back to attach this glyph to its base */ -#define cursive_chain() var.i16[1] /* character to which this connects, may be positive or negative */ +#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */ +#define attach_type() var.u8[2] /* attachment type */ +/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */ + +enum attach_type_t { + ATTACH_TYPE_NONE = 0X00, + + /* Each attachment should be either a mark or a cursive; can't be both. */ + ATTACH_TYPE_MARK = 0X01, + ATTACH_TYPE_CURSIVE = 0X02, +}; /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ @@ -94,18 +103,17 @@ struct ValueFormat : USHORT inline unsigned int get_size (void) const { return get_len () * Value::static_size; } - void apply_value (hb_font_t *font, - hb_direction_t direction, + void apply_value (hb_apply_context_t *c, const void *base, const Value *values, hb_glyph_position_t &glyph_pos) const { - unsigned int x_ppem, y_ppem; unsigned int format = *this; - hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (direction); - if (!format) return; + hb_font_t *font = c->font; + hb_bool_t horizontal = HB_DIRECTION_IS_HORIZONTAL (c->direction); + if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++)); if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++)); if (format & xAdvance) { @@ -120,27 +128,29 @@ struct ValueFormat : USHORT if (!has_device ()) return; - x_ppem = font->x_ppem; - y_ppem = font->y_ppem; + bool use_x_device = font->x_ppem || font->num_coords; + bool use_y_device = font->y_ppem || font->num_coords; + + if (!use_x_device && !use_y_device) return; - if (!x_ppem && !y_ppem) return; + const VariationStore &store = c->var_store; /* pixel -> fractional pixel */ if (format & xPlaDevice) { - if (x_ppem) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font); + if (use_x_device) glyph_pos.x_offset += (base + get_device (values)).get_x_delta (font, store); values++; } if (format & yPlaDevice) { - if (y_ppem) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font); + if (use_y_device) glyph_pos.y_offset += (base + get_device (values)).get_y_delta (font, store); values++; } if (format & xAdvDevice) { - if (horizontal && x_ppem) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font); + if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values)).get_x_delta (font, store); values++; } if (format & yAdvDevice) { /* y_advance values grow downward but font-space grows upward, hence negation */ - if (!horizontal && y_ppem) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font); + if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values)).get_y_delta (font, store); values++; } } @@ -222,11 +232,12 @@ struct ValueFormat : USHORT struct AnchorFormat1 { - inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, + inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED, hb_position_t *x, hb_position_t *y) const { - *x = font->em_scale_x (xCoordinate); - *y = font->em_scale_y (yCoordinate); + hb_font_t *font = c->font; + *x = font->em_scale_x (xCoordinate); + *y = font->em_scale_y (yCoordinate); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -245,18 +256,19 @@ struct AnchorFormat1 struct AnchorFormat2 { - inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, + inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id, hb_position_t *x, hb_position_t *y) const { - unsigned int x_ppem = font->x_ppem; - unsigned int y_ppem = font->y_ppem; - hb_position_t cx, cy; - hb_bool_t ret; + hb_font_t *font = c->font; + unsigned int x_ppem = font->x_ppem; + unsigned int y_ppem = font->y_ppem; + hb_position_t cx, cy; + hb_bool_t ret; - ret = (x_ppem || y_ppem) && - font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); - *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); - *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); + ret = (x_ppem || y_ppem) && + font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy); + *x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate); + *y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -276,16 +288,17 @@ struct AnchorFormat2 struct AnchorFormat3 { - inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED, + inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED, hb_position_t *x, hb_position_t *y) const { - *x = font->em_scale_x (xCoordinate); - *y = font->em_scale_y (yCoordinate); + hb_font_t *font = c->font; + *x = font->em_scale_x (xCoordinate); + *y = font->em_scale_y (yCoordinate); - if (font->x_ppem) - *x += (this+xDeviceTable).get_x_delta (font); - if (font->y_ppem) - *y += (this+yDeviceTable).get_x_delta (font); + if (font->x_ppem || font->num_coords) + *x += (this+xDeviceTable).get_x_delta (font, c->var_store); + if (font->y_ppem || font->num_coords) + *y += (this+yDeviceTable).get_y_delta (font, c->var_store); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -312,14 +325,14 @@ struct AnchorFormat3 struct Anchor { - inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id, + inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id, hb_position_t *x, hb_position_t *y) const { *x = *y = 0; switch (u.format) { - case 1: u.format1.get_anchor (font, glyph_id, x, y); return; - case 2: u.format2.get_anchor (font, glyph_id, x, y); return; - case 3: u.format3.get_anchor (font, glyph_id, x, y); return; + case 1: u.format1.get_anchor (c, glyph_id, x, y); return; + case 2: u.format2.get_anchor (c, glyph_id, x, y); return; + case 3: u.format3.get_anchor (c, glyph_id, x, y); return; default: return; } } @@ -361,7 +374,7 @@ struct AnchorMatrix { TRACE_SANITIZE (this); if (!c->check_struct (this)) return_trace (false); - if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return_trace (false); + if (unlikely (_hb_unsigned_int_mul_overflows (rows, cols))) return_trace (false); unsigned int count = rows * cols; if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false); for (unsigned int i = 0; i < count; i++) @@ -419,13 +432,15 @@ struct MarkArray : ArrayOf /* Array of MarkRecords--in Coverage orde hb_position_t mark_x, mark_y, base_x, base_y; - mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y); - glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x, &base_y); + mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y); + glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y); hb_glyph_position_t &o = buffer->cur_pos(); o.x_offset = base_x - mark_x; o.y_offset = base_y - mark_y; - o.attach_lookback() = buffer->idx - glyph_pos; + o.attach_type() = ATTACH_TYPE_MARK; + o.attach_chain() = (int) glyph_pos - (int) buffer->idx; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; buffer->idx++; return_trace (true); @@ -461,8 +476,7 @@ struct SinglePosFormat1 unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - valueFormat.apply_value (c->font, c->direction, this, - values, buffer->cur_pos()); + valueFormat.apply_value (c, this, values, buffer->cur_pos()); buffer->idx++; return_trace (true); @@ -512,7 +526,7 @@ struct SinglePosFormat2 if (likely (index >= valueCount)) return_trace (false); - valueFormat.apply_value (c->font, c->direction, this, + valueFormat.apply_value (c, this, &values[index * valueFormat.get_len ()], buffer->cur_pos()); @@ -629,10 +643,8 @@ struct PairSet min = mid + 1; else { - valueFormats[0].apply_value (c->font, c->direction, this, - &record->values[0], buffer->cur_pos()); - valueFormats[1].apply_value (c->font, c->direction, this, - &record->values[len1], buffer->pos[pos]); + valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); + valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); if (len2) pos++; buffer->idx = pos; @@ -678,7 +690,7 @@ struct PairPosFormat1 (this+coverage).add_coverage (c->input); unsigned int count = pairSet.len; for (unsigned int i = 0; i < count; i++) - (this+pairSet[i]).collect_glyphs (c, &valueFormat1); + (this+pairSet[i]).collect_glyphs (c, valueFormat); } inline const Coverage &get_coverage (void) const @@ -697,7 +709,7 @@ struct PairPosFormat1 skippy_iter.reset (buffer->idx, 1); if (!skippy_iter.next ()) return_trace (false); - return_trace ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); + return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx)); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -706,11 +718,11 @@ struct PairPosFormat1 if (!c->check_struct (this)) return_trace (false); - unsigned int len1 = valueFormat1.get_len (); - unsigned int len2 = valueFormat2.get_len (); + unsigned int len1 = valueFormat[0].get_len (); + unsigned int len2 = valueFormat[1].get_len (); PairSet::sanitize_closure_t closure = { this, - &valueFormat1, + valueFormat, len1, 1 + len1 + len2 }; @@ -723,10 +735,10 @@ struct PairPosFormat1 OffsetTo coverage; /* Offset to Coverage table--from * beginning of subtable */ - ValueFormat valueFormat1; /* Defines the types of data in + ValueFormat valueFormat[2]; /* [0] Defines the types of data in * ValueRecord1--for the first glyph * in the pair--may be zero (0) */ - ValueFormat valueFormat2; /* Defines the types of data in + /* [1] Defines the types of data in * ValueRecord2--for the second glyph * in the pair--may be zero (0) */ OffsetArrayOf @@ -741,7 +753,7 @@ struct PairPosFormat2 inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - /* (this+coverage).add_coverage (c->input); // Don't need this. */ + (this+coverage).add_coverage (c->input); unsigned int count1 = class1Count; const ClassDef &klass1 = this+classDef1; @@ -779,10 +791,8 @@ struct PairPosFormat2 if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; - valueFormat1.apply_value (c->font, c->direction, this, - v, buffer->cur_pos()); - valueFormat2.apply_value (c->font, c->direction, this, - v + len1, buffer->pos[skippy_iter.idx]); + valueFormat1.apply_value (c, this, v, buffer->cur_pos()); + valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]); buffer->idx = skippy_iter.idx; if (len2) @@ -906,9 +916,6 @@ struct CursivePosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; - /* We don't handle mark glyphs here. */ - if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return_trace (false); - const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.exitAnchor) return_trace (false); @@ -923,8 +930,8 @@ struct CursivePosFormat1 unsigned int j = skippy_iter.idx; hb_position_t entry_x, entry_y, exit_x, exit_y; - (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint, &exit_x, &exit_y); - (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoint, &entry_x, &entry_y); + (this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); + (this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y); hb_glyph_position_t *pos = buffer->pos; @@ -992,7 +999,9 @@ struct CursivePosFormat1 */ reverse_cursive_minor_offset (pos, child, c->direction, parent); - pos[child].cursive_chain() = parent - child; + pos[child].attach_type() = ATTACH_TYPE_CURSIVE; + pos[child].attach_chain() = (int) parent - (int) child; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT; if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) pos[child].y_offset = y_offset; else @@ -1067,7 +1076,7 @@ struct MarkBasePosFormat1 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); if (likely (mark_index == NOT_COVERED)) return_trace (false); - /* now we search backwards for a non-mark glyph */ + /* Now we search backwards for a non-mark glyph */ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); @@ -1079,7 +1088,7 @@ struct MarkBasePosFormat1 } while (1); /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ - if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } + //if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { return_trace (false); } unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); if (base_index == NOT_COVERED) return_trace (false); @@ -1168,14 +1177,14 @@ struct MarkLigPosFormat1 unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint); if (likely (mark_index == NOT_COVERED)) return_trace (false); - /* now we search backwards for a non-mark glyph */ + /* Now we search backwards for a non-mark glyph */ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); if (!skippy_iter.prev ()) return_trace (false); /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ - if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } + //if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { return_trace (false); } unsigned int j = skippy_iter.idx; unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); @@ -1499,7 +1508,8 @@ struct GPOS : GSUBGPOS { return CastR (GSUBGPOS::get_lookup (i)); } static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); - static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer); + static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); + static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer); inline bool sanitize (hb_sanitize_context_t *c) const { @@ -1508,21 +1518,19 @@ struct GPOS : GSUBGPOS const OffsetTo &list = CastR > (lookupList); return_trace (list.sanitize (c, this)); } - public: - DEFINE_SIZE_STATIC (10); }; static void reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) { - unsigned int j = pos[i].cursive_chain(); - if (likely (!j)) + int chain = pos[i].attach_chain(), type = pos[i].attach_type(); + if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE))) return; - j += i; + pos[i].attach_chain() = 0; - pos[i].cursive_chain() = 0; + unsigned int j = (int) i + chain; /* Stop if we see new parent in the chain. */ if (j == new_parent) @@ -1535,62 +1543,68 @@ reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direc else pos[j].x_offset = -pos[i].x_offset; - pos[j].cursive_chain() = i - j; + pos[j].attach_chain() = -chain; + pos[j].attach_type() = type; } static void -fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) +propagate_attachment_offsets (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) { - unsigned int j = pos[i].cursive_chain(); - if (likely (!j)) + /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate + * offset of glyph they are attached to. */ + int chain = pos[i].attach_chain(), type = pos[i].attach_type(); + if (likely (!chain)) return; - j += i; - - pos[i].cursive_chain() = 0; + unsigned int j = (int) i + chain; - fix_cursive_minor_offset (pos, j, direction); + pos[i].attach_chain() = 0; - if (HB_DIRECTION_IS_HORIZONTAL (direction)) - pos[i].y_offset += pos[j].y_offset; - else - pos[i].x_offset += pos[j].x_offset; -} + propagate_attachment_offsets (pos, j, direction); -static void -fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) -{ - if (likely (!(pos[i].attach_lookback()))) - return; + assert (!!(type & ATTACH_TYPE_MARK) ^ !!(type & ATTACH_TYPE_CURSIVE)); - unsigned int j = i - pos[i].attach_lookback(); - - pos[i].x_offset += pos[j].x_offset; - pos[i].y_offset += pos[j].y_offset; + if (type & ATTACH_TYPE_CURSIVE) + { + if (HB_DIRECTION_IS_HORIZONTAL (direction)) + pos[i].y_offset += pos[j].y_offset; + else + pos[i].x_offset += pos[j].x_offset; + } + else /*if (type & ATTACH_TYPE_MARK)*/ + { + pos[i].x_offset += pos[j].x_offset; + pos[i].y_offset += pos[j].y_offset; - if (HB_DIRECTION_IS_FORWARD (direction)) - for (unsigned int k = j; k < i; k++) { - pos[i].x_offset -= pos[k].x_advance; - pos[i].y_offset -= pos[k].y_advance; - } - else - for (unsigned int k = j + 1; k < i + 1; k++) { - pos[i].x_offset += pos[k].x_advance; - pos[i].y_offset += pos[k].y_advance; - } + assert (j < i); + if (HB_DIRECTION_IS_FORWARD (direction)) + for (unsigned int k = j; k < i; k++) { + pos[i].x_offset -= pos[k].x_advance; + pos[i].y_offset -= pos[k].y_advance; + } + else + for (unsigned int k = j + 1; k < i + 1; k++) { + pos[i].x_offset += pos[k].x_advance; + pos[i].y_offset += pos[k].y_advance; + } + } } void GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { - buffer->clear_positions (); - unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) - buffer->pos[i].attach_lookback() = buffer->pos[i].cursive_chain() = 0; + buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0; } void -GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) +GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) +{ + //_hb_buffer_assert_gsubgpos_vars (buffer); +} + +void +GPOS::position_finish_offsets (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { _hb_buffer_assert_gsubgpos_vars (buffer); @@ -1598,13 +1612,10 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len); hb_direction_t direction = buffer->props.direction; - /* Handle cursive connections */ - for (unsigned int i = 0; i < len; i++) - fix_cursive_minor_offset (pos, i, direction); - /* Handle attachments */ - for (unsigned int i = 0; i < len; i++) - fix_mark_attachment (pos, i, direction); + if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT) + for (unsigned int i = 0; i < len; i++) + propagate_attachment_offsets (pos, i, direction); } @@ -1633,8 +1644,8 @@ template } -#undef attach_lookback -#undef cursive_chain +#undef attach_chain +#undef attach_type } /* namespace OT */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh index eebc87b4c5..66fcb3f3af 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh @@ -41,7 +41,10 @@ struct SingleSubstFormat1 { TRACE_CLOSURE (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + /* TODO Switch to range-based API to work around malicious fonts. + * https://github.com/behdad/harfbuzz/issues/363 */ hb_codepoint_t glyph_id = iter.get_glyph (); if (c->glyphs->has (glyph_id)) c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu); @@ -52,7 +55,10 @@ struct SingleSubstFormat1 { TRACE_COLLECT_GLYPHS (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + /* TODO Switch to range-based API to work around malicious fonts. + * https://github.com/behdad/harfbuzz/issues/363 */ hb_codepoint_t glyph_id = iter.get_glyph (); c->input->add (glyph_id); c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu); @@ -120,7 +126,11 @@ struct SingleSubstFormat2 { TRACE_CLOSURE (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + unsigned int count = substitute.len; + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + if (unlikely (iter.get_coverage () >= count)) + break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) c->glyphs->add (substitute[iter.get_coverage ()]); } @@ -130,7 +140,11 @@ struct SingleSubstFormat2 { TRACE_COLLECT_GLYPHS (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + unsigned int count = substitute.len; + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + if (unlikely (iter.get_coverage () >= count)) + break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */ c->input->add (iter.get_glyph ()); c->output->add (substitute[iter.get_coverage ()]); } @@ -265,16 +279,6 @@ struct Sequence TRACE_APPLY (this); unsigned int count = substitute.len; - /* TODO: - * Testing shows that Uniscribe actually allows zero-len susbstitute, - * which essentially deletes a glyph. We don't allow for now. It - * can be confusing to the client since the cluster from the deleted - * glyph won't be merged with any output cluster... Also, currently - * buffer->move_to() makes assumptions about this too. Perhaps fix - * in the future after figuring out what to do with the clusters. - */ - if (unlikely (!count)) return_trace (false); - /* Special-case to make it in-place and not consider this * as a "multiplied" substitution. */ if (unlikely (count == 1)) @@ -282,6 +286,13 @@ struct Sequence c->replace_glyph (substitute.array[0]); return_trace (true); } + /* Spec disallows this, but Uniscribe allows it. + * https://github.com/behdad/harfbuzz/issues/253 */ + else if (unlikely (count == 0)) + { + c->buffer->delete_glyph (); + return_trace (true); + } unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0; @@ -324,7 +335,11 @@ struct MultipleSubstFormat1 { TRACE_CLOSURE (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + unsigned int count = sequence.len; + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + if (unlikely (iter.get_coverage () >= count)) + break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) (this+sequence[iter.get_coverage ()]).closure (c); } @@ -442,7 +457,11 @@ struct AlternateSubstFormat1 { TRACE_CLOSURE (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + unsigned int count = alternateSet.len; + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + if (unlikely (iter.get_coverage () >= count)) + break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) { const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; unsigned int count = alt_set.len; @@ -456,7 +475,11 @@ struct AlternateSubstFormat1 { TRACE_COLLECT_GLYPHS (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + unsigned int count = alternateSet.len; + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + if (unlikely (iter.get_coverage () >= count)) + break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */ c->input->add (iter.get_glyph ()); const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; unsigned int count = alt_set.len; @@ -630,7 +653,7 @@ struct Ligature unsigned int total_component_count = 0; unsigned int match_length = 0; - unsigned int match_positions[MAX_CONTEXT_LENGTH]; + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; if (likely (!match_input (c, count, &component[1], @@ -765,7 +788,11 @@ struct LigatureSubstFormat1 { TRACE_CLOSURE (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + unsigned int count = ligatureSet.len; + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + if (unlikely (iter.get_coverage () >= count)) + break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) (this+ligatureSet[iter.get_coverage ()]).closure (c); } @@ -775,7 +802,11 @@ struct LigatureSubstFormat1 { TRACE_COLLECT_GLYPHS (this); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + unsigned int count = ligatureSet.len; + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + if (unlikely (iter.get_coverage () >= count)) + break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */ c->input->add (iter.get_glyph ()); (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c); } @@ -926,7 +957,11 @@ struct ReverseChainSingleSubstFormat1 const ArrayOf &substitute = StructAfter > (lookahead); Coverage::Iter iter; - for (iter.init (this+coverage); iter.more (); iter.next ()) { + count = substitute.len; + for (iter.init (this+coverage); iter.more (); iter.next ()) + { + if (unlikely (iter.get_coverage () >= count)) + break; /* Work around malicious fonts. https://github.com/behdad/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) c->glyphs->add (substitute[iter.get_coverage ()]); } @@ -970,7 +1005,7 @@ struct ReverseChainSingleSubstFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - if (unlikely (c->nesting_level_left != MAX_NESTING_LEVEL)) + if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) return_trace (false); /* No chaining to this type */ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); @@ -1268,7 +1303,6 @@ struct GSUB : GSUBGPOS { return CastR (GSUBGPOS::get_lookup (i)); } static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer); - static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer); inline bool sanitize (hb_sanitize_context_t *c) const { @@ -1277,8 +1311,6 @@ struct GSUB : GSUBGPOS const OffsetTo &list = CastR > (lookupList); return_trace (list.sanitize (c, this)); } - public: - DEFINE_SIZE_STATIC (10); }; @@ -1297,11 +1329,6 @@ GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer) } } -void -GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED) -{ -} - /* Out-of-class implementation for methods recursing */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh index 230b3b6851..fd75c5425a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh @@ -74,7 +74,7 @@ struct hb_closure_context_t : hb_closure_context_t (hb_face_t *face_, hb_set_t *glyphs_, - unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : + unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), glyphs (glyphs_), recurse_func (NULL), @@ -196,7 +196,7 @@ struct hb_collect_glyphs_context_t : hb_set_t *glyphs_input, /* OUT. May be NULL */ hb_set_t *glyphs_after, /* OUT. May be NULL */ hb_set_t *glyphs_output, /* OUT. May be NULL */ - unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : + unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) : face (face_), before (glyphs_before ? glyphs_before : hb_set_get_empty ()), input (glyphs_input ? glyphs_input : hb_set_get_empty ()), @@ -319,7 +319,7 @@ struct hb_apply_context_t : if (!c->check_glyph_property (&info, lookup_props)) return SKIP_YES; - if (unlikely (_hb_glyph_info_is_default_ignorable (&info) && + if (unlikely (_hb_glyph_info_is_default_ignorable_and_not_fvs (&info) && (ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) && (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) return SKIP_MAYBE; @@ -469,6 +469,7 @@ struct hb_apply_context_t : unsigned int lookup_props; const GDEF &gdef; bool has_glyph_classes; + const VariationStore &var_store; skipping_iterator_t iter_input, iter_context; unsigned int lookup_index; unsigned int debug_depth; @@ -483,10 +484,11 @@ struct hb_apply_context_t : lookup_mask (1), auto_zwj (true), recurse_func (NULL), - nesting_level_left (MAX_NESTING_LEVEL), + nesting_level_left (HB_MAX_NESTING_LEVEL), lookup_props (0), gdef (*hb_ot_layout_from_face (face)->gdef), has_glyph_classes (gdef.has_glyph_classes ()), + var_store (gdef.get_var_store ()), iter_input (), iter_context (), lookup_index ((unsigned int) -1), @@ -704,13 +706,13 @@ static inline bool match_input (hb_apply_context_t *c, match_func_t match_func, const void *match_data, unsigned int *end_offset, - unsigned int match_positions[MAX_CONTEXT_LENGTH], + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], bool *p_is_mark_ligature = NULL, unsigned int *p_total_component_count = NULL) { TRACE_APPLY (NULL); - if (unlikely (count > MAX_CONTEXT_LENGTH)) return_trace (false); + if (unlikely (count > HB_MAX_CONTEXT_LENGTH)) return_trace (false); hb_buffer_t *buffer = c->buffer; @@ -784,7 +786,7 @@ static inline bool match_input (hb_apply_context_t *c, } static inline bool ligate_input (hb_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int match_length, hb_codepoint_t lig_glyph, bool is_mark_ligature, @@ -836,19 +838,21 @@ static inline bool ligate_input (hb_apply_context_t *c, if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) { _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER); - _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0); } } c->replace_glyph_with_ligature (lig_glyph, klass); for (unsigned int i = 1; i < count; i++) { - while (buffer->idx < match_positions[i]) + while (buffer->idx < match_positions[i] && !buffer->in_error) { if (!is_mark_ligature) { + unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur()); + if (this_comp == 0) + this_comp = last_num_components; unsigned int new_lig_comp = components_so_far - last_num_components + - MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components); - _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); + MIN (this_comp, last_num_components); + _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); } buffer->next_glyph (); } @@ -865,8 +869,11 @@ static inline bool ligate_input (hb_apply_context_t *c, /* Re-adjust components for any marks following. */ for (unsigned int i = buffer->idx; i < buffer->len; i++) { if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) { + unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]); + if (!this_comp) + break; unsigned int new_lig_comp = components_so_far - last_num_components + - MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components); + MIN (this_comp, last_num_components); _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp); } else break; @@ -944,7 +951,7 @@ static inline void recurse_lookups (context_t *c, static inline bool apply_lookup (hb_apply_context_t *c, unsigned int count, /* Including the first glyph */ - unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */ unsigned int match_length) @@ -966,12 +973,17 @@ static inline bool apply_lookup (hb_apply_context_t *c, match_positions[j] += delta; } - for (unsigned int i = 0; i < lookupCount; i++) + for (unsigned int i = 0; i < lookupCount && !buffer->in_error; i++) { unsigned int idx = lookupRecord[i].sequenceIndex; if (idx >= count) continue; + /* Don't recurse to ourself at same position. + * Note that this test is too naive, it doesn't catch longer loops. */ + if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index) + continue; + buffer->move_to (match_positions[idx]); unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); @@ -986,16 +998,23 @@ static inline bool apply_lookup (hb_apply_context_t *c, /* Recursed lookup changed buffer len. Adjust. */ - /* end can't go back past the current match position. - * Note: this is only true because we do NOT allow MultipleSubst - * with zero sequence len. */ - end = MAX ((int) match_positions[idx] + 1, int (end) + delta); + end = int (end) + delta; + if (end <= match_positions[idx]) + { + /* End might end up being smaller than match_positions[idx] if the recursed + * lookup ended up removing many items, more than we have had matched. + * Just never rewind end back and get out of here. + * https://bugs.chromium.org/p/chromium/issues/detail?id=659496 */ + end = match_positions[idx]; + /* There can't be any further changes. */ + break; + } unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */ if (delta > 0) { - if (unlikely (delta + count > MAX_CONTEXT_LENGTH)) + if (unlikely (delta + count > HB_MAX_CONTEXT_LENGTH)) break; } else @@ -1094,7 +1113,7 @@ static inline bool context_apply_lookup (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) { unsigned int match_length = 0; - unsigned int match_positions[MAX_CONTEXT_LENGTH]; + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data, @@ -1621,7 +1640,7 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) { unsigned int match_length = 0; - unsigned int match_positions[MAX_CONTEXT_LENGTH]; + unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; return match_input (c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data[1], @@ -2256,6 +2275,24 @@ struct GSUBGPOS inline const Lookup& get_lookup (unsigned int i) const { return (this+lookupList)[i]; } + inline bool find_variations_index (const int *coords, unsigned int num_coords, + unsigned int *index) const + { return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations)) + .find_index (coords, num_coords, index); } + inline const Feature& get_feature_variation (unsigned int feature_index, + unsigned int variations_index) const + { + if (FeatureVariations::NOT_FOUND_INDEX != variations_index && + version.to_int () >= 0x00010001u) + { + const Feature *feature = (this+featureVars).find_substitute (variations_index, + feature_index); + if (feature) + return *feature; + } + return get_feature (feature_index); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -2263,11 +2300,12 @@ struct GSUBGPOS likely (version.major == 1) && scriptList.sanitize (c, this) && featureList.sanitize (c, this) && - lookupList.sanitize (c, this)); + lookupList.sanitize (c, this) && + (version.to_int () < 0x00010001u || featureVars.sanitize (c, this))); } protected: - FixedVersion version; /* Version of the GSUB/GPOS table--initially set + FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set * to 0x00010000u */ OffsetTo scriptList; /* ScriptList table */ @@ -2275,8 +2313,13 @@ struct GSUBGPOS featureList; /* FeatureList table */ OffsetTo lookupList; /* LookupList table */ + OffsetTo + featureVars; /* Offset to Feature Variations + table--from beginning of table + * (may be NULL). Introduced + * in version 0x00010001. */ public: - DEFINE_SIZE_STATIC (10); + DEFINE_SIZE_MIN (10); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh index 7e199c2e14..c3068491be 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh @@ -218,7 +218,7 @@ struct JSTF } protected: - FixedVersion version; /* Version of the JSTF table--initially set + FixedVersion<>version; /* Version of the JSTF table--initially set * to 0x00010000u */ RecordArrayOf scriptList; /* Array of JstfScripts--listed diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-math-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-math-table.hh new file mode 100644 index 0000000000..b52b1215d2 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-math-table.hh @@ -0,0 +1,722 @@ +/* + * Copyright © 2016 Igalia S.L. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Igalia Author(s): Frédéric Wang + */ + +#ifndef HB_OT_LAYOUT_MATH_TABLE_HH +#define HB_OT_LAYOUT_MATH_TABLE_HH + +#include "hb-open-type-private.hh" +#include "hb-ot-layout-common-private.hh" +#include "hb-ot-math.h" + +namespace OT { + + +struct MathValueRecord +{ + inline hb_position_t get_x_value (hb_font_t *font, const void *base) const + { return font->em_scale_x (value) + (base+deviceTable).get_x_delta (font); } + inline hb_position_t get_y_value (hb_font_t *font, const void *base) const + { return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && deviceTable.sanitize (c, base)); + } + + protected: + SHORT value; /* The X or Y value in design units */ + OffsetTo deviceTable; /* Offset to the device table - from the + * beginning of parent table. May be NULL. + * Suggested format for device table is 1. */ + + public: + DEFINE_SIZE_STATIC (4); +}; + +struct MathConstants +{ + inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + + unsigned int count = ARRAY_LENGTH (mathValueRecords); + for (unsigned int i = 0; i < count; i++) + if (!mathValueRecords[i].sanitize (c, this)) + return_trace (false); + + return_trace (true); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && sanitize_math_value_records(c)); + } + + inline hb_position_t get_value (hb_ot_math_constant_t constant, + hb_font_t *font) const + { + switch (constant) { + + case HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN: + case HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN: + return percentScaleDown[constant - HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN]; + + case HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT: + case HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT: + return font->em_scale_y (minHeight[constant - HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT]); + + case HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE: + case HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE: + case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP: + case HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT: + return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value(font, this); + + case HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT: + case HB_OT_MATH_CONSTANT_AXIS_HEIGHT: + case HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT: + case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN: + case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN: + case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN: + case HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN: + case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP: + case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN: + case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP: + case HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN: + case HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS: + case HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN: + case HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN: + case HB_OT_MATH_CONSTANT_MATH_LEADING: + case HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER: + case HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS: + case HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP: + case HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP: + case HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER: + case HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS: + case HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP: + case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP: + case HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN: + case HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN: + case HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN: + case HB_OT_MATH_CONSTANT_STACK_GAP_MIN: + case HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP: + case HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP: + case HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN: + case HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN: + case HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN: + case HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP: + case HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN: + case HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN: + case HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX: + case HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN: + case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX: + case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT: + case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN: + case HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP: + case HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED: + case HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER: + case HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS: + case HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP: + case HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN: + case HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN: + return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value(font, this); + + case HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT: + return radicalDegreeBottomRaisePercent; + + default: + return 0; + } + } + + protected: + SHORT percentScaleDown[2]; + USHORT minHeight[2]; + MathValueRecord mathValueRecords[51]; + SHORT radicalDegreeBottomRaisePercent; + + public: + DEFINE_SIZE_STATIC (214); +}; + +struct MathItalicsCorrectionInfo +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + coverage.sanitize (c, this) && + italicsCorrection.sanitize (c, this)); + } + + inline hb_position_t get_value (hb_codepoint_t glyph, + hb_font_t *font) const + { + unsigned int index = (this+coverage).get_coverage (glyph); + return italicsCorrection[index].get_x_value (font, this); + } + + protected: + OffsetTo coverage; /* Offset to Coverage table - + * from the beginning of + * MathItalicsCorrectionInfo + * table. */ + ArrayOf italicsCorrection; /* Array of MathValueRecords + * defining italics correction + * values for each + * covered glyph. */ + + public: + DEFINE_SIZE_ARRAY (4, italicsCorrection); +}; + +struct MathTopAccentAttachment +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + topAccentCoverage.sanitize (c, this) && + topAccentAttachment.sanitize (c, this)); + } + + inline hb_position_t get_value (hb_codepoint_t glyph, + hb_font_t *font) const + { + unsigned int index = (this+topAccentCoverage).get_coverage (glyph); + if (index == NOT_COVERED) + return font->get_glyph_h_advance (glyph) / 2; + return topAccentAttachment[index].get_x_value(font, this); + } + + protected: + OffsetTo topAccentCoverage; /* Offset to Coverage table - + * from the beginning of + * MathTopAccentAttachment + * table. */ + ArrayOf topAccentAttachment; /* Array of MathValueRecords + * defining top accent + * attachment points for each + * covered glyph. */ + + public: + DEFINE_SIZE_ARRAY (2 + 2, topAccentAttachment); +}; + +struct MathKern +{ + inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + unsigned int count = 2 * heightCount + 1; + for (unsigned int i = 0; i < count; i++) + if (!mathValueRecords[i].sanitize (c, this)) return_trace (false); + return_trace (true); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + c->check_array (mathValueRecords, + mathValueRecords[0].static_size, + 2 * heightCount + 1) && + sanitize_math_value_records (c)); + } + + inline hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const + { + const MathValueRecord* correctionHeight = mathValueRecords; + const MathValueRecord* kernValue = mathValueRecords + heightCount; + int sign = font->y_scale < 0 ? -1 : +1; + + /* The description of the MathKern table is a ambiguous, but interpreting + * "between the two heights found at those indexes" for 0 < i < len as + * + * correctionHeight[i-1] < correction_height <= correctionHeight[i] + * + * makes the result consistent with the limit cases and we can just use the + * binary search algorithm of std::upper_bound: + */ + unsigned int i = 0; + unsigned int count = heightCount; + while (count > 0) + { + unsigned int half = count / 2; + hb_position_t height = correctionHeight[i + half].get_y_value(font, this); + if (sign * height < sign * correction_height) + { + i += half + 1; + count -= half + 1; + } else + count = half; + } + return kernValue[i].get_x_value(font, this); + } + + protected: + USHORT heightCount; + MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at + * which the kern value changes. + * Sorted by the height value in + * design units (heightCount entries), + * Followed by: + * Array of kern values corresponding + * to heights. (heightCount+1 entries). + */ + + public: + DEFINE_SIZE_ARRAY (2, mathValueRecords); +}; + +struct MathKernInfoRecord +{ + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + + unsigned int count = ARRAY_LENGTH (mathKern); + for (unsigned int i = 0; i < count; i++) + if (unlikely (!mathKern[i].sanitize (c, base))) + return_trace (false); + + return_trace (true); + } + + inline hb_position_t get_kerning (hb_ot_math_kern_t kern, + hb_position_t correction_height, + hb_font_t *font, + const void *base) const + { + unsigned int idx = kern; + if (unlikely (idx >= ARRAY_LENGTH (mathKern))) return 0; + return (base+mathKern[idx]).get_value (correction_height, font); + } + + protected: + /* Offset to MathKern table for each corner - + * from the beginning of MathKernInfo table. May be NULL. */ + OffsetTo mathKern[4]; + + public: + DEFINE_SIZE_STATIC (8); +}; + +struct MathKernInfo +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + mathKernCoverage.sanitize (c, this) && + mathKernInfoRecords.sanitize (c, this)); + } + + inline hb_position_t get_kerning (hb_codepoint_t glyph, + hb_ot_math_kern_t kern, + hb_position_t correction_height, + hb_font_t *font) const + { + unsigned int index = (this+mathKernCoverage).get_coverage (glyph); + return mathKernInfoRecords[index].get_kerning (kern, correction_height, font, this); + } + + protected: + OffsetTo mathKernCoverage; /* Offset to Coverage table - + * from the beginning of the + * MathKernInfo table. */ + ArrayOf mathKernInfoRecords; /* Array of + * MathKernInfoRecords, + * per-glyph information for + * mathematical positioning + * of subscripts and + * superscripts. */ + + public: + DEFINE_SIZE_ARRAY (4, mathKernInfoRecords); +}; + +struct MathGlyphInfo +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + mathItalicsCorrectionInfo.sanitize (c, this) && + mathTopAccentAttachment.sanitize (c, this) && + extendedShapeCoverage.sanitize (c, this) && + mathKernInfo.sanitize(c, this)); + } + + inline hb_position_t + get_italics_correction (hb_codepoint_t glyph, hb_font_t *font) const + { return (this+mathItalicsCorrectionInfo).get_value (glyph, font); } + + inline hb_position_t + get_top_accent_attachment (hb_codepoint_t glyph, hb_font_t *font) const + { return (this+mathTopAccentAttachment).get_value (glyph, font); } + + inline bool is_extended_shape (hb_codepoint_t glyph) const + { return (this+extendedShapeCoverage).get_coverage (glyph) != NOT_COVERED; } + + inline hb_position_t get_kerning (hb_codepoint_t glyph, + hb_ot_math_kern_t kern, + hb_position_t correction_height, + hb_font_t *font) const + { return (this+mathKernInfo).get_kerning (glyph, kern, correction_height, font); } + + protected: + /* Offset to MathItalicsCorrectionInfo table - + * from the beginning of MathGlyphInfo table. */ + OffsetTo mathItalicsCorrectionInfo; + + /* Offset to MathTopAccentAttachment table - + * from the beginning of MathGlyphInfo table. */ + OffsetTo mathTopAccentAttachment; + + /* Offset to coverage table for Extended Shape glyphs - + * from the beginning of MathGlyphInfo table. When the left or right glyph of + * a box is an extended shape variant, the (ink) box (and not the default + * position defined by values in MathConstants table) should be used for + * vertical positioning purposes. May be NULL.. */ + OffsetTo extendedShapeCoverage; + + /* Offset to MathKernInfo table - + * from the beginning of MathGlyphInfo table. */ + OffsetTo mathKernInfo; + + public: + DEFINE_SIZE_STATIC (8); +}; + +struct MathGlyphVariantRecord +{ + friend struct MathGlyphConstruction; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + GlyphID variantGlyph; /* Glyph ID for the variant. */ + USHORT advanceMeasurement; /* Advance width/height, in design units, of the + * variant, in the direction of requested + * glyph extension. */ + + public: + DEFINE_SIZE_STATIC (4); +}; + +struct PartFlags : USHORT +{ + enum Flags { + Extender = 0x0001u, /* If set, the part can be skipped or repeated. */ + + Defined = 0x0001u, /* All defined flags. */ + }; + + public: + DEFINE_SIZE_STATIC (2); +}; + +struct MathGlyphPartRecord +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + inline void extract (hb_ot_math_glyph_part_t &out, + int scale, + hb_font_t *font) const + { + out.glyph = glyph; + + out.start_connector_length = font->em_scale (startConnectorLength, scale); + out.end_connector_length = font->em_scale (endConnectorLength, scale); + out.full_advance = font->em_scale (fullAdvance, scale); + + ASSERT_STATIC ((unsigned int) HB_MATH_GLYPH_PART_FLAG_EXTENDER == + (unsigned int) PartFlags::Extender); + + out.flags = (hb_ot_math_glyph_part_flags_t) + (unsigned int) + (partFlags & PartFlags::Defined); + } + + protected: + GlyphID glyph; /* Glyph ID for the part. */ + USHORT startConnectorLength; /* Advance width/ height of the straight bar + * connector material, in design units, is at + * the beginning of the glyph, in the + * direction of the extension. */ + USHORT endConnectorLength; /* Advance width/ height of the straight bar + * connector material, in design units, is at + * the end of the glyph, in the direction of + * the extension. */ + USHORT fullAdvance; /* Full advance width/height for this part, + * in the direction of the extension. + * In design units. */ + PartFlags partFlags; /* Part qualifiers. */ + + public: + DEFINE_SIZE_STATIC (10); +}; + +struct MathGlyphAssembly +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + italicsCorrection.sanitize(c, this) && + partRecords.sanitize(c)); + } + + inline unsigned int get_parts (hb_direction_t direction, + hb_font_t *font, + unsigned int start_offset, + unsigned int *parts_count, /* IN/OUT */ + hb_ot_math_glyph_part_t *parts /* OUT */, + hb_position_t *italics_correction /* OUT */) const + { + if (parts_count) + { + int scale = font->dir_scale (direction); + const MathGlyphPartRecord *arr = + partRecords.sub_array (start_offset, parts_count); + unsigned int count = *parts_count; + for (unsigned int i = 0; i < count; i++) + arr[i].extract (parts[i], scale, font); + } + + if (italics_correction) + *italics_correction = italicsCorrection.get_x_value (font, this); + + return partRecords.len; + } + + protected: + MathValueRecord italicsCorrection; /* Italics correction of this + * MathGlyphAssembly. Should not + * depend on the assembly size. */ + ArrayOf partRecords; /* Array of part records, from + * left to right and bottom to + * top. */ + + public: + DEFINE_SIZE_ARRAY (6, partRecords); +}; + +struct MathGlyphConstruction +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + glyphAssembly.sanitize(c, this) && + mathGlyphVariantRecord.sanitize(c)); + } + + inline const MathGlyphAssembly &get_assembly (void) const + { return this+glyphAssembly; } + + inline unsigned int get_variants (hb_direction_t direction, + hb_font_t *font, + unsigned int start_offset, + unsigned int *variants_count, /* IN/OUT */ + hb_ot_math_glyph_variant_t *variants /* OUT */) const + { + if (variants_count) + { + int scale = font->dir_scale (direction); + const MathGlyphVariantRecord *arr = + mathGlyphVariantRecord.sub_array (start_offset, variants_count); + unsigned int count = *variants_count; + for (unsigned int i = 0; i < count; i++) + { + variants[i].glyph = arr[i].variantGlyph; + variants[i].advance = font->em_scale (arr[i].advanceMeasurement, scale); + } + } + return mathGlyphVariantRecord.len; + } + + protected: + /* Offset to MathGlyphAssembly table for this shape - from the beginning of + MathGlyphConstruction table. May be NULL. */ + OffsetTo glyphAssembly; + + /* MathGlyphVariantRecords for alternative variants of the glyphs. */ + ArrayOf mathGlyphVariantRecord; + + public: + DEFINE_SIZE_ARRAY (4, mathGlyphVariantRecord); +}; + +struct MathVariants +{ + inline bool sanitize_offsets (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + unsigned int count = vertGlyphCount + horizGlyphCount; + for (unsigned int i = 0; i < count; i++) + if (!glyphConstruction[i].sanitize (c, this)) return_trace (false); + return_trace (true); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + vertGlyphCoverage.sanitize (c, this) && + horizGlyphCoverage.sanitize (c, this) && + c->check_array (glyphConstruction, + glyphConstruction[0].static_size, + vertGlyphCount + horizGlyphCount) && + sanitize_offsets (c)); + } + + inline hb_position_t get_min_connector_overlap (hb_direction_t direction, + hb_font_t *font) const + { return font->em_scale_dir (minConnectorOverlap, direction); } + + inline unsigned int get_glyph_variants (hb_codepoint_t glyph, + hb_direction_t direction, + hb_font_t *font, + unsigned int start_offset, + unsigned int *variants_count, /* IN/OUT */ + hb_ot_math_glyph_variant_t *variants /* OUT */) const + { return get_glyph_construction (glyph, direction, font) + .get_variants (direction, font, start_offset, variants_count, variants); } + + inline unsigned int get_glyph_parts (hb_codepoint_t glyph, + hb_direction_t direction, + hb_font_t *font, + unsigned int start_offset, + unsigned int *parts_count, /* IN/OUT */ + hb_ot_math_glyph_part_t *parts /* OUT */, + hb_position_t *italics_correction /* OUT */) const + { return get_glyph_construction (glyph, direction, font) + .get_assembly () + .get_parts (direction, font, + start_offset, parts_count, parts, + italics_correction); } + + private: + inline const MathGlyphConstruction & + get_glyph_construction (hb_codepoint_t glyph, + hb_direction_t direction, + hb_font_t *font) const + { + bool vertical = HB_DIRECTION_IS_VERTICAL (direction); + unsigned int count = vertical ? vertGlyphCount : horizGlyphCount; + const OffsetTo &coverage = vertical ? vertGlyphCoverage + : horizGlyphCoverage; + + unsigned int index = (this+coverage).get_coverage (glyph); + if (unlikely (index >= count)) return Null(MathGlyphConstruction); + + if (!vertical) + index += vertGlyphCount; + + return this+glyphConstruction[index]; + } + + protected: + USHORT minConnectorOverlap; /* Minimum overlap of connecting + * glyphs during glyph construction, + * in design units. */ + OffsetTo vertGlyphCoverage; /* Offset to Coverage table - + * from the beginning of MathVariants + * table. */ + OffsetTo horizGlyphCoverage; /* Offset to Coverage table - + * from the beginning of MathVariants + * table. */ + USHORT vertGlyphCount; /* Number of glyphs for which + * information is provided for + * vertically growing variants. */ + USHORT horizGlyphCount; /* Number of glyphs for which + * information is provided for + * horizontally growing variants. */ + + /* Array of offsets to MathGlyphConstruction tables - from the beginning of + the MathVariants table, for shapes growing in vertical/horizontal + direction. */ + OffsetTo glyphConstruction[VAR]; + + public: + DEFINE_SIZE_ARRAY (10, glyphConstruction); +}; + + +/* + * MATH -- The MATH Table + */ + +struct MATH +{ + static const hb_tag_t tableTag = HB_OT_TAG_MATH; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + likely (version.major == 1) && + mathConstants.sanitize (c, this) && + mathGlyphInfo.sanitize (c, this) && + mathVariants.sanitize (c, this)); + } + + inline hb_position_t get_constant (hb_ot_math_constant_t constant, + hb_font_t *font) const + { return (this+mathConstants).get_value (constant, font); } + + inline const MathGlyphInfo &get_math_glyph_info (void) const + { return this+mathGlyphInfo; } + + inline const MathVariants &get_math_variants (void) const + { return this+mathVariants; } + + protected: + FixedVersion<>version; /* Version of the MATH table + * initially set to 0x00010000u */ + OffsetTo mathConstants;/* MathConstants table */ + OffsetTo mathGlyphInfo;/* MathGlyphInfo table */ + OffsetTo mathVariants; /* MathVariants table */ + + public: + DEFINE_SIZE_STATIC (10); +}; + +} /* mathspace OT */ + + +#endif /* HB_OT_LAYOUT_MATH_TABLE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh index d168e27f53..a4272de631 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh @@ -49,7 +49,7 @@ hb_ot_layout_table_find_feature (hb_face_t *face, * GDEF */ -typedef enum +enum hb_ot_layout_glyph_props_flags_t { /* The following three match LookupFlags::Ignore* numbers. */ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u, @@ -64,7 +64,8 @@ typedef enum HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED -} hb_ot_layout_glyph_class_mask_t; +}; +HB_MARK_AS_FLAG_T (hb_ot_layout_glyph_props_flags_t); /* @@ -98,21 +99,20 @@ hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, const hb_ot_layout_lookup_accelerator_t &accel); -/* Should be called after all the substitute_lookup's are done */ -HB_INTERNAL void -hb_ot_layout_substitute_finish (hb_font_t *font, - hb_buffer_t *buffer); - - -/* Should be called before all the position_lookup's are done. Resets positions to zero. */ +/* Should be called before all the position_lookup's are done. */ HB_INTERNAL void hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer); -/* Should be called after all the position_lookup's are done */ +/* Should be called after all the position_lookup's are done, to finish advances. */ +HB_INTERNAL void +hb_ot_layout_position_finish_advances (hb_font_t *font, + hb_buffer_t *buffer); + +/* Should be called after hb_ot_layout_position_finish_advances, to finish offsets. */ HB_INTERNAL void -hb_ot_layout_position_finish (hb_font_t *font, - hb_buffer_t *buffer); +hb_ot_layout_position_finish_offsets (hb_font_t *font, + hb_buffer_t *buffer); @@ -124,6 +124,7 @@ namespace OT { struct GDEF; struct GSUB; struct GPOS; + struct MATH; } struct hb_ot_layout_lookup_accelerator_t @@ -152,10 +153,12 @@ struct hb_ot_layout_t hb_blob_t *gdef_blob; hb_blob_t *gsub_blob; hb_blob_t *gpos_blob; + hb_blob_t *math_blob; const struct OT::GDEF *gdef; const struct OT::GSUB *gsub; const struct OT::GPOS *gpos; + const struct OT::MATH *math; unsigned int gsub_lookup_count; unsigned int gpos_lookup_count; @@ -180,8 +183,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout); */ /* buffer var allocations, used during the entire shaping process */ -#define unicode_props0() var2.u8[0] -#define unicode_props1() var2.u8[1] +#define unicode_props() var2.u16[0] /* buffer var allocations, used during the GSUB/GPOS processing */ #define glyph_props() var1.u16[0] /* GDEF glyph properties */ @@ -214,48 +216,146 @@ _next_syllable (hb_buffer_t *buffer, unsigned int start) /* unicode_props */ -enum { - MASK0_ZWJ = 0x20u, - MASK0_ZWNJ = 0x40u, - MASK0_IGNORABLE = 0x80u, - MASK0_GEN_CAT = 0x1Fu +/* Design: + * unicode_props() is a two-byte number. The low byte includes: + * - General_Category: 5 bits. + * - A bit each for: + * * Is it Default_Ignorable(); we have a modified Default_Ignorable(). + * * Whether it's one of the three Mongolian Free Variation Selectors. + * * One free bit right now. + * + * The high-byte has different meanings, switched by the Gen-Cat: + * - For Mn,Mc,Me: the modified Combining_Class. + * - For Cf: whether it's ZWJ, ZWNJ, or something else. + * - For Ws: index of which space character this is, if space fallback + * is needed, ie. we don't set this by default, only if asked to. + */ + +enum hb_unicode_props_flags_t { + UPROPS_MASK_GEN_CAT = 0x001Fu, + UPROPS_MASK_IGNORABLE = 0x0020u, + UPROPS_MASK_FVS = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3 */ + + /* If GEN_CAT=FORMAT, top byte masks: */ + UPROPS_MASK_Cf_ZWJ = 0x0100u, + UPROPS_MASK_Cf_ZWNJ = 0x0200u }; +HB_MARK_AS_FLAG_T (hb_unicode_props_flags_t); static inline void -_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode) +_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer) { - /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */ - info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) | - (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) | - (info->codepoint == 0x200Cu ? MASK0_ZWNJ : 0) | - (info->codepoint == 0x200Du ? MASK0_ZWJ : 0); - info->unicode_props1() = unicode->modified_combining_class (info->codepoint); + hb_unicode_funcs_t *unicode = buffer->unicode; + unsigned int u = info->codepoint; + unsigned int gen_cat = (unsigned int) unicode->general_category (u); + unsigned int props = gen_cat; + + if (u >= 0x80) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII; + if (unlikely (unicode->is_default_ignorable (u))) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES; + props |= UPROPS_MASK_IGNORABLE; + if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ; + if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ; + /* Mongolian Free Variation Selectors need to be remembered + * because although we need to hide them like default-ignorables, + * they need to non-ignorable during shaping. This is similar to + * what we do for joiners in Indic-like shapers, but since the + * FVSes are GC=Mn, we have use a separate bit to remember them. + * Fixes: + * https://github.com/behdad/harfbuzz/issues/234 + */ + if (unlikely (hb_in_range (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_FVS; + } + else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat))) + { + /* The above check is just an optimization to let in only things we need further + * processing on. */ + + /* Only Mn and Mc can have non-zero ccc: + * http://www.unicode.org/policies/stability_policy.html#Property_Value + * """ + * Canonical_Combining_Class, General_Category + * All characters other than those with General_Category property values + * Spacing_Mark (Mc) and Nonspacing_Mark (Mn) have the Canonical_Combining_Class + * property value 0. + * 1.1.5+ + * """ + * + * Also, all Mn's that are Default_Ignorable, have ccc=0, hence + * the "else if". + */ + props |= unicode->modified_combining_class (info->codepoint)<<8; + + /* Recategorize emoji skin-tone modifiers as Unicode mark, so they + * behave correctly in non-native directionality. They originally + * are MODIFIER_SYMBOL. Fixes: + * https://github.com/behdad/harfbuzz/issues/169 + */ + if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu))) + { + props = gen_cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK; + } + } + } + + info->unicode_props() = props; } static inline void _hb_glyph_info_set_general_category (hb_glyph_info_t *info, hb_unicode_general_category_t gen_cat) { - info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT); + /* Clears top-byte. */ + info->unicode_props() = (unsigned int) gen_cat | (info->unicode_props() & (0xFF & ~UPROPS_MASK_GEN_CAT)); } static inline hb_unicode_general_category_t _hb_glyph_info_get_general_category (const hb_glyph_info_t *info) { - return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT); + return (hb_unicode_general_category_t) (info->unicode_props() & UPROPS_MASK_GEN_CAT); } +static inline bool +_hb_glyph_info_is_unicode_mark (const hb_glyph_info_t *info) +{ + return HB_UNICODE_GENERAL_CATEGORY_IS_MARK (info->unicode_props() & UPROPS_MASK_GEN_CAT); +} static inline void _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class) { - info->unicode_props1() = modified_class; + if (unlikely (!_hb_glyph_info_is_unicode_mark (info))) + return; + info->unicode_props() = (modified_class<<8) | (info->unicode_props() & 0xFF); } - static inline unsigned int _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) { - return info->unicode_props1(); + return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0; +} + +static inline bool +_hb_glyph_info_is_unicode_space (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_get_general_category (info) == + HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR; +} +static inline void +_hb_glyph_info_set_unicode_space_fallback_type (hb_glyph_info_t *info, hb_unicode_funcs_t::space_t s) +{ + if (unlikely (!_hb_glyph_info_is_unicode_space (info))) + return; + info->unicode_props() = (((unsigned int) s)<<8) | (info->unicode_props() & 0xFF); +} +static inline hb_unicode_funcs_t::space_t +_hb_glyph_info_get_unicode_space_fallback_type (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_is_unicode_space (info) ? + (hb_unicode_funcs_t::space_t) (info->unicode_props()>>8) : + hb_unicode_funcs_t::NOT_SPACE; } static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); @@ -263,25 +363,44 @@ static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); static inline hb_bool_t _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) { - return (info->unicode_props0() & MASK0_IGNORABLE) && !_hb_glyph_info_ligated (info); + return (info->unicode_props() & UPROPS_MASK_IGNORABLE) && + !_hb_glyph_info_ligated (info); +} +static inline hb_bool_t +_hb_glyph_info_is_default_ignorable_and_not_fvs (const hb_glyph_info_t *info) +{ + return ((info->unicode_props() & (UPROPS_MASK_IGNORABLE|UPROPS_MASK_FVS)) + == UPROPS_MASK_IGNORABLE) && + !_hb_glyph_info_ligated (info); } +static inline bool +_hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_get_general_category (info) == + HB_UNICODE_GENERAL_CATEGORY_FORMAT; +} static inline hb_bool_t _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info) { - return !!(info->unicode_props0() & MASK0_ZWNJ); + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWNJ); } - static inline hb_bool_t _hb_glyph_info_is_zwj (const hb_glyph_info_t *info) { - return !!(info->unicode_props0() & MASK0_ZWJ); + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & UPROPS_MASK_Cf_ZWJ); +} +static inline hb_bool_t +_hb_glyph_info_is_joiner (const hb_glyph_info_t *info) +{ + return _hb_glyph_info_is_unicode_format (info) && (info->unicode_props() & (UPROPS_MASK_Cf_ZWNJ|UPROPS_MASK_Cf_ZWJ)); } - static inline void _hb_glyph_info_flip_joiners (hb_glyph_info_t *info) { - info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ; + if (!_hb_glyph_info_is_unicode_format (info)) + return; + info->unicode_props() ^= UPROPS_MASK_Cf_ZWNJ | UPROPS_MASK_Cf_ZWJ; } /* lig_props: aka lig_id / lig_comp @@ -442,11 +561,9 @@ _hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info) } static inline void -_hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *info) +_hb_glyph_info_clear_substituted (hb_glyph_info_t *info) { - info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | - HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | - HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); + info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED); } @@ -455,22 +572,19 @@ _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *in static inline void _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer) { - HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0); - HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1); + HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props); } static inline void _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer) { - HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0); - HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1); + HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props); } static inline void _hb_buffer_assert_unicode_vars (hb_buffer_t *buffer) { - HB_BUFFER_ASSERT_VAR (buffer, unicode_props0); - HB_BUFFER_ASSERT_VAR (buffer, unicode_props1); + HB_BUFFER_ASSERT_VAR (buffer, unicode_props); } static inline void diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc index 275a960d58..145ec76389 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc @@ -60,6 +60,92 @@ _hb_ot_layout_create (hb_face_t *face) layout->gpos_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_GPOS)); layout->gpos = OT::Sanitizer::lock_instance (layout->gpos_blob); + /* The MATH table is rarely used, so only try and load it in _get_math. */ + layout->math_blob = NULL; + layout->math = NULL; + + { + /* + * The ugly business of blacklisting individual fonts' tables happen here! + * See this thread for why we finally had to bend in and do this: + * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html + */ + unsigned int gdef_len = hb_blob_get_length (layout->gdef_blob); + unsigned int gsub_len = hb_blob_get_length (layout->gsub_blob); + unsigned int gpos_len = hb_blob_get_length (layout->gpos_blob); + if (0 + /* sha1sum:c5ee92f0bca4bfb7d06c4d03e8cf9f9cf75d2e8a Windows 7? timesi.ttf */ + || (442 == gdef_len && 42038 == gpos_len && 2874 == gsub_len) + /* sha1sum:37fc8c16a0894ab7b749e35579856c73c840867b Windows 7? timesbi.ttf */ + || (430 == gdef_len && 40662 == gpos_len && 2874 == gsub_len) + /* sha1sum:19fc45110ea6cd3cdd0a5faca256a3797a069a80 Windows 7 timesi.ttf */ + || (442 == gdef_len && 39116 == gpos_len && 2874 == gsub_len) + /* sha1sum:6d2d3c9ed5b7de87bc84eae0df95ee5232ecde26 Windows 7 timesbi.ttf */ + || (430 == gdef_len && 39374 == gpos_len && 2874 == gsub_len) + /* sha1sum:8583225a8b49667c077b3525333f84af08c6bcd8 OS X 10.11.3 Times New Roman Italic.ttf */ + || (490 == gdef_len && 41638 == gpos_len && 3046 == gsub_len) + /* sha1sum:ec0f5a8751845355b7c3271d11f9918a966cb8c9 OS X 10.11.3 Times New Roman Bold Italic.ttf */ + || (478 == gdef_len && 41902 == gpos_len && 3046 == gsub_len) + ) + { + /* In certain versions of Times New Roman Italic and Bold Italic, + * ASCII double quotation mark U+0022, mapped to glyph 5, has wrong + * glyph class 3 (mark) in GDEF. Nuke the GDEF to avoid zero-width + * double-quote. See: + * https://lists.freedesktop.org/archives/harfbuzz/2016-February/005489.html + */ + if (3 == layout->gdef->get_glyph_class (5)) + layout->gdef = &OT::Null(OT::GDEF); + } + else if (0 + /* sha1sum:96eda93f7d33e79962451c6c39a6b51ee893ce8c tahoma.ttf from Windows 8 */ + || (898 == gdef_len && 46470 == gpos_len && 12554 == gsub_len) + /* sha1sum:20928dc06014e0cd120b6fc942d0c3b1a46ac2bc tahomabd.ttf from Windows 8 */ + || (910 == gdef_len && 47732 == gpos_len && 12566 == gsub_len) + /* sha1sum:4f95b7e4878f60fa3a39ca269618dfde9721a79e tahoma.ttf from Windows 8.1 */ + || (928 == gdef_len && 59332 == gpos_len && 23298 == gsub_len) + /* sha1sum:6d400781948517c3c0441ba42acb309584b73033 tahomabd.ttf from Windows 8.1 */ + || (940 == gdef_len && 60732 == gpos_len && 23310 == gsub_len) + /* sha1sum:e55fa2dfe957a9f7ec26be516a0e30b0c925f846 tahoma.ttf from Windows 10 */ + || (994 == gdef_len && 60336 == gpos_len && 24474 == gsub_len) + /* sha1sum:7199385abb4c2cc81c83a151a7599b6368e92343 tahomabd.ttf from Windows 10 */ + || (1006 == gdef_len && 61740 == gpos_len && 24470 == gsub_len) + /* sha1sum:b0d36cf5a2fbe746a3dd277bffc6756a820807a7 Tahoma.ttf from Mac OS X 10.9 */ + || (832 == gdef_len && 47162 == gpos_len && 7324 == gsub_len) + /* sha1sum:12fc4538e84d461771b30c18b5eb6bd434e30fba Tahoma Bold.ttf from Mac OS X 10.9 */ + || (844 == gdef_len && 45474 == gpos_len && 7302 == gsub_len) + /* sha1sum:73da7f025b238a3f737aa1fde22577a6370f77b0 himalaya.ttf from Windows 8 */ + || (192 == gdef_len && 7254 == gpos_len && 12638 == gsub_len) + /* sha1sum:6e80fd1c0b059bbee49272401583160dc1e6a427 himalaya.ttf from Windows 8.1 */ + || (192 == gdef_len && 7254 == gpos_len && 12690 == gsub_len) + /* 8d9267aea9cd2c852ecfb9f12a6e834bfaeafe44 cantarell-fonts-0.0.21/otf/Cantarell-Regular.otf */ + /* 983988ff7b47439ab79aeaf9a45bd4a2c5b9d371 cantarell-fonts-0.0.21/otf/Cantarell-Oblique.otf */ + || (188 == gdef_len && 3852 == gpos_len && 248 == gsub_len) + /* 2c0c90c6f6087ffbfea76589c93113a9cbb0e75f cantarell-fonts-0.0.21/otf/Cantarell-Bold.otf */ + /* 55461f5b853c6da88069ffcdf7f4dd3f8d7e3e6b cantarell-fonts-0.0.21/otf/Cantarell-Bold-Oblique.otf */ + || (188 == gdef_len && 3426 == gpos_len && 264 == gsub_len) + /* 6c93b63b64e8b2c93f5e824e78caca555dc887c7 padauk-2.80/Padauk-book.ttf */ + || (1046 == gdef_len && 17112 == gpos_len && 71788 == gsub_len) + /* d89b1664058359b8ec82e35d3531931125991fb9 padauk-2.80/Padauk-bookbold.ttf */ + || (1058 == gdef_len && 17514 == gpos_len && 71794 == gsub_len) + /* 824cfd193aaf6234b2b4dc0cf3c6ef576c0d00ef padauk-3.0/Padauk-book.ttf */ + || (1330 == gdef_len && 57938 == gpos_len && 109904 == gsub_len) + /* 91fcc10cf15e012d27571e075b3b4dfe31754a8a padauk-3.0/Padauk-bookbold.ttf */ + || (1330 == gdef_len && 58972 == gpos_len && 109904 == gsub_len) + ) + { + /* Many versions of Tahoma have bad GDEF tables that incorrectly classify some spacing marks + * such as certain IPA symbols as glyph class 3. So do older versions of Microsoft Himalaya, + * and the version of Cantarell shipped by Ubuntu 16.04. + * Nuke the GDEF tables of these fonts to avoid unwanted width-zeroing. + * See https://bugzilla.mozilla.org/show_bug.cgi?id=1279925 + * https://bugzilla.mozilla.org/show_bug.cgi?id=1279693 + * https://bugzilla.mozilla.org/show_bug.cgi?id=1279875 + */ + layout->gdef = &OT::Null(OT::GDEF); + } + } + layout->gsub_lookup_count = layout->gsub->get_lookup_count (); layout->gpos_lookup_count = layout->gpos->get_lookup_count (); @@ -95,6 +181,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) hb_blob_destroy (layout->gdef_blob); hb_blob_destroy (layout->gsub_blob); hb_blob_destroy (layout->gpos_blob); + hb_blob_destroy (layout->math_blob); free (layout); } @@ -118,7 +205,6 @@ _get_gpos (hb_face_t *face) return *hb_ot_layout_from_face (face)->gpos; } - /* * GDEF */ @@ -130,6 +216,8 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face) } /** + * hb_ot_layout_get_glyph_class: + * * Since: 0.9.7 **/ hb_ot_layout_glyph_class_t @@ -140,6 +228,8 @@ hb_ot_layout_get_glyph_class (hb_face_t *face, } /** + * hb_ot_layout_get_glyphs_in_class: + * * Since: 0.9.7 **/ void @@ -365,6 +455,8 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, } /** + * hb_ot_layout_language_get_required_feature: + * * Since: 0.9.30 **/ hb_bool_t @@ -452,6 +544,8 @@ hb_ot_layout_language_find_feature (hb_face_t *face, } /** + * hb_ot_layout_feature_get_lookups: + * * Since: 0.9.7 **/ unsigned int @@ -462,13 +556,18 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, unsigned int *lookup_count /* IN/OUT */, unsigned int *lookup_indexes /* OUT */) { - const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); - const OT::Feature &f = g.get_feature (feature_index); - - return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); + return hb_ot_layout_feature_with_variations_get_lookups (face, + table_tag, + feature_index, + HB_OT_LAYOUT_NO_VARIATIONS_INDEX, + start_offset, + lookup_count, + lookup_indexes); } /** + * hb_ot_layout_table_get_lookup_count: + * * Since: 0.9.22 **/ unsigned int @@ -629,6 +728,8 @@ _hb_ot_layout_collect_lookups_languages (hb_face_t *face, } /** + * hb_ot_layout_collect_lookups: + * * Since: 0.9.8 **/ void @@ -673,6 +774,8 @@ hb_ot_layout_collect_lookups (hb_face_t *face, } /** + * hb_ot_layout_lookup_collect_glyphs: + * * Since: 0.9.7 **/ void @@ -710,6 +813,38 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, } +/* Variations support */ + +hb_bool_t +hb_ot_layout_table_find_feature_variations (hb_face_t *face, + hb_tag_t table_tag, + const int *coords, + unsigned int num_coords, + unsigned int *variations_index /* out */) +{ + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + return g.find_variations_index (coords, num_coords, variations_index); +} + +unsigned int +hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + unsigned int variations_index, + unsigned int start_offset, + unsigned int *lookup_count /* IN/OUT */, + unsigned int *lookup_indexes /* OUT */) +{ + ASSERT_STATIC (OT::FeatureVariations::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_VARIATIONS_INDEX); + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + const OT::Feature &f = g.get_feature_variation (feature_index, variations_index); + + return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); +} + + /* * OT::GSUB */ @@ -721,6 +856,8 @@ hb_ot_layout_has_substitution (hb_face_t *face) } /** + * hb_ot_layout_lookup_would_substitute: + * * Since: 0.9.7 **/ hb_bool_t @@ -742,7 +879,7 @@ hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, hb_bool_t zero_context) { if (unlikely (lookup_index >= hb_ot_layout_from_face (face)->gsub_lookup_count)) return false; - OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, zero_context); + OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context); const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); @@ -755,13 +892,9 @@ hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) OT::GSUB::substitute_start (font, buffer); } -void -hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) -{ - OT::GSUB::substitute_finish (font, buffer); -} - /** + * hb_ot_layout_lookup_substitute_closure: + * * Since: 0.9.7 **/ void @@ -793,12 +926,20 @@ hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) } void -hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) +hb_ot_layout_position_finish_advances (hb_font_t *font, hb_buffer_t *buffer) +{ + OT::GPOS::position_finish_advances (font, buffer); +} + +void +hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) { - OT::GPOS::position_finish (font, buffer); + OT::GPOS::position_finish_offsets (font, buffer); } /** + * hb_ot_layout_get_size_params: + * * Since: 0.9.10 **/ hb_bool_t @@ -882,20 +1023,79 @@ struct GPOSProxy }; -template +struct hb_get_subtables_context_t : + OT::hb_dispatch_context_t +{ + template + static inline bool apply_to (const void *obj, OT::hb_apply_context_t *c) + { + const Type *typed_obj = (const Type *) obj; + return typed_obj->apply (c); + } + + typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_apply_context_t *c); + + struct hb_applicable_t + { + inline void init (const void *obj_, hb_apply_func_t apply_func_) + { + obj = obj_; + apply_func = apply_func_; + } + + inline bool apply (OT::hb_apply_context_t *c) const { return apply_func (obj, c); } + + private: + const void *obj; + hb_apply_func_t apply_func; + }; + + typedef hb_auto_array_t array_t; + + /* Dispatch interface. */ + inline const char *get_name (void) { return "GET_SUBTABLES"; } + template + inline return_t dispatch (const T &obj) + { + hb_applicable_t *entry = array.push(); + if (likely (entry)) + entry->init (&obj, apply_to); + return HB_VOID; + } + static return_t default_return_value (void) { return HB_VOID; } + bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return false; } + + hb_get_subtables_context_t (array_t &array_) : + array (array_), + debug_depth (0) {} + + array_t &array; + unsigned int debug_depth; +}; + static inline bool apply_forward (OT::hb_apply_context_t *c, - const Obj &obj, - const hb_ot_layout_lookup_accelerator_t &accel) + const hb_ot_layout_lookup_accelerator_t &accel, + const hb_get_subtables_context_t::array_t &subtables) { bool ret = false; hb_buffer_t *buffer = c->buffer; - while (buffer->idx < buffer->len) + while (buffer->idx < buffer->len && !buffer->in_error) { + bool applied = false; if (accel.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props) && - obj.apply (c)) + c->check_glyph_property (&buffer->cur(), c->lookup_props)) + { + for (unsigned int i = 0; i < subtables.len; i++) + if (subtables[i].apply (c)) + { + applied = true; + break; + } + } + + if (applied) ret = true; else buffer->next_glyph (); @@ -903,11 +1103,10 @@ apply_forward (OT::hb_apply_context_t *c, return ret; } -template static inline bool apply_backward (OT::hb_apply_context_t *c, - const Obj &obj, - const hb_ot_layout_lookup_accelerator_t &accel) + const hb_ot_layout_lookup_accelerator_t &accel, + const hb_get_subtables_context_t::array_t &subtables) { bool ret = false; hb_buffer_t *buffer = c->buffer; @@ -915,9 +1114,15 @@ apply_backward (OT::hb_apply_context_t *c, { if (accel.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && - c->check_glyph_property (&buffer->cur(), c->lookup_props) && - obj.apply (c)) - ret = true; + c->check_glyph_property (&buffer->cur(), c->lookup_props)) + { + for (unsigned int i = 0; i < subtables.len; i++) + if (subtables[i].apply (c)) + { + ret = true; + break; + } + } /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; @@ -926,26 +1131,6 @@ apply_backward (OT::hb_apply_context_t *c, return ret; } -struct hb_apply_forward_context_t : - OT::hb_dispatch_context_t -{ - inline const char *get_name (void) { return "APPLY_FWD"; } - template - inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel); } - static return_t default_return_value (void) { return false; } - bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return true; } - - hb_apply_forward_context_t (OT::hb_apply_context_t *c_, - const hb_ot_layout_lookup_accelerator_t &accel_) : - c (c_), - accel (accel_), - debug_depth (0) {} - - OT::hb_apply_context_t *c; - const hb_ot_layout_lookup_accelerator_t &accel; - unsigned int debug_depth; -}; - template static inline void apply_string (OT::hb_apply_context_t *c, @@ -959,6 +1144,10 @@ apply_string (OT::hb_apply_context_t *c, c->set_lookup_props (lookup.get_props ()); + hb_get_subtables_context_t::array_t subtables; + hb_get_subtables_context_t c_get_subtables (subtables); + lookup.dispatch (&c_get_subtables); + if (likely (!lookup.is_reverse ())) { /* in/out forward substitution/positioning */ @@ -967,13 +1156,7 @@ apply_string (OT::hb_apply_context_t *c, buffer->idx = 0; bool ret; - if (lookup.get_subtable_count () == 1) - { - hb_apply_forward_context_t c_forward (c, accel); - ret = lookup.dispatch (&c_forward); - } - else - ret = apply_forward (c, lookup, accel); + ret = apply_forward (c, accel, subtables); if (ret) { if (!Proxy::inplace) @@ -989,7 +1172,7 @@ apply_string (OT::hb_apply_context_t *c, buffer->remove_output (); buffer->idx = buffer->len - 1; - apply_backward (c, lookup, accel); + apply_backward (c, accel, subtables); } } @@ -1008,25 +1191,15 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, const stage_map_t *stage = &stages[table_index][stage_index]; for (; i < stage->last_lookup; i++) { -#if 0 - char buf[4096]; - hb_buffer_serialize_glyphs (buffer, 0, buffer->len, - buf, sizeof (buf), NULL, - font, - HB_BUFFER_SERIALIZE_FORMAT_TEXT, - Proxy::table_index == 0 ? - HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS : - HB_BUFFER_SERIALIZE_FLAG_DEFAULT); - printf ("buf: [%s]\n", buf); -#endif - unsigned int lookup_index = lookups[table_index][i].index; + if (!buffer->message (font, "start lookup %d", lookup_index)) continue; c.set_lookup_index (lookup_index); c.set_lookup_mask (lookups[table_index][i].mask); c.set_auto_zwj (lookups[table_index][i].auto_zwj); apply_string (&c, proxy.table.get_lookup (lookup_index), proxy.accels[lookup_index]); + (void) buffer->message (font, "end lookup %d", lookup_index); } if (stage->pause_func) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h index 949678ac42..9861f0fc7b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h @@ -48,7 +48,7 @@ HB_BEGIN_DECLS * GDEF */ -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_has_glyph_classes (hb_face_t *face); typedef enum { @@ -59,11 +59,11 @@ typedef enum { HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 4 } hb_ot_layout_glyph_class_t; -hb_ot_layout_glyph_class_t +HB_EXTERN hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_face_t *face, hb_codepoint_t glyph); -void +HB_EXTERN void hb_ot_layout_get_glyphs_in_class (hb_face_t *face, hb_ot_layout_glyph_class_t klass, hb_set_t *glyphs /* OUT */); @@ -71,7 +71,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, /* Not that useful. Provides list of attach points for a glyph that a * client may want to cache */ -unsigned int +HB_EXTERN unsigned int hb_ot_layout_get_attach_points (hb_face_t *face, hb_codepoint_t glyph, unsigned int start_offset, @@ -79,7 +79,7 @@ hb_ot_layout_get_attach_points (hb_face_t *face, unsigned int *point_array /* OUT */); /* Ligature caret positions */ -unsigned int +HB_EXTERN unsigned int hb_ot_layout_get_ligature_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph, @@ -95,36 +95,37 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, #define HB_OT_LAYOUT_NO_SCRIPT_INDEX 0xFFFFu #define HB_OT_LAYOUT_NO_FEATURE_INDEX 0xFFFFu #define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX 0xFFFFu +#define HB_OT_LAYOUT_NO_VARIATIONS_INDEX 0xFFFFFFFFu -unsigned int +HB_EXTERN unsigned int hb_ot_layout_table_get_script_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int start_offset, unsigned int *script_count /* IN/OUT */, hb_tag_t *script_tags /* OUT */); -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_table_find_script (hb_face_t *face, hb_tag_t table_tag, hb_tag_t script_tag, unsigned int *script_index); /* Like find_script, but takes zero-terminated array of scripts to test */ -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_table_choose_script (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *script_tags, unsigned int *script_index, hb_tag_t *chosen_script); -unsigned int +HB_EXTERN unsigned int hb_ot_layout_table_get_feature_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, hb_tag_t *feature_tags /* OUT */); -unsigned int +HB_EXTERN unsigned int hb_ot_layout_script_get_language_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, @@ -132,21 +133,21 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, unsigned int *language_count /* IN/OUT */, hb_tag_t *language_tags /* OUT */); -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_script_find_language (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, hb_tag_t language_tag, unsigned int *language_index); -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_language_get_required_feature_index (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, unsigned int language_index, unsigned int *feature_index); -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_language_get_required_feature (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, @@ -154,7 +155,7 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face, unsigned int *feature_index, hb_tag_t *feature_tag); -unsigned int +HB_EXTERN unsigned int hb_ot_layout_language_get_feature_indexes (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, @@ -163,7 +164,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face, unsigned int *feature_count /* IN/OUT */, unsigned int *feature_indexes /* OUT */); -unsigned int +HB_EXTERN unsigned int hb_ot_layout_language_get_feature_tags (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, @@ -172,7 +173,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, unsigned int *feature_count /* IN/OUT */, hb_tag_t *feature_tags /* OUT */); -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_language_find_feature (hb_face_t *face, hb_tag_t table_tag, unsigned int script_index, @@ -180,7 +181,7 @@ hb_ot_layout_language_find_feature (hb_face_t *face, hb_tag_t feature_tag, unsigned int *feature_index); -unsigned int +HB_EXTERN unsigned int hb_ot_layout_feature_get_lookups (hb_face_t *face, hb_tag_t table_tag, unsigned int feature_index, @@ -188,12 +189,12 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, unsigned int *lookup_count /* IN/OUT */, unsigned int *lookup_indexes /* OUT */); -unsigned int +HB_EXTERN unsigned int hb_ot_layout_table_get_lookup_count (hb_face_t *face, hb_tag_t table_tag); -void +HB_EXTERN void hb_ot_layout_collect_lookups (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *scripts, @@ -201,7 +202,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */); -void +HB_EXTERN void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, unsigned int lookup_index, @@ -228,7 +229,7 @@ typedef hb_bool_t const hb_ot_layout_glyph_sequence_t *sequence, void *user_data); -void +HB_EXTERN void Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face, hb_tag_t table_tag, unsigned int lookup_index, @@ -236,22 +237,40 @@ Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face, void *user_data); #endif +/* Variations support */ + +HB_EXTERN hb_bool_t +hb_ot_layout_table_find_feature_variations (hb_face_t *face, + hb_tag_t table_tag, + const int *coords, + unsigned int num_coords, + unsigned int *variations_index /* out */); + +HB_EXTERN unsigned int +hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, + hb_tag_t table_tag, + unsigned int feature_index, + unsigned int variations_index, + unsigned int start_offset, + unsigned int *lookup_count /* IN/OUT */, + unsigned int *lookup_indexes /* OUT */); + /* * GSUB */ -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_has_substitution (hb_face_t *face); -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int lookup_index, const hb_codepoint_t *glyphs, unsigned int glyphs_length, hb_bool_t zero_context); -void +HB_EXTERN void hb_ot_layout_lookup_substitute_closure (hb_face_t *face, unsigned int lookup_index, hb_set_t *glyphs @@ -259,7 +278,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, #ifdef HB_NOT_IMPLEMENTED /* Note: You better have GDEF when using this API, or marks won't do much. */ -hb_bool_t +HB_EXTERN hb_bool_t Xhb_ot_layout_lookup_substitute (hb_font_t *font, unsigned int lookup_index, const hb_ot_layout_glyph_sequence_t *sequence, @@ -274,12 +293,12 @@ Xhb_ot_layout_lookup_substitute (hb_font_t *font, * GPOS */ -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_has_positioning (hb_face_t *face); #ifdef HB_NOT_IMPLEMENTED /* Note: You better have GDEF when using this API, or marks won't do much. */ -hb_bool_t +HB_EXTERN hb_bool_t Xhb_ot_layout_lookup_position (hb_font_t *font, unsigned int lookup_index, const hb_ot_layout_glyph_sequence_t *sequence, @@ -288,7 +307,7 @@ Xhb_ot_layout_lookup_position (hb_font_t *font, /* Optical 'size' feature info. Returns true if found. * http://www.microsoft.com/typography/otspec/features_pt.htm#size */ -hb_bool_t +HB_EXTERN hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *design_size, /* OUT. May be NULL */ unsigned int *subfamily_id, /* OUT. May be NULL */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh index f9538af183..0395c9c22f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh @@ -139,12 +139,6 @@ struct hb_ot_map_t private: - HB_INTERNAL void add_lookups (hb_face_t *face, - unsigned int table_index, - unsigned int feature_index, - hb_mask_t mask, - bool auto_zwj); - hb_mask_t global_mask; hb_prealloced_array_t features; @@ -159,23 +153,9 @@ enum hb_ot_map_feature_flags_t { F_MANUAL_ZWJ = 0x0004u, /* Don't skip over ZWJ when matching. */ F_GLOBAL_SEARCH = 0x0008u /* If feature not found in LangSys, look for it in global feature list and pick one. */ }; +HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t); /* Macro version for where const is desired. */ #define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r))) -static inline hb_ot_map_feature_flags_t -operator | (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r) -{ return hb_ot_map_feature_flags_t ((unsigned int) l | (unsigned int) r); } -static inline hb_ot_map_feature_flags_t -operator & (hb_ot_map_feature_flags_t l, hb_ot_map_feature_flags_t r) -{ return hb_ot_map_feature_flags_t ((unsigned int) l & (unsigned int) r); } -static inline hb_ot_map_feature_flags_t -operator ~ (hb_ot_map_feature_flags_t r) -{ return hb_ot_map_feature_flags_t (~(unsigned int) r); } -static inline hb_ot_map_feature_flags_t& -operator |= (hb_ot_map_feature_flags_t &l, hb_ot_map_feature_flags_t r) -{ l = l | r; return l; } -static inline hb_ot_map_feature_flags_t& -operator &= (hb_ot_map_feature_flags_t& l, hb_ot_map_feature_flags_t r) -{ l = l & r; return l; } struct hb_ot_map_builder_t @@ -196,7 +176,9 @@ struct hb_ot_map_builder_t inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func) { add_pause (1, pause_func); } - HB_INTERNAL void compile (struct hb_ot_map_t &m); + HB_INTERNAL void compile (hb_ot_map_t &m, + const int *coords, + unsigned int num_coords); inline void finish (void) { feature_infos.finish (); @@ -208,6 +190,14 @@ struct hb_ot_map_builder_t private: + HB_INTERNAL void add_lookups (hb_ot_map_t &m, + hb_face_t *face, + unsigned int table_index, + unsigned int feature_index, + unsigned int variations_index, + hb_mask_t mask, + bool auto_zwj); + struct feature_info_t { hb_tag_t tag; unsigned int seq; /* sequence#, used for stable sorting only */ @@ -217,7 +207,8 @@ struct hb_ot_map_builder_t unsigned int stage[2]; /* GSUB/GPOS */ static int cmp (const feature_info_t *a, const feature_info_t *b) - { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : (a->seq < b->seq ? -1 : 1); } + { return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) : + (a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); } }; struct stage_info_t { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc index 95bd04ee8e..9b331d5210 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc @@ -31,44 +31,13 @@ #include "hb-ot-layout-private.hh" -void -hb_ot_map_t::add_lookups (hb_face_t *face, - unsigned int table_index, - unsigned int feature_index, - hb_mask_t mask, - bool auto_zwj) +void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const { - unsigned int lookup_indices[32]; - unsigned int offset, len; - unsigned int table_lookup_count; - - table_lookup_count = hb_ot_layout_table_get_lookup_count (face, table_tags[table_index]); - - offset = 0; - do { - len = ARRAY_LENGTH (lookup_indices); - hb_ot_layout_feature_get_lookups (face, - table_tags[table_index], - feature_index, - offset, &len, - lookup_indices); - - for (unsigned int i = 0; i < len; i++) - { - if (lookup_indices[i] >= table_lookup_count) - continue; - hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push (); - if (unlikely (!lookup)) - return; - lookup->mask = mask; - lookup->index = lookup_indices[i]; - lookup->auto_zwj = auto_zwj; - } - - offset += len; - } while (len == ARRAY_LENGTH (lookup_indices)); + for (unsigned int i = 0; i < lookups[table_index].len; i++) + hb_set_add (lookups_out, lookups[table_index][i].index); } + hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, const hb_segment_properties_t *props_) { @@ -89,7 +58,7 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, for (unsigned int table_index = 0; table_index < 2; table_index++) { hb_tag_t table_tag = table_tags[table_index]; - found_script[table_index] = hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]); + found_script[table_index] = (bool) hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]); hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]); } } @@ -109,13 +78,48 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, info->stage[1] = current_stage[1]; } - -void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const +void +hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, + hb_face_t *face, + unsigned int table_index, + unsigned int feature_index, + unsigned int variations_index, + hb_mask_t mask, + bool auto_zwj) { - for (unsigned int i = 0; i < lookups[table_index].len; i++) - hb_set_add (lookups_out, lookups[table_index][i].index); + unsigned int lookup_indices[32]; + unsigned int offset, len; + unsigned int table_lookup_count; + + table_lookup_count = hb_ot_layout_table_get_lookup_count (face, table_tags[table_index]); + + offset = 0; + do { + len = ARRAY_LENGTH (lookup_indices); + hb_ot_layout_feature_with_variations_get_lookups (face, + table_tags[table_index], + feature_index, + variations_index, + offset, &len, + lookup_indices); + + for (unsigned int i = 0; i < len; i++) + { + if (lookup_indices[i] >= table_lookup_count) + continue; + hb_ot_map_t::lookup_map_t *lookup = m.lookups[table_index].push (); + if (unlikely (!lookup)) + return; + lookup->mask = mask; + lookup->index = lookup_indices[i]; + lookup->auto_zwj = auto_zwj; + } + + offset += len; + } while (len == ARRAY_LENGTH (lookup_indices)); } + void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func) { stage_info_t *s = stages[table_index].push (); @@ -128,7 +132,9 @@ void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::paus } void -hb_ot_map_builder_t::compile (hb_ot_map_t &m) +hb_ot_map_builder_t::compile (hb_ot_map_t &m, + const int *coords, + unsigned int num_coords) { m.global_mask = 1; @@ -193,7 +199,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) /* Uses the global bit */ bits_needed = 0; else - bits_needed = _hb_bit_storage (info->max_value); + /* Limit to 8 bits per feature. */ + bits_needed = MIN(8u, _hb_bit_storage (info->max_value)); if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t)) continue; /* Feature disabled, or not enough bits. */ @@ -204,11 +211,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) for (unsigned int table_index = 0; table_index < 2; table_index++) { if (required_feature_tag[table_index] == info->tag) - { required_feature_stage[table_index] = info->stage[table_index]; - found = true; - continue; - } + found |= hb_ot_layout_language_find_feature (face, table_tags[table_index], script_index[table_index], @@ -246,11 +250,11 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) map->mask = 1; } else { map->shift = next_bit; - map->mask = (1 << (next_bit + bits_needed)) - (1 << next_bit); + map->mask = (1u << (next_bit + bits_needed)) - (1u << next_bit); next_bit += bits_needed; m.global_mask |= (info->default_value << map->shift) & map->mask; } - map->_1_mask = (1 << map->shift) & map->mask; + map->_1_mask = (1u << map->shift) & map->mask; map->needs_fallback = !found; } @@ -264,23 +268,32 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) { /* Collect lookup indices for features */ + unsigned int variations_index; + hb_ot_layout_table_find_feature_variations (face, + table_tags[table_index], + coords, + num_coords, + &variations_index); + unsigned int stage_index = 0; unsigned int last_num_lookups = 0; for (unsigned stage = 0; stage < current_stage[table_index]; stage++) { if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX && required_feature_stage[table_index] == stage) - m.add_lookups (face, table_index, - required_feature_index[table_index], - 1 /* mask */, - true /* auto_zwj */); + add_lookups (m, face, table_index, + required_feature_index[table_index], + variations_index, + 1 /* mask */, + true /* auto_zwj */); for (unsigned i = 0; i < m.features.len; i++) if (m.features[i].stage[table_index] == stage) - m.add_lookups (face, table_index, - m.features[i].index[table_index], - m.features[i].mask, - m.features[i].auto_zwj); + add_lookups (m, face, table_index, + m.features[i].index[table_index], + variations_index, + m.features[i].mask, + m.features[i].auto_zwj); /* Sort lookups and merge duplicates */ if (last_num_lookups < m.lookups[table_index].len) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc new file mode 100644 index 0000000000..9ef21d2995 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc @@ -0,0 +1,272 @@ +/* + * Copyright © 2016 Igalia S.L. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Igalia Author(s): Frédéric Wang + */ + +#include "hb-open-type-private.hh" + +#include "hb-ot-layout-math-table.hh" + +HB_SHAPER_DATA_ENSURE_DECLARE(ot, face) + +static inline const OT::MATH& +_get_math (hb_face_t *face) +{ + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::MATH); + + hb_ot_layout_t * layout = hb_ot_layout_from_face (face); + +retry: + const OT::MATH *math = (const OT::MATH *) hb_atomic_ptr_get (&layout->math); + + if (unlikely (!math)) + { + hb_blob_t *blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_MATH)); + math = OT::Sanitizer::lock_instance (blob); + if (!hb_atomic_ptr_cmpexch (&layout->math, NULL, math)) + { + hb_blob_destroy (blob); + goto retry; + } + layout->math_blob = blob; + } + + return *math; +} + +/* + * OT::MATH + */ + +/** + * hb_ot_math_has_data: + * @face: #hb_face_t to test + * + * This function allows to verify the presence of an OpenType MATH table on the + * face. If so, such a table will be loaded into memory and sanitized. You can + * then safely call other functions for math layout and shaping. + * + * Return value: #TRUE if face has a MATH table and #FALSE otherwise + * + * Since: 1.3.3 + **/ +hb_bool_t +hb_ot_math_has_data (hb_face_t *face) +{ + return &_get_math (face) != &OT::Null(OT::MATH); +} + +/** + * hb_ot_math_get_constant: + * @font: #hb_font_t from which to retrieve the value + * @constant: #hb_ot_math_constant_t the constant to retrieve + * + * This function returns the requested math constants as a #hb_position_t. + * If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, + * HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or + * HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is + * actually an integer between 0 and 100 representing that percentage. + * + * Return value: the requested constant or 0 + * + * Since: 1.3.3 + **/ +hb_position_t +hb_ot_math_get_constant (hb_font_t *font, + hb_ot_math_constant_t constant) +{ + const OT::MATH &math = _get_math (font->face); + return math.get_constant(constant, font); +} + +/** + * hb_ot_math_get_glyph_italics_correction: + * @font: #hb_font_t from which to retrieve the value + * @glyph: glyph index from which to retrieve the value + * + * Return value: the italics correction of the glyph or 0 + * + * Since: 1.3.3 + **/ +hb_position_t +hb_ot_math_get_glyph_italics_correction (hb_font_t *font, + hb_codepoint_t glyph) +{ + const OT::MATH &math = _get_math (font->face); + return math.get_math_glyph_info().get_italics_correction (glyph, font); +} + +/** + * hb_ot_math_get_glyph_top_accent_attachment: + * @font: #hb_font_t from which to retrieve the value + * @glyph: glyph index from which to retrieve the value + * + * Return value: the top accent attachment of the glyph or 0 + * + * Since: 1.3.3 + **/ +hb_position_t +hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, + hb_codepoint_t glyph) +{ + const OT::MATH &math = _get_math (font->face); + return math.get_math_glyph_info().get_top_accent_attachment (glyph, font); +} + +/** + * hb_ot_math_is_glyph_extended_shape: + * @font: a #hb_font_t to test + * @glyph: a glyph index to test + * + * Return value: #TRUE if the glyph is an extended shape and #FALSE otherwise + * + * Since: 1.3.3 + **/ +hb_bool_t +hb_ot_math_is_glyph_extended_shape (hb_face_t *face, + hb_codepoint_t glyph) +{ + const OT::MATH &math = _get_math (face); + return math.get_math_glyph_info().is_extended_shape (glyph); +} + +/** + * hb_ot_math_get_glyph_kerning: + * @font: #hb_font_t from which to retrieve the value + * @glyph: glyph index from which to retrieve the value + * @kern: the #hb_ot_math_kern_t from which to retrieve the value + * @correction_height: the correction height to use to determine the kerning. + * + * This function tries to retrieve the MathKern table for the specified font, + * glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the + * MathKern table to find one value that is greater or equal to specified + * correction_height. If one is found the corresponding value from the list of + * kerns is returned and otherwise the last kern value is returned. + * + * Return value: requested kerning or 0 + * + * Since: 1.3.3 + **/ +hb_position_t +hb_ot_math_get_glyph_kerning (hb_font_t *font, + hb_codepoint_t glyph, + hb_ot_math_kern_t kern, + hb_position_t correction_height) +{ + const OT::MATH &math = _get_math (font->face); + return math.get_math_glyph_info().get_kerning (glyph, kern, correction_height, font); +} + +/** + * hb_ot_math_get_glyph_variants: + * @font: #hb_font_t from which to retrieve the values + * @glyph: index of the glyph to stretch + * @direction: direction of the stretching + * @start_offset: offset of the first variant to retrieve + * @variants_count: maximum number of variants to retrieve after start_offset + * (IN) and actual number of variants retrieved (OUT) + * @variants: array of size at least @variants_count to store the result + * + * This function tries to retrieve the MathGlyphConstruction for the specified + * font, glyph and direction. Note that only the value of + * #HB_DIRECTION_IS_HORIZONTAL is considered. It provides the corresponding list + * of size variants as an array of hb_ot_math_glyph_variant_t structs. + * + * Return value: the total number of size variants available or 0 + * + * Since: 1.3.3 + **/ +unsigned int +hb_ot_math_get_glyph_variants (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, + unsigned int start_offset, + unsigned int *variants_count, /* IN/OUT */ + hb_ot_math_glyph_variant_t *variants /* OUT */) +{ + const OT::MATH &math = _get_math (font->face); + return math.get_math_variants().get_glyph_variants (glyph, direction, font, + start_offset, + variants_count, + variants); +} + +/** + * hb_ot_math_get_min_connector_overlap: + * @font: #hb_font_t from which to retrieve the value + * @direction: direction of the stretching + * + * This function tries to retrieve the MathVariants table for the specified + * font and returns the minimum overlap of connecting glyphs to draw a glyph + * assembly in the specified direction. Note that only the value of + * #HB_DIRECTION_IS_HORIZONTAL is considered. + * + * Return value: requested min connector overlap or 0 + * + * Since: 1.3.3 + **/ +hb_position_t +hb_ot_math_get_min_connector_overlap (hb_font_t *font, + hb_direction_t direction) +{ + const OT::MATH &math = _get_math (font->face); + return math.get_math_variants().get_min_connector_overlap (direction, font); +} + +/** + * hb_ot_math_get_glyph_assembly: + * @font: #hb_font_t from which to retrieve the values + * @glyph: index of the glyph to stretch + * @direction: direction of the stretching + * @start_offset: offset of the first glyph part to retrieve + * @parts_count: maximum number of glyph parts to retrieve after start_offset + * (IN) and actual number of parts retrieved (OUT) + * @parts: array of size at least @parts_count to store the result + * @italics_correction: italic correction of the glyph assembly + * + * This function tries to retrieve the GlyphAssembly for the specified font, + * glyph and direction. Note that only the value of #HB_DIRECTION_IS_HORIZONTAL + * is considered. It provides the information necessary to draw the glyph + * assembly as an array of #hb_ot_math_glyph_part_t. + * + * Return value: the total number of parts in the glyph assembly + * + * Since: 1.3.3 + **/ +unsigned int +hb_ot_math_get_glyph_assembly (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, + unsigned int start_offset, + unsigned int *parts_count, /* IN/OUT */ + hb_ot_math_glyph_part_t *parts, /* OUT */ + hb_position_t *italics_correction /* OUT */) +{ + const OT::MATH &math = _get_math (font->face); + return math.get_math_variants().get_glyph_parts (glyph, direction, font, + start_offset, + parts_count, + parts, + italics_correction); +} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h new file mode 100644 index 0000000000..521a5ca037 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.h @@ -0,0 +1,209 @@ +/* + * Copyright © 2016 Igalia S.L. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Igalia Author(s): Frédéric Wang + */ + +#ifndef HB_OT_H_IN +#error "Include instead." +#endif + +#ifndef HB_OT_MATH_H +#define HB_OT_MATH_H + +#include "hb.h" + +HB_BEGIN_DECLS + + +/* + * MATH + */ + +#define HB_OT_TAG_MATH HB_TAG('M','A','T','H') + +/* Use with hb_buffer_set_script() for math shaping. */ +#define HB_OT_MATH_SCRIPT HB_TAG('m','a','t','h') + +/* Types */ + +/** + * hb_ot_math_constant_t: + * + * Since: 1.3.3 + */ +typedef enum { + HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN = 0, + HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN = 1, + HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT = 2, + HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT = 3, + HB_OT_MATH_CONSTANT_MATH_LEADING = 4, + HB_OT_MATH_CONSTANT_AXIS_HEIGHT = 5, + HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT = 6, + HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT = 7, + HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN = 8, + HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX = 9, + HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN = 10, + HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP = 11, + HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED = 12, + HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN = 13, + HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX = 14, + HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN = 15, + HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT = 16, + HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT = 17, + HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN = 18, + HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN = 19, + HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN = 20, + HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN = 21, + HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP = 22, + HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP = 23, + HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN = 24, + HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN = 25, + HB_OT_MATH_CONSTANT_STACK_GAP_MIN = 26, + HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN = 27, + HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP = 28, + HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN = 29, + HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN = 30, + HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN = 31, + HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP = 32, + HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP = 33, + HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN = 34, + HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN = 35, + HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN = 36, + HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN = 37, + HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS = 38, + HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN = 39, + HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN = 40, + HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP = 41, + HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP = 42, + HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP = 43, + HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS = 44, + HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER = 45, + HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP = 46, + HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS = 47, + HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER = 48, + HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP = 49, + HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP = 50, + HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS = 51, + HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER = 52, + HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE = 53, + HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE = 54, + HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT = 55 +} hb_ot_math_constant_t; + +/** + * hb_ot_math_kern_t: + * + * Since: 1.3.3 + */ +typedef enum { + HB_OT_MATH_KERN_TOP_RIGHT = 0, + HB_OT_MATH_KERN_TOP_LEFT = 1, + HB_OT_MATH_KERN_BOTTOM_RIGHT = 2, + HB_OT_MATH_KERN_BOTTOM_LEFT = 3 +} hb_ot_math_kern_t; + +/** + * hb_ot_math_glyph_variant_t: + * + * Since: 1.3.3 + */ +typedef struct hb_ot_math_glyph_variant_t { + hb_codepoint_t glyph; + hb_position_t advance; +} hb_ot_math_glyph_variant_t; + +/** + * hb_ot_math_glyph_part_flags_t: + * + * Since: 1.3.3 + */ +typedef enum { /*< flags >*/ + HB_MATH_GLYPH_PART_FLAG_EXTENDER = 0x00000001u /* Extender glyph */ +} hb_ot_math_glyph_part_flags_t; + +/** + * hb_ot_math_glyph_part_t: + * + * Since: 1.3.3 + */ +typedef struct hb_ot_math_glyph_part_t { + hb_codepoint_t glyph; + hb_position_t start_connector_length; + hb_position_t end_connector_length; + hb_position_t full_advance; + hb_ot_math_glyph_part_flags_t flags; +} hb_ot_math_glyph_part_t; + +/* Methods */ + +HB_EXTERN hb_bool_t +hb_ot_math_has_data (hb_face_t *face); + +HB_EXTERN hb_position_t +hb_ot_math_get_constant (hb_font_t *font, + hb_ot_math_constant_t constant); + +HB_EXTERN hb_position_t +hb_ot_math_get_glyph_italics_correction (hb_font_t *font, + hb_codepoint_t glyph); + +HB_EXTERN hb_position_t +hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, + hb_codepoint_t glyph); + +HB_EXTERN hb_bool_t +hb_ot_math_is_glyph_extended_shape (hb_face_t *face, + hb_codepoint_t glyph); + +HB_EXTERN hb_position_t +hb_ot_math_get_glyph_kerning (hb_font_t *font, + hb_codepoint_t glyph, + hb_ot_math_kern_t kern, + hb_position_t correction_height); + +HB_EXTERN unsigned int +hb_ot_math_get_glyph_variants (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, + unsigned int start_offset, + unsigned int *variants_count, /* IN/OUT */ + hb_ot_math_glyph_variant_t *variants /* OUT */); + +HB_EXTERN hb_position_t +hb_ot_math_get_min_connector_overlap (hb_font_t *font, + hb_direction_t direction); + +HB_EXTERN unsigned int +hb_ot_math_get_glyph_assembly (hb_font_t *font, + hb_codepoint_t glyph, + hb_direction_t direction, + unsigned int start_offset, + unsigned int *parts_count, /* IN/OUT */ + hb_ot_math_glyph_part_t *parts, /* OUT */ + hb_position_t *italics_correction /* OUT */); + + +HB_END_DECLS + +#endif /* HB_OT_MATH_H */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh index 27105af132..943e3908c7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh @@ -58,7 +58,7 @@ struct maxp /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */ protected: - FixedVersion version; /* Version of the maxp table (0.5 or 1.0), + FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0), * 0x00005000u or 0x00010000u. */ USHORT numGlyphs; /* The number of glyphs in the font. */ public: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh new file mode 100644 index 0000000000..4709cd6e87 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-os2-table.hh @@ -0,0 +1,105 @@ +/* + * Copyright © 2011,2012 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_OS2_TABLE_HH +#define HB_OT_OS2_TABLE_HH + +#include "hb-open-type-private.hh" + + +namespace OT { + +/* + * OS/2 and Windows Metrics + * http://www.microsoft.com/typography/otspec/os2.htm + */ + +#define HB_OT_TAG_os2 HB_TAG('O','S','/','2') + +struct os2 +{ + static const hb_tag_t tableTag = HB_OT_TAG_os2; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + public: + USHORT version; + + /* Version 0 */ + SHORT xAvgCharWidth; + USHORT usWeightClass; + USHORT usWidthClass; + USHORT fsType; + SHORT ySubscriptXSize; + SHORT ySubscriptYSize; + SHORT ySubscriptXOffset; + SHORT ySubscriptYOffset; + SHORT ySuperscriptXSize; + SHORT ySuperscriptYSize; + SHORT ySuperscriptXOffset; + SHORT ySuperscriptYOffset; + SHORT yStrikeoutSize; + SHORT yStrikeoutPosition; + SHORT sFamilyClass; + BYTE panose[10]; + ULONG ulUnicodeRange[4]; + Tag achVendID; + USHORT fsSelection; + USHORT usFirstCharIndex; + USHORT usLastCharIndex; + SHORT sTypoAscender; + SHORT sTypoDescender; + SHORT sTypoLineGap; + USHORT usWinAscent; + USHORT usWinDescent; + + /* Version 1 */ + //ULONG ulCodePageRange1; + //ULONG ulCodePageRange2; + + /* Version 2 */ + //SHORT sxHeight; + //SHORT sCapHeight; + //USHORT usDefaultChar; + //USHORT usBreakChar; + //USHORT usMaxContext; + + /* Version 5 */ + //USHORT usLowerOpticalPointSize; + //USHORT usUpperOpticalPointSize; + + public: + DEFINE_SIZE_STATIC (78); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_OS2_TABLE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh new file mode 100644 index 0000000000..82ab3882a8 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-post-table.hh @@ -0,0 +1,119 @@ +/* + * Copyright © 2016 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_POST_TABLE_HH +#define HB_OT_POST_TABLE_HH + +#include "hb-open-type-private.hh" + + +namespace OT { + + +/* + * post -- PostScript + */ + +#define HB_OT_TAG_post HB_TAG('p','o','s','t') + + +struct postV2Tail +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (numberOfGlyphs.sanitize (c) && + c->check_array (glyphNameIndex, sizeof (USHORT), numberOfGlyphs)); + } + + USHORT numberOfGlyphs; /* Number of glyphs (this should be the + * same as numGlyphs in 'maxp' table). */ + USHORT glyphNameIndex[VAR]; /* This is not an offset, but is the + * ordinal number of the glyph in 'post' + * string tables. */ + BYTE namesX[VAR]; /* Glyph names with length bytes [variable] + * (a Pascal string). */ + + DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX); +}; + +struct post +{ + static const hb_tag_t tableTag = HB_OT_TAG_post; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!c->check_struct (this))) + return_trace (false); + if (version.to_int () == 0x00020000) + { + const postV2Tail &v2 = StructAfter(*this); + return_trace (v2.sanitize (c)); + } + return_trace (true); + } + + public: + FixedVersion<>version; /* 0x00010000 for version 1.0 + * 0x00020000 for version 2.0 + * 0x00025000 for version 2.5 (deprecated) + * 0x00030000 for version 3.0 */ + Fixed italicAngle; /* Italic angle in counter-clockwise degrees + * from the vertical. Zero for upright text, + * negative for text that leans to the right + * (forward). */ + FWORD underlinePosition; /* This is the suggested distance of the top + * of the underline from the baseline + * (negative values indicate below baseline). + * The PostScript definition of this FontInfo + * dictionary key (the y coordinate of the + * center of the stroke) is not used for + * historical reasons. The value of the + * PostScript key may be calculated by + * subtracting half the underlineThickness + * from the value of this field. */ + FWORD underlineThickness; /* Suggested values for the underline + thickness. */ + ULONG isFixedPitch; /* Set to 0 if the font is proportionally + * spaced, non-zero if the font is not + * proportionally spaced (i.e. monospaced). */ + ULONG minMemType42; /* Minimum memory usage when an OpenType font + * is downloaded. */ + ULONG maxMemType42; /* Maximum memory usage when an OpenType font + * is downloaded. */ + ULONG minMemType1; /* Minimum memory usage when an OpenType font + * is downloaded as a Type 1 font. */ + ULONG maxMemType1; /* Maximum memory usage when an OpenType font + * is downloaded as a Type 1 font. */ +/*postV2Tail v2[VAR];*/ + DEFINE_SIZE_STATIC (32); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_POST_TABLE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh index 80d5044354..736c7f76b3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-8.0.0.txt - * # Date: 2015-02-17, 23:33:00 GMT [RP] - * # Blocks-8.0.0.txt - * # Date: 2014-11-10, 23:04:00 GMT [KW] + * # ArabicShaping-9.0.0.txt + * # Date: 2016-02-24, 22:25:00 GMT [RP] + * # Blocks-9.0.0.txt + * # Date: 2016-02-05, 23:48:00 GMT [KW] * UnicodeData.txt does not have a header. */ @@ -19,6 +19,7 @@ #define X JOINING_TYPE_X #define R JOINING_TYPE_R +#define T JOINING_TYPE_T #define U JOINING_TYPE_U #define A JOINING_GROUP_ALAPH #define DR JOINING_GROUP_DALATH_RISH @@ -76,9 +77,11 @@ static const uint8_t joining_table[] = /* Arabic Extended-A */ - /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D, + /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D,X,D,D,D,R,D,D,D,D,X,X, + /* 08C0 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 08E0 */ X,X,U, -#define joining_offset_0x1806u 693 +#define joining_offset_0x1806u 739 /* Mongolian */ @@ -86,43 +89,48 @@ static const uint8_t joining_table[] = /* 1820 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 1840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 1860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,X,X,X,X,X,X,X,X, - /* 1880 */ U,U,U,U,U,U,U,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, + /* 1880 */ U,U,U,U,U,T,T,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 18A0 */ D,D,D,D,D,D,D,D,D,X,D, -#define joining_offset_0x200cu 858 +#define joining_offset_0x200cu 904 /* General Punctuation */ - /* 2000 */ U,C, + /* 2000 */ U,C,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 2020 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,U,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 2040 */ X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X,X, + /* 2060 */ X,X,X,X,X,X,U,U,U,U, -#define joining_offset_0x2066u 860 - - /* General Punctuation */ - - /* 2060 */ U,U,U,U, - -#define joining_offset_0xa840u 864 +#define joining_offset_0xa840u 998 /* Phags-pa */ /* A840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* A860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,L,U, -#define joining_offset_0x10ac0u 916 +#define joining_offset_0x10ac0u 1050 /* Manichaean */ /* 10AC0 */ D,D,D,D,D,R,U,R,U,R,R,U,U,L,R,R,R,R,R,D,D,D,D,L,D,D,D,D,D,R,D,D, /* 10AE0 */ D,R,U,U,R,X,X,X,X,X,X,D,D,D,D,R, -#define joining_offset_0x10b80u 964 +#define joining_offset_0x10b80u 1098 /* Psalter Pahlavi */ /* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U, -}; /* Table items: 1012; occupancy: 57% */ +#define joining_offset_0x1e900u 1146 + + /* Adlam */ + + /* 1E900 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, + /* 1E920 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, + /* 1E940 */ D,D,D,D, + +}; /* Table items: 1214; occupancy: 54% */ static unsigned int @@ -131,7 +139,7 @@ joining_type (hb_codepoint_t u) switch (u >> 12) { case 0x0u: - if (hb_in_range (u, 0x0600u, 0x08B4u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; + if (hb_in_range (u, 0x0600u, 0x08E2u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; break; case 0x1u: @@ -139,8 +147,7 @@ joining_type (hb_codepoint_t u) break; case 0x2u: - if (hb_in_range (u, 0x200Cu, 0x200Du)) return joining_table[u - 0x200Cu + joining_offset_0x200cu]; - if (hb_in_range (u, 0x2066u, 0x2069u)) return joining_table[u - 0x2066u + joining_offset_0x2066u]; + if (hb_in_range (u, 0x200Cu, 0x2069u)) return joining_table[u - 0x200Cu + joining_offset_0x200cu]; break; case 0xAu: @@ -152,6 +159,10 @@ joining_type (hb_codepoint_t u) if (hb_in_range (u, 0x10B80u, 0x10BAFu)) return joining_table[u - 0x10B80u + joining_offset_0x10b80u]; break; + case 0x1Eu: + if (hb_in_range (u, 0x1E900u, 0x1E943u)) return joining_table[u - 0x1E900u + joining_offset_0x1e900u]; + break; + default: break; } @@ -160,6 +171,7 @@ joining_type (hb_codepoint_t u) #undef X #undef R +#undef T #undef U #undef A #undef DR diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh new file mode 100644 index 0000000000..e70c48f427 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-win1256.hh @@ -0,0 +1,323 @@ +/* + * Copyright © 2014 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH + + +/* + * The macros in the first part of this file are generic macros that can + * be used to define the bytes for OpenType table data in code in a + * readable manner. We can move the macros to reside with their respective + * struct types, but since we only use these to define one data table, the + * Windows-1256 Arabic shaping table in this file, we keep them here. + */ + + +/* First we measure, then we cut. */ +#ifndef OT_MEASURE +#define OT_MEASURE +#define OT_TABLE_START static const struct TABLE_NAME { +#define OT_TABLE_END } +#define OT_LABEL_START(Name) unsigned char Name[ +#define OT_LABEL_END ]; +#define OT_BYTE(u8) +1/*byte*/ +#define OT_USHORT(u16) +2/*bytes*/ +#else +#undef OT_MEASURE +#define OT_TABLE_START TABLE_NAME = { +#define OT_TABLE_END }; +#define OT_LABEL_START(Name) { +#define OT_LABEL_END }, +#define OT_BYTE(u8) (u8), +#define OT_USHORT(u16) (unsigned char)((u16)>>8), (unsigned char)((u16)&0xFFu), +#define OT_COUNT(Name, ItemSize) ((unsigned int) sizeof(((struct TABLE_NAME*)0)->Name) \ + / (unsigned int)(ItemSize) \ + /* OT_ASSERT it's divisible (and positive). */) +#define OT_DISTANCE(From,To) ((unsigned int) \ + ((char*)(&((struct TABLE_NAME*)0)->To) - \ + (char*)(&((struct TABLE_NAME*)0)->From)) \ + /* OT_ASSERT it's positive. */) +#endif + + +#define OT_LABEL(Name) \ + OT_LABEL_END \ + OT_LABEL_START(Name) + +/* Whenever we receive an argument that is a list, it will expand to + * contain commas. That cannot be passed to another macro because the + * commas will throw off the preprocessor. The solution is to wrap + * the passed-in argument in OT_LIST() before passing to the next macro. + * Unfortunately this trick requires vararg macros. */ +#define OT_LIST(...) __VA_ARGS__ + + +/* + * Basic Types + */ + +#define OT_TAG(a,b,c,d) \ + OT_BYTE(a) OT_BYTE(b) OT_BYTE(c) OT_BYTE(d) + +#define OT_OFFSET(From, To) /* Offset from From to To in bytes */ \ + OT_USHORT(OT_DISTANCE(From, To)) + +#define OT_GLYPHID /* GlyphID */ \ + OT_USHORT + +#define OT_UARRAY(Name, Items) \ + OT_LABEL_START(Name) \ + OT_USHORT(OT_COUNT(Name##Data, 2)) \ + OT_LABEL(Name##Data) \ + Items \ + OT_LABEL_END + +#define OT_UHEADLESSARRAY(Name, Items) \ + OT_LABEL_START(Name) \ + OT_USHORT(OT_COUNT(Name##Data, 2) + 1) \ + OT_LABEL(Name##Data) \ + Items \ + OT_LABEL_END + + +/* + * Common Types + */ + +#define OT_LOOKUP_FLAG_IGNORE_MARKS 0x08u + +#define OT_LOOKUP(Name, LookupType, LookupFlag, SubLookupOffsets) \ + OT_LABEL_START(Name) \ + OT_USHORT(LookupType) \ + OT_USHORT(LookupFlag) \ + OT_LABEL_END \ + OT_UARRAY(Name##SubLookupOffsetsArray, OT_LIST(SubLookupOffsets)) + +#define OT_SUBLOOKUP(Name, SubFormat, Items) \ + OT_LABEL_START(Name) \ + OT_USHORT(SubFormat) \ + Items + +#define OT_COVERAGE1(Name, Items) \ + OT_LABEL_START(Name) \ + OT_USHORT(1) \ + OT_LABEL_END \ + OT_UARRAY(Name##Glyphs, OT_LIST(Items)) + + +/* + * GSUB + */ + +#define OT_LOOKUP_TYPE_SUBST_SINGLE 1u +#define OT_LOOKUP_TYPE_SUBST_LIGATURE 4u + +#define OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(Name, FromGlyphs, ToGlyphs) \ + OT_SUBLOOKUP(Name, 2, \ + OT_OFFSET(Name, Name##Coverage) \ + OT_LABEL_END \ + OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \ + ) \ + OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \ + /* ASSERT_STATIC_EXPR_ZERO (len(FromGlyphs) == len(ToGlyphs)) */ + +#define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \ + OT_SUBLOOKUP(Name, 1, \ + OT_OFFSET(Name, Name##Coverage) \ + OT_LABEL_END \ + OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \ + ) \ + OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \ + /* ASSERT_STATIC_EXPR_ZERO (len(FirstGlyphs) == len(LigatureSetOffsets)) */ + +#define OT_LIGATURE_SET(Name, LigatureSetOffsets) \ + OT_UARRAY(Name, OT_LIST(LigatureSetOffsets)) + +#define OT_LIGATURE(Name, Components, LigGlyph) \ + OT_LABEL_START(Name) \ + LigGlyph \ + OT_LABEL_END \ + OT_UHEADLESSARRAY(Name##ComponentsArray, OT_LIST(Components)) + +/* + * + * Start of Windows-1256 shaping table. + * + */ + +/* Table name. */ +#define TABLE_NAME arabic_win1256_gsub_lookups + +/* Table manifest. */ +#define MANIFEST(Items) \ + OT_LABEL_START(manifest) \ + OT_USHORT(OT_COUNT(manifestData, 6)) \ + OT_LABEL(manifestData) \ + Items \ + OT_LABEL_END + +#define MANIFEST_LOOKUP(Tag, Name) \ + Tag \ + OT_OFFSET(manifest, Name) + +/* Shorthand. */ +#define G OT_GLYPHID + +/* + * Table Start + */ +OT_TABLE_START + + +/* + * Manifest + */ +MANIFEST( + MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligLookup) + MANIFEST_LOOKUP(OT_TAG('i','n','i','t'), initLookup) + MANIFEST_LOOKUP(OT_TAG('m','e','d','i'), mediLookup) + MANIFEST_LOOKUP(OT_TAG('f','i','n','a'), finaLookup) + MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligMarksLookup) +) + +/* + * Lookups + */ +OT_LOOKUP(initLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS, + OT_OFFSET(initLookup, initmediSubLookup) + OT_OFFSET(initLookup, initSubLookup) +) +OT_LOOKUP(mediLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS, + OT_OFFSET(mediLookup, initmediSubLookup) + OT_OFFSET(mediLookup, mediSubLookup) + OT_OFFSET(mediLookup, medifinaLamAlefSubLookup) +) +OT_LOOKUP(finaLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS, + OT_OFFSET(finaLookup, finaSubLookup) + /* We don't need this one currently as the sequence inherits masks + * from the first item. Just in case we change that in the future + * to be smart about Arabic masks when ligating... */ + OT_OFFSET(finaLookup, medifinaLamAlefSubLookup) +) +OT_LOOKUP(rligLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, OT_LOOKUP_FLAG_IGNORE_MARKS, + OT_OFFSET(rligLookup, lamAlefLigaturesSubLookup) +) +OT_LOOKUP(rligMarksLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, 0, + OT_OFFSET(rligMarksLookup, shaddaLigaturesSubLookup) +) + +/* + * init/medi/fina forms + */ +OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initmediSubLookup, + G(198) G(200) G(201) G(202) G(203) G(204) G(205) G(206) G(211) + G(212) G(213) G(214) G(223) G(225) G(227) G(228) G(236) G(237), + G(162) G(4) G(5) G(5) G(6) G(7) G(9) G(11) G(13) + G(14) G(15) G(26) G(140) G(141) G(142) G(143) G(154) G(154) +) +OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initSubLookup, + G(218) G(219) G(221) G(222) G(229), + G(27) G(30) G(128) G(131) G(144) +) +OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(mediSubLookup, + G(218) G(219) G(221) G(222) G(229), + G(28) G(31) G(129) G(138) G(149) +) +OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(finaSubLookup, + G(194) G(195) G(197) G(198) G(199) G(201) G(204) G(205) G(206) + G(218) G(219) G(229) G(236) G(237), + G(2) G(1) G(3) G(181) G(0) G(159) G(8) G(10) G(12) + G(29) G(127) G(152) G(160) G(156) +) +OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(medifinaLamAlefSubLookup, + G(165) G(178) G(180) G(252), + G(170) G(179) G(185) G(255) +) + +/* + * Lam+Alef ligatures + */ +OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(lamAlefLigaturesSubLookup, + G(225), + OT_OFFSET(lamAlefLigaturesSubLookup, lamLigatureSet) +) +OT_LIGATURE_SET(lamLigatureSet, + OT_OFFSET(lamLigatureSet, lamInitLigature1) + OT_OFFSET(lamLigatureSet, lamInitLigature2) + OT_OFFSET(lamLigatureSet, lamInitLigature3) + OT_OFFSET(lamLigatureSet, lamInitLigature4) +) +OT_LIGATURE(lamInitLigature1, G(199), G(165)) +OT_LIGATURE(lamInitLigature2, G(195), G(178)) +OT_LIGATURE(lamInitLigature3, G(194), G(180)) +OT_LIGATURE(lamInitLigature4, G(197), G(252)) + +/* + * Shadda ligatures + */ +OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(shaddaLigaturesSubLookup, + G(248), + OT_OFFSET(shaddaLigaturesSubLookup, shaddaLigatureSet) +) +OT_LIGATURE_SET(shaddaLigatureSet, + OT_OFFSET(shaddaLigatureSet, shaddaLigature1) + OT_OFFSET(shaddaLigatureSet, shaddaLigature2) + OT_OFFSET(shaddaLigatureSet, shaddaLigature3) +) +OT_LIGATURE(shaddaLigature1, G(243), G(172)) +OT_LIGATURE(shaddaLigature2, G(245), G(173)) +OT_LIGATURE(shaddaLigature3, G(246), G(175)) + +/* + * Table end + */ +OT_TABLE_END + + +/* + * Clean up + */ +#undef OT_TABLE_START +#undef OT_TABLE_END +#undef OT_LABEL_START +#undef OT_LABEL_END +#undef OT_BYTE +#undef OT_USHORT +#undef OT_DISTANCE +#undef OT_COUNT + +/* + * Include a second time to get the table data... + */ +#if 0 +#include "hb-private.hh" /* Make check-includes.sh happy. */ +#endif +#ifdef OT_MEASURE +#include "hb-ot-shape-complex-arabic-win1256.hh" +#endif + +#define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH +#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc index cde02e0a56..56ec5cd65c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc @@ -28,9 +28,38 @@ #include "hb-ot-shape-private.hh" +#ifndef HB_DEBUG_ARABIC +#define HB_DEBUG_ARABIC (HB_DEBUG+0) +#endif + + /* buffer var allocations */ #define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */ +#define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0 + +/* See: + * https://github.com/behdad/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */ +#define HB_ARABIC_GENERAL_CATEGORY_IS_WORD(gen_cat) \ + (FLAG_SAFE (gen_cat) & \ + (FLAG (HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_PRIVATE_USE) | \ + /*FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |*/ \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) | \ + /*FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) |*/ \ + /*FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER) |*/ \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_LETTER_NUMBER) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_NUMBER) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_CURRENCY_SYMBOL) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_MATH_SYMBOL) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_SYMBOL))) + /* * Joining types: @@ -84,7 +113,7 @@ static const hb_tag_t arabic_features[] = /* Same order as the feature array */ -enum { +enum arabic_action_t { ISOL, FINA, FIN2, @@ -95,7 +124,11 @@ enum { NONE, - ARABIC_NUM_FEATURES = NONE + ARABIC_NUM_FEATURES = NONE, + + /* We abuse the same byte for other things... */ + STCH_FIXED, + STCH_REPEATING, }; static const struct arabic_state_table_entry { @@ -139,6 +172,11 @@ arabic_fallback_shape (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); +static void +record_stch (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + static void collect_features_arabic (hb_ot_shape_planner_t *plan) { @@ -165,6 +203,9 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) map->add_gsub_pause (nuke_joiners); + map->add_global_bool_feature (HB_TAG('s','t','c','h')); + map->add_gsub_pause (record_stch); + map->add_global_bool_feature (HB_TAG('c','c','m','p')); map->add_global_bool_feature (HB_TAG('l','o','c','l')); @@ -182,7 +223,6 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) map->add_gsub_pause (arabic_fallback_shape); map->add_global_bool_feature (HB_TAG('c','a','l','t')); - map->add_gsub_pause (NULL); /* The spec includes 'cswh'. Earlier versions of Windows * used to enable this by default, but testing suggests @@ -192,6 +232,7 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) * Note that IranNastaliq uses this feature extensively * to fixup broken glyph sequences. Oh well... * Test case: U+0643,U+0640,U+0631. */ + //map->add_gsub_pause (NULL); //map->add_global_bool_feature (HB_TAG('c','s','w','h')); map->add_global_bool_feature (HB_TAG('m','s','e','t')); } @@ -208,8 +249,10 @@ struct arabic_shape_plan_t * mask_array[NONE] == 0. */ hb_mask_t mask_array[ARABIC_NUM_FEATURES + 1]; - bool do_fallback; arabic_fallback_plan_t *fallback_plan; + + unsigned int do_fallback : 1; + unsigned int has_stch : 1; }; void * @@ -220,6 +263,7 @@ data_create_arabic (const hb_ot_shape_plan_t *plan) return NULL; arabic_plan->do_fallback = plan->props.script == HB_SCRIPT_ARABIC; + arabic_plan->has_stch = !!plan->map.get_1_mask (HB_TAG ('s','t','c','h')); for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) { arabic_plan->mask_array[i] = plan->map.get_1_mask (arabic_features[i]); arabic_plan->do_fallback = arabic_plan->do_fallback && @@ -320,8 +364,6 @@ setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) info[i].mask |= arabic_plan->mask_array[info[i].arabic_shaping_action()]; - - HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); } static void @@ -371,6 +413,197 @@ retry: arabic_fallback_plan_shape (fallback_plan, font, buffer); } +/* + * Stretch feature: "stch". + * See example here: + * https://www.microsoft.com/typography/OpenTypeDev/syriac/intro.htm + * We implement this in a generic way, such that the Arabic subtending + * marks can use it as well. + */ + +static void +record_stch (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; + if (!arabic_plan->has_stch) + return; + + /* 'stch' feature was just applied. Look for anything that multiplied, + * and record it for stch treatment later. Note that rtlm, frac, etc + * are applied before stch, but we assume that they didn't result in + * anything multiplying into 5 pieces, so it's safe-ish... */ + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if (unlikely (_hb_glyph_info_multiplied (&info[i]))) + { + unsigned int comp = _hb_glyph_info_get_lig_comp (&info[i]); + info[i].arabic_shaping_action() = comp % 2 ? STCH_REPEATING : STCH_FIXED; + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH; + } +} + +static void +apply_stch (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font) +{ + if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH))) + return; + + /* The Arabic shaper currently always processes in RTL mode, so we should + * stretch / position the stretched pieces to the left / preceding glyphs. */ + + /* We do a two pass implementation: + * First pass calculates the exact number of extra glyphs we need, + * We then enlarge buffer to have that much room, + * Second pass applies the stretch, copying things to the end of buffer. + */ + + int sign = font->x_scale < 0 ? -1 : +1; + unsigned int extra_glyphs_needed = 0; // Set during MEASURE, used during CUT + typedef enum { MEASURE, CUT } step_t; + + for (step_t step = MEASURE; step <= CUT; step = (step_t) (step + 1)) + { + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + unsigned int new_len = count + extra_glyphs_needed; // write head during CUT + unsigned int j = new_len; + for (unsigned int i = count; i; i--) + { + if (!hb_in_range (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING)) + { + if (step == CUT) + { + --j; + info[j] = info[i - 1]; + pos[j] = pos[i - 1]; + } + continue; + } + + /* Yay, justification! */ + + hb_position_t w_total = 0; // Total to be filled + hb_position_t w_fixed = 0; // Sum of fixed tiles + hb_position_t w_repeating = 0; // Sum of repeating tiles + int n_fixed = 0; + int n_repeating = 0; + + unsigned int end = i; + while (i && + hb_in_range (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING)) + { + i--; + hb_position_t width = font->get_glyph_h_advance (info[i].codepoint); + if (info[i].arabic_shaping_action() == STCH_FIXED) + { + w_fixed += width; + n_fixed++; + } + else + { + w_repeating += width; + n_repeating++; + } + } + unsigned int start = i; + unsigned int context = i; + while (context && + !hb_in_range (info[context - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING) && + (_hb_glyph_info_is_default_ignorable (&info[context - 1]) || + HB_ARABIC_GENERAL_CATEGORY_IS_WORD (_hb_glyph_info_get_general_category (&info[context - 1])))) + { + context--; + w_total += pos[context].x_advance; + } + i++; // Don't touch i again. + + DEBUG_MSG (ARABIC, NULL, "%s stretch at (%d,%d,%d)", + step == MEASURE ? "measuring" : "cutting", context, start, end); + DEBUG_MSG (ARABIC, NULL, "rest of word: count=%d width %d", start - context, w_total); + DEBUG_MSG (ARABIC, NULL, "fixed tiles: count=%d width=%d", n_fixed, w_fixed); + DEBUG_MSG (ARABIC, NULL, "repeating tiles: count=%d width=%d", n_repeating, w_repeating); + + /* Number of additional times to repeat each repeating tile. */ + int n_copies = 0; + + hb_position_t w_remaining = w_total - w_fixed; + if (sign * w_remaining > sign * w_repeating && sign * w_repeating > 0) + n_copies = (sign * w_remaining) / (sign * w_repeating) - 1; + + /* See if we can improve the fit by adding an extra repeat and squeezing them together a bit. */ + hb_position_t extra_repeat_overlap = 0; + hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1); + if (shortfall > 0) + { + ++n_copies; + hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining; + if (excess > 0) + extra_repeat_overlap = excess / (n_copies * n_repeating); + } + + if (step == MEASURE) + { + extra_glyphs_needed += n_copies * n_repeating; + DEBUG_MSG (ARABIC, NULL, "will add extra %d copies of repeating tiles", n_copies); + } + else + { + hb_position_t x_offset = 0; + for (unsigned int k = end; k > start; k--) + { + hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint); + + unsigned int repeat = 1; + if (info[k - 1].arabic_shaping_action() == STCH_REPEATING) + repeat += n_copies; + + DEBUG_MSG (ARABIC, NULL, "appending %d copies of glyph %d; j=%d", + repeat, info[k - 1].codepoint, j); + for (unsigned int n = 0; n < repeat; n++) + { + x_offset -= width; + if (n > 0) + x_offset += extra_repeat_overlap; + pos[k - 1].x_offset = x_offset; + /* Append copy. */ + --j; + info[j] = info[k - 1]; + pos[j] = pos[k - 1]; + } + } + } + } + + if (step == MEASURE) + { + if (unlikely (!buffer->ensure (count + extra_glyphs_needed))) + break; + } + else + { + assert (j == 0); + buffer->len = new_len; + } + } +} + + +static void +postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font) +{ + apply_stch (plan, buffer, font); + + HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); +} const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = { @@ -379,11 +612,13 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = NULL, /* override_features */ data_create_arabic, data_destroy_arabic, - NULL, /* preprocess_text_arabic */ + NULL, /* preprocess_text */ + postprocess_glyphs_arabic, HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ NULL, /* compose */ setup_masks_arabic, + NULL, /* disable_otl */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc index f7f097eeda..42830ab618 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-default.cc @@ -35,10 +35,12 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = NULL, /* data_create */ NULL, /* data_destroy */ NULL, /* preprocess_text */ + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, + NULL, /* disable_otl */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc index 1fa79ce6d4..eb95a28c09 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc @@ -188,7 +188,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, */ unsigned int count = buffer->len; - for (buffer->idx = 0; buffer->idx < count;) + for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;) { hb_codepoint_t u = buffer->cur().codepoint; @@ -411,13 +411,15 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul = "hangul", collect_features_hangul, override_features_hangul, - data_create_hangul, /* data_create */ - data_destroy_hangul, /* data_destroy */ + data_create_hangul, + data_destroy_hangul, preprocess_text_hangul, + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_NONE, NULL, /* decompose */ NULL, /* compose */ - setup_masks_hangul, /* setup_masks */ + setup_masks_hangul, + NULL, /* disable_otl */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc index c7b7a5eba6..96f2494616 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hebrew.cc @@ -68,7 +68,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, 0xFB4Au /* TAV */ }; - bool found = c->unicode->compose (a, b, ab); + bool found = (bool) c->unicode->compose (a, b, ab); if (!found && !c->plan->has_mark) { @@ -154,6 +154,18 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, return found; } +static bool +disable_otl_hebrew (const hb_ot_shape_plan_t *plan) +{ + /* For Hebrew shaper, use fallback if GPOS does not have 'hebr' + * script. This matches Uniscribe better, and makes fonts like + * Arial that have GSUB/GPOS/GDEF but no data for Hebrew work. + * See: + * https://github.com/behdad/harfbuzz/issues/347#issuecomment-267838368 + */ + return plan->map.chosen_script[1] != HB_TAG ('h','e','b','r'); +} + const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = { @@ -163,10 +175,12 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = NULL, /* data_create */ NULL, /* data_destroy */ NULL, /* preprocess_text */ + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ compose_hebrew, NULL, /* setup_masks */ + disable_otl_hebrew, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh index f652d4fda7..5a7a265c87 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh @@ -56,52 +56,52 @@ static const unsigned char _indic_syllable_machine_trans_keys[] = { 5u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 8u, 8u, 1u, 16u, 8u, 13u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, - 16u, 16u, 8u, 8u, 1u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 5u, 14u, + 16u, 16u, 8u, 8u, 1u, 18u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, + 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, + 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, - 5u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 31u, 3u, 31u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 5u, 14u, - 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, - 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, - 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, - 5u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 4u, 14u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, - 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, - 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 5u, 14u, 5u, 10u, + 5u, 14u, 3u, 14u, 1u, 16u, 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 3u, 17u, 3u, 17u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, + 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, + 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, - 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 4u, 14u, 3u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, - 3u, 31u, 4u, 31u, 1u, 16u, 3u, 31u, 3u, 31u, 4u, 31u, 5u, 14u, 5u, 14u, - 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, - 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, + 3u, 14u, 1u, 16u, 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 1u, 16u, + 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, + 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, + 3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u, 5u, 10u, 9u, 10u, 9u, 9u, + 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u, + 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, + 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 1u, 16u, + 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, + 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, + 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 3u, 17u, 4u, 14u, + 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, + 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, + 3u, 17u, 3u, 17u, 4u, 17u, 5u, 14u, 5u, 14u, 5u, 10u, 9u, 10u, 9u, 9u, + 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u, + 3u, 13u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, + 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 1u, 16u, + 4u, 14u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, + 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, + 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, + 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u, + 1u, 17u, 4u, 14u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, + 5u, 10u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 3u, 17u, 3u, 17u, 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, - 5u, 14u, 3u, 14u, 1u, 16u, 4u, 31u, 4u, 14u, 3u, 31u, 3u, 31u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 1u, 16u, 3u, 31u, 3u, 31u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, - 1u, 16u, 3u, 31u, 1u, 31u, 3u, 31u, 1u, 31u, 4u, 14u, 5u, 10u, 9u, 10u, - 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 1u, 16u, 3u, 31u, 3u, 31u, - 4u, 31u, 3u, 31u, 3u, 31u, 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, - 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, - 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u, 3u, 13u, 1u, 16u, 3u, 10u, 5u, 10u, - 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, 9u, 10u, 9u, 9u, 5u, 10u, 0 + 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 13u, 3u, 10u, 5u, 10u, 3u, 10u, + 3u, 13u, 1u, 16u, 3u, 10u, 5u, 10u, 5u, 10u, 9u, 10u, 9u, 9u, 9u, 10u, + 9u, 10u, 9u, 9u, 5u, 10u, 0 }; static const char _indic_syllable_machine_key_spans[] = { @@ -127,52 +127,52 @@ static const char _indic_syllable_machine_key_spans[] = { 3, 4, 3, 1, 4, 3, 1, 4, 3, 1, 1, 16, 6, 5, 1, 1, 5, 1, 1, 5, 1, 1, 5, 1, - 1, 1, 31, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 10, 10, + 1, 1, 18, 15, 15, 14, 16, 15, + 15, 14, 16, 15, 15, 14, 16, 15, + 15, 14, 16, 15, 15, 14, 10, 10, 6, 2, 1, 2, 2, 1, 6, 11, 8, 6, 8, 11, 12, 12, 11, 10, 12, 11, 10, 12, 11, 10, 12, 11, - 10, 12, 16, 28, 11, 29, 29, 16, - 16, 16, 16, 16, 29, 29, 16, 16, - 16, 16, 16, 29, 29, 16, 16, 16, - 16, 16, 29, 29, 16, 16, 16, 16, - 16, 29, 29, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 10, 10, - 6, 2, 1, 2, 2, 1, 6, 11, - 8, 6, 8, 11, 12, 12, 11, 10, - 12, 11, 10, 12, 11, 10, 12, 11, - 10, 12, 16, 28, 11, 29, 29, 16, - 16, 16, 16, 16, 29, 29, 16, 16, - 16, 16, 16, 29, 29, 16, 16, 16, - 16, 16, 29, 29, 16, 16, 16, 16, - 11, 16, 29, 29, 28, 16, 29, 29, - 28, 16, 29, 29, 28, 16, 29, 29, - 28, 16, 29, 29, 28, 10, 10, 6, + 10, 12, 16, 11, 15, 15, 16, 16, + 16, 16, 16, 15, 15, 16, 16, 16, + 16, 16, 15, 15, 16, 16, 16, 16, + 16, 15, 15, 16, 16, 16, 16, 16, + 15, 15, 15, 15, 14, 16, 15, 15, + 14, 16, 15, 15, 14, 16, 15, 15, + 14, 16, 15, 15, 14, 10, 10, 6, 2, 1, 2, 2, 1, 6, 11, 8, 6, 8, 11, 12, 12, 11, 10, 12, 11, 10, 12, 11, 10, 12, 11, 10, - 12, 16, 28, 11, 29, 29, 16, 16, - 16, 16, 16, 29, 29, 16, 16, 16, - 16, 16, 29, 29, 16, 16, 16, 16, - 16, 29, 29, 16, 16, 16, 16, 16, - 11, 29, 11, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 16, 29, - 29, 28, 16, 29, 29, 28, 10, 10, - 6, 2, 1, 2, 2, 1, 6, 11, - 8, 6, 8, 11, 12, 12, 11, 10, + 12, 16, 11, 15, 15, 16, 16, 16, + 16, 16, 15, 15, 16, 16, 16, 16, + 16, 15, 15, 16, 16, 16, 16, 16, + 15, 15, 16, 16, 16, 16, 11, 16, + 15, 15, 14, 16, 15, 15, 14, 16, + 15, 15, 14, 16, 15, 15, 14, 16, + 15, 15, 14, 10, 10, 6, 2, 1, + 2, 2, 1, 6, 11, 8, 6, 8, + 11, 12, 12, 11, 10, 12, 11, 10, + 12, 11, 10, 12, 11, 10, 12, 16, + 11, 15, 15, 16, 16, 16, 16, 16, + 15, 15, 16, 16, 16, 16, 16, 15, + 15, 16, 16, 16, 16, 16, 15, 15, + 16, 16, 16, 16, 16, 11, 15, 11, + 15, 15, 14, 16, 15, 15, 14, 16, + 15, 15, 14, 16, 15, 15, 14, 16, + 15, 15, 14, 10, 10, 6, 2, 1, + 2, 2, 1, 6, 11, 8, 6, 8, + 11, 12, 12, 11, 10, 12, 11, 10, + 12, 11, 10, 12, 11, 10, 12, 16, + 11, 15, 15, 16, 16, 16, 16, 16, + 15, 15, 16, 16, 16, 16, 16, 15, + 15, 16, 16, 16, 16, 16, 15, 15, + 16, 16, 16, 16, 16, 15, 17, 15, + 17, 11, 6, 2, 1, 2, 2, 1, + 6, 16, 15, 15, 14, 15, 15, 16, 12, 11, 10, 12, 11, 10, 12, 11, - 10, 12, 16, 28, 11, 29, 29, 16, - 16, 16, 16, 16, 29, 29, 16, 16, - 16, 16, 16, 29, 29, 16, 16, 16, - 16, 16, 29, 29, 16, 16, 16, 16, - 16, 29, 31, 29, 31, 11, 6, 2, - 1, 2, 2, 1, 6, 16, 29, 29, - 28, 29, 29, 16, 12, 11, 10, 12, - 11, 10, 12, 11, 10, 12, 11, 10, - 11, 8, 6, 8, 11, 16, 8, 6, - 6, 2, 1, 2, 2, 1, 6 + 10, 12, 11, 10, 11, 8, 6, 8, + 11, 16, 8, 6, 6, 2, 1, 2, + 2, 1, 6 }; static const short _indic_syllable_machine_index_offsets[] = { @@ -198,52 +198,52 @@ static const short _indic_syllable_machine_index_offsets[] = { 954, 958, 963, 967, 969, 974, 978, 980, 985, 989, 991, 993, 1010, 1017, 1023, 1025, 1027, 1033, 1035, 1037, 1043, 1045, 1047, 1053, - 1055, 1057, 1059, 1091, 1121, 1151, 1180, 1197, - 1227, 1257, 1286, 1303, 1333, 1363, 1392, 1409, - 1439, 1469, 1498, 1515, 1545, 1575, 1604, 1615, - 1626, 1633, 1636, 1638, 1641, 1644, 1646, 1653, - 1665, 1674, 1681, 1690, 1702, 1715, 1728, 1740, - 1751, 1764, 1776, 1787, 1800, 1812, 1823, 1836, - 1848, 1859, 1872, 1889, 1918, 1930, 1960, 1990, - 2007, 2024, 2041, 2058, 2075, 2105, 2135, 2152, - 2169, 2186, 2203, 2220, 2250, 2280, 2297, 2314, - 2331, 2348, 2365, 2395, 2425, 2442, 2459, 2476, - 2493, 2510, 2540, 2570, 2600, 2630, 2659, 2676, - 2706, 2736, 2765, 2782, 2812, 2842, 2871, 2888, - 2918, 2948, 2977, 2994, 3024, 3054, 3083, 3094, - 3105, 3112, 3115, 3117, 3120, 3123, 3125, 3132, - 3144, 3153, 3160, 3169, 3181, 3194, 3207, 3219, - 3230, 3243, 3255, 3266, 3279, 3291, 3302, 3315, - 3327, 3338, 3351, 3368, 3397, 3409, 3439, 3469, - 3486, 3503, 3520, 3537, 3554, 3584, 3614, 3631, - 3648, 3665, 3682, 3699, 3729, 3759, 3776, 3793, - 3810, 3827, 3844, 3874, 3904, 3921, 3938, 3955, - 3972, 3984, 4001, 4031, 4061, 4090, 4107, 4137, - 4167, 4196, 4213, 4243, 4273, 4302, 4319, 4349, - 4379, 4408, 4425, 4455, 4485, 4514, 4525, 4536, - 4543, 4546, 4548, 4551, 4554, 4556, 4563, 4575, - 4584, 4591, 4600, 4612, 4625, 4638, 4650, 4661, - 4674, 4686, 4697, 4710, 4722, 4733, 4746, 4758, - 4769, 4782, 4799, 4828, 4840, 4870, 4900, 4917, - 4934, 4951, 4968, 4985, 5015, 5045, 5062, 5079, - 5096, 5113, 5130, 5160, 5190, 5207, 5224, 5241, - 5258, 5275, 5305, 5335, 5352, 5369, 5386, 5403, - 5420, 5432, 5462, 5474, 5504, 5534, 5563, 5580, - 5610, 5640, 5669, 5686, 5716, 5746, 5775, 5792, - 5822, 5852, 5881, 5898, 5928, 5958, 5987, 5998, - 6009, 6016, 6019, 6021, 6024, 6027, 6029, 6036, - 6048, 6057, 6064, 6073, 6085, 6098, 6111, 6123, - 6134, 6147, 6159, 6170, 6183, 6195, 6206, 6219, - 6231, 6242, 6255, 6272, 6301, 6313, 6343, 6373, - 6390, 6407, 6424, 6441, 6458, 6488, 6518, 6535, - 6552, 6569, 6586, 6603, 6633, 6663, 6680, 6697, - 6714, 6731, 6748, 6778, 6808, 6825, 6842, 6859, - 6876, 6893, 6923, 6955, 6985, 7017, 7029, 7036, - 7039, 7041, 7044, 7047, 7049, 7056, 7073, 7103, - 7133, 7162, 7192, 7222, 7239, 7252, 7264, 7275, - 7288, 7300, 7311, 7324, 7336, 7347, 7360, 7372, - 7383, 7395, 7404, 7411, 7420, 7432, 7449, 7458, - 7465, 7472, 7475, 7477, 7480, 7483, 7485 + 1055, 1057, 1059, 1078, 1094, 1110, 1125, 1142, + 1158, 1174, 1189, 1206, 1222, 1238, 1253, 1270, + 1286, 1302, 1317, 1334, 1350, 1366, 1381, 1392, + 1403, 1410, 1413, 1415, 1418, 1421, 1423, 1430, + 1442, 1451, 1458, 1467, 1479, 1492, 1505, 1517, + 1528, 1541, 1553, 1564, 1577, 1589, 1600, 1613, + 1625, 1636, 1649, 1666, 1678, 1694, 1710, 1727, + 1744, 1761, 1778, 1795, 1811, 1827, 1844, 1861, + 1878, 1895, 1912, 1928, 1944, 1961, 1978, 1995, + 2012, 2029, 2045, 2061, 2078, 2095, 2112, 2129, + 2146, 2162, 2178, 2194, 2210, 2225, 2242, 2258, + 2274, 2289, 2306, 2322, 2338, 2353, 2370, 2386, + 2402, 2417, 2434, 2450, 2466, 2481, 2492, 2503, + 2510, 2513, 2515, 2518, 2521, 2523, 2530, 2542, + 2551, 2558, 2567, 2579, 2592, 2605, 2617, 2628, + 2641, 2653, 2664, 2677, 2689, 2700, 2713, 2725, + 2736, 2749, 2766, 2778, 2794, 2810, 2827, 2844, + 2861, 2878, 2895, 2911, 2927, 2944, 2961, 2978, + 2995, 3012, 3028, 3044, 3061, 3078, 3095, 3112, + 3129, 3145, 3161, 3178, 3195, 3212, 3229, 3241, + 3258, 3274, 3290, 3305, 3322, 3338, 3354, 3369, + 3386, 3402, 3418, 3433, 3450, 3466, 3482, 3497, + 3514, 3530, 3546, 3561, 3572, 3583, 3590, 3593, + 3595, 3598, 3601, 3603, 3610, 3622, 3631, 3638, + 3647, 3659, 3672, 3685, 3697, 3708, 3721, 3733, + 3744, 3757, 3769, 3780, 3793, 3805, 3816, 3829, + 3846, 3858, 3874, 3890, 3907, 3924, 3941, 3958, + 3975, 3991, 4007, 4024, 4041, 4058, 4075, 4092, + 4108, 4124, 4141, 4158, 4175, 4192, 4209, 4225, + 4241, 4258, 4275, 4292, 4309, 4326, 4338, 4354, + 4366, 4382, 4398, 4413, 4430, 4446, 4462, 4477, + 4494, 4510, 4526, 4541, 4558, 4574, 4590, 4605, + 4622, 4638, 4654, 4669, 4680, 4691, 4698, 4701, + 4703, 4706, 4709, 4711, 4718, 4730, 4739, 4746, + 4755, 4767, 4780, 4793, 4805, 4816, 4829, 4841, + 4852, 4865, 4877, 4888, 4901, 4913, 4924, 4937, + 4954, 4966, 4982, 4998, 5015, 5032, 5049, 5066, + 5083, 5099, 5115, 5132, 5149, 5166, 5183, 5200, + 5216, 5232, 5249, 5266, 5283, 5300, 5317, 5333, + 5349, 5366, 5383, 5400, 5417, 5434, 5450, 5468, + 5484, 5502, 5514, 5521, 5524, 5526, 5529, 5532, + 5534, 5541, 5558, 5574, 5590, 5605, 5621, 5637, + 5654, 5667, 5679, 5690, 5703, 5715, 5726, 5739, + 5751, 5762, 5775, 5787, 5798, 5810, 5819, 5826, + 5835, 5847, 5864, 5873, 5880, 5887, 5890, 5892, + 5895, 5898, 5900 }; static const short _indic_syllable_machine_indicies[] = { @@ -381,882 +381,684 @@ static const short _indic_syllable_machine_indicies[] = { 161, 161, 162, 157, 0, 183, 0, 184, 0, 186, 185, 188, 189, 190, 191, 192, 193, 84, 79, 194, 195, 196, 196, 156, - 197, 198, 199, 200, 201, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, - 187, 202, 187, 204, 205, 206, 207, 6, - 1, 208, 209, 203, 203, 38, 210, 203, - 203, 211, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 212, - 203, 213, 205, 214, 214, 6, 1, 208, - 209, 203, 203, 203, 210, 203, 203, 211, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 212, 203, 205, - 214, 214, 6, 1, 208, 209, 203, 203, - 203, 210, 203, 203, 211, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 212, 203, 215, 203, 203, 203, - 19, 216, 203, 1, 208, 209, 203, 203, - 203, 217, 203, 215, 203, 218, 219, 220, - 221, 6, 1, 208, 209, 203, 203, 36, - 222, 203, 203, 211, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 212, 203, 223, 219, 224, 224, 6, - 1, 208, 209, 203, 203, 203, 222, 203, - 203, 211, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 212, - 203, 219, 224, 224, 6, 1, 208, 209, - 203, 203, 203, 222, 203, 203, 211, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 212, 203, 225, 203, - 203, 203, 19, 226, 203, 1, 208, 209, - 203, 203, 203, 217, 203, 225, 203, 227, - 228, 229, 230, 6, 1, 208, 209, 203, - 203, 34, 231, 203, 203, 211, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 212, 203, 232, 228, 233, - 233, 6, 1, 208, 209, 203, 203, 203, - 231, 203, 203, 211, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 212, 203, 228, 233, 233, 6, 1, - 208, 209, 203, 203, 203, 231, 203, 203, - 211, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 212, 203, - 234, 203, 203, 203, 19, 235, 203, 1, - 208, 209, 203, 203, 203, 217, 203, 234, - 203, 236, 237, 238, 239, 6, 1, 208, - 209, 203, 203, 32, 240, 203, 203, 211, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 212, 203, 241, - 237, 242, 242, 6, 1, 208, 209, 203, - 203, 203, 240, 203, 203, 211, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 212, 203, 237, 242, 242, - 6, 1, 208, 209, 203, 203, 203, 240, - 203, 203, 211, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 212, 203, 243, 203, 203, 203, 19, 244, - 203, 1, 208, 209, 203, 203, 203, 217, - 203, 243, 203, 245, 246, 247, 248, 6, - 1, 208, 209, 203, 203, 30, 249, 203, - 203, 211, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 212, - 203, 250, 246, 251, 251, 6, 1, 208, - 209, 203, 203, 203, 249, 203, 203, 211, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 212, 203, 246, - 251, 251, 6, 1, 208, 209, 203, 203, - 203, 249, 203, 203, 211, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 212, 203, 19, 252, 203, 1, - 208, 209, 203, 203, 203, 217, 203, 253, - 253, 203, 1, 208, 209, 203, 203, 203, - 217, 203, 254, 203, 203, 255, 208, 209, - 203, 208, 209, 203, 256, 203, 208, 257, - 203, 208, 258, 203, 208, 203, 254, 203, - 203, 203, 208, 209, 203, 259, 203, 260, - 261, 203, 1, 208, 209, 203, 203, 4, - 203, 3, 203, 253, 253, 203, 1, 208, - 209, 203, 253, 253, 203, 1, 208, 209, - 203, 259, 203, 253, 253, 203, 1, 208, - 209, 203, 259, 203, 260, 253, 203, 1, - 208, 209, 203, 203, 4, 203, 19, 203, - 262, 262, 6, 1, 208, 209, 203, 203, - 203, 217, 203, 263, 28, 264, 265, 9, - 1, 208, 209, 203, 203, 203, 217, 203, - 28, 264, 265, 9, 1, 208, 209, 203, - 203, 203, 217, 203, 264, 264, 9, 1, - 208, 209, 203, 203, 203, 217, 203, 266, - 25, 267, 268, 12, 1, 208, 209, 203, - 203, 203, 217, 203, 25, 267, 268, 12, - 1, 208, 209, 203, 203, 203, 217, 203, - 267, 267, 12, 1, 208, 209, 203, 203, - 203, 217, 203, 269, 22, 270, 271, 15, - 1, 208, 209, 203, 203, 203, 217, 203, - 22, 270, 271, 15, 1, 208, 209, 203, - 203, 203, 217, 203, 270, 270, 15, 1, - 208, 209, 203, 203, 203, 217, 203, 272, - 19, 253, 273, 203, 1, 208, 209, 203, - 203, 203, 217, 203, 19, 253, 273, 203, - 1, 208, 209, 203, 203, 203, 217, 203, - 253, 274, 203, 1, 208, 209, 203, 203, - 203, 217, 203, 19, 203, 253, 253, 203, - 1, 208, 209, 203, 203, 203, 217, 203, - 2, 3, 203, 203, 19, 252, 203, 1, - 208, 209, 203, 203, 203, 217, 203, 2, - 203, 246, 251, 251, 6, 1, 208, 209, - 203, 203, 203, 249, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 212, 203, 246, 251, - 251, 6, 1, 208, 209, 203, 203, 203, - 249, 203, 245, 246, 251, 251, 6, 1, - 208, 209, 203, 203, 203, 249, 203, 203, - 211, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 212, 203, - 245, 246, 247, 251, 6, 1, 208, 209, - 203, 203, 30, 249, 203, 203, 211, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 212, 203, 243, 203, - 275, 203, 262, 262, 6, 1, 208, 209, - 203, 203, 203, 217, 203, 243, 203, 243, - 203, 203, 203, 253, 253, 203, 1, 208, - 209, 203, 203, 203, 217, 203, 243, 203, - 243, 203, 203, 203, 253, 276, 203, 1, - 208, 209, 203, 203, 203, 217, 203, 243, - 203, 243, 203, 275, 203, 253, 253, 203, - 1, 208, 209, 203, 203, 203, 217, 203, - 243, 203, 243, 3, 203, 203, 19, 244, - 203, 1, 208, 209, 203, 203, 203, 217, - 203, 243, 203, 236, 237, 242, 242, 6, - 1, 208, 209, 203, 203, 203, 240, 203, - 203, 211, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 212, - 203, 236, 237, 238, 242, 6, 1, 208, - 209, 203, 203, 32, 240, 203, 203, 211, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 212, 203, 234, - 203, 277, 203, 262, 262, 6, 1, 208, - 209, 203, 203, 203, 217, 203, 234, 203, - 234, 203, 203, 203, 253, 253, 203, 1, - 208, 209, 203, 203, 203, 217, 203, 234, - 203, 234, 203, 203, 203, 253, 278, 203, - 1, 208, 209, 203, 203, 203, 217, 203, - 234, 203, 234, 203, 277, 203, 253, 253, - 203, 1, 208, 209, 203, 203, 203, 217, - 203, 234, 203, 234, 3, 203, 203, 19, - 235, 203, 1, 208, 209, 203, 203, 203, - 217, 203, 234, 203, 227, 228, 233, 233, - 6, 1, 208, 209, 203, 203, 203, 231, - 203, 203, 211, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 212, 203, 227, 228, 229, 233, 6, 1, - 208, 209, 203, 203, 34, 231, 203, 203, - 211, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 212, 203, - 225, 203, 279, 203, 262, 262, 6, 1, - 208, 209, 203, 203, 203, 217, 203, 225, - 203, 225, 203, 203, 203, 253, 253, 203, - 1, 208, 209, 203, 203, 203, 217, 203, - 225, 203, 225, 203, 203, 203, 253, 280, - 203, 1, 208, 209, 203, 203, 203, 217, - 203, 225, 203, 225, 203, 279, 203, 253, - 253, 203, 1, 208, 209, 203, 203, 203, - 217, 203, 225, 203, 225, 3, 203, 203, - 19, 226, 203, 1, 208, 209, 203, 203, - 203, 217, 203, 225, 203, 218, 219, 224, - 224, 6, 1, 208, 209, 203, 203, 203, - 222, 203, 203, 211, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 212, 203, 218, 219, 220, 224, 6, - 1, 208, 209, 203, 203, 36, 222, 203, - 203, 211, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 212, - 203, 215, 203, 281, 203, 262, 262, 6, - 1, 208, 209, 203, 203, 203, 217, 203, - 215, 203, 215, 203, 203, 203, 253, 253, - 203, 1, 208, 209, 203, 203, 203, 217, - 203, 215, 203, 215, 203, 203, 203, 253, - 282, 203, 1, 208, 209, 203, 203, 203, - 217, 203, 215, 203, 215, 203, 281, 203, - 253, 253, 203, 1, 208, 209, 203, 203, - 203, 217, 203, 215, 203, 215, 3, 203, - 203, 19, 216, 203, 1, 208, 209, 203, - 203, 203, 217, 203, 215, 203, 204, 205, - 214, 214, 6, 1, 208, 209, 203, 203, - 203, 210, 203, 203, 211, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 212, 203, 204, 205, 206, 214, - 6, 1, 208, 209, 203, 203, 38, 210, - 203, 203, 211, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 212, 203, 284, 285, 286, 287, 45, 40, - 288, 289, 283, 283, 77, 290, 283, 283, - 291, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 292, 283, - 293, 285, 294, 287, 45, 40, 288, 289, - 283, 283, 283, 290, 283, 283, 291, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 292, 283, 285, 294, - 287, 45, 40, 288, 289, 283, 283, 283, - 290, 283, 283, 291, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 292, 283, 295, 283, 283, 283, 58, - 296, 283, 40, 288, 289, 283, 283, 283, - 297, 283, 295, 283, 298, 299, 300, 301, - 45, 40, 288, 289, 283, 283, 75, 302, - 283, 283, 291, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 292, 283, 303, 299, 304, 304, 45, 40, - 288, 289, 283, 283, 283, 302, 283, 283, - 291, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 292, 283, - 299, 304, 304, 45, 40, 288, 289, 283, - 283, 283, 302, 283, 283, 291, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 292, 283, 305, 283, 283, - 283, 58, 306, 283, 40, 288, 289, 283, - 283, 283, 297, 283, 305, 283, 307, 308, - 309, 310, 45, 40, 288, 289, 283, 283, - 73, 311, 283, 283, 291, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 292, 283, 312, 308, 313, 313, - 45, 40, 288, 289, 283, 283, 283, 311, - 283, 283, 291, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 292, 283, 308, 313, 313, 45, 40, 288, - 289, 283, 283, 283, 311, 283, 283, 291, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 292, 283, 314, - 283, 283, 283, 58, 315, 283, 40, 288, - 289, 283, 283, 283, 297, 283, 314, 283, - 316, 317, 318, 319, 45, 40, 288, 289, - 283, 283, 71, 320, 283, 283, 291, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 292, 283, 321, 317, - 322, 322, 45, 40, 288, 289, 283, 283, - 283, 320, 283, 283, 291, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 292, 283, 317, 322, 322, 45, - 40, 288, 289, 283, 283, 283, 320, 283, - 283, 291, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 292, - 283, 323, 283, 283, 283, 58, 324, 283, - 40, 288, 289, 283, 283, 283, 297, 283, - 323, 283, 325, 326, 327, 328, 45, 40, - 288, 289, 283, 283, 69, 329, 283, 283, - 291, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 292, 283, - 330, 326, 331, 331, 45, 40, 288, 289, - 283, 283, 283, 329, 283, 283, 291, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 292, 283, 326, 331, - 331, 45, 40, 288, 289, 283, 283, 283, - 329, 283, 283, 291, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 292, 283, 58, 332, 283, 40, 288, - 289, 283, 283, 283, 297, 283, 333, 333, - 283, 40, 288, 289, 283, 283, 283, 297, - 283, 334, 283, 283, 335, 288, 289, 283, - 288, 289, 283, 336, 283, 288, 337, 283, - 288, 338, 283, 288, 283, 334, 283, 283, - 283, 288, 289, 283, 339, 283, 340, 341, - 283, 40, 288, 289, 283, 283, 43, 283, - 42, 283, 333, 333, 283, 40, 288, 289, - 283, 333, 333, 283, 40, 288, 289, 283, - 339, 283, 333, 333, 283, 40, 288, 289, - 283, 339, 283, 340, 333, 283, 40, 288, - 289, 283, 283, 43, 283, 58, 283, 342, - 342, 45, 40, 288, 289, 283, 283, 283, - 297, 283, 343, 67, 344, 345, 48, 40, - 288, 289, 283, 283, 283, 297, 283, 67, - 344, 345, 48, 40, 288, 289, 283, 283, - 283, 297, 283, 344, 344, 48, 40, 288, - 289, 283, 283, 283, 297, 283, 346, 64, - 347, 348, 51, 40, 288, 289, 283, 283, - 283, 297, 283, 64, 347, 348, 51, 40, - 288, 289, 283, 283, 283, 297, 283, 347, - 347, 51, 40, 288, 289, 283, 283, 283, - 297, 283, 349, 61, 350, 351, 54, 40, - 288, 289, 283, 283, 283, 297, 283, 61, - 350, 351, 54, 40, 288, 289, 283, 283, - 283, 297, 283, 350, 350, 54, 40, 288, - 289, 283, 283, 283, 297, 283, 352, 58, - 333, 353, 283, 40, 288, 289, 283, 283, - 283, 297, 283, 58, 333, 353, 283, 40, - 288, 289, 283, 283, 283, 297, 283, 333, - 354, 283, 40, 288, 289, 283, 283, 283, - 297, 283, 58, 283, 333, 333, 283, 40, - 288, 289, 283, 283, 283, 297, 283, 41, - 42, 283, 283, 58, 332, 283, 40, 288, - 289, 283, 283, 283, 297, 283, 41, 283, - 326, 331, 331, 45, 40, 288, 289, 283, - 283, 283, 329, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 292, 283, 326, 331, 331, - 45, 40, 288, 289, 283, 283, 283, 329, - 283, 325, 326, 331, 331, 45, 40, 288, - 289, 283, 283, 283, 329, 283, 283, 291, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 292, 283, 325, - 326, 327, 331, 45, 40, 288, 289, 283, - 283, 69, 329, 283, 283, 291, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 292, 283, 323, 283, 355, - 283, 342, 342, 45, 40, 288, 289, 283, - 283, 283, 297, 283, 323, 283, 323, 283, - 283, 283, 333, 333, 283, 40, 288, 289, - 283, 283, 283, 297, 283, 323, 283, 323, - 283, 283, 283, 333, 356, 283, 40, 288, - 289, 283, 283, 283, 297, 283, 323, 283, - 323, 283, 355, 283, 333, 333, 283, 40, - 288, 289, 283, 283, 283, 297, 283, 323, - 283, 323, 42, 283, 283, 58, 324, 283, - 40, 288, 289, 283, 283, 283, 297, 283, - 323, 283, 316, 317, 322, 322, 45, 40, - 288, 289, 283, 283, 283, 320, 283, 283, - 291, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 292, 283, - 316, 317, 318, 322, 45, 40, 288, 289, - 283, 283, 71, 320, 283, 283, 291, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 292, 283, 314, 283, - 357, 283, 342, 342, 45, 40, 288, 289, - 283, 283, 283, 297, 283, 314, 283, 314, - 283, 283, 283, 333, 333, 283, 40, 288, - 289, 283, 283, 283, 297, 283, 314, 283, - 314, 283, 283, 283, 333, 358, 283, 40, - 288, 289, 283, 283, 283, 297, 283, 314, - 283, 314, 283, 357, 283, 333, 333, 283, - 40, 288, 289, 283, 283, 283, 297, 283, - 314, 283, 314, 42, 283, 283, 58, 315, - 283, 40, 288, 289, 283, 283, 283, 297, - 283, 314, 283, 307, 308, 313, 313, 45, - 40, 288, 289, 283, 283, 283, 311, 283, - 283, 291, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 292, - 283, 307, 308, 309, 313, 45, 40, 288, - 289, 283, 283, 73, 311, 283, 283, 291, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 292, 283, 305, - 283, 359, 283, 342, 342, 45, 40, 288, - 289, 283, 283, 283, 297, 283, 305, 283, - 305, 283, 283, 283, 333, 333, 283, 40, - 288, 289, 283, 283, 283, 297, 283, 305, - 283, 305, 283, 283, 283, 333, 360, 283, - 40, 288, 289, 283, 283, 283, 297, 283, - 305, 283, 305, 283, 359, 283, 333, 333, - 283, 40, 288, 289, 283, 283, 283, 297, - 283, 305, 283, 305, 42, 283, 283, 58, - 306, 283, 40, 288, 289, 283, 283, 283, - 297, 283, 305, 283, 298, 299, 304, 304, - 45, 40, 288, 289, 283, 283, 283, 302, - 283, 283, 291, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 292, 283, 298, 299, 300, 304, 45, 40, - 288, 289, 283, 283, 75, 302, 283, 283, - 291, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 292, 283, - 295, 283, 361, 283, 342, 342, 45, 40, - 288, 289, 283, 283, 283, 297, 283, 295, - 283, 295, 283, 283, 283, 333, 333, 283, - 40, 288, 289, 283, 283, 283, 297, 283, - 295, 283, 295, 283, 283, 283, 333, 362, - 283, 40, 288, 289, 283, 283, 283, 297, - 283, 295, 283, 295, 283, 361, 283, 333, - 333, 283, 40, 288, 289, 283, 283, 283, - 297, 283, 295, 283, 76, 44, 44, 45, - 40, 283, 283, 283, 283, 283, 76, 283, - 295, 42, 283, 283, 58, 296, 283, 40, - 288, 289, 283, 283, 283, 297, 283, 295, - 283, 284, 285, 294, 287, 45, 40, 288, - 289, 283, 283, 283, 290, 283, 283, 291, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 292, 283, 364, - 191, 365, 365, 84, 79, 194, 195, 363, - 363, 363, 197, 363, 363, 200, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 202, 363, 191, 365, 365, - 84, 79, 194, 195, 363, 363, 363, 197, - 363, 363, 200, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 202, 363, 366, 363, 363, 363, 98, 367, - 363, 79, 194, 195, 363, 363, 363, 368, - 363, 366, 363, 369, 370, 371, 372, 84, - 79, 194, 195, 363, 363, 115, 373, 363, - 363, 200, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 202, - 363, 374, 370, 375, 375, 84, 79, 194, - 195, 363, 363, 363, 373, 363, 363, 200, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 202, 363, 370, - 375, 375, 84, 79, 194, 195, 363, 363, - 363, 373, 363, 363, 200, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 202, 363, 376, 363, 363, 363, - 98, 377, 363, 79, 194, 195, 363, 363, - 363, 368, 363, 376, 363, 378, 379, 380, - 381, 84, 79, 194, 195, 363, 363, 113, - 382, 363, 363, 200, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 202, 363, 383, 379, 384, 384, 84, - 79, 194, 195, 363, 363, 363, 382, 363, - 363, 200, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 202, - 363, 379, 384, 384, 84, 79, 194, 195, - 363, 363, 363, 382, 363, 363, 200, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 202, 363, 385, 363, - 363, 363, 98, 386, 363, 79, 194, 195, - 363, 363, 363, 368, 363, 385, 363, 387, - 388, 389, 390, 84, 79, 194, 195, 363, - 363, 111, 391, 363, 363, 200, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 202, 363, 392, 388, 393, - 393, 84, 79, 194, 195, 363, 363, 363, - 391, 363, 363, 200, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 202, 363, 388, 393, 393, 84, 79, - 194, 195, 363, 363, 363, 391, 363, 363, - 200, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 202, 363, - 394, 363, 363, 363, 98, 395, 363, 79, - 194, 195, 363, 363, 363, 368, 363, 394, - 363, 396, 397, 398, 399, 84, 79, 194, - 195, 363, 363, 109, 400, 363, 363, 200, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 202, 363, 401, - 397, 402, 402, 84, 79, 194, 195, 363, - 363, 363, 400, 363, 363, 200, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 202, 363, 397, 402, 402, - 84, 79, 194, 195, 363, 363, 363, 400, - 363, 363, 200, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 202, 363, 98, 403, 363, 79, 194, 195, - 363, 363, 363, 368, 363, 404, 404, 363, - 79, 194, 195, 363, 363, 363, 368, 363, - 405, 363, 363, 406, 194, 195, 363, 194, - 195, 363, 407, 363, 194, 408, 363, 194, - 409, 363, 194, 363, 405, 363, 363, 363, - 194, 195, 363, 410, 363, 411, 412, 363, - 79, 194, 195, 363, 363, 82, 363, 81, - 363, 404, 404, 363, 79, 194, 195, 363, - 404, 404, 363, 79, 194, 195, 363, 410, - 363, 404, 404, 363, 79, 194, 195, 363, - 410, 363, 411, 404, 363, 79, 194, 195, - 363, 363, 82, 363, 98, 363, 413, 413, - 84, 79, 194, 195, 363, 363, 363, 368, - 363, 414, 107, 415, 416, 88, 79, 194, - 195, 363, 363, 363, 368, 363, 107, 415, - 416, 88, 79, 194, 195, 363, 363, 363, - 368, 363, 415, 415, 88, 79, 194, 195, - 363, 363, 363, 368, 363, 417, 104, 418, - 419, 91, 79, 194, 195, 363, 363, 363, - 368, 363, 104, 418, 419, 91, 79, 194, - 195, 363, 363, 363, 368, 363, 418, 418, - 91, 79, 194, 195, 363, 363, 363, 368, - 363, 420, 101, 421, 422, 94, 79, 194, - 195, 363, 363, 363, 368, 363, 101, 421, - 422, 94, 79, 194, 195, 363, 363, 363, - 368, 363, 421, 421, 94, 79, 194, 195, - 363, 363, 363, 368, 363, 423, 98, 404, - 424, 363, 79, 194, 195, 363, 363, 363, - 368, 363, 98, 404, 424, 363, 79, 194, - 195, 363, 363, 363, 368, 363, 404, 425, - 363, 79, 194, 195, 363, 363, 363, 368, - 363, 98, 363, 404, 404, 363, 79, 194, - 195, 363, 363, 363, 368, 363, 80, 81, - 363, 363, 98, 403, 363, 79, 194, 195, - 363, 363, 363, 368, 363, 80, 363, 397, - 402, 402, 84, 79, 194, 195, 363, 363, - 363, 400, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 202, 363, 397, 402, 402, 84, - 79, 194, 195, 363, 363, 363, 400, 363, - 396, 397, 402, 402, 84, 79, 194, 195, - 363, 363, 363, 400, 363, 363, 200, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 202, 363, 396, 397, - 398, 402, 84, 79, 194, 195, 363, 363, - 109, 400, 363, 363, 200, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 202, 363, 394, 363, 426, 363, - 413, 413, 84, 79, 194, 195, 363, 363, - 363, 368, 363, 394, 363, 394, 363, 363, - 363, 404, 404, 363, 79, 194, 195, 363, - 363, 363, 368, 363, 394, 363, 394, 363, - 363, 363, 404, 427, 363, 79, 194, 195, - 363, 363, 363, 368, 363, 394, 363, 394, - 363, 426, 363, 404, 404, 363, 79, 194, - 195, 363, 363, 363, 368, 363, 394, 363, - 394, 81, 363, 363, 98, 395, 363, 79, - 194, 195, 363, 363, 363, 368, 363, 394, - 363, 387, 388, 393, 393, 84, 79, 194, - 195, 363, 363, 363, 391, 363, 363, 200, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 202, 363, 387, - 388, 389, 393, 84, 79, 194, 195, 363, - 363, 111, 391, 363, 363, 200, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 202, 363, 385, 363, 428, - 363, 413, 413, 84, 79, 194, 195, 363, - 363, 363, 368, 363, 385, 363, 385, 363, - 363, 363, 404, 404, 363, 79, 194, 195, - 363, 363, 363, 368, 363, 385, 363, 385, - 363, 363, 363, 404, 429, 363, 79, 194, - 195, 363, 363, 363, 368, 363, 385, 363, - 385, 363, 428, 363, 404, 404, 363, 79, - 194, 195, 363, 363, 363, 368, 363, 385, - 363, 385, 81, 363, 363, 98, 386, 363, - 79, 194, 195, 363, 363, 363, 368, 363, - 385, 363, 378, 379, 384, 384, 84, 79, - 194, 195, 363, 363, 363, 382, 363, 363, - 200, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 202, 363, - 378, 379, 380, 384, 84, 79, 194, 195, - 363, 363, 113, 382, 363, 363, 200, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 202, 363, 376, 363, - 430, 363, 413, 413, 84, 79, 194, 195, - 363, 363, 363, 368, 363, 376, 363, 376, - 363, 363, 363, 404, 404, 363, 79, 194, - 195, 363, 363, 363, 368, 363, 376, 363, - 376, 363, 363, 363, 404, 431, 363, 79, - 194, 195, 363, 363, 363, 368, 363, 376, - 363, 376, 363, 430, 363, 404, 404, 363, - 79, 194, 195, 363, 363, 363, 368, 363, - 376, 363, 376, 81, 363, 363, 98, 377, - 363, 79, 194, 195, 363, 363, 363, 368, - 363, 376, 363, 369, 370, 375, 375, 84, - 79, 194, 195, 363, 363, 363, 373, 363, - 363, 200, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 202, - 363, 369, 370, 371, 375, 84, 79, 194, - 195, 363, 363, 115, 373, 363, 363, 200, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 202, 363, 366, - 363, 432, 363, 413, 413, 84, 79, 194, - 195, 363, 363, 363, 368, 363, 366, 363, - 366, 363, 363, 363, 404, 404, 363, 79, - 194, 195, 363, 363, 363, 368, 363, 366, - 363, 366, 363, 363, 363, 404, 433, 363, - 79, 194, 195, 363, 363, 363, 368, 363, - 366, 363, 366, 363, 432, 363, 404, 404, - 363, 79, 194, 195, 363, 363, 363, 368, - 363, 366, 363, 366, 81, 363, 363, 98, - 367, 363, 79, 194, 195, 363, 363, 363, - 368, 363, 366, 363, 116, 83, 83, 84, - 79, 434, 434, 434, 434, 156, 116, 434, - 190, 191, 365, 365, 84, 79, 194, 195, - 363, 363, 363, 197, 363, 363, 200, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 363, 363, 363, 202, 363, 116, 83, - 83, 84, 79, 434, 434, 434, 434, 434, - 116, 434, 436, 437, 438, 439, 123, 118, - 440, 441, 435, 435, 155, 442, 435, 435, - 443, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 444, 435, - 445, 437, 439, 439, 123, 118, 440, 441, - 435, 435, 435, 442, 435, 435, 443, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 444, 435, 437, 439, - 439, 123, 118, 440, 441, 435, 435, 435, - 442, 435, 435, 443, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 444, 435, 446, 435, 435, 435, 136, - 447, 435, 118, 440, 441, 435, 435, 435, - 448, 435, 446, 435, 449, 450, 451, 452, - 123, 118, 440, 441, 435, 435, 153, 453, - 435, 435, 443, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 444, 435, 454, 450, 455, 455, 123, 118, - 440, 441, 435, 435, 435, 453, 435, 435, - 443, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 444, 435, - 450, 455, 455, 123, 118, 440, 441, 435, - 435, 435, 453, 435, 435, 443, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 444, 435, 456, 435, 435, - 435, 136, 457, 435, 118, 440, 441, 435, - 435, 435, 448, 435, 456, 435, 458, 459, - 460, 461, 123, 118, 440, 441, 435, 435, - 151, 462, 435, 435, 443, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 444, 435, 463, 459, 464, 464, - 123, 118, 440, 441, 435, 435, 435, 462, - 435, 435, 443, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 444, 435, 459, 464, 464, 123, 118, 440, - 441, 435, 435, 435, 462, 435, 435, 443, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 444, 435, 465, - 435, 435, 435, 136, 466, 435, 118, 440, - 441, 435, 435, 435, 448, 435, 465, 435, - 467, 468, 469, 470, 123, 118, 440, 441, - 435, 435, 149, 471, 435, 435, 443, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 444, 435, 472, 468, - 473, 473, 123, 118, 440, 441, 435, 435, - 435, 471, 435, 435, 443, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 444, 435, 468, 473, 473, 123, - 118, 440, 441, 435, 435, 435, 471, 435, - 435, 443, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 444, - 435, 474, 435, 435, 435, 136, 475, 435, - 118, 440, 441, 435, 435, 435, 448, 435, - 474, 435, 476, 477, 478, 479, 123, 118, - 440, 441, 435, 435, 147, 480, 435, 435, - 443, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 444, 435, - 481, 477, 482, 482, 123, 118, 440, 441, - 435, 435, 435, 480, 435, 435, 443, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 444, 435, 477, 482, - 482, 123, 118, 440, 441, 435, 435, 435, - 480, 435, 435, 443, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 444, 435, 136, 483, 435, 118, 440, - 441, 435, 435, 435, 448, 435, 484, 484, - 435, 118, 440, 441, 435, 435, 435, 448, - 435, 485, 435, 435, 486, 440, 441, 435, - 440, 441, 435, 487, 435, 440, 488, 435, - 440, 489, 435, 440, 435, 485, 435, 435, - 435, 440, 441, 435, 490, 435, 491, 492, - 435, 118, 440, 441, 435, 435, 121, 435, - 120, 435, 484, 484, 435, 118, 440, 441, - 435, 484, 484, 435, 118, 440, 441, 435, - 490, 435, 484, 484, 435, 118, 440, 441, - 435, 490, 435, 491, 484, 435, 118, 440, - 441, 435, 435, 121, 435, 136, 435, 493, - 493, 123, 118, 440, 441, 435, 435, 435, - 448, 435, 494, 145, 495, 496, 126, 118, - 440, 441, 435, 435, 435, 448, 435, 145, - 495, 496, 126, 118, 440, 441, 435, 435, - 435, 448, 435, 495, 495, 126, 118, 440, - 441, 435, 435, 435, 448, 435, 497, 142, - 498, 499, 129, 118, 440, 441, 435, 435, - 435, 448, 435, 142, 498, 499, 129, 118, - 440, 441, 435, 435, 435, 448, 435, 498, - 498, 129, 118, 440, 441, 435, 435, 435, - 448, 435, 500, 139, 501, 502, 132, 118, - 440, 441, 435, 435, 435, 448, 435, 139, - 501, 502, 132, 118, 440, 441, 435, 435, - 435, 448, 435, 501, 501, 132, 118, 440, - 441, 435, 435, 435, 448, 435, 503, 136, - 484, 504, 435, 118, 440, 441, 435, 435, - 435, 448, 435, 136, 484, 504, 435, 118, - 440, 441, 435, 435, 435, 448, 435, 484, - 505, 435, 118, 440, 441, 435, 435, 435, - 448, 435, 136, 435, 484, 484, 435, 118, - 440, 441, 435, 435, 435, 448, 435, 119, - 120, 435, 435, 136, 483, 435, 118, 440, - 441, 435, 435, 435, 448, 435, 119, 435, - 477, 482, 482, 123, 118, 440, 441, 435, - 435, 435, 480, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 444, 435, 477, 482, 482, - 123, 118, 440, 441, 435, 435, 435, 480, - 435, 476, 477, 482, 482, 123, 118, 440, - 441, 435, 435, 435, 480, 435, 435, 443, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 444, 435, 476, - 477, 478, 482, 123, 118, 440, 441, 435, - 435, 147, 480, 435, 435, 443, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 444, 435, 474, 435, 506, - 435, 493, 493, 123, 118, 440, 441, 435, - 435, 435, 448, 435, 474, 435, 474, 435, - 435, 435, 484, 484, 435, 118, 440, 441, - 435, 435, 435, 448, 435, 474, 435, 474, - 435, 435, 435, 484, 507, 435, 118, 440, - 441, 435, 435, 435, 448, 435, 474, 435, - 474, 435, 506, 435, 484, 484, 435, 118, - 440, 441, 435, 435, 435, 448, 435, 474, - 435, 474, 120, 435, 435, 136, 475, 435, - 118, 440, 441, 435, 435, 435, 448, 435, - 474, 435, 467, 468, 473, 473, 123, 118, - 440, 441, 435, 435, 435, 471, 435, 435, - 443, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 444, 435, - 467, 468, 469, 473, 123, 118, 440, 441, - 435, 435, 149, 471, 435, 435, 443, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 444, 435, 465, 435, - 508, 435, 493, 493, 123, 118, 440, 441, - 435, 435, 435, 448, 435, 465, 435, 465, - 435, 435, 435, 484, 484, 435, 118, 440, - 441, 435, 435, 435, 448, 435, 465, 435, - 465, 435, 435, 435, 484, 509, 435, 118, - 440, 441, 435, 435, 435, 448, 435, 465, - 435, 465, 435, 508, 435, 484, 484, 435, - 118, 440, 441, 435, 435, 435, 448, 435, - 465, 435, 465, 120, 435, 435, 136, 466, - 435, 118, 440, 441, 435, 435, 435, 448, - 435, 465, 435, 458, 459, 464, 464, 123, - 118, 440, 441, 435, 435, 435, 462, 435, - 435, 443, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 444, - 435, 458, 459, 460, 464, 123, 118, 440, - 441, 435, 435, 151, 462, 435, 435, 443, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 444, 435, 456, - 435, 510, 435, 493, 493, 123, 118, 440, - 441, 435, 435, 435, 448, 435, 456, 435, - 456, 435, 435, 435, 484, 484, 435, 118, - 440, 441, 435, 435, 435, 448, 435, 456, - 435, 456, 435, 435, 435, 484, 511, 435, - 118, 440, 441, 435, 435, 435, 448, 435, - 456, 435, 456, 435, 510, 435, 484, 484, - 435, 118, 440, 441, 435, 435, 435, 448, - 435, 456, 435, 456, 120, 435, 435, 136, - 457, 435, 118, 440, 441, 435, 435, 435, - 448, 435, 456, 435, 449, 450, 455, 455, - 123, 118, 440, 441, 435, 435, 435, 453, - 435, 435, 443, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 444, 435, 449, 450, 451, 455, 123, 118, - 440, 441, 435, 435, 153, 453, 435, 435, - 443, 435, 435, 435, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 444, 435, - 446, 435, 512, 435, 493, 493, 123, 118, - 440, 441, 435, 435, 435, 448, 435, 446, - 435, 446, 435, 435, 435, 484, 484, 435, - 118, 440, 441, 435, 435, 435, 448, 435, - 446, 435, 446, 435, 435, 435, 484, 513, - 435, 118, 440, 441, 435, 435, 435, 448, - 435, 446, 435, 446, 435, 512, 435, 484, - 484, 435, 118, 440, 441, 435, 435, 435, - 448, 435, 446, 435, 446, 120, 435, 435, - 136, 447, 435, 118, 440, 441, 435, 435, - 435, 448, 435, 446, 435, 436, 437, 439, - 439, 123, 118, 440, 441, 435, 435, 435, - 442, 435, 435, 443, 435, 435, 435, 435, - 435, 435, 435, 435, 435, 435, 435, 435, - 435, 444, 435, 188, 189, 190, 191, 514, - 365, 84, 79, 194, 195, 196, 196, 156, - 197, 363, 188, 200, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 363, 363, 363, - 363, 202, 363, 204, 515, 206, 207, 6, - 1, 208, 209, 203, 203, 38, 210, 203, - 203, 211, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 212, - 203, 215, 189, 190, 191, 516, 517, 84, - 157, 518, 519, 203, 196, 156, 520, 203, - 215, 200, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 202, - 203, 116, 521, 521, 84, 157, 208, 209, - 203, 203, 156, 522, 203, 523, 203, 203, - 524, 518, 519, 203, 518, 519, 203, 256, - 203, 518, 525, 203, 518, 526, 203, 518, - 203, 523, 203, 203, 203, 518, 519, 203, - 527, 3, 363, 363, 404, 433, 363, 79, - 194, 195, 363, 363, 363, 368, 363, 527, - 363, 528, 370, 529, 530, 84, 157, 518, - 519, 203, 203, 158, 373, 203, 203, 200, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 202, 203, 531, - 370, 532, 532, 84, 157, 518, 519, 203, - 203, 203, 373, 203, 203, 200, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 202, 203, 370, 532, 532, - 84, 157, 518, 519, 203, 203, 203, 373, - 203, 203, 200, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 202, 203, 528, 370, 532, 532, 84, 157, - 518, 519, 203, 203, 203, 373, 203, 203, - 200, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 202, 203, - 528, 370, 529, 532, 84, 157, 518, 519, - 203, 203, 158, 373, 203, 203, 200, 203, - 203, 203, 203, 203, 203, 203, 203, 203, - 203, 203, 203, 203, 202, 203, 215, 203, - 281, 116, 533, 533, 160, 157, 208, 209, - 203, 203, 203, 522, 203, 215, 203, 534, - 184, 535, 536, 162, 157, 518, 519, 203, - 203, 203, 537, 203, 184, 535, 536, 162, - 157, 518, 519, 203, 203, 203, 537, 203, - 535, 535, 162, 157, 518, 519, 203, 203, - 203, 537, 203, 538, 181, 539, 540, 165, - 157, 518, 519, 203, 203, 203, 537, 203, - 181, 539, 540, 165, 157, 518, 519, 203, - 203, 203, 537, 203, 539, 539, 165, 157, - 518, 519, 203, 203, 203, 537, 203, 541, - 178, 542, 543, 168, 157, 518, 519, 203, - 203, 203, 537, 203, 178, 542, 543, 168, - 157, 518, 519, 203, 203, 203, 537, 203, - 542, 542, 168, 157, 518, 519, 203, 203, - 203, 537, 203, 544, 175, 545, 546, 203, - 157, 518, 519, 203, 203, 203, 537, 203, - 175, 545, 546, 203, 157, 518, 519, 203, - 203, 203, 537, 203, 545, 545, 203, 157, - 518, 519, 203, 203, 203, 537, 203, 547, - 203, 548, 549, 203, 157, 518, 519, 203, - 203, 172, 203, 171, 203, 545, 545, 203, - 157, 518, 519, 203, 545, 545, 203, 157, - 518, 519, 203, 547, 203, 545, 545, 203, - 157, 518, 519, 203, 547, 203, 548, 545, - 203, 157, 518, 519, 203, 203, 172, 203, - 527, 171, 363, 363, 98, 367, 363, 79, - 194, 195, 363, 363, 363, 368, 363, 527, - 363, 551, 550, 552, 552, 550, 186, 553, - 554, 550, 552, 552, 550, 186, 553, 554, - 550, 555, 550, 550, 556, 553, 554, 550, - 553, 554, 550, 557, 550, 553, 558, 550, - 553, 559, 550, 553, 550, 555, 550, 550, - 550, 553, 554, 550, 0 + 197, 198, 199, 200, 201, 187, 203, 204, + 205, 206, 6, 1, 207, 208, 202, 202, + 38, 209, 202, 202, 210, 202, 211, 204, + 212, 212, 6, 1, 207, 208, 202, 202, + 202, 209, 202, 202, 210, 202, 204, 212, + 212, 6, 1, 207, 208, 202, 202, 202, + 209, 202, 202, 210, 202, 213, 202, 202, + 202, 19, 214, 202, 1, 207, 208, 202, + 202, 202, 215, 202, 213, 202, 216, 217, + 218, 219, 6, 1, 207, 208, 202, 202, + 36, 220, 202, 202, 210, 202, 221, 217, + 222, 222, 6, 1, 207, 208, 202, 202, + 202, 220, 202, 202, 210, 202, 217, 222, + 222, 6, 1, 207, 208, 202, 202, 202, + 220, 202, 202, 210, 202, 223, 202, 202, + 202, 19, 224, 202, 1, 207, 208, 202, + 202, 202, 215, 202, 223, 202, 225, 226, + 227, 228, 6, 1, 207, 208, 202, 202, + 34, 229, 202, 202, 210, 202, 230, 226, + 231, 231, 6, 1, 207, 208, 202, 202, + 202, 229, 202, 202, 210, 202, 226, 231, + 231, 6, 1, 207, 208, 202, 202, 202, + 229, 202, 202, 210, 202, 232, 202, 202, + 202, 19, 233, 202, 1, 207, 208, 202, + 202, 202, 215, 202, 232, 202, 234, 235, + 236, 237, 6, 1, 207, 208, 202, 202, + 32, 238, 202, 202, 210, 202, 239, 235, + 240, 240, 6, 1, 207, 208, 202, 202, + 202, 238, 202, 202, 210, 202, 235, 240, + 240, 6, 1, 207, 208, 202, 202, 202, + 238, 202, 202, 210, 202, 241, 202, 202, + 202, 19, 242, 202, 1, 207, 208, 202, + 202, 202, 215, 202, 241, 202, 243, 244, + 245, 246, 6, 1, 207, 208, 202, 202, + 30, 247, 202, 202, 210, 202, 248, 244, + 249, 249, 6, 1, 207, 208, 202, 202, + 202, 247, 202, 202, 210, 202, 244, 249, + 249, 6, 1, 207, 208, 202, 202, 202, + 247, 202, 202, 210, 202, 19, 250, 202, + 1, 207, 208, 202, 202, 202, 215, 202, + 251, 251, 202, 1, 207, 208, 202, 202, + 202, 215, 202, 252, 202, 202, 253, 207, + 208, 202, 207, 208, 202, 254, 202, 207, + 255, 202, 207, 256, 202, 207, 202, 252, + 202, 202, 202, 207, 208, 202, 257, 202, + 258, 259, 202, 1, 207, 208, 202, 202, + 4, 202, 3, 202, 251, 251, 202, 1, + 207, 208, 202, 251, 251, 202, 1, 207, + 208, 202, 257, 202, 251, 251, 202, 1, + 207, 208, 202, 257, 202, 258, 251, 202, + 1, 207, 208, 202, 202, 4, 202, 19, + 202, 260, 260, 6, 1, 207, 208, 202, + 202, 202, 215, 202, 261, 28, 262, 263, + 9, 1, 207, 208, 202, 202, 202, 215, + 202, 28, 262, 263, 9, 1, 207, 208, + 202, 202, 202, 215, 202, 262, 262, 9, + 1, 207, 208, 202, 202, 202, 215, 202, + 264, 25, 265, 266, 12, 1, 207, 208, + 202, 202, 202, 215, 202, 25, 265, 266, + 12, 1, 207, 208, 202, 202, 202, 215, + 202, 265, 265, 12, 1, 207, 208, 202, + 202, 202, 215, 202, 267, 22, 268, 269, + 15, 1, 207, 208, 202, 202, 202, 215, + 202, 22, 268, 269, 15, 1, 207, 208, + 202, 202, 202, 215, 202, 268, 268, 15, + 1, 207, 208, 202, 202, 202, 215, 202, + 270, 19, 251, 271, 202, 1, 207, 208, + 202, 202, 202, 215, 202, 19, 251, 271, + 202, 1, 207, 208, 202, 202, 202, 215, + 202, 251, 272, 202, 1, 207, 208, 202, + 202, 202, 215, 202, 19, 202, 251, 251, + 202, 1, 207, 208, 202, 202, 202, 215, + 202, 2, 3, 202, 202, 19, 250, 202, + 1, 207, 208, 202, 202, 202, 215, 202, + 2, 202, 244, 249, 249, 6, 1, 207, + 208, 202, 202, 202, 247, 202, 243, 244, + 249, 249, 6, 1, 207, 208, 202, 202, + 202, 247, 202, 202, 210, 202, 243, 244, + 245, 249, 6, 1, 207, 208, 202, 202, + 30, 247, 202, 202, 210, 202, 241, 202, + 273, 202, 260, 260, 6, 1, 207, 208, + 202, 202, 202, 215, 202, 241, 202, 241, + 202, 202, 202, 251, 251, 202, 1, 207, + 208, 202, 202, 202, 215, 202, 241, 202, + 241, 202, 202, 202, 251, 274, 202, 1, + 207, 208, 202, 202, 202, 215, 202, 241, + 202, 241, 202, 273, 202, 251, 251, 202, + 1, 207, 208, 202, 202, 202, 215, 202, + 241, 202, 241, 3, 202, 202, 19, 242, + 202, 1, 207, 208, 202, 202, 202, 215, + 202, 241, 202, 234, 235, 240, 240, 6, + 1, 207, 208, 202, 202, 202, 238, 202, + 202, 210, 202, 234, 235, 236, 240, 6, + 1, 207, 208, 202, 202, 32, 238, 202, + 202, 210, 202, 232, 202, 275, 202, 260, + 260, 6, 1, 207, 208, 202, 202, 202, + 215, 202, 232, 202, 232, 202, 202, 202, + 251, 251, 202, 1, 207, 208, 202, 202, + 202, 215, 202, 232, 202, 232, 202, 202, + 202, 251, 276, 202, 1, 207, 208, 202, + 202, 202, 215, 202, 232, 202, 232, 202, + 275, 202, 251, 251, 202, 1, 207, 208, + 202, 202, 202, 215, 202, 232, 202, 232, + 3, 202, 202, 19, 233, 202, 1, 207, + 208, 202, 202, 202, 215, 202, 232, 202, + 225, 226, 231, 231, 6, 1, 207, 208, + 202, 202, 202, 229, 202, 202, 210, 202, + 225, 226, 227, 231, 6, 1, 207, 208, + 202, 202, 34, 229, 202, 202, 210, 202, + 223, 202, 277, 202, 260, 260, 6, 1, + 207, 208, 202, 202, 202, 215, 202, 223, + 202, 223, 202, 202, 202, 251, 251, 202, + 1, 207, 208, 202, 202, 202, 215, 202, + 223, 202, 223, 202, 202, 202, 251, 278, + 202, 1, 207, 208, 202, 202, 202, 215, + 202, 223, 202, 223, 202, 277, 202, 251, + 251, 202, 1, 207, 208, 202, 202, 202, + 215, 202, 223, 202, 223, 3, 202, 202, + 19, 224, 202, 1, 207, 208, 202, 202, + 202, 215, 202, 223, 202, 216, 217, 222, + 222, 6, 1, 207, 208, 202, 202, 202, + 220, 202, 202, 210, 202, 216, 217, 218, + 222, 6, 1, 207, 208, 202, 202, 36, + 220, 202, 202, 210, 202, 213, 202, 279, + 202, 260, 260, 6, 1, 207, 208, 202, + 202, 202, 215, 202, 213, 202, 213, 202, + 202, 202, 251, 251, 202, 1, 207, 208, + 202, 202, 202, 215, 202, 213, 202, 213, + 202, 202, 202, 251, 280, 202, 1, 207, + 208, 202, 202, 202, 215, 202, 213, 202, + 213, 202, 279, 202, 251, 251, 202, 1, + 207, 208, 202, 202, 202, 215, 202, 213, + 202, 213, 3, 202, 202, 19, 214, 202, + 1, 207, 208, 202, 202, 202, 215, 202, + 213, 202, 203, 204, 212, 212, 6, 1, + 207, 208, 202, 202, 202, 209, 202, 202, + 210, 202, 203, 204, 205, 212, 6, 1, + 207, 208, 202, 202, 38, 209, 202, 202, + 210, 202, 282, 283, 284, 285, 45, 40, + 286, 287, 281, 281, 77, 288, 281, 281, + 289, 281, 290, 283, 291, 285, 45, 40, + 286, 287, 281, 281, 281, 288, 281, 281, + 289, 281, 283, 291, 285, 45, 40, 286, + 287, 281, 281, 281, 288, 281, 281, 289, + 281, 292, 281, 281, 281, 58, 293, 281, + 40, 286, 287, 281, 281, 281, 294, 281, + 292, 281, 295, 296, 297, 298, 45, 40, + 286, 287, 281, 281, 75, 299, 281, 281, + 289, 281, 300, 296, 301, 301, 45, 40, + 286, 287, 281, 281, 281, 299, 281, 281, + 289, 281, 296, 301, 301, 45, 40, 286, + 287, 281, 281, 281, 299, 281, 281, 289, + 281, 302, 281, 281, 281, 58, 303, 281, + 40, 286, 287, 281, 281, 281, 294, 281, + 302, 281, 304, 305, 306, 307, 45, 40, + 286, 287, 281, 281, 73, 308, 281, 281, + 289, 281, 309, 305, 310, 310, 45, 40, + 286, 287, 281, 281, 281, 308, 281, 281, + 289, 281, 305, 310, 310, 45, 40, 286, + 287, 281, 281, 281, 308, 281, 281, 289, + 281, 311, 281, 281, 281, 58, 312, 281, + 40, 286, 287, 281, 281, 281, 294, 281, + 311, 281, 313, 314, 315, 316, 45, 40, + 286, 287, 281, 281, 71, 317, 281, 281, + 289, 281, 318, 314, 319, 319, 45, 40, + 286, 287, 281, 281, 281, 317, 281, 281, + 289, 281, 314, 319, 319, 45, 40, 286, + 287, 281, 281, 281, 317, 281, 281, 289, + 281, 320, 281, 281, 281, 58, 321, 281, + 40, 286, 287, 281, 281, 281, 294, 281, + 320, 281, 322, 323, 324, 325, 45, 40, + 286, 287, 281, 281, 69, 326, 281, 281, + 289, 281, 327, 323, 328, 328, 45, 40, + 286, 287, 281, 281, 281, 326, 281, 281, + 289, 281, 323, 328, 328, 45, 40, 286, + 287, 281, 281, 281, 326, 281, 281, 289, + 281, 58, 329, 281, 40, 286, 287, 281, + 281, 281, 294, 281, 330, 330, 281, 40, + 286, 287, 281, 281, 281, 294, 281, 331, + 281, 281, 332, 286, 287, 281, 286, 287, + 281, 333, 281, 286, 334, 281, 286, 335, + 281, 286, 281, 331, 281, 281, 281, 286, + 287, 281, 336, 281, 337, 338, 281, 40, + 286, 287, 281, 281, 43, 281, 42, 281, + 330, 330, 281, 40, 286, 287, 281, 330, + 330, 281, 40, 286, 287, 281, 336, 281, + 330, 330, 281, 40, 286, 287, 281, 336, + 281, 337, 330, 281, 40, 286, 287, 281, + 281, 43, 281, 58, 281, 339, 339, 45, + 40, 286, 287, 281, 281, 281, 294, 281, + 340, 67, 341, 342, 48, 40, 286, 287, + 281, 281, 281, 294, 281, 67, 341, 342, + 48, 40, 286, 287, 281, 281, 281, 294, + 281, 341, 341, 48, 40, 286, 287, 281, + 281, 281, 294, 281, 343, 64, 344, 345, + 51, 40, 286, 287, 281, 281, 281, 294, + 281, 64, 344, 345, 51, 40, 286, 287, + 281, 281, 281, 294, 281, 344, 344, 51, + 40, 286, 287, 281, 281, 281, 294, 281, + 346, 61, 347, 348, 54, 40, 286, 287, + 281, 281, 281, 294, 281, 61, 347, 348, + 54, 40, 286, 287, 281, 281, 281, 294, + 281, 347, 347, 54, 40, 286, 287, 281, + 281, 281, 294, 281, 349, 58, 330, 350, + 281, 40, 286, 287, 281, 281, 281, 294, + 281, 58, 330, 350, 281, 40, 286, 287, + 281, 281, 281, 294, 281, 330, 351, 281, + 40, 286, 287, 281, 281, 281, 294, 281, + 58, 281, 330, 330, 281, 40, 286, 287, + 281, 281, 281, 294, 281, 41, 42, 281, + 281, 58, 329, 281, 40, 286, 287, 281, + 281, 281, 294, 281, 41, 281, 323, 328, + 328, 45, 40, 286, 287, 281, 281, 281, + 326, 281, 322, 323, 328, 328, 45, 40, + 286, 287, 281, 281, 281, 326, 281, 281, + 289, 281, 322, 323, 324, 328, 45, 40, + 286, 287, 281, 281, 69, 326, 281, 281, + 289, 281, 320, 281, 352, 281, 339, 339, + 45, 40, 286, 287, 281, 281, 281, 294, + 281, 320, 281, 320, 281, 281, 281, 330, + 330, 281, 40, 286, 287, 281, 281, 281, + 294, 281, 320, 281, 320, 281, 281, 281, + 330, 353, 281, 40, 286, 287, 281, 281, + 281, 294, 281, 320, 281, 320, 281, 352, + 281, 330, 330, 281, 40, 286, 287, 281, + 281, 281, 294, 281, 320, 281, 320, 42, + 281, 281, 58, 321, 281, 40, 286, 287, + 281, 281, 281, 294, 281, 320, 281, 313, + 314, 319, 319, 45, 40, 286, 287, 281, + 281, 281, 317, 281, 281, 289, 281, 313, + 314, 315, 319, 45, 40, 286, 287, 281, + 281, 71, 317, 281, 281, 289, 281, 311, + 281, 354, 281, 339, 339, 45, 40, 286, + 287, 281, 281, 281, 294, 281, 311, 281, + 311, 281, 281, 281, 330, 330, 281, 40, + 286, 287, 281, 281, 281, 294, 281, 311, + 281, 311, 281, 281, 281, 330, 355, 281, + 40, 286, 287, 281, 281, 281, 294, 281, + 311, 281, 311, 281, 354, 281, 330, 330, + 281, 40, 286, 287, 281, 281, 281, 294, + 281, 311, 281, 311, 42, 281, 281, 58, + 312, 281, 40, 286, 287, 281, 281, 281, + 294, 281, 311, 281, 304, 305, 310, 310, + 45, 40, 286, 287, 281, 281, 281, 308, + 281, 281, 289, 281, 304, 305, 306, 310, + 45, 40, 286, 287, 281, 281, 73, 308, + 281, 281, 289, 281, 302, 281, 356, 281, + 339, 339, 45, 40, 286, 287, 281, 281, + 281, 294, 281, 302, 281, 302, 281, 281, + 281, 330, 330, 281, 40, 286, 287, 281, + 281, 281, 294, 281, 302, 281, 302, 281, + 281, 281, 330, 357, 281, 40, 286, 287, + 281, 281, 281, 294, 281, 302, 281, 302, + 281, 356, 281, 330, 330, 281, 40, 286, + 287, 281, 281, 281, 294, 281, 302, 281, + 302, 42, 281, 281, 58, 303, 281, 40, + 286, 287, 281, 281, 281, 294, 281, 302, + 281, 295, 296, 301, 301, 45, 40, 286, + 287, 281, 281, 281, 299, 281, 281, 289, + 281, 295, 296, 297, 301, 45, 40, 286, + 287, 281, 281, 75, 299, 281, 281, 289, + 281, 292, 281, 358, 281, 339, 339, 45, + 40, 286, 287, 281, 281, 281, 294, 281, + 292, 281, 292, 281, 281, 281, 330, 330, + 281, 40, 286, 287, 281, 281, 281, 294, + 281, 292, 281, 292, 281, 281, 281, 330, + 359, 281, 40, 286, 287, 281, 281, 281, + 294, 281, 292, 281, 292, 281, 358, 281, + 330, 330, 281, 40, 286, 287, 281, 281, + 281, 294, 281, 292, 281, 76, 44, 44, + 45, 40, 281, 281, 281, 281, 281, 76, + 281, 292, 42, 281, 281, 58, 293, 281, + 40, 286, 287, 281, 281, 281, 294, 281, + 292, 281, 282, 283, 291, 285, 45, 40, + 286, 287, 281, 281, 281, 288, 281, 281, + 289, 281, 361, 191, 362, 362, 84, 79, + 194, 195, 360, 360, 360, 197, 360, 360, + 200, 360, 191, 362, 362, 84, 79, 194, + 195, 360, 360, 360, 197, 360, 360, 200, + 360, 363, 360, 360, 360, 98, 364, 360, + 79, 194, 195, 360, 360, 360, 365, 360, + 363, 360, 366, 367, 368, 369, 84, 79, + 194, 195, 360, 360, 115, 370, 360, 360, + 200, 360, 371, 367, 372, 372, 84, 79, + 194, 195, 360, 360, 360, 370, 360, 360, + 200, 360, 367, 372, 372, 84, 79, 194, + 195, 360, 360, 360, 370, 360, 360, 200, + 360, 373, 360, 360, 360, 98, 374, 360, + 79, 194, 195, 360, 360, 360, 365, 360, + 373, 360, 375, 376, 377, 378, 84, 79, + 194, 195, 360, 360, 113, 379, 360, 360, + 200, 360, 380, 376, 381, 381, 84, 79, + 194, 195, 360, 360, 360, 379, 360, 360, + 200, 360, 376, 381, 381, 84, 79, 194, + 195, 360, 360, 360, 379, 360, 360, 200, + 360, 382, 360, 360, 360, 98, 383, 360, + 79, 194, 195, 360, 360, 360, 365, 360, + 382, 360, 384, 385, 386, 387, 84, 79, + 194, 195, 360, 360, 111, 388, 360, 360, + 200, 360, 389, 385, 390, 390, 84, 79, + 194, 195, 360, 360, 360, 388, 360, 360, + 200, 360, 385, 390, 390, 84, 79, 194, + 195, 360, 360, 360, 388, 360, 360, 200, + 360, 391, 360, 360, 360, 98, 392, 360, + 79, 194, 195, 360, 360, 360, 365, 360, + 391, 360, 393, 394, 395, 396, 84, 79, + 194, 195, 360, 360, 109, 397, 360, 360, + 200, 360, 398, 394, 399, 399, 84, 79, + 194, 195, 360, 360, 360, 397, 360, 360, + 200, 360, 394, 399, 399, 84, 79, 194, + 195, 360, 360, 360, 397, 360, 360, 200, + 360, 98, 400, 360, 79, 194, 195, 360, + 360, 360, 365, 360, 401, 401, 360, 79, + 194, 195, 360, 360, 360, 365, 360, 402, + 360, 360, 403, 194, 195, 360, 194, 195, + 360, 404, 360, 194, 405, 360, 194, 406, + 360, 194, 360, 402, 360, 360, 360, 194, + 195, 360, 407, 360, 408, 409, 360, 79, + 194, 195, 360, 360, 82, 360, 81, 360, + 401, 401, 360, 79, 194, 195, 360, 401, + 401, 360, 79, 194, 195, 360, 407, 360, + 401, 401, 360, 79, 194, 195, 360, 407, + 360, 408, 401, 360, 79, 194, 195, 360, + 360, 82, 360, 98, 360, 410, 410, 84, + 79, 194, 195, 360, 360, 360, 365, 360, + 411, 107, 412, 413, 88, 79, 194, 195, + 360, 360, 360, 365, 360, 107, 412, 413, + 88, 79, 194, 195, 360, 360, 360, 365, + 360, 412, 412, 88, 79, 194, 195, 360, + 360, 360, 365, 360, 414, 104, 415, 416, + 91, 79, 194, 195, 360, 360, 360, 365, + 360, 104, 415, 416, 91, 79, 194, 195, + 360, 360, 360, 365, 360, 415, 415, 91, + 79, 194, 195, 360, 360, 360, 365, 360, + 417, 101, 418, 419, 94, 79, 194, 195, + 360, 360, 360, 365, 360, 101, 418, 419, + 94, 79, 194, 195, 360, 360, 360, 365, + 360, 418, 418, 94, 79, 194, 195, 360, + 360, 360, 365, 360, 420, 98, 401, 421, + 360, 79, 194, 195, 360, 360, 360, 365, + 360, 98, 401, 421, 360, 79, 194, 195, + 360, 360, 360, 365, 360, 401, 422, 360, + 79, 194, 195, 360, 360, 360, 365, 360, + 98, 360, 401, 401, 360, 79, 194, 195, + 360, 360, 360, 365, 360, 80, 81, 360, + 360, 98, 400, 360, 79, 194, 195, 360, + 360, 360, 365, 360, 80, 360, 394, 399, + 399, 84, 79, 194, 195, 360, 360, 360, + 397, 360, 393, 394, 399, 399, 84, 79, + 194, 195, 360, 360, 360, 397, 360, 360, + 200, 360, 393, 394, 395, 399, 84, 79, + 194, 195, 360, 360, 109, 397, 360, 360, + 200, 360, 391, 360, 423, 360, 410, 410, + 84, 79, 194, 195, 360, 360, 360, 365, + 360, 391, 360, 391, 360, 360, 360, 401, + 401, 360, 79, 194, 195, 360, 360, 360, + 365, 360, 391, 360, 391, 360, 360, 360, + 401, 424, 360, 79, 194, 195, 360, 360, + 360, 365, 360, 391, 360, 391, 360, 423, + 360, 401, 401, 360, 79, 194, 195, 360, + 360, 360, 365, 360, 391, 360, 391, 81, + 360, 360, 98, 392, 360, 79, 194, 195, + 360, 360, 360, 365, 360, 391, 360, 384, + 385, 390, 390, 84, 79, 194, 195, 360, + 360, 360, 388, 360, 360, 200, 360, 384, + 385, 386, 390, 84, 79, 194, 195, 360, + 360, 111, 388, 360, 360, 200, 360, 382, + 360, 425, 360, 410, 410, 84, 79, 194, + 195, 360, 360, 360, 365, 360, 382, 360, + 382, 360, 360, 360, 401, 401, 360, 79, + 194, 195, 360, 360, 360, 365, 360, 382, + 360, 382, 360, 360, 360, 401, 426, 360, + 79, 194, 195, 360, 360, 360, 365, 360, + 382, 360, 382, 360, 425, 360, 401, 401, + 360, 79, 194, 195, 360, 360, 360, 365, + 360, 382, 360, 382, 81, 360, 360, 98, + 383, 360, 79, 194, 195, 360, 360, 360, + 365, 360, 382, 360, 375, 376, 381, 381, + 84, 79, 194, 195, 360, 360, 360, 379, + 360, 360, 200, 360, 375, 376, 377, 381, + 84, 79, 194, 195, 360, 360, 113, 379, + 360, 360, 200, 360, 373, 360, 427, 360, + 410, 410, 84, 79, 194, 195, 360, 360, + 360, 365, 360, 373, 360, 373, 360, 360, + 360, 401, 401, 360, 79, 194, 195, 360, + 360, 360, 365, 360, 373, 360, 373, 360, + 360, 360, 401, 428, 360, 79, 194, 195, + 360, 360, 360, 365, 360, 373, 360, 373, + 360, 427, 360, 401, 401, 360, 79, 194, + 195, 360, 360, 360, 365, 360, 373, 360, + 373, 81, 360, 360, 98, 374, 360, 79, + 194, 195, 360, 360, 360, 365, 360, 373, + 360, 366, 367, 372, 372, 84, 79, 194, + 195, 360, 360, 360, 370, 360, 360, 200, + 360, 366, 367, 368, 372, 84, 79, 194, + 195, 360, 360, 115, 370, 360, 360, 200, + 360, 363, 360, 429, 360, 410, 410, 84, + 79, 194, 195, 360, 360, 360, 365, 360, + 363, 360, 363, 360, 360, 360, 401, 401, + 360, 79, 194, 195, 360, 360, 360, 365, + 360, 363, 360, 363, 360, 360, 360, 401, + 430, 360, 79, 194, 195, 360, 360, 360, + 365, 360, 363, 360, 363, 360, 429, 360, + 401, 401, 360, 79, 194, 195, 360, 360, + 360, 365, 360, 363, 360, 363, 81, 360, + 360, 98, 364, 360, 79, 194, 195, 360, + 360, 360, 365, 360, 363, 360, 116, 83, + 83, 84, 79, 431, 431, 431, 431, 156, + 116, 431, 190, 191, 362, 362, 84, 79, + 194, 195, 360, 360, 360, 197, 360, 360, + 200, 360, 116, 83, 83, 84, 79, 431, + 431, 431, 431, 431, 116, 431, 433, 434, + 435, 436, 123, 118, 437, 438, 432, 432, + 155, 439, 432, 432, 440, 432, 441, 434, + 436, 436, 123, 118, 437, 438, 432, 432, + 432, 439, 432, 432, 440, 432, 434, 436, + 436, 123, 118, 437, 438, 432, 432, 432, + 439, 432, 432, 440, 432, 442, 432, 432, + 432, 136, 443, 432, 118, 437, 438, 432, + 432, 432, 444, 432, 442, 432, 445, 446, + 447, 448, 123, 118, 437, 438, 432, 432, + 153, 449, 432, 432, 440, 432, 450, 446, + 451, 451, 123, 118, 437, 438, 432, 432, + 432, 449, 432, 432, 440, 432, 446, 451, + 451, 123, 118, 437, 438, 432, 432, 432, + 449, 432, 432, 440, 432, 452, 432, 432, + 432, 136, 453, 432, 118, 437, 438, 432, + 432, 432, 444, 432, 452, 432, 454, 455, + 456, 457, 123, 118, 437, 438, 432, 432, + 151, 458, 432, 432, 440, 432, 459, 455, + 460, 460, 123, 118, 437, 438, 432, 432, + 432, 458, 432, 432, 440, 432, 455, 460, + 460, 123, 118, 437, 438, 432, 432, 432, + 458, 432, 432, 440, 432, 461, 432, 432, + 432, 136, 462, 432, 118, 437, 438, 432, + 432, 432, 444, 432, 461, 432, 463, 464, + 465, 466, 123, 118, 437, 438, 432, 432, + 149, 467, 432, 432, 440, 432, 468, 464, + 469, 469, 123, 118, 437, 438, 432, 432, + 432, 467, 432, 432, 440, 432, 464, 469, + 469, 123, 118, 437, 438, 432, 432, 432, + 467, 432, 432, 440, 432, 470, 432, 432, + 432, 136, 471, 432, 118, 437, 438, 432, + 432, 432, 444, 432, 470, 432, 472, 473, + 474, 475, 123, 118, 437, 438, 432, 432, + 147, 476, 432, 432, 440, 432, 477, 473, + 478, 478, 123, 118, 437, 438, 432, 432, + 432, 476, 432, 432, 440, 432, 473, 478, + 478, 123, 118, 437, 438, 432, 432, 432, + 476, 432, 432, 440, 432, 136, 479, 432, + 118, 437, 438, 432, 432, 432, 444, 432, + 480, 480, 432, 118, 437, 438, 432, 432, + 432, 444, 432, 481, 432, 432, 482, 437, + 438, 432, 437, 438, 432, 483, 432, 437, + 484, 432, 437, 485, 432, 437, 432, 481, + 432, 432, 432, 437, 438, 432, 486, 432, + 487, 488, 432, 118, 437, 438, 432, 432, + 121, 432, 120, 432, 480, 480, 432, 118, + 437, 438, 432, 480, 480, 432, 118, 437, + 438, 432, 486, 432, 480, 480, 432, 118, + 437, 438, 432, 486, 432, 487, 480, 432, + 118, 437, 438, 432, 432, 121, 432, 136, + 432, 489, 489, 123, 118, 437, 438, 432, + 432, 432, 444, 432, 490, 145, 491, 492, + 126, 118, 437, 438, 432, 432, 432, 444, + 432, 145, 491, 492, 126, 118, 437, 438, + 432, 432, 432, 444, 432, 491, 491, 126, + 118, 437, 438, 432, 432, 432, 444, 432, + 493, 142, 494, 495, 129, 118, 437, 438, + 432, 432, 432, 444, 432, 142, 494, 495, + 129, 118, 437, 438, 432, 432, 432, 444, + 432, 494, 494, 129, 118, 437, 438, 432, + 432, 432, 444, 432, 496, 139, 497, 498, + 132, 118, 437, 438, 432, 432, 432, 444, + 432, 139, 497, 498, 132, 118, 437, 438, + 432, 432, 432, 444, 432, 497, 497, 132, + 118, 437, 438, 432, 432, 432, 444, 432, + 499, 136, 480, 500, 432, 118, 437, 438, + 432, 432, 432, 444, 432, 136, 480, 500, + 432, 118, 437, 438, 432, 432, 432, 444, + 432, 480, 501, 432, 118, 437, 438, 432, + 432, 432, 444, 432, 136, 432, 480, 480, + 432, 118, 437, 438, 432, 432, 432, 444, + 432, 119, 120, 432, 432, 136, 479, 432, + 118, 437, 438, 432, 432, 432, 444, 432, + 119, 432, 473, 478, 478, 123, 118, 437, + 438, 432, 432, 432, 476, 432, 472, 473, + 478, 478, 123, 118, 437, 438, 432, 432, + 432, 476, 432, 432, 440, 432, 472, 473, + 474, 478, 123, 118, 437, 438, 432, 432, + 147, 476, 432, 432, 440, 432, 470, 432, + 502, 432, 489, 489, 123, 118, 437, 438, + 432, 432, 432, 444, 432, 470, 432, 470, + 432, 432, 432, 480, 480, 432, 118, 437, + 438, 432, 432, 432, 444, 432, 470, 432, + 470, 432, 432, 432, 480, 503, 432, 118, + 437, 438, 432, 432, 432, 444, 432, 470, + 432, 470, 432, 502, 432, 480, 480, 432, + 118, 437, 438, 432, 432, 432, 444, 432, + 470, 432, 470, 120, 432, 432, 136, 471, + 432, 118, 437, 438, 432, 432, 432, 444, + 432, 470, 432, 463, 464, 469, 469, 123, + 118, 437, 438, 432, 432, 432, 467, 432, + 432, 440, 432, 463, 464, 465, 469, 123, + 118, 437, 438, 432, 432, 149, 467, 432, + 432, 440, 432, 461, 432, 504, 432, 489, + 489, 123, 118, 437, 438, 432, 432, 432, + 444, 432, 461, 432, 461, 432, 432, 432, + 480, 480, 432, 118, 437, 438, 432, 432, + 432, 444, 432, 461, 432, 461, 432, 432, + 432, 480, 505, 432, 118, 437, 438, 432, + 432, 432, 444, 432, 461, 432, 461, 432, + 504, 432, 480, 480, 432, 118, 437, 438, + 432, 432, 432, 444, 432, 461, 432, 461, + 120, 432, 432, 136, 462, 432, 118, 437, + 438, 432, 432, 432, 444, 432, 461, 432, + 454, 455, 460, 460, 123, 118, 437, 438, + 432, 432, 432, 458, 432, 432, 440, 432, + 454, 455, 456, 460, 123, 118, 437, 438, + 432, 432, 151, 458, 432, 432, 440, 432, + 452, 432, 506, 432, 489, 489, 123, 118, + 437, 438, 432, 432, 432, 444, 432, 452, + 432, 452, 432, 432, 432, 480, 480, 432, + 118, 437, 438, 432, 432, 432, 444, 432, + 452, 432, 452, 432, 432, 432, 480, 507, + 432, 118, 437, 438, 432, 432, 432, 444, + 432, 452, 432, 452, 432, 506, 432, 480, + 480, 432, 118, 437, 438, 432, 432, 432, + 444, 432, 452, 432, 452, 120, 432, 432, + 136, 453, 432, 118, 437, 438, 432, 432, + 432, 444, 432, 452, 432, 445, 446, 451, + 451, 123, 118, 437, 438, 432, 432, 432, + 449, 432, 432, 440, 432, 445, 446, 447, + 451, 123, 118, 437, 438, 432, 432, 153, + 449, 432, 432, 440, 432, 442, 432, 508, + 432, 489, 489, 123, 118, 437, 438, 432, + 432, 432, 444, 432, 442, 432, 442, 432, + 432, 432, 480, 480, 432, 118, 437, 438, + 432, 432, 432, 444, 432, 442, 432, 442, + 432, 432, 432, 480, 509, 432, 118, 437, + 438, 432, 432, 432, 444, 432, 442, 432, + 442, 432, 508, 432, 480, 480, 432, 118, + 437, 438, 432, 432, 432, 444, 432, 442, + 432, 442, 120, 432, 432, 136, 443, 432, + 118, 437, 438, 432, 432, 432, 444, 432, + 442, 432, 433, 434, 436, 436, 123, 118, + 437, 438, 432, 432, 432, 439, 432, 432, + 440, 432, 188, 189, 190, 191, 510, 362, + 84, 79, 194, 195, 196, 196, 156, 197, + 360, 188, 200, 360, 203, 511, 205, 206, + 6, 1, 207, 208, 202, 202, 38, 209, + 202, 202, 210, 202, 213, 189, 190, 191, + 512, 513, 84, 157, 514, 515, 202, 196, + 156, 516, 202, 213, 200, 202, 116, 517, + 517, 84, 157, 207, 208, 202, 202, 156, + 518, 202, 519, 202, 202, 520, 514, 515, + 202, 514, 515, 202, 254, 202, 514, 521, + 202, 514, 522, 202, 514, 202, 519, 202, + 202, 202, 514, 515, 202, 523, 3, 360, + 360, 401, 430, 360, 79, 194, 195, 360, + 360, 360, 365, 360, 523, 360, 524, 367, + 525, 526, 84, 157, 514, 515, 202, 202, + 158, 370, 202, 202, 200, 202, 527, 367, + 528, 528, 84, 157, 514, 515, 202, 202, + 202, 370, 202, 202, 200, 202, 367, 528, + 528, 84, 157, 514, 515, 202, 202, 202, + 370, 202, 202, 200, 202, 524, 367, 528, + 528, 84, 157, 514, 515, 202, 202, 202, + 370, 202, 202, 200, 202, 524, 367, 525, + 528, 84, 157, 514, 515, 202, 202, 158, + 370, 202, 202, 200, 202, 213, 202, 279, + 116, 529, 529, 160, 157, 207, 208, 202, + 202, 202, 518, 202, 213, 202, 530, 184, + 531, 532, 162, 157, 514, 515, 202, 202, + 202, 533, 202, 184, 531, 532, 162, 157, + 514, 515, 202, 202, 202, 533, 202, 531, + 531, 162, 157, 514, 515, 202, 202, 202, + 533, 202, 534, 181, 535, 536, 165, 157, + 514, 515, 202, 202, 202, 533, 202, 181, + 535, 536, 165, 157, 514, 515, 202, 202, + 202, 533, 202, 535, 535, 165, 157, 514, + 515, 202, 202, 202, 533, 202, 537, 178, + 538, 539, 168, 157, 514, 515, 202, 202, + 202, 533, 202, 178, 538, 539, 168, 157, + 514, 515, 202, 202, 202, 533, 202, 538, + 538, 168, 157, 514, 515, 202, 202, 202, + 533, 202, 540, 175, 541, 542, 202, 157, + 514, 515, 202, 202, 202, 533, 202, 175, + 541, 542, 202, 157, 514, 515, 202, 202, + 202, 533, 202, 541, 541, 202, 157, 514, + 515, 202, 202, 202, 533, 202, 543, 202, + 544, 545, 202, 157, 514, 515, 202, 202, + 172, 202, 171, 202, 541, 541, 202, 157, + 514, 515, 202, 541, 541, 202, 157, 514, + 515, 202, 543, 202, 541, 541, 202, 157, + 514, 515, 202, 543, 202, 544, 541, 202, + 157, 514, 515, 202, 202, 172, 202, 523, + 171, 360, 360, 98, 364, 360, 79, 194, + 195, 360, 360, 360, 365, 360, 523, 360, + 547, 546, 548, 548, 546, 186, 549, 550, + 546, 548, 548, 546, 186, 549, 550, 546, + 551, 546, 546, 552, 549, 550, 546, 549, + 550, 546, 553, 546, 549, 554, 546, 549, + 555, 546, 549, 546, 551, 546, 546, 546, + 549, 550, 546, 0 }; static const short _indic_syllable_machine_trans_targs[] = { 178, 200, 207, 209, 210, 4, 213, 5, 7, 216, 8, 10, 219, 11, 13, 222, 14, 16, 17, 199, 19, 20, 221, 22, - 23, 218, 25, 26, 215, 224, 229, 233, - 236, 240, 243, 247, 250, 254, 257, 178, - 280, 287, 289, 290, 41, 293, 42, 44, - 296, 45, 47, 299, 48, 50, 302, 51, - 53, 54, 279, 56, 57, 301, 59, 60, - 298, 62, 63, 295, 304, 309, 313, 316, - 320, 323, 327, 330, 334, 338, 178, 359, - 366, 368, 369, 78, 372, 178, 79, 81, - 375, 82, 84, 378, 85, 87, 381, 88, - 90, 91, 358, 93, 94, 380, 96, 97, - 377, 99, 100, 374, 383, 388, 392, 395, - 399, 402, 406, 409, 413, 178, 440, 447, - 449, 450, 114, 453, 115, 117, 456, 118, - 120, 459, 121, 123, 462, 124, 126, 127, - 439, 129, 130, 461, 132, 133, 458, 135, - 136, 455, 464, 469, 473, 476, 480, 483, - 487, 490, 494, 497, 417, 502, 513, 152, - 516, 154, 519, 155, 157, 522, 158, 160, - 525, 161, 528, 530, 531, 166, 167, 527, - 169, 170, 524, 172, 173, 521, 175, 176, - 518, 178, 536, 178, 179, 259, 339, 341, - 416, 418, 361, 362, 419, 415, 498, 499, - 386, 534, 387, 178, 180, 182, 36, 258, - 202, 203, 256, 227, 228, 181, 35, 183, - 252, 1, 184, 186, 34, 251, 249, 185, - 33, 187, 245, 188, 190, 32, 244, 242, - 189, 31, 191, 238, 192, 194, 30, 237, - 235, 193, 29, 195, 231, 196, 198, 28, - 230, 226, 197, 27, 212, 0, 201, 206, - 178, 204, 205, 208, 2, 211, 3, 214, - 6, 24, 217, 9, 21, 220, 12, 18, - 223, 15, 225, 232, 234, 239, 241, 246, - 248, 253, 255, 178, 260, 262, 73, 336, - 282, 283, 337, 307, 308, 261, 72, 263, - 332, 38, 264, 266, 71, 331, 329, 265, - 70, 267, 325, 268, 270, 69, 324, 322, - 269, 68, 271, 318, 272, 274, 67, 317, - 315, 273, 66, 275, 311, 276, 278, 65, - 310, 306, 277, 64, 292, 37, 281, 286, - 178, 284, 285, 288, 39, 291, 40, 294, - 43, 61, 297, 46, 58, 300, 49, 55, - 303, 52, 305, 312, 314, 319, 321, 326, - 328, 333, 335, 178, 340, 109, 342, 411, - 75, 343, 345, 108, 410, 408, 344, 107, - 346, 404, 347, 349, 106, 403, 401, 348, - 105, 350, 397, 351, 353, 104, 396, 394, - 352, 103, 354, 390, 355, 357, 102, 389, - 385, 356, 101, 371, 74, 360, 365, 178, - 363, 364, 367, 76, 370, 77, 373, 80, - 98, 376, 83, 95, 379, 86, 92, 382, - 89, 384, 391, 393, 398, 400, 405, 407, - 412, 414, 178, 178, 420, 422, 146, 145, - 442, 443, 496, 467, 468, 421, 423, 492, - 111, 424, 426, 144, 491, 489, 425, 143, - 427, 485, 428, 430, 142, 484, 482, 429, - 141, 431, 478, 432, 434, 140, 477, 475, - 433, 139, 435, 471, 436, 438, 138, 470, - 466, 437, 137, 452, 110, 441, 446, 178, - 444, 445, 448, 112, 451, 113, 454, 116, - 134, 457, 119, 131, 460, 122, 128, 463, - 125, 465, 472, 474, 479, 481, 486, 488, - 493, 495, 147, 500, 501, 515, 504, 505, - 533, 148, 509, 503, 508, 506, 507, 510, - 511, 150, 514, 512, 149, 151, 517, 153, - 174, 163, 520, 156, 171, 523, 159, 168, - 526, 162, 165, 529, 164, 532, 178, 535, - 177, 538, 539, 537, 542, 178, 540, 541 + 23, 218, 25, 26, 215, 224, 228, 232, + 235, 239, 242, 246, 249, 253, 256, 178, + 279, 286, 288, 289, 41, 292, 42, 44, + 295, 45, 47, 298, 48, 50, 301, 51, + 53, 54, 278, 56, 57, 300, 59, 60, + 297, 62, 63, 294, 303, 307, 311, 314, + 318, 321, 325, 328, 332, 336, 178, 357, + 364, 366, 367, 78, 370, 178, 79, 81, + 373, 82, 84, 376, 85, 87, 379, 88, + 90, 91, 356, 93, 94, 378, 96, 97, + 375, 99, 100, 372, 381, 385, 389, 392, + 396, 399, 403, 406, 410, 178, 437, 444, + 446, 447, 114, 450, 115, 117, 453, 118, + 120, 456, 121, 123, 459, 124, 126, 127, + 436, 129, 130, 458, 132, 133, 455, 135, + 136, 452, 461, 465, 469, 472, 476, 479, + 483, 486, 490, 493, 414, 498, 509, 152, + 512, 154, 515, 155, 157, 518, 158, 160, + 521, 161, 524, 526, 527, 166, 167, 523, + 169, 170, 520, 172, 173, 517, 175, 176, + 514, 178, 532, 178, 179, 258, 337, 339, + 413, 415, 359, 360, 416, 412, 494, 495, + 384, 530, 178, 180, 182, 36, 257, 202, + 203, 255, 227, 181, 35, 183, 251, 1, + 184, 186, 34, 250, 248, 185, 33, 187, + 244, 188, 190, 32, 243, 241, 189, 31, + 191, 237, 192, 194, 30, 236, 234, 193, + 29, 195, 230, 196, 198, 28, 229, 226, + 197, 27, 212, 0, 201, 206, 178, 204, + 205, 208, 2, 211, 3, 214, 6, 24, + 217, 9, 21, 220, 12, 18, 223, 15, + 225, 231, 233, 238, 240, 245, 247, 252, + 254, 178, 259, 261, 73, 334, 281, 282, + 335, 306, 260, 72, 262, 330, 38, 263, + 265, 71, 329, 327, 264, 70, 266, 323, + 267, 269, 69, 322, 320, 268, 68, 270, + 316, 271, 273, 67, 315, 313, 272, 66, + 274, 309, 275, 277, 65, 308, 305, 276, + 64, 291, 37, 280, 285, 178, 283, 284, + 287, 39, 290, 40, 293, 43, 61, 296, + 46, 58, 299, 49, 55, 302, 52, 304, + 310, 312, 317, 319, 324, 326, 331, 333, + 178, 338, 109, 340, 408, 75, 341, 343, + 108, 407, 405, 342, 107, 344, 401, 345, + 347, 106, 400, 398, 346, 105, 348, 394, + 349, 351, 104, 393, 391, 350, 103, 352, + 387, 353, 355, 102, 386, 383, 354, 101, + 369, 74, 358, 363, 178, 361, 362, 365, + 76, 368, 77, 371, 80, 98, 374, 83, + 95, 377, 86, 92, 380, 89, 382, 388, + 390, 395, 397, 402, 404, 409, 411, 178, + 178, 417, 419, 146, 145, 439, 440, 492, + 464, 418, 420, 488, 111, 421, 423, 144, + 487, 485, 422, 143, 424, 481, 425, 427, + 142, 480, 478, 426, 141, 428, 474, 429, + 431, 140, 473, 471, 430, 139, 432, 467, + 433, 435, 138, 466, 463, 434, 137, 449, + 110, 438, 443, 178, 441, 442, 445, 112, + 448, 113, 451, 116, 134, 454, 119, 131, + 457, 122, 128, 460, 125, 462, 468, 470, + 475, 477, 482, 484, 489, 491, 147, 496, + 497, 511, 500, 501, 529, 148, 505, 499, + 504, 502, 503, 506, 507, 150, 510, 508, + 149, 151, 513, 153, 174, 163, 516, 156, + 171, 519, 159, 168, 522, 162, 165, 525, + 164, 528, 178, 531, 177, 534, 535, 533, + 538, 178, 536, 537 }; static const char _indic_syllable_machine_trans_actions[] = { @@ -1285,51 +1087,51 @@ static const char _indic_syllable_machine_trans_actions[] = { 0, 0, 2, 0, 0, 2, 0, 0, 2, 9, 0, 12, 2, 2, 6, 2, 13, 13, 0, 0, 2, 2, 6, 2, - 6, 2, 6, 14, 2, 2, 0, 2, - 0, 0, 2, 2, 2, 2, 0, 2, - 2, 0, 2, 2, 0, 2, 2, 2, - 0, 2, 2, 2, 2, 0, 2, 2, - 2, 0, 2, 2, 2, 2, 0, 2, - 2, 2, 0, 2, 2, 2, 2, 0, - 2, 2, 2, 0, 2, 0, 0, 0, - 15, 0, 0, 2, 0, 2, 0, 2, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 16, 2, 2, 0, 2, - 0, 0, 2, 2, 2, 2, 0, 2, - 2, 0, 2, 2, 0, 2, 2, 2, - 0, 2, 2, 2, 2, 0, 2, 2, - 2, 0, 2, 2, 2, 2, 0, 2, - 2, 2, 0, 2, 2, 2, 2, 0, - 2, 2, 2, 0, 2, 0, 0, 0, - 17, 0, 0, 2, 0, 2, 0, 2, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 18, 6, 0, 6, 6, - 0, 6, 2, 0, 6, 2, 6, 0, - 6, 6, 6, 2, 0, 6, 2, 6, - 0, 6, 6, 6, 2, 0, 6, 2, - 6, 0, 6, 6, 6, 2, 0, 6, - 2, 6, 0, 6, 0, 0, 0, 19, - 0, 0, 2, 0, 2, 0, 2, 0, - 0, 2, 0, 0, 2, 0, 0, 2, - 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 20, 21, 2, 2, 0, 0, - 0, 0, 2, 2, 2, 2, 2, 2, - 0, 2, 2, 0, 2, 2, 2, 0, + 6, 2, 14, 2, 2, 0, 2, 0, + 0, 2, 2, 2, 0, 2, 2, 0, + 2, 2, 0, 2, 2, 2, 0, 2, + 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, - 2, 0, 2, 2, 2, 2, 0, 2, - 2, 2, 0, 2, 0, 0, 0, 22, - 0, 0, 2, 0, 2, 0, 2, 0, + 2, 0, 2, 0, 0, 0, 15, 0, + 0, 2, 0, 2, 0, 2, 0, 0, + 2, 0, 0, 2, 0, 0, 2, 0, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 16, 2, 2, 0, 2, 0, 0, + 2, 2, 2, 0, 2, 2, 0, 2, + 2, 0, 2, 2, 2, 0, 2, 2, + 2, 2, 0, 2, 2, 2, 0, 2, + 2, 2, 2, 0, 2, 2, 2, 0, + 2, 2, 2, 2, 0, 2, 2, 2, + 0, 2, 0, 0, 0, 17, 0, 0, + 2, 0, 2, 0, 2, 0, 0, 2, + 0, 0, 2, 0, 0, 2, 0, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 18, 6, 0, 6, 6, 0, 6, 2, + 0, 6, 2, 6, 0, 6, 6, 6, + 2, 0, 6, 2, 6, 0, 6, 6, + 6, 2, 0, 6, 2, 6, 0, 6, + 6, 6, 2, 0, 6, 2, 6, 0, + 6, 0, 0, 0, 19, 0, 0, 2, + 0, 2, 0, 2, 0, 0, 2, 0, + 0, 2, 0, 0, 2, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 20, + 21, 2, 2, 0, 0, 0, 0, 2, + 2, 2, 2, 2, 0, 2, 2, 0, + 2, 2, 2, 0, 2, 2, 2, 2, + 0, 2, 2, 2, 0, 2, 2, 2, + 2, 0, 2, 2, 2, 0, 2, 2, + 2, 2, 0, 2, 2, 2, 0, 2, + 0, 0, 0, 22, 0, 0, 2, 0, + 2, 0, 2, 0, 0, 2, 0, 0, + 2, 0, 0, 2, 0, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 0, + 8, 2, 0, 0, 2, 0, 2, 0, + 0, 0, 0, 8, 8, 0, 8, 8, + 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, - 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 0, 0, 8, 2, 0, 0, - 2, 0, 2, 0, 0, 0, 0, 8, - 8, 0, 8, 8, 0, 0, 2, 0, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 0, 2, 0, 2, 23, 2, - 0, 0, 0, 0, 0, 24, 0, 0 + 0, 2, 23, 2, 0, 0, 0, 0, + 0, 24, 0, 0 }; static const char _indic_syllable_machine_to_state_actions[] = { @@ -1400,7 +1202,7 @@ static const char _indic_syllable_machine_to_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0 }; static const char _indic_syllable_machine_from_state_actions[] = { @@ -1471,7 +1273,7 @@ static const char _indic_syllable_machine_from_state_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0 }; static const short _indic_syllable_machine_eof_trans[] = { @@ -1497,52 +1299,52 @@ static const short _indic_syllable_machine_eof_trans[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 186, 0, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 284, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 364, 364, 364, 364, - 435, 364, 435, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 436, - 436, 436, 364, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 364, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 364, 551, 551, - 551, 551, 551, 551, 551, 551, 551 + 1, 186, 0, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 432, 361, 432, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 361, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 361, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 361, 547, 547, 547, 547, 547, 547, + 547, 547, 547 }; static const int indic_syllable_machine_start = 178; @@ -1556,7 +1358,7 @@ static const int indic_syllable_machine_en_main = 178; -#line 97 "hb-ot-shape-complex-indic-machine.rl" +#line 96 "hb-ot-shape-complex-indic-machine.rl" #define found_syllable(syllable_type) \ @@ -1576,7 +1378,7 @@ find_syllables (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 1580 "hb-ot-shape-complex-indic-machine.hh" +#line 1382 "hb-ot-shape-complex-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -1584,7 +1386,7 @@ find_syllables (hb_buffer_t *buffer) act = 0; } -#line 118 "hb-ot-shape-complex-indic-machine.rl" +#line 117 "hb-ot-shape-complex-indic-machine.rl" p = 0; @@ -1593,7 +1395,7 @@ find_syllables (hb_buffer_t *buffer) unsigned int last = 0; unsigned int syllable_serial = 1; -#line 1597 "hb-ot-shape-complex-indic-machine.hh" +#line 1399 "hb-ot-shape-complex-indic-machine.hh" { int _slen; int _trans; @@ -1607,7 +1409,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 1611 "hb-ot-shape-complex-indic-machine.hh" +#line 1413 "hb-ot-shape-complex-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -1630,71 +1432,71 @@ _eof_trans: {te = p+1;} break; case 15: -#line 88 "hb-ot-shape-complex-indic-machine.rl" +#line 87 "hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (consonant_syllable); }} break; case 17: -#line 89 "hb-ot-shape-complex-indic-machine.rl" +#line 88 "hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (vowel_syllable); }} break; case 22: -#line 90 "hb-ot-shape-complex-indic-machine.rl" +#line 89 "hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (standalone_cluster); }} break; case 24: -#line 91 "hb-ot-shape-complex-indic-machine.rl" +#line 90 "hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (symbol_cluster); }} break; case 19: -#line 92 "hb-ot-shape-complex-indic-machine.rl" +#line 91 "hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (broken_cluster); }} break; case 12: -#line 93 "hb-ot-shape-complex-indic-machine.rl" +#line 92 "hb-ot-shape-complex-indic-machine.rl" {te = p+1;{ found_syllable (non_indic_cluster); }} break; case 14: -#line 88 "hb-ot-shape-complex-indic-machine.rl" +#line 87 "hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (consonant_syllable); }} break; case 16: -#line 89 "hb-ot-shape-complex-indic-machine.rl" +#line 88 "hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (vowel_syllable); }} break; case 21: -#line 90 "hb-ot-shape-complex-indic-machine.rl" +#line 89 "hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (standalone_cluster); }} break; case 23: -#line 91 "hb-ot-shape-complex-indic-machine.rl" +#line 90 "hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (symbol_cluster); }} break; case 18: -#line 92 "hb-ot-shape-complex-indic-machine.rl" +#line 91 "hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; case 20: -#line 93 "hb-ot-shape-complex-indic-machine.rl" +#line 92 "hb-ot-shape-complex-indic-machine.rl" {te = p;p--;{ found_syllable (non_indic_cluster); }} break; case 1: -#line 88 "hb-ot-shape-complex-indic-machine.rl" +#line 87 "hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} break; case 3: -#line 89 "hb-ot-shape-complex-indic-machine.rl" +#line 88 "hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (vowel_syllable); }} break; case 7: -#line 90 "hb-ot-shape-complex-indic-machine.rl" +#line 89 "hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (standalone_cluster); }} break; case 9: -#line 91 "hb-ot-shape-complex-indic-machine.rl" +#line 90 "hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (symbol_cluster); }} break; case 4: -#line 92 "hb-ot-shape-complex-indic-machine.rl" +#line 91 "hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (broken_cluster); }} break; case 5: @@ -1715,22 +1517,22 @@ _eof_trans: case 8: #line 1 "NONE" {te = p+1;} -#line 88 "hb-ot-shape-complex-indic-machine.rl" +#line 87 "hb-ot-shape-complex-indic-machine.rl" {act = 1;} break; case 6: #line 1 "NONE" {te = p+1;} -#line 92 "hb-ot-shape-complex-indic-machine.rl" +#line 91 "hb-ot-shape-complex-indic-machine.rl" {act = 5;} break; case 13: #line 1 "NONE" {te = p+1;} -#line 93 "hb-ot-shape-complex-indic-machine.rl" +#line 92 "hb-ot-shape-complex-indic-machine.rl" {act = 6;} break; -#line 1734 "hb-ot-shape-complex-indic-machine.hh" +#line 1536 "hb-ot-shape-complex-indic-machine.hh" } _again: @@ -1739,7 +1541,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 1743 "hb-ot-shape-complex-indic-machine.hh" +#line 1545 "hb-ot-shape-complex-indic-machine.hh" } if ( ++p != pe ) @@ -1755,7 +1557,7 @@ _again: } -#line 127 "hb-ot-shape-complex-indic-machine.rl" +#line 126 "hb-ot-shape-complex-indic-machine.rl" } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh index 559ebe4986..5879c3e491 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh @@ -60,11 +60,10 @@ enum indic_category_t { OT_Repha = 15, /* Atomically-encoded logical or visual repha. */ OT_Ra = 16, OT_CM = 17, /* Consonant-Medial. */ - OT_Symbol = 18, /* Avagraha, etc that take marks (SM,A,VD). */ - OT_CM2 = 31 /* Consonant-Medial, second slot. */ + OT_Symbol = 18 /* Avagraha, etc that take marks (SM,A,VD). */ }; -#define MEDIAL_FLAGS (FLAG (OT_CM) | FLAG (OT_CM2)) +#define MEDIAL_FLAGS (FLAG (OT_CM)) /* Note: * @@ -109,27 +108,31 @@ enum indic_syllabic_category_t { INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Symbol, INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM, - INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER = OT_PLACEHOLDER, /* TODO */ + INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER = OT_PLACEHOLDER, /* Don't care. */ INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK = OT_A, INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C, INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C, INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_CM, INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C, + INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER = OT_M, /* U+17CD only. */ INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM, INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_PLACEHOLDER, INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA = OT_Repha, + INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED = OT_X, /* Don't care. */ INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM, INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_N, + INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_Repha, /* TODO */ INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, - INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_H, /* TODO */ + INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_Coeng, INDIC_SYLLABIC_CATEGORY_JOINER = OT_ZWJ, INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X, INDIC_SYLLABIC_CATEGORY_NON_JOINER = OT_ZWNJ, INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N, INDIC_SYLLABIC_CATEGORY_NUMBER = OT_PLACEHOLDER, - INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER = OT_PLACEHOLDER, /* TODO */ - INDIC_SYLLABIC_CATEGORY_PURE_KILLER = OT_H, /* TODO */ + INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER = OT_PLACEHOLDER, /* Don't care. */ + INDIC_SYLLABIC_CATEGORY_PURE_KILLER = OT_M, /* Is like a vowel matra. */ INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS, + INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER = OT_M, /* Misc Khmer signs. */ INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X, INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N, INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H, @@ -162,17 +165,23 @@ enum indic_matra_category_t { }; #define INDIC_COMBINE_CATEGORIES(S,M) \ - (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || \ - ( \ - S == INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL || \ - S == INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK || \ - S == INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER || \ - S == INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA || \ - S == INDIC_SYLLABIC_CATEGORY_VIRAMA || \ - S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT || \ - false)) + \ - ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \ - ((M << 8) | S)) + ( \ + ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \ + ( S | \ + ( \ + ( \ + S == INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL || \ + S == INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK || \ + S == INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER || \ + S == INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA || \ + S == INDIC_SYLLABIC_CATEGORY_VIRAMA || \ + S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT || \ + false \ + ? M : INDIC_MATRA_CATEGORY_NOT_APPLICABLE \ + ) << 8 \ + ) \ + ) \ + ) HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE hb_indic_get_categories (hb_codepoint_t u); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc index 2e159a12b0..80a6b25e3b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.cc @@ -2,67 +2,71 @@ /* * The following table is generated by running: * - * ./gen-indic-table.py IndicSyllabicCategory.txt IndicMatraCategory.txt Blocks.txt + * ./gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt Blocks.txt * * on files with these headers: * - * # IndicSyllabicCategory-7.0.0.txt - * # Date: 2014-06-03, 07:00:00 GMT [KW, LI, AG, RP] - * # IndicMatraCategory-7.0.0.txt - * # Date: 2014-06-03, 07:00:00 GMT [KW, LI, AG, RP] - * # Blocks-7.0.0.txt - * # Date: 2014-04-03, 23:23:00 GMT [RP, KW] + * # IndicSyllabicCategory-9.0.0.txt + * # Date: 2016-05-21, 02:46:00 GMT [RP] + * # IndicPositionalCategory-9.0.0.txt + * # Date: 2016-02-25, 00:48:00 GMT [RP] + * # Blocks-9.0.0.txt + * # Date: 2016-02-05, 23:48:00 GMT [KW] */ #include "hb-ot-shape-complex-indic-private.hh" -#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 13 chars; Avagraha */ -#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 59 chars; Bindu */ +#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 15 chars; Avagraha */ +#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 67 chars; Bindu */ #define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */ -#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 30 chars; Cantillation_Mark */ -#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 1744 chars; Consonant */ -#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 7 chars; Consonant_Dead */ -#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 61 chars; Consonant_Final */ +#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 53 chars; Cantillation_Mark */ +#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 1907 chars; Consonant */ +#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 10 chars; Consonant_Dead */ +#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 62 chars; Consonant_Final */ #define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */ -#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 19 chars; Consonant_Medial */ -#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 11 chars; Consonant_Placeholder */ +#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */ +#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 22 chars; Consonant_Medial */ +#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 16 chars; Consonant_Placeholder */ #define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 1 chars; Consonant_Preceding_Repha */ -#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 61 chars; Consonant_Subjoined */ +#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 2 chars; Consonant_Prefixed */ +#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 90 chars; Consonant_Subjoined */ #define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */ +#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 4 chars; Consonant_With_Stacker */ #define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 2 chars; Gemination_Mark */ #define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 7 chars; Invisible_Stacker */ #define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */ #define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */ #define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */ -#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 18 chars; Nukta */ -#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 408 chars; Number */ +#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 24 chars; Nukta */ +#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 459 chars; Number */ #define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */ #define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */ -#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 15 chars; Pure_Killer */ -#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 3 chars; Register_Shifter */ +#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 16 chars; Pure_Killer */ +#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */ +#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 22 chars; Syllable_Modifier */ #define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */ -#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 62 chars; Tone_Mark */ -#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 22 chars; Virama */ -#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 29 chars; Visarga */ +#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */ +#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 24 chars; Virama */ +#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 31 chars; Visarga */ #define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */ -#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 553 chars; Vowel_Dependent */ -#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 395 chars; Vowel_Independent */ +#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 602 chars; Vowel_Dependent */ +#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 431 chars; Vowel_Independent */ -#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 142 chars; Bottom */ +#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 300 chars; Bottom */ #define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */ #define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 57 chars; Left */ #define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */ #define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */ -#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 2 chars; Overstruck */ -#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 163 chars; Right */ -#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 169 chars; Top */ +#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */ +#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 258 chars; Right */ +#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 342 chars; Top */ #define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */ #define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */ #define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */ #define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */ #define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */ -#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 15 chars; Visual_Order_Left */ +#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */ #define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M) @@ -79,29 +83,33 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0030 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 0038 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define indic_offset_0x00d0u 24 +#define indic_offset_0x00b0u 24 /* Latin-1 Supplement */ + /* 00B0 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00C0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 00C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 00D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), -#define indic_offset_0x0900u 32 +#define indic_offset_0x0900u 64 /* Devanagari */ - /* 0900 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), + /* 0900 */ _(Bi,T), _(Bi,T), _(Bi,T), _(Vs,R), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 0908 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 0910 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0920 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0928 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,x), _(A,x), _(M,R), _(M,L), + /* 0938 */ _(C,x), _(C,x), _(M,T), _(M,R), _(N,B), _(A,x), _(M,R), _(M,L), /* 0940 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), /* 0948 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(M,L), _(M,R), - /* 0950 */ _(x,x), _(TM,x), _(TM,x), _(x,x), _(x,x), _(M,T), _(M,B), _(M,B), + /* 0950 */ _(x,x), _(Ca,T), _(Ca,B), _(x,T), _(x,T), _(M,T), _(M,B), _(M,B), /* 0958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0960 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0968 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), @@ -110,14 +118,14 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Bengali */ - /* 0980 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0980 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0988 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), /* 0990 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 09A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 09A8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 09B0 */ _(C,x), _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), - /* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,L), + /* 09B8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L), /* 09C0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L), /* 09C8 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,B), _(CD,x), _(x,x), /* 09D0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), @@ -129,33 +137,33 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Gurmukhi */ - /* 0A00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0A00 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0A08 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x), /* 0A10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0A18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0A28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0A30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), - /* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(x,x), _(M,R), _(M,L), + /* 0A38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(x,x), _(M,R), _(M,L), /* 0A40 */ _(M,R), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), /* 0A48 */ _(M,T), _(x,x), _(x,x), _(M,T), _(M,T), _(V,B), _(x,x), _(x,x), /* 0A50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 0A58 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), /* 0A60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0A68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0A70 */ _(Bi,x), _(GM,T), _(CP,x), _(CP,x), _(x,x), _(CM,x), _(x,x), _(x,x), + /* 0A70 */ _(Bi,T), _(GM,T), _(CP,x), _(CP,x), _(x,x), _(CM,B), _(x,x), _(x,x), /* 0A78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* Gujarati */ - /* 0A80 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0A80 */ _(x,x), _(Bi,T), _(Bi,T), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0A88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), /* 0A90 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0A98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0AA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0AA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0AB0 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,L), + /* 0AB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,L), /* 0AC0 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(x,x), _(M,T), /* 0AC8 */ _(M,T), _(M,TR), _(x,x), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x), /* 0AD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), @@ -163,18 +171,18 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0AE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0AE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 0AF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 0AF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0AF8 */ _(x,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* Oriya */ - /* 0B00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0B00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), /* 0B10 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0B28 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0B30 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,T), + /* 0B38 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T), /* 0B40 */ _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), _(M,L), /* 0B48 */ _(M,TL), _(x,x), _(x,x), _(M,LR),_(M,TLR), _(V,B), _(x,x), _(x,x), /* 0B50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,TR), @@ -186,7 +194,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Tamil */ - /* 0B80 */ _(x,x), _(x,x), _(Bi,x), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0B80 */ _(x,x), _(x,x), _(Bi,T), _(ML,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0B88 */ _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(x,x), _(VI,x), _(VI,x), /* 0B90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(x,x), _(x,x), /* 0B98 */ _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(x,x), _(C,x), _(C,x), @@ -194,7 +202,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0BA8 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), /* 0BB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0BB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), - /* 0BC0 */ _(M,T), _(M,B), _(M,B), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L), + /* 0BC0 */ _(M,T), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(M,L), _(M,L), /* 0BC8 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T), _(x,x), _(x,x), /* 0BD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), /* 0BD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), @@ -205,7 +213,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Telugu */ - /* 0C00 */ _(Bi,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0C00 */ _(Bi,T), _(Bi,R), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0C08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), /* 0C10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -216,7 +224,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0C40 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,T), /* 0C48 */ _(M,TB), _(x,x), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), _(x,x), /* 0C50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,T), _(M,B), _(x,x), - /* 0C58 */ _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0C58 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 0C60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0C68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 0C70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), @@ -224,26 +232,26 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Kannada */ - /* 0C80 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0C80 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0C88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), /* 0C90 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0C98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0CA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0CA8 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 0CB0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,T), + /* 0CB8 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,B), _(A,x), _(M,R), _(M,T), /* 0CC0 */ _(M,TR), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(M,T), _(M,TR), /* 0CC8 */ _(M,TR), _(x,x), _(M,TR), _(M,TR), _(M,T), _(V,T), _(x,x), _(x,x), /* 0CD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), /* 0CD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(C,x), _(x,x), /* 0CE0 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0CE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 0CF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0CF0 */ _(x,x),_(CWS,x),_(CWS,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* 0CF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), /* Malayalam */ - /* 0D00 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0D00 */ _(x,x), _(Bi,T), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0D08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), /* 0D10 */ _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), /* 0D18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -253,8 +261,8 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0D38 */ _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(A,x), _(M,R), _(M,R), /* 0D40 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(x,x), _(M,L), _(M,L), /* 0D48 */ _(M,L), _(x,x), _(M,LR), _(M,LR), _(M,LR), _(V,T),_(CPR,x), _(x,x), - /* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), - /* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 0D50 */ _(x,x), _(x,x), _(x,x), _(x,x), _(CD,x), _(CD,x), _(CD,x), _(M,R), + /* 0D58 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(VI,x), /* 0D60 */ _(VI,x), _(VI,x), _(M,B), _(M,B), _(x,x), _(x,x), _(Nd,x), _(Nd,x), /* 0D68 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 0D70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), @@ -262,7 +270,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* Sinhala */ - /* 0D80 */ _(x,x), _(x,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), + /* 0D80 */ _(x,x), _(x,x), _(Bi,R), _(Vs,R), _(x,x), _(VI,x), _(VI,x), _(VI,x), /* 0D88 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 0D90 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), /* 0D98 */ _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -278,7 +286,7 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 0DE8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 0DF0 */ _(x,x), _(x,x), _(M,R), _(M,R), _(x,x), _(x,x), _(x,x), _(x,x), -#define indic_offset_0x1000u 1304 +#define indic_offset_0x1000u 1336 /* Myanmar */ @@ -289,52 +297,24 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 1018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* 1020 */ _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 1028 */ _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), _(M,T), _(M,T), _(M,B), - /* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,x), _(TM,x), - /* 1038 */ _(Vs,x), _(IS,x), _(PK,T), _(CM,x), _(CM,x), _(CM,x), _(CM,x), _(C,x), + /* 1030 */ _(M,B), _(M,L), _(M,T), _(M,T), _(M,T), _(M,T), _(Bi,T), _(TM,B), + /* 1038 */ _(Vs,R), _(IS,x), _(PK,T), _(CM,R), _(CM,x), _(CM,B), _(CM,B), _(C,x), /* 1040 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 1048 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(CP,x), _(x,x), /* 1050 */ _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(M,R), _(M,R), - /* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,x), _(CM,x), - /* 1060 */ _(CM,x), _(C,x), _(M,R), _(TM,x), _(TM,x), _(C,x), _(C,x), _(M,R), - /* 1068 */ _(M,R), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(C,x), + /* 1058 */ _(M,B), _(M,B), _(C,x), _(C,x), _(C,x), _(C,x), _(CM,B), _(CM,B), + /* 1060 */ _(CM,B), _(C,x), _(M,R), _(TM,R), _(TM,R), _(C,x), _(C,x), _(M,R), + /* 1068 */ _(M,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(C,x), _(C,x), /* 1070 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(C,x), _(C,x), _(C,x), /* 1078 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1080 */ _(C,x), _(C,x), _(CM,x), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,x), - /* 1088 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(TM,x), + /* 1080 */ _(C,x), _(C,x), _(CM,B), _(M,R), _(M,L), _(M,T), _(M,T), _(TM,R), + /* 1088 */ _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,R), _(TM,B), _(C,x), _(TM,R), /* 1090 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1098 */ _(Nd,x), _(Nd,x), _(TM,x), _(TM,x), _(M,R), _(M,T), _(x,x), _(x,x), + /* 1098 */ _(Nd,x), _(Nd,x), _(TM,R), _(TM,R), _(M,R), _(M,T), _(x,x), _(x,x), -#define indic_offset_0x1700u 1464 +#define indic_offset_0x1780u 1496 - /* Tagalog */ - - /* 1700 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1708 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), - /* 1710 */ _(C,x), _(C,x), _(M,T), _(M,B), _(PK,B), _(x,x), _(x,x), _(x,x), - /* 1718 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Hanunoo */ - - /* 1720 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1728 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1730 */ _(C,x), _(C,x), _(M,T), _(M,B), _(PK,B), _(x,x), _(x,x), _(x,x), - /* 1738 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Buhid */ - - /* 1740 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1748 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1750 */ _(C,x), _(C,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1758 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Tagbanwa */ - - /* 1760 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1768 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), - /* 1770 */ _(C,x), _(x,x), _(M,T), _(M,B), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1778 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* Khmer */ /* 1780 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), @@ -345,515 +325,72 @@ static const INDIC_TABLE_ELEMENT_TYPE indic_table[] = { /* 17A8 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), /* 17B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(M,R), _(M,T), /* 17B8 */ _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,TL),_(M,TLR), - /* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,x), _(Vs,x), - /* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(RS,T),_(CSR,T), _(M,T), _(M,T), _(M,T), - /* 17D0 */ _(M,T), _(PK,T), _(IS,x), _(M,T), _(x,x), _(x,x), _(x,x), _(x,x), - /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(x,x), _(x,x), _(x,x), + /* 17C0 */ _(M,LR), _(M,L), _(M,L), _(M,L), _(M,LR), _(M,LR), _(Bi,T), _(Vs,R), + /* 17C8 */ _(M,R), _(RS,T), _(RS,T), _(SM,T),_(CSR,T), _(CK,T), _(SM,T), _(SM,T), + /* 17D0 */ _(SM,T), _(PK,T), _(IS,x), _(SM,T), _(x,x), _(x,x), _(x,x), _(x,x), + /* 17D8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(A,x), _(SM,T), _(x,x), _(x,x), /* 17E0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* 17E8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define indic_offset_0x1900u 1704 - - - /* Limbu */ - - /* 1900 */ _(CP,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1908 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), - /* 1920 */ _(M,T), _(M,T), _(M,B), _(M,R), _(M,R), _(M,TR), _(M,TR), _(M,T), - /* 1928 */ _(M,T), _(CS,x), _(CS,x), _(CS,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1930 */ _(CF,x), _(CF,x), _(Bi,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), - /* 1938 */ _(CF,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1940 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Nd,x), _(Nd,x), - /* 1948 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - - /* Tai Le */ - - /* 1950 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1958 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1960 */ _(C,x), _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), - /* 1968 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(x,x), _(x,x), - /* 1970 */ _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(TL,x), _(x,x), _(x,x), _(x,x), - /* 1978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* New Tai Lue */ - - /* 1980 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1988 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 19A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 19A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19B0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,L), _(M,L), _(M,L), - /* 19B8 */ _(M,R), _(M,R), _(M,L), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), - /* 19C0 */ _(M,R), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), - /* 19C8 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 19D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19E0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19E8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19F0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 19F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Buginese */ - - /* 1A00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1A08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), - /* 1A18 */ _(M,B), _(M,L), _(M,R), _(M,T), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Tai Tham */ - - /* 1A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1A38 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1A40 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1A48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), - /* 1A50 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(CM,L), _(CM,x), _(CF,x), - /* 1A58 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x), - /* 1A60 */ _(IS,x), _(M,R), _(M,T), _(M,R), _(M,R), _(M,T), _(M,T), _(M,T), - /* 1A68 */ _(M,T), _(M,B), _(M,B), _(M,T), _(M,B), _(M,R), _(M,L), _(M,L), - /* 1A70 */ _(M,L), _(M,L), _(M,L), _(M,T), _(M,T), _(TM,x), _(TM,x), _(TM,x), - /* 1A78 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1A80 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1A88 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1A90 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1A98 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x1b00u 2120 - - - /* Balinese */ - - /* 1B00 */ _(Bi,x), _(Bi,x), _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), - /* 1B08 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 1B10 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1B18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1B20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1B28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1B30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(N,x), _(M,R), _(M,T), _(M,T), - /* 1B38 */ _(M,B), _(M,B), _(M,B), _(M,BR), _(M,TB),_(M,TBR), _(M,L), _(M,L), - /* 1B40 */ _(M,LR), _(M,LR), _(M,T), _(M,TR), _(V,R), _(C,x), _(C,x), _(C,x), - /* 1B48 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1B50 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1B58 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1B60 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1B68 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1B70 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1B78 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Sundanese */ - - /* 1B80 */ _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 1B88 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1B90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1B98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1BA0 */ _(C,x), _(CS,x), _(CS,x), _(CS,x), _(M,T), _(M,B), _(M,L), _(M,R), - /* 1BA8 */ _(M,T), _(M,T), _(PK,R), _(IS,x), _(CS,x), _(CS,x), _(C,x), _(C,x), - /* 1BB0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1BB8 */ _(Nd,x), _(Nd,x), _(A,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), - - /* Batak */ - - /* 1BC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1BC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1BD0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1BD8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1BE0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(N,x), _(M,R), - /* 1BE8 */ _(M,T), _(M,T), _(M,R), _(M,R), _(M,R), _(M,T), _(M,R), _(M,T), - /* 1BF0 */ _(CF,x), _(CF,x), _(PK,R), _(PK,R), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1BF8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Lepcha */ - - /* 1C00 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1C08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1C10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1C18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 1C20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CS,x), _(CS,x), _(M,R), _(M,L), - /* 1C28 */ _(M,L), _(M,TL), _(M,R), _(M,R), _(M,B), _(CF,x), _(CF,x), _(CF,x), - /* 1C30 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(Bi,L), _(Bi,L), _(x,x), _(N,x), - /* 1C38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1C40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 1C48 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(C,x), _(C,x), _(C,x), - -#define indic_offset_0x1cd0u 2456 +#define indic_offset_0x1cd0u 1608 /* Vedic Extensions */ - /* 1CD0 */ _(TM,x), _(TM,x), _(TM,x), _(x,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), - /* 1CD8 */ _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), _(TM,x), - /* 1CE0 */ _(TM,x), _(TM,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1CE8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(TM,x), _(x,x), _(x,x), _(x,x), + /* 1CD0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(x,x), _(Ca,O), _(Ca,B), _(Ca,B), _(Ca,B), + /* 1CD8 */ _(Ca,B), _(Ca,B), _(Ca,T), _(Ca,T), _(Ca,B), _(Ca,B), _(Ca,B), _(Ca,B), + /* 1CE0 */ _(Ca,T), _(Ca,R), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), _(x,O), + /* 1CE8 */ _(x,O), _(x,x), _(x,x), _(x,x), _(x,x), _(x,B), _(x,x), _(x,x), + /* 1CF0 */ _(x,x), _(x,x), _(Vs,x), _(Vs,x), _(Ca,T), _(x,x), _(x,x), _(x,x), + /* 1CF8 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), -#define indic_offset_0x2008u 2496 +#define indic_offset_0x2008u 1656 /* General Punctuation */ /* 2008 */ _(x,x), _(x,x), _(x,x), _(x,x),_(ZWNJ,x),_(ZWJ,x), _(x,x), _(x,x), - /* 2010 */ _(x,x), _(x,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0xa800u 2512 - - - /* Syloti Nagri */ - - /* A800 */ _(VI,x), _(VI,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), _(PK,T), _(C,x), - /* A808 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A810 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A818 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A820 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,B), _(M,T), _(M,R), - /* A828 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A830 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A838 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Phags-pa */ - - /* A840 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A848 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A850 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A858 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Vo,x), _(Vo,x), - /* A860 */ _(Vo,x), _(Vo,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Vo,x), _(CS,x), - /* A868 */ _(CS,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A870 */ _(C,x), _(CS,x), _(C,x), _(Bi,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A878 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Saurashtra */ - - /* A880 */ _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* A888 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* A890 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A898 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A8A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A8A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A8B0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(CF,x), _(M,R), _(M,R), _(M,R), - /* A8B8 */ _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), _(M,R), - /* A8C0 */ _(M,R), _(M,R), _(M,R), _(M,R), _(V,B), _(x,x), _(x,x), _(x,x), - /* A8C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A8D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* A8D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 2010 */ _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), _(x,x), _(x,x), + +#define indic_offset_0x2070u 1672 + + + /* Superscripts and Subscripts */ + + /* 2070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(SM,x), _(x,x), _(x,x), _(x,x), + /* 2078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* 2080 */ _(x,x), _(x,x), _(SM,x), _(SM,x), _(SM,x), _(x,x), _(x,x), _(x,x), + +#define indic_offset_0xa8e0u 1696 + /* Devanagari Extended */ - /* A8E0 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), - /* A8E8 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), - /* A8F0 */ _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A8F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Kayah Li */ - - /* A900 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* A908 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A910 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A918 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A920 */ _(C,x), _(C,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), - /* A928 */ _(Vo,x), _(Vo,x), _(Vo,x), _(TM,x), _(TM,x), _(TM,x), _(x,x), _(x,x), - - /* Rejang */ - - /* A930 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A938 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A940 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,B), - /* A948 */ _(M,B), _(M,B), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B), _(CF,x), - /* A950 */ _(CF,x), _(CF,x), _(CF,x), _(PK,R), _(x,x), _(x,x), _(x,x), _(x,x), - /* A958 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A960 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A968 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A970 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A978 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Javanese */ - - /* A980 */ _(Bi,x), _(Bi,x),_(CSR,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* A988 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), - /* A990 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A998 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A9A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A9A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* A9B0 */ _(C,x), _(C,x), _(C,x), _(N,x), _(M,R), _(M,R), _(M,T), _(M,T), - /* A9B8 */ _(M,B), _(M,B), _(M,L), _(M,L), _(M,T), _(CS,x), _(CM,x), _(CM,x), - /* A9C0 */ _(V,BR), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A9C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* A9D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* A9D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + /* A8E0 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), + /* A8E8 */ _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), _(Ca,T), + /* A8F0 */ _(Ca,T), _(Ca,T), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), + +#define indic_offset_0xa9e0u 1720 + /* Myanmar Extended-B */ - /* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(C,x), + /* A9E0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), _(x,x), _(C,x), /* A9E8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* A9F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), /* A9F8 */ _(Nd,x), _(Nd,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), - /* Cham */ - - /* AA00 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), - /* AA08 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA18 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA28 */ _(C,x), _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,T), _(M,L), - /* AA30 */ _(M,L), _(M,T), _(M,B), _(CM,x), _(CM,L), _(CM,x), _(CM,x), _(x,x), - /* AA38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* AA40 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), - /* AA48 */ _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(x,x), _(x,x), - /* AA50 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* AA58 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), +#define indic_offset_0xaa60u 1752 + /* Myanmar Extended-A */ /* AA60 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), /* AA68 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,x), _(TM,x), _(TM,x), _(C,x), _(C,x), - - /* Tai Viet */ - - /* AA80 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA88 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA90 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AA98 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AAA0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AAA8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AAB0 */ _(M,T), _(M,R), _(M,T), _(M,T), _(M,B),_(M,VOL),_(M,VOL), _(M,T), - /* AAB8 */ _(M,T),_(M,VOL), _(M,R),_(M,VOL),_(M,VOL), _(M,R), _(M,T), _(TM,x), - /* AAC0 */ _(TL,x), _(TM,x), _(TL,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* AAC8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* AAD0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* AAD8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Meetei Mayek Extensions */ - - /* AAE0 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* AAE8 */ _(C,x), _(C,x), _(C,x), _(M,L), _(M,B), _(M,T), _(M,L), _(M,R), - /* AAF0 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(Vs,x), _(IS,x), _(x,x), - -#define indic_offset_0xabc0u 3272 - - - /* Meetei Mayek */ - - /* ABC0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* ABC8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(VI,x), _(VI,x), - /* ABD0 */ _(C,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* ABD8 */ _(C,x), _(C,x), _(C,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), _(CF,x), - /* ABE0 */ _(CF,x), _(CF,x), _(CF,x), _(M,R), _(M,R), _(M,T), _(M,R), _(M,R), - /* ABE8 */ _(M,B), _(M,R), _(M,R), _(x,x), _(TM,x), _(PK,B), _(x,x), _(x,x), - /* ABF0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* ABF8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x10a00u 3336 - - - /* Kharoshthi */ - - /* 10A00 */ _(C,x), _(M,O), _(M,B), _(M,B), _(x,x), _(M,T), _(M,O), _(x,x), - /* 10A08 */ _(x,x), _(x,x), _(x,x), _(x,x), _(M,B), _(x,x), _(Bi,x), _(Vs,x), - /* 10A10 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 10A18 */ _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 10A20 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 10A28 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 10A30 */ _(C,x), _(C,x), _(C,x), _(C,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 10A38 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(IS,x), - /* 10A40 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - -#define indic_offset_0x11000u 3408 - - - /* Brahmi */ - - /* 11000 */ _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 11008 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11010 */ _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11018 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11020 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11028 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11030 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11038 */ _(M,T), _(M,T), _(M,T), _(M,T), _(M,B), _(M,B), _(M,B), _(M,B), - /* 11040 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(x,x), - /* 11048 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11050 */ _(x,x), _(x,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), - /* 11058 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), - /* 11060 */_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x),_(BJN,x), _(Nd,x), _(Nd,x), - /* 11068 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 11070 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11078 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(NJ,x), - - /* Kaithi */ - - /* 11080 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11088 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 11090 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11098 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 110A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 110A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 110B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,R), - /* 110B8 */ _(M,R), _(V,B), _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x11100u 3600 - - - /* Chakma */ - - /* 11100 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), - /* 11108 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11110 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11118 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11120 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,T), - /* 11128 */ _(M,T), _(M,T), _(M,B), _(M,B), _(M,L), _(M,T), _(M,TB), _(M,TB), - /* 11130 */ _(M,T), _(M,B), _(M,B), _(IS,x), _(PK,T), _(x,x), _(Nd,x), _(Nd,x), - /* 11138 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 11140 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11148 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Mahajani */ - - /* 11150 */ _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(Vo,x), _(C,x), _(C,x), _(C,x), - /* 11158 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11160 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11168 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11170 */ _(C,x), _(C,x), _(C,x), _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11178 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Sharada */ - - /* 11180 */ _(Bi,x), _(Bi,x), _(Vs,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11188 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11190 */ _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11198 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 111A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 111A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 111B0 */ _(C,x), _(C,x), _(C,x), _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), - /* 111B8 */ _(M,B), _(M,B), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,TR), - /* 111C0 */ _(V,R), _(A,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 111C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 111D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 111D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Sinhala Archaic Numbers */ - - /* 111E0 */ _(x,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 111E8 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 111F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), - /* 111F8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Khojki */ - - /* 11200 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11208 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11210 */ _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11218 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11220 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11228 */ _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), _(M,R), _(M,R), _(M,B), - /* 11230 */ _(M,T), _(M,T), _(M,TR), _(M,TR), _(Bi,x), _(V,R), _(N,x), _(GM,T), - -#define indic_offset_0x112b0u 3912 - - - /* Khudawadi */ - - /* 112B0 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 112B8 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112C0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112C8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112D0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 112D8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(Bi,x), - /* 112E0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), - /* 112E8 */ _(M,T), _(N,x), _(PK,B), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 112F0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 112F8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Grantha */ - - /* 11300 */ _(x,x), _(Bi,x), _(Bi,x), _(Vs,x), _(x,x), _(VI,x), _(VI,x), _(VI,x), - /* 11308 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(x,x), _(x,x), _(VI,x), - /* 11310 */ _(VI,x), _(x,x), _(x,x), _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), - /* 11318 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11320 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11328 */ _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11330 */ _(C,x), _(x,x), _(C,x), _(C,x), _(x,x), _(C,x), _(C,x), _(C,x), - /* 11338 */ _(C,x), _(C,x), _(x,x), _(x,x), _(N,x), _(A,x), _(M,R), _(M,R), - /* 11340 */ _(M,T), _(M,R), _(M,R), _(M,R), _(M,R), _(x,x), _(x,x), _(M,L), - /* 11348 */ _(M,L), _(x,x), _(x,x), _(M,LR), _(M,LR), _(V,R), _(x,x), _(x,x), - /* 11350 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(M,R), - /* 11358 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11360 */ _(VI,x), _(VI,x), _(M,R), _(M,R), _(x,x), _(x,x), _(Ca,x), _(Ca,x), - /* 11368 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), - /* 11370 */ _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(Ca,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x11480u 4112 - - - /* Tirhuta */ - - /* 11480 */ _(x,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11488 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), - /* 11490 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11498 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 114A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 114A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 114B0 */ _(M,R), _(M,L), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,B), - /* 114B8 */ _(M,B), _(M,L), _(M,T), _(M,TL), _(M,LR), _(M,R), _(M,LR), _(Bi,x), - /* 114C0 */ _(Bi,x), _(Vs,x), _(V,B), _(N,x), _(A,x), _(x,x), _(x,x), _(x,x), - /* 114C8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 114D0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 114D8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x11580u 4208 - - - /* Siddham */ - - /* 11580 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11588 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), - /* 11590 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11598 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 115A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 115A8 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(M,R), - /* 115B0 */ _(M,L), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(x,x), _(x,x), - /* 115B8 */ _(M,L), _(M,TL), _(M,LR),_(M,TLR), _(Bi,x), _(Bi,x), _(Vs,x), _(V,B), - /* 115C0 */ _(N,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -#define indic_offset_0x11600u 4280 - - - /* Modi */ - - /* 11600 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11608 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(C,x), _(C,x), - /* 11610 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11618 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11620 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11628 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11630 */ _(M,R), _(M,R), _(M,R), _(M,B), _(M,B), _(M,B), _(M,B), _(M,B), - /* 11638 */ _(M,B), _(M,T), _(M,T), _(M,R), _(M,R), _(Bi,x), _(Vs,x), _(V,B), - /* 11640 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11648 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11650 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 11658 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11660 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11668 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11670 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 11678 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - - /* Takri */ - - /* 11680 */ _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), _(VI,x), - /* 11688 */ _(VI,x), _(VI,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11690 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 11698 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 116A0 */ _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), _(C,x), - /* 116A8 */ _(C,x), _(C,x), _(C,x), _(Bi,x), _(Vs,x), _(M,T), _(M,L), _(M,R), - /* 116B0 */ _(M,B), _(M,B), _(M,T), _(M,T), _(M,T), _(M,T), _(V,T), _(N,x), - /* 116B8 */ _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - /* 116C0 */ _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), _(Nd,x), - /* 116C8 */ _(Nd,x), _(Nd,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), _(x,x), - -}; /* Table items: 4488; occupancy: 73% */ + /* AA70 */ _(x,x), _(C,x), _(C,x), _(C,x), _(CP,x), _(CP,x), _(CP,x), _(x,x), + /* AA78 */ _(x,x), _(x,x), _(C,x), _(TM,R), _(TM,T), _(TM,R), _(C,x), _(C,x), + +}; /* Table items: 1784; occupancy: 69% */ INDIC_TABLE_ELEMENT_TYPE hb_indic_get_categories (hb_codepoint_t u) @@ -862,40 +399,27 @@ hb_indic_get_categories (hb_codepoint_t u) { case 0x0u: if (hb_in_range (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u]; - if (hb_in_range (u, 0x00D0u, 0x00D7u)) return indic_table[u - 0x00D0u + indic_offset_0x00d0u]; + if (hb_in_range (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u]; if (hb_in_range (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u]; if (unlikely (u == 0x00A0u)) return _(CP,x); break; case 0x1u: if (hb_in_range (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u]; - if (hb_in_range (u, 0x1700u, 0x17EFu)) return indic_table[u - 0x1700u + indic_offset_0x1700u]; - if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return indic_table[u - 0x1900u + indic_offset_0x1900u]; - if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return indic_table[u - 0x1B00u + indic_offset_0x1b00u]; - if (hb_in_range (u, 0x1CD0u, 0x1CF7u)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u]; + if (hb_in_range (u, 0x1780u, 0x17EFu)) return indic_table[u - 0x1780u + indic_offset_0x1780u]; + if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u]; break; case 0x2u: if (hb_in_range (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u]; + if (hb_in_range (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u]; if (unlikely (u == 0x25CCu)) return _(CP,x); break; case 0xAu: - if (hb_in_range (u, 0xA800u, 0xAAF7u)) return indic_table[u - 0xA800u + indic_offset_0xa800u]; - if (hb_in_range (u, 0xABC0u, 0xABFFu)) return indic_table[u - 0xABC0u + indic_offset_0xabc0u]; - break; - - case 0x10u: - if (hb_in_range (u, 0x10A00u, 0x10A47u)) return indic_table[u - 0x10A00u + indic_offset_0x10a00u]; - break; - - case 0x11u: - if (hb_in_range (u, 0x11000u, 0x110BFu)) return indic_table[u - 0x11000u + indic_offset_0x11000u]; - if (hb_in_range (u, 0x11100u, 0x11237u)) return indic_table[u - 0x11100u + indic_offset_0x11100u]; - if (hb_in_range (u, 0x112B0u, 0x11377u)) return indic_table[u - 0x112B0u + indic_offset_0x112b0u]; - if (hb_in_range (u, 0x11480u, 0x114DFu)) return indic_table[u - 0x11480u + indic_offset_0x11480u]; - if (hb_in_range (u, 0x11580u, 0x115C7u)) return indic_table[u - 0x11580u + indic_offset_0x11580u]; - if (hb_in_range (u, 0x11600u, 0x116CFu)) return indic_table[u - 0x11600u + indic_offset_0x11600u]; + if (hb_in_range (u, 0xA8E0u, 0xA8F7u)) return indic_table[u - 0xA8E0u + indic_offset_0xa8e0u]; + if (hb_in_range (u, 0xA9E0u, 0xA9FFu)) return indic_table[u - 0xA9E0u + indic_offset_0xa9e0u]; + if (hb_in_range (u, 0xAA60u, 0xAA7Fu)) return indic_table[u - 0xAA60u + indic_offset_0xaa60u]; break; default: @@ -914,11 +438,14 @@ hb_indic_get_categories (hb_codepoint_t u) #undef ISC_CD #undef ISC_CF #undef ISC_CHL +#undef ISC_CK #undef ISC_CM #undef ISC_CP #undef ISC_CPR +#undef ISC_CPrf #undef ISC_CS #undef ISC_CSR +#undef ISC_CWS #undef ISC_GM #undef ISC_IS #undef ISC_ZWJ @@ -930,6 +457,7 @@ hb_indic_get_categories (hb_codepoint_t u) #undef ISC_x #undef ISC_PK #undef ISC_RS +#undef ISC_SM #undef ISC_TL #undef ISC_TM #undef ISC_V diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc index 44481dbb4c..b48fb561c3 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc @@ -176,24 +176,8 @@ set_indic_properties (hb_glyph_info_t &info) * Re-assign category */ - - /* The spec says U+0952 is OT_A. However, testing shows that Uniscribe - * treats a whole bunch of characters similarly. - * TESTS: For example, for U+0951: - * U+092E,U+0947,U+0952 - * U+092E,U+0952,U+0947 - * U+092E,U+0947,U+0951 - * U+092E,U+0951,U+0947 - * U+092E,U+0951,U+0952 - * U+092E,U+0952,U+0951 - */ - if (unlikely (hb_in_ranges (u, 0x0951u, 0x0952u, - 0x1CD0u, 0x1CD2u, - 0x1CD4u, 0x1CE1u) || - u == 0x1CF4u)) - cat = OT_A; /* The following act more like the Bindus. */ - else if (unlikely (hb_in_range (u, 0x0953u, 0x0954u))) + if (unlikely (hb_in_range (u, 0x0953u, 0x0954u))) cat = OT_SM; /* The following act like consonants. */ else if (unlikely (hb_in_ranges (u, 0x0A72u, 0x0A73u, @@ -216,21 +200,10 @@ set_indic_properties (hb_glyph_info_t &info) cat = OT_Symbol; ASSERT_STATIC ((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol); } - else if (unlikely (hb_in_range (u, 0x17CDu, 0x17D1u) || - u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */ - { - /* These are like Top Matras. */ - cat = OT_M; - pos = POS_ABOVE_C; - } else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */ - else if (unlikely (u == 0x17D2u)) cat = OT_Coeng; /* Khmer coeng */ else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u))) cat = OT_PLACEHOLDER; else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; - else if (unlikely (u == 0xA982u)) cat = OT_SM; /* Javanese repha. */ - else if (unlikely (u == 0xA9BEu)) cat = OT_CM2; /* Javanese medial ya. */ - else if (unlikely (u == 0xA9BDu)) { cat = OT_M; pos = POS_POST_C; } /* Javanese vocalic r. */ /* @@ -296,11 +269,6 @@ enum blwf_mode_t { BLWF_MODE_PRE_AND_POST, /* Below-forms feature applied to pre-base and post-base. */ BLWF_MODE_POST_ONLY /* Below-forms feature applied to post-base only. */ }; -enum pref_len_t { - PREF_LEN_1 = 1, - PREF_LEN_2 = 2, - PREF_LEN_DONT_CARE = PREF_LEN_2 -}; struct indic_config_t { hb_script_t script; @@ -310,26 +278,24 @@ struct indic_config_t reph_position_t reph_pos; reph_mode_t reph_mode; blwf_mode_t blwf_mode; - pref_len_t pref_len; }; static const indic_config_t indic_configs[] = { /* Default. Should be first. */ - {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_1}, - {HB_SCRIPT_DEVANAGARI,true, 0x094Du,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, - {HB_SCRIPT_BENGALI, true, 0x09CDu,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, - {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, - {HB_SCRIPT_GUJARATI, true, 0x0ACDu,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, - {HB_SCRIPT_ORIYA, true, 0x0B4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, - {HB_SCRIPT_TAMIL, true, 0x0BCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_2}, - {HB_SCRIPT_TELUGU, true, 0x0C4Du,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2}, - {HB_SCRIPT_KANNADA, true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2}, - {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2}, + {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_DEVANAGARI,true, 0x094Du,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_BENGALI, true, 0x09CDu,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_GURMUKHI, true, 0x0A4Du,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_GUJARATI, true, 0x0ACDu,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_ORIYA, true, 0x0B4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_TAMIL, true, 0x0BCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_TELUGU, true, 0x0C4Du,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY}, + {HB_SCRIPT_KANNADA, true, 0x0CCDu,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY}, + {HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST}, {HB_SCRIPT_SINHALA, false,0x0DCAu,BASE_POS_LAST_SINHALA, - REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE}, - {HB_SCRIPT_KHMER, false,0x17D2u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2}, - {HB_SCRIPT_JAVANESE, false,0xA9C0u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1}, + REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST}, + {HB_SCRIPT_KHMER, false,0x17D2u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST}, }; @@ -512,12 +478,12 @@ struct indic_shape_plan_t hb_codepoint_t glyph = virama_glyph; if (unlikely (virama_glyph == (hb_codepoint_t) -1)) { - if (!config->virama || !font->get_glyph (config->virama, 0, &glyph)) + if (!config->virama || !font->get_nominal_glyph (config->virama, &glyph)) glyph = 0; /* Technically speaking, the spec says we should apply 'locl' to virama too. * Maybe one day... */ - /* Our get_glyph() function needs a font, so we can't get the virama glyph + /* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph * during shape planning... Instead, overwrite it here. It's safe. Don't worry! */ (const_cast (this))->virama_glyph = glyph; } @@ -557,8 +523,15 @@ data_create_indic (const hb_ot_shape_plan_t *plan) indic_plan->virama_glyph = (hb_codepoint_t) -1; /* Use zero-context would_substitute() matching for new-spec of the main - * Indic scripts, and scripts with one spec only, but not for old-specs. */ - bool zero_context = !indic_plan->is_old_spec; + * Indic scripts, and scripts with one spec only, but not for old-specs. + * The new-spec for all dual-spec scripts says zero-context matching happens. + * + * However, testing with Malayalam shows that old and new spec both allow + * context. Testing with Bengali new-spec however shows that it doesn't. + * So, the heuristic here is the way it is. It should *only* be changed, + * as we discover more cases of what Windows does. DON'T TOUCH OTHERWISE. + */ + bool zero_context = !indic_plan->is_old_spec && plan->props.script != HB_SCRIPT_MALAYALAM; indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context); indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context); indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context); @@ -600,12 +573,8 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan, if (indic_plan->pstf.would_substitute (glyphs , 2, face) || indic_plan->pstf.would_substitute (glyphs+1, 2, face)) return POS_POST_C; - unsigned int pref_len = indic_plan->config->pref_len; - if ((pref_len == PREF_LEN_2 && - (indic_plan->pref.would_substitute (glyphs , 2, face) || - indic_plan->pref.would_substitute (glyphs+1, 2, face))) - || (pref_len == PREF_LEN_1 && - indic_plan->pref.would_substitute (glyphs+1, 1, face))) + if (indic_plan->pref.would_substitute (glyphs , 2, face) || + indic_plan->pref.would_substitute (glyphs+1, 2, face)) return POS_POST_C; return POS_BASE_C; } @@ -754,10 +723,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, switch (indic_plan->config->base_pos) { - default: - assert (false); - HB_FALLTHROUGH; - case BASE_POS_LAST: { /* -> starting from the end of the syllable, move backwards */ @@ -1115,10 +1080,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, } } - unsigned int pref_len = indic_plan->config->pref_len; + unsigned int pref_len = 2; if (indic_plan->mask_array[PREF] && base + pref_len < end) { - assert (1 <= pref_len && pref_len <= 2); /* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */ for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) { hb_codepoint_t glyphs[2]; @@ -1231,7 +1195,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_codepoint_t dottedcircle_glyph; - if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) + if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) return; hb_glyph_info_t dottedcircle = {0}; @@ -1243,7 +1207,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx = 0; unsigned int last_syllable = 0; - while (buffer->idx < buffer->len) + while (buffer->idx < buffer->len && !buffer->in_error) { unsigned int syllable = buffer->cur().syllable(); syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); @@ -1258,7 +1222,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && + while (buffer->idx < buffer->len && !buffer->in_error && last_syllable == buffer->cur().syllable() && buffer->cur().indic_category() == OT_Repha) buffer->next_glyph (); @@ -1328,7 +1292,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, for (base = start; base < end; base++) if (info[base].indic_position() >= POS_BASE_C) { - if (try_pref && base + 1 < end && indic_plan->config->pref_len == 2) + if (try_pref && base + 1 < end) { for (unsigned int i = base + 1; i < end; i++) if ((info[i].mask & indic_plan->mask_array[PREF]) != 0) @@ -1348,6 +1312,25 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, break; } } + /* For Malayalam, skip over unformed below- (but NOT post-) forms. */ + if (buffer->props.script == HB_SCRIPT_MALAYALAM) + { + for (unsigned int i = base + 1; i < end; i++) + { + while (i < end && is_joiner (info[i])) + i++; + if (i == end || !is_halant_or_coeng (info[i])) + break; + i++; /* Skip halant. */ + while (i < end && is_joiner (info[i])) + i++; + if (i < end && is_consonant (info[i]) && info[i].indic_position() == POS_BELOW_C) + { + base = i; + info[base].indic_position() = POS_BASE_C; + } + } + } if (start < base && info[base].indic_position() > POS_BASE_C) base--; @@ -1591,7 +1574,6 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */ { - unsigned int pref_len = indic_plan->config->pref_len; for (unsigned int i = base + 1; i < end; i++) if ((info[i].mask & indic_plan->mask_array[PREF]) != 0) { @@ -1602,10 +1584,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, /* Note: We just check that something got substituted. We don't check that * the feature actually did it... * - * If pref len is longer than one, then only reorder if it ligated. If - * pref len is one, only reorder if it didn't ligate with other things. */ - if (_hb_glyph_info_substituted (&info[i]) && - ((pref_len == 1) ^ _hb_glyph_info_ligated_and_didnt_multiply (&info[i]))) + * Reorder pref only if it ligated. */ + if (_hb_glyph_info_ligated_and_didnt_multiply (&info[i])) { /* * 2. Try to find a target position the same way as for pre-base matra. @@ -1733,33 +1713,28 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, switch (ab) { /* Don't decompose these. */ - case 0x0931u : return false; - case 0x0B94u : return false; + case 0x0931u : return false; /* DEVANAGARI LETTER RRA */ + case 0x0B94u : return false; /* TAMIL LETTER AU */ /* * Decompose split matras that don't have Unicode decompositions. */ - case 0x0F77u : *a = 0x0FB2u; *b= 0x0F81u; return true; - case 0x0F79u : *a = 0x0FB3u; *b= 0x0F81u; return true; + /* Khmer */ case 0x17BEu : *a = 0x17C1u; *b= 0x17BEu; return true; case 0x17BFu : *a = 0x17C1u; *b= 0x17BFu; return true; case 0x17C0u : *a = 0x17C1u; *b= 0x17C0u; return true; case 0x17C4u : *a = 0x17C1u; *b= 0x17C4u; return true; case 0x17C5u : *a = 0x17C1u; *b= 0x17C5u; return true; - case 0x1925u : *a = 0x1920u; *b= 0x1923u; return true; - case 0x1926u : *a = 0x1920u; *b= 0x1924u; return true; - case 0x1B3Cu : *a = 0x1B42u; *b= 0x1B3Cu; return true; - case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true; - case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true; + #if 0 + /* Gujarati */ /* This one has no decomposition in Unicode, but needs no decomposition either. */ /* case 0x0AC9u : return false; */ + + /* Oriya */ case 0x0B57u : *a = no decomp, -> RIGHT; return true; - case 0x1C29u : *a = no decomp, -> LEFT; return true; - case 0xA9C0u : *a = no decomp, -> RIGHT; return true; - case 0x111BuF : *a = no decomp, -> ABOVE; return true; #endif } @@ -1796,7 +1771,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t glyph; if (hb_options ().uniscribe_bug_compatible || - (c->font->get_glyph (ab, 0, &glyph) && + (c->font->get_nominal_glyph (ab, &glyph) && indic_plan->pstf.would_substitute (&glyph, 1, c->font->face))) { /* Ok, safe to use Uniscribe-style decomposition. */ @@ -1806,7 +1781,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c, } } - return c->unicode->decompose (ab, a, b); + return (bool) c->unicode->decompose (ab, a, b); } static bool @@ -1822,7 +1797,7 @@ compose_indic (const hb_ot_shape_normalize_context_t *c, /* Composition-exclusion exceptions that we want to recompose. */ if (a == 0x09AFu && b == 0x09BCu) { *ab = 0x09DFu; return true; } - return c->unicode->compose (a, b, ab); + return (bool) c->unicode->compose (a, b, ab); } @@ -1834,10 +1809,12 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic = data_create_indic, data_destroy_indic, NULL, /* preprocess_text */ + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, decompose_indic, compose_indic, setup_masks_indic, + NULL, /* disable_otl */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc index 7f74f2df82..bb68622e2a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc @@ -199,6 +199,10 @@ set_myanmar_properties (hb_glyph_info_t &info) cat = (indic_category_t) OT_A; break; + case 0x1039u: + cat = (indic_category_t) OT_H; + break; + case 0x103Au: cat = (indic_category_t) OT_As; break; @@ -245,6 +249,11 @@ set_myanmar_properties (hb_glyph_info_t &info) case 0x104Au: case 0x104Bu: cat = (indic_category_t) OT_P; break; + + case 0xAA74u: case 0xAA75u: case 0xAA76u: + /* https://github.com/roozbehp/unicode-data/issues/3 */ + cat = (indic_category_t) OT_C; + break; } if (cat == OT_M) @@ -435,7 +444,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_codepoint_t dottedcircle_glyph; - if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) + if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) return; hb_glyph_info_t dottedcircle = {0}; @@ -447,7 +456,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->idx = 0; unsigned int last_syllable = 0; - while (buffer->idx < buffer->len) + while (buffer->idx < buffer->len && !buffer->in_error) { unsigned int syllable = buffer->cur().syllable(); syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); @@ -507,10 +516,12 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old = NULL, /* data_create */ NULL, /* data_destroy */ NULL, /* preprocess_text */ + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ + NULL, /* disable_otl */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; @@ -523,10 +534,12 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar = NULL, /* data_create */ NULL, /* data_destroy */ NULL, /* preprocess_text */ + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, NULL, /* decompose */ NULL, /* compose */ setup_masks_myanmar, + NULL, /* disable_otl */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh index 8d03dee51f..39572dfe00 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh @@ -41,12 +41,8 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, -// HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, - - HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT = HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE }; @@ -110,6 +106,15 @@ struct hb_ot_complex_shaper_t hb_buffer_t *buffer, hb_font_t *font); + /* postprocess_glyphs() + * Called during shape(). + * Shapers can use to modify glyphs after shaping ends. + * May be NULL. + */ + void (*postprocess_glyphs) (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font); + hb_ot_shape_normalization_mode_t normalization_preference; @@ -141,6 +146,14 @@ struct hb_ot_complex_shaper_t hb_buffer_t *buffer, hb_font_t *font); + /* disable_otl() + * Called during shape(). + * If set and returns true, GDEF/GSUB/GPOS of the font are ignored + * and fallback operations used. + * May be NULL. + */ + bool (*disable_otl) (const hb_ot_shape_plan_t *plan); + hb_ot_shape_zero_width_marks_type_t zero_width_marks; bool fallback_position; @@ -236,9 +249,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-3.0 additions */ case HB_SCRIPT_SINHALA: - /* Unicode-5.2 additions */ - case HB_SCRIPT_JAVANESE: - /* If the designer designed the font for the 'DFLT' script, * use the default shaper. Otherwise, use the specific shaper. * Note that for some simple scripts, there may not be *any* @@ -311,7 +321,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-5.2 additions */ case HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: - //case HB_SCRIPT_JAVANESE: + case HB_SCRIPT_JAVANESE: case HB_SCRIPT_KAITHI: case HB_SCRIPT_MEETEI_MAYEK: case HB_SCRIPT_TAI_THAM: @@ -340,6 +350,15 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_SIDDHAM: case HB_SCRIPT_TIRHUTA: + /* Unicode-8.0 additions */ + case HB_SCRIPT_AHOM: + //case HB_SCRIPT_MULTANI: + + /* Unicode-9.0 additions */ + case HB_SCRIPT_BHAIKSUKI: + case HB_SCRIPT_MARCHEN: + case HB_SCRIPT_NEWA: + /* If the designer designed the font for the 'DFLT' script, * use the default shaper. Otherwise, use the specific shaper. * Note that for some simple scripts, there may not be *any* diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc index 8a8f2f7991..e6f80f59e7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc @@ -139,7 +139,6 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) }; switch (action) { - default: assert (false); HB_FALLTHROUGH; case NOP: return u; case SD: pua_mappings = SD_mappings; break; case SDL: pua_mappings = SDL_mappings; break; @@ -315,7 +314,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, buffer->clear_output (); unsigned int count = buffer->len; - for (buffer->idx = 0; buffer->idx < count;) + for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;) { hb_codepoint_t u = buffer->cur().codepoint; if (likely (!IS_SARA_AM (u))) { @@ -330,7 +329,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, if (unlikely (buffer->in_error)) return; - /* Make Nikhahit be recognized as a mark when zeroing widths. */ + /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ unsigned int end = buffer->out_len; _hb_glyph_info_set_general_category (&buffer->out_info[end - 2], HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK); @@ -372,10 +371,12 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai = NULL, /* data_create */ NULL, /* data_destroy */ preprocess_text_thai, + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, + NULL, /* disable_otl */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, false,/* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc index 01465a426f..aadf59f5ad 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-tibetan.cc @@ -52,10 +52,12 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan = NULL, /* data_create */ NULL, /* data_destroy */ NULL, /* preprocess_text */ + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, NULL, /* decompose */ NULL, /* compose */ NULL, /* setup_masks */ - HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, + NULL, /* disable_otl */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh index ced9d97f28..44e5d0d56b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh @@ -36,291 +36,222 @@ #line 38 "hb-ot-shape-complex-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 0u, 0u, 4u, 4u, 1u, 1u, 0u, 39u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, - 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, + 1u, 1u, 0u, 39u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u, + 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, + 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 13u, 21u, + 4u, 4u, 13u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, - 8u, 39u, 12u, 21u, 12u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, - 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u, + 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u, 42u, 42u, 0 }; static const char _use_syllable_machine_key_spans[] = { - 0, 1, 1, 40, 1, 32, 32, 1, - 32, 32, 32, 19, 19, 19, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 1, 32, 32, 19, 19, + 1, 40, 1, 32, 32, 1, 32, 32, + 32, 19, 19, 19, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 9, + 1, 1, 32, 32, 32, 32, 19, 19, 19, 32, 32, 32, 32, 32, 32, 32, - 32, 10, 2, 32, 32, 32, 32, 19, - 19, 19, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 39, 32, 22, 2, + 32, 32, 32, 1, 39, 32, 22, 2, 1 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 0, 2, 4, 45, 47, 80, 113, - 115, 148, 181, 214, 234, 254, 274, 307, - 340, 373, 406, 439, 472, 505, 538, 571, - 604, 637, 670, 703, 705, 738, 771, 791, - 811, 831, 864, 897, 930, 963, 996, 1029, - 1062, 1095, 1106, 1109, 1142, 1175, 1208, 1241, - 1261, 1281, 1301, 1334, 1367, 1400, 1433, 1466, - 1499, 1532, 1565, 1598, 1631, 1671, 1704, 1727, - 1730 + 0, 2, 43, 45, 78, 111, 113, 146, + 179, 212, 232, 252, 272, 305, 338, 371, + 404, 437, 470, 503, 536, 569, 602, 635, + 645, 647, 649, 682, 715, 748, 781, 801, + 821, 841, 874, 907, 940, 973, 1006, 1039, + 1072, 1105, 1138, 1171, 1173, 1213, 1246, 1269, + 1272 }; static const char _use_syllable_machine_indicies[] = { - 1, 0, 3, 2, 4, 5, 6, - 4, 1, 5, 8, 8, 7, 8, 8, - 3, 9, 8, 8, 8, 4, 4, 10, - 11, 8, 8, 12, 13, 14, 15, 16, - 17, 18, 12, 19, 20, 21, 22, 23, - 24, 8, 25, 26, 27, 8, 29, 28, - 31, 30, 30, 32, 33, 30, 30, 30, - 30, 30, 30, 30, 30, 34, 35, 36, - 37, 38, 39, 40, 41, 35, 42, 34, - 43, 44, 45, 46, 30, 47, 48, 49, - 30, 31, 30, 30, 32, 33, 30, 30, - 30, 30, 30, 30, 30, 30, 50, 35, - 36, 37, 38, 39, 40, 41, 35, 42, - 43, 43, 44, 45, 46, 30, 47, 48, - 49, 30, 32, 51, 31, 30, 30, 32, - 33, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 35, 36, 37, 38, 39, 40, - 41, 35, 42, 43, 43, 44, 45, 46, - 30, 47, 48, 49, 30, 31, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 35, 36, 37, 38, 39, - 30, 30, 30, 30, 30, 30, 44, 45, - 46, 30, 47, 48, 49, 30, 31, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 36, 37, 38, - 39, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 47, 48, 49, 30, 31, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 37, - 38, 39, 30, 31, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 38, 39, 30, 31, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 39, 30, 31, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 37, 38, 39, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 47, 48, 49, 30, 31, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 37, 38, 39, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 48, 49, 30, 31, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 37, 38, 39, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 49, 30, 31, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 36, 37, 38, - 39, 30, 30, 30, 30, 30, 30, 44, - 45, 46, 30, 47, 48, 49, 30, 31, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 36, 37, - 38, 39, 30, 30, 30, 30, 30, 30, - 30, 45, 46, 30, 47, 48, 49, 30, - 31, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 36, - 37, 38, 39, 30, 30, 30, 30, 30, - 30, 30, 30, 46, 30, 47, 48, 49, - 30, 31, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 35, - 36, 37, 38, 39, 30, 41, 35, 30, - 30, 30, 44, 45, 46, 30, 47, 48, - 49, 30, 31, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 35, 36, 37, 38, 39, 30, 30, 35, - 30, 30, 30, 44, 45, 46, 30, 47, - 48, 49, 30, 31, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 35, 36, 37, 38, 39, 40, 41, - 35, 30, 30, 30, 44, 45, 46, 30, - 47, 48, 49, 30, 31, 30, 30, 32, - 33, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 35, 36, 37, 38, 39, 40, - 41, 35, 42, 30, 43, 44, 45, 46, - 30, 47, 48, 49, 30, 31, 30, 30, - 32, 33, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 35, 36, 37, 38, 39, - 40, 41, 35, 42, 34, 43, 44, 45, - 46, 30, 47, 48, 49, 30, 53, 52, - 52, 54, 55, 52, 52, 52, 52, 52, - 52, 52, 52, 56, 52, 57, 58, 59, - 60, 61, 62, 57, 63, 56, 64, 52, - 52, 52, 52, 65, 66, 67, 52, 53, - 52, 52, 54, 55, 52, 52, 52, 52, - 52, 52, 52, 52, 68, 52, 57, 58, - 59, 60, 61, 62, 57, 63, 64, 64, - 52, 52, 52, 52, 65, 66, 67, 52, - 54, 51, 53, 52, 52, 54, 55, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 57, 58, 59, 60, 61, 62, 57, - 63, 64, 64, 52, 52, 52, 52, 65, - 66, 67, 52, 53, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 57, 58, 59, 60, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 65, 66, 67, 52, 53, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 58, 59, 60, 52, - 53, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 59, 60, 52, 53, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 60, 52, - 53, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 58, 59, 60, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 65, 66, 67, - 52, 53, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 58, 59, 60, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 66, - 67, 52, 53, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 58, 59, 60, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 67, 52, 53, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 57, 58, 59, 60, 52, 62, - 57, 52, 52, 52, 52, 52, 52, 52, - 65, 66, 67, 52, 53, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 57, 58, 59, 60, 52, - 52, 57, 52, 52, 52, 52, 52, 52, - 52, 65, 66, 67, 52, 53, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 57, 58, 59, 60, - 61, 62, 57, 52, 52, 52, 52, 52, - 52, 52, 65, 66, 67, 52, 53, 52, - 52, 54, 55, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 57, 58, 59, - 60, 61, 62, 57, 63, 52, 64, 52, - 52, 52, 52, 65, 66, 67, 52, 53, - 52, 52, 54, 55, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 57, 58, - 59, 60, 61, 62, 57, 63, 56, 64, - 52, 52, 52, 52, 65, 66, 67, 52, - 70, 71, 69, 69, 69, 69, 69, 69, - 69, 72, 69, 70, 71, 69, 7, 73, - 73, 3, 9, 73, 73, 73, 73, 73, - 73, 73, 73, 74, 12, 13, 14, 15, - 16, 17, 18, 12, 19, 21, 21, 22, - 23, 24, 73, 25, 26, 27, 73, 7, - 73, 73, 3, 9, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 12, 13, 14, - 15, 16, 17, 18, 12, 19, 21, 21, - 22, 23, 24, 73, 25, 26, 27, 73, - 7, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 12, 13, - 14, 15, 16, 73, 73, 73, 73, 73, - 73, 22, 23, 24, 73, 25, 26, 27, - 73, 7, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 13, 14, 15, 16, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 25, 26, - 27, 73, 7, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 14, 15, 16, 73, 7, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 15, - 16, 73, 7, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 16, 73, 7, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 14, 15, - 16, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 25, 26, 27, 73, 7, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 14, - 15, 16, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 26, 27, 73, - 7, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 14, 15, 16, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 27, - 73, 7, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 13, 14, 15, 16, 73, 73, 73, 73, - 73, 73, 22, 23, 24, 73, 25, 26, - 27, 73, 7, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 13, 14, 15, 16, 73, 73, 73, - 73, 73, 73, 73, 23, 24, 73, 25, - 26, 27, 73, 7, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 13, 14, 15, 16, 73, 73, - 73, 73, 73, 73, 73, 73, 24, 73, - 25, 26, 27, 73, 7, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 12, 13, 14, 15, 16, 73, - 18, 12, 73, 73, 73, 22, 23, 24, - 73, 25, 26, 27, 73, 7, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 12, 13, 14, 15, 16, - 73, 73, 12, 73, 73, 73, 22, 23, - 24, 73, 25, 26, 27, 73, 7, 73, - 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 12, 13, 14, 15, - 16, 17, 18, 12, 73, 73, 73, 22, - 23, 24, 73, 25, 26, 27, 73, 7, - 73, 73, 3, 9, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 12, 13, 14, - 15, 16, 17, 18, 12, 19, 73, 21, - 22, 23, 24, 73, 25, 26, 27, 73, - 5, 6, 73, 73, 5, 73, 73, 7, - 73, 73, 3, 9, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 12, 13, 14, - 15, 16, 17, 18, 12, 19, 20, 21, - 22, 23, 24, 73, 25, 26, 27, 73, - 7, 73, 73, 3, 9, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 12, 13, - 14, 15, 16, 17, 18, 12, 19, 20, - 21, 22, 23, 24, 73, 25, 26, 27, - 73, 76, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 76, 77, 75, - 76, 77, 75, 77, 75, 0 + 1, 0, 2, 3, 4, 2, 5, 3, + 4, 4, 6, 4, 4, 1, 7, 4, + 4, 4, 2, 2, 8, 9, 4, 4, + 10, 11, 12, 13, 14, 15, 16, 10, + 17, 18, 19, 20, 21, 22, 4, 23, + 24, 25, 4, 27, 26, 29, 28, 28, + 30, 31, 28, 28, 28, 28, 28, 28, + 28, 28, 32, 33, 34, 35, 36, 37, + 38, 39, 33, 40, 32, 41, 42, 43, + 44, 28, 45, 46, 47, 28, 29, 28, + 28, 30, 31, 28, 28, 28, 28, 28, + 28, 28, 28, 48, 33, 34, 35, 36, + 37, 38, 39, 33, 40, 41, 41, 42, + 43, 44, 28, 45, 46, 47, 28, 30, + 49, 29, 28, 28, 30, 31, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 33, + 34, 35, 36, 37, 38, 39, 33, 40, + 41, 41, 42, 43, 44, 28, 45, 46, + 47, 28, 29, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 33, 34, 35, 36, 37, 28, 28, 28, + 28, 28, 28, 42, 43, 44, 28, 45, + 46, 47, 28, 29, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 34, 35, 36, 37, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 45, 46, 47, 28, 29, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 35, 36, 37, 28, + 29, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 36, 37, 28, 29, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 37, 28, + 29, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 35, 36, 37, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 45, 46, 47, + 28, 29, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 35, 36, 37, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 46, + 47, 28, 29, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 35, 36, 37, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 47, 28, 29, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 34, 35, 36, 37, 28, 28, + 28, 28, 28, 28, 42, 43, 44, 28, + 45, 46, 47, 28, 29, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 34, 35, 36, 37, 28, + 28, 28, 28, 28, 28, 28, 43, 44, + 28, 45, 46, 47, 28, 29, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 34, 35, 36, 37, + 28, 28, 28, 28, 28, 28, 28, 28, + 44, 28, 45, 46, 47, 28, 29, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 33, 34, 35, 36, + 37, 28, 39, 33, 28, 28, 28, 42, + 43, 44, 28, 45, 46, 47, 28, 29, + 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 33, 34, 35, + 36, 37, 28, 28, 33, 28, 28, 28, + 42, 43, 44, 28, 45, 46, 47, 28, + 29, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 33, 34, + 35, 36, 37, 38, 39, 33, 28, 28, + 28, 42, 43, 44, 28, 45, 46, 47, + 28, 29, 28, 28, 30, 31, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 33, + 34, 35, 36, 37, 38, 39, 33, 40, + 28, 41, 42, 43, 44, 28, 45, 46, + 47, 28, 29, 28, 28, 30, 31, 28, + 28, 28, 28, 28, 28, 28, 28, 28, + 33, 34, 35, 36, 37, 38, 39, 33, + 40, 32, 41, 42, 43, 44, 28, 45, + 46, 47, 28, 51, 50, 50, 50, 50, + 50, 50, 50, 52, 50, 5, 53, 51, + 50, 6, 54, 54, 1, 55, 54, 54, + 54, 54, 54, 54, 54, 54, 56, 10, + 11, 12, 13, 14, 15, 16, 10, 17, + 19, 19, 20, 21, 22, 54, 23, 24, + 25, 54, 6, 54, 54, 1, 55, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 10, 11, 12, 13, 14, 15, 16, 10, + 17, 19, 19, 20, 21, 22, 54, 23, + 24, 25, 54, 6, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 10, 11, 12, 13, 14, 54, 54, + 54, 54, 54, 54, 20, 21, 22, 54, + 23, 24, 25, 54, 6, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 11, 12, 13, 14, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 23, 24, 25, 54, 6, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 12, 13, 14, + 54, 6, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 13, 14, 54, 6, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 14, + 54, 6, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 12, 13, 14, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 23, 24, + 25, 54, 6, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 12, 13, 14, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 24, 25, 54, 6, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 12, 13, 14, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 25, 54, 6, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 11, 12, 13, 14, 54, + 54, 54, 54, 54, 54, 20, 21, 22, + 54, 23, 24, 25, 54, 6, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 11, 12, 13, 14, + 54, 54, 54, 54, 54, 54, 54, 21, + 22, 54, 23, 24, 25, 54, 6, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 11, 12, 13, + 14, 54, 54, 54, 54, 54, 54, 54, + 54, 22, 54, 23, 24, 25, 54, 6, + 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 10, 11, 12, + 13, 14, 54, 16, 10, 54, 54, 54, + 20, 21, 22, 54, 23, 24, 25, 54, + 6, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 10, 11, + 12, 13, 14, 54, 54, 10, 54, 54, + 54, 20, 21, 22, 54, 23, 24, 25, + 54, 6, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 10, + 11, 12, 13, 14, 15, 16, 10, 54, + 54, 54, 20, 21, 22, 54, 23, 24, + 25, 54, 6, 54, 54, 1, 55, 54, + 54, 54, 54, 54, 54, 54, 54, 54, + 10, 11, 12, 13, 14, 15, 16, 10, + 17, 54, 19, 20, 21, 22, 54, 23, + 24, 25, 54, 1, 57, 3, 54, 54, + 54, 3, 54, 54, 6, 54, 54, 1, + 55, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 10, 11, 12, 13, 14, 15, + 16, 10, 17, 18, 19, 20, 21, 22, + 54, 23, 24, 25, 54, 6, 54, 54, + 1, 55, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 10, 11, 12, 13, 14, + 15, 16, 10, 17, 18, 19, 20, 21, + 22, 54, 23, 24, 25, 54, 59, 58, + 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 59, 60, 58, 59, 60, 58, + 60, 58, 0 }; static const char _use_syllable_machine_trans_targs[] = { - 3, 41, 3, 43, 4, 5, 25, 3, - 0, 2, 60, 62, 45, 46, 47, 48, - 49, 56, 57, 58, 61, 59, 53, 54, - 55, 50, 51, 52, 3, 3, 3, 3, - 6, 7, 24, 9, 10, 11, 12, 13, - 20, 21, 22, 23, 17, 18, 19, 14, - 15, 16, 8, 3, 3, 3, 26, 27, - 40, 29, 30, 31, 32, 36, 37, 38, - 39, 33, 34, 35, 28, 3, 3, 1, - 42, 3, 44, 3, 63, 64 + 1, 26, 2, 3, 1, 23, 1, 43, + 44, 46, 28, 29, 30, 31, 32, 39, + 40, 41, 45, 42, 36, 37, 38, 33, + 34, 35, 1, 1, 1, 1, 4, 5, + 22, 7, 8, 9, 10, 11, 18, 19, + 20, 21, 15, 16, 17, 12, 13, 14, + 6, 1, 1, 24, 25, 1, 1, 0, + 27, 1, 1, 47, 48 }; static const char _use_syllable_machine_trans_actions[] = { - 1, 2, 3, 4, 0, 0, 0, 7, - 0, 0, 4, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4, 4, 0, 0, - 0, 0, 0, 0, 8, 9, 10, 11, + 1, 2, 0, 0, 5, 0, 6, 0, + 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 13, 14, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 15, 16, 0, - 2, 17, 4, 18, 0, 0 + 0, 11, 12, 0, 0, 13, 14, 0, + 2, 15, 16, 0, 0 }; static const char _use_syllable_machine_to_state_actions[] = { - 0, 0, 0, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -330,9 +261,7 @@ static const char _use_syllable_machine_to_state_actions[] = { }; static const char _use_syllable_machine_from_state_actions[] = { - 0, 0, 0, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -342,29 +271,27 @@ static const char _use_syllable_machine_from_state_actions[] = { }; static const short _use_syllable_machine_eof_trans[] = { - 0, 1, 3, 0, 29, 31, 31, 52, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 53, 53, 52, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, - 53, 70, 70, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 76, 76, - 76 + 1, 0, 27, 29, 29, 50, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 51, + 54, 51, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 58, 55, 55, 59, 59, + 59 }; -static const int use_syllable_machine_start = 3; -static const int use_syllable_machine_first_final = 3; -static const int use_syllable_machine_error = 0; +static const int use_syllable_machine_start = 1; +static const int use_syllable_machine_first_final = 1; +static const int use_syllable_machine_error = -1; -static const int use_syllable_machine_en_main = 3; +static const int use_syllable_machine_en_main = 1; #line 38 "hb-ot-shape-complex-use-machine.rl" -#line 145 "hb-ot-shape-complex-use-machine.rl" +#line 138 "hb-ot-shape-complex-use-machine.rl" #define found_syllable(syllable_type) \ @@ -384,7 +311,7 @@ find_syllables (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 388 "hb-ot-shape-complex-use-machine.hh" +#line 315 "hb-ot-shape-complex-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -392,7 +319,7 @@ find_syllables (hb_buffer_t *buffer) act = 0; } -#line 166 "hb-ot-shape-complex-use-machine.rl" +#line 159 "hb-ot-shape-complex-use-machine.rl" p = 0; @@ -401,7 +328,7 @@ find_syllables (hb_buffer_t *buffer) unsigned int last = 0; unsigned int syllable_serial = 1; -#line 405 "hb-ot-shape-complex-use-machine.hh" +#line 332 "hb-ot-shape-complex-use-machine.hh" { int _slen; int _trans; @@ -409,15 +336,13 @@ find_syllables (hb_buffer_t *buffer) const char *_inds; if ( p == pe ) goto _test_eof; - if ( cs == 0 ) - goto _out; _resume: switch ( _use_syllable_machine_from_state_actions[cs] ) { - case 6: + case 4: #line 1 "NONE" {ts = p;} break; -#line 421 "hb-ot-shape-complex-use-machine.hh" +#line 346 "hb-ot-shape-complex-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -439,92 +364,70 @@ _eof_trans: #line 1 "NONE" {te = p+1;} break; - case 9: -#line 134 "hb-ot-shape-complex-use-machine.rl" + case 8: +#line 127 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (independent_cluster); }} break; - case 11: -#line 136 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (consonant_cluster); }} - break; - case 14: -#line 137 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (vowel_cluster); }} - break; - case 16: -#line 138 "hb-ot-shape-complex-use-machine.rl" - {te = p+1;{ found_syllable (number_joiner_terminated_cluster); }} + case 10: +#line 129 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (standard_cluster); }} break; - case 7: -#line 141 "hb-ot-shape-complex-use-machine.rl" + case 6: +#line 133 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (broken_cluster); }} break; - case 8: + case 5: #line 134 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (non_cluster); }} + break; + case 7: +#line 127 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (independent_cluster); }} break; - case 12: -#line 135 "hb-ot-shape-complex-use-machine.rl" + case 11: +#line 128 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (virama_terminated_cluster); }} break; - case 10: -#line 136 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (consonant_cluster); }} + case 9: +#line 129 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (standard_cluster); }} break; case 13: -#line 137 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (vowel_cluster); }} +#line 130 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} break; - case 15: -#line 139 "hb-ot-shape-complex-use-machine.rl" + case 12: +#line 131 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (numeral_cluster); }} break; - case 18: -#line 140 "hb-ot-shape-complex-use-machine.rl" + case 16: +#line 132 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (symbol_cluster); }} break; - case 17: -#line 141 "hb-ot-shape-complex-use-machine.rl" + case 14: +#line 133 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; - case 1: -#line 139 "hb-ot-shape-complex-use-machine.rl" - {{p = ((te))-1;}{ found_syllable (numeral_cluster); }} - break; - case 3: -#line 1 "NONE" - { switch( act ) { - case 0: - {{cs = 0; goto _again;}} - break; - case 8: - {{p = ((te))-1;} found_syllable (broken_cluster); } - break; - } - } + case 15: +#line 134 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (non_cluster); }} break; - case 4: -#line 1 "NONE" - {te = p+1;} -#line 141 "hb-ot-shape-complex-use-machine.rl" - {act = 8;} + case 1: +#line 133 "hb-ot-shape-complex-use-machine.rl" + {{p = ((te))-1;}{ found_syllable (broken_cluster); }} break; -#line 513 "hb-ot-shape-complex-use-machine.hh" +#line 420 "hb-ot-shape-complex-use-machine.hh" } _again: switch ( _use_syllable_machine_to_state_actions[cs] ) { - case 5: + case 3: #line 1 "NONE" {ts = 0;} -#line 1 "NONE" - {act = 0;} break; -#line 524 "hb-ot-shape-complex-use-machine.hh" +#line 429 "hb-ot-shape-complex-use-machine.hh" } - if ( cs == 0 ) - goto _out; if ( ++p != pe ) goto _resume; _test_eof: {} @@ -536,10 +439,9 @@ _again: } } - _out: {} } -#line 175 "hb-ot-shape-complex-use-machine.rl" +#line 168 "hb-ot-shape-complex-use-machine.rl" } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh index a143736211..ae428cb5eb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh @@ -46,7 +46,6 @@ enum use_category_t { USE_O = 0, /* OTHER */ USE_B = 1, /* BASE */ - USE_IV = 2, /* BASE_VOWEL */ USE_IND = 3, /* BASE_IND */ USE_N = 4, /* BASE_NUM */ USE_GB = 5, /* BASE_OTHER */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc index 6cd1c5db75..38c46d002d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-8.0.0.txt - * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI] - * # IndicPositionalCategory-8.0.0.txt - * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI] - * # Blocks-8.0.0.txt - * # Date: 2014-11-10, 23:04:00 GMT [KW] + * # IndicSyllabicCategory-9.0.0.txt + * # Date: 2016-05-21, 02:46:00 GMT [RP] + * # IndicPositionalCategory-9.0.0.txt + * # Date: 2016-02-25, 00:48:00 GMT [RP] + * # Blocks-9.0.0.txt + * # Date: 2016-02-05, 23:48:00 GMT [KW] * UnicodeData.txt does not have a header. */ @@ -24,7 +24,6 @@ #define H USE_H /* HALANT */ #define HN USE_HN /* HALANT_NUM */ #define IND USE_IND /* BASE_IND */ -#define IV USE_IV /* BASE_VOWEL */ #define N USE_N /* BASE_NUM */ #define O USE_O /* OTHER */ #define R USE_R /* REPHA */ @@ -80,30 +79,30 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Devanagari */ - /* 0900 */ VMAbv, VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 0910 */ IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0900 */ VMAbv, VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0930 */ B, B, B, B, B, B, B, B, B, B, VAbv, VPst, CMBlw, B, VPst, VPre, /* 0940 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst, /* 0950 */ O, VMAbv, VMBlw, O, O, VAbv, VBlw, VBlw, B, B, B, B, B, B, B, B, - /* 0960 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0970 */ O, O, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, + /* 0960 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0970 */ O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* Bengali */ - /* 0980 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, - /* 0990 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0980 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B, + /* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre, /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, IND, O, /* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B, - /* 09E0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Gurmukhi */ - /* 0A00 */ O, VMAbv, VMAbv, VMPst, O, IV, IV, IV, IV, IV, IV, O, O, O, O, IV, - /* 0A10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0A00 */ O, VMAbv, VMAbv, VMPst, O, B, B, B, B, B, B, O, O, O, O, B, + /* 0A10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0A20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0A30 */ B, O, B, B, O, B, B, O, B, B, O, O, CMBlw, O, VPst, VPre, /* 0A40 */ VPst, VBlw, VBlw, O, O, O, O, VAbv, VAbv, O, O, VAbv, VAbv, H, O, O, @@ -113,30 +112,30 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Gujarati */ - /* 0A80 */ O, VMAbv, VMAbv, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, - /* 0A90 */ IV, IV, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0A80 */ O, VMAbv, VMAbv, VMPst, O, B, B, B, B, B, B, B, B, B, O, B, + /* 0A90 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0AA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0AB0 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPre, /* 0AC0 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, O, VAbv, VAbv, VAbv, O, VPst, VPst, H, O, O, /* 0AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 0AE0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0AE0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0AF0 */ O, O, O, O, O, O, O, O, O, B, O, O, O, O, O, O, /* Oriya */ - /* 0B00 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, - /* 0B10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0B00 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B, + /* 0B10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv, /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, /* 0B50 */ O, O, O, O, O, O, VAbv, VAbv, O, O, O, O, B, B, O, B, - /* 0B60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0B60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Tamil */ - /* 0B80 */ O, O, VMAbv, IND, O, IV, IV, IV, IV, IV, IV, O, O, O, IV, IV, - /* 0B90 */ IV, O, IV, IV, IV, B, O, O, O, B, B, O, B, O, B, B, + /* 0B80 */ O, O, VMAbv, IND, O, B, B, B, B, B, B, O, O, O, B, B, + /* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B, /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B, /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst, /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O, @@ -146,41 +145,41 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Telugu */ - /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, - /* 0C10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B, + /* 0C10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0C20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, VAbv, VAbv, /* 0C40 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O, /* 0C50 */ O, O, O, O, O, VAbv, VBlw, O, B, B, B, O, O, O, O, O, - /* 0C60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0C60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0C70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Kannada */ - /* 0C80 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, - /* 0C90 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0C80 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B, + /* 0C90 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0CA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 0CB0 */ B, B, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv, /* 0CC0 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O, /* 0CD0 */ O, O, O, O, O, VPst, VPst, O, O, O, O, O, O, O, B, O, - /* 0CE0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0CE0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0CF0 */ O, R, R, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Malayalam */ - /* 0D00 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, - /* 0D10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0D00 */ O, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, B, B, + /* 0D10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, O, O, B, VPst, VPst, /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O, - /* 0D50 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, IV, - /* 0D60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B, + /* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND, /* Sinhala */ - /* 0D80 */ O, O, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 0D90 */ IV, IV, IV, IV, IV, IV, IV, O, O, O, B, B, B, B, B, B, + /* 0D80 */ O, O, VMPst, VMPst, O, B, B, B, B, B, B, B, B, B, B, B, + /* 0D90 */ B, B, B, B, B, B, B, O, O, O, B, B, B, B, B, B, /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O, /* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst, @@ -195,10 +194,10 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1020 */ B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, VPst, VPst, VAbv, VAbv, VBlw, + /* 1020 */ B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VAbv, VAbv, VBlw, /* 1030 */ VBlw, VPre, VAbv, VAbv, VAbv, VAbv, VMAbv, VMBlw, VMPst, H, VAbv, MPst, MPre, MBlw, MBlw, B, /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, GB, O, - /* 1050 */ B, B, IV, IV, IV, IV, VPst, VPst, VBlw, VBlw, B, B, B, B, MBlw, MBlw, + /* 1050 */ B, B, B, B, B, B, VPst, VPst, VBlw, VBlw, B, B, B, B, MBlw, MBlw, /* 1060 */ MBlw, B, VPst, VMPst, VMPst, B, B, VPst, VPst, VMPst, VMPst, VMPst, VMPst, VMPst, B, B, /* 1070 */ B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, B, B, B, B, B, B, /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, @@ -209,30 +208,30 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Tagalog */ - /* 1700 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, + /* 1700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, B, /* 1710 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O, /* Hanunoo */ - /* 1720 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1720 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1730 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O, /* Buhid */ - /* 1740 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1740 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1750 */ B, B, VAbv, VBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* Tagbanwa */ - /* 1760 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, + /* 1760 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, B, /* 1770 */ B, O, VAbv, VBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* Khmer */ /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17A0 */ B, B, B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 17B0 */ IV, IV, IV, IV, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, + /* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FM, FAbv, CMAbv, FM, FM, /* 17D0 */ FM, VAbv, H, FM, O, O, O, O, O, O, O, O, B, VAbv, O, O, /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, @@ -274,8 +273,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, IV, - /* 1A50 */ IV, IV, IV, B, B, MPre, MBlw, FPst, FAbv, FAbv, FAbv, FBlw, FBlw, FBlw, FBlw, O, + /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A50 */ B, B, B, B, B, MPre, MBlw, FPst, FAbv, FAbv, FAbv, FBlw, FBlw, FBlw, FBlw, O, /* 1A60 */ H, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, /* 1A70 */ VPre, VPre, VPre, VAbv, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, FM, FM, FM, O, O, FM, /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, @@ -286,8 +285,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Balinese */ - /* 1B00 */ VMAbv, VMAbv, VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 1B10 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1B00 */ VMAbv, VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, + /* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, @@ -297,7 +296,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Sundanese */ - /* 1B80 */ VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 1B80 */ VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1BA0 */ B, SUB, SUB, SUB, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, H, SUB, SUB, B, B, /* 1BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, @@ -306,7 +305,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BE0 */ B, B, B, B, IV, IV, CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, + /* 1BE0 */ B, B, B, B, B, B, CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, /* 1BF0 */ FAbv, FAbv, VPst, VPst, O, O, O, O, O, O, O, O, O, O, O, O, /* Lepcha */ @@ -326,14 +325,20 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, /* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, O, VMAbv, VMAbv, O, O, O, O, O, O, -#define use_offset_0x2008u 2552 +#define use_offset_0x1df8u 2552 + + + /* Combining Diacritical Marks Supplement */ + O, O, O, FM, O, O, O, O, + +#define use_offset_0x2008u 2560 /* General Punctuation */ O, O, O, O, ZWNJ, ZWJ, O, O, /* 2010 */ GB, GB, GB, GB, GB, O, O, O, -#define use_offset_0x2060u 2568 +#define use_offset_0x2060u 2576 /* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -342,12 +347,12 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O, /* 2080 */ O, O, FM, FM, FM, O, O, O, -#define use_offset_0xa800u 2608 +#define use_offset_0xa800u 2616 /* Syloti Nagri */ - /* A800 */ IV, IV, O, IV, IV, IV, VAbv, B, B, B, B, VMAbv, B, B, B, B, + /* A800 */ B, B, O, B, B, B, VAbv, B, B, B, B, VMAbv, B, B, B, B, /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* A820 */ B, B, B, VPst, VPst, VBlw, VAbv, VPst, O, O, O, O, O, O, O, O, /* A830 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -361,11 +366,11 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Saurashtra */ - /* A880 */ VMPst, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* A890 */ IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A880 */ VMPst, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* A8A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* A8B0 */ B, B, B, B, FPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, - /* A8C0 */ VPst, VPst, VPst, VPst, H, O, O, O, O, O, O, O, O, O, O, O, + /* A8C0 */ VPst, VPst, VPst, VPst, H, VMAbv, O, O, O, O, O, O, O, O, O, O, /* A8D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* Devanagari Extended */ @@ -389,7 +394,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Javanese */ - /* A980 */ VMAbv, VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, B, B, B, IV, IV, IV, B, + /* A980 */ VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, /* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, SUB, MPst, MPst, @@ -403,7 +408,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Cham */ - /* AA00 */ IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, + /* AA00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* AA20 */ B, B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MBlw, MBlw, O, O, O, O, O, O, O, O, O, @@ -413,7 +418,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Myanmar Extended-A */ /* AA60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA70 */ O, B, B, B, O, O, O, O, O, O, B, VMPst, VMAbv, VMPst, B, B, + /* AA70 */ O, B, B, B, GB, GB, GB, O, O, O, B, VMPst, VMAbv, VMPst, B, B, /* Tai Viet */ @@ -426,27 +431,27 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Meetei Mayek Extensions */ - /* AAE0 */ IV, IV, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, + /* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, /* AAF0 */ O, O, O, O, O, VMPst, H, O, -#define use_offset_0xabc0u 3368 +#define use_offset_0xabc0u 3376 /* Meetei Mayek */ - /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, - /* ABD0 */ B, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* ABD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0xfe00u 3432 +#define use_offset_0xfe00u 3440 /* Variation Selectors */ /* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, -#define use_offset_0x10a00u 3448 +#define use_offset_0x10a00u 3456 /* Kharoshthi */ @@ -457,13 +462,13 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 10A30 */ B, B, B, B, O, O, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, /* 10A40 */ B, B, B, B, B, B, B, B, -#define use_offset_0x11000u 3520 +#define use_offset_0x11000u 3528 /* Brahmi */ - /* 11000 */ VMPst, VMAbv, VMPst, R, R, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 11010 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11000 */ VMPst, VMAbv, VMPst, R, R, B, B, B, B, B, B, B, B, B, B, B, + /* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O, @@ -473,17 +478,17 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Kaithi */ - /* 11080 */ VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, + /* 11080 */ VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, -#define use_offset_0x11100u 3712 +#define use_offset_0x11100u 3720 /* Chakma */ - /* 11100 */ VMAbv, VMAbv, VMAbv, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, + /* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11120 */ B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv, /* 11130 */ VAbv, VBlw, VBlw, H, VAbv, O, B, B, B, B, B, B, B, B, B, B, @@ -497,8 +502,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Sharada */ - /* 11180 */ VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, - /* 11190 */ IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11180 */ VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, /* 111C0 */ H, B, R, R, O, O, O, O, O, O, CMBlw, VAbv, VBlw, O, O, O, @@ -511,23 +516,23 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Khojki */ - /* 11200 */ IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, + /* 11200 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11210 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, - /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, + /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O, -#define use_offset_0x11280u 4024 +#define use_offset_0x11280u 4040 /* Multani */ - /* 11280 */ IV, IV, IV, IV, B, B, B, O, B, O, B, B, B, B, O, B, + /* 11280 */ B, B, B, B, B, B, B, O, B, O, B, B, B, B, O, B, /* 11290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, /* 112A0 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, /* Khudawadi */ - /* 112B0 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 112B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 112C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 112D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, /* 112E0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, CMBlw, VBlw, O, O, O, O, O, @@ -535,44 +540,55 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Grantha */ - /* 11300 */ VMAbv, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, - /* 11310 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 11300 */ VMAbv, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, O, O, B, + /* 11310 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPst, /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, /* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O, - /* 11360 */ IV, IV, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, + /* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, -#define use_offset_0x11480u 4272 +#define use_offset_0x11400u 4288 + /* Newa */ + + /* 11400 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11410 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11430 */ B, B, B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, + /* 11440 */ VPst, VPst, H, VMAbv, VMAbv, VMPst, CMBlw, B, O, O, O, O, O, O, O, O, + /* 11450 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 11460 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11470 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* Tirhuta */ - /* 11480 */ O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, + /* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv, /* 114C0 */ VMAbv, VMPst, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x11580u 4368 +#define use_offset_0x11580u 4512 /* Siddham */ - /* 11580 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, + /* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H, /* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 115D0 */ O, O, O, O, O, O, O, O, IV, IV, IV, IV, VBlw, VBlw, O, O, + /* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, O, O, /* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 115F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* Modi */ - /* 11600 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, + /* 11600 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11610 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11620 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11630 */ VPst, VPst, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPst, VPst, VMAbv, VMPst, H, @@ -583,7 +599,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* Takri */ - /* 11680 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 11680 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11690 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 116A0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMPst, VAbv, VPre, VPst, /* 116B0 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, CMBlw, O, O, O, O, O, O, O, O, @@ -599,7 +615,28 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O, /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, -}; /* Table items: 4816; occupancy: 72% */ +#define use_offset_0x11c00u 4960 + + + /* Bhaiksuki */ + + /* 11C00 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 11C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, + /* 11C30 */ VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VBlw, O, VAbv, VAbv, VAbv, VAbv, VMAbv, VMAbv, VMPst, H, + /* 11C40 */ B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, + + /* Marchen */ + + /* 11C70 */ O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11C90 */ O, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, + /* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, + /* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O, + +}; /* Table items: 5144; occupancy: 72% */ USE_TABLE_ELEMENT_TYPE hb_use_get_categories (hb_codepoint_t u) @@ -619,6 +656,7 @@ hb_use_get_categories (hb_codepoint_t u) if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u]; if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u]; if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u]; + if (hb_in_range (u, 0x1DF8u, 0x1DFFu)) return use_table[u - 0x1DF8u + use_offset_0x1df8u]; break; case 0x2u: @@ -642,10 +680,11 @@ hb_use_get_categories (hb_codepoint_t u) case 0x11u: if (hb_in_range (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u]; - if (hb_in_range (u, 0x11100u, 0x11237u)) return use_table[u - 0x11100u + use_offset_0x11100u]; + if (hb_in_range (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u]; if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; - if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u]; + if (hb_in_range (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u]; if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; + if (hb_in_range (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u]; if (unlikely (u == 0x1107Fu)) return HN; break; @@ -662,7 +701,6 @@ hb_use_get_categories (hb_codepoint_t u) #undef H #undef HN #undef IND -#undef IV #undef N #undef O #undef R diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc index 779a9cb1d0..5b19d5d74a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc @@ -184,6 +184,9 @@ has_arabic_joining (hb_script_t script) case HB_SCRIPT_MANICHAEAN: case HB_SCRIPT_PSALTER_PAHLAVI: + /* Unicode-9.0 additions */ + case HB_SCRIPT_ADLAM: + return true; default: @@ -227,12 +230,12 @@ data_destroy_use (void *data) enum syllable_type_t { independent_cluster, virama_terminated_cluster, - consonant_cluster, - vowel_cluster, + standard_cluster, number_joiner_terminated_cluster, numeral_cluster, symbol_cluster, broken_cluster, + non_cluster, }; #include "hb-ot-shape-complex-use-machine.hh" @@ -285,6 +288,9 @@ static void setup_topographical_masks (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer) { + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; + if (use_plan->arabic_plan) + return; ASSERT_STATIC (INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4); hb_mask_t masks[4], all_masks = 0; @@ -309,13 +315,13 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan, { case independent_cluster: case symbol_cluster: + case non_cluster: /* These don't join. Nothing to do. */ last_form = _NONE; break; case virama_terminated_cluster: - case consonant_cluster: - case vowel_cluster: + case standard_cluster: case number_joiner_terminated_cluster: case numeral_cluster: case broken_cluster: @@ -360,7 +366,7 @@ clear_substitution_flags (const hb_ot_shape_plan_t *plan, hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) - _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (&info[i]); + _hb_glyph_info_clear_substituted (&info[i]); } static void @@ -405,6 +411,12 @@ record_pref (const hb_ot_shape_plan_t *plan, } } +static inline bool +is_halant (const hb_glyph_info_t &info) +{ + return info.use_category() == USE_H && !_hb_glyph_info_ligated (&info); +} + static void reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) { @@ -412,28 +424,26 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) /* Only a few syllable types need reordering. */ if (unlikely (!(FLAG_SAFE (syllable_type) & (FLAG (virama_terminated_cluster) | - FLAG (consonant_cluster) | - FLAG (vowel_cluster) | + FLAG (standard_cluster) | FLAG (broken_cluster) | 0)))) return; hb_glyph_info_t *info = buffer->info; -#define HALANT_FLAGS FLAG(USE_H) -#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV)) +#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB)) /* Move things forward. */ if (info[start].use_category() == USE_R && end - start > 1) { /* Got a repha. Reorder it to after first base, before first halant. */ for (unsigned int i = start + 1; i < end; i++) - if (FLAG_UNSAFE (info[i].use_category()) & (HALANT_FLAGS | BASE_FLAGS)) + if ((FLAG_UNSAFE (info[i].use_category()) & (BASE_FLAGS)) || is_halant (info[i])) { /* If we hit a halant, move before it; otherwise it's a base: move to it's * place, and shift things in between backward. */ - if (info[i].use_category() == USE_H) + if (is_halant (info[i])) i--; buffer->merge_clusters (start, i + 1); @@ -450,11 +460,11 @@ reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) for (unsigned int i = start; i < end; i++) { uint32_t flag = FLAG_UNSAFE (info[i].use_category()); - if (flag & (HALANT_FLAGS | BASE_FLAGS)) + if ((flag & (BASE_FLAGS)) || is_halant (info[i])) { - /* If we hit a halant, move before it; otherwise it's a base: move to it's + /* If we hit a halant, move after it; otherwise it's a base: move to it's * place, and shift things in between backward. */ - if (info[i].use_category() == USE_H) + if (is_halant (info[i])) j = i + 1; else j = i; @@ -490,22 +500,16 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, if (likely (!has_broken_syllables)) return; - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) - return; - hb_glyph_info_t dottedcircle = {0}; - if (!font->get_glyph (0x25CCu, 0, &dottedcircle.codepoint)) + if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint)) return; dottedcircle.use_category() = hb_use_get_categories (0x25CC); buffer->clear_output (); buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len) + while (buffer->idx < buffer->len && !buffer->in_error) { unsigned int syllable = buffer->cur().syllable(); syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); @@ -520,7 +524,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ - while (buffer->idx < buffer->len && + while (buffer->idx < buffer->len && !buffer->in_error && last_syllable == buffer->cur().syllable() && buffer->cur().use_category() == USE_R) buffer->next_glyph (); @@ -554,6 +558,47 @@ reorder (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); } +static bool +decompose_use (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t ab, + hb_codepoint_t *a, + hb_codepoint_t *b) +{ + switch (ab) + { + /* Chakma: + * Special case where the Unicode decomp gives matras in the wrong order + * for cluster validation. + */ + case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true; + case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true; + + /* + * Decompose split matras that don't have Unicode decompositions. + */ + + /* Limbu */ + case 0x1925u : *a = 0x1920u; *b= 0x1923u; return true; + case 0x1926u : *a = 0x1920u; *b= 0x1924u; return true; + + /* Balinese */ + case 0x1B3Cu : *a = 0x1B42u; *b= 0x1B3Cu; return true; + +#if 0 + /* Lepcha */ + case 0x1C29u : *a = no decomp, -> LEFT; return true; + + /* Javanese */ + case 0xA9C0u : *a = no decomp, -> RIGHT; return true; + + /* Sharada */ + case 0x111BFu : *a = no decomp, -> ABOVE; return true; +#endif + } + + return (bool) c->unicode->decompose (ab, a, b); +} + static bool compose_use (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t a, @@ -564,7 +609,7 @@ compose_use (const hb_ot_shape_normalize_context_t *c, if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a))) return false; - return c->unicode->compose (a, b, ab); + return (bool)c->unicode->compose (a, b, ab); } @@ -576,10 +621,12 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = data_create_use, data_destroy_use, NULL, /* preprocess_text */ + NULL, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, - NULL, /* decompose */ + decompose_use, compose_use, setup_masks_use, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, + NULL, /* disable_otl */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh index ec653513f1..e134224df9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback-private.hh @@ -45,5 +45,9 @@ HB_INTERNAL void _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); +HB_INTERNAL void _hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + #endif /* HB_OT_SHAPE_FALLBACK_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc index 3cb3456f1a..ea8312b223 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc @@ -484,3 +484,70 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, idx = skippy_iter.idx; } } + + +/* Adjusts width of various spaces. */ +void +_hb_ot_shape_fallback_spaces (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) + return; + + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + if (_hb_glyph_info_is_unicode_space (&info[i]) && !_hb_glyph_info_ligated (&info[i])) + { + hb_unicode_funcs_t::space_t space_type = _hb_glyph_info_get_unicode_space_fallback_type (&info[i]); + hb_codepoint_t glyph; + typedef hb_unicode_funcs_t t; + switch (space_type) + { + case t::NOT_SPACE: /* Shouldn't happen. */ + case t::SPACE: + break; + + case t::SPACE_EM: + case t::SPACE_EM_2: + case t::SPACE_EM_3: + case t::SPACE_EM_4: + case t::SPACE_EM_5: + case t::SPACE_EM_6: + case t::SPACE_EM_16: + pos[i].x_advance = (font->x_scale + ((int) space_type)/2) / (int) space_type; + break; + + case t::SPACE_4_EM_18: + pos[i].x_advance = font->x_scale * 4 / 18; + break; + + case t::SPACE_FIGURE: + for (char u = '0'; u <= '9'; u++) + if (font->get_nominal_glyph (u, &glyph)) + { + pos[i].x_advance = font->get_glyph_h_advance (glyph); + break; + } + break; + + case t::SPACE_PUNCTUATION: + if (font->get_nominal_glyph ('.', &glyph)) + pos[i].x_advance = font->get_glyph_h_advance (glyph); + else if (font->get_nominal_glyph (',', &glyph)) + pos[i].x_advance = font->get_glyph_h_advance (glyph); + break; + + case t::SPACE_NARROW: + /* Half-space? + * Unicode doc http://www.unicode.org/charts/PDF/U2000.pdf says ~1/4 or 1/5 of EM. + * However, in my testing, many fonts have their regular space being about that + * size. To me, a percentage of the space width makes more sense. Half is as + * good as any. */ + pos[i].x_advance /= 2; + break; + } + } +} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc index 0a4d40499f..107617e81c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc @@ -76,7 +76,7 @@ decompose_unicode (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t *a, hb_codepoint_t *b) { - return c->unicode->decompose (ab, a, b); + return (bool) c->unicode->decompose (ab, a, b); } static bool @@ -85,21 +85,21 @@ compose_unicode (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t b, hb_codepoint_t *ab) { - return c->unicode->compose (a, b, ab); + return (bool) c->unicode->compose (a, b, ab); } static inline void set_glyph (hb_glyph_info_t &info, hb_font_t *font) { - font->get_glyph (info.codepoint, 0, &info.glyph_index()); + font->get_nominal_glyph (info.codepoint, &info.glyph_index()); } static inline void output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) { buffer->cur().glyph_index() = glyph; - buffer->output_glyph (unichar); - _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer->unicode); + buffer->output_glyph (unichar); /* This is very confusing indeed. */ + _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer); } static inline void @@ -124,10 +124,10 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint hb_font_t * const font = c->font; if (!c->decompose (c, ab, &a, &b) || - (b && !font->get_glyph (b, 0, &b_glyph))) + (b && !font->get_nominal_glyph (b, &b_glyph))) return 0; - bool has_a = font->get_glyph (a, 0, &a_glyph); + bool has_a = (bool) font->get_nominal_glyph (a, &a_glyph); if (shortest && has_a) { /* Output a and b */ output_char (buffer, a, a_glyph); @@ -166,15 +166,50 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor hb_codepoint_t u = buffer->cur().codepoint; hb_codepoint_t glyph; - /* Kind of a cute waterfall here... */ - if (shortest && c->font->get_glyph (u, 0, &glyph)) + if (shortest && c->font->get_nominal_glyph (u, &glyph)) + { next_char (buffer, glyph); - else if (decompose (c, shortest, u)) + return; + } + + if (decompose (c, shortest, u)) + { skip_char (buffer); - else if (!shortest && c->font->get_glyph (u, 0, &glyph)) + return; + } + + if (!shortest && c->font->get_nominal_glyph (u, &glyph)) + { next_char (buffer, glyph); - else - next_char (buffer, glyph); /* glyph is initialized in earlier branches. */ + return; + } + + if (_hb_glyph_info_is_unicode_space (&buffer->cur())) + { + hb_codepoint_t space_glyph; + hb_unicode_funcs_t::space_t space_type = buffer->unicode->space_fallback_type (u); + if (space_type != hb_unicode_funcs_t::NOT_SPACE && c->font->get_nominal_glyph (0x0020u, &space_glyph)) + { + _hb_glyph_info_set_unicode_space_fallback_type (&buffer->cur(), space_type); + next_char (buffer, space_glyph); + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK; + return; + } + } + + if (u == 0x2011u) + { + /* U+2011 is the only sensible character that is a no-break version of another character + * and not a space. The space ones are handled already. Handle this lone one. */ + hb_codepoint_t other_glyph; + if (c->font->get_nominal_glyph (0x2010u, &other_glyph)) + { + next_char (buffer, other_glyph); + return; + } + } + + next_char (buffer, glyph); /* glyph is initialized in earlier branches. */ } static inline void @@ -183,10 +218,10 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, uns /* TODO Currently if there's a variation-selector we give-up, it's just too hard. */ hb_buffer_t * const buffer = c->buffer; hb_font_t * const font = c->font; - for (; buffer->idx < end - 1;) { + for (; buffer->idx < end - 1 && !buffer->in_error;) { if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) { /* The next two lines are some ugly lines... But work. */ - if (font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) + if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) { buffer->replace_glyphs (2, 1, &buffer->cur().codepoint); } @@ -219,13 +254,13 @@ static inline void decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool short_circuit) { hb_buffer_t * const buffer = c->buffer; - for (unsigned int i = buffer->idx; i < end; i++) + for (unsigned int i = buffer->idx; i < end && !buffer->in_error; i++) if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) { handle_variation_selector_cluster (c, end, short_circuit); return; } - while (buffer->idx < end) + while (buffer->idx < end && !buffer->in_error) decompose_current_character (c, short_circuit); } @@ -285,7 +320,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, buffer->clear_output (); count = buffer->len; - for (buffer->idx = 0; buffer->idx < count;) + for (buffer->idx = 0; buffer->idx < count && !buffer->in_error;) { unsigned int end; for (end = buffer->idx + 1; end < count; end++) @@ -335,7 +370,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, count = buffer->len; unsigned int starter = 0; buffer->next_glyph (); - while (buffer->idx < count) + while (buffer->idx < count && !buffer->in_error) { hb_codepoint_t composed, glyph; if (/* We don't try to compose a non-mark character with it's preceding starter. @@ -353,7 +388,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, buffer->cur().codepoint, &composed) && /* And the font has glyph for the composite. */ - font->get_glyph (composed, 0, &glyph)) + font->get_nominal_glyph (composed, &glyph)) { /* Composes. */ buffer->next_glyph (); /* Copy to out-buffer. */ @@ -364,7 +399,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, /* Modify starter and carry on. */ buffer->out_info[starter].codepoint = composed; buffer->out_info[starter].glyph_index() = glyph; - _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer->unicode); + _hb_glyph_info_set_unicode_props (&buffer->out_info[starter], buffer); continue; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh index 54ac2c3cf7..594e54c026 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh @@ -77,11 +77,13 @@ struct hb_ot_shape_planner_t map (face, &props) {} ~hb_ot_shape_planner_t (void) { map.finish (); } - inline void compile (hb_ot_shape_plan_t &plan) + inline void compile (hb_ot_shape_plan_t &plan, + const int *coords, + unsigned int num_coords) { plan.props = props; plan.shaper = shaper; - map.compile (plan.map); + map.compile (plan.map, coords, num_coords); plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m')); plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c')); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc index 40332d69f1..ddd6662e84 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc @@ -69,6 +69,9 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, { hb_ot_map_builder_t *map = &planner->map; + map->add_global_bool_feature (HB_TAG('r','v','r','n')); + map->add_gsub_pause (NULL); + switch (props->direction) { case HB_DIRECTION_LTR: map->add_global_bool_feature (HB_TAG ('l','t','r','a')); @@ -145,7 +148,7 @@ _hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data) struct hb_ot_shaper_font_data_t {}; hb_ot_shaper_font_data_t * -_hb_ot_shaper_font_data_create (hb_font_t *font) +_hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED) { return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED; } @@ -163,7 +166,9 @@ _hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data) hb_ot_shaper_shape_plan_data_t * _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, const hb_feature_t *user_features, - unsigned int num_user_features) + unsigned int num_user_features, + const int *coords, + unsigned int num_coords) { hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t)); if (unlikely (!plan)) @@ -173,9 +178,10 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, planner.shaper = hb_ot_shape_complex_categorize (&planner); - hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features); + hb_ot_shape_collect_features (&planner, &shape_plan->props, + user_features, num_user_features); - planner.compile (*plan); + planner.compile (*plan, coords, num_coords); if (plan->shaper->data_create) { plan->data = plan->shaper->data_create (plan); @@ -212,6 +218,8 @@ struct hb_ot_shape_context_t unsigned int num_user_features; /* Transient stuff */ + bool fallback_positioning; + bool fallback_glyph_classes; hb_direction_t target_direction; }; @@ -228,7 +236,7 @@ hb_set_unicode_props (hb_buffer_t *buffer) unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode); + _hb_glyph_info_set_unicode_props (&info[i], buffer); } static void @@ -245,7 +253,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) hb_glyph_info_t dottedcircle = {0}; dottedcircle.codepoint = 0x25CCu; - _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode); + _hb_glyph_info_set_unicode_props (&dottedcircle, buffer); buffer->clear_output (); @@ -254,7 +262,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) info.cluster = buffer->cur().cluster; info.mask = buffer->cur().mask; buffer->output_info (info); - while (buffer->idx < buffer->len) + while (buffer->idx < buffer->len && !buffer->in_error) buffer->next_glyph (); buffer->swap_buffers (); @@ -263,16 +271,18 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) static void hb_form_clusters (hb_buffer_t *buffer) { - if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || + buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) return; - /* Loop duplicated in hb_ensure_native_direction(). */ + /* Loop duplicated in hb_ensure_native_direction(), and in _hb-coretext.cc */ unsigned int base = 0; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) { - if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])) && + !_hb_glyph_info_is_joiner (&info[i]))) { buffer->merge_clusters (base, i); base = i; @@ -346,7 +356,8 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c) static inline void hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) { - if (!c->plan->has_frac) + if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) || + !c->plan->has_frac) return; hb_buffer_t *buffer = c->buffer; @@ -416,7 +427,8 @@ hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; - if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) || + (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)) return; unsigned int count = buffer->len; @@ -433,7 +445,8 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; - if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) + if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) || + (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)) return; unsigned int count = buffer->len; @@ -451,7 +464,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) return; hb_codepoint_t space; - if (c->font->get_glyph (' ', 0, &space)) + if (c->font->get_nominal_glyph (' ', &space)) { /* Replace default-ignorables with a zero-advance space glyph. */ for (/*continue*/; i < count; i++) @@ -525,7 +538,7 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c) hb_glyph_info_t *info = c->buffer->info; for (unsigned int i = 0; i < count; i++) { - hb_ot_layout_glyph_class_mask_t klass; + hb_ot_layout_glyph_props_flags_t klass; /* Never mark default-ignorables as marks. * They won't get in the way of lookups anyway, @@ -549,9 +562,6 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; - if (c->plan->shaper->preprocess_text) - c->plan->shaper->preprocess_text (c->plan, buffer, c->font); - hb_ot_shape_initialize_masks (c); hb_ot_mirror_chars (c); @@ -563,7 +573,7 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c) hb_ot_shape_setup_masks (c); /* This is unfortunate to go here, but necessary... */ - if (!hb_ot_layout_has_positioning (c->face)) + if (c->fallback_positioning) _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer); hb_ot_map_glyphs_fast (buffer); @@ -576,7 +586,6 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c) { hb_buffer_t *buffer = c->buffer; - _hb_buffer_allocate_gsubgpos_vars (buffer); hb_ot_layout_substitute_start (c->font, buffer); if (!hb_ot_layout_has_glyph_classes (c->face)) @@ -584,8 +593,6 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c) c->plan->substitute (c->font, buffer); - hb_ot_layout_substitute_finish (c->font, buffer); - return; } @@ -593,6 +600,9 @@ static inline void hb_ot_substitute (hb_ot_shape_context_t *c) { hb_ot_substitute_default (c); + + _hb_buffer_allocate_gsubgpos_vars (c->buffer); + hb_ot_substitute_complex (c); } @@ -612,20 +622,6 @@ zero_mark_width (hb_glyph_position_t *pos) pos->y_advance = 0; } -static inline void -zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets) -{ - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) - { - if (adjust_offsets) - adjust_mark_offsets (&buffer->pos[i]); - zero_mark_width (&buffer->pos[i]); - } -} - static inline void zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets) { @@ -647,26 +643,39 @@ hb_ot_position_default (hb_ot_shape_context_t *c) unsigned int count = c->buffer->len; hb_glyph_info_t *info = c->buffer->info; hb_glyph_position_t *pos = c->buffer->pos; - for (unsigned int i = 0; i < count; i++) - { - c->font->get_glyph_advance_for_direction (info[i].codepoint, - direction, - &pos[i].x_advance, - &pos[i].y_advance); - c->font->subtract_glyph_origin_for_direction (info[i].codepoint, - direction, - &pos[i].x_offset, - &pos[i].y_offset); + if (HB_DIRECTION_IS_HORIZONTAL (direction)) + { + for (unsigned int i = 0; i < count; i++) + pos[i].x_advance = c->font->get_glyph_h_advance (info[i].codepoint); + /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ + if (c->font->has_glyph_h_origin_func ()) + for (unsigned int i = 0; i < count; i++) + c->font->subtract_glyph_h_origin (info[i].codepoint, + &pos[i].x_offset, + &pos[i].y_offset); } + else + { + for (unsigned int i = 0; i < count; i++) + { + pos[i].y_advance = c->font->get_glyph_v_advance (info[i].codepoint); + c->font->subtract_glyph_v_origin (info[i].codepoint, + &pos[i].x_offset, + &pos[i].y_offset); + } + } + if (c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK) + _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer); } -static inline bool +static inline void hb_ot_position_complex (hb_ot_shape_context_t *c) { - bool ret = false; + hb_ot_layout_position_start (c->font, c->buffer); + unsigned int count = c->buffer->len; - bool has_positioning = hb_ot_layout_has_positioning (c->face); + /* If the font has no GPOS, AND, no fallback positioning will * happen, AND, direction is forward, then when zeroing mark * widths, we shift the mark with it, such that the mark @@ -676,8 +685,9 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) * If fallback positinoing happens or GPOS is present, we don't * care. */ - bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position || - HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)); + bool adjust_offsets_when_zeroing = c->fallback_positioning && + !c->plan->shaper->fallback_position && + HB_DIRECTION_IS_FORWARD (c->buffer->props.direction); switch (c->plan->shaper->zero_width_marks) { @@ -685,79 +695,65 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); break; - /* Not currently used for any shaper: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: - zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); - break; - */ - default: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: break; } - if (has_positioning) + if (likely (!c->fallback_positioning)) { hb_glyph_info_t *info = c->buffer->info; hb_glyph_position_t *pos = c->buffer->pos; - /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */ + /* Change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */ - for (unsigned int i = 0; i < count; i++) { - c->font->add_glyph_origin_for_direction (info[i].codepoint, - HB_DIRECTION_LTR, - &pos[i].x_offset, - &pos[i].y_offset); - } + /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ + if (c->font->has_glyph_h_origin_func ()) + for (unsigned int i = 0; i < count; i++) + c->font->add_glyph_h_origin (info[i].codepoint, + &pos[i].x_offset, + &pos[i].y_offset); c->plan->position (c->font, c->buffer); - for (unsigned int i = 0; i < count; i++) { - c->font->subtract_glyph_origin_for_direction (info[i].codepoint, - HB_DIRECTION_LTR, - &pos[i].x_offset, - &pos[i].y_offset); - } + /* The nil glyph_h_origin() func returns 0, so no need to apply it. */ + if (c->font->has_glyph_h_origin_func ()) + for (unsigned int i = 0; i < count; i++) + c->font->subtract_glyph_h_origin (info[i].codepoint, + &pos[i].x_offset, + &pos[i].y_offset); - ret = true; } switch (c->plan->shaper->zero_width_marks) { - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: - zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing); - break; - case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing); break; default: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE: - //case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: break; } - return ret; + /* Finishing off GPOS has to follow a certain order. */ + hb_ot_layout_position_finish_advances (c->font, c->buffer); + hb_ot_zero_width_default_ignorables (c); + hb_ot_layout_position_finish_offsets (c->font, c->buffer); } static inline void hb_ot_position (hb_ot_shape_context_t *c) { - hb_ot_layout_position_start (c->font, c->buffer); + c->buffer->clear_positions (); hb_ot_position_default (c); - hb_bool_t fallback = !hb_ot_position_complex (c); - - hb_ot_zero_width_default_ignorables (c); - - hb_ot_layout_position_finish (c->font, c->buffer); + hb_ot_position_complex (c); - if (fallback && c->plan->shaper->fallback_position) + if (c->fallback_positioning && c->plan->shaper->fallback_position) _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) @@ -765,7 +761,7 @@ hb_ot_position (hb_ot_shape_context_t *c) /* Visual fallback goes here. */ - if (fallback) + if (c->fallback_positioning) _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); _hb_buffer_deallocate_gsubgpos_vars (c->buffer); @@ -778,6 +774,17 @@ static void hb_ot_shape_internal (hb_ot_shape_context_t *c) { c->buffer->deallocate_var_all (); + c->buffer->scratch_flags = HB_BUFFER_SCRATCH_FLAG_DEFAULT; + if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_EXPANSION_FACTOR))) + { + c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_EXPANSION_FACTOR, + (unsigned) HB_BUFFER_MAX_LEN_MIN); + } + + bool disable_otl = c->plan->shaper->disable_otl && c->plan->shaper->disable_otl (c->plan); + //c->fallback_substitute = disable_otl || !hb_ot_layout_has_substitution (c->face); + c->fallback_positioning = disable_otl || !hb_ot_layout_has_positioning (c->face); + c->fallback_glyph_classes = disable_otl || !hb_ot_layout_has_glyph_classes (c->face); /* Save the original direction, we use it later. */ c->target_direction = c->buffer->props.direction; @@ -792,15 +799,22 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ensure_native_direction (c->buffer); + if (c->plan->shaper->preprocess_text) + c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); + hb_ot_substitute (c); hb_ot_position (c); hb_ot_hide_default_ignorables (c); + if (c->plan->shaper->postprocess_glyphs) + c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font); + _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction; + c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT; c->buffer->deallocate_var_all (); } @@ -820,6 +834,8 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan, /** + * hb_ot_shape_plan_collect_lookups: + * * Since: 0.9.7 **/ void @@ -841,18 +857,20 @@ add_char (hb_font_t *font, hb_set_t *glyphs) { hb_codepoint_t glyph; - if (font->get_glyph (u, 0, &glyph)) + if (font->get_nominal_glyph (u, &glyph)) glyphs->add (glyph); if (mirror) { hb_codepoint_t m = unicode->mirroring (u); - if (m != u && font->get_glyph (m, 0, &glyph)) + if (m != u && font->get_nominal_glyph (m, &glyph)) glyphs->add (glyph); } } /** + * hb_ot_shape_glyphs_closure: + * * Since: 0.9.2 **/ void diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h index 1402f54acc..7b1bcc0637 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.h @@ -36,14 +36,14 @@ HB_BEGIN_DECLS /* TODO port to shape-plan / set. */ -void +HB_EXTERN void hb_ot_shape_glyphs_closure (hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features, hb_set_t *glyphs); -void +HB_EXTERN void hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, hb_tag_t table_tag, hb_set_t *lookup_indexes /* OUT */); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc index a2e5728fcd..5f21ac0967 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc @@ -186,14 +186,18 @@ static const LangTag ot_languages[] = { {"aa", HB_TAG('A','F','R',' ')}, /* Afar */ {"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */ {"abq", HB_TAG('A','B','A',' ')}, /* Abaza */ + {"acf", HB_TAG('F','A','N',' ')}, /* French Antillean */ {"ach", HB_TAG('A','C','H',' ')}, /* Acoli */ + {"acr", HB_TAG('A','C','R',' ')}, /* Achi */ {"ada", HB_TAG('D','N','G',' ')}, /* Dangme */ {"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */ {"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */ + {"ahg", HB_TAG('A','G','W',' ')}, /* Agaw */ {"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */ {"aio", HB_TAG('A','I','O',' ')}, /* Aiton */ {"aiw", HB_TAG('A','R','I',' ')}, /* Aari */ {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] */ + {"aka", HB_TAG('A','K','A',' ')}, /* Akan */ {"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */ {"am", HB_TAG('A','M','H',' ')}, /* Amharic */ {"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */ @@ -206,6 +210,7 @@ static const LangTag ot_languages[] = { {"as", HB_TAG('A','S','M',' ')}, /* Assamese */ {"ast", HB_TAG('A','S','T',' ')}, /* Asturian/Asturleonese/Bable/Leonese */ {"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */ + {"atj", HB_TAG('R','C','R',' ')}, /* R-Cree */ {"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */ {"av", HB_TAG('A','V','R',' ')}, /* Avaric */ {"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */ @@ -214,6 +219,7 @@ static const LangTag ot_languages[] = { {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani */ {"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani */ {"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */ + {"bad", HB_TAG('B','A','D','0')}, /* Banda */ {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */ {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolangauge] */ {"ban", HB_TAG('B','A','N',' ')}, /* Balinese */ @@ -222,11 +228,13 @@ static const LangTag ot_languages[] = { {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */ {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */ + {"bdy", HB_TAG('B','D','Y',' ')}, /* Bandjalang */ {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */ {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */ {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */ {"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */ {"bft", HB_TAG('B','L','T',' ')}, /* Balti */ + {"bfu", HB_TAG('L','A','H',' ')}, /* Lahuli */ {"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */ {"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */ {"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */ @@ -260,11 +268,13 @@ static const LangTag ot_languages[] = { {"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */ {"byn", HB_TAG('B','I','L',' ')}, /* Bilen */ {"ca", HB_TAG('C','A','T',' ')}, /* Catalan */ + {"cak", HB_TAG('C','A','K',' ')}, /* Kaqchikel */ {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */ {"ce", HB_TAG('C','H','E',' ')}, /* Chechen */ {"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */ {"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */ {"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */ + {"chk", HB_TAG('C','H','K','0')}, /* Chuukese */ {"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */ {"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */ {"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */ @@ -272,9 +282,12 @@ static const LangTag ot_languages[] = { {"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */ {"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */ {"cop", HB_TAG('C','O','P',' ')}, /* Coptic */ + {"cpp", HB_TAG('C','P','P',' ')}, /* Creoles */ {"cr", HB_TAG('C','R','E',' ')}, /* Cree */ + {"cre", HB_TAG('Y','C','R',' ')}, /* Y-Cree */ {"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */ {"crj", HB_TAG('E','C','R',' ')}, /* [Southern] East Cree */ + {"crk", HB_TAG('W','C','R',' ')}, /* West-Cree */ {"crl", HB_TAG('E','C','R',' ')}, /* [Northern] East Cree */ {"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */ {"crx", HB_TAG('C','R','R',' ')}, /* Carrier */ @@ -283,21 +296,27 @@ static const LangTag ot_languages[] = { {"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */ {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */ {"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */ + {"cuk", HB_TAG('C','U','K',' ')}, /* San Blas Kuna */ {"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */ {"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */ {"cy", HB_TAG('W','E','L',' ')}, /* Welsh */ {"da", HB_TAG('D','A','N',' ')}, /* Danish */ {"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */ {"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */ + {"dax", HB_TAG('D','A','X',' ')}, /* Dayi */ {"de", HB_TAG('D','E','U',' ')}, /* German */ {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */ {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari */ + {"dhg", HB_TAG('D','H','G',' ')}, /* Dhangu */ {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */ {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */ {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */ + {"djr", HB_TAG('D','J','R','0')}, /* Djambarrpuyngu */ {"dng", HB_TAG('D','U','N',' ')}, /* Dungan */ + {"dnj", HB_TAG('D','N','J',' ')}, /* Dan */ {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */ {"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */ + {"duj", HB_TAG('D','U','J',' ')}, /* Dhuwal */ {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi/Divehi/Maldivian */ {"dyu", HB_TAG('J','U','L',' ')}, /* Jula */ {"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */ @@ -307,23 +326,30 @@ static const LangTag ot_languages[] = { {"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */ {"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan */ {"en", HB_TAG('E','N','G',' ')}, /* English */ + {"enf", HB_TAG('F','N','E',' ')}, /* Forest Nenets */ + {"enh", HB_TAG('T','N','E',' ')}, /* Tundra Nenets */ {"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */ {"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */ {"es", HB_TAG('E','S','P',' ')}, /* Spanish */ + {"esu", HB_TAG('E','S','U',' ')}, /* Central Yupik */ {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */ {"eu", HB_TAG('E','U','Q',' ')}, /* Basque */ {"eve", HB_TAG('E','V','N',' ')}, /* Even */ {"evn", HB_TAG('E','V','K',' ')}, /* Evenki */ {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */ + {"fan", HB_TAG('F','A','N','0')}, /* Fang */ + {"fat", HB_TAG('F','A','T',' ')}, /* Fanti */ {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */ {"fi", HB_TAG('F','I','N',' ')}, /* Finnish */ {"fil", HB_TAG('P','I','L',' ')}, /* Filipino */ {"fj", HB_TAG('F','J','I',' ')}, /* Fijian */ + {"flm", HB_TAG('H','A','L',' ')}, /* Halam */ {"fo", HB_TAG('F','O','S',' ')}, /* Faroese */ {"fon", HB_TAG('F','O','N',' ')}, /* Fon */ {"fr", HB_TAG('F','R','A',' ')}, /* French */ {"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */ {"frp", HB_TAG('F','R','P',' ')}, /* Arpitan/Francoprovençal */ + {"fuf", HB_TAG('F','T','A',' ')}, /* Futa */ {"fur", HB_TAG('F','R','L',' ')}, /* Friulian */ {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */ {"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */ @@ -334,17 +360,24 @@ static const LangTag ot_languages[] = { {"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */ {"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */ {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi */ + {"gih", HB_TAG('G','I','H',' ')}, /* Githabul */ + {"gil", HB_TAG('G','I','L','0')}, /* Kiribati (Gilbertese) */ + {"gkp", HB_TAG('G','K','P',' ')}, /* Kpelle (Guinea) */ {"gl", HB_TAG('G','A','L',' ')}, /* Galician */ {"gld", HB_TAG('N','A','N',' ')}, /* Nanai */ + {"gle", HB_TAG('I','R','T',' ')}, /* Irish Traditional */ {"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */ {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */ + {"gnn", HB_TAG('G','N','N',' ')}, /* Gumatj */ {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi */ {"gog", HB_TAG('G','O','G',' ')}, /* Gogo */ {"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */ {"grt", HB_TAG('G','R','O',' ')}, /* Garo */ {"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */ + {"gsw", HB_TAG('A','L','S',' ')}, /* Alsatian */ {"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */ {"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */ + {"guf", HB_TAG('G','U','F',' ')}, /* Gupapuyngu */ {"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */ /*{"guk", HB_TAG('G','U','K',' ')},*/ /* Gumuz (in SIL fonts) */ {"guz", HB_TAG('G','U','Z',' ')}, /* Ekegusii/Gusii */ @@ -355,9 +388,9 @@ static const LangTag ot_languages[] = { {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */ {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */ {"he", HB_TAG('I','W','R',' ')}, /* Hebrew */ - {"hz", HB_TAG('H','E','R',' ')}, /* Herero */ {"hi", HB_TAG('H','I','N',' ')}, /* Hindi */ {"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */ + {"hmn", HB_TAG('H','M','N',' ')}, /* Hmong */ {"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */ {"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */ {"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */ @@ -371,11 +404,13 @@ static const LangTag ot_languages[] = { {"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */ {"hz", HB_TAG('H','E','R',' ')}, /* Herero */ {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */ + {"iba", HB_TAG('I','B','A',' ')}, /* Iban */ {"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */ {"id", HB_TAG('I','N','D',' ')}, /* Indonesian */ {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue/Occidental */ {"ig", HB_TAG('I','B','O',' ')}, /* Igbo */ {"igb", HB_TAG('E','B','I',' ')}, /* Ebira */ + {"ii", HB_TAG('Y','I','M',' ')}, /* Yi Modern */ {"ijc", HB_TAG('I','J','O',' ')}, /* Izon */ {"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */ {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] */ @@ -391,15 +426,20 @@ static const LangTag ot_languages[] = { {"jv", HB_TAG('J','A','V',' ')}, /* Javanese */ {"ka", HB_TAG('K','A','T',' ')}, /* Georgian */ {"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */ - {"kab", HB_TAG('K','A','B',' ')}, /* Kabyle */ + {"kab", HB_TAG('K','A','B','0')}, /* Kabyle */ {"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */ {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */ + {"kat", HB_TAG('K','G','E',' ')}, /* Khutsuri Georgian */ {"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */ {"kde", HB_TAG('K','D','E',' ')}, /* Makonde */ {"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */ {"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */ + {"kea", HB_TAG('K','E','A',' ')}, /* Kabuverdianu (Crioulo) */ + {"kek", HB_TAG('K','E','K',' ')}, /* Kekchi */ {"kex", HB_TAG('K','K','N',' ')}, /* Kokni */ + {"kfa", HB_TAG('K','O','D',' ')}, /* Kodagu */ {"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */ + {"kfx", HB_TAG('K','U','L',' ')}, /* Kulvi */ {"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */ {"kg", HB_TAG('K','O','N',' ')}, /* Kongo [macrolanguage] */ {"kha", HB_TAG('K','S','I',' ')}, /* Khasi */ @@ -408,7 +448,9 @@ static const LangTag ot_languages[] = { /*{"kht", HB_TAG('K','H','T',' ')},*/ /* Khamti (OpenType spec and SIL fonts) */ {"khw", HB_TAG('K','H','W',' ')}, /* Khowar */ {"ki", HB_TAG('K','I','K',' ')}, /* Gikuyu/Kikuyu */ + {"kiu", HB_TAG('K','I','U',' ')}, /* Kirmanjki */ {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama/Kwanyama */ + {"kjd", HB_TAG('K','J','D',' ')}, /* Southern Kiwai */ {"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */ {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen */ {"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */ @@ -422,6 +464,8 @@ static const LangTag ot_languages[] = { {"ko", HB_TAG('K','O','R',' ')}, /* Korean */ {"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */ {"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */ + {"kon", HB_TAG('K','O','N','0')}, /* Kongo */ + {"kos", HB_TAG('K','O','S',' ')}, /* Kosraean */ {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */ {"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */ {"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */ @@ -431,9 +475,11 @@ static const LangTag ot_languages[] = { {"krl", HB_TAG('K','R','L',' ')}, /* Karelian */ {"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */ {"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */ - {"ksh", HB_TAG('K','S','H',' ')}, /* Kölsch */ + {"ksh", HB_TAG('K','S','H','0')}, /* Ripuarian, Kölsch */ /*{"ksw", HB_TAG('K','R','N',' ')},*/ /* S'gaw Karen (Microsoft fonts?) */ {"ksw", HB_TAG('K','S','W',' ')}, /* S'gaw Karen (OpenType spec and SIL fonts) */ + {"ktb", HB_TAG('K','E','B',' ')}, /* Kebena */ + {"ktu", HB_TAG('K','O','N',' ')}, /* Kikongo */ {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */ {"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */ {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */ @@ -461,6 +507,7 @@ static const LangTag ot_languages[] = { {"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */ {"ln", HB_TAG('L','I','N',' ')}, /* Lingala */ {"lo", HB_TAG('L','A','O',' ')}, /* Lao */ + {"lom", HB_TAG('L','O','M',' ')}, /* Loma */ {"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri */ {"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */ {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */ @@ -475,6 +522,8 @@ static const LangTag ot_languages[] = { {"mag", HB_TAG('M','A','G',' ')}, /* Magahi */ {"mai", HB_TAG('M','T','H',' ')}, /* Maithili */ {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */ + {"mal", HB_TAG('M','A','L',' ')}, /* Malayalam */ + {"mam", HB_TAG('M','A','M',' ')}, /* Mam */ {"man", HB_TAG('M','N','K',' ')}, /* Manding/Mandingo [macrolanguage] */ {"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */ {"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */ @@ -517,6 +566,7 @@ static const LangTag ot_languages[] = { {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */ {"my", HB_TAG('B','R','M',' ')}, /* Burmese */ {"mym", HB_TAG('M','E','N',' ')}, /* Me'en */ + {"myn", HB_TAG('M','Y','N',' ')}, /* Mayan */ {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) */ {"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */ {"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */ @@ -534,6 +584,7 @@ static const LangTag ot_languages[] = { {"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */ {"nga", HB_TAG('N','G','A',' ')}, /* Ngabaka */ {"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */ + {"ngo", HB_TAG('S','X','T',' ')}, /* Sutu */ {"niu", HB_TAG('N','I','U',' ')}, /* Niuean */ {"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */ {"nl", HB_TAG('N','L','D',' ')}, /* Dutch */ @@ -554,13 +605,15 @@ static const LangTag ot_languages[] = { {"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */ {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] */ {"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */ + {"okm", HB_TAG('K','O','H',' ')}, /* Korean Old Hangul */ {"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */ {"or", HB_TAG('O','R','I',' ')}, /* Oriya */ {"os", HB_TAG('O','S','S',' ')}, /* Ossetian */ {"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */ {"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */ {"pam", HB_TAG('P','A','M',' ')}, /* Kapampangan/Pampanga */ - {"pap", HB_TAG('P','A','P',' ')}, /* Papiamento */ + {"pap", HB_TAG('P','A','P','0')}, /* Papiamento */ + {"pau", HB_TAG('P','A','U',' ')}, /* Palauan */ {"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */ {"pcd", HB_TAG('P','C','D',' ')}, /* Picard */ {"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */ @@ -574,24 +627,34 @@ static const LangTag ot_languages[] = { {"plp", HB_TAG('P','A','P',' ')}, /* Palpa */ {"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */ {"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */ + {"poh", HB_TAG('P','O','H',' ')}, /* Pocomchi */ + {"pon", HB_TAG('P','O','N',' ')}, /* Pohnpeian */ {"prs", HB_TAG('D','R','I',' ')}, /* Afghan Persian/Dari */ {"ps", HB_TAG('P','A','S',' ')}, /* Pashto/Pushto [macrolanguage] */ {"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */ {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen */ {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */ {"quc", HB_TAG('Q','U','C',' ')}, /* K'iche'/Quiché */ + {"quh", HB_TAG('Q','U','H',' ')}, /* Quechua (Bolivia) */ {"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua */ + {"qvi", HB_TAG('Q','V','I',' ')}, /* Quechua (Ecuador) */ + {"qwh", HB_TAG('Q','W','H',' ')}, /* Quechua (Peru) */ {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */ + {"rar", HB_TAG('R','A','R',' ')}, /* Rarotongan */ {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung */ {"rej", HB_TAG('R','E','J',' ')}, /* Rejang */ {"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */ + {"rif", HB_TAG('R','I','F',' ')}, /* Tarifit */ {"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */ + {"rit", HB_TAG('R','I','T',' ')}, /* Ritarungo */ {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */ + {"rkw", HB_TAG('R','K','W',' ')}, /* Arakwal */ {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */ {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */ {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */ {"ro", HB_TAG('R','O','M',' ')}, /* Romanian */ {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */ + {"rtm", HB_TAG('R','T','M',' ')}, /* Rotuman */ {"ru", HB_TAG('R','U','S',' ')}, /* Russian */ {"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */ {"rup", HB_TAG('R','U','P',' ')}, /* Aromanian/Arumanian/Macedo-Romanian */ @@ -599,10 +662,11 @@ static const LangTag ot_languages[] = { {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */ {"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */ {"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */ + {"sam", HB_TAG('P','A','A',' ')}, /* Palestinian Aramaic */ {"sas", HB_TAG('S','A','S',' ')}, /* Sasak */ {"sat", HB_TAG('S','A','T',' ')}, /* Santali */ - {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */ {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */ + {"sck", HB_TAG('S','A','D',' ')}, /* Sadri */ {"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */ {"sco", HB_TAG('S','C','O',' ')}, /* Scots */ {"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */ @@ -615,6 +679,7 @@ static const LangTag ot_languages[] = { {"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */ {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage */ /*{"sgw", HB_TAG('S','G','W',' ')},*/ /* Sebat Bet Gurage (in SIL fonts) */ + {"shi", HB_TAG('S','H','I',' ')}, /* Tachelhit */ {"shn", HB_TAG('S','H','N',' ')}, /* Shan */ {"si", HB_TAG('S','N','H',' ')}, /* Sinhala */ {"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */ @@ -627,7 +692,7 @@ static const LangTag ot_languages[] = { {"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */ {"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */ {"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */ - {"sn", HB_TAG('S','N','A',' ')}, /* Shona */ + {"sn", HB_TAG('S','N','A','0')}, /* Shona */ {"snk", HB_TAG('S','N','K',' ')}, /* Soninke */ {"so", HB_TAG('S','M','L',' ')}, /* Somali */ {"sop", HB_TAG('S','O','P',' ')}, /* Songe */ @@ -665,20 +730,24 @@ static const LangTag ot_languages[] = { {"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */ {"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */ {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */ - {"tmh", HB_TAG('t','m','h',' ')}, /* Tamashek [macrolanguage] */ + {"tmh", HB_TAG('T','M','H',' ')}, /* Tamashek */ {"tn", HB_TAG('T','N','A',' ')}, /* Tswana */ {"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */ + {"tod", HB_TAG('T','O','D','0')}, /* Toma */ + {"toi", HB_TAG('T','N','G',' ')}, /* Tonga */ {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */ {"tr", HB_TAG('T','R','K',' ')}, /* Turkish */ {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */ {"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */ {"tt", HB_TAG('T','A','T',' ')}, /* Tatar */ {"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka */ + {"tvl", HB_TAG('T','V','L',' ')}, /* Tuvalu */ {"tw", HB_TAG('T','W','I',' ')}, /* Twi */ {"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */ {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */ {"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */ {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight */ + {"tzo", HB_TAG('T','Z','O',' ')}, /* Tzotzil */ {"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */ {"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */ {"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */ @@ -690,8 +759,8 @@ static const LangTag ot_languages[] = { {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek */ {"ve", HB_TAG('V','E','N',' ')}, /* Venda */ {"vec", HB_TAG('V','E','C',' ')}, /* Venetian */ - {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams */ {"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */ + {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams */ {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */ {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */ {"vro", HB_TAG('V','R','O',' ')}, /* Võro */ @@ -700,85 +769,76 @@ static const LangTag ot_languages[] = { {"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */ {"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */ {"wle", HB_TAG('S','I','G',' ')}, /* Wolane */ + {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */ {"wry", HB_TAG('M','A','W',' ')}, /* Merwari */ {"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */ - {"wo", HB_TAG('W','L','F',' ')}, /* Wolof */ {"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */ + {"xan", HB_TAG('S','E','K',' ')}, /* Sekota */ {"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */ + {"xjb", HB_TAG('X','J','B',' ')}, /* Minjangbal */ {"xog", HB_TAG('X','O','G',' ')}, /* Soga */ {"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */ + {"xpe", HB_TAG('X','P','E',' ')}, /* Kpelle (Liberia) */ {"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */ {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) */ {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat (Todo) */ {"yao", HB_TAG('Y','A','O',' ')}, /* Yao */ + {"yap", HB_TAG('Y','A','P',' ')}, /* Yapese */ {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */ {"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */ {"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */ {"za", HB_TAG('Z','H','A',' ')}, /* Chuang/Zhuang [macrolanguage] */ {"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws */ + {"zgh", HB_TAG('Z','G','H',' ')}, /* Standard Morrocan Tamazigh */ {"zne", HB_TAG('Z','N','D',' ')}, /* Zande */ {"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */ - {"zum", HB_TAG('L','R','C',' ')} /* Kumzari */ + {"zum", HB_TAG('L','R','C',' ')}, /* Kumzari */ + {"zza", HB_TAG('Z','Z','A',' ')}, /* Zazaki */ /* The corresponding languages IDs for the following IDs are unclear, * overlap, or are architecturally weird. Needs more research. */ -/*{"ahg/awn/xan?", HB_TAG('A','G','W',' ')},*/ /* Agaw */ -/*{"gsw?/gsw-FR?", HB_TAG('A','L','S',' ')},*/ /* Alsatian */ +/*{"chp", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */ +/*{"cwd", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */ +/*{"emk", HB_TAG('E','M','K',' ')},*/ /* Eastern Maninkakan */ /*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */ /*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */ /*{"zh?", HB_TAG('C','H','N',' ')},*/ /* Chinese (seen in Microsoft fonts) */ -/*{"acf/gcf?", HB_TAG('F','A','N',' ')},*/ /* French Antillean */ -/*{"enf?/yrk?", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */ -/*{"fuf?", HB_TAG('F','T','A',' ')},*/ /* Futa */ /*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */ -/*{"cfm/rnl?", HB_TAG('H','A','L',' ')},*/ /* Halam */ -/*{"ga-Latg?/Latg?", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */ +/*{"hy?", HB_TAG('H','Y','E','0')},*/ /* Armenian East (ISO 639-3 hye according to Microsoft, but that’s equivalent to ISO 639-1 hy) */ +/*{"ga-Latg?/" HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */ /*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */ -/*{"alw?/ktb?", HB_TAG('K','E','B',' ')},*/ /* Kebena */ -/*{"Geok", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */ +/*{"ka-Geok?", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */ /*{"kca", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */ /*{"kca", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */ /*{"kca", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */ -/*{"guz?/kqs?/kss?", HB_TAG('K','I','S',' ')},*/ /* Kisii */ -/*{"kfa/kfi?/kpb?/xua?/xuj?", HB_TAG('K','O','D',' ')},*/ /* Kodagu */ -/*{"okm?/oko?", HB_TAG('K','O','H',' ')},*/ /* Korean Old Hangul */ -/*{"kon?/ktu?/...", HB_TAG('K','O','N',' ')},*/ /* Kikongo */ -/*{"kfx?", HB_TAG('K','U','L',' ')},*/ /* Kulvi */ -/*{"??", HB_TAG('L','A','H',' ')},*/ /* Lahuli */ -/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */ +/*{"kqs, kss", HB_TAG('K','I','S',' ')},*/ /* Kisii */ +/*{"lua", HB_TAG('L','U','A',' ')},*/ /* Luba-Lulua */ +/*{"mlq", HB_TAG('M','L','N',' ')},*/ /* Malinke */ +/*{"nso", HB_TAG('N','S','O',' ')},*/ /* Sotho, Northern */ /*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */ -/*{"mnk?/mlq?/...", HB_TAG('M','L','N',' ')},*/ /* Malinke */ -/*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */ -/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */ -/*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */ -/*{"polyton", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */ -/*{"??", HB_TAG('Q','I','N',' ')},*/ /* Asho Chin */ -/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */ -/*{"chp?", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */ -/*{"xan?", HB_TAG('S','E','K',' ')},*/ /* Sekota */ -/*{"ngo?", HB_TAG('S','X','T',' ')},*/ /* Sutu */ -/*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */ -/*{"tnz?/tog?/toi?", HB_TAG('T','N','G',' ')},*/ /* Tonga */ -/*{"enh?/yrk?", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */ -/*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */ -/*{"cre?", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */ +/*{"csw", HB_TAG('N','C','R',' ')},*/ /* N-Cree */ +/*{"csw", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */ +/*{"el-polyton", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */ +/*{"bgr, cnh, cnw, czt, sez, tcp, csy, ctd, flm, pck, tcz, zom, cmr, dao, hlt, cka, cnk, mrh, mwg, cbl, cnb, csh", HB_TAG('Q','I','N',' ')},*/ /* Chin */ /*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */ -/*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */ -/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */ +/*{"zh-Latn-pinyin", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */ }; typedef struct { - char language[8]; + char language[11]; hb_tag_t tag; } LangTagLong; static const LangTagLong ot_languages_zh[] = { + /* Store longest-first, if one is a prefix of another. */ {"zh-cn", HB_TAG('Z','H','S',' ')}, /* Chinese (China) */ {"zh-hk", HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */ - {"zh-mo", HB_TAG('Z','H','T',' ')}, /* Chinese (Macao) */ + {"zh-mo", HB_TAG('Z','H','H',' ')}, /* Chinese (Macao) */ {"zh-sg", HB_TAG('Z','H','S',' ')}, /* Chinese (Singapore) */ {"zh-tw", HB_TAG('Z','H','T',' ')}, /* Chinese (Taiwan) */ {"zh-hans", HB_TAG('Z','H','S',' ')}, /* Chinese (Simplified) */ + {"zh-hant-hk",HB_TAG('Z','H','H',' ')}, /* Chinese (Hong Kong) */ + {"zh-hant-mo",HB_TAG('Z','H','H',' ')}, /* Chinese (Macao) */ {"zh-hant", HB_TAG('Z','H','T',' ')}, /* Chinese (Traditional) */ }; @@ -832,13 +892,21 @@ hb_ot_tag_from_language (hb_language_t language) } /* - * The International Phonetic Alphabet is a variant tag in BCP-47, - * which can be applied to any language. + * "fonipa" is a variant tag in BCP-47, meaning the International Phonetic Alphabet. + * It can be applied to any language. */ if (strstr (lang_str, "-fonipa")) { return HB_TAG('I','P','P','H'); /* Phonetic transcription—IPA conventions */ } + /* + * "fonnapa" is a variant tag in BCP-47, meaning the North American Phonetic Alphabet + * also known as Americanist Phonetic Notation. It can be applied to any language. + */ + if (strstr (lang_str, "-fonnapa")) { + return HB_TAG('A','P','P','H'); /* Phonetic transcription—Americanist conventions */ + } + /* Find a language matching in the first component */ { const LangTag *lang_tag; @@ -910,6 +978,8 @@ hb_ot_tag_to_language (hb_tag_t tag) /* struct LangTag has only room for 3-letter language tags. */ switch (tag) { + case HB_TAG('A','P','P','H'): /* Phonetic transcription—Americanist conventions */ + return hb_language_from_string ("und-fonnapa", -1); case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */ return hb_language_from_string ("und-fonipa", -1); } @@ -928,4 +998,27 @@ hb_ot_tag_to_language (hb_tag_t tag) } } +#ifdef MAIN +static inline void +test_langs_sorted (void) +{ + for (unsigned int i = 1; i < ARRAY_LENGTH (ot_languages); i++) + { + int c = lang_compare_first_component (ot_languages[i-1].language, ot_languages[i].language); + if (c >= 0) + { + fprintf (stderr, "ot_languages not sorted at index %d: %s %d %s\n", + i, ot_languages[i-1].language, c, ot_languages[i].language); + abort(); + } + } +} + +int +main (void) +{ + test_langs_sorted (); + return 0; +} +#endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h index 1bf12ab3c0..54fb747f58 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.h @@ -39,18 +39,18 @@ HB_BEGIN_DECLS #define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T') #define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't') -void +HB_EXTERN void hb_ot_tags_from_script (hb_script_t script, hb_tag_t *script_tag_1, hb_tag_t *script_tag_2); -hb_script_t +HB_EXTERN hb_script_t hb_ot_tag_to_script (hb_tag_t tag); -hb_tag_t +HB_EXTERN hb_tag_t hb_ot_tag_from_language (hb_language_t language); -hb_language_t +HB_EXTERN hb_language_t hb_ot_tag_to_language (hb_tag_t tag); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot.h b/src/3rdparty/harfbuzz-ng/src/hb-ot.h index 47c92a58e4..113e37b08a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot.h @@ -32,6 +32,7 @@ #include "hb-ot-font.h" #include "hb-ot-layout.h" +#include "hb-ot-math.h" #include "hb-ot-tag.h" #include "hb-ot-shape.h" diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh index 53e0510a92..666af6260b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh @@ -83,7 +83,7 @@ extern "C" void hb_free_impl(void *ptr); #define unlikely(expr) (expr) #endif -#ifndef __GNUC__ +#if !defined(__GNUC__) && !defined(__clang__) #undef __attribute__ #define __attribute__(x) #endif @@ -169,6 +169,7 @@ extern "C" void hb_free_impl(void *ptr); # if defined(_WIN32_WCE) /* Some things not defined on Windows CE. */ # define strdup _strdup +# define vsnprintf _vsnprintf # define getenv(Name) NULL # if _WIN32_WCE < 0x800 # define setlocale(Category, Locale) "C" @@ -179,6 +180,9 @@ static int errno = 0; /* Use something better? */ # endif # if defined(_MSC_VER) && _MSC_VER < 1900 # define snprintf _snprintf +# elif defined(_MSC_VER) && _MSC_VER >= 1900 +# /* Covers VC++ Error for strdup being a deprecated POSIX name and to instead use _strdup instead */ +# define strdup _strdup # endif #endif @@ -608,6 +612,15 @@ static inline unsigned char TOLOWER (unsigned char c) /* Debug */ +/* HB_NDEBUG disables some sanity checks that are very safe to disable and + * should be disabled in production systems. If NDEBUG is defined, enable + * HB_NDEBUG; but if it's desirable that normal assert()s (which are very + * light-weight) to be enabled, then HB_DEBUG can be defined to disable + * the costlier checks. */ +#ifdef NDEBUG +#define HB_NDEBUG +#endif + #ifndef HB_DEBUG #define HB_DEBUG 0 #endif @@ -676,17 +689,20 @@ _hb_debug_msg_va (const char *what, fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), ""); if (indented) { -/* One may want to add ASCII version of these. See: - * https://bugs.freedesktop.org/show_bug.cgi?id=50970 */ #define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ #define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ #define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */ #define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */ #define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */ - static const char bars[] = VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR; + static const char bars[] = + VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR + VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR + VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR + VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR + VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR; fprintf (stderr, "%2u %s" VRBAR "%s", level, - bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars), (unsigned int) (sizeof (VBAR) - 1) * level), + bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level), level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR); } else fprintf (stderr, " " VRBAR LBAR); @@ -891,6 +907,29 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) } +/* Enable bitwise ops on enums marked as flags_t */ +/* To my surprise, looks like the function resolver is happy to silently cast + * one enum to another... So this doesn't provide the type-checking that I + * originally had in mind... :(. + * + * For MSVC warnings, see: https://github.com/behdad/harfbuzz/pull/163 + */ +#ifdef _MSC_VER +# pragma warning(disable:4200) +# pragma warning(disable:4800) +#endif +#define HB_MARK_AS_FLAG_T(T) \ + extern "C++" { \ + static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \ + static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \ + static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \ + static inline T operator ~ (T r) { return T (~(unsigned int) r); } \ + static inline T& operator |= (T &l, T r) { l = l | r; return l; } \ + static inline T& operator &= (T& l, T r) { l = l & r; return l; } \ + static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ + } + + /* Useful for set-operations on small enums. * For example, for testing "x ∈ {x1, x2, x3}" use: * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) @@ -979,5 +1018,7 @@ hb_options (void) return _hb_options.opts; } +/* Size signifying variable-sized array */ +#define VAR 1 #endif /* HB_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh index 3c302b1daf..e2010d7626 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh @@ -313,7 +313,7 @@ struct hb_set_t for (unsigned int i = 0; i < ELTS; i++) if (elts[i]) for (unsigned int j = 0; j < BITS; j++) - if (elts[i] & (1 << j)) + if (elts[i] & (1u << j)) return i * BITS + j; return INVALID; } @@ -322,7 +322,7 @@ struct hb_set_t for (unsigned int i = ELTS; i; i--) if (elts[i - 1]) for (unsigned int j = BITS; j; j--) - if (elts[i - 1] & (1 << (j - 1))) + if (elts[i - 1] & (1u << (j - 1))) return (i - 1) * BITS + (j - 1); return INVALID; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.h b/src/3rdparty/harfbuzz-ng/src/hb-set.h index 29bf6556ab..2164c1a654 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-set.h @@ -44,109 +44,109 @@ HB_BEGIN_DECLS typedef struct hb_set_t hb_set_t; -hb_set_t * +HB_EXTERN hb_set_t * hb_set_create (void); -hb_set_t * +HB_EXTERN hb_set_t * hb_set_get_empty (void); -hb_set_t * +HB_EXTERN hb_set_t * hb_set_reference (hb_set_t *set); -void +HB_EXTERN void hb_set_destroy (hb_set_t *set); -hb_bool_t +HB_EXTERN hb_bool_t hb_set_set_user_data (hb_set_t *set, hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy, hb_bool_t replace); -void * +HB_EXTERN void * hb_set_get_user_data (hb_set_t *set, hb_user_data_key_t *key); /* Returns false if allocation has failed before */ -hb_bool_t +HB_EXTERN hb_bool_t hb_set_allocation_successful (const hb_set_t *set); -void +HB_EXTERN void hb_set_clear (hb_set_t *set); -hb_bool_t +HB_EXTERN hb_bool_t hb_set_is_empty (const hb_set_t *set); -hb_bool_t +HB_EXTERN hb_bool_t hb_set_has (const hb_set_t *set, hb_codepoint_t codepoint); /* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1 * which we will use as a sentinel. */ -void +HB_EXTERN void hb_set_add (hb_set_t *set, hb_codepoint_t codepoint); -void +HB_EXTERN void hb_set_add_range (hb_set_t *set, hb_codepoint_t first, hb_codepoint_t last); -void +HB_EXTERN void hb_set_del (hb_set_t *set, hb_codepoint_t codepoint); -void +HB_EXTERN void hb_set_del_range (hb_set_t *set, hb_codepoint_t first, hb_codepoint_t last); -hb_bool_t +HB_EXTERN hb_bool_t hb_set_is_equal (const hb_set_t *set, const hb_set_t *other); -void +HB_EXTERN void hb_set_set (hb_set_t *set, const hb_set_t *other); -void +HB_EXTERN void hb_set_union (hb_set_t *set, const hb_set_t *other); -void +HB_EXTERN void hb_set_intersect (hb_set_t *set, const hb_set_t *other); -void +HB_EXTERN void hb_set_subtract (hb_set_t *set, const hb_set_t *other); -void +HB_EXTERN void hb_set_symmetric_difference (hb_set_t *set, const hb_set_t *other); -void +HB_EXTERN void hb_set_invert (hb_set_t *set); -unsigned int +HB_EXTERN unsigned int hb_set_get_population (const hb_set_t *set); /* Returns -1 if set empty. */ -hb_codepoint_t +HB_EXTERN hb_codepoint_t hb_set_get_min (const hb_set_t *set); /* Returns -1 if set empty. */ -hb_codepoint_t +HB_EXTERN hb_codepoint_t hb_set_get_max (const hb_set_t *set); /* Pass -1 in to get started. */ -hb_bool_t +HB_EXTERN hb_bool_t hb_set_next (const hb_set_t *set, hb_codepoint_t *codepoint); /* Pass -1 for first and last to get started. */ -hb_bool_t +HB_EXTERN hb_bool_t hb_set_next_range (const hb_set_t *set, hb_codepoint_t *first, hb_codepoint_t *last); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh index 607da5e779..aa0413a272 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh @@ -47,12 +47,17 @@ struct hb_shape_plan_t hb_feature_t *user_features; unsigned int num_user_features; + int *coords; + unsigned int num_coords; + struct hb_shaper_data_t shaper_data; }; #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \ - , const hb_feature_t *user_features \ - , unsigned int num_user_features + , const hb_feature_t *user_features \ + , unsigned int num_user_features \ + , const int *coords \ + , unsigned int num_coords #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc index 56e2ea5c19..600faaeb18 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc @@ -46,11 +46,14 @@ static void hb_shape_plan_plan (hb_shape_plan_t *shape_plan, const hb_feature_t *user_features, unsigned int num_user_features, + const int *coords, + unsigned int num_coords, const char * const *shaper_list) { DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, - "num_features=%d shaper_list=%p", + "num_features=%d num_coords=%d shaper_list=%p", num_user_features, + num_coords, shaper_list); const hb_shaper_pair_t *shapers = _hb_shapers_get (); @@ -59,7 +62,9 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan, HB_STMT_START { \ if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \ HB_SHAPER_DATA (shaper, shape_plan) = \ - HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \ + HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, \ + user_features, num_user_features, \ + coords, num_coords); \ shape_plan->shaper_func = _hb_##shaper##_shape; \ shape_plan->shaper_name = #shaper; \ return; \ @@ -114,15 +119,32 @@ hb_shape_plan_create (hb_face_t *face, const hb_feature_t *user_features, unsigned int num_user_features, const char * const *shaper_list) +{ + return hb_shape_plan_create2 (face, props, + user_features, num_user_features, + NULL, 0, + shaper_list); +} + +hb_shape_plan_t * +hb_shape_plan_create2 (hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *orig_coords, + unsigned int num_coords, + const char * const *shaper_list) { DEBUG_MSG_FUNC (SHAPE_PLAN, NULL, - "face=%p num_features=%d shaper_list=%p", + "face=%p num_features=%d num_coords=%d shaper_list=%p", face, num_user_features, + num_coords, shaper_list); hb_shape_plan_t *shape_plan; hb_feature_t *features = NULL; + int *coords = NULL; if (unlikely (!face)) face = hb_face_get_empty (); @@ -130,7 +152,14 @@ hb_shape_plan_create (hb_face_t *face, return hb_shape_plan_get_empty (); if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t)))) return hb_shape_plan_get_empty (); - if (!(shape_plan = hb_object_create ())) { + if (num_coords && !(coords = (int *) calloc (num_coords, sizeof (int)))) + { + free (features); + return hb_shape_plan_get_empty (); + } + if (!(shape_plan = hb_object_create ())) + { + free (coords); free (features); return hb_shape_plan_get_empty (); } @@ -145,8 +174,15 @@ hb_shape_plan_create (hb_face_t *face, shape_plan->user_features = features; if (num_user_features) memcpy (features, user_features, num_user_features * sizeof (hb_feature_t)); + shape_plan->num_coords = num_coords; + shape_plan->coords = coords; + if (num_coords) + memcpy (coords, orig_coords, num_coords * sizeof (int)); - hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list); + hb_shape_plan_plan (shape_plan, + user_features, num_user_features, + coords, num_coords, + shaper_list); return shape_plan; } @@ -176,6 +212,9 @@ hb_shape_plan_get_empty (void) NULL, /* user_features */ 0, /* num_user_featurs */ + NULL, /* coords */ + 0, /* num_coords */ + { #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, #include "hb-shaper-list.hh" @@ -220,6 +259,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) #undef HB_SHAPER_IMPLEMENT free (shape_plan->user_features); + free (shape_plan->coords); free (shape_plan); } @@ -289,9 +329,10 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, unsigned int num_features) { DEBUG_MSG_FUNC (SHAPE_PLAN, shape_plan, - "num_features=%d shaper_func=%p", + "num_features=%d shaper_func=%p, shaper_name=%s", num_features, - shape_plan->shaper_func); + shape_plan->shaper_func, + shape_plan->shaper_name); if (unlikely (!buffer->len)) return true; @@ -350,6 +391,8 @@ struct hb_shape_plan_proposal_t const char * const *shaper_list; const hb_feature_t *user_features; unsigned int num_user_features; + const int *coords; + unsigned int num_coords; hb_shape_func_t *shaper_func; }; @@ -357,12 +400,26 @@ static inline hb_bool_t hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan, const hb_shape_plan_proposal_t *proposal) { - if (proposal->num_user_features != shape_plan->num_user_features) return false; + if (proposal->num_user_features != shape_plan->num_user_features) + return false; for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++) if (proposal->user_features[i].tag != shape_plan->user_features[i].tag || proposal->user_features[i].value != shape_plan->user_features[i].value || proposal->user_features[i].start != shape_plan->user_features[i].start || - proposal->user_features[i].end != shape_plan->user_features[i].end) return false; + proposal->user_features[i].end != shape_plan->user_features[i].end) + return false; + return true; +} + +static inline hb_bool_t +hb_shape_plan_coords_match (const hb_shape_plan_t *shape_plan, + const hb_shape_plan_proposal_t *proposal) +{ + if (proposal->num_coords != shape_plan->num_coords) + return false; + for (unsigned int i = 0, n = proposal->num_coords; i < n; i++) + if (proposal->coords[i] != shape_plan->coords[i]) + return false; return true; } @@ -372,6 +429,7 @@ hb_shape_plan_matches (const hb_shape_plan_t *shape_plan, { return hb_segment_properties_equal (&shape_plan->props, &proposal->props) && hb_shape_plan_user_features_match (shape_plan, proposal) && + hb_shape_plan_coords_match (shape_plan, proposal) && ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) || (shape_plan->shaper_func == proposal->shaper_func)); } @@ -388,6 +446,13 @@ hb_non_global_user_features_present (const hb_feature_t *user_features, return false; } +static inline hb_bool_t +hb_coords_present (const int *coords, + unsigned int num_coords) +{ + return num_coords != 0; +} + /** * hb_shape_plan_create_cached: * @face: @@ -408,6 +473,21 @@ hb_shape_plan_create_cached (hb_face_t *face, const hb_feature_t *user_features, unsigned int num_user_features, const char * const *shaper_list) +{ + return hb_shape_plan_create_cached2 (face, props, + user_features, num_user_features, + NULL, 0, + shaper_list); +} + +hb_shape_plan_t * +hb_shape_plan_create_cached2 (hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *coords, + unsigned int num_coords, + const char * const *shaper_list) { DEBUG_MSG_FUNC (SHAPE_PLAN, NULL, "face=%p num_features=%d shaper_list=%p", @@ -455,16 +535,21 @@ retry: /* Not found. */ - hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list); + hb_shape_plan_t *shape_plan = hb_shape_plan_create2 (face, props, + user_features, num_user_features, + coords, num_coords, + shaper_list); /* Don't add to the cache if face is inert. */ if (unlikely (hb_object_is_inert (face))) return shape_plan; /* Don't add the plan to the cache if there were user features with non-global ranges */ - if (hb_non_global_user_features_present (user_features, num_user_features)) return shape_plan; + /* Don't add the plan to the cache if there were variation coordinates XXX Fix me. */ + if (hb_coords_present (coords, num_coords)) + return shape_plan; hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t)); if (unlikely (!node)) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h index 8f54552f90..b62ae7ca35 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.h @@ -38,49 +38,68 @@ HB_BEGIN_DECLS typedef struct hb_shape_plan_t hb_shape_plan_t; -hb_shape_plan_t * +HB_EXTERN hb_shape_plan_t * hb_shape_plan_create (hb_face_t *face, const hb_segment_properties_t *props, const hb_feature_t *user_features, unsigned int num_user_features, const char * const *shaper_list); -hb_shape_plan_t * +HB_EXTERN hb_shape_plan_t * hb_shape_plan_create_cached (hb_face_t *face, const hb_segment_properties_t *props, const hb_feature_t *user_features, unsigned int num_user_features, const char * const *shaper_list); -hb_shape_plan_t * +HB_EXTERN hb_shape_plan_t * +hb_shape_plan_create2 (hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *coords, + unsigned int num_coords, + const char * const *shaper_list); + +HB_EXTERN hb_shape_plan_t * +hb_shape_plan_create_cached2 (hb_face_t *face, + const hb_segment_properties_t *props, + const hb_feature_t *user_features, + unsigned int num_user_features, + const int *coords, + unsigned int num_coords, + const char * const *shaper_list); + + +HB_EXTERN hb_shape_plan_t * hb_shape_plan_get_empty (void); -hb_shape_plan_t * +HB_EXTERN hb_shape_plan_t * hb_shape_plan_reference (hb_shape_plan_t *shape_plan); -void +HB_EXTERN void hb_shape_plan_destroy (hb_shape_plan_t *shape_plan); -hb_bool_t +HB_EXTERN hb_bool_t hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy, hb_bool_t replace); -void * +HB_EXTERN void * hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, hb_user_data_key_t *key); -hb_bool_t +HB_EXTERN hb_bool_t hb_shape_plan_execute (hb_shape_plan_t *shape_plan, hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features); -const char * +HB_EXTERN const char * hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc index 8a98583989..706f14420d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc @@ -210,13 +210,15 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) /** * hb_feature_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is nul-terminated + * @len: length of @str, or -1 if string is %NULL terminated * @feature: (out): the #hb_feature_t to initialize with the parsed values * - * Parses a string into a #hb_feature_t. If @len is -1 then @str is - * %NULL-terminated. + * Parses a string into a #hb_feature_t. * - * Return value: %TRUE if @str is successfully parsed, %FALSE otherwise + * TODO: document the syntax here. + * + * Return value: + * %true if @str is successfully parsed, %false otherwise. * * Since: 0.9.5 **/ @@ -371,7 +373,10 @@ hb_shape_full (hb_font_t *font, unsigned int num_features, const char * const *shaper_list) { - hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list); + hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached2 (font->face, &buffer->props, + features, num_features, + font->coords, font->num_coords, + shaper_list); hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); hb_shape_plan_destroy (shape_plan); @@ -392,8 +397,6 @@ hb_shape_full (hb_font_t *font, * positioned glyphs. If @features is not %NULL, it will be used to control the * features applied during shaping. * - * Return value: %FALSE if all shapers failed, %TRUE otherwise - * * Since: 0.9.2 **/ void diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-shape.h index b665509a0d..53bb845bf4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.h @@ -47,29 +47,29 @@ typedef struct hb_feature_t { unsigned int end; } hb_feature_t; -hb_bool_t +HB_EXTERN hb_bool_t hb_feature_from_string (const char *str, int len, hb_feature_t *feature); -void +HB_EXTERN void hb_feature_to_string (hb_feature_t *feature, char *buf, unsigned int size); -void +HB_EXTERN void hb_shape (hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features); -hb_bool_t +HB_EXTERN hb_bool_t hb_shape_full (hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features, const char * const *shaper_list); -const char ** +HB_EXTERN const char ** hb_shape_list_shapers (void); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh index 6c537d4921..b0835d31ab 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper-list.hh @@ -46,6 +46,9 @@ HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */ #ifdef HAVE_UNISCRIBE HB_SHAPER_IMPLEMENT (uniscribe) #endif +#ifdef HAVE_DIRECTWRITE +HB_SHAPER_IMPLEMENT (directwrite) +#endif #ifdef HAVE_CORETEXT HB_SHAPER_IMPLEMENT (coretext) #endif diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh index 968bca5567..a4d118b6dc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh @@ -115,6 +115,8 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE /* XXX This hack belongs to the Tibetan shaper: * Reorder PADMA to ensure it comes after any vowel marks. */ if (unlikely (unicode == 0x0FC6u)) return 254; + /* Reorder TSA -PHRU to reorder before U+0F74 */ + if (unlikely (unicode == 0x0F39u)) return 127; return _hb_modified_combining_class[combining_class (unicode)]; } @@ -180,8 +182,8 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE case 0x17: return hb_in_range (ch, 0x17B4u, 0x17B5u); case 0x18: return hb_in_range (ch, 0x180Bu, 0x180Eu); case 0x20: return hb_in_ranges (ch, 0x200Bu, 0x200Fu, - 0x202Au, 0x202Eu, - 0x2060u, 0x206Fu); + 0x202Au, 0x202Eu, + 0x2060u, 0x206Fu); case 0xFE: return hb_in_range (ch, 0xFE00u, 0xFE0Fu) || ch == 0xFEFFu; case 0xFF: return hb_in_range (ch, 0xFFF0u, 0xFFF8u); default: return false; @@ -199,6 +201,50 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE } } + /* Space estimates based on: + * http://www.unicode.org/charts/PDF/U2000.pdf + * https://www.microsoft.com/typography/developers/fdsspec/spaces.aspx + */ + enum space_t { + NOT_SPACE = 0, + SPACE_EM = 1, + SPACE_EM_2 = 2, + SPACE_EM_3 = 3, + SPACE_EM_4 = 4, + SPACE_EM_5 = 5, + SPACE_EM_6 = 6, + SPACE_EM_16 = 16, + SPACE_4_EM_18, /* 4/18th of an EM! */ + SPACE, + SPACE_FIGURE, + SPACE_PUNCTUATION, + SPACE_NARROW, + }; + static inline space_t + space_fallback_type (hb_codepoint_t u) + { + switch (u) + { + /* All GC=Zs chars that can use a fallback. */ + default: return NOT_SPACE; /* U+1680 OGHAM SPACE MARK */ + case 0x0020u: return SPACE; /* U+0020 SPACE */ + case 0x00A0u: return SPACE; /* U+00A0 NO-BREAK SPACE */ + case 0x2000u: return SPACE_EM_2; /* U+2000 EN QUAD */ + case 0x2001u: return SPACE_EM; /* U+2001 EM QUAD */ + case 0x2002u: return SPACE_EM_2; /* U+2002 EN SPACE */ + case 0x2003u: return SPACE_EM; /* U+2003 EM SPACE */ + case 0x2004u: return SPACE_EM_3; /* U+2004 THREE-PER-EM SPACE */ + case 0x2005u: return SPACE_EM_4; /* U+2005 FOUR-PER-EM SPACE */ + case 0x2006u: return SPACE_EM_6; /* U+2006 SIX-PER-EM SPACE */ + case 0x2007u: return SPACE_FIGURE; /* U+2007 FIGURE SPACE */ + case 0x2008u: return SPACE_PUNCTUATION; /* U+2008 PUNCTUATION SPACE */ + case 0x2009u: return SPACE_EM_5; /* U+2009 THIN SPACE */ + case 0x200Au: return SPACE_EM_16; /* U+200A HAIR SPACE */ + case 0x202Fu: return SPACE_NARROW; /* U+202F NARROW NO-BREAK SPACE */ + case 0x205Fu: return SPACE_4_EM_18; /* U+205F MEDIUM MATHEMATICAL SPACE */ + case 0x3000u: return SPACE_EM; /* U+3000 IDEOGRAPHIC SPACE */ + } + } struct { #define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_func_t name; @@ -299,10 +345,12 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; #define HB_MODIFIED_COMBINING_CLASS_CCC118 118 /* sign u / sign uu */ #define HB_MODIFIED_COMBINING_CLASS_CCC122 122 /* mai * */ -/* Tibetan */ +/* Tibetan + * Modify U+0F74 (ccc=132) to reorder before ccc=130 marks. + */ #define HB_MODIFIED_COMBINING_CLASS_CCC129 129 /* sign aa */ #define HB_MODIFIED_COMBINING_CLASS_CCC130 130 /* sign i */ -#define HB_MODIFIED_COMBINING_CLASS_CCC132 132 /* sign u */ +#define HB_MODIFIED_COMBINING_CLASS_CCC132 128 /* sign u */ /* Misc */ @@ -313,5 +361,10 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) +#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL(gen_cat) \ + (FLAG_SAFE (gen_cat) & \ + (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \ + FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL))) #endif /* HB_UNICODE_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc index 487d10b939..d553a7172f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc @@ -131,12 +131,12 @@ hb_unicode_funcs_get_default (void) #define HB_UNICODE_FUNCS_IMPLEMENT(set) \ return hb_##set##_get_unicode_funcs (); -#ifdef HAVE_GLIB +#if defined(HAVE_UCDN) + HB_UNICODE_FUNCS_IMPLEMENT(ucdn) +#elif defined(HAVE_GLIB) HB_UNICODE_FUNCS_IMPLEMENT(glib) #elif defined(HAVE_ICU) && defined(HAVE_ICU_BUILTIN) HB_UNICODE_FUNCS_IMPLEMENT(icu) -#elif defined(HAVE_UCDN) - HB_UNICODE_FUNCS_IMPLEMENT(ucdn) #else #define HB_UNICODE_FUNCS_NIL 1 HB_UNICODE_FUNCS_IMPLEMENT(nil) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h index 3a12e2f9a2..2657f48130 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h @@ -174,23 +174,23 @@ typedef struct hb_unicode_funcs_t hb_unicode_funcs_t; /* * just give me the best implementation you've got there. */ -hb_unicode_funcs_t * +HB_EXTERN hb_unicode_funcs_t * hb_unicode_funcs_get_default (void); -hb_unicode_funcs_t * +HB_EXTERN hb_unicode_funcs_t * hb_unicode_funcs_create (hb_unicode_funcs_t *parent); -hb_unicode_funcs_t * +HB_EXTERN hb_unicode_funcs_t * hb_unicode_funcs_get_empty (void); -hb_unicode_funcs_t * +HB_EXTERN hb_unicode_funcs_t * hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs); -void +HB_EXTERN void hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs); -hb_bool_t +HB_EXTERN hb_bool_t hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, hb_user_data_key_t *key, void * data, @@ -198,18 +198,18 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, hb_bool_t replace); -void * +HB_EXTERN void * hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, hb_user_data_key_t *key); -void +HB_EXTERN void hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs); -hb_bool_t +HB_EXTERN hb_bool_t hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs); -hb_unicode_funcs_t * +HB_EXTERN hb_unicode_funcs_t * hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs); @@ -285,7 +285,7 @@ typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_ * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, hb_unicode_combining_class_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -301,7 +301,7 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, hb_unicode_eastasian_width_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -317,7 +317,7 @@ hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, hb_unicode_general_category_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -333,7 +333,7 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, hb_unicode_mirroring_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -349,7 +349,7 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, hb_unicode_script_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -365,7 +365,7 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, hb_unicode_compose_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -381,7 +381,7 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, hb_unicode_decompose_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -397,7 +397,7 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, * * Since: 0.9.2 **/ -void +HB_EXTERN void hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, hb_unicode_decompose_compatibility_func_t func, void *user_data, hb_destroy_func_t destroy); @@ -405,62 +405,63 @@ hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, /* accessors */ /** + * hb_unicode_combining_class: + * * Since: 0.9.2 **/ -hb_unicode_combining_class_t +HB_EXTERN hb_unicode_combining_class_t hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); /** + * hb_unicode_eastasian_width: + * * Since: 0.9.2 **/ -unsigned int +HB_EXTERN unsigned int hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); /** + * hb_unicode_general_category: + * * Since: 0.9.2 **/ -hb_unicode_general_category_t +HB_EXTERN hb_unicode_general_category_t hb_unicode_general_category (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); /** + * hb_unicode_mirroring: + * * Since: 0.9.2 **/ -hb_codepoint_t +HB_EXTERN hb_codepoint_t hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); /** + * hb_unicode_script: + * * Since: 0.9.2 **/ -hb_script_t +HB_EXTERN hb_script_t hb_unicode_script (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); -/** - * Since: 0.9.2 - **/ -hb_bool_t +HB_EXTERN hb_bool_t hb_unicode_compose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab); -/** - * Since: 0.9.2 - **/ -hb_bool_t +HB_EXTERN hb_bool_t hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b); -/** - * Since: 0.9.2 - **/ -unsigned int +HB_EXTERN unsigned int hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, hb_codepoint_t u, hb_codepoint_t *decomposed); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh index 14d3c2e369..74cf5d66a2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-utf-private.hh @@ -146,11 +146,11 @@ struct hb_utf16_t return text; } - if (likely (hb_in_range (c, 0xD800u, 0xDBFFu))) + if (likely (c <= 0xDBFFu && text < end)) { /* High-surrogate in c */ - hb_codepoint_t l; - if (text < end && ((l = *text), likely (hb_in_range (l, 0xDC00u, 0xDFFFu)))) + hb_codepoint_t l = *text; + if (likely (hb_in_range (l, 0xDC00u, 0xDFFFu))) { /* Low-surrogate in l */ *unicode = (c << 10) + l - ((0xD800u << 10) - 0x10000u + 0xDC00u); @@ -170,8 +170,7 @@ struct hb_utf16_t hb_codepoint_t *unicode, hb_codepoint_t replacement) { - const uint16_t *end = text--; - hb_codepoint_t c = *text; + hb_codepoint_t c = *--text; if (likely (!hb_in_range (c, 0xD800u, 0xDFFFu))) { @@ -179,14 +178,22 @@ struct hb_utf16_t return text; } - if (likely (start < text && hb_in_range (c, 0xDC00u, 0xDFFFu))) - text--; - - if (likely (next (text, end, unicode, replacement) == end)) - return text; + if (likely (c >= 0xDC00u && start < text)) + { + /* Low-surrogate in c */ + hb_codepoint_t h = text[-1]; + if (likely (hb_in_range (h, 0xD800u, 0xDBFFu))) + { + /* High-surrogate in h */ + *unicode = (h << 10) + c - ((0xD800u << 10) - 0x10000u + 0xDC00u); + text--; + return text; + } + } + /* Lonely / out-of-order surrogate. */ *unicode = replacement; - return end - 1; + return text; } @@ -211,14 +218,9 @@ struct hb_utf32_t hb_codepoint_t *unicode, hb_codepoint_t replacement) { - hb_codepoint_t c = *text++; - if (validate && unlikely (c > 0x10FFFFu || hb_in_range (c, 0xD800u, 0xDFFFu))) - goto error; - *unicode = c; - return text; - - error: - *unicode = replacement; + hb_codepoint_t c = *unicode = *text++; + if (validate && unlikely (c >= 0xD800u && (c <= 0xDFFFu || c > 0x10FFFFu))) + *unicode = replacement; return text; } @@ -228,8 +230,10 @@ struct hb_utf32_t hb_codepoint_t *unicode, hb_codepoint_t replacement) { - next (text - 1, text, unicode, replacement); - return text - 1; + hb_codepoint_t c = *unicode = *--text; + if (validate && unlikely (c >= 0xD800u && (c <= 0xDFFFu || c > 0x10FFFFu))) + *unicode = replacement; + return text; } static inline unsigned int diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index bd9ac3d1fc..0cbe947062 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -37,25 +37,25 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 1 -#define HB_VERSION_MINOR 0 -#define HB_VERSION_MICRO 6 +#define HB_VERSION_MINOR 4 +#define HB_VERSION_MICRO 1 -#define HB_VERSION_STRING "1.0.6" +#define HB_VERSION_STRING "1.4.1" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ HB_VERSION_MAJOR*10000+HB_VERSION_MINOR*100+HB_VERSION_MICRO) -void +HB_EXTERN void hb_version (unsigned int *major, unsigned int *minor, unsigned int *micro); -const char * +HB_EXTERN const char * hb_version_string (void); -hb_bool_t +HB_EXTERN hb_bool_t hb_version_atleast (unsigned int major, unsigned int minor, unsigned int micro); diff --git a/src/3rdparty/harfbuzz-ng/src/hb.h b/src/3rdparty/harfbuzz-ng/src/hb.h index c5a938a381..7402034f43 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb.h +++ b/src/3rdparty/harfbuzz-ng/src/hb.h @@ -28,6 +28,10 @@ #define HB_H #define HB_H_IN +#ifndef HB_EXTERN +#define HB_EXTERN extern +#endif + #include "hb-blob.h" #include "hb-buffer.h" #include "hb-common.h" -- cgit v1.2.3