author | prr |
Wed, 30 May 2018 12:20:00 -0700 | |
changeset 50352 | 25db2c8f3cf8 |
parent 50351 | 9289c4214a35 |
child 50353 | 204621ae8e7c |
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-atomic-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-atomic-private.hh Wed May 30 12:20:00 2018 -0700 @@ -70,6 +70,29 @@ #define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) +#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) + +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V)) + +#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) + + +#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) + +#include <atomic.h> +#include <mbarrier.h> + +typedef unsigned int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) + +#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) +#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(__APPLE__) #include <libkern/OSAtomic.h> @@ -96,29 +119,6 @@ #endif -#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) - -typedef int hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V)) - -#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P)) -#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) - - -#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) - -#include <atomic.h> -#include <mbarrier.h> - -typedef unsigned int hb_atomic_int_impl_t; -#define HB_ATOMIC_INT_IMPL_INIT(V) (V) -#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) - -#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) -#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 <builtins.h>
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.cc Wed May 30 12:20:00 2018 -0700 @@ -26,7 +26,7 @@ /* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */ #ifndef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 199309L +#define _POSIX_C_SOURCE 200809L #endif #include "hb-private.hh" @@ -171,6 +171,31 @@ } /** + * hb_blob_copy_writable_or_fail: + * @blob: A blob. + * + * Makes a writable copy of @blob. + * + * Return value: New blob, or nullptr if allocation failed. + * + * Since: 1.8.0 + **/ +hb_blob_t * +hb_blob_copy_writable_or_fail (hb_blob_t *blob) +{ + blob = hb_blob_create (blob->data, + blob->length, + HB_MEMORY_MODE_DUPLICATE, + nullptr, + nullptr); + + if (unlikely (blob == hb_blob_get_empty ())) + blob = nullptr; + + return blob; +} + +/** * hb_blob_get_empty: * * Returns the singleton empty blob. @@ -222,7 +247,7 @@ * hb_blob_destroy: (skip) * @blob: a blob. * - * Descreases the reference count on @blob, and if it reaches zero, destroys + * Decreases the reference count on @blob, and if it reaches zero, destroys * @blob, freeing all memory, possibly calling the destroy-callback the blob * was created for if it has not been called already. *
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.h Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-blob.h Wed May 30 12:20:00 2018 -0700 @@ -44,7 +44,7 @@ * any such possibility, MODE_DUPLICATE should be used * such that HarfBuzz makes a copy immediately, * - * - Use MODE_READONLY otherse, unless you really really + * - Use MODE_READONLY otherwise, unless you really really * really know what you are doing, * * - MODE_WRITABLE is appropriate if you really made a @@ -83,6 +83,9 @@ unsigned int length); HB_EXTERN hb_blob_t * +hb_blob_copy_writable_or_fail (hb_blob_t *blob); + +HB_EXTERN hb_blob_t * hb_blob_get_empty (void); HB_EXTERN hb_blob_t *
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-private.hh Wed May 30 12:20:00 2018 -0700 @@ -35,8 +35,8 @@ #include "hb-unicode-private.hh" -#ifndef HB_BUFFER_MAX_EXPANSION_FACTOR -#define HB_BUFFER_MAX_EXPANSION_FACTOR 32 +#ifndef HB_BUFFER_MAX_LEN_FACTOR +#define HB_BUFFER_MAX_LEN_FACTOR 32 #endif #ifndef HB_BUFFER_MAX_LEN_MIN #define HB_BUFFER_MAX_LEN_MIN 8192 @@ -45,6 +45,16 @@ #define HB_BUFFER_MAX_LEN_DEFAULT 0x3FFFFFFF /* Shaping more than a billion chars? Let us know! */ #endif +#ifndef HB_BUFFER_MAX_OPS_FACTOR +#define HB_BUFFER_MAX_OPS_FACTOR 64 +#endif +#ifndef HB_BUFFER_MAX_OPS_MIN +#define HB_BUFFER_MAX_OPS_MIN 1024 +#endif +#ifndef HB_BUFFER_MAX_OPS_DEFAULT +#define HB_BUFFER_MAX_OPS_DEFAULT 0x1FFFFFFF /* Shaping more than a billion operations? Let us know! */ +#endif + static_assert ((sizeof (hb_glyph_info_t) == 20), ""); static_assert ((sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t)), ""); @@ -59,6 +69,7 @@ HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u, HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u, HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u, + HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000020u, /* Reserved for complex shapers' internal use. */ HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u, @@ -82,8 +93,9 @@ 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. */ + hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ unsigned int max_len; /* Maximum allowed len. */ + int max_ops; /* Maximum allowed operations. */ /* Buffer contents */ hb_buffer_content_type_t content_type; @@ -102,17 +114,6 @@ hb_glyph_info_t *out_info; hb_glyph_position_t *pos; - inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; } - inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; } - - 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 ? 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; /* Text before / after the main buffer contents. @@ -132,6 +133,10 @@ #ifndef HB_NDEBUG uint8_t allocated_var_bits; #endif + + + /* Methods */ + inline void allocate_var (unsigned int start, unsigned int count) { #ifndef HB_NDEBUG @@ -168,8 +173,17 @@ #endif } + inline hb_glyph_info_t &cur (unsigned int i = 0) { return info[idx + i]; } + inline hb_glyph_info_t cur (unsigned int i = 0) const { return info[idx + i]; } - /* Methods */ + 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 ? 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; } + HB_INTERNAL void reset (void); HB_INTERNAL void clear (void); @@ -293,45 +307,44 @@ HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0); static inline void - set_cluster (hb_glyph_info_t &info, unsigned int cluster, unsigned int mask = 0) + set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0) { - if (info.cluster != cluster) + if (inf.cluster != cluster) { if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) - info.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + inf.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; else - info.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + inf.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK; } - info.cluster = cluster; + inf.cluster = cluster; } inline int - _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *info, + _unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos, unsigned int start, unsigned int end, unsigned int cluster) const { for (unsigned int i = start; i < end; i++) - cluster = MIN<unsigned int> (cluster, info[i].cluster); + cluster = MIN<unsigned int> (cluster, infos[i].cluster); return cluster; } inline void - _unsafe_to_break_set_mask (hb_glyph_info_t *info, + _unsafe_to_break_set_mask (hb_glyph_info_t *infos, unsigned int start, unsigned int end, unsigned int cluster) { for (unsigned int i = start; i < end; i++) - if (cluster != info[i].cluster) + if (cluster != infos[i].cluster) { scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK; - info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + infos[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; } } inline void unsafe_to_break_all (void) { - for (unsigned int i = 0; i < len; i++) - info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK; + unsafe_to_break_impl (0, len); } inline void safe_to_break_all (void)
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-serialize.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer-serialize.cc Wed May 30 12:20:00 2018 -0700 @@ -109,6 +109,7 @@ nullptr : hb_buffer_get_glyph_positions (buffer, nullptr); *buf_consumed = 0; + hb_position_t x = 0, y = 0; for (unsigned int i = start; i < end; i++) { char b[1024]; @@ -146,9 +147,10 @@ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d", - pos[i].x_offset, pos[i].y_offset)); - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", - pos[i].x_advance, pos[i].y_advance)); + x+pos[i].x_offset, y+pos[i].y_offset)); + if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d", + pos[i].x_advance, pos[i].y_advance)); } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) @@ -179,6 +181,12 @@ *buf = '\0'; } else return i - start; + + if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) + { + x += pos[i].x_advance; + y += pos[i].y_advance; + } } return end - start; @@ -199,6 +207,7 @@ nullptr : hb_buffer_get_glyph_positions (buffer, nullptr); *buf_consumed = 0; + hb_position_t x = 0, y = 0; for (unsigned int i = start; i < end; i++) { char b[1024]; @@ -223,13 +232,16 @@ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS)) { - if (pos[i].x_offset || pos[i].y_offset) - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset)); + if (x+pos[i].x_offset || y+pos[i].y_offset) + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset)); - *p++ = '+'; - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance)); - if (pos[i].y_advance) - p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); + if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) + { + *p++ = '+'; + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance)); + if (pos[i].y_advance) + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance)); + } } if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS) @@ -255,6 +267,12 @@ *buf = '\0'; } else return i - start; + + if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES)) + { + x += pos[i].x_advance; + y += pos[i].y_advance; + } } return end - start;
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.cc Wed May 30 12:20:00 2018 -0700 @@ -722,6 +722,7 @@ return hb_buffer_get_empty (); buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT; + buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT; buffer->reset (); @@ -749,6 +750,7 @@ HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, HB_BUFFER_SCRATCH_FLAG_DEFAULT, HB_BUFFER_MAX_LEN_DEFAULT, + HB_BUFFER_MAX_OPS_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, HB_SEGMENT_PROPERTIES_DEFAULT, @@ -1931,7 +1933,7 @@ result |= HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH; if (buf_info->cluster != ref_info->cluster) result |= HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH; - if ((buf_info->mask & HB_GLYPH_FLAG_DEFINED) != (ref_info->mask & HB_GLYPH_FLAG_DEFINED)) + if ((buf_info->mask & ~ref_info->mask & HB_GLYPH_FLAG_DEFINED)) result |= HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH; if (contains && ref_info->codepoint == dottedcircle_glyph) result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.h Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-buffer.h Wed May 30 12:20:00 2018 -0700 @@ -71,6 +71,24 @@ hb_var_int_t var2; } hb_glyph_info_t; +/** + * hb_glyph_flags_t: + * @HB_GLYPH_FLAG_UNSAFE_TO_BREAK: Indicates that if input text is broken at the + * beginning of the cluster this glyph is part of, + * then both sides need to be re-shaped, as the + * result might be different. On the flip side, + * it means that when this flag is not present, + * then it's safe to break the glyph-run at the + * beginning of this cluster, and the two sides + * represent the exact same result one would get + * if breaking input text at the beginning of + * this cluster and shaping the two sides + * separately. This can be used to optimize + * paragraph layout, by avoiding re-shaping + * of each line after line-breaking, or limiting + * the reshaping to a small piece around the + * breaking point only. + */ typedef enum { /*< flags >*/ HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001, @@ -247,13 +265,21 @@ * 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_BOT. * @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.) + * from the font, instead of hiding them (done by + * replacing them with the space glyph and zeroing the + * advance width.) This flag takes precedence over + * @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES. + * @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES: + * flag indication that character with Default_Ignorable + * Unicode property should be removed from glyph string + * instead of hiding them (done by replacing them with the + * space glyph and zeroing the advance width.) + * @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES takes + * precedence over this flag. Since: 1.8.0 * * Since: 0.9.20 */ @@ -261,7 +287,8 @@ HB_BUFFER_FLAG_DEFAULT = 0x00000000u, HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */ HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */ - HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u + HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u, + HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u } hb_buffer_flags_t; HB_EXTERN void @@ -412,6 +439,9 @@ * @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. + * @HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS: serialize glyph flags. Since: 1.5.0 + * @HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES: do not serialize glyph advances, + * glyph offsets will reflect absolute glyph positions. Since: 1.8.0 * * Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs(). * @@ -423,7 +453,8 @@ HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u, HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u, HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u, - HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u + HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u, + HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES = 0x00000020u } hb_buffer_serialize_flags_t; /**
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.cc Wed May 30 12:20:00 2018 -0700 @@ -524,6 +524,7 @@ case HB_SCRIPT_PSALTER_PAHLAVI: /* Unicode-8.0 additions */ + case HB_SCRIPT_HATRAN: case HB_SCRIPT_OLD_HUNGARIAN: /* Unicode-9.0 additions */ @@ -784,9 +785,9 @@ (*pp)++; /* CSS allows on/off as aliases 1/0. */ - if (*pp - p == 2 || 0 == strncmp (p, "on", 2)) + if (*pp - p == 2 && 0 == strncmp (p, "on", 2)) *pv = 1; - else if (*pp - p == 3 || 0 == strncmp (p, "off", 2)) + else if (*pp - p == 3 && 0 == strncmp (p, "off", 3)) *pv = 0; else return false; @@ -878,7 +879,7 @@ parse_bool (pp, end, &feature->value); /* CSS doesn't use equal-sign between tag and value. * If there was an equal-sign, then there *must* be a value. - * A value without an eqaul-sign is ok, but not required. */ + * A value without an equal-sign is ok, but not required. */ return !had_equal || had_value; }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.cc Wed May 30 12:20:00 2018 -0700 @@ -39,7 +39,7 @@ #define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f static CGFloat -coretext_font_size (float ptem) +coretext_font_size_from_ptem (float ptem) { /* CoreText points are CSS pixels (96 per inch), * NOT typographic points (72 per inch). @@ -49,6 +49,12 @@ ptem *= 96.f / 72.f; return ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : ptem; } +static float +coretext_font_size_to_ptem (CGFloat size) +{ + size *= 72.f / 96.f; + return size <= 0.f ? 0 : size; +} static void release_table_data (void *user_data) @@ -68,7 +74,10 @@ const char *data = reinterpret_cast<const char*> (CFDataGetBytePtr (cf_data)); const size_t length = CFDataGetLength (cf_data); if (!data || !length) + { + CFRelease (cf_data); return nullptr; + } return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, reinterpret_cast<void *> (const_cast<__CFData *> (cf_data)), @@ -81,21 +90,12 @@ CGFontRelease ((CGFontRef) data); } -hb_face_t * -hb_coretext_face_create (CGFontRef cg_font) -{ - return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release); -} HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face) HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font, - fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size (font->ptem)) <= .5 + fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5 ) -/* - * shaper face data - */ - static CTFontDescriptorRef get_last_resort_font_desc (void) { @@ -267,6 +267,12 @@ CFRelease ((CGFontRef) data); } +hb_face_t * +hb_coretext_face_create (CGFontRef cg_font) +{ + return hb_face_create_for_tables (reference_table, CGFontRetain (cg_font), _hb_cg_font_release); +} + /* * Since: 0.9.10 */ @@ -278,10 +284,6 @@ } -/* - * shaper font data - */ - hb_coretext_shaper_font_data_t * _hb_coretext_shaper_font_data_create (hb_font_t *font) { @@ -289,7 +291,7 @@ if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr; CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face); - CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size (font->ptem)); + CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem)); if (unlikely (!ct_font)) { @@ -306,6 +308,37 @@ CFRelease ((CTFontRef) data); } +/* + * Since: 1.7.2 + */ +hb_font_t * +hb_coretext_font_create (CTFontRef ct_font) +{ + CGFontRef cg_font = CTFontCopyGraphicsFont (ct_font, nullptr); + hb_face_t *face = hb_coretext_face_create (cg_font); + CFRelease (cg_font); + hb_font_t *font = hb_font_create (face); + hb_face_destroy (face); + + if (unlikely (hb_object_is_inert (font))) + return font; + + hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font))); + + /* Let there be dragons here... */ + HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font); + + return font; +} + +CTFontRef +hb_coretext_font_get_ct_font (hb_font_t *font) +{ + if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr; + return (CTFontRef) HB_SHAPER_DATA_GET (font); +} + + /* * shaper shape_plan data @@ -328,13 +361,6 @@ { } -CTFontRef -hb_coretext_font_get_ct_font (hb_font_t *font) -{ - if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr; - return (CTFontRef)HB_SHAPER_DATA_GET (font); -} - /* * shaper @@ -854,7 +880,10 @@ kCFStringEncodingUTF8, kCFAllocatorNull); if (unlikely (!lang)) + { + CFRelease (attr_string); FAIL ("CFStringCreateWithCStringNoCopy failed"); + } CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len), kCTLanguageAttributeName, lang); CFRelease (lang); @@ -923,7 +952,10 @@ &kCFTypeDictionaryValueCallBacks); CFRelease (level_number); if (unlikely (!options)) + { + CFRelease (attr_string); FAIL ("CFDictionaryCreate failed"); + } CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options); CFRelease (options); @@ -1000,7 +1032,7 @@ * However, even that wouldn't work if we were passed in the CGFont to * construct a hb_face to begin with. * - * See: http://github.com/behdad/harfbuzz/pull/36 + * See: http://github.com/harfbuzz/harfbuzz/pull/36 * * Also see: https://bugs.chromium.org/p/chromium/issues/detail?id=597098 */ @@ -1013,7 +1045,7 @@ } if (!matched) { - CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0); + CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, nullptr); if (run_cg_font) { matched = CFEqual (run_cg_font, cg_font); @@ -1186,7 +1218,7 @@ } /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel, - * or if it does, it doesn't resepct it. So we get runs with wrong + * or if it does, it doesn't respect it. So we get runs with wrong * directions. As such, disable the assert... It wouldn't crash, but * cursoring will be off... * @@ -1212,8 +1244,6 @@ pos->x_offset = info->var1.i32; pos->y_offset = info->var2.i32; - info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; - info++, pos++; } else @@ -1223,8 +1253,6 @@ pos->x_offset = info->var1.i32; pos->y_offset = info->var2.i32; - info->mask = HB_GLYPH_FLAG_UNSAFE_TO_BREAK; - info++, pos++; }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.h Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-coretext.h Wed May 30 12:20:00 2018 -0700 @@ -48,6 +48,9 @@ HB_EXTERN hb_face_t * hb_coretext_face_create (CGFontRef cg_font); +HB_EXTERN hb_font_t * +hb_coretext_font_create (CTFontRef ct_font); + HB_EXTERN CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-debug.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-debug.hh Wed May 30 12:20:00 2018 -0700 @@ -93,7 +93,7 @@ fprintf (stderr, "%-10s", what ? what : ""); if (obj) - fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj); + fprintf (stderr, "(%*p) ", (unsigned int) (2 * sizeof (void *)), obj); else fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), ""); @@ -220,13 +220,15 @@ {} template <int max_level, typename ret_t> -struct hb_auto_trace_t { +struct hb_auto_trace_t +{ explicit inline hb_auto_trace_t (unsigned int *plevel_, const char *what_, const void *obj_, const char *func, const char *message, - ...) : plevel (plevel_), what (what_), obj (obj_), returned (false) + ...) HB_PRINTF_FUNC(6, 7) + : plevel (plevel_), what (what_), obj (obj_), returned (false) { if (plevel) ++*plevel; @@ -267,10 +269,20 @@ bool returned; }; template <typename ret_t> /* Make sure we don't use hb_auto_trace_t when not tracing. */ -struct hb_auto_trace_t<0, ret_t>; +struct hb_auto_trace_t<0, ret_t> +{ + explicit inline hb_auto_trace_t (unsigned int *plevel_, + const char *what_, + const void *obj_, + const char *func, + const char *message, + ...) HB_PRINTF_FUNC(6, 7) {} + + inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } +}; /* For disabled tracing; optimize out everything. - * https://github.com/behdad/harfbuzz/pull/605 */ + * https://github.com/harfbuzz/harfbuzz/pull/605 */ template <typename ret_t> struct hb_no_trace_t { inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } @@ -343,7 +355,7 @@ #define TRACE_CLOSURE(this) \ hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \ (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "") + " ") #else #define TRACE_CLOSURE(this) hb_no_trace_t<hb_void_t> trace HB_UNUSED #endif @@ -355,7 +367,7 @@ #define TRACE_COLLECT_GLYPHS(this) \ hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \ (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "") + " ") #else #define TRACE_COLLECT_GLYPHS(this) hb_no_trace_t<hb_void_t> trace HB_UNUSED #endif @@ -367,7 +379,7 @@ #define TRACE_SANITIZE(this) \ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \ (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - ""); + " "); #else #define TRACE_SANITIZE(this) hb_no_trace_t<bool> trace #endif @@ -379,11 +391,23 @@ #define TRACE_SERIALIZE(this) \ hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \ (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \ - ""); + " "); #else #define TRACE_SERIALIZE(this) hb_no_trace_t<bool> trace #endif +#ifndef HB_DEBUG_SUBSET +#define HB_DEBUG_SUBSET (HB_DEBUG+0) +#endif +#if HB_DEBUG_SUBSET +#define TRACE_SUBSET(this) \ + hb_auto_trace_t<HB_DEBUG_SUBSET, bool> trace \ + (&c->debug_depth, c->get_name (), this, HB_FUNC, \ + " "); +#else +#define TRACE_SUBSET(this) hb_no_trace_t<bool> trace +#endif + #ifndef HB_DEBUG_WOULD_APPLY #define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0) #endif @@ -403,6 +427,7 @@ HB_DEBUG_COLLECT_GLYPHS + \ HB_DEBUG_SANITIZE + \ HB_DEBUG_SERIALIZE + \ + HB_DEBUG_SUBSET + \ HB_DEBUG_WOULD_APPLY + \ 0) #endif
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-dsalgs.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-dsalgs.hh Wed May 30 12:20:00 2018 -0700 @@ -76,12 +76,8 @@ /* swap a, b iff a>b */ -#ifndef __SUNPRO_CC /* __restrict is same as restrict but better support on old machines */ static int sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w, -#else -static int sort_r_cmpswap(char *a, char *b, size_t w, -#endif int (*compar)(const void *_a, const void *_b, void *_arg), void *arg)
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.cc Wed May 30 12:20:00 2018 -0700 @@ -170,7 +170,7 @@ if (unlikely (!blob)) blob = hb_blob_get_empty (); - hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); + hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>().sanitize (hb_blob_reference (blob)), index); if (unlikely (!closure)) return hb_face_get_empty (); @@ -430,7 +430,7 @@ void hb_face_t::load_upem (void) const { - hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head)); + hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (reference_table (HB_OT_TAG_head)); const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob); upem = head_table->get_upem (); hb_blob_destroy (head_blob); @@ -474,7 +474,7 @@ void hb_face_t::load_num_glyphs (void) const { - hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp)); + hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (reference_table (HB_OT_TAG_maxp)); const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob); num_glyphs = maxp_table->get_num_glyphs (); hb_blob_destroy (maxp_blob);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.h Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-face.h Wed May 30 12:20:00 2018 -0700 @@ -71,7 +71,6 @@ hb_destroy_func_t destroy, hb_bool_t replace); - HB_EXTERN void * hb_face_get_user_data (hb_face_t *face, hb_user_data_key_t *key);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font-private.hh Wed May 30 12:20:00 2018 -0700 @@ -128,6 +128,8 @@ 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 float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); } + inline float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); } inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction) { return em_scale (v, dir_scale (direction)); } @@ -541,7 +543,11 @@ } inline hb_position_t em_scalef (float v, int scale) { - return (hb_position_t) (v * scale / face->get_upem ()); + return (hb_position_t) round (v * scale / face->get_upem ()); + } + inline float em_fscale (int16_t v, int scale) + { + return (float) v * scale / face->get_upem (); } };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.h Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-font.h Wed May 30 12:20:00 2018 -0700 @@ -456,7 +456,7 @@ /* high-level funcs, with fallback */ /* Calls either hb_font_get_nominal_glyph() if variation_selector is 0, - * otherwise callse hb_font_get_variation_glyph(). */ + * otherwise calls 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,
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ft.cc Wed May 30 12:20:00 2018 -0700 @@ -58,7 +58,7 @@ * * - In the future, we should add constructors to create fonts in font space? * - * - FT_Load_Glyph() is exteremely costly. Do something about it? + * - FT_Load_Glyph() is extremely costly. Do something about it? */ @@ -635,15 +635,27 @@ { if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, ft_coords)) { + bool nonzero = false; + for (unsigned int i = 0; i < mm_var->num_axis; ++i) + { coords[i] = ft_coords[i] >>= 2; + nonzero = nonzero || coords[i]; + } - hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis); + if (nonzero) + hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis); + else + hb_font_set_var_coords_normalized (font, nullptr, 0); } } free (coords); free (ft_coords); +#ifdef HAVE_FT_DONE_MM_VAR + FT_Done_MM_Var (ft_face->glyph->library, mm_var); +#else free (mm_var); +#endif } #endif } @@ -747,6 +759,7 @@ FT_Set_Transform (ft_face, &matrix, nullptr); } +#ifdef HAVE_FT_SET_VAR_BLEND_COORDINATES unsigned int num_coords; const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); if (num_coords) @@ -760,6 +773,7 @@ free (ft_coords); } } +#endif ft_face->generic.data = blob; ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-file-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-file-private.hh Wed May 30 12:20:00 2018 -0700 @@ -30,6 +30,7 @@ #define HB_OPEN_FILE_PRIVATE_HH #include "hb-open-type-private.hh" +#include "hb-ot-head-table.hh" namespace OT { @@ -54,7 +55,14 @@ typedef struct TableRecord { int cmp (Tag t) const - { return t.cmp (tag); } + { return -t.cmp (tag); } + + static int cmp (const void *pa, const void *pb) + { + const TableRecord *a = (const TableRecord *) pa; + const TableRecord *b = (const TableRecord *) pb; + return b->cmp (a->tag); + } inline bool sanitize (hb_sanitize_context_t *c) const { @@ -64,9 +72,9 @@ Tag tag; /* 4-byte identifier. */ CheckSum checkSum; /* CheckSum for this table. */ - ULONG offset; /* Offset from beginning of TrueType font + Offset32 offset; /* Offset from beginning of TrueType font * file. */ - ULONG length; /* Length of this table. */ + HBUINT32 length; /* Length of this table. */ public: DEFINE_SIZE_STATIC (16); } OpenTypeTable; @@ -81,7 +89,7 @@ { return tables[i]; } - inline unsigned int get_table_tags (unsigned int start_offset, + inline unsigned int get_table_tags (unsigned int start_offset, unsigned int *table_count, /* IN/OUT */ hb_tag_t *table_tags /* OUT */) const { @@ -118,6 +126,78 @@ } public: + + inline bool serialize (hb_serialize_context_t *c, + hb_tag_t sfnt_tag, + Supplier<hb_tag_t> &tags, + Supplier<hb_blob_t *> &blobs, + unsigned int table_count) + { + TRACE_SERIALIZE (this); + /* Alloc 12 for the OTHeader. */ + if (unlikely (!c->extend_min (*this))) return_trace (false); + /* Write sfntVersion (bytes 0..3). */ + sfnt_version.set (sfnt_tag); + /* Take space for numTables, searchRange, entrySelector, RangeShift + * and the TableRecords themselves. */ + if (unlikely (!tables.serialize (c, table_count))) return_trace (false); + + const char *dir_end = (const char *) c->head; + HBUINT32 *checksum_adjustment = nullptr; + + /* Write OffsetTables, alloc for and write actual table blobs. */ + for (unsigned int i = 0; i < table_count; i++) + { + TableRecord &rec = tables.array[i]; + hb_blob_t *blob = blobs[i]; + rec.tag.set (tags[i]); + rec.length.set (hb_blob_get_length (blob)); + rec.offset.serialize (c, this); + + /* Allocate room for the table and copy it. */ + char *start = (char *) c->allocate_size<void> (rec.length); + if (unlikely (!start)) {return false;} + + memcpy (start, hb_blob_get_data (blob, nullptr), rec.length); + + /* 4-byte allignment. */ + if (rec.length % 4) + c->allocate_size<void> (4 - rec.length % 4); + const char *end = (const char *) c->head; + + if (tags[i] == HB_OT_TAG_head && end - start >= head::static_size) + { + head *h = (head *) start; + checksum_adjustment = &h->checkSumAdjustment; + checksum_adjustment->set (0); + } + + rec.checkSum.set_for_data (start, end - start); + } + tags += table_count; + blobs += table_count; + + tables.qsort (); + + if (checksum_adjustment) + { + CheckSum checksum; + + /* The following line is a slower version of the following block. */ + //checksum.set_for_data (this, (const char *) c->head - (const char *) this); + checksum.set_for_data (this, dir_end - (const char *) this); + for (unsigned int i = 0; i < table_count; i++) + { + TableRecord &rec = tables.array[i]; + checksum.set (checksum + rec.checkSum); + } + + checksum_adjustment->set (0xB1B0AFBAu - checksum); + } + + return_trace (true); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -154,7 +234,7 @@ Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */ FixedVersion<>version; /* Version of the TTC Header (1.0), * 0x00010000u */ - ArrayOf<LOffsetTo<OffsetTable>, ULONG> + ArrayOf<LOffsetTo<OffsetTable>, HBUINT32> table; /* Array of offsets to the OffsetTable for each font * from the beginning of the file */ public: @@ -249,6 +329,18 @@ } } + inline bool serialize_single (hb_serialize_context_t *c, + hb_tag_t sfnt_tag, + Supplier<hb_tag_t> &tags, + Supplier<hb_blob_t *> &blobs, + unsigned int table_count) + { + TRACE_SERIALIZE (this); + assert (sfnt_tag != TTCTag); + if (unlikely (!c->extend_min (*this))) return_trace (false); + return_trace (u.fontFace.serialize (c, sfnt_tag, tags, blobs, table_count)); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh Wed May 30 12:20:00 2018 -0700 @@ -134,7 +134,17 @@ #define HB_NULL_POOL_SIZE 264 static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE."); -extern HB_INTERNAL const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)]; + +#ifdef HB_NO_VISIBILITY +static +#else +extern HB_INTERNAL +#endif +const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] +#ifdef HB_NO_VISIBILITY += {} +#endif +; /* Generic nul-content Null objects. */ template <typename Type> @@ -179,6 +189,12 @@ #ifndef HB_SANITIZE_MAX_EDITS #define HB_SANITIZE_MAX_EDITS 32 #endif +#ifndef HB_SANITIZE_MAX_OPS_FACTOR +#define HB_SANITIZE_MAX_OPS_FACTOR 8 +#endif +#ifndef HB_SANITIZE_MAX_OPS_MIN +#define HB_SANITIZE_MAX_OPS_MIN 16384 +#endif struct hb_sanitize_context_t : hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> @@ -186,8 +202,9 @@ inline hb_sanitize_context_t (void) : debug_depth (0), start (nullptr), end (nullptr), - writable (false), edit_count (0), - blob (nullptr) {} + writable (false), edit_count (0), max_ops (0), + blob (nullptr), + num_glyphs (0) {} inline const char *get_name (void) { return "SANITIZE"; } template <typename T, typename F> @@ -210,6 +227,8 @@ this->start = hb_blob_get_data (this->blob, nullptr); this->end = this->start + hb_blob_get_length (this->blob); assert (this->start <= this->end); /* Must not overflow. */ + this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR, + (unsigned) HB_SANITIZE_MAX_OPS_MIN); this->edit_count = 0; this->debug_depth = 0; @@ -233,7 +252,10 @@ inline bool check_range (const void *base, unsigned int len) const { const char *p = (const char *) base; - bool ok = this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len; + bool ok = this->max_ops-- > 0 && + this->start <= p && + p <= this->end && + (unsigned int) (this->end - p) >= len; DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0, "check_range [%p..%p] (%d bytes) in [%p..%p] -> %s", @@ -297,7 +319,9 @@ const char *start, *end; bool writable; unsigned int edit_count; + mutable int max_ops; hb_blob_t *blob; + unsigned int num_glyphs; }; @@ -306,8 +330,9 @@ template <typename Type> struct Sanitizer { - static hb_blob_t *sanitize (hb_blob_t *blob) { - hb_sanitize_context_t c[1]; + inline Sanitizer (void) {} + + inline hb_blob_t *sanitize (hb_blob_t *blob) { bool sane; /* TODO is_sane() stuff */ @@ -370,6 +395,11 @@ const char *base = hb_blob_get_data (blob, nullptr); return unlikely (!base) ? &Null(Type) : CastP<Type> (base); } + + inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; } + + private: + hb_sanitize_context_t c[1]; }; @@ -491,23 +521,25 @@ template <typename Type> struct Supplier { - inline Supplier (const Type *array, unsigned int len_) + inline Supplier (const Type *array, unsigned int len_, unsigned int stride_=sizeof(Type)) { head = array; len = len_; + stride = stride_; } inline const Type operator [] (unsigned int i) const { if (unlikely (i >= len)) return Type (); - return head[i]; + return * (const Type *) (const void *) ((const char *) head + stride * i); } - inline void advance (unsigned int count) + inline Supplier<Type> & operator += (unsigned int count) { if (unlikely (count > len)) count = len; len -= count; - head += count; + head = (const Type *) (const void *) ((const char *) head + stride * count); + return *this; } private: @@ -515,12 +547,11 @@ inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */ unsigned int len; + unsigned int stride; const Type *head; }; - - /* * * The OpenType Font File: Data Types @@ -635,23 +666,22 @@ DEFINE_SIZE_STATIC (Size); }; -typedef IntType<int8_t, 1> CHAR; /* 8-bit signed integer. */ -typedef IntType<uint8_t, 1> BYTE; /* 8-bit unsigned integer. */ -typedef IntType<int8_t, 1> INT8; /* 8-bit signed integer. */ -typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ -typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ -typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ -typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */ +typedef IntType<uint8_t, 1> HBUINT8; /* 8-bit unsigned integer. */ +typedef IntType<int8_t, 1> HBINT8; /* 8-bit signed integer. */ +typedef IntType<uint16_t, 2> HBUINT16; /* 16-bit unsigned integer. */ +typedef IntType<int16_t, 2> HBINT16; /* 16-bit signed integer. */ +typedef IntType<uint32_t, 4> HBUINT32; /* 32-bit unsigned integer. */ +typedef IntType<int32_t, 4> HBINT32; /* 32-bit signed integer. */ typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ -/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ -typedef SHORT FWORD; +/* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */ +typedef HBINT16 FWORD; -/* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ -typedef USHORT UFWORD; +/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */ +typedef HBUINT16 UFWORD; /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */ -struct F2DOT14 : SHORT +struct F2DOT14 : HBINT16 { //inline float to_float (void) const { return ???; } //inline void set_float (float f) { v.set (f * ???); } @@ -660,10 +690,10 @@ }; /* 32-bit signed fixed-point number (16.16). */ -struct Fixed: LONG +struct Fixed: HBINT32 { - //inline float to_float (void) const { return ???; } - //inline void set_float (float f) { v.set (f * ???); } + inline float to_float (void) const { return ((int32_t) v) / 65536.0; } + inline void set_float (float f) { v.set (round (f * 65536.0)); } public: DEFINE_SIZE_STATIC (4); }; @@ -678,15 +708,15 @@ return_trace (likely (c->check_struct (this))); } protected: - LONG major; - ULONG minor; + HBINT32 major; + HBUINT32 minor; public: DEFINE_SIZE_STATIC (8); }; /* Array of four uint8s (length = 32 bits) used to identify a script, language * system, feature, or baseline */ -struct Tag : ULONG +struct Tag : HBUINT32 { /* What the char* converters return is NOT nul-terminated. Print using "%.4s" */ inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); } @@ -697,32 +727,44 @@ DEFINE_NULL_DATA (Tag, " "); /* Glyph index number, same as uint16 (length = 16 bits) */ -typedef USHORT GlyphID; +typedef HBUINT16 GlyphID; /* Script/language-system/feature index */ -struct Index : USHORT { +struct Index : HBUINT16 { static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; }; DEFINE_NULL_DATA (Index, "\xff\xff"); /* Offset, Null offset = 0 */ -template <typename Type=USHORT> +template <typename Type> struct Offset : Type { inline bool is_null (void) const { return 0 == *this; } + + inline void *serialize (hb_serialize_context_t *c, const void *base) + { + void *t = c->start_embed<void> (); + this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ + return t; + } + public: DEFINE_SIZE_STATIC (sizeof(Type)); }; +typedef Offset<HBUINT16> Offset16; +typedef Offset<HBUINT32> Offset32; + /* CheckSum */ -struct CheckSum : ULONG +struct CheckSum : HBUINT32 { /* This is reference implementation from the spec. */ - static inline uint32_t CalcTableChecksum (const ULONG *Table, uint32_t Length) + static inline uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length) { uint32_t Sum = 0L; - const ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size; + assert (0 == (Length & 3)); + const HBUINT32 *EndPtr = Table + Length / HBUINT32::static_size; while (Table < EndPtr) Sum += *Table++; @@ -731,7 +773,7 @@ /* Note: data should be 4byte aligned and have 4byte padding at the end. */ inline void set_for_data (const void *data, unsigned int length) - { set (CalcTableChecksum ((const ULONG *) data, length)); } + { set (CalcTableChecksum ((const HBUINT32 *) data, length)); } public: DEFINE_SIZE_STATIC (4); @@ -742,7 +784,7 @@ * Version Numbers */ -template <typename FixedType=USHORT> +template <typename FixedType=HBUINT16> struct FixedVersion { inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; } @@ -766,7 +808,7 @@ * Use: (base+offset) */ -template <typename Type, typename OffsetType=USHORT> +template <typename Type, typename OffsetType=HBUINT16> struct OffsetTo : Offset<OffsetType> { inline const Type& operator () (const void *base) const @@ -778,9 +820,7 @@ inline Type& serialize (hb_serialize_context_t *c, const void *base) { - Type *t = c->start_embed<Type> (); - this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ - return *t; + return * (Type *) Offset<OffsetType>::serialize (c, base); } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -811,7 +851,7 @@ } DEFINE_SIZE_STATIC (sizeof(OffsetType)); }; -template <typename Type> struct LOffsetTo : OffsetTo<Type, ULONG> {}; +template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {}; template <typename Base, typename OffsetType, typename Type> static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); } template <typename Base, typename OffsetType, typename Type> @@ -823,7 +863,7 @@ */ /* An array with a number of elements. */ -template <typename Type, typename LenType=USHORT> +template <typename Type, typename LenType=HBUINT16> struct ArrayOf { const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const @@ -868,7 +908,7 @@ if (unlikely (!serialize (c, items_len))) return_trace (false); for (unsigned int i = 0; i < items_len; i++) array[i] = items[i]; - items.advance (items_len); + items += items_len; return_trace (true); } @@ -920,6 +960,11 @@ return -1; } + inline void qsort (void) + { + ::qsort (array, len, sizeof (Type), Type::cmp); + } + private: inline bool sanitize_shallow (hb_sanitize_context_t *c) const { @@ -933,10 +978,10 @@ public: DEFINE_SIZE_ARRAY (sizeof (LenType), array); }; -template <typename Type> struct LArrayOf : ArrayOf<Type, ULONG> {}; +template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {}; /* Array of Offset's */ -template <typename Type, typename OffsetType=USHORT> +template <typename Type, typename OffsetType=HBUINT16> struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {}; /* Array of offsets relative to the beginning of the array itself. */ @@ -964,7 +1009,7 @@ /* An array starting at second element. */ -template <typename Type, typename LenType=USHORT> +template <typename Type, typename LenType=HBUINT16> struct HeadlessArrayOf { inline const Type& operator [] (unsigned int i) const @@ -986,7 +1031,7 @@ if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items_len - 1; i++) array[i] = items[i]; - items.advance (items_len - 1); + items += items_len - 1; return_trace (true); } @@ -1026,19 +1071,19 @@ /* * An array with sorted elements. Supports binary searching. */ -template <typename Type, typename LenType=USHORT> +template <typename Type, typename LenType=HBUINT16> struct SortedArrayOf : ArrayOf<Type, LenType> { template <typename SearchType> inline int bsearch (const SearchType &x) const { /* Hand-coded bsearch here since this is in the hot inner loop. */ - const Type *array = this->array; + const Type *arr = this->array; int min = 0, max = (int) this->len - 1; while (min <= max) { int mid = (min + max) / 2; - int c = array[mid].cmp (x); + int c = arr[mid].cmp (x); if (c < 0) max = mid - 1; else if (c > 0) @@ -1064,11 +1109,22 @@ return_trace (c->check_struct (this)); } + inline void set (unsigned int v) + { + len.set (v); + assert (len == v); + entrySelectorZ.set (MAX (1u, _hb_bit_storage (v)) - 1); + searchRangeZ.set (16 * (1u << entrySelectorZ)); + rangeShiftZ.set (v * 16 > searchRangeZ + ? 16 * v - searchRangeZ + : 0); + } + protected: - USHORT len; - USHORT searchRangeZ; - USHORT entrySelectorZ; - USHORT rangeShiftZ; + HBUINT16 len; + HBUINT16 searchRangeZ; + HBUINT16 entrySelectorZ; + HBUINT16 rangeShiftZ; public: DEFINE_SIZE_STATIC (8); @@ -1137,8 +1193,8 @@ inline void init (hb_face_t *face_) { face = face_; + blob = nullptr; instance = nullptr; - blob = nullptr; } inline void fini (void) @@ -1152,7 +1208,7 @@ T *p = (T *) hb_atomic_ptr_get (&instance); if (unlikely (!p)) { - hb_blob_t *blob_ = OT::Sanitizer<T>::sanitize (face->reference_table (T::tableTag)); + hb_blob_t *blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag)); p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_)); if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)) { @@ -1169,10 +1225,10 @@ return get(); } + hb_face_t *face; + mutable hb_blob_t *blob; private: - hb_face_t *face; - T *instance; - mutable hb_blob_t *blob; + mutable T *instance; };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cbdt-table.hh Wed May 30 08:10:41 2018 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,384 +0,0 @@ -/* - * 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 <typename OffsetType> -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<OffsetType> offsetArrayZ[VAR]; - - DEFINE_SIZE_ARRAY(8, offsetArrayZ); -}; - -struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<ULONG> {}; -struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<USHORT> {}; - -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; - LOffsetTo<IndexSubtable> 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 nullptr; - } - - 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: - LOffsetTo<IndexSubtableArray> 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 nullptr; - } - - protected: - FixedVersion<> version; - LArrayOf<BitmapSizeTable> 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 */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh Wed May 30 12:20:00 2018 -0700 @@ -28,7 +28,7 @@ #define HB_OT_CMAP_TABLE_HH #include "hb-open-type-private.hh" - +#include "hb-subset-plan.hh" namespace OT { @@ -58,10 +58,10 @@ } protected: - USHORT format; /* Format number is set to 0. */ - USHORT lengthZ; /* Byte length of this subtable. */ - USHORT languageZ; /* Ignore. */ - BYTE glyphIdArray[256];/* An array that maps character + HBUINT16 format; /* Format number is set to 0. */ + HBUINT16 lengthZ; /* Byte length of this subtable. */ + HBUINT16 languageZ; /* Ignore. */ + HBUINT8 glyphIdArray[256];/* An array that maps character * code to glyph index values. */ public: DEFINE_SIZE_STATIC (6 + 256); @@ -88,8 +88,8 @@ /* Custom two-array bsearch. */ int min = 0, max = (int) thiz->segCount - 1; - const USHORT *startCount = thiz->startCount; - const USHORT *endCount = thiz->endCount; + const HBUINT16 *startCount = thiz->startCount; + const HBUINT16 *endCount = thiz->endCount; unsigned int i; while (min <= max) { @@ -127,11 +127,11 @@ return true; } - const USHORT *endCount; - const USHORT *startCount; - const USHORT *idDelta; - const USHORT *idRangeOffset; - const USHORT *glyphIdArray; + const HBUINT16 *endCount; + const HBUINT16 *startCount; + const HBUINT16 *idDelta; + const HBUINT16 *idRangeOffset; + const HBUINT16 *glyphIdArray; unsigned int segCount; unsigned int glyphIdArrayLength; }; @@ -165,24 +165,24 @@ } protected: - USHORT format; /* Format number is set to 4. */ - USHORT length; /* This is the length in bytes of the + HBUINT16 format; /* Format number is set to 4. */ + HBUINT16 length; /* This is the length in bytes of the * subtable. */ - USHORT languageZ; /* Ignore. */ - USHORT segCountX2; /* 2 x segCount. */ - USHORT searchRangeZ; /* 2 * (2**floor(log2(segCount))) */ - USHORT entrySelectorZ; /* log2(searchRange/2) */ - USHORT rangeShiftZ; /* 2 x segCount - searchRange */ + HBUINT16 languageZ; /* Ignore. */ + HBUINT16 segCountX2; /* 2 x segCount. */ + HBUINT16 searchRangeZ; /* 2 * (2**floor(log2(segCount))) */ + HBUINT16 entrySelectorZ; /* log2(searchRange/2) */ + HBUINT16 rangeShiftZ; /* 2 x segCount - searchRange */ - USHORT values[VAR]; + HBUINT16 values[VAR]; #if 0 - USHORT endCount[segCount]; /* End characterCode for each segment, + HBUINT16 endCount[segCount]; /* End characterCode for each segment, * last=0xFFFFu. */ - USHORT reservedPad; /* Set to 0. */ - USHORT startCount[segCount]; /* Start character code for each segment. */ - SHORT idDelta[segCount]; /* Delta for all character codes in segment. */ - USHORT idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ - USHORT glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ + HBUINT16 reservedPad; /* Set to 0. */ + HBUINT16 startCount[segCount]; /* Start character code for each segment. */ + HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */ + HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */ + HBUINT16 glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */ #endif public: @@ -193,6 +193,7 @@ { friend struct CmapSubtableFormat12; friend struct CmapSubtableFormat13; + friend struct cmap; int cmp (hb_codepoint_t codepoint) const { @@ -208,9 +209,9 @@ } private: - ULONG startCharCode; /* First character code in this group. */ - ULONG endCharCode; /* Last character code in this group. */ - ULONG glyphID; /* Glyph index; interpretation depends on + HBUINT32 startCharCode; /* First character code in this group. */ + HBUINT32 endCharCode; /* Last character code in this group. */ + HBUINT32 glyphID; /* Glyph index; interpretation depends on * subtable format. */ public: DEFINE_SIZE_STATIC (12); @@ -247,12 +248,14 @@ DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray); }; -struct CmapSubtableFormat6 : CmapSubtableTrimmed<USHORT> {}; -struct CmapSubtableFormat10 : CmapSubtableTrimmed<ULONG > {}; +struct CmapSubtableFormat6 : CmapSubtableTrimmed<HBUINT16> {}; +struct CmapSubtableFormat10 : CmapSubtableTrimmed<HBUINT32 > {}; template <typename T> struct CmapSubtableLongSegmented { + friend struct cmap; + inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const { int i = groups.bsearch (codepoint); @@ -268,12 +271,22 @@ return_trace (c->check_struct (this) && groups.sanitize (c)); } + inline bool serialize (hb_serialize_context_t *c, + hb_prealloced_array_t<CmapSubtableLongGroup> &group_data) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (*this))) return_trace (false); + Supplier<CmapSubtableLongGroup> supplier (group_data.array, group_data.len); + if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false); + return true; + } + protected: - USHORT format; /* Subtable format; set to 12. */ - USHORT reservedZ; /* Reserved; set to 0. */ - ULONG lengthZ; /* Byte length of this subtable. */ - ULONG languageZ; /* Ignore. */ - SortedArrayOf<CmapSubtableLongGroup, ULONG> + HBUINT16 format; /* Subtable format; set to 12. */ + HBUINT16 reservedZ; /* Reserved; set to 0. */ + HBUINT32 lengthZ; /* Byte length of this subtable. */ + HBUINT32 languageZ; /* Ignore. */ + SortedArrayOf<CmapSubtableLongGroup, HBUINT32> groups; /* Groupings. */ public: DEFINE_SIZE_ARRAY (16, groups); @@ -316,13 +329,13 @@ } UINT24 startUnicodeValue; /* First value in this range. */ - BYTE additionalCount; /* Number of additional values in this + HBUINT8 additionalCount; /* Number of additional values in this * range. */ public: DEFINE_SIZE_STATIC (4); }; -typedef SortedArrayOf<UnicodeValueRange, ULONG> DefaultUVS; +typedef SortedArrayOf<UnicodeValueRange, HBUINT32> DefaultUVS; struct UVSMapping { @@ -343,7 +356,7 @@ DEFINE_SIZE_STATIC (5); }; -typedef SortedArrayOf<UVSMapping, ULONG> NonDefaultUVS; +typedef SortedArrayOf<UVSMapping, HBUINT32> NonDefaultUVS; struct VariationSelectorRecord { @@ -405,9 +418,9 @@ } protected: - USHORT format; /* Format number is set to 14. */ - ULONG lengthZ; /* Byte length of this subtable. */ - SortedArrayOf<VariationSelectorRecord, ULONG> + HBUINT16 format; /* Format number is set to 14. */ + HBUINT32 lengthZ; /* Byte length of this subtable. */ + SortedArrayOf<VariationSelectorRecord, HBUINT32> record; /* Variation selector records; sorted * in increasing order of `varSelector'. */ public: @@ -422,12 +435,12 @@ hb_codepoint_t *glyph) const { switch (u.format) { - case 0: return u.format0 .get_glyph(codepoint, glyph); - case 4: return u.format4 .get_glyph(codepoint, glyph); - case 6: return u.format6 .get_glyph(codepoint, glyph); - case 10: return u.format10.get_glyph(codepoint, glyph); - case 12: return u.format12.get_glyph(codepoint, glyph); - case 13: return u.format13.get_glyph(codepoint, glyph); + case 0: return u.format0 .get_glyph (codepoint, glyph); + case 4: return u.format4 .get_glyph (codepoint, glyph); + case 6: return u.format6 .get_glyph (codepoint, glyph); + case 10: return u.format10.get_glyph (codepoint, glyph); + case 12: return u.format12.get_glyph (codepoint, glyph); + case 13: return u.format13.get_glyph (codepoint, glyph); case 14: default: return false; } @@ -451,7 +464,7 @@ public: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ CmapSubtableFormat0 format0; CmapSubtableFormat4 format4; CmapSubtableFormat6 format6; @@ -484,8 +497,8 @@ subtable.sanitize (c, base)); } - USHORT platformID; /* Platform ID. */ - USHORT encodingID; /* Platform-specific encoding ID. */ + HBUINT16 platformID; /* Platform ID. */ + HBUINT16 encodingID; /* Platform-specific encoding ID. */ LOffsetTo<CmapSubtable> subtable; /* Byte offset from beginning of table to the subtable for this encoding. */ public: @@ -496,6 +509,254 @@ { static const hb_tag_t tableTag = HB_OT_TAG_cmap; + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version == 0) && + encodingRecord.sanitize (c, this)); + } + + inline bool populate_groups (hb_subset_plan_t *plan, + hb_prealloced_array_t<CmapSubtableLongGroup> *groups) const + { + CmapSubtableLongGroup *group = nullptr; + for (unsigned int i = 0; i < plan->codepoints.len; i++) { + + hb_codepoint_t cp = plan->codepoints[i]; + if (!group || cp - 1 != group->endCharCode) + { + group = groups->push (); + group->startCharCode.set (cp); + group->endCharCode.set (cp); + hb_codepoint_t new_gid; + if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, cp, &new_gid))) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp); + return false; + } + group->glyphID.set (new_gid); + } else + { + group->endCharCode.set (cp); + } + } + + DEBUG_MSG(SUBSET, nullptr, "cmap"); + for (unsigned int i = 0; i < groups->len; i++) { + CmapSubtableLongGroup& group = (*groups)[i]; + DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode)); + } + + return true; + } + + inline bool _subset (hb_prealloced_array_t<CmapSubtableLongGroup> &groups, + size_t dest_sz, + void *dest) const + { + hb_serialize_context_t c (dest, dest_sz); + + OT::cmap *cmap = c.start_serialize<OT::cmap> (); + if (unlikely (!c.extend_min (*cmap))) + { + return false; + } + + cmap->version.set (0); + + if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 1))) return false; + + EncodingRecord &rec = cmap->encodingRecord[0]; + rec.platformID.set (3); // Windows + rec.encodingID.set (10); // Unicode UCS-4 + + /* capture offset to subtable */ + CmapSubtable &subtable = rec.subtable.serialize (&c, cmap); + + subtable.u.format.set (12); + + CmapSubtableFormat12 &format12 = subtable.u.format12; + if (unlikely (!c.extend_min (format12))) return false; + + format12.format.set (12); + format12.reservedZ.set (0); + format12.lengthZ.set (16 + 12 * groups.len); + + if (unlikely (!format12.serialize (&c, groups))) return false; + + c.end_serialize (); + + return true; + } + + inline bool subset (hb_subset_plan_t *plan) const + { + hb_auto_array_t<CmapSubtableLongGroup> groups; + + if (unlikely (!populate_groups (plan, &groups))) return false; + + // We now know how big our blob needs to be + // TODO use APIs from the structs to get size? + size_t dest_sz = 4 // header + + 8 // 1 EncodingRecord + + 16 // Format 12 header + + 12 * groups.len; // SequentialMapGroup records + void *dest = malloc (dest_sz); + if (unlikely (!dest)) { + DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz); + return false; + } + + if (unlikely (!_subset (groups, dest_sz, dest))) + { + free (dest); + return false; + } + + // all done, write the blob into dest + hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest, + dest_sz, + HB_MEMORY_MODE_READONLY, + dest, + free); + bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_cmap, cmap_prime); + hb_blob_destroy (cmap_prime); + return result; + } + + struct accelerator_t + { + inline void init (hb_face_t *face) + { + this->blob = OT::Sanitizer<OT::cmap>().sanitize (face->reference_table (HB_OT_TAG_cmap)); + const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); + const OT::CmapSubtable *subtable = nullptr; + const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; + + bool symbol = false; + /* 32-bit subtables. */ + if (!subtable) subtable = cmap->find_subtable (3, 10); + if (!subtable) subtable = cmap->find_subtable (0, 6); + if (!subtable) subtable = cmap->find_subtable (0, 4); + /* 16-bit subtables. */ + if (!subtable) subtable = cmap->find_subtable (3, 1); + if (!subtable) subtable = cmap->find_subtable (0, 3); + 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) symbol = true; + } + /* Meh. */ + if (!subtable) subtable = &OT::Null(OT::CmapSubtable); + + /* UVS subtable. */ + 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::CmapSubtableFormat14); + + this->uvs_table = subtable_uvs; + + this->get_glyph_data = subtable; + if (unlikely (symbol)) + this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>; + else + switch (subtable->u.format) { + /* Accelerate format 4 and format 12. */ + default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break; + case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; 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) + { + hb_blob_destroy (this->blob); + } + + inline bool get_nominal_glyph (hb_codepoint_t unicode, + hb_codepoint_t *glyph) const + { + 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)) + { + case OT::GLYPH_VARIANT_NOT_FOUND: return false; + case OT::GLYPH_VARIANT_FOUND: return true; + case OT::GLYPH_VARIANT_USE_DEFAULT: break; + } + + return get_nominal_glyph (unicode, glyph); + } + + protected: + typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, + hb_codepoint_t codepoint, + hb_codepoint_t *glyph); + + template <typename Type> + 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 <typename Type> + 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; + } + + private: + 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; + }; + + protected: + inline const CmapSubtable *find_subtable (unsigned int platform_id, unsigned int encoding_id) const { @@ -513,15 +774,8 @@ return &(this+encodingRecord[result].subtable); } - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version == 0) && - encodingRecord.sanitize (c, this)); - } - - USHORT version; /* Table version number (0). */ + protected: + HBUINT16 version; /* Table version number (0). */ SortedArrayOf<EncodingRecord> encodingRecord; /* Encoding tables. */ public:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-cbdt-table.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,471 @@ +/* + * 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_COLOR_CBDT_TABLE_HH +#define HB_OT_COLOR_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; + } + + HBUINT8 height; + HBUINT8 width; + HBINT8 bearingX; + HBINT8 bearingY; + HBUINT8 advance; + + DEFINE_SIZE_STATIC(5); +}; + +struct BigGlyphMetrics : SmallGlyphMetrics +{ + HBINT8 vertBearingX; + HBINT8 vertBearingY; + HBUINT8 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)); + } + + HBINT8 ascender; + HBINT8 decender; + HBUINT8 widthMax; + HBINT8 caretSlopeNumerator; + HBINT8 caretSlopeDenominator; + HBINT8 caretOffset; + HBINT8 minOriginSB; + HBINT8 minAdvanceSB; + HBINT8 maxBeforeBL; + HBINT8 minAfterBL; + HBINT8 padding1; + HBINT8 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)); + } + + HBUINT16 indexFormat; + HBUINT16 imageFormat; + HBUINT32 imageDataOffset; + + DEFINE_SIZE_STATIC(8); +}; + +template <typename OffsetType> +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<OffsetType> offsetArrayZ[VAR]; + + DEFINE_SIZE_ARRAY(8, offsetArrayZ); +}; + +struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {}; +struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<HBUINT16> {}; + +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); + } + + HBUINT16 firstGlyphIndex; + HBUINT16 lastGlyphIndex; + LOffsetTo<IndexSubtable> 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 nullptr; + } + + 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: + LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset; + HBUINT32 indexTablesSize; + HBUINT32 numberOfIndexSubtables; + HBUINT32 colorRef; + SBitLineMetrics horizontal; + SBitLineMetrics vertical; + HBUINT16 startGlyphIndex; + HBUINT16 endGlyphIndex; + HBUINT8 ppemX; + HBUINT8 ppemY; + HBUINT8 bitDepth; + HBINT8 flags; + + public: + DEFINE_SIZE_STATIC(48); +}; + + +/* + * Glyph Bitmap Data Formats. + */ + +struct GlyphBitmapDataFormat17 +{ + SmallGlyphMetrics glyphMetrics; + HBUINT32 dataLen; + HBUINT8 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 +{ + friend struct CBDT; + + 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)); + } + + protected: + 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 nullptr; + } + + protected: + FixedVersion<> version; + LArrayOf<BitmapSizeTable> 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)); + } + + struct accelerator_t + { + inline void init (hb_face_t *face) + { + upem = hb_face_get_upem (face); + + cblc_blob = Sanitizer<CBLC>().sanitize (face->reference_table (HB_OT_TAG_CBLC)); + cbdt_blob = Sanitizer<CBDT>().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 = nullptr; + cbdt = nullptr; + return; /* Not a bitmap font. */ + } + cblc = Sanitizer<CBLC>::lock_instance (cblc_blob); + cbdt = Sanitizer<CBDT>::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) + return false; // Not a color bitmap font. + + const IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); + if (!subtable_record || !x_ppem || !y_ppem) + 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; + + { + if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length)) + return false; + + switch (image_format) + { + case 17: { + if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) + return false; + + const GlyphBitmapDataFormat17& glyphFormat17 = + StructAtOffset<GlyphBitmapDataFormat17> (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; + } + + private: + hb_blob_t *cblc_blob; + hb_blob_t *cbdt_blob; + const CBLC *cblc; + const CBDT *cbdt; + + unsigned int cbdt_len; + unsigned int upem; + }; + + + protected: + FixedVersion<>version; + HBUINT8 dataZ[VAR]; + + public: + DEFINE_SIZE_ARRAY(4, dataZ); +}; + +} /* namespace OT */ + +#endif /* HB_OT_COLOR_CBDT_TABLE_HH */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-colr-table.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,142 @@ +/* + * Copyright © 2018 Ebrahim Byagowi + * + * 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. + */ + +#ifndef HB_OT_COLOR_COLR_TABLE_HH +#define HB_OT_COLOR_COLR_TABLE_HH + +#include "hb-open-type-private.hh" + +/* + * Color Palette + * http://www.microsoft.com/typography/otspec/colr.htm + */ + +#define HB_OT_TAG_COLR HB_TAG('C','O','L','R') + +namespace OT { + + +struct LayerRecord +{ + friend struct COLR; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + GlyphID gID; /* Glyph ID of layer glyph */ + HBUINT16 paletteIndex; /* Index value to use with a selected color palette */ + public: + DEFINE_SIZE_STATIC (4); +}; + +struct BaseGlyphRecord +{ + friend struct COLR; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + GlyphID gID; /* Glyph ID of reference glyph */ + HBUINT16 firstLayerIndex; /* Index to the layer record */ + HBUINT16 numLayers; /* Number of color layers associated with this glyph */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct COLR +{ + static const hb_tag_t tableTag = HB_OT_TAG_COLR; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!(c->check_struct (this) && + c->check_array ((const void*) &layerRecordsOffsetZ, sizeof (LayerRecord), numLayerRecords) && + c->check_array ((const void*) &baseGlyphRecordsZ, sizeof (BaseGlyphRecord), numBaseGlyphRecords))) + return_trace (false); + + const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this); + for (unsigned int i = 0; i < numBaseGlyphRecords; ++i) + if (base_glyph_records[i].firstLayerIndex + + base_glyph_records[i].numLayers > numLayerRecords) + return_trace (false); + + return_trace (true); + } + + inline bool get_base_glyph_record ( + hb_codepoint_t glyph_id, unsigned int &first_layer, unsigned int &num_layers) const + { + const BaseGlyphRecord* base_glyph_records = &baseGlyphRecordsZ (this); + unsigned int min = 0, max = numBaseGlyphRecords - 1; + while (min <= max) + { + unsigned int mid = (min + max) / 2; + hb_codepoint_t gID = base_glyph_records[mid].gID; + if (gID > glyph_id) + max = mid - 1; + else if (gID < glyph_id) + min = mid + 1; + else + { + first_layer = base_glyph_records[mid].firstLayerIndex; + num_layers = base_glyph_records[mid].numLayers; + return true; + } + } + return false; + } + + inline void get_layer_record (int layer, + hb_codepoint_t &glyph_id, unsigned int &palette_index) const + { + const LayerRecord* records = &layerRecordsOffsetZ (this); + glyph_id = records[layer].gID; + palette_index = records[layer].paletteIndex; + } + + protected: + HBUINT16 version; /* Table version number */ + HBUINT16 numBaseGlyphRecords; /* Number of Base Glyph Records */ + LOffsetTo<BaseGlyphRecord> + baseGlyphRecordsZ; /* Offset to Base Glyph records. */ + LOffsetTo<LayerRecord> + layerRecordsOffsetZ; /* Offset to Layer Records */ + HBUINT16 numLayerRecords; /* Number of Layer Records */ + public: + DEFINE_SIZE_STATIC (14); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_COLOR_COLR_TABLE_HH */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-color-cpal-table.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,208 @@ +/* + * Copyright © 2016 Google, Inc. + * Copyright © 2018 Ebrahim Byagowi + * + * 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): Sascha Brawer + */ + +#ifndef HB_OT_COLOR_CPAL_TABLE_HH +#define HB_OT_COLOR_CPAL_TABLE_HH + +#include "hb-open-type-private.hh" + + +/* + * Following parts to be moved to a public header. + */ + +/** + * hb_ot_color_t: + * ARGB data type for holding color values. + * + * Since: REPLACEME + */ +typedef uint32_t hb_ot_color_t; + + +/** + * hb_ot_color_palette_flags_t: + * @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special to note about a color palette. + * @HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND: flag indicating that the color palette is suitable for rendering text on light background. + * @HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND: flag indicating that the color palette is suitable for rendering text on dark background. + * + * Since: REPLACEME + */ +typedef enum { /*< flags >*/ + HB_OT_COLOR_PALETTE_FLAG_DEFAULT = 0x00000000u, + HB_OT_COLOR_PALETTE_FLAG_FOR_LIGHT_BACKGROUND = 0x00000001u, + HB_OT_COLOR_PALETTE_FLAG_FOR_DARK_BACKGROUND = 0x00000002u, +} hb_ot_color_palette_flags_t; + +// HB_EXTERN unsigned int +// hb_ot_color_get_palette_count (hb_face_t *face); + +// HB_EXTERN unsigned int +// hb_ot_color_get_palette_name_id (hb_face_t *face, unsigned int palette); + +// HB_EXTERN hb_ot_color_palette_flags_t +// hb_ot_color_get_palette_flags (hb_face_t *face, unsigned int palette); + +// HB_EXTERN unsigned int +// hb_ot_color_get_palette_colors (hb_face_t *face, +// unsigned int palette, /* default=0 */ +// unsigned int start_offset, +// unsigned int *color_count /* IN/OUT */, +// hb_ot_color_t *colors /* OUT */); + + + + + +/* + * Color Palette + * http://www.microsoft.com/typography/otspec/cpal.htm + */ + +#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L') + +namespace OT { + + +struct CPALV1Tail +{ + friend struct CPAL; + + inline bool sanitize (hb_sanitize_context_t *c, unsigned int palettes) const + { + TRACE_SANITIZE (this); + return_trace ( + c->check_struct (this) && + c->check_array ((const void*) &paletteFlags, sizeof (HBUINT32), palettes) && + c->check_array ((const void*) &paletteLabel, sizeof (HBUINT16), palettes) && + c->check_array ((const void*) &paletteEntryLabel, sizeof (HBUINT16), palettes)); + } + + private: + inline hb_ot_color_palette_flags_t + get_palette_flags (const void *base, unsigned int palette) const + { + const HBUINT32* flags = &paletteFlags (base); + return (hb_ot_color_palette_flags_t) (uint32_t) flags[palette]; + } + + inline unsigned int + get_palette_name_id (const void *base, unsigned int palette) const + { + const HBUINT16* name_ids = &paletteLabel (base); + return name_ids[palette]; + } + + protected: + LOffsetTo<HBUINT32> paletteFlags; + LOffsetTo<HBUINT16> paletteLabel; + LOffsetTo<HBUINT16> paletteEntryLabel; + public: + DEFINE_SIZE_STATIC (12); +}; + +typedef HBUINT32 BGRAColor; + +struct CPAL +{ + static const hb_tag_t tableTag = HB_OT_TAG_CPAL; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!(c->check_struct (this) && // This checks colorRecordIndicesX sanity also, see #get_size + c->check_array ((const void*) &colorRecordsZ, sizeof (BGRAColor), numColorRecords))) + return_trace (false); + + // Check for indices sanity so no need for doing it runtime + for (unsigned int i = 0; i < numPalettes; ++i) + if (colorRecordIndicesX[i] + numPaletteEntries > numColorRecords) + return_trace (false); + + // If version is zero, we are done here; otherwise we need to check tail also + if (version == 0) + return_trace (true); + + const CPALV1Tail &v1 = StructAfter<CPALV1Tail> (*this); + return_trace (v1.sanitize (c, numPalettes)); + } + + inline unsigned int get_size (void) const + { + return min_size + numPalettes * sizeof (HBUINT16); + } + + inline hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette) const + { + if (version == 0 || palette >= numPalettes) + return HB_OT_COLOR_PALETTE_FLAG_DEFAULT; + + const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this); + return cpal1.get_palette_flags (this, palette); + } + + inline unsigned int get_palette_name_id (unsigned int palette) const + { + if (version == 0 || palette >= numPalettes) + return 0xFFFF; + + const CPALV1Tail& cpal1 = StructAfter<CPALV1Tail> (*this); + return cpal1.get_palette_name_id (this, palette); + } + + inline unsigned int get_palette_count () const + { + return numPalettes; + } + + inline hb_ot_color_t get_color_record_argb (unsigned int color_index, unsigned int palette) const + { + if (color_index >= numPaletteEntries || palette >= numPalettes) + return 0; + + const BGRAColor* records = &colorRecordsZ(this); + // No need for more range check as it is already done on #sanitize + return records[colorRecordIndicesX[palette] + color_index]; + } + + protected: + HBUINT16 version; + /* Version 0 */ + HBUINT16 numPaletteEntries; + HBUINT16 numPalettes; + HBUINT16 numColorRecords; + LOffsetTo<HBUINT32> colorRecordsZ; + HBUINT16 colorRecordIndicesX[VAR]; // VAR=numPalettes +/*CPALV1Tail v1[VAR];*/ + public: + DEFINE_SIZE_ARRAY (12, colorRecordIndicesX); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_COLOR_CPAL_TABLE_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-font.cc Wed May 30 12:20:00 2018 -0700 @@ -31,468 +31,23 @@ #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-kern-table.hh" -#include "hb-ot-os2-table.hh" #include "hb-ot-post-table.hh" -#include "hb-ot-var-hvar-table.hh" - - -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::hmtxvmtx *table; - hb_blob_t *blob; - - const OT::HVARVVAR *var; - hb_blob_t *var_blob; - - inline void init (hb_face_t *face, - hb_tag_t _hea_tag, - hb_tag_t _mtx_tag, - hb_tag_t _var_tag, - hb_tag_t os2_tag, - unsigned int default_advance = 0) - { - 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<OT::os2>::sanitize (face->reference_table (os2_tag)); - const OT::os2 *os2 = OT::Sanitizer<OT::os2>::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<OT::_hea>::sanitize (face->reference_table (_hea_tag)); - const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::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<OT::hmtxvmtx>::sanitize (face->reference_table (_mtx_tag)); - - /* 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); - this->blob = hb_blob_get_empty (); - } - this->table = OT::Sanitizer<OT::hmtxvmtx>::lock_instance (this->blob); - - this->var_blob = OT::Sanitizer<OT::HVARVVAR>::sanitize (face->reference_table (_var_tag)); - this->var = OT::Sanitizer<OT::HVARVVAR>::lock_instance (this->var_blob); - } - - inline void fini (void) - { - hb_blob_destroy (this->blob); - hb_blob_destroy (this->var_blob); - } - - inline unsigned int get_advance (hb_codepoint_t glyph, - hb_font_t *font) const - { - if (unlikely (glyph >= this->num_metrics)) - { - /* If this->num_metrics is zero, it means we don't have the metrics table - * for this direction: return default advance. Otherwise, it means that the - * glyph index is out of bound: return zero. */ - if (this->num_metrics) - return 0; - else - return this->default_advance; - } - - return this->table->longMetric[MIN (glyph, (uint32_t) this->num_advances - 1)].advance - + this->var->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?! - } -}; - -struct hb_ot_face_glyf_accelerator_t -{ - bool short_offset; - unsigned int num_glyphs; - const OT::loca *loca; - const OT::glyf *glyf; - hb_blob_t *loca_blob; - hb_blob_t *glyf_blob; - unsigned int glyf_len; - - inline void init (hb_face_t *face) - { - hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (face->reference_table (HB_OT_TAG_head)); - const OT::head *head = OT::Sanitizer<OT::head>::lock_instance (head_blob); - if ((unsigned int) head->indexToLocFormat > 1 || head->glyphDataFormat != 0) - { - /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ - hb_blob_destroy (head_blob); - return; - } - this->short_offset = 0 == head->indexToLocFormat; - hb_blob_destroy (head_blob); - - this->loca_blob = OT::Sanitizer<OT::loca>::sanitize (face->reference_table (HB_OT_TAG_loca)); - this->loca = OT::Sanitizer<OT::loca>::lock_instance (this->loca_blob); - this->glyf_blob = OT::Sanitizer<OT::glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf)); - this->glyf = OT::Sanitizer<OT::glyf>::lock_instance (this->glyf_blob); - - this->num_glyphs = MAX (1u, hb_blob_get_length (this->loca_blob) / (this->short_offset ? 2 : 4)) - 1; - this->glyf_len = hb_blob_get_length (this->glyf_blob); - } - - inline void fini (void) - { - hb_blob_destroy (this->loca_blob); - hb_blob_destroy (this->glyf_blob); - } - - inline bool get_extents (hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const - { - if (unlikely (glyph >= this->num_glyphs)) - return false; - - unsigned int start_offset, end_offset; - if (this->short_offset) - { - start_offset = 2 * this->loca->u.shortsZ[glyph]; - end_offset = 2 * this->loca->u.shortsZ[glyph + 1]; - } - else - { - start_offset = this->loca->u.longsZ[glyph]; - end_offset = this->loca->u.longsZ[glyph + 1]; - } - - if (start_offset > end_offset || end_offset > this->glyf_len) - return false; - - if (end_offset - start_offset < OT::glyfGlyphHeader::static_size) - return true; /* Empty glyph; zero extents. */ - - const OT::glyfGlyphHeader &glyph_header = OT::StructAtOffset<OT::glyfGlyphHeader> (this->glyf, start_offset); - - extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); - extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); - extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; - extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; - - return true; - } -}; - -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; - unsigned int upem; - - inline void init (hb_face_t *face) - { - upem = face->get_upem(); - - cblc_blob = OT::Sanitizer<OT::CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC)); - cbdt_blob = OT::Sanitizer<OT::CBDT>::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 = nullptr; - cbdt = nullptr; - return; /* Not a bitmap font. */ - } - cblc = OT::Sanitizer<OT::CBLC>::lock_instance (cblc_blob); - cbdt = OT::Sanitizer<OT::CBDT>::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) - return false; // Not a color bitmap font. - const OT::IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); - if (!subtable_record || !x_ppem || !y_ppem) - 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<OT::GlyphBitmapDataFormat17> (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; - } -}; - -struct hb_ot_face_post_accelerator_t -{ - hb_blob_t *post_blob; - OT::post::accelerator_t accel; - - inline void init (hb_face_t *face) - { - hb_blob_t *blob = this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post)); - accel.init (OT::Sanitizer<OT::post>::lock_instance (blob), hb_blob_get_length (blob)); - } - - inline void fini (void) - { - accel.fini (); - hb_blob_destroy (this->post_blob); - } - - inline bool get_glyph_name (hb_codepoint_t glyph, - char *name, unsigned int size) const - { - return this->accel.get_glyph_name (glyph, name, size); - } - - inline bool get_glyph_from_name (const char *name, int len, - hb_codepoint_t *glyph) const - { - if (unlikely (!len)) - return false; - - return this->accel.get_glyph_from_name (name, len, glyph); - } -}; - -struct hb_ot_face_kern_accelerator_t -{ - hb_blob_t *kern_blob; - OT::kern::accelerator_t accel; - - inline void init (hb_face_t *face) - { - hb_blob_t *blob = this->kern_blob = OT::Sanitizer<OT::kern>::sanitize (face->reference_table (HB_OT_TAG_kern)); - accel.init (OT::Sanitizer<OT::kern>::lock_instance (blob), hb_blob_get_length (blob)); - } - - inline void fini (void) - { - accel.fini (); - hb_blob_destroy (this->kern_blob); - } - - inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const - { return accel.get_h_kerning (left, right); } -}; - -typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj, - hb_codepoint_t codepoint, - hb_codepoint_t *glyph); - -template <typename Type> -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); -} +#include "hb-ot-color-cbdt-table.hh" -template <typename Type> -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 -{ - 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) - { - this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap)); - const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob); - const OT::CmapSubtable *subtable = nullptr; - const OT::CmapSubtableFormat14 *subtable_uvs = nullptr; - - bool symbol = false; - /* 32-bit subtables. */ - if (!subtable) subtable = cmap->find_subtable (3, 10); - if (!subtable) subtable = cmap->find_subtable (0, 6); - if (!subtable) subtable = cmap->find_subtable (0, 4); - /* 16-bit subtables. */ - if (!subtable) subtable = cmap->find_subtable (3, 1); - if (!subtable) subtable = cmap->find_subtable (0, 3); - 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) symbol = true; - } - /* Meh. */ - if (!subtable) subtable = &OT::Null(OT::CmapSubtable); - - /* UVS subtable. */ - 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::CmapSubtableFormat14); - - this->uvs_table = subtable_uvs; - - this->get_glyph_data = subtable; - if (unlikely (symbol)) - this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>; - else - switch (subtable->u.format) { - /* Accelerate format 4 and format 12. */ - default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break; - case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; 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) - { - hb_blob_destroy (this->blob); - } - - inline bool get_nominal_glyph (hb_codepoint_t unicode, - hb_codepoint_t *glyph) const - { - 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)) - { - case OT::GLYPH_VARIANT_NOT_FOUND: return false; - case OT::GLYPH_VARIANT_FOUND: return true; - case OT::GLYPH_VARIANT_USE_DEFAULT: break; - } - - return get_nominal_glyph (unicode, glyph); - } -}; 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; - OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf; - OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt; - OT::hb_lazy_loader_t<hb_ot_face_post_accelerator_t> post; - OT::hb_lazy_loader_t<hb_ot_face_kern_accelerator_t> kern; + OT::cmap::accelerator_t cmap; + OT::hmtx::accelerator_t h_metrics; + OT::vmtx::accelerator_t v_metrics; + OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf; + OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt; + OT::hb_lazy_loader_t<OT::post::accelerator_t> post; + OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern; }; @@ -505,9 +60,8 @@ return nullptr; ot_font->cmap.init (face); - ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, HB_OT_TAG_HVAR, HB_OT_TAG_os2); - ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, HB_OT_TAG_VVAR, HB_TAG_NONE, - ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */ + ot_font->h_metrics.init (face); + ot_font->v_metrics.init (face, 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); ot_font->post.init (face); @@ -688,7 +242,7 @@ hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr); //hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr); hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); - //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); TODO + //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-glyf-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-glyf-table.hh Wed May 30 12:20:00 2018 -0700 @@ -28,7 +28,10 @@ #define HB_OT_GLYF_TABLE_HH #include "hb-open-type-private.hh" - +#include "hb-ot-head-table.hh" +#include "hb-subset-glyf.hh" +#include "hb-subset-plan.hh" +#include "hb-subset-private.hh" namespace OT { @@ -42,6 +45,8 @@ struct loca { + friend struct glyf; + static const hb_tag_t tableTag = HB_OT_TAG_loca; inline bool sanitize (hb_sanitize_context_t *c) const @@ -50,12 +55,9 @@ return_trace (true); } - public: - union { - USHORT shortsZ[VAR]; /* Location offset divided by 2. */ - ULONG longsZ[VAR]; /* Location offset. */ - } u; - DEFINE_SIZE_ARRAY (0, u.longsZ); + protected: + HBUINT8 dataX[VAR]; /* Location data. */ + DEFINE_SIZE_ARRAY (0, dataX); }; @@ -78,26 +80,393 @@ return_trace (true); } - public: - BYTE dataX[VAR]; /* Glyphs data. */ + inline bool subset (hb_subset_plan_t *plan) const + { + hb_blob_t *glyf_prime = nullptr; + hb_blob_t *loca_prime = nullptr; + + bool success = true; + bool use_short_loca = false; + if (hb_subset_glyf_and_loca (plan, &use_short_loca, &glyf_prime, &loca_prime)) { + success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_glyf, glyf_prime); + success = success && hb_subset_plan_add_table (plan, HB_OT_TAG_loca, loca_prime); + success = success && _add_head_and_set_loca_version (plan->source, use_short_loca, plan->dest); + } else { + success = false; + } + hb_blob_destroy (loca_prime); + hb_blob_destroy (glyf_prime); + + return success; + } + + static bool + _add_head_and_set_loca_version (hb_face_t *source, bool use_short_loca, hb_face_t *dest) + { + hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (source, HB_OT_TAG_head)); + hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob); + hb_blob_destroy (head_blob); + + if (unlikely (!head_prime_blob)) + return false; + + OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr); + head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1); + bool success = hb_subset_face_add_table (dest, HB_OT_TAG_head, head_prime_blob); + + hb_blob_destroy (head_prime_blob); + return success; + } + + struct GlyphHeader + { + HBINT16 numberOfContours; /* If the number of contours is + * greater than or equal to zero, + * this is a simple glyph; if negative, + * this is a composite glyph. */ + 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); + }; + + struct CompositeGlyphHeader + { + static const uint16_t ARG_1_AND_2_ARE_WORDS = 0x0001; + static const uint16_t ARGS_ARE_XY_VALUES = 0x0002; + static const uint16_t ROUND_XY_TO_GRID = 0x0004; + static const uint16_t WE_HAVE_A_SCALE = 0x0008; + static const uint16_t MORE_COMPONENTS = 0x0020; + static const uint16_t WE_HAVE_AN_X_AND_Y_SCALE = 0x0040; + static const uint16_t WE_HAVE_A_TWO_BY_TWO = 0x0080; + static const uint16_t WE_HAVE_INSTRUCTIONS = 0x0100; + static const uint16_t USE_MY_METRICS = 0x0200; + static const uint16_t OVERLAP_COMPOUND = 0x0400; + static const uint16_t SCALED_COMPONENT_OFFSET = 0x0800; + static const uint16_t UNSCALED_COMPONENT_OFFSET = 0x1000; + + HBUINT16 flags; + HBUINT16 glyphIndex; + + inline unsigned int get_size (void) const + { + unsigned int size = min_size; + if (flags & ARG_1_AND_2_ARE_WORDS) { + // arg1 and 2 are int16 + size += 4; + } else { + // arg1 and 2 are int8 + size += 2; + } + if (flags & WE_HAVE_A_SCALE) { + // One x 16 bit (scale) + size += 2; + } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { + // Two x 16 bit (xscale, yscale) + size += 4; + } else if (flags & WE_HAVE_A_TWO_BY_TWO) { + // Four x 16 bit (xscale, scale01, scale10, yscale) + size += 8; + } + return size; + } + + struct Iterator + { + const char *glyph_start; + const char *glyph_end; + const CompositeGlyphHeader *current; + + inline bool move_to_next () + { + if (current->flags & CompositeGlyphHeader::MORE_COMPONENTS) + { + const CompositeGlyphHeader *possible = + &StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (*current); + if (!in_range (possible)) + return false; + current = possible; + return true; + } + return false; + } + + inline bool in_range (const CompositeGlyphHeader *composite) const + { + return (const char *) composite >= glyph_start + && ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end + && ((const char *) composite + composite->get_size()) <= glyph_end; + } + }; + + static inline bool get_iterator (const char * glyph_data, + unsigned int length, + CompositeGlyphHeader::Iterator *iterator /* OUT */) + { + if (length < GlyphHeader::static_size) + return false; /* Empty glyph; zero extents. */ + + const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0); + if (glyph_header.numberOfContours < 0) + { + const CompositeGlyphHeader *possible = + &StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header); + + iterator->glyph_start = glyph_data; + iterator->glyph_end = (const char *) glyph_data + length; + if (!iterator->in_range (possible)) + return false; + iterator->current = possible; + return true; + } + + return false; + } + + DEFINE_SIZE_MIN (4); + }; + + struct accelerator_t + { + inline void init (hb_face_t *face) + { + hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head)); + const head *head_table = Sanitizer<head>::lock_instance (head_blob); + if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) + { + /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + hb_blob_destroy (head_blob); + return; + } + short_offset = 0 == head_table->indexToLocFormat; + hb_blob_destroy (head_blob); + + loca_blob = Sanitizer<loca>().sanitize (face->reference_table (HB_OT_TAG_loca)); + loca_table = Sanitizer<loca>::lock_instance (loca_blob); + glyf_blob = Sanitizer<glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf)); + glyf_table = Sanitizer<glyf>::lock_instance (glyf_blob); + + num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1; + glyf_len = hb_blob_get_length (glyf_blob); + } + + inline void fini (void) + { + hb_blob_destroy (loca_blob); + hb_blob_destroy (glyf_blob); + } + + /* + * Returns true if the referenced glyph is a valid glyph and a composite glyph. + * If true is returned a pointer to the composite glyph will be written into + * composite. + */ + inline bool get_composite (hb_codepoint_t glyph, + CompositeGlyphHeader::Iterator *composite /* OUT */) const + { + unsigned int start_offset, end_offset; + if (!get_offsets (glyph, &start_offset, &end_offset)) + return false; /* glyph not found */ + + return CompositeGlyphHeader::get_iterator ((const char*) this->glyf_table + start_offset, + end_offset - start_offset, + composite); + } + + /* based on FontTools _g_l_y_f.py::trim */ + inline bool remove_padding(unsigned int start_offset, + unsigned int *end_offset) const + { + static const int FLAG_X_SHORT = 0x02; + static const int FLAG_Y_SHORT = 0x04; + static const int FLAG_REPEAT = 0x08; + static const int FLAG_X_SAME = 0x10; + static const int FLAG_Y_SAME = 0x20; + + if (*end_offset - start_offset < GlyphHeader::static_size) + return true; + + const char *glyph = ((const char *) glyf_table) + start_offset; + const char * const glyph_end = glyph + (*end_offset - start_offset); + const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph, 0); + int16_t num_contours = (int16_t) glyph_header.numberOfContours; + + if (num_contours < 0) + /* Trimming for composites not implemented. + * If removing hints it falls out of that. */ + return true; + else if (num_contours > 0) + { + /* simple glyph w/contours, possibly trimmable */ + glyph += GlyphHeader::static_size + 2 * num_contours; + + if (unlikely (glyph + 2 >= glyph_end)) return false; + uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16>(glyph - 2, 0) + 1; + uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16>(glyph, 0); + + glyph += 2 + nInstructions; + if (unlikely (glyph + 2 >= glyph_end)) return false; + + unsigned int coordBytes = 0; + unsigned int coordsWithFlags = 0; + while (glyph < glyph_end) + { + uint8_t flag = (uint8_t) *glyph; + glyph++; + + unsigned int repeat = 1; + if (flag & FLAG_REPEAT) + { + if (glyph >= glyph_end) + { + DEBUG_MSG(SUBSET, nullptr, "Bad flag"); + return false; + } + repeat = ((uint8_t) *glyph) + 1; + glyph++; + } + + unsigned int xBytes, yBytes; + xBytes = yBytes = 0; + if (flag & FLAG_X_SHORT) + xBytes = 1; + else if ((flag & FLAG_X_SAME) == 0) + xBytes = 2; + + if (flag & FLAG_Y_SHORT) + yBytes = 1; + else if ((flag & FLAG_Y_SAME) == 0) + yBytes = 2; + + coordBytes += (xBytes + yBytes) * repeat; + coordsWithFlags += repeat; + if (coordsWithFlags >= nCoordinates) + break; + } + + if (coordsWithFlags != nCoordinates) + { + DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags); + return false; + } + glyph += coordBytes; + + if (glyph < glyph_end) + *end_offset -= glyph_end - glyph; + } + return true; + } + + inline bool get_offsets (hb_codepoint_t glyph, + unsigned int *start_offset /* OUT */, + unsigned int *end_offset /* OUT */) const + { + if (unlikely (glyph >= num_glyphs)) + return false; + + if (short_offset) + { + const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataX; + *start_offset = 2 * offsets[glyph]; + *end_offset = 2 * offsets[glyph + 1]; + } + else + { + const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX; + + *start_offset = offsets[glyph]; + *end_offset = offsets[glyph + 1]; + } + + if (*start_offset > *end_offset || *end_offset > glyf_len) + return false; + + return true; + } + + inline bool get_instruction_offsets(unsigned int start_offset, + unsigned int end_offset, + unsigned int *instruction_start /* OUT */, + unsigned int *instruction_end /* OUT */) const + { + if (end_offset - start_offset < GlyphHeader::static_size) + { + *instruction_start = 0; + *instruction_end = 0; + return true; /* Empty glyph; no instructions. */ + } + const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset); + int16_t num_contours = (int16_t) glyph_header.numberOfContours; + if (num_contours < 0) + { + CompositeGlyphHeader::Iterator composite_it; + if (unlikely (!CompositeGlyphHeader::get_iterator ( + (const char*) this->glyf_table + start_offset, + end_offset - start_offset, &composite_it))) return false; + const CompositeGlyphHeader *last; + do { + last = composite_it.current; + } while (composite_it.move_to_next()); + + if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS) + *instruction_start = ((char *) last - (char *) glyf_table->dataX) + last->get_size(); + else + *instruction_start = end_offset; + *instruction_end = end_offset; + if (unlikely (*instruction_start > *instruction_end)) + { + DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset); + return false; + } + } + else + { + unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours; + const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset); + *instruction_start = instruction_length_offset + 2; + *instruction_end = *instruction_start + (uint16_t) instruction_length; + } + return true; + } + + inline bool get_extents (hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + unsigned int start_offset, end_offset; + if (!get_offsets (glyph, &start_offset, &end_offset)) + return false; + + if (end_offset - start_offset < GlyphHeader::static_size) + return true; /* Empty glyph; zero extents. */ + + const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset); + + extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); + extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); + extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; + extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; + + return true; + } + + private: + bool short_offset; + unsigned int num_glyphs; + const loca *loca_table; + const glyf *glyf_table; + hb_blob_t *loca_blob; + hb_blob_t *glyf_blob; + unsigned int glyf_len; + }; + + protected: + HBUINT8 dataX[VAR]; /* Glyphs data. */ DEFINE_SIZE_ARRAY (0, dataX); }; -struct glyfGlyphHeader -{ - SHORT numberOfContours; /* If the number of contours is - * greater than or equal to zero, - * this is a simple glyph; if negative, - * this is a composite glyph. */ - 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); -}; - } /* namespace OT */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-head-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-head-table.hh Wed May 30 12:20:00 2018 -0700 @@ -43,6 +43,8 @@ struct head { + friend struct OffsetTable; + static const hb_tag_t tableTag = HB_OT_TAG_head; inline unsigned int get_upem (void) const @@ -64,11 +66,11 @@ FixedVersion<>version; /* Version of the head table--currently * 0x00010000u for version 1.0. */ FixedVersion<>fontRevision; /* Set by font manufacturer. */ - ULONG checkSumAdjustment; /* To compute: set it to 0, sum the - * entire font as ULONG, then store + HBUINT32 checkSumAdjustment; /* To compute: set it to 0, sum the + * entire font as HBUINT32, then store * 0xB1B0AFBAu - sum. */ - ULONG magicNumber; /* Set to 0x5F0F3CF5u. */ - USHORT flags; /* Bit 0: Baseline for font at y=0; + HBUINT32 magicNumber; /* Set to 0x5F0F3CF5u. */ + HBUINT16 flags; /* Bit 0: Baseline for font at y=0; * Bit 1: Left sidebearing point at x=0; * Bit 2: Instructions may depend on point size; * Bit 3: Force ppem to integer values for all @@ -76,7 +78,6 @@ * ppem sizes if this bit is clear; * Bit 4: Instructions may alter advance width * (the advance widths might not scale linearly); - * Bits 5-10: These should be set according to * Apple's specification. However, they are not * implemented in OpenType. @@ -96,7 +97,6 @@ * contains any strong right-to-left glyphs. * Bit 10: This bit should be set if the font * contains Indic-style rearrangement effects. - * Bit 11: Font data is 'lossless,' as a result * of having been compressed and decompressed * with the Agfa MicroType Express engine. @@ -114,18 +114,18 @@ * encoded in the cmap subtables represent proper * support for those code points. * Bit 15: Reserved, set to 0. */ - USHORT unitsPerEm; /* Valid range is from 16 to 16384. This value + HBUINT16 unitsPerEm; /* Valid range is from 16 to 16384. This value * should be a power of 2 for fonts that have * TrueType outlines. */ LONGDATETIME created; /* Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer */ LONGDATETIME modified; /* Number of seconds since 12:00 midnight, January 1, 1904. 64-bit integer */ - SHORT xMin; /* For all glyph bounding boxes. */ - SHORT yMin; /* For all glyph bounding boxes. */ - SHORT xMax; /* For all glyph bounding boxes. */ - SHORT yMax; /* For all glyph bounding boxes. */ - USHORT macStyle; /* Bit 0: Bold (if set to 1); + HBINT16 xMin; /* For all glyph bounding boxes. */ + HBINT16 yMin; /* For all glyph bounding boxes. */ + HBINT16 xMax; /* For all glyph bounding boxes. */ + HBINT16 yMax; /* For all glyph bounding boxes. */ + HBUINT16 macStyle; /* Bit 0: Bold (if set to 1); * Bit 1: Italic (if set to 1) * Bit 2: Underline (if set to 1) * Bit 3: Outline (if set to 1) @@ -133,16 +133,16 @@ * Bit 5: Condensed (if set to 1) * Bit 6: Extended (if set to 1) * Bits 7-15: Reserved (set to 0). */ - USHORT lowestRecPPEM; /* Smallest readable size in pixels. */ - SHORT fontDirectionHint; /* Deprecated (Set to 2). + HBUINT16 lowestRecPPEM; /* Smallest readable size in pixels. */ + HBINT16 fontDirectionHint; /* Deprecated (Set to 2). * 0: Fully mixed directional glyphs; * 1: Only strongly left to right; * 2: Like 1 but also contains neutrals; * -1: Only strongly right to left; * -2: Like -1 but also contains neutrals. */ public: - SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */ - SHORT glyphDataFormat; /* 0 for current format. */ + HBINT16 indexToLocFormat; /* 0 for short offsets, 1 for long. */ + HBINT16 glyphDataFormat; /* 0 for current format. */ DEFINE_SIZE_STATIC (54); };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hhea-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hhea-table.hh Wed May 30 12:20:00 2018 -0700 @@ -41,14 +41,9 @@ #define HB_OT_TAG_hhea HB_TAG('h','h','e','a') #define HB_OT_TAG_vhea HB_TAG('v','h','e','a') - +template <typename T> struct _hea { - static const hb_tag_t tableTag = HB_TAG('_','h','e','a'); - - static const hb_tag_t hheaTag = HB_OT_TAG_hhea; - static const hb_tag_t vheaTag = HB_OT_TAG_vhea; - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -69,30 +64,30 @@ * (xMax - xMin)) for horizontal. */ FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)), * vertical: minLeadingBearing+(yMax-yMin). */ - SHORT caretSlopeRise; /* Used to calculate the slope of the + HBINT16 caretSlopeRise; /* Used to calculate the slope of the * cursor (rise/run); 1 for vertical caret, * 0 for horizontal.*/ - SHORT caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */ - SHORT caretOffset; /* The amount by which a slanted + HBINT16 caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */ + HBINT16 caretOffset; /* The amount by which a slanted * highlight on a glyph needs * to be shifted to produce the * best appearance. Set to 0 for * non-slanted fonts. */ - SHORT reserved1; /* Set to 0. */ - SHORT reserved2; /* Set to 0. */ - SHORT reserved3; /* Set to 0. */ - SHORT reserved4; /* Set to 0. */ - SHORT metricDataFormat; /* 0 for current format. */ - USHORT numberOfLongMetrics; /* Number of LongMetric entries in metric + HBINT16 reserved1; /* Set to 0. */ + HBINT16 reserved2; /* Set to 0. */ + HBINT16 reserved3; /* Set to 0. */ + HBINT16 reserved4; /* Set to 0. */ + HBINT16 metricDataFormat; /* 0 for current format. */ + HBUINT16 numberOfLongMetrics; /* Number of LongMetric entries in metric * table. */ public: DEFINE_SIZE_STATIC (36); }; -struct hhea : _hea { +struct hhea : _hea<hhea> { static const hb_tag_t tableTag = HB_OT_TAG_hhea; }; -struct vhea : _hea { +struct vhea : _hea<vhea> { static const hb_tag_t tableTag = HB_OT_TAG_vhea; };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hmtx-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-hmtx-table.hh Wed May 30 12:20:00 2018 -0700 @@ -21,13 +21,16 @@ * 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 + * Google Author(s): Behdad Esfahbod, Roderick Sheeter */ #ifndef HB_OT_HMTX_TABLE_HH #define HB_OT_HMTX_TABLE_HH #include "hb-open-type-private.hh" +#include "hb-ot-hhea-table.hh" +#include "hb-ot-os2-table.hh" +#include "hb-ot-var-hvar-table.hh" namespace OT { @@ -50,11 +53,9 @@ DEFINE_SIZE_STATIC (4); }; +template <typename T, typename H> struct hmtxvmtx { - static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx; - static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx; - inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -63,7 +64,228 @@ return_trace (true); } - public: + + inline bool subset_update_header (hb_subset_plan_t *plan, + unsigned int num_hmetrics) const + { + hb_blob_t *src_blob = OT::Sanitizer<H> ().sanitize (plan->source->reference_table (H::tableTag)); + hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail(src_blob); + hb_blob_destroy (src_blob); + + if (unlikely (!dest_blob)) { + return false; + } + + unsigned int length; + H *table = (H *) hb_blob_get_data (dest_blob, &length); + table->numberOfLongMetrics.set (num_hmetrics); + + bool result = hb_subset_plan_add_table (plan, H::tableTag, dest_blob); + hb_blob_destroy (dest_blob); + + return result; + } + + inline bool subset (hb_subset_plan_t *plan) const + { + typename T::accelerator_t _mtx; + _mtx.init (plan->source); + + /* All the trailing glyphs with the same advance can use one LongMetric + * and just keep LSB */ + hb_prealloced_array_t<hb_codepoint_t> &gids = plan->gids_to_retain_sorted; + unsigned int num_advances = gids.len; + unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]); + while (num_advances > 1 + && last_advance == _mtx.get_advance (gids[num_advances - 2])) + { + num_advances--; + } + + /* alloc the new table */ + size_t dest_sz = num_advances * 4 + + (gids.len - num_advances) * 2; + void *dest = (void *) malloc (dest_sz); + if (unlikely (!dest)) + { + return false; + } + DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in src has %d advances, %d lsbs", HB_UNTAG(T::tableTag), _mtx.num_advances, _mtx.num_metrics - _mtx.num_advances); + DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in dest has %d advances, %d lsbs, %u bytes", HB_UNTAG(T::tableTag), num_advances, gids.len - num_advances, (unsigned int) dest_sz); + + const char *source_table = hb_blob_get_data (_mtx.blob, nullptr); + // Copy everything over + LongMetric * old_metrics = (LongMetric *) source_table; + FWORD *lsbs = (FWORD *) (old_metrics + _mtx.num_advances); + char * dest_pos = (char *) dest; + for (unsigned int i = 0; i < gids.len; i++) + { + /* the last metric or the one for gids[i] */ + LongMetric *src_metric = old_metrics + MIN ((hb_codepoint_t) _mtx.num_advances - 1, gids[i]); + if (gids[i] < _mtx.num_advances) + { + /* src is a LongMetric */ + if (i < num_advances) + { + /* dest is a LongMetric, copy it */ + *((LongMetric *) dest_pos) = *src_metric; + } + else + { + /* dest just lsb */ + *((FWORD *) dest_pos) = src_metric->lsb; + } + } + else + { + FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); + if (i < num_advances) + { + /* dest needs a full LongMetric */ + LongMetric *metric = (LongMetric *)dest_pos; + metric->advance = src_metric->advance; + metric->lsb = src_lsb; + } + else + { + /* dest just needs an lsb */ + *((FWORD *) dest_pos) = src_lsb; + } + } + dest_pos += (i < num_advances ? 4 : 2); + } + _mtx.fini (); + + // Amend header num hmetrics + if (unlikely (!subset_update_header (plan, num_advances))) + { + free (dest); + return false; + } + + hb_blob_t *result = hb_blob_create ((const char *)dest, + dest_sz, + HB_MEMORY_MODE_READONLY, + dest, + free); + bool success = hb_subset_plan_add_table (plan, T::tableTag, result); + hb_blob_destroy (result); + return success; + } + + struct accelerator_t + { + friend struct hmtxvmtx; + + inline void init (hb_face_t *face, + unsigned int default_advance_ = 0) + { + default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face); + + bool got_font_extents = false; + if (T::os2Tag) + { + hb_blob_t *os2_blob = Sanitizer<os2> ().sanitize (face->reference_table (T::os2Tag)); + const os2 *os2_table = Sanitizer<os2>::lock_instance (os2_blob); +#define USE_TYPO_METRICS (1u<<7) + if (0 != (os2_table->fsSelection & USE_TYPO_METRICS)) + { + ascender = os2_table->sTypoAscender; + descender = os2_table->sTypoDescender; + line_gap = os2_table->sTypoLineGap; + got_font_extents = (ascender | descender) != 0; + } + hb_blob_destroy (os2_blob); + } + + hb_blob_t *_hea_blob = Sanitizer<H> ().sanitize (face->reference_table (H::tableTag)); + const H *_hea_table = Sanitizer<H>::lock_instance (_hea_blob); + num_advances = _hea_table->numberOfLongMetrics; + if (!got_font_extents) + { + ascender = _hea_table->ascender; + descender = _hea_table->descender; + line_gap = _hea_table->lineGap; + got_font_extents = (ascender | descender) != 0; + } + hb_blob_destroy (_hea_blob); + + has_font_extents = got_font_extents; + + blob = Sanitizer<hmtxvmtx> ().sanitize (face->reference_table (T::tableTag)); + + /* Cap num_metrics() and num_advances() based on table length. */ + unsigned int len = hb_blob_get_length (blob); + if (unlikely (num_advances * 4 > len)) + num_advances = len / 4; + num_metrics = num_advances + (len - 4 * num_advances) / 2; + + /* We MUST set num_metrics to zero if num_advances is zero. + * Our get_advance() depends on that. */ + if (unlikely (!num_advances)) + { + num_metrics = num_advances = 0; + hb_blob_destroy (blob); + blob = hb_blob_get_empty (); + } + table = Sanitizer<hmtxvmtx>::lock_instance (blob); + + var_blob = Sanitizer<HVARVVAR> ().sanitize (face->reference_table (T::variationsTag)); + var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob); + } + + inline void fini (void) + { + hb_blob_destroy (blob); + hb_blob_destroy (var_blob); + } + + inline unsigned int get_advance (hb_codepoint_t glyph) const + { + if (unlikely (glyph >= num_metrics)) + { + /* If num_metrics is zero, it means we don't have the metrics table + * for this direction: return default advance. Otherwise, it means that the + * glyph index is out of bound: return zero. */ + if (num_metrics) + return 0; + else + return default_advance; + } + + return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance; + } + + inline unsigned int get_advance (hb_codepoint_t glyph, + hb_font_t *font) const + { + unsigned int advance = get_advance (glyph); + if (likely(glyph < num_metrics)) + { + advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?! + } + return advance; + } + + public: + bool has_font_extents; + unsigned short ascender; + unsigned short descender; + unsigned short line_gap; + + protected: + unsigned int num_metrics; + unsigned int num_advances; + unsigned int default_advance; + + private: + const hmtxvmtx *table; + hb_blob_t *blob; + const HVARVVAR *var_table; + hb_blob_t *var_blob; + }; + + protected: LongMetric longMetric[VAR]; /* Paired advance width and leading * bearing values for each glyph. The * value numOfHMetrics comes from @@ -72,7 +294,7 @@ * be in the array, but that entry is * required. The last entry applies to * all subsequent glyphs. */ - FWORD 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 @@ -86,14 +308,18 @@ * font to vary the side bearing * values for each glyph. */ public: - DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX); + DEFINE_SIZE_ARRAY (0, longMetric); }; -struct hmtx : hmtxvmtx { +struct hmtx : hmtxvmtx<hmtx, hhea> { static const hb_tag_t tableTag = HB_OT_TAG_hmtx; + static const hb_tag_t variationsTag = HB_OT_TAG_HVAR; + static const hb_tag_t os2Tag = HB_OT_TAG_os2; }; -struct vmtx : hmtxvmtx { +struct vmtx : hmtxvmtx<vmtx, vhea> { static const hb_tag_t tableTag = HB_OT_TAG_vmtx; + static const hb_tag_t variationsTag = HB_OT_TAG_VVAR; + static const hb_tag_t os2Tag = HB_TAG_NONE; }; } /* namespace OT */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-kern-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-kern-table.hh Wed May 30 12:20:00 2018 -0700 @@ -104,8 +104,8 @@ } protected: - USHORT firstGlyph; /* First glyph in class range. */ - ArrayOf<USHORT> classes; /* Glyph classes. */ + HBUINT16 firstGlyph; /* First glyph in class range. */ + ArrayOf<HBUINT16> classes; /* Glyph classes. */ public: DEFINE_SIZE_ARRAY (4, classes); }; @@ -115,7 +115,7 @@ inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const { unsigned int l = (this+leftClassTable).get_class (left); - unsigned int r = (this+leftClassTable).get_class (left); + unsigned int r = (this+rightClassTable).get_class (right); unsigned int offset = l * rowWidth + r * sizeof (FWORD); const FWORD *arr = &(this+array); if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end)) @@ -136,7 +136,7 @@ } protected: - USHORT rowWidth; /* The width, in bytes, of a row in the table. */ + HBUINT16 rowWidth; /* The width, in bytes, of a row in the table. */ OffsetTo<KernClassTable> leftClassTable; /* Offset from beginning of this subtable to * left-hand class table. */ @@ -275,19 +275,19 @@ }; protected: - USHORT versionZ; /* Unused. */ - USHORT length; /* Length of the subtable (including this header). */ - BYTE format; /* Subtable format. */ - BYTE coverage; /* Coverage bits. */ + HBUINT16 versionZ; /* Unused. */ + HBUINT16 length; /* Length of the subtable (including this header). */ + HBUINT8 format; /* Subtable format. */ + HBUINT8 coverage; /* Coverage bits. */ KernSubTable subtable; /* Subtable data. */ public: DEFINE_SIZE_MIN (6); }; protected: - USHORT version; /* Version--0x0000u */ - USHORT nTables; /* Number of subtables in the kerning table. */ - BYTE data[VAR]; + HBUINT16 version; /* Version--0x0000u */ + HBUINT16 nTables; /* Number of subtables in the kerning table. */ + HBUINT8 data[VAR]; public: DEFINE_SIZE_ARRAY (4, data); }; @@ -314,10 +314,10 @@ }; protected: - ULONG length; /* Length of the subtable (including this header). */ - BYTE coverage; /* Coverage bits. */ - BYTE format; /* Subtable format. */ - USHORT tupleIndex; /* The tuple index (used for variations fonts). + HBUINT32 length; /* Length of the subtable (including this header). */ + HBUINT8 coverage; /* Coverage bits. */ + HBUINT8 format; /* Subtable format. */ + HBUINT16 tupleIndex; /* The tuple index (used for variations fonts). * This value specifies which tuple this subtable covers. */ KernSubTable subtable; /* Subtable data. */ public: @@ -325,9 +325,9 @@ }; protected: - ULONG version; /* Version--0x00010000u */ - ULONG nTables; /* Number of subtables in the kerning table. */ - BYTE data[VAR]; + HBUINT32 version; /* Version--0x00010000u */ + HBUINT32 nTables; /* Number of subtables in the kerning table. */ + HBUINT8 data[VAR]; public: DEFINE_SIZE_ARRAY (8, data); }; @@ -358,24 +358,29 @@ struct accelerator_t { - inline void init (const kern *table_, unsigned int table_length_) + inline void init (hb_face_t *face) { - table = table_; - table_length = table_length_; + blob = Sanitizer<kern>().sanitize (face->reference_table (HB_OT_TAG_kern)); + table = Sanitizer<kern>::lock_instance (blob); + table_length = hb_blob_get_length (blob); } - inline void fini (void) {} + inline void fini (void) + { + hb_blob_destroy (blob); + } inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const { return table->get_h_kerning (left, right, table_length); } private: + hb_blob_t *blob; const kern *table; unsigned int table_length; }; protected: union { - USHORT major; + HBUINT16 major; KernOT ot; KernAAT aat; } u;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-base-table.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,655 @@ +/* + * Copyright © 2016 Elie Roux <elie.roux@telecom-bretagne.eu> + * Copyright © 2018 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_LAYOUT_BASE_TABLE_HH +#define HB_OT_LAYOUT_BASE_TABLE_HH + +#include "hb-open-type-private.hh" +#include "hb-ot-layout-common-private.hh" + +namespace OT { + +#define NOT_INDEXED ((unsigned int) -1) + +/* + * BASE -- The BASE Table + */ + +struct BaseCoordFormat1 +{ + inline int get_coord (void) const { return coordinate; } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 1 */ + HBINT16 coordinate; /* X or Y value, in design units */ + public: + DEFINE_SIZE_STATIC (4); +}; + +struct BaseCoordFormat2 +{ + inline int get_coord (void) const + { + /* TODO */ + return coordinate; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 2 */ + HBINT16 coordinate; /* X or Y value, in design units */ + GlyphID referenceGlyph; /* Glyph ID of control glyph */ + HBUINT16 coordPoint; /* Index of contour point on the + * reference glyph */ + public: + DEFINE_SIZE_STATIC (8); +}; + +struct BaseCoordFormat3 +{ + inline int get_coord (void) const + { + /* TODO */ + return coordinate; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && deviceTable.sanitize (c, this)); + } + + protected: + HBUINT16 format; /* Format identifier--format = 3 */ + HBINT16 coordinate; /* X or Y value, in design units */ + OffsetTo<Device> deviceTable; /* Offset to Device table for X or + * Y value, from beginning of + * BaseCoord table (may be NULL). */ + public: + DEFINE_SIZE_STATIC (6); +}; + +struct BaseCoord +{ + inline int get_coord (void) const + { + switch (u.format) { + case 1: return u.format1.get_coord (); + case 2: return u.format2.get_coord (); + case 3: return u.format3.get_coord (); + default:return 0; + } + } + + 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)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); + default:return_trace (false); + } + } + + protected: + union { + HBUINT16 format; + BaseCoordFormat1 format1; + BaseCoordFormat2 format2; + BaseCoordFormat3 format3; + } u; + public: + DEFINE_SIZE_UNION (2, format); +}; + +struct FeatMinMaxRecord +{ + inline int get_min_value (void) const + { return (this+minCoord).get_coord(); } + + inline int get_max_value (void) const + { return (this+maxCoord).get_coord(); } + + inline const Tag &get_tag () const + { return tag; } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + minCoord.sanitize (c, base) && + maxCoord.sanitize (c, base)); + } + + protected: + Tag tag; /* 4-byte feature identification tag--must + * match feature tag in FeatureList */ + OffsetTo<BaseCoord> minCoord; /* Offset to BaseCoord table that defines + * the minimum extent value, from beginning + * of MinMax table (may be NULL) */ + OffsetTo<BaseCoord> maxCoord; /* Offset to BaseCoord table that defines + * the maximum extent value, from beginning + * of MinMax table (may be NULL) */ + public: + DEFINE_SIZE_STATIC (8); + +}; + +struct MinMax +{ + inline unsigned int get_feature_tag_index (Tag featureTableTag) const + { + /* TODO bsearch */ + unsigned int count = featMinMaxRecords.len; + for (unsigned int i = 0; i < count; i++) + { + Tag tag = featMinMaxRecords[i].get_tag(); + int cmp = tag.cmp(featureTableTag); + if (cmp == 0) return i; + if (cmp > 0) return NOT_INDEXED; + } + return NOT_INDEXED; + } + + inline int get_min_value (unsigned int featureTableTagIndex) const + { + if (featureTableTagIndex == NOT_INDEXED) + return (this+minCoord).get_coord(); + return featMinMaxRecords[featureTableTagIndex].get_min_value(); + } + + inline int get_max_value (unsigned int featureTableTagIndex) const + { + if (featureTableTagIndex == NOT_INDEXED) + return (this+maxCoord).get_coord(); + return featMinMaxRecords[featureTableTagIndex].get_max_value(); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + minCoord.sanitize (c, this) && + maxCoord.sanitize (c, this) && + featMinMaxRecords.sanitize (c, this)); + } + + protected: + OffsetTo<BaseCoord> minCoord; /* Offset to BaseCoord table that defines + * minimum extent value, from the beginning + * of MinMax table (may be NULL) */ + OffsetTo<BaseCoord> maxCoord; /* Offset to BaseCoord table that defines + * maximum extent value, from the beginning + * of MinMax table (may be NULL) */ + ArrayOf<FeatMinMaxRecord> + featMinMaxRecords; /* Array of FeatMinMaxRecords, in alphabetical + * order by featureTableTag */ + public: + DEFINE_SIZE_ARRAY (6, featMinMaxRecords); +}; + +/* TODO... */ +struct BaseLangSysRecord +{ + inline const Tag& get_tag(void) const + { return baseLangSysTag; } + + inline unsigned int get_feature_tag_index (Tag featureTableTag) const + { return (this+minMax).get_feature_tag_index(featureTableTag); } + + inline int get_min_value (unsigned int featureTableTagIndex) const + { return (this+minMax).get_min_value(featureTableTagIndex); } + + inline int get_max_value (unsigned int featureTableTagIndex) const + { return (this+minMax).get_max_value(featureTableTagIndex); } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + minMax.sanitize (c, base)); + } + + protected: + Tag baseLangSysTag; + OffsetTo<MinMax> minMax; + public: + DEFINE_SIZE_STATIC (6); + +}; + +struct BaseValues +{ + inline unsigned int get_default_base_tag_index (void) const + { return defaultIndex; } + + inline int get_base_coord (unsigned int baselineTagIndex) const + { + return (this+baseCoords[baselineTagIndex]).get_coord(); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + defaultIndex <= baseCoordCount && + baseCoords.sanitize (c, this)); + } + + protected: + Index defaultIndex; + HBUINT16 baseCoordCount; + OffsetArrayOf<BaseCoord> baseCoords; + public: + DEFINE_SIZE_ARRAY (6, baseCoords); + +}; + +struct BaseScript { + + inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const + { + Tag tag; + int cmp; + for (unsigned int i = 0; i < baseLangSysCount; i++) { + tag = baseLangSysRecords[i].get_tag(); + // taking advantage of alphabetical order + cmp = tag.cmp(baseLangSysTag); + if (cmp == 0) return i; + if (cmp > 0) return NOT_INDEXED; + } + return NOT_INDEXED; + } + + inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (baseLangSysIndex == NOT_INDEXED) { + if (unlikely(defaultMinMax)) return NOT_INDEXED; + return (this+defaultMinMax).get_feature_tag_index(featureTableTag); + } + if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NOT_INDEXED; + return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index(featureTableTag); + } + + inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + if (baseLangSysIndex == NOT_INDEXED) + return (this+defaultMinMax).get_min_value(featureTableTagIndex); + return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex); + } + + inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + if (baseLangSysIndex == NOT_INDEXED) + return (this+defaultMinMax).get_min_value(featureTableTagIndex); + return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex); + } + + inline unsigned int get_default_base_tag_index (void) const + { return (this+baseValues).get_default_base_tag_index(); } + + inline int get_base_coord (unsigned int baselineTagIndex) const + { return (this+baseValues).get_base_coord(baselineTagIndex); } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + baseValues.sanitize (c, this) && + defaultMinMax.sanitize (c, this) && + baseLangSysRecords.sanitize (c, this)); + } + + protected: + OffsetTo<BaseValues> baseValues; + OffsetTo<MinMax> defaultMinMax; + HBUINT16 baseLangSysCount; + ArrayOf<BaseLangSysRecord> baseLangSysRecords; + + public: + DEFINE_SIZE_ARRAY (8, baseLangSysRecords); +}; + + +struct BaseScriptRecord { + + inline const Tag& get_tag (void) const + { return baseScriptTag; } + + inline unsigned int get_default_base_tag_index(void) const + { return (this+baseScript).get_default_base_tag_index(); } + + inline int get_base_coord(unsigned int baselineTagIndex) const + { return (this+baseScript).get_base_coord(baselineTagIndex); } + + inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const + { return (this+baseScript).get_lang_tag_index(baseLangSysTag); } + + inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const + { return (this+baseScript).get_feature_tag_index(baseLangSysIndex, featureTableTag); } + + inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { return (this+baseScript).get_max_value(baseLangSysIndex, featureTableTagIndex); } + + inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { return (this+baseScript).get_min_value(baseLangSysIndex, featureTableTagIndex); } + + inline bool sanitize (hb_sanitize_context_t *c, const void *base) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + baseScript != Null(OffsetTo<BaseScript>) && + baseScript.sanitize (c, base)); + } + + protected: + Tag baseScriptTag; + OffsetTo<BaseScript> baseScript; + + public: + DEFINE_SIZE_STATIC (6); +}; + +struct BaseScriptList { + + inline unsigned int get_base_script_index (Tag baseScriptTag) const + { + for (unsigned int i = 0; i < baseScriptCount; i++) + if (baseScriptRecords[i].get_tag() == baseScriptTag) + return i; + return NOT_INDEXED; + } + + inline unsigned int get_default_base_tag_index (unsigned int baseScriptIndex) const + { + if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; + return baseScriptRecords[baseScriptIndex].get_default_base_tag_index(); + } + + inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + { + return baseScriptRecords[baseScriptIndex].get_base_coord(baselineTagIndex); + } + + inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + { + if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; + return baseScriptRecords[baseScriptIndex].get_lang_tag_index(baseLangSysTag); + } + + inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; + return baseScriptRecords[baseScriptIndex].get_feature_tag_index(baseLangSysIndex, featureTableTag); + } + + inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return baseScriptRecords[baseScriptIndex].get_max_value(baseLangSysIndex, featureTableTagIndex); + } + + inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return baseScriptRecords[baseScriptIndex].get_min_value(baseLangSysIndex, featureTableTagIndex); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + baseScriptRecords.sanitize (c, this)); + } + + protected: + HBUINT16 baseScriptCount; + ArrayOf<BaseScriptRecord> baseScriptRecords; + + public: + DEFINE_SIZE_ARRAY (4, baseScriptRecords); + +}; + +struct BaseTagList +{ + + inline unsigned int get_tag_index(Tag baselineTag) const + { + for (unsigned int i = 0; i < baseTagCount; i++) + if (baselineTags[i] == baselineTag) + return i; + return NOT_INDEXED; + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + HBUINT16 baseTagCount; + SortedArrayOf<Tag> baselineTags; + + public: + DEFINE_SIZE_ARRAY (4, baselineTags); +}; + +struct Axis +{ + + inline unsigned int get_base_tag_index(Tag baselineTag) const + { + if (unlikely(baseTagList == Null(OffsetTo<BaseTagList>))) return NOT_INDEXED; + return (this+baseTagList).get_tag_index(baselineTag); + } + + inline unsigned int get_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + { + if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; + return (this+baseScriptList).get_default_base_tag_index(baseScriptIndex); + } + + inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + { + return (this+baseScriptList).get_base_coord(baseScriptIndex, baselineTagIndex); + } + + inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + { + if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; + return (this+baseScriptList).get_lang_tag_index(baseScriptIndex, baseLangSysTag); + } + + inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; + return (this+baseScriptList).get_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); + } + + inline int get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+baseScriptList).get_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline int get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+baseScriptList).get_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + baseTagList.sanitize (c, this) && + baseScriptList.sanitize (c, this)); + } + + protected: + OffsetTo<BaseTagList> baseTagList; + OffsetTo<BaseScriptList> baseScriptList; + + public: + DEFINE_SIZE_STATIC (4); +}; + +struct BASE +{ + static const hb_tag_t tableTag = HB_OT_TAG_BASE; + + inline bool has_vert_axis(void) + { return vertAxis != Null(OffsetTo<Axis>); } + + inline bool has_horiz_axis(void) + { return horizAxis != Null(OffsetTo<Axis>); } + + // horizontal axis base coords: + + inline unsigned int get_horiz_base_tag_index(Tag baselineTag) const + { + if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+horizAxis).get_base_tag_index(baselineTag); + } + + inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + { + if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+horizAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); + } + + inline int get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + { + return (this+horizAxis).get_base_coord(baseScriptIndex, baselineTagIndex); + } + + // vertical axis base coords: + + inline unsigned int get_vert_base_tag_index(Tag baselineTag) const + { + if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+vertAxis).get_base_tag_index(baselineTag); + } + + inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + { + if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+vertAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); + } + + inline int get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + { + return (this+vertAxis).get_base_coord(baseScriptIndex, baselineTagIndex); + } + + // horizontal axis min/max coords: + + inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + { + if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+horizAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); + } + + inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+horizAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); + } + + inline int get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+horizAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline int get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+horizAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + // vertical axis min/max coords: + + inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + { + if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+vertAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); + } + + inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + { + if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; + return (this+vertAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); + } + + inline int get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+vertAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline int get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + { + return (this+vertAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && + likely (version.major == 1) && + horizAxis.sanitize (c, this) && + vertAxis.sanitize (c, this) && + (version.to_int () < 0x00010001u || varStore.sanitize (c, this))); + } + + protected: + FixedVersion<> version; + OffsetTo<Axis> horizAxis; + OffsetTo<Axis> vertAxis; + LOffsetTo<VariationStore> + varStore; /* Offset to the table of Item Variation + * Store--from beginning of BASE + * header (may be NULL). Introduced + * in version 0x00010001. */ + public: + DEFINE_SIZE_MIN (8); +}; + + +} /* namespace OT */ + + +#endif /* HB_OT_LAYOUT_BASE_TABLE_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-common-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-common-private.hh Wed May 30 12:20:00 2018 -0700 @@ -155,13 +155,13 @@ } template <typename set_t> - inline void add_coverage (set_t *glyphs) const { - glyphs->add_range (start, end); + inline bool add_coverage (set_t *glyphs) const { + return glyphs->add_range (start, end); } GlyphID start; /* First GlyphID in the range */ GlyphID end; /* Last GlyphID in the range */ - USHORT value; /* Value */ + HBUINT16 value; /* Value */ public: DEFINE_SIZE_STATIC (6); }; @@ -175,7 +175,7 @@ unsigned int *_indexes /* OUT */) const { if (_count) { - const USHORT *arr = this->sub_array (start_offset, _count); + const HBUINT16 *arr = this->sub_array (start_offset, _count); unsigned int count = *_count; for (unsigned int i = 0; i < count; i++) _indexes[i] = arr[i]; @@ -216,9 +216,9 @@ return_trace (c->check_struct (this) && featureIndex.sanitize (c)); } - Offset<> lookupOrderZ; /* = Null (reserved for an offset to a + Offset16 lookupOrderZ; /* = Null (reserved for an offset to a * reordering table) */ - USHORT reqFeatureIndex;/* Index of a feature required for this + HBUINT16 reqFeatureIndex;/* Index of a feature required for this * language system--if no required features * = 0xFFFFu */ IndexArray featureIndex; /* Array of indices into the FeatureList */ @@ -299,7 +299,7 @@ * better. * * Assume that the offset to the size feature is according to specification, - * and make the following value checks. If it fails, assume the the size + * and make the following value checks. If it fails, assume the size * feature is calculated as versions of MakeOTF before the AFDKO 2.0 built it. * If this fails, reject the 'size' feature. The older makeOTF's calculated the * offset from the beginning of the FeatureList table, rather than from the @@ -343,12 +343,12 @@ return_trace (true); } - USHORT designSize; /* Represents the design size in 720/inch + HBUINT16 designSize; /* Represents the design size in 720/inch * units (decipoints). The design size entry * must be non-zero. When there is a design * size but no recommended size range, the * rest of the array will consist of zeros. */ - USHORT subfamilyID; /* Has no independent meaning, but serves + HBUINT16 subfamilyID; /* Has no independent meaning, but serves * as an identifier that associates fonts * in a subfamily. All fonts which share a * Preferred or Font Family name and which @@ -358,7 +358,7 @@ * same subfamily value. If this value is * zero, the remaining fields in the array * will be ignored. */ - USHORT subfamilyNameID;/* If the preceding value is non-zero, this + HBUINT16 subfamilyNameID;/* If the preceding value is non-zero, this * value must be set in the range 256 - 32767 * (inclusive). It records the value of a * field in the name table, which must @@ -372,10 +372,10 @@ * subfamily in a menu. Applications will * choose the appropriate version based on * their selection criteria. */ - USHORT rangeStart; /* Large end of the recommended usage range + HBUINT16 rangeStart; /* Large end of the recommended usage range * (inclusive), stored in 720/inch units * (decipoints). */ - USHORT rangeEnd; /* Small end of the recommended usage range + HBUINT16 rangeEnd; /* Small end of the recommended usage range (exclusive), stored in 720/inch units * (decipoints). */ public: @@ -393,12 +393,12 @@ return_trace (c->check_struct (this)); } - USHORT version; /* (set to 0): This corresponds to a “minor” + HBUINT16 version; /* (set to 0): This corresponds to a “minor” * version number. Additional data may be * added to the end of this Feature Parameters * table in the future. */ - USHORT uiNameID; /* The 'name' table name ID that specifies a + HBUINT16 uiNameID; /* The 'name' table name ID that specifies a * string (or strings, for multiple languages) * for a user-interface label for this * feature. The values of uiLabelNameId and @@ -426,25 +426,25 @@ characters.sanitize (c)); } - USHORT format; /* Format number is set to 0. */ - USHORT featUILableNameID; /* The ‘name’ table name ID that + HBUINT16 format; /* Format number is set to 0. */ + HBUINT16 featUILableNameID; /* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) for a * user-interface label for this * feature. (May be nullptr.) */ - USHORT featUITooltipTextNameID;/* The ‘name’ table name ID that + HBUINT16 featUITooltipTextNameID;/* The ‘name’ table name ID that * specifies a string (or strings, * for multiple languages) that an * application can use for tooltip * text for this feature. (May be * nullptr.) */ - USHORT sampleTextNameID; /* The ‘name’ table name ID that + HBUINT16 sampleTextNameID; /* The ‘name’ table name ID that * specifies sample text that * illustrates the effect of this * feature. (May be nullptr.) */ - USHORT numNamedParameters; /* Number of named parameters. (May + HBUINT16 numNamedParameters; /* Number of named parameters. (May * be zero.) */ - USHORT firstParamUILabelNameID;/* The first ‘name’ table name ID + HBUINT16 firstParamUILabelNameID;/* The first ‘name’ table name ID * used to specify strings for * user-interface labels for the * feature parameters. (Must be zero @@ -562,7 +562,7 @@ typedef RecordListOf<Feature> FeatureList; -struct LookupFlag : USHORT +struct LookupFlag : HBUINT16 { enum Flags { RightToLeft = 0x0001u, @@ -608,7 +608,7 @@ unsigned int flag = lookupFlag; if (unlikely (flag & LookupFlag::UseMarkFilteringSet)) { - const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); + const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); flag += (markFilteringSet << 16); } return flag; @@ -640,7 +640,7 @@ if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { - USHORT &markFilteringSet = StructAfter<USHORT> (subTable); + HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); markFilteringSet.set (lookup_props >> 16); } return_trace (true); @@ -653,18 +653,18 @@ if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { - const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); + const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); if (!markFilteringSet.sanitize (c)) return_trace (false); } return_trace (true); } private: - USHORT lookupType; /* Different enumerations for GSUB and GPOS */ - USHORT lookupFlag; /* Lookup qualifiers */ - ArrayOf<Offset<> > + HBUINT16 lookupType; /* Different enumerations for GSUB and GPOS */ + HBUINT16 lookupFlag; /* Lookup qualifiers */ + ArrayOf<Offset16> subTable; /* Array of SubTables */ - USHORT markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets + HBUINT16 markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets * structure. This field is only present if bit * UseMarkFilteringSet of lookup flags is set. */ public: @@ -700,7 +700,7 @@ if (unlikely (!c->extend (glyphArray))) return_trace (false); for (unsigned int i = 0; i < num_glyphs; i++) glyphArray[i] = glyphs[i]; - glyphs.advance (num_glyphs); + glyphs += num_glyphs; return_trace (true); } @@ -715,10 +715,8 @@ } template <typename set_t> - inline void add_coverage (set_t *glyphs) const { - unsigned int count = glyphArray.len; - for (unsigned int i = 0; i < count; i++) - glyphs->add (glyphArray[i]); + inline bool add_coverage (set_t *glyphs) const { + return glyphs->add_sorted_array (glyphArray.array, glyphArray.len); } public: @@ -737,7 +735,7 @@ private: protected: - USHORT coverageFormat; /* Format identifier--format = 1 */ + HBUINT16 coverageFormat; /* Format identifier--format = 1 */ SortedArrayOf<GlyphID> glyphArray; /* Array of GlyphIDs--in numerical order */ public: @@ -791,7 +789,7 @@ } else { rangeRecord[range].end = glyphs[i]; } - glyphs.advance (num_glyphs); + glyphs += num_glyphs; return_trace (true); } @@ -817,10 +815,12 @@ } template <typename set_t> - inline void add_coverage (set_t *glyphs) const { + inline bool add_coverage (set_t *glyphs) const { unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) - rangeRecord[i].add_coverage (glyphs); + if (unlikely (!rangeRecord[i].add_coverage (glyphs))) + return false; + return true; } public: @@ -860,7 +860,7 @@ private: protected: - USHORT coverageFormat; /* Format identifier--format = 2 */ + HBUINT16 coverageFormat; /* Format identifier--format = 2 */ SortedArrayOf<RangeRecord> rangeRecord; /* Array of glyph ranges--ordered by * Start GlyphID. rangeCount entries @@ -874,8 +874,8 @@ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const { switch (u.format) { - case 1: return u.format1.get_coverage(glyph_id); - case 2: return u.format2.get_coverage(glyph_id); + case 1: return u.format1.get_coverage (glyph_id); + case 2: return u.format2.get_coverage (glyph_id); default:return NOT_COVERED; } } @@ -927,12 +927,14 @@ } } + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ template <typename set_t> - inline void add_coverage (set_t *glyphs) const { + inline bool add_coverage (set_t *glyphs) const { switch (u.format) { - case 1: u.format1.add_coverage (glyphs); break; - case 2: u.format2.add_coverage (glyphs); break; - default: break; + case 1: return u.format1.add_coverage (glyphs); + case 2: return u.format2.add_coverage (glyphs); + default:return false; } } @@ -985,7 +987,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ CoverageFormat1 format1; CoverageFormat2 format2; } u; @@ -1018,11 +1020,36 @@ } template <typename set_t> - inline void add_class (set_t *glyphs, unsigned int klass) const { + inline bool add_coverage (set_t *glyphs) const { + unsigned int start = 0; unsigned int count = classValue.len; for (unsigned int i = 0; i < count; i++) + { + if (classValue[i]) + continue; + + if (start != i) + if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i))) + return false; + + start = i + 1; + } + if (start != count) + if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + count))) + return false; + + return true; + } + + template <typename set_t> + inline bool add_class (set_t *glyphs, unsigned int klass) const { + unsigned int count = classValue.len; + for (unsigned int i = 0; i < count; i++) + { if (classValue[i] == klass) glyphs->add (startGlyph + i); + } + return true; } inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { @@ -1030,7 +1057,7 @@ if (klass == 0) { /* Match if there's any glyph that is not listed! */ - hb_codepoint_t g = -1; + hb_codepoint_t g = HB_SET_VALUE_INVALID; if (!hb_set_next (glyphs, &g)) return false; if (g < startGlyph) @@ -1047,9 +1074,9 @@ } protected: - USHORT classFormat; /* Format identifier--format = 1 */ + HBUINT16 classFormat; /* Format identifier--format = 1 */ GlyphID startGlyph; /* First GlyphID of the classValueArray */ - ArrayOf<USHORT> + ArrayOf<HBUINT16> classValue; /* Array of Class Values--one per GlyphID */ public: DEFINE_SIZE_ARRAY (6, classValue); @@ -1075,11 +1102,25 @@ } template <typename set_t> - inline void add_class (set_t *glyphs, unsigned int klass) const { + inline bool add_coverage (set_t *glyphs) const { unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) + if (rangeRecord[i].value) + if (unlikely (!rangeRecord[i].add_coverage (glyphs))) + return false; + return true; + } + + template <typename set_t> + inline bool add_class (set_t *glyphs, unsigned int klass) const { + unsigned int count = rangeRecord.len; + for (unsigned int i = 0; i < count; i++) + { if (rangeRecord[i].value == klass) - rangeRecord[i].add_coverage (glyphs); + if (unlikely (!rangeRecord[i].add_coverage (glyphs))) + return false; + } + return true; } inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { @@ -1087,7 +1128,7 @@ if (klass == 0) { /* Match if there's any glyph that is not listed! */ - hb_codepoint_t g = (hb_codepoint_t) -1; + hb_codepoint_t g = HB_SET_VALUE_INVALID; for (unsigned int i = 0; i < count; i++) { if (!hb_set_next (glyphs, &g)) @@ -1096,7 +1137,7 @@ return true; g = rangeRecord[i].end; } - if (g != (hb_codepoint_t) -1 && hb_set_next (glyphs, &g)) + if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) return true; /* Fall through. */ } @@ -1107,7 +1148,7 @@ } protected: - USHORT classFormat; /* Format identifier--format = 2 */ + HBUINT16 classFormat; /* Format identifier--format = 2 */ SortedArrayOf<RangeRecord> rangeRecord; /* Array of glyph ranges--ordered by * Start GlyphID */ @@ -1120,8 +1161,8 @@ inline unsigned int get_class (hb_codepoint_t glyph_id) const { switch (u.format) { - case 1: return u.format1.get_class(glyph_id); - case 2: return u.format2.get_class(glyph_id); + case 1: return u.format1.get_class (glyph_id); + case 2: return u.format2.get_class (glyph_id); default:return 0; } } @@ -1137,11 +1178,25 @@ } } - inline void add_class (hb_set_t *glyphs, unsigned int klass) const { + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template <typename set_t> + inline bool add_coverage (set_t *glyphs) const { switch (u.format) { - case 1: u.format1.add_class (glyphs, klass); return; - case 2: u.format2.add_class (glyphs, klass); return; - default:return; + case 1: return u.format1.add_coverage (glyphs); + case 2: return u.format2.add_coverage (glyphs); + default:return false; + } + } + + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template <typename set_t> + inline bool add_class (set_t *glyphs, unsigned int klass) const { + switch (u.format) { + case 1: return u.format1.add_class (glyphs, klass); + case 2: return u.format2.add_class (glyphs, klass); + default:return false; } } @@ -1155,7 +1210,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ ClassDefFormat1 format1; ClassDefFormat2 format2; } u; @@ -1220,10 +1275,11 @@ const VarRegionAxis *axes = axesZ + (region_index * axisCount); float v = 1.; - unsigned int count = MIN (coord_len, (unsigned int) axisCount); + unsigned int count = axisCount; for (unsigned int i = 0; i < count; i++) { - float factor = axes[i].evaluate (coords[i]); + int coord = i < coord_len ? coords[i] : 0; + float factor = axes[i].evaluate (coord); if (factor == 0.) return 0.; v *= factor; @@ -1240,8 +1296,8 @@ } protected: - USHORT axisCount; - USHORT regionCount; + HBUINT16 axisCount; + HBUINT16 regionCount; VarRegionAxis axesZ[VAR]; public: DEFINE_SIZE_ARRAY (4, axesZ); @@ -1265,19 +1321,19 @@ unsigned int count = regionIndices.len; unsigned int scount = shortCount; - const BYTE *bytes = &StructAfter<BYTE> (regionIndices); - const BYTE *row = bytes + inner * (scount + count); + const HBUINT8 *bytes = &StructAfter<HBUINT8> (regionIndices); + const HBUINT8 *row = bytes + inner * (scount + count); float delta = 0.; unsigned int i = 0; - const SHORT *scursor = reinterpret_cast<const SHORT *> (row); + const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row); for (; i < scount; i++) { float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); delta += scalar * *scursor++; } - const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor); + const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor); for (; i < count; i++) { float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count); @@ -1293,15 +1349,15 @@ return_trace (c->check_struct (this) && regionIndices.sanitize(c) && shortCount <= regionIndices.len && - c->check_array (&StructAfter<BYTE> (regionIndices), + c->check_array (&StructAfter<HBUINT8> (regionIndices), get_row_size (), itemCount)); } protected: - USHORT itemCount; - USHORT shortCount; - ArrayOf<USHORT> regionIndices; - BYTE bytesX[VAR]; + HBUINT16 itemCount; + HBUINT16 shortCount; + ArrayOf<HBUINT16> regionIndices; + HBUINT8 bytesX[VAR]; public: DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX); }; @@ -1337,9 +1393,9 @@ } protected: - USHORT format; + HBUINT16 format; LOffsetTo<VarRegionList> regions; - OffsetArrayOf<VarData, ULONG> dataSets; + OffsetArrayOf<VarData, HBUINT32> dataSets; public: DEFINE_SIZE_ARRAY (8, dataSets); }; @@ -1366,8 +1422,8 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ - USHORT axisIndex; + HBUINT16 format; /* Format identifier--format = 1 */ + HBUINT16 axisIndex; F2DOT14 filterRangeMinValue; F2DOT14 filterRangeMaxValue; public: @@ -1396,7 +1452,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ ConditionFormat1 format1; } u; public: @@ -1421,7 +1477,7 @@ } protected: - OffsetArrayOf<Condition, ULONG> conditions; + OffsetArrayOf<Condition, HBUINT32> conditions; public: DEFINE_SIZE_ARRAY (2, conditions); }; @@ -1437,7 +1493,7 @@ } protected: - USHORT featureIndex; + HBUINT16 featureIndex; LOffsetTo<Feature> feature; public: DEFINE_SIZE_STATIC (6); @@ -1557,8 +1613,8 @@ 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))); + if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * HBUINT16::static_size; + return HBUINT16::static_size * (4 + ((endSize - startSize) >> (4 - f))); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -1603,14 +1659,14 @@ } protected: - USHORT startSize; /* Smallest size to correct--in ppem */ - USHORT endSize; /* Largest size to correct--in ppem */ - USHORT deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 + HBUINT16 startSize; /* Smallest size to correct--in ppem */ + HBUINT16 endSize; /* Largest size to correct--in ppem */ + HBUINT16 deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3 * 1 Signed 2-bit value, 8 values per uint16 * 2 Signed 4-bit value, 4 values per uint16 * 3 Signed 8-bit value, 2 values per uint16 */ - USHORT deltaValue[VAR]; /* Array of compressed data */ + HBUINT16 deltaValue[VAR]; /* Array of compressed data */ public: DEFINE_SIZE_ARRAY (6, deltaValue); }; @@ -1641,9 +1697,9 @@ } protected: - USHORT outerIndex; - USHORT innerIndex; - USHORT deltaFormat; /* Format identifier for this table: 0x0x8000 */ + HBUINT16 outerIndex; + HBUINT16 innerIndex; + HBUINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */ public: DEFINE_SIZE_STATIC (6); }; @@ -1651,10 +1707,10 @@ struct DeviceHeader { protected: - USHORT reserved1; - USHORT reserved2; + HBUINT16 reserved1; + HBUINT16 reserved2; public: - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ public: DEFINE_SIZE_STATIC (6); };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gdef-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gdef-table.hh Wed May 30 12:20:00 2018 -0700 @@ -41,7 +41,7 @@ * Attachment List Table */ -typedef ArrayOf<USHORT> AttachPoint; /* Array of contour point indices--in +typedef ArrayOf<HBUINT16> AttachPoint; /* Array of contour point indices--in * increasing numerical order */ struct AttachList @@ -62,7 +62,7 @@ const AttachPoint &points = this+attachPoint[index]; if (point_count) { - const USHORT *array = points.sub_array (start_offset, point_count); + const HBUINT16 *array = points.sub_array (start_offset, point_count); unsigned int count = *point_count; for (unsigned int i = 0; i < count; i++) point_array[i] = array[i]; @@ -109,8 +109,8 @@ } protected: - USHORT caretValueFormat; /* Format identifier--format = 1 */ - SHORT coordinate; /* X or Y value, in design units */ + HBUINT16 caretValueFormat; /* Format identifier--format = 1 */ + FWORD coordinate; /* X or Y value, in design units */ public: DEFINE_SIZE_STATIC (4); }; @@ -136,8 +136,8 @@ } protected: - USHORT caretValueFormat; /* Format identifier--format = 2 */ - USHORT caretValuePoint; /* Contour point index on glyph */ + HBUINT16 caretValueFormat; /* Format identifier--format = 2 */ + HBUINT16 caretValuePoint; /* Contour point index on glyph */ public: DEFINE_SIZE_STATIC (4); }; @@ -160,8 +160,8 @@ } protected: - USHORT caretValueFormat; /* Format identifier--format = 3 */ - SHORT coordinate; /* X or Y value, in design units */ + HBUINT16 caretValueFormat; /* Format identifier--format = 3 */ + FWORD coordinate; /* X or Y value, in design units */ OffsetTo<Device> deviceTable; /* Offset to Device table for X or Y * value--from beginning of CaretValue @@ -199,7 +199,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ CaretValueFormat1 format1; CaretValueFormat2 format2; CaretValueFormat3 format3; @@ -294,7 +294,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ ArrayOf<LOffsetTo<Coverage> > coverage; /* Array of long offsets to mark set * coverage tables */ @@ -324,7 +324,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ MarkGlyphSetsFormat1 format1; } u; public:
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gpos-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gpos-table.hh Wed May 30 12:20:00 2018 -0700 @@ -51,11 +51,11 @@ /* Shared Tables: ValueRecord, Anchor Table, and MarkArray */ -typedef USHORT Value; +typedef HBUINT16 Value; typedef Value ValueRecord[VAR]; -struct ValueFormat : USHORT +struct ValueFormat : HBUINT16 { enum Flags { xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */ @@ -74,14 +74,14 @@ /* All fields are options. Only those available advance the value pointer. */ #if 0 - SHORT xPlacement; /* Horizontal adjustment for + HBINT16 xPlacement; /* Horizontal adjustment for * placement--in design units */ - SHORT yPlacement; /* Vertical adjustment for + HBINT16 yPlacement; /* Vertical adjustment for * placement--in design units */ - SHORT xAdvance; /* Horizontal adjustment for + HBINT16 xAdvance; /* Horizontal adjustment for * advance--in design units (only used * for horizontal writing) */ - SHORT yAdvance; /* Vertical adjustment for advance--in + HBINT16 yAdvance; /* Vertical adjustment for advance--in * design units (only used for vertical * writing) */ Offset xPlaDevice; /* Offset to Device table for @@ -99,11 +99,11 @@ #endif inline unsigned int get_len (void) const - { return _hb_popcount32 ((unsigned int) *this); } + { return _hb_popcount ((unsigned int) *this); } inline unsigned int get_size (void) const { return get_len () * Value::static_size; } - void apply_value (hb_apply_context_t *c, + void apply_value (hb_ot_apply_context_t *c, const void *base, const Value *values, hb_glyph_position_t &glyph_pos) const @@ -178,8 +178,8 @@ static inline const OffsetTo<Device>& get_device (const Value* value) { return *CastP<OffsetTo<Device> > (value); } - static inline const SHORT& get_short (const Value* value) - { return *CastP<SHORT> (value); } + static inline const HBINT16& get_short (const Value* value) + { return *CastP<HBINT16> (value); } public: @@ -232,12 +232,12 @@ struct AnchorFormat1 { - 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 + inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED, + float *x, float *y) const { hb_font_t *font = c->font; - *x = font->em_scale_x (xCoordinate); - *y = font->em_scale_y (yCoordinate); + *x = font->em_fscale_x (xCoordinate); + *y = font->em_fscale_y (yCoordinate); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -247,17 +247,17 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ - SHORT xCoordinate; /* Horizontal value--in design units */ - SHORT yCoordinate; /* Vertical value--in design units */ + HBUINT16 format; /* Format identifier--format = 1 */ + FWORD xCoordinate; /* Horizontal value--in design units */ + FWORD yCoordinate; /* Vertical value--in design units */ public: DEFINE_SIZE_STATIC (6); }; struct AnchorFormat2 { - inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id, - hb_position_t *x, hb_position_t *y) const + inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id, + float *x, float *y) const { hb_font_t *font = c->font; unsigned int x_ppem = font->x_ppem; @@ -267,8 +267,8 @@ 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); + *x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate); + *y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -278,22 +278,22 @@ } protected: - USHORT format; /* Format identifier--format = 2 */ - SHORT xCoordinate; /* Horizontal value--in design units */ - SHORT yCoordinate; /* Vertical value--in design units */ - USHORT anchorPoint; /* Index to glyph contour point */ + HBUINT16 format; /* Format identifier--format = 2 */ + FWORD xCoordinate; /* Horizontal value--in design units */ + FWORD yCoordinate; /* Vertical value--in design units */ + HBUINT16 anchorPoint; /* Index to glyph contour point */ public: DEFINE_SIZE_STATIC (8); }; struct AnchorFormat3 { - 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 + inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED, + float *x, float *y) const { hb_font_t *font = c->font; - *x = font->em_scale_x (xCoordinate); - *y = font->em_scale_y (yCoordinate); + *x = font->em_fscale_x (xCoordinate); + *y = font->em_fscale_y (yCoordinate); if (font->x_ppem || font->num_coords) *x += (this+xDeviceTable).get_x_delta (font, c->var_store); @@ -308,9 +308,9 @@ } protected: - USHORT format; /* Format identifier--format = 3 */ - SHORT xCoordinate; /* Horizontal value--in design units */ - SHORT yCoordinate; /* Vertical value--in design units */ + HBUINT16 format; /* Format identifier--format = 3 */ + FWORD xCoordinate; /* Horizontal value--in design units */ + FWORD yCoordinate; /* Vertical value--in design units */ OffsetTo<Device> xDeviceTable; /* Offset to Device table for X * coordinate-- from beginning of @@ -325,15 +325,15 @@ struct Anchor { - inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id, - hb_position_t *x, hb_position_t *y) const + inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id, + float *x, float *y) const { *x = *y = 0; switch (u.format) { 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; + default: return; } } @@ -351,7 +351,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ AnchorFormat1 format1; AnchorFormat2 format2; AnchorFormat3 format3; @@ -382,7 +382,7 @@ return_trace (true); } - USHORT rows; /* Number of rows */ + HBUINT16 rows; /* Number of rows */ protected: OffsetTo<Anchor> matrixZ[VAR]; /* Matrix of offsets to Anchor tables-- @@ -403,7 +403,7 @@ } protected: - USHORT klass; /* Class defined for this mark */ + HBUINT16 klass; /* Class defined for this mark */ OffsetTo<Anchor> markAnchor; /* Offset to Anchor table--from * beginning of MarkArray table */ @@ -413,7 +413,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage order */ { - inline bool apply (hb_apply_context_t *c, + inline bool apply (hb_ot_apply_context_t *c, unsigned int mark_index, unsigned int glyph_index, const AnchorMatrix &anchors, unsigned int class_count, unsigned int glyph_pos) const @@ -430,15 +430,15 @@ * return false such that the subsequent subtables have a chance at it. */ if (unlikely (!found)) return_trace (false); - hb_position_t mark_x, mark_y, base_x, base_y; + float mark_x, mark_y, base_x, base_y; buffer->unsafe_to_break (glyph_pos, buffer->idx); 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.x_offset = round (base_x - mark_x); + o.y_offset = round (base_y - mark_y); 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; @@ -462,7 +462,7 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+coverage).add_coverage (c->input); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; } inline const Coverage &get_coverage (void) const @@ -470,7 +470,7 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; @@ -492,7 +492,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ @@ -510,7 +510,7 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+coverage).add_coverage (c->input); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; } inline const Coverage &get_coverage (void) const @@ -518,7 +518,7 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; @@ -544,13 +544,13 @@ } protected: - USHORT format; /* Format identifier--format = 2 */ + HBUINT16 format; /* Format identifier--format = 2 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat; /* Defines the types of data in the * ValueRecord */ - USHORT valueCount; /* Number of ValueRecords */ + HBUINT16 valueCount; /* Number of ValueRecords */ ValueRecord values; /* Array of ValueRecords--positioning * values applied to glyphs */ public: @@ -573,7 +573,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ SinglePosFormat1 format1; SinglePosFormat2 format2; } u; @@ -604,18 +604,13 @@ TRACE_COLLECT_GLYPHS (this); unsigned int len1 = valueFormats[0].get_len (); unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = USHORT::static_size * (1 + len1 + len2); + unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - { - c->input->add (record->secondGlyph); - record = &StructAtOffset<PairValueRecord> (record, record_size); - } + c->input->add_array (&record->secondGlyph, len, record_size); } - inline bool apply (hb_apply_context_t *c, + inline bool apply (hb_ot_apply_context_t *c, const ValueFormat *valueFormats, unsigned int pos) const { @@ -623,7 +618,7 @@ hb_buffer_t *buffer = c->buffer; unsigned int len1 = valueFormats[0].get_len (); unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = USHORT::static_size * (1 + len1 + len2); + unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ); unsigned int count = len; @@ -668,7 +663,7 @@ { TRACE_SANITIZE (this); if (!(c->check_struct (this) - && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return_trace (false); + && c->check_array (arrayZ, HBUINT16::static_size * closure->stride, len))) return_trace (false); unsigned int count = len; const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); @@ -677,8 +672,8 @@ } protected: - USHORT len; /* Number of PairValueRecords */ - USHORT arrayZ[VAR]; /* Array of PairValueRecords--ordered + HBUINT16 len; /* Number of PairValueRecords */ + HBUINT16 arrayZ[VAR]; /* Array of PairValueRecords--ordered * by GlyphID of the second glyph */ public: DEFINE_SIZE_ARRAY (2, arrayZ); @@ -689,7 +684,7 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+coverage).add_coverage (c->input); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; unsigned int count = pairSet.len; for (unsigned int i = 0; i < count; i++) (this+pairSet[i]).collect_glyphs (c, valueFormat); @@ -700,14 +695,14 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); if (!skippy_iter.next ()) return_trace (false); @@ -733,7 +728,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ @@ -755,17 +750,8 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+coverage).add_coverage (c->input); - - unsigned int count1 = class1Count; - const ClassDef &klass1 = this+classDef1; - for (unsigned int i = 0; i < count1; i++) - klass1.add_class (c->input, i); - - unsigned int count2 = class2Count; - const ClassDef &klass2 = this+classDef2; - for (unsigned int i = 0; i < count2; i++) - klass2.add_class (c->input, i); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; + if (unlikely (!(this+classDef2).add_coverage (c->input))) return; } inline const Coverage &get_coverage (void) const @@ -773,14 +759,14 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); if (!skippy_iter.next ()) return_trace (false); @@ -823,7 +809,7 @@ } protected: - USHORT format; /* Format identifier--format = 2 */ + HBUINT16 format; /* Format identifier--format = 2 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ @@ -841,9 +827,9 @@ classDef2; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the second glyph of the pair */ - USHORT class1Count; /* Number of classes in ClassDef1 + HBUINT16 class1Count; /* Number of classes in ClassDef1 * table--includes Class0 */ - USHORT class2Count; /* Number of classes in ClassDef2 + HBUINT16 class2Count; /* Number of classes in ClassDef2 * table--includes Class0 */ ValueRecord values; /* Matrix of value pairs: * class1-major, class2-minor, @@ -868,7 +854,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ PairPosFormat1 format1; PairPosFormat2 format2; } u; @@ -906,7 +892,7 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+coverage).add_coverage (c->input); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; } inline const Coverage &get_coverage (void) const @@ -914,7 +900,7 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; @@ -922,7 +908,7 @@ const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; if (!this_record.exitAnchor) return_trace (false); - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); if (!skippy_iter.next ()) return_trace (false); @@ -933,7 +919,7 @@ unsigned int j = skippy_iter.idx; buffer->unsafe_to_break (i, j); - hb_position_t entry_x, entry_y, exit_x, exit_y; + float entry_x, entry_y, exit_x, exit_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); @@ -943,32 +929,32 @@ /* Main-direction adjustment */ switch (c->direction) { case HB_DIRECTION_LTR: - pos[i].x_advance = exit_x + pos[i].x_offset; + pos[i].x_advance = round (exit_x) + pos[i].x_offset; - d = entry_x + pos[j].x_offset; + d = round (entry_x) + pos[j].x_offset; pos[j].x_advance -= d; pos[j].x_offset -= d; break; case HB_DIRECTION_RTL: - d = exit_x + pos[i].x_offset; + d = round (exit_x) + pos[i].x_offset; pos[i].x_advance -= d; pos[i].x_offset -= d; - pos[j].x_advance = entry_x + pos[j].x_offset; + pos[j].x_advance = round (entry_x) + pos[j].x_offset; break; case HB_DIRECTION_TTB: - pos[i].y_advance = exit_y + pos[i].y_offset; + pos[i].y_advance = round (exit_y) + pos[i].y_offset; - d = entry_y + pos[j].y_offset; + d = round (entry_y) + pos[j].y_offset; pos[j].y_advance -= d; pos[j].y_offset -= d; break; case HB_DIRECTION_BTT: - d = exit_y + pos[i].y_offset; + d = round (exit_y) + pos[i].y_offset; pos[i].y_advance -= d; pos[i].y_offset -= d; - pos[j].y_advance = entry_y; + pos[j].y_advance = round (entry_y); break; case HB_DIRECTION_INVALID: default: @@ -1022,7 +1008,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ @@ -1048,7 +1034,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ CursivePosFormat1 format1; } u; }; @@ -1064,8 +1050,8 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+markCoverage).add_coverage (c->input); - (this+baseCoverage).add_coverage (c->input); + if (unlikely (!(this+markCoverage).add_coverage (c->input))) return; + if (unlikely (!(this+baseCoverage).add_coverage (c->input))) return; } inline const Coverage &get_coverage (void) const @@ -1073,7 +1059,7 @@ return this+markCoverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; @@ -1081,14 +1067,22 @@ if (likely (mark_index == NOT_COVERED)) return_trace (false); /* Now we search backwards for a non-mark glyph */ - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); do { if (!skippy_iter.prev ()) return_trace (false); - /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */ + /* We only want to attach to the first of a MultipleSubst sequence. + * https://github.com/harfbuzz/harfbuzz/issues/740 + * Reject others. */ if (!_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx]) || - 0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) + 0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) || + (skippy_iter.idx == 0 || + _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) != + _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) || + _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) != + _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx - 1]) + 1 + )) break; skippy_iter.reject (); } while (1); @@ -1113,14 +1107,14 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> markCoverage; /* Offset to MarkCoverage table--from * beginning of MarkBasePos subtable */ OffsetTo<Coverage> baseCoverage; /* Offset to BaseCoverage table--from * beginning of MarkBasePos subtable */ - USHORT classCount; /* Number of classes defined for marks */ + HBUINT16 classCount; /* Number of classes defined for marks */ OffsetTo<MarkArray> markArray; /* Offset to MarkArray table--from * beginning of MarkBasePos subtable */ @@ -1146,7 +1140,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ MarkBasePosFormat1 format1; } u; }; @@ -1167,8 +1161,8 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+markCoverage).add_coverage (c->input); - (this+ligatureCoverage).add_coverage (c->input); + if (unlikely (!(this+markCoverage).add_coverage (c->input))) return; + if (unlikely (!(this+ligatureCoverage).add_coverage (c->input))) return; } inline const Coverage &get_coverage (void) const @@ -1176,7 +1170,7 @@ return this+markCoverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; @@ -1184,7 +1178,7 @@ if (likely (mark_index == NOT_COVERED)) return_trace (false); /* Now we search backwards for a non-mark glyph */ - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + hb_ot_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); @@ -1230,7 +1224,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> markCoverage; /* Offset to Mark Coverage table--from * beginning of MarkLigPos subtable */ @@ -1238,7 +1232,7 @@ ligatureCoverage; /* Offset to Ligature Coverage * table--from beginning of MarkLigPos * subtable */ - USHORT classCount; /* Number of defined mark classes */ + HBUINT16 classCount; /* Number of defined mark classes */ OffsetTo<MarkArray> markArray; /* Offset to MarkArray table--from * beginning of MarkLigPos subtable */ @@ -1264,7 +1258,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ MarkLigPosFormat1 format1; } u; }; @@ -1280,8 +1274,8 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+mark1Coverage).add_coverage (c->input); - (this+mark2Coverage).add_coverage (c->input); + if (unlikely (!(this+mark1Coverage).add_coverage (c->input))) return; + if (unlikely (!(this+mark2Coverage).add_coverage (c->input))) return; } inline const Coverage &get_coverage (void) const @@ -1289,7 +1283,7 @@ return this+mark1Coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; @@ -1297,7 +1291,7 @@ if (likely (mark1_index == NOT_COVERED)) return_trace (false); /* now we search backwards for a suitable mark glyph until a non-mark glyph */ - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); if (!skippy_iter.prev ()) return_trace (false); @@ -1344,7 +1338,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> mark1Coverage; /* Offset to Combining Mark1 Coverage * table--from beginning of MarkMarkPos @@ -1353,7 +1347,7 @@ mark2Coverage; /* Offset to Combining Mark2 Coverage * table--from beginning of MarkMarkPos * subtable */ - USHORT classCount; /* Number of defined mark classes */ + HBUINT16 classCount; /* Number of defined mark classes */ OffsetTo<MarkArray> mark1Array; /* Offset to Mark1Array table--from * beginning of MarkMarkPos subtable */ @@ -1379,7 +1373,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ MarkMarkPosFormat1 format1; } u; }; @@ -1438,7 +1432,7 @@ protected: union { - USHORT sub_format; + HBUINT16 sub_format; SinglePos single; PairPos pair; CursivePos cursive; @@ -1464,7 +1458,7 @@ return false; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); return_trace (dispatch (c)); @@ -1483,7 +1477,7 @@ dispatch (&c); } - static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); + static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); template <typename context_t> static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); @@ -1635,7 +1629,7 @@ return l.dispatch (c); } -/*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) +/*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) { const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); const PosLookup &l = gpos.get_lookup (lookup_index);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsub-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsub-table.hh Wed May 30 12:20:00 2018 -0700 @@ -44,7 +44,7 @@ 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 */ + * https://github.com/harfbuzz/harfbuzz/issues/363 */ hb_codepoint_t glyph_id = iter.get_glyph (); if (c->glyphs->has (glyph_id)) c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFFu); @@ -54,13 +54,13 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; Coverage::Iter iter; 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 */ + * https://github.com/harfbuzz/harfbuzz/issues/363 */ hb_codepoint_t glyph_id = iter.get_glyph (); - c->input->add (glyph_id); c->output->add ((glyph_id + deltaGlyphID) & 0xFFFFu); } } @@ -76,7 +76,7 @@ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; @@ -110,11 +110,11 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - SHORT deltaGlyphID; /* Add to original GlyphID to get + HBINT16 deltaGlyphID; /* Add to original GlyphID to get * substitute GlyphID */ public: DEFINE_SIZE_STATIC (6); @@ -130,7 +130,7 @@ 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 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) c->glyphs->add (substitute[iter.get_coverage ()]); } @@ -139,13 +139,13 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; Coverage::Iter iter; 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 ()); + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ c->output->add (substitute[iter.get_coverage ()]); } } @@ -161,7 +161,7 @@ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; @@ -195,7 +195,7 @@ } protected: - USHORT format; /* Format identifier--format = 2 */ + HBUINT16 format; /* Format identifier--format = 2 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ @@ -249,7 +249,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ SingleSubstFormat1 format1; SingleSubstFormat2 format2; } u; @@ -269,12 +269,10 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - unsigned int count = substitute.len; - for (unsigned int i = 0; i < count; i++) - c->output->add (substitute[i]); + c->output->add_array (substitute.array, substitute.len); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int count = substitute.len; @@ -287,7 +285,7 @@ return_trace (true); } /* Spec disallows this, but Uniscribe allows it. - * https://github.com/behdad/harfbuzz/issues/253 */ + * https://github.com/harfbuzz/harfbuzz/issues/253 */ else if (unlikely (count == 0)) { c->buffer->delete_glyph (); @@ -339,7 +337,7 @@ 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 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) (this+sequence[iter.get_coverage ()]).closure (c); } @@ -348,7 +346,7 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - (this+coverage).add_coverage (c->input); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; unsigned int count = sequence.len; for (unsigned int i = 0; i < count; i++) (this+sequence[i]).collect_glyphs (c); @@ -365,7 +363,7 @@ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); @@ -388,7 +386,7 @@ if (unlikely (!sequence[i].serialize (c, this).serialize (c, substitute_glyphs_list, substitute_len_list[i]))) return_trace (false); - substitute_len_list.advance (num_glyphs); + substitute_len_list += num_glyphs; if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); return_trace (true); } @@ -400,7 +398,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ @@ -442,7 +440,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ MultipleSubstFormat1 format1; } u; }; @@ -461,7 +459,7 @@ 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 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/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; @@ -474,17 +472,15 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; Coverage::Iter iter; 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 ()); + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()]; - unsigned int count = alt_set.len; - for (unsigned int i = 0; i < count; i++) - c->output->add (alt_set[i]); + c->output->add_array (alt_set.array, alt_set.len); } } @@ -499,7 +495,7 @@ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; @@ -540,7 +536,7 @@ if (unlikely (!alternateSet[i].serialize (c, this).serialize (c, alternate_glyphs_list, alternate_len_list[i]))) return_trace (false); - alternate_len_list.advance (num_glyphs); + alternate_len_list += num_glyphs; if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); return_trace (true); } @@ -552,7 +548,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ @@ -594,7 +590,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ AlternateSubstFormat1 format1; } u; }; @@ -615,9 +611,7 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - unsigned int count = component.len; - for (unsigned int i = 1; i < count; i++) - c->input->add (component[i]); + c->input->add_array (component.array, component.len ? component.len - 1 : 0); c->output->add (ligGlyph); } @@ -634,7 +628,7 @@ return_trace (true); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int count = component.len; @@ -736,7 +730,7 @@ return_trace (false); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int num_ligs = ligature.len; @@ -763,8 +757,8 @@ ligatures[i], component_list, component_count_list[i]))) return_trace (false); - ligatures.advance (num_ligatures); - component_count_list.advance (num_ligatures); + ligatures += num_ligatures; + component_count_list += num_ligatures; return_trace (true); } @@ -792,7 +786,7 @@ 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 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) (this+ligatureSet[iter.get_coverage ()]).closure (c); } @@ -801,13 +795,13 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; Coverage::Iter iter; 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 ()); + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c); } } @@ -827,7 +821,7 @@ return_trace (lig_set.would_apply (c)); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; @@ -856,7 +850,7 @@ component_count_list, ligature_per_first_glyph_count_list[i], component_list))) return_trace (false); - ligature_per_first_glyph_count_list.advance (num_first_glyphs); + ligature_per_first_glyph_count_list += num_first_glyphs; if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return_trace (false); return_trace (true); } @@ -868,7 +862,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ @@ -918,7 +912,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ LigatureSubstFormat1 format1; } u; }; @@ -961,7 +955,7 @@ 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 */ + break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */ if (c->glyphs->has (iter.get_glyph ())) c->glyphs->add (substitute[iter.get_coverage ()]); } @@ -970,25 +964,22 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - - const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); + if (unlikely (!(this+coverage).add_coverage (c->input))) return; unsigned int count; - (this+coverage).add_coverage (c->input); - count = backtrack.len; for (unsigned int i = 0; i < count; i++) - (this+backtrack[i]).add_coverage (c->before); + if (unlikely (!(this+backtrack[i]).add_coverage (c->before))) return; + const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); count = lookahead.len; for (unsigned int i = 0; i < count; i++) - (this+lookahead[i]).add_coverage (c->after); + if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return; const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); count = substitute.len; - for (unsigned int i = 0; i < count; i++) - c->output->add (substitute[i]); + c->output->add_array (substitute.array, substitute.len); } inline const Coverage &get_coverage (void) const @@ -1002,7 +993,7 @@ return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL)) @@ -1016,11 +1007,11 @@ unsigned int start_index = 0, end_index = 0; if (match_backtrack (c, - backtrack.len, (USHORT *) backtrack.array, + backtrack.len, (HBUINT16 *) backtrack.array, match_coverage, this, &start_index) && match_lookahead (c, - lookahead.len, (USHORT *) lookahead.array, + lookahead.len, (HBUINT16 *) lookahead.array, match_coverage, this, 1, &end_index)) { @@ -1048,7 +1039,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -1082,7 +1073,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ ReverseChainSingleSubstFormat1 format1; } u; }; @@ -1128,7 +1119,7 @@ protected: union { - USHORT sub_format; + HBUINT16 sub_format; SingleSubst single; MultipleSubst multiple; AlternateSubst alternate; @@ -1159,7 +1150,7 @@ return lookup_type_is_reverse (type); } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); return_trace (dispatch (c)); @@ -1195,7 +1186,7 @@ return_trace (dispatch (c)); } - static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); + static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index); inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, unsigned int i) @@ -1280,8 +1271,9 @@ if (unlikely (get_type () == SubstLookupSubTable::Extension)) { /* The spec says all subtables of an Extension lookup should - * have the same type. This is specially important if one has - * a reverse type! */ + * have the same type, which shall not be the Extension type + * itself (but we already checked for that). + * This is specially important if one has a reverse type! */ unsigned int type = get_subtable (0).u.extension.get_type (); unsigned int count = get_subtable_count (); for (unsigned int i = 1; i < count; i++) @@ -1351,7 +1343,7 @@ return l.dispatch (c); } -/*static*/ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index) +/*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index) { const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); const SubstLookup &l = gsub.get_lookup (lookup_index);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsubgpos-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-gsubgpos-private.hh Wed May 30 12:20:00 2018 -0700 @@ -218,8 +218,8 @@ }; -struct hb_apply_context_t : - hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY> +struct hb_ot_apply_context_t : + hb_dispatch_context_t<hb_ot_apply_context_t, bool, HB_DEBUG_APPLY> { struct matcher_t { @@ -234,7 +234,7 @@ match_func (nullptr), match_data (nullptr) {}; - typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); + typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data); inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; } inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; } @@ -252,7 +252,7 @@ }; inline may_match_t may_match (const hb_glyph_info_t &info, - const USHORT *glyph_data) const + const HBUINT16 *glyph_data) const { if (!(info.mask & mask) || (syllable && syllable != info.syllable ())) @@ -271,7 +271,7 @@ }; inline may_skip_t - may_skip (const hb_apply_context_t *c, + may_skip (const hb_ot_apply_context_t *c, const hb_glyph_info_t &info) const { if (!c->check_glyph_property (&info, lookup_props)) @@ -297,7 +297,7 @@ struct skipping_iterator_t { - inline void init (hb_apply_context_t *c_, bool context_match = false) + inline void init (hb_ot_apply_context_t *c_, bool context_match = false) { c = c_; match_glyph_data = nullptr; @@ -315,7 +315,7 @@ } inline void set_match_func (matcher_t::match_func_t match_func_, const void *match_data_, - const USHORT glyph_data[]) + const HBUINT16 glyph_data[]) { matcher.set_match_func (match_func_, match_data_); match_glyph_data = glyph_data; @@ -333,8 +333,7 @@ inline void reject (void) { num_items++; match_glyph_data--; } inline matcher_t::may_skip_t - may_skip (const hb_apply_context_t *c, - const hb_glyph_info_t &info) const + may_skip (const hb_glyph_info_t &info) const { return matcher.may_skip (c, info); } @@ -396,9 +395,9 @@ unsigned int idx; protected: - hb_apply_context_t *c; + hb_ot_apply_context_t *c; matcher_t matcher; - const USHORT *match_glyph_data; + const HBUINT16 *match_glyph_data; unsigned int num_items; unsigned int end; @@ -406,18 +405,18 @@ inline const char *get_name (void) { return "APPLY"; } - typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); + typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index); template <typename T> inline return_t dispatch (const T &obj) { return obj.apply (this); } static return_t default_return_value (void) { return false; } bool stop_sublookup_iteration (return_t r) const { return r; } - return_t recurse (unsigned int lookup_index) + return_t recurse (unsigned int sub_lookup_index) { - if (unlikely (nesting_level_left == 0 || !recurse_func)) + if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0)) return default_return_value (); nesting_level_left--; - bool ret = recurse_func (this, lookup_index); + bool ret = recurse_func (this, sub_lookup_index); nesting_level_left++; return ret; } @@ -444,7 +443,7 @@ bool has_glyph_classes; - hb_apply_context_t (unsigned int table_index_, + hb_ot_apply_context_t (unsigned int table_index_, hb_font_t *font_, hb_buffer_t *buffer_) : iter_input (), iter_context (), @@ -568,9 +567,9 @@ -typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); -typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data); -typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data); +typedef bool (*intersects_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data); +typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data); +typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data); struct ContextClosureFuncs { @@ -586,16 +585,16 @@ }; -static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) +static inline bool intersects_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) { return glyphs->has (value); } -static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data) +static inline bool intersects_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); return class_def.intersects_class (glyphs, value); } -static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) +static inline bool intersects_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data) { const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; return (data+coverage).intersects (glyphs); @@ -603,7 +602,7 @@ static inline bool intersects_array (hb_closure_context_t *c, unsigned int count, - const USHORT values[], + const HBUINT16 values[], intersects_func_t intersects_func, const void *intersects_data) { @@ -614,16 +613,16 @@ } -static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED) +static inline void collect_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) { glyphs->add (value); } -static inline void collect_class (hb_set_t *glyphs, const USHORT &value, const void *data) +static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); class_def.add_class (glyphs, value); } -static inline void collect_coverage (hb_set_t *glyphs, const USHORT &value, const void *data) +static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data) { const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; (data+coverage).add_coverage (glyphs); @@ -631,7 +630,7 @@ static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, hb_set_t *glyphs, unsigned int count, - const USHORT values[], + const HBUINT16 values[], collect_glyphs_func_t collect_func, const void *collect_data) { @@ -640,16 +639,16 @@ } -static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED) +static inline bool match_glyph (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data HB_UNUSED) { return glyph_id == value; } -static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data) +static inline bool match_class (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); return class_def.get_class (glyph_id) == value; } -static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data) +static inline bool match_coverage (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data) { const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value; return (data+coverage).get_coverage (glyph_id) != NOT_COVERED; @@ -657,7 +656,7 @@ static inline bool would_match_input (hb_would_apply_context_t *c, unsigned int count, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data) { @@ -670,9 +669,9 @@ return true; } -static inline bool match_input (hb_apply_context_t *c, +static inline bool match_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data, unsigned int *end_offset, @@ -686,7 +685,7 @@ hb_buffer_t *buffer = c->buffer; - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, count - 1); skippy_iter.set_match_func (match_func, match_data, input); @@ -711,7 +710,7 @@ * o If two marks want to ligate and they belong to different components of the * same ligature glyph, and said ligature glyph is to be ignored according to * mark-filtering rules, then allow. - * https://github.com/behdad/harfbuzz/issues/545 + * https://github.com/harfbuzz/harfbuzz/issues/545 */ bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur()); @@ -763,7 +762,7 @@ j--; } - if (found && skippy_iter.may_skip (c, out[j]) == hb_apply_context_t::matcher_t::SKIP_YES) + if (found && skippy_iter.may_skip (out[j]) == hb_ot_apply_context_t::matcher_t::SKIP_YES) ligbase = LIGBASE_MAY_SKIP; else ligbase = LIGBASE_MAY_NOT_SKIP; @@ -796,7 +795,7 @@ return_trace (true); } -static inline bool ligate_input (hb_apply_context_t *c, +static inline bool ligate_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int match_length, @@ -894,16 +893,16 @@ return_trace (true); } -static inline bool match_backtrack (hb_apply_context_t *c, +static inline bool match_backtrack (hb_ot_apply_context_t *c, unsigned int count, - const USHORT backtrack[], + const HBUINT16 backtrack[], match_func_t match_func, const void *match_data, unsigned int *match_start) { TRACE_APPLY (nullptr); - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->backtrack_len (), count); skippy_iter.set_match_func (match_func, match_data, backtrack); @@ -916,9 +915,9 @@ return_trace (true); } -static inline bool match_lookahead (hb_apply_context_t *c, +static inline bool match_lookahead (hb_ot_apply_context_t *c, unsigned int count, - const USHORT lookahead[], + const HBUINT16 lookahead[], match_func_t match_func, const void *match_data, unsigned int offset, @@ -926,7 +925,7 @@ { TRACE_APPLY (nullptr); - hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; + hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->idx + offset - 1, count); skippy_iter.set_match_func (match_func, match_data, lookahead); @@ -949,9 +948,9 @@ return_trace (c->check_struct (this)); } - USHORT sequenceIndex; /* Index into current glyph + HBUINT16 sequenceIndex; /* Index into current glyph * sequence--first glyph = 0 */ - USHORT lookupListIndex; /* Lookup to apply to that + HBUINT16 lookupListIndex; /* Lookup to apply to that * position--zero--based */ public: DEFINE_SIZE_STATIC (4); @@ -967,7 +966,7 @@ c->recurse (lookupRecord[i].lookupListIndex); } -static inline bool apply_lookup (hb_apply_context_t *c, +static inline bool apply_lookup (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph */ unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int lookupCount, @@ -1002,7 +1001,11 @@ if (idx == 0 && lookupRecord[i].lookupListIndex == c->lookup_index) continue; - buffer->move_to (match_positions[idx]); + if (unlikely (!buffer->move_to (match_positions[idx]))) + break; + + if (unlikely (buffer->max_ops <= 0)) + break; unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len (); if (!c->recurse (lookupRecord[i].lookupListIndex)) @@ -1108,7 +1111,7 @@ static inline void context_closure_lookup (hb_closure_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextClosureLookupContext &lookup_context) @@ -1122,7 +1125,7 @@ static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextCollectGlyphsLookupContext &lookup_context) @@ -1136,7 +1139,7 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, ContextApplyLookupContext &lookup_context) @@ -1145,9 +1148,9 @@ inputCount, input, lookup_context.funcs.match, lookup_context.match_data); } -static inline bool context_apply_lookup (hb_apply_context_t *c, +static inline bool context_apply_lookup (hb_ot_apply_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextApplyLookupContext &lookup_context) @@ -1194,7 +1197,7 @@ return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); } - inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const + inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); @@ -1209,20 +1212,20 @@ lookupCount.sanitize (c) && c->check_range (inputZ, inputZ[0].static_size * inputCount + - lookupRecordX[0].static_size * lookupCount)); + LookupRecord::static_size * lookupCount)); } protected: - USHORT inputCount; /* Total number of glyphs in input + HBUINT16 inputCount; /* Total number of glyphs in input * glyph sequence--includes the first * glyph */ - USHORT lookupCount; /* Number of LookupRecords */ - USHORT inputZ[VAR]; /* Array of match inputs--start with + HBUINT16 lookupCount; /* Number of LookupRecords */ + HBUINT16 inputZ[VAR]; /* Array of match inputs--start with * second glyph */ - LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in +/*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in * design order */ public: - DEFINE_SIZE_ARRAY2 (4, inputZ, lookupRecordX); + DEFINE_SIZE_ARRAY (4, inputZ); }; struct RuleSet @@ -1255,7 +1258,7 @@ return_trace (false); } - inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const + inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); unsigned int num_rules = rule.len; @@ -1335,7 +1338,7 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); @@ -1357,7 +1360,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -1427,7 +1430,7 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); @@ -1450,7 +1453,7 @@ } protected: - USHORT format; /* Format identifier--format = 2 */ + HBUINT16 format; /* Format identifier--format = 2 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -1479,7 +1482,7 @@ this }; context_closure_lookup (c, - glyphCount, (const USHORT *) (coverageZ + 1), + glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context); } @@ -1496,7 +1499,7 @@ }; context_collect_glyphs_lookup (c, - glyphCount, (const USHORT *) (coverageZ + 1), + glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context); } @@ -1510,7 +1513,7 @@ {match_coverage}, this }; - return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1518,7 +1521,7 @@ return this+coverageZ[0]; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); @@ -1529,7 +1532,7 @@ {match_coverage}, this }; - return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -1546,17 +1549,17 @@ } protected: - USHORT format; /* Format identifier--format = 3 */ - USHORT glyphCount; /* Number of glyphs in the input glyph + HBUINT16 format; /* Format identifier--format = 3 */ + HBUINT16 glyphCount; /* Number of glyphs in the input glyph * sequence */ - USHORT lookupCount; /* Number of LookupRecords */ + HBUINT16 lookupCount; /* Number of LookupRecords */ OffsetTo<Coverage> coverageZ[VAR]; /* Array of offsets to Coverage * table in glyph sequence order */ - LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in +/*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in * design order */ public: - DEFINE_SIZE_ARRAY2 (6, coverageZ, lookupRecordX); + DEFINE_SIZE_ARRAY (6, coverageZ); }; struct Context @@ -1576,7 +1579,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ ContextFormat1 format1; ContextFormat2 format2; ContextFormat3 format3; @@ -1606,11 +1609,11 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, unsigned int backtrackCount, - const USHORT backtrack[], + const HBUINT16 backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const USHORT lookahead[], + const HBUINT16 lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextClosureLookupContext &lookup_context) @@ -1630,11 +1633,11 @@ static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int backtrackCount, - const USHORT backtrack[], + const HBUINT16 backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const USHORT lookahead[], + const HBUINT16 lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextCollectGlyphsLookupContext &lookup_context) @@ -1654,11 +1657,11 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, unsigned int backtrackCount, - const USHORT backtrack[] HB_UNUSED, + const HBUINT16 backtrack[] HB_UNUSED, unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const USHORT lookahead[] HB_UNUSED, + const HBUINT16 lookahead[] HB_UNUSED, unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, ChainContextApplyLookupContext &lookup_context) @@ -1669,13 +1672,13 @@ lookup_context.funcs.match, lookup_context.match_data[1]); } -static inline bool chain_context_apply_lookup (hb_apply_context_t *c, +static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, unsigned int backtrackCount, - const USHORT backtrack[], + const HBUINT16 backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const USHORT input[], /* Array of input values--start with second glyph */ + const HBUINT16 input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const USHORT lookahead[], + const HBUINT16 lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextApplyLookupContext &lookup_context) @@ -1706,8 +1709,8 @@ inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); + const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.array, @@ -1720,8 +1723,8 @@ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const { TRACE_COLLECT_GLYPHS (this); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); + const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.array, @@ -1734,8 +1737,8 @@ inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { TRACE_WOULD_APPLY (this); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); + const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_would_apply_lookup (c, backtrack.len, backtrack.array, @@ -1744,11 +1747,11 @@ lookup.array, lookup_context)); } - inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const + inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); + const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.array, @@ -1761,23 +1764,23 @@ { TRACE_SANITIZE (this); if (!backtrack.sanitize (c)) return_trace (false); - const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); + const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack); if (!input.sanitize (c)) return_trace (false); - const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); + const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input); if (!lookahead.sanitize (c)) return_trace (false); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); return_trace (lookup.sanitize (c)); } protected: - ArrayOf<USHORT> + ArrayOf<HBUINT16> backtrack; /* Array of backtracking values * (to be matched before the input * sequence) */ - HeadlessArrayOf<USHORT> + HeadlessArrayOf<HBUINT16> inputX; /* Array of input values (start with * second glyph) */ - ArrayOf<USHORT> + ArrayOf<HBUINT16> lookaheadX; /* Array of lookahead values's (to be * matched after the input sequence) */ ArrayOf<LookupRecord> @@ -1816,7 +1819,7 @@ return_trace (false); } - inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const + inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); unsigned int num_rules = rule.len; @@ -1893,7 +1896,7 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); @@ -1914,7 +1917,7 @@ } protected: - USHORT format; /* Format identifier--format = 1 */ + HBUINT16 format; /* Format identifier--format = 1 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -1997,7 +2000,7 @@ return this+coverage; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); @@ -2029,7 +2032,7 @@ } protected: - USHORT format; /* Format identifier--format = 2 */ + HBUINT16 format; /* Format identifier--format = 2 */ OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ @@ -2069,9 +2072,9 @@ {this, this, this} }; chain_context_closure_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, + backtrack.len, (const HBUINT16 *) backtrack.array, + input.len, (const HBUINT16 *) input.array + 1, + lookahead.len, (const HBUINT16 *) lookahead.array, lookup.len, lookup.array, lookup_context); } @@ -2090,9 +2093,9 @@ {this, this, this} }; chain_context_collect_glyphs_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, + backtrack.len, (const HBUINT16 *) backtrack.array, + input.len, (const HBUINT16 *) input.array + 1, + lookahead.len, (const HBUINT16 *) lookahead.array, lookup.len, lookup.array, lookup_context); } @@ -2109,9 +2112,9 @@ {this, this, this} }; return_trace (chain_context_would_apply_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, + backtrack.len, (const HBUINT16 *) backtrack.array, + input.len, (const HBUINT16 *) input.array + 1, + lookahead.len, (const HBUINT16 *) lookahead.array, lookup.len, lookup.array, lookup_context)); } @@ -2121,7 +2124,7 @@ return this+input[0]; } - inline bool apply (hb_apply_context_t *c) const + inline bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); @@ -2136,9 +2139,9 @@ {this, this, this} }; return_trace (chain_context_apply_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, + backtrack.len, (const HBUINT16 *) backtrack.array, + input.len, (const HBUINT16 *) input.array + 1, + lookahead.len, (const HBUINT16 *) lookahead.array, lookup.len, lookup.array, lookup_context)); } @@ -2156,7 +2159,7 @@ } protected: - USHORT format; /* Format identifier--format = 3 */ + HBUINT16 format; /* Format identifier--format = 3 */ OffsetArrayOf<Coverage> backtrack; /* Array of coverage tables * in backtracking sequence, in glyph @@ -2193,7 +2196,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ ChainContextFormat1 format1; ChainContextFormat2 format2; ChainContextFormat3 format3; @@ -2226,15 +2229,17 @@ inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && extensionOffset != 0); + return_trace (c->check_struct (this) && + extensionOffset != 0 && + extensionLookupType != T::LookupSubTable::Extension); } protected: - USHORT format; /* Format identifier. Set to 1. */ - USHORT extensionLookupType; /* Lookup type of subtable referenced + HBUINT16 format; /* Format identifier. Set to 1. */ + HBUINT16 extensionLookupType; /* Lookup type of subtable referenced * by ExtensionOffset (i.e. the * extension subtable). */ - ULONG extensionOffset; /* Offset to the extension subtable, + HBUINT32 extensionOffset; /* Offset to the extension subtable, * of lookup type subtable. */ public: DEFINE_SIZE_STATIC (8); @@ -2272,7 +2277,7 @@ protected: union { - USHORT format; /* Format identifier */ + HBUINT16 format; /* Format identifier */ ExtensionFormat1<T> format1; } u; }; @@ -2284,9 +2289,6 @@ struct GSUBGPOS { - static const hb_tag_t GSUBTag = HB_OT_TAG_GSUB; - static const hb_tag_t GPOSTag = HB_OT_TAG_GPOS; - inline unsigned int get_script_count (void) const { return (this+scriptList).len; } inline const Tag& get_script_tag (unsigned int i) const
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout-private.hh Wed May 30 12:20:00 2018 -0700 @@ -90,12 +90,12 @@ struct hb_ot_layout_lookup_accelerator_t; namespace OT { - struct hb_apply_context_t; + struct hb_ot_apply_context_t; struct SubstLookup; } HB_INTERNAL void -hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, +hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, const OT::SubstLookup &lookup, const hb_ot_layout_lookup_accelerator_t &accel); @@ -122,6 +122,9 @@ */ namespace OT { + struct BASE; + struct COLR; + struct CPAL; struct GDEF; struct GSUB; struct GPOS; @@ -130,6 +133,13 @@ struct avar; } +namespace AAT { + struct ankr; + struct kerx; + struct morx; + struct trak; +} + struct hb_ot_layout_lookup_accelerator_t { template <typename TLookup> @@ -162,9 +172,16 @@ const struct OT::GPOS *gpos; /* TODO Move the following out of this struct. */ + OT::hb_lazy_table_loader_t<struct OT::BASE> base; + OT::hb_lazy_table_loader_t<struct OT::COLR> colr; + OT::hb_lazy_table_loader_t<struct OT::CPAL> cpal; OT::hb_lazy_table_loader_t<struct OT::MATH> math; OT::hb_lazy_table_loader_t<struct OT::fvar> fvar; OT::hb_lazy_table_loader_t<struct OT::avar> avar; + OT::hb_lazy_table_loader_t<struct AAT::ankr> ankr; + OT::hb_lazy_table_loader_t<struct AAT::kerx> kerx; + OT::hb_lazy_table_loader_t<struct AAT::morx> morx; + OT::hb_lazy_table_loader_t<struct AAT::trak> trak; unsigned int gsub_lookup_count; unsigned int gpos_lookup_count; @@ -273,14 +290,18 @@ * 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 */ + * https://github.com/harfbuzz/harfbuzz/issues/234 */ else if (unlikely (hb_in_range (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_HIDDEN; /* TAG characters need similar treatment. Fixes: - * https://github.com/behdad/harfbuzz/issues/463 */ + * https://github.com/harfbuzz/harfbuzz/issues/463 */ else if (unlikely (hb_in_range (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN; /* COMBINING GRAPHEME JOINER should not be skipped; at least some times. - * https://github.com/behdad/harfbuzz/issues/554 */ - else if (unlikely (u == 0x034Fu)) props |= UPROPS_MASK_HIDDEN; + * https://github.com/harfbuzz/harfbuzz/issues/554 */ + else if (unlikely (u == 0x034Fu)) + { + buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CGJ; + props |= UPROPS_MASK_HIDDEN; + } } else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat))) { @@ -305,7 +326,7 @@ /* 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 + * https://github.com/harfbuzz/harfbuzz/issues/169 */ if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu))) { @@ -350,6 +371,28 @@ return _hb_glyph_info_is_unicode_mark (info) ? info->unicode_props()>>8 : 0; } + +/* Loop over grapheme. Based on foreach_cluster(). */ +#define foreach_grapheme(buffer, start, end) \ + for (unsigned int \ + _count = buffer->len, \ + start = 0, end = _count ? _next_grapheme (buffer, 0) : 0; \ + start < _count; \ + start = end, end = _next_grapheme (buffer, start)) + +static inline unsigned int +_next_grapheme (hb_buffer_t *buffer, unsigned int start) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + while (++start < count && _hb_glyph_info_is_unicode_mark (&info[start])) + ; + + return start; +} + + #define info_cc(info) (_hb_glyph_info_get_modified_combining_class (&(info))) static inline bool @@ -388,6 +431,11 @@ == UPROPS_MASK_IGNORABLE) && !_hb_glyph_info_ligated (info); } +static inline void +_hb_glyph_info_unhide (hb_glyph_info_t *info) +{ + info->unicode_props() &= ~ UPROPS_MASK_HIDDEN; +} static inline bool _hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.cc Wed May 30 12:20:00 2018 -0700 @@ -31,16 +31,21 @@ #include "hb-open-type-private.hh" #include "hb-ot-layout-private.hh" +#include "hb-ot-layout-base-table.hh" #include "hb-ot-layout-gdef-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise. #include "hb-ot-name-table.hh" // Just so we compile it; unused otherwise. +#include "hb-ot-color-colr-table.hh" +#include "hb-ot-color-cpal-table.hh" #include "hb-ot-map-private.hh" +#ifndef HB_NO_VISIBILITY const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {}; +#endif hb_ot_layout_t * @@ -50,18 +55,25 @@ if (unlikely (!layout)) return nullptr; - layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF)); + layout->gdef_blob = OT::Sanitizer<OT::GDEF>().sanitize (face->reference_table (HB_OT_TAG_GDEF)); layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob); - layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB)); + layout->gsub_blob = OT::Sanitizer<OT::GSUB>().sanitize (face->reference_table (HB_OT_TAG_GSUB)); layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob); - layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS)); + layout->gpos_blob = OT::Sanitizer<OT::GPOS>().sanitize (face->reference_table (HB_OT_TAG_GPOS)); layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob); + layout->base.init (face); + layout->colr.init (face); + layout->cpal.init (face); layout->math.init (face); layout->fvar.init (face); layout->avar.init (face); + layout->ankr.init (face); + layout->kerx.init (face); + layout->morx.init (face); + layout->trak.init (face); { /* @@ -194,10 +206,12 @@ void _hb_ot_layout_destroy (hb_ot_layout_t *layout) { - for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) - layout->gsub_accels[i].fini (); - for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) - layout->gpos_accels[i].fini (); + if (layout->gsub_accels) + for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) + layout->gsub_accels[i].fini (); + if (layout->gpos_accels) + for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) + layout->gpos_accels[i].fini (); free (layout->gsub_accels); free (layout->gpos_accels); @@ -206,13 +220,28 @@ hb_blob_destroy (layout->gsub_blob); hb_blob_destroy (layout->gpos_blob); + layout->base.fini (); + layout->colr.fini (); + layout->cpal.fini (); layout->math.fini (); layout->fvar.fini (); layout->avar.fini (); + layout->ankr.fini (); + layout->kerx.fini (); + layout->morx.fini (); + layout->trak.fini (); free (layout); } +// static inline const OT::BASE& +// _get_base (hb_face_t *face) +// { +// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE); +// hb_ot_layout_t * layout = hb_ot_layout_from_face (face); +// return *(layout->base.get ()); +// } + static inline const OT::GDEF& _get_gdef (hb_face_t *face) { @@ -601,6 +630,7 @@ hb_ot_layout_table_get_lookup_count (hb_face_t *face, hb_tag_t table_tag) { + if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return 0; switch (table_tag) { case HB_OT_TAG_GSUB: @@ -1054,13 +1084,13 @@ OT::hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY> { template <typename Type> - static inline bool apply_to (const void *obj, OT::hb_apply_context_t *c) + static inline bool apply_to (const void *obj, OT::hb_ot_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); + typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c); struct hb_applicable_t { @@ -1070,7 +1100,7 @@ apply_func = apply_func_; } - inline bool apply (OT::hb_apply_context_t *c) const { return apply_func (obj, c); } + inline bool apply (OT::hb_ot_apply_context_t *c) const { return apply_func (obj, c); } private: const void *obj; @@ -1101,7 +1131,7 @@ }; static inline bool -apply_forward (OT::hb_apply_context_t *c, +apply_forward (OT::hb_ot_apply_context_t *c, const hb_ot_layout_lookup_accelerator_t &accel, const hb_get_subtables_context_t::array_t &subtables) { @@ -1131,7 +1161,7 @@ } static inline bool -apply_backward (OT::hb_apply_context_t *c, +apply_backward (OT::hb_ot_apply_context_t *c, const hb_ot_layout_lookup_accelerator_t &accel, const hb_get_subtables_context_t::array_t &subtables) { @@ -1160,7 +1190,7 @@ template <typename Proxy> static inline void -apply_string (OT::hb_apply_context_t *c, +apply_string (OT::hb_ot_apply_context_t *c, const typename Proxy::Lookup &lookup, const hb_ot_layout_lookup_accelerator_t &accel) { @@ -1211,7 +1241,7 @@ { const unsigned int table_index = proxy.table_index; unsigned int i = 0; - OT::hb_apply_context_t c (table_index, font, buffer); + OT::hb_ot_apply_context_t c (table_index, font, buffer); c.set_recurse_func (Proxy::Lookup::apply_recurse_func); for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { @@ -1250,10 +1280,34 @@ apply (proxy, plan, font, buffer); } -HB_INTERNAL void -hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, +void +hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, const OT::SubstLookup &lookup, const hb_ot_layout_lookup_accelerator_t &accel) { apply_string<GSUBProxy> (c, lookup, accel); } + + + + +/* + * OT::BASE + */ + +// /** +// * hb_ot_base_has_data: +// * @face: #hb_face_t to test +// * +// * This function allows to verify the presence of an OpenType BASE table on the +// * face. +// * +// * Return value: true if face has a BASE table, false otherwise +// * +// * Since: XXX +// **/ +// hb_bool_t +// hb_ot_base_has_data (hb_face_t *face) +// { +// return &_get_base (face) != &OT::Null(OT::BASE); +// }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.h Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-layout.h Wed May 30 12:20:00 2018 -0700 @@ -38,6 +38,7 @@ HB_BEGIN_DECLS +#define HB_OT_TAG_BASE HB_TAG('B','A','S','E') #define HB_OT_TAG_GDEF HB_TAG('G','D','E','F') #define HB_OT_TAG_GSUB HB_TAG('G','S','U','B') #define HB_OT_TAG_GPOS HB_TAG('G','P','O','S') @@ -316,6 +317,22 @@ unsigned int *range_end /* OUT. May be NULL */); +/* + * BASE + */ +#if 0 + +#define HB_OT_TAG_BASE_HANG HB_TAG('h','a','n','g') +#define HB_OT_TAG_BASE_ICFB HB_TAG('i','c','f','b') +#define HB_OT_TAG_BASE_ICFT HB_TAG('i','c','f','t') +#define HB_OT_TAG_BASE_IDEO HB_TAG('i','d','e','o') +#define HB_OT_TAG_BASE_IDTB HB_TAG('i','d','t','b') +#define HB_OT_TAG_BASE_MATH HB_TAG('m','a','t','h') +#define HB_OT_TAG_BASE_ROMN HB_TAG('r','o','m','n') + +#endif + + HB_END_DECLS #endif /* HB_OT_LAYOUT_H */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map-private.hh Wed May 30 12:20:00 2018 -0700 @@ -84,28 +84,28 @@ inline hb_mask_t get_global_mask (void) const { return global_mask; } inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = nullptr) const { - const feature_map_t *map = features.bsearch (&feature_tag); + const feature_map_t *map = features.bsearch (feature_tag); if (shift) *shift = map ? map->shift : 0; return map ? map->mask : 0; } inline bool needs_fallback (hb_tag_t feature_tag) const { - const feature_map_t *map = features.bsearch (&feature_tag); + const feature_map_t *map = features.bsearch (feature_tag); return map ? map->needs_fallback : false; } inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const { - const feature_map_t *map = features.bsearch (&feature_tag); + const feature_map_t *map = features.bsearch (feature_tag); return map ? map->_1_mask : 0; } inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const { - const feature_map_t *map = features.bsearch (&feature_tag); + const feature_map_t *map = features.bsearch (feature_tag); return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX; } inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const { - const feature_map_t *map = features.bsearch (&feature_tag); + const feature_map_t *map = features.bsearch (feature_tag); return map ? map->stage[table_index] : (unsigned int) -1; } @@ -198,7 +198,6 @@ 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,
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-map.cc Wed May 30 12:20:00 2018 -0700 @@ -80,7 +80,6 @@ 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, @@ -140,7 +139,7 @@ { static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), ""); unsigned int global_bit_mask = HB_GLYPH_FLAG_DEFINED + 1; - unsigned int global_bit_shift = _hb_popcount32 (HB_GLYPH_FLAG_DEFINED); + unsigned int global_bit_shift = _hb_popcount (HB_GLYPH_FLAG_DEFINED); m.global_mask = global_bit_mask; @@ -289,14 +288,14 @@ { if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX && required_feature_stage[table_index] == stage) - add_lookups (m, face, table_index, + add_lookups (m, table_index, required_feature_index[table_index], variations_index, global_bit_mask); for (unsigned i = 0; i < m.features.len; i++) if (m.features[i].stage[table_index] == stage) - add_lookups (m, face, table_index, + add_lookups (m, table_index, m.features[i].index[table_index], variations_index, m.features[i].mask,
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-maxp-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-maxp-table.hh Wed May 30 12:20:00 2018 -0700 @@ -28,7 +28,7 @@ #define HB_OT_MAXP_TABLE_HH #include "hb-open-type-private.hh" - +#include "hb-subset-plan.hh" namespace OT { @@ -39,28 +39,104 @@ #define HB_OT_TAG_maxp HB_TAG('m','a','x','p') +struct maxpV1Tail +{ + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + HBUINT16 maxPoints; /* Maximum points in a non-composite glyph. */ + HBUINT16 maxContours; /* Maximum contours in a non-composite glyph. */ + HBUINT16 maxCompositePoints; /* Maximum points in a composite glyph. */ + HBUINT16 maxCompositeContours; /* Maximum contours in a composite glyph. */ + HBUINT16 maxZones; /* 1 if instructions do not use the twilight zone (Z0), + * or 2 if instructions do use Z0; should be set to 2 in + * most cases. */ + HBUINT16 maxTwilightPoints; /* Maximum points used in Z0. */ + HBUINT16 maxStorage; /* Number of Storage Area locations. */ + HBUINT16 maxFunctionDefs; /* Number of FDEFs, equal to the highest function number + 1. */ + HBUINT16 maxInstructionDefs; /* Number of IDEFs. */ + HBUINT16 maxStackElements; /* Maximum stack depth. (This includes Font and CVT + * Programs, as well as the instructions for each glyph.) */ + HBUINT16 maxSizeOfInstructions; /* Maximum byte count for glyph instructions. */ + HBUINT16 maxComponentElements; /* Maximum number of components referenced at + * "top level" for any composite glyph. */ + HBUINT16 maxComponentDepth; /* Maximum levels of recursion; 1 for simple components. */ + public: + DEFINE_SIZE_STATIC (26); +}; + + struct maxp { - static const hb_tag_t tableTag = HB_OT_TAG_maxp; + static const hb_tag_t tableTag = HB_OT_TAG_maxp; inline unsigned int get_num_glyphs (void) const { return numGlyphs; } + inline void set_num_glyphs (unsigned int count) + { + numGlyphs.set (count); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - likely (version.major == 1 || - (version.major == 0 && version.minor == 0x5000u))); + if (unlikely (!c->check_struct (this))) + return_trace (false); + + if (version.major == 1) + { + const maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*this); + return v1.sanitize (c); + } + return_trace (likely (version.major == 0 && version.minor == 0x5000u)); } - /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */ + inline bool subset (hb_subset_plan_t *plan) const + { + hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_maxp)); + hb_blob_t *maxp_prime_blob = hb_blob_copy_writable_or_fail (maxp_blob); + hb_blob_destroy (maxp_blob); + + if (unlikely (!maxp_prime_blob)) { + return false; + } + OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data (maxp_prime_blob, nullptr); + + maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len); + if (plan->drop_hints) + drop_hint_fields (plan, maxp_prime); + + bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_maxp, maxp_prime_blob); + hb_blob_destroy (maxp_prime_blob); + return result; + } + + static inline void drop_hint_fields (hb_subset_plan_t *plan, OT::maxp *maxp_prime) + { + if (maxp_prime->version.major == 1) + { + maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*maxp_prime); + v1.maxZones.set (1); + v1.maxTwilightPoints.set (0); + v1.maxStorage.set (0); + v1.maxFunctionDefs.set (0); + v1.maxInstructionDefs.set (0); + v1.maxStackElements.set (0); + v1.maxSizeOfInstructions.set (0); + } + } + protected: FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0), * 0x00005000u or 0x00010000u. */ - USHORT numGlyphs; /* The number of glyphs in the font. */ + HBUINT16 numGlyphs; /* The number of glyphs in the font. */ +/*maxpV1Tail v1Tail[VAR]; */ public: DEFINE_SIZE_STATIC (6); };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-name-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-name-table.hh Wed May 30 12:20:00 2018 -0700 @@ -65,12 +65,12 @@ return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset)); } - USHORT platformID; /* Platform ID. */ - USHORT encodingID; /* Platform-specific encoding ID. */ - USHORT languageID; /* Language ID. */ - USHORT nameID; /* Name ID. */ - USHORT length; /* String length (in bytes). */ - USHORT offset; /* String offset from start of storage area (in bytes). */ + HBUINT16 platformID; /* Platform ID. */ + HBUINT16 encodingID; /* Platform-specific encoding ID. */ + HBUINT16 languageID; /* Language ID. */ + HBUINT16 nameID; /* Name ID. */ + HBUINT16 length; /* String length (in bytes). */ + HBUINT16 offset; /* String offset from start of storage area (in bytes). */ public: DEFINE_SIZE_STATIC (12); }; @@ -123,9 +123,9 @@ } /* We only implement format 0 for now. */ - USHORT format; /* Format selector (=0/1). */ - USHORT count; /* Number of name records. */ - Offset<> stringOffset; /* Offset to start of string storage (from start of table). */ + HBUINT16 format; /* Format selector (=0/1). */ + HBUINT16 count; /* Number of name records. */ + Offset16 stringOffset; /* Offset to start of string storage (from start of table). */ NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */ public: DEFINE_SIZE_ARRAY (6, nameRecord);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-table.hh Wed May 30 12:20:00 2018 -0700 @@ -28,7 +28,7 @@ #define HB_OT_OS2_TABLE_HH #include "hb-open-type-private.hh" - +#include "hb-ot-os2-unicode-ranges.hh" namespace OT { @@ -49,51 +49,127 @@ return_trace (c->check_struct (this)); } + inline bool subset (hb_subset_plan_t *plan) const + { + hb_blob_t *os2_blob = OT::Sanitizer<OT::os2>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_os2)); + hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1); + // TODO(grieger): move to hb_blob_copy_writable_or_fail + hb_blob_destroy (os2_blob); + + OT::os2 *os2_prime = (OT::os2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr); + if (unlikely (!os2_prime)) { + hb_blob_destroy (os2_prime_blob); + return false; + } + + uint16_t min_cp, max_cp; + find_min_and_max_codepoint (plan->codepoints, &min_cp, &max_cp); + os2_prime->usFirstCharIndex.set (min_cp); + os2_prime->usLastCharIndex.set (max_cp); + + _update_unicode_ranges (plan->codepoints, os2_prime->ulUnicodeRange); + bool result = hb_subset_plan_add_table(plan, HB_OT_TAG_os2, os2_prime_blob); + + hb_blob_destroy (os2_prime_blob); + return result; + } + + inline void _update_unicode_ranges (const hb_prealloced_array_t<hb_codepoint_t> &codepoints, + HBUINT32 ulUnicodeRange[4]) const + { + for (unsigned int i = 0; i < 4; i++) + ulUnicodeRange[i].set (0); + + for (unsigned int i = 0; i < codepoints.len; i++) + { + hb_codepoint_t cp = codepoints[i]; + unsigned int bit = hb_get_unicode_range_bit (cp); + if (bit < 128) + { + unsigned int block = bit / 32; + unsigned int bit_in_block = bit % 32; + unsigned int mask = 1 << bit_in_block; + ulUnicodeRange[block].set (ulUnicodeRange[block] | mask); + } + if (cp >= 0x10000 && cp <= 0x110000) + { + /* the spec says that bit 57 ("Non Plane 0") implies that there's + at least one codepoint beyond the BMP; so I also include all + the non-BMP codepoints here */ + ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25)); + } + } + } + + static inline void find_min_and_max_codepoint (const hb_prealloced_array_t<hb_codepoint_t> &codepoints, + uint16_t *min_cp, /* OUT */ + uint16_t *max_cp /* OUT */) + { + hb_codepoint_t min = -1, max = 0; + + for (unsigned int i = 0; i < codepoints.len; i++) + { + hb_codepoint_t cp = codepoints[i]; + if (cp < min) + min = cp; + if (cp > max) + max = cp; + } + + if (min > 0xFFFF) + min = 0xFFFF; + if (max > 0xFFFF) + max = 0xFFFF; + + *min_cp = min; + *max_cp = max; + } + public: - USHORT version; + HBUINT16 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]; + HBINT16 xAvgCharWidth; + HBUINT16 usWeightClass; + HBUINT16 usWidthClass; + HBUINT16 fsType; + HBINT16 ySubscriptXSize; + HBINT16 ySubscriptYSize; + HBINT16 ySubscriptXOffset; + HBINT16 ySubscriptYOffset; + HBINT16 ySuperscriptXSize; + HBINT16 ySuperscriptYSize; + HBINT16 ySuperscriptXOffset; + HBINT16 ySuperscriptYOffset; + HBINT16 yStrikeoutSize; + HBINT16 yStrikeoutPosition; + HBINT16 sFamilyClass; + HBUINT8 panose[10]; + HBUINT32 ulUnicodeRange[4]; Tag achVendID; - USHORT fsSelection; - USHORT usFirstCharIndex; - USHORT usLastCharIndex; - SHORT sTypoAscender; - SHORT sTypoDescender; - SHORT sTypoLineGap; - USHORT usWinAscent; - USHORT usWinDescent; + HBUINT16 fsSelection; + HBUINT16 usFirstCharIndex; + HBUINT16 usLastCharIndex; + HBINT16 sTypoAscender; + HBINT16 sTypoDescender; + HBINT16 sTypoLineGap; + HBUINT16 usWinAscent; + HBUINT16 usWinDescent; /* Version 1 */ - //ULONG ulCodePageRange1; - //ULONG ulCodePageRange2; + //HBUINT32 ulCodePageRange1; + //HBUINT32 ulCodePageRange2; /* Version 2 */ - //SHORT sxHeight; - //SHORT sCapHeight; - //USHORT usDefaultChar; - //USHORT usBreakChar; - //USHORT usMaxContext; + //HBINT16 sxHeight; + //HBINT16 sCapHeight; + //HBUINT16 usDefaultChar; + //HBUINT16 usBreakChar; + //HBUINT16 usMaxContext; /* Version 5 */ - //USHORT usLowerOpticalPointSize; - //USHORT usUpperOpticalPointSize; + //HBUINT16 usLowerOpticalPointSize; + //HBUINT16 usUpperOpticalPointSize; public: DEFINE_SIZE_STATIC (78);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-os2-unicode-ranges.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,247 @@ +/* + * Copyright © 2018 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): Garret Rieger + */ + +#ifndef HB_OT_OS2_UNICODE_RANGES_HH +#define HB_OT_OS2_UNICODE_RANGES_HH + +#include "hb-private.hh" +#include "hb-dsalgs.hh" + +namespace OT { + +struct Range { + hb_codepoint_t start; + hb_codepoint_t end; + unsigned int bit; +}; + +/* Note: The contents of this array was generated using src/gen-unicode-ranges.py. */ +static Range os2UnicodeRangesSorted[] = +{ + { 0x0, 0x7F, 0}, // Basic Latin + { 0x80, 0xFF, 1}, // Latin-1 Supplement + { 0x100, 0x17F, 2}, // Latin Extended-A + { 0x180, 0x24F, 3}, // Latin Extended-B + { 0x250, 0x2AF, 4}, // IPA Extensions + { 0x2B0, 0x2FF, 5}, // Spacing Modifier Letters + { 0x300, 0x36F, 6}, // Combining Diacritical Marks + { 0x370, 0x3FF, 7}, // Greek and Coptic + { 0x400, 0x4FF, 9}, // Cyrillic + { 0x500, 0x52F, 9}, // Cyrillic Supplement + { 0x530, 0x58F, 10}, // Armenian + { 0x590, 0x5FF, 11}, // Hebrew + { 0x600, 0x6FF, 13}, // Arabic + { 0x700, 0x74F, 71}, // Syriac + { 0x750, 0x77F, 13}, // Arabic Supplement + { 0x780, 0x7BF, 72}, // Thaana + { 0x7C0, 0x7FF, 14}, // NKo + { 0x900, 0x97F, 15}, // Devanagari + { 0x980, 0x9FF, 16}, // Bengali + { 0xA00, 0xA7F, 17}, // Gurmukhi + { 0xA80, 0xAFF, 18}, // Gujarati + { 0xB00, 0xB7F, 19}, // Oriya + { 0xB80, 0xBFF, 20}, // Tamil + { 0xC00, 0xC7F, 21}, // Telugu + { 0xC80, 0xCFF, 22}, // Kannada + { 0xD00, 0xD7F, 23}, // Malayalam + { 0xD80, 0xDFF, 73}, // Sinhala + { 0xE00, 0xE7F, 24}, // Thai + { 0xE80, 0xEFF, 25}, // Lao + { 0xF00, 0xFFF, 70}, // Tibetan + { 0x1000, 0x109F, 74}, // Myanmar + { 0x10A0, 0x10FF, 26}, // Georgian + { 0x1100, 0x11FF, 28}, // Hangul Jamo + { 0x1200, 0x137F, 75}, // Ethiopic + { 0x1380, 0x139F, 75}, // Ethiopic Supplement + { 0x13A0, 0x13FF, 76}, // Cherokee + { 0x1400, 0x167F, 77}, // Unified Canadian Aboriginal Syllabics + { 0x1680, 0x169F, 78}, // Ogham + { 0x16A0, 0x16FF, 79}, // Runic + { 0x1700, 0x171F, 84}, // Tagalog + { 0x1720, 0x173F, 84}, // Hanunoo + { 0x1740, 0x175F, 84}, // Buhid + { 0x1760, 0x177F, 84}, // Tagbanwa + { 0x1780, 0x17FF, 80}, // Khmer + { 0x1800, 0x18AF, 81}, // Mongolian + { 0x1900, 0x194F, 93}, // Limbu + { 0x1950, 0x197F, 94}, // Tai Le + { 0x1980, 0x19DF, 95}, // New Tai Lue + { 0x19E0, 0x19FF, 80}, // Khmer Symbols + { 0x1A00, 0x1A1F, 96}, // Buginese + { 0x1B00, 0x1B7F, 27}, // Balinese + { 0x1B80, 0x1BBF, 112}, // Sundanese + { 0x1C00, 0x1C4F, 113}, // Lepcha + { 0x1C50, 0x1C7F, 114}, // Ol Chiki + { 0x1D00, 0x1D7F, 4}, // Phonetic Extensions + { 0x1D80, 0x1DBF, 4}, // Phonetic Extensions Supplement + { 0x1DC0, 0x1DFF, 6}, // Combining Diacritical Marks Supplement + { 0x1E00, 0x1EFF, 29}, // Latin Extended Additional + { 0x1F00, 0x1FFF, 30}, // Greek Extended + { 0x2000, 0x206F, 31}, // General Punctuation + { 0x2070, 0x209F, 32}, // Superscripts And Subscripts + { 0x20A0, 0x20CF, 33}, // Currency Symbols + { 0x20D0, 0x20FF, 34}, // Combining Diacritical Marks For Symbols + { 0x2100, 0x214F, 35}, // Letterlike Symbols + { 0x2150, 0x218F, 36}, // Number Forms + { 0x2190, 0x21FF, 37}, // Arrows + { 0x2200, 0x22FF, 38}, // Mathematical Operators + { 0x2300, 0x23FF, 39}, // Miscellaneous Technical + { 0x2400, 0x243F, 40}, // Control Pictures + { 0x2440, 0x245F, 41}, // Optical Character Recognition + { 0x2460, 0x24FF, 42}, // Enclosed Alphanumerics + { 0x2500, 0x257F, 43}, // Box Drawing + { 0x2580, 0x259F, 44}, // Block Elements + { 0x25A0, 0x25FF, 45}, // Geometric Shapes + { 0x2600, 0x26FF, 46}, // Miscellaneous Symbols + { 0x2700, 0x27BF, 47}, // Dingbats + { 0x27C0, 0x27EF, 38}, // Miscellaneous Mathematical Symbols-A + { 0x27F0, 0x27FF, 37}, // Supplemental Arrows-A + { 0x2800, 0x28FF, 82}, // Braille Patterns + { 0x2900, 0x297F, 37}, // Supplemental Arrows-B + { 0x2980, 0x29FF, 38}, // Miscellaneous Mathematical Symbols-B + { 0x2A00, 0x2AFF, 38}, // Supplemental Mathematical Operators + { 0x2B00, 0x2BFF, 37}, // Miscellaneous Symbols and Arrows + { 0x2C00, 0x2C5F, 97}, // Glagolitic + { 0x2C60, 0x2C7F, 29}, // Latin Extended-C + { 0x2C80, 0x2CFF, 8}, // Coptic + { 0x2D00, 0x2D2F, 26}, // Georgian Supplement + { 0x2D30, 0x2D7F, 98}, // Tifinagh + { 0x2D80, 0x2DDF, 75}, // Ethiopic Extended + { 0x2DE0, 0x2DFF, 9}, // Cyrillic Extended-A + { 0x2E00, 0x2E7F, 31}, // Supplemental Punctuation + { 0x2E80, 0x2EFF, 59}, // CJK Radicals Supplement + { 0x2F00, 0x2FDF, 59}, // Kangxi Radicals + { 0x2FF0, 0x2FFF, 59}, // Ideographic Description Characters + { 0x3000, 0x303F, 48}, // CJK Symbols And Punctuation + { 0x3040, 0x309F, 49}, // Hiragana + { 0x30A0, 0x30FF, 50}, // Katakana + { 0x3100, 0x312F, 51}, // Bopomofo + { 0x3130, 0x318F, 52}, // Hangul Compatibility Jamo + { 0x3190, 0x319F, 59}, // Kanbun + { 0x31A0, 0x31BF, 51}, // Bopomofo Extended + { 0x31C0, 0x31EF, 61}, // CJK Strokes + { 0x31F0, 0x31FF, 50}, // Katakana Phonetic Extensions + { 0x3200, 0x32FF, 54}, // Enclosed CJK Letters And Months + { 0x3300, 0x33FF, 55}, // CJK Compatibility + { 0x3400, 0x4DBF, 59}, // CJK Unified Ideographs Extension A + { 0x4DC0, 0x4DFF, 99}, // Yijing Hexagram Symbols + { 0x4E00, 0x9FFF, 59}, // CJK Unified Ideographs + { 0xA000, 0xA48F, 83}, // Yi Syllables + { 0xA490, 0xA4CF, 83}, // Yi Radicals + { 0xA500, 0xA63F, 12}, // Vai + { 0xA640, 0xA69F, 9}, // Cyrillic Extended-B + { 0xA700, 0xA71F, 5}, // Modifier Tone Letters + { 0xA720, 0xA7FF, 29}, // Latin Extended-D + { 0xA800, 0xA82F, 100}, // Syloti Nagri + { 0xA840, 0xA87F, 53}, // Phags-pa + { 0xA880, 0xA8DF, 115}, // Saurashtra + { 0xA900, 0xA92F, 116}, // Kayah Li + { 0xA930, 0xA95F, 117}, // Rejang + { 0xAA00, 0xAA5F, 118}, // Cham + { 0xAC00, 0xD7AF, 56}, // Hangul Syllables + { 0xD800, 0xDFFF, 57}, // Non-Plane 0 * + { 0xE000, 0xF8FF, 60}, // Private Use Area (plane 0) + { 0xF900, 0xFAFF, 61}, // CJK Compatibility Ideographs + { 0xFB00, 0xFB4F, 62}, // Alphabetic Presentation Forms + { 0xFB50, 0xFDFF, 63}, // Arabic Presentation Forms-A + { 0xFE00, 0xFE0F, 91}, // Variation Selectors + { 0xFE10, 0xFE1F, 65}, // Vertical Forms + { 0xFE20, 0xFE2F, 64}, // Combining Half Marks + { 0xFE30, 0xFE4F, 65}, // CJK Compatibility Forms + { 0xFE50, 0xFE6F, 66}, // Small Form Variants + { 0xFE70, 0xFEFF, 67}, // Arabic Presentation Forms-B + { 0xFF00, 0xFFEF, 68}, // Halfwidth And Fullwidth Forms + { 0xFFF0, 0xFFFF, 69}, // Specials + { 0x10000, 0x1007F, 101}, // Linear B Syllabary + { 0x10080, 0x100FF, 101}, // Linear B Ideograms + { 0x10100, 0x1013F, 101}, // Aegean Numbers + { 0x10140, 0x1018F, 102}, // Ancient Greek Numbers + { 0x10190, 0x101CF, 119}, // Ancient Symbols + { 0x101D0, 0x101FF, 120}, // Phaistos Disc + { 0x10280, 0x1029F, 121}, // Lycian + { 0x102A0, 0x102DF, 121}, // Carian + { 0x10300, 0x1032F, 85}, // Old Italic + { 0x10330, 0x1034F, 86}, // Gothic + { 0x10380, 0x1039F, 103}, // Ugaritic + { 0x103A0, 0x103DF, 104}, // Old Persian + { 0x10400, 0x1044F, 87}, // Deseret + { 0x10450, 0x1047F, 105}, // Shavian + { 0x10480, 0x104AF, 106}, // Osmanya + { 0x10800, 0x1083F, 107}, // Cypriot Syllabary + { 0x10900, 0x1091F, 58}, // Phoenician + { 0x10920, 0x1093F, 121}, // Lydian + { 0x10A00, 0x10A5F, 108}, // Kharoshthi + { 0x12000, 0x123FF, 110}, // Cuneiform + { 0x12400, 0x1247F, 110}, // Cuneiform Numbers and Punctuation + { 0x1D000, 0x1D0FF, 88}, // Byzantine Musical Symbols + { 0x1D100, 0x1D1FF, 88}, // Musical Symbols + { 0x1D200, 0x1D24F, 88}, // Ancient Greek Musical Notation + { 0x1D300, 0x1D35F, 109}, // Tai Xuan Jing Symbols + { 0x1D360, 0x1D37F, 111}, // Counting Rod Numerals + { 0x1D400, 0x1D7FF, 89}, // Mathematical Alphanumeric Symbols + { 0x1F000, 0x1F02F, 122}, // Mahjong Tiles + { 0x1F030, 0x1F09F, 122}, // Domino Tiles + { 0x20000, 0x2A6DF, 59}, // CJK Unified Ideographs Extension B + { 0x2F800, 0x2FA1F, 61}, // CJK Compatibility Ideographs Supplement + { 0xE0000, 0xE007F, 92}, // Tags + { 0xE0100, 0xE01EF, 91}, // Variation Selectors Supplement + { 0xF0000, 0xFFFFD, 90}, // Private Use (plane 15) + {0x100000, 0x10FFFD, 90}, // Private Use (plane 16) +}; + +static int +_compare_range (const void *_key, const void *_item, void *_arg) +{ + hb_codepoint_t cp = *((hb_codepoint_t *) _key); + const Range *range = (Range *) _item; + + if (cp < range->start) + return -1; + else if (cp <= range->end) + return 0; + else + return 1; +} + +/** + * hb_get_unicode_range_bit: + * Returns the bit to be set in os/2 ulUnicodeRange for a given codepoint. + **/ +static unsigned int +hb_get_unicode_range_bit (hb_codepoint_t cp) +{ + Range *range = (Range*) hb_bsearch_r (&cp, os2UnicodeRangesSorted, + sizeof (os2UnicodeRangesSorted) / sizeof(Range), + sizeof(Range), + _compare_range, nullptr); + if (range != NULL) + return range->bit; + return -1; +} + +} /* namespace OT */ + +#endif /* HB_OT_OS2_UNICODE_RANGES_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-post-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-post-table.hh Wed May 30 12:20:00 2018 -0700 @@ -56,10 +56,10 @@ return_trace (glyphNameIndex.sanitize (c)); } - ArrayOf<USHORT>glyphNameIndex; /* This is not an offset, but is the + ArrayOf<HBUINT16>glyphNameIndex; /* 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] + HBUINT8 namesX[VAR]; /* Glyph names with length bytes [variable] * (a Pascal string). */ DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX); @@ -84,8 +84,12 @@ struct accelerator_t { - inline void init (const post *table, unsigned int post_len) + inline void init (hb_face_t *face) { + blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post)); + const post *table = Sanitizer<post>::lock_instance (blob); + unsigned int table_length = hb_blob_get_length (blob); + version = table->version.to_int (); index_to_offset.init (); if (version != 0x00020000) @@ -96,7 +100,7 @@ glyphNameIndex = &v2.glyphNameIndex; pool = &StructAfter<uint8_t> (v2.glyphNameIndex); - const uint8_t *end = (uint8_t *) table + post_len; + const uint8_t *end = (uint8_t *) table + table_length; for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data) { uint32_t *offset = index_to_offset.push (); @@ -227,8 +231,10 @@ return hb_string_t ((const char *) data, name_length); } + private: + hb_blob_t *blob; uint32_t version; - const ArrayOf<USHORT> *glyphNameIndex; + const ArrayOf<HBUINT16> *glyphNameIndex; hb_prealloced_array_t<uint32_t, 1> index_to_offset; const uint8_t *pool; mutable uint16_t *gids_sorted_by_name; @@ -255,16 +261,16 @@ * from the value of this field. */ FWORD underlineThickness; /* Suggested values for the underline thickness. */ - ULONG isFixedPitch; /* Set to 0 if the font is proportionally + HBUINT32 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 + HBUINT32 minMemType42; /* Minimum memory usage when an OpenType font * is downloaded. */ - ULONG maxMemType42; /* Maximum memory usage when an OpenType font + HBUINT32 maxMemType42; /* Maximum memory usage when an OpenType font * is downloaded. */ - ULONG minMemType1; /* Minimum memory usage when an OpenType font + HBUINT32 minMemType1; /* Minimum memory usage when an OpenType font * is downloaded as a Type 1 font. */ - ULONG maxMemType1; /* Maximum memory usage when an OpenType font + HBUINT32 maxMemType1; /* Maximum memory usage when an OpenType font * is downloaded as a Type 1 font. */ /*postV2Tail v2[VAR];*/ DEFINE_SIZE_STATIC (32);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-fallback.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-fallback.hh Wed May 30 12:20:00 2018 -0700 @@ -77,13 +77,7 @@ /* Bubble-sort or something equally good! * May not be good-enough for presidential candidate interviews, but good-enough for us... */ - -#if defined(_AIX) - /* Workaround AIX xlC 12 compilation problems caused by the overloaded versions of 'cmp' in IntType */ hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]); -#else - hb_stable_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]); -#endif OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs); OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs); @@ -132,13 +126,7 @@ first_glyphs_indirection[num_first_glyphs] = first_glyph_idx; num_first_glyphs++; } - -#if defined(_AIX) - /* Workaround AIX xlC 12 compilation problems caused by the overloaded versions of 'cmp' in IntType */ - hb_stable_sort (&first_glyphs[0], num_first_glyphs, (int(*)(const OT::GlyphID *, const OT::GlyphID *)) OT::GlyphID::cmp, &first_glyphs_indirection[0]); -#else - hb_stable_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]); -#endif + hb_stable_sort (&first_glyphs[0], num_first_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &first_glyphs_indirection[0]); /* Now that the first-glyphs are sorted, walk again, populate ligatures. */ for (unsigned int i = 0; i < num_first_glyphs; i++) @@ -352,7 +340,7 @@ hb_font_t *font, hb_buffer_t *buffer) { - OT::hb_apply_context_t c (0, font, buffer); + OT::hb_ot_apply_context_t c (0, font, buffer); for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) if (fallback_plan->lookup_array[i]) { c.set_lookup_mask (fallback_plan->mask_array[i]);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-win1256.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic-win1256.hh Wed May 30 12:20:00 2018 -0700 @@ -43,16 +43,16 @@ #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*/ +#define OT_UINT8(u8) +1/*byte*/ +#define OT_UINT16(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_UINT8(u8) (u8), +#define OT_UINT16(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). */) @@ -80,24 +80,24 @@ */ #define OT_TAG(a,b,c,d) \ - OT_BYTE(a) OT_BYTE(b) OT_BYTE(c) OT_BYTE(d) + OT_UINT8(a) OT_UINT8(b) OT_UINT8(c) OT_UINT8(d) #define OT_OFFSET(From, To) /* Offset from From to To in bytes */ \ - OT_USHORT(OT_DISTANCE(From, To)) + OT_UINT16(OT_DISTANCE(From, To)) #define OT_GLYPHID /* GlyphID */ \ - OT_USHORT + OT_UINT16 #define OT_UARRAY(Name, Items) \ OT_LABEL_START(Name) \ - OT_USHORT(OT_COUNT(Name##Data, 2)) \ + OT_UINT16(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_UINT16(OT_COUNT(Name##Data, 2) + 1) \ OT_LABEL(Name##Data) \ Items \ OT_LABEL_END @@ -111,19 +111,19 @@ #define OT_LOOKUP(Name, LookupType, LookupFlag, SubLookupOffsets) \ OT_LABEL_START(Name) \ - OT_USHORT(LookupType) \ - OT_USHORT(LookupFlag) \ + OT_UINT16(LookupType) \ + OT_UINT16(LookupFlag) \ OT_LABEL_END \ OT_UARRAY(Name##SubLookupOffsetsArray, OT_LIST(SubLookupOffsets)) #define OT_SUBLOOKUP(Name, SubFormat, Items) \ OT_LABEL_START(Name) \ - OT_USHORT(SubFormat) \ + OT_UINT16(SubFormat) \ Items #define OT_COVERAGE1(Name, Items) \ OT_LABEL_START(Name) \ - OT_USHORT(1) \ + OT_UINT16(1) \ OT_LABEL_END \ OT_UARRAY(Name##Glyphs, OT_LIST(Items)) @@ -174,7 +174,7 @@ /* Table manifest. */ #define MANIFEST(Items) \ OT_LABEL_START(manifest) \ - OT_USHORT(OT_COUNT(manifestData, 6)) \ + OT_UINT16(OT_COUNT(manifestData, 6)) \ OT_LABEL(manifestData) \ Items \ OT_LABEL_END @@ -304,8 +304,8 @@ #undef OT_TABLE_END #undef OT_LABEL_START #undef OT_LABEL_END -#undef OT_BYTE -#undef OT_USHORT +#undef OT_UINT8 +#undef OT_UINT16 #undef OT_DISTANCE #undef OT_COUNT
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-arabic.cc Wed May 30 12:20:00 2018 -0700 @@ -36,7 +36,7 @@ #define HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH HB_BUFFER_SCRATCH_FLAG_COMPLEX0 /* See: - * https://github.com/behdad/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */ + * https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */ #define HB_ARABIC_GENERAL_CATEGORY_IS_WORD(gen_cat) \ (FLAG_UNSAFE (gen_cat) & \ (FLAG (HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) | \ @@ -198,7 +198,7 @@ * pause for Arabic, not other scripts. * * A pause after calt is required to make KFGQPC Uthmanic Script HAFS - * work correctly. See https://github.com/behdad/harfbuzz/issues/505 + * work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505 */ map->add_gsub_pause (nuke_joiners); @@ -644,13 +644,15 @@ { hb_glyph_info_t *info = buffer->info; + DEBUG_MSG (ARABIC, buffer, "Reordering marks from %d to %d", start, end); + unsigned int i = start; for (unsigned int cc = 220; cc <= 230; cc += 10) { - DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d\n", cc, i); + DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d", cc, i); while (i < end && info_cc(info[i]) < cc) i++; - DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d\n", cc, i); + DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d", cc, i); if (i == end) break; @@ -658,20 +660,17 @@ if (info_cc(info[i]) > cc) continue; - /* Technically we should also check "info_cc(info[j]) == cc" - * in the following loop. But not doing it is safe; we might - * end up moving all the 220 MCMs and 230 MCMs together in one - * move and be done. */ unsigned int j = i; - while (j < end && info_is_mcm (info[j])) + while (j < end && info_cc(info[j]) == cc && info_is_mcm (info[j])) j++; - DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d\n", cc, i, j); if (i == j) continue; + DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d", cc, i, j); + /* Shift it! */ - DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d\n", cc, i, j); + DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d", cc, i, j); hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS]; assert (j - i <= ARRAY_LENGTH (temp)); buffer->merge_clusters (start, j); @@ -679,7 +678,25 @@ memmove (&info[start + j - i], &info[start], (i - start) * sizeof (hb_glyph_info_t)); memmove (&info[start], temp, (j - i) * sizeof (hb_glyph_info_t)); - start += j - i; + /* Renumber CC such that the reordered sequence is still sorted. + * 22 and 26 are chosen because they are smaller than all Arabic categories, + * and are folded back to 220/230 respectively during fallback mark positioning. + * + * We do this because the CGJ-handling logic in the normalizer relies on + * mark sequences having an increasing order even after this reordering. + * https://github.com/harfbuzz/harfbuzz/issues/554 + * This, however, does break some obscure sequences, where the normalizer + * might compose a sequence that it should not. For example, in the seequence + * ALEF, HAMZAH, MADDAH, we should NOT try to compose ALEF+MADDAH, but with this + * renumbering, we will. + */ + unsigned int new_start = start + j - i; + unsigned int new_cc = cc == 220 ? HB_MODIFIED_COMBINING_CLASS_CCC22 : HB_MODIFIED_COMBINING_CLASS_CCC26; + while (start < new_start) + { + _hb_glyph_info_set_modified_combining_class (&info[start], new_cc); + start++; + } i = j; }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hebrew.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-hebrew.cc Wed May 30 12:20:00 2018 -0700 @@ -161,7 +161,7 @@ * 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 + * https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368 */ return plan->map.chosen_script[1] != HB_TAG ('h','e','b','r'); }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-machine.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-machine.hh Wed May 30 12:20:00 2018 -0700 @@ -34,1106 +34,889 @@ #line 36 "hb-ot-shape-complex-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { - 8u, 8u, 1u, 16u, 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, - 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, - 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, - 4u, 8u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, - 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, 8u, 13u, - 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, - 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, - 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, - 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, - 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, - 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, - 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, - 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, - 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 8u, 8u, 1u, 16u, - 8u, 13u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, + 8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, - 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, - 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 5u, 8u, 4u, 14u, 4u, 14u, 5u, 8u, - 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, + 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, + 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, + 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, - 16u, 16u, 8u, 8u, 1u, 19u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, + 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, + 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 8u, 8u, 5u, 8u, + 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, + 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, + 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, + 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, + 8u, 8u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, + 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 4u, 8u, 6u, 6u, 16u, 16u, + 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, 16u, 16u, 4u, 8u, 6u, 6u, + 16u, 16u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, 4u, 13u, 4u, 8u, + 4u, 13u, 4u, 8u, 4u, 13u, 4u, 13u, 5u, 8u, 5u, 8u, 5u, 7u, 5u, 8u, + 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, 5u, 8u, 5u, 7u, 7u, 7u, + 8u, 8u, 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, 19u, 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, + 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 1u, 16u, 3u, 17u, + 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, + 5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, + 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, + 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, + 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 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, 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, + 4u, 17u, 1u, 16u, 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, + 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, + 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, + 5u, 10u, 3u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, + 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 4u, 8u, 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, 10u, + 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u, + 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, + 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, + 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 13u, 3u, 17u, 4u, 8u, 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, 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, 1u, 16u, 0 + 3u, 17u, 3u, 17u, 4u, 17u, 5u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, + 10u, 10u, 5u, 10u, 3u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, + 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, + 4u, 10u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, + 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, + 1u, 16u, 1u, 16u, 1u, 16u, 3u, 17u, 3u, 17u, 1u, 16u, 1u, 16u, 1u, 16u, + 1u, 16u, 3u, 17u, 1u, 17u, 3u, 17u, 1u, 17u, 4u, 13u, 5u, 10u, 10u, 10u, + 10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, + 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, 3u, 10u, 4u, 10u, 5u, 10u, + 3u, 10u, 5u, 10u, 5u, 10u, 10u, 10u, 10u, 10u, 10u, 10u, 5u, 10u, 1u, 16u, + 0 }; static const char _indic_syllable_machine_key_spans[] = { - 1, 16, 6, 4, 3, 1, 4, 3, - 1, 4, 3, 1, 4, 3, 1, 5, - 1, 1, 5, 1, 1, 5, 1, 1, - 5, 1, 1, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 1, 16, 6, - 4, 3, 1, 4, 3, 1, 4, 3, - 1, 4, 3, 1, 5, 1, 1, 5, - 1, 1, 5, 1, 1, 5, 1, 1, - 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 1, 16, 6, 4, 3, 1, - 4, 3, 1, 4, 3, 1, 4, 3, - 1, 5, 1, 1, 5, 1, 1, 5, - 1, 1, 5, 1, 1, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 1, 16, - 6, 4, 3, 1, 4, 3, 1, 4, + 1, 4, 3, 1, 4, 3, 1, 4, 3, 1, 4, 3, 1, 5, 1, 1, 5, 1, 1, 5, 1, 1, 5, 1, - 1, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 4, 11, 11, 4, - 3, 4, 3, 1, 4, 3, 1, 4, - 3, 1, 1, 16, 6, 5, 1, 1, + 1, 5, 10, 5, 10, 5, 10, 5, + 10, 5, 10, 1, 4, 3, 1, 4, + 3, 1, 4, 3, 1, 4, 3, 1, 5, 1, 1, 5, 1, 1, 5, 1, - 1, 1, 19, 15, 15, 14, 16, 15, + 1, 5, 1, 1, 5, 10, 5, 10, + 5, 10, 5, 10, 5, 10, 1, 4, + 3, 1, 4, 3, 1, 4, 3, 1, + 4, 3, 1, 5, 1, 1, 5, 1, + 1, 5, 1, 1, 5, 1, 1, 5, + 10, 5, 10, 5, 10, 5, 10, 5, + 1, 4, 3, 1, 4, 3, 1, 4, + 3, 1, 4, 3, 1, 5, 1, 1, + 5, 1, 1, 5, 1, 1, 5, 1, + 1, 5, 10, 5, 10, 5, 10, 5, + 10, 5, 10, 10, 4, 4, 3, 4, + 3, 1, 4, 3, 1, 4, 3, 1, + 1, 5, 1, 1, 5, 1, 1, 5, + 1, 1, 5, 1, 1, 1, 19, 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, + 15, 14, 16, 15, 15, 14, 16, 15, + 15, 14, 6, 6, 6, 1, 1, 1, + 6, 8, 8, 7, 6, 8, 7, 6, + 8, 7, 6, 8, 7, 6, 8, 7, + 15, 15, 16, 16, 16, 16, 15, 15, + 16, 16, 16, 16, 15, 15, 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, 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, + 14, 16, 15, 15, 14, 6, 6, 6, + 1, 1, 1, 6, 8, 8, 7, 6, + 8, 7, 6, 8, 7, 6, 8, 7, + 6, 8, 7, 15, 15, 16, 16, 16, + 16, 15, 15, 16, 16, 16, 16, 15, + 15, 16, 16, 16, 16, 15, 15, 16, + 16, 16, 16, 5, 15, 15, 14, 16, + 15, 15, 14, 16, 15, 15, 14, 16, + 15, 15, 14, 16, 15, 15, 14, 6, + 6, 6, 1, 1, 1, 6, 8, 8, + 7, 6, 8, 7, 6, 8, 7, 6, + 8, 7, 6, 8, 7, 15, 15, 16, + 16, 16, 16, 15, 15, 16, 16, 16, + 16, 15, 15, 16, 16, 16, 16, 15, + 15, 16, 16, 16, 16, 10, 15, 5, 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, 11, 10, 11, 8, 6, 8, - 11, 16, 8, 6, 6, 2, 1, 2, - 2, 1, 6, 16 + 15, 15, 14, 6, 6, 6, 1, 1, + 1, 6, 8, 8, 7, 6, 8, 7, + 6, 8, 7, 6, 8, 7, 6, 8, + 7, 15, 15, 16, 16, 16, 16, 15, + 15, 16, 16, 16, 16, 15, 15, 16, + 16, 16, 16, 15, 15, 16, 16, 16, + 16, 15, 17, 15, 17, 10, 6, 1, + 1, 1, 6, 16, 8, 7, 6, 8, + 7, 6, 8, 7, 6, 8, 7, 6, + 8, 6, 6, 1, 1, 1, 6, 16 }; static const short _indic_syllable_machine_index_offsets[] = { - 0, 2, 19, 26, 31, 35, 37, 42, - 46, 48, 53, 57, 59, 64, 68, 70, - 76, 78, 80, 86, 88, 90, 96, 98, - 100, 106, 108, 110, 122, 134, 146, 158, - 170, 182, 194, 206, 218, 230, 232, 249, - 256, 261, 265, 267, 272, 276, 278, 283, - 287, 289, 294, 298, 300, 306, 308, 310, - 316, 318, 320, 326, 328, 330, 336, 338, - 340, 352, 364, 376, 388, 400, 412, 424, - 436, 448, 460, 462, 479, 486, 491, 495, - 497, 502, 506, 508, 513, 517, 519, 524, - 528, 530, 536, 538, 540, 546, 548, 550, - 556, 558, 560, 566, 568, 570, 582, 594, - 606, 618, 630, 642, 654, 666, 678, 680, - 697, 704, 709, 713, 715, 720, 724, 726, - 731, 735, 737, 742, 746, 748, 754, 756, - 758, 764, 766, 768, 774, 776, 778, 784, - 786, 788, 800, 812, 824, 836, 848, 860, - 872, 884, 896, 908, 920, 925, 937, 949, - 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, 1079, 1095, 1111, 1126, 1143, - 1159, 1175, 1190, 1207, 1223, 1239, 1254, 1271, - 1287, 1303, 1318, 1335, 1351, 1367, 1382, 1393, - 1404, 1411, 1414, 1416, 1419, 1422, 1424, 1431, - 1443, 1452, 1459, 1468, 1480, 1493, 1506, 1518, - 1529, 1542, 1554, 1565, 1578, 1590, 1601, 1614, - 1626, 1637, 1650, 1667, 1679, 1695, 1711, 1728, - 1745, 1762, 1779, 1796, 1812, 1828, 1845, 1862, - 1879, 1896, 1913, 1929, 1945, 1962, 1979, 1996, - 2013, 2030, 2046, 2062, 2079, 2096, 2113, 2130, - 2147, 2163, 2179, 2195, 2211, 2226, 2243, 2259, - 2275, 2290, 2307, 2323, 2339, 2354, 2371, 2387, - 2403, 2418, 2435, 2451, 2467, 2482, 2493, 2504, - 2511, 2514, 2516, 2519, 2522, 2524, 2531, 2543, - 2552, 2559, 2568, 2580, 2593, 2606, 2618, 2629, - 2642, 2654, 2665, 2678, 2690, 2701, 2714, 2726, - 2737, 2750, 2767, 2779, 2795, 2811, 2828, 2845, - 2862, 2879, 2896, 2912, 2928, 2945, 2962, 2979, - 2996, 3013, 3029, 3045, 3062, 3079, 3096, 3113, - 3130, 3146, 3162, 3179, 3196, 3213, 3230, 3242, - 3259, 3275, 3291, 3306, 3323, 3339, 3355, 3370, - 3387, 3403, 3419, 3434, 3451, 3467, 3483, 3498, - 3515, 3531, 3547, 3562, 3573, 3584, 3591, 3594, - 3596, 3599, 3602, 3604, 3611, 3623, 3632, 3639, - 3648, 3660, 3673, 3686, 3698, 3709, 3722, 3734, - 3745, 3758, 3770, 3781, 3794, 3806, 3817, 3830, - 3847, 3859, 3875, 3891, 3908, 3925, 3942, 3959, - 3976, 3992, 4008, 4025, 4042, 4059, 4076, 4093, - 4109, 4125, 4142, 4159, 4176, 4193, 4210, 4226, - 4242, 4259, 4276, 4293, 4310, 4327, 4339, 4355, - 4367, 4383, 4399, 4414, 4431, 4447, 4463, 4478, - 4495, 4511, 4527, 4542, 4559, 4575, 4591, 4606, - 4623, 4639, 4655, 4670, 4681, 4692, 4699, 4702, - 4704, 4707, 4710, 4712, 4719, 4731, 4740, 4747, - 4756, 4768, 4781, 4794, 4806, 4817, 4830, 4842, - 4853, 4866, 4878, 4889, 4902, 4914, 4925, 4938, - 4955, 4967, 4983, 4999, 5016, 5033, 5050, 5067, - 5084, 5100, 5116, 5133, 5150, 5167, 5184, 5201, - 5217, 5233, 5250, 5267, 5284, 5301, 5318, 5334, - 5350, 5367, 5384, 5401, 5418, 5435, 5451, 5469, - 5485, 5503, 5515, 5522, 5525, 5527, 5530, 5533, - 5535, 5542, 5559, 5575, 5591, 5606, 5622, 5638, - 5655, 5668, 5680, 5691, 5704, 5716, 5727, 5740, - 5752, 5763, 5776, 5788, 5799, 5811, 5820, 5827, - 5836, 5848, 5865, 5874, 5881, 5888, 5891, 5893, - 5896, 5899, 5901, 5908 + 0, 2, 7, 11, 13, 18, 22, 24, + 29, 33, 35, 40, 44, 46, 52, 54, + 56, 62, 64, 66, 72, 74, 76, 82, + 84, 86, 92, 103, 109, 120, 126, 137, + 143, 154, 160, 171, 173, 178, 182, 184, + 189, 193, 195, 200, 204, 206, 211, 215, + 217, 223, 225, 227, 233, 235, 237, 243, + 245, 247, 253, 255, 257, 263, 274, 280, + 291, 297, 308, 314, 325, 331, 342, 344, + 349, 353, 355, 360, 364, 366, 371, 375, + 377, 382, 386, 388, 394, 396, 398, 404, + 406, 408, 414, 416, 418, 424, 426, 428, + 434, 445, 451, 462, 468, 479, 485, 496, + 502, 504, 509, 513, 515, 520, 524, 526, + 531, 535, 537, 542, 546, 548, 554, 556, + 558, 564, 566, 568, 574, 576, 578, 584, + 586, 588, 594, 605, 611, 622, 628, 639, + 645, 656, 662, 673, 684, 689, 694, 698, + 703, 707, 709, 714, 718, 720, 725, 729, + 731, 733, 739, 741, 743, 749, 751, 753, + 759, 761, 763, 769, 771, 773, 775, 795, + 811, 827, 842, 859, 875, 891, 906, 923, + 939, 955, 970, 987, 1003, 1019, 1034, 1051, + 1067, 1083, 1098, 1105, 1112, 1119, 1121, 1123, + 1125, 1132, 1141, 1150, 1158, 1165, 1174, 1182, + 1189, 1198, 1206, 1213, 1222, 1230, 1237, 1246, + 1254, 1270, 1286, 1303, 1320, 1337, 1354, 1370, + 1386, 1403, 1420, 1437, 1454, 1470, 1486, 1503, + 1520, 1537, 1554, 1570, 1586, 1603, 1620, 1637, + 1654, 1670, 1686, 1702, 1718, 1733, 1750, 1766, + 1782, 1797, 1814, 1830, 1846, 1861, 1878, 1894, + 1910, 1925, 1942, 1958, 1974, 1989, 1996, 2003, + 2010, 2012, 2014, 2016, 2023, 2032, 2041, 2049, + 2056, 2065, 2073, 2080, 2089, 2097, 2104, 2113, + 2121, 2128, 2137, 2145, 2161, 2177, 2194, 2211, + 2228, 2245, 2261, 2277, 2294, 2311, 2328, 2345, + 2361, 2377, 2394, 2411, 2428, 2445, 2461, 2477, + 2494, 2511, 2528, 2545, 2551, 2567, 2583, 2598, + 2615, 2631, 2647, 2662, 2679, 2695, 2711, 2726, + 2743, 2759, 2775, 2790, 2807, 2823, 2839, 2854, + 2861, 2868, 2875, 2877, 2879, 2881, 2888, 2897, + 2906, 2914, 2921, 2930, 2938, 2945, 2954, 2962, + 2969, 2978, 2986, 2993, 3002, 3010, 3026, 3042, + 3059, 3076, 3093, 3110, 3126, 3142, 3159, 3176, + 3193, 3210, 3226, 3242, 3259, 3276, 3293, 3310, + 3326, 3342, 3359, 3376, 3393, 3410, 3421, 3437, + 3443, 3459, 3475, 3490, 3507, 3523, 3539, 3554, + 3571, 3587, 3603, 3618, 3635, 3651, 3667, 3682, + 3699, 3715, 3731, 3746, 3753, 3760, 3767, 3769, + 3771, 3773, 3780, 3789, 3798, 3806, 3813, 3822, + 3830, 3837, 3846, 3854, 3861, 3870, 3878, 3885, + 3894, 3902, 3918, 3934, 3951, 3968, 3985, 4002, + 4018, 4034, 4051, 4068, 4085, 4102, 4118, 4134, + 4151, 4168, 4185, 4202, 4218, 4234, 4251, 4268, + 4285, 4302, 4318, 4336, 4352, 4370, 4381, 4388, + 4390, 4392, 4394, 4401, 4418, 4427, 4435, 4442, + 4451, 4459, 4466, 4475, 4483, 4490, 4499, 4507, + 4514, 4523, 4530, 4537, 4539, 4541, 4543, 4550 }; static const short _indic_syllable_machine_indicies[] = { - 1, 0, 2, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 0, 1, 0, 0, 0, 0, - 4, 0, 5, 5, 6, 1, 0, 7, - 7, 6, 0, 6, 0, 8, 8, 9, - 1, 0, 10, 10, 9, 0, 9, 0, - 11, 11, 12, 1, 0, 13, 13, 12, - 0, 12, 0, 14, 14, 15, 1, 0, - 16, 16, 15, 0, 15, 0, 17, 0, - 0, 0, 1, 0, 18, 0, 19, 0, - 20, 14, 14, 15, 1, 0, 21, 0, - 22, 0, 23, 11, 11, 12, 1, 0, - 24, 0, 25, 0, 26, 8, 8, 9, - 1, 0, 27, 0, 28, 0, 29, 5, - 5, 6, 1, 0, 0, 0, 0, 0, - 29, 0, 29, 5, 5, 6, 1, 0, - 0, 0, 0, 30, 29, 0, 31, 5, - 5, 6, 1, 0, 0, 0, 0, 0, - 31, 0, 31, 5, 5, 6, 1, 0, - 0, 0, 0, 32, 31, 0, 33, 5, - 5, 6, 1, 0, 0, 0, 0, 0, - 33, 0, 33, 5, 5, 6, 1, 0, - 0, 0, 0, 34, 33, 0, 35, 5, - 5, 6, 1, 0, 0, 0, 0, 0, - 35, 0, 35, 5, 5, 6, 1, 0, - 0, 0, 0, 36, 35, 0, 37, 5, - 5, 6, 1, 0, 0, 0, 0, 0, - 37, 0, 37, 5, 5, 6, 1, 0, - 0, 0, 0, 38, 37, 0, 40, 39, - 41, 42, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 41, - 39, 40, 39, 39, 39, 39, 43, 39, - 44, 44, 45, 40, 39, 46, 46, 45, - 39, 45, 39, 47, 47, 48, 40, 39, - 49, 49, 48, 39, 48, 39, 50, 50, - 51, 40, 39, 52, 52, 51, 39, 51, - 39, 53, 53, 54, 40, 39, 55, 55, - 54, 39, 54, 39, 56, 39, 39, 39, - 40, 39, 57, 39, 58, 39, 59, 53, - 53, 54, 40, 39, 60, 39, 61, 39, - 62, 50, 50, 51, 40, 39, 63, 39, - 64, 39, 65, 47, 47, 48, 40, 39, - 66, 39, 67, 39, 68, 44, 44, 45, - 40, 39, 39, 39, 39, 39, 68, 39, - 68, 44, 44, 45, 40, 39, 39, 39, - 39, 69, 68, 39, 70, 44, 44, 45, - 40, 39, 39, 39, 39, 39, 70, 39, - 70, 44, 44, 45, 40, 39, 39, 39, - 39, 71, 70, 39, 72, 44, 44, 45, - 40, 39, 39, 39, 39, 39, 72, 39, - 72, 44, 44, 45, 40, 39, 39, 39, - 39, 73, 72, 39, 74, 44, 44, 45, - 40, 39, 39, 39, 39, 39, 74, 39, - 74, 44, 44, 45, 40, 39, 39, 39, - 39, 75, 74, 39, 76, 44, 44, 45, - 40, 39, 39, 39, 39, 39, 76, 39, - 76, 44, 44, 45, 40, 39, 39, 39, - 39, 77, 76, 39, 79, 78, 80, 81, - 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 80, 78, 79, - 78, 78, 78, 78, 82, 78, 83, 83, - 84, 79, 78, 86, 86, 84, 85, 84, - 85, 87, 87, 88, 79, 78, 89, 89, - 88, 78, 88, 78, 90, 90, 91, 79, - 78, 92, 92, 91, 78, 91, 78, 93, - 93, 94, 79, 78, 95, 95, 94, 78, - 94, 78, 96, 78, 78, 78, 79, 78, - 97, 78, 98, 78, 99, 93, 93, 94, - 79, 78, 100, 78, 101, 78, 102, 90, - 90, 91, 79, 78, 103, 78, 104, 78, - 105, 87, 87, 88, 79, 78, 106, 78, - 107, 78, 108, 83, 83, 84, 79, 78, - 78, 78, 78, 78, 108, 78, 108, 83, - 83, 84, 79, 78, 78, 78, 78, 109, - 108, 78, 110, 83, 83, 84, 79, 78, - 78, 78, 78, 78, 110, 78, 110, 83, - 83, 84, 79, 78, 78, 78, 78, 111, - 110, 78, 112, 83, 83, 84, 79, 78, - 78, 78, 78, 78, 112, 78, 112, 83, - 83, 84, 79, 78, 78, 78, 78, 113, - 112, 78, 114, 83, 83, 84, 79, 78, - 78, 78, 78, 78, 114, 78, 114, 83, - 83, 84, 79, 78, 78, 78, 78, 115, - 114, 78, 116, 83, 83, 84, 79, 78, - 78, 78, 78, 78, 116, 78, 118, 117, - 119, 120, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 119, - 117, 118, 117, 117, 117, 117, 121, 117, - 122, 122, 123, 118, 117, 124, 124, 123, - 117, 123, 117, 125, 125, 126, 118, 117, - 127, 127, 126, 117, 126, 117, 128, 128, - 129, 118, 117, 130, 130, 129, 117, 129, - 117, 131, 131, 132, 118, 117, 133, 133, - 132, 117, 132, 117, 134, 117, 117, 117, - 118, 117, 135, 117, 136, 117, 137, 131, - 131, 132, 118, 117, 138, 117, 139, 117, - 140, 128, 128, 129, 118, 117, 141, 117, - 142, 117, 143, 125, 125, 126, 118, 117, - 144, 117, 145, 117, 146, 122, 122, 123, - 118, 117, 117, 117, 117, 117, 146, 117, - 146, 122, 122, 123, 118, 117, 117, 117, - 117, 147, 146, 117, 148, 122, 122, 123, - 118, 117, 117, 117, 117, 117, 148, 117, - 148, 122, 122, 123, 118, 117, 117, 117, - 117, 149, 148, 117, 150, 122, 122, 123, - 118, 117, 117, 117, 117, 117, 150, 117, - 150, 122, 122, 123, 118, 117, 117, 117, - 117, 151, 150, 117, 152, 122, 122, 123, - 118, 117, 117, 117, 117, 117, 152, 117, - 152, 122, 122, 123, 118, 117, 117, 117, - 117, 153, 152, 117, 154, 122, 122, 123, - 118, 117, 117, 117, 117, 117, 154, 117, - 154, 122, 122, 123, 118, 117, 117, 117, - 117, 155, 154, 117, 116, 83, 83, 84, - 79, 78, 78, 78, 78, 156, 116, 78, - 86, 86, 84, 1, 0, 114, 83, 83, - 84, 157, 0, 0, 0, 0, 0, 114, - 0, 114, 83, 83, 84, 157, 0, 0, - 0, 0, 158, 114, 0, 159, 159, 160, - 1, 0, 7, 7, 160, 0, 161, 161, - 162, 157, 0, 163, 163, 162, 0, 162, - 0, 164, 164, 165, 157, 0, 166, 166, - 165, 0, 165, 0, 167, 167, 168, 157, - 0, 169, 169, 168, 0, 168, 0, 157, - 0, 170, 171, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 170, 0, 157, 0, 0, 0, 0, 172, - 0, 173, 0, 0, 0, 157, 0, 174, - 0, 175, 0, 176, 167, 167, 168, 157, - 0, 177, 0, 178, 0, 179, 164, 164, - 165, 157, 0, 180, 0, 181, 0, 182, - 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, 202, 187, 204, - 205, 206, 207, 6, 1, 208, 209, 203, - 203, 38, 210, 203, 203, 211, 203, 212, - 205, 213, 213, 6, 1, 208, 209, 203, - 203, 203, 210, 203, 203, 211, 203, 205, - 213, 213, 6, 1, 208, 209, 203, 203, - 203, 210, 203, 203, 211, 203, 214, 203, - 203, 203, 19, 215, 203, 1, 208, 209, - 203, 203, 203, 216, 203, 214, 203, 217, - 218, 219, 220, 6, 1, 208, 209, 203, - 203, 36, 221, 203, 203, 211, 203, 222, - 218, 223, 223, 6, 1, 208, 209, 203, - 203, 203, 221, 203, 203, 211, 203, 218, - 223, 223, 6, 1, 208, 209, 203, 203, - 203, 221, 203, 203, 211, 203, 224, 203, - 203, 203, 19, 225, 203, 1, 208, 209, - 203, 203, 203, 216, 203, 224, 203, 226, - 227, 228, 229, 6, 1, 208, 209, 203, - 203, 34, 230, 203, 203, 211, 203, 231, - 227, 232, 232, 6, 1, 208, 209, 203, - 203, 203, 230, 203, 203, 211, 203, 227, - 232, 232, 6, 1, 208, 209, 203, 203, - 203, 230, 203, 203, 211, 203, 233, 203, - 203, 203, 19, 234, 203, 1, 208, 209, - 203, 203, 203, 216, 203, 233, 203, 235, - 236, 237, 238, 6, 1, 208, 209, 203, - 203, 32, 239, 203, 203, 211, 203, 240, - 236, 241, 241, 6, 1, 208, 209, 203, - 203, 203, 239, 203, 203, 211, 203, 236, - 241, 241, 6, 1, 208, 209, 203, 203, - 203, 239, 203, 203, 211, 203, 242, 203, - 203, 203, 19, 243, 203, 1, 208, 209, - 203, 203, 203, 216, 203, 242, 203, 244, - 245, 246, 247, 6, 1, 208, 209, 203, - 203, 30, 248, 203, 203, 211, 203, 249, - 245, 250, 250, 6, 1, 208, 209, 203, - 203, 203, 248, 203, 203, 211, 203, 245, - 250, 250, 6, 1, 208, 209, 203, 203, - 203, 248, 203, 203, 211, 203, 19, 251, - 203, 1, 208, 209, 203, 203, 203, 216, - 203, 252, 252, 203, 1, 208, 209, 203, - 203, 203, 216, 203, 253, 203, 203, 254, - 208, 209, 203, 208, 209, 203, 255, 203, - 208, 256, 203, 208, 257, 203, 208, 203, - 253, 203, 203, 203, 208, 209, 203, 258, - 203, 259, 260, 203, 1, 208, 209, 203, - 203, 4, 203, 3, 203, 252, 252, 203, - 1, 208, 209, 203, 252, 252, 203, 1, - 208, 209, 203, 258, 203, 252, 252, 203, - 1, 208, 209, 203, 258, 203, 259, 252, - 203, 1, 208, 209, 203, 203, 4, 203, - 19, 203, 261, 261, 6, 1, 208, 209, - 203, 203, 203, 216, 203, 262, 28, 263, - 264, 9, 1, 208, 209, 203, 203, 203, - 216, 203, 28, 263, 264, 9, 1, 208, - 209, 203, 203, 203, 216, 203, 263, 263, - 9, 1, 208, 209, 203, 203, 203, 216, - 203, 265, 25, 266, 267, 12, 1, 208, - 209, 203, 203, 203, 216, 203, 25, 266, - 267, 12, 1, 208, 209, 203, 203, 203, - 216, 203, 266, 266, 12, 1, 208, 209, - 203, 203, 203, 216, 203, 268, 22, 269, - 270, 15, 1, 208, 209, 203, 203, 203, - 216, 203, 22, 269, 270, 15, 1, 208, - 209, 203, 203, 203, 216, 203, 269, 269, - 15, 1, 208, 209, 203, 203, 203, 216, - 203, 271, 19, 252, 272, 203, 1, 208, - 209, 203, 203, 203, 216, 203, 19, 252, - 272, 203, 1, 208, 209, 203, 203, 203, - 216, 203, 252, 273, 203, 1, 208, 209, - 203, 203, 203, 216, 203, 19, 203, 252, - 252, 203, 1, 208, 209, 203, 203, 203, - 216, 203, 2, 3, 203, 203, 19, 251, - 203, 1, 208, 209, 203, 203, 203, 216, - 203, 2, 203, 245, 250, 250, 6, 1, - 208, 209, 203, 203, 203, 248, 203, 244, - 245, 250, 250, 6, 1, 208, 209, 203, - 203, 203, 248, 203, 203, 211, 203, 244, - 245, 246, 250, 6, 1, 208, 209, 203, - 203, 30, 248, 203, 203, 211, 203, 242, - 203, 274, 203, 261, 261, 6, 1, 208, - 209, 203, 203, 203, 216, 203, 242, 203, - 242, 203, 203, 203, 252, 252, 203, 1, - 208, 209, 203, 203, 203, 216, 203, 242, - 203, 242, 203, 203, 203, 252, 275, 203, - 1, 208, 209, 203, 203, 203, 216, 203, - 242, 203, 242, 203, 274, 203, 252, 252, - 203, 1, 208, 209, 203, 203, 203, 216, - 203, 242, 203, 242, 3, 203, 203, 19, - 243, 203, 1, 208, 209, 203, 203, 203, - 216, 203, 242, 203, 235, 236, 241, 241, - 6, 1, 208, 209, 203, 203, 203, 239, - 203, 203, 211, 203, 235, 236, 237, 241, - 6, 1, 208, 209, 203, 203, 32, 239, - 203, 203, 211, 203, 233, 203, 276, 203, - 261, 261, 6, 1, 208, 209, 203, 203, - 203, 216, 203, 233, 203, 233, 203, 203, - 203, 252, 252, 203, 1, 208, 209, 203, - 203, 203, 216, 203, 233, 203, 233, 203, - 203, 203, 252, 277, 203, 1, 208, 209, - 203, 203, 203, 216, 203, 233, 203, 233, - 203, 276, 203, 252, 252, 203, 1, 208, - 209, 203, 203, 203, 216, 203, 233, 203, - 233, 3, 203, 203, 19, 234, 203, 1, - 208, 209, 203, 203, 203, 216, 203, 233, - 203, 226, 227, 232, 232, 6, 1, 208, - 209, 203, 203, 203, 230, 203, 203, 211, - 203, 226, 227, 228, 232, 6, 1, 208, - 209, 203, 203, 34, 230, 203, 203, 211, - 203, 224, 203, 278, 203, 261, 261, 6, - 1, 208, 209, 203, 203, 203, 216, 203, - 224, 203, 224, 203, 203, 203, 252, 252, - 203, 1, 208, 209, 203, 203, 203, 216, - 203, 224, 203, 224, 203, 203, 203, 252, - 279, 203, 1, 208, 209, 203, 203, 203, - 216, 203, 224, 203, 224, 203, 278, 203, - 252, 252, 203, 1, 208, 209, 203, 203, - 203, 216, 203, 224, 203, 224, 3, 203, - 203, 19, 225, 203, 1, 208, 209, 203, - 203, 203, 216, 203, 224, 203, 217, 218, - 223, 223, 6, 1, 208, 209, 203, 203, - 203, 221, 203, 203, 211, 203, 217, 218, - 219, 223, 6, 1, 208, 209, 203, 203, - 36, 221, 203, 203, 211, 203, 214, 203, - 280, 203, 261, 261, 6, 1, 208, 209, - 203, 203, 203, 216, 203, 214, 203, 214, - 203, 203, 203, 252, 252, 203, 1, 208, - 209, 203, 203, 203, 216, 203, 214, 203, - 214, 203, 203, 203, 252, 281, 203, 1, - 208, 209, 203, 203, 203, 216, 203, 214, - 203, 214, 203, 280, 203, 252, 252, 203, - 1, 208, 209, 203, 203, 203, 216, 203, - 214, 203, 214, 3, 203, 203, 19, 215, - 203, 1, 208, 209, 203, 203, 203, 216, - 203, 214, 203, 204, 205, 213, 213, 6, - 1, 208, 209, 203, 203, 203, 210, 203, - 203, 211, 203, 204, 205, 206, 213, 6, - 1, 208, 209, 203, 203, 38, 210, 203, - 203, 211, 203, 283, 284, 285, 286, 45, - 40, 287, 288, 282, 282, 77, 289, 282, - 282, 290, 282, 291, 284, 292, 286, 45, - 40, 287, 288, 282, 282, 282, 289, 282, - 282, 290, 282, 284, 292, 286, 45, 40, - 287, 288, 282, 282, 282, 289, 282, 282, - 290, 282, 293, 282, 282, 282, 58, 294, - 282, 40, 287, 288, 282, 282, 282, 295, - 282, 293, 282, 296, 297, 298, 299, 45, - 40, 287, 288, 282, 282, 75, 300, 282, - 282, 290, 282, 301, 297, 302, 302, 45, - 40, 287, 288, 282, 282, 282, 300, 282, - 282, 290, 282, 297, 302, 302, 45, 40, - 287, 288, 282, 282, 282, 300, 282, 282, - 290, 282, 303, 282, 282, 282, 58, 304, - 282, 40, 287, 288, 282, 282, 282, 295, - 282, 303, 282, 305, 306, 307, 308, 45, - 40, 287, 288, 282, 282, 73, 309, 282, - 282, 290, 282, 310, 306, 311, 311, 45, - 40, 287, 288, 282, 282, 282, 309, 282, - 282, 290, 282, 306, 311, 311, 45, 40, - 287, 288, 282, 282, 282, 309, 282, 282, - 290, 282, 312, 282, 282, 282, 58, 313, - 282, 40, 287, 288, 282, 282, 282, 295, - 282, 312, 282, 314, 315, 316, 317, 45, - 40, 287, 288, 282, 282, 71, 318, 282, - 282, 290, 282, 319, 315, 320, 320, 45, - 40, 287, 288, 282, 282, 282, 318, 282, - 282, 290, 282, 315, 320, 320, 45, 40, - 287, 288, 282, 282, 282, 318, 282, 282, - 290, 282, 321, 282, 282, 282, 58, 322, - 282, 40, 287, 288, 282, 282, 282, 295, - 282, 321, 282, 323, 324, 325, 326, 45, - 40, 287, 288, 282, 282, 69, 327, 282, - 282, 290, 282, 328, 324, 329, 329, 45, - 40, 287, 288, 282, 282, 282, 327, 282, - 282, 290, 282, 324, 329, 329, 45, 40, - 287, 288, 282, 282, 282, 327, 282, 282, - 290, 282, 58, 330, 282, 40, 287, 288, - 282, 282, 282, 295, 282, 331, 331, 282, - 40, 287, 288, 282, 282, 282, 295, 282, - 332, 282, 282, 333, 287, 288, 282, 287, - 288, 282, 334, 282, 287, 335, 282, 287, - 336, 282, 287, 282, 332, 282, 282, 282, - 287, 288, 282, 337, 282, 338, 339, 282, - 40, 287, 288, 282, 282, 43, 282, 42, - 282, 331, 331, 282, 40, 287, 288, 282, - 331, 331, 282, 40, 287, 288, 282, 337, - 282, 331, 331, 282, 40, 287, 288, 282, - 337, 282, 338, 331, 282, 40, 287, 288, - 282, 282, 43, 282, 58, 282, 340, 340, - 45, 40, 287, 288, 282, 282, 282, 295, - 282, 341, 67, 342, 343, 48, 40, 287, - 288, 282, 282, 282, 295, 282, 67, 342, - 343, 48, 40, 287, 288, 282, 282, 282, - 295, 282, 342, 342, 48, 40, 287, 288, - 282, 282, 282, 295, 282, 344, 64, 345, - 346, 51, 40, 287, 288, 282, 282, 282, - 295, 282, 64, 345, 346, 51, 40, 287, - 288, 282, 282, 282, 295, 282, 345, 345, - 51, 40, 287, 288, 282, 282, 282, 295, - 282, 347, 61, 348, 349, 54, 40, 287, - 288, 282, 282, 282, 295, 282, 61, 348, - 349, 54, 40, 287, 288, 282, 282, 282, - 295, 282, 348, 348, 54, 40, 287, 288, - 282, 282, 282, 295, 282, 350, 58, 331, - 351, 282, 40, 287, 288, 282, 282, 282, - 295, 282, 58, 331, 351, 282, 40, 287, - 288, 282, 282, 282, 295, 282, 331, 352, - 282, 40, 287, 288, 282, 282, 282, 295, - 282, 58, 282, 331, 331, 282, 40, 287, - 288, 282, 282, 282, 295, 282, 41, 42, - 282, 282, 58, 330, 282, 40, 287, 288, - 282, 282, 282, 295, 282, 41, 282, 324, - 329, 329, 45, 40, 287, 288, 282, 282, - 282, 327, 282, 323, 324, 329, 329, 45, - 40, 287, 288, 282, 282, 282, 327, 282, - 282, 290, 282, 323, 324, 325, 329, 45, - 40, 287, 288, 282, 282, 69, 327, 282, - 282, 290, 282, 321, 282, 353, 282, 340, - 340, 45, 40, 287, 288, 282, 282, 282, - 295, 282, 321, 282, 321, 282, 282, 282, - 331, 331, 282, 40, 287, 288, 282, 282, - 282, 295, 282, 321, 282, 321, 282, 282, - 282, 331, 354, 282, 40, 287, 288, 282, - 282, 282, 295, 282, 321, 282, 321, 282, - 353, 282, 331, 331, 282, 40, 287, 288, - 282, 282, 282, 295, 282, 321, 282, 321, - 42, 282, 282, 58, 322, 282, 40, 287, - 288, 282, 282, 282, 295, 282, 321, 282, - 314, 315, 320, 320, 45, 40, 287, 288, - 282, 282, 282, 318, 282, 282, 290, 282, - 314, 315, 316, 320, 45, 40, 287, 288, - 282, 282, 71, 318, 282, 282, 290, 282, - 312, 282, 355, 282, 340, 340, 45, 40, - 287, 288, 282, 282, 282, 295, 282, 312, - 282, 312, 282, 282, 282, 331, 331, 282, - 40, 287, 288, 282, 282, 282, 295, 282, - 312, 282, 312, 282, 282, 282, 331, 356, - 282, 40, 287, 288, 282, 282, 282, 295, - 282, 312, 282, 312, 282, 355, 282, 331, - 331, 282, 40, 287, 288, 282, 282, 282, - 295, 282, 312, 282, 312, 42, 282, 282, - 58, 313, 282, 40, 287, 288, 282, 282, - 282, 295, 282, 312, 282, 305, 306, 311, - 311, 45, 40, 287, 288, 282, 282, 282, - 309, 282, 282, 290, 282, 305, 306, 307, - 311, 45, 40, 287, 288, 282, 282, 73, - 309, 282, 282, 290, 282, 303, 282, 357, - 282, 340, 340, 45, 40, 287, 288, 282, - 282, 282, 295, 282, 303, 282, 303, 282, - 282, 282, 331, 331, 282, 40, 287, 288, - 282, 282, 282, 295, 282, 303, 282, 303, - 282, 282, 282, 331, 358, 282, 40, 287, - 288, 282, 282, 282, 295, 282, 303, 282, - 303, 282, 357, 282, 331, 331, 282, 40, - 287, 288, 282, 282, 282, 295, 282, 303, - 282, 303, 42, 282, 282, 58, 304, 282, - 40, 287, 288, 282, 282, 282, 295, 282, - 303, 282, 296, 297, 302, 302, 45, 40, - 287, 288, 282, 282, 282, 300, 282, 282, - 290, 282, 296, 297, 298, 302, 45, 40, - 287, 288, 282, 282, 75, 300, 282, 282, - 290, 282, 293, 282, 359, 282, 340, 340, - 45, 40, 287, 288, 282, 282, 282, 295, - 282, 293, 282, 293, 282, 282, 282, 331, - 331, 282, 40, 287, 288, 282, 282, 282, - 295, 282, 293, 282, 293, 282, 282, 282, - 331, 360, 282, 40, 287, 288, 282, 282, - 282, 295, 282, 293, 282, 293, 282, 359, - 282, 331, 331, 282, 40, 287, 288, 282, - 282, 282, 295, 282, 293, 282, 76, 44, - 44, 45, 40, 282, 282, 282, 282, 282, - 76, 282, 293, 42, 282, 282, 58, 294, - 282, 40, 287, 288, 282, 282, 282, 295, - 282, 293, 282, 283, 284, 292, 286, 45, - 40, 287, 288, 282, 282, 282, 289, 282, - 282, 290, 282, 362, 191, 363, 363, 84, - 79, 194, 195, 361, 361, 361, 197, 361, - 361, 200, 361, 191, 363, 363, 84, 79, - 194, 195, 361, 361, 361, 197, 361, 361, - 200, 361, 364, 361, 361, 361, 98, 365, - 361, 79, 194, 195, 361, 361, 361, 366, - 361, 364, 361, 367, 368, 369, 370, 84, - 79, 194, 195, 361, 361, 115, 371, 361, - 361, 200, 361, 372, 368, 373, 373, 84, - 79, 194, 195, 361, 361, 361, 371, 361, - 361, 200, 361, 368, 373, 373, 84, 79, - 194, 195, 361, 361, 361, 371, 361, 361, - 200, 361, 374, 361, 361, 361, 98, 375, - 361, 79, 194, 195, 361, 361, 361, 366, - 361, 374, 361, 376, 377, 378, 379, 84, - 79, 194, 195, 361, 361, 113, 380, 361, - 361, 200, 361, 381, 377, 382, 382, 84, - 79, 194, 195, 361, 361, 361, 380, 361, - 361, 200, 361, 377, 382, 382, 84, 79, - 194, 195, 361, 361, 361, 380, 361, 361, - 200, 361, 383, 361, 361, 361, 98, 384, - 361, 79, 194, 195, 361, 361, 361, 366, - 361, 383, 361, 385, 386, 387, 388, 84, - 79, 194, 195, 361, 361, 111, 389, 361, - 361, 200, 361, 390, 386, 391, 391, 84, - 79, 194, 195, 361, 361, 361, 389, 361, - 361, 200, 361, 386, 391, 391, 84, 79, - 194, 195, 361, 361, 361, 389, 361, 361, - 200, 361, 392, 361, 361, 361, 98, 393, - 361, 79, 194, 195, 361, 361, 361, 366, - 361, 392, 361, 394, 395, 396, 397, 84, - 79, 194, 195, 361, 361, 109, 398, 361, - 361, 200, 361, 399, 395, 400, 400, 84, - 79, 194, 195, 361, 361, 361, 398, 361, - 361, 200, 361, 395, 400, 400, 84, 79, - 194, 195, 361, 361, 361, 398, 361, 361, - 200, 361, 98, 401, 361, 79, 194, 195, - 361, 361, 361, 366, 361, 402, 402, 361, - 79, 194, 195, 361, 361, 361, 366, 361, - 403, 361, 361, 404, 194, 195, 361, 194, - 195, 361, 405, 361, 194, 406, 361, 194, - 407, 361, 194, 361, 403, 361, 361, 361, - 194, 195, 361, 408, 361, 409, 410, 361, - 79, 194, 195, 361, 361, 82, 361, 81, - 361, 402, 402, 361, 79, 194, 195, 361, - 402, 402, 361, 79, 194, 195, 361, 408, - 361, 402, 402, 361, 79, 194, 195, 361, - 408, 361, 409, 402, 361, 79, 194, 195, - 361, 361, 82, 361, 98, 361, 411, 411, - 84, 79, 194, 195, 361, 361, 361, 366, - 361, 412, 107, 413, 414, 88, 79, 194, - 195, 361, 361, 361, 366, 361, 107, 413, - 414, 88, 79, 194, 195, 361, 361, 361, - 366, 361, 413, 413, 88, 79, 194, 195, - 361, 361, 361, 366, 361, 415, 104, 416, - 417, 91, 79, 194, 195, 361, 361, 361, - 366, 361, 104, 416, 417, 91, 79, 194, - 195, 361, 361, 361, 366, 361, 416, 416, - 91, 79, 194, 195, 361, 361, 361, 366, - 361, 418, 101, 419, 420, 94, 79, 194, - 195, 361, 361, 361, 366, 361, 101, 419, - 420, 94, 79, 194, 195, 361, 361, 361, - 366, 361, 419, 419, 94, 79, 194, 195, - 361, 361, 361, 366, 361, 421, 98, 402, - 422, 361, 79, 194, 195, 361, 361, 361, - 366, 361, 98, 402, 422, 361, 79, 194, - 195, 361, 361, 361, 366, 361, 402, 423, - 361, 79, 194, 195, 361, 361, 361, 366, - 361, 98, 361, 402, 402, 361, 79, 194, - 195, 361, 361, 361, 366, 361, 80, 81, - 361, 361, 98, 401, 361, 79, 194, 195, - 361, 361, 361, 366, 361, 80, 361, 395, - 400, 400, 84, 79, 194, 195, 361, 361, - 361, 398, 361, 394, 395, 400, 400, 84, - 79, 194, 195, 361, 361, 361, 398, 361, - 361, 200, 361, 394, 395, 396, 400, 84, - 79, 194, 195, 361, 361, 109, 398, 361, - 361, 200, 361, 392, 361, 424, 361, 411, - 411, 84, 79, 194, 195, 361, 361, 361, - 366, 361, 392, 361, 392, 361, 361, 361, - 402, 402, 361, 79, 194, 195, 361, 361, - 361, 366, 361, 392, 361, 392, 361, 361, - 361, 402, 425, 361, 79, 194, 195, 361, - 361, 361, 366, 361, 392, 361, 392, 361, - 424, 361, 402, 402, 361, 79, 194, 195, - 361, 361, 361, 366, 361, 392, 361, 392, - 81, 361, 361, 98, 393, 361, 79, 194, - 195, 361, 361, 361, 366, 361, 392, 361, - 385, 386, 391, 391, 84, 79, 194, 195, - 361, 361, 361, 389, 361, 361, 200, 361, - 385, 386, 387, 391, 84, 79, 194, 195, - 361, 361, 111, 389, 361, 361, 200, 361, - 383, 361, 426, 361, 411, 411, 84, 79, - 194, 195, 361, 361, 361, 366, 361, 383, - 361, 383, 361, 361, 361, 402, 402, 361, - 79, 194, 195, 361, 361, 361, 366, 361, - 383, 361, 383, 361, 361, 361, 402, 427, - 361, 79, 194, 195, 361, 361, 361, 366, - 361, 383, 361, 383, 361, 426, 361, 402, - 402, 361, 79, 194, 195, 361, 361, 361, - 366, 361, 383, 361, 383, 81, 361, 361, - 98, 384, 361, 79, 194, 195, 361, 361, - 361, 366, 361, 383, 361, 376, 377, 382, - 382, 84, 79, 194, 195, 361, 361, 361, - 380, 361, 361, 200, 361, 376, 377, 378, - 382, 84, 79, 194, 195, 361, 361, 113, - 380, 361, 361, 200, 361, 374, 361, 428, - 361, 411, 411, 84, 79, 194, 195, 361, - 361, 361, 366, 361, 374, 361, 374, 361, - 361, 361, 402, 402, 361, 79, 194, 195, - 361, 361, 361, 366, 361, 374, 361, 374, - 361, 361, 361, 402, 429, 361, 79, 194, - 195, 361, 361, 361, 366, 361, 374, 361, - 374, 361, 428, 361, 402, 402, 361, 79, - 194, 195, 361, 361, 361, 366, 361, 374, - 361, 374, 81, 361, 361, 98, 375, 361, - 79, 194, 195, 361, 361, 361, 366, 361, - 374, 361, 367, 368, 373, 373, 84, 79, - 194, 195, 361, 361, 361, 371, 361, 361, - 200, 361, 367, 368, 369, 373, 84, 79, - 194, 195, 361, 361, 115, 371, 361, 361, - 200, 361, 364, 361, 430, 361, 411, 411, - 84, 79, 194, 195, 361, 361, 361, 366, - 361, 364, 361, 364, 361, 361, 361, 402, - 402, 361, 79, 194, 195, 361, 361, 361, - 366, 361, 364, 361, 364, 361, 361, 361, - 402, 431, 361, 79, 194, 195, 361, 361, - 361, 366, 361, 364, 361, 364, 361, 430, - 361, 402, 402, 361, 79, 194, 195, 361, - 361, 361, 366, 361, 364, 361, 364, 81, - 361, 361, 98, 365, 361, 79, 194, 195, - 361, 361, 361, 366, 361, 364, 361, 116, - 83, 83, 84, 79, 432, 432, 432, 432, - 156, 116, 432, 190, 191, 363, 363, 84, - 79, 194, 195, 361, 361, 361, 197, 361, - 361, 200, 361, 116, 83, 83, 84, 79, - 432, 432, 432, 432, 432, 116, 432, 434, - 435, 436, 437, 123, 118, 438, 439, 433, - 433, 155, 440, 433, 433, 441, 433, 442, - 435, 437, 437, 123, 118, 438, 439, 433, - 433, 433, 440, 433, 433, 441, 433, 435, - 437, 437, 123, 118, 438, 439, 433, 433, - 433, 440, 433, 433, 441, 433, 443, 433, - 433, 433, 136, 444, 433, 118, 438, 439, - 433, 433, 433, 445, 433, 443, 433, 446, - 447, 448, 449, 123, 118, 438, 439, 433, - 433, 153, 450, 433, 433, 441, 433, 451, - 447, 452, 452, 123, 118, 438, 439, 433, - 433, 433, 450, 433, 433, 441, 433, 447, - 452, 452, 123, 118, 438, 439, 433, 433, - 433, 450, 433, 433, 441, 433, 453, 433, - 433, 433, 136, 454, 433, 118, 438, 439, - 433, 433, 433, 445, 433, 453, 433, 455, - 456, 457, 458, 123, 118, 438, 439, 433, - 433, 151, 459, 433, 433, 441, 433, 460, - 456, 461, 461, 123, 118, 438, 439, 433, - 433, 433, 459, 433, 433, 441, 433, 456, - 461, 461, 123, 118, 438, 439, 433, 433, - 433, 459, 433, 433, 441, 433, 462, 433, - 433, 433, 136, 463, 433, 118, 438, 439, - 433, 433, 433, 445, 433, 462, 433, 464, - 465, 466, 467, 123, 118, 438, 439, 433, - 433, 149, 468, 433, 433, 441, 433, 469, - 465, 470, 470, 123, 118, 438, 439, 433, - 433, 433, 468, 433, 433, 441, 433, 465, - 470, 470, 123, 118, 438, 439, 433, 433, - 433, 468, 433, 433, 441, 433, 471, 433, - 433, 433, 136, 472, 433, 118, 438, 439, - 433, 433, 433, 445, 433, 471, 433, 473, - 474, 475, 476, 123, 118, 438, 439, 433, - 433, 147, 477, 433, 433, 441, 433, 478, - 474, 479, 479, 123, 118, 438, 439, 433, - 433, 433, 477, 433, 433, 441, 433, 474, - 479, 479, 123, 118, 438, 439, 433, 433, - 433, 477, 433, 433, 441, 433, 136, 480, - 433, 118, 438, 439, 433, 433, 433, 445, - 433, 481, 481, 433, 118, 438, 439, 433, - 433, 433, 445, 433, 482, 433, 433, 483, - 438, 439, 433, 438, 439, 433, 484, 433, - 438, 485, 433, 438, 486, 433, 438, 433, - 482, 433, 433, 433, 438, 439, 433, 487, - 433, 488, 489, 433, 118, 438, 439, 433, - 433, 121, 433, 120, 433, 481, 481, 433, - 118, 438, 439, 433, 481, 481, 433, 118, - 438, 439, 433, 487, 433, 481, 481, 433, - 118, 438, 439, 433, 487, 433, 488, 481, - 433, 118, 438, 439, 433, 433, 121, 433, - 136, 433, 490, 490, 123, 118, 438, 439, - 433, 433, 433, 445, 433, 491, 145, 492, - 493, 126, 118, 438, 439, 433, 433, 433, - 445, 433, 145, 492, 493, 126, 118, 438, - 439, 433, 433, 433, 445, 433, 492, 492, - 126, 118, 438, 439, 433, 433, 433, 445, - 433, 494, 142, 495, 496, 129, 118, 438, - 439, 433, 433, 433, 445, 433, 142, 495, - 496, 129, 118, 438, 439, 433, 433, 433, - 445, 433, 495, 495, 129, 118, 438, 439, - 433, 433, 433, 445, 433, 497, 139, 498, - 499, 132, 118, 438, 439, 433, 433, 433, - 445, 433, 139, 498, 499, 132, 118, 438, - 439, 433, 433, 433, 445, 433, 498, 498, - 132, 118, 438, 439, 433, 433, 433, 445, - 433, 500, 136, 481, 501, 433, 118, 438, - 439, 433, 433, 433, 445, 433, 136, 481, - 501, 433, 118, 438, 439, 433, 433, 433, - 445, 433, 481, 502, 433, 118, 438, 439, - 433, 433, 433, 445, 433, 136, 433, 481, - 481, 433, 118, 438, 439, 433, 433, 433, - 445, 433, 119, 120, 433, 433, 136, 480, - 433, 118, 438, 439, 433, 433, 433, 445, - 433, 119, 433, 474, 479, 479, 123, 118, - 438, 439, 433, 433, 433, 477, 433, 473, - 474, 479, 479, 123, 118, 438, 439, 433, - 433, 433, 477, 433, 433, 441, 433, 473, - 474, 475, 479, 123, 118, 438, 439, 433, - 433, 147, 477, 433, 433, 441, 433, 471, - 433, 503, 433, 490, 490, 123, 118, 438, - 439, 433, 433, 433, 445, 433, 471, 433, - 471, 433, 433, 433, 481, 481, 433, 118, - 438, 439, 433, 433, 433, 445, 433, 471, - 433, 471, 433, 433, 433, 481, 504, 433, - 118, 438, 439, 433, 433, 433, 445, 433, - 471, 433, 471, 433, 503, 433, 481, 481, - 433, 118, 438, 439, 433, 433, 433, 445, - 433, 471, 433, 471, 120, 433, 433, 136, - 472, 433, 118, 438, 439, 433, 433, 433, - 445, 433, 471, 433, 464, 465, 470, 470, - 123, 118, 438, 439, 433, 433, 433, 468, - 433, 433, 441, 433, 464, 465, 466, 470, - 123, 118, 438, 439, 433, 433, 149, 468, - 433, 433, 441, 433, 462, 433, 505, 433, - 490, 490, 123, 118, 438, 439, 433, 433, - 433, 445, 433, 462, 433, 462, 433, 433, - 433, 481, 481, 433, 118, 438, 439, 433, - 433, 433, 445, 433, 462, 433, 462, 433, - 433, 433, 481, 506, 433, 118, 438, 439, - 433, 433, 433, 445, 433, 462, 433, 462, - 433, 505, 433, 481, 481, 433, 118, 438, - 439, 433, 433, 433, 445, 433, 462, 433, - 462, 120, 433, 433, 136, 463, 433, 118, - 438, 439, 433, 433, 433, 445, 433, 462, - 433, 455, 456, 461, 461, 123, 118, 438, - 439, 433, 433, 433, 459, 433, 433, 441, - 433, 455, 456, 457, 461, 123, 118, 438, - 439, 433, 433, 151, 459, 433, 433, 441, - 433, 453, 433, 507, 433, 490, 490, 123, - 118, 438, 439, 433, 433, 433, 445, 433, - 453, 433, 453, 433, 433, 433, 481, 481, - 433, 118, 438, 439, 433, 433, 433, 445, - 433, 453, 433, 453, 433, 433, 433, 481, - 508, 433, 118, 438, 439, 433, 433, 433, - 445, 433, 453, 433, 453, 433, 507, 433, - 481, 481, 433, 118, 438, 439, 433, 433, - 433, 445, 433, 453, 433, 453, 120, 433, - 433, 136, 454, 433, 118, 438, 439, 433, - 433, 433, 445, 433, 453, 433, 446, 447, - 452, 452, 123, 118, 438, 439, 433, 433, - 433, 450, 433, 433, 441, 433, 446, 447, - 448, 452, 123, 118, 438, 439, 433, 433, - 153, 450, 433, 433, 441, 433, 443, 433, - 509, 433, 490, 490, 123, 118, 438, 439, - 433, 433, 433, 445, 433, 443, 433, 443, - 433, 433, 433, 481, 481, 433, 118, 438, - 439, 433, 433, 433, 445, 433, 443, 433, - 443, 433, 433, 433, 481, 510, 433, 118, - 438, 439, 433, 433, 433, 445, 433, 443, - 433, 443, 433, 509, 433, 481, 481, 433, - 118, 438, 439, 433, 433, 433, 445, 433, - 443, 433, 443, 120, 433, 433, 136, 444, - 433, 118, 438, 439, 433, 433, 433, 445, - 433, 443, 433, 434, 435, 437, 437, 123, - 118, 438, 439, 433, 433, 433, 440, 433, - 433, 441, 433, 188, 189, 190, 191, 511, - 363, 84, 79, 194, 195, 196, 196, 156, - 197, 361, 188, 200, 361, 204, 512, 206, - 207, 6, 1, 208, 209, 203, 203, 38, - 210, 203, 203, 211, 203, 214, 189, 190, - 191, 513, 514, 84, 157, 515, 516, 203, - 196, 156, 517, 203, 214, 200, 203, 116, - 518, 518, 84, 157, 208, 209, 203, 203, - 156, 519, 203, 520, 203, 203, 521, 515, - 516, 203, 515, 516, 203, 255, 203, 515, - 522, 203, 515, 523, 203, 515, 203, 520, - 203, 203, 203, 515, 516, 203, 524, 3, - 361, 361, 402, 431, 361, 79, 194, 195, - 361, 361, 361, 366, 361, 524, 361, 525, - 368, 526, 527, 84, 157, 515, 516, 203, - 203, 158, 371, 203, 203, 200, 203, 528, - 368, 529, 529, 84, 157, 515, 516, 203, - 203, 203, 371, 203, 203, 200, 203, 368, - 529, 529, 84, 157, 515, 516, 203, 203, - 203, 371, 203, 203, 200, 203, 525, 368, - 529, 529, 84, 157, 515, 516, 203, 203, - 203, 371, 203, 203, 200, 203, 525, 368, - 526, 529, 84, 157, 515, 516, 203, 203, - 158, 371, 203, 203, 200, 203, 214, 203, - 280, 116, 530, 530, 160, 157, 208, 209, - 203, 203, 203, 519, 203, 214, 203, 531, - 184, 532, 533, 162, 157, 515, 516, 203, - 203, 203, 534, 203, 184, 532, 533, 162, - 157, 515, 516, 203, 203, 203, 534, 203, - 532, 532, 162, 157, 515, 516, 203, 203, - 203, 534, 203, 535, 181, 536, 537, 165, - 157, 515, 516, 203, 203, 203, 534, 203, - 181, 536, 537, 165, 157, 515, 516, 203, - 203, 203, 534, 203, 536, 536, 165, 157, - 515, 516, 203, 203, 203, 534, 203, 538, - 178, 539, 540, 168, 157, 515, 516, 203, - 203, 203, 534, 203, 178, 539, 540, 168, - 157, 515, 516, 203, 203, 203, 534, 203, - 539, 539, 168, 157, 515, 516, 203, 203, - 203, 534, 203, 541, 175, 542, 543, 203, - 157, 515, 516, 203, 203, 203, 534, 203, - 175, 542, 543, 203, 157, 515, 516, 203, - 203, 203, 534, 203, 542, 542, 203, 157, - 515, 516, 203, 203, 203, 534, 203, 544, - 203, 545, 546, 203, 157, 515, 516, 203, - 203, 172, 203, 171, 203, 542, 542, 203, - 157, 515, 516, 203, 542, 542, 203, 157, - 515, 516, 203, 544, 203, 542, 542, 203, - 157, 515, 516, 203, 544, 203, 545, 542, - 203, 157, 515, 516, 203, 203, 172, 203, - 524, 171, 361, 361, 98, 365, 361, 79, - 194, 195, 361, 361, 361, 366, 361, 524, - 361, 548, 547, 549, 549, 547, 186, 550, - 551, 547, 549, 549, 547, 186, 550, 551, - 547, 552, 547, 547, 553, 550, 551, 547, - 550, 551, 547, 554, 547, 550, 555, 547, - 550, 556, 547, 550, 547, 552, 547, 547, - 547, 550, 551, 547, 188, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 196, 432, - 432, 432, 432, 188, 432, 0 + 1, 0, 2, 2, 3, 1, 0, 4, + 4, 3, 0, 3, 0, 5, 5, 6, + 1, 0, 7, 7, 6, 0, 6, 0, + 8, 8, 9, 1, 0, 10, 10, 9, + 0, 9, 0, 11, 11, 12, 1, 0, + 13, 13, 12, 0, 12, 0, 14, 0, + 0, 0, 1, 0, 15, 0, 16, 0, + 17, 11, 11, 12, 1, 0, 18, 0, + 19, 0, 20, 8, 8, 9, 1, 0, + 21, 0, 22, 0, 23, 5, 5, 6, + 1, 0, 24, 0, 25, 0, 26, 2, + 2, 3, 1, 0, 26, 2, 2, 3, + 1, 0, 0, 0, 0, 27, 0, 28, + 2, 2, 3, 1, 0, 28, 2, 2, + 3, 1, 0, 0, 0, 0, 29, 0, + 30, 2, 2, 3, 1, 0, 30, 2, + 2, 3, 1, 0, 0, 0, 0, 31, + 0, 32, 2, 2, 3, 1, 0, 32, + 2, 2, 3, 1, 0, 0, 0, 0, + 33, 0, 34, 2, 2, 3, 1, 0, + 34, 2, 2, 3, 1, 0, 0, 0, + 0, 35, 0, 37, 36, 38, 38, 39, + 37, 36, 40, 40, 39, 36, 39, 36, + 41, 41, 42, 37, 36, 43, 43, 42, + 36, 42, 36, 44, 44, 45, 37, 36, + 46, 46, 45, 36, 45, 36, 47, 47, + 48, 37, 36, 49, 49, 48, 36, 48, + 36, 50, 36, 36, 36, 37, 36, 51, + 36, 52, 36, 53, 47, 47, 48, 37, + 36, 54, 36, 55, 36, 56, 44, 44, + 45, 37, 36, 57, 36, 58, 36, 59, + 41, 41, 42, 37, 36, 60, 36, 61, + 36, 62, 38, 38, 39, 37, 36, 62, + 38, 38, 39, 37, 36, 36, 36, 36, + 63, 36, 64, 38, 38, 39, 37, 36, + 64, 38, 38, 39, 37, 36, 36, 36, + 36, 65, 36, 66, 38, 38, 39, 37, + 36, 66, 38, 38, 39, 37, 36, 36, + 36, 36, 67, 36, 68, 38, 38, 39, + 37, 36, 68, 38, 38, 39, 37, 36, + 36, 36, 36, 69, 36, 70, 38, 38, + 39, 37, 36, 70, 38, 38, 39, 37, + 36, 36, 36, 36, 71, 36, 73, 72, + 74, 74, 75, 73, 72, 77, 77, 75, + 76, 75, 76, 78, 78, 79, 73, 72, + 80, 80, 79, 72, 79, 72, 81, 81, + 82, 73, 72, 83, 83, 82, 72, 82, + 72, 84, 84, 85, 73, 72, 86, 86, + 85, 72, 85, 72, 87, 72, 72, 72, + 73, 72, 88, 72, 89, 72, 90, 84, + 84, 85, 73, 72, 91, 72, 92, 72, + 93, 81, 81, 82, 73, 72, 94, 72, + 95, 72, 96, 78, 78, 79, 73, 72, + 97, 72, 98, 72, 99, 74, 74, 75, + 73, 72, 99, 74, 74, 75, 73, 72, + 72, 72, 72, 100, 72, 101, 74, 74, + 75, 73, 72, 101, 74, 74, 75, 73, + 72, 72, 72, 72, 102, 72, 103, 74, + 74, 75, 73, 72, 103, 74, 74, 75, + 73, 72, 72, 72, 72, 104, 72, 105, + 74, 74, 75, 73, 72, 105, 74, 74, + 75, 73, 72, 72, 72, 72, 106, 72, + 107, 74, 74, 75, 73, 72, 109, 108, + 110, 110, 111, 109, 108, 112, 112, 111, + 108, 111, 108, 113, 113, 114, 109, 108, + 115, 115, 114, 108, 114, 108, 116, 116, + 117, 109, 108, 118, 118, 117, 108, 117, + 108, 119, 119, 120, 109, 108, 121, 121, + 120, 108, 120, 108, 122, 108, 108, 108, + 109, 108, 123, 108, 124, 108, 125, 119, + 119, 120, 109, 108, 126, 108, 127, 108, + 128, 116, 116, 117, 109, 108, 129, 108, + 130, 108, 131, 113, 113, 114, 109, 108, + 132, 108, 133, 108, 134, 110, 110, 111, + 109, 108, 134, 110, 110, 111, 109, 108, + 108, 108, 108, 135, 108, 136, 110, 110, + 111, 109, 108, 136, 110, 110, 111, 109, + 108, 108, 108, 108, 137, 108, 138, 110, + 110, 111, 109, 108, 138, 110, 110, 111, + 109, 108, 108, 108, 108, 139, 108, 140, + 110, 110, 111, 109, 108, 140, 110, 110, + 111, 109, 108, 108, 108, 108, 141, 108, + 142, 110, 110, 111, 109, 108, 142, 110, + 110, 111, 109, 108, 108, 108, 108, 143, + 108, 107, 74, 74, 75, 73, 72, 72, + 72, 72, 144, 72, 77, 77, 75, 1, + 0, 145, 145, 146, 1, 0, 4, 4, + 146, 0, 147, 147, 148, 149, 0, 150, + 150, 148, 0, 148, 0, 151, 151, 152, + 149, 0, 153, 153, 152, 0, 152, 0, + 154, 154, 155, 149, 0, 156, 156, 155, + 0, 155, 0, 149, 0, 157, 0, 0, + 0, 149, 0, 158, 0, 159, 0, 160, + 154, 154, 155, 149, 0, 161, 0, 162, + 0, 163, 151, 151, 152, 149, 0, 164, + 0, 165, 0, 166, 147, 147, 148, 149, + 0, 167, 0, 168, 0, 170, 169, 172, + 173, 174, 175, 176, 177, 75, 73, 171, + 178, 179, 179, 144, 171, 180, 181, 182, + 183, 184, 171, 186, 187, 188, 189, 3, + 1, 185, 190, 185, 185, 35, 185, 185, + 185, 191, 185, 192, 187, 193, 193, 3, + 1, 185, 190, 185, 185, 185, 185, 185, + 185, 191, 185, 187, 193, 193, 3, 1, + 185, 190, 185, 185, 185, 185, 185, 185, + 191, 185, 194, 185, 185, 185, 16, 195, + 185, 1, 185, 190, 185, 185, 185, 185, + 185, 194, 185, 196, 197, 198, 199, 3, + 1, 185, 190, 185, 185, 33, 185, 185, + 185, 191, 185, 200, 197, 201, 201, 3, + 1, 185, 190, 185, 185, 185, 185, 185, + 185, 191, 185, 197, 201, 201, 3, 1, + 185, 190, 185, 185, 185, 185, 185, 185, + 191, 185, 202, 185, 185, 185, 16, 203, + 185, 1, 185, 190, 185, 185, 185, 185, + 185, 202, 185, 204, 205, 206, 207, 3, + 1, 185, 190, 185, 185, 31, 185, 185, + 185, 191, 185, 208, 205, 209, 209, 3, + 1, 185, 190, 185, 185, 185, 185, 185, + 185, 191, 185, 205, 209, 209, 3, 1, + 185, 190, 185, 185, 185, 185, 185, 185, + 191, 185, 210, 185, 185, 185, 16, 211, + 185, 1, 185, 190, 185, 185, 185, 185, + 185, 210, 185, 212, 213, 214, 215, 3, + 1, 185, 190, 185, 185, 29, 185, 185, + 185, 191, 185, 216, 213, 217, 217, 3, + 1, 185, 190, 185, 185, 185, 185, 185, + 185, 191, 185, 213, 217, 217, 3, 1, + 185, 190, 185, 185, 185, 185, 185, 185, + 191, 185, 218, 185, 185, 185, 16, 219, + 185, 1, 185, 190, 185, 185, 185, 185, + 185, 218, 185, 220, 221, 222, 223, 3, + 1, 185, 190, 185, 185, 27, 185, 185, + 185, 191, 185, 224, 221, 225, 225, 3, + 1, 185, 190, 185, 185, 185, 185, 185, + 185, 191, 185, 221, 225, 225, 3, 1, + 185, 190, 185, 185, 185, 185, 185, 185, + 191, 185, 16, 226, 185, 1, 185, 190, + 185, 227, 227, 185, 1, 185, 190, 185, + 228, 185, 185, 229, 185, 190, 185, 190, + 185, 230, 185, 231, 185, 228, 185, 185, + 185, 185, 190, 185, 16, 185, 232, 232, + 3, 1, 185, 190, 185, 233, 25, 234, + 235, 6, 1, 185, 190, 185, 25, 234, + 235, 6, 1, 185, 190, 185, 234, 234, + 6, 1, 185, 190, 185, 236, 22, 237, + 238, 9, 1, 185, 190, 185, 22, 237, + 238, 9, 1, 185, 190, 185, 237, 237, + 9, 1, 185, 190, 185, 239, 19, 240, + 241, 12, 1, 185, 190, 185, 19, 240, + 241, 12, 1, 185, 190, 185, 240, 240, + 12, 1, 185, 190, 185, 242, 16, 227, + 243, 185, 1, 185, 190, 185, 16, 227, + 243, 185, 1, 185, 190, 185, 227, 244, + 185, 1, 185, 190, 185, 16, 185, 227, + 227, 185, 1, 185, 190, 185, 221, 225, + 225, 3, 1, 185, 190, 185, 220, 221, + 225, 225, 3, 1, 185, 190, 185, 185, + 185, 185, 185, 185, 191, 185, 220, 221, + 222, 225, 3, 1, 185, 190, 185, 185, + 27, 185, 185, 185, 191, 185, 218, 185, + 245, 185, 232, 232, 3, 1, 185, 190, + 185, 185, 185, 185, 185, 218, 185, 218, + 185, 185, 185, 227, 227, 185, 1, 185, + 190, 185, 185, 185, 185, 185, 218, 185, + 218, 185, 185, 185, 227, 246, 185, 1, + 185, 190, 185, 185, 185, 185, 185, 218, + 185, 218, 185, 245, 185, 227, 227, 185, + 1, 185, 190, 185, 185, 185, 185, 185, + 218, 185, 212, 213, 217, 217, 3, 1, + 185, 190, 185, 185, 185, 185, 185, 185, + 191, 185, 212, 213, 214, 217, 3, 1, + 185, 190, 185, 185, 29, 185, 185, 185, + 191, 185, 210, 185, 247, 185, 232, 232, + 3, 1, 185, 190, 185, 185, 185, 185, + 185, 210, 185, 210, 185, 185, 185, 227, + 227, 185, 1, 185, 190, 185, 185, 185, + 185, 185, 210, 185, 210, 185, 185, 185, + 227, 248, 185, 1, 185, 190, 185, 185, + 185, 185, 185, 210, 185, 210, 185, 247, + 185, 227, 227, 185, 1, 185, 190, 185, + 185, 185, 185, 185, 210, 185, 204, 205, + 209, 209, 3, 1, 185, 190, 185, 185, + 185, 185, 185, 185, 191, 185, 204, 205, + 206, 209, 3, 1, 185, 190, 185, 185, + 31, 185, 185, 185, 191, 185, 202, 185, + 249, 185, 232, 232, 3, 1, 185, 190, + 185, 185, 185, 185, 185, 202, 185, 202, + 185, 185, 185, 227, 227, 185, 1, 185, + 190, 185, 185, 185, 185, 185, 202, 185, + 202, 185, 185, 185, 227, 250, 185, 1, + 185, 190, 185, 185, 185, 185, 185, 202, + 185, 202, 185, 249, 185, 227, 227, 185, + 1, 185, 190, 185, 185, 185, 185, 185, + 202, 185, 196, 197, 201, 201, 3, 1, + 185, 190, 185, 185, 185, 185, 185, 185, + 191, 185, 196, 197, 198, 201, 3, 1, + 185, 190, 185, 185, 33, 185, 185, 185, + 191, 185, 194, 185, 251, 185, 232, 232, + 3, 1, 185, 190, 185, 185, 185, 185, + 185, 194, 185, 194, 185, 185, 185, 227, + 227, 185, 1, 185, 190, 185, 185, 185, + 185, 185, 194, 185, 194, 185, 185, 185, + 227, 252, 185, 1, 185, 190, 185, 185, + 185, 185, 185, 194, 185, 194, 185, 251, + 185, 227, 227, 185, 1, 185, 190, 185, + 185, 185, 185, 185, 194, 185, 186, 187, + 193, 193, 3, 1, 185, 190, 185, 185, + 185, 185, 185, 185, 191, 185, 186, 187, + 188, 193, 3, 1, 185, 190, 185, 185, + 35, 185, 185, 185, 191, 185, 254, 255, + 256, 257, 39, 37, 253, 258, 253, 253, + 71, 253, 253, 253, 259, 253, 260, 255, + 261, 257, 39, 37, 253, 258, 253, 253, + 253, 253, 253, 253, 259, 253, 255, 261, + 257, 39, 37, 253, 258, 253, 253, 253, + 253, 253, 253, 259, 253, 262, 253, 253, + 253, 52, 263, 253, 37, 253, 258, 253, + 253, 253, 253, 253, 262, 253, 264, 265, + 266, 267, 39, 37, 253, 258, 253, 253, + 69, 253, 253, 253, 259, 253, 268, 265, + 269, 269, 39, 37, 253, 258, 253, 253, + 253, 253, 253, 253, 259, 253, 265, 269, + 269, 39, 37, 253, 258, 253, 253, 253, + 253, 253, 253, 259, 253, 270, 253, 253, + 253, 52, 271, 253, 37, 253, 258, 253, + 253, 253, 253, 253, 270, 253, 272, 273, + 274, 275, 39, 37, 253, 258, 253, 253, + 67, 253, 253, 253, 259, 253, 276, 273, + 277, 277, 39, 37, 253, 258, 253, 253, + 253, 253, 253, 253, 259, 253, 273, 277, + 277, 39, 37, 253, 258, 253, 253, 253, + 253, 253, 253, 259, 253, 278, 253, 253, + 253, 52, 279, 253, 37, 253, 258, 253, + 253, 253, 253, 253, 278, 253, 280, 281, + 282, 283, 39, 37, 253, 258, 253, 253, + 65, 253, 253, 253, 259, 253, 284, 281, + 285, 285, 39, 37, 253, 258, 253, 253, + 253, 253, 253, 253, 259, 253, 281, 285, + 285, 39, 37, 253, 258, 253, 253, 253, + 253, 253, 253, 259, 253, 286, 253, 253, + 253, 52, 287, 253, 37, 253, 258, 253, + 253, 253, 253, 253, 286, 253, 288, 289, + 290, 291, 39, 37, 253, 258, 253, 253, + 63, 253, 253, 253, 259, 253, 292, 289, + 293, 293, 39, 37, 253, 258, 253, 253, + 253, 253, 253, 253, 259, 253, 289, 293, + 293, 39, 37, 253, 258, 253, 253, 253, + 253, 253, 253, 259, 253, 52, 294, 253, + 37, 253, 258, 253, 295, 295, 253, 37, + 253, 258, 253, 296, 253, 253, 297, 253, + 258, 253, 258, 253, 298, 253, 299, 253, + 296, 253, 253, 253, 253, 258, 253, 52, + 253, 300, 300, 39, 37, 253, 258, 253, + 301, 61, 302, 303, 42, 37, 253, 258, + 253, 61, 302, 303, 42, 37, 253, 258, + 253, 302, 302, 42, 37, 253, 258, 253, + 304, 58, 305, 306, 45, 37, 253, 258, + 253, 58, 305, 306, 45, 37, 253, 258, + 253, 305, 305, 45, 37, 253, 258, 253, + 307, 55, 308, 309, 48, 37, 253, 258, + 253, 55, 308, 309, 48, 37, 253, 258, + 253, 308, 308, 48, 37, 253, 258, 253, + 310, 52, 295, 311, 253, 37, 253, 258, + 253, 52, 295, 311, 253, 37, 253, 258, + 253, 295, 312, 253, 37, 253, 258, 253, + 52, 253, 295, 295, 253, 37, 253, 258, + 253, 289, 293, 293, 39, 37, 253, 258, + 253, 288, 289, 293, 293, 39, 37, 253, + 258, 253, 253, 253, 253, 253, 253, 259, + 253, 288, 289, 290, 293, 39, 37, 253, + 258, 253, 253, 63, 253, 253, 253, 259, + 253, 286, 253, 313, 253, 300, 300, 39, + 37, 253, 258, 253, 253, 253, 253, 253, + 286, 253, 286, 253, 253, 253, 295, 295, + 253, 37, 253, 258, 253, 253, 253, 253, + 253, 286, 253, 286, 253, 253, 253, 295, + 314, 253, 37, 253, 258, 253, 253, 253, + 253, 253, 286, 253, 286, 253, 313, 253, + 295, 295, 253, 37, 253, 258, 253, 253, + 253, 253, 253, 286, 253, 280, 281, 285, + 285, 39, 37, 253, 258, 253, 253, 253, + 253, 253, 253, 259, 253, 280, 281, 282, + 285, 39, 37, 253, 258, 253, 253, 65, + 253, 253, 253, 259, 253, 278, 253, 315, + 253, 300, 300, 39, 37, 253, 258, 253, + 253, 253, 253, 253, 278, 253, 278, 253, + 253, 253, 295, 295, 253, 37, 253, 258, + 253, 253, 253, 253, 253, 278, 253, 278, + 253, 253, 253, 295, 316, 253, 37, 253, + 258, 253, 253, 253, 253, 253, 278, 253, + 278, 253, 315, 253, 295, 295, 253, 37, + 253, 258, 253, 253, 253, 253, 253, 278, + 253, 272, 273, 277, 277, 39, 37, 253, + 258, 253, 253, 253, 253, 253, 253, 259, + 253, 272, 273, 274, 277, 39, 37, 253, + 258, 253, 253, 67, 253, 253, 253, 259, + 253, 270, 253, 317, 253, 300, 300, 39, + 37, 253, 258, 253, 253, 253, 253, 253, + 270, 253, 270, 253, 253, 253, 295, 295, + 253, 37, 253, 258, 253, 253, 253, 253, + 253, 270, 253, 270, 253, 253, 253, 295, + 318, 253, 37, 253, 258, 253, 253, 253, + 253, 253, 270, 253, 270, 253, 317, 253, + 295, 295, 253, 37, 253, 258, 253, 253, + 253, 253, 253, 270, 253, 264, 265, 269, + 269, 39, 37, 253, 258, 253, 253, 253, + 253, 253, 253, 259, 253, 264, 265, 266, + 269, 39, 37, 253, 258, 253, 253, 69, + 253, 253, 253, 259, 253, 262, 253, 319, + 253, 300, 300, 39, 37, 253, 258, 253, + 253, 253, 253, 253, 262, 253, 262, 253, + 253, 253, 295, 295, 253, 37, 253, 258, + 253, 253, 253, 253, 253, 262, 253, 262, + 253, 253, 253, 295, 320, 253, 37, 253, + 258, 253, 253, 253, 253, 253, 262, 253, + 262, 253, 319, 253, 295, 295, 253, 37, + 253, 258, 253, 253, 253, 253, 253, 262, + 253, 70, 38, 38, 39, 37, 253, 254, + 255, 261, 257, 39, 37, 253, 258, 253, + 253, 253, 253, 253, 253, 259, 253, 322, + 175, 323, 323, 75, 73, 321, 178, 321, + 321, 321, 321, 321, 321, 182, 321, 175, + 323, 323, 75, 73, 321, 178, 321, 321, + 321, 321, 321, 321, 182, 321, 324, 321, + 321, 321, 89, 325, 321, 73, 321, 178, + 321, 321, 321, 321, 321, 324, 321, 326, + 327, 328, 329, 75, 73, 321, 178, 321, + 321, 106, 321, 321, 321, 182, 321, 330, + 327, 331, 331, 75, 73, 321, 178, 321, + 321, 321, 321, 321, 321, 182, 321, 327, + 331, 331, 75, 73, 321, 178, 321, 321, + 321, 321, 321, 321, 182, 321, 332, 321, + 321, 321, 89, 333, 321, 73, 321, 178, + 321, 321, 321, 321, 321, 332, 321, 334, + 335, 336, 337, 75, 73, 321, 178, 321, + 321, 104, 321, 321, 321, 182, 321, 338, + 335, 339, 339, 75, 73, 321, 178, 321, + 321, 321, 321, 321, 321, 182, 321, 335, + 339, 339, 75, 73, 321, 178, 321, 321, + 321, 321, 321, 321, 182, 321, 340, 321, + 321, 321, 89, 341, 321, 73, 321, 178, + 321, 321, 321, 321, 321, 340, 321, 342, + 343, 344, 345, 75, 73, 321, 178, 321, + 321, 102, 321, 321, 321, 182, 321, 346, + 343, 347, 347, 75, 73, 321, 178, 321, + 321, 321, 321, 321, 321, 182, 321, 343, + 347, 347, 75, 73, 321, 178, 321, 321, + 321, 321, 321, 321, 182, 321, 348, 321, + 321, 321, 89, 349, 321, 73, 321, 178, + 321, 321, 321, 321, 321, 348, 321, 350, + 351, 352, 353, 75, 73, 321, 178, 321, + 321, 100, 321, 321, 321, 182, 321, 354, + 351, 355, 355, 75, 73, 321, 178, 321, + 321, 321, 321, 321, 321, 182, 321, 351, + 355, 355, 75, 73, 321, 178, 321, 321, + 321, 321, 321, 321, 182, 321, 89, 356, + 321, 73, 321, 178, 321, 357, 357, 321, + 73, 321, 178, 321, 358, 321, 321, 359, + 321, 178, 321, 178, 321, 360, 321, 361, + 321, 358, 321, 321, 321, 321, 178, 321, + 89, 321, 362, 362, 75, 73, 321, 178, + 321, 363, 98, 364, 365, 79, 73, 321, + 178, 321, 98, 364, 365, 79, 73, 321, + 178, 321, 364, 364, 79, 73, 321, 178, + 321, 366, 95, 367, 368, 82, 73, 321, + 178, 321, 95, 367, 368, 82, 73, 321, + 178, 321, 367, 367, 82, 73, 321, 178, + 321, 369, 92, 370, 371, 85, 73, 321, + 178, 321, 92, 370, 371, 85, 73, 321, + 178, 321, 370, 370, 85, 73, 321, 178, + 321, 372, 89, 357, 373, 321, 73, 321, + 178, 321, 89, 357, 373, 321, 73, 321, + 178, 321, 357, 374, 321, 73, 321, 178, + 321, 89, 321, 357, 357, 321, 73, 321, + 178, 321, 351, 355, 355, 75, 73, 321, + 178, 321, 350, 351, 355, 355, 75, 73, + 321, 178, 321, 321, 321, 321, 321, 321, + 182, 321, 350, 351, 352, 355, 75, 73, + 321, 178, 321, 321, 100, 321, 321, 321, + 182, 321, 348, 321, 375, 321, 362, 362, + 75, 73, 321, 178, 321, 321, 321, 321, + 321, 348, 321, 348, 321, 321, 321, 357, + 357, 321, 73, 321, 178, 321, 321, 321, + 321, 321, 348, 321, 348, 321, 321, 321, + 357, 376, 321, 73, 321, 178, 321, 321, + 321, 321, 321, 348, 321, 348, 321, 375, + 321, 357, 357, 321, 73, 321, 178, 321, + 321, 321, 321, 321, 348, 321, 342, 343, + 347, 347, 75, 73, 321, 178, 321, 321, + 321, 321, 321, 321, 182, 321, 342, 343, + 344, 347, 75, 73, 321, 178, 321, 321, + 102, 321, 321, 321, 182, 321, 340, 321, + 377, 321, 362, 362, 75, 73, 321, 178, + 321, 321, 321, 321, 321, 340, 321, 340, + 321, 321, 321, 357, 357, 321, 73, 321, + 178, 321, 321, 321, 321, 321, 340, 321, + 340, 321, 321, 321, 357, 378, 321, 73, + 321, 178, 321, 321, 321, 321, 321, 340, + 321, 340, 321, 377, 321, 357, 357, 321, + 73, 321, 178, 321, 321, 321, 321, 321, + 340, 321, 334, 335, 339, 339, 75, 73, + 321, 178, 321, 321, 321, 321, 321, 321, + 182, 321, 334, 335, 336, 339, 75, 73, + 321, 178, 321, 321, 104, 321, 321, 321, + 182, 321, 332, 321, 379, 321, 362, 362, + 75, 73, 321, 178, 321, 321, 321, 321, + 321, 332, 321, 332, 321, 321, 321, 357, + 357, 321, 73, 321, 178, 321, 321, 321, + 321, 321, 332, 321, 332, 321, 321, 321, + 357, 380, 321, 73, 321, 178, 321, 321, + 321, 321, 321, 332, 321, 332, 321, 379, + 321, 357, 357, 321, 73, 321, 178, 321, + 321, 321, 321, 321, 332, 321, 326, 327, + 331, 331, 75, 73, 321, 178, 321, 321, + 321, 321, 321, 321, 182, 321, 326, 327, + 328, 331, 75, 73, 321, 178, 321, 321, + 106, 321, 321, 321, 182, 321, 324, 321, + 381, 321, 362, 362, 75, 73, 321, 178, + 321, 321, 321, 321, 321, 324, 321, 324, + 321, 321, 321, 357, 357, 321, 73, 321, + 178, 321, 321, 321, 321, 321, 324, 321, + 324, 321, 321, 321, 357, 382, 321, 73, + 321, 178, 321, 321, 321, 321, 321, 324, + 321, 324, 321, 381, 321, 357, 357, 321, + 73, 321, 178, 321, 321, 321, 321, 321, + 324, 321, 107, 74, 74, 75, 73, 383, + 383, 383, 383, 144, 383, 174, 175, 323, + 323, 75, 73, 321, 178, 321, 321, 321, + 321, 321, 321, 182, 321, 107, 74, 74, + 75, 73, 383, 385, 386, 387, 388, 111, + 109, 384, 389, 384, 384, 143, 384, 384, + 384, 390, 384, 391, 386, 388, 388, 111, + 109, 384, 389, 384, 384, 384, 384, 384, + 384, 390, 384, 386, 388, 388, 111, 109, + 384, 389, 384, 384, 384, 384, 384, 384, + 390, 384, 392, 384, 384, 384, 124, 393, + 384, 109, 384, 389, 384, 384, 384, 384, + 384, 392, 384, 394, 395, 396, 397, 111, + 109, 384, 389, 384, 384, 141, 384, 384, + 384, 390, 384, 398, 395, 399, 399, 111, + 109, 384, 389, 384, 384, 384, 384, 384, + 384, 390, 384, 395, 399, 399, 111, 109, + 384, 389, 384, 384, 384, 384, 384, 384, + 390, 384, 400, 384, 384, 384, 124, 401, + 384, 109, 384, 389, 384, 384, 384, 384, + 384, 400, 384, 402, 403, 404, 405, 111, + 109, 384, 389, 384, 384, 139, 384, 384, + 384, 390, 384, 406, 403, 407, 407, 111, + 109, 384, 389, 384, 384, 384, 384, 384, + 384, 390, 384, 403, 407, 407, 111, 109, + 384, 389, 384, 384, 384, 384, 384, 384, + 390, 384, 408, 384, 384, 384, 124, 409, + 384, 109, 384, 389, 384, 384, 384, 384, + 384, 408, 384, 410, 411, 412, 413, 111, + 109, 384, 389, 384, 384, 137, 384, 384, + 384, 390, 384, 414, 411, 415, 415, 111, + 109, 384, 389, 384, 384, 384, 384, 384, + 384, 390, 384, 411, 415, 415, 111, 109, + 384, 389, 384, 384, 384, 384, 384, 384, + 390, 384, 416, 384, 384, 384, 124, 417, + 384, 109, 384, 389, 384, 384, 384, 384, + 384, 416, 384, 418, 419, 420, 421, 111, + 109, 384, 389, 384, 384, 135, 384, 384, + 384, 390, 384, 422, 419, 423, 423, 111, + 109, 384, 389, 384, 384, 384, 384, 384, + 384, 390, 384, 419, 423, 423, 111, 109, + 384, 389, 384, 384, 384, 384, 384, 384, + 390, 384, 124, 424, 384, 109, 384, 389, + 384, 425, 425, 384, 109, 384, 389, 384, + 426, 384, 384, 427, 384, 389, 384, 389, + 384, 428, 384, 429, 384, 426, 384, 384, + 384, 384, 389, 384, 124, 384, 430, 430, + 111, 109, 384, 389, 384, 431, 133, 432, + 433, 114, 109, 384, 389, 384, 133, 432, + 433, 114, 109, 384, 389, 384, 432, 432, + 114, 109, 384, 389, 384, 434, 130, 435, + 436, 117, 109, 384, 389, 384, 130, 435, + 436, 117, 109, 384, 389, 384, 435, 435, + 117, 109, 384, 389, 384, 437, 127, 438, + 439, 120, 109, 384, 389, 384, 127, 438, + 439, 120, 109, 384, 389, 384, 438, 438, + 120, 109, 384, 389, 384, 440, 124, 425, + 441, 384, 109, 384, 389, 384, 124, 425, + 441, 384, 109, 384, 389, 384, 425, 442, + 384, 109, 384, 389, 384, 124, 384, 425, + 425, 384, 109, 384, 389, 384, 419, 423, + 423, 111, 109, 384, 389, 384, 418, 419, + 423, 423, 111, 109, 384, 389, 384, 384, + 384, 384, 384, 384, 390, 384, 418, 419, + 420, 423, 111, 109, 384, 389, 384, 384, + 135, 384, 384, 384, 390, 384, 416, 384, + 443, 384, 430, 430, 111, 109, 384, 389, + 384, 384, 384, 384, 384, 416, 384, 416, + 384, 384, 384, 425, 425, 384, 109, 384, + 389, 384, 384, 384, 384, 384, 416, 384, + 416, 384, 384, 384, 425, 444, 384, 109, + 384, 389, 384, 384, 384, 384, 384, 416, + 384, 416, 384, 443, 384, 425, 425, 384, + 109, 384, 389, 384, 384, 384, 384, 384, + 416, 384, 410, 411, 415, 415, 111, 109, + 384, 389, 384, 384, 384, 384, 384, 384, + 390, 384, 410, 411, 412, 415, 111, 109, + 384, 389, 384, 384, 137, 384, 384, 384, + 390, 384, 408, 384, 445, 384, 430, 430, + 111, 109, 384, 389, 384, 384, 384, 384, + 384, 408, 384, 408, 384, 384, 384, 425, + 425, 384, 109, 384, 389, 384, 384, 384, + 384, 384, 408, 384, 408, 384, 384, 384, + 425, 446, 384, 109, 384, 389, 384, 384, + 384, 384, 384, 408, 384, 408, 384, 445, + 384, 425, 425, 384, 109, 384, 389, 384, + 384, 384, 384, 384, 408, 384, 402, 403, + 407, 407, 111, 109, 384, 389, 384, 384, + 384, 384, 384, 384, 390, 384, 402, 403, + 404, 407, 111, 109, 384, 389, 384, 384, + 139, 384, 384, 384, 390, 384, 400, 384, + 447, 384, 430, 430, 111, 109, 384, 389, + 384, 384, 384, 384, 384, 400, 384, 400, + 384, 384, 384, 425, 425, 384, 109, 384, + 389, 384, 384, 384, 384, 384, 400, 384, + 400, 384, 384, 384, 425, 448, 384, 109, + 384, 389, 384, 384, 384, 384, 384, 400, + 384, 400, 384, 447, 384, 425, 425, 384, + 109, 384, 389, 384, 384, 384, 384, 384, + 400, 384, 394, 395, 399, 399, 111, 109, + 384, 389, 384, 384, 384, 384, 384, 384, + 390, 384, 394, 395, 396, 399, 111, 109, + 384, 389, 384, 384, 141, 384, 384, 384, + 390, 384, 392, 384, 449, 384, 430, 430, + 111, 109, 384, 389, 384, 384, 384, 384, + 384, 392, 384, 392, 384, 384, 384, 425, + 425, 384, 109, 384, 389, 384, 384, 384, + 384, 384, 392, 384, 392, 384, 384, 384, + 425, 450, 384, 109, 384, 389, 384, 384, + 384, 384, 384, 392, 384, 392, 384, 449, + 384, 425, 425, 384, 109, 384, 389, 384, + 384, 384, 384, 384, 392, 384, 385, 386, + 388, 388, 111, 109, 384, 389, 384, 384, + 384, 384, 384, 384, 390, 384, 172, 173, + 174, 175, 451, 323, 75, 73, 321, 178, + 179, 179, 144, 321, 321, 172, 182, 321, + 186, 452, 188, 189, 3, 1, 185, 190, + 185, 185, 35, 185, 185, 185, 191, 185, + 194, 173, 174, 175, 453, 454, 75, 149, + 185, 455, 185, 179, 144, 185, 185, 194, + 182, 185, 107, 456, 456, 75, 149, 185, + 190, 185, 185, 144, 185, 457, 185, 185, + 458, 185, 455, 185, 455, 185, 459, 185, + 231, 185, 457, 185, 185, 185, 185, 455, + 185, 194, 185, 251, 107, 460, 460, 146, + 149, 185, 190, 185, 185, 185, 185, 185, + 194, 185, 461, 168, 462, 463, 148, 149, + 185, 455, 185, 168, 462, 463, 148, 149, + 185, 455, 185, 462, 462, 148, 149, 185, + 455, 185, 464, 165, 465, 466, 152, 149, + 185, 455, 185, 165, 465, 466, 152, 149, + 185, 455, 185, 465, 465, 152, 149, 185, + 455, 185, 467, 162, 468, 469, 155, 149, + 185, 455, 185, 162, 468, 469, 155, 149, + 185, 455, 185, 468, 468, 155, 149, 185, + 455, 185, 470, 159, 471, 472, 185, 149, + 185, 455, 185, 159, 471, 472, 185, 149, + 185, 455, 185, 471, 471, 185, 149, 185, + 455, 185, 474, 473, 475, 475, 473, 170, + 473, 476, 473, 475, 475, 473, 170, 473, + 476, 473, 477, 473, 473, 478, 473, 476, + 473, 476, 473, 479, 473, 480, 473, 477, + 473, 473, 473, 473, 476, 473, 172, 383, + 383, 383, 383, 383, 383, 383, 383, 383, + 179, 383, 383, 383, 383, 172, 383, 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, 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, 539, 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 + 166, 188, 2, 194, 3, 5, 197, 6, + 8, 200, 9, 11, 203, 12, 14, 15, + 187, 17, 18, 202, 20, 21, 199, 23, + 24, 196, 205, 208, 212, 214, 218, 220, + 224, 226, 230, 232, 166, 255, 37, 261, + 38, 40, 264, 41, 43, 267, 44, 46, + 270, 47, 49, 50, 254, 52, 53, 269, + 55, 56, 266, 58, 59, 263, 272, 275, + 279, 281, 285, 287, 291, 293, 297, 300, + 166, 321, 72, 327, 166, 73, 75, 330, + 76, 78, 333, 79, 81, 336, 82, 84, + 85, 320, 87, 88, 335, 90, 91, 332, + 93, 94, 329, 338, 341, 345, 347, 351, + 353, 357, 359, 363, 166, 389, 106, 395, + 107, 109, 398, 110, 112, 401, 113, 115, + 404, 116, 118, 119, 388, 121, 122, 403, + 124, 125, 400, 127, 128, 397, 406, 409, + 413, 415, 419, 421, 425, 427, 431, 433, + 366, 142, 444, 144, 447, 438, 145, 147, + 450, 148, 150, 453, 151, 154, 155, 455, + 157, 158, 452, 160, 161, 449, 163, 164, + 446, 166, 458, 166, 167, 234, 301, 303, + 365, 367, 323, 368, 434, 435, 340, 456, + 463, 166, 168, 170, 34, 233, 190, 207, + 169, 33, 171, 228, 172, 174, 32, 227, + 173, 31, 175, 222, 176, 178, 30, 221, + 177, 29, 179, 216, 180, 182, 28, 215, + 181, 27, 183, 210, 184, 186, 26, 209, + 185, 25, 193, 0, 189, 192, 191, 166, + 1, 195, 4, 22, 198, 7, 19, 201, + 10, 16, 204, 13, 206, 211, 213, 217, + 219, 223, 225, 229, 231, 166, 235, 237, + 69, 299, 257, 274, 236, 68, 238, 295, + 239, 241, 67, 294, 240, 66, 242, 289, + 243, 245, 65, 288, 244, 64, 246, 283, + 247, 249, 63, 282, 248, 62, 250, 277, + 251, 253, 61, 276, 252, 60, 260, 35, + 256, 259, 258, 166, 36, 262, 39, 57, + 265, 42, 54, 268, 45, 51, 271, 48, + 273, 278, 280, 284, 286, 290, 292, 296, + 298, 166, 302, 103, 304, 361, 305, 307, + 102, 360, 306, 101, 308, 355, 309, 311, + 100, 354, 310, 99, 312, 349, 313, 315, + 98, 348, 314, 97, 316, 343, 317, 319, + 96, 342, 318, 95, 326, 70, 322, 325, + 324, 166, 71, 328, 74, 92, 331, 77, + 89, 334, 80, 86, 337, 83, 339, 344, + 346, 350, 352, 356, 358, 362, 364, 166, + 166, 369, 371, 138, 137, 391, 408, 370, + 372, 429, 373, 375, 136, 428, 374, 135, + 376, 423, 377, 379, 134, 422, 378, 133, + 380, 417, 381, 383, 132, 416, 382, 131, + 384, 411, 385, 387, 130, 410, 386, 129, + 394, 104, 390, 393, 392, 166, 105, 396, + 108, 126, 399, 111, 123, 402, 114, 120, + 405, 117, 407, 412, 414, 418, 420, 424, + 426, 430, 432, 139, 436, 437, 443, 440, + 140, 439, 442, 441, 141, 445, 143, 162, + 448, 146, 159, 451, 149, 156, 454, 152, + 153, 166, 457, 165, 460, 459, 462, 461, + 166 }; static const char _indic_syllable_machine_trans_actions[] = { - 1, 0, 2, 2, 2, 0, 2, 0, - 0, 2, 0, 0, 2, 0, 0, 2, - 0, 0, 0, 2, 0, 0, 2, 0, - 0, 2, 0, 0, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 3, - 0, 2, 2, 2, 0, 2, 0, 0, - 2, 0, 0, 2, 0, 0, 2, 0, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 0, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 4, 0, - 2, 2, 2, 0, 2, 5, 0, 0, - 2, 0, 0, 2, 0, 0, 2, 0, - 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 0, 2, 2, 6, 2, 6, - 2, 6, 2, 6, 2, 7, 0, 2, - 2, 2, 0, 2, 0, 0, 2, 0, + 1, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 6, 0, 8, 0, - 2, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 2, 2, 2, 0, 0, 2, + 2, 2, 2, 2, 3, 0, 0, 2, + 0, 0, 2, 0, 0, 2, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 2, + 0, 0, 2, 0, 0, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 4, 0, 0, 2, 5, 0, 0, 2, + 0, 0, 2, 0, 0, 2, 0, 0, + 0, 2, 0, 0, 2, 0, 0, 2, + 0, 0, 2, 2, 6, 2, 6, 2, + 6, 2, 6, 2, 7, 0, 0, 2, + 0, 0, 2, 0, 0, 2, 0, 0, + 2, 0, 0, 0, 2, 0, 0, 2, + 0, 0, 2, 0, 0, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 6, 0, 2, 0, 2, 0, 0, 0, + 2, 0, 0, 2, 0, 0, 0, 2, 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, 0, 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, 0, 0, 0, 15, - 0, 0, 2, 0, 2, 0, 2, 0, + 2, 8, 0, 11, 2, 2, 6, 0, + 12, 12, 0, 2, 6, 2, 6, 2, + 0, 13, 2, 0, 0, 2, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 2, 2, 0, 0, 2, + 2, 0, 2, 0, 0, 0, 0, 14, 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, + 0, 0, 2, 0, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 15, 2, 0, + 0, 2, 0, 2, 2, 0, 2, 2, + 2, 0, 0, 2, 2, 0, 2, 2, + 2, 0, 0, 2, 2, 0, 2, 2, + 2, 0, 0, 2, 2, 0, 2, 2, + 2, 0, 0, 2, 2, 0, 2, 0, + 0, 0, 0, 16, 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, + 2, 17, 6, 0, 6, 6, 6, 0, + 0, 6, 6, 0, 6, 6, 6, 0, + 0, 6, 6, 0, 6, 6, 6, 0, + 0, 6, 6, 0, 6, 6, 6, 0, + 0, 6, 6, 0, 6, 0, 0, 0, + 0, 18, 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, + 2, 2, 2, 2, 2, 2, 2, 19, + 20, 2, 0, 0, 0, 0, 2, 2, + 2, 2, 2, 0, 0, 2, 2, 0, + 2, 2, 2, 0, 0, 2, 2, 0, + 2, 2, 2, 0, 0, 2, 2, 0, + 2, 2, 2, 0, 0, 2, 2, 0, + 2, 0, 0, 0, 0, 21, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, - 2, 0, 2, 23, 2, 0, 0, 0, - 0, 0, 24, 0, 0 + 2, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 0, 0, 22, 2, 0, + 0, 0, 0, 0, 0, 2, 0, 0, + 2, 0, 0, 2, 0, 0, 2, 0, + 0, 23, 2, 0, 0, 0, 0, 0, + 24 }; static const char _indic_syllable_machine_to_state_actions[] = { @@ -1157,9 +940,7 @@ 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, 0, 0, 0, 0, 0, 0, - 0, 0, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 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, @@ -1196,15 +977,7 @@ 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, 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, 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[] = { @@ -1228,17 +1001,7 @@ 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, 0, 0, 0, 0, 0, 0, - 0, 0, 11, 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, 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, 0, + 0, 0, 0, 0, 0, 0, 10, 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, @@ -1275,7 +1038,7 @@ 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, 0, 0 }; static const short _indic_syllable_machine_eof_trans[] = { @@ -1283,84 +1046,74 @@ 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, 1, 1, 1, 1, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 40, 40, 40, 40, 40, 40, - 40, 40, 79, 79, 79, 79, 86, 86, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 79, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 73, 73, + 77, 77, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 109, 109, 109, 109, 109, + 109, 109, 109, 73, 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, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 283, 283, - 283, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 433, 362, 433, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 434, 434, - 434, 434, 434, 434, 434, 434, 362, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 362, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 204, 204, 204, 204, 204, 204, 204, - 204, 362, 548, 548, 548, 548, 548, 548, - 548, 548, 548, 433 + 1, 1, 1, 1, 1, 170, 0, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 384, 322, 384, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 322, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, + 474, 474, 474, 474, 474, 474, 474, 384 }; -static const int indic_syllable_machine_start = 178; -static const int indic_syllable_machine_first_final = 178; +static const int indic_syllable_machine_start = 166; +static const int indic_syllable_machine_first_final = 166; static const int indic_syllable_machine_error = -1; -static const int indic_syllable_machine_en_main = 178; +static const int indic_syllable_machine_en_main = 166; #line 36 "hb-ot-shape-complex-indic-machine.rl" -#line 97 "hb-ot-shape-complex-indic-machine.rl" +#line 92 "hb-ot-shape-complex-indic-machine.rl" #define found_syllable(syllable_type) \ @@ -1380,7 +1133,7 @@ int cs; hb_glyph_info_t *info = buffer->info; -#line 1384 "hb-ot-shape-complex-indic-machine.hh" +#line 1137 "hb-ot-shape-complex-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -1388,7 +1141,7 @@ act = 0; } -#line 118 "hb-ot-shape-complex-indic-machine.rl" +#line 113 "hb-ot-shape-complex-indic-machine.rl" p = 0; @@ -1397,7 +1150,7 @@ unsigned int last = 0; unsigned int syllable_serial = 1; -#line 1401 "hb-ot-shape-complex-indic-machine.hh" +#line 1154 "hb-ot-shape-complex-indic-machine.hh" { int _slen; int _trans; @@ -1407,11 +1160,11 @@ goto _test_eof; _resume: switch ( _indic_syllable_machine_from_state_actions[cs] ) { - case 11: + case 10: #line 1 "NONE" {ts = p;} break; -#line 1415 "hb-ot-shape-complex-indic-machine.hh" +#line 1168 "hb-ot-shape-complex-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -1433,72 +1186,72 @@ #line 1 "NONE" {te = p+1;} break; - case 15: -#line 88 "hb-ot-shape-complex-indic-machine.rl" + case 14: +#line 83 "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" + case 16: +#line 84 "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" + case 21: +#line 85 "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 86 "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" + case 18: +#line 87 "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" + case 11: +#line 88 "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" + case 13: +#line 83 "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" + case 15: +#line 84 "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" + case 20: +#line 85 "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 86 "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" + case 17: +#line 87 "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" + case 19: +#line 88 "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 83 "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 84 "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 85 "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" + case 8: +#line 86 "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 87 "hb-ot-shape-complex-indic-machine.rl" {{p = ((te))-1;}{ found_syllable (broken_cluster); }} break; case 5: @@ -1516,34 +1269,34 @@ } } break; - case 8: + case 22: #line 1 "NONE" {te = p+1;} -#line 88 "hb-ot-shape-complex-indic-machine.rl" +#line 83 "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 87 "hb-ot-shape-complex-indic-machine.rl" {act = 5;} break; - case 13: + case 12: #line 1 "NONE" {te = p+1;} -#line 93 "hb-ot-shape-complex-indic-machine.rl" +#line 88 "hb-ot-shape-complex-indic-machine.rl" {act = 6;} break; -#line 1538 "hb-ot-shape-complex-indic-machine.hh" +#line 1291 "hb-ot-shape-complex-indic-machine.hh" } _again: switch ( _indic_syllable_machine_to_state_actions[cs] ) { - case 10: + case 9: #line 1 "NONE" {ts = 0;} break; -#line 1547 "hb-ot-shape-complex-indic-machine.hh" +#line 1300 "hb-ot-shape-complex-indic-machine.hh" } if ( ++p != pe ) @@ -1559,7 +1312,7 @@ } -#line 127 "hb-ot-shape-complex-indic-machine.rl" +#line 122 "hb-ot-shape-complex-indic-machine.rl" }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-private.hh Wed May 30 12:20:00 2018 -0700 @@ -34,6 +34,11 @@ #include "hb-ot-shape-private.hh" /* XXX Remove */ +/* buffer var allocations */ +#define indic_category() complex_var_u8_0() /* indic_category_t */ +#define indic_position() complex_var_u8_1() /* indic_position_t */ + + #define INDIC_TABLE_ELEMENT_TYPE uint16_t /* Cateories used in the OpenType spec: @@ -51,7 +56,7 @@ OT_ZWJ = 6, OT_M = 7, OT_SM = 8, - OT_VD = 9, + /* OT_VD = 9, UNUSED; we use OT_A instead. */ OT_A = 10, OT_PLACEHOLDER = 11, OT_DOTTEDCIRCLE = 12, @@ -73,34 +78,33 @@ * consonant syllable logic from the vowel syllable function and get it all right! */ #define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE)) #define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ)) -#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng)) /* Visual positions in a syllable from left to right. */ enum indic_position_t { - POS_START, + POS_START = 0, - POS_RA_TO_BECOME_REPH, - POS_PRE_M, - POS_PRE_C, + POS_RA_TO_BECOME_REPH = 1, + POS_PRE_M = 2, + POS_PRE_C = 3, - POS_BASE_C, - POS_AFTER_MAIN, + POS_BASE_C = 4, + POS_AFTER_MAIN = 5, - POS_ABOVE_C, + POS_ABOVE_C = 6, - POS_BEFORE_SUB, - POS_BELOW_C, - POS_AFTER_SUB, + POS_BEFORE_SUB = 7, + POS_BELOW_C = 8, + POS_AFTER_SUB = 9, - POS_BEFORE_POST, - POS_POST_C, - POS_AFTER_POST, + POS_BEFORE_POST = 10, + POS_POST_C = 11, + POS_AFTER_POST = 12, - POS_FINAL_C, - POS_SMVD, + POS_FINAL_C = 13, + POS_SMVD = 14, - POS_END + POS_END = 15 }; /* Categories used in IndicSyllabicCategory.txt from UCD. */ @@ -123,7 +127,7 @@ INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_CM, INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA = OT_N, INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER = OT_CS, - INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, /* https://github.com/behdad/harfbuzz/issues/552 */ + INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK = OT_SM, /* https://github.com/harfbuzz/harfbuzz/issues/552 */ INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER = OT_Coeng, INDIC_SYLLABIC_CATEGORY_JOINER = OT_ZWJ, INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X, @@ -187,4 +191,211 @@ HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE hb_indic_get_categories (hb_codepoint_t u); + +static inline bool +is_one_of (const hb_glyph_info_t &info, unsigned int flags) +{ + /* If it ligated, all bets are off. */ + if (_hb_glyph_info_ligated (&info)) return false; + return !!(FLAG_UNSAFE (info.indic_category()) & flags); +} + +static inline bool +is_joiner (const hb_glyph_info_t &info) +{ + return is_one_of (info, JOINER_FLAGS); +} + +static inline bool +is_consonant (const hb_glyph_info_t &info) +{ + return is_one_of (info, CONSONANT_FLAGS); +} + +static inline bool +is_halant (const hb_glyph_info_t &info) +{ + return is_one_of (info, FLAG (OT_H)); +} + +#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base)) + +#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u)) +#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u)) +#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u)) +#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u)) +#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u)) +#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u)) +#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u)) +#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u)) +#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u)) +#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u)) + + +#define MATRA_POS_LEFT(u) POS_PRE_M +#define MATRA_POS_RIGHT(u) ( \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_BENG(u) ? POS_AFTER_POST : \ + IS_GURU(u) ? POS_AFTER_POST : \ + IS_GUJR(u) ? POS_AFTER_POST : \ + IS_ORYA(u) ? POS_AFTER_POST : \ + IS_TAML(u) ? POS_AFTER_POST : \ + IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ + IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ + IS_MLYM(u) ? POS_AFTER_POST : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + /*default*/ POS_AFTER_SUB \ + ) +#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \ + IS_GUJR(u) ? POS_AFTER_SUB : \ + IS_ORYA(u) ? POS_AFTER_MAIN : \ + IS_TAML(u) ? POS_AFTER_SUB : \ + IS_TELU(u) ? POS_BEFORE_SUB : \ + IS_KNDA(u) ? POS_BEFORE_SUB : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + /*default*/ POS_AFTER_SUB \ + ) +#define MATRA_POS_BOTTOM(u) ( \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_BENG(u) ? POS_AFTER_SUB : \ + IS_GURU(u) ? POS_AFTER_POST : \ + IS_GUJR(u) ? POS_AFTER_POST : \ + IS_ORYA(u) ? POS_AFTER_SUB : \ + IS_TAML(u) ? POS_AFTER_POST : \ + IS_TELU(u) ? POS_BEFORE_SUB : \ + IS_KNDA(u) ? POS_BEFORE_SUB : \ + IS_MLYM(u) ? POS_AFTER_POST : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + /*default*/ POS_AFTER_SUB \ + ) + +static inline indic_position_t +matra_position_indic (hb_codepoint_t u, indic_position_t side) +{ + switch ((int) side) + { + case POS_PRE_C: return MATRA_POS_LEFT (u); + case POS_POST_C: return MATRA_POS_RIGHT (u); + case POS_ABOVE_C: return MATRA_POS_TOP (u); + case POS_BELOW_C: return MATRA_POS_BOTTOM (u); + }; + return side; +} + +/* XXX + * This is a hack for now. We should move this data into the main Indic table. + * Or completely remove it and just check in the tables. + */ +static const hb_codepoint_t ra_chars[] = { + 0x0930u, /* Devanagari */ + 0x09B0u, /* Bengali */ + 0x09F0u, /* Bengali */ + 0x0A30u, /* Gurmukhi */ /* No Reph */ + 0x0AB0u, /* Gujarati */ + 0x0B30u, /* Oriya */ + 0x0BB0u, /* Tamil */ /* No Reph */ + 0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */ + 0x0CB0u, /* Kannada */ + 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ + + 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ +}; + +static inline bool +is_ra (hb_codepoint_t u) +{ + for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++) + if (u == ra_chars[i]) + return true; + return false; +} + +static inline void +set_indic_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_position_t pos = (indic_position_t) (type >> 8); + + + /* + * Re-assign category + */ + + /* The following act more like the Bindus. */ + if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0953u, 0x0954u))) + cat = OT_SM; + /* The following act like consonants. */ + else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x0A72u, 0x0A73u, + 0x1CF5u, 0x1CF6u))) + cat = OT_C; + /* TODO: The following should only be allowed after a Visarga. + * For now, just treat them like regular tone marks. */ + else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1CE2u, 0x1CE8u))) + cat = OT_A; + /* TODO: The following should only be allowed after some of + * the nasalization marks, maybe only for U+1CE9..U+1CF1. + * For now, just treat them like tone marks. */ + else if (unlikely (u == 0x1CEDu)) + cat = OT_A; + /* The following take marks in standalone clusters, similar to Avagraha. */ + else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0xA8F2u, 0xA8F7u, + 0x1CE9u, 0x1CECu, + 0x1CEEu, 0x1CF1u))) + { + cat = OT_Symbol; + static_assert (((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol), ""); + } + else if (unlikely (u == 0x0A51u)) + { + /* https://github.com/harfbuzz/harfbuzz/issues/524 */ + cat = OT_M; + pos = POS_BELOW_C; + } + + /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil, + * so the Indic shaper needs to know their categories. */ + else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM; + else if (unlikely (u == 0x1133cu)) cat = OT_N; + + else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */ + + else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */ + else if (unlikely (u == 0x0C80u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/623 */ + else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u))) + cat = OT_PLACEHOLDER; + else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; + + + /* + * Re-assign position. + */ + + if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) + { + pos = POS_BASE_C; + if (is_ra (u)) + cat = OT_Ra; + } + else if (cat == OT_M) + { + pos = matra_position_indic (u, pos); + } + else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) /* | FLAG (OT_VD) */ | FLAG (OT_A) | FLAG (OT_Symbol)))) + { + pos = POS_SMVD; + } + + if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */ + + + + info.indic_category() = cat; + info.indic_position() = pos; +} + + #endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-table.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic-table.cc Wed May 30 12:20:00 2018 -0700 @@ -399,10 +399,10 @@ switch (u >> 12) { case 0x0u: + if (unlikely (u == 0x00A0u)) return _(CP,x); if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u]; if (hb_in_range<hb_codepoint_t> (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u]; if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u]; - if (unlikely (u == 0x00A0u)) return _(CP,x); break; case 0x1u: @@ -412,9 +412,9 @@ break; case 0x2u: + if (unlikely (u == 0x25CCu)) return _(CP,x); if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u]; if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u]; - if (unlikely (u == 0x25CCu)) return _(CP,x); break; case 0xAu:
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-indic.cc Wed May 30 12:20:00 2018 -0700 @@ -27,240 +27,12 @@ #include "hb-ot-shape-complex-indic-private.hh" #include "hb-ot-layout-private.hh" -/* buffer var allocations */ -#define indic_category() complex_var_u8_0() /* indic_category_t */ -#define indic_position() complex_var_u8_1() /* indic_position_t */ - /* * Indic shaper. */ -#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base)) - -#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u)) -#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u)) -#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u)) -#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u)) -#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u)) -#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u)) -#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u)) -#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u)) -#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u)) -#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u)) -#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780u)) - - -#define MATRA_POS_LEFT(u) POS_PRE_M -#define MATRA_POS_RIGHT(u) ( \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_BENG(u) ? POS_AFTER_POST : \ - IS_GURU(u) ? POS_AFTER_POST : \ - IS_GUJR(u) ? POS_AFTER_POST : \ - IS_ORYA(u) ? POS_AFTER_POST : \ - IS_TAML(u) ? POS_AFTER_POST : \ - IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ - IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ - IS_MLYM(u) ? POS_AFTER_POST : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - IS_KHMR(u) ? POS_AFTER_POST : \ - /*default*/ POS_AFTER_SUB \ - ) -#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \ - IS_GUJR(u) ? POS_AFTER_SUB : \ - IS_ORYA(u) ? POS_AFTER_MAIN : \ - IS_TAML(u) ? POS_AFTER_SUB : \ - IS_TELU(u) ? POS_BEFORE_SUB : \ - IS_KNDA(u) ? POS_BEFORE_SUB : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - IS_KHMR(u) ? POS_AFTER_POST : \ - /*default*/ POS_AFTER_SUB \ - ) -#define MATRA_POS_BOTTOM(u) ( \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_BENG(u) ? POS_AFTER_SUB : \ - IS_GURU(u) ? POS_AFTER_POST : \ - IS_GUJR(u) ? POS_AFTER_POST : \ - IS_ORYA(u) ? POS_AFTER_SUB : \ - IS_TAML(u) ? POS_AFTER_POST : \ - IS_TELU(u) ? POS_BEFORE_SUB : \ - IS_KNDA(u) ? POS_BEFORE_SUB : \ - IS_MLYM(u) ? POS_AFTER_POST : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - IS_KHMR(u) ? POS_AFTER_POST : \ - /*default*/ POS_AFTER_SUB \ - ) - -static inline indic_position_t -matra_position (hb_codepoint_t u, indic_position_t side) -{ - switch ((int) side) - { - case POS_PRE_C: return MATRA_POS_LEFT (u); - case POS_POST_C: return MATRA_POS_RIGHT (u); - case POS_ABOVE_C: return MATRA_POS_TOP (u); - case POS_BELOW_C: return MATRA_POS_BOTTOM (u); - }; - return side; -} - -/* XXX - * This is a hack for now. We should move this data into the main Indic table. - * Or completely remove it and just check in the tables. - */ -static const hb_codepoint_t ra_chars[] = { - 0x0930u, /* Devanagari */ - 0x09B0u, /* Bengali */ - 0x09F0u, /* Bengali */ - 0x0A30u, /* Gurmukhi */ /* No Reph */ - 0x0AB0u, /* Gujarati */ - 0x0B30u, /* Oriya */ - 0x0BB0u, /* Tamil */ /* No Reph */ - 0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */ - 0x0CB0u, /* Kannada */ - 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ - - 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ - - 0x179Au, /* Khmer */ /* No Reph, Visual Repha */ -}; - -static inline bool -is_ra (hb_codepoint_t u) -{ - for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++) - if (u == ra_chars[i]) - return true; - return false; -} - -static inline bool -is_one_of (const hb_glyph_info_t &info, unsigned int flags) -{ - /* If it ligated, all bets are off. */ - if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG_UNSAFE (info.indic_category()) & flags); -} - -static inline bool -is_joiner (const hb_glyph_info_t &info) -{ - return is_one_of (info, JOINER_FLAGS); -} - -static inline bool -is_consonant (const hb_glyph_info_t &info) -{ - return is_one_of (info, CONSONANT_FLAGS); -} - -static inline bool -is_halant_or_coeng (const hb_glyph_info_t &info) -{ - return is_one_of (info, HALANT_OR_COENG_FLAGS); -} - -static inline void -set_indic_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); - indic_position_t pos = (indic_position_t) (type >> 8); - - - /* - * Re-assign category - */ - - /* The following act more like the Bindus. */ - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0953u, 0x0954u))) - cat = OT_SM; - /* The following act like consonants. */ - else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x0A72u, 0x0A73u, - 0x1CF5u, 0x1CF6u))) - cat = OT_C; - /* TODO: The following should only be allowed after a Visarga. - * For now, just treat them like regular tone marks. */ - else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1CE2u, 0x1CE8u))) - cat = OT_A; - /* TODO: The following should only be allowed after some of - * the nasalization marks, maybe only for U+1CE9..U+1CF1. - * For now, just treat them like tone marks. */ - else if (unlikely (u == 0x1CEDu)) - cat = OT_A; - /* The following take marks in standalone clusters, similar to Avagraha. */ - else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0xA8F2u, 0xA8F7u, - 0x1CE9u, 0x1CECu, - 0x1CEEu, 0x1CF1u))) - { - cat = OT_Symbol; - static_assert (((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol), ""); - } - else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CDu, 0x17D1u) || - u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */ - { - /* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier. - * https://github.com/roozbehp/unicode-data/issues/5 */ - cat = OT_M; - pos = POS_ABOVE_C; - } - else if (unlikely (u == 0x0A51u)) - { - /* https://github.com/behdad/harfbuzz/issues/524 */ - cat = OT_M; - pos = POS_BELOW_C; - } - - /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil, - * so the Indic shaper needs to know their categories. */ - else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM; - else if (unlikely (u == 0x1133cu)) cat = OT_N; - - else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/behdad/harfbuzz/issues/552 */ - - else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/behdad/harfbuzz/issues/538 */ - else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */ - else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u))) - cat = OT_PLACEHOLDER; - else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; - - - /* - * Re-assign position. - */ - - if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) - { - pos = POS_BASE_C; - if (is_ra (u)) - cat = OT_Ra; - } - else if (cat == OT_M) - { - pos = matra_position (u, pos); - } - else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol)))) - { - pos = POS_SMVD; - } - - if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */ - - - - info.indic_category() = cat; - info.indic_position() = pos; -} - -/* - * Things above this line should ideally be moved to the Indic table itself. - */ - - /* * Indic configurations. Note that we do not want to keep every single script-specific * behavior in these tables necessarily. This should mainly be used for per-script @@ -270,7 +42,6 @@ */ enum base_position_t { - BASE_POS_FIRST, BASE_POS_LAST_SINHALA, BASE_POS_LAST }; @@ -279,13 +50,11 @@ REPH_POS_BEFORE_SUB = POS_BEFORE_SUB, REPH_POS_AFTER_SUB = POS_AFTER_SUB, REPH_POS_BEFORE_POST = POS_BEFORE_POST, - REPH_POS_AFTER_POST = POS_AFTER_POST, - REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH + REPH_POS_AFTER_POST = POS_AFTER_POST }; enum reph_mode_t { REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */ REPH_MODE_EXPLICIT, /* Reph formed out of initial Ra,H,ZWJ sequence. */ - REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */ REPH_MODE_LOG_REPHA /* Encoded Repha character, needs reordering. */ }; enum blwf_mode_t { @@ -318,7 +87,6 @@ {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}, - {HB_SCRIPT_KHMER, false,0x17D2u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST}, }; @@ -350,7 +118,6 @@ {HB_TAG('p','s','t','f'), F_NONE}, {HB_TAG('v','a','t','u'), F_GLOBAL}, {HB_TAG('c','j','c','t'), F_GLOBAL}, - {HB_TAG('c','f','a','r'), F_NONE}, /* * Other features. * These features are applied all at once, after final_reordering. @@ -384,7 +151,6 @@ PSTF, _VATU, _CJCT, - CFAR, INIT, _PRES, @@ -451,17 +217,6 @@ static void override_features_indic (hb_ot_shape_planner_t *plan) { - /* Uniscribe does not apply 'kern' in Khmer. */ - if (hb_options ().uniscribe_bug_compatible) - { - switch ((hb_tag_t) plan->props.script) - { - case HB_SCRIPT_KHMER: - plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL); - break; - } - } - plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); } @@ -691,7 +446,7 @@ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data; hb_glyph_info_t *info = buffer->info; - /* https://github.com/behdad/harfbuzz/issues/435#issuecomment-335560167 + /* https://github.com/harfbuzz/harfbuzz/issues/435#issuecomment-335560167 * // For compatibility with legacy usage in Kannada, * // Ra+h+ZWJ must behave like Ra+ZWJ+h... */ @@ -713,7 +468,7 @@ * following algorithm: starting from the end of the syllable, move backwards * until a consonant is found that does not have a below-base or post-base * form (post-base forms have to follow below-base forms), or that is not a - * pre-base reordering Ra, or arrive at the first consonant. The consonant + * pre-base-reordering Ra, or arrive at the first consonant. The consonant * stopped at will be the base. * * o If the syllable starts with Ra + Halant (in a script that has Reph) @@ -729,8 +484,7 @@ * and has more than one consonant, Ra is excluded from candidates for * base consonants. */ unsigned int limit = start; - if (indic_plan->config->reph_pos != REPH_POS_DONT_CARE && - indic_plan->mask_array[RPHF] && + if (indic_plan->mask_array[RPHF] && start + 3 <= end && ( (indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) || @@ -784,11 +538,11 @@ if (info[i].indic_position() == POS_BELOW_C) seen_below = true; - /* -> or that is not a pre-base reordering Ra, + /* -> or that is not a pre-base-reordering Ra, * * IMPLEMENTATION NOTES: * - * Our pre-base reordering Ra's are marked POS_POST_C, so will be skipped + * Our pre-base-reordering Ra's are marked POS_POST_C, so will be skipped * by the logic above already. */ @@ -839,22 +593,6 @@ info[i].indic_position() = POS_BELOW_C; } break; - - case BASE_POS_FIRST: - { - /* The first consonant is always the base. */ - - assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA); - assert (!has_reph); - - base = start; - - /* Mark all subsequent consonants as below. */ - for (unsigned int i = base + 1; i < end; i++) - if (is_consonant (info[i])) - info[i].indic_position() = POS_BELOW_C; - } - break; } /* -> If the syllable starts with Ra + Halant (in a script that has Reph) @@ -909,15 +647,15 @@ if (base < end) info[base].indic_position() = POS_BASE_C; - /* Mark final consonants. A final consonant is one appearing after a matra, - * like in Khmer. */ + /* Mark final consonants. A final consonant is one appearing after a matra. + * Happens in Sinhala. */ for (unsigned int i = base + 1; i < end; i++) if (info[i].indic_category() == OT_M) { for (unsigned int j = i + 1; j < end; j++) if (is_consonant (info[j])) { - info[j].indic_position() = POS_FINAL_C; - break; - } + info[j].indic_position() = POS_FINAL_C; + break; + } break; } @@ -968,7 +706,7 @@ indic_position_t last_pos = POS_START; for (unsigned int i = start; i < end; i++) { - if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS))) + if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_H)))) { info[i].indic_position() = last_pos; if (unlikely (info[i].indic_category() == OT_H && @@ -1123,7 +861,7 @@ unsigned int pref_len = 2; if (indic_plan->mask_array[PREF] && base + pref_len < end) { - /* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */ + /* 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]; for (unsigned int j = 0; j < pref_len; j++) @@ -1132,17 +870,6 @@ { for (unsigned int j = 0; j < pref_len; j++) info[i++].mask |= indic_plan->mask_array[PREF]; - - /* Mark the subsequent stuff with 'cfar'. Used in Khmer. - * Read the feature spec. - * This allows distinguishing the following cases with MS Khmer fonts: - * U+1784,U+17D2,U+179A,U+17D2,U+1782 - * U+1784,U+17D2,U+1782,U+17D2,U+179A - */ - if (indic_plan->mask_array[CFAR]) - for (; i < end; i++) - info[i].mask |= indic_plan->mask_array[CFAR]; - break; } } @@ -1310,7 +1037,7 @@ _hb_glyph_info_ligated (&info[i]) && _hb_glyph_info_multiplied (&info[i])) { - /* This will make sure that this glyph passes is_halant_or_coeng() test. */ + /* This will make sure that this glyph passes is_halant() test. */ info[i].indic_category() = OT_H; _hb_glyph_info_clear_ligated_and_multiplied (&info[i]); } @@ -1343,7 +1070,7 @@ /* Ok, this was a 'pref' candidate but didn't form any. * Base is around here... */ base = i; - while (base < end && is_halant_or_coeng (info[base])) + while (base < end && is_halant (info[base])) base++; info[base].indic_position() = POS_BASE_C; @@ -1359,7 +1086,7 @@ { while (i < end && is_joiner (info[i])) i++; - if (i == end || !is_halant_or_coeng (info[i])) + if (i == end || !is_halant (info[i])) break; i++; /* Skip halant. */ while (i < end && is_joiner (info[i])) @@ -1381,7 +1108,7 @@ base--; if (base < end) while (start < base && - is_one_of (info[base], (FLAG (OT_N) | HALANT_OR_COENG_FLAGS))) + is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_H)))) base--; @@ -1407,13 +1134,13 @@ if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL) { while (new_pos > start && - !(is_one_of (info[new_pos], (FLAG (OT_M) | HALANT_OR_COENG_FLAGS)))) + !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H))))) new_pos--; /* If we found no Halant we are done. * Otherwise only proceed if the Halant does * not belong to the Matra itself! */ - if (is_halant_or_coeng (info[new_pos]) && + if (is_halant (info[new_pos]) && info[new_pos].indic_position() != POS_PRE_M) { /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ @@ -1480,8 +1207,6 @@ unsigned int new_reph_pos; reph_position_t reph_pos = indic_plan->config->reph_pos; - assert (reph_pos != REPH_POS_DONT_CARE); - /* 1. If reph should be positioned after post-base consonant forms, * proceed to step 5. */ @@ -1503,10 +1228,10 @@ */ { new_reph_pos = start + 1; - while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos])) + while (new_reph_pos < base && !is_halant (info[new_reph_pos])) new_reph_pos++; - if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos])) + if (new_reph_pos < base && is_halant (info[new_reph_pos])) { /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */ if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1])) @@ -1517,7 +1242,7 @@ /* 3. If reph should be repositioned after the main consonant: find the * first consonant not ligated with main, or find the first - * consonant that is not a potential pre-base reordering Ra. + * consonant that is not a potential pre-base-reordering Ra. */ if (reph_pos == REPH_POS_AFTER_MAIN) { @@ -1555,10 +1280,10 @@ { /* Copied from step 2. */ new_reph_pos = start + 1; - while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos])) + while (new_reph_pos < base && !is_halant (info[new_reph_pos])) new_reph_pos++; - if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos])) + if (new_reph_pos < base && is_halant (info[new_reph_pos])) { /* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */ if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1])) @@ -1582,7 +1307,7 @@ * TEST: U+0930,U+094D,U+0915,U+094B,U+094D */ if (!hb_options ().uniscribe_bug_compatible && - unlikely (is_halant_or_coeng (info[new_reph_pos]))) { + unlikely (is_halant (info[new_reph_pos]))) { for (unsigned int i = base + 1; i < new_reph_pos; i++) if (info[i].indic_category() == OT_M) { /* Ok, got it. */ @@ -1606,13 +1331,13 @@ } - /* o Reorder pre-base reordering consonants: + /* o Reorder pre-base-reordering consonants: * - * If a pre-base reordering consonant is found, reorder it according to + * If a pre-base-reordering consonant is found, reorder it according to * the following rules: */ - if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */ + if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */ { for (unsigned int i = base + 1; i < end; i++) if ((info[i].mask & indic_plan->mask_array[PREF]) != 0) @@ -1643,24 +1368,11 @@ if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL) { while (new_pos > start && - !(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS))) + !(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_H)))) new_pos--; - - /* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a - * split matra, it should be reordered to *before* the left part of such matra. */ - if (new_pos > start && info[new_pos - 1].indic_category() == OT_M) - { - unsigned int old_pos = i; - for (unsigned int j = base + 1; j < old_pos; j++) - if (info[j].indic_category() == OT_M) - { - new_pos--; - break; - } - } } - if (new_pos > start && is_halant_or_coeng (info[new_pos - 1])) + if (new_pos > start && is_halant (info[new_pos - 1])) { /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ if (new_pos < end && is_joiner (info[new_pos])) @@ -1765,13 +1477,6 @@ * Decompose split matras that don't have Unicode decompositions. */ - /* 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; - #if 0 /* Gujarati */ /* This one has no decomposition in Unicode, but needs no decomposition either. */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-khmer-machine.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,294 @@ + +#line 1 "hb-ot-shape-complex-khmer-machine.rl" +/* + * 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_SHAPE_COMPLEX_KHMER_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH + +#include "hb-private.hh" + + +#line 36 "hb-ot-shape-complex-khmer-machine.hh" +static const unsigned char _khmer_syllable_machine_trans_keys[] = { + 7u, 7u, 1u, 16u, 13u, 13u, 1u, 16u, 7u, 13u, 7u, 7u, 1u, 16u, 13u, 13u, + 1u, 16u, 7u, 13u, 1u, 16u, 3u, 14u, 3u, 14u, 5u, 14u, 3u, 14u, 5u, 14u, + 8u, 8u, 3u, 13u, 3u, 8u, 8u, 8u, 3u, 8u, 3u, 14u, 3u, 14u, 5u, 14u, + 3u, 14u, 5u, 14u, 8u, 8u, 3u, 13u, 3u, 8u, 8u, 8u, 3u, 8u, 3u, 14u, + 3u, 14u, 7u, 13u, 7u, 7u, 1u, 16u, 0 +}; + +static const char _khmer_syllable_machine_key_spans[] = { + 1, 16, 1, 16, 7, 1, 16, 1, + 16, 7, 16, 12, 12, 10, 12, 10, + 1, 11, 6, 1, 6, 12, 12, 10, + 12, 10, 1, 11, 6, 1, 6, 12, + 12, 7, 1, 16 +}; + +static const short _khmer_syllable_machine_index_offsets[] = { + 0, 2, 19, 21, 38, 46, 48, 65, + 67, 84, 92, 109, 122, 135, 146, 159, + 170, 172, 184, 191, 193, 200, 213, 226, + 237, 250, 261, 263, 275, 282, 284, 291, + 304, 317, 325, 327 +}; + +static const char _khmer_syllable_machine_indicies[] = { + 1, 0, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 3, 0, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 0, 1, 0, + 0, 0, 0, 0, 5, 0, 7, 6, + 8, 8, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 8, + 6, 9, 6, 10, 10, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 10, 6, 7, 6, 6, 6, + 6, 6, 11, 6, 4, 4, 13, 12, + 14, 15, 7, 16, 12, 12, 4, 4, + 11, 17, 12, 4, 12, 19, 18, 20, + 21, 1, 22, 18, 18, 18, 18, 5, + 23, 18, 24, 18, 21, 21, 1, 22, + 18, 18, 18, 18, 18, 23, 18, 21, + 21, 1, 22, 18, 18, 18, 18, 18, + 23, 18, 25, 18, 21, 21, 1, 22, + 18, 18, 18, 18, 18, 26, 18, 21, + 21, 1, 22, 18, 18, 18, 18, 18, + 26, 18, 27, 18, 28, 18, 29, 18, + 18, 22, 18, 18, 18, 18, 3, 18, + 30, 18, 18, 18, 18, 22, 18, 22, + 18, 28, 18, 18, 18, 18, 22, 18, + 19, 18, 21, 21, 1, 22, 18, 18, + 18, 18, 18, 23, 18, 32, 31, 33, + 33, 7, 16, 31, 31, 31, 31, 31, + 34, 31, 33, 33, 7, 16, 31, 31, + 31, 31, 31, 34, 31, 35, 31, 33, + 33, 7, 16, 31, 31, 31, 31, 31, + 36, 31, 33, 33, 7, 16, 31, 31, + 31, 31, 31, 36, 31, 37, 31, 38, + 31, 39, 31, 31, 16, 31, 31, 31, + 31, 9, 31, 40, 31, 31, 31, 31, + 16, 31, 16, 31, 38, 31, 31, 31, + 31, 16, 31, 13, 31, 41, 33, 7, + 16, 31, 31, 31, 31, 11, 34, 31, + 13, 31, 33, 33, 7, 16, 31, 31, + 31, 31, 31, 34, 31, 7, 42, 42, + 42, 42, 42, 11, 42, 7, 42, 10, + 10, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 10, 42, + 0 +}; + +static const char _khmer_syllable_machine_trans_targs[] = { + 10, 14, 17, 20, 11, 21, 10, 24, + 27, 30, 31, 32, 10, 22, 33, 34, + 26, 35, 10, 12, 4, 0, 16, 3, + 13, 15, 1, 10, 18, 2, 19, 10, + 23, 5, 8, 25, 6, 10, 28, 7, + 29, 9, 10 +}; + +static const char _khmer_syllable_machine_trans_actions[] = { + 1, 2, 2, 0, 2, 2, 3, 2, + 2, 0, 2, 2, 6, 2, 0, 0, + 0, 0, 7, 2, 0, 0, 0, 0, + 2, 2, 0, 8, 0, 0, 0, 9, + 2, 0, 0, 2, 0, 10, 0, 0, + 0, 0, 11 +}; + +static const char _khmer_syllable_machine_to_state_actions[] = { + 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 +}; + +static const char _khmer_syllable_machine_from_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 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, + 0, 0, 0, 0 +}; + +static const unsigned char _khmer_syllable_machine_eof_trans[] = { + 1, 1, 1, 1, 1, 7, 7, 7, + 7, 7, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 43, 43, 43 +}; + +static const int khmer_syllable_machine_start = 10; +static const int khmer_syllable_machine_first_final = 10; +static const int khmer_syllable_machine_error = -1; + +static const int khmer_syllable_machine_en_main = 10; + + +#line 36 "hb-ot-shape-complex-khmer-machine.rl" + + + +#line 74 "hb-ot-shape-complex-khmer-machine.rl" + + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ + for (unsigned int i = last; i < p+1; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + last = p+1; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +static void +find_syllables (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + +#line 181 "hb-ot-shape-complex-khmer-machine.hh" + { + cs = khmer_syllable_machine_start; + ts = 0; + te = 0; + act = 0; + } + +#line 95 "hb-ot-shape-complex-khmer-machine.rl" + + + p = 0; + pe = eof = buffer->len; + + unsigned int last = 0; + unsigned int syllable_serial = 1; + +#line 198 "hb-ot-shape-complex-khmer-machine.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; +_resume: + switch ( _khmer_syllable_machine_from_state_actions[cs] ) { + case 5: +#line 1 "NONE" + {ts = p;} + break; +#line 212 "hb-ot-shape-complex-khmer-machine.hh" + } + + _keys = _khmer_syllable_machine_trans_keys + (cs<<1); + _inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs]; + + _slen = _khmer_syllable_machine_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) && + ( info[p].khmer_category()) <= _keys[1] ? + ( info[p].khmer_category()) - _keys[0] : _slen ]; + +_eof_trans: + cs = _khmer_syllable_machine_trans_targs[_trans]; + + if ( _khmer_syllable_machine_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _khmer_syllable_machine_trans_actions[_trans] ) { + case 2: +#line 1 "NONE" + {te = p+1;} + break; + case 8: +#line 68 "hb-ot-shape-complex-khmer-machine.rl" + {te = p+1;{ found_syllable (consonant_syllable); }} + break; + case 10: +#line 69 "hb-ot-shape-complex-khmer-machine.rl" + {te = p+1;{ found_syllable (broken_cluster); }} + break; + case 6: +#line 70 "hb-ot-shape-complex-khmer-machine.rl" + {te = p+1;{ found_syllable (non_khmer_cluster); }} + break; + case 7: +#line 68 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p--;{ found_syllable (consonant_syllable); }} + break; + case 9: +#line 69 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p--;{ found_syllable (broken_cluster); }} + break; + case 11: +#line 70 "hb-ot-shape-complex-khmer-machine.rl" + {te = p;p--;{ found_syllable (non_khmer_cluster); }} + break; + case 1: +#line 68 "hb-ot-shape-complex-khmer-machine.rl" + {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} + break; + case 3: +#line 69 "hb-ot-shape-complex-khmer-machine.rl" + {{p = ((te))-1;}{ found_syllable (broken_cluster); }} + break; +#line 266 "hb-ot-shape-complex-khmer-machine.hh" + } + +_again: + switch ( _khmer_syllable_machine_to_state_actions[cs] ) { + case 4: +#line 1 "NONE" + {ts = 0;} + break; +#line 275 "hb-ot-shape-complex-khmer-machine.hh" + } + + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) { + _trans = _khmer_syllable_machine_eof_trans[cs] - 1; + goto _eof_trans; + } + } + + } + +#line 104 "hb-ot-shape-complex-khmer-machine.rl" + +} + +#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-khmer-private.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,124 @@ +/* + * Copyright © 2018 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_KHMER_PRIVATE_HH +#define HB_OT_SHAPE_COMPLEX_KHMER_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-ot-shape-complex-indic-private.hh" + + +/* buffer var allocations */ +#define khmer_category() indic_category() /* khmer_category_t */ +#define khmer_position() indic_position() /* khmer_position_t */ + + +typedef indic_category_t khmer_category_t; +typedef indic_position_t khmer_position_t; + + +static inline khmer_position_t +matra_position_khmer (khmer_position_t side) +{ + switch ((int) side) + { + case POS_PRE_C: + return POS_PRE_M; + + case POS_POST_C: + case POS_ABOVE_C: + case POS_BELOW_C: + return POS_AFTER_POST; + + default: + return side; + }; +} + +static inline bool +is_consonant_or_vowel (const hb_glyph_info_t &info) +{ + return is_one_of (info, CONSONANT_FLAGS | FLAG (OT_V)); +} + +static inline bool +is_coeng (const hb_glyph_info_t &info) +{ + return is_one_of (info, FLAG (OT_Coeng)); +} + +static inline void +set_khmer_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + khmer_category_t cat = (khmer_category_t) (type & 0x7Fu); + khmer_position_t pos = (khmer_position_t) (type >> 8); + + + /* + * Re-assign category + */ + + if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */ + else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CDu, 0x17D1u) || + u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */ + { + /* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier. + * https://github.com/roozbehp/unicode-data/issues/5 */ + cat = OT_M; + pos = POS_ABOVE_C; + } + else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u))) cat = OT_PLACEHOLDER; + else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; + + + /* + * Re-assign position. + */ + + if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) + { + pos = POS_BASE_C; + if (u == 0x179Au) + cat = OT_Ra; + } + else if (cat == OT_M) + { + pos = matra_position_khmer (pos); + } + else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_A) | FLAG (OT_Symbol)))) + { + pos = POS_SMVD; + } + + info.khmer_category() = cat; + info.khmer_position() = pos; +} + + +#endif /* HB_OT_SHAPE_COMPLEX_KHMER_PRIVATE_HH */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-khmer.cc Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,835 @@ +/* + * 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 + */ + +#include "hb-ot-shape-complex-khmer-private.hh" +#include "hb-ot-layout-private.hh" + + +/* + * Khmer shaper. + */ + +struct feature_list_t { + hb_tag_t tag; + hb_ot_map_feature_flags_t flags; +}; + +static const feature_list_t +khmer_features[] = +{ + /* + * Basic features. + * These features are applied in order, one at a time, after initial_reordering. + */ + {HB_TAG('p','r','e','f'), F_NONE}, + {HB_TAG('b','l','w','f'), F_NONE}, + {HB_TAG('a','b','v','f'), F_NONE}, + {HB_TAG('p','s','t','f'), F_NONE}, + {HB_TAG('c','f','a','r'), F_NONE}, + /* + * Other features. + * These features are applied all at once, after final_reordering. + * Default Bengali font in Windows for example has intermixed + * lookups for init,pres,abvs,blws features. + */ + {HB_TAG('p','r','e','s'), F_GLOBAL}, + {HB_TAG('a','b','v','s'), F_GLOBAL}, + {HB_TAG('b','l','w','s'), F_GLOBAL}, + {HB_TAG('p','s','t','s'), F_GLOBAL}, + /* Positioning features, though we don't care about the types. */ + {HB_TAG('d','i','s','t'), F_GLOBAL}, + {HB_TAG('a','b','v','m'), F_GLOBAL}, + {HB_TAG('b','l','w','m'), F_GLOBAL}, +}; + +/* + * Must be in the same order as the khmer_features array. + */ +enum { + PREF, + BLWF, + ABVF, + PSTF, + CFAR, + + _PRES, + _ABVS, + _BLWS, + _PSTS, + _DIST, + _ABVM, + _BLWM, + + KHMER_NUM_FEATURES, + KHMER_BASIC_FEATURES = _PRES /* Don't forget to update this! */ +}; + +static void +setup_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +initial_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +final_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +clear_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + +static void +collect_features_khmer (hb_ot_shape_planner_t *plan) +{ + hb_ot_map_builder_t *map = &plan->map; + + /* Do this before any lookups have been applied. */ + map->add_gsub_pause (setup_syllables); + + map->add_global_bool_feature (HB_TAG('l','o','c','l')); + /* The Indic specs do not require ccmp, but we apply it here since if + * there is a use of it, it's typically at the beginning. */ + map->add_global_bool_feature (HB_TAG('c','c','m','p')); + + + unsigned int i = 0; + map->add_gsub_pause (initial_reordering); + for (; i < KHMER_BASIC_FEATURES; i++) { + map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); + map->add_gsub_pause (nullptr); + } + map->add_gsub_pause (final_reordering); + for (; i < KHMER_NUM_FEATURES; i++) { + map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ); + } + + map->add_global_bool_feature (HB_TAG('c','a','l','t')); + map->add_global_bool_feature (HB_TAG('c','l','i','g')); + + map->add_gsub_pause (clear_syllables); +} + +static void +override_features_khmer (hb_ot_shape_planner_t *plan) +{ + /* Uniscribe does not apply 'kern' in Khmer. */ + if (hb_options ().uniscribe_bug_compatible) + { + plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL); + } + + plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); +} + + +struct would_substitute_feature_t +{ + inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_) + { + zero_context = zero_context_; + map->get_stage_lookups (0/*GSUB*/, + map->get_feature_stage (0/*GSUB*/, feature_tag), + &lookups, &count); + } + + inline bool would_substitute (const hb_codepoint_t *glyphs, + unsigned int glyphs_count, + hb_face_t *face) const + { + for (unsigned int i = 0; i < count; i++) + if (hb_ot_layout_lookup_would_substitute_fast (face, lookups[i].index, glyphs, glyphs_count, zero_context)) + return true; + return false; + } + + private: + const hb_ot_map_t::lookup_map_t *lookups; + unsigned int count; + bool zero_context; +}; + +struct khmer_shape_plan_t +{ + ASSERT_POD (); + + inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const + { + hb_codepoint_t glyph = virama_glyph; + if (unlikely (virama_glyph == (hb_codepoint_t) -1)) + { + if (!font->get_nominal_glyph (0x17D2u, &glyph)) + glyph = 0; + /* Technically speaking, the spec says we should apply 'locl' to virama too. + * Maybe one day... */ + + /* 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! */ + virama_glyph = glyph; + } + + *pglyph = glyph; + return glyph != 0; + } + + mutable hb_codepoint_t virama_glyph; + + would_substitute_feature_t pref; + + hb_mask_t mask_array[KHMER_NUM_FEATURES]; +}; + +static void * +data_create_khmer (const hb_ot_shape_plan_t *plan) +{ + khmer_shape_plan_t *khmer_plan = (khmer_shape_plan_t *) calloc (1, sizeof (khmer_shape_plan_t)); + if (unlikely (!khmer_plan)) + return nullptr; + + khmer_plan->virama_glyph = (hb_codepoint_t) -1; + + khmer_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), true); + + for (unsigned int i = 0; i < ARRAY_LENGTH (khmer_plan->mask_array); i++) + khmer_plan->mask_array[i] = (khmer_features[i].flags & F_GLOBAL) ? + 0 : plan->map.get_1_mask (khmer_features[i].tag); + + return khmer_plan; +} + +static void +data_destroy_khmer (void *data) +{ + free (data); +} + + +enum syllable_type_t { + consonant_syllable, + broken_cluster, + non_khmer_cluster, +}; + +#include "hb-ot-shape-complex-khmer-machine.hh" + +static void +setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_buffer_t *buffer, + hb_font_t *font HB_UNUSED) +{ + HB_BUFFER_ALLOCATE_VAR (buffer, khmer_category); + HB_BUFFER_ALLOCATE_VAR (buffer, khmer_position); + + /* We cannot setup masks here. We save information about characters + * and setup masks later on in a pause-callback. */ + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + set_khmer_properties (info[i]); +} + +static void +setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + find_syllables (buffer); + foreach_syllable (buffer, start, end) + buffer->unsafe_to_break (start, end); +} + +static int +compare_khmer_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) +{ + int a = pa->khmer_position(); + int b = pb->khmer_position(); + + return a < b ? -1 : a == b ? 0 : +1; +} + + +/* Rules from: + * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */ + +static void +initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data; + hb_glyph_info_t *info = buffer->info; + + /* 1. Khmer shaping assumes that a syllable will begin with a Cons, IndV, or Number. */ + + /* The first consonant is always the base. */ + unsigned int base = start; + info[base].khmer_position() = POS_BASE_C; + + /* Mark all subsequent consonants as below. */ + for (unsigned int i = base + 1; i < end; i++) + if (is_consonant_or_vowel (info[i])) + info[i].khmer_position() = POS_BELOW_C; + + /* Mark final consonants. A final consonant is one appearing after a matra, + * like in Khmer. */ + for (unsigned int i = base + 1; i < end; i++) + if (info[i].khmer_category() == OT_M) { + for (unsigned int j = i + 1; j < end; j++) + if (is_consonant_or_vowel (info[j])) { + info[j].khmer_position() = POS_FINAL_C; + break; + } + break; + } + + /* Attach misc marks to previous char to move with them. */ + { + khmer_position_t last_pos = POS_START; + for (unsigned int i = start; i < end; i++) + { + if ((FLAG_UNSAFE (info[i].khmer_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_Coeng)))) + { + info[i].khmer_position() = last_pos; + if (unlikely (info[i].khmer_category() == OT_H && + info[i].khmer_position() == POS_PRE_M)) + { + /* + * Uniscribe doesn't move the Halant with Left Matra. + * TEST: U+092B,U+093F,U+094DE + * We follow. This is important for the Sinhala + * U+0DDA split matra since it decomposes to U+0DD9,U+0DCA + * where U+0DD9 is a left matra and U+0DCA is the virama. + * We don't want to move the virama with the left matra. + * TEST: U+0D9A,U+0DDA + */ + for (unsigned int j = i; j > start; j--) + if (info[j - 1].khmer_position() != POS_PRE_M) { + info[i].khmer_position() = info[j - 1].khmer_position(); + break; + } + } + } else if (info[i].khmer_position() != POS_SMVD) { + last_pos = (khmer_position_t) info[i].khmer_position(); + } + } + } + /* For post-base consonants let them own anything before them + * since the last consonant or matra. */ + { + unsigned int last = base; + for (unsigned int i = base + 1; i < end; i++) + if (is_consonant_or_vowel (info[i])) + { + for (unsigned int j = last + 1; j < i; j++) + if (info[j].khmer_position() < POS_SMVD) + info[j].khmer_position() = info[i].khmer_position(); + last = i; + } else if (info[i].khmer_category() == OT_M) + last = i; + } + + { + /* Use syllable() for sort accounting temporarily. */ + unsigned int syllable = info[start].syllable(); + for (unsigned int i = start; i < end; i++) + info[i].syllable() = i - start; + + /* Sit tight, rock 'n roll! */ + hb_stable_sort (info + start, end - start, compare_khmer_order); + /* Find base again */ + base = end; + for (unsigned int i = start; i < end; i++) + if (info[i].khmer_position() == POS_BASE_C) + { + base = i; + break; + } + + /* Note! syllable() is a one-byte field. */ + for (unsigned int i = base; i < end; i++) + if (info[i].syllable() != 255) + { + unsigned int max = i; + unsigned int j = start + info[i].syllable(); + while (j != i) + { + max = MAX (max, j); + unsigned int next = start + info[j].syllable(); + info[j].syllable() = 255; /* So we don't process j later again. */ + j = next; + } + if (i != max) + buffer->merge_clusters (i, max + 1); + } + + /* Put syllable back in. */ + for (unsigned int i = start; i < end; i++) + info[i].syllable() = syllable; + } + + /* Setup masks now */ + + { + hb_mask_t mask; + + /* Post-base */ + mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF]; + for (unsigned int i = base + 1; i < end; i++) + info[i].mask |= mask; + } + + unsigned int pref_len = 2; + if (khmer_plan->mask_array[PREF] && base + pref_len < end) + { + /* 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]; + for (unsigned int j = 0; j < pref_len; j++) + glyphs[j] = info[i + j].codepoint; + if (khmer_plan->pref.would_substitute (glyphs, pref_len, face)) + { + for (unsigned int j = 0; j < pref_len; j++) + info[i++].mask |= khmer_plan->mask_array[PREF]; + + /* Mark the subsequent stuff with 'cfar'. Used in Khmer. + * Read the feature spec. + * This allows distinguishing the following cases with MS Khmer fonts: + * U+1784,U+17D2,U+179A,U+17D2,U+1782 + * U+1784,U+17D2,U+1782,U+17D2,U+179A + */ + if (khmer_plan->mask_array[CFAR]) + for (; i < end; i++) + info[i].mask |= khmer_plan->mask_array[CFAR]; + + break; + } + } + } +} + +static void +initial_reordering_syllable (const hb_ot_shape_plan_t *plan, + hb_face_t *face, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); + switch (syllable_type) + { + case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */ + case consonant_syllable: + initial_reordering_consonant_syllable (plan, face, buffer, start, end); + break; + + case non_khmer_cluster: + break; + } +} + +static inline void +insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font, + hb_buffer_t *buffer) +{ + /* Note: This loop is extra overhead, but should not be measurable. */ + bool has_broken_syllables = false; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if ((info[i].syllable() & 0x0F) == broken_cluster) + { + has_broken_syllables = true; + break; + } + if (likely (!has_broken_syllables)) + return; + + + hb_codepoint_t dottedcircle_glyph; + if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph)) + return; + + hb_glyph_info_t dottedcircle = {0}; + dottedcircle.codepoint = 0x25CCu; + set_khmer_properties (dottedcircle); + dottedcircle.codepoint = dottedcircle_glyph; + + buffer->clear_output (); + + buffer->idx = 0; + unsigned int last_syllable = 0; + while (buffer->idx < buffer->len && !buffer->in_error) + { + unsigned int syllable = buffer->cur().syllable(); + syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); + if (unlikely (last_syllable != syllable && syllable_type == broken_cluster)) + { + last_syllable = syllable; + + hb_glyph_info_t ginfo = dottedcircle; + ginfo.cluster = buffer->cur().cluster; + ginfo.mask = buffer->cur().mask; + ginfo.syllable() = buffer->cur().syllable(); + /* TODO Set glyph_props? */ + + /* Insert dottedcircle after possible Repha. */ + while (buffer->idx < buffer->len && !buffer->in_error && + last_syllable == buffer->cur().syllable() && + buffer->cur().khmer_category() == OT_Repha) + buffer->next_glyph (); + + buffer->output_info (ginfo); + } + else + buffer->next_glyph (); + } + + buffer->swap_buffers (); +} + +static void +initial_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + insert_dotted_circles (plan, font, buffer); + + foreach_syllable (buffer, start, end) + initial_reordering_syllable (plan, font->face, buffer, start, end); +} + +static void +final_reordering_syllable (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data; + hb_glyph_info_t *info = buffer->info; + + + /* This function relies heavily on halant glyphs. Lots of ligation + * and possibly multiple substitutions happened prior to this + * phase, and that might have messed up our properties. Recover + * from a particular case of that where we're fairly sure that a + * class of OT_H is desired but has been lost. */ + if (khmer_plan->virama_glyph) + { + unsigned int virama_glyph = khmer_plan->virama_glyph; + for (unsigned int i = start; i < end; i++) + if (info[i].codepoint == virama_glyph && + _hb_glyph_info_ligated (&info[i]) && + _hb_glyph_info_multiplied (&info[i])) + { + /* This will make sure that this glyph passes is_coeng() test. */ + info[i].khmer_category() = OT_H; + _hb_glyph_info_clear_ligated_and_multiplied (&info[i]); + } + } + + + /* 4. Final reordering: + * + * After the localized forms and basic shaping forms GSUB features have been + * applied (see below), the shaping engine performs some final glyph + * reordering before applying all the remaining font features to the entire + * syllable. + */ + + bool try_pref = !!khmer_plan->mask_array[PREF]; + + /* Find base again */ + unsigned int base; + for (base = start; base < end; base++) + if (info[base].khmer_position() >= POS_BASE_C) + { + if (try_pref && base + 1 < end) + { + for (unsigned int i = base + 1; i < end; i++) + if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0) + { + if (!(_hb_glyph_info_substituted (&info[i]) && + _hb_glyph_info_ligated_and_didnt_multiply (&info[i]))) + { + /* Ok, this was a 'pref' candidate but didn't form any. + * Base is around here... */ + base = i; + while (base < end && is_coeng (info[base])) + base++; + info[base].khmer_position() = POS_BASE_C; + + try_pref = false; + } + break; + } + } + + if (start < base && info[base].khmer_position() > POS_BASE_C) + base--; + break; + } + if (base == end && start < base && + is_one_of (info[base - 1], FLAG (OT_ZWJ))) + base--; + if (base < end) + while (start < base && + is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_Coeng)))) + base--; + + + /* o Reorder matras: + * + * If a pre-base matra character had been reordered before applying basic + * features, the glyph can be moved closer to the main consonant based on + * whether half-forms had been formed. Actual position for the matra is + * defined as “after last standalone halant glyph, after initial matra + * position and before the main consonant”. If ZWJ or ZWNJ follow this + * halant, position is moved after it. + */ + + if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */ + { + /* If we lost track of base, alas, position before last thingy. */ + unsigned int new_pos = base == end ? base - 2 : base - 1; + + while (new_pos > start && + !(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_Coeng))))) + new_pos--; + + /* If we found no Halant we are done. + * Otherwise only proceed if the Halant does + * not belong to the Matra itself! */ + if (is_coeng (info[new_pos]) && + info[new_pos].khmer_position() != POS_PRE_M) + { + /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ + if (new_pos + 1 < end && is_joiner (info[new_pos + 1])) + new_pos++; + } + else + new_pos = start; /* No move. */ + + if (start < new_pos && info[new_pos].khmer_position () != POS_PRE_M) + { + /* Now go see if there's actually any matras... */ + for (unsigned int i = new_pos; i > start; i--) + if (info[i - 1].khmer_position () == POS_PRE_M) + { + unsigned int old_pos = i - 1; + if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */ + base--; + + hb_glyph_info_t tmp = info[old_pos]; + memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0])); + info[new_pos] = tmp; + + /* Note: this merge_clusters() is intentionally *after* the reordering. + * Indic matra reordering is special and tricky... */ + buffer->merge_clusters (new_pos, MIN (end, base + 1)); + + new_pos--; + } + } else { + for (unsigned int i = start; i < base; i++) + if (info[i].khmer_position () == POS_PRE_M) { + buffer->merge_clusters (i, MIN (end, base + 1)); + break; + } + } + } + + + /* o Reorder pre-base-reordering consonants: + * + * If a pre-base-reordering consonant is found, reorder it according to + * the following rules: + */ + + if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */ + { + for (unsigned int i = base + 1; i < end; i++) + if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0) + { + /* 1. Only reorder a glyph produced by substitution during application + * of the <pref> feature. (Note that a font may shape a Ra consonant with + * the feature generally but block it in certain contexts.) + */ + /* Note: We just check that something got substituted. We don't check that + * the <pref> feature actually did it... + * + * 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. + * If it is found, reorder pre-base consonant glyph. + * + * 3. If position is not found, reorder immediately before main + * consonant. + */ + + unsigned int new_pos = base; + while (new_pos > start && + !(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_Coeng)))) + new_pos--; + + /* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a + * split matra, it should be reordered to *before* the left part of such matra. */ + if (new_pos > start && info[new_pos - 1].khmer_category() == OT_M) + { + unsigned int old_pos = i; + for (unsigned int j = base + 1; j < old_pos; j++) + if (info[j].khmer_category() == OT_M) + { + new_pos--; + break; + } + } + + if (new_pos > start && is_coeng (info[new_pos - 1])) + { + /* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */ + if (new_pos < end && is_joiner (info[new_pos])) + new_pos++; + } + + { + unsigned int old_pos = i; + + buffer->merge_clusters (new_pos, old_pos + 1); + hb_glyph_info_t tmp = info[old_pos]; + memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0])); + info[new_pos] = tmp; + + if (new_pos <= base && base < old_pos) + base++; + } + } + + break; + } + } + + + /* + * Finish off the clusters and go home! + */ + if (hb_options ().uniscribe_bug_compatible) + { + /* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala. + * This means, half forms are submerged into the main consonant's cluster. + * This is unnecessary, and makes cursor positioning harder, but that's what + * Uniscribe does. */ + buffer->merge_clusters (start, end); + } +} + + +static void +final_reordering (const hb_ot_shape_plan_t *plan, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + unsigned int count = buffer->len; + if (unlikely (!count)) return; + + foreach_syllable (buffer, start, end) + final_reordering_syllable (plan, buffer, start, end); + + HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category); + HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_position); +} + + +static void +clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + info[i].syllable() = 0; +} + + +static bool +decompose_khmer (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t ab, + hb_codepoint_t *a, + hb_codepoint_t *b) +{ + switch (ab) + { + /* + * Decompose split matras that don't have Unicode decompositions. + */ + + /* 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; + } + + return (bool) c->unicode->decompose (ab, a, b); +} + +static bool +compose_khmer (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t a, + hb_codepoint_t b, + hb_codepoint_t *ab) +{ + /* Avoid recomposing split matras. */ + if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a))) + return false; + + return (bool) c->unicode->compose (a, b, ab); +} + + +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_khmer = +{ + collect_features_khmer, + override_features_khmer, + data_create_khmer, + data_destroy_khmer, + nullptr, /* preprocess_text */ + nullptr, /* postprocess_glyphs */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, + decompose_khmer, + compose_khmer, + setup_masks_khmer, + nullptr, /* disable_otl */ + nullptr, /* reorder_marks */ + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, + false, /* fallback_position */ +};
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar-machine.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar-machine.hh Wed May 30 12:20:00 2018 -0700 @@ -36,28 +36,29 @@ static const unsigned char _myanmar_syllable_machine_trans_keys[] = { 1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, - 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u, - 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, - 3u, 30u, 3u, 29u, 1u, 32u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, - 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 32u, 8u, 8u, 0 + 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, + 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, + 3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, + 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 32u, 8u, 8u, + 0 }; static const char _myanmar_syllable_machine_key_spans[] = { 32, 28, 25, 4, 25, 23, 21, 21, 27, 27, 27, 27, 16, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 25, 4, - 25, 23, 21, 21, 27, 27, 27, 27, - 28, 27, 32, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 32, 1 + 27, 27, 28, 27, 27, 27, 27, 25, + 4, 25, 23, 21, 21, 27, 27, 27, + 27, 28, 27, 32, 27, 27, 27, 27, + 27, 28, 27, 27, 27, 27, 32, 1 }; static const short _myanmar_syllable_machine_index_offsets[] = { 0, 33, 62, 88, 93, 119, 143, 165, 187, 215, 243, 271, 299, 316, 344, 372, - 400, 428, 456, 484, 512, 540, 568, 594, - 599, 625, 649, 671, 693, 721, 749, 777, - 805, 834, 862, 895, 923, 951, 979, 1007, - 1035, 1063, 1091, 1119, 1147, 1180 + 400, 428, 456, 485, 513, 541, 569, 597, + 623, 628, 654, 678, 700, 722, 750, 778, + 806, 834, 863, 891, 924, 952, 980, 1008, + 1036, 1064, 1093, 1121, 1149, 1177, 1205, 1238 }; static const char _myanmar_syllable_machine_indicies[] = { @@ -105,7 +106,7 @@ 21, 21, 21, 27, 21, 21, 28, 29, 30, 31, 32, 33, 34, 35, 36, 21, 22, 21, 24, 24, 21, 25, 21, 26, - 21, 21, 21, 21, 21, 21, 21, 35, + 21, 21, 21, 21, 21, 21, 21, 43, 21, 21, 21, 21, 21, 21, 32, 33, 34, 35, 36, 21, 22, 21, 24, 24, 21, 25, 21, 26, 21, 21, 21, 21, @@ -119,106 +120,114 @@ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 32, 21, 34, 21, 36, 21, 22, 21, 24, 24, 21, 25, 21, 26, - 21, 21, 21, 21, 21, 21, 21, 35, - 21, 21, 28, 21, 30, 21, 32, 33, - 34, 35, 36, 21, 22, 21, 24, 24, - 21, 25, 21, 26, 21, 21, 21, 21, - 21, 21, 21, 35, 21, 21, 28, 21, - 21, 21, 32, 33, 34, 35, 36, 21, - 22, 21, 24, 24, 21, 25, 21, 26, - 21, 21, 21, 21, 21, 21, 21, 35, - 21, 21, 28, 29, 30, 21, 32, 33, - 34, 35, 36, 21, 22, 23, 24, 24, - 21, 25, 21, 26, 21, 21, 21, 21, - 21, 21, 21, 27, 21, 21, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 21, - 3, 3, 43, 5, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 44, 43, 43, - 43, 43, 43, 43, 14, 43, 43, 43, - 18, 43, 3, 3, 43, 5, 43, 3, - 3, 43, 5, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 14, 43, 43, 43, 18, - 43, 45, 43, 3, 3, 43, 5, 43, - 14, 43, 43, 43, 43, 43, 43, 43, - 46, 43, 43, 43, 43, 43, 43, 14, - 43, 3, 3, 43, 5, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 46, 43, - 43, 43, 43, 43, 43, 14, 43, 3, - 3, 43, 5, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 14, 43, 2, 43, 3, - 3, 43, 5, 43, 6, 43, 43, 43, - 43, 43, 43, 43, 47, 43, 43, 47, - 43, 43, 43, 14, 48, 43, 43, 18, - 43, 2, 43, 3, 3, 43, 5, 43, - 6, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 14, - 43, 43, 43, 18, 43, 2, 43, 3, - 3, 43, 5, 43, 6, 43, 43, 43, - 43, 43, 43, 43, 47, 43, 43, 43, - 43, 43, 43, 14, 48, 43, 43, 18, - 43, 2, 43, 3, 3, 43, 5, 43, - 6, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 14, - 48, 43, 43, 18, 43, 22, 23, 24, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 32, 33, + 34, 35, 36, 43, 21, 22, 21, 24, + 24, 21, 25, 21, 26, 21, 21, 21, + 21, 21, 21, 21, 43, 21, 21, 28, + 21, 30, 21, 32, 33, 34, 35, 36, + 21, 22, 21, 24, 24, 21, 25, 21, + 26, 21, 21, 21, 21, 21, 21, 21, + 43, 21, 21, 28, 21, 21, 21, 32, + 33, 34, 35, 36, 21, 22, 21, 24, 24, 21, 25, 21, 26, 21, 21, 21, - 21, 21, 21, 21, 49, 21, 21, 28, - 29, 30, 31, 32, 33, 34, 35, 36, - 37, 21, 22, 50, 24, 24, 21, 25, + 21, 21, 21, 21, 43, 21, 21, 28, + 29, 30, 21, 32, 33, 34, 35, 36, + 21, 22, 23, 24, 24, 21, 25, 21, + 26, 21, 21, 21, 21, 21, 21, 21, + 27, 21, 21, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 21, 3, 3, 44, + 5, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 45, 44, 44, 44, 44, 44, + 44, 14, 44, 44, 44, 18, 44, 3, + 3, 44, 5, 44, 3, 3, 44, 5, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 14, 44, 44, 44, 18, 44, 46, 44, + 3, 3, 44, 5, 44, 14, 44, 44, + 44, 44, 44, 44, 44, 47, 44, 44, + 44, 44, 44, 44, 14, 44, 3, 3, + 44, 5, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 47, 44, 44, 44, 44, + 44, 44, 14, 44, 3, 3, 44, 5, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 14, 44, 2, 44, 3, 3, 44, 5, + 44, 6, 44, 44, 44, 44, 44, 44, + 44, 48, 44, 44, 48, 44, 44, 44, + 14, 49, 44, 44, 18, 44, 2, 44, + 3, 3, 44, 5, 44, 6, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 14, 44, 44, 44, + 18, 44, 2, 44, 3, 3, 44, 5, + 44, 6, 44, 44, 44, 44, 44, 44, + 44, 48, 44, 44, 44, 44, 44, 44, + 14, 49, 44, 44, 18, 44, 2, 44, + 3, 3, 44, 5, 44, 6, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 14, 49, 44, 44, + 18, 44, 22, 23, 24, 24, 21, 25, 21, 26, 21, 21, 21, 21, 21, 21, - 21, 27, 21, 21, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 21, 1, 1, - 2, 3, 3, 3, 43, 5, 43, 6, - 1, 43, 43, 43, 43, 1, 43, 8, - 43, 43, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 43, 1, 43, 2, - 43, 3, 3, 43, 5, 43, 6, 43, - 43, 43, 43, 43, 43, 43, 8, 43, - 43, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 43, 2, 43, 3, 3, 43, - 5, 43, 6, 43, 43, 43, 43, 43, - 43, 43, 17, 43, 43, 43, 43, 43, - 43, 14, 15, 16, 17, 18, 43, 2, - 43, 3, 3, 43, 5, 43, 6, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 14, 15, 16, - 17, 18, 43, 2, 43, 3, 3, 43, - 5, 43, 6, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 14, 15, 16, 43, 18, 43, 2, - 43, 3, 3, 43, 5, 43, 6, 43, - 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 14, 43, 16, - 43, 18, 43, 2, 43, 3, 3, 43, - 5, 43, 6, 43, 43, 43, 43, 43, - 43, 43, 17, 43, 43, 10, 43, 12, - 43, 14, 15, 16, 17, 18, 43, 2, - 43, 3, 3, 43, 5, 43, 6, 43, - 43, 43, 43, 43, 43, 43, 17, 43, - 43, 10, 43, 43, 43, 14, 15, 16, - 17, 18, 43, 2, 43, 3, 3, 43, - 5, 43, 6, 43, 43, 43, 43, 43, - 43, 43, 17, 43, 43, 10, 11, 12, - 43, 14, 15, 16, 17, 18, 43, 2, - 3, 3, 3, 43, 5, 43, 6, 43, - 43, 43, 43, 43, 43, 43, 8, 43, - 43, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 43, 1, 1, 51, 51, 51, - 51, 51, 51, 51, 51, 1, 51, 51, - 51, 51, 1, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 1, 51, 52, 51, 0 + 21, 50, 21, 21, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 21, 22, + 51, 24, 24, 21, 25, 21, 26, 21, + 21, 21, 21, 21, 21, 21, 27, 21, + 21, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 21, 1, 1, 2, 3, 3, + 3, 44, 5, 44, 6, 1, 44, 44, + 44, 44, 1, 44, 8, 44, 44, 10, + 11, 12, 13, 14, 15, 16, 17, 18, + 19, 44, 1, 44, 2, 44, 3, 3, + 44, 5, 44, 6, 44, 44, 44, 44, + 44, 44, 44, 8, 44, 44, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 44, + 2, 44, 3, 3, 44, 5, 44, 6, + 44, 44, 44, 44, 44, 44, 44, 52, + 44, 44, 44, 44, 44, 44, 14, 15, + 16, 17, 18, 44, 2, 44, 3, 3, + 44, 5, 44, 6, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 14, 15, 16, 17, 18, 44, + 2, 44, 3, 3, 44, 5, 44, 6, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 14, 15, + 16, 44, 18, 44, 2, 44, 3, 3, + 44, 5, 44, 6, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 14, 44, 16, 44, 18, 44, + 2, 44, 3, 3, 44, 5, 44, 6, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 14, 15, + 16, 17, 18, 52, 44, 2, 44, 3, + 3, 44, 5, 44, 6, 44, 44, 44, + 44, 44, 44, 44, 52, 44, 44, 10, + 44, 12, 44, 14, 15, 16, 17, 18, + 44, 2, 44, 3, 3, 44, 5, 44, + 6, 44, 44, 44, 44, 44, 44, 44, + 52, 44, 44, 10, 44, 44, 44, 14, + 15, 16, 17, 18, 44, 2, 44, 3, + 3, 44, 5, 44, 6, 44, 44, 44, + 44, 44, 44, 44, 52, 44, 44, 10, + 11, 12, 44, 14, 15, 16, 17, 18, + 44, 2, 3, 3, 3, 44, 5, 44, + 6, 44, 44, 44, 44, 44, 44, 44, + 8, 44, 44, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 44, 1, 1, 53, + 53, 53, 53, 53, 53, 53, 53, 1, + 53, 53, 53, 53, 1, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 1, 53, 54, 53, + 0 }; static const char _myanmar_syllable_machine_trans_targs[] = { - 0, 1, 22, 0, 0, 23, 29, 32, - 35, 44, 36, 40, 41, 42, 25, 38, - 39, 37, 28, 43, 45, 0, 2, 12, - 0, 3, 9, 13, 14, 18, 19, 20, - 5, 16, 17, 15, 8, 21, 4, 6, - 7, 10, 11, 0, 24, 26, 27, 30, - 31, 33, 34, 0, 0 + 0, 1, 23, 0, 0, 24, 30, 33, + 36, 46, 37, 42, 43, 44, 26, 39, + 40, 41, 29, 45, 47, 0, 2, 12, + 0, 3, 9, 13, 14, 19, 20, 21, + 5, 16, 17, 18, 8, 22, 4, 6, + 7, 10, 11, 15, 0, 25, 27, 28, + 31, 32, 34, 35, 38, 0, 0 }; static const char _myanmar_syllable_machine_trans_actions[] = { @@ -227,8 +236,8 @@ 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 0, 0, 0, 0, - 0, 0, 0, 9, 10 + 0, 0, 0, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 10 }; static const char _myanmar_syllable_machine_to_state_actions[] = { @@ -237,7 +246,7 @@ 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, 0, 0, 0, 0 }; static const char _myanmar_syllable_machine_from_state_actions[] = { @@ -246,16 +255,16 @@ 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, 0, 0, 0, 0 }; static const short _myanmar_syllable_machine_eof_trans[] = { 0, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, - 22, 22, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 52, 52 + 22, 22, 22, 22, 22, 22, 22, 45, + 45, 45, 45, 45, 45, 45, 45, 45, + 45, 22, 22, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 54, 54 }; static const int myanmar_syllable_machine_start = 0; @@ -289,7 +298,7 @@ int cs; hb_glyph_info_t *info = buffer->info; -#line 293 "hb-ot-shape-complex-myanmar-machine.hh" +#line 302 "hb-ot-shape-complex-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -306,7 +315,7 @@ unsigned int last = 0; unsigned int syllable_serial = 1; -#line 310 "hb-ot-shape-complex-myanmar-machine.hh" +#line 319 "hb-ot-shape-complex-myanmar-machine.hh" { int _slen; int _trans; @@ -320,7 +329,7 @@ #line 1 "NONE" {ts = p;} break; -#line 324 "hb-ot-shape-complex-myanmar-machine.hh" +#line 333 "hb-ot-shape-complex-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -370,7 +379,7 @@ #line 90 "hb-ot-shape-complex-myanmar-machine.rl" {te = p;p--;{ found_syllable (non_myanmar_cluster); }} break; -#line 374 "hb-ot-shape-complex-myanmar-machine.hh" +#line 383 "hb-ot-shape-complex-myanmar-machine.hh" } _again: @@ -379,7 +388,7 @@ #line 1 "NONE" {ts = 0;} break; -#line 383 "hb-ot-shape-complex-myanmar-machine.hh" +#line 392 "hb-ot-shape-complex-myanmar-machine.hh" } if ( ++p != pe )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar-private.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,171 @@ +/* + * Copyright © 2018 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_MYANMAR_PRIVATE_HH +#define HB_OT_SHAPE_COMPLEX_MYANMAR_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-ot-shape-complex-indic-private.hh" + + +/* buffer var allocations */ +#define myanmar_category() indic_category() /* myanmar_category_t */ +#define myanmar_position() indic_position() /* myanmar_position_t */ + + +/* Note: This enum is duplicated in the -machine.rl source file. + * Not sure how to avoid duplication. */ +enum myanmar_category_t { + OT_As = 18, /* Asat */ + OT_D0 = 20, /* Digit zero */ + OT_DB = OT_N, /* Dot below */ + OT_GB = OT_PLACEHOLDER, + OT_MH = 21, /* Various consonant medial types */ + OT_MR = 22, /* Various consonant medial types */ + OT_MW = 23, /* Various consonant medial types */ + OT_MY = 24, /* Various consonant medial types */ + OT_PT = 25, /* Pwo and other tones */ + OT_VAbv = 26, + OT_VBlw = 27, + OT_VPre = 28, + OT_VPst = 29, + OT_VS = 30, /* Variation selectors */ + OT_P = 31, /* Punctuation */ + OT_D = 32, /* Digits except zero */ +}; + + +static inline void +set_myanmar_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_position_t pos = (indic_position_t) (type >> 8); + + /* Myanmar + * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze + */ + if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu))) + cat = (indic_category_t) OT_VS; + + switch (u) + { + case 0x104Eu: + cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */ + break; + + case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u: + case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u: + case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu: + case 0x25FEu: + cat = (indic_category_t) OT_GB; + break; + + case 0x1004u: case 0x101Bu: case 0x105Au: + cat = (indic_category_t) OT_Ra; + break; + + case 0x1032u: case 0x1036u: + 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; + + case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u: + case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u: + case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u: + case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u: + case 0x1097u: case 0x1098u: case 0x1099u: + cat = (indic_category_t) OT_D; + break; + + case 0x1040u: + cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ + break; + + case 0x103Eu: case 0x1060u: + cat = (indic_category_t) OT_MH; + break; + + case 0x103Cu: + cat = (indic_category_t) OT_MR; + break; + + case 0x103Du: case 0x1082u: + cat = (indic_category_t) OT_MW; + break; + + case 0x103Bu: case 0x105Eu: case 0x105Fu: + cat = (indic_category_t) OT_MY; + break; + + case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au: + case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu: + cat = (indic_category_t) OT_PT; + break; + + case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u: + case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du: + case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu: + cat = (indic_category_t) OT_SM; + break; + + 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) + { + switch ((int) pos) + { + case POS_PRE_C: cat = (indic_category_t) OT_VPre; + pos = POS_PRE_M; break; + case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; + case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; + case POS_POST_C: cat = (indic_category_t) OT_VPst; break; + } + } + + info.myanmar_category() = (myanmar_category_t) cat; + info.myanmar_position() = pos; +} + + +#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_PRIVATE_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-myanmar.cc Wed May 30 12:20:00 2018 -0700 @@ -24,11 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#include "hb-ot-shape-complex-indic-private.hh" - -/* buffer var allocations */ -#define myanmar_category() complex_var_u8_0() /* myanmar_category_t */ -#define myanmar_position() complex_var_u8_1() /* myanmar_position_t */ +#include "hb-ot-shape-complex-myanmar-private.hh" /* @@ -127,153 +123,6 @@ #include "hb-ot-shape-complex-myanmar-machine.hh" -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum myanmar_category_t { - OT_As = 18, /* Asat */ - OT_D0 = 20, /* Digit zero */ - OT_DB = OT_N, /* Dot below */ - OT_GB = OT_PLACEHOLDER, - OT_MH = 21, /* Various consonant medial types */ - OT_MR = 22, /* Various consonant medial types */ - OT_MW = 23, /* Various consonant medial types */ - OT_MY = 24, /* Various consonant medial types */ - OT_PT = 25, /* Pwo and other tones */ - OT_VAbv = 26, - OT_VBlw = 27, - OT_VPre = 28, - OT_VPst = 29, - OT_VS = 30, /* Variation selectors */ - OT_P = 31, /* Punctuation */ - OT_D = 32, /* Digits except zero */ -}; - - -static inline bool -is_one_of (const hb_glyph_info_t &info, unsigned int flags) -{ - /* If it ligated, all bets are off. */ - if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG_UNSAFE (info.myanmar_category()) & flags); -} - -static inline bool -is_consonant (const hb_glyph_info_t &info) -{ - return is_one_of (info, CONSONANT_FLAGS); -} - - -static inline void -set_myanmar_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); - indic_position_t pos = (indic_position_t) (type >> 8); - - /* Myanmar - * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze - */ - if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu))) - cat = (indic_category_t) OT_VS; - - switch (u) - { - case 0x104Eu: - cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */ - break; - - case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u: - case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u: - case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu: - case 0x25FEu: - cat = (indic_category_t) OT_GB; - break; - - case 0x1004u: case 0x101Bu: case 0x105Au: - cat = (indic_category_t) OT_Ra; - break; - - case 0x1032u: case 0x1036u: - 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; - - case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u: - case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u: - case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u: - case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u: - case 0x1097u: case 0x1098u: case 0x1099u: - cat = (indic_category_t) OT_D; - break; - - case 0x1040u: - cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ - break; - - case 0x103Eu: case 0x1060u: - cat = (indic_category_t) OT_MH; - break; - - case 0x103Cu: - cat = (indic_category_t) OT_MR; - break; - - case 0x103Du: case 0x1082u: - cat = (indic_category_t) OT_MW; - break; - - case 0x103Bu: case 0x105Eu: case 0x105Fu: - cat = (indic_category_t) OT_MY; - break; - - case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au: - case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu: - cat = (indic_category_t) OT_PT; - break; - - case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u: - case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du: - case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu: - cat = (indic_category_t) OT_SM; - break; - - 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) - { - switch ((int) pos) - { - case POS_PRE_C: cat = (indic_category_t) OT_VPre; - pos = POS_PRE_M; break; - case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; - case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; - case POS_POST_C: cat = (indic_category_t) OT_VPst; break; - } - } - - info.myanmar_category() = (myanmar_category_t) cat; - info.myanmar_position() = pos; -} - - - static void setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, @@ -374,6 +223,11 @@ { continue; } + if (info[i].myanmar_category() == OT_VS) + { + info[i].myanmar_position() = info[i - 1].myanmar_position(); + continue; + } if (pos == POS_AFTER_MAIN && info[i].myanmar_category() == OT_VBlw) {
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-private.hh Wed May 30 12:20:00 2018 -0700 @@ -54,9 +54,10 @@ HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \ HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \ HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \ + HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ + HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \ + HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \ - HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ - HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \ HB_COMPLEX_SHAPER_IMPLEMENT (use) \ @@ -285,7 +286,7 @@ planner->map.language_index[0], HB_TAG ('p','r','e','f'), nullptr)) - return &_hb_ot_complex_shaper_indic; + return &_hb_ot_complex_shaper_khmer; else return &_hb_ot_complex_shaper_default;
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-machine.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-machine.hh Wed May 30 12:20:00 2018 -0700 @@ -36,271 +36,286 @@ #line 38 "hb-ot-shape-complex-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 1u, 1u, 0u, 43u, 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, + 12u, 12u, 1u, 15u, 1u, 1u, 12u, 12u, 0u, 43u, 21u, 21u, 8u, 39u, 8u, 39u, + 1u, 15u, 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, - 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, 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 1u, 39u, 8u, 39u, - 21u, 42u, 41u, 42u, 42u, 42u, 1u, 5u, 0 + 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, 8u, 39u, 8u, 39u, + 8u, 39u, 1u, 15u, 12u, 12u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u, 42u, 42u, + 1u, 5u, 0 }; static const char _use_syllable_machine_key_spans[] = { - 1, 44, 1, 32, 32, 1, 32, 32, - 32, 19, 19, 19, 32, 32, 32, 32, + 1, 15, 1, 1, 44, 1, 32, 32, + 15, 1, 32, 32, 32, 19, 19, 19, 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, 32, 32, 32, 1, 39, 32, - 22, 2, 1, 5 + 32, 32, 32, 32, 9, 1, 1, 32, + 32, 32, 32, 19, 19, 19, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 15, 1, 39, 32, 22, 2, 1, + 5 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 2, 47, 49, 82, 115, 117, 150, - 183, 216, 236, 256, 276, 309, 342, 375, - 408, 441, 474, 507, 540, 573, 606, 639, - 672, 682, 684, 686, 719, 752, 785, 818, - 838, 858, 878, 911, 944, 977, 1010, 1043, - 1076, 1109, 1142, 1175, 1208, 1241, 1243, 1283, - 1316, 1339, 1342, 1344 + 0, 2, 18, 20, 22, 67, 69, 102, + 135, 151, 153, 186, 219, 252, 272, 292, + 312, 345, 378, 411, 444, 477, 510, 543, + 576, 609, 642, 675, 708, 718, 720, 722, + 755, 788, 821, 854, 874, 894, 914, 947, + 980, 1013, 1046, 1079, 1112, 1145, 1178, 1211, + 1244, 1277, 1293, 1295, 1335, 1368, 1391, 1394, + 1396 }; static const char _use_syllable_machine_indicies[] = { - 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, 4, 4, 26, 4, 28, - 27, 30, 29, 29, 31, 32, 29, 29, - 29, 29, 29, 29, 29, 29, 33, 34, - 35, 36, 37, 38, 39, 40, 34, 41, - 33, 42, 43, 44, 45, 29, 46, 47, - 48, 29, 30, 29, 29, 31, 32, 29, - 29, 29, 29, 29, 29, 29, 29, 49, - 34, 35, 36, 37, 38, 39, 40, 34, - 41, 42, 42, 43, 44, 45, 29, 46, - 47, 48, 29, 31, 50, 30, 29, 29, - 31, 32, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 34, 35, 36, 37, 38, - 39, 40, 34, 41, 42, 42, 43, 44, - 45, 29, 46, 47, 48, 29, 30, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 34, 35, 36, 37, - 38, 29, 29, 29, 29, 29, 29, 43, - 44, 45, 29, 46, 47, 48, 29, 30, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 35, 36, - 37, 38, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 46, 47, 48, 29, - 30, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 36, 37, 38, 29, 30, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 37, 38, 29, - 30, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 38, 29, 30, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 36, 37, 38, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 46, 47, 48, 29, 30, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 36, 37, 38, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 47, 48, 29, 30, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 36, 37, - 38, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 48, 29, 30, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 35, 36, - 37, 38, 29, 29, 29, 29, 29, 29, - 43, 44, 45, 29, 46, 47, 48, 29, - 30, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 35, - 36, 37, 38, 29, 29, 29, 29, 29, - 29, 29, 44, 45, 29, 46, 47, 48, - 29, 30, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 35, 36, 37, 38, 29, 29, 29, 29, - 29, 29, 29, 29, 45, 29, 46, 47, - 48, 29, 30, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 34, 35, 36, 37, 38, 29, 40, 34, - 29, 29, 29, 43, 44, 45, 29, 46, - 47, 48, 29, 30, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 34, 35, 36, 37, 38, 29, 51, - 34, 29, 29, 29, 43, 44, 45, 29, - 46, 47, 48, 29, 30, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 34, 35, 36, 37, 38, 29, - 29, 34, 29, 29, 29, 43, 44, 45, - 29, 46, 47, 48, 29, 30, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 34, 35, 36, 37, 38, - 39, 40, 34, 29, 29, 29, 43, 44, - 45, 29, 46, 47, 48, 29, 30, 29, - 29, 31, 32, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 34, 35, 36, 37, - 38, 39, 40, 34, 41, 29, 42, 43, - 44, 45, 29, 46, 47, 48, 29, 30, - 29, 29, 31, 32, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 34, 35, 36, - 37, 38, 39, 40, 34, 41, 33, 42, - 43, 44, 45, 29, 46, 47, 48, 29, - 53, 52, 52, 52, 52, 52, 52, 52, - 54, 52, 5, 55, 53, 52, 6, 56, - 56, 1, 57, 56, 56, 56, 56, 56, - 56, 56, 56, 58, 10, 11, 12, 13, - 14, 15, 16, 10, 17, 19, 19, 20, - 21, 22, 56, 23, 24, 25, 56, 6, - 56, 56, 1, 57, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 10, 11, 12, - 13, 14, 15, 16, 10, 17, 19, 19, - 20, 21, 22, 56, 23, 24, 25, 56, - 6, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 10, 11, - 12, 13, 14, 56, 56, 56, 56, 56, - 56, 20, 21, 22, 56, 23, 24, 25, - 56, 6, 56, 56, 56, 56, 56, 56, + 1, 0, 3, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 4, 2, 3, 2, 6, 5, 7, 8, + 9, 7, 10, 8, 9, 9, 11, 9, + 9, 3, 12, 9, 9, 13, 7, 7, + 14, 15, 9, 9, 16, 17, 18, 19, + 20, 21, 22, 16, 23, 24, 25, 26, + 27, 28, 9, 29, 30, 31, 9, 9, + 9, 32, 9, 34, 33, 36, 35, 35, + 37, 1, 35, 35, 38, 35, 35, 35, + 35, 35, 39, 40, 41, 42, 43, 44, + 45, 46, 40, 47, 39, 48, 49, 50, + 51, 35, 52, 53, 54, 35, 36, 35, + 35, 37, 1, 35, 35, 38, 35, 35, + 35, 35, 35, 55, 40, 41, 42, 43, + 44, 45, 46, 40, 47, 48, 48, 49, + 50, 51, 35, 52, 53, 54, 35, 37, 56, 56, 56, 56, 56, 56, 56, 56, - 11, 12, 13, 14, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 23, 24, - 25, 56, 6, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 12, 13, 14, 56, 6, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 13, - 14, 56, 6, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 14, 56, 6, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 12, 13, - 14, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 23, 24, 25, 56, 6, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 12, - 13, 14, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 24, 25, 56, - 6, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 12, 13, 14, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 25, - 56, 6, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 11, 12, 13, 14, 56, 56, 56, 56, - 56, 56, 20, 21, 22, 56, 23, 24, - 25, 56, 6, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 11, 12, 13, 14, 56, 56, 56, - 56, 56, 56, 56, 21, 22, 56, 23, - 24, 25, 56, 6, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 11, 12, 13, 14, 56, 56, - 56, 56, 56, 56, 56, 56, 22, 56, - 23, 24, 25, 56, 6, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 10, 11, 12, 13, 14, 56, - 16, 10, 56, 56, 56, 20, 21, 22, - 56, 23, 24, 25, 56, 6, 56, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 10, 11, 12, 13, 14, - 56, 59, 10, 56, 56, 56, 20, 21, - 22, 56, 23, 24, 25, 56, 6, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 10, 11, 12, 13, - 14, 56, 56, 10, 56, 56, 56, 20, - 21, 22, 56, 23, 24, 25, 56, 6, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 10, 11, 12, - 13, 14, 15, 16, 10, 56, 56, 56, - 20, 21, 22, 56, 23, 24, 25, 56, - 6, 56, 56, 1, 57, 56, 56, 56, - 56, 56, 56, 56, 56, 56, 10, 11, - 12, 13, 14, 15, 16, 10, 17, 56, - 19, 20, 21, 22, 56, 23, 24, 25, - 56, 1, 60, 3, 56, 56, 56, 3, - 56, 56, 6, 56, 56, 1, 57, 56, - 56, 56, 56, 56, 56, 56, 56, 56, - 10, 11, 12, 13, 14, 15, 16, 10, - 17, 18, 19, 20, 21, 22, 56, 23, - 24, 25, 56, 6, 56, 56, 1, 57, - 56, 56, 56, 56, 56, 56, 56, 56, - 56, 10, 11, 12, 13, 14, 15, 16, - 10, 17, 18, 19, 20, 21, 22, 56, - 23, 24, 25, 56, 62, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 61, - 62, 63, 61, 62, 63, 61, 63, 61, - 3, 60, 60, 60, 3, 60, 0 + 56, 56, 56, 56, 56, 57, 56, 37, + 56, 36, 35, 35, 37, 1, 35, 35, + 38, 35, 35, 35, 35, 35, 35, 40, + 41, 42, 43, 44, 45, 46, 40, 47, + 48, 48, 49, 50, 51, 35, 52, 53, + 54, 35, 36, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 40, 41, 42, 43, 44, 35, 35, 35, + 35, 35, 35, 49, 50, 51, 35, 52, + 53, 54, 35, 36, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 41, 42, 43, 44, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 52, 53, 54, 35, 36, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 42, 43, 44, 35, + 36, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 43, 44, 35, 36, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 44, 35, + 36, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 42, 43, 44, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 52, 53, 54, + 35, 36, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 42, 43, 44, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 53, + 54, 35, 36, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 42, 43, 44, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 54, 35, 36, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 41, 42, 43, 44, 35, 35, + 35, 35, 35, 35, 49, 50, 51, 35, + 52, 53, 54, 35, 36, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 41, 42, 43, 44, 35, + 35, 35, 35, 35, 35, 35, 50, 51, + 35, 52, 53, 54, 35, 36, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 41, 42, 43, 44, + 35, 35, 35, 35, 35, 35, 35, 35, + 51, 35, 52, 53, 54, 35, 36, 35, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 40, 41, 42, 43, + 44, 35, 46, 40, 35, 35, 35, 49, + 50, 51, 35, 52, 53, 54, 35, 36, + 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 40, 41, 42, + 43, 44, 35, 58, 40, 35, 35, 35, + 49, 50, 51, 35, 52, 53, 54, 35, + 36, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 40, 41, + 42, 43, 44, 35, 35, 40, 35, 35, + 35, 49, 50, 51, 35, 52, 53, 54, + 35, 36, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 40, + 41, 42, 43, 44, 45, 46, 40, 35, + 35, 35, 49, 50, 51, 35, 52, 53, + 54, 35, 36, 35, 35, 37, 1, 35, + 35, 38, 35, 35, 35, 35, 35, 35, + 40, 41, 42, 43, 44, 45, 46, 40, + 47, 35, 48, 49, 50, 51, 35, 52, + 53, 54, 35, 36, 35, 35, 37, 1, + 35, 35, 38, 35, 35, 35, 35, 35, + 35, 40, 41, 42, 43, 44, 45, 46, + 40, 47, 39, 48, 49, 50, 51, 35, + 52, 53, 54, 35, 60, 59, 59, 59, + 59, 59, 59, 59, 61, 59, 10, 62, + 60, 59, 11, 63, 63, 3, 6, 63, + 63, 64, 63, 63, 63, 63, 63, 65, + 16, 17, 18, 19, 20, 21, 22, 16, + 23, 25, 25, 26, 27, 28, 63, 29, + 30, 31, 63, 11, 63, 63, 3, 6, + 63, 63, 64, 63, 63, 63, 63, 63, + 63, 16, 17, 18, 19, 20, 21, 22, + 16, 23, 25, 25, 26, 27, 28, 63, + 29, 30, 31, 63, 11, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 16, 17, 18, 19, 20, 63, + 63, 63, 63, 63, 63, 26, 27, 28, + 63, 29, 30, 31, 63, 11, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 17, 18, 19, 20, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 29, 30, 31, 63, 11, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 18, 19, + 20, 63, 11, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 19, 20, 63, 11, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 20, 63, 11, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 18, 19, 20, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 29, + 30, 31, 63, 11, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 18, 19, 20, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 30, 31, 63, 11, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 18, 19, 20, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 31, 63, 11, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 17, 18, 19, 20, + 63, 63, 63, 63, 63, 63, 26, 27, + 28, 63, 29, 30, 31, 63, 11, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 17, 18, 19, + 20, 63, 63, 63, 63, 63, 63, 63, + 27, 28, 63, 29, 30, 31, 63, 11, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 17, 18, + 19, 20, 63, 63, 63, 63, 63, 63, + 63, 63, 28, 63, 29, 30, 31, 63, + 11, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 16, 17, + 18, 19, 20, 63, 22, 16, 63, 63, + 63, 26, 27, 28, 63, 29, 30, 31, + 63, 11, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 16, + 17, 18, 19, 20, 63, 66, 16, 63, + 63, 63, 26, 27, 28, 63, 29, 30, + 31, 63, 11, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 16, 17, 18, 19, 20, 63, 63, 16, + 63, 63, 63, 26, 27, 28, 63, 29, + 30, 31, 63, 11, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 16, 17, 18, 19, 20, 21, 22, + 16, 63, 63, 63, 26, 27, 28, 63, + 29, 30, 31, 63, 11, 63, 63, 3, + 6, 63, 63, 64, 63, 63, 63, 63, + 63, 63, 16, 17, 18, 19, 20, 21, + 22, 16, 23, 63, 25, 26, 27, 28, + 63, 29, 30, 31, 63, 3, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 4, 67, 6, 67, 8, + 63, 63, 63, 8, 63, 63, 11, 63, + 63, 3, 6, 63, 63, 64, 63, 63, + 63, 63, 63, 63, 16, 17, 18, 19, + 20, 21, 22, 16, 23, 24, 25, 26, + 27, 28, 63, 29, 30, 31, 63, 11, + 63, 63, 3, 6, 63, 63, 64, 63, + 63, 63, 63, 63, 63, 16, 17, 18, + 19, 20, 21, 22, 16, 23, 24, 25, + 26, 27, 28, 63, 29, 30, 31, 63, + 69, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 69, 70, 68, 69, + 70, 68, 70, 68, 8, 67, 67, 67, + 8, 67, 0 }; static const char _use_syllable_machine_trans_targs[] = { - 1, 27, 2, 3, 1, 24, 1, 45, - 46, 48, 29, 30, 31, 32, 33, 40, - 41, 43, 47, 44, 37, 38, 39, 34, - 35, 36, 51, 1, 1, 1, 1, 4, - 5, 23, 7, 8, 9, 10, 11, 18, - 19, 21, 22, 15, 16, 17, 12, 13, - 14, 6, 1, 20, 1, 25, 26, 1, - 1, 0, 28, 42, 1, 1, 49, 50 + 4, 8, 4, 31, 2, 4, 1, 5, + 6, 4, 28, 4, 49, 50, 51, 53, + 33, 34, 35, 36, 37, 44, 45, 47, + 52, 48, 41, 42, 43, 38, 39, 40, + 56, 4, 4, 4, 4, 7, 0, 27, + 11, 12, 13, 14, 15, 22, 23, 25, + 26, 19, 20, 21, 16, 17, 18, 10, + 4, 9, 24, 4, 29, 30, 4, 4, + 3, 32, 46, 4, 4, 54, 55 }; static const char _use_syllable_machine_trans_actions[] = { - 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, 0, 7, 8, 9, 10, 0, + 1, 0, 2, 3, 0, 4, 0, 0, + 7, 8, 0, 9, 10, 10, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 3, 0, 0, 0, 0, 0, 0, + 0, 11, 12, 13, 14, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 11, 0, 12, 0, 0, 13, - 14, 0, 2, 0, 15, 16, 0, 0 + 7, 0, 0, 0, 0, 0, 0, 7, + 15, 0, 0, 16, 0, 0, 17, 18, + 0, 3, 0, 19, 20, 0, 0 }; static const char _use_syllable_machine_to_state_actions[] = { - 0, 3, 0, 0, 0, 0, 0, 0, + 0, 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, 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, + 0 }; static const char _use_syllable_machine_from_state_actions[] = { - 0, 4, 0, 0, 0, 0, 0, 0, + 0, 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, 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 + 0 }; static const short _use_syllable_machine_eof_trans[] = { - 1, 0, 28, 30, 30, 51, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, - 53, 56, 53, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 57, 57, 61, 57, 57, - 62, 62, 62, 61 + 1, 3, 3, 6, 0, 34, 36, 36, + 57, 57, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 60, 63, 60, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 68, 68, 64, 64, 69, 69, 69, + 68 }; -static const int use_syllable_machine_start = 1; -static const int use_syllable_machine_first_final = 1; +static const int use_syllable_machine_start = 4; +static const int use_syllable_machine_first_final = 4; static const int use_syllable_machine_error = -1; -static const int use_syllable_machine_en_main = 1; +static const int use_syllable_machine_en_main = 4; #line 38 "hb-ot-shape-complex-use-machine.rl" -#line 140 "hb-ot-shape-complex-use-machine.rl" +#line 141 "hb-ot-shape-complex-use-machine.rl" #define found_syllable(syllable_type) \ @@ -320,7 +335,7 @@ int cs; hb_glyph_info_t *info = buffer->info; -#line 324 "hb-ot-shape-complex-use-machine.hh" +#line 339 "hb-ot-shape-complex-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -328,7 +343,7 @@ act = 0; } -#line 161 "hb-ot-shape-complex-use-machine.rl" +#line 162 "hb-ot-shape-complex-use-machine.rl" p = 0; @@ -337,7 +352,7 @@ unsigned int last = 0; unsigned int syllable_serial = 1; -#line 341 "hb-ot-shape-complex-use-machine.hh" +#line 356 "hb-ot-shape-complex-use-machine.hh" { int _slen; int _trans; @@ -347,11 +362,11 @@ goto _test_eof; _resume: switch ( _use_syllable_machine_from_state_actions[cs] ) { - case 4: + case 6: #line 1 "NONE" {ts = p;} break; -#line 355 "hb-ot-shape-complex-use-machine.hh" +#line 370 "hb-ot-shape-complex-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -369,72 +384,100 @@ goto _again; switch ( _use_syllable_machine_trans_actions[_trans] ) { - case 2: + case 7: #line 1 "NONE" {te = p+1;} break; - case 8: -#line 129 "hb-ot-shape-complex-use-machine.rl" + case 12: +#line 130 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (independent_cluster); }} break; - case 10: -#line 131 "hb-ot-shape-complex-use-machine.rl" + case 14: +#line 132 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (standard_cluster); }} break; - case 6: -#line 135 "hb-ot-shape-complex-use-machine.rl" + case 9: +#line 136 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (broken_cluster); }} break; - case 5: -#line 136 "hb-ot-shape-complex-use-machine.rl" + case 8: +#line 137 "hb-ot-shape-complex-use-machine.rl" {te = p+1;{ found_syllable (non_cluster); }} break; - case 7: -#line 129 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (independent_cluster); }} - break; case 11: #line 130 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (virama_terminated_cluster); }} + {te = p;p--;{ found_syllable (independent_cluster); }} break; - case 9: + case 15: #line 131 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (standard_cluster); }} + {te = p;p--;{ found_syllable (virama_terminated_cluster); }} break; case 13: #line 132 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} + {te = p;p--;{ found_syllable (standard_cluster); }} break; - case 12: + case 17: #line 133 "hb-ot-shape-complex-use-machine.rl" - {te = p;p--;{ found_syllable (numeral_cluster); }} + {te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }} break; case 16: #line 134 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (numeral_cluster); }} + break; + case 20: +#line 135 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (symbol_cluster); }} break; - case 14: -#line 135 "hb-ot-shape-complex-use-machine.rl" + case 18: +#line 136 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (broken_cluster); }} break; - case 15: -#line 136 "hb-ot-shape-complex-use-machine.rl" + case 19: +#line 137 "hb-ot-shape-complex-use-machine.rl" {te = p;p--;{ found_syllable (non_cluster); }} break; case 1: -#line 135 "hb-ot-shape-complex-use-machine.rl" +#line 132 "hb-ot-shape-complex-use-machine.rl" + {{p = ((te))-1;}{ found_syllable (standard_cluster); }} + break; + case 4: +#line 136 "hb-ot-shape-complex-use-machine.rl" {{p = ((te))-1;}{ found_syllable (broken_cluster); }} break; -#line 429 "hb-ot-shape-complex-use-machine.hh" + case 2: +#line 1 "NONE" + { switch( act ) { + case 7: + {{p = ((te))-1;} found_syllable (broken_cluster); } + break; + case 8: + {{p = ((te))-1;} found_syllable (non_cluster); } + break; + } + } + break; + case 3: +#line 1 "NONE" + {te = p+1;} +#line 136 "hb-ot-shape-complex-use-machine.rl" + {act = 7;} + break; + case 10: +#line 1 "NONE" + {te = p+1;} +#line 137 "hb-ot-shape-complex-use-machine.rl" + {act = 8;} + break; +#line 472 "hb-ot-shape-complex-use-machine.hh" } _again: switch ( _use_syllable_machine_to_state_actions[cs] ) { - case 3: + case 5: #line 1 "NONE" {ts = 0;} break; -#line 438 "hb-ot-shape-complex-use-machine.hh" +#line 481 "hb-ot-shape-complex-use-machine.hh" } if ( ++p != pe ) @@ -450,7 +493,7 @@ } -#line 170 "hb-ot-shape-complex-use-machine.rl" +#line 171 "hb-ot-shape-complex-use-machine.rl" }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-private.hh Wed May 30 12:20:00 2018 -0700 @@ -92,6 +92,6 @@ }; HB_INTERNAL USE_TABLE_ELEMENT_TYPE -hb_use_get_categories (hb_codepoint_t u); +hb_use_get_category (hb_codepoint_t u); #endif /* HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-table.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use-table.cc Wed May 30 12:20:00 2018 -0700 @@ -75,7 +75,13 @@ /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 00D0 */ O, O, O, O, O, O, O, GB, -#define use_offset_0x0900u 80 +#define use_offset_0x0348u 80 + + + /* Combining Diacritical Marks */ + O, O, O, O, O, O, O, CGJ, + +#define use_offset_0x0900u 88 /* Devanagari */ @@ -188,7 +194,7 @@ /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* 0DF0 */ O, O, VPst, VPst, O, O, O, O, -#define use_offset_0x1000u 1352 +#define use_offset_0x1000u 1360 /* Myanmar */ @@ -204,7 +210,7 @@ /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, -#define use_offset_0x1700u 1512 +#define use_offset_0x1700u 1520 /* Tagalog */ @@ -237,7 +243,7 @@ /* 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, -#define use_offset_0x1900u 1752 +#define use_offset_0x1900u 1760 /* Limbu */ @@ -281,7 +287,7 @@ /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -#define use_offset_0x1b00u 2168 +#define use_offset_0x1b00u 2176 /* Balinese */ @@ -307,7 +313,7 @@ /* 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, 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, + /* 1BF0 */ FAbv, FAbv, CMBlw, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* Lepcha */ @@ -317,7 +323,7 @@ /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FM, CMBlw, O, O, O, O, O, O, O, O, /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, -#define use_offset_0x1cd0u 2504 +#define use_offset_0x1cd0u 2512 /* Vedic Extensions */ @@ -326,20 +332,20 @@ /* 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, VMPst, VMAbv, VMAbv, O, O, O, O, O, O, -#define use_offset_0x1df8u 2552 +#define use_offset_0x1df8u 2560 /* Combining Diacritical Marks Supplement */ O, O, O, FM, O, O, O, O, -#define use_offset_0x2008u 2560 +#define use_offset_0x2008u 2568 /* General Punctuation */ O, O, O, O, ZWNJ, ZWJ, O, O, /* 2010 */ GB, GB, GB, GB, GB, O, O, O, -#define use_offset_0x2060u 2576 +#define use_offset_0x2060u 2584 /* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, @@ -348,7 +354,20 @@ /* 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 2616 +#define use_offset_0x20f0u 2624 + + + /* Combining Diacritical Marks for Symbols */ + + /* 20F0 */ VMAbv, O, O, O, O, O, O, O, + +#define use_offset_0x25c8u 2632 + + + /* Geometric Shapes */ + O, O, O, O, GB, O, O, O, + +#define use_offset_0xa800u 2640 /* Syloti Nagri */ @@ -370,7 +389,7 @@ /* 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, + /* A8B0 */ B, B, B, B, MPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, /* 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, @@ -435,7 +454,7 @@ /* 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 3376 +#define use_offset_0xabc0u 3400 /* Meetei Mayek */ @@ -445,14 +464,14 @@ /* 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 3440 +#define use_offset_0xfe00u 3464 /* Variation Selectors */ /* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, -#define use_offset_0x10a00u 3456 +#define use_offset_0x10a00u 3480 /* Kharoshthi */ @@ -463,7 +482,7 @@ /* 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 3528 +#define use_offset_0x11000u 3552 /* Brahmi */ @@ -475,7 +494,7 @@ /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O, /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N, /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, - /* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, HN, /* Kaithi */ @@ -484,7 +503,7 @@ /* 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 3720 +#define use_offset_0x11100u 3744 /* Chakma */ @@ -522,7 +541,7 @@ /* 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, O, O, O, O, O, O, VMAbv, O, -#define use_offset_0x11280u 4040 +#define use_offset_0x11280u 4064 /* Multani */ @@ -550,7 +569,7 @@ /* 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_0x11400u 4288 +#define use_offset_0x11400u 4312 /* Newa */ @@ -573,7 +592,7 @@ /* 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 4512 +#define use_offset_0x11580u 4536 /* Siddham */ @@ -616,7 +635,7 @@ /* 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, -#define use_offset_0x11a00u 4960 +#define use_offset_0x11a00u 4984 /* Zanabazar Square */ @@ -635,7 +654,7 @@ /* 11A80 */ B, B, B, B, O, O, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, O, O, O, -#define use_offset_0x11c00u 5120 +#define use_offset_0x11c00u 5144 /* Bhaiksuki */ @@ -656,7 +675,7 @@ /* 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, -#define use_offset_0x11d00u 5304 +#define use_offset_0x11d00u 5328 /* Masaram Gondi */ @@ -668,18 +687,18 @@ /* 11D40 */ VMAbv, VMAbv, CMBlw, VAbv, VBlw, H, R, MBlw, O, O, O, O, O, O, O, O, /* 11D50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, -}; /* Table items: 5400; occupancy: 73% */ +}; /* Table items: 5424; occupancy: 73% */ USE_TABLE_ELEMENT_TYPE -hb_use_get_categories (hb_codepoint_t u) +hb_use_get_category (hb_codepoint_t u) { switch (u >> 12) { case 0x0u: if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u]; if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; - if (unlikely (u == 0x034Fu)) return CGJ; break; case 0x1u: @@ -694,7 +713,8 @@ case 0x2u: if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; if (hb_in_range<hb_codepoint_t> (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u]; - if (unlikely (u == 0x25CCu)) return GB; + if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u]; + if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u]; break; case 0xAu: @@ -719,7 +739,6 @@ if (hb_in_range<hb_codepoint_t> (u, 0x11A00u, 0x11A9Fu)) return use_table[u - 0x11A00u + use_offset_0x11a00u]; if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u]; if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11D5Fu)) return use_table[u - 0x11D00u + use_offset_0x11d00u]; - if (unlikely (u == 0x1107Fu)) return HN; break; default:
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use.cc Wed May 30 12:20:00 2018 -0700 @@ -262,7 +262,7 @@ unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - info[i].use_category() = hb_use_get_categories (info[i].codepoint); + info[i].use_category() = hb_use_get_category (info[i].codepoint); } static void @@ -505,7 +505,7 @@ hb_glyph_info_t dottedcircle = {0}; if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint)) return; - dottedcircle.use_category() = hb_use_get_categories (0x25CC); + dottedcircle.use_category() = hb_use_get_category (0x25CC); buffer->clear_output ();
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-fallback.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-fallback.cc Wed May 30 12:20:00 2018 -0700 @@ -200,8 +200,7 @@ unsigned int combining_class) { hb_glyph_extents_t mark_extents; - if (!font->get_glyph_extents (buffer->info[i].codepoint, - &mark_extents)) + if (!font->get_glyph_extents (buffer->info[i].codepoint, &mark_extents)) return; hb_position_t y_gap = font->y_scale / 16; @@ -218,10 +217,10 @@ case HB_UNICODE_COMBINING_CLASS_DOUBLE_BELOW: case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE: if (buffer->props.direction == HB_DIRECTION_LTR) { - pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing; + pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing; break; } else if (buffer->props.direction == HB_DIRECTION_RTL) { - pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing; + pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing; break; } HB_FALLTHROUGH; @@ -322,7 +321,9 @@ base_extents.y_bearing += buffer->pos[base].y_offset; unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[base]); - unsigned int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]); + /* Use integer for num_lig_components such that it doesn't convert to unsigned + * when we divide or multiply by it. */ + int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]); hb_position_t x_offset = 0, y_offset = 0; if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) { @@ -331,7 +332,7 @@ } hb_glyph_extents_t component_extents = base_extents; - unsigned int last_lig_component = (unsigned int) -1; + int last_lig_component = -1; unsigned int last_combining_class = 255; hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */ hb_glyph_info_t *info = buffer->info; @@ -340,7 +341,7 @@ { if (num_lig_components > 1) { unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&info[i]); - unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i]) - 1; + int this_lig_component = _hb_glyph_info_get_lig_comp (&info[i]) - 1; /* Conditions for attaching to the last component. */ if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components) this_lig_component = num_lig_components - 1; @@ -442,10 +443,10 @@ { if (!plan->has_kern) return; - OT::hb_apply_context_t c (1, font, buffer); + OT::hb_ot_apply_context_t c (1, font, buffer); c.set_lookup_mask (plan->kern_mask); c.set_lookup_props (OT::LookupFlag::IgnoreMarks); - OT::hb_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; + OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input; skippy_iter.init (&c); unsigned int count = buffer->len; @@ -473,6 +474,7 @@ pos[idx].x_advance += kern1; pos[skippy_iter.idx].x_advance += kern2; pos[skippy_iter.idx].x_offset += kern2; + buffer->unsafe_to_break (idx, skippy_iter.idx + 1); } if (y_kern) @@ -482,6 +484,7 @@ pos[idx].y_advance += kern1; pos[skippy_iter.idx].y_advance += kern2; pos[skippy_iter.idx].y_offset += kern2; + buffer->unsafe_to_break (idx, skippy_iter.idx + 1); } idx = skippy_iter.idx; @@ -524,7 +527,7 @@ break; case t::SPACE_4_EM_18: - pos[i].x_advance = font->x_scale * 4 / 18; + pos[i].x_advance = (int64_t) font->x_scale * 4 / 18; break; case t::SPACE_FIGURE:
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-normalize.cc Wed May 30 12:20:00 2018 -0700 @@ -345,9 +345,8 @@ if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0) break; - /* We are going to do a O(n^2). Only do this if the sequence is short, - * but not too short ;). */ - if (end - i < 2 || end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) { + /* We are going to do a O(n^2). Only do this if the sequence is short. */ + if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) { i = end; continue; } @@ -373,13 +372,11 @@ buffer->clear_output (); count = buffer->len; unsigned int starter = 0; - bool combine = true; buffer->next_glyph (); while (buffer->idx < count && !buffer->in_error) { hb_codepoint_t composed, glyph; - if (combine && - /* We don't try to compose a non-mark character with it's preceding starter. + if (/* We don't try to compose a non-mark character with it's preceding starter. * This is both an optimization to avoid trying to compose every two neighboring * glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul * fonts are not designed to mix-and-match pre-composed syllables and Jamo. */ @@ -410,22 +407,27 @@ continue; } - else if (/* We sometimes custom-tailor the sorted order of marks. In that case, stop - * trying to combine as soon as combining-class drops. */ - starter < buffer->out_len - 1 && - info_cc (buffer->prev()) > info_cc (buffer->cur())) - combine = false; } /* Blocked, or doesn't compose. */ buffer->next_glyph (); if (info_cc (buffer->prev()) == 0) - { starter = buffer->out_len - 1; - combine = true; - } } buffer->swap_buffers (); + if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ) + { + /* For all CGJ, check if it prevented any reordering at all. + * If it did NOT, then make it skippable. + * https://github.com/harfbuzz/harfbuzz/issues/554 + */ + for (unsigned int i = 1; i + 1 < buffer->len; i++) + if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ && + info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1])) + { + _hb_glyph_info_unhide (&buffer->info[i]); + } + } }
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape.cc Wed May 30 12:20:00 2018 -0700 @@ -40,6 +40,8 @@ #include "hb-unicode-private.hh" #include "hb-set-private.hh" +#include "hb-ot-layout-gsubgpos-private.hh" +//#include "hb-aat-layout-private.hh" static hb_tag_t common_features[] = { HB_TAG('c','c','m','p'), @@ -108,7 +110,7 @@ /* We really want to find a 'vert' feature if there's any in the font, no * matter which script/langsys it is listed (or not) under. * See various bugs referenced from: - * https://github.com/behdad/harfbuzz/issues/63 */ + * https://github.com/harfbuzz/harfbuzz/issues/63 */ map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH); } @@ -450,7 +452,8 @@ hb_buffer_t *buffer = c->buffer; if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) || - (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)) + (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) || + (buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES)) return; unsigned int count = buffer->len; @@ -486,7 +489,8 @@ return; hb_codepoint_t space; - if (c->font->get_nominal_glyph (' ', &space)) + if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) && + c->font->get_nominal_glyph (' ', &space)) { /* Replace default-ignorables with a zero-advance space glyph. */ for (/*continue*/; i < count; i++) @@ -614,7 +618,8 @@ c->plan->substitute (c->font, buffer); - return; + /* XXX Call morx instead. */ + //hb_aat_layout_substitute (c->font, c->buffer); } static inline void @@ -782,6 +787,8 @@ _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer); _hb_buffer_deallocate_gsubgpos_vars (c->buffer); + + //hb_aat_layout_position (c->font, c->buffer); } static inline void @@ -817,11 +824,16 @@ { 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))) + if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_LEN_FACTOR))) { - c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_EXPANSION_FACTOR, + c->buffer->max_len = MAX (c->buffer->len * HB_BUFFER_MAX_LEN_FACTOR, (unsigned) HB_BUFFER_MAX_LEN_MIN); } + if (likely (!_hb_unsigned_int_mul_overflows (c->buffer->len, HB_BUFFER_MAX_OPS_FACTOR))) + { + c->buffer->max_ops = MAX (c->buffer->len * HB_BUFFER_MAX_OPS_FACTOR, + (unsigned) HB_BUFFER_MAX_OPS_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); @@ -861,6 +873,7 @@ c->buffer->props.direction = c->target_direction; c->buffer->max_len = HB_BUFFER_MAX_LEN_DEFAULT; + c->buffer->max_ops = HB_BUFFER_MAX_OPS_DEFAULT; c->buffer->deallocate_var_all (); } @@ -946,7 +959,7 @@ hb_set_t *copy = hb_set_create (); do { copy->set (glyphs); - for (hb_codepoint_t lookup_index = -1; hb_set_next (lookups, &lookup_index);) + for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);) hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs); } while (!copy->is_equal (glyphs)); hb_set_destroy (copy);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-tag.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-tag.cc Wed May 30 12:20:00 2018 -0700 @@ -920,7 +920,7 @@ char tag[4]; int i; s += 6; - for (i = 0; i < 4 && ISALPHA (s[i]); i++) + for (i = 0; i < 4 && ISALNUM (s[i]); i++) tag[i] = TOUPPER (s[i]); if (i) { for (; i < 4; i++)
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-avar-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-avar-table.hh Wed May 30 12:20:00 2018 -0700 @@ -133,8 +133,8 @@ protected: FixedVersion<>version; /* Version of the avar table * initially set to 0x00010000u */ - USHORT reserved; /* This field is permanently reserved. Set to 0. */ - USHORT axisCount; /* The number of variation axes in the font. This + HBUINT16 reserved; /* This field is permanently reserved. Set to 0. */ + HBUINT16 axisCount; /* The number of variation axes in the font. This * must be the same number as axisCount in the * 'fvar' table. */ SegmentMaps axisSegmentMapsZ;
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-fvar-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-fvar-table.hh Wed May 30 12:20:00 2018 -0700 @@ -42,11 +42,11 @@ } protected: - USHORT subfamilyNameID;/* The name ID for entries in the 'name' table + HBUINT16 subfamilyNameID;/* The name ID for entries in the 'name' table * that provide subfamily names for this instance. */ - USHORT reserved; /* Reserved for future use — set to 0. */ + HBUINT16 reserved; /* Reserved for future use — set to 0. */ Fixed coordinates[VAR];/* The coordinates array for this instance. */ - //USHORT postScriptNameIDX;/*Optional. The name ID for entries in the 'name' + //HBUINT16 postScriptNameIDX;/*Optional. The name ID for entries in the 'name' // * table that provide PostScript names for this // * instance. */ @@ -67,8 +67,8 @@ Fixed minValue; /* The minimum coordinate value for the axis. */ Fixed defaultValue; /* The default coordinate value for the axis. */ Fixed maxValue; /* The maximum coordinate value for the axis. */ - USHORT reserved; /* Reserved for future use — set to 0. */ - USHORT axisNameID; /* The name ID for entries in the 'name' table that + HBUINT16 reserved; /* Reserved for future use — set to 0. */ + HBUINT16 axisNameID; /* The name ID for entries in the 'name' table that * provide a display name for this axis. */ public: @@ -186,16 +186,16 @@ protected: FixedVersion<>version; /* Version of the fvar table * initially set to 0x00010000u */ - Offset<> things; /* Offset in bytes from the beginning of the table + Offset16 things; /* Offset in bytes from the beginning of the table * to the start of the AxisRecord array. */ - USHORT reserved; /* This field is permanently reserved. Set to 2. */ - USHORT axisCount; /* The number of variation axes in the font (the + HBUINT16 reserved; /* This field is permanently reserved. Set to 2. */ + HBUINT16 axisCount; /* The number of variation axes in the font (the * number of records in the axes array). */ - USHORT axisSize; /* The size in bytes of each VariationAxisRecord — + HBUINT16 axisSize; /* The size in bytes of each VariationAxisRecord — * set to 20 (0x0014) for this version. */ - USHORT instanceCount; /* The number of named instances defined in the font + HBUINT16 instanceCount; /* The number of named instances defined in the font * (the number of records in the instances array). */ - USHORT instanceSize; /* The size in bytes of each InstanceRecord — set + HBUINT16 instanceSize; /* The size in bytes of each InstanceRecord — set * to either axisCount * sizeof(Fixed) + 4, or to * axisCount * sizeof(Fixed) + 6. */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-hvar-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-hvar-table.hh Wed May 30 12:20:00 2018 -0700 @@ -55,7 +55,7 @@ unsigned int u = 0; { /* Fetch it. */ unsigned int w = get_width (); - const BYTE *p = mapData + w * v; + const HBUINT8 *p = mapData + w * v; for (; w; w--) u = (u << 8) + *p++; } @@ -78,10 +78,10 @@ { return (format & 0xF) + 1; } protected: - USHORT format; /* A packed field that describes the compressed + HBUINT16 format; /* A packed field that describes the compressed * representation of delta-set indices. */ - USHORT mapCount; /* The number of mapping entries. */ - BYTE mapData[VAR]; /* The delta-set index mapping data. */ + HBUINT16 mapCount; /* The number of mapping entries. */ + HBUINT8 mapData[VAR]; /* The delta-set index mapping data. */ public: DEFINE_SIZE_ARRAY (4, mapData);
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-mvar-table.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-var-mvar-table.hh Wed May 30 12:20:00 2018 -0700 @@ -43,7 +43,7 @@ public: Tag valueTag; /* Four-byte tag identifying a font-wide measure. */ - ULONG varIdx; /* Outer/inner index into VariationStore item. */ + HBUINT32 varIdx; /* Outer/inner index into VariationStore item. */ public: DEFINE_SIZE_STATIC (8); @@ -95,13 +95,13 @@ protected: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ - USHORT reserved; /* Not used; set to 0. */ - USHORT valueRecordSize;/* The size in bytes of each value record — + HBUINT16 reserved; /* Not used; set to 0. */ + HBUINT16 valueRecordSize;/* The size in bytes of each value record — * must be greater than zero. */ - USHORT valueRecordCount;/* The number of value records — may be zero. */ + HBUINT16 valueRecordCount;/* The number of value records — may be zero. */ OffsetTo<VariationStore> varStore; /* Offset to item variation store table. */ - BYTE values[VAR]; /* Array of value records. The records must be + HBUINT8 values[VAR]; /* Array of value records. The records must be * in binary order of their valueTag field. */ public:
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-private.hh Wed May 30 12:20:00 2018 -0700 @@ -29,6 +29,8 @@ #ifndef HB_PRIVATE_HH #define HB_PRIVATE_HH +#define _GNU_SOURCE 1 + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -40,6 +42,7 @@ #define HB_OT_H_IN #endif +#include <math.h> #include <stdlib.h> #include <stddef.h> #include <string.h> @@ -48,6 +51,9 @@ #include <stdio.h> #include <stdarg.h> +#if defined(_MSC_VER) || defined(__MINGW32__) +#include <intrin.h> +#endif #define HB_PASTE1(a,b) a##b #define HB_PASTE(a,b) HB_PASTE1(a,b) @@ -86,8 +92,6 @@ #endif // __cplusplus < 201103L -#define _GNU_SOURCE 1 - #if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__) #define likely(expr) (__builtin_expect (!!(expr), 1)) #define unlikely(expr) (__builtin_expect (!!(expr), 0)) @@ -112,15 +116,18 @@ #endif #if __GNUC__ >= 4 #define HB_UNUSED __attribute__((unused)) +#elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */ +#define HB_UNUSED __pragma(warning(suppress: 4100 4101)) #else #define HB_UNUSED #endif #ifndef HB_INTERNAL -# if !defined(__MINGW32__) && !defined(__CYGWIN__) +# if !defined(HB_NO_VISIBILITY) && !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(_MSC_VER) && !defined(__SUNPRO_CC) # define HB_INTERNAL __attribute__((__visibility__("hidden"))) # else # define HB_INTERNAL +# define HB_NO_VISIBILITY 1 # endif #endif @@ -132,6 +139,11 @@ #define HB_FUNC __func__ #endif +#ifdef __SUNPRO_CC +/* https://github.com/harfbuzz/harfbuzz/issues/630 */ +#define __restrict +#endif + /* * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch @@ -151,6 +163,9 @@ #if defined(__clang__) && __cplusplus >= 201103L /* clang's fallthrough annotations are only available starting in C++11. */ # define HB_FALLTHROUGH [[clang::fallthrough]] +#elif __GNUC__ >= 7 + /* GNU fallthrough attribute is available from GCC7 */ +# define HB_FALLTHROUGH __attribute__((fallthrough)) #elif defined(_MSC_VER) /* * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis): @@ -218,6 +233,12 @@ * https://developer.android.com/tools/sdk/ndk/index.html */ # define HB_USE_ATEXIT 1 +# elif defined(__APPLE__) +/* For macOS and related platforms, the atexit man page indicates + * that it will be invoked when the library is unloaded, not only + * at application exit. + */ +# define HB_USE_ATEXIT 1 # endif #endif @@ -295,69 +316,198 @@ /* Misc */ -/* Void! */ -struct _hb_void_t {}; -typedef const _hb_void_t *hb_void_t; +/* + * Void! + */ +typedef const struct _hb_void_t *hb_void_t; #define HB_VOID ((const _hb_void_t *) nullptr) -/* Return the number of 1 bits in mask. */ +/* Return the number of 1 bits in v. */ +template <typename T> static inline HB_CONST_FUNC unsigned int -_hb_popcount32 (uint32_t mask) +_hb_popcount (T v) { -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) - return __builtin_popcount (mask); -#else - /* "HACKMEM 169" */ - uint32_t y; - y = (mask >> 1) &033333333333; - y = mask - y - ((y >>1) & 033333333333); - return (((y + (y >> 3)) & 030707070707) % 077); +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined(__OPTIMIZE__) + if (sizeof (T) <= sizeof (unsigned int)) + return __builtin_popcount (v); + + if (sizeof (T) <= sizeof (unsigned long)) + return __builtin_popcountl (v); + + if (sizeof (T) <= sizeof (unsigned long long)) + return __builtin_popcountll (v); #endif + + if (sizeof (T) <= 4) + { + /* "HACKMEM 169" */ + uint32_t y; + y = (v >> 1) &033333333333; + y = v - y - ((y >>1) & 033333333333); + return (((y + (y >> 3)) & 030707070707) % 077); + } + + if (sizeof (T) == 8) + { + unsigned int shift = 32; + return _hb_popcount<uint32_t> ((uint32_t) v) + _hb_popcount ((uint32_t) (v >> shift)); + } + + if (sizeof (T) == 16) + { + unsigned int shift = 64; + return _hb_popcount<uint64_t> ((uint64_t) v) + _hb_popcount ((uint64_t) (v >> shift)); + } + + assert (0); + return 0; } -static inline HB_CONST_FUNC unsigned int -_hb_popcount64 (uint64_t mask) -{ -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) - if (sizeof (long) >= sizeof (mask)) - return __builtin_popcountl (mask); -#endif - return _hb_popcount32 (mask & 0xFFFFFFFF) + _hb_popcount32 (mask >> 32); -} -template <typename T> static inline unsigned int _hb_popcount (T mask); -template <> inline unsigned int _hb_popcount<uint32_t> (uint32_t mask) { return _hb_popcount32 (mask); } -template <> inline unsigned int _hb_popcount<uint64_t> (uint64_t mask) { return _hb_popcount64 (mask); } /* Returns the number of bits needed to store number */ +template <typename T> static inline HB_CONST_FUNC unsigned int -_hb_bit_storage (unsigned int number) +_hb_bit_storage (T v) { + if (unlikely (!v)) return 0; + #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) - return likely (number) ? (sizeof (unsigned int) * 8 - __builtin_clz (number)) : 0; -#else - unsigned int n_bits = 0; - while (number) { - n_bits++; - number >>= 1; + if (sizeof (T) <= sizeof (unsigned int)) + return sizeof (unsigned int) * 8 - __builtin_clz (v); + + if (sizeof (T) <= sizeof (unsigned long)) + return sizeof (unsigned long) * 8 - __builtin_clzl (v); + + if (sizeof (T) <= sizeof (unsigned long long)) + return sizeof (unsigned long long) * 8 - __builtin_clzll (v); +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) + if (sizeof (T) <= sizeof (unsigned int)) + { + unsigned long where; + _BitScanReverse (&where, v); + return 1 + where; + } +# if _WIN64 + if (sizeof (T) <= 8) + { + unsigned long where; + _BitScanReverse64 (&where, v); + return 1 + where; } - return n_bits; +# endif #endif + + if (sizeof (T) <= 4) + { + /* "bithacks" */ + const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; + const unsigned int S[] = {1, 2, 4, 8, 16}; + unsigned int r = 0; + for (int i = 4; i >= 0; i--) + if (v & b[i]) + { + v >>= S[i]; + r |= S[i]; + } + return r + 1; + } + if (sizeof (T) <= 8) + { + /* "bithacks" */ + const uint64_t b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000, 0xFFFFFFFF00000000}; + const unsigned int S[] = {1, 2, 4, 8, 16, 32}; + unsigned int r = 0; + for (int i = 5; i >= 0; i--) + if (v & b[i]) + { + v >>= S[i]; + r |= S[i]; + } + return r + 1; + } + if (sizeof (T) == 16) + { + unsigned int shift = 64; + return (v >> shift) ? _hb_bit_storage<uint64_t> ((uint64_t) v >> shift) + shift : + _hb_bit_storage<uint64_t> ((uint64_t) v); + } + + assert (0); + return 0; } -/* Returns the number of zero bits in the least significant side of number */ +/* Returns the number of zero bits in the least significant side of v */ +template <typename T> static inline HB_CONST_FUNC unsigned int -_hb_ctz (unsigned int number) +_hb_ctz (T v) { + if (unlikely (!v)) return 0; + #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) - return likely (number) ? __builtin_ctz (number) : 0; -#else - unsigned int n_bits = 0; - if (unlikely (!number)) return 0; - while (!(number & 1)) { - n_bits++; - number >>= 1; + if (sizeof (T) <= sizeof (unsigned int)) + return __builtin_ctz (v); + + if (sizeof (T) <= sizeof (unsigned long)) + return __builtin_ctzl (v); + + if (sizeof (T) <= sizeof (unsigned long long)) + return __builtin_ctzll (v); +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) + if (sizeof (T) <= sizeof (unsigned int)) + { + unsigned long where; + _BitScanForward (&where, v); + return where; + } +# if _WIN64 + if (sizeof (T) <= 8) + { + unsigned long where; + _BitScanForward64 (&where, v); + return where; } - return n_bits; +# endif #endif + + if (sizeof (T) <= 4) + { + /* "bithacks" */ + unsigned int c = 32; + v &= - (int32_t) v; + if (v) c--; + if (v & 0x0000FFFF) c -= 16; + if (v & 0x00FF00FF) c -= 8; + if (v & 0x0F0F0F0F) c -= 4; + if (v & 0x33333333) c -= 2; + if (v & 0x55555555) c -= 1; + return c; + } + if (sizeof (T) <= 8) + { + /* "bithacks" */ + unsigned int c = 64; + v &= - (int64_t) (v); + if (v) c--; + if (v & 0x00000000FFFFFFFF) c -= 32; + if (v & 0x0000FFFF0000FFFF) c -= 16; + if (v & 0x00FF00FF00FF00FF) c -= 8; + if (v & 0x0F0F0F0F0F0F0F0F) c -= 4; + if (v & 0x3333333333333333) c -= 2; + if (v & 0x5555555555555555) c -= 1; + return c; + } + if (sizeof (T) == 16) + { + unsigned int shift = 64; + return (uint64_t) v ? _hb_bit_storage<uint64_t> ((uint64_t) v) : + _hb_bit_storage<uint64_t> ((uint64_t) v >> shift) + shift; + } + + assert (0); + return 0; } static inline bool @@ -366,6 +516,12 @@ return (size > 0) && (count >= ((unsigned int) -1) / size); } +static inline unsigned int +_hb_ceil_to_4 (unsigned int v) +{ + return ((v - 1) | 3) + 1; +} + /* arrays and maps */ @@ -398,35 +554,44 @@ return &array[len - 1]; } + /* Allocate for size but don't adjust len. */ + inline bool alloc(unsigned int size) + { + if (likely (size <= allocated)) + return true; + + /* Reallocate */ + + unsigned int new_allocated = allocated; + while (size >= new_allocated) + new_allocated += (new_allocated >> 1) + 8; + + Type *new_array = nullptr; + + if (array == static_array) { + new_array = (Type *) calloc (new_allocated, sizeof (Type)); + if (new_array) + memcpy (new_array, array, len * sizeof (Type)); + } else { + bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type)); + if (likely (!overflows)) { + new_array = (Type *) realloc (array, new_allocated * sizeof (Type)); + } + } + + if (unlikely (!new_array)) + return false; + + array = new_array; + allocated = new_allocated; + + return true; + } + inline bool resize (unsigned int size) { - if (unlikely (size > allocated)) - { - /* Need to reallocate */ - - unsigned int new_allocated = allocated; - while (size >= new_allocated) - new_allocated += (new_allocated >> 1) + 8; - - Type *new_array = nullptr; - - if (array == static_array) { - new_array = (Type *) calloc (new_allocated, sizeof (Type)); - if (new_array) - memcpy (new_array, array, len * sizeof (Type)); - } else { - bool overflows = (new_allocated < allocated) || _hb_unsigned_int_mul_overflows (new_allocated, sizeof (Type)); - if (likely (!overflows)) { - new_array = (Type *) realloc (array, new_allocated * sizeof (Type)); - } - } - - if (unlikely (!new_array)) - return false; - - array = new_array; - allocated = new_allocated; - } + if (!alloc (size)) + return false; len = size; return true; @@ -468,6 +633,11 @@ return nullptr; } + inline void qsort (int (*cmp)(const void*, const void*)) + { + ::qsort (array, len, sizeof (Type), cmp); + } + inline void qsort (void) { ::qsort (array, len, sizeof (Type), Type::cmp); @@ -479,25 +649,34 @@ } template <typename T> - inline Type *bsearch (T *x) + inline Type *lsearch (const T &x) + { + for (unsigned int i = 0; i < len; i++) + if (0 == this->array[i].cmp (&x)) + return &array[i]; + return nullptr; + } + + template <typename T> + inline Type *bsearch (const T &x) { unsigned int i; return bfind (x, &i) ? &array[i] : nullptr; } template <typename T> - inline const Type *bsearch (T *x) const + inline const Type *bsearch (const T &x) const { unsigned int i; return bfind (x, &i) ? &array[i] : nullptr; } template <typename T> - inline bool bfind (T *x, unsigned int *i) const + inline bool bfind (const T &x, unsigned int *i) const { int min = 0, max = (int) this->len - 1; while (min <= max) { int mid = (min + max) / 2; - int c = this->array[mid].cmp (x); + int c = this->array[mid].cmp (&x); if (c < 0) max = mid - 1; else if (c > 0) @@ -508,7 +687,7 @@ return true; } } - if (max < 0 || (max < (int) this->len && this->array[max].cmp (x) > 0)) + if (max < 0 || (max < (int) this->len && this->array[max].cmp (&x) > 0)) max++; *i = max; return false; @@ -692,7 +871,7 @@ * 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 + * For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163 */ #ifdef _MSC_VER # pragma warning(disable:4200)
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set-digest-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set-digest-private.hh Wed May 30 12:20:00 2018 -0700 @@ -71,7 +71,7 @@ mask |= mask_for (g); } - inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { + inline bool add_range (hb_codepoint_t a, hb_codepoint_t b) { if ((b >> shift) - (a >> shift) >= mask_bits - 1) mask = (mask_t) -1; else { @@ -79,6 +79,27 @@ mask_t mb = mask_for (b); mask |= mb + (mb - ma) - (mb < ma); } + return true; + } + + template <typename T> + inline void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { + for (unsigned int i = 0; i < count; i++) + { + add (*array); + array = (const T *) (stride + (const char *) array); + } + } + template <typename T> + inline bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { + for (unsigned int i = 0; i < count; i++) + { + add (*array); + array = (const T *) (stride + (const char *) array); + } + return true; } inline bool may_have (hb_codepoint_t g) const { @@ -108,9 +129,23 @@ tail.add (g); } - inline void add_range (hb_codepoint_t a, hb_codepoint_t b) { + inline bool add_range (hb_codepoint_t a, hb_codepoint_t b) { head.add_range (a, b); tail.add_range (a, b); + return true; + } + template <typename T> + inline void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { + head.add_array (array, count, stride); + tail.add_array (array, count, stride); + } + template <typename T> + inline bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { + head.add_sorted_array (array, count, stride); + tail.add_sorted_array (array, count, stride); + return true; } inline bool may_have (hb_codepoint_t g) const {
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set-private.hh Wed May 30 12:20:00 2018 -0700 @@ -35,6 +35,9 @@ * hb_set_t */ +/* TODO Keep a free-list so we can free pages that are completely zeroed. At that + * point maybe also use a sentinel value for "all-1" pages? */ + struct hb_set_t { struct page_map_t @@ -47,9 +50,8 @@ struct page_t { - inline void init (void) { - memset (&v, 0, sizeof (v)); - } + inline void init0 (void) { memset (&v, 0, sizeof (v)); } + inline void init1 (void) { memset (&v, 0xff, sizeof (v)); } inline unsigned int len (void) const { return ARRAY_LENGTH_CONST (v); } @@ -66,6 +68,23 @@ inline void del (hb_codepoint_t g) { elt (g) &= ~mask (g); } inline bool has (hb_codepoint_t g) const { return !!(elt (g) & mask (g)); } + inline void add_range (hb_codepoint_t a, hb_codepoint_t b) + { + elt_t *la = &elt (a); + elt_t *lb = &elt (b); + if (la == lb) + *la |= (mask (b) << 1) - mask(a); + else + { + *la |= ~(mask (a) - 1); + la++; + + memset (la, 0xff, (char *) lb - (char *) la); + + *lb |= ((mask (b) << 1) - 1); + } + } + inline bool is_equal (const page_t *other) const { return 0 == memcmp (&v, &other->v, sizeof (v)); @@ -90,51 +109,60 @@ unsigned int i = m / ELT_BITS; unsigned int j = m & ELT_MASK; - for (; j < ELT_BITS; j++) - if (v[i] & (elt_t (1) << j)) - goto found; - for (i++; i < len (); i++) - if (v[i]) - for (j = 0; j < ELT_BITS; j++) - if (v[i] & (elt_t (1) << j)) - goto found; + const elt_t vv = v[i] & ~((elt_t (1) << j) - 1); + for (const elt_t *p = &vv; i < len (); p = &v[++i]) + if (*p) + { + *codepoint = i * ELT_BITS + elt_get_min (*p); + return true; + } *codepoint = INVALID; return false; + } + inline bool previous (hb_codepoint_t *codepoint) const + { + unsigned int m = (*codepoint - 1) & MASK; + if (m == MASK) + { + *codepoint = INVALID; + return false; + } + unsigned int i = m / ELT_BITS; + unsigned int j = m & ELT_MASK; - found: - *codepoint = i * ELT_BITS + j; - return true; + const elt_t vv = v[i] & ((elt_t (1) << (j + 1)) - 1); + for (const elt_t *p = &vv; (int) i >= 0; p = &v[--i]) + if (*p) + { + *codepoint = i * ELT_BITS + elt_get_max (*p); + return true; + } + + *codepoint = INVALID; + return false; } inline hb_codepoint_t get_min (void) const { for (unsigned int i = 0; i < len (); i++) if (v[i]) - { - elt_t e = v[i]; - for (unsigned int j = 0; j < ELT_BITS; j++) - if (e & (elt_t (1) << j)) - return i * ELT_BITS + j; - } + return i * ELT_BITS + elt_get_min (v[i]); return INVALID; } inline hb_codepoint_t get_max (void) const { for (int i = len () - 1; i >= 0; i--) if (v[i]) - { - elt_t e = v[i]; - for (int j = ELT_BITS - 1; j >= 0; j--) - if (e & (elt_t (1) << j)) - return i * ELT_BITS + j; - } + return i * ELT_BITS + elt_get_max (v[i]); return 0; } - static const unsigned int PAGE_BITS = 512; /* Use to tune. */ + typedef unsigned long long elt_t; + static const unsigned int PAGE_BITS = 1024; static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, ""); - typedef uint64_t elt_t; + static inline unsigned int elt_get_min (const elt_t &elt) { return _hb_ctz (elt); } + static inline unsigned int elt_get_max (const elt_t &elt) { return _hb_bit_storage (elt) - 1; } #if 0 && HAVE_VECTOR_SIZE /* The vectorized version does not work with clang as non-const @@ -162,7 +190,19 @@ ASSERT_POD (); bool in_error; hb_prealloced_array_t<page_map_t, 8> page_map; - hb_prealloced_array_t<page_t, 8> pages; + hb_prealloced_array_t<page_t, 1> pages; + + inline void init (void) + { + in_error = false; + page_map.init (); + pages.init (); + } + inline void finish (void) + { + page_map.finish (); + pages.finish (); + } inline bool resize (unsigned int count) { @@ -195,18 +235,90 @@ { if (unlikely (in_error)) return; if (unlikely (g == INVALID)) return; - page_t *page = page_for_insert (g); - if (!page) - return; + page_t *page = page_for_insert (g); if (unlikely (!page)) return; page->add (g); } - inline void add_range (hb_codepoint_t a, hb_codepoint_t b) + inline bool add_range (hb_codepoint_t a, hb_codepoint_t b) + { + if (unlikely (in_error)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ + if (unlikely (a > b || a == INVALID || b == INVALID)) return false; + unsigned int ma = get_major (a); + unsigned int mb = get_major (b); + if (ma == mb) + { + page_t *page = page_for_insert (a); if (unlikely (!page)) return false; + page->add_range (a, b); + } + else + { + page_t *page = page_for_insert (a); if (unlikely (!page)) return false; + page->add_range (a, major_start (ma + 1) - 1); + + for (unsigned int m = ma + 1; m < mb; m++) + { + page = page_for_insert (major_start (m)); if (unlikely (!page)) return false; + page->init1 (); + } + + page = page_for_insert (b); if (unlikely (!page)) return false; + page->add_range (major_start (mb), b); + } + return true; + } + + template <typename T> + inline void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) { if (unlikely (in_error)) return; - /* TODO Speedup */ - for (unsigned int i = a; i < b + 1; i++) - add (i); + if (!count) return; + hb_codepoint_t g = *array; + while (count) + { + unsigned int m = get_major (g); + page_t *page = page_for_insert (g); if (unlikely (!page)) return; + unsigned int start = major_start (m); + unsigned int end = major_start (m + 1); + do + { + page->add (g); + + array = (const T *) ((const char *) array + stride); + count--; + } + while (count && (g = *array, start <= g && g < end)); + } } + + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template <typename T> + inline bool add_sorted_array (const T *array, unsigned int count, unsigned int stride=sizeof(T)) + { + if (unlikely (in_error)) return true; /* https://github.com/harfbuzz/harfbuzz/issues/657 */ + if (!count) return true; + hb_codepoint_t g = *array; + hb_codepoint_t last_g = g; + while (count) + { + unsigned int m = get_major (g); + page_t *page = page_for_insert (g); if (unlikely (!page)) return false; + unsigned int end = major_start (m + 1); + do + { + /* If we try harder we can change the following comparison to <=; + * Not sure if it's worth it. */ + if (g < last_g) return false; + last_g = g; + page->add (g); + + array = (const T *) ((const char *) array + stride); + count--; + } + while (count && (g = *array, g < end)); + } + return true; + } + inline void del (hb_codepoint_t g) { if (unlikely (in_error)) return; @@ -217,6 +329,7 @@ } inline void del_range (hb_codepoint_t a, hb_codepoint_t b) { + /* TODO Optimize, like add_range(). */ if (unlikely (in_error)) return; for (unsigned int i = a; i < b + 1; i++) del (i); @@ -276,6 +389,7 @@ unsigned int na = pages.len; unsigned int nb = other->pages.len; + unsigned int next_page = na; unsigned int count = 0; unsigned int a = 0, b = 0; @@ -317,27 +431,47 @@ { a--; b--; - Op::process (page_at (--count).v, page_at (a).v, other->page_at (b).v); + count--; + page_map[count] = page_map[a]; + Op::process (page_at (count).v, page_at (a).v, other->page_at (b).v); } else if (page_map[a - 1].major > other->page_map[b - 1].major) { a--; if (Op::passthru_left) - page_at (--count).v = page_at (a).v; + { + count--; + page_map[count] = page_map[a]; + } } else { b--; if (Op::passthru_right) - page_at (--count).v = other->page_at (b).v; + { + count--; + page_map[count].major = other->page_map[b].major; + page_map[count].index = next_page++; + page_at (count).v = other->page_at (b).v; + } } } if (Op::passthru_left) while (a) - page_at (--count).v = page_at (--a).v; + { + a--; + count--; + page_map[count] = page_map [a]; + } if (Op::passthru_right) while (b) - page_at (--count).v = other->page_at (--b).v; + { + b--; + count--; + page_map[count].major = other->page_map[b].major; + page_map[count].index = next_page++; + page_at (count).v = other->page_at (b).v; + } assert (!count); } @@ -366,8 +500,8 @@ page_map_t map = {get_major (*codepoint), 0}; unsigned int i; - page_map.bfind (&map, &i); - if (i < page_map.len) + page_map.bfind (map, &i); + if (i < page_map.len && page_map[i].major == map.major) { if (pages[page_map[i].index].next (codepoint)) { @@ -388,6 +522,37 @@ *codepoint = INVALID; return false; } + inline bool previous (hb_codepoint_t *codepoint) const + { + if (unlikely (*codepoint == INVALID)) { + *codepoint = get_max (); + return *codepoint != INVALID; + } + + page_map_t map = {get_major (*codepoint), 0}; + unsigned int i; + page_map.bfind (map, &i); + if (i < page_map.len && page_map[i].major == map.major) + { + if (pages[page_map[i].index].previous (codepoint)) + { + *codepoint += page_map[i].major * page_t::PAGE_BITS; + return true; + } + } + i--; + for (; (int) i >= 0; i--) + { + hb_codepoint_t m = pages[page_map[i].index].get_max (); + if (m != INVALID) + { + *codepoint = page_map[i].major * page_t::PAGE_BITS + m; + return true; + } + } + *codepoint = INVALID; + return false; + } inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const { hb_codepoint_t i; @@ -399,12 +564,31 @@ return false; } + /* TODO Speed up. */ *last = *first = i; while (next (&i) && i == *last + 1) (*last)++; return true; } + inline bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const + { + hb_codepoint_t i; + + i = *first; + if (!previous (&i)) + { + *last = *first = INVALID; + return false; + } + + /* TODO Speed up. */ + *last = *first = i; + while (previous (&i) && i == *first - 1) + (*first)--; + + return true; + } inline unsigned int get_population (void) const { @@ -433,40 +617,41 @@ static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID; - page_t *page_for_insert (hb_codepoint_t g) + inline page_t *page_for_insert (hb_codepoint_t g) { page_map_t map = {get_major (g), pages.len}; unsigned int i; - if (!page_map.bfind (&map, &i)) + if (!page_map.bfind (map, &i)) { if (!resize (pages.len + 1)) return nullptr; - pages[map.index].init (); + pages[map.index].init0 (); memmove (&page_map[i + 1], &page_map[i], (page_map.len - 1 - i) * sizeof (page_map[0])); page_map[i] = map; } return &pages[page_map[i].index]; } - page_t *page_for (hb_codepoint_t g) + inline page_t *page_for (hb_codepoint_t g) { page_map_t key = {get_major (g)}; - const page_map_t *found = page_map.bsearch (&key); + const page_map_t *found = page_map.bsearch (key); if (found) return &pages[found->index]; return nullptr; } - const page_t *page_for (hb_codepoint_t g) const + inline const page_t *page_for (hb_codepoint_t g) const { page_map_t key = {get_major (g)}; - const page_map_t *found = page_map.bsearch (&key); + const page_map_t *found = page_map.bsearch (key); if (found) return &pages[found->index]; return nullptr; } - page_t &page_at (unsigned int i) { return pages[page_map[i].index]; } - const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; } - unsigned int get_major (hb_codepoint_t g) const { return g / page_t::PAGE_BITS; } + inline page_t &page_at (unsigned int i) { return pages[page_map[i].index]; } + inline const page_t &page_at (unsigned int i) const { return pages[page_map[i].index]; } + inline unsigned int get_major (hb_codepoint_t g) const { return g / page_t::PAGE_BITS; } + inline hb_codepoint_t major_start (unsigned int major) const { return major * page_t::PAGE_BITS; } };
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.cc Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.cc Wed May 30 12:20:00 2018 -0700 @@ -45,12 +45,18 @@ if (!(set = hb_object_create<hb_set_t> ())) return hb_set_get_empty (); - set->page_map.init (); - set->pages.init (); + set->init (); return set; } +static const hb_set_t _hb_set_nil = { + HB_OBJECT_HEADER_STATIC, + true, /* in_error */ + + {0} /* elts */ +}; + /** * hb_set_get_empty: * @@ -61,13 +67,6 @@ hb_set_t * hb_set_get_empty (void) { - static const hb_set_t _hb_set_nil = { - HB_OBJECT_HEADER_STATIC, - true, /* in_error */ - - {0} /* elts */ - }; - return const_cast<hb_set_t *> (&_hb_set_nil); } @@ -96,8 +95,7 @@ { if (!hb_object_destroy (set)) return; - set->page_map.finish (); - set->pages.finish (); + set->finish (); free (set); } @@ -439,7 +437,9 @@ * @set: a set. * @codepoint: (inout): * + * Gets the next number in @set that is greater than current value of @codepoint. * + * Set @codepoint to %HB_SET_VALUE_INVALID to get started. * * Return value: whether there was a next value. * @@ -453,6 +453,26 @@ } /** + * hb_set_previous: + * @set: a set. + * @codepoint: (inout): + * + * Gets the previous number in @set that is slower than current value of @codepoint. + * + * Set @codepoint to %HB_SET_VALUE_INVALID to get started. + * + * Return value: whether there was a previous value. + * + * Since: 1.8.0 + **/ +hb_bool_t +hb_set_previous (const hb_set_t *set, + hb_codepoint_t *codepoint) +{ + return set->previous (codepoint); +} + +/** * hb_set_next_range: * @set: a set. * @first: (out): output first codepoint in the range. @@ -461,6 +481,8 @@ * Gets the next consecutive range of numbers in @set that * are greater than current value of @last. * + * Set @last to %HB_SET_VALUE_INVALID to get started. + * * Return value: whether there was a next range. * * Since: 0.9.7 @@ -472,3 +494,26 @@ { return set->next_range (first, last); } + +/** + * hb_set_previous_range: + * @set: a set. + * @first: (inout): input current first and output first codepoint in the range. + * @last: (out): output last codepoint in the range. + * + * Gets the previous consecutive range of numbers in @set that + * are greater than current value of @last. + * + * Set @first to %HB_SET_VALUE_INVALID to get started. + * + * Return value: whether there was a previous range. + * + * Since: 1.8.0 + **/ +hb_bool_t +hb_set_previous_range (const hb_set_t *set, + hb_codepoint_t *first, + hb_codepoint_t *last) +{ + return set->previous_range (first, last); +}
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.h Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-set.h Wed May 30 12:20:00 2018 -0700 @@ -129,25 +129,36 @@ HB_EXTERN unsigned int hb_set_get_population (const hb_set_t *set); -/* Returns -1 if set empty. */ +/* Returns HB_SET_VALUE_INVALID if set empty. */ HB_EXTERN hb_codepoint_t hb_set_get_min (const hb_set_t *set); -/* Returns -1 if set empty. */ +/* Returns HB_SET_VALUE_INVALID if set empty. */ HB_EXTERN hb_codepoint_t hb_set_get_max (const hb_set_t *set); -/* Pass -1 in to get started. */ +/* Pass HB_SET_VALUE_INVALID in to get started. */ 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. */ +/* Pass HB_SET_VALUE_INVALID in to get started. */ +HB_EXTERN hb_bool_t +hb_set_previous (const hb_set_t *set, + hb_codepoint_t *codepoint); + +/* Pass HB_SET_VALUE_INVALID for first and last to get started. */ HB_EXTERN hb_bool_t hb_set_next_range (const hb_set_t *set, hb_codepoint_t *first, hb_codepoint_t *last); +/* Pass HB_SET_VALUE_INVALID for first and last to get started. */ +HB_EXTERN hb_bool_t +hb_set_previous_range (const hb_set_t *set, + hb_codepoint_t *first, + hb_codepoint_t *last); + HB_END_DECLS
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-string-array.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-string-array.hh Wed May 30 12:20:00 2018 -0700 @@ -48,7 +48,7 @@ #include HB_STRING_ARRAY_LIST #undef _S } st; - char str[1]; + char str[VAR]; } HB_STRING_ARRAY_POOL_NAME = {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset-glyf.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright © 2018 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): Garret Rieger + */ + +#ifndef HB_SUBSET_GLYF_HH +#define HB_SUBSET_GLYF_HH + +#include "hb-private.hh" + +#include "hb-subset-plan.hh" + +HB_INTERNAL bool +hb_subset_glyf_and_loca (hb_subset_plan_t *plan, + bool *use_short_loca, /* OUT */ + hb_blob_t **glyf_prime /* OUT */, + hb_blob_t **loca_prime /* OUT */); + +#endif /* HB_SUBSET_GLYF_HH */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset-plan.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,85 @@ +/* + * Copyright © 2018 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): Garret Rieger, Roderick Sheeter + */ + +#ifndef HB_SUBSET_PLAN_HH +#define HB_SUBSET_PLAN_HH + +#include "hb-private.hh" + +#include "hb-subset.h" + +#include "hb-object-private.hh" + +struct hb_subset_plan_t { + hb_object_header_t header; + ASSERT_POD (); + + hb_bool_t drop_hints; + + // TODO(Q1) actual map, drop this crap + // Look at me ma, I'm a poor mans map codepoint : new gid + // codepoints is sorted and aligned with gids_to_retain. + + // These first two lists provide a mapping from cp -> gid + // As a result it does not list the full set of glyphs to retain. + hb_prealloced_array_t<hb_codepoint_t> codepoints; + hb_prealloced_array_t<hb_codepoint_t> gids_to_retain; + + // This list contains the complete set of glyphs to retain and may contain + // more glyphs then the lists above. + hb_prealloced_array_t<hb_codepoint_t> gids_to_retain_sorted; + + // Plan is only good for a specific source/dest so keep them with it + hb_face_t *source; + hb_face_t *dest; +}; + +typedef struct hb_subset_plan_t hb_subset_plan_t; + +HB_INTERNAL hb_subset_plan_t * +hb_subset_plan_create (hb_face_t *face, + hb_subset_profile_t *profile, + hb_subset_input_t *input); + +HB_INTERNAL hb_bool_t +hb_subset_plan_new_gid_for_old_id(hb_subset_plan_t *plan, + hb_codepoint_t old_gid, + hb_codepoint_t *new_gid /* OUT */); + +HB_INTERNAL hb_bool_t +hb_subset_plan_new_gid_for_codepoint(hb_subset_plan_t *plan, + hb_codepoint_t codepont, + hb_codepoint_t *new_gid /* OUT */); + +HB_INTERNAL hb_bool_t +hb_subset_plan_add_table(hb_subset_plan_t *plan, + hb_tag_t tag, + hb_blob_t *contents); + +HB_INTERNAL void +hb_subset_plan_destroy (hb_subset_plan_t *plan); + +#endif /* HB_SUBSET_PLAN_HH */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset-private.hh Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,62 @@ +/* + * Copyright © 2018 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): Garret Rieger, Roderick Sheeter + */ + +#ifndef HB_SUBSET_PRIVATE_HH +#define HB_SUBSET_PRIVATE_HH + + +#include "hb-private.hh" + +#include "hb-subset.h" + +#include "hb-font-private.hh" + +typedef struct hb_subset_face_data_t hb_subset_face_data_t; + +struct hb_subset_input_t { + hb_object_header_t header; + ASSERT_POD (); + + hb_set_t *unicodes; + hb_set_t *glyphs; + + hb_bool_t drop_hints; + /* TODO + * + * features + * lookups + * nameIDs + * ... + */ +}; + +HB_INTERNAL hb_face_t * +hb_subset_face_create (void); + +HB_INTERNAL hb_bool_t +hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob); + +#endif /* HB_SUBSET_PRIVATE_HH */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-subset.h Wed May 30 12:20:00 2018 -0700 @@ -0,0 +1,83 @@ +/* + * Copyright © 2018 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): Rod Sheeter + */ + +#ifndef HB_SUBSET_H +#define HB_SUBSET_H + +#include "hb.h" + +HB_BEGIN_DECLS + +/* + * hb_subset_profile_t + * Things that change based on target environment, e.g. OS. + * Threadsafe for multiple concurrent subset operations. + */ + +typedef struct hb_subset_profile_t hb_subset_profile_t; + +HB_EXTERN hb_subset_profile_t * +hb_subset_profile_create (void); + +HB_EXTERN void +hb_subset_profile_destroy (hb_subset_profile_t *profile); + +/* + * hb_subset_input_t + * + * Things that change based on the input. Characters to keep, etc. + */ + +typedef struct hb_subset_input_t hb_subset_input_t; + +HB_EXTERN hb_subset_input_t * +hb_subset_input_create_or_fail (void); + +HB_EXTERN hb_subset_input_t * +hb_subset_input_reference (hb_subset_input_t *subset_input); + +HB_EXTERN void +hb_subset_input_destroy (hb_subset_input_t *subset_input); + +HB_EXTERN hb_set_t * +hb_subset_input_unicode_set (hb_subset_input_t *subset_input); + +HB_EXTERN hb_set_t * +hb_subset_input_glyph_set (hb_subset_input_t *subset_input); + +HB_EXTERN hb_bool_t * +hb_subset_input_drop_hints (hb_subset_input_t *subset_input); + +/* hb_subset() */ + +HB_EXTERN hb_face_t * +hb_subset (hb_face_t *source, + hb_subset_profile_t *profile, + hb_subset_input_t *input); + +HB_END_DECLS + +#endif /* HB_SUBSET_H */
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode-private.hh Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-unicode-private.hh Wed May 30 12:20:00 2018 -0700 @@ -137,7 +137,7 @@ * we do NOT want to hide them, as the way Uniscribe has implemented them * is with regular spacing glyphs, and that's the way fonts are made to work. * As such, we make exceptions for those four. - * Also ignoring U+1BCA0..1BCA3. https://github.com/behdad/harfbuzz/issues/503 + * Also ignoring U+1BCA0..1BCA3. https://github.com/harfbuzz/harfbuzz/issues/503 * * Unicode 7.0: * $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
--- a/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-version.h Wed May 30 08:10:41 2018 -0700 +++ b/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-version.h Wed May 30 12:20:00 2018 -0700 @@ -38,9 +38,9 @@ #define HB_VERSION_MAJOR 1 #define HB_VERSION_MINOR 7 -#define HB_VERSION_MICRO 1 +#define HB_VERSION_MICRO 6 -#define HB_VERSION_STRING "1.7.1" +#define HB_VERSION_STRING "1.7.6" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \