summaryrefslogtreecommitdiffstats
path: root/third_party/harfbuzz-ng
diff options
context:
space:
mode:
authorjshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-11 20:33:21 +0000
committerjshin@chromium.org <jshin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-11 20:33:21 +0000
commit307f7bdd33cf295aac89b436982d40d8ba63fc6a (patch)
tree6aa1ed56388d1bb2066eacdbaf05c760d1b8f3b3 /third_party/harfbuzz-ng
parentabebfb09457bd903745e5809b3c5ecb99e8f1c63 (diff)
downloadchromium_src-307f7bdd33cf295aac89b436982d40d8ba63fc6a.zip
chromium_src-307f7bdd33cf295aac89b436982d40d8ba63fc6a.tar.gz
chromium_src-307f7bdd33cf295aac89b436982d40d8ba63fc6a.tar.bz2
Update harfbuzz-ng to 0.9.10 (Jan 3, 2013)
Previous revision: 431bef2e16c7888ca3960f5797432d3a20903550 New revision: 34e6c3e3e452bdf6f93df565a70453a6e74d4c6e BUG=160254 TEST=See the bug. Review URL: https://codereview.chromium.org/11781005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176429 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/harfbuzz-ng')
-rw-r--r--third_party/harfbuzz-ng/README.chromium6
-rw-r--r--third_party/harfbuzz-ng/harfbuzz.gyp3
-rw-r--r--third_party/harfbuzz-ng/src/hb-atomic-private.hh15
-rw-r--r--third_party/harfbuzz-ng/src/hb-buffer-private.hh42
-rw-r--r--third_party/harfbuzz-ng/src/hb-buffer.cc326
-rw-r--r--third_party/harfbuzz-ng/src/hb-buffer.h128
-rw-r--r--third_party/harfbuzz-ng/src/hb-common.cc12
-rw-r--r--third_party/harfbuzz-ng/src/hb-coretext.cc56
-rw-r--r--third_party/harfbuzz-ng/src/hb-coretext.h3
-rw-r--r--third_party/harfbuzz-ng/src/hb-fallback-shape.cc12
-rw-r--r--third_party/harfbuzz-ng/src/hb-font-private.hh9
-rw-r--r--third_party/harfbuzz-ng/src/hb-font.cc29
-rw-r--r--third_party/harfbuzz-ng/src/hb-font.h7
-rw-r--r--third_party/harfbuzz-ng/src/hb-ft.cc2
-rw-r--r--third_party/harfbuzz-ng/src/hb-glib.cc2
-rw-r--r--third_party/harfbuzz-ng/src/hb-graphite2.cc30
-rw-r--r--third_party/harfbuzz-ng/src/hb-graphite2.h8
-rw-r--r--third_party/harfbuzz-ng/src/hb-icu-le.cc8
-rw-r--r--third_party/harfbuzz-ng/src/hb-object-private.hh44
-rw-r--r--third_party/harfbuzz-ng/src/hb-old.cc24
-rw-r--r--third_party/harfbuzz-ng/src/hb-open-file-private.hh12
-rw-r--r--third_party/harfbuzz-ng/src/hb-open-type-private.hh128
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-head-table.hh6
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-hhea-table.hh4
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-hmtx-table.hh4
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh346
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh38
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh538
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh759
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh864
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-layout-private.hh16
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-layout.cc302
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-layout.h115
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-map-private.hh27
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-map.cc66
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-maxp-table.hh4
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-name-table.hh8
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh4
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh4
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc67
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc226
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh1683
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl119
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh25
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.hh12
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc219
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-misc.cc208
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh89
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc378
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc10
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh24
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc272
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape-private.hh15
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-shape.cc97
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot-tag.cc218
-rw-r--r--third_party/harfbuzz-ng/src/hb-ot.h1
-rw-r--r--third_party/harfbuzz-ng/src/hb-private.hh70
-rw-r--r--third_party/harfbuzz-ng/src/hb-set-private.hh56
-rw-r--r--third_party/harfbuzz-ng/src/hb-set.cc95
-rw-r--r--third_party/harfbuzz-ng/src/hb-set.h58
-rw-r--r--third_party/harfbuzz-ng/src/hb-shape-plan-private.hh4
-rw-r--r--third_party/harfbuzz-ng/src/hb-shape-plan.cc31
-rw-r--r--third_party/harfbuzz-ng/src/hb-shape-plan.h48
-rw-r--r--third_party/harfbuzz-ng/src/hb-shape.cc4
-rw-r--r--third_party/harfbuzz-ng/src/hb-shape.h2
-rw-r--r--third_party/harfbuzz-ng/src/hb-shaper-list.hh15
-rw-r--r--third_party/harfbuzz-ng/src/hb-shaper-private.hh2
-rw-r--r--third_party/harfbuzz-ng/src/hb-shaper.cc2
-rw-r--r--third_party/harfbuzz-ng/src/hb-tt-font.cc2
-rw-r--r--third_party/harfbuzz-ng/src/hb-ucdn.cc27
-rw-r--r--third_party/harfbuzz-ng/src/hb-uniscribe.cc33
-rw-r--r--third_party/harfbuzz-ng/src/hb-utf-private.hh8
-rw-r--r--third_party/harfbuzz-ng/src/hb.h1
-rw-r--r--third_party/harfbuzz-ng/src/test-size-params.cc93
-rw-r--r--third_party/harfbuzz-ng/src/test-would-substitute.cc2
75 files changed, 5191 insertions, 3036 deletions
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium
index 7e29086..ec10ad8 100644
--- a/third_party/harfbuzz-ng/README.chromium
+++ b/third_party/harfbuzz-ng/README.chromium
@@ -2,8 +2,8 @@ Name: harfbuzz-ng
Short Name: harfbuzz-ng
URL: http://freedesktop.org/wiki/Software/HarfBuzz
Version: unknown
-Date: 20121102
-Revision: 431bef2e16c7888ca3960f5797432d3a20903550
+Date: 20120103
+Revision: 34e6c3e3e452bdf6f93df565a70453a6e74d4c6e (0.9.10)
Security Critical: yes
License: MIT
License File: NOT_SHIPPED
@@ -12,4 +12,4 @@ Description:
This is harfbuzz-ng, a new implementation of harfbuzz with a different
API from the old one.
-I also deleted all unneeded files from the root directory (but left src/ alone).
+I also deleted all unneeded files from the root directory and src/ directory (hb-icu-le, hb-ucdn, hb-old, scripts to generate data tables, automake/conf files).
diff --git a/third_party/harfbuzz-ng/harfbuzz.gyp b/third_party/harfbuzz-ng/harfbuzz.gyp
index 58bcbd4..af5d0fc 100644
--- a/third_party/harfbuzz-ng/harfbuzz.gyp
+++ b/third_party/harfbuzz-ng/harfbuzz.gyp
@@ -58,12 +58,13 @@
'src/hb-ot-shape-complex-arabic-fallback.hh',
'src/hb-ot-shape-complex-arabic-table.hh',
'src/hb-ot-shape-complex-arabic.cc',
+ 'src/hb-ot-shape-complex-default.cc',
'src/hb-ot-shape-complex-indic-machine.hh',
'src/hb-ot-shape-complex-indic-private.hh',
'src/hb-ot-shape-complex-indic-table.hh',
'src/hb-ot-shape-complex-indic.cc',
- 'src/hb-ot-shape-complex-misc.cc',
'src/hb-ot-shape-complex-private.hh',
+ 'src/hb-ot-shape-complex-thai.cc',
'src/hb-ot-shape-fallback-private.hh',
'src/hb-ot-shape-fallback.cc',
'src/hb-ot-shape-normalize-private.hh',
diff --git a/third_party/harfbuzz-ng/src/hb-atomic-private.hh b/third_party/harfbuzz-ng/src/hb-atomic-private.hh
index 5861a71..67579cd 100644
--- a/third_party/harfbuzz-ng/src/hb-atomic-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-atomic-private.hh
@@ -59,7 +59,7 @@ static inline void HBMemoryBarrier (void) {
}
#endif
-typedef long hb_atomic_int_t;
+typedef LONG hb_atomic_int_t;
#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
#define hb_atomic_ptr_get(P) (HBMemoryBarrier (), (void *) *(P))
@@ -69,12 +69,25 @@ typedef long hb_atomic_int_t;
#elif !defined(HB_NO_MT) && defined(__APPLE__)
#include <libkern/OSAtomic.h>
+#ifdef __MAC_OS_X_MIN_REQUIRED
+#include <AvailabilityMacros.h>
+#elif defined(__IPHONE_OS_MIN_REQUIRED)
+#include <Availability.h>
+#endif
typedef int32_t hb_atomic_int_t;
#define hb_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
#define hb_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P))
+#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
+#else
+#if __ppc64__ || __x86_64__
+#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
+#else
+#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
+#endif
+#endif
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
diff --git a/third_party/harfbuzz-ng/src/hb-buffer-private.hh b/third_party/harfbuzz-ng/src/hb-buffer-private.hh
index c1acffd..13cf4bb 100644
--- a/third_party/harfbuzz-ng/src/hb-buffer-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-buffer-private.hh
@@ -36,48 +36,11 @@
#include "hb-unicode-private.hh"
-
ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
/*
- * hb_segment_properties_t
- */
-
-typedef struct hb_segment_properties_t {
- hb_direction_t direction;
- hb_script_t script;
- hb_language_t language;
- ASSERT_POD ();
-} hb_segment_properties_t;
-
-#define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
-
-static inline hb_bool_t
-hb_segment_properties_equal (const hb_segment_properties_t *a,
- const hb_segment_properties_t *b)
-{
- return a->direction == b->direction &&
- a->script == b->script &&
- a->language == b->language;
-}
-
-
-#if 0
-static inline unsigned int
-hb_segment_properties_hash (const hb_segment_properties_t *p)
-{
- /* TODO improve */
- return (unsigned int) p->direction +
- (unsigned int) p->script +
- (intptr_t) (p->language);
-}
-#endif
-
-
-
-/*
* hb_buffer_t
*/
@@ -89,6 +52,7 @@ struct hb_buffer_t {
hb_unicode_funcs_t *unicode; /* Unicode functions */
hb_segment_properties_t props; /* Script, language, direction */
+ hb_buffer_flags_t flags; /* BOT / EOT / etc. */
/* Buffer contents */
@@ -133,6 +97,7 @@ struct hb_buffer_t {
/* Methods */
HB_INTERNAL void reset (void);
+ HB_INTERNAL void clear (void);
inline unsigned int backtrack_len (void) const
{ return have_output? out_len : idx; }
@@ -144,13 +109,12 @@ struct hb_buffer_t {
HB_INTERNAL void deallocate_var_all (void);
HB_INTERNAL void add (hb_codepoint_t codepoint,
- hb_mask_t mask,
unsigned int cluster);
HB_INTERNAL void reverse_range (unsigned int start, unsigned int end);
HB_INTERNAL void reverse (void);
HB_INTERNAL void reverse_clusters (void);
- HB_INTERNAL void guess_properties (void);
+ HB_INTERNAL void guess_segment_properties (void);
HB_INTERNAL void swap_buffers (void);
HB_INTERNAL void remove_output (void);
diff --git a/third_party/harfbuzz-ng/src/hb-buffer.cc b/third_party/harfbuzz-ng/src/hb-buffer.cc
index 06b5c05..4b644e4 100644
--- a/third_party/harfbuzz-ng/src/hb-buffer.cc
+++ b/third_party/harfbuzz-ng/src/hb-buffer.cc
@@ -35,6 +35,29 @@
#define HB_DEBUG_BUFFER (HB_DEBUG+0)
#endif
+
+hb_bool_t
+hb_segment_properties_equal (const hb_segment_properties_t *a,
+ const hb_segment_properties_t *b)
+{
+ return a->direction == b->direction &&
+ a->script == b->script &&
+ a->language == b->language &&
+ a->reserved1 == b->reserved1 &&
+ a->reserved2 == b->reserved2;
+
+}
+
+unsigned int
+hb_segment_properties_hash (const hb_segment_properties_t *p)
+{
+ return (unsigned int) p->direction ^
+ (unsigned int) p->script ^
+ (intptr_t) (p->language);
+}
+
+
+
/* Here is how the buffer works internally:
*
* There are two info pointers: info and out_info. They always have
@@ -142,8 +165,18 @@ hb_buffer_t::reset (void)
hb_unicode_funcs_destroy (unicode);
unicode = hb_unicode_funcs_get_default ();
- hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
+ clear ();
+}
+
+void
+hb_buffer_t::clear (void)
+{
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+
+ hb_segment_properties_t default_props = HB_SEGMENT_PROPERTIES_DEFAULT;
props = default_props;
+ flags = HB_BUFFER_FLAGS_DEFAULT;
content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
in_error = false;
@@ -165,7 +198,6 @@ hb_buffer_t::reset (void)
void
hb_buffer_t::add (hb_codepoint_t codepoint,
- hb_mask_t mask,
unsigned int cluster)
{
hb_glyph_info_t *glyph;
@@ -176,7 +208,7 @@ hb_buffer_t::add (hb_codepoint_t codepoint,
memset (glyph, 0, sizeof (*glyph));
glyph->codepoint = codepoint;
- glyph->mask = mask;
+ glyph->mask = 1;
glyph->cluster = cluster;
len++;
@@ -459,10 +491,10 @@ hb_buffer_t::merge_out_clusters (unsigned int start,
}
void
-hb_buffer_t::guess_properties (void)
+hb_buffer_t::guess_segment_properties (void)
{
- if (unlikely (!len)) return;
- assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
+ assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+ (!len && content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
/* If script is set to INVALID, guess from buffer contents */
if (props.script == HB_SCRIPT_INVALID) {
@@ -561,7 +593,7 @@ void hb_buffer_t::deallocate_var_all (void)
/* Public API */
hb_buffer_t *
-hb_buffer_create ()
+hb_buffer_create (void)
{
hb_buffer_t *buffer;
@@ -580,7 +612,8 @@ hb_buffer_get_empty (void)
HB_OBJECT_HEADER_STATIC,
const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
- _HB_BUFFER_PROPS_DEFAULT,
+ HB_SEGMENT_PROPERTIES_DEFAULT,
+ HB_BUFFER_FLAGS_DEFAULT,
HB_BUFFER_CONTENT_TYPE_INVALID,
true, /* in_error */
@@ -715,6 +748,40 @@ hb_buffer_get_language (hb_buffer_t *buffer)
return buffer->props.language;
}
+void
+hb_buffer_set_segment_properties (hb_buffer_t *buffer,
+ const hb_segment_properties_t *props)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ buffer->props = *props;
+}
+
+void
+hb_buffer_get_segment_properties (hb_buffer_t *buffer,
+ hb_segment_properties_t *props)
+{
+ *props = buffer->props;
+}
+
+
+void
+hb_buffer_set_flags (hb_buffer_t *buffer,
+ hb_buffer_flags_t flags)
+{
+ if (unlikely (hb_object_is_inert (buffer)))
+ return;
+
+ buffer->flags = flags;
+}
+
+hb_buffer_flags_t
+hb_buffer_get_flags (hb_buffer_t *buffer)
+{
+ return buffer->flags;
+}
+
void
hb_buffer_reset (hb_buffer_t *buffer)
@@ -722,6 +789,12 @@ hb_buffer_reset (hb_buffer_t *buffer)
buffer->reset ();
}
+void
+hb_buffer_clear (hb_buffer_t *buffer)
+{
+ buffer->clear ();
+}
+
hb_bool_t
hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
{
@@ -737,10 +810,9 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer)
void
hb_buffer_add (hb_buffer_t *buffer,
hb_codepoint_t codepoint,
- hb_mask_t mask,
unsigned int cluster)
{
- buffer->add (codepoint, mask, cluster);
+ buffer->add (codepoint, cluster);
buffer->clear_context (1);
}
@@ -814,9 +886,9 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
}
void
-hb_buffer_guess_properties (hb_buffer_t *buffer)
+hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
{
- buffer->guess_properties ();
+ buffer->guess_segment_properties ();
}
template <typename T>
@@ -869,7 +941,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
hb_codepoint_t u;
const T *old_next = next;
next = hb_utf_next (next, end, &u);
- buffer->add (u, 1, old_next - (const T *) text);
+ buffer->add (u, old_next - (const T *) text);
}
/* Add post-context */
@@ -992,3 +1064,231 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
}
normalize_glyphs_cluster (buffer, start, end, backward);
}
+
+
+/*
+ * Serialize
+ */
+
+static const char *serialize_formats[] = {
+ "text",
+ "json",
+ NULL
+};
+
+const char **
+hb_buffer_serialize_list_formats (void)
+{
+ return serialize_formats;
+}
+
+hb_buffer_serialize_format_t
+hb_buffer_serialize_format_from_string (const char *str, int len)
+{
+ /* Upper-case it. */
+ return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020);
+}
+
+const char *
+hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
+{
+ switch (format)
+ {
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
+ default:
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return NULL;
+ }
+}
+
+static unsigned int
+_hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_flags_t flags)
+{
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
+
+ *buf_consumed = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ char b[1024];
+ char *p = b;
+
+ /* In the following code, we know b is large enough that no overflow can happen. */
+
+#define APPEND(s) HB_STMT_START { strcpy (p, s); p += strlen (s); } HB_STMT_END
+
+ if (i)
+ *p++ = ',';
+
+ *p++ = '{';
+
+ APPEND ("\"g\":");
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
+ {
+ char g[128];
+ hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
+ *p++ = '"';
+ for (char *q = g; *q; q++) {
+ if (*q == '"')
+ *p++ = '\\';
+ *p++ = *q;
+ }
+ *p++ = '"';
+ }
+ else
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint);
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"cl\":%u", info[i].cluster);
+ }
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
+ {
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
+ pos[i].x_offset, pos[i].y_offset);
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
+ pos[i].x_advance, pos[i].y_advance);
+ }
+
+ *p++ = '}';
+
+ if (buf_size > (p - b))
+ {
+ unsigned int l = p - b;
+ memcpy (buf, b, l);
+ buf += l;
+ buf_size -= l;
+ *buf_consumed += l;
+ *buf = '\0';
+ } else
+ return i - start;
+ }
+
+ return end - start;
+}
+
+static unsigned int
+_hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font,
+ hb_buffer_serialize_flags_t flags)
+{
+ hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL);
+ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL);
+ hb_direction_t direction = hb_buffer_get_direction (buffer);
+
+ *buf_consumed = 0;
+ for (unsigned int i = start; i < end; i++)
+ {
+ char b[1024];
+ char *p = b;
+
+ /* In the following code, we know b is large enough that no overflow can happen. */
+
+ if (i)
+ *p++ = '|';
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES))
+ {
+ hb_font_glyph_to_string (font, info[i].codepoint, p, 128);
+ p += strlen (p);
+ }
+ else
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%u", info[i].codepoint);
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS)) {
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "=%u", info[i].cluster);
+ }
+
+ if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
+ {
+ if (pos[i].x_offset || pos[i].y_offset)
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset);
+
+ *p++ = '+';
+ if (HB_DIRECTION_IS_HORIZONTAL (direction) || pos[i].x_advance)
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance);
+ if (HB_DIRECTION_IS_VERTICAL (direction) || pos->y_advance)
+ p += snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance);
+ }
+
+ if (buf_size > (p - b))
+ {
+ unsigned int l = p - b;
+ memcpy (buf, b, l);
+ buf += l;
+ buf_size -= l;
+ *buf_consumed += l;
+ *buf = '\0';
+ } else
+ return i - start;
+ }
+
+ return end - start;
+}
+
+/* Returns number of items, starting at start, that were serialized. */
+unsigned int
+hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags)
+{
+ assert (start <= end && end <= buffer->len);
+
+ *buf_consumed = 0;
+
+ assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
+ buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
+
+ if (unlikely (start == end))
+ return 0;
+
+ if (!font)
+ font = hb_font_get_empty ();
+
+ switch (format)
+ {
+ case HB_BUFFER_SERIALIZE_FORMAT_TEXT:
+ return _hb_buffer_serialize_glyphs_text (buffer, start, end,
+ buf, buf_size, buf_consumed,
+ font, flags);
+
+ case HB_BUFFER_SERIALIZE_FORMAT_JSON:
+ return _hb_buffer_serialize_glyphs_json (buffer, start, end,
+ buf, buf_size, buf_consumed,
+ font, flags);
+
+ default:
+ case HB_BUFFER_SERIALIZE_FORMAT_INVALID:
+ return 0;
+
+ }
+}
+
+hb_bool_t
+hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
+ const char *buf,
+ unsigned int buf_len,
+ unsigned int *buf_consumed,
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format)
+{
+ return false;
+}
diff --git a/third_party/harfbuzz-ng/src/hb-buffer.h b/third_party/harfbuzz-ng/src/hb-buffer.h
index dc63d1b..48ec4a5 100644
--- a/third_party/harfbuzz-ng/src/hb-buffer.h
+++ b/third_party/harfbuzz-ng/src/hb-buffer.h
@@ -36,12 +36,11 @@
#include "hb-common.h"
#include "hb-unicode.h"
+#include "hb-font.h"
HB_BEGIN_DECLS
-typedef struct hb_buffer_t hb_buffer_t;
-
typedef struct hb_glyph_info_t {
hb_codepoint_t codepoint;
hb_mask_t mask;
@@ -62,13 +61,37 @@ typedef struct hb_glyph_position_t {
hb_var_int_t var;
} hb_glyph_position_t;
-typedef enum {
- HB_BUFFER_CONTENT_TYPE_INVALID = 0,
- HB_BUFFER_CONTENT_TYPE_UNICODE,
- HB_BUFFER_CONTENT_TYPE_GLYPHS
-} hb_buffer_content_type_t;
+
+typedef struct hb_segment_properties_t {
+ hb_direction_t direction;
+ hb_script_t script;
+ hb_language_t language;
+ /*< private >*/
+ void *reserved1;
+ void *reserved2;
+} hb_segment_properties_t;
+
+#define HB_SEGMENT_PROPERTIES_DEFAULT {HB_DIRECTION_INVALID, \
+ HB_SCRIPT_INVALID, \
+ HB_LANGUAGE_INVALID, \
+ NULL, \
+ NULL}
+
+hb_bool_t
+hb_segment_properties_equal (const hb_segment_properties_t *a,
+ const hb_segment_properties_t *b);
+
+unsigned int
+hb_segment_properties_hash (const hb_segment_properties_t *p);
+
+/*
+ * hb_buffer_t
+ */
+
+typedef struct hb_buffer_t hb_buffer_t;
+
hb_buffer_t *
hb_buffer_create (void);
@@ -93,6 +116,12 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key);
+typedef enum {
+ HB_BUFFER_CONTENT_TYPE_INVALID = 0,
+ HB_BUFFER_CONTENT_TYPE_UNICODE,
+ HB_BUFFER_CONTENT_TYPE_GLYPHS
+} hb_buffer_content_type_t;
+
void
hb_buffer_set_content_type (hb_buffer_t *buffer,
hb_buffer_content_type_t content_type);
@@ -126,15 +155,46 @@ void
hb_buffer_set_language (hb_buffer_t *buffer,
hb_language_t language);
+
hb_language_t
hb_buffer_get_language (hb_buffer_t *buffer);
+void
+hb_buffer_set_segment_properties (hb_buffer_t *buffer,
+ const hb_segment_properties_t *props);
+
+void
+hb_buffer_get_segment_properties (hb_buffer_t *buffer,
+ hb_segment_properties_t *props);
+
+void
+hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
+
+
+typedef enum {
+ HB_BUFFER_FLAGS_DEFAULT = 0x00000000,
+ HB_BUFFER_FLAG_BOT = 0x00000001, /* Beginning-of-text */
+ HB_BUFFER_FLAG_EOT = 0x00000002, /* End-of-text */
+ HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004
+} hb_buffer_flags_t;
+
+void
+hb_buffer_set_flags (hb_buffer_t *buffer,
+ hb_buffer_flags_t flags);
+
+hb_buffer_flags_t
+hb_buffer_get_flags (hb_buffer_t *buffer);
+
/* Resets the buffer. Afterwards it's as if it was just created,
* except that it has a larger buffer allocated perhaps... */
void
hb_buffer_reset (hb_buffer_t *buffer);
+/* Like reset, but does NOT clear unicode_funcs. */
+void
+hb_buffer_clear (hb_buffer_t *buffer);
+
/* Returns false if allocation failed */
hb_bool_t
hb_buffer_pre_allocate (hb_buffer_t *buffer,
@@ -151,16 +211,12 @@ hb_buffer_reverse (hb_buffer_t *buffer);
void
hb_buffer_reverse_clusters (hb_buffer_t *buffer);
-void
-hb_buffer_guess_properties (hb_buffer_t *buffer);
-
/* Filling the buffer in */
void
hb_buffer_add (hb_buffer_t *buffer,
hb_codepoint_t codepoint,
- hb_mask_t mask,
unsigned int cluster);
void
@@ -213,11 +269,53 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
+
/*
- * NOT IMPLEMENTED
- void
- hb_buffer_normalize_characters (hb_buffer_t *buffer);
-*/
+ * Serialize
+ */
+
+typedef enum {
+ HB_BUFFER_SERIALIZE_FLAGS_DEFAULT = 0x00000000,
+ HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001,
+ HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002,
+ HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004
+} hb_buffer_serialize_flags_t;
+
+typedef enum {
+ HB_BUFFER_SERIALIZE_FORMAT_TEXT = HB_TAG('T','E','X','T'),
+ HB_BUFFER_SERIALIZE_FORMAT_JSON = HB_TAG('J','S','O','N'),
+ HB_BUFFER_SERIALIZE_FORMAT_INVALID = HB_TAG_NONE
+} hb_buffer_serialize_format_t;
+
+/* len=-1 means str is NUL-terminated. */
+hb_buffer_serialize_format_t
+hb_buffer_serialize_format_from_string (const char *str, int len);
+
+const char *
+hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format);
+
+const char **
+hb_buffer_serialize_list_formats (void);
+
+/* Returns number of items, starting at start, that were serialized. */
+unsigned int
+hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
+ unsigned int start,
+ unsigned int end,
+ char *buf,
+ unsigned int buf_size,
+ unsigned int *buf_consumed,
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format,
+ hb_buffer_serialize_flags_t flags);
+
+hb_bool_t
+hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
+ const char *buf,
+ unsigned int buf_len,
+ unsigned int *buf_consumed,
+ hb_font_t *font, /* May be NULL */
+ hb_buffer_serialize_format_t format);
HB_END_DECLS
diff --git a/third_party/harfbuzz-ng/src/hb-common.cc b/third_party/harfbuzz-ng/src/hb-common.cc
index 33a514d..9422555 100644
--- a/third_party/harfbuzz-ng/src/hb-common.cc
+++ b/third_party/harfbuzz-ng/src/hb-common.cc
@@ -363,8 +363,7 @@ bool
hb_user_data_array_t::set (hb_user_data_key_t *key,
void * data,
hb_destroy_func_t destroy,
- hb_bool_t replace,
- hb_mutex_t &lock)
+ hb_bool_t replace)
{
if (!key)
return false;
@@ -382,20 +381,13 @@ hb_user_data_array_t::set (hb_user_data_key_t *key,
}
void *
-hb_user_data_array_t::get (hb_user_data_key_t *key,
- hb_mutex_t &lock)
+hb_user_data_array_t::get (hb_user_data_key_t *key)
{
hb_user_data_item_t item = {NULL };
return items.find (key, &item, lock) ? item.data : NULL;
}
-void
-hb_user_data_array_t::finish (hb_mutex_t &lock)
-{
- items.finish (lock);
-}
-
/* hb_version */
diff --git a/third_party/harfbuzz-ng/src/hb-coretext.cc b/third_party/harfbuzz-ng/src/hb-coretext.cc
index 4152a39..8f94795 100644
--- a/third_party/harfbuzz-ng/src/hb-coretext.cc
+++ b/third_party/harfbuzz-ng/src/hb-coretext.cc
@@ -29,10 +29,6 @@
#define HB_SHAPER coretext
#include "hb-shaper-impl-private.hh"
-#define GlyphID GlyphID_mac
-#include <ApplicationServices/ApplicationServices.h>
-#undef GlyphID
-
#include "hb-coretext.h"
@@ -95,6 +91,14 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
free (data);
}
+CGFontRef
+hb_coretext_face_get_cg_font (hb_face_t *face)
+{
+ if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return NULL;
+ hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+ return face_data->cg_font;
+}
+
/*
* shaper font data
@@ -153,19 +157,19 @@ _hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_
{
}
-
-/*
- * shaper
- */
-
CTFontRef
hb_coretext_font_get_ct_font (hb_font_t *font)
{
- if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return 0;
+ if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return NULL;
hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
return font_data->ct_font;
}
+
+/*
+ * shaper
+ */
+
hb_bool_t
_hb_coretext_shape (hb_shape_plan_t *shape_plan,
hb_font_t *font,
@@ -212,26 +216,22 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
CFDictionaryRef attrs = CFDictionaryCreate (kCFAllocatorDefault,
(const void**) &kCTFontAttributeName,
(const void**) &font_data->ct_font,
- 1, // count of attributes
+ 1, /* count of attributes */
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- // TODO: support features
+ /* TODO: support features */
- // Now we can create an attributed string
CFAttributedStringRef attr_string = CFAttributedStringCreate (kCFAllocatorDefault, string_ref, attrs);
CFRelease (string_ref);
CFRelease (attrs);
- // Create the CoreText line from our string, then we're done with it
CTLineRef line = CTLineCreateWithAttributedString (attr_string);
CFRelease (attr_string);
- // and finally retrieve the glyph data and store into the gfxTextRun
CFArrayRef glyph_runs = CTLineGetGlyphRuns (line);
unsigned int num_runs = CFArrayGetCount (glyph_runs);
- // Iterate through the glyph runs.
bool success = true;
buffer->len = 0;
@@ -246,11 +246,9 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
buffer->ensure (buffer->len + num_glyphs);
- // retrieve the laid-out glyph data from the CTRun
-
- // Testing indicates that CTRunGetGlyphsPtr (almost?) always succeeds,
- // and so copying data to our own buffer with CTRunGetGlyphs will be
- // extremely rare.
+ /* Testing indicates that CTRunGetGlyphsPtr (almost?) always succeeds,
+ * and so copying data to our own buffer with CTRunGetGlyphs will be
+ * extremely rare. */
unsigned int scratch_size;
char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
@@ -294,7 +292,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
info->codepoint = glyphs[j];
info->cluster = string_indices[j];
- // currently, we do all x-positioning by setting the advance, we never use x-offset
+ /* Currently, we do all x-positioning by setting the advance, we never use x-offset. */
info->mask = advance;
info->var1.u32 = 0;
info->var2.u32 = positions[j].y;
@@ -316,12 +314,13 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
pos->y_offset = info->var2.u32;
}
- // Fix up clusters so that we never return out-of-order indices;
- // if core text has reordered glyphs, we'll merge them to the
- // beginning of the reordered cluster.
- // This does *not* mean we'll form the same clusters as Uniscribe
- // or the native OT backend, only that the cluster indices will be
- // non-decreasing in the output buffer.
+ /* Fix up clusters so that we never return out-of-order indices;
+ * if core text has reordered glyphs, we'll merge them to the
+ * beginning of the reordered cluster.
+ *
+ * This does *not* mean we'll form the same clusters as Uniscribe
+ * or the native OT backend, only that the cluster indices will be
+ * monotonic in the output buffer. */
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
unsigned int prev_cluster = 0;
for (unsigned int i = 0; i < count; i++) {
@@ -337,7 +336,6 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
prev_cluster = curr_cluster;
}
} else {
- // For RTL runs, we make them non-increasing instead.
unsigned int prev_cluster = (unsigned int)-1;
for (unsigned int i = 0; i < count; i++) {
unsigned int curr_cluster = buffer->info[i].cluster;
diff --git a/third_party/harfbuzz-ng/src/hb-coretext.h b/third_party/harfbuzz-ng/src/hb-coretext.h
index 0b34203..c4954fa 100644
--- a/third_party/harfbuzz-ng/src/hb-coretext.h
+++ b/third_party/harfbuzz-ng/src/hb-coretext.h
@@ -34,6 +34,9 @@
HB_BEGIN_DECLS
+CGFontRef
+hb_coretext_face_get_cg_font (hb_face_t *face);
+
CTFontRef
hb_coretext_font_get_ct_font (hb_font_t *font);
diff --git a/third_party/harfbuzz-ng/src/hb-fallback-shape.cc b/third_party/harfbuzz-ng/src/hb-fallback-shape.cc
index 3f9024f..bdc8a80 100644
--- a/third_party/harfbuzz-ng/src/hb-fallback-shape.cc
+++ b/third_party/harfbuzz-ng/src/hb-fallback-shape.cc
@@ -35,13 +35,13 @@
struct hb_fallback_shaper_face_data_t {};
hb_fallback_shaper_face_data_t *
-_hb_fallback_shaper_face_data_create (hb_face_t *face)
+_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
{
return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
-_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data)
+_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
{
}
@@ -53,13 +53,13 @@ _hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data)
struct hb_fallback_shaper_font_data_t {};
hb_fallback_shaper_font_data_t *
-_hb_fallback_shaper_font_data_create (hb_font_t *font)
+_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
{
return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
-_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data)
+_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
{
}
@@ -89,7 +89,7 @@ _hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_
*/
hb_bool_t
-_hb_fallback_shape (hb_shape_plan_t *shape_plan,
+_hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features HB_UNUSED,
@@ -98,7 +98,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan,
hb_codepoint_t space;
font->get_glyph (' ', 0, &space);
- buffer->guess_properties ();
+ buffer->guess_segment_properties ();
buffer->clear_positions ();
unsigned int count = buffer->len;
diff --git a/third_party/harfbuzz-ng/src/hb-font-private.hh b/third_party/harfbuzz-ng/src/hb-font-private.hh
index b6dafbf..48fbb0e 100644
--- a/third_party/harfbuzz-ng/src/hb-font-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-font-private.hh
@@ -100,6 +100,7 @@ struct hb_face_t {
unsigned int index;
mutable unsigned int upem;
+ mutable unsigned int num_glyphs;
struct hb_shaper_data_t shaper_data;
@@ -130,8 +131,16 @@ struct hb_face_t {
return upem;
}
+ inline unsigned int get_num_glyphs (void) const
+ {
+ if (unlikely (num_glyphs == (unsigned int) -1))
+ load_num_glyphs ();
+ return num_glyphs;
+ }
+
private:
HB_INTERNAL void load_upem (void) const;
+ HB_INTERNAL void load_num_glyphs (void) const;
};
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
diff --git a/third_party/harfbuzz-ng/src/hb-font.cc b/third_party/harfbuzz-ng/src/hb-font.cc
index 0627032..b59fdeb 100644
--- a/third_party/harfbuzz-ng/src/hb-font.cc
+++ b/third_party/harfbuzz-ng/src/hb-font.cc
@@ -34,6 +34,7 @@
#include "hb-blob.h"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
+#include "hb-ot-maxp-table.hh"
#include "hb-cache-private.hh"
@@ -520,6 +521,7 @@ static const hb_face_t _hb_face_nil = {
0, /* index */
1000, /* upem */
+ 0, /* num_glyphs */
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
@@ -549,6 +551,7 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
face->destroy = destroy;
face->upem = 0;
+ face->num_glyphs = (unsigned int) -1;
return face;
}
@@ -736,7 +739,6 @@ hb_face_get_upem (hb_face_t *face)
return face->get_upem ();
}
-
void
hb_face_t::load_upem (void) const
{
@@ -746,6 +748,31 @@ hb_face_t::load_upem (void) const
hb_blob_destroy (head_blob);
}
+void
+hb_face_set_glyph_count (hb_face_t *face,
+ unsigned int glyph_count)
+{
+ if (hb_object_is_inert (face))
+ return;
+
+ face->num_glyphs = glyph_count;
+}
+
+unsigned int
+hb_face_get_glyph_count (hb_face_t *face)
+{
+ return face->get_num_glyphs ();
+}
+
+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));
+ 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);
+}
+
/*
* hb_font_t
diff --git a/third_party/harfbuzz-ng/src/hb-font.h b/third_party/harfbuzz-ng/src/hb-font.h
index d796856..88d4895 100644
--- a/third_party/harfbuzz-ng/src/hb-font.h
+++ b/third_party/harfbuzz-ng/src/hb-font.h
@@ -105,6 +105,13 @@ hb_face_set_upem (hb_face_t *face,
unsigned int
hb_face_get_upem (hb_face_t *face);
+void
+hb_face_set_glyph_count (hb_face_t *face,
+ unsigned int glyph_count);
+
+unsigned int
+hb_face_get_glyph_count (hb_face_t *face);
+
/*
* hb_font_funcs_t
diff --git a/third_party/harfbuzz-ng/src/hb-ft.cc b/third_party/harfbuzz-ng/src/hb-ft.cc
index 9ac556e..6198185 100644
--- a/third_party/harfbuzz-ng/src/hb-ft.cc
+++ b/third_party/harfbuzz-ng/src/hb-ft.cc
@@ -242,7 +242,7 @@ hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED,
FT_Face ft_face = (FT_Face) font_data;
hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size);
- if (!ret)
+ if (!ret || (size && !*name))
snprintf (name, size, "gid%u", glyph);
return ret;
diff --git a/third_party/harfbuzz-ng/src/hb-glib.cc b/third_party/harfbuzz-ng/src/hb-glib.cc
index 0462758..676e660 100644
--- a/third_party/harfbuzz-ng/src/hb-glib.cc
+++ b/third_party/harfbuzz-ng/src/hb-glib.cc
@@ -334,7 +334,7 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
}
static unsigned int
-hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
+hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t u,
hb_codepoint_t *decomposed,
void *user_data HB_UNUSED)
diff --git a/third_party/harfbuzz-ng/src/hb-graphite2.cc b/third_party/harfbuzz-ng/src/hb-graphite2.cc
index 6c890d4..16ef9a4 100644
--- a/third_party/harfbuzz-ng/src/hb-graphite2.cc
+++ b/third_party/harfbuzz-ng/src/hb-graphite2.cc
@@ -113,7 +113,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face)
hb_blob_destroy (silf_blob);
data->face = face;
- data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_default);
+ data->grface = gr_make_face (data, &hb_graphite2_get_table, gr_face_preloadAll);
if (unlikely (!data->grface)) {
free (data);
@@ -141,6 +141,13 @@ _hb_graphite2_shaper_face_data_destroy (hb_graphite2_shaper_face_data_t *data)
free (data);
}
+gr_face *
+hb_graphite2_face_get_gr_face (hb_face_t *face)
+{
+ if (unlikely (!hb_graphite2_shaper_face_data_ensure (face))) return NULL;
+ return HB_SHAPER_DATA_GET (face)->grface;
+}
+
/*
* shaper font data
@@ -168,6 +175,13 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_shaper_font_data_t *data)
gr_font_destroy (data);
}
+gr_font *
+hb_graphite2_font_get_gr_font (hb_font_t *font)
+{
+ if (unlikely (!hb_graphite2_shaper_font_data_ensure (font))) return NULL;
+ return HB_SHAPER_DATA_GET (font);
+}
+
/*
* shaper shape_plan data
@@ -311,10 +325,18 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
}
ci++;
- buffer->clear_output ();
+ //buffer->clear_output ();
for (unsigned int i = 0; i < ci; ++i)
- buffer->replace_glyphs (clusters[i].num_chars, clusters[i].num_glyphs, gids + clusters[i].base_glyph);
- buffer->swap_buffers ();
+ {
+ for (unsigned int j = 0; j < clusters[i].num_glyphs; ++j)
+ {
+ hb_glyph_info_t *info = &buffer->info[clusters[i].base_glyph + j];
+ info->codepoint = gids[clusters[i].base_glyph + j];
+ info->cluster = gr_cinfo_base(gr_seg_cinfo(seg, clusters[i].base_char));
+ }
+ }
+ buffer->len = glyph_count;
+ //buffer->swap_buffers ();
if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
curradvx = gr_seg_advance_X(seg);
diff --git a/third_party/harfbuzz-ng/src/hb-graphite2.h b/third_party/harfbuzz-ng/src/hb-graphite2.h
index 8122495..bea68f9 100644
--- a/third_party/harfbuzz-ng/src/hb-graphite2.h
+++ b/third_party/harfbuzz-ng/src/hb-graphite2.h
@@ -33,7 +33,13 @@ HB_BEGIN_DECLS
#define HB_GRAPHITE2_TAG_SILF HB_TAG('S','i','l','f')
-/* TODO add gr_font/face etc getters and other glue API */
+
+gr_face *
+hb_graphite2_face_get_gr_face (hb_face_t *face);
+
+gr_font *
+hb_graphite2_font_get_gr_font (hb_font_t *font);
+
HB_END_DECLS
diff --git a/third_party/harfbuzz-ng/src/hb-icu-le.cc b/third_party/harfbuzz-ng/src/hb-icu-le.cc
index d73752d..c05d330 100644
--- a/third_party/harfbuzz-ng/src/hb-icu-le.cc
+++ b/third_party/harfbuzz-ng/src/hb-icu-le.cc
@@ -43,13 +43,13 @@
struct hb_icu_le_shaper_face_data_t {};
hb_icu_le_shaper_face_data_t *
-_hb_icu_le_shaper_face_data_create (hb_face_t *face)
+_hb_icu_le_shaper_face_data_create (hb_face_t *face HB_UNUSED)
{
return (hb_icu_le_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
-_hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data)
+_hb_icu_le_shaper_face_data_destroy (hb_icu_le_shaper_face_data_t *data HB_UNUSED)
{
}
@@ -88,7 +88,7 @@ _hb_icu_le_shaper_font_data_destroy (hb_icu_le_shaper_font_data_t *data)
struct hb_icu_le_shaper_shape_plan_data_t {};
hb_icu_le_shaper_shape_plan_data_t *
-_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
+_hb_icu_le_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
@@ -115,7 +115,7 @@ _hb_icu_le_shape (hb_shape_plan_t *shape_plan,
LEFontInstance *font_instance = HB_SHAPER_DATA_GET (font);
le_int32 script_code = hb_icu_script_from_script (shape_plan->props.script);
le_int32 language_code = -1 /* TODO */;
- le_int32 typography_flags = 3; // essential for ligatures and kerning
+ le_int32 typography_flags = 3; /* Needed for ligatures and kerning */
LEErrorCode status = LE_NO_ERROR;
le_engine *le = le_create ((const le_font *) font_instance,
script_code,
diff --git a/third_party/harfbuzz-ng/src/hb-object-private.hh b/third_party/harfbuzz-ng/src/hb-object-private.hh
index c48f242..8a9ae34d 100644
--- a/third_party/harfbuzz-ng/src/hb-object-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-object-private.hh
@@ -65,7 +65,7 @@ struct hb_reference_count_t
/* user_data */
-#define HB_USER_DATA_ARRAY_INIT {HB_LOCKABLE_SET_INIT}
+#define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT}
struct hb_user_data_array_t
{
/* TODO Add tracing. */
@@ -81,20 +81,19 @@ struct hb_user_data_array_t
void finish (void) { if (destroy) destroy (data); }
};
+ hb_mutex_t lock;
hb_lockable_set_t<hb_user_data_item_t, hb_mutex_t> items;
- inline void init (void) { items.init (); }
+ inline void init (void) { lock.init (); items.init (); }
HB_INTERNAL bool set (hb_user_data_key_t *key,
void * data,
hb_destroy_func_t destroy,
- hb_bool_t replace,
- hb_mutex_t &lock);
+ hb_bool_t replace);
- HB_INTERNAL void *get (hb_user_data_key_t *key,
- hb_mutex_t &lock);
+ HB_INTERNAL void *get (hb_user_data_key_t *key);
- HB_INTERNAL void finish (hb_mutex_t &lock);
+ inline void finish (void) { items.finish (lock); lock.finish (); }
};
@@ -103,10 +102,9 @@ struct hb_user_data_array_t
struct hb_object_header_t
{
hb_reference_count_t ref_count;
- hb_mutex_t mutex;
hb_user_data_array_t user_data;
-#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_MUTEX_INIT, HB_USER_DATA_ARRAY_INIT}
+#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT}
static inline void *create (unsigned int size) {
hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size);
@@ -119,7 +117,6 @@ struct hb_object_header_t
inline void init (void) {
ref_count.init (1);
- mutex.init ();
user_data.init ();
}
@@ -140,20 +137,11 @@ struct hb_object_header_t
return false;
ref_count.finish (); /* Do this before user_data */
- user_data.finish (mutex);
- mutex.finish ();
+ user_data.finish ();
return true;
}
- inline void lock (void) {
- mutex.lock ();
- }
-
- inline void unlock (void) {
- mutex.unlock ();
- }
-
inline bool set_user_data (hb_user_data_key_t *key,
void * data,
hb_destroy_func_t destroy_func,
@@ -161,14 +149,14 @@ struct hb_object_header_t
if (unlikely (!this || this->is_inert ()))
return false;
- return user_data.set (key, data, destroy_func, replace, mutex);
+ return user_data.set (key, data, destroy_func, replace);
}
inline void *get_user_data (hb_user_data_key_t *key) {
if (unlikely (!this || this->is_inert ()))
return NULL;
- return user_data.get (key, mutex);
+ return user_data.get (key);
}
inline void trace (const char *function) const {
@@ -219,18 +207,6 @@ static inline bool hb_object_destroy (Type *obj)
return obj->header.destroy ();
}
template <typename Type>
-static inline void hb_object_lock (Type *obj)
-{
- hb_object_trace (obj, HB_FUNC);
- return obj->header.lock ();
-}
-template <typename Type>
-static inline void hb_object_unlock (Type *obj)
-{
- hb_object_trace (obj, HB_FUNC);
- return obj->header.unlock ();
-}
-template <typename Type>
static inline bool hb_object_set_user_data (Type *obj,
hb_user_data_key_t *key,
void * data,
diff --git a/third_party/harfbuzz-ng/src/hb-old.cc b/third_party/harfbuzz-ng/src/hb-old.cc
index 529bffa..a7ea8ed 100644
--- a/third_party/harfbuzz-ng/src/hb-old.cc
+++ b/third_party/harfbuzz-ng/src/hb-old.cc
@@ -100,7 +100,7 @@ hb_old_convertStringToGlyphIndices (HB_Font old_font,
glyphs[i] = u;
}
- *numGlyphs = length; // XXX
+ *numGlyphs = length; /* XXX */
return true;
}
@@ -110,7 +110,7 @@ hb_old_getGlyphAdvances (HB_Font old_font,
const HB_Glyph *glyphs,
hb_uint32 numGlyphs,
HB_Fixed *advances,
- int flags /*HB_ShaperFlag*/)
+ int flags /*HB_ShaperFlag*/ HB_UNUSED)
{
hb_font_t *font = (hb_font_t *) old_font->userData;
@@ -123,7 +123,7 @@ hb_old_canRender (HB_Font old_font,
const HB_UChar16 *string,
hb_uint32 length)
{
- return true; // TODO
+ return true; /* TODO */
}
static HB_Error
@@ -135,7 +135,7 @@ hb_old_getPointInOutline (HB_Font old_font,
HB_Fixed *ypos,
hb_uint32 *nPoints)
{
- return HB_Err_Ok; // TODO
+ return HB_Err_Ok; /* TODO */
}
static void
@@ -230,8 +230,8 @@ _hb_old_shaper_font_data_create (hb_font_t *font)
data->klass = &hb_old_font_class;
data->x_ppem = font->x_ppem;
data->y_ppem = font->y_ppem;
- data->x_scale = font->x_scale; // XXX
- data->y_scale = font->y_scale; // XXX
+ data->x_scale = font->x_scale; /* XXX */
+ data->y_scale = font->y_scale; /* XXX */
data->userData = font;
return data;
@@ -251,15 +251,15 @@ _hb_old_shaper_font_data_destroy (hb_old_shaper_font_data_t *data)
struct hb_old_shaper_shape_plan_data_t {};
hb_old_shaper_shape_plan_data_t *
-_hb_old_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
- const hb_feature_t *user_features,
- unsigned int num_user_features)
+_hb_old_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
+ const hb_feature_t *user_features HB_UNUSED,
+ unsigned int num_user_features HB_UNUSED)
{
return (hb_old_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
-_hb_old_shaper_shape_plan_data_destroy (hb_old_shaper_shape_plan_data_t *data)
+_hb_old_shaper_shape_plan_data_destroy (hb_old_shaper_shape_plan_data_t *data HB_UNUSED)
{
}
@@ -269,7 +269,7 @@ _hb_old_shaper_shape_plan_data_destroy (hb_old_shaper_shape_plan_data_t *data)
*/
hb_bool_t
-_hb_old_shape (hb_shape_plan_t *shape_plan,
+_hb_old_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
@@ -369,7 +369,7 @@ retry:
*p = MIN (*p, buffer->info[i].cluster);
}
for (unsigned int i = 1; i < num_glyphs; i++)
- if (vis_clusters[i] == -1)
+ if (vis_clusters[i] == (uint32_t) -1)
vis_clusters[i] = vis_clusters[i - 1];
#undef utf16_index
diff --git a/third_party/harfbuzz-ng/src/hb-open-file-private.hh b/third_party/harfbuzz-ng/src/hb-open-file-private.hh
index 31fedfb..250504a 100644
--- a/third_party/harfbuzz-ng/src/hb-open-file-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-open-file-private.hh
@@ -54,7 +54,7 @@ struct TTCHeader;
typedef struct TableRecord
{
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -103,7 +103,7 @@ typedef struct OffsetTable
public:
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
}
@@ -131,7 +131,7 @@ struct TTCHeaderVersion1
inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (table.sanitize (c, this));
}
@@ -170,7 +170,7 @@ struct TTCHeader
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false);
switch (u.header.version.major) {
case 2: /* version 2 is compatible with version 1 */
@@ -232,7 +232,7 @@ struct OpenTypeFontFile
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false);
switch (u.tag) {
case CFFTag: /* All the non-collection tags */
@@ -255,7 +255,7 @@ struct OpenTypeFontFile
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OPEN_FILE_PRIVATE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-open-type-private.hh b/third_party/harfbuzz-ng/src/hb-open-type-private.hh
index 3067b90..5bfeb16 100644
--- a/third_party/harfbuzz-ng/src/hb-open-type-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-open-type-private.hh
@@ -37,6 +37,7 @@
namespace OT {
+
/*
* Casts
*/
@@ -138,13 +139,13 @@ static const void *_NullPool[64 / sizeof (void *)];
/* Generic nul-content Null objects. */
template <typename Type>
static inline const Type& Null (void) {
- ASSERT_STATIC (Type::min_size <= sizeof (_NullPool));
+ ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool));
return *CastP<Type> (_NullPool);
}
/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
#define DEFINE_NULL_DATA(Type, data) \
-static const char _Null##Type[Type::min_size + 1] = data; /* +1 is for nul-termination in data */ \
+static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
template <> \
inline const Type& Null<Type> (void) { \
return *CastP<Type> (_Null##Type); \
@@ -165,12 +166,22 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
#endif
-#define TRACE_SANITIZE() \
- hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&c->debug_depth, "SANITIZE", this, HB_FUNC, "");
+#define TRACE_SANITIZE(this) \
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "");
struct hb_sanitize_context_t
{
+ inline const char *get_name (void) { return "SANITIZE"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE;
+ typedef bool return_t;
+ template <typename T>
+ inline return_t process (const T &obj) { return obj.sanitize (this); }
+ static return_t default_return_value (void) { return true; }
+ bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; }
+
inline void init (hb_blob_t *b)
{
this->blob = hb_blob_reference (b);
@@ -205,10 +216,11 @@ struct hb_sanitize_context_t
{
const char *p = (const char *) base;
- hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&this->debug_depth, "SANITIZE", this->blob, NULL,
- "check_range [%p..%p] (%d bytes) in [%p..%p]",
- p, p + len, len,
- this->start, this->end);
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
+ (&this->debug_depth, "SANITIZE", this->blob, NULL,
+ "check_range [%p..%p] (%d bytes) in [%p..%p]",
+ p, p + len, len,
+ this->start, this->end);
return TRACE_RETURN (likely (this->start <= p && p <= this->end && (unsigned int) (this->end - p) >= len));
}
@@ -218,10 +230,11 @@ struct hb_sanitize_context_t
const char *p = (const char *) base;
bool overflows = _hb_unsigned_int_mul_overflows (len, record_size);
- hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&this->debug_depth, "SANITIZE", this->blob, NULL,
- "check_array [%p..%p] (%d*%d=%ld bytes) in [%p..%p]",
- p, p + (record_size * len), record_size, len, (unsigned long) record_size * len,
- this->start, this->end);
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
+ (&this->debug_depth, "SANITIZE", this->blob, NULL,
+ "check_array [%p..%p] (%d*%d=%ld bytes) in [%p..%p]",
+ p, p + (record_size * len), record_size, len, (unsigned long) record_size * len,
+ this->start, this->end);
return TRACE_RETURN (likely (!overflows && this->check_range (base, record_size * len)));
}
@@ -237,11 +250,13 @@ struct hb_sanitize_context_t
const char *p = (const char *) base;
this->edit_count++;
- hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&this->debug_depth, "SANITIZE", this->blob, NULL,
- "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
- this->edit_count,
- p, p + len, len,
- this->start, this->end);
+ hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace
+ (&this->debug_depth, "SANITIZE", this->blob, NULL,
+ "may_edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s",
+ this->edit_count,
+ p, p + len, len,
+ this->start, this->end,
+ this->writable ? "GRANTED" : "DENIED");
return TRACE_RETURN (this->writable);
}
@@ -336,8 +351,10 @@ struct Sanitizer
#endif
-#define TRACE_SERIALIZE() \
- hb_auto_trace_t<HB_DEBUG_SERIALIZE> trace (&c->debug_depth, "SERIALIZE", c, HB_FUNC, "");
+#define TRACE_SERIALIZE(this) \
+ hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
+ (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
+ "");
struct hb_serialize_context_t
@@ -518,32 +535,43 @@ struct BEInt<Type, 4>
inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o); }
private: uint8_t v[4];
};
+template <typename Type>
+struct BEInt<Type, 3>
+{
+ public:
+ inline void set (Type i) { hb_be_uint24_put (v,i); }
+ inline operator Type (void) const { return hb_be_uint24_get (v); }
+ inline bool operator == (const BEInt<Type, 3>& o) const { return hb_be_uint24_eq (v, o.v); }
+ inline bool operator != (const BEInt<Type, 3>& o) const { return !(*this == o); }
+ private: uint8_t v[3];
+};
/* Integer types in big-endian order and no alignment requirement */
-template <typename Type>
+template <typename Type, unsigned int Size>
struct IntType
{
inline void set (Type i) { v.set (i); }
inline operator Type(void) const { return v; }
- inline bool operator == (const IntType<Type> &o) const { return v == o.v; }
- inline bool operator != (const IntType<Type> &o) const { return v != o.v; }
- static inline int cmp (const IntType<Type> *a, const IntType<Type> *b) { return b->cmp (*a); }
- inline int cmp (IntType<Type> va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
+ inline bool operator == (const IntType<Type,Size> &o) const { return v == o.v; }
+ inline bool operator != (const IntType<Type,Size> &o) const { return v != o.v; }
+ static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
+ inline int cmp (IntType<Type,Size> va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (likely (c->check_struct (this)));
}
protected:
- BEInt<Type, sizeof (Type)> v;
+ BEInt<Type, Size> v;
public:
- DEFINE_SIZE_STATIC (sizeof (Type));
+ DEFINE_SIZE_STATIC (Size);
};
-typedef IntType<uint16_t> USHORT; /* 16-bit unsigned integer. */
-typedef IntType<int16_t> SHORT; /* 16-bit signed integer. */
-typedef IntType<uint32_t> ULONG; /* 32-bit unsigned integer. */
-typedef IntType<int32_t> LONG; /* 32-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<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
typedef SHORT FWORD;
@@ -556,7 +584,7 @@ typedef USHORT UFWORD;
struct LONGDATETIME
{
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (likely (c->check_struct (this)));
}
private:
@@ -620,7 +648,7 @@ struct FixedVersion
inline uint32_t to_int (void) const { return (major << 16) + minor; }
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -660,7 +688,7 @@ struct GenericOffsetTo : OffsetType
}
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
unsigned int offset = *this;
if (unlikely (!offset)) return TRACE_RETURN (true);
@@ -669,7 +697,7 @@ struct GenericOffsetTo : OffsetType
}
template <typename T>
inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
unsigned int offset = *this;
if (unlikely (!offset)) return TRACE_RETURN (true);
@@ -677,7 +705,13 @@ struct GenericOffsetTo : OffsetType
return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
}
- private:
+ inline bool try_set (hb_sanitize_context_t *c, const OffsetType &v) {
+ if (c->may_edit (this, this->static_size)) {
+ this->set (v);
+ return true;
+ }
+ return false;
+ }
/* Set the offset to Null */
inline bool neuter (hb_sanitize_context_t *c) {
if (c->may_edit (this, this->static_size)) {
@@ -733,7 +767,7 @@ struct GenericArrayOf
inline bool serialize (hb_serialize_context_t *c,
unsigned int items_len)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
len.set (items_len); /* TODO(serialize) Overflow? */
if (unlikely (!c->extend (*this))) return TRACE_RETURN (false);
@@ -744,7 +778,7 @@ struct GenericArrayOf
Supplier<Type> &items,
unsigned int items_len)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false);
for (unsigned int i = 0; i < items_len; i++)
array[i] = items[i];
@@ -753,7 +787,7 @@ struct GenericArrayOf
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
/* Note: for structs that do not reference other structs,
@@ -768,7 +802,7 @@ struct GenericArrayOf
return TRACE_RETURN (true);
}
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
@@ -778,7 +812,7 @@ struct GenericArrayOf
}
template <typename T>
inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
@@ -789,7 +823,7 @@ struct GenericArrayOf
private:
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len));
}
@@ -831,12 +865,12 @@ struct OffsetListOf : OffsetArrayOf<Type>
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this));
}
template <typename T>
inline bool sanitize (hb_sanitize_context_t *c, T user_data) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data));
}
};
@@ -859,7 +893,7 @@ struct HeadlessArrayOf
Supplier<Type> &items,
unsigned int items_len)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
len.set (items_len); /* TODO(serialize) Overflow? */
if (unlikely (!items_len)) return TRACE_RETURN (true);
@@ -876,7 +910,7 @@ struct HeadlessArrayOf
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
/* Note: for structs that do not reference other structs,
@@ -922,7 +956,7 @@ struct SortedArrayOf : ArrayOf<Type> {
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OPEN_TYPE_PRIVATE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-head-table.hh b/third_party/harfbuzz-ng/src/hb-ot-head-table.hh
index 0934168..3a94512 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-head-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-head-table.hh
@@ -47,12 +47,12 @@ struct head
inline unsigned int get_upem (void) const {
unsigned int upem = unitsPerEm;
- /* If no valid head table found, assume 1000, which matches typicaly Type1 usage. */
+ /* If no valid head table found, assume 1000, which matches typical Type1 usage. */
return 16 <= upem && upem <= 16384 ? upem : 1000;
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
}
@@ -143,7 +143,7 @@ struct head
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_HEAD_TABLE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-hhea-table.hh b/third_party/harfbuzz-ng/src/hb-ot-hhea-table.hh
index 5009e6b..2b89c4e 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-hhea-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-hhea-table.hh
@@ -45,7 +45,7 @@ struct hhea
static const hb_tag_t Tag = HB_OT_TAG_hhea;
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
}
@@ -91,7 +91,7 @@ struct hhea
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_HHEA_TABLE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/third_party/harfbuzz-ng/src/hb-ot-hmtx-table.hh
index feb6016..b94337d 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-hmtx-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-hmtx-table.hh
@@ -53,7 +53,7 @@ struct hmtx
static const hb_tag_t Tag = HB_OT_TAG_hmtx;
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
/* We don't check for anything specific here. The users of the
* struct do all the hard work... */
return TRACE_RETURN (true);
@@ -86,7 +86,7 @@ struct hmtx
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_HMTX_TABLE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh
index f5a067a..e6018db 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh
@@ -60,9 +60,14 @@ struct Record
return tag.cmp (a);
}
+ struct sanitize_closure_t {
+ hb_tag_t tag;
+ void *list_base;
+ };
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
- TRACE_SANITIZE ();
- return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base));
+ TRACE_SANITIZE (this);
+ const sanitize_closure_t closure = {tag, base};
+ return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure));
}
Tag tag; /* 4-byte Tag identifier */
@@ -115,7 +120,7 @@ struct RecordListOf : RecordArrayOf<Type>
{ return this+RecordArrayOf<Type>::operator [](i).offset; }
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this));
}
};
@@ -129,7 +134,7 @@ struct RangeRecord
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -192,8 +197,9 @@ struct LangSys
return reqFeatureIndex;;
}
- inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<LangSys>::sanitize_closure_t * = NULL) {
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c));
}
@@ -230,8 +236,9 @@ struct Script
inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
- inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<Script>::sanitize_closure_t * = NULL) {
+ TRACE_SANITIZE (this);
return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
}
@@ -249,6 +256,219 @@ struct Script
typedef RecordListOf<Script> ScriptList;
+/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+struct FeatureParamsSize
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
+
+ /* This subtable has some "history", if you will. Some earlier versions of
+ * Adobe tools calculated the offset of the FeatureParams sutable from the
+ * beginning of the FeatureList table! Now, that is dealt with in the
+ * Feature implementation. But we still need to be able to tell junk from
+ * real data. Note: We don't check that the nameID actually exists.
+ *
+ * Read Roberts wrote on 9/15/06 on opentype-list@indx.co.uk :
+ *
+ * Yes, it is correct that a new version of the AFDKO (version 2.0) will be
+ * coming out soon, and that the makeotf program will build a font with a
+ * 'size' feature that is correct by the specification.
+ *
+ * The specification for this feature tag is in the "OpenType Layout Tag
+ * Registry". You can see a copy of this at:
+ * http://partners.adobe.com/public/developer/opentype/index_tag8.html#size
+ *
+ * Here is one set of rules to determine if the 'size' feature is built
+ * correctly, or as by the older versions of MakeOTF. You may be able to do
+ * 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
+ * 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
+ * beginning of the 'size' Feature table.
+ *
+ * If "design size" == 0:
+ * fails check
+ *
+ * Else if ("subfamily identifier" == 0 and
+ * "range start" == 0 and
+ * "range end" == 0 and
+ * "range start" == 0 and
+ * "menu name ID" == 0)
+ * passes check: this is the format used when there is a design size
+ * specified, but there is no recommended size range.
+ *
+ * Else if ("design size" < "range start" or
+ * "design size" > "range end" or
+ * "range end" <= "range start" or
+ * "menu name ID" < 256 or
+ * "menu name ID" > 32767 or
+ * menu name ID is not a name ID which is actually in the name table)
+ * fails test
+ * Else
+ * passes test.
+ */
+
+ if (!designSize)
+ return TRACE_RETURN (false);
+ else if (subfamilyID == 0 &&
+ subfamilyNameID == 0 &&
+ rangeStart == 0 &&
+ rangeEnd == 0)
+ return TRACE_RETURN (true);
+ else if (designSize < rangeStart ||
+ designSize > rangeEnd ||
+ subfamilyNameID < 256 ||
+ subfamilyNameID > 32767)
+ return TRACE_RETURN (false);
+ else
+ return TRACE_RETURN (true);
+ }
+
+ USHORT 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
+ * as an identifier that associates fonts
+ * in a subfamily. All fonts which share a
+ * Preferred or Font Family name and which
+ * differ only by size range shall have the
+ * same subfamily value, and no fonts which
+ * differ in weight or style shall have the
+ * 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
+ * value must be set in the range 256 - 32767
+ * (inclusive). It records the value of a
+ * field in the name table, which must
+ * contain English-language strings encoded
+ * in Windows Unicode and Macintosh Roman,
+ * and may contain additional strings
+ * localized to other scripts and languages.
+ * Each of these strings is the name an
+ * application should use, in combination
+ * with the family name, to represent the
+ * subfamily in a menu. Applications will
+ * choose the appropriate version based on
+ * their selection criteria. */
+ USHORT rangeStart; /* Large end of the recommended usage range
+ * (inclusive), stored in 720/inch units
+ * (decipoints). */
+ USHORT rangeEnd; /* Small end of the recommended usage range
+ (exclusive), stored in 720/inch units
+ * (decipoints). */
+ public:
+ DEFINE_SIZE_STATIC (10);
+};
+
+/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */
+struct FeatureParamsStylisticSet
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ /* Right now minorVersion is at zero. Which means, any table supports
+ * the uiNameID field. */
+ return TRACE_RETURN (c->check_struct (this));
+ }
+
+ USHORT minorVersion; /* (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
+ * string (or strings, for multiple languages)
+ * for a user-interface label for this
+ * feature. The values of uiLabelNameId and
+ * sampleTextNameId are expected to be in the
+ * font-specific name ID range (256-32767),
+ * though that is not a requirement in this
+ * Feature Parameters specification. The
+ * user-interface label for the feature can
+ * be provided in multiple languages. An
+ * English string should be included as a
+ * fallback. The string should be kept to a
+ * minimal length to fit comfortably with
+ * different application interfaces. */
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct FeatureParamsCharacterVariants
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) &&
+ characters.sanitize (c));
+ }
+
+ USHORT format; /* Format number is set to 0. */
+ USHORT 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 NULL.) */
+ USHORT 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
+ * NULL.) */
+ USHORT sampleTextNameID; /* The ‘name’ table name ID that
+ * specifies sample text that
+ * illustrates the effect of this
+ * feature. (May be NULL.) */
+ USHORT numNamedParameters; /* Number of named parameters. (May
+ * be zero.) */
+ USHORT firstParamUILabelNameID;/* The first ‘name’ table name ID
+ * used to specify strings for
+ * user-interface labels for the
+ * feature parameters. (Must be zero
+ * if numParameters is zero.) */
+ ArrayOf<UINT24>
+ characters; /* Array of the Unicode Scalar Value
+ * of the characters for which this
+ * feature provides glyph variants.
+ * (May be zero.) */
+ public:
+ DEFINE_SIZE_ARRAY (14, characters);
+};
+
+struct FeatureParams
+{
+ inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) {
+ TRACE_SANITIZE (this);
+ if (tag == HB_TAG ('s','i','z','e'))
+ return TRACE_RETURN (u.size.sanitize (c));
+ if ((tag & 0xFFFF0000) == HB_TAG ('s','s','\0','\0')) /* ssXX */
+ return TRACE_RETURN (u.stylisticSet.sanitize (c));
+ if ((tag & 0xFFFF0000) == HB_TAG ('c','v','\0','\0')) /* cvXX */
+ return TRACE_RETURN (u.characterVariants.sanitize (c));
+ return TRACE_RETURN (true);
+ }
+
+ inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const
+ {
+ if (tag == HB_TAG ('s','i','z','e'))
+ return u.size;
+ return Null(FeatureParamsSize);
+ }
+
+ private:
+ union {
+ FeatureParamsSize size;
+ FeatureParamsStylisticSet stylisticSet;
+ FeatureParamsCharacterVariants characterVariants;
+ } u;
+ DEFINE_SIZE_STATIC (17);
+};
+
struct Feature
{
inline unsigned int get_lookup_count (void) const
@@ -260,12 +480,54 @@ struct Feature
unsigned int *lookup_tags /* OUT */) const
{ return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
- inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
- return TRACE_RETURN (c->check_struct (this) && lookupIndex.sanitize (c));
+ inline const FeatureParams &get_feature_params (void) const
+ { return this+featureParams; }
+
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<Feature>::sanitize_closure_t *closure) {
+ TRACE_SANITIZE (this);
+ if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
+ return TRACE_RETURN (false);
+
+ /* Some earlier versions of Adobe tools calculated the offset of the
+ * FeatureParams subtable from the beginning of the FeatureList table!
+ *
+ * If sanitizing "failed" for the FeatureParams subtable, try it with the
+ * alternative location. We would know sanitize "failed" if old value
+ * of the offset was non-zero, but it's zeroed now.
+ *
+ * Only do this for the 'size' feature, since at the time of the faulty
+ * Adobe tools, only the 'size' feature had FeatureParams defined.
+ */
+
+ Offset orig_offset = featureParams;
+ if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)))
+ return TRACE_RETURN (false);
+
+ if (likely (!orig_offset))
+ return TRACE_RETURN (true);
+
+ if (featureParams == 0 && closure &&
+ closure->tag == HB_TAG ('s','i','z','e') &&
+ closure->list_base && closure->list_base < this)
+ {
+ unsigned int new_offset_int = (unsigned int) orig_offset -
+ ((char *) this - (char *) closure->list_base);
+
+ Offset new_offset;
+ /* Check that it did not overflow. */
+ new_offset.set (new_offset_int);
+ if (new_offset == new_offset_int &&
+ featureParams.try_set (c, new_offset) &&
+ !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))
+ return TRACE_RETURN (false);
+ }
+
+ return TRACE_RETURN (true);
}
- Offset featureParams; /* Offset to Feature Parameters table (if one
+ OffsetTo<FeatureParams>
+ featureParams; /* Offset to Feature Parameters table (if one
* has been defined for the feature), relative
* to the beginning of the Feature Table; = Null
* if not required */
@@ -318,7 +580,7 @@ struct Lookup
uint32_t lookup_props,
unsigned int num_subtables)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
lookupType.set (lookup_type);
lookupFlag.set (lookup_props & 0xFFFF);
@@ -332,7 +594,7 @@ struct Lookup
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
/* Real sanitize of the subtables is done by GSUB/GPOS/... */
if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false);
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
@@ -377,7 +639,7 @@ struct CoverageFormat1
Supplier<GlyphID> &glyphs,
unsigned int num_glyphs)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
glyphArray.len.set (num_glyphs);
if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false);
@@ -388,7 +650,7 @@ struct CoverageFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (glyphArray.sanitize (c));
}
@@ -403,6 +665,8 @@ struct CoverageFormat1
glyphs->add (glyphArray[i]);
}
+ public:
+ /* Older compilers need this to be public. */
struct Iter {
inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
inline bool more (void) { return i < c->glyphArray.len; }
@@ -414,6 +678,7 @@ struct CoverageFormat1
const struct CoverageFormat1 *c;
unsigned int i;
};
+ private:
protected:
USHORT coverageFormat; /* Format identifier--format = 1 */
@@ -442,7 +707,7 @@ struct CoverageFormat2
Supplier<GlyphID> &glyphs,
unsigned int num_glyphs)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
if (unlikely (!num_glyphs)) return TRACE_RETURN (true);
@@ -471,7 +736,7 @@ struct CoverageFormat2
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (rangeRecord.sanitize (c));
}
@@ -497,6 +762,8 @@ struct CoverageFormat2
rangeRecord[i].add_coverage (glyphs);
}
+ public:
+ /* Older compilers need this to be public. */
struct Iter {
inline void init (const CoverageFormat2 &c_) {
c = &c_;
@@ -522,6 +789,7 @@ struct CoverageFormat2
const struct CoverageFormat2 *c;
unsigned int i, j, coverage;
};
+ private:
protected:
USHORT coverageFormat; /* Format identifier--format = 2 */
@@ -535,8 +803,6 @@ struct CoverageFormat2
struct Coverage
{
- inline unsigned int operator () (hb_codepoint_t glyph_id) const { return get_coverage (glyph_id); }
-
inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
{
switch (u.format) {
@@ -550,7 +816,7 @@ struct Coverage
Supplier<GlyphID> &glyphs,
unsigned int num_glyphs)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
unsigned int num_ranges = 1;
for (unsigned int i = 1; i < num_glyphs; i++)
@@ -565,7 +831,7 @@ struct Coverage
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -676,10 +942,18 @@ struct ClassDefFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c));
}
+ template <typename set_t>
+ inline void 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);
+ }
+
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
unsigned int count = classValue.len;
for (unsigned int i = 0; i < count; i++)
@@ -711,10 +985,18 @@ struct ClassDefFormat2
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (rangeRecord.sanitize (c));
}
+ template <typename set_t>
+ inline void 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);
+ }
+
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
unsigned int count = rangeRecord.len;
for (unsigned int i = 0; i < count; i++)
@@ -734,8 +1016,6 @@ struct ClassDefFormat2
struct ClassDef
{
- inline unsigned int operator () (hb_codepoint_t glyph_id) const { return get_class (glyph_id); }
-
inline unsigned int get_class (hb_codepoint_t glyph_id) const
{
switch (u.format) {
@@ -746,7 +1026,7 @@ struct ClassDef
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -755,6 +1035,14 @@ struct ClassDef
}
}
+ inline void add_class (hb_set_t *glyphs, unsigned int klass) const {
+ switch (u.format) {
+ case 1: u.format1.add_class (glyphs, klass); return;
+ case 2: u.format2.add_class (glyphs, klass); return;
+ default:return;
+ }
+ }
+
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
switch (u.format) {
case 1: return u.format1.intersects_class (glyphs, klass);
@@ -830,7 +1118,7 @@ struct Device
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ()));
}
@@ -848,7 +1136,7 @@ struct Device
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
index 92ae1cf..ff2d09c 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
@@ -51,7 +51,7 @@ struct AttachList
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */) const
{
- unsigned int index = (this+coverage) (glyph_id);
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
if (index == NOT_COVERED)
{
if (point_count)
@@ -72,7 +72,7 @@ struct AttachList
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
}
@@ -102,7 +102,7 @@ struct CaretValueFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -128,7 +128,7 @@ struct CaretValueFormat2
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -151,7 +151,7 @@ struct CaretValueFormat3
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this));
}
@@ -179,7 +179,7 @@ struct CaretValue
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -220,7 +220,7 @@ struct LigGlyph
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (carets.sanitize (c, this));
}
@@ -242,7 +242,7 @@ struct LigCaretList
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */) const
{
- unsigned int index = (this+coverage) (glyph_id);
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
if (index == NOT_COVERED)
{
if (caret_count)
@@ -254,7 +254,7 @@ struct LigCaretList
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
}
@@ -276,7 +276,7 @@ struct MarkGlyphSetsFormat1
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this));
}
@@ -300,7 +300,7 @@ struct MarkGlyphSets
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -337,6 +337,8 @@ struct GDEF
inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
{ return (this+glyphClassDef).get_class (glyph); }
+ inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
+ { (this+glyphClassDef).add_class (glyphs, klass); }
inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
@@ -363,7 +365,7 @@ struct GDEF
{ return version.to_int () >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (version.sanitize (c) &&
likely (version.major == 1) &&
glyphClassDef.sanitize (c, this) &&
@@ -383,13 +385,13 @@ struct GDEF
switch (klass) {
default:
- case UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
- case BaseGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
- case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE;
- case ComponentGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT;
+ case UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED;
+ case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+ case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+ case ComponentGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT;
case MarkGlyph:
klass = get_mark_attachment_type (glyph);
- return HB_OT_LAYOUT_GLYPH_CLASS_MARK | (klass << 8);
+ return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
}
}
@@ -423,7 +425,7 @@ struct GDEF
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
index 41cb93d..d27ce4f 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
@@ -172,12 +172,12 @@ struct ValueFormat : USHORT
}
inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *values) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
}
inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
unsigned int len = get_len ();
if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false);
@@ -195,7 +195,7 @@ struct ValueFormat : USHORT
/* Just sanitize referenced Device tables. Doesn't check the values themselves. */
inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count, unsigned int stride) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!has_device ()) return TRACE_RETURN (true);
@@ -212,9 +212,6 @@ struct ValueFormat : USHORT
struct AnchorFormat1
{
- friend struct Anchor;
-
- private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
{
@@ -223,7 +220,7 @@ struct AnchorFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -237,9 +234,6 @@ struct AnchorFormat1
struct AnchorFormat2
{
- friend struct Anchor;
-
- private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
hb_position_t *x, hb_position_t *y) const
{
@@ -255,7 +249,7 @@ struct AnchorFormat2
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -270,9 +264,6 @@ struct AnchorFormat2
struct AnchorFormat3
{
- friend struct Anchor;
-
- private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
{
@@ -286,7 +277,7 @@ struct AnchorFormat3
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
}
@@ -321,7 +312,7 @@ struct Anchor
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -351,7 +342,7 @@ struct AnchorMatrix
}
inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!c->check_struct (this)) return TRACE_RETURN (false);
if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false);
unsigned int count = rows * cols;
@@ -376,7 +367,7 @@ struct MarkRecord
friend struct MarkArray;
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base));
}
@@ -396,7 +387,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
const AnchorMatrix &anchors, unsigned int class_count,
unsigned int glyph_pos) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
unsigned int mark_class = record.klass;
@@ -418,7 +409,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this));
}
};
@@ -428,9 +419,11 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
struct SinglePosFormat1
{
- friend struct SinglePos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
inline const Coverage &get_coverage (void) const
{
@@ -439,8 +432,8 @@ struct SinglePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
valueFormat.apply_value (c->font, c->direction, this,
@@ -451,7 +444,7 @@ struct SinglePosFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values));
}
@@ -471,9 +464,11 @@ struct SinglePosFormat1
struct SinglePosFormat2
{
- friend struct SinglePos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
inline const Coverage &get_coverage (void) const
{
@@ -482,8 +477,8 @@ struct SinglePosFormat2
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (likely (index >= valueCount)) return TRACE_RETURN (false);
@@ -497,7 +492,7 @@ struct SinglePosFormat2
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount));
}
@@ -517,31 +512,19 @@ struct SinglePosFormat2
struct SinglePos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage ();
- case 2: return u.format2.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- case 2: return TRACE_RETURN (u.format2.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ case 2: return TRACE_RETURN (c->process (u.format2));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -577,17 +560,34 @@ struct PairSet
{
friend struct PairPosFormat1;
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ 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);
+
+ const PairValueRecord *record = CastP<PairValueRecord> (array);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ c->input->add (record->secondGlyph);
+ record = &StructAtOffset<PairValueRecord> (record, record_size);
+ }
+ }
+
inline bool apply (hb_apply_context_t *c,
const ValueFormat *valueFormats,
unsigned int pos) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (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 count = len;
const PairValueRecord *record = CastP<PairValueRecord> (array);
+ unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
{
if (c->buffer->info[pos].codepoint == record->secondGlyph)
@@ -615,7 +615,7 @@ struct PairSet
};
inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!(c->check_struct (this)
&& c->check_array (array, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false);
@@ -635,9 +635,14 @@ struct PairSet
struct PairPosFormat1
{
- friend struct PairPos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ unsigned int count = pairSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+pairSet[i]).collect_glyphs (c, &valueFormat1);
+ }
inline const Coverage &get_coverage (void) const
{
@@ -646,11 +651,11 @@ struct PairPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
@@ -659,7 +664,7 @@ struct PairPosFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
unsigned int len1 = valueFormat1.get_len ();
unsigned int len2 = valueFormat2.get_len ();
@@ -693,9 +698,23 @@ struct PairPosFormat1
struct PairPosFormat2
{
- friend struct PairPos;
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ /* (this+coverage).add_coverage (c->input); // Don't need this. */
- private:
+ /* TODO only add values for pairs that have nonzero adjustments. */
+
+ 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);
+ }
inline const Coverage &get_coverage (void) const
{
@@ -704,11 +723,11 @@ struct PairPosFormat2
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
@@ -717,8 +736,8 @@ struct PairPosFormat2
unsigned int len2 = valueFormat2.get_len ();
unsigned int record_len = len1 + len2;
- unsigned int klass1 = (this+classDef1) (c->buffer->cur().codepoint);
- unsigned int klass2 = (this+classDef2) (c->buffer->info[skippy_iter.idx].codepoint);
+ unsigned int klass1 = (this+classDef1).get_class (c->buffer->cur().codepoint);
+ unsigned int klass2 = (this+classDef2).get_class (c->buffer->info[skippy_iter.idx].codepoint);
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false);
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
@@ -735,7 +754,7 @@ struct PairPosFormat2
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!(c->check_struct (this)
&& coverage.sanitize (c, this)
&& classDef1.sanitize (c, this)
@@ -783,31 +802,19 @@ struct PairPosFormat2
struct PairPos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage ();
- case 2: return u.format2.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- case 2: return TRACE_RETURN (u.format2.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ case 2: return TRACE_RETURN (c->process (u.format2));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -830,7 +837,7 @@ struct EntryExitRecord
friend struct CursivePosFormat1;
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
}
@@ -849,9 +856,11 @@ struct EntryExitRecord
struct CursivePosFormat1
{
- friend struct CursivePos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
inline const Coverage &get_coverage (void) const
{
@@ -860,20 +869,20 @@ struct CursivePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
/* We don't handle mark glyphs here. */
- if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) return TRACE_RETURN (false);
+ if (c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false);
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->cur().codepoint)];
+ const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->cur().codepoint)];
if (!this_record.exitAnchor) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
- const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buffer->info[skippy_iter.idx].codepoint)];
+ const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint)];
if (!next_record.entryAnchor) return TRACE_RETURN (false);
unsigned int i = c->buffer->idx;
@@ -941,7 +950,7 @@ struct CursivePosFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
}
@@ -959,29 +968,18 @@ struct CursivePosFormat1
struct CursivePos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -1004,9 +1002,13 @@ typedef AnchorMatrix BaseArray; /* base-major--
struct MarkBasePosFormat1
{
- friend struct MarkBasePos;
-
- private:
+ 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);
+ /* TODO only add combinations that have nonzero adjustment. */
+ }
inline const Coverage &get_coverage (void) const
{
@@ -1015,8 +1017,8 @@ struct MarkBasePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
@@ -1030,16 +1032,16 @@ struct MarkBasePosFormat1
} while (1);
/* The following assertion is too strong, so we've disabled it. */
- if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
+ if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
- unsigned int base_index = (this+baseCoverage) (c->buffer->info[skippy_iter.idx].codepoint);
+ unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint);
if (base_index == NOT_COVERED) return TRACE_RETURN (false);
return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) &&
markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount));
}
@@ -1065,29 +1067,18 @@ struct MarkBasePosFormat1
struct MarkBasePos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -1115,9 +1106,13 @@ typedef OffsetListOf<LigatureAttach> LigatureArray;
struct MarkLigPosFormat1
{
- friend struct MarkLigPos;
-
- private:
+ 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);
+ /* TODO only add combinations that have nonzero adjustment. */
+ }
inline const Coverage &get_coverage (void) const
{
@@ -1126,8 +1121,8 @@ struct MarkLigPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
@@ -1136,10 +1131,10 @@ struct MarkLigPosFormat1
if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
/* The following assertion is too strong, so we've disabled it. */
- if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
+ if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
unsigned int j = skippy_iter.idx;
- unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoint);
+ unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->info[j].codepoint);
if (lig_index == NOT_COVERED) return TRACE_RETURN (false);
const LigatureArray& lig_array = this+ligatureArray;
@@ -1166,7 +1161,7 @@ struct MarkLigPosFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) &&
markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount));
}
@@ -1193,29 +1188,18 @@ struct MarkLigPosFormat1
struct MarkLigPos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -1238,9 +1222,13 @@ typedef AnchorMatrix Mark2Array; /* mark2-major--
struct MarkMarkPosFormat1
{
- friend struct MarkMarkPos;
-
- private:
+ 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);
+ /* TODO only add combinations that have nonzero adjustment. */
+ }
inline const Coverage &get_coverage (void) const
{
@@ -1249,8 +1237,8 @@ struct MarkMarkPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int mark1_index = (this+mark1Coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int mark1_index = (this+mark1Coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
@@ -1258,7 +1246,7 @@ struct MarkMarkPosFormat1
hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (!skippy_iter.prev (&property)) return TRACE_RETURN (false);
- if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) return TRACE_RETURN (false);
+ if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) return TRACE_RETURN (false);
unsigned int j = skippy_iter.idx;
@@ -1283,14 +1271,14 @@ struct MarkMarkPosFormat1
return TRACE_RETURN (false);
good:
- unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoint);
+ unsigned int mark2_index = (this+mark2Coverage).get_coverage (c->buffer->info[j].codepoint);
if (mark2_index == NOT_COVERED) return TRACE_RETURN (false);
return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) &&
mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this)
&& mark2Array.sanitize (c, this, (unsigned int) classCount));
@@ -1319,29 +1307,18 @@ struct MarkMarkPosFormat1
struct MarkMarkPos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -1357,50 +1334,13 @@ struct MarkMarkPos
};
-static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index);
+struct ContextPos : Context {};
-struct ContextPos : Context
-{
- friend struct PosLookupSubTable;
-
- private:
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- return TRACE_RETURN (Context::apply (c, position_lookup));
- }
-};
+struct ChainContextPos : ChainContext {};
-struct ChainContextPos : ChainContext
+struct ExtensionPos : Extension<ExtensionPos>
{
- friend struct PosLookupSubTable;
-
- private:
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- return TRACE_RETURN (ChainContext::apply (c, position_lookup));
- }
-};
-
-
-struct ExtensionPos : Extension
-{
- friend struct PosLookupSubTable;
-
- private:
- inline const struct PosLookupSubTable& get_subtable (void) const
- {
- unsigned int offset = get_offset ();
- if (unlikely (!offset)) return Null(PosLookupSubTable);
- return StructAtOffset<PosLookupSubTable> (this, offset);
- }
-
- inline const Coverage &get_coverage (void) const;
-
- inline bool apply (hb_apply_context_t *c) const;
-
- inline bool sanitize (hb_sanitize_context_t *c);
+ typedef struct PosLookupSubTable LookupSubTable;
};
@@ -1426,41 +1366,26 @@ struct PosLookupSubTable
Extension = 9
};
- inline const Coverage &get_coverage (unsigned int lookup_type) const
- {
- switch (lookup_type) {
- case Single: return u.single.get_coverage ();
- case Pair: return u.pair.get_coverage ();
- case Cursive: return u.cursive.get_coverage ();
- case MarkBase: return u.markBase.get_coverage ();
- case MarkLig: return u.markLig.get_coverage ();
- case MarkMark: return u.markMark.get_coverage ();
- case Context: return u.context.get_coverage ();
- case ChainContext: return u.chainContext.get_coverage ();
- case Extension: return u.extension.get_coverage ();
- default: return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c, unsigned int lookup_type) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (lookup_type) {
- case Single: return TRACE_RETURN (u.single.apply (c));
- case Pair: return TRACE_RETURN (u.pair.apply (c));
- case Cursive: return TRACE_RETURN (u.cursive.apply (c));
- case MarkBase: return TRACE_RETURN (u.markBase.apply (c));
- case MarkLig: return TRACE_RETURN (u.markLig.apply (c));
- case MarkMark: return TRACE_RETURN (u.markMark.apply (c));
- case Context: return TRACE_RETURN (u.context.apply (c));
- case ChainContext: return TRACE_RETURN (u.chainContext.apply (c));
- case Extension: return TRACE_RETURN (u.extension.apply (c));
- default: return TRACE_RETURN (false);
+ case Single: return TRACE_RETURN (u.single.process (c));
+ case Pair: return TRACE_RETURN (u.pair.process (c));
+ case Cursive: return TRACE_RETURN (u.cursive.process (c));
+ case MarkBase: return TRACE_RETURN (u.markBase.process (c));
+ case MarkLig: return TRACE_RETURN (u.markLig.process (c));
+ case MarkMark: return TRACE_RETURN (u.markMark.process (c));
+ case Context: return TRACE_RETURN (u.context.process (c));
+ case ChainContext: return TRACE_RETURN (u.chainContext.process (c));
+ case Extension: return TRACE_RETURN (u.extension.process (c));
+ default: return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.header.sub_format.sanitize (c))
return TRACE_RETURN (false);
switch (lookup_type) {
@@ -1480,7 +1405,7 @@ struct PosLookupSubTable
protected:
union {
struct {
- USHORT sub_format;
+ USHORT sub_format;
} header;
SinglePos single;
PairPos pair;
@@ -1502,35 +1427,54 @@ struct PosLookup : Lookup
inline const PosLookupSubTable& get_subtable (unsigned int i) const
{ return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
+ {
+ TRACE_PROCESS (this);
+ unsigned int lookup_type = get_type ();
+ unsigned int count = get_subtable_count ();
+ for (unsigned int i = 0; i < count; i++) {
+ typename context_t::return_t r = get_subtable (i).process (c, lookup_type);
+ if (c->stop_sublookup_iteration (r))
+ return TRACE_RETURN (r);
+ }
+ return TRACE_RETURN (c->default_return_value ());
+ }
+ template <typename context_t>
+ static inline typename context_t::return_t process_recurse_func (context_t *c, unsigned int lookup_index);
+
+ inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ c->set_recurse_func (NULL);
+ return TRACE_RETURN (process (c));
+ }
+
template <typename set_t>
inline void add_coverage (set_t *glyphs) const
{
+ hb_get_coverage_context_t c;
const Coverage *last = NULL;
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++) {
- const Coverage *c = &get_subtable (i).get_coverage (get_type ());
- if (c != last) {
- c->add_coverage (glyphs);
- last = c;
+ const Coverage *coverage = &get_subtable (i).process (&c, get_type ());
+ if (coverage != last) {
+ coverage->add_coverage (glyphs);
+ last = coverage;
}
}
}
inline bool apply_once (hb_apply_context_t *c) const
{
- unsigned int lookup_type = get_type ();
-
+ TRACE_APPLY (this);
if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property))
- return false;
-
- unsigned int count = get_subtable_count ();
- for (unsigned int i = 0; i < count; i++)
- if (get_subtable (i).apply (c, lookup_type))
- return true;
-
- return false;
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (process (c));
}
+ static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+
inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest) const
{
bool ret = false;
@@ -1538,6 +1482,7 @@ struct PosLookup : Lookup
if (unlikely (!c->buffer->len || !c->lookup_mask))
return false;
+ c->set_recurse_func (apply_recurse_func);
c->set_lookup (*this);
c->buffer->idx = 0;
@@ -1556,7 +1501,7 @@ struct PosLookup : Lookup
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable);
return TRACE_RETURN (list.sanitize (c, this, get_type ()));
@@ -1576,15 +1521,11 @@ struct GPOS : GSUBGPOS
inline const PosLookup& get_lookup (unsigned int i) const
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
- template <typename set_t>
- inline void add_coverage (set_t *glyphs, unsigned int lookup_index) const
- { get_lookup (lookup_index).add_coverage (glyphs); }
-
static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attahced_marks);
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
return TRACE_RETURN (list.sanitize (c, this));
@@ -1673,38 +1614,25 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t
/* Out-of-class implementation for methods recursing */
-inline const Coverage & ExtensionPos::get_coverage (void) const
+template <typename context_t>
+inline typename context_t::return_t PosLookup::process_recurse_func (context_t *c, unsigned int lookup_index)
{
- return get_subtable ().get_coverage (get_type ());
-}
-
-inline bool ExtensionPos::apply (hb_apply_context_t *c) const
-{
- TRACE_APPLY ();
- return TRACE_RETURN (get_subtable ().apply (c, get_type ()));
-}
-
-inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c)
-{
- TRACE_SANITIZE ();
- if (unlikely (!Extension::sanitize (c))) return TRACE_RETURN (false);
- unsigned int offset = get_offset ();
- if (unlikely (!offset)) return TRACE_RETURN (true);
- return TRACE_RETURN (StructAtOffset<PosLookupSubTable> (this, offset).sanitize (c, get_type ()));
+ const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
+ const PosLookup &l = gpos.get_lookup (lookup_index);
+ return l.process (c);
}
-static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index)
+inline bool PosLookup::apply_recurse_func (hb_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);
-
- if (unlikely (c->nesting_level_left == 0))
- return false;
-
- hb_apply_context_t new_c (*c);
- new_c.nesting_level_left--;
- new_c.set_lookup (l);
- return l.apply_once (&new_c);
+ unsigned int saved_lookup_props = c->lookup_props;
+ unsigned int saved_property = c->property;
+ c->set_lookup (l);
+ bool ret = l.apply_once (c);
+ c->lookup_props = saved_lookup_props;
+ c->property = saved_property;
+ return ret;
}
@@ -1712,7 +1640,7 @@ static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
#undef cursive_chain
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
index 05b18cc..2642acb 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
@@ -37,13 +37,9 @@ namespace OT {
struct SingleSubstFormat1
{
- friend struct SingleSubst;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
hb_codepoint_t glyph_id = iter.get_glyph ();
@@ -52,16 +48,33 @@ struct SingleSubstFormat1
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ hb_codepoint_t glyph_id = iter.get_glyph ();
+ c->input->add (glyph_id);
+ c->output->add ((glyph_id + deltaGlyphID) & 0xFFFF);
+ }
+ }
+
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
- unsigned int index = (this+coverage) (glyph_id);
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
/* According to the Adobe Annotated OpenType Suite, result is always
@@ -77,7 +90,7 @@ struct SingleSubstFormat1
unsigned int num_glyphs,
int delta)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */
@@ -85,7 +98,7 @@ struct SingleSubstFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
}
@@ -102,13 +115,9 @@ struct SingleSubstFormat1
struct SingleSubstFormat2
{
- friend struct SingleSubst;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ()))
@@ -116,16 +125,32 @@ struct SingleSubstFormat2
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ c->input->add (iter.get_glyph ());
+ c->output->add (substitute[iter.get_coverage ()]);
+ }
+ }
+
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
- unsigned int index = (this+coverage) (glyph_id);
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (unlikely (index >= substitute.len)) return TRACE_RETURN (false);
@@ -141,7 +166,7 @@ struct SingleSubstFormat2
Supplier<GlyphID> &substitutes,
unsigned int num_glyphs)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return TRACE_RETURN (false);
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
@@ -149,7 +174,7 @@ struct SingleSubstFormat2
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c));
}
@@ -167,37 +192,14 @@ struct SingleSubstFormat2
struct SingleSubst
{
- friend struct SubstLookupSubTable;
- friend struct SubstLookup;
-
- private:
-
- inline void closure (hb_closure_context_t *c) const
- {
- TRACE_CLOSURE ();
- switch (u.format) {
- case 1: u.format1.closure (c); break;
- case 2: u.format2.closure (c); break;
- default: break;
- }
- }
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage ();
- case 2: return u.format2.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- case 2: return TRACE_RETURN (u.format2.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ case 2: return TRACE_RETURN (c->process (u.format2));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
@@ -206,7 +208,7 @@ struct SingleSubst
Supplier<GlyphID> &substitutes,
unsigned int num_glyphs)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
unsigned int format = 2;
int delta;
@@ -229,7 +231,7 @@ struct SingleSubst
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -249,24 +251,28 @@ struct SingleSubst
struct Sequence
{
- friend struct MultipleSubstFormat1;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
unsigned int count = substitute.len;
for (unsigned int i = 0; i < count; i++)
c->glyphs->add (substitute[i]);
}
+ 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]);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
if (unlikely (!substitute.len)) return TRACE_RETURN (false);
- unsigned int klass = c->property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE ? HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH : 0;
+ unsigned int klass = c->property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
unsigned int count = substitute.len;
for (unsigned int i = 0; i < count; i++) {
set_lig_props_for_component (c->buffer->cur(), i);
@@ -281,15 +287,14 @@ struct Sequence
Supplier<GlyphID> &glyphs,
unsigned int num_glyphs)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false);
return TRACE_RETURN (true);
}
- public:
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (substitute.sanitize (c));
}
@@ -302,13 +307,9 @@ struct Sequence
struct MultipleSubstFormat1
{
- friend struct MultipleSubst;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ()))
@@ -316,16 +317,31 @@ struct MultipleSubstFormat1
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ unsigned int count = sequence.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+sequence[i]).collect_glyphs (c);
+ }
+
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
return TRACE_RETURN ((this+sequence[index]).apply (c));
@@ -337,7 +353,7 @@ struct MultipleSubstFormat1
unsigned int num_glyphs,
Supplier<GlyphID> &substitute_glyphs_list)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false);
for (unsigned int i = 0; i < num_glyphs; i++)
@@ -350,7 +366,7 @@ struct MultipleSubstFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this));
}
@@ -368,34 +384,13 @@ struct MultipleSubstFormat1
struct MultipleSubst
{
- friend struct SubstLookupSubTable;
- friend struct SubstLookup;
-
- private:
-
- inline void closure (hb_closure_context_t *c) const
- {
- TRACE_CLOSURE ();
- switch (u.format) {
- case 1: u.format1.closure (c); break;
- default: break;
- }
- }
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
@@ -405,7 +400,7 @@ struct MultipleSubst
unsigned int num_glyphs,
Supplier<GlyphID> &substitute_glyphs_list)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
unsigned int format = 1;
u.format.set (format);
@@ -416,7 +411,7 @@ struct MultipleSubst
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -437,13 +432,9 @@ typedef ArrayOf<GlyphID> AlternateSet; /* Array of alternate GlyphIDs--in
struct AlternateSubstFormat1
{
- friend struct AlternateSubst;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ())) {
@@ -455,17 +446,36 @@ struct AlternateSubstFormat1
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ c->input->add (iter.get_glyph ());
+ 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]);
+ }
+ }
+
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
- unsigned int index = (this+coverage) (glyph_id);
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const AlternateSet &alt_set = this+alternateSet[index];
@@ -494,7 +504,7 @@ struct AlternateSubstFormat1
unsigned int num_glyphs,
Supplier<GlyphID> &alternate_glyphs_list)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false);
for (unsigned int i = 0; i < num_glyphs; i++)
@@ -507,7 +517,7 @@ struct AlternateSubstFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
}
@@ -525,34 +535,13 @@ struct AlternateSubstFormat1
struct AlternateSubst
{
- friend struct SubstLookupSubTable;
- friend struct SubstLookup;
-
- private:
-
- inline void closure (hb_closure_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: u.format1.closure (c); break;
- default: break;
- }
- }
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
@@ -562,7 +551,7 @@ struct AlternateSubst
unsigned int num_glyphs,
Supplier<GlyphID> &alternate_glyphs_list)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
unsigned int format = 1;
u.format.set (format);
@@ -573,7 +562,7 @@ struct AlternateSubst
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -591,13 +580,9 @@ struct AlternateSubst
struct Ligature
{
- friend struct LigatureSet;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
unsigned int count = component.len;
for (unsigned int i = 1; i < count; i++)
if (!c->glyphs->has (component[i]))
@@ -605,27 +590,37 @@ struct Ligature
c->glyphs->add (ligGlyph);
}
+ 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->output->add (ligGlyph);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c) const
{
+ TRACE_WOULD_APPLY (this);
if (c->len != component.len)
- return false;
+ return TRACE_RETURN (false);
for (unsigned int i = 1; i < c->len; i++)
if (likely (c->glyphs[i] != component[i]))
- return false;
+ return TRACE_RETURN (false);
- return true;
+ return TRACE_RETURN (true);
}
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
unsigned int count = component.len;
if (unlikely (count < 1)) return TRACE_RETURN (false);
- unsigned int end_offset;
- bool is_mark_ligature;
- unsigned int total_component_count;
+ unsigned int end_offset = 0;
+ bool is_mark_ligature = false;
+ unsigned int total_component_count = 0;
if (likely (!match_input (c, count,
&component[1],
@@ -656,7 +651,7 @@ struct Ligature
Supplier<GlyphID> &components, /* Starting from second */
unsigned int num_components /* Including first component */)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
ligGlyph = ligature;
if (unlikely (!component.serialize (c, components, num_components))) return TRACE_RETURN (false);
@@ -665,7 +660,7 @@ struct Ligature
public:
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c));
}
@@ -681,33 +676,38 @@ struct Ligature
struct LigatureSet
{
- friend struct LigatureSubstFormat1;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
unsigned int num_ligs = ligature.len;
for (unsigned int i = 0; i < num_ligs; i++)
(this+ligature[i]).closure (c);
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ (this+ligature[i]).collect_glyphs (c);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c) const
{
+ TRACE_WOULD_APPLY (this);
unsigned int num_ligs = ligature.len;
for (unsigned int i = 0; i < num_ligs; i++)
{
const Ligature &lig = this+ligature[i];
if (lig.would_apply (c))
- return true;
+ return TRACE_RETURN (true);
}
- return false;
+ return TRACE_RETURN (false);
}
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
unsigned int num_ligs = ligature.len;
for (unsigned int i = 0; i < num_ligs; i++)
{
@@ -724,7 +724,7 @@ struct LigatureSet
unsigned int num_ligatures,
Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
if (unlikely (!ligature.serialize (c, num_ligatures))) return TRACE_RETURN (false);
for (unsigned int i = 0; i < num_ligatures; i++)
@@ -737,9 +737,8 @@ struct LigatureSet
return TRACE_RETURN (true);
}
- public:
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (ligature.sanitize (c, this));
}
@@ -753,13 +752,9 @@ struct LigatureSet
struct LigatureSubstFormat1
{
- friend struct LigatureSubst;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ()))
@@ -767,6 +762,16 @@ struct LigatureSubstFormat1
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ c->input->add (iter.get_glyph ());
+ (this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
+ }
+ }
+
inline const Coverage &get_coverage (void) const
{
return this+coverage;
@@ -774,15 +779,20 @@ struct LigatureSubstFormat1
inline bool would_apply (hb_would_apply_context_t *c) const
{
- return (this+ligatureSet[(this+coverage) (c->glyphs[0])]).would_apply (c);
+ TRACE_WOULD_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
+ if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
+
+ const LigatureSet &lig_set = this+ligatureSet[index];
+ return TRACE_RETURN (lig_set.would_apply (c));
}
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
- unsigned int index = (this+coverage) (glyph_id);
+ unsigned int index = (this+coverage).get_coverage (glyph_id);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const LigatureSet &lig_set = this+ligatureSet[index];
@@ -797,7 +807,7 @@ struct LigatureSubstFormat1
Supplier<unsigned int> &component_count_list,
Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false);
if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return TRACE_RETURN (false);
for (unsigned int i = 0; i < num_first_glyphs; i++)
@@ -812,7 +822,7 @@ struct LigatureSubstFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
}
@@ -830,42 +840,13 @@ struct LigatureSubstFormat1
struct LigatureSubst
{
- friend struct SubstLookupSubTable;
- friend struct SubstLookup;
-
- private:
-
- inline void closure (hb_closure_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: u.format1.closure (c); break;
- default: break;
- }
- }
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool would_apply (hb_would_apply_context_t *c) const
- {
- switch (u.format) {
- case 1: return u.format1.would_apply (c);
- default:return false;
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
@@ -877,7 +858,7 @@ struct LigatureSubst
Supplier<unsigned int> &component_count_list,
Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false);
unsigned int format = 1;
u.format.set (format);
@@ -889,7 +870,7 @@ struct LigatureSubst
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -905,70 +886,13 @@ struct LigatureSubst
};
-static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index);
-static inline void closure_lookup (hb_closure_context_t *c, unsigned int lookup_index);
+struct ContextSubst : Context {};
-struct ContextSubst : Context
-{
- friend struct SubstLookupSubTable;
+struct ChainContextSubst : ChainContext {};
- private:
-
- inline void closure (hb_closure_context_t *c) const
- {
- TRACE_CLOSURE ();
- return Context::closure (c, closure_lookup);
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- return TRACE_RETURN (Context::apply (c, substitute_lookup));
- }
-};
-
-struct ChainContextSubst : ChainContext
-{
- friend struct SubstLookupSubTable;
-
- private:
-
- inline void closure (hb_closure_context_t *c) const
- {
- TRACE_CLOSURE ();
- return ChainContext::closure (c, closure_lookup);
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- return TRACE_RETURN (ChainContext::apply (c, substitute_lookup));
- }
-};
-
-
-struct ExtensionSubst : Extension
+struct ExtensionSubst : Extension<ExtensionSubst>
{
- friend struct SubstLookupSubTable;
- friend struct SubstLookup;
-
- private:
- inline const struct SubstLookupSubTable& get_subtable (void) const
- {
- unsigned int offset = get_offset ();
- if (unlikely (!offset)) return Null(SubstLookupSubTable);
- return StructAtOffset<SubstLookupSubTable> (this, offset);
- }
-
- inline void closure (hb_closure_context_t *c) const;
-
- inline const Coverage &get_coverage (void) const;
-
- inline bool would_apply (hb_would_apply_context_t *c) const;
-
- inline bool apply (hb_apply_context_t *c) const;
-
- inline bool sanitize (hb_sanitize_context_t *c);
+ typedef struct SubstLookupSubTable LookupSubTable;
inline bool is_reverse (void) const;
};
@@ -976,13 +900,9 @@ struct ExtensionSubst : Extension
struct ReverseChainSingleSubstFormat1
{
- friend struct ReverseChainSingleSubst;
-
- private:
-
inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
unsigned int count;
@@ -1005,18 +925,48 @@ struct ReverseChainSingleSubstFormat1
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ 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);
+
+ count = lookahead.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+lookahead[i]).add_coverage (c->after);
+
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ count = substitute.len;
+ for (unsigned int i = 0; i < count; i++)
+ c->output->add (substitute[i]);
+ }
+
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
+ inline bool would_apply (hb_would_apply_context_t *c) const
+ {
+ TRACE_WOULD_APPLY (this);
+ return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
if (unlikely (c->nesting_level_left != MAX_NESTING_LEVEL))
return TRACE_RETURN (false); /* No chaining to this type */
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
@@ -1039,7 +989,7 @@ struct ReverseChainSingleSubstFormat1
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
return TRACE_RETURN (false);
OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
@@ -1071,38 +1021,18 @@ struct ReverseChainSingleSubstFormat1
struct ReverseChainSingleSubst
{
- friend struct SubstLookupSubTable;
-
- private:
-
- inline void closure (hb_closure_context_t *c) const
- {
- TRACE_CLOSURE ();
- switch (u.format) {
- case 1: u.format1.closure (c); break;
- default: break;
- }
- }
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -1138,82 +1068,25 @@ struct SubstLookupSubTable
ReverseChainSingle = 8
};
- inline void closure (hb_closure_context_t *c,
- unsigned int lookup_type) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c, unsigned int lookup_type) const
{
- TRACE_CLOSURE ();
+ TRACE_PROCESS (this);
switch (lookup_type) {
- case Single: u.single.closure (c); break;
- case Multiple: u.multiple.closure (c); break;
- case Alternate: u.alternate.closure (c); break;
- case Ligature: u.ligature.closure (c); break;
- case Context: u.context.closure (c); break;
- case ChainContext: u.chainContext.closure (c); break;
- case Extension: u.extension.closure (c); break;
- case ReverseChainSingle: u.reverseChainContextSingle.closure (c); break;
- default: break;
- }
- }
-
- inline const Coverage &get_coverage (unsigned int lookup_type) const
- {
- switch (lookup_type) {
- case Single: return u.single.get_coverage ();
- case Multiple: return u.multiple.get_coverage ();
- case Alternate: return u.alternate.get_coverage ();
- case Ligature: return u.ligature.get_coverage ();
- case Context: return u.context.get_coverage ();
- case ChainContext: return u.chainContext.get_coverage ();
- case Extension: return u.extension.get_coverage ();
- case ReverseChainSingle: return u.reverseChainContextSingle.get_coverage ();
- default: return Null(Coverage);
- }
- }
-
- inline bool would_apply (hb_would_apply_context_t *c,
- unsigned int lookup_type) const
- {
- TRACE_WOULD_APPLY ();
- if (get_coverage (lookup_type).get_coverage (c->glyphs[0]) == NOT_COVERED) return false;
- if (c->len == 1) {
- switch (lookup_type) {
- case Single:
- case Multiple:
- case Alternate:
- case ReverseChainSingle:
- return true;
- }
- }
-
- /* Only need to look further for lookups that support substitutions
- * of input longer than 1. */
- switch (lookup_type) {
- case Ligature: return u.ligature.would_apply (c);
- case Context: return u.context.would_apply (c);
- case ChainContext: return u.chainContext.would_apply (c);
- case Extension: return u.extension.would_apply (c);
- default: return false;
- }
- }
-
- inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
- {
- TRACE_APPLY ();
- switch (lookup_type) {
- case Single: return TRACE_RETURN (u.single.apply (c));
- case Multiple: return TRACE_RETURN (u.multiple.apply (c));
- case Alternate: return TRACE_RETURN (u.alternate.apply (c));
- case Ligature: return TRACE_RETURN (u.ligature.apply (c));
- case Context: return TRACE_RETURN (u.context.apply (c));
- case ChainContext: return TRACE_RETURN (u.chainContext.apply (c));
- case Extension: return TRACE_RETURN (u.extension.apply (c));
- case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.apply (c));
- default: return TRACE_RETURN (false);
+ case Single: return TRACE_RETURN (u.single.process (c));
+ case Multiple: return TRACE_RETURN (u.multiple.process (c));
+ case Alternate: return TRACE_RETURN (u.alternate.process (c));
+ case Ligature: return TRACE_RETURN (u.ligature.process (c));
+ case Context: return TRACE_RETURN (u.context.process (c));
+ case ChainContext: return TRACE_RETURN (u.chainContext.process (c));
+ case Extension: return TRACE_RETURN (u.extension.process (c));
+ case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.process (c));
+ default: return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.header.sub_format.sanitize (c))
return TRACE_RETURN (false);
switch (lookup_type) {
@@ -1264,55 +1137,68 @@ struct SubstLookup : Lookup
return lookup_type_is_reverse (type);
}
- inline void closure (hb_closure_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
unsigned int lookup_type = get_type ();
unsigned int count = get_subtable_count ();
- for (unsigned int i = 0; i < count; i++)
- get_subtable (i).closure (c, lookup_type);
+ for (unsigned int i = 0; i < count; i++) {
+ typename context_t::return_t r = get_subtable (i).process (c, lookup_type);
+ if (c->stop_sublookup_iteration (r))
+ return TRACE_RETURN (r);
+ }
+ return TRACE_RETURN (c->default_return_value ());
+ }
+ template <typename context_t>
+ static inline typename context_t::return_t process_recurse_func (context_t *c, unsigned int lookup_index);
+
+ inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE (this);
+ c->set_recurse_func (process_recurse_func<hb_closure_context_t>);
+ return TRACE_RETURN (process (c));
+ }
+
+ inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ c->set_recurse_func (process_recurse_func<hb_collect_glyphs_context_t>);
+ return TRACE_RETURN (process (c));
}
template <typename set_t>
inline void add_coverage (set_t *glyphs) const
{
+ hb_get_coverage_context_t c;
const Coverage *last = NULL;
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++) {
- const Coverage *c = &get_subtable (i).get_coverage (get_type ());
- if (c != last) {
- c->add_coverage (glyphs);
- last = c;
+ const Coverage *coverage = &get_subtable (i).process (&c, get_type ());
+ if (coverage != last) {
+ coverage->add_coverage (glyphs);
+ last = coverage;
}
}
}
inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const
{
- if (unlikely (!c->len)) return false;
- if (!digest->may_have (c->glyphs[0])) return false;
- unsigned int lookup_type = get_type ();
- unsigned int count = get_subtable_count ();
- for (unsigned int i = 0; i < count; i++)
- if (get_subtable (i).would_apply (c, lookup_type))
- return true;
- return false;
+ TRACE_WOULD_APPLY (this);
+ if (unlikely (!c->len)) return TRACE_RETURN (false);
+ if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false);
+ return TRACE_RETURN (process (c));
}
inline bool apply_once (hb_apply_context_t *c) const
{
- unsigned int lookup_type = get_type ();
-
+ TRACE_APPLY (this);
if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property))
- return false;
-
- unsigned int count = get_subtable_count ();
- for (unsigned int i = 0; i < count; i++)
- if (get_subtable (i).apply (c, lookup_type))
- return true;
-
- return false;
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (process (c));
}
+ static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest) const
{
bool ret = false;
@@ -1320,6 +1206,7 @@ struct SubstLookup : Lookup
if (unlikely (!c->buffer->len || !c->lookup_mask))
return false;
+ c->set_recurse_func (apply_recurse_func);
c->set_lookup (*this);
if (likely (!is_reverse ()))
@@ -1361,11 +1248,9 @@ struct SubstLookup : Lookup
return ret;
}
- private:
inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
unsigned int i)
{ return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c, this); }
- public:
inline bool serialize_single (hb_serialize_context_t *c,
uint32_t lookup_props,
@@ -1373,7 +1258,7 @@ struct SubstLookup : Lookup
Supplier<GlyphID> &substitutes,
unsigned int num_glyphs)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return TRACE_RETURN (false);
return TRACE_RETURN (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs));
}
@@ -1385,7 +1270,7 @@ struct SubstLookup : Lookup
unsigned int num_glyphs,
Supplier<GlyphID> &substitute_glyphs_list)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return TRACE_RETURN (false);
return TRACE_RETURN (serialize_subtable (c, 0).u.multiple.serialize (c, glyphs, substitute_len_list, num_glyphs,
substitute_glyphs_list));
@@ -1398,7 +1283,7 @@ struct SubstLookup : Lookup
unsigned int num_glyphs,
Supplier<GlyphID> &alternate_glyphs_list)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return TRACE_RETURN (false);
return TRACE_RETURN (serialize_subtable (c, 0).u.alternate.serialize (c, glyphs, alternate_len_list, num_glyphs,
alternate_glyphs_list));
@@ -1413,7 +1298,7 @@ struct SubstLookup : Lookup
Supplier<unsigned int> &component_count_list,
Supplier<GlyphID> &component_list /* Starting from second for each ligature */)
{
- TRACE_SERIALIZE ();
+ TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return TRACE_RETURN (false);
return TRACE_RETURN (serialize_subtable (c, 0).u.ligature.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs,
ligatures_list, component_count_list, component_list));
@@ -1421,7 +1306,7 @@ struct SubstLookup : Lookup
inline bool sanitize (hb_sanitize_context_t *c)
{
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable);
if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false);
@@ -1456,19 +1341,11 @@ struct GSUB : GSUBGPOS
inline const SubstLookup& get_lookup (unsigned int i) const
{ return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
- template <typename set_t>
- inline void add_coverage (set_t *glyphs, unsigned int lookup_index) const
- { get_lookup (lookup_index).add_coverage (glyphs); }
-
static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer);
static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer);
- inline void closure_lookup (hb_closure_context_t *c,
- unsigned int lookup_index) const
- { return get_lookup (lookup_index).closure (c); }
-
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
return TRACE_RETURN (list.sanitize (c, this));
@@ -1501,73 +1378,37 @@ GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE
/* Out-of-class implementation for methods recursing */
-inline void ExtensionSubst::closure (hb_closure_context_t *c) const
-{
- get_subtable ().closure (c, get_type ());
-}
-
-inline const Coverage & ExtensionSubst::get_coverage (void) const
-{
- return get_subtable ().get_coverage (get_type ());
-}
-
-inline bool ExtensionSubst::would_apply (hb_would_apply_context_t *c) const
-{
- return get_subtable ().would_apply (c, get_type ());
-}
-
-inline bool ExtensionSubst::apply (hb_apply_context_t *c) const
-{
- TRACE_APPLY ();
- return TRACE_RETURN (get_subtable ().apply (c, get_type ()));
-}
-
-inline bool ExtensionSubst::sanitize (hb_sanitize_context_t *c)
-{
- TRACE_SANITIZE ();
- if (unlikely (!Extension::sanitize (c))) return TRACE_RETURN (false);
- unsigned int offset = get_offset ();
- if (unlikely (!offset)) return TRACE_RETURN (true);
- return TRACE_RETURN (StructAtOffset<SubstLookupSubTable> (this, offset).sanitize (c, get_type ()));
-}
-
inline bool ExtensionSubst::is_reverse (void) const
{
unsigned int type = get_type ();
if (unlikely (type == SubstLookupSubTable::Extension))
- return CastR<ExtensionSubst> (get_subtable()).is_reverse ();
+ return CastR<ExtensionSubst> (get_subtable<SubstLookupSubTable>()).is_reverse ();
return SubstLookup::lookup_type_is_reverse (type);
}
-static inline void closure_lookup (hb_closure_context_t *c, unsigned int lookup_index)
+template <typename context_t>
+inline typename context_t::return_t SubstLookup::process_recurse_func (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);
-
- if (unlikely (c->nesting_level_left == 0))
- return;
-
- c->nesting_level_left--;
- l.closure (c);
- c->nesting_level_left++;
+ return l.process (c);
}
-static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index)
+inline bool SubstLookup::apply_recurse_func (hb_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);
-
- if (unlikely (c->nesting_level_left == 0))
- return false;
-
- hb_apply_context_t new_c (*c);
- new_c.nesting_level_left--;
- new_c.set_lookup (l);
- return l.apply_once (&new_c);
+ unsigned int saved_lookup_props = c->lookup_props;
+ unsigned int saved_property = c->property;
+ c->set_lookup (l);
+ bool ret = l.apply_once (c);
+ c->lookup_props = saved_lookup_props;
+ c->property = saved_property;
+ return ret;
}
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_LAYOUT_GSUB_TABLE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
index dd7bdd3..40be861 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -37,44 +37,82 @@
namespace OT {
+
+#define TRACE_PROCESS(this) \
+ hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "");
+
+
#ifndef HB_DEBUG_CLOSURE
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
#endif
-#define TRACE_CLOSURE() \
- hb_auto_trace_t<HB_DEBUG_CLOSURE> trace (&c->debug_depth, "CLOSURE", this, HB_FUNC, "");
-
+#define TRACE_CLOSURE(this) \
+ hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "");
struct hb_closure_context_t
{
+ inline const char *get_name (void) { return "CLOSURE"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
+ typedef hb_void_t return_t;
+ typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t process (const T &obj) { obj.closure (this); return HB_VOID; }
+ static return_t default_return_value (void) { return HB_VOID; }
+ bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ nesting_level_left--;
+ recurse_func (this, lookup_index);
+ nesting_level_left++;
+ return HB_VOID;
+ }
+
hb_face_t *face;
hb_set_t *glyphs;
+ recurse_func_t recurse_func;
unsigned int nesting_level_left;
unsigned int debug_depth;
-
hb_closure_context_t (hb_face_t *face_,
hb_set_t *glyphs_,
unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
face (face_),
glyphs (glyphs_),
+ recurse_func (NULL),
nesting_level_left (nesting_level_left_),
debug_depth (0) {}
+
+ void set_recurse_func (recurse_func_t func) { recurse_func = func; }
};
-/* TODO Add TRACE_RETURN annotation to gsub. */
#ifndef HB_DEBUG_WOULD_APPLY
#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
#endif
-#define TRACE_WOULD_APPLY() \
- hb_auto_trace_t<HB_DEBUG_WOULD_APPLY> trace (&c->debug_depth, "WOULD_APPLY", this, HB_FUNC, "%d glyphs", c->len);
-
+#define TRACE_WOULD_APPLY(this) \
+ hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "%d glyphs", c->len);
struct hb_would_apply_context_t
{
+ inline const char *get_name (void) { return "WOULD_APPLY"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
+ typedef bool return_t;
+ template <typename T>
+ inline return_t process (const T &obj) { return obj.would_apply (this); }
+ static return_t default_return_value (void) { return false; }
+ bool stop_sublookup_iteration (const return_t r) const { return r; }
+
hb_face_t *face;
const hb_codepoint_t *glyphs;
unsigned int len;
@@ -89,31 +127,146 @@ struct hb_would_apply_context_t
glyphs (glyphs_),
len (len_),
zero_context (zero_context_),
- debug_depth (0) {};
+ debug_depth (0) {}
+};
+
+
+
+#ifndef HB_DEBUG_COLLECT_GLYPHS
+#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0)
+#endif
+
+#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, \
+ "");
+
+struct hb_collect_glyphs_context_t
+{
+ inline const char *get_name (void) { return "COLLECT_GLYPHS"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
+ typedef hb_void_t return_t;
+ typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t process (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
+ static return_t default_return_value (void) { return HB_VOID; }
+ bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ /* Note that GPOS sets recurse_func to NULL already, so it doesn't get
+ * past the previous check. For GSUB, we only want to collect the output
+ * glyphs in the recursion. If output is not requested, we can go home now. */
+
+ if (output == hb_set_get_empty ())
+ return HB_VOID;
+
+ hb_set_t *old_before = before;
+ hb_set_t *old_input = input;
+ hb_set_t *old_after = after;
+ before = input = after = hb_set_get_empty ();
+
+ nesting_level_left--;
+ recurse_func (this, lookup_index);
+ nesting_level_left++;
+
+ before = old_before;
+ input = old_input;
+ after = old_after;
+
+ return HB_VOID;
+ }
+
+ hb_face_t *face;
+ hb_set_t *before;
+ hb_set_t *input;
+ hb_set_t *after;
+ hb_set_t *output;
+ recurse_func_t recurse_func;
+ unsigned int nesting_level_left;
+ unsigned int debug_depth;
+
+ hb_collect_glyphs_context_t (hb_face_t *face_,
+ hb_set_t *glyphs_before, /* OUT. May be NULL */
+ hb_set_t *glyphs_input, /* OUT. May be NULL */
+ hb_set_t *glyphs_after, /* OUT. May be NULL */
+ hb_set_t *glyphs_output, /* OUT. May be NULL */
+ unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
+ face (face_),
+ before (glyphs_before ? glyphs_before : hb_set_get_empty ()),
+ input (glyphs_input ? glyphs_input : hb_set_get_empty ()),
+ after (glyphs_after ? glyphs_after : hb_set_get_empty ()),
+ output (glyphs_output ? glyphs_output : hb_set_get_empty ()),
+ recurse_func (NULL),
+ nesting_level_left (nesting_level_left_),
+ debug_depth (0) {}
+
+ void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+};
+
+
+
+struct hb_get_coverage_context_t
+{
+ inline const char *get_name (void) { return "GET_COVERAGE"; }
+ static const unsigned int max_debug_depth = 0;
+ typedef const Coverage &return_t;
+ template <typename T>
+ inline return_t process (const T &obj) { return obj.get_coverage (); }
+ static return_t default_return_value (void) { return Null(Coverage); }
+
+ hb_get_coverage_context_t (void) :
+ debug_depth (0) {}
+
+ unsigned int debug_depth;
};
+
#ifndef HB_DEBUG_APPLY
#define HB_DEBUG_APPLY (HB_DEBUG+0)
#endif
-#define TRACE_APPLY() \
- hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", this, HB_FUNC, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
-
+#define TRACE_APPLY(this) \
+ hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
+ (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+ "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
struct hb_apply_context_t
{
+ inline const char *get_name (void) { return "APPLY"; }
+ static const unsigned int max_debug_depth = HB_DEBUG_APPLY;
+ typedef bool return_t;
+ typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
+ template <typename T>
+ inline return_t process (const T &obj) { return obj.apply (this); }
+ static return_t default_return_value (void) { return false; }
+ bool stop_sublookup_iteration (const return_t r) const { return r; }
+ return_t recurse (unsigned int lookup_index)
+ {
+ if (unlikely (nesting_level_left == 0 || !recurse_func))
+ return default_return_value ();
+
+ nesting_level_left--;
+ bool ret = recurse_func (this, lookup_index);
+ nesting_level_left++;
+ return ret;
+ }
+
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
hb_direction_t direction;
hb_mask_t lookup_mask;
+ recurse_func_t recurse_func;
unsigned int nesting_level_left;
unsigned int lookup_props;
unsigned int property; /* propety of first glyph */
- unsigned int debug_depth;
const GDEF &gdef;
bool has_glyph_classes;
+ unsigned int debug_depth;
hb_apply_context_t (hb_font_t *font_,
@@ -122,18 +275,16 @@ struct hb_apply_context_t
font (font_), face (font->face), buffer (buffer_),
direction (buffer_->props.direction),
lookup_mask (lookup_mask_),
+ recurse_func (NULL),
nesting_level_left (MAX_NESTING_LEVEL),
- lookup_props (0), property (0), debug_depth (0),
+ lookup_props (0), property (0),
gdef (*hb_ot_layout_from_face (face)->gdef),
- has_glyph_classes (gdef.has_glyph_classes ()) {}
+ has_glyph_classes (gdef.has_glyph_classes ()),
+ debug_depth (0) {}
- void set_lookup_props (unsigned int lookup_props_) {
- lookup_props = lookup_props_;
- }
-
- void set_lookup (const Lookup &l) {
- lookup_props = l.get_props ();
- }
+ void set_recurse_func (recurse_func_t func) { recurse_func = func; }
+ void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
+ void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
struct mark_skipping_forward_iterator_t
{
@@ -264,7 +415,7 @@ struct hb_apply_context_t
if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
return false;
- if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
+ if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
return match_properties_mark (glyph, glyph_props, lookup_props);
return true;
@@ -295,7 +446,7 @@ struct hb_apply_context_t
*property_out = property;
/* If it's a mark, skip it if we don't accept it. */
- if (unlikely (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK))
+ if (unlikely (property & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
return !match_properties (info->codepoint, property, lookup_props);
/* If not a mark, don't skip. */
@@ -339,21 +490,23 @@ struct hb_apply_context_t
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 void (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
-typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
struct ContextClosureFuncs
{
intersects_func_t intersects;
- closure_lookup_func_t closure;
+};
+struct ContextCollectGlyphsFuncs
+{
+ collect_glyphs_func_t collect;
};
struct ContextApplyFuncs
{
match_func_t match;
- apply_lookup_func_t apply;
};
+
static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
{
return glyphs->has (value);
@@ -382,6 +535,32 @@ static inline bool intersects_array (hb_closure_context_t *c,
}
+static inline void collect_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+{
+ glyphs->add (value);
+}
+static inline void collect_class (hb_set_t *glyphs, const USHORT &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)
+{
+ const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+ (data+coverage).add_coverage (glyphs);
+}
+static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
+ hb_set_t *glyphs,
+ unsigned int count,
+ const USHORT values[],
+ collect_glyphs_func_t collect_func,
+ const void *collect_data)
+{
+ for (unsigned int i = 0; i < count; i++)
+ collect_func (glyphs, values[i], collect_data);
+}
+
+
static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED)
{
return glyph_id == value;
@@ -397,7 +576,6 @@ static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value,
return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
}
-
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 */
@@ -422,7 +600,7 @@ static inline bool match_input (hb_apply_context_t *c,
bool *p_is_mark_ligature = NULL,
unsigned int *p_total_component_count = NULL)
{
- hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", NULL, HB_FUNC, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
+ TRACE_APPLY (NULL);
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
@@ -445,7 +623,7 @@ static inline bool match_input (hb_apply_context_t *c,
* ligate with a conjunct...)
*/
- bool is_mark_ligature = !!(c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
+ bool is_mark_ligature = !!(c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
unsigned int total_component_count = 0;
total_component_count += get_lig_num_comps (c->buffer->cur());
@@ -478,7 +656,7 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (false);
}
- is_mark_ligature = is_mark_ligature && (property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
+ is_mark_ligature = is_mark_ligature && (property & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]);
}
@@ -495,10 +673,10 @@ static inline bool match_input (hb_apply_context_t *c,
}
static inline void ligate_input (hb_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 USHORT input[] HB_UNUSED, /* Array of input values--start with second glyph */
hb_codepoint_t lig_glyph,
- match_func_t match_func,
- const void *match_data,
+ match_func_t match_func HB_UNUSED,
+ const void *match_data HB_UNUSED,
bool is_mark_ligature,
unsigned int total_component_count)
{
@@ -530,7 +708,7 @@ static inline void ligate_input (hb_apply_context_t *c,
* https://bugzilla.gnome.org/show_bug.cgi?id=437633
*/
- unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE;
+ unsigned int klass = is_mark_ligature ? 0 : HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
unsigned int lig_id = is_mark_ligature ? 0 : allocate_lig_id (c->buffer);
unsigned int last_lig_id = get_lig_id (c->buffer->cur());
unsigned int last_num_components = get_lig_num_comps (c->buffer->cur());
@@ -579,7 +757,7 @@ static inline bool match_backtrack (hb_apply_context_t *c,
match_func_t match_func,
const void *match_data)
{
- hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", NULL, HB_FUNC, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
+ TRACE_APPLY (NULL);
hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true);
if (skippy_iter.has_no_chance ())
@@ -604,7 +782,7 @@ static inline bool match_lookahead (hb_apply_context_t *c,
const void *match_data,
unsigned int offset)
{
- hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", NULL, HB_FUNC, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
+ TRACE_APPLY (NULL);
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true);
if (skippy_iter.has_no_chance ())
@@ -627,7 +805,7 @@ static inline bool match_lookahead (hb_apply_context_t *c,
struct LookupRecord
{
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -640,22 +818,22 @@ struct LookupRecord
};
-static inline void closure_lookup (hb_closure_context_t *c,
- unsigned int lookupCount,
- const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
- closure_lookup_func_t closure_func)
+template <typename context_t>
+static inline void recurse_lookups (context_t *c,
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
{
for (unsigned int i = 0; i < lookupCount; i++)
- closure_func (c, lookupRecord->lookupListIndex);
+ c->recurse (lookupRecord->lookupListIndex);
}
static inline bool apply_lookup (hb_apply_context_t *c,
unsigned int count, /* Including the first glyph */
unsigned int lookupCount,
- const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
- apply_lookup_func_t apply_func)
+ const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
{
- hb_auto_trace_t<HB_DEBUG_APPLY> trace (&c->debug_depth, "APPLY", NULL, HB_FUNC, "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint);
+ TRACE_APPLY (NULL);
+
unsigned int end = c->buffer->len;
if (unlikely (count == 0 || c->buffer->idx + count > end))
return TRACE_RETURN (false);
@@ -684,7 +862,7 @@ static inline bool apply_lookup (hb_apply_context_t *c,
unsigned int old_pos = c->buffer->idx;
/* Apply a lookup */
- bool done = apply_func (c, lookupRecord->lookupListIndex);
+ bool done = c->recurse (lookupRecord->lookupListIndex);
lookupRecord++;
lookupCount--;
@@ -718,6 +896,12 @@ struct ContextClosureLookupContext
const void *intersects_data;
};
+struct ContextCollectGlyphsLookupContext
+{
+ ContextCollectGlyphsFuncs funcs;
+ const void *collect_data;
+};
+
struct ContextApplyLookupContext
{
ContextApplyFuncs funcs;
@@ -734,17 +918,29 @@ static inline void context_closure_lookup (hb_closure_context_t *c,
if (intersects_array (c,
inputCount ? inputCount - 1 : 0, input,
lookup_context.funcs.intersects, lookup_context.intersects_data))
- closure_lookup (c,
- lookupCount, lookupRecord,
- lookup_context.funcs.closure);
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
}
+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 */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextCollectGlyphsLookupContext &lookup_context)
+{
+ collect_array (c, c->input,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.collect, lookup_context.collect_data);
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
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 */
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
+ unsigned int lookupCount HB_UNUSED,
+ const LookupRecord lookupRecord[] HB_UNUSED,
ContextApplyLookupContext &lookup_context)
{
return would_match_input (c,
@@ -763,19 +959,14 @@ static inline bool context_apply_lookup (hb_apply_context_t *c,
lookup_context.funcs.match, lookup_context.match_data)
&& apply_lookup (c,
inputCount,
- lookupCount, lookupRecord,
- lookup_context.funcs.apply);
+ lookupCount, lookupRecord);
}
struct Rule
{
- friend struct RuleSet;
-
- private:
-
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
context_closure_lookup (c,
inputCount, input,
@@ -783,23 +974,33 @@ struct Rule
lookup_context);
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
+ context_collect_glyphs_lookup (c,
+ inputCount, input,
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
return TRACE_RETURN (context_would_apply_lookup (c, inputCount, input, lookupCount, lookupRecord, lookup_context));
}
inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
return TRACE_RETURN (context_apply_lookup (c, inputCount, input, lookupCount, lookupRecord, lookup_context));
}
public:
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return inputCount.sanitize (c)
&& lookupCount.sanitize (c)
&& c->check_range (input,
@@ -824,15 +1025,23 @@ struct RuleSet
{
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
unsigned int num_rules = rule.len;
for (unsigned int i = 0; i < num_rules; i++)
(this+rule[i]).closure (c, lookup_context);
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).collect_glyphs (c, lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
unsigned int num_rules = rule.len;
for (unsigned int i = 0; i < num_rules; i++)
{
@@ -844,7 +1053,7 @@ struct RuleSet
inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
unsigned int num_rules = rule.len;
for (unsigned int i = 0; i < num_rules; i++)
{
@@ -855,7 +1064,7 @@ struct RuleSet
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (rule.sanitize (c, this));
}
@@ -870,18 +1079,14 @@ struct RuleSet
struct ContextFormat1
{
- friend struct Context;
-
- private:
-
- inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
const Coverage &cov = (this+coverage);
struct ContextClosureLookupContext lookup_context = {
- {intersects_glyph, closure_func},
+ {intersects_glyph},
NULL
};
@@ -893,35 +1098,55 @@ struct ContextFormat1
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_glyph},
+ NULL
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
- const RuleSet &rule_set = this+ruleSet[(this+coverage) (c->glyphs[0])];
+ const RuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
struct ContextApplyLookupContext lookup_context = {
- {match_glyph, NULL},
+ {match_glyph},
NULL
};
return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
}
- inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED))
return TRACE_RETURN (false);
const RuleSet &rule_set = this+ruleSet[index];
struct ContextApplyLookupContext lookup_context = {
- {match_glyph, apply_func},
+ {match_glyph},
NULL
};
return TRACE_RETURN (rule_set.apply (c, lookup_context));
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
}
@@ -940,21 +1165,17 @@ struct ContextFormat1
struct ContextFormat2
{
- friend struct Context;
-
- private:
-
- inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
if (!(this+coverage).intersects (c->glyphs))
return;
const ClassDef &class_def = this+classDef;
struct ContextClosureLookupContext lookup_context = {
- {intersects_class, closure_func},
- NULL
+ {intersects_class},
+ &class_def
};
unsigned int count = ruleSet.len;
@@ -965,38 +1186,59 @@ struct ContextFormat2
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ const ClassDef &class_def = this+classDef;
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_class},
+ &class_def
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
const ClassDef &class_def = this+classDef;
- unsigned int index = class_def (c->glyphs[0]);
+ unsigned int index = class_def.get_class (c->glyphs[0]);
const RuleSet &rule_set = this+ruleSet[index];
struct ContextApplyLookupContext lookup_context = {
- {match_class, NULL},
+ {match_class},
&class_def
};
return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
}
- inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const ClassDef &class_def = this+classDef;
- index = class_def (c->buffer->cur().codepoint);
+ index = class_def.get_class (c->buffer->cur().codepoint);
const RuleSet &rule_set = this+ruleSet[index];
struct ContextApplyLookupContext lookup_context = {
- {match_class, apply_func},
+ {match_class},
&class_def
};
return TRACE_RETURN (rule_set.apply (c, lookup_context));
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
}
@@ -1018,19 +1260,15 @@ struct ContextFormat2
struct ContextFormat3
{
- friend struct Context;
-
- private:
-
- inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
if (!(this+coverage[0]).intersects (c->glyphs))
return;
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
struct ContextClosureLookupContext lookup_context = {
- {intersects_coverage, closure_func},
+ {intersects_coverage},
this
};
context_closure_lookup (c,
@@ -1039,34 +1277,56 @@ struct ContextFormat3
lookup_context);
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage[0]).add_coverage (c->input);
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
+ struct ContextCollectGlyphsLookupContext lookup_context = {
+ {collect_coverage},
+ this
+ };
+
+ context_collect_glyphs_lookup (c,
+ glyphCount, (const USHORT *) (coverage + 1),
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
struct ContextApplyLookupContext lookup_context = {
- {match_coverage, NULL},
+ {match_coverage},
this
};
return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverage + 1), lookupCount, lookupRecord, lookup_context));
}
- inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
+ inline const Coverage &get_coverage (void) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage[0]) (c->buffer->cur().codepoint);
+ return this+coverage[0];
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage[0]).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
struct ContextApplyLookupContext lookup_context = {
- {match_coverage, apply_func},
+ {match_coverage},
this
};
return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverage + 1), lookupCount, lookupRecord, lookup_context));
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!c->check_struct (this)) return TRACE_RETURN (false);
unsigned int count = glyphCount;
if (!c->check_array (coverage, coverage[0].static_size, count)) return TRACE_RETURN (false);
@@ -1092,52 +1352,20 @@ struct ContextFormat3
struct Context
{
- protected:
-
- inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: u.format1.closure (c, closure_func); break;
- case 2: u.format2.closure (c, closure_func); break;
- case 3: u.format3.closure (c, closure_func); break;
- default: break;
- }
- }
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return this + u.format1.coverage;
- case 2: return this + u.format2.coverage;
- case 3: return this + u.format3.coverage[0];
- default:return Null(Coverage);
- }
- }
-
- inline bool would_apply (hb_would_apply_context_t *c) const
- {
- switch (u.format) {
- case 1: return u.format1.would_apply (c);
- case 2: return u.format2.would_apply (c);
- case 3: return u.format3.would_apply (c);
- default:return false;
- }
- }
-
- inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c, apply_func));
- case 2: return TRACE_RETURN (u.format2.apply (c, apply_func));
- case 3: return TRACE_RETURN (u.format3.apply (c, apply_func));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ case 2: return TRACE_RETURN (c->process (u.format2));
+ case 3: return TRACE_RETURN (c->process (u.format3));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -1165,6 +1393,12 @@ struct ChainContextClosureLookupContext
const void *intersects_data[3];
};
+struct ChainContextCollectGlyphsLookupContext
+{
+ ContextCollectGlyphsFuncs funcs;
+ const void *collect_data[3];
+};
+
struct ChainContextApplyLookupContext
{
ContextApplyFuncs funcs;
@@ -1191,20 +1425,43 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c,
&& intersects_array (c,
lookaheadCount, lookahead,
lookup_context.funcs.intersects, lookup_context.intersects_data[2]))
- closure_lookup (c,
- lookupCount, lookupRecord,
- lookup_context.funcs.closure);
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
+}
+
+static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
+ unsigned int backtrackCount,
+ const USHORT backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const USHORT lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextCollectGlyphsLookupContext &lookup_context)
+{
+ collect_array (c, c->before,
+ backtrackCount, backtrack,
+ lookup_context.funcs.collect, lookup_context.collect_data[0]);
+ collect_array (c, c->input,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.collect, lookup_context.collect_data[1]);
+ collect_array (c, c->after,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.collect, lookup_context.collect_data[2]);
+ recurse_lookups (c,
+ lookupCount, lookupRecord);
}
static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c,
unsigned int backtrackCount,
- const USHORT backtrack[],
+ const USHORT backtrack[] HB_UNUSED,
unsigned int inputCount, /* Including the first glyph (not matched) */
const USHORT input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
- const USHORT lookahead[],
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
+ const USHORT lookahead[] HB_UNUSED,
+ unsigned int lookupCount HB_UNUSED,
+ const LookupRecord lookupRecord[] HB_UNUSED,
ChainContextApplyLookupContext &lookup_context)
{
return (c->zero_context ? !backtrackCount && !lookaheadCount : true)
@@ -1224,7 +1481,7 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
const LookupRecord lookupRecord[],
ChainContextApplyLookupContext &lookup_context)
{
- unsigned int lookahead_offset;
+ unsigned int lookahead_offset = 0;
return match_input (c,
inputCount, input,
lookup_context.funcs.match, lookup_context.match_data[1],
@@ -1238,19 +1495,14 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
lookahead_offset)
&& apply_lookup (c,
inputCount,
- lookupCount, lookupRecord,
- lookup_context.funcs.apply);
+ lookupCount, lookupRecord);
}
struct ChainRule
{
- friend struct ChainRuleSet;
-
- private:
-
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
@@ -1262,9 +1514,23 @@ struct ChainRule
lookup_context);
}
+ 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 ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ chain_context_collect_glyphs_lookup (c,
+ backtrack.len, backtrack.array,
+ input.len, input.array,
+ lookahead.len, lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
@@ -1277,7 +1543,7 @@ struct ChainRule
inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
@@ -1288,9 +1554,8 @@ struct ChainRule
lookup.array, lookup_context));
}
- public:
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!backtrack.sanitize (c)) return TRACE_RETURN (false);
HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
if (!input.sanitize (c)) return TRACE_RETURN (false);
@@ -1322,15 +1587,23 @@ struct ChainRuleSet
{
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
unsigned int num_rules = rule.len;
for (unsigned int i = 0; i < num_rules; i++)
(this+rule[i]).closure (c, lookup_context);
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ (this+rule[i]).collect_glyphs (c, lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
unsigned int num_rules = rule.len;
for (unsigned int i = 0; i < num_rules; i++)
if ((this+rule[i]).would_apply (c, lookup_context))
@@ -1341,7 +1614,7 @@ struct ChainRuleSet
inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
unsigned int num_rules = rule.len;
for (unsigned int i = 0; i < num_rules; i++)
if ((this+rule[i]).apply (c, lookup_context))
@@ -1351,7 +1624,7 @@ struct ChainRuleSet
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (rule.sanitize (c, this));
}
@@ -1365,17 +1638,13 @@ struct ChainRuleSet
struct ChainContextFormat1
{
- friend struct ChainContext;
-
- private:
-
- inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
const Coverage &cov = (this+coverage);
struct ChainContextClosureLookupContext lookup_context = {
- {intersects_glyph, closure_func},
+ {intersects_glyph},
{NULL, NULL, NULL}
};
@@ -1387,34 +1656,54 @@ struct ChainContextFormat1
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_glyph},
+ {NULL, NULL, NULL}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
- const ChainRuleSet &rule_set = this+ruleSet[(this+coverage) (c->glyphs[0])];
+ const ChainRuleSet &rule_set = this+ruleSet[(this+coverage).get_coverage (c->glyphs[0])];
struct ChainContextApplyLookupContext lookup_context = {
- {match_glyph, NULL},
+ {match_glyph},
{NULL, NULL, NULL}
};
return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
}
- inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
+ inline const Coverage &get_coverage (void) const
+ {
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const ChainRuleSet &rule_set = this+ruleSet[index];
struct ChainContextApplyLookupContext lookup_context = {
- {match_glyph, apply_func},
+ {match_glyph},
{NULL, NULL, NULL}
};
return TRACE_RETURN (rule_set.apply (c, lookup_context));
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
}
@@ -1432,13 +1721,9 @@ struct ChainContextFormat1
struct ChainContextFormat2
{
- friend struct ChainContext;
-
- private:
-
- inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
if (!(this+coverage).intersects (c->glyphs))
return;
@@ -1447,7 +1732,7 @@ struct ChainContextFormat2
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
struct ChainContextClosureLookupContext lookup_context = {
- {intersects_class, closure_func},
+ {intersects_class},
{&backtrack_class_def,
&input_class_def,
&lookahead_class_def}
@@ -1461,35 +1746,65 @@ struct ChainContextFormat2
}
}
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+ruleSet[i]).collect_glyphs (c, lookup_context);
+ }
+
inline bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
- unsigned int index = input_class_def (c->glyphs[0]);
+ unsigned int index = input_class_def.get_class (c->glyphs[0]);
const ChainRuleSet &rule_set = this+ruleSet[index];
struct ChainContextApplyLookupContext lookup_context = {
- {match_class, NULL},
- {NULL, &input_class_def, NULL}
+ {match_class},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
};
return TRACE_RETURN (rule_set.would_apply (c, lookup_context));
}
- inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
+ inline const Coverage &get_coverage (void) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ return this+coverage;
+ }
+
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const ClassDef &backtrack_class_def = this+backtrackClassDef;
const ClassDef &input_class_def = this+inputClassDef;
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
- index = input_class_def (c->buffer->cur().codepoint);
+ index = input_class_def.get_class (c->buffer->cur().codepoint);
const ChainRuleSet &rule_set = this+ruleSet[index];
struct ChainContextApplyLookupContext lookup_context = {
- {match_class, apply_func},
+ {match_class},
{&backtrack_class_def,
&input_class_def,
&lookahead_class_def}
@@ -1498,7 +1813,7 @@ struct ChainContextFormat2
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) &&
inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) &&
ruleSet.sanitize (c, this));
@@ -1530,13 +1845,9 @@ struct ChainContextFormat2
struct ChainContextFormat3
{
- friend struct ChainContext;
-
- private:
-
- inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c) const
{
- TRACE_CLOSURE ();
+ TRACE_CLOSURE (this);
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
if (!(this+input[0]).intersects (c->glyphs))
@@ -1545,7 +1856,7 @@ struct ChainContextFormat3
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
struct ChainContextClosureLookupContext lookup_context = {
- {intersects_coverage, closure_func},
+ {intersects_coverage},
{this, this, this}
};
chain_context_closure_lookup (c,
@@ -1556,21 +1867,36 @@ struct ChainContextFormat3
lookup_context);
}
- inline const Coverage &get_coverage (void) const
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
+ TRACE_COLLECT_GLYPHS (this);
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
- return this+input[0];
+
+ (this+input[0]).add_coverage (c->input);
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextCollectGlyphsLookupContext lookup_context = {
+ {collect_coverage},
+ {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,
+ lookup.len, lookup.array,
+ lookup_context);
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
- TRACE_WOULD_APPLY ();
+ TRACE_WOULD_APPLY (this);
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
struct ChainContextApplyLookupContext lookup_context = {
- {match_coverage, NULL},
+ {match_coverage},
{this, this, this}
};
return TRACE_RETURN (chain_context_would_apply_lookup (c,
@@ -1580,18 +1906,24 @@ struct ChainContextFormat3
lookup.len, lookup.array, lookup_context));
}
- inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
+ inline const Coverage &get_coverage (void) const
{
- TRACE_APPLY ();
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+ return this+input[0];
+ }
- unsigned int index = (this+input[0]) (c->buffer->cur().codepoint);
+ inline bool apply (hb_apply_context_t *c) const
+ {
+ TRACE_APPLY (this);
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
struct ChainContextApplyLookupContext lookup_context = {
- {match_coverage, apply_func},
+ {match_coverage},
{this, this, this}
};
return TRACE_RETURN (chain_context_apply_lookup (c,
@@ -1602,7 +1934,7 @@ struct ChainContextFormat3
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false);
OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
if (!input.sanitize (c, this)) return TRACE_RETURN (false);
@@ -1635,52 +1967,20 @@ struct ChainContextFormat3
struct ChainContext
{
- protected:
-
- inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
- {
- TRACE_CLOSURE ();
- switch (u.format) {
- case 1: u.format1.closure (c, closure_func); break;
- case 2: u.format2.closure (c, closure_func); break;
- case 3: u.format3.closure (c, closure_func); break;
- default: break;
- }
- }
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return this + u.format1.coverage;
- case 2: return this + u.format2.coverage;
- case 3: return u.format3.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool would_apply (hb_would_apply_context_t *c) const
- {
- switch (u.format) {
- case 1: return u.format1.would_apply (c);
- case 2: return u.format2.would_apply (c);
- case 3: return u.format3.would_apply (c);
- default:return false;
- }
- }
-
- inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c, apply_func));
- case 2: return TRACE_RETURN (u.format2.apply (c, apply_func));
- case 3: return TRACE_RETURN (u.format3.apply (c, apply_func));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ case 2: return TRACE_RETURN (c->process (u.format2));
+ case 3: return TRACE_RETURN (c->process (u.format3));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -1702,14 +2002,11 @@ struct ChainContext
struct ExtensionFormat1
{
- friend struct Extension;
-
- protected:
inline unsigned int get_type (void) const { return extensionLookupType; }
inline unsigned int get_offset (void) const { return extensionOffset; }
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
@@ -1724,6 +2021,7 @@ struct ExtensionFormat1
DEFINE_SIZE_STATIC (8);
};
+template <typename T>
struct Extension
{
inline unsigned int get_type (void) const
@@ -1741,8 +2039,22 @@ struct Extension
}
}
- inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ template <typename X>
+ inline const X& get_subtable (void) const
+ {
+ unsigned int offset = get_offset ();
+ if (unlikely (!offset)) return Null(typename T::LookupSubTable);
+ return StructAtOffset<typename T::LookupSubTable> (this, offset);
+ }
+
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
+ {
+ return get_subtable<typename T::LookupSubTable> ().process (c, get_type ());
+ }
+
+ inline bool sanitize_self (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
@@ -1750,6 +2062,14 @@ struct Extension
}
}
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ if (!sanitize_self (c)) return TRACE_RETURN (false);
+ unsigned int offset = get_offset ();
+ if (unlikely (!offset)) return TRACE_RETURN (true);
+ return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ()));
+ }
+
protected:
union {
USHORT format; /* Format identifier */
@@ -1799,7 +2119,7 @@ struct GSUBGPOS
{ return (this+lookupList)[i]; }
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
scriptList.sanitize (c, this) &&
featureList.sanitize (c, this) &&
@@ -1820,7 +2140,7 @@ struct GSUBGPOS
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh
index 70fda8e..49093de 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-private.hh
@@ -50,12 +50,12 @@
*/
typedef enum {
- HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0001,
- HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002,
- HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 0x0004,
- HB_OT_LAYOUT_GLYPH_CLASS_MARK = 0x0008,
- HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010
-} hb_ot_layout_glyph_class_t;
+ HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED = 0x0001,
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x0002,
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x0004,
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x0008,
+ HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT = 0x0010
+} hb_ot_layout_glyph_class_mask_t;
@@ -123,7 +123,7 @@ get_lig_comp (const hb_glyph_info_t &info)
static inline unsigned int
get_lig_num_comps (const hb_glyph_info_t &info)
{
- if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE) && is_a_ligature (info))
+ if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info))
return info.lig_props() & 0x0F;
else
return 1;
@@ -138,7 +138,7 @@ static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
HB_INTERNAL hb_bool_t
-hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face,
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
unsigned int lookup_index,
const hb_codepoint_t *glyphs,
unsigned int glyphs_length,
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout.cc b/third_party/harfbuzz-ng/src/hb-ot-layout.cc
index e241e33..5c266e6 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout.cc
@@ -33,7 +33,6 @@
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
-#include "hb-ot-maxp-table.hh"
#include <stdlib.h>
#include <string.h>
@@ -71,9 +70,9 @@ _hb_ot_layout_create (hb_face_t *face)
}
for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
- layout->gsub->add_coverage (&layout->gsub_digests[i], i);
+ layout->gsub->get_lookup (i).add_coverage (&layout->gsub_digests[i]);
for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
- layout->gpos->add_coverage (&layout->gpos_digests[i], i);
+ layout->gpos->get_lookup (i).add_coverage (&layout->gpos_digests[i]);
return layout;
}
@@ -121,6 +120,20 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face)
return _get_gdef (face).has_glyph_classes ();
}
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class (hb_face_t *face,
+ hb_codepoint_t glyph)
+{
+ return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph);
+}
+
+void
+hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
+ hb_ot_layout_glyph_class_t klass,
+ hb_set_t *glyphs /* OUT */)
+{
+ return _get_gdef (face).get_glyphs_in_class (klass, glyphs);
+}
unsigned int
hb_ot_layout_get_attach_points (hb_face_t *face,
@@ -374,12 +387,12 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
}
unsigned int
-hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face,
- hb_tag_t table_tag,
- unsigned int feature_index,
- unsigned int start_offset,
- unsigned int *lookup_count /* IN/OUT */,
- unsigned int *lookup_indexes /* OUT */)
+hb_ot_layout_feature_get_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int feature_index,
+ unsigned int start_offset,
+ unsigned int *lookup_count /* IN/OUT */,
+ unsigned int *lookup_indexes /* OUT */)
{
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const OT::Feature &f = g.get_feature (feature_index);
@@ -387,6 +400,219 @@ hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face,
return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
}
+static void
+_hb_ot_layout_collect_lookups_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int feature_index,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ unsigned int lookup_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (lookup_indices);
+ hb_ot_layout_feature_get_lookups (face,
+ table_tag,
+ feature_index,
+ offset, &len,
+ lookup_indices);
+
+ for (unsigned int i = 0; i < len; i++)
+ lookup_indexes->add (lookup_indices[i]);
+
+ offset += len;
+ } while (len == ARRAY_LENGTH (lookup_indices));
+}
+
+static void
+_hb_ot_layout_collect_lookups_features (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ unsigned int language_index,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ unsigned int required_feature_index;
+ if (hb_ot_layout_language_get_required_feature_index (face,
+ table_tag,
+ script_index,
+ language_index,
+ &required_feature_index))
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ required_feature_index,
+ lookup_indexes);
+
+ if (!features)
+ {
+ /* All features */
+ unsigned int feature_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (feature_indices);
+ hb_ot_layout_language_get_feature_indexes (face,
+ table_tag,
+ script_index,
+ language_index,
+ offset, &len,
+ feature_indices);
+
+ for (unsigned int i = 0; i < len; i++)
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ feature_indices[i],
+ lookup_indexes);
+
+ offset += len;
+ } while (len == ARRAY_LENGTH (feature_indices));
+ }
+ else
+ {
+ for (; *features; features++)
+ {
+ unsigned int feature_index;
+ if (hb_ot_layout_language_find_feature (face,
+ table_tag,
+ script_index,
+ language_index,
+ *features,
+ &feature_index))
+ _hb_ot_layout_collect_lookups_lookups (face,
+ table_tag,
+ feature_index,
+ lookup_indexes);
+ }
+ }
+}
+
+static void
+_hb_ot_layout_collect_lookups_languages (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int script_index,
+ const hb_tag_t *languages,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
+ features,
+ lookup_indexes);
+
+ if (!languages)
+ {
+ /* All languages */
+ unsigned int count = hb_ot_layout_script_get_language_tags (face,
+ table_tag,
+ script_index,
+ 0, NULL, NULL);
+ for (unsigned int language_index = 0; language_index < count; language_index++)
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ language_index,
+ features,
+ lookup_indexes);
+ }
+ else
+ {
+ for (; *languages; languages++)
+ {
+ unsigned int language_index;
+ if (hb_ot_layout_script_find_language (face,
+ table_tag,
+ script_index,
+ *languages,
+ &language_index))
+ _hb_ot_layout_collect_lookups_features (face,
+ table_tag,
+ script_index,
+ language_index,
+ features,
+ lookup_indexes);
+ }
+ }
+}
+
+void
+hb_ot_layout_collect_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ const hb_tag_t *scripts,
+ const hb_tag_t *languages,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ if (!scripts)
+ {
+ /* All scripts */
+ unsigned int count = hb_ot_layout_table_get_script_tags (face,
+ table_tag,
+ 0, NULL, NULL);
+ for (unsigned int script_index = 0; script_index < count; script_index++)
+ _hb_ot_layout_collect_lookups_languages (face,
+ table_tag,
+ script_index,
+ languages,
+ features,
+ lookup_indexes);
+ }
+ else
+ {
+ for (; *scripts; scripts++)
+ {
+ unsigned int script_index;
+ if (hb_ot_layout_table_find_script (face,
+ table_tag,
+ *scripts,
+ &script_index))
+ _hb_ot_layout_collect_lookups_languages (face,
+ table_tag,
+ script_index,
+ languages,
+ features,
+ lookup_indexes);
+ }
+ }
+}
+
+void
+hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ hb_set_t *glyphs_before, /* OUT. May be NULL */
+ hb_set_t *glyphs_input, /* OUT. May be NULL */
+ hb_set_t *glyphs_after, /* OUT. May be NULL */
+ hb_set_t *glyphs_output /* OUT. May be NULL */)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
+
+ OT::hb_collect_glyphs_context_t c (face,
+ glyphs_before,
+ glyphs_input,
+ glyphs_after,
+ glyphs_output);
+
+ switch (table_tag)
+ {
+ case HB_OT_TAG_GSUB:
+ {
+ const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
+ l.collect_glyphs_lookup (&c);
+ return;
+ }
+ case HB_OT_TAG_GPOS:
+ {
+ const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index);
+ l.collect_glyphs_lookup (&c);
+ return;
+ }
+ }
+}
+
/*
* OT::GSUB
@@ -399,18 +625,18 @@ hb_ot_layout_has_substitution (hb_face_t *face)
}
hb_bool_t
-hb_ot_layout_would_substitute_lookup (hb_face_t *face,
+hb_ot_layout_lookup_would_substitute (hb_face_t *face,
unsigned int lookup_index,
const hb_codepoint_t *glyphs,
unsigned int glyphs_length,
hb_bool_t zero_context)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false;
- return hb_ot_layout_would_substitute_lookup_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
+ return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context);
}
hb_bool_t
-hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face,
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
unsigned int lookup_index,
const hb_codepoint_t *glyphs,
unsigned int glyphs_length,
@@ -452,12 +678,15 @@ hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer)
}
void
-hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
+hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
unsigned int lookup_index,
hb_set_t *glyphs)
{
OT::hb_closure_context_t c (face, glyphs);
- _get_gsub (face).closure_lookup (&c, lookup_index);
+
+ const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index);
+
+ l.closure (&c);
}
/*
@@ -496,3 +725,48 @@ hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t ze
{
OT::GPOS::position_finish (font, buffer, zero_width_attached_marks);
}
+
+hb_bool_t
+hb_ot_layout_get_size_params (hb_face_t *face,
+ unsigned int *design_size, /* OUT. May be NULL */
+ unsigned int *subfamily_id, /* OUT. May be NULL */
+ unsigned int *subfamily_name_id, /* OUT. May be NULL */
+ unsigned int *range_start, /* OUT. May be NULL */
+ unsigned int *range_end /* OUT. May be NULL */)
+{
+ const OT::GPOS &gpos = _get_gpos (face);
+ const hb_tag_t tag = HB_TAG ('s','i','z','e');
+
+ unsigned int num_features = gpos.get_feature_count ();
+ for (unsigned int i = 0; i < num_features; i++)
+ {
+ if (tag == gpos.get_feature_tag (i))
+ {
+ const OT::Feature &f = gpos.get_feature (i);
+ const OT::FeatureParamsSize &params = f.get_feature_params ().get_size_params (tag);
+
+ if (params.designSize)
+ {
+#define PARAM(a, A) if (a) *a = params.A
+ PARAM (design_size, designSize);
+ PARAM (subfamily_id, subfamilyID);
+ PARAM (subfamily_name_id, subfamilyNameID);
+ PARAM (range_start, rangeStart);
+ PARAM (range_end, rangeEnd);
+#undef PARAM
+
+ return true;
+ }
+ }
+ }
+
+#define PARAM(a, A) if (a) *a = 0
+ PARAM (design_size, designSize);
+ PARAM (subfamily_id, subfamilyID);
+ PARAM (subfamily_name_id, subfamilyNameID);
+ PARAM (range_start, rangeStart);
+ PARAM (range_end, rangeEnd);
+#undef PARAM
+
+ return false;
+}
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout.h b/third_party/harfbuzz-ng/src/hb-ot-layout.h
index d431a38..134f1a6 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-layout.h
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout.h
@@ -50,6 +50,24 @@ HB_BEGIN_DECLS
hb_bool_t
hb_ot_layout_has_glyph_classes (hb_face_t *face);
+typedef enum {
+ HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0,
+ HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 1,
+ HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 2,
+ HB_OT_LAYOUT_GLYPH_CLASS_MARK = 3,
+ HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 4
+} hb_ot_layout_glyph_class_t;
+
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class (hb_face_t *face,
+ hb_codepoint_t glyph);
+
+void
+hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
+ hb_ot_layout_glyph_class_t klass,
+ hb_set_t *glyphs /* OUT */);
+
+
/* Not that useful. Provides list of attach points for a glyph that a
* client may want to cache */
unsigned int
@@ -154,12 +172,60 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
unsigned int *feature_index);
unsigned int
-hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face,
+hb_ot_layout_feature_get_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int feature_index,
+ unsigned int start_offset,
+ unsigned int *lookup_count /* IN/OUT */,
+ unsigned int *lookup_indexes /* OUT */);
+
+void
+hb_ot_layout_collect_lookups (hb_face_t *face,
+ hb_tag_t table_tag,
+ const hb_tag_t *scripts,
+ const hb_tag_t *languages,
+ const hb_tag_t *features,
+ hb_set_t *lookup_indexes /* OUT */);
+
+void
+hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
+ hb_tag_t table_tag,
+ hb_set_t *lookup_indexes /* OUT */);
+
+void
+hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ hb_set_t *glyphs_before, /* OUT. May be NULL */
+ hb_set_t *glyphs_input, /* OUT. May be NULL */
+ hb_set_t *glyphs_after, /* OUT. May be NULL */
+ hb_set_t *glyphs_output /* OUT. May be NULL */);
+
+#ifdef HB_NOT_IMPLEMENTED
+typedef struct
+{
+ const hb_codepoint_t *before,
+ unsigned int before_length,
+ const hb_codepoint_t *input,
+ unsigned int input_length,
+ const hb_codepoint_t *after,
+ unsigned int after_length,
+} hb_ot_layout_glyph_sequence_t;
+
+typedef hb_bool_t
+(*hb_ot_layout_glyph_sequence_func_t) (hb_font_t *font,
+ hb_tag_t table_tag,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ void *user_data);
+
+void
+Xhb_ot_layout_lookup_enumerate_sequences (hb_face_t *face,
hb_tag_t table_tag,
- unsigned int feature_index,
- unsigned int start_offset,
- unsigned int *lookup_count /* IN/OUT */,
- unsigned int *lookup_indexes /* OUT */);
+ unsigned int lookup_index,
+ hb_ot_layout_glyph_sequence_func_t callback,
+ void *user_data);
+#endif
/*
@@ -170,16 +236,30 @@ hb_bool_t
hb_ot_layout_has_substitution (hb_face_t *face);
hb_bool_t
-hb_ot_layout_would_substitute_lookup (hb_face_t *face,
+hb_ot_layout_lookup_would_substitute (hb_face_t *face,
unsigned int lookup_index,
const hb_codepoint_t *glyphs,
unsigned int glyphs_length,
hb_bool_t zero_context);
void
-hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
+hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
unsigned int lookup_index,
- hb_set_t *glyphs);
+ hb_set_t *glyphs
+ /*TODO , hb_bool_t inclusive */);
+
+#ifdef HB_NOT_IMPLEMENTED
+/* Note: You better have GDEF when using this API, or marks won't do much. */
+hb_bool_t
+Xhb_ot_layout_lookup_substitute (hb_font_t *font,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ unsigned int out_size,
+ hb_codepoint_t *glyphs_out, /* OUT */
+ unsigned int *clusters_out, /* OUT */
+ unsigned int *out_length /* OUT */);
+#endif
+
/*
* GPOS
@@ -188,6 +268,25 @@ hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
hb_bool_t
hb_ot_layout_has_positioning (hb_face_t *face);
+#ifdef HB_NOT_IMPLEMENTED
+/* Note: You better have GDEF when using this API, or marks won't do much. */
+hb_bool_t
+Xhb_ot_layout_lookup_position (hb_font_t *font,
+ unsigned int lookup_index,
+ const hb_ot_layout_glyph_sequence_t *sequence,
+ hb_glyph_position_t *positions /* IN / OUT */);
+#endif
+
+/* Optical 'size' feature info. Returns true if found.
+ * http://www.microsoft.com/typography/otspec/features_pt.htm#size */
+hb_bool_t
+hb_ot_layout_get_size_params (hb_face_t *face,
+ unsigned int *design_size, /* OUT. May be NULL */
+ unsigned int *subfamily_id, /* OUT. May be NULL */
+ unsigned int *subfamily_name_id, /* OUT. May be NULL */
+ unsigned int *range_start, /* OUT. May be NULL */
+ unsigned int *range_end /* OUT. May be NULL */);
+
HB_END_DECLS
diff --git a/third_party/harfbuzz-ng/src/hb-ot-map-private.hh b/third_party/harfbuzz-ng/src/hb-ot-map-private.hh
index 7eb85c89..b140207 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-map-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-map-private.hh
@@ -115,10 +115,7 @@ struct hb_ot_map_t
*lookup_count = end - start;
}
- inline hb_tag_t get_chosen_script (unsigned int table_index) const
- { return chosen_script[table_index]; }
-
- HB_INTERNAL void substitute_closure (const struct hb_ot_shape_plan_t *plan, hb_face_t *face, hb_set_t *glyphs) const;
+ HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const;
HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const;
@@ -130,6 +127,9 @@ struct hb_ot_map_t
pauses[1].finish ();
}
+ public:
+ hb_tag_t chosen_script[2];
+ bool found_script[2];
private:
@@ -140,7 +140,6 @@ struct hb_ot_map_t
hb_mask_t global_mask;
- hb_tag_t chosen_script[2];
hb_prealloced_array_t<feature_map_t, 8> features;
hb_prealloced_array_t<lookup_map_t, 32> lookups[2]; /* GSUB/GPOS */
hb_prealloced_array_t<pause_map_t, 1> pauses[2]; /* GSUB/GPOS */
@@ -151,7 +150,8 @@ struct hb_ot_map_builder_t
{
public:
- hb_ot_map_builder_t (void) { memset (this, 0, sizeof (*this)); }
+ HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_,
+ const hb_segment_properties_t *props_);
HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback = false);
@@ -163,9 +163,7 @@ struct hb_ot_map_builder_t
inline void add_gpos_pause (hb_ot_map_t::pause_func_t pause_func)
{ add_pause (1, pause_func); }
- HB_INTERNAL void compile (hb_face_t *face,
- const hb_segment_properties_t *props,
- struct hb_ot_map_t &m);
+ HB_INTERNAL void compile (struct hb_ot_map_t &m);
inline void finish (void) {
feature_infos.finish ();
@@ -195,6 +193,17 @@ struct hb_ot_map_builder_t
HB_INTERNAL void add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func);
+ public:
+
+ hb_face_t *face;
+ hb_segment_properties_t props;
+
+ hb_tag_t chosen_script[2];
+ bool found_script[2];
+ unsigned int script_index[2], language_index[2];
+
+ private:
+
unsigned int current_stage[2]; /* GSUB/GPOS */
hb_prealloced_array_t<feature_info_t,16> feature_infos;
hb_prealloced_array_t<pause_info_t, 1> pauses[2]; /* GSUB/GPOS */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-map.cc b/third_party/harfbuzz-ng/src/hb-ot-map.cc
index f290c98..62f7904 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-map.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-map.cc
@@ -41,11 +41,11 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
offset = 0;
do {
len = ARRAY_LENGTH (lookup_indices);
- hb_ot_layout_feature_get_lookup_indexes (face,
- table_tags[table_index],
- feature_index,
- offset, &len,
- lookup_indices);
+ hb_ot_layout_feature_get_lookups (face,
+ table_tags[table_index],
+ feature_index,
+ offset, &len,
+ lookup_indices);
for (unsigned int i = 0; i < len; i++) {
hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push ();
@@ -59,6 +59,30 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
} while (len == ARRAY_LENGTH (lookup_indices));
}
+hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
+ const hb_segment_properties_t *props_)
+{
+ memset (this, 0, sizeof (*this));
+
+ face = face_;
+ props = *props_;
+
+
+ /* Fetch script/language indices for GSUB/GPOS. We need these later to skip
+ * features not available in either table and not waste precious bits for them. */
+
+ hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE};
+ hb_tag_t language_tag;
+
+ hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]);
+ language_tag = hb_ot_tag_from_language (props.language);
+
+ for (unsigned int table_index = 0; table_index < 2; table_index++) {
+ hb_tag_t table_tag = table_tags[table_index];
+ found_script[table_index] = hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]);
+ hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
+ }
+}
void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool global, bool has_fallback)
{
@@ -114,11 +138,10 @@ void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_
hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
}
-void hb_ot_map_t::substitute_closure (const hb_ot_shape_plan_t *plan, hb_face_t *face, hb_set_t *glyphs) const
+void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const
{
- unsigned int table_index = 0;
for (unsigned int i = 0; i < lookups[table_index].len; i++)
- hb_ot_layout_substitute_closure_lookup (face, lookups[table_index][i].index, glyphs);
+ hb_set_add (lookups_out, lookups[table_index][i].index);
}
void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func)
@@ -133,32 +156,17 @@ void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::paus
}
void
-hb_ot_map_builder_t::compile (hb_face_t *face,
- const hb_segment_properties_t *props,
- hb_ot_map_t &m)
+hb_ot_map_builder_t::compile (hb_ot_map_t &m)
{
- m.global_mask = 1;
+ m.global_mask = 1;
- if (!feature_infos.len)
- return;
-
-
- /* Fetch script/language indices for GSUB/GPOS. We need these later to skip
- * features not available in either table and not waste precious bits for them. */
-
- hb_tag_t script_tags[3] = {HB_TAG_NONE};
- hb_tag_t language_tag;
-
- hb_ot_tags_from_script (props->script, &script_tags[0], &script_tags[1]);
- language_tag = hb_ot_tag_from_language (props->language);
-
- unsigned int script_index[2], language_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++) {
- hb_tag_t table_tag = table_tags[table_index];
- hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &m.chosen_script[table_index]);
- hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
+ m.chosen_script[table_index] = chosen_script[table_index];
+ m.found_script[table_index] = found_script[table_index];
}
+ if (!feature_infos.len)
+ return;
/* Sort features and merge duplicates */
{
diff --git a/third_party/harfbuzz-ng/src/hb-ot-maxp-table.hh b/third_party/harfbuzz-ng/src/hb-ot-maxp-table.hh
index 9e113c7..0ce3ebc 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-maxp-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-maxp-table.hh
@@ -48,7 +48,7 @@ struct maxp
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) &&
likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000)));
}
@@ -63,7 +63,7 @@ struct maxp
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_MAXP_TABLE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-name-table.hh b/third_party/harfbuzz-ng/src/hb-ot-name-table.hh
index 6cc7a5ea..75a1b94 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-name-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-name-table.hh
@@ -57,7 +57,7 @@ struct NameRecord
}
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
/* We can check from base all the way up to the end of string... */
return TRACE_RETURN (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
}
@@ -99,7 +99,7 @@ struct name
}
inline bool sanitize_records (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
char *string_pool = (char *) this + stringOffset;
unsigned int _count = count;
for (unsigned int i = 0; i < _count; i++)
@@ -108,7 +108,7 @@ struct name
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) &&
likely (format == 0 || format == 1) &&
c->check_array (nameRecord, nameRecord[0].static_size, count) &&
@@ -126,7 +126,7 @@ struct name
};
-} // namespace OT
+} /* namespace OT */
#endif /* HB_OT_NAME_TABLE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
index bf68561..4fcd0a2 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -53,7 +53,7 @@ enum {
};
static OT::SubstLookup *
-arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan,
+arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
unsigned int feature_index)
{
@@ -103,7 +103,7 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan,
}
static OT::SubstLookup *
-arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan,
+arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font)
{
OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
index 5e29167..730a275 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh
@@ -6,8 +6,8 @@
*
* on files with these headers:
*
- * # ArabicShaping-6.1.0.txt
- * # Date: 2011-04-15, 23:16:00 GMT [KW]
+ * # ArabicShaping-6.2.0.txt
+ * # Date: 2012-05-15, 21:05:00 GMT [KW]
* UnicodeData.txt does not have a header.
*/
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
index 8428534..35356fe 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
@@ -64,15 +64,31 @@ static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ
return j_type;
}
- /* Mongolian joining data is not in ArabicJoining.txt yet */
+ /* Mongolian joining data is not in ArabicJoining.txt yet. */
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1800, 0x18AF)))
{
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1880, 0x1886)))
+ return JOINING_TYPE_U;
+
/* All letters, SIBE SYLLABLE BOUNDARY MARKER, and NIRUGU are D */
- if (gen_cat == HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER || u == 0x1807 || u == 0x180A)
+ if ((FLAG(gen_cat) & (FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) |
+ FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_LETTER)))
+ || u == 0x1807 || u == 0x180A)
+ return JOINING_TYPE_D;
+ }
+
+ /* 'Phags-pa joining data is not in ArabicJoining.txt yet. */
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xA840, 0xA872)))
+ {
+ if (unlikely (u == 0xA872))
+ /* XXX Looks like this should be TYPE_L, but we don't support that yet! */
+ return JOINING_TYPE_R;
+
return JOINING_TYPE_D;
}
- if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D))) {
+ if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D)))
+ {
return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C;
}
@@ -235,17 +251,18 @@ arabic_joining (hb_buffer_t *buffer)
HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
/* Check pre-context */
- for (unsigned int i = 0; i < buffer->context_len[0]; i++)
- {
- unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
+ if (!(buffer->flags & HB_BUFFER_FLAG_BOT))
+ for (unsigned int i = 0; i < buffer->context_len[0]; i++)
+ {
+ unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
- if (unlikely (this_type == JOINING_TYPE_T))
- continue;
+ if (unlikely (this_type == JOINING_TYPE_T))
+ continue;
- const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
- state = entry->next_state;
- break;
- }
+ const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+ state = entry->next_state;
+ break;
+ }
for (unsigned int i = 0; i < count; i++)
{
@@ -267,18 +284,19 @@ arabic_joining (hb_buffer_t *buffer)
state = entry->next_state;
}
- for (unsigned int i = 0; i < buffer->context_len[1]; i++)
- {
- unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[0][i]));
+ if (!(buffer->flags & HB_BUFFER_FLAG_EOT))
+ for (unsigned int i = 0; i < buffer->context_len[1]; i++)
+ {
+ unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[1][i]));
- if (unlikely (this_type == JOINING_TYPE_T))
- continue;
+ if (unlikely (this_type == JOINING_TYPE_T))
+ continue;
- const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
- if (entry->prev_action != NONE && prev != (unsigned int) -1)
- buffer->info[prev].arabic_shaping_action() = entry->prev_action;
- break;
- }
+ const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+ if (entry->prev_action != NONE && prev != (unsigned int) -1)
+ buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+ break;
+ }
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
@@ -287,7 +305,7 @@ arabic_joining (hb_buffer_t *buffer)
static void
setup_masks_arabic (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
- hb_font_t *font)
+ hb_font_t *font HB_UNUSED)
{
const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data;
@@ -333,6 +351,9 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
data_destroy_arabic,
NULL, /* preprocess_text_arabic */
NULL, /* normalization_preference */
+ NULL, /* decompose */
+ NULL, /* compose */
setup_masks_arabic,
true, /* zero_width_attached_marks */
+ true, /* fallback_position */
};
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
new file mode 100644
index 0000000..5340293
--- /dev/null
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-default.cc
@@ -0,0 +1,226 @@
+/*
+ * Copyright © 2010,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-private.hh"
+
+
+/* TODO Add kana, and other small shapers here */
+
+
+/* The default shaper *only* adds additional per-script features.*/
+
+static const hb_tag_t hangul_features[] =
+{
+ HB_TAG('l','j','m','o'),
+ HB_TAG('v','j','m','o'),
+ HB_TAG('t','j','m','o'),
+ HB_TAG_NONE
+};
+
+static const hb_tag_t tibetan_features[] =
+{
+ HB_TAG('a','b','v','s'),
+ HB_TAG('b','l','w','s'),
+ HB_TAG('a','b','v','m'),
+ HB_TAG('b','l','w','m'),
+ HB_TAG_NONE
+};
+
+static void
+collect_features_default (hb_ot_shape_planner_t *plan)
+{
+ const hb_tag_t *script_features = NULL;
+
+ switch ((hb_tag_t) plan->props.script)
+ {
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_HANGUL:
+ script_features = hangul_features;
+ break;
+
+ /* Unicode-2.0 additions */
+ case HB_SCRIPT_TIBETAN:
+ script_features = tibetan_features;
+ break;
+ }
+
+ for (; script_features && *script_features; script_features++)
+ plan->map.add_bool_feature (*script_features);
+}
+
+static hb_ot_shape_normalization_mode_t
+normalization_preference_default (const hb_segment_properties_t *props)
+{
+ switch ((hb_tag_t) props->script)
+ {
+ /* Unicode-1.1 additions */
+ case HB_SCRIPT_HANGUL:
+ return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL;
+ }
+ return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
+}
+
+static bool
+compose_default (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab)
+{
+ /* Hebrew presentation-form shaping.
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=728866
+ * Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
+ * Note that some letters do not have a dagesh presForm encoded.
+ */
+ static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
+ 0xFB30, /* ALEF */
+ 0xFB31, /* BET */
+ 0xFB32, /* GIMEL */
+ 0xFB33, /* DALET */
+ 0xFB34, /* HE */
+ 0xFB35, /* VAV */
+ 0xFB36, /* ZAYIN */
+ 0x0000, /* HET */
+ 0xFB38, /* TET */
+ 0xFB39, /* YOD */
+ 0xFB3A, /* FINAL KAF */
+ 0xFB3B, /* KAF */
+ 0xFB3C, /* LAMED */
+ 0x0000, /* FINAL MEM */
+ 0xFB3E, /* MEM */
+ 0x0000, /* FINAL NUN */
+ 0xFB40, /* NUN */
+ 0xFB41, /* SAMEKH */
+ 0x0000, /* AYIN */
+ 0xFB43, /* FINAL PE */
+ 0xFB44, /* PE */
+ 0x0000, /* FINAL TSADI */
+ 0xFB46, /* TSADI */
+ 0xFB47, /* QOF */
+ 0xFB48, /* RESH */
+ 0xFB49, /* SHIN */
+ 0xFB4A /* TAV */
+ };
+
+ bool found = c->unicode->compose (a, b, ab);
+
+ if (!found && (b & ~0x7F) == 0x0580) {
+ /* Special-case Hebrew presentation forms that are excluded from
+ * standard normalization, but wanted for old fonts. */
+ switch (b) {
+ case 0x05B4: /* HIRIQ */
+ if (a == 0x05D9) { /* YOD */
+ *ab = 0xFB1D;
+ found = true;
+ }
+ break;
+ case 0x05B7: /* patah */
+ if (a == 0x05F2) { /* YIDDISH YOD YOD */
+ *ab = 0xFB1F;
+ found = true;
+ } else if (a == 0x05D0) { /* ALEF */
+ *ab = 0xFB2E;
+ found = true;
+ }
+ break;
+ case 0x05B8: /* QAMATS */
+ if (a == 0x05D0) { /* ALEF */
+ *ab = 0xFB2F;
+ found = true;
+ }
+ break;
+ case 0x05B9: /* HOLAM */
+ if (a == 0x05D5) { /* VAV */
+ *ab = 0xFB4B;
+ found = true;
+ }
+ break;
+ case 0x05BC: /* DAGESH */
+ if (a >= 0x05D0 && a <= 0x05EA) {
+ *ab = sDageshForms[a - 0x05D0];
+ found = (*ab != 0);
+ } else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */
+ *ab = 0xFB2C;
+ found = true;
+ } else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */
+ *ab = 0xFB2D;
+ found = true;
+ }
+ break;
+ case 0x05BF: /* RAFE */
+ switch (a) {
+ case 0x05D1: /* BET */
+ *ab = 0xFB4C;
+ found = true;
+ break;
+ case 0x05DB: /* KAF */
+ *ab = 0xFB4D;
+ found = true;
+ break;
+ case 0x05E4: /* PE */
+ *ab = 0xFB4E;
+ found = true;
+ break;
+ }
+ break;
+ case 0x05C1: /* SHIN DOT */
+ if (a == 0x05E9) { /* SHIN */
+ *ab = 0xFB2A;
+ found = true;
+ } else if (a == 0xFB49) { /* SHIN WITH DAGESH */
+ *ab = 0xFB2C;
+ found = true;
+ }
+ break;
+ case 0x05C2: /* SIN DOT */
+ if (a == 0x05E9) { /* SHIN */
+ *ab = 0xFB2B;
+ found = true;
+ } else if (a == 0xFB49) { /* SHIN WITH DAGESH */
+ *ab = 0xFB2D;
+ found = true;
+ }
+ break;
+ }
+ }
+
+ return found;
+}
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
+{
+ "default",
+ collect_features_default,
+ NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
+ NULL, /* preprocess_text */
+ normalization_preference_default,
+ NULL, /* decompose */
+ compose_default,
+ NULL, /* setup_masks */
+ true, /* zero_width_attached_marks */
+ true, /* fallback_position */
+};
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
index 53f22e3..ed40b96 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.hh
@@ -51,45 +51,52 @@ static const unsigned char _indic_syllable_machine_trans_keys[] = {
5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u,
7u, 7u, 4u, 4u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u,
6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 14u, 4u, 14u, 4u, 14u,
- 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 1u, 16u,
- 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u,
- 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u,
- 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u,
- 3u, 13u, 3u, 9u, 8u, 9u, 3u, 9u, 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, 6u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u,
- 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u,
- 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u,
- 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
- 1u, 16u, 3u, 14u, 3u, 14u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u,
- 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u,
- 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u,
- 5u, 9u, 9u, 9u, 9u, 9u, 3u, 13u, 3u, 9u, 8u, 9u, 3u, 9u, 3u, 13u,
+ 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u, 4u, 14u,
+ 4u, 14u, 5u, 7u, 5u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 5u, 7u, 5u, 7u,
+ 7u, 7u, 5u, 7u, 5u, 7u, 7u, 7u, 1u, 16u, 13u, 13u, 4u, 4u, 6u, 6u,
+ 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u, 6u, 6u, 16u, 16u, 4u, 7u,
+ 6u, 6u, 16u, 16u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
+ 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
+ 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u,
+ 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, 8u, 9u, 3u, 9u, 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, 6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u,
- 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u,
- 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u,
- 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u,
- 1u, 16u, 1u, 16u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u,
- 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u,
- 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 5u, 14u,
- 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 13u, 3u, 9u, 8u, 9u, 3u, 9u,
- 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, 6u, 14u, 3u, 14u, 1u, 16u,
+ 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 6u, 14u, 3u, 14u, 4u, 14u, 1u, 16u,
3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u,
3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u,
1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u,
- 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 3u, 14u, 4u, 14u, 3u, 14u,
- 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u,
- 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 14u,
- 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 13u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 3u, 14u, 3u, 14u,
+ 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
+ 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
+ 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u,
+ 8u, 9u, 3u, 9u, 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, 6u, 14u,
+ 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u,
+ 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u, 1u, 16u, 3u, 14u,
+ 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
+ 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u,
+ 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 17u,
3u, 9u, 8u, 9u, 3u, 9u, 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,
6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u,
1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u,
- 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u,
- 1u, 16u, 3u, 14u, 1u, 16u, 0
+ 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 4u, 14u,
+ 3u, 14u, 4u, 14u, 3u, 14u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
+ 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u,
+ 4u, 14u, 1u, 16u, 3u, 17u, 3u, 14u, 4u, 14u, 5u, 14u, 8u, 14u, 5u, 9u,
+ 9u, 9u, 9u, 9u, 3u, 17u, 3u, 9u, 8u, 9u, 3u, 9u, 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, 6u, 14u, 3u, 14u, 1u, 16u, 3u, 14u, 3u, 14u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 1u, 16u, 3u, 14u, 3u, 14u, 1u, 16u, 1u, 16u, 1u, 16u,
+ 1u, 16u, 1u, 16u, 3u, 14u, 1u, 16u, 3u, 17u, 1u, 16u, 4u, 14u, 1u, 16u,
+ 3u, 17u, 3u, 14u, 4u, 14u, 5u, 9u, 9u, 9u, 9u, 9u, 3u, 14u, 3u, 14u,
+ 1u, 16u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 5u, 14u, 3u, 14u,
+ 4u, 14u, 5u, 14u, 3u, 14u, 4u, 14u, 8u, 14u, 3u, 17u, 3u, 9u, 8u, 9u,
+ 3u, 9u, 3u, 13u, 1u, 16u, 0
};
static const char _indic_syllable_machine_key_spans[] = {
@@ -110,45 +117,52 @@ static const char _indic_syllable_machine_key_spans[] = {
3, 3, 1, 3, 3, 1, 3, 3,
1, 1, 1, 1, 4, 1, 1, 4,
1, 1, 4, 1, 1, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 16,
- 12, 12, 11, 16, 12, 12, 11, 16,
- 12, 12, 11, 16, 12, 12, 11, 16,
- 12, 12, 11, 10, 7, 5, 1, 1,
- 11, 7, 2, 7, 11, 12, 12, 11,
- 10, 12, 11, 10, 12, 11, 10, 12,
- 11, 9, 12, 11, 16, 12, 12, 16,
- 16, 16, 16, 16, 12, 12, 16, 16,
- 16, 16, 16, 12, 12, 16, 16, 16,
- 16, 16, 12, 12, 16, 16, 16, 16,
- 16, 12, 12, 12, 12, 11, 16, 12,
- 12, 11, 16, 12, 12, 11, 16, 12,
- 12, 11, 16, 12, 12, 11, 10, 7,
- 5, 1, 1, 11, 7, 2, 7, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 3, 3, 3, 3, 1, 3, 3,
+ 1, 3, 3, 1, 16, 1, 1, 1,
+ 1, 4, 1, 1, 4, 1, 1, 4,
+ 1, 1, 16, 15, 12, 11, 16, 15,
+ 12, 11, 16, 15, 12, 11, 16, 15,
+ 12, 11, 16, 15, 12, 11, 10, 7,
+ 5, 1, 1, 15, 7, 2, 7, 11,
12, 12, 11, 10, 12, 11, 10, 12,
- 11, 10, 12, 11, 9, 12, 16, 12,
- 12, 16, 16, 16, 16, 16, 12, 12,
- 16, 16, 16, 16, 16, 12, 12, 16,
- 16, 16, 16, 16, 12, 12, 16, 16,
- 16, 16, 11, 16, 12, 12, 11, 16,
- 12, 12, 11, 16, 12, 12, 11, 16,
- 12, 12, 11, 16, 12, 12, 11, 10,
- 7, 5, 1, 1, 11, 7, 2, 7,
- 11, 12, 12, 11, 10, 12, 11, 10,
- 12, 11, 10, 12, 11, 9, 12, 16,
+ 11, 10, 12, 11, 9, 12, 11, 16,
12, 12, 16, 16, 16, 16, 16, 12,
12, 16, 16, 16, 16, 16, 12, 12,
16, 16, 16, 16, 16, 12, 12, 16,
- 16, 16, 16, 16, 11, 12, 11, 12,
- 12, 11, 16, 12, 12, 11, 16, 12,
- 12, 11, 16, 12, 12, 11, 16, 12,
- 12, 11, 10, 7, 5, 1, 1, 11,
+ 16, 16, 16, 16, 12, 12, 12, 12,
+ 11, 16, 15, 12, 11, 16, 15, 12,
+ 11, 16, 15, 12, 11, 16, 15, 12,
+ 11, 10, 7, 5, 1, 1, 15, 7,
+ 2, 7, 11, 12, 12, 11, 10, 12,
+ 11, 10, 12, 11, 10, 12, 11, 9,
+ 12, 16, 12, 12, 16, 16, 16, 16,
+ 16, 12, 12, 16, 16, 16, 16, 16,
+ 12, 12, 16, 16, 16, 16, 16, 12,
+ 12, 16, 16, 16, 16, 11, 16, 12,
+ 12, 11, 16, 15, 12, 11, 16, 15,
+ 12, 11, 16, 15, 12, 11, 16, 15,
+ 12, 11, 10, 7, 5, 1, 1, 15,
7, 2, 7, 11, 12, 12, 11, 10,
12, 11, 10, 12, 11, 10, 12, 11,
9, 12, 16, 12, 12, 16, 16, 16,
16, 16, 12, 12, 16, 16, 16, 16,
16, 12, 12, 16, 16, 16, 16, 16,
- 12, 12, 16, 16, 16, 16, 16, 12,
- 16, 12, 16
+ 12, 12, 16, 16, 16, 16, 16, 11,
+ 12, 11, 12, 12, 11, 16, 15, 12,
+ 11, 16, 15, 12, 11, 16, 15, 12,
+ 11, 16, 15, 12, 11, 10, 7, 5,
+ 1, 1, 15, 7, 2, 7, 11, 12,
+ 12, 11, 10, 12, 11, 10, 12, 11,
+ 10, 12, 11, 9, 12, 16, 12, 12,
+ 16, 16, 16, 16, 16, 12, 12, 16,
+ 16, 16, 16, 16, 12, 12, 16, 16,
+ 16, 16, 16, 12, 12, 16, 16, 16,
+ 16, 16, 12, 16, 15, 16, 11, 16,
+ 15, 12, 11, 5, 1, 1, 12, 12,
+ 16, 12, 11, 10, 12, 11, 10, 12,
+ 11, 10, 12, 11, 7, 15, 7, 2,
+ 7, 11, 16
};
static const short _indic_syllable_machine_index_offsets[] = {
@@ -170,44 +184,51 @@ static const short _indic_syllable_machine_index_offsets[] = {
681, 683, 685, 687, 689, 694, 696, 698,
703, 705, 707, 712, 714, 716, 728, 740,
752, 764, 776, 788, 800, 812, 824, 836,
- 853, 866, 879, 891, 908, 921, 934, 946,
- 963, 976, 989, 1001, 1018, 1031, 1044, 1056,
- 1073, 1086, 1099, 1111, 1122, 1130, 1136, 1138,
- 1140, 1152, 1160, 1163, 1171, 1183, 1196, 1209,
- 1221, 1232, 1245, 1257, 1268, 1281, 1293, 1304,
- 1317, 1329, 1339, 1352, 1364, 1381, 1394, 1407,
- 1424, 1441, 1458, 1475, 1492, 1505, 1518, 1535,
- 1552, 1569, 1586, 1603, 1616, 1629, 1646, 1663,
- 1680, 1697, 1714, 1727, 1740, 1757, 1774, 1791,
- 1808, 1825, 1838, 1851, 1864, 1877, 1889, 1906,
- 1919, 1932, 1944, 1961, 1974, 1987, 1999, 2016,
- 2029, 2042, 2054, 2071, 2084, 2097, 2109, 2120,
- 2128, 2134, 2136, 2138, 2150, 2158, 2161, 2169,
- 2181, 2194, 2207, 2219, 2230, 2243, 2255, 2266,
- 2279, 2291, 2302, 2315, 2327, 2337, 2350, 2367,
- 2380, 2393, 2410, 2427, 2444, 2461, 2478, 2491,
- 2504, 2521, 2538, 2555, 2572, 2589, 2602, 2615,
- 2632, 2649, 2666, 2683, 2700, 2713, 2726, 2743,
- 2760, 2777, 2794, 2806, 2823, 2836, 2849, 2861,
- 2878, 2891, 2904, 2916, 2933, 2946, 2959, 2971,
- 2988, 3001, 3014, 3026, 3043, 3056, 3069, 3081,
- 3092, 3100, 3106, 3108, 3110, 3122, 3130, 3133,
- 3141, 3153, 3166, 3179, 3191, 3202, 3215, 3227,
- 3238, 3251, 3263, 3274, 3287, 3299, 3309, 3322,
- 3339, 3352, 3365, 3382, 3399, 3416, 3433, 3450,
- 3463, 3476, 3493, 3510, 3527, 3544, 3561, 3574,
- 3587, 3604, 3621, 3638, 3655, 3672, 3685, 3698,
- 3715, 3732, 3749, 3766, 3783, 3795, 3808, 3820,
- 3833, 3846, 3858, 3875, 3888, 3901, 3913, 3930,
- 3943, 3956, 3968, 3985, 3998, 4011, 4023, 4040,
- 4053, 4066, 4078, 4089, 4097, 4103, 4105, 4107,
- 4119, 4127, 4130, 4138, 4150, 4163, 4176, 4188,
- 4199, 4212, 4224, 4235, 4248, 4260, 4271, 4284,
- 4296, 4306, 4319, 4336, 4349, 4362, 4379, 4396,
- 4413, 4430, 4447, 4460, 4473, 4490, 4507, 4524,
- 4541, 4558, 4571, 4584, 4601, 4618, 4635, 4652,
- 4669, 4682, 4695, 4712, 4729, 4746, 4763, 4780,
- 4793, 4810, 4823
+ 848, 860, 864, 868, 872, 876, 878, 882,
+ 886, 888, 892, 896, 898, 915, 917, 919,
+ 921, 923, 928, 930, 932, 937, 939, 941,
+ 946, 948, 950, 967, 983, 996, 1008, 1025,
+ 1041, 1054, 1066, 1083, 1099, 1112, 1124, 1141,
+ 1157, 1170, 1182, 1199, 1215, 1228, 1240, 1251,
+ 1259, 1265, 1267, 1269, 1285, 1293, 1296, 1304,
+ 1316, 1329, 1342, 1354, 1365, 1378, 1390, 1401,
+ 1414, 1426, 1437, 1450, 1462, 1472, 1485, 1497,
+ 1514, 1527, 1540, 1557, 1574, 1591, 1608, 1625,
+ 1638, 1651, 1668, 1685, 1702, 1719, 1736, 1749,
+ 1762, 1779, 1796, 1813, 1830, 1847, 1860, 1873,
+ 1890, 1907, 1924, 1941, 1958, 1971, 1984, 1997,
+ 2010, 2022, 2039, 2055, 2068, 2080, 2097, 2113,
+ 2126, 2138, 2155, 2171, 2184, 2196, 2213, 2229,
+ 2242, 2254, 2265, 2273, 2279, 2281, 2283, 2299,
+ 2307, 2310, 2318, 2330, 2343, 2356, 2368, 2379,
+ 2392, 2404, 2415, 2428, 2440, 2451, 2464, 2476,
+ 2486, 2499, 2516, 2529, 2542, 2559, 2576, 2593,
+ 2610, 2627, 2640, 2653, 2670, 2687, 2704, 2721,
+ 2738, 2751, 2764, 2781, 2798, 2815, 2832, 2849,
+ 2862, 2875, 2892, 2909, 2926, 2943, 2955, 2972,
+ 2985, 2998, 3010, 3027, 3043, 3056, 3068, 3085,
+ 3101, 3114, 3126, 3143, 3159, 3172, 3184, 3201,
+ 3217, 3230, 3242, 3253, 3261, 3267, 3269, 3271,
+ 3287, 3295, 3298, 3306, 3318, 3331, 3344, 3356,
+ 3367, 3380, 3392, 3403, 3416, 3428, 3439, 3452,
+ 3464, 3474, 3487, 3504, 3517, 3530, 3547, 3564,
+ 3581, 3598, 3615, 3628, 3641, 3658, 3675, 3692,
+ 3709, 3726, 3739, 3752, 3769, 3786, 3803, 3820,
+ 3837, 3850, 3863, 3880, 3897, 3914, 3931, 3948,
+ 3960, 3973, 3985, 3998, 4011, 4023, 4040, 4056,
+ 4069, 4081, 4098, 4114, 4127, 4139, 4156, 4172,
+ 4185, 4197, 4214, 4230, 4243, 4255, 4266, 4274,
+ 4280, 4282, 4284, 4300, 4308, 4311, 4319, 4331,
+ 4344, 4357, 4369, 4380, 4393, 4405, 4416, 4429,
+ 4441, 4452, 4465, 4477, 4487, 4500, 4517, 4530,
+ 4543, 4560, 4577, 4594, 4611, 4628, 4641, 4654,
+ 4671, 4688, 4705, 4722, 4739, 4752, 4765, 4782,
+ 4799, 4816, 4833, 4850, 4863, 4876, 4893, 4910,
+ 4927, 4944, 4961, 4974, 4991, 5007, 5024, 5036,
+ 5053, 5069, 5082, 5094, 5100, 5102, 5104, 5117,
+ 5130, 5147, 5160, 5172, 5183, 5196, 5208, 5219,
+ 5232, 5244, 5255, 5268, 5280, 5288, 5304, 5312,
+ 5315, 5323, 5335
};
static const short _indic_syllable_machine_indicies[] = {
@@ -285,7 +306,7 @@ static const short _indic_syllable_machine_indicies[] = {
76, 76, 76, 76, 76, 76, 109, 76,
109, 80, 80, 81, 76, 76, 76, 76,
76, 110, 109, 76, 111, 80, 80, 81,
- 76, 76, 76, 76, 76, 76, 111, 76,
+ 82, 82, 82, 82, 82, 82, 111, 82,
111, 80, 80, 81, 76, 76, 76, 76,
76, 112, 111, 76, 113, 80, 80, 81,
76, 76, 76, 76, 76, 76, 113, 76,
@@ -315,569 +336,640 @@ static const short _indic_syllable_machine_indicies[] = {
114, 149, 148, 114, 150, 118, 118, 119,
114, 114, 114, 114, 114, 114, 150, 114,
150, 118, 118, 119, 114, 114, 114, 114,
- 114, 151, 150, 114, 153, 154, 155, 156,
- 157, 158, 81, 159, 160, 152, 161, 161,
- 162, 163, 164, 165, 152, 167, 168, 169,
- 170, 5, 171, 172, 173, 166, 166, 37,
- 174, 166, 175, 168, 176, 176, 5, 171,
- 172, 173, 166, 166, 166, 174, 166, 168,
- 176, 176, 5, 171, 172, 173, 166, 166,
- 166, 174, 166, 177, 166, 166, 166, 18,
- 178, 166, 171, 172, 166, 166, 166, 166,
- 179, 166, 177, 166, 180, 181, 182, 183,
- 5, 171, 172, 173, 166, 166, 35, 184,
- 166, 185, 181, 186, 186, 5, 171, 172,
- 173, 166, 166, 166, 184, 166, 181, 186,
- 186, 5, 171, 172, 173, 166, 166, 166,
- 184, 166, 187, 166, 166, 166, 18, 188,
- 166, 171, 172, 166, 166, 166, 166, 179,
- 166, 187, 166, 189, 190, 191, 192, 5,
- 171, 172, 173, 166, 166, 33, 193, 166,
- 194, 190, 195, 195, 5, 171, 172, 173,
- 166, 166, 166, 193, 166, 190, 195, 195,
- 5, 171, 172, 173, 166, 166, 166, 193,
- 166, 196, 166, 166, 166, 18, 197, 166,
- 171, 172, 166, 166, 166, 166, 179, 166,
- 196, 166, 198, 199, 200, 201, 5, 171,
- 172, 173, 166, 166, 31, 202, 166, 203,
- 199, 204, 204, 5, 171, 172, 173, 166,
- 166, 166, 202, 166, 199, 204, 204, 5,
- 171, 172, 173, 166, 166, 166, 202, 166,
- 205, 166, 166, 166, 18, 206, 166, 171,
- 172, 166, 166, 166, 166, 179, 166, 205,
- 166, 207, 208, 209, 210, 5, 171, 172,
- 173, 166, 166, 29, 211, 166, 212, 208,
- 213, 213, 5, 171, 172, 173, 166, 166,
- 166, 211, 166, 208, 213, 213, 5, 171,
- 172, 173, 166, 166, 166, 211, 166, 18,
- 214, 166, 171, 172, 166, 166, 166, 166,
- 179, 166, 171, 172, 166, 166, 166, 166,
- 179, 166, 215, 166, 166, 166, 172, 166,
- 172, 166, 216, 166, 217, 166, 218, 219,
- 166, 171, 172, 166, 166, 166, 3, 166,
- 2, 166, 166, 166, 166, 171, 172, 166,
- 171, 172, 166, 217, 166, 166, 166, 166,
- 171, 172, 166, 217, 166, 218, 166, 166,
- 171, 172, 166, 166, 166, 3, 166, 18,
- 166, 220, 220, 5, 171, 172, 166, 166,
- 166, 166, 179, 166, 221, 27, 222, 223,
- 8, 171, 172, 166, 166, 166, 166, 179,
- 166, 27, 222, 223, 8, 171, 172, 166,
- 166, 166, 166, 179, 166, 222, 222, 8,
- 171, 172, 166, 166, 166, 166, 179, 166,
- 224, 24, 225, 226, 11, 171, 172, 166,
- 166, 166, 166, 179, 166, 24, 225, 226,
- 11, 171, 172, 166, 166, 166, 166, 179,
- 166, 225, 225, 11, 171, 172, 166, 166,
- 166, 166, 179, 166, 227, 21, 228, 229,
- 14, 171, 172, 166, 166, 166, 166, 179,
- 166, 21, 228, 229, 14, 171, 172, 166,
- 166, 166, 166, 179, 166, 228, 228, 14,
- 171, 172, 166, 166, 166, 166, 179, 166,
- 230, 18, 166, 231, 166, 171, 172, 166,
- 166, 166, 166, 179, 166, 18, 166, 231,
- 166, 171, 172, 166, 166, 166, 166, 179,
- 166, 232, 166, 171, 172, 166, 166, 166,
- 166, 179, 166, 18, 166, 166, 166, 166,
- 171, 172, 166, 166, 166, 166, 179, 166,
- 208, 213, 213, 5, 171, 172, 166, 166,
- 166, 166, 211, 166, 1, 2, 166, 166,
- 18, 214, 166, 171, 172, 166, 166, 166,
- 166, 179, 166, 1, 166, 207, 208, 213,
- 213, 5, 171, 172, 173, 166, 166, 166,
- 211, 166, 207, 208, 209, 213, 5, 171,
- 172, 173, 166, 166, 29, 211, 166, 205,
- 166, 233, 166, 220, 220, 5, 171, 172,
- 166, 166, 166, 166, 179, 166, 205, 166,
- 205, 166, 166, 166, 166, 166, 166, 171,
- 172, 166, 166, 166, 166, 179, 166, 205,
- 166, 205, 166, 166, 166, 166, 234, 166,
- 171, 172, 166, 166, 166, 166, 179, 166,
- 205, 166, 205, 166, 233, 166, 166, 166,
- 166, 171, 172, 166, 166, 166, 166, 179,
- 166, 205, 166, 205, 2, 166, 166, 18,
- 206, 166, 171, 172, 166, 166, 166, 166,
- 179, 166, 205, 166, 198, 199, 204, 204,
- 5, 171, 172, 173, 166, 166, 166, 202,
- 166, 198, 199, 200, 204, 5, 171, 172,
- 173, 166, 166, 31, 202, 166, 196, 166,
- 235, 166, 220, 220, 5, 171, 172, 166,
- 166, 166, 166, 179, 166, 196, 166, 196,
- 166, 166, 166, 166, 166, 166, 171, 172,
- 166, 166, 166, 166, 179, 166, 196, 166,
- 196, 166, 166, 166, 166, 236, 166, 171,
- 172, 166, 166, 166, 166, 179, 166, 196,
- 166, 196, 166, 235, 166, 166, 166, 166,
- 171, 172, 166, 166, 166, 166, 179, 166,
- 196, 166, 196, 2, 166, 166, 18, 197,
- 166, 171, 172, 166, 166, 166, 166, 179,
- 166, 196, 166, 189, 190, 195, 195, 5,
- 171, 172, 173, 166, 166, 166, 193, 166,
- 189, 190, 191, 195, 5, 171, 172, 173,
- 166, 166, 33, 193, 166, 187, 166, 237,
- 166, 220, 220, 5, 171, 172, 166, 166,
- 166, 166, 179, 166, 187, 166, 187, 166,
- 166, 166, 166, 166, 166, 171, 172, 166,
- 166, 166, 166, 179, 166, 187, 166, 187,
- 166, 166, 166, 166, 238, 166, 171, 172,
- 166, 166, 166, 166, 179, 166, 187, 166,
- 187, 166, 237, 166, 166, 166, 166, 171,
- 172, 166, 166, 166, 166, 179, 166, 187,
- 166, 187, 2, 166, 166, 18, 188, 166,
- 171, 172, 166, 166, 166, 166, 179, 166,
- 187, 166, 180, 181, 186, 186, 5, 171,
- 172, 173, 166, 166, 166, 184, 166, 180,
- 181, 182, 186, 5, 171, 172, 173, 166,
- 166, 35, 184, 166, 177, 166, 239, 166,
- 220, 220, 5, 171, 172, 166, 166, 166,
- 166, 179, 166, 177, 166, 177, 166, 166,
- 166, 166, 166, 166, 171, 172, 166, 166,
- 166, 166, 179, 166, 177, 166, 177, 166,
- 166, 166, 166, 240, 166, 171, 172, 166,
- 166, 166, 166, 179, 166, 177, 166, 177,
- 166, 239, 166, 166, 166, 166, 171, 172,
- 166, 166, 166, 166, 179, 166, 177, 166,
- 177, 2, 166, 166, 18, 178, 166, 171,
- 172, 166, 166, 166, 166, 179, 166, 177,
- 166, 167, 168, 176, 176, 5, 171, 172,
- 173, 166, 166, 166, 174, 166, 167, 168,
- 169, 176, 5, 171, 172, 173, 166, 166,
- 37, 174, 166, 242, 243, 244, 245, 43,
- 246, 247, 241, 241, 241, 75, 248, 241,
- 249, 243, 250, 245, 43, 246, 247, 241,
- 241, 241, 241, 248, 241, 243, 250, 245,
- 43, 246, 247, 241, 241, 241, 241, 248,
- 241, 251, 241, 241, 241, 56, 252, 241,
- 246, 247, 241, 241, 241, 241, 253, 241,
- 251, 241, 254, 255, 256, 257, 43, 246,
- 247, 241, 241, 241, 73, 258, 241, 259,
- 255, 260, 260, 43, 246, 247, 241, 241,
- 241, 241, 258, 241, 255, 260, 260, 43,
- 246, 247, 241, 241, 241, 241, 258, 241,
- 261, 241, 241, 241, 56, 262, 241, 246,
- 247, 241, 241, 241, 241, 253, 241, 261,
- 241, 263, 264, 265, 266, 43, 246, 247,
- 241, 241, 241, 71, 267, 241, 268, 264,
- 269, 269, 43, 246, 247, 241, 241, 241,
- 241, 267, 241, 264, 269, 269, 43, 246,
- 247, 241, 241, 241, 241, 267, 241, 270,
- 241, 241, 241, 56, 271, 241, 246, 247,
- 241, 241, 241, 241, 253, 241, 270, 241,
- 272, 273, 274, 275, 43, 246, 247, 241,
- 241, 241, 69, 276, 241, 277, 273, 278,
- 278, 43, 246, 247, 241, 241, 241, 241,
- 276, 241, 273, 278, 278, 43, 246, 247,
- 241, 241, 241, 241, 276, 241, 279, 241,
- 241, 241, 56, 280, 241, 246, 247, 241,
- 241, 241, 241, 253, 241, 279, 241, 281,
- 282, 283, 284, 43, 246, 247, 241, 241,
- 241, 67, 285, 241, 286, 282, 287, 287,
- 43, 246, 247, 241, 241, 241, 241, 285,
- 241, 282, 287, 287, 43, 246, 247, 241,
- 241, 241, 241, 285, 241, 56, 288, 241,
- 246, 247, 241, 241, 241, 241, 253, 241,
- 246, 247, 241, 241, 241, 241, 253, 241,
- 289, 241, 241, 241, 247, 241, 247, 241,
- 290, 241, 291, 241, 292, 293, 241, 246,
- 247, 241, 241, 241, 41, 241, 40, 241,
- 241, 241, 241, 246, 247, 241, 246, 247,
- 241, 291, 241, 241, 241, 241, 246, 247,
- 241, 291, 241, 292, 241, 241, 246, 247,
- 241, 241, 241, 41, 241, 56, 241, 294,
- 294, 43, 246, 247, 241, 241, 241, 241,
- 253, 241, 295, 65, 296, 297, 46, 246,
- 247, 241, 241, 241, 241, 253, 241, 65,
- 296, 297, 46, 246, 247, 241, 241, 241,
- 241, 253, 241, 296, 296, 46, 246, 247,
- 241, 241, 241, 241, 253, 241, 298, 62,
- 299, 300, 49, 246, 247, 241, 241, 241,
- 241, 253, 241, 62, 299, 300, 49, 246,
- 247, 241, 241, 241, 241, 253, 241, 299,
- 299, 49, 246, 247, 241, 241, 241, 241,
- 253, 241, 301, 59, 302, 303, 52, 246,
- 247, 241, 241, 241, 241, 253, 241, 59,
- 302, 303, 52, 246, 247, 241, 241, 241,
- 241, 253, 241, 302, 302, 52, 246, 247,
- 241, 241, 241, 241, 253, 241, 304, 56,
- 241, 305, 241, 246, 247, 241, 241, 241,
- 241, 253, 241, 56, 241, 305, 241, 246,
- 247, 241, 241, 241, 241, 253, 241, 306,
- 241, 246, 247, 241, 241, 241, 241, 253,
- 241, 56, 241, 241, 241, 241, 246, 247,
- 241, 241, 241, 241, 253, 241, 39, 40,
- 241, 241, 56, 288, 241, 246, 247, 241,
- 241, 241, 241, 253, 241, 39, 241, 281,
- 282, 287, 287, 43, 246, 247, 241, 241,
- 241, 241, 285, 241, 281, 282, 283, 287,
- 43, 246, 247, 241, 241, 241, 67, 285,
- 241, 279, 241, 307, 241, 294, 294, 43,
- 246, 247, 241, 241, 241, 241, 253, 241,
- 279, 241, 279, 241, 241, 241, 241, 241,
- 241, 246, 247, 241, 241, 241, 241, 253,
- 241, 279, 241, 279, 241, 241, 241, 241,
- 308, 241, 246, 247, 241, 241, 241, 241,
- 253, 241, 279, 241, 279, 241, 307, 241,
- 241, 241, 241, 246, 247, 241, 241, 241,
- 241, 253, 241, 279, 241, 279, 40, 241,
- 241, 56, 280, 241, 246, 247, 241, 241,
- 241, 241, 253, 241, 279, 241, 272, 273,
- 278, 278, 43, 246, 247, 241, 241, 241,
- 241, 276, 241, 272, 273, 274, 278, 43,
- 246, 247, 241, 241, 241, 69, 276, 241,
- 270, 241, 309, 241, 294, 294, 43, 246,
- 247, 241, 241, 241, 241, 253, 241, 270,
- 241, 270, 241, 241, 241, 241, 241, 241,
- 246, 247, 241, 241, 241, 241, 253, 241,
- 270, 241, 270, 241, 241, 241, 241, 310,
- 241, 246, 247, 241, 241, 241, 241, 253,
- 241, 270, 241, 270, 241, 309, 241, 241,
- 241, 241, 246, 247, 241, 241, 241, 241,
- 253, 241, 270, 241, 270, 40, 241, 241,
- 56, 271, 241, 246, 247, 241, 241, 241,
- 241, 253, 241, 270, 241, 263, 264, 269,
- 269, 43, 246, 247, 241, 241, 241, 241,
- 267, 241, 263, 264, 265, 269, 43, 246,
- 247, 241, 241, 241, 71, 267, 241, 261,
- 241, 311, 241, 294, 294, 43, 246, 247,
- 241, 241, 241, 241, 253, 241, 261, 241,
- 261, 241, 241, 241, 241, 241, 241, 246,
- 247, 241, 241, 241, 241, 253, 241, 261,
- 241, 261, 241, 241, 241, 241, 312, 241,
- 246, 247, 241, 241, 241, 241, 253, 241,
- 261, 241, 261, 241, 311, 241, 241, 241,
- 241, 246, 247, 241, 241, 241, 241, 253,
- 241, 261, 241, 261, 40, 241, 241, 56,
- 262, 241, 246, 247, 241, 241, 241, 241,
- 253, 241, 261, 241, 254, 255, 260, 260,
- 43, 246, 247, 241, 241, 241, 241, 258,
- 241, 254, 255, 256, 260, 43, 246, 247,
- 241, 241, 241, 73, 258, 241, 251, 241,
- 313, 241, 294, 294, 43, 246, 247, 241,
- 241, 241, 241, 253, 241, 251, 241, 251,
- 241, 241, 241, 241, 241, 241, 246, 247,
- 241, 241, 241, 241, 253, 241, 251, 241,
- 251, 241, 241, 241, 241, 314, 241, 246,
- 247, 241, 241, 241, 241, 253, 241, 251,
- 241, 251, 241, 313, 241, 241, 241, 241,
- 246, 247, 241, 241, 241, 241, 253, 241,
- 251, 241, 74, 42, 42, 43, 241, 241,
- 241, 241, 241, 241, 74, 241, 251, 40,
- 241, 241, 56, 252, 241, 246, 247, 241,
- 241, 241, 241, 253, 241, 251, 241, 242,
- 243, 250, 245, 43, 246, 247, 241, 241,
- 241, 241, 248, 241, 316, 156, 317, 317,
- 81, 159, 160, 315, 315, 315, 315, 163,
- 315, 156, 317, 317, 81, 159, 160, 315,
- 315, 315, 315, 163, 315, 318, 315, 315,
- 315, 95, 319, 315, 159, 160, 315, 315,
- 315, 315, 320, 315, 318, 315, 321, 322,
- 323, 324, 81, 159, 160, 315, 315, 315,
- 112, 325, 315, 326, 322, 327, 327, 81,
- 159, 160, 315, 315, 315, 315, 325, 315,
- 322, 327, 327, 81, 159, 160, 315, 315,
- 315, 315, 325, 315, 328, 315, 315, 315,
- 95, 329, 315, 159, 160, 315, 315, 315,
- 315, 320, 315, 328, 315, 330, 331, 332,
- 333, 81, 159, 160, 315, 315, 315, 110,
- 334, 315, 335, 331, 336, 336, 81, 159,
- 160, 315, 315, 315, 315, 334, 315, 331,
- 336, 336, 81, 159, 160, 315, 315, 315,
- 315, 334, 315, 337, 315, 315, 315, 95,
- 338, 315, 159, 160, 315, 315, 315, 315,
- 320, 315, 337, 315, 339, 340, 341, 342,
- 81, 159, 160, 315, 315, 315, 108, 343,
- 315, 344, 340, 345, 345, 81, 159, 160,
- 315, 315, 315, 315, 343, 315, 340, 345,
- 345, 81, 159, 160, 315, 315, 315, 315,
- 343, 315, 346, 315, 315, 315, 95, 347,
- 315, 159, 160, 315, 315, 315, 315, 320,
- 315, 346, 315, 348, 349, 350, 351, 81,
- 159, 160, 315, 315, 315, 106, 352, 315,
- 353, 349, 354, 354, 81, 159, 160, 315,
- 315, 315, 315, 352, 315, 349, 354, 354,
- 81, 159, 160, 315, 315, 315, 315, 352,
- 315, 95, 355, 315, 159, 160, 315, 315,
- 315, 315, 320, 315, 159, 160, 315, 315,
- 315, 315, 320, 315, 356, 315, 315, 315,
- 160, 315, 160, 315, 357, 315, 358, 315,
- 359, 360, 315, 159, 160, 315, 315, 315,
- 79, 315, 78, 315, 315, 315, 315, 159,
- 160, 315, 159, 160, 315, 358, 315, 315,
- 315, 315, 159, 160, 315, 358, 315, 359,
- 315, 315, 159, 160, 315, 315, 315, 79,
- 315, 95, 315, 361, 361, 81, 159, 160,
- 315, 315, 315, 315, 320, 315, 362, 104,
- 363, 364, 85, 159, 160, 315, 315, 315,
- 315, 320, 315, 104, 363, 364, 85, 159,
- 160, 315, 315, 315, 315, 320, 315, 363,
- 363, 85, 159, 160, 315, 315, 315, 315,
- 320, 315, 365, 101, 366, 367, 88, 159,
- 160, 315, 315, 315, 315, 320, 315, 101,
- 366, 367, 88, 159, 160, 315, 315, 315,
- 315, 320, 315, 366, 366, 88, 159, 160,
- 315, 315, 315, 315, 320, 315, 368, 98,
- 369, 370, 91, 159, 160, 315, 315, 315,
- 315, 320, 315, 98, 369, 370, 91, 159,
- 160, 315, 315, 315, 315, 320, 315, 369,
- 369, 91, 159, 160, 315, 315, 315, 315,
- 320, 315, 371, 95, 315, 372, 315, 159,
- 160, 315, 315, 315, 315, 320, 315, 95,
- 315, 372, 315, 159, 160, 315, 315, 315,
- 315, 320, 315, 373, 315, 159, 160, 315,
- 315, 315, 315, 320, 315, 95, 315, 315,
- 315, 315, 159, 160, 315, 315, 315, 315,
- 320, 315, 77, 78, 315, 315, 95, 355,
- 315, 159, 160, 315, 315, 315, 315, 320,
- 315, 77, 315, 348, 349, 354, 354, 81,
- 159, 160, 315, 315, 315, 315, 352, 315,
- 348, 349, 350, 354, 81, 159, 160, 315,
- 315, 315, 106, 352, 315, 346, 315, 374,
- 315, 361, 361, 81, 159, 160, 315, 315,
- 315, 315, 320, 315, 346, 315, 346, 315,
- 315, 315, 315, 315, 315, 159, 160, 315,
- 315, 315, 315, 320, 315, 346, 315, 346,
- 315, 315, 315, 315, 375, 315, 159, 160,
- 315, 315, 315, 315, 320, 315, 346, 315,
- 346, 315, 374, 315, 315, 315, 315, 159,
- 160, 315, 315, 315, 315, 320, 315, 346,
- 315, 346, 78, 315, 315, 95, 347, 315,
- 159, 160, 315, 315, 315, 315, 320, 315,
- 346, 315, 339, 340, 345, 345, 81, 159,
- 160, 315, 315, 315, 315, 343, 315, 339,
- 340, 341, 345, 81, 159, 160, 315, 315,
- 315, 108, 343, 315, 337, 315, 376, 315,
- 361, 361, 81, 159, 160, 315, 315, 315,
- 315, 320, 315, 337, 315, 337, 315, 315,
- 315, 315, 315, 315, 159, 160, 315, 315,
- 315, 315, 320, 315, 337, 315, 337, 315,
- 315, 315, 315, 377, 315, 159, 160, 315,
- 315, 315, 315, 320, 315, 337, 315, 337,
- 315, 376, 315, 315, 315, 315, 159, 160,
- 315, 315, 315, 315, 320, 315, 337, 315,
- 337, 78, 315, 315, 95, 338, 315, 159,
- 160, 315, 315, 315, 315, 320, 315, 337,
- 315, 330, 331, 336, 336, 81, 159, 160,
- 315, 315, 315, 315, 334, 315, 330, 331,
- 332, 336, 81, 159, 160, 315, 315, 315,
- 110, 334, 315, 328, 315, 378, 315, 361,
- 361, 81, 159, 160, 315, 315, 315, 315,
- 320, 315, 328, 315, 328, 315, 315, 315,
- 315, 315, 315, 159, 160, 315, 315, 315,
- 315, 320, 315, 328, 315, 328, 315, 315,
- 315, 315, 379, 315, 159, 160, 315, 315,
- 315, 315, 320, 315, 328, 315, 328, 315,
- 378, 315, 315, 315, 315, 159, 160, 315,
- 315, 315, 315, 320, 315, 328, 315, 328,
- 78, 315, 315, 95, 329, 315, 159, 160,
- 315, 315, 315, 315, 320, 315, 328, 315,
- 321, 322, 327, 327, 81, 159, 160, 315,
- 315, 315, 315, 325, 315, 321, 322, 323,
- 327, 81, 159, 160, 315, 315, 315, 112,
- 325, 315, 318, 315, 380, 315, 361, 361,
- 81, 159, 160, 315, 315, 315, 315, 320,
- 315, 318, 315, 318, 315, 315, 315, 315,
- 315, 315, 159, 160, 315, 315, 315, 315,
- 320, 315, 318, 315, 318, 315, 315, 315,
- 315, 381, 315, 159, 160, 315, 315, 315,
- 315, 320, 315, 318, 315, 318, 315, 380,
- 315, 315, 315, 315, 159, 160, 315, 315,
- 315, 315, 320, 315, 318, 315, 318, 78,
- 315, 315, 95, 319, 315, 159, 160, 315,
- 315, 315, 315, 320, 315, 318, 315, 113,
- 80, 80, 81, 382, 382, 382, 382, 382,
- 162, 113, 382, 155, 156, 317, 317, 81,
- 159, 160, 315, 315, 315, 315, 163, 315,
- 113, 80, 80, 81, 382, 382, 382, 382,
- 382, 382, 113, 382, 384, 385, 386, 387,
- 119, 388, 389, 383, 383, 383, 151, 390,
- 383, 391, 385, 387, 387, 119, 388, 389,
- 383, 383, 383, 383, 390, 383, 385, 387,
- 387, 119, 388, 389, 383, 383, 383, 383,
- 390, 383, 392, 383, 383, 383, 132, 393,
- 383, 388, 389, 383, 383, 383, 383, 394,
- 383, 392, 383, 395, 396, 397, 398, 119,
- 388, 389, 383, 383, 383, 149, 399, 383,
- 400, 396, 401, 401, 119, 388, 389, 383,
- 383, 383, 383, 399, 383, 396, 401, 401,
- 119, 388, 389, 383, 383, 383, 383, 399,
- 383, 402, 383, 383, 383, 132, 403, 383,
- 388, 389, 383, 383, 383, 383, 394, 383,
- 402, 383, 404, 405, 406, 407, 119, 388,
- 389, 383, 383, 383, 147, 408, 383, 409,
- 405, 410, 410, 119, 388, 389, 383, 383,
- 383, 383, 408, 383, 405, 410, 410, 119,
- 388, 389, 383, 383, 383, 383, 408, 383,
- 411, 383, 383, 383, 132, 412, 383, 388,
- 389, 383, 383, 383, 383, 394, 383, 411,
- 383, 413, 414, 415, 416, 119, 388, 389,
- 383, 383, 383, 145, 417, 383, 418, 414,
- 419, 419, 119, 388, 389, 383, 383, 383,
- 383, 417, 383, 414, 419, 419, 119, 388,
- 389, 383, 383, 383, 383, 417, 383, 420,
- 383, 383, 383, 132, 421, 383, 388, 389,
- 383, 383, 383, 383, 394, 383, 420, 383,
- 422, 423, 424, 425, 119, 388, 389, 383,
- 383, 383, 143, 426, 383, 427, 423, 428,
- 428, 119, 388, 389, 383, 383, 383, 383,
- 426, 383, 423, 428, 428, 119, 388, 389,
- 383, 383, 383, 383, 426, 383, 132, 429,
- 383, 388, 389, 383, 383, 383, 383, 394,
- 383, 388, 389, 383, 383, 383, 383, 394,
- 383, 430, 383, 383, 383, 389, 383, 389,
- 383, 431, 383, 432, 383, 433, 434, 383,
- 388, 389, 383, 383, 383, 117, 383, 116,
- 383, 383, 383, 383, 388, 389, 383, 388,
- 389, 383, 432, 383, 383, 383, 383, 388,
- 389, 383, 432, 383, 433, 383, 383, 388,
- 389, 383, 383, 383, 117, 383, 132, 383,
- 435, 435, 119, 388, 389, 383, 383, 383,
- 383, 394, 383, 436, 141, 437, 438, 122,
- 388, 389, 383, 383, 383, 383, 394, 383,
- 141, 437, 438, 122, 388, 389, 383, 383,
- 383, 383, 394, 383, 437, 437, 122, 388,
- 389, 383, 383, 383, 383, 394, 383, 439,
- 138, 440, 441, 125, 388, 389, 383, 383,
- 383, 383, 394, 383, 138, 440, 441, 125,
- 388, 389, 383, 383, 383, 383, 394, 383,
- 440, 440, 125, 388, 389, 383, 383, 383,
- 383, 394, 383, 442, 135, 443, 444, 128,
- 388, 389, 383, 383, 383, 383, 394, 383,
- 135, 443, 444, 128, 388, 389, 383, 383,
- 383, 383, 394, 383, 443, 443, 128, 388,
- 389, 383, 383, 383, 383, 394, 383, 445,
- 132, 383, 446, 383, 388, 389, 383, 383,
- 383, 383, 394, 383, 132, 383, 446, 383,
- 388, 389, 383, 383, 383, 383, 394, 383,
- 447, 383, 388, 389, 383, 383, 383, 383,
- 394, 383, 132, 383, 383, 383, 383, 388,
- 389, 383, 383, 383, 383, 394, 383, 115,
- 116, 383, 383, 132, 429, 383, 388, 389,
- 383, 383, 383, 383, 394, 383, 115, 383,
- 422, 423, 428, 428, 119, 388, 389, 383,
- 383, 383, 383, 426, 383, 422, 423, 424,
- 428, 119, 388, 389, 383, 383, 383, 143,
- 426, 383, 420, 383, 448, 383, 435, 435,
- 119, 388, 389, 383, 383, 383, 383, 394,
- 383, 420, 383, 420, 383, 383, 383, 383,
- 383, 383, 388, 389, 383, 383, 383, 383,
- 394, 383, 420, 383, 420, 383, 383, 383,
- 383, 449, 383, 388, 389, 383, 383, 383,
- 383, 394, 383, 420, 383, 420, 383, 448,
- 383, 383, 383, 383, 388, 389, 383, 383,
- 383, 383, 394, 383, 420, 383, 420, 116,
- 383, 383, 132, 421, 383, 388, 389, 383,
- 383, 383, 383, 394, 383, 420, 383, 413,
- 414, 419, 419, 119, 388, 389, 383, 383,
- 383, 383, 417, 383, 413, 414, 415, 419,
- 119, 388, 389, 383, 383, 383, 145, 417,
- 383, 411, 383, 450, 383, 435, 435, 119,
- 388, 389, 383, 383, 383, 383, 394, 383,
- 411, 383, 411, 383, 383, 383, 383, 383,
- 383, 388, 389, 383, 383, 383, 383, 394,
- 383, 411, 383, 411, 383, 383, 383, 383,
- 451, 383, 388, 389, 383, 383, 383, 383,
- 394, 383, 411, 383, 411, 383, 450, 383,
- 383, 383, 383, 388, 389, 383, 383, 383,
- 383, 394, 383, 411, 383, 411, 116, 383,
- 383, 132, 412, 383, 388, 389, 383, 383,
- 383, 383, 394, 383, 411, 383, 404, 405,
- 410, 410, 119, 388, 389, 383, 383, 383,
- 383, 408, 383, 404, 405, 406, 410, 119,
- 388, 389, 383, 383, 383, 147, 408, 383,
- 402, 383, 452, 383, 435, 435, 119, 388,
- 389, 383, 383, 383, 383, 394, 383, 402,
- 383, 402, 383, 383, 383, 383, 383, 383,
- 388, 389, 383, 383, 383, 383, 394, 383,
- 402, 383, 402, 383, 383, 383, 383, 453,
- 383, 388, 389, 383, 383, 383, 383, 394,
- 383, 402, 383, 402, 383, 452, 383, 383,
- 383, 383, 388, 389, 383, 383, 383, 383,
- 394, 383, 402, 383, 402, 116, 383, 383,
- 132, 403, 383, 388, 389, 383, 383, 383,
- 383, 394, 383, 402, 383, 395, 396, 401,
- 401, 119, 388, 389, 383, 383, 383, 383,
- 399, 383, 395, 396, 397, 401, 119, 388,
- 389, 383, 383, 383, 149, 399, 383, 392,
- 383, 454, 383, 435, 435, 119, 388, 389,
- 383, 383, 383, 383, 394, 383, 392, 383,
- 392, 383, 383, 383, 383, 383, 383, 388,
- 389, 383, 383, 383, 383, 394, 383, 392,
- 383, 392, 383, 383, 383, 383, 455, 383,
- 388, 389, 383, 383, 383, 383, 394, 383,
- 392, 383, 392, 383, 454, 383, 383, 383,
- 383, 388, 389, 383, 383, 383, 383, 394,
- 383, 392, 383, 392, 116, 383, 383, 132,
- 393, 383, 388, 389, 383, 383, 383, 383,
- 394, 383, 392, 383, 384, 385, 387, 387,
- 119, 388, 389, 383, 383, 383, 383, 390,
- 383, 153, 154, 382, 382, 382, 382, 382,
- 382, 382, 382, 161, 161, 382, 382, 382,
- 153, 382, 167, 456, 169, 170, 5, 171,
- 172, 173, 166, 166, 37, 174, 166, 177,
- 154, 166, 166, 18, 178, 166, 171, 172,
- 166, 161, 161, 166, 179, 166, 177, 166,
+ 114, 151, 150, 114, 113, 80, 80, 81,
+ 76, 76, 76, 76, 76, 152, 113, 76,
+ 111, 80, 80, 81, 0, 0, 0, 0,
+ 0, 153, 111, 0, 154, 154, 155, 0,
+ 6, 6, 155, 0, 156, 156, 157, 0,
+ 158, 158, 157, 0, 157, 0, 159, 159,
+ 160, 0, 161, 161, 160, 0, 160, 0,
+ 162, 162, 163, 0, 164, 164, 163, 0,
+ 163, 0, 165, 166, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 165, 0, 167, 0, 168, 0, 169,
+ 0, 170, 0, 171, 162, 162, 163, 0,
+ 172, 0, 173, 0, 174, 159, 159, 160,
+ 0, 175, 0, 176, 0, 177, 156, 156,
+ 157, 0, 178, 0, 179, 0, 181, 182,
+ 183, 184, 185, 186, 81, 187, 188, 180,
+ 189, 189, 152, 190, 191, 192, 180, 194,
+ 195, 196, 197, 5, 198, 199, 200, 193,
+ 193, 37, 201, 193, 193, 181, 193, 202,
+ 195, 203, 203, 5, 198, 199, 200, 193,
+ 193, 193, 201, 193, 195, 203, 203, 5,
+ 198, 199, 200, 193, 193, 193, 201, 193,
+ 204, 193, 193, 193, 18, 205, 193, 198,
+ 199, 193, 193, 193, 193, 206, 193, 204,
+ 193, 207, 208, 209, 210, 5, 198, 199,
+ 200, 193, 193, 35, 211, 193, 193, 204,
+ 193, 212, 208, 213, 213, 5, 198, 199,
+ 200, 193, 193, 193, 211, 193, 208, 213,
+ 213, 5, 198, 199, 200, 193, 193, 193,
+ 211, 193, 214, 193, 193, 193, 18, 215,
+ 193, 198, 199, 193, 193, 193, 193, 206,
+ 193, 214, 193, 216, 217, 218, 219, 5,
+ 198, 199, 200, 193, 193, 33, 220, 193,
+ 193, 214, 193, 221, 217, 222, 222, 5,
+ 198, 199, 200, 193, 193, 193, 220, 193,
+ 217, 222, 222, 5, 198, 199, 200, 193,
+ 193, 193, 220, 193, 223, 193, 193, 193,
+ 18, 224, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 223, 193, 225, 226, 227,
+ 228, 5, 198, 199, 200, 193, 193, 31,
+ 229, 193, 193, 223, 193, 230, 226, 231,
+ 231, 5, 198, 199, 200, 193, 193, 193,
+ 229, 193, 226, 231, 231, 5, 198, 199,
+ 200, 193, 193, 193, 229, 193, 232, 193,
+ 193, 193, 18, 233, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 232, 193, 234,
+ 235, 236, 237, 5, 198, 199, 200, 193,
+ 193, 29, 238, 193, 193, 232, 193, 239,
+ 235, 240, 240, 5, 198, 199, 200, 193,
+ 193, 193, 238, 193, 235, 240, 240, 5,
+ 198, 199, 200, 193, 193, 193, 238, 193,
+ 18, 241, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 242, 193, 193, 193, 199,
+ 193, 199, 193, 243, 193, 244, 193, 245,
+ 246, 193, 198, 199, 193, 193, 193, 3,
+ 193, 193, 193, 1, 193, 2, 193, 193,
+ 193, 193, 198, 199, 193, 198, 199, 193,
+ 244, 193, 193, 193, 193, 198, 199, 193,
+ 244, 193, 245, 193, 193, 198, 199, 193,
+ 193, 193, 3, 193, 18, 193, 247, 247,
+ 5, 198, 199, 193, 193, 193, 193, 206,
+ 193, 248, 27, 249, 250, 8, 198, 199,
+ 193, 193, 193, 193, 206, 193, 27, 249,
+ 250, 8, 198, 199, 193, 193, 193, 193,
+ 206, 193, 249, 249, 8, 198, 199, 193,
+ 193, 193, 193, 206, 193, 251, 24, 252,
+ 253, 11, 198, 199, 193, 193, 193, 193,
+ 206, 193, 24, 252, 253, 11, 198, 199,
+ 193, 193, 193, 193, 206, 193, 252, 252,
+ 11, 198, 199, 193, 193, 193, 193, 206,
+ 193, 254, 21, 255, 256, 14, 198, 199,
+ 193, 193, 193, 193, 206, 193, 21, 255,
+ 256, 14, 198, 199, 193, 193, 193, 193,
+ 206, 193, 255, 255, 14, 198, 199, 193,
+ 193, 193, 193, 206, 193, 257, 18, 193,
+ 258, 193, 198, 199, 193, 193, 193, 193,
+ 206, 193, 18, 193, 258, 193, 198, 199,
+ 193, 193, 193, 193, 206, 193, 259, 193,
+ 198, 199, 193, 193, 193, 193, 206, 193,
+ 18, 193, 193, 193, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 235, 240, 240,
+ 5, 198, 199, 193, 193, 193, 193, 238,
+ 193, 1, 2, 193, 193, 18, 241, 193,
+ 198, 199, 193, 193, 193, 193, 206, 193,
+ 1, 193, 234, 235, 240, 240, 5, 198,
+ 199, 200, 193, 193, 193, 238, 193, 234,
+ 235, 236, 240, 5, 198, 199, 200, 193,
+ 193, 29, 238, 193, 232, 193, 260, 193,
+ 247, 247, 5, 198, 199, 193, 193, 193,
+ 193, 206, 193, 232, 193, 232, 193, 193,
+ 193, 193, 193, 193, 198, 199, 193, 193,
+ 193, 193, 206, 193, 232, 193, 232, 193,
+ 193, 193, 193, 261, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 232, 193, 232,
+ 193, 260, 193, 193, 193, 193, 198, 199,
+ 193, 193, 193, 193, 206, 193, 232, 193,
+ 232, 2, 193, 193, 18, 233, 193, 198,
+ 199, 193, 193, 193, 193, 206, 193, 232,
+ 193, 225, 226, 231, 231, 5, 198, 199,
+ 200, 193, 193, 193, 229, 193, 225, 226,
+ 227, 231, 5, 198, 199, 200, 193, 193,
+ 31, 229, 193, 223, 193, 262, 193, 247,
+ 247, 5, 198, 199, 193, 193, 193, 193,
+ 206, 193, 223, 193, 223, 193, 193, 193,
+ 193, 193, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 223, 193, 223, 193, 193,
+ 193, 193, 263, 193, 198, 199, 193, 193,
+ 193, 193, 206, 193, 223, 193, 223, 193,
+ 262, 193, 193, 193, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 223, 193, 223,
+ 2, 193, 193, 18, 224, 193, 198, 199,
+ 193, 193, 193, 193, 206, 193, 223, 193,
+ 216, 217, 222, 222, 5, 198, 199, 200,
+ 193, 193, 193, 220, 193, 216, 217, 218,
+ 222, 5, 198, 199, 200, 193, 193, 33,
+ 220, 193, 214, 193, 264, 193, 247, 247,
+ 5, 198, 199, 193, 193, 193, 193, 206,
+ 193, 214, 193, 214, 193, 193, 193, 193,
+ 193, 193, 198, 199, 193, 193, 193, 193,
+ 206, 193, 214, 193, 214, 193, 193, 193,
+ 193, 265, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 214, 193, 214, 193, 264,
+ 193, 193, 193, 193, 198, 199, 193, 193,
+ 193, 193, 206, 193, 214, 193, 214, 2,
+ 193, 193, 18, 215, 193, 198, 199, 193,
+ 193, 193, 193, 206, 193, 214, 193, 207,
+ 208, 213, 213, 5, 198, 199, 200, 193,
+ 193, 193, 211, 193, 207, 208, 209, 213,
+ 5, 198, 199, 200, 193, 193, 35, 211,
+ 193, 204, 193, 266, 193, 247, 247, 5,
+ 198, 199, 193, 193, 193, 193, 206, 193,
+ 204, 193, 204, 193, 193, 193, 193, 193,
+ 193, 198, 199, 193, 193, 193, 193, 206,
+ 193, 204, 193, 204, 193, 193, 193, 193,
+ 267, 193, 198, 199, 193, 193, 193, 193,
+ 206, 193, 204, 193, 204, 193, 266, 193,
+ 193, 193, 193, 198, 199, 193, 193, 193,
+ 193, 206, 193, 204, 193, 204, 2, 193,
+ 193, 18, 205, 193, 198, 199, 193, 193,
+ 193, 193, 206, 193, 204, 193, 194, 195,
+ 203, 203, 5, 198, 199, 200, 193, 193,
+ 193, 201, 193, 194, 195, 196, 203, 5,
+ 198, 199, 200, 193, 193, 37, 201, 193,
+ 269, 270, 271, 272, 43, 273, 274, 268,
+ 268, 268, 75, 275, 268, 276, 270, 277,
+ 272, 43, 273, 274, 268, 268, 268, 268,
+ 275, 268, 270, 277, 272, 43, 273, 274,
+ 268, 268, 268, 268, 275, 268, 278, 268,
+ 268, 268, 56, 279, 268, 273, 274, 268,
+ 268, 268, 268, 280, 268, 278, 268, 281,
+ 282, 283, 284, 43, 273, 274, 268, 268,
+ 268, 73, 285, 268, 268, 278, 268, 286,
+ 282, 287, 287, 43, 273, 274, 268, 268,
+ 268, 268, 285, 268, 282, 287, 287, 43,
+ 273, 274, 268, 268, 268, 268, 285, 268,
+ 288, 268, 268, 268, 56, 289, 268, 273,
+ 274, 268, 268, 268, 268, 280, 268, 288,
+ 268, 290, 291, 292, 293, 43, 273, 274,
+ 268, 268, 268, 71, 294, 268, 268, 288,
+ 268, 295, 291, 296, 296, 43, 273, 274,
+ 268, 268, 268, 268, 294, 268, 291, 296,
+ 296, 43, 273, 274, 268, 268, 268, 268,
+ 294, 268, 297, 268, 268, 268, 56, 298,
+ 268, 273, 274, 268, 268, 268, 268, 280,
+ 268, 297, 268, 299, 300, 301, 302, 43,
+ 273, 274, 268, 268, 268, 69, 303, 268,
+ 268, 297, 268, 304, 300, 305, 305, 43,
+ 273, 274, 268, 268, 268, 268, 303, 268,
+ 300, 305, 305, 43, 273, 274, 268, 268,
+ 268, 268, 303, 268, 306, 268, 268, 268,
+ 56, 307, 268, 273, 274, 268, 268, 268,
+ 268, 280, 268, 306, 268, 308, 309, 310,
+ 311, 43, 273, 274, 268, 268, 268, 67,
+ 312, 268, 268, 306, 268, 313, 309, 314,
+ 314, 43, 273, 274, 268, 268, 268, 268,
+ 312, 268, 309, 314, 314, 43, 273, 274,
+ 268, 268, 268, 268, 312, 268, 56, 315,
+ 268, 273, 274, 268, 268, 268, 268, 280,
+ 268, 273, 274, 268, 268, 268, 268, 280,
+ 268, 316, 268, 268, 268, 274, 268, 274,
+ 268, 317, 268, 318, 268, 319, 320, 268,
+ 273, 274, 268, 268, 268, 41, 268, 268,
+ 268, 39, 268, 40, 268, 268, 268, 268,
+ 273, 274, 268, 273, 274, 268, 318, 268,
+ 268, 268, 268, 273, 274, 268, 318, 268,
+ 319, 268, 268, 273, 274, 268, 268, 268,
+ 41, 268, 56, 268, 321, 321, 43, 273,
+ 274, 268, 268, 268, 268, 280, 268, 322,
+ 65, 323, 324, 46, 273, 274, 268, 268,
+ 268, 268, 280, 268, 65, 323, 324, 46,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 323, 323, 46, 273, 274, 268, 268, 268,
+ 268, 280, 268, 325, 62, 326, 327, 49,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 62, 326, 327, 49, 273, 274, 268, 268,
+ 268, 268, 280, 268, 326, 326, 49, 273,
+ 274, 268, 268, 268, 268, 280, 268, 328,
+ 59, 329, 330, 52, 273, 274, 268, 268,
+ 268, 268, 280, 268, 59, 329, 330, 52,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 329, 329, 52, 273, 274, 268, 268, 268,
+ 268, 280, 268, 331, 56, 268, 332, 268,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 56, 268, 332, 268, 273, 274, 268, 268,
+ 268, 268, 280, 268, 333, 268, 273, 274,
+ 268, 268, 268, 268, 280, 268, 56, 268,
+ 268, 268, 268, 273, 274, 268, 268, 268,
+ 268, 280, 268, 39, 40, 268, 268, 56,
+ 315, 268, 273, 274, 268, 268, 268, 268,
+ 280, 268, 39, 268, 308, 309, 314, 314,
+ 43, 273, 274, 268, 268, 268, 268, 312,
+ 268, 308, 309, 310, 314, 43, 273, 274,
+ 268, 268, 268, 67, 312, 268, 306, 268,
+ 334, 268, 321, 321, 43, 273, 274, 268,
+ 268, 268, 268, 280, 268, 306, 268, 306,
+ 268, 268, 268, 268, 268, 268, 273, 274,
+ 268, 268, 268, 268, 280, 268, 306, 268,
+ 306, 268, 268, 268, 268, 335, 268, 273,
+ 274, 268, 268, 268, 268, 280, 268, 306,
+ 268, 306, 268, 334, 268, 268, 268, 268,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 306, 268, 306, 40, 268, 268, 56, 307,
+ 268, 273, 274, 268, 268, 268, 268, 280,
+ 268, 306, 268, 299, 300, 305, 305, 43,
+ 273, 274, 268, 268, 268, 268, 303, 268,
+ 299, 300, 301, 305, 43, 273, 274, 268,
+ 268, 268, 69, 303, 268, 297, 268, 336,
+ 268, 321, 321, 43, 273, 274, 268, 268,
+ 268, 268, 280, 268, 297, 268, 297, 268,
+ 268, 268, 268, 268, 268, 273, 274, 268,
+ 268, 268, 268, 280, 268, 297, 268, 297,
+ 268, 268, 268, 268, 337, 268, 273, 274,
+ 268, 268, 268, 268, 280, 268, 297, 268,
+ 297, 268, 336, 268, 268, 268, 268, 273,
+ 274, 268, 268, 268, 268, 280, 268, 297,
+ 268, 297, 40, 268, 268, 56, 298, 268,
+ 273, 274, 268, 268, 268, 268, 280, 268,
+ 297, 268, 290, 291, 296, 296, 43, 273,
+ 274, 268, 268, 268, 268, 294, 268, 290,
+ 291, 292, 296, 43, 273, 274, 268, 268,
+ 268, 71, 294, 268, 288, 268, 338, 268,
+ 321, 321, 43, 273, 274, 268, 268, 268,
+ 268, 280, 268, 288, 268, 288, 268, 268,
+ 268, 268, 268, 268, 273, 274, 268, 268,
+ 268, 268, 280, 268, 288, 268, 288, 268,
+ 268, 268, 268, 339, 268, 273, 274, 268,
+ 268, 268, 268, 280, 268, 288, 268, 288,
+ 268, 338, 268, 268, 268, 268, 273, 274,
+ 268, 268, 268, 268, 280, 268, 288, 268,
+ 288, 40, 268, 268, 56, 289, 268, 273,
+ 274, 268, 268, 268, 268, 280, 268, 288,
+ 268, 281, 282, 287, 287, 43, 273, 274,
+ 268, 268, 268, 268, 285, 268, 281, 282,
+ 283, 287, 43, 273, 274, 268, 268, 268,
+ 73, 285, 268, 278, 268, 340, 268, 321,
+ 321, 43, 273, 274, 268, 268, 268, 268,
+ 280, 268, 278, 268, 278, 268, 268, 268,
+ 268, 268, 268, 273, 274, 268, 268, 268,
+ 268, 280, 268, 278, 268, 278, 268, 268,
+ 268, 268, 341, 268, 273, 274, 268, 268,
+ 268, 268, 280, 268, 278, 268, 278, 268,
+ 340, 268, 268, 268, 268, 273, 274, 268,
+ 268, 268, 268, 280, 268, 278, 268, 74,
+ 42, 42, 43, 268, 268, 268, 268, 268,
+ 268, 74, 268, 278, 40, 268, 268, 56,
+ 279, 268, 273, 274, 268, 268, 268, 268,
+ 280, 268, 278, 268, 269, 270, 277, 272,
+ 43, 273, 274, 268, 268, 268, 268, 275,
+ 268, 343, 184, 344, 344, 81, 187, 188,
+ 342, 342, 342, 342, 190, 342, 184, 344,
+ 344, 81, 187, 188, 342, 342, 342, 342,
+ 190, 342, 345, 342, 342, 342, 95, 346,
+ 342, 187, 188, 342, 342, 342, 342, 347,
+ 342, 345, 342, 348, 349, 350, 351, 81,
+ 187, 188, 342, 342, 342, 112, 352, 342,
+ 342, 345, 342, 353, 349, 354, 354, 81,
+ 187, 188, 342, 342, 342, 342, 352, 342,
+ 349, 354, 354, 81, 187, 188, 342, 342,
+ 342, 342, 352, 342, 355, 342, 342, 342,
+ 95, 356, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 355, 342, 357, 358, 359,
+ 360, 81, 187, 188, 342, 342, 342, 110,
+ 361, 342, 342, 355, 342, 362, 358, 363,
+ 363, 81, 187, 188, 342, 342, 342, 342,
+ 361, 342, 358, 363, 363, 81, 187, 188,
+ 342, 342, 342, 342, 361, 342, 364, 342,
+ 342, 342, 95, 365, 342, 187, 188, 342,
+ 342, 342, 342, 347, 342, 364, 342, 366,
+ 367, 368, 369, 81, 187, 188, 342, 342,
+ 342, 108, 370, 342, 342, 364, 342, 371,
+ 367, 372, 372, 81, 187, 188, 342, 342,
+ 342, 342, 370, 342, 367, 372, 372, 81,
+ 187, 188, 342, 342, 342, 342, 370, 342,
+ 373, 342, 342, 342, 95, 374, 342, 187,
+ 188, 342, 342, 342, 342, 347, 342, 373,
+ 342, 375, 376, 377, 378, 81, 187, 188,
+ 342, 342, 342, 106, 379, 342, 342, 373,
+ 342, 380, 376, 381, 381, 81, 187, 188,
+ 342, 342, 342, 342, 379, 342, 376, 381,
+ 381, 81, 187, 188, 342, 342, 342, 342,
+ 379, 342, 95, 382, 342, 187, 188, 342,
+ 342, 342, 342, 347, 342, 187, 188, 342,
+ 342, 342, 342, 347, 342, 383, 342, 342,
+ 342, 188, 342, 188, 342, 384, 342, 385,
+ 342, 386, 387, 342, 187, 188, 342, 342,
+ 342, 79, 342, 342, 342, 77, 342, 78,
+ 342, 342, 342, 342, 187, 188, 342, 187,
+ 188, 342, 385, 342, 342, 342, 342, 187,
+ 188, 342, 385, 342, 386, 342, 342, 187,
+ 188, 342, 342, 342, 79, 342, 95, 342,
+ 388, 388, 81, 187, 188, 342, 342, 342,
+ 342, 347, 342, 389, 104, 390, 391, 85,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 104, 390, 391, 85, 187, 188, 342, 342,
+ 342, 342, 347, 342, 390, 390, 85, 187,
+ 188, 342, 342, 342, 342, 347, 342, 392,
+ 101, 393, 394, 88, 187, 188, 342, 342,
+ 342, 342, 347, 342, 101, 393, 394, 88,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 393, 393, 88, 187, 188, 342, 342, 342,
+ 342, 347, 342, 395, 98, 396, 397, 91,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 98, 396, 397, 91, 187, 188, 342, 342,
+ 342, 342, 347, 342, 396, 396, 91, 187,
+ 188, 342, 342, 342, 342, 347, 342, 398,
+ 95, 342, 399, 342, 187, 188, 342, 342,
+ 342, 342, 347, 342, 95, 342, 399, 342,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 400, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 95, 342, 342, 342, 342, 187,
+ 188, 342, 342, 342, 342, 347, 342, 77,
+ 78, 342, 342, 95, 382, 342, 187, 188,
+ 342, 342, 342, 342, 347, 342, 77, 342,
+ 375, 376, 381, 381, 81, 187, 188, 342,
+ 342, 342, 342, 379, 342, 375, 376, 377,
+ 381, 81, 187, 188, 342, 342, 342, 106,
+ 379, 342, 373, 342, 401, 342, 388, 388,
+ 81, 187, 188, 342, 342, 342, 342, 347,
+ 342, 373, 342, 373, 342, 342, 342, 342,
+ 342, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 373, 342, 373, 342, 342, 342,
+ 342, 402, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 373, 342, 373, 342, 401,
+ 342, 342, 342, 342, 187, 188, 342, 342,
+ 342, 342, 347, 342, 373, 342, 373, 78,
+ 342, 342, 95, 374, 342, 187, 188, 342,
+ 342, 342, 342, 347, 342, 373, 342, 366,
+ 367, 372, 372, 81, 187, 188, 342, 342,
+ 342, 342, 370, 342, 366, 367, 368, 372,
+ 81, 187, 188, 342, 342, 342, 108, 370,
+ 342, 364, 342, 403, 342, 388, 388, 81,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 364, 342, 364, 342, 342, 342, 342, 342,
+ 342, 187, 188, 342, 342, 342, 342, 347,
+ 342, 364, 342, 364, 342, 342, 342, 342,
+ 404, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 364, 342, 364, 342, 403, 342,
+ 342, 342, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 364, 342, 364, 78, 342,
+ 342, 95, 365, 342, 187, 188, 342, 342,
+ 342, 342, 347, 342, 364, 342, 357, 358,
+ 363, 363, 81, 187, 188, 342, 342, 342,
+ 342, 361, 342, 357, 358, 359, 363, 81,
+ 187, 188, 342, 342, 342, 110, 361, 342,
+ 355, 342, 405, 342, 388, 388, 81, 187,
+ 188, 342, 342, 342, 342, 347, 342, 355,
+ 342, 355, 342, 342, 342, 342, 342, 342,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 355, 342, 355, 342, 342, 342, 342, 406,
+ 342, 187, 188, 342, 342, 342, 342, 347,
+ 342, 355, 342, 355, 342, 405, 342, 342,
+ 342, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 355, 342, 355, 78, 342, 342,
+ 95, 356, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 355, 342, 348, 349, 354,
+ 354, 81, 187, 188, 342, 342, 342, 342,
+ 352, 342, 348, 349, 350, 354, 81, 187,
+ 188, 342, 342, 342, 112, 352, 342, 345,
+ 342, 407, 342, 388, 388, 81, 187, 188,
+ 342, 342, 342, 342, 347, 342, 345, 342,
+ 345, 342, 342, 342, 342, 342, 342, 187,
+ 188, 342, 342, 342, 342, 347, 342, 345,
+ 342, 345, 342, 342, 342, 342, 408, 342,
+ 187, 188, 342, 342, 342, 342, 347, 342,
+ 345, 342, 345, 342, 407, 342, 342, 342,
+ 342, 187, 188, 342, 342, 342, 342, 347,
+ 342, 345, 342, 345, 78, 342, 342, 95,
+ 346, 342, 187, 188, 342, 342, 342, 342,
+ 347, 342, 345, 342, 113, 80, 80, 81,
+ 409, 409, 409, 409, 409, 152, 113, 409,
+ 183, 184, 344, 344, 81, 187, 188, 342,
+ 342, 342, 342, 190, 342, 113, 80, 80,
+ 81, 409, 409, 409, 409, 409, 409, 113,
+ 409, 411, 412, 413, 414, 119, 415, 416,
+ 410, 410, 410, 151, 417, 410, 418, 412,
+ 414, 414, 119, 415, 416, 410, 410, 410,
+ 410, 417, 410, 412, 414, 414, 119, 415,
+ 416, 410, 410, 410, 410, 417, 410, 419,
+ 410, 410, 410, 132, 420, 410, 415, 416,
+ 410, 410, 410, 410, 421, 410, 419, 410,
+ 422, 423, 424, 425, 119, 415, 416, 410,
+ 410, 410, 149, 426, 410, 410, 419, 410,
+ 427, 423, 428, 428, 119, 415, 416, 410,
+ 410, 410, 410, 426, 410, 423, 428, 428,
+ 119, 415, 416, 410, 410, 410, 410, 426,
+ 410, 429, 410, 410, 410, 132, 430, 410,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 429, 410, 431, 432, 433, 434, 119, 415,
+ 416, 410, 410, 410, 147, 435, 410, 410,
+ 429, 410, 436, 432, 437, 437, 119, 415,
+ 416, 410, 410, 410, 410, 435, 410, 432,
+ 437, 437, 119, 415, 416, 410, 410, 410,
+ 410, 435, 410, 438, 410, 410, 410, 132,
+ 439, 410, 415, 416, 410, 410, 410, 410,
+ 421, 410, 438, 410, 440, 441, 442, 443,
+ 119, 415, 416, 410, 410, 410, 145, 444,
+ 410, 410, 438, 410, 445, 441, 446, 446,
+ 119, 415, 416, 410, 410, 410, 410, 444,
+ 410, 441, 446, 446, 119, 415, 416, 410,
+ 410, 410, 410, 444, 410, 447, 410, 410,
+ 410, 132, 448, 410, 415, 416, 410, 410,
+ 410, 410, 421, 410, 447, 410, 449, 450,
+ 451, 452, 119, 415, 416, 410, 410, 410,
+ 143, 453, 410, 410, 447, 410, 454, 450,
+ 455, 455, 119, 415, 416, 410, 410, 410,
+ 410, 453, 410, 450, 455, 455, 119, 415,
+ 416, 410, 410, 410, 410, 453, 410, 132,
+ 456, 410, 415, 416, 410, 410, 410, 410,
+ 421, 410, 415, 416, 410, 410, 410, 410,
+ 421, 410, 457, 410, 410, 410, 416, 410,
+ 416, 410, 458, 410, 459, 410, 460, 461,
+ 410, 415, 416, 410, 410, 410, 117, 410,
+ 410, 410, 115, 410, 116, 410, 410, 410,
+ 410, 415, 416, 410, 415, 416, 410, 459,
+ 410, 410, 410, 410, 415, 416, 410, 459,
+ 410, 460, 410, 410, 415, 416, 410, 410,
+ 410, 117, 410, 132, 410, 462, 462, 119,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 463, 141, 464, 465, 122, 415, 416, 410,
+ 410, 410, 410, 421, 410, 141, 464, 465,
+ 122, 415, 416, 410, 410, 410, 410, 421,
+ 410, 464, 464, 122, 415, 416, 410, 410,
+ 410, 410, 421, 410, 466, 138, 467, 468,
+ 125, 415, 416, 410, 410, 410, 410, 421,
+ 410, 138, 467, 468, 125, 415, 416, 410,
+ 410, 410, 410, 421, 410, 467, 467, 125,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 469, 135, 470, 471, 128, 415, 416, 410,
+ 410, 410, 410, 421, 410, 135, 470, 471,
+ 128, 415, 416, 410, 410, 410, 410, 421,
+ 410, 470, 470, 128, 415, 416, 410, 410,
+ 410, 410, 421, 410, 472, 132, 410, 473,
+ 410, 415, 416, 410, 410, 410, 410, 421,
+ 410, 132, 410, 473, 410, 415, 416, 410,
+ 410, 410, 410, 421, 410, 474, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 132,
+ 410, 410, 410, 410, 415, 416, 410, 410,
+ 410, 410, 421, 410, 115, 116, 410, 410,
+ 132, 456, 410, 415, 416, 410, 410, 410,
+ 410, 421, 410, 115, 410, 449, 450, 455,
+ 455, 119, 415, 416, 410, 410, 410, 410,
+ 453, 410, 449, 450, 451, 455, 119, 415,
+ 416, 410, 410, 410, 143, 453, 410, 447,
+ 410, 475, 410, 462, 462, 119, 415, 416,
+ 410, 410, 410, 410, 421, 410, 447, 410,
+ 447, 410, 410, 410, 410, 410, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 447,
+ 410, 447, 410, 410, 410, 410, 476, 410,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 447, 410, 447, 410, 475, 410, 410, 410,
+ 410, 415, 416, 410, 410, 410, 410, 421,
+ 410, 447, 410, 447, 116, 410, 410, 132,
+ 448, 410, 415, 416, 410, 410, 410, 410,
+ 421, 410, 447, 410, 440, 441, 446, 446,
+ 119, 415, 416, 410, 410, 410, 410, 444,
+ 410, 440, 441, 442, 446, 119, 415, 416,
+ 410, 410, 410, 145, 444, 410, 438, 410,
+ 477, 410, 462, 462, 119, 415, 416, 410,
+ 410, 410, 410, 421, 410, 438, 410, 438,
+ 410, 410, 410, 410, 410, 410, 415, 416,
+ 410, 410, 410, 410, 421, 410, 438, 410,
+ 438, 410, 410, 410, 410, 478, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 438,
+ 410, 438, 410, 477, 410, 410, 410, 410,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 438, 410, 438, 116, 410, 410, 132, 439,
+ 410, 415, 416, 410, 410, 410, 410, 421,
+ 410, 438, 410, 431, 432, 437, 437, 119,
+ 415, 416, 410, 410, 410, 410, 435, 410,
+ 431, 432, 433, 437, 119, 415, 416, 410,
+ 410, 410, 147, 435, 410, 429, 410, 479,
+ 410, 462, 462, 119, 415, 416, 410, 410,
+ 410, 410, 421, 410, 429, 410, 429, 410,
+ 410, 410, 410, 410, 410, 415, 416, 410,
+ 410, 410, 410, 421, 410, 429, 410, 429,
+ 410, 410, 410, 410, 480, 410, 415, 416,
+ 410, 410, 410, 410, 421, 410, 429, 410,
+ 429, 410, 479, 410, 410, 410, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 429,
+ 410, 429, 116, 410, 410, 132, 430, 410,
+ 415, 416, 410, 410, 410, 410, 421, 410,
+ 429, 410, 422, 423, 428, 428, 119, 415,
+ 416, 410, 410, 410, 410, 426, 410, 422,
+ 423, 424, 428, 119, 415, 416, 410, 410,
+ 410, 149, 426, 410, 419, 410, 481, 410,
+ 462, 462, 119, 415, 416, 410, 410, 410,
+ 410, 421, 410, 419, 410, 419, 410, 410,
+ 410, 410, 410, 410, 415, 416, 410, 410,
+ 410, 410, 421, 410, 419, 410, 419, 410,
+ 410, 410, 410, 482, 410, 415, 416, 410,
+ 410, 410, 410, 421, 410, 419, 410, 419,
+ 410, 481, 410, 410, 410, 410, 415, 416,
+ 410, 410, 410, 410, 421, 410, 419, 410,
+ 419, 116, 410, 410, 132, 420, 410, 415,
+ 416, 410, 410, 410, 410, 421, 410, 419,
+ 410, 411, 412, 414, 414, 119, 415, 416,
+ 410, 410, 410, 410, 417, 410, 181, 182,
+ 183, 184, 483, 344, 81, 187, 188, 342,
+ 189, 189, 152, 190, 342, 181, 342, 194,
+ 484, 196, 197, 5, 198, 199, 200, 193,
+ 193, 37, 201, 193, 193, 181, 193, 204,
+ 182, 183, 184, 485, 486, 81, 487, 488,
+ 193, 189, 189, 152, 489, 193, 204, 193,
+ 113, 80, 80, 81, 198, 199, 193, 193,
+ 193, 152, 490, 193, 491, 2, 342, 342,
+ 342, 408, 342, 187, 188, 342, 342, 342,
+ 342, 347, 342, 491, 342, 492, 349, 493,
+ 494, 81, 487, 488, 193, 193, 193, 153,
+ 352, 193, 193, 491, 193, 495, 349, 354,
+ 354, 81, 487, 488, 193, 193, 193, 193,
+ 352, 193, 349, 354, 354, 81, 487, 488,
+ 193, 193, 193, 193, 352, 193, 496, 193,
+ 193, 193, 488, 193, 488, 193, 243, 193,
+ 492, 349, 354, 354, 81, 487, 488, 193,
+ 193, 193, 193, 352, 193, 492, 349, 493,
+ 354, 81, 487, 488, 193, 193, 193, 153,
+ 352, 193, 204, 193, 266, 113, 497, 497,
+ 155, 198, 199, 193, 193, 193, 193, 490,
+ 193, 204, 193, 498, 179, 499, 500, 157,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 179, 499, 500, 157, 487, 488, 193, 193,
+ 193, 193, 501, 193, 499, 499, 157, 487,
+ 488, 193, 193, 193, 193, 501, 193, 502,
+ 176, 503, 504, 160, 487, 488, 193, 193,
+ 193, 193, 501, 193, 176, 503, 504, 160,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 503, 503, 160, 487, 488, 193, 193, 193,
+ 193, 501, 193, 505, 173, 506, 507, 163,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 173, 506, 507, 163, 487, 488, 193, 193,
+ 193, 193, 501, 193, 506, 506, 163, 487,
+ 488, 193, 193, 193, 193, 501, 193, 508,
+ 170, 193, 509, 193, 487, 488, 193, 193,
+ 193, 193, 501, 193, 170, 193, 509, 193,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 487, 488, 193, 193, 193, 193, 501, 193,
+ 510, 193, 511, 512, 193, 487, 488, 193,
+ 193, 193, 167, 193, 193, 193, 165, 193,
+ 166, 193, 193, 193, 193, 487, 488, 193,
+ 487, 488, 193, 510, 193, 193, 193, 193,
+ 487, 488, 193, 510, 193, 511, 193, 193,
+ 487, 488, 193, 193, 193, 167, 193, 491,
+ 166, 342, 342, 95, 346, 342, 187, 188,
+ 342, 342, 342, 342, 347, 342, 491, 342,
0
};
static const short _indic_syllable_machine_trans_targs[] = {
- 143, 168, 170, 171, 3, 174, 4, 6,
- 177, 7, 9, 180, 10, 12, 183, 13,
- 15, 16, 164, 18, 19, 182, 21, 22,
- 179, 24, 25, 176, 185, 189, 193, 196,
- 200, 203, 207, 210, 214, 217, 143, 243,
- 245, 246, 39, 249, 40, 42, 252, 43,
- 45, 255, 46, 48, 258, 49, 51, 52,
- 239, 54, 55, 257, 57, 58, 254, 60,
- 61, 251, 260, 263, 267, 270, 274, 277,
- 281, 284, 288, 292, 143, 316, 318, 319,
- 75, 322, 143, 76, 78, 325, 79, 81,
- 328, 82, 84, 331, 85, 87, 88, 312,
- 90, 91, 330, 93, 94, 327, 96, 97,
- 324, 333, 336, 340, 343, 347, 350, 354,
- 357, 361, 143, 391, 393, 394, 110, 397,
- 111, 113, 400, 114, 116, 403, 117, 119,
- 406, 120, 122, 123, 387, 125, 126, 405,
- 128, 129, 402, 131, 132, 399, 408, 411,
- 415, 418, 422, 425, 429, 432, 436, 439,
- 143, 144, 219, 293, 295, 364, 366, 313,
- 315, 367, 365, 363, 440, 441, 143, 145,
- 147, 35, 218, 165, 167, 187, 216, 146,
- 34, 148, 212, 0, 149, 151, 33, 211,
- 209, 150, 32, 152, 205, 153, 155, 31,
- 204, 202, 154, 30, 156, 198, 157, 159,
- 29, 197, 195, 158, 28, 160, 191, 161,
- 163, 27, 190, 188, 162, 26, 173, 166,
- 143, 169, 1, 172, 2, 175, 5, 23,
- 178, 8, 20, 181, 11, 17, 184, 14,
- 186, 192, 194, 199, 201, 206, 208, 213,
- 215, 143, 220, 222, 71, 290, 240, 242,
- 291, 221, 70, 223, 286, 36, 224, 226,
- 69, 285, 283, 225, 68, 227, 279, 228,
- 230, 67, 278, 276, 229, 66, 231, 272,
- 232, 234, 65, 271, 269, 233, 64, 235,
- 265, 236, 238, 63, 264, 262, 237, 62,
- 248, 241, 143, 244, 37, 247, 38, 250,
- 41, 59, 253, 44, 56, 256, 47, 53,
- 259, 50, 261, 266, 268, 273, 275, 280,
- 282, 287, 289, 143, 294, 106, 296, 359,
- 72, 297, 299, 105, 358, 356, 298, 104,
- 300, 352, 301, 303, 103, 351, 349, 302,
- 102, 304, 345, 305, 307, 101, 344, 342,
- 306, 100, 308, 338, 309, 311, 99, 337,
- 335, 310, 98, 321, 314, 143, 317, 73,
- 320, 74, 323, 77, 95, 326, 80, 92,
- 329, 83, 89, 332, 86, 334, 339, 341,
- 346, 348, 353, 355, 360, 362, 143, 143,
- 368, 370, 142, 141, 388, 390, 438, 369,
- 371, 434, 107, 372, 374, 140, 433, 431,
- 373, 139, 375, 427, 376, 378, 138, 426,
- 424, 377, 137, 379, 420, 380, 382, 136,
- 419, 417, 381, 135, 383, 413, 384, 386,
- 134, 412, 410, 385, 133, 396, 389, 143,
- 392, 108, 395, 109, 398, 112, 130, 401,
- 115, 127, 404, 118, 124, 407, 121, 409,
- 414, 416, 421, 423, 428, 430, 435, 437,
- 442
+ 170, 195, 197, 198, 3, 201, 4, 6,
+ 204, 7, 9, 207, 10, 12, 210, 13,
+ 15, 16, 191, 18, 19, 209, 21, 22,
+ 206, 24, 25, 203, 212, 216, 220, 223,
+ 227, 230, 234, 237, 241, 244, 170, 270,
+ 272, 273, 39, 276, 40, 42, 279, 43,
+ 45, 282, 46, 48, 285, 49, 51, 52,
+ 266, 54, 55, 284, 57, 58, 281, 60,
+ 61, 278, 287, 290, 294, 297, 301, 304,
+ 308, 311, 315, 319, 170, 343, 345, 346,
+ 75, 349, 170, 76, 78, 352, 79, 81,
+ 355, 82, 84, 358, 85, 87, 88, 339,
+ 90, 91, 357, 93, 94, 354, 96, 97,
+ 351, 360, 363, 367, 370, 374, 377, 381,
+ 384, 388, 170, 418, 420, 421, 110, 424,
+ 111, 113, 427, 114, 116, 430, 117, 119,
+ 433, 120, 122, 123, 414, 125, 126, 432,
+ 128, 129, 429, 131, 132, 426, 435, 438,
+ 442, 445, 449, 452, 456, 459, 463, 466,
+ 392, 478, 146, 481, 148, 484, 149, 151,
+ 487, 152, 154, 490, 155, 493, 495, 496,
+ 159, 160, 492, 162, 163, 489, 165, 166,
+ 486, 168, 169, 483, 170, 171, 246, 320,
+ 322, 391, 393, 340, 342, 394, 390, 467,
+ 468, 170, 172, 174, 35, 245, 192, 194,
+ 214, 243, 173, 34, 175, 239, 0, 176,
+ 178, 33, 238, 236, 177, 32, 179, 232,
+ 180, 182, 31, 231, 229, 181, 30, 183,
+ 225, 184, 186, 29, 224, 222, 185, 28,
+ 187, 218, 188, 190, 27, 217, 215, 189,
+ 26, 200, 193, 170, 196, 1, 199, 2,
+ 202, 5, 23, 205, 8, 20, 208, 11,
+ 17, 211, 14, 213, 219, 221, 226, 228,
+ 233, 235, 240, 242, 170, 247, 249, 71,
+ 317, 267, 269, 318, 248, 70, 250, 313,
+ 36, 251, 253, 69, 312, 310, 252, 68,
+ 254, 306, 255, 257, 67, 305, 303, 256,
+ 66, 258, 299, 259, 261, 65, 298, 296,
+ 260, 64, 262, 292, 263, 265, 63, 291,
+ 289, 264, 62, 275, 268, 170, 271, 37,
+ 274, 38, 277, 41, 59, 280, 44, 56,
+ 283, 47, 53, 286, 50, 288, 293, 295,
+ 300, 302, 307, 309, 314, 316, 170, 321,
+ 106, 323, 386, 72, 324, 326, 105, 385,
+ 383, 325, 104, 327, 379, 328, 330, 103,
+ 378, 376, 329, 102, 331, 372, 332, 334,
+ 101, 371, 369, 333, 100, 335, 365, 336,
+ 338, 99, 364, 362, 337, 98, 348, 341,
+ 170, 344, 73, 347, 74, 350, 77, 95,
+ 353, 80, 92, 356, 83, 89, 359, 86,
+ 361, 366, 368, 373, 375, 380, 382, 387,
+ 389, 170, 170, 395, 397, 142, 141, 415,
+ 417, 465, 396, 398, 461, 107, 399, 401,
+ 140, 460, 458, 400, 139, 402, 454, 403,
+ 405, 138, 453, 451, 404, 137, 406, 447,
+ 407, 409, 136, 446, 444, 408, 135, 410,
+ 440, 411, 413, 134, 439, 437, 412, 133,
+ 423, 416, 170, 419, 108, 422, 109, 425,
+ 112, 130, 428, 115, 127, 431, 118, 124,
+ 434, 121, 436, 441, 443, 448, 450, 455,
+ 457, 462, 464, 143, 469, 470, 480, 475,
+ 477, 498, 471, 472, 473, 144, 479, 474,
+ 476, 145, 482, 147, 167, 156, 485, 150,
+ 164, 488, 153, 161, 491, 158, 494, 157,
+ 497
};
static const char _indic_syllable_machine_trans_actions[] = {
@@ -900,44 +992,51 @@ static const char _indic_syllable_machine_trans_actions[] = {
2, 0, 0, 0, 2, 0, 0, 2,
0, 0, 2, 0, 0, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
- 10, 2, 2, 6, 2, 11, 11, 0,
- 0, 2, 6, 2, 0, 2, 12, 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,
- 13, 0, 0, 2, 0, 2, 0, 0,
+ 6, 8, 0, 2, 0, 2, 0, 0,
+ 2, 0, 0, 2, 0, 2, 0, 0,
+ 0, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 11, 2, 2, 6,
+ 2, 12, 12, 0, 0, 2, 2, 6,
+ 2, 13, 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, 14, 0, 0, 2, 0,
+ 2, 0, 0, 2, 0, 0, 2, 0,
+ 0, 2, 0, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 15, 2, 2, 0,
+ 2, 0, 0, 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, 16, 0, 0,
+ 2, 0, 2, 0, 0, 2, 0, 0,
+ 2, 0, 0, 2, 0, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 17, 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,
+ 18, 0, 0, 2, 0, 2, 0, 0,
2, 0, 0, 2, 0, 0, 2, 0,
2, 2, 2, 2, 2, 2, 2, 2,
- 2, 14, 2, 2, 0, 2, 0, 0,
- 2, 2, 0, 2, 2, 0, 2, 2,
+ 2, 19, 20, 2, 2, 0, 0, 0,
+ 0, 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, 15, 0, 0, 2, 0, 2,
+ 2, 0, 21, 0, 0, 2, 0, 2,
0, 0, 2, 0, 0, 2, 0, 0,
2, 0, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 16, 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, 17, 0, 0,
- 2, 0, 2, 0, 0, 2, 0, 0,
- 2, 0, 0, 2, 0, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 18, 19,
- 2, 2, 0, 0, 0, 0, 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, 20,
- 0, 0, 2, 0, 2, 0, 0, 2,
- 0, 0, 2, 0, 0, 2, 0, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 0, 0, 8, 2, 0,
+ 0, 2, 2, 8, 8, 0, 8, 8,
+ 0, 0, 2, 0, 0, 0, 2, 0,
+ 0, 2, 0, 0, 2, 0, 0, 0,
2
};
@@ -959,7 +1058,14 @@ static const char _indic_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 8,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -1018,7 +1124,14 @@ static const char _indic_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 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, 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, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -1073,63 +1186,70 @@ static const short _indic_syllable_machine_eof_trans[] = {
77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77,
77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 115, 115, 115, 115, 115,
+ 83, 77, 77, 115, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 115, 115,
115, 115, 115, 115, 115, 115, 115, 115,
- 115, 115, 115, 115, 115, 115, 115, 0,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 242, 242, 242,
- 242, 242, 242, 242, 242, 316, 316, 316,
- 316, 316, 316, 316, 316, 316, 316, 316,
- 316, 316, 316, 316, 316, 316, 316, 316,
- 316, 316, 316, 316, 316, 316, 316, 316,
- 316, 316, 316, 316, 316, 316, 316, 316,
- 316, 316, 316, 316, 316, 316, 316, 316,
- 316, 316, 316, 316, 316, 316, 316, 316,
- 316, 316, 316, 316, 316, 316, 316, 316,
- 316, 316, 316, 316, 316, 316, 316, 316,
- 316, 316, 316, 316, 383, 316, 383, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 384, 384, 384, 384, 384, 384, 384, 384,
- 383, 167, 167
+ 115, 115, 115, 115, 115, 115, 115, 77,
+ 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, 0, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 343,
+ 343, 343, 343, 343, 343, 343, 343, 410,
+ 343, 410, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 411, 411, 411, 411, 411,
+ 411, 411, 411, 343, 194, 194, 194, 343,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 343
};
-static const int indic_syllable_machine_start = 143;
-static const int indic_syllable_machine_first_final = 143;
+static const int indic_syllable_machine_start = 170;
+static const int indic_syllable_machine_first_final = 170;
static const int indic_syllable_machine_error = -1;
-static const int indic_syllable_machine_en_main = 143;
+static const int indic_syllable_machine_en_main = 170;
#line 36 "../../src/hb-ot-shape-complex-indic-machine.rl"
-#line 90 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 91 "../../src/hb-ot-shape-complex-indic-machine.rl"
#define found_syllable(syllable_type) \
@@ -1145,11 +1265,11 @@ static const int indic_syllable_machine_en_main = 143;
static void
find_syllables (hb_buffer_t *buffer)
{
- unsigned int p, pe, eof, ts, te, act;
+ unsigned int p, pe, eof, ts HB_UNUSED, te, act;
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 1153 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
+#line 1273 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
{
cs = indic_syllable_machine_start;
ts = 0;
@@ -1157,7 +1277,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
-#line 111 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 112 "../../src/hb-ot-shape-complex-indic-machine.rl"
p = 0;
@@ -1166,7 +1286,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
-#line 1170 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
+#line 1290 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
{
int _slen;
int _trans;
@@ -1176,11 +1296,11 @@ find_syllables (hb_buffer_t *buffer)
goto _test_eof;
_resume:
switch ( _indic_syllable_machine_from_state_actions[cs] ) {
- case 9:
-#line 1 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 10:
+#line 1 "NONE"
{ts = p;}
break;
-#line 1184 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
+#line 1304 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
}
_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -1199,68 +1319,71 @@ _eof_trans:
switch ( _indic_syllable_machine_trans_actions[_trans] ) {
case 2:
-#line 1 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 1 "NONE"
{te = p+1;}
break;
- case 13:
-#line 82 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 14:
+#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
- case 15:
-#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 16:
+#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (vowel_syllable); }}
break;
- case 20:
-#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 21:
+#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (standalone_cluster); }}
break;
- case 17:
-#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 18:
+#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
- case 10:
-#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 11:
+#line 87 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p+1;{ found_syllable (non_indic_cluster); }}
break;
- case 12:
-#line 82 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 13:
+#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
- case 14:
-#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 15:
+#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (vowel_syllable); }}
break;
- case 19:
-#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 20:
+#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (standalone_cluster); }}
break;
- case 16:
-#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 17:
+#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
- case 18:
-#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 19:
+#line 87 "../../src/hb-ot-shape-complex-indic-machine.rl"
{te = p;p--;{ found_syllable (non_indic_cluster); }}
break;
case 1:
-#line 82 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
break;
case 3:
-#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (vowel_syllable); }}
break;
case 7:
-#line 84 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (standalone_cluster); }}
break;
case 4:
-#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
case 5:
-#line 1 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 1 "NONE"
{ switch( act ) {
+ case 1:
+ {{p = ((te))-1;} found_syllable (consonant_syllable); }
+ break;
case 4:
{{p = ((te))-1;} found_syllable (broken_cluster); }
break;
@@ -1270,28 +1393,34 @@ _eof_trans:
}
}
break;
+ case 8:
+#line 1 "NONE"
+ {te = p+1;}
+#line 83 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ {act = 1;}
+ break;
case 6:
-#line 1 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 1 "NONE"
{te = p+1;}
-#line 85 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl"
{act = 4;}
break;
- case 11:
-#line 1 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 12:
+#line 1 "NONE"
{te = p+1;}
-#line 86 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 87 "../../src/hb-ot-shape-complex-indic-machine.rl"
{act = 5;}
break;
-#line 1286 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
+#line 1415 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
}
_again:
switch ( _indic_syllable_machine_to_state_actions[cs] ) {
- case 8:
-#line 1 "../../src/hb-ot-shape-complex-indic-machine.rl"
+ case 9:
+#line 1 "NONE"
{ts = 0;}
break;
-#line 1295 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
+#line 1424 "../../src/hb-ot-shape-complex-indic-machine.hh.tmp"
}
if ( ++p != pe )
@@ -1307,7 +1436,7 @@ _again:
}
-#line 120 "../../src/hb-ot-shape-complex-indic-machine.rl"
+#line 121 "../../src/hb-ot-shape-complex-indic-machine.rl"
}
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl
index 53dc20d..11115c9 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-machine.rl
@@ -1,5 +1,5 @@
/*
- * Copyright © 2011 Google, Inc.
+ * Copyright © 2011,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -29,8 +29,6 @@
#include "hb-private.hh"
-HB_BEGIN_DECLS
-
%%{
machine indic_syllable_machine;
alphtype unsigned char;
@@ -42,78 +40,85 @@ HB_BEGIN_DECLS
# Same order as enum indic_category_t. Not sure how to avoid duplication.
X = 0;
C = 1;
-Ra = 2;
-V = 3;
-N = 4;
-H = 5;
-ZWNJ = 6;
-ZWJ = 7;
-M = 8;
-SM = 9;
-VD = 10;
-A = 11;
-NBSP = 12;
-
-c = C | Ra;
-z = ZWJ|ZWNJ;
-matra_group = M N? H?;
-syllable_tail = SM? (VD VD?)?;
-
-action found_consonant_syllable { found_consonant_syllable (map, buffer, mask_array, last, p); }
-action found_vowel_syllable { found_vowel_syllable (map, buffer, mask_array, last, p); }
-action found_standalone_cluster { found_standalone_cluster (map, buffer, mask_array, last, p); }
-action found_non_indic { found_non_indic (map, buffer, mask_array, last, p); }
-
-action next_syllable { set_cluster (buffer, p, last); last = p; }
-
-consonant_syllable = (c.N? (z.H|H.z?))* c.N? A? (H.z? | matra_group*)? syllable_tail %(found_consonant_syllable);
-vowel_syllable = (Ra H)? V N? (z.H.c | ZWJ.c)? matra_group* syllable_tail %(found_vowel_syllable);
-standalone_cluster = (Ra H)? NBSP N? (z? H c)? matra_group* syllable_tail %(found_standalone_cluster);
-non_indic = X %(found_non_indic);
-
-syllable =
- consonant_syllable
- | vowel_syllable
- | standalone_cluster
- | non_indic
- ;
-
-main := (syllable %(next_syllable))**;
-
-}%%
+V = 2;
+N = 3;
+H = 4;
+ZWNJ = 5;
+ZWJ = 6;
+M = 7;
+SM = 8;
+VD = 9;
+A = 10;
+NBSP = 11;
+DOTTEDCIRCLE = 12;
+RS = 13;
+Coeng = 14;
+Repha = 15;
+Ra = 16;
+CM = 17;
+
+c = (C | Ra)CM*; # is_consonant
+n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier
+z = ZWJ|ZWNJ; # is_joiner
+h = H | Coeng; # is_halant_or_coeng
+reph = (Ra H | Repha); # possible reph
+
+cn = c.ZWJ?.n?;
+forced_rakar = ZWJ H ZWJ Ra;
+matra_group = z{0,3}.M.N?.(H | forced_rakar)?;
+syllable_tail = (Coeng (cn|V))? (SM.ZWNJ?)? (VD VD?)?;
+place_holder = NBSP | DOTTEDCIRCLE;
+halant_group = (z?.h.(ZWJ.N?)?);
+final_halant_group = halant_group | h.ZWNJ;
+halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4});
+
+
+consonant_syllable = Repha? (cn.halant_group){0,4} cn A? halant_or_matra_group? syllable_tail;
+vowel_syllable = reph? V.n? (ZWJ | (halant_group.cn){0,4} halant_or_matra_group? syllable_tail);
+standalone_cluster = reph? place_holder.n? (halant_group.cn){0,4} halant_or_matra_group? syllable_tail;
+broken_cluster = reph? n? (halant_group.cn){0,4} halant_or_matra_group syllable_tail;
+other = any;
+
+main := |*
+ consonant_syllable => { found_syllable (consonant_syllable); };
+ vowel_syllable => { found_syllable (vowel_syllable); };
+ standalone_cluster => { found_syllable (standalone_cluster); };
+ broken_cluster => { found_syllable (broken_cluster); };
+ other => { found_syllable (non_indic_cluster); };
+*|;
-static void
-set_cluster (hb_buffer_t *buffer,
- unsigned int start, unsigned int end)
-{
- unsigned int cluster = buffer->info[start].cluster;
+}%%
- for (unsigned int i = start + 1; i < end; i++)
- cluster = MIN (cluster, buffer->info[i].cluster);
- for (unsigned int i = start; i < end; i++)
- buffer->info[i].cluster = cluster;
-}
+#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 (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array)
+find_syllables (hb_buffer_t *buffer)
{
- unsigned int p, pe, eof;
+ unsigned int p, pe, eof, ts HB_UNUSED, te, act;
int cs;
+ hb_glyph_info_t *info = buffer->info;
%%{
write init;
- getkey buffer->info[p].indic_category();
+ getkey info[p].indic_category();
}%%
p = 0;
pe = eof = buffer->len;
unsigned int last = 0;
+ unsigned int syllable_serial = 1;
%%{
write exec;
}%%
}
-HB_END_DECLS
-
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
index 91b0be5..e36090e 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
@@ -39,7 +39,7 @@
#define indic_position() complex_var_u8_1() /* indic_matra_category_t */
-#define INDIC_TABLE_ELEMENT_TYPE uint8_t
+#define INDIC_TABLE_ELEMENT_TYPE uint16_t
/* Cateories used in the OpenType spec:
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
@@ -63,7 +63,8 @@ enum indic_category_t {
OT_RS, /* Register Shifter, used in Khmer OT spec */
OT_Coeng,
OT_Repha,
- OT_Ra /* Not explicitly listed in the OT spec, but used in the grammar. */
+ OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */
+ OT_CM
};
/* Visual positions in a syllable from left to right. */
@@ -103,7 +104,7 @@ enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_C,
INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_CM,
INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_NBSP,
INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_C,
INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_Repha,
@@ -111,7 +112,7 @@ enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_RS,
INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
- INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_X,
+ INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_N,
INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
@@ -138,16 +139,16 @@ enum indic_matra_category_t {
INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
INDIC_MATRA_CATEGORY_INVISIBLE = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
- INDIC_MATRA_CATEGORY_OVERSTRUCK = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
- INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = INDIC_MATRA_CATEGORY_NOT_APPLICABLE
+ INDIC_MATRA_CATEGORY_OVERSTRUCK = POS_AFTER_MAIN,
+ INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M
};
/* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation
* because gcc fails to optimize the latter and fills the table in at runtime. */
#define INDIC_COMBINE_CATEGORIES(S,M) \
(ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || (S == INDIC_SYLLABIC_CATEGORY_VIRAMA || S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT)) + \
- ASSERT_STATIC_EXPR_ZERO (S < 16 && M < 16) + \
- ((M << 4) | S))
+ ASSERT_STATIC_EXPR_ZERO (S < 255 && M < 255) + \
+ ((M << 8) | S))
#include "hb-ot-shape-complex-indic-table.hh"
@@ -221,7 +222,7 @@ matra_position (hb_codepoint_t u, indic_position_t side)
case POS_ABOVE_C: return MATRA_POS_TOP (u);
case POS_BELOW_C: return MATRA_POS_BOTTOM (u);
};
- abort ();
+ return side;
}
@@ -285,7 +286,7 @@ is_joiner (const hb_glyph_info_t &info)
* We treat Vowels and placeholders as if they were consonants. This is safe because Vowels
* cannot happen in a consonant syllable. The plus side however is, we can call the
* consonant syllable logic from the vowel syllable function and get it all right! */
-#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
static inline bool
is_consonant (const hb_glyph_info_t &info)
{
@@ -304,8 +305,8 @@ set_indic_properties (hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = get_indic_categories (u);
- indic_category_t cat = (indic_category_t) (type & 0x0F);
- indic_position_t pos = (indic_position_t) (type >> 4);
+ indic_category_t cat = (indic_category_t) (type & 0x7F);
+ indic_position_t pos = (indic_position_t) (type >> 8);
/*
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.hh
index 5b4b344..70765b6 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic-table.hh
@@ -6,12 +6,12 @@
*
* on files with these headers:
*
- * # IndicSyllabicCategory-6.1.0.txt
- * # Date: 2011-08-31, 23:54:00 GMT [KW]
- * # IndicMatraCategory-6.1.0.txt
- * # Date: 2011-08-31, 23:50:00 GMT [KW]
- * # Blocks-6.1.0.txt
- * # Date: 2011-06-14, 18:26:00 GMT [KW, LI]
+ * # IndicSyllabicCategory-6.2.0.txt
+ * # Date: 2012-05-15, 21:12:00 GMT [KW]
+ * # IndicMatraCategory-6.2.0.txt
+ * # Date: 2012-05-15, 21:10:00 GMT [KW]
+ * # Blocks-6.2.0.txt
+ * # Date: 2012-05-14, 22:42:00 GMT [KW, LI]
*/
#ifndef HB_OT_SHAPE_COMPLEX_INDIC_TABLE_HH
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
index 30a9a1f..1bc8a77 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
@@ -123,6 +123,8 @@ static const indic_config_t indic_configs[] =
{HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA},
{HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_FIRST,REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT},
{HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DEFAULT, REPH_MODE_VIS_REPHA},
+ /* Myanmar does not have the "old_indic" behavior, even though it has a "new" tag. */
+ {HB_SCRIPT_MYANMAR, false,0x1039,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_EXPLICIT},
};
@@ -247,6 +249,8 @@ override_features_indic (hb_ot_shape_planner_t *plan)
/* Uniscribe does not apply 'kern'. */
if (indic_options ().uniscribe_bug_compatible)
plan->map.add_feature (HB_TAG('k','e','r','n'), 0, true);
+
+ plan->map.add_feature (HB_TAG('l','i','g','a'), 0, true);
}
@@ -265,7 +269,7 @@ struct would_substitute_feature_t
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
- if (hb_ot_layout_would_substitute_lookup_fast (face, lookups[i].index, glyphs, glyphs_count, zero_context))
+ if (hb_ot_layout_lookup_would_substitute_fast (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
@@ -303,6 +307,7 @@ struct indic_shape_plan_t
bool is_old_spec;
hb_codepoint_t virama_glyph;
+ would_substitute_feature_t rphf;
would_substitute_feature_t pref;
would_substitute_feature_t blwf;
would_substitute_feature_t pstf;
@@ -324,9 +329,10 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
break;
}
- indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.get_chosen_script (0) & 0x000000FF) != '2');
+ indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FF) != '2');
indic_plan->virama_glyph = (hb_codepoint_t) -1;
+ indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'));
indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'));
indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'));
indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'));
@@ -428,7 +434,9 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
static void
-initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer,
+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 indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
@@ -459,22 +467,36 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
unsigned int limit = start;
if (indic_plan->mask_array[RPHF] &&
start + 3 <= end &&
- info[start].indic_category() == OT_Ra &&
- info[start + 1].indic_category() == OT_H &&
- (/* TODO Handle other Reph modes. */
+ (
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
(indic_plan->config->reph_mode == REPH_MODE_EXPLICIT && info[start + 2].indic_category() == OT_ZWJ)
))
{
- limit += 2;
- while (limit < end && is_joiner (info[limit]))
- limit++;
- base = start;
- has_reph = true;
- };
+ /* See if it matches the 'rphf' feature. */
+ hb_codepoint_t glyphs[2] = {info[start].codepoint, info[start + 1].codepoint};
+ if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
+ {
+ limit += 2;
+ while (limit < end && is_joiner (info[limit]))
+ limit++;
+ base = start;
+ has_reph = true;
+ }
+ } else if (indic_plan->config->reph_mode == REPH_MODE_LOG_REPHA && info[start].indic_category() == OT_Repha)
+ {
+ limit += 1;
+ while (limit < end && is_joiner (info[limit]))
+ limit++;
+ base = start;
+ has_reph = true;
+ }
switch (indic_plan->config->base_pos)
{
+ default:
+ assert (false);
+ /* fallthrough */
+
case BASE_POS_LAST:
{
/* -> starting from the end of the syllable, move backwards */
@@ -514,7 +536,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
* half form.
* A ZWJ before a Halant, requests a subjoined form instead, and hence
* search continues. This is particularly important for Bengali
- * sequence Ra,H,Ya that shouls form Ya-Phalaa by subjoining Ya. */
+ * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
if (start < i &&
info[i].indic_category() == OT_ZWJ &&
info[i - 1].indic_category() == OT_H)
@@ -548,9 +570,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
info[i].indic_position() = POS_BELOW_C;
}
break;
-
- default:
- abort ();
}
/* -> If the syllable starts with Ra + Halant (in a script that has Reph)
@@ -558,7 +577,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
* base consonants.
*
* Only do this for unforced Reph. (ie. not for Ra,H,ZWJ. */
- if (has_reph && base == start && start + 2 == limit) {
+ if (has_reph && base == start && start - limit <= 2) {
/* Have no other consonant, so Reph is not formed and Ra becomes base. */
has_reph = false;
}
@@ -651,13 +670,17 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | HALANT_OR_COENG_FLAGS)))
{
info[i].indic_position() = last_pos;
- if (unlikely (indic_options ().uniscribe_bug_compatible &&
- info[i].indic_category() == OT_H &&
+ if (unlikely (info[i].indic_category() == OT_H &&
info[i].indic_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].indic_position() != POS_PRE_M) {
@@ -725,9 +748,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
if (indic_plan->mask_array[PREF] && base + 2 < end)
{
/* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
- for (unsigned int i = base + 1; i + 1 < end; i++)
- if (is_halant_or_coeng (info[i + (indic_plan->is_old_spec ? 1 : 0)]) &&
- info[i + (indic_plan->is_old_spec ? 0 : 1)].indic_category() == OT_Ra)
+ for (unsigned int i = base + 1; i + 1 < end; i++) {
+ hb_codepoint_t glyphs[2] = {info[i].codepoint, info[i + 1].codepoint};
+ if (indic_plan->pref.would_substitute (glyphs, ARRAY_LENGTH (glyphs), true, face))
{
info[i++].mask |= indic_plan->mask_array[PREF];
info[i++].mask |= indic_plan->mask_array[PREF];
@@ -743,6 +766,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
break;
}
+ }
}
/* Apply ZWJ/ZWNJ effects */
@@ -768,15 +792,17 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, hb_buffer
static void
initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
/* We made the vowels look like consonants. So let's call the consonant logic! */
- initial_reordering_consonant_syllable (plan, buffer, start, end);
+ initial_reordering_consonant_syllable (plan, face, buffer, start, end);
}
static void
initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
@@ -792,20 +818,22 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
return;
}
- initial_reordering_consonant_syllable (plan, buffer, start, end);
+ initial_reordering_consonant_syllable (plan, face, buffer, start, end);
}
static void
initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
+ hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
/* We already inserted dotted-circles, so just call the standalone_cluster. */
- initial_reordering_standalone_cluster (plan, buffer, start, end);
+ initial_reordering_standalone_cluster (plan, face, buffer, start, end);
}
static void
initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_face_t *face HB_UNUSED,
hb_buffer_t *buffer HB_UNUSED,
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
{
@@ -816,21 +844,22 @@ initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
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 consonant_syllable: initial_reordering_consonant_syllable (plan, buffer, start, end); return;
- case vowel_syllable: initial_reordering_vowel_syllable (plan, buffer, start, end); return;
- case standalone_cluster: initial_reordering_standalone_cluster (plan, buffer, start, end); return;
- case broken_cluster: initial_reordering_broken_cluster (plan, buffer, start, end); return;
- case non_indic_cluster: initial_reordering_non_indic_cluster (plan, buffer, start, end); return;
+ case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
+ case vowel_syllable: initial_reordering_vowel_syllable (plan, face, buffer, start, end); return;
+ case standalone_cluster: initial_reordering_standalone_cluster (plan, face, buffer, start, end); return;
+ case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
+ case non_indic_cluster: initial_reordering_non_indic_cluster (plan, face, buffer, start, end); return;
}
}
static inline void
-insert_dotted_circles (const hb_ot_shape_plan_t *plan,
+insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
@@ -850,7 +879,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan,
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
return;
- hb_glyph_info_t dottedcircle;
+ hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CC;
set_indic_properties (dottedcircle);
dottedcircle.codepoint = dottedcircle_glyph;
@@ -865,14 +894,23 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan,
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 info = dottedcircle;
info.cluster = buffer->cur().cluster;
info.mask = buffer->cur().mask;
info.syllable() = buffer->cur().syllable();
+
+ /* Insert dottedcircle after possible Repha. */
+ while (buffer->idx < buffer->len &&
+ last_syllable == buffer->cur().syllable() &&
+ buffer->cur().indic_category() == OT_Repha)
+ buffer->next_glyph ();
+
buffer->output_info (info);
- last_syllable = syllable;
}
- buffer->next_glyph ();
+ else
+ buffer->next_glyph ();
}
buffer->swap_buffers ();
@@ -893,11 +931,11 @@ initial_reordering (const hb_ot_shape_plan_t *plan,
unsigned int last_syllable = info[0].syllable();
for (unsigned int i = 1; i < count; i++)
if (last_syllable != info[i].syllable()) {
- initial_reordering_syllable (plan, buffer, last, i);
+ initial_reordering_syllable (plan, font->face, buffer, last, i);
last = i;
last_syllable = info[last].syllable();
}
- initial_reordering_syllable (plan, buffer, last, count);
+ initial_reordering_syllable (plan, font->face, buffer, last, count);
}
static void
@@ -1224,7 +1262,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
static void
final_reordering (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
+ hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
@@ -1251,11 +1289,113 @@ final_reordering (const hb_ot_shape_plan_t *plan,
static hb_ot_shape_normalization_mode_t
-normalization_preference_indic (const hb_ot_shape_plan_t *plan)
+normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
{
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
}
+static bool
+decompose_indic (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b)
+{
+ switch (ab)
+ {
+ /* Don't decompose these. */
+ case 0x0931 : return false;
+ case 0x0B94 : return false;
+
+
+ /*
+ * Decompose split matras that don't have Unicode decompositions.
+ */
+
+ case 0x0F77 : *a = 0x0FB2; *b= 0x0F81; return true;
+ case 0x0F79 : *a = 0x0FB3; *b= 0x0F81; return true;
+ case 0x17BE : *a = 0x17C1; *b= 0x17BE; return true;
+ case 0x17BF : *a = 0x17C1; *b= 0x17BF; return true;
+ case 0x17C0 : *a = 0x17C1; *b= 0x17C0; return true;
+ case 0x17C4 : *a = 0x17C1; *b= 0x17C4; return true;
+ case 0x17C5 : *a = 0x17C1; *b= 0x17C5; return true;
+ case 0x1925 : *a = 0x1920; *b= 0x1923; return true;
+ case 0x1926 : *a = 0x1920; *b= 0x1924; return true;
+ case 0x1B3C : *a = 0x1B42; *b= 0x1B3C; return true;
+ case 0x1112E : *a = 0x11127; *b= 0x11131; return true;
+ case 0x1112F : *a = 0x11127; *b= 0x11132; return true;
+#if 0
+ /* This one has no decomposition in Unicode, but needs no decomposition either. */
+ /* case 0x0AC9 : return false; */
+ case 0x0B57 : *a = no decomp, -> RIGHT; return true;
+ case 0x1C29 : *a = no decomp, -> LEFT; return true;
+ case 0xA9C0 : *a = no decomp, -> RIGHT; return true;
+ case 0x111BF : *a = no decomp, -> ABOVE; return true;
+#endif
+ }
+
+ if ((ab == 0x0DDA || hb_in_range<hb_codepoint_t> (ab, 0x0DDC, 0x0DDE)))
+ {
+ /*
+ * Sinhala split matras... Let the fun begin.
+ *
+ * These four characters have Unicode decompositions. However, Uniscribe
+ * decomposes them "Khmer-style", that is, it uses the character itself to
+ * get the second half. The first half of all four decompositions is always
+ * U+0DD9.
+ *
+ * Now, there are buggy fonts, namely, the widely used lklug.ttf, that are
+ * broken with Uniscribe. But we need to support them. As such, we only
+ * do the Uniscribe-style decomposition if the character is transformed into
+ * its "sec.half" form by the 'pstf' feature. Otherwise, we fall back to
+ * Unicode decomposition.
+ *
+ * Note that we can't unconditionally use Unicode decomposition. That would
+ * break some other fonts, that are designed to work with Uniscribe, and
+ * don't have positioning features for the Unicode-style decomposition.
+ *
+ * Argh...
+ *
+ * The Uniscribe behavior is now documented in the newly published Sinhala
+ * spec in 2012:
+ *
+ * http://www.microsoft.com/typography/OpenTypeDev/sinhala/intro.htm#shaping
+ */
+
+ const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
+
+ hb_codepoint_t glyph;
+
+ if (indic_options ().uniscribe_bug_compatible ||
+ (c->font->get_glyph (ab, 0, &glyph) &&
+ indic_plan->pstf.would_substitute (&glyph, 1, true, c->font->face)))
+ {
+ /* Ok, safe to use Uniscribe-style decomposition. */
+ *a = 0x0DD9;
+ *b = ab;
+ return true;
+ }
+ }
+
+ return c->unicode->decompose (ab, a, b);
+}
+
+static bool
+compose_indic (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;
+
+ /* Composition-exclusion exceptions that we want to recompose. */
+ if (a == 0x09AF && b == 0x09BC) { *ab = 0x09DF; return true; }
+
+ return c->unicode->compose (a, b, ab);
+}
+
+
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
{
"indic",
@@ -1265,6 +1405,9 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
data_destroy_indic,
NULL, /* preprocess_text */
normalization_preference_indic,
+ decompose_indic,
+ compose_indic,
setup_masks_indic,
false, /* zero_width_attached_marks */
+ false, /* fallback_position */
};
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-misc.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-misc.cc
deleted file mode 100644
index 13bc22b..0000000
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-misc.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright © 2010,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-private.hh"
-
-
-/* TODO Add kana, and other small shapers here */
-
-
-/* The default shaper *only* adds additional per-script features.*/
-
-static const hb_tag_t hangul_features[] =
-{
- HB_TAG('l','j','m','o'),
- HB_TAG('v','j','m','o'),
- HB_TAG('t','j','m','o'),
- HB_TAG_NONE
-};
-
-static const hb_tag_t tibetan_features[] =
-{
- HB_TAG('a','b','v','s'),
- HB_TAG('b','l','w','s'),
- HB_TAG('a','b','v','m'),
- HB_TAG('b','l','w','m'),
- HB_TAG_NONE
-};
-
-static void
-collect_features_default (hb_ot_shape_planner_t *plan)
-{
- const hb_tag_t *script_features = NULL;
-
- switch ((hb_tag_t) plan->props.script)
- {
- /* Unicode-1.1 additions */
- case HB_SCRIPT_HANGUL:
- script_features = hangul_features;
- break;
-
- /* Unicode-2.0 additions */
- case HB_SCRIPT_TIBETAN:
- script_features = tibetan_features;
- break;
- }
-
- for (; script_features && *script_features; script_features++)
- plan->map.add_bool_feature (*script_features);
-}
-
-static hb_ot_shape_normalization_mode_t
-normalization_preference_default (const hb_ot_shape_plan_t *plan)
-{
- switch ((hb_tag_t) plan->props.script)
- {
- /* Unicode-1.1 additions */
- case HB_SCRIPT_HANGUL:
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL;
- }
- return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
-}
-
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
-{
- "default",
- collect_features_default,
- NULL, /* override_features */
- NULL, /* data_create */
- NULL, /* data_destroy */
- NULL, /* preprocess_text */
- normalization_preference_default,
- NULL, /* setup_masks */
- true, /* zero_width_attached_marks */
-};
-
-
-/* Thai / Lao shaper */
-
-static void
-preprocess_text_thai (const hb_ot_shape_plan_t *plan HB_UNUSED,
- hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
-{
- /* The following is NOT specified in the MS OT Thai spec, however, it seems
- * to be what Uniscribe and other engines implement. According to Eric Muller:
- *
- * When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
- * NIKHAHIT backwards over any tone mark (0E48-0E4B).
- *
- * <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32>
- *
- * This reordering is legit only when the NIKHAHIT comes from a SARA AM, not
- * when it's there to start with. The string <0E14, 0E4B, 0E4D> is probably
- * not what a user wanted, but the rendering is nevertheless nikhahit above
- * chattawa.
- *
- * Same for Lao.
- *
- * Note:
- *
- * Uniscribe also does so below-marks reordering. Namely, it positions U+0E3A
- * after U+0E38 and U+0E39. We do that by modifying the ccc for U+0E3A.
- * See unicode->modified_combining_class (). Lao does NOT have a U+0E3A
- * equivalent.
- */
-
-
- /*
- * Here are the characters of significance:
- *
- * Thai Lao
- * SARA AM: U+0E33 U+0EB3
- * SARA AA: U+0E32 U+0EB2
- * Nikhahit: U+0E4D U+0ECD
- *
- * Testing shows that Uniscribe reorder the following marks:
- * Thai: <0E31,0E34..0E37,0E47..0E4E>
- * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE>
- *
- * Note how the Lao versions are the same as Thai + 0x80.
- */
-
- /* We only get one script at a time, so a script-agnostic implementation
- * is adequate here. */
-#define IS_SARA_AM(x) (((x) & ~0x0080) == 0x0E33)
-#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0xE33 + 0xE4D)
-#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
-#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080, 0x0E34, 0x0E37, 0x0E47, 0x0E4E, 0x0E31, 0x0E31))
-
- buffer->clear_output ();
- unsigned int count = buffer->len;
- for (buffer->idx = 0; buffer->idx < count;)
- {
- hb_codepoint_t u = buffer->cur().codepoint;
- if (likely (!IS_SARA_AM (u))) {
- buffer->next_glyph ();
- continue;
- }
-
- /* Is SARA AM. Decompose and reorder. */
- hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
- hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
- buffer->replace_glyphs (1, 2, decomposed);
- if (unlikely (buffer->in_error))
- return;
-
- /* Ok, let's see... */
- unsigned int end = buffer->out_len;
- unsigned int start = end - 2;
- while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint))
- start--;
-
- if (start + 2 < end)
- {
- /* Move Nikhahit (end-2) to the beginning */
- buffer->merge_out_clusters (start, end);
- hb_glyph_info_t t = buffer->out_info[end - 2];
- memmove (buffer->out_info + start + 1,
- buffer->out_info + start,
- sizeof (buffer->out_info[0]) * (end - start - 2));
- buffer->out_info[start] = t;
- }
- else
- {
- /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the
- * previous cluster. */
- if (start)
- buffer->merge_out_clusters (start - 1, end);
- }
- }
- buffer->swap_buffers ();
-}
-
-const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
-{
- "thai",
- NULL, /* collect_features */
- NULL, /* override_features */
- NULL, /* data_create */
- NULL, /* data_destroy */
- preprocess_text_thai,
- NULL, /* normalization_preference */
- NULL, /* setup_masks */
- true, /* zero_width_attached_marks */
-};
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
index e84c490..26871c2 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
@@ -56,6 +56,7 @@ struct hb_ot_complex_shaper_t
/* collect_features()
* Called during shape_plan().
* Shapers should use plan->map to add their features and callbacks.
+ * May be NULL.
*/
void (*collect_features) (hb_ot_shape_planner_t *plan);
@@ -63,6 +64,7 @@ struct hb_ot_complex_shaper_t
* Called during shape_plan().
* Shapers should use plan->map to override features and add callbacks after
* common features are added.
+ * May be NULL.
*/
void (*override_features) (hb_ot_shape_planner_t *plan);
@@ -78,13 +80,15 @@ struct hb_ot_complex_shaper_t
* Called when the shape_plan is being destroyed.
* plan->data is passed here for destruction.
* If NULL is returned, means a plan failure.
- * May be NULL. */
+ * May be NULL.
+ */
void (*data_destroy) (void *data);
/* preprocess_text()
* Called during shape().
* Shapers can use to modify text before shaping starts.
+ * May be NULL.
*/
void (*preprocess_text) (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
@@ -93,20 +97,41 @@ struct hb_ot_complex_shaper_t
/* normalization_preference()
* Called during shape().
+ * May be NULL.
*/
hb_ot_shape_normalization_mode_t
- (*normalization_preference) (const hb_ot_shape_plan_t *plan);
+ (*normalization_preference) (const hb_segment_properties_t *props);
+
+ /* decompose()
+ * Called during shape()'s normalization.
+ * May be NULL.
+ */
+ bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b);
+
+ /* compose()
+ * Called during shape()'s normalization.
+ * May be NULL.
+ */
+ bool (*compose) (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab);
/* setup_masks()
* Called during shape().
* Shapers should use map to get feature masks and set on buffer.
* Shapers may NOT modify characters.
+ * May be NULL.
*/
void (*setup_masks) (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
hb_font_t *font);
bool zero_width_attached_marks;
+ bool fallback_position;
};
#define HB_COMPLEX_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_complex_shaper_t _hb_ot_complex_shaper_##name;
@@ -115,9 +140,9 @@ HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS
static inline const hb_ot_complex_shaper_t *
-hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
+hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
{
- switch ((hb_tag_t) props->script)
+ switch ((hb_tag_t) planner->props.script)
{
default:
return &_hb_ot_complex_shaper_default;
@@ -130,11 +155,18 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
/* Unicode-5.0 additions */
case HB_SCRIPT_NKO:
+ case HB_SCRIPT_PHAGS_PA:
/* Unicode-6.0 additions */
case HB_SCRIPT_MANDAIC:
- return &_hb_ot_complex_shaper_arabic;
+ /* For Arabic script, use the Arabic shaper even if no OT script tag was found.
+ * This is because we do fallback shaping for Arabic script (and not others). */
+ if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
+ planner->props.script == HB_SCRIPT_ARABIC)
+ return &_hb_ot_complex_shaper_arabic;
+ else
+ return &_hb_ot_complex_shaper_default;
/* Unicode-1.1 additions */
@@ -170,9 +202,6 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
/* Unicode-5.1 additions */
case HB_SCRIPT_SAURASHTRA:
- /* Unicode-5.2 additions */
- case HB_SCRIPT_MEETEI_MAYEK:
-
/* Unicode-6.0 additions */
case HB_SCRIPT_BATAK:
case HB_SCRIPT_BRAHMI:
@@ -197,11 +226,9 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
case HB_SCRIPT_TAI_LE:
/* Unicode-4.1 additions */
+ case HB_SCRIPT_KHAROSHTHI:
case HB_SCRIPT_SYLOTI_NAGRI:
- /* Unicode-5.0 additions */
- case HB_SCRIPT_PHAGS_PA:
-
/* Unicode-5.1 additions */
case HB_SCRIPT_KAYAH_LI:
@@ -209,12 +236,6 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
case HB_SCRIPT_TAI_VIET:
- /* May need Indic treatment in the future? */
-
- /* Unicode-3.0 additions */
- case HB_SCRIPT_MYANMAR:
-
-
#endif
/* Unicode-1.1 additions */
@@ -229,12 +250,10 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
case HB_SCRIPT_TELUGU:
/* Unicode-3.0 additions */
- case HB_SCRIPT_KHMER:
case HB_SCRIPT_SINHALA:
/* Unicode-4.1 additions */
case HB_SCRIPT_BUGINESE:
- case HB_SCRIPT_KHAROSHTHI:
case HB_SCRIPT_NEW_TAI_LUE:
/* Unicode-5.0 additions */
@@ -249,14 +268,44 @@ hb_ot_shape_complex_categorize (const hb_segment_properties_t *props)
/* Unicode-5.2 additions */
case HB_SCRIPT_JAVANESE:
case HB_SCRIPT_KAITHI:
+ case HB_SCRIPT_MEETEI_MAYEK:
case HB_SCRIPT_TAI_THAM:
+
/* Unicode-6.1 additions */
case HB_SCRIPT_CHAKMA:
case HB_SCRIPT_SHARADA:
case HB_SCRIPT_TAKRI:
- return &_hb_ot_complex_shaper_indic;
+ /* Only use Indic shaper if the font has Indic tables. */
+ if (planner->map.found_script[0])
+ return &_hb_ot_complex_shaper_indic;
+ else
+ return &_hb_ot_complex_shaper_default;
+
+ case HB_SCRIPT_KHMER:
+ /* A number of Khmer fonts in the wild don't have a 'pref' feature,
+ * and as such won't shape properly via the Indic shaper;
+ * however, they typically have 'liga' / 'clig' features that implement
+ * the necessary "reordering" by means of ligature substitutions.
+ * So we send such pref-less fonts through the generic shaper instead. */
+ if (planner->map.found_script[0] &&
+ hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
+ planner->map.script_index[0],
+ planner->map.language_index[0],
+ HB_TAG ('p','r','e','f'),
+ NULL))
+ return &_hb_ot_complex_shaper_indic;
+ else
+ return &_hb_ot_complex_shaper_default;
+
+ case HB_SCRIPT_MYANMAR:
+ /* For Myanmar, we only want to use the Indic shaper if the "new" script
+ * tag is found. For "old" script tag we want to use the default shaper. */
+ if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
+ return &_hb_ot_complex_shaper_indic;
+ else
+ return &_hb_ot_complex_shaper_default;
}
}
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
new file mode 100644
index 0000000..24d476a
--- /dev/null
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc
@@ -0,0 +1,378 @@
+/*
+ * Copyright © 2010,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-private.hh"
+
+
+/* Thai / Lao shaper */
+
+
+/* PUA shaping */
+
+
+enum thai_consonant_type_t
+{
+ NC,
+ AC,
+ RC,
+ DC,
+ NOT_CONSONANT,
+ NUM_CONSONANT_TYPES = NOT_CONSONANT
+};
+
+static thai_consonant_type_t
+get_consonant_type (hb_codepoint_t u)
+{
+ if (u == 0x0E1B || u == 0x0E1D || u == 0x0E1F/* || u == 0x0E2C*/)
+ return AC;
+ if (u == 0x0E0D || u == 0x0E10)
+ return RC;
+ if (u == 0x0E0E || u == 0x0E0F)
+ return DC;
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E01, 0x0E2E))
+ return NC;
+ return NOT_CONSONANT;
+}
+
+
+enum thai_mark_type_t
+{
+ AV,
+ BV,
+ T,
+ NOT_MARK,
+ NUM_MARK_TYPES = NOT_MARK
+};
+
+static thai_mark_type_t
+get_mark_type (hb_codepoint_t u)
+{
+ if (u == 0x0E31 || hb_in_range<hb_codepoint_t> (u, 0x0E34, 0x0E37) ||
+ u == 0x0E47 || hb_in_range<hb_codepoint_t> (u, 0x0E4D, 0x0E4E))
+ return AV;
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E38, 0x0E3A))
+ return BV;
+ if (hb_in_range<hb_codepoint_t> (u, 0x0E48, 0x0E4C))
+ return T;
+ return NOT_MARK;
+}
+
+
+enum thai_action_t
+{
+ NOP,
+ SD, /* Shift combining-mark down */
+ SL, /* Shift combining-mark left */
+ SDL, /* Shift combining-mark down-left */
+ RD /* Remove descender from base */
+};
+
+static hb_codepoint_t
+thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font)
+{
+ struct thai_pua_mapping_t {
+ hb_codepoint_t u;
+ hb_codepoint_t win_pua;
+ hb_codepoint_t mac_pua;
+ } const *pua_mappings = NULL;
+ static const thai_pua_mapping_t SD_mappings[] = {
+ {0x0E48, 0xF70A, 0xF88B}, /* MAI EK */
+ {0x0E49, 0xF70B, 0xF88E}, /* MAI THO */
+ {0x0E4A, 0xF70C, 0xF891}, /* MAI TRI */
+ {0x0E4B, 0xF70D, 0xF894}, /* MAI CHATTAWA */
+ {0x0E4C, 0xF70E, 0xF897}, /* THANTHAKHAT */
+ {0x0E38, 0xF718, 0xF89B}, /* SARA U */
+ {0x0E39, 0xF719, 0xF89C}, /* SARA UU */
+ {0x0E3A, 0xF71A, 0xF89D}, /* PHINTHU */
+ {0x0000, 0x0000, 0x0000}
+ };
+ static const thai_pua_mapping_t SDL_mappings[] = {
+ {0x0E48, 0xF705, 0xF88C}, /* MAI EK */
+ {0x0E49, 0xF706, 0xF88F}, /* MAI THO */
+ {0x0E4A, 0xF707, 0xF892}, /* MAI TRI */
+ {0x0E4B, 0xF708, 0xF895}, /* MAI CHATTAWA */
+ {0x0E4C, 0xF709, 0xF898}, /* THANTHAKHAT */
+ {0x0000, 0x0000, 0x0000}
+ };
+ static const thai_pua_mapping_t SL_mappings[] = {
+ {0x0E48, 0xF713, 0xF88A}, /* MAI EK */
+ {0x0E49, 0xF714, 0xF88D}, /* MAI THO */
+ {0x0E4A, 0xF715, 0xF890}, /* MAI TRI */
+ {0x0E4B, 0xF716, 0xF893}, /* MAI CHATTAWA */
+ {0x0E4C, 0xF717, 0xF896}, /* THANTHAKHAT */
+ {0x0E31, 0xF710, 0xF884}, /* MAI HAN-AKAT */
+ {0x0E34, 0xF701, 0xF885}, /* SARA I */
+ {0x0E35, 0xF702, 0xF886}, /* SARA II */
+ {0x0E36, 0xF703, 0xF887}, /* SARA UE */
+ {0x0E37, 0xF704, 0xF888}, /* SARA UEE */
+ {0x0E47, 0xF712, 0xF889}, /* MAITAIKHU */
+ {0x0E4D, 0xF711, 0xF899}, /* NIKHAHIT */
+ {0x0000, 0x0000, 0x0000}
+ };
+ static const thai_pua_mapping_t RD_mappings[] = {
+ {0x0E0D, 0xF70F, 0xF89A}, /* YO YING */
+ {0x0E10, 0xF700, 0xF89E}, /* THO THAN */
+ {0x0000, 0x0000, 0x0000}
+ };
+
+ switch (action) {
+ default: assert (false); /* Fallthrough */
+ case NOP: return u;
+ case SD: pua_mappings = SD_mappings; break;
+ case SDL: pua_mappings = SDL_mappings; break;
+ case SL: pua_mappings = SL_mappings; break;
+ case RD: pua_mappings = RD_mappings; break;
+ }
+ for (; pua_mappings->u; pua_mappings++)
+ if (pua_mappings->u == u)
+ {
+ hb_codepoint_t glyph;
+ if (hb_font_get_glyph (font, pua_mappings->win_pua, 0, &glyph))
+ return pua_mappings->win_pua;
+ if (hb_font_get_glyph (font, pua_mappings->mac_pua, 0, &glyph))
+ return pua_mappings->mac_pua;
+ break;
+ }
+ return u;
+}
+
+
+static enum thai_above_state_t
+{ /* Cluster above looks like: */
+ T0, /* ⣤ */
+ T1, /* ⣼ */
+ T2, /* ⣾ */
+ T3, /* ⣿ */
+ NUM_ABOVE_STATES
+} thai_above_start_state[NUM_CONSONANT_TYPES + 1/* For NOT_CONSONANT */] =
+{
+ T0, /* NC */
+ T1, /* AC */
+ T0, /* RC */
+ T0, /* DC */
+ T3, /* NOT_CONSONANT */
+};
+
+static const struct thai_above_state_machine_edge_t {
+ thai_action_t action;
+ thai_above_state_t next_state;
+} thai_above_state_machine[NUM_ABOVE_STATES][NUM_MARK_TYPES] =
+{ /*AV*/ /*BV*/ /*T*/
+/*T0*/ {{NOP,T3}, {NOP,T0}, {SD, T3}},
+/*T1*/ {{SL, T2}, {NOP,T1}, {SDL,T2}},
+/*T2*/ {{NOP,T3}, {NOP,T2}, {SL, T3}},
+/*T3*/ {{NOP,T3}, {NOP,T3}, {NOP,T3}},
+};
+
+
+static enum thai_below_state_t
+{
+ B0, /* No descender */
+ B1, /* Removable descender */
+ B2, /* Strict descender */
+ NUM_BELOW_STATES
+} thai_below_start_state[NUM_CONSONANT_TYPES + 1/* For NOT_CONSONANT */] =
+{
+ B0, /* NC */
+ B0, /* AC */
+ B1, /* RC */
+ B2, /* DC */
+ B2, /* NOT_CONSONANT */
+};
+
+static const struct thai_below_state_machine_edge_t {
+ thai_action_t action;
+ thai_below_state_t next_state;
+} thai_below_state_machine[NUM_BELOW_STATES][NUM_MARK_TYPES] =
+{ /*AV*/ /*BV*/ /*T*/
+/*B0*/ {{NOP,B0}, {NOP,B2}, {NOP, B0}},
+/*B1*/ {{NOP,B1}, {RD, B2}, {NOP, B1}},
+/*B2*/ {{NOP,B2}, {SD, B2}, {NOP, B2}},
+};
+
+
+static void
+do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
+{
+ thai_above_state_t above_state = thai_above_start_state[NOT_CONSONANT];
+ thai_below_state_t below_state = thai_below_start_state[NOT_CONSONANT];
+ unsigned int base = 0;
+
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ thai_mark_type_t mt = get_mark_type (info[i].codepoint);
+
+ if (mt == NOT_MARK) {
+ thai_consonant_type_t ct = get_consonant_type (info[i].codepoint);
+ above_state = thai_above_start_state[ct];
+ below_state = thai_below_start_state[ct];
+ base = i;
+ continue;
+ }
+
+ const thai_above_state_machine_edge_t &above_edge = thai_above_state_machine[above_state][mt];
+ const thai_below_state_machine_edge_t &below_edge = thai_below_state_machine[below_state][mt];
+ above_state = above_edge.next_state;
+ below_state = below_edge.next_state;
+
+ /* At least one of the above/below actions is NOP. */
+ thai_action_t action = above_edge.action != NOP ? above_edge.action : below_edge.action;
+
+ if (action == RD)
+ info[base].codepoint = thai_pua_shape (info[base].codepoint, action, font);
+ else
+ info[i].codepoint = thai_pua_shape (info[i].codepoint, action, font);
+ }
+}
+
+
+static void
+preprocess_text_thai (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
+{
+ /* This function implements the shaping logic documented here:
+ *
+ * http://linux.thai.net/~thep/th-otf/shaping.html
+ *
+ * The first shaping rule listed there is needed even if the font has Thai
+ * OpenType tables. The rest do fallback positioning based on PUA codepoints.
+ * We implement that only if there exist no Thai GSUB in the font.
+ */
+
+ /* The following is NOT specified in the MS OT Thai spec, however, it seems
+ * to be what Uniscribe and other engines implement. According to Eric Muller:
+ *
+ * When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
+ * NIKHAHIT backwards over any tone mark (0E48-0E4B).
+ *
+ * <0E14, 0E4B, 0E33> -> <0E14, 0E4D, 0E4B, 0E32>
+ *
+ * This reordering is legit only when the NIKHAHIT comes from a SARA AM, not
+ * when it's there to start with. The string <0E14, 0E4B, 0E4D> is probably
+ * not what a user wanted, but the rendering is nevertheless nikhahit above
+ * chattawa.
+ *
+ * Same for Lao.
+ *
+ * Note:
+ *
+ * Uniscribe also does some below-marks reordering. Namely, it positions U+0E3A
+ * after U+0E38 and U+0E39. We do that by modifying the ccc for U+0E3A.
+ * See unicode->modified_combining_class (). Lao does NOT have a U+0E3A
+ * equivalent.
+ */
+
+
+ /*
+ * Here are the characters of significance:
+ *
+ * Thai Lao
+ * SARA AM: U+0E33 U+0EB3
+ * SARA AA: U+0E32 U+0EB2
+ * Nikhahit: U+0E4D U+0ECD
+ *
+ * Testing shows that Uniscribe reorder the following marks:
+ * Thai: <0E31,0E34..0E37,0E47..0E4E>
+ * Lao: <0EB1,0EB4..0EB7,0EC7..0ECE>
+ *
+ * Note how the Lao versions are the same as Thai + 0x80.
+ */
+
+ /* We only get one script at a time, so a script-agnostic implementation
+ * is adequate here. */
+#define IS_SARA_AM(x) (((x) & ~0x0080) == 0x0E33)
+#define NIKHAHIT_FROM_SARA_AM(x) ((x) - 0xE33 + 0xE4D)
+#define SARA_AA_FROM_SARA_AM(x) ((x) - 1)
+#define IS_TONE_MARK(x) (hb_in_ranges<hb_codepoint_t> ((x) & ~0x0080, 0x0E34, 0x0E37, 0x0E47, 0x0E4E, 0x0E31, 0x0E31))
+
+ buffer->clear_output ();
+ unsigned int count = buffer->len;
+ for (buffer->idx = 0; buffer->idx < count;)
+ {
+ hb_codepoint_t u = buffer->cur().codepoint;
+ if (likely (!IS_SARA_AM (u))) {
+ buffer->next_glyph ();
+ continue;
+ }
+
+ /* Is SARA AM. Decompose and reorder. */
+ hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
+ hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
+ buffer->replace_glyphs (1, 2, decomposed);
+ if (unlikely (buffer->in_error))
+ return;
+
+ /* Ok, let's see... */
+ unsigned int end = buffer->out_len;
+ unsigned int start = end - 2;
+ while (start > 0 && IS_TONE_MARK (buffer->out_info[start - 1].codepoint))
+ start--;
+
+ if (start + 2 < end)
+ {
+ /* Move Nikhahit (end-2) to the beginning */
+ buffer->merge_out_clusters (start, end);
+ hb_glyph_info_t t = buffer->out_info[end - 2];
+ memmove (buffer->out_info + start + 1,
+ buffer->out_info + start,
+ sizeof (buffer->out_info[0]) * (end - start - 2));
+ buffer->out_info[start] = t;
+ }
+ else
+ {
+ /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the
+ * previous cluster. */
+ if (start)
+ buffer->merge_out_clusters (start - 1, end);
+ }
+ }
+ buffer->swap_buffers ();
+
+ /* If font has Thai GSUB, we are done. */
+ if (plan->props.script == HB_SCRIPT_THAI && !plan->map.found_script[0])
+ do_thai_pua_shaping (plan, buffer, font);
+}
+
+const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
+{
+ "thai",
+ NULL, /* collect_features */
+ NULL, /* override_features */
+ NULL, /* data_create */
+ NULL, /* data_destroy */
+ preprocess_text_thai,
+ NULL, /* normalization_preference */
+ NULL, /* decompose */
+ NULL, /* compose */
+ NULL, /* setup_masks */
+ true, /* zero_width_attached_marks */
+ false,/* fallback_position */
+};
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc
index eb7777e..6f3426e 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-fallback.cc
@@ -138,10 +138,10 @@ recategorize_combining_class (hb_codepoint_t u,
/* Lao */
case HB_MODIFIED_COMBINING_CLASS_CCC118: /* sign u / sign uu */
- return HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT;
+ return HB_UNICODE_COMBINING_CLASS_BELOW;
case HB_MODIFIED_COMBINING_CLASS_CCC122: /* mai */
- return HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
+ return HB_UNICODE_COMBINING_CLASS_ABOVE;
/* Tibetan */
@@ -161,8 +161,8 @@ recategorize_combining_class (hb_codepoint_t u,
}
void
-_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
- hb_font_t *font,
+_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
@@ -311,7 +311,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
hb_glyph_extents_t component_extents = base_extents;
unsigned int last_lig_component = (unsigned int) -1;
unsigned int last_combining_class = 255;
- hb_glyph_extents_t cluster_extents;
+ hb_glyph_extents_t cluster_extents = base_extents; /* Initialization is just to shut gcc up. */
for (unsigned int i = base + 1; i < end; i++)
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
{
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
index c5fcbea..8112f03 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
@@ -35,6 +35,8 @@
/* buffer var allocations, used during the normalization process */
#define glyph_index() var1.u32
+struct hb_ot_shape_plan_t;
+
enum hb_ot_shape_normalization_mode_t {
HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED,
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* never composes base-to-base */
@@ -44,8 +46,26 @@ enum hb_ot_shape_normalization_mode_t {
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS
};
-HB_INTERNAL void _hb_ot_shape_normalize (hb_font_t *font,
+HB_INTERNAL void _hb_ot_shape_normalize (const hb_ot_shape_plan_t *shaper,
hb_buffer_t *buffer,
- hb_ot_shape_normalization_mode_t mode);
+ hb_font_t *font);
+
+
+struct hb_ot_shape_normalize_context_t
+{
+ const hb_ot_shape_plan_t *plan;
+ hb_buffer_t *buffer;
+ hb_font_t *font;
+ hb_unicode_funcs_t *unicode;
+ bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b);
+ bool (*compose) (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab);
+};
+
#endif /* HB_OT_SHAPE_NORMALIZE_PRIVATE_HH */
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc
index 18a3f3f..c5325e4 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -25,6 +25,7 @@
*/
#include "hb-ot-shape-normalize-private.hh"
+#include "hb-ot-shape-complex-private.hh"
#include "hb-ot-shape-private.hh"
@@ -81,181 +82,24 @@
* egrep "`echo -n ';('; grep ';<' UnicodeData.txt | cut -d';' -f1 | tr '\n' '|'; echo ') '`" UnicodeData.txt
*/
-static hb_bool_t
-decompose_func (hb_unicode_funcs_t *unicode,
- hb_codepoint_t ab,
- hb_codepoint_t *a,
- hb_codepoint_t *b)
+static bool
+decompose_unicode (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t ab,
+ hb_codepoint_t *a,
+ hb_codepoint_t *b)
{
- /* XXX FIXME, move these to complex shapers and propagage to normalizer.*/
- switch (ab) {
- case 0x0AC9 : return false;
-
- case 0x0931 : return false;
- case 0x0B94 : return false;
-
- /* These ones have Unicode decompositions, but we do it
- * this way to be close to what Uniscribe does. */
- case 0x0DDA : *a = 0x0DD9; *b= 0x0DDA; return true;
- case 0x0DDC : *a = 0x0DD9; *b= 0x0DDC; return true;
- case 0x0DDD : *a = 0x0DD9; *b= 0x0DDD; return true;
- case 0x0DDE : *a = 0x0DD9; *b= 0x0DDE; return true;
-
- case 0x0F77 : *a = 0x0FB2; *b= 0x0F81; return true;
- case 0x0F79 : *a = 0x0FB3; *b= 0x0F81; return true;
- case 0x17BE : *a = 0x17C1; *b= 0x17BE; return true;
- case 0x17BF : *a = 0x17C1; *b= 0x17BF; return true;
- case 0x17C0 : *a = 0x17C1; *b= 0x17C0; return true;
- case 0x17C4 : *a = 0x17C1; *b= 0x17C4; return true;
- case 0x17C5 : *a = 0x17C1; *b= 0x17C5; return true;
- case 0x1925 : *a = 0x1920; *b= 0x1923; return true;
- case 0x1926 : *a = 0x1920; *b= 0x1924; return true;
- case 0x1B3C : *a = 0x1B42; *b= 0x1B3C; return true;
- case 0x1112E : *a = 0x11127; *b= 0x11131; return true;
- case 0x1112F : *a = 0x11127; *b= 0x11132; return true;
-#if 0
- case 0x0B57 : *a = 0xno decomp, -> RIGHT; return true;
- case 0x1C29 : *a = 0xno decomp, -> LEFT; return true;
- case 0xA9C0 : *a = 0xno decomp, -> RIGHT; return true;
- case 0x111BF : *a = 0xno decomp, -> ABOVE; return true;
-#endif
- }
- return unicode->decompose (ab, a, b);
+ return c->unicode->decompose (ab, a, b);
}
-static hb_bool_t
-compose_func (hb_unicode_funcs_t *unicode,
- hb_codepoint_t a,
- hb_codepoint_t b,
- hb_codepoint_t *ab)
+static bool
+compose_unicode (const hb_ot_shape_normalize_context_t *c,
+ hb_codepoint_t a,
+ hb_codepoint_t b,
+ hb_codepoint_t *ab)
{
- /* XXX, this belongs to indic normalizer. */
- if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (unicode->general_category (a)))
- return false;
- /* XXX, add composition-exclusion exceptions to Indic shaper. */
- if (a == 0x09AF && b == 0x09BC) { *ab = 0x09DF; return true; }
-
- /* XXX, these belong to the hebew / default shaper. */
- /* Hebrew presentation-form shaping.
- * https://bugzilla.mozilla.org/show_bug.cgi?id=728866 */
- // Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA;
- // note that some letters do not have a dagesh presForm encoded
- static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = {
- 0xFB30, // ALEF
- 0xFB31, // BET
- 0xFB32, // GIMEL
- 0xFB33, // DALET
- 0xFB34, // HE
- 0xFB35, // VAV
- 0xFB36, // ZAYIN
- 0, // HET
- 0xFB38, // TET
- 0xFB39, // YOD
- 0xFB3A, // FINAL KAF
- 0xFB3B, // KAF
- 0xFB3C, // LAMED
- 0, // FINAL MEM
- 0xFB3E, // MEM
- 0, // FINAL NUN
- 0xFB40, // NUN
- 0xFB41, // SAMEKH
- 0, // AYIN
- 0xFB43, // FINAL PE
- 0xFB44, // PE
- 0, // FINAL TSADI
- 0xFB46, // TSADI
- 0xFB47, // QOF
- 0xFB48, // RESH
- 0xFB49, // SHIN
- 0xFB4A // TAV
- };
-
- hb_bool_t found = unicode->compose (a, b, ab);
-
- if (!found && (b & ~0x7F) == 0x0580) {
- // special-case Hebrew presentation forms that are excluded from
- // standard normalization, but wanted for old fonts
- switch (b) {
- case 0x05B4: // HIRIQ
- if (a == 0x05D9) { // YOD
- *ab = 0xFB1D;
- found = true;
- }
- break;
- case 0x05B7: // patah
- if (a == 0x05F2) { // YIDDISH YOD YOD
- *ab = 0xFB1F;
- found = true;
- } else if (a == 0x05D0) { // ALEF
- *ab = 0xFB2E;
- found = true;
- }
- break;
- case 0x05B8: // QAMATS
- if (a == 0x05D0) { // ALEF
- *ab = 0xFB2F;
- found = true;
- }
- break;
- case 0x05B9: // HOLAM
- if (a == 0x05D5) { // VAV
- *ab = 0xFB4B;
- found = true;
- }
- break;
- case 0x05BC: // DAGESH
- if (a >= 0x05D0 && a <= 0x05EA) {
- *ab = sDageshForms[a - 0x05D0];
- found = (*ab != 0);
- } else if (a == 0xFB2A) { // SHIN WITH SHIN DOT
- *ab = 0xFB2C;
- found = true;
- } else if (a == 0xFB2B) { // SHIN WITH SIN DOT
- *ab = 0xFB2D;
- found = true;
- }
- break;
- case 0x05BF: // RAFE
- switch (a) {
- case 0x05D1: // BET
- *ab = 0xFB4C;
- found = true;
- break;
- case 0x05DB: // KAF
- *ab = 0xFB4D;
- found = true;
- break;
- case 0x05E4: // PE
- *ab = 0xFB4E;
- found = true;
- break;
- }
- break;
- case 0x05C1: // SHIN DOT
- if (a == 0x05E9) { // SHIN
- *ab = 0xFB2A;
- found = true;
- } else if (a == 0xFB49) { // SHIN WITH DAGESH
- *ab = 0xFB2C;
- found = true;
- }
- break;
- case 0x05C2: // SIN DOT
- if (a == 0x05E9) { // SHIN
- *ab = 0xFB2B;
- found = true;
- } else if (a == 0xFB49) { // SHIN WITH DAGESH
- *ab = 0xFB2D;
- found = true;
- }
- break;
- }
- }
-
- return found;
+ return c->unicode->compose (a, b, ab);
}
-
static inline void
set_glyph (hb_glyph_info_t &info, hb_font_t *font)
{
@@ -285,38 +129,38 @@ skip_char (hb_buffer_t *buffer)
/* Returns 0 if didn't decompose, number of resulting characters otherwise. */
static inline unsigned int
-decompose (hb_font_t *font, hb_buffer_t *buffer, bool shortest, hb_codepoint_t ab)
+decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
{
hb_codepoint_t a, b, a_glyph, b_glyph;
- if (!decompose_func (buffer->unicode, ab, &a, &b) ||
- (b && !font->get_glyph (b, 0, &b_glyph)))
+ if (!c->decompose (c, ab, &a, &b) ||
+ (b && !c->font->get_glyph (b, 0, &b_glyph)))
return 0;
- bool has_a = font->get_glyph (a, 0, &a_glyph);
+ bool has_a = c->font->get_glyph (a, 0, &a_glyph);
if (shortest && has_a) {
/* Output a and b */
- output_char (buffer, a, a_glyph);
+ output_char (c->buffer, a, a_glyph);
if (likely (b)) {
- output_char (buffer, b, b_glyph);
+ output_char (c->buffer, b, b_glyph);
return 2;
}
return 1;
}
unsigned int ret;
- if ((ret = decompose (font, buffer, shortest, a))) {
+ if ((ret = decompose (c, shortest, a))) {
if (b) {
- output_char (buffer, b, b_glyph);
+ output_char (c->buffer, b, b_glyph);
return ret + 1;
}
return ret;
}
if (has_a) {
- output_char (buffer, a, a_glyph);
+ output_char (c->buffer, a, a_glyph);
if (likely (b)) {
- output_char (buffer, b, b_glyph);
+ output_char (c->buffer, b, b_glyph);
return 2;
}
return 1;
@@ -327,41 +171,42 @@ decompose (hb_font_t *font, hb_buffer_t *buffer, bool shortest, hb_codepoint_t a
/* Returns 0 if didn't decompose, number of resulting characters otherwise. */
static inline bool
-decompose_compatibility (hb_font_t *font, hb_buffer_t *buffer, hb_codepoint_t u)
+decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t u)
{
unsigned int len, i;
hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
hb_codepoint_t glyphs[HB_UNICODE_MAX_DECOMPOSITION_LEN];
- len = buffer->unicode->decompose_compatibility (u, decomposed);
+ len = c->buffer->unicode->decompose_compatibility (u, decomposed);
if (!len)
return 0;
for (i = 0; i < len; i++)
- if (!font->get_glyph (decomposed[i], 0, &glyphs[i]))
+ if (!c->font->get_glyph (decomposed[i], 0, &glyphs[i]))
return 0;
for (i = 0; i < len; i++)
- output_char (buffer, decomposed[i], glyphs[i]);
+ output_char (c->buffer, decomposed[i], glyphs[i]);
return len;
}
/* Returns true if recomposition may be benefitial. */
static inline bool
-decompose_current_character (hb_font_t *font, hb_buffer_t *buffer, bool shortest)
+decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest)
{
+ hb_buffer_t * const buffer = c->buffer;
hb_codepoint_t glyph;
unsigned int len = 1;
/* Kind of a cute waterfall here... */
- if (shortest && font->get_glyph (buffer->cur().codepoint, 0, &glyph))
+ if (shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph))
next_char (buffer, glyph);
- else if ((len = decompose (font, buffer, shortest, buffer->cur().codepoint)))
+ else if ((len = decompose (c, shortest, buffer->cur().codepoint)))
skip_char (buffer);
- else if (!shortest && font->get_glyph (buffer->cur().codepoint, 0, &glyph))
+ else if (!shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph))
next_char (buffer, glyph);
- else if ((len = decompose_compatibility (font, buffer, buffer->cur().codepoint)))
+ else if ((len = decompose_compatibility (c, buffer->cur().codepoint)))
skip_char (buffer);
else
next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
@@ -374,49 +219,51 @@ decompose_current_character (hb_font_t *font, hb_buffer_t *buffer, bool shortest
}
static inline void
-handle_variation_selector_cluster (hb_font_t *font, hb_buffer_t *buffer, unsigned int end)
+handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
{
+ hb_buffer_t * const buffer = c->buffer;
for (; buffer->idx < end - 1;) {
if (unlikely (buffer->unicode->is_variation_selector (buffer->cur(+1).codepoint))) {
/* The next two lines are some ugly lines... But work. */
- font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index());
+ c->font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index());
buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
} else {
- set_glyph (buffer->cur(), font);
+ set_glyph (buffer->cur(), c->font);
buffer->next_glyph ();
}
}
if (likely (buffer->idx < end)) {
- set_glyph (buffer->cur(), font);
+ set_glyph (buffer->cur(), c->font);
buffer->next_glyph ();
}
}
/* Returns true if recomposition may be benefitial. */
static inline bool
-decompose_multi_char_cluster (hb_font_t *font, hb_buffer_t *buffer, unsigned int end)
+decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
{
+ hb_buffer_t * const buffer = c->buffer;
/* TODO Currently if there's a variation-selector we give-up, it's just too hard. */
for (unsigned int i = buffer->idx; i < end; i++)
if (unlikely (buffer->unicode->is_variation_selector (buffer->info[i].codepoint))) {
- handle_variation_selector_cluster (font, buffer, end);
+ handle_variation_selector_cluster (c, end);
return false;
}
while (buffer->idx < end)
- decompose_current_character (font, buffer, false);
+ decompose_current_character (c, false);
/* We can be smarter here and only return true if there are at least two ccc!=0 marks.
* But does not matter. */
return true;
}
static inline bool
-decompose_cluster (hb_font_t *font, hb_buffer_t *buffer, bool short_circuit, unsigned int end)
+decompose_cluster (const hb_ot_shape_normalize_context_t *c, bool short_circuit, unsigned int end)
{
- if (likely (buffer->idx + 1 == end))
- return decompose_current_character (font, buffer, short_circuit);
+ if (likely (c->buffer->idx + 1 == end))
+ return decompose_current_character (c, short_circuit);
else
- return decompose_multi_char_cluster (font, buffer, end);
+ return decompose_multi_char_cluster (c, end);
}
@@ -431,9 +278,22 @@ compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
void
-_hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
- hb_ot_shape_normalization_mode_t mode)
+_hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
+ hb_buffer_t *buffer,
+ hb_font_t *font)
{
+ hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference ?
+ plan->shaper->normalization_preference (&buffer->props) :
+ HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT;
+ const hb_ot_shape_normalize_context_t c = {
+ plan,
+ buffer,
+ font,
+ buffer->unicode,
+ plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode,
+ plan->shaper->compose ? plan->shaper->compose : compose_unicode
+ };
+
bool short_circuit = mode != HB_OT_SHAPE_NORMALIZATION_MODE_DECOMPOSED &&
mode != HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT;
bool can_use_recompose = false;
@@ -457,7 +317,7 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
if (buffer->cur().cluster != buffer->info[end].cluster)
break;
- can_use_recompose = decompose_cluster (font, buffer, short_circuit, end) || can_use_recompose;
+ can_use_recompose = decompose_cluster (&c, short_circuit, end) || can_use_recompose;
}
buffer->swap_buffers ();
@@ -517,10 +377,10 @@ _hb_ot_shape_normalize (hb_font_t *font, hb_buffer_t *buffer,
(starter == buffer->out_len - 1 ||
_hb_glyph_info_get_modified_combining_class (&buffer->prev()) < _hb_glyph_info_get_modified_combining_class (&buffer->cur())) &&
/* And compose. */
- compose_func (buffer->unicode,
- buffer->out_info[starter].codepoint,
- buffer->cur().codepoint,
- &composed) &&
+ c.compose (&c,
+ buffer->out_info[starter].codepoint,
+ buffer->cur().codepoint,
+ &composed) &&
/* And the font has glyph for the composite. */
font->get_glyph (composed, 0, &glyph))
{
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh b/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh
index ae01215..23e80b7 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape-private.hh
@@ -46,7 +46,16 @@ struct hb_ot_shape_plan_t
hb_ot_map_t map;
const void *data;
- inline void substitute_closure (hb_face_t *face, hb_set_t *glyphs) const { map.substitute_closure (this, face, glyphs); }
+ inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
+ {
+ unsigned int table_index;
+ switch (table_tag) {
+ case HB_OT_TAG_GSUB: table_index = 0; break;
+ case HB_OT_TAG_GPOS: table_index = 1; break;
+ default: return;
+ }
+ map.collect_lookups (table_index, lookups);
+ }
inline void substitute (hb_font_t *font, hb_buffer_t *buffer) const { map.substitute (this, font, buffer); }
inline void position (hb_font_t *font, hb_buffer_t *buffer) const { map.position (this, font, buffer); }
@@ -65,14 +74,14 @@ struct hb_ot_shape_planner_t
face (master_plan->face),
props (master_plan->props),
shaper (NULL),
- map () {}
+ map (face, &props) {}
~hb_ot_shape_planner_t (void) { map.finish (); }
inline void compile (hb_ot_shape_plan_t &plan)
{
plan.props = props;
plan.shaper = shaper;
- map.compile (face, &props, plan.map);
+ map.compile (plan.map);
}
private:
diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape.cc b/third_party/harfbuzz-ng/src/hb-ot-shape.cc
index 9a6260a..96461d7 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-shape.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-shape.cc
@@ -175,7 +175,7 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
hb_ot_shape_planner_t planner (shape_plan);
- planner.shaper = hb_ot_shape_complex_categorize (&shape_plan->props);
+ planner.shaper = hb_ot_shape_complex_categorize (&planner);
hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
@@ -237,7 +237,7 @@ hb_set_unicode_props (hb_buffer_t *buffer)
static void
hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
{
- if (buffer->context_len[0] ||
+ if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
_hb_glyph_info_get_general_category (&buffer->info[0]) !=
HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
return;
@@ -348,8 +348,8 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++)
c->buffer->info[i].glyph_props() = _hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
- HB_OT_LAYOUT_GLYPH_CLASS_MARK :
- HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK :
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
}
static inline void
@@ -362,10 +362,7 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);
- _hb_ot_shape_normalize (c->font, c->buffer,
- c->plan->shaper->normalization_preference ?
- c->plan->shaper->normalization_preference (c->plan) :
- HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT);
+ _hb_ot_shape_normalize (c->plan, c->buffer, c->font);
hb_ot_shape_setup_masks (c);
@@ -455,12 +452,6 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
}
static inline void
-hb_ot_position_complex_fallback (hb_ot_shape_context_t *c)
-{
- _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
-}
-
-static inline void
hb_ot_truetype_kern (hb_ot_shape_context_t *c)
{
/* TODO Check for kern=0 */
@@ -486,34 +477,33 @@ hb_ot_truetype_kern (hb_ot_shape_context_t *c)
}
static inline void
-hb_position_complex_fallback_visual (hb_ot_shape_context_t *c)
-{
- hb_ot_truetype_kern (c);
-}
-
-static inline void
hb_ot_position (hb_ot_shape_context_t *c)
{
hb_ot_position_default (c);
hb_bool_t fallback = !hb_ot_position_complex (c);
- if (fallback)
- hb_ot_position_complex_fallback (c);
+ if (fallback && c->plan->shaper->fallback_position)
+ _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
hb_buffer_reverse (c->buffer);
+ /* Visual fallback goes here. */
+
if (fallback)
- hb_position_complex_fallback_visual (c);
+ hb_ot_truetype_kern (c);
}
/* Post-process */
static void
-hb_ot_hide_zerowidth (hb_ot_shape_context_t *c)
+hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
{
+ if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
+ return;
+
hb_codepoint_t space = 0;
unsigned int count = c->buffer->len;
@@ -557,7 +547,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
hb_ot_substitute (c);
hb_ot_position (c);
- hb_ot_hide_zerowidth (c);
+ hb_ot_hide_default_ignorables (c);
HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
@@ -582,16 +572,36 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan,
}
+void
+hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
+ hb_tag_t table_tag,
+ hb_set_t *lookup_indexes /* OUT */)
+{
+ /* XXX Does the first part always succeed? */
+ HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes);
+}
-static inline void
-hb_ot_map_glyphs_dumb (hb_font_t *font,
- hb_buffer_t *buffer)
+
+/* TODO Move this to hb-ot-shape-normalize, make it do decompose, and make it public. */
+static void
+add_char (hb_font_t *font,
+ hb_unicode_funcs_t *unicode,
+ hb_bool_t mirror,
+ hb_codepoint_t u,
+ hb_set_t *glyphs)
{
- unsigned int count = buffer->len;
- for (unsigned int i = 0; i < count; i++)
- font->get_glyph (buffer->info[i].codepoint, 0, &buffer->info[i].codepoint);
+ hb_codepoint_t glyph;
+ if (font->get_glyph (u, 0, &glyph))
+ glyphs->add (glyph);
+ if (mirror)
+ {
+ hb_codepoint_t m = unicode->mirroring (u);
+ if (m != u && font->get_glyph (m, 0, &glyph))
+ glyphs->add (glyph);
+ }
}
+
void
hb_ot_shape_glyphs_closure (hb_font_t *font,
hb_buffer_t *buffer,
@@ -601,29 +611,30 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
{
hb_ot_shape_plan_t plan;
- buffer->guess_properties ();
+ buffer->guess_segment_properties ();
- /* TODO cache / ensure correct backend, etc. */
- hb_shape_plan_t *shape_plan = hb_shape_plan_create (font->face, &buffer->props, features, num_features, NULL);
+ const char *shapers[] = {"ot", NULL};
+ hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props,
+ features, num_features, shapers);
- /* TODO: normalization? have shapers do closure()? */
- /* TODO: Deal with mirrored chars? */
- hb_ot_map_glyphs_dumb (font, buffer);
+ bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
- /* Seed it. It's user's responsibility to have cleard glyphs
- * if that's what they desire. */
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
- glyphs->add (buffer->info[i].codepoint);
+ add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs);
+
+ hb_set_t lookups;
+ lookups.init ();
+ hb_ot_shape_plan_collect_lookups (shape_plan, HB_OT_TAG_GSUB, &lookups);
/* And find transitive closure. */
hb_set_t copy;
copy.init ();
-
do {
copy.set (glyphs);
- HB_SHAPER_DATA_GET (shape_plan)->substitute_closure (font->face, glyphs);
- } while (!copy.equal (glyphs));
+ for (hb_codepoint_t lookup_index = -1; hb_set_next (&lookups, &lookup_index);)
+ hb_ot_layout_lookup_substitute_closure (font->face, lookup_index, glyphs);
+ } while (!copy.is_equal (glyphs));
hb_shape_plan_destroy (shape_plan);
}
diff --git a/third_party/harfbuzz-ng/src/hb-ot-tag.cc b/third_party/harfbuzz-ng/src/hb-ot-tag.cc
index ac60e96..91ebec7 100644
--- a/third_party/harfbuzz-ng/src/hb-ot-tag.cc
+++ b/third_party/harfbuzz-ng/src/hb-ot-tag.cc
@@ -23,7 +23,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
- * Google Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Roozbeh Pournader
*/
#include "hb-private.hh"
@@ -38,6 +38,8 @@
static hb_tag_t
hb_ot_old_tag_from_script (hb_script_t script)
{
+ /* This seems to be accurate as of end of 2012. */
+
switch ((hb_tag_t) script) {
case HB_SCRIPT_INVALID: return HB_OT_TAG_DEFAULT_SCRIPT;
@@ -91,6 +93,7 @@ hb_ot_new_tag_from_script (hb_script_t script)
case HB_SCRIPT_ORIYA: return HB_TAG('o','r','y','2');
case HB_SCRIPT_TAMIL: return HB_TAG('t','m','l','2');
case HB_SCRIPT_TELUGU: return HB_TAG('t','e','l','2');
+ case HB_SCRIPT_MYANMAR: return HB_TAG('m','y','m','2');
}
return HB_OT_TAG_DEFAULT_SCRIPT;
@@ -109,6 +112,7 @@ hb_ot_new_tag_to_script (hb_tag_t tag)
case HB_TAG('o','r','y','2'): return HB_SCRIPT_ORIYA;
case HB_TAG('t','m','l','2'): return HB_SCRIPT_TAMIL;
case HB_TAG('t','e','l','2'): return HB_SCRIPT_TELUGU;
+ case HB_TAG('m','y','m','2'): return HB_SCRIPT_MYANMAR;
}
return HB_SCRIPT_UNKNOWN;
@@ -165,7 +169,9 @@ typedef struct {
* Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
* 2008/08/04, matching on name, and finally adjusted manually.
*
- * Many items still missing. Those are commented out at the end.
+ * Updated on 2012/12/07 with more research into remaining codes.
+ *
+ * Some items still missing. Those are commented out at the end.
* Keep sorted for bsearch.
*/
@@ -173,43 +179,63 @@ static const LangTag ot_languages[] = {
{"aa", HB_TAG('A','F','R',' ')}, /* Afar */
{"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
{"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
+ {"ada", HB_TAG('D','N','G',' ')}, /* Dangme */
{"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */
{"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
+ {"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */
{"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
+ {"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */
{"am", HB_TAG('A','M','H',' ')}, /* Amharic */
+ {"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */
{"ar", HB_TAG('A','R','A',' ')}, /* Arabic */
{"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
{"as", HB_TAG('A','S','M',' ')}, /* Assamese */
+ {"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */
+ {"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */
{"av", HB_TAG('A','V','R',' ')}, /* Avaric */
{"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */
{"ay", HB_TAG('A','Y','M',' ')}, /* Aymara */
{"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani */
{"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
+ {"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
{"bal", HB_TAG('B','L','I',' ')}, /* Baluchi */
+ {"bci", HB_TAG('B','A','U',' ')}, /* Baule */
{"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
+ {"be", HB_TAG('B','E','L',' ')}, /* Belarussian */
{"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
+ {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */
{"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
{"bft", HB_TAG('B','L','T',' ')}, /* Balti */
+ {"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */
{"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
{"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
{"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
{"bik", HB_TAG('B','I','K',' ')}, /* Bikol */
{"bin", HB_TAG('E','D','O',' ')}, /* Bini */
+ {"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */
+ {"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */
+ {"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */
{"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
{"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
{"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
{"br", HB_TAG('B','R','E',' ')}, /* Breton */
+ {"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */
{"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
{"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
{"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
+ {"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */
+ {"byn", HB_TAG('B','I','L',' ')}, /* Bilen */
{"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
{"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
{"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
+ {"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
{"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
{"cr", HB_TAG('C','R','E',' ')}, /* Cree */
{"crh", HB_TAG('C','R','T',' ')}, /* Crimean Tatar */
+ {"crj", HB_TAG('E','C','R',' ')}, /* [Southern] East Cree */
+ {"crl", HB_TAG('E','C','R',' ')}, /* [Northern] East Cree */
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
@@ -222,10 +248,12 @@ static const LangTag ot_languages[] = {
{"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
{"de", HB_TAG('D','E','U',' ')}, /* German */
{"din", HB_TAG('D','N','K',' ')}, /* Dinka */
+ {"dje", HB_TAG('D','J','R',' ')}, /* Djerma */
{"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
{"doi", HB_TAG('D','G','R',' ')}, /* Dogri */
{"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
{"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */
+ {"dyu", HB_TAG('J','U','L',' ')}, /* Jula */
{"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
{"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
{"efi", HB_TAG('E','F','I',' ')}, /* Efik */
@@ -253,20 +281,27 @@ static const LangTag ot_languages[] = {
{"gag", HB_TAG('G','A','G',' ')}, /* Gagauz */
{"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
{"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
+ {"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */
{"gl", HB_TAG('G','A','L',' ')}, /* Galician */
{"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
{"gn", HB_TAG('G','U','A',' ')}, /* Guarani */
{"gon", HB_TAG('G','O','N',' ')}, /* Gondi */
{"grt", HB_TAG('G','R','O',' ')}, /* Garo */
+ {"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */
{"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
{"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
{"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */
{"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
{"har", HB_TAG('H','R','I',' ')}, /* Harari */
+ {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiin */
{"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
{"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
{"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
+ {"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */
+ {"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */
+ {"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */
{"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
+ {"hoj", HB_TAG('H','A','R',' ')}, /* Harauti */
{"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
{"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
{"ht", HB_TAG('H','A','I',' ')}, /* Haitian */
@@ -275,6 +310,8 @@ static const LangTag ot_languages[] = {
{"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
{"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
{"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
+ {"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */
+ {"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */
{"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
{"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
{"it", HB_TAG('I','T','A',' ')}, /* Italian */
@@ -282,19 +319,25 @@ static const LangTag ot_languages[] = {
{"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
{"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
{"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
+ {"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */
{"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
+ {"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
{"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
{"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
{"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
+ {"kex", HB_TAG('K','K','N',' ')}, /* Kokni */
{"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
{"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
{"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
+ {"khb", HB_TAG('X','B','D',' ')}, /* Tai Lue */
{"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
{"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */
+ {"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */
{"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
{"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */
{"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */
{"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */
+ {"kmb", HB_TAG('M','B','N',' ')}, /* [North] Mbundu */
{"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
{"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
{"ko", HB_TAG('K','O','R',' ')}, /* Korean */
@@ -312,6 +355,7 @@ static const LangTag ot_languages[] = {
{"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */
{"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
{"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
+ {"kxc", HB_TAG('K','M','S',' ')}, /* Komso */
{"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
{"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */
{"la", HB_TAG('L','A','T',' ')}, /* Latin */
@@ -319,13 +363,19 @@ static const LangTag ot_languages[] = {
{"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
{"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
{"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
+ {"lez", HB_TAG('L','E','Z',' ')}, /* Lezgi */
+ {"lg", HB_TAG('L','U','G',' ')}, /* Luganda */
{"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
{"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
+ {"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */
{"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
{"lo", HB_TAG('L','A','O',' ')}, /* Lao */
{"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
+ {"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */
+ {"lua", HB_TAG('L','U','B',' ')}, /* Luba-Kasai */
{"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */
- {"luw", HB_TAG('L','U','O',' ')}, /* Luo (Cameroon) */
+ {"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */
+ {"luy", HB_TAG('L','U','H',' ')}, /* Luhya [macrolanguage] */
{"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
{"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
{"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
@@ -334,6 +384,7 @@ static const LangTag ot_languages[] = {
{"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
{"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
{"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */
+ {"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */
{"mi", HB_TAG('M','R','I',' ')}, /* Maori */
{"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
{"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
@@ -347,14 +398,17 @@ static const LangTag ot_languages[] = {
{"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
{"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
{"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
+ {"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */
{"ms", HB_TAG('M','L','Y',' ')}, /* Malay */
{"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
{"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */
{"my", HB_TAG('B','R','M',' ')}, /* Burmese */
{"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
{"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
+ {"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */
{"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
{"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
+ {"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */
{"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
{"new", HB_TAG('N','E','W',' ')}, /* Newari */
{"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
@@ -364,33 +418,45 @@ static const LangTag ot_languages[] = {
{"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
{"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */
{"no", HB_TAG('N','O','R',' ')}, /* Norwegian (deprecated) */
+ {"nod", HB_TAG('N','T','A',' ')}, /* Northern Tai */
{"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
{"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */
+ {"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */
{"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
+ {"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */
{"ny", HB_TAG('C','H','I',' ')}, /* Nyanja */
+ {"nyn", HB_TAG('N','K','L',' ')}, /* Nkole */
{"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
{"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */
+ {"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */
{"om", HB_TAG('O','R','O',' ')}, /* Oromo */
{"or", HB_TAG('O','R','I',' ')}, /* Oriya */
{"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
{"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
+ {"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */
{"pi", HB_TAG('P','A','L',' ')}, /* Pali */
{"pl", HB_TAG('P','L','K',' ')}, /* Polish */
+ {"pll", HB_TAG('P','L','G',' ')}, /* [Shwe] Palaung */
{"plp", HB_TAG('P','A','P',' ')}, /* Palpa */
{"prs", HB_TAG('D','R','I',' ')}, /* Dari */
{"ps", HB_TAG('P','A','S',' ')}, /* Pushto */
{"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
{"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */
+ {"rbb", HB_TAG('P','L','G',' ')}, /* [Rumai] Palaung */
{"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */
{"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */
+ {"rki", HB_TAG('A','R','K',' ')}, /* Arakanese */
+ {"rm", HB_TAG('R','M','S',' ')}, /* Rhaeto-Romanic */
{"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
{"rom", HB_TAG('R','O','Y',' ')}, /* Romany */
{"ru", HB_TAG('R','U','S',' ')}, /* Russian */
{"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
+ {"rw", HB_TAG('R','U','A',' ')}, /* Ruanda */
{"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
{"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
{"sat", HB_TAG('S','A','T',' ')}, /* Santali */
{"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
+ {"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */
{"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */
{"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
{"seh", HB_TAG('S','N','A',' ')}, /* Sena */
@@ -413,6 +479,8 @@ static const LangTag ot_languages[] = {
{"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */
{"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
{"srr", HB_TAG('S','R','R',' ')}, /* Serer */
+ {"ss", HB_TAG('S','W','Z',' ')}, /* Swazi */
+ {"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */
{"suq", HB_TAG('S','U','R',' ')}, /* Suri */
{"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
{"sva", HB_TAG('S','V','A',' ')}, /* Svan */
@@ -420,31 +488,34 @@ static const LangTag ot_languages[] = {
{"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
{"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */
{"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
+ {"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */
{"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
{"te", HB_TAG('T','E','L',' ')}, /* Telugu */
+ {"tem", HB_TAG('T','M','N',' ')}, /* Temne */
{"tg", HB_TAG('T','A','J',' ')}, /* Tajik */
{"th", HB_TAG('T','H','A',' ')}, /* Thai */
{"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
{"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
{"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
{"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
- {"tnz", HB_TAG('T','N','G',' ')}, /* Tonga (Thailand) */
- {"to", HB_TAG('T','N','G',' ')}, /* Tonga (Tonga Islands) */
- {"tog", HB_TAG('T','N','G',' ')}, /* Tonga (Nyasa) */
- {"toi", HB_TAG('T','N','G',' ')}, /* Tonga (Zambia) */
+ {"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */
{"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
+ {"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */
{"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
{"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
{"tw", HB_TAG('T','W','I',' ')}, /* Twi */
{"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
+ {"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */
{"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */
{"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */
{"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
+ {"umb", HB_TAG('M','B','N',' ')}, /* [South] Mbundu */
{"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
{"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
{"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */
{"ve", HB_TAG('V','E','N',' ')}, /* Venda */
{"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
+ {"vmw", HB_TAG('M','A','K',' ')}, /* Makua */
{"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
{"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
{"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
@@ -458,115 +529,56 @@ static const LangTag ot_languages[] = {
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
{"zu", HB_TAG('Z','U','L',' ')} /* Zulu */
- /* I couldn't find the language id for these */
-
-/*{"??", HB_TAG('A','G','W',' ')},*/ /* Agaw */
-/*{"??", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
-/*{"??", HB_TAG('A','L','T',' ')},*/ /* Altai */
-/*{"??", HB_TAG('A','R','K',' ')},*/ /* Arakanese */
-/*{"??", HB_TAG('A','T','H',' ')},*/ /* Athapaskan */
-/*{"??", HB_TAG('B','A','G',' ')},*/ /* Baghelkhandi */
-/*{"??", HB_TAG('B','A','L',' ')},*/ /* Balkar */
-/*{"??", HB_TAG('B','A','U',' ')},*/ /* Baule */
-/*{"??", HB_TAG('B','B','R',' ')},*/ /* Berber */
+ /* The corresponding languages IDs for the following IDs are unclear,
+ * overlap, or are architecturally weird. Needs more research. */
+
+/*{"ahg/awn/xan?", HB_TAG('A','G','W',' ')},*/ /* Agaw */
+/*{"gsw?/gsw-FR?", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
+/*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */
/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
-/*{"??", HB_TAG('B','E','L',' ')},*/ /* Belarussian */
-/*{"??", HB_TAG('B','I','L',' ')},*/ /* Bilen */
-/*{"??", HB_TAG('B','K','F',' ')},*/ /* Blackfoot */
-/*{"??", HB_TAG('B','L','N',' ')},*/ /* Balante */
-/*{"??", HB_TAG('B','M','L',' ')},*/ /* Bamileke */
-/*{"??", HB_TAG('B','R','I',' ')},*/ /* Braj Bhasha */
-/*{"??", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
-/*{"??", HB_TAG('C','H','H',' ')},*/ /* Chattisgarhi */
-/*{"??", HB_TAG('C','H','K',' ')},*/ /* Chukchi */
-/*{"??", HB_TAG('D','J','R',' ')},*/ /* Djerma */
-/*{"??", HB_TAG('D','N','G',' ')},*/ /* Dangme */
-/*{"??", HB_TAG('E','C','R',' ')},*/ /* Eastern Cree */
-/*{"??", HB_TAG('F','A','N',' ')},*/ /* French Antillean */
-/*{"??", HB_TAG('F','L','E',' ')},*/ /* Flemish */
-/*{"??", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */
-/*{"??", HB_TAG('F','T','A',' ')},*/ /* Futa */
-/*{"??", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
-/*{"??", HB_TAG('G','E','Z',' ')},*/ /* Ge'ez */
-/*{"??", HB_TAG('H','A','L',' ')},*/ /* Halam */
-/*{"??", HB_TAG('H','A','R',' ')},*/ /* Harauti */
-/*{"??", HB_TAG('H','A','W',' ')},*/ /* Hawaiin */
-/*{"??", HB_TAG('H','B','N',' ')},*/ /* Hammer-Banna */
-/*{"??", HB_TAG('H','M','A',' ')},*/ /* High Mari */
-/*{"??", HB_TAG('H','N','D',' ')},*/ /* Hindko */
-/*{"??", HB_TAG('I','J','O',' ')},*/ /* Ijo */
-/*{"??", HB_TAG('I','L','O',' ')},*/ /* Ilokano */
-/*{"??", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
-/*{"??", HB_TAG('J','U','L',' ')},*/ /* Jula */
-/*{"??", HB_TAG('K','A','R',' ')},*/ /* Karachay */
-/*{"??", HB_TAG('K','E','B',' ')},*/ /* Kebena */
-/*{"??", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */
-/*{"??", HB_TAG('K','H','A',' ')},*/ /* Khakass */
-/*{"??", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */
-/*{"??", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */
-/*{"??", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */
-/*{"??", HB_TAG('K','I','S',' ')},*/ /* Kisii */
-/*{"??", HB_TAG('K','K','N',' ')},*/ /* Kokni */
-/*{"??", HB_TAG('K','M','S',' ')},*/ /* Komso */
-/*{"??", HB_TAG('K','O','D',' ')},*/ /* Kodagu */
-/*{"??", HB_TAG('K','O','H',' ')},*/ /* Korean Old Hangul */
-/*{"??", HB_TAG('K','O','N',' ')},*/ /* Kikongo */
-/*{"??", HB_TAG('K','R','K',' ')},*/ /* Karakalpak */
-/*{"??", HB_TAG('K','R','N',' ')},*/ /* Karen */
-/*{"??", HB_TAG('K','U','L',' ')},*/ /* Kulvi */
+/*{"sgw?", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
+/*{"acf/gcf?", HB_TAG('F','A','N',' ')},*/ /* French Antillean */
+/*{"vls/nl-be", HB_TAG('F','L','E',' ')},*/ /* Flemish */
+/*{"enf?/yrk?", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */
+/*{"fuf?", HB_TAG('F','T','A',' ')},*/ /* Futa */
+/*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
+/*{"cfm/rnl?", HB_TAG('H','A','L',' ')},*/ /* Halam */
+/*{"ga-Latg?/Latg?", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
+/*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */
+/*{"alw?/ktb?", HB_TAG('K','E','B',' ')},*/ /* Kebena */
+/*{"Geok", HB_TAG('K','G','E',' ')},*/ /* Khutsuri Georgian */
+/*{"kca", HB_TAG('K','H','K',' ')},*/ /* Khanty-Kazim */
+/*{"kca", HB_TAG('K','H','S',' ')},*/ /* Khanty-Shurishkar */
+/*{"kca", HB_TAG('K','H','V',' ')},*/ /* Khanty-Vakhi */
+/*{"guz?/kqs?/kss?", HB_TAG('K','I','S',' ')},*/ /* Kisii */
+/*{"kfa/kfi?/kpb?/xua?/xuj?", HB_TAG('K','O','D',' ')},*/ /* Kodagu */
+/*{"okm?/oko?", HB_TAG('K','O','H',' ')},*/ /* Korean Old Hangul */
+/*{"kon?/ktu?/...", HB_TAG('K','O','N',' ')},*/ /* Kikongo */
+/*{"kfx?", HB_TAG('K','U','L',' ')},*/ /* Kulvi */
/*{"??", HB_TAG('L','A','H',' ')},*/ /* Lahuli */
-/*{"??", HB_TAG('L','A','M',' ')},*/ /* Lambani */
/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */
-/*{"??", HB_TAG('L','E','Z',' ')},*/ /* Lezgi */
-/*{"??", HB_TAG('L','M','A',' ')},*/ /* Low Mari */
-/*{"??", HB_TAG('L','U','B',' ')},*/ /* Luba */
-/*{"??", HB_TAG('L','U','G',' ')},*/ /* Luganda */
-/*{"??", HB_TAG('L','U','H',' ')},*/ /* Luhya */
-/*{"??", HB_TAG('M','A','K',' ')},*/ /* Makua */
/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
-/*{"??", HB_TAG('M','B','N',' ')},*/ /* Mbundu */
-/*{"??", HB_TAG('M','I','Z',' ')},*/ /* Mizo */
-/*{"??", HB_TAG('M','L','N',' ')},*/ /* Malinke */
-/*{"??", HB_TAG('M','N','K',' ')},*/ /* Maninka */
+/*{"mnk?/mlq?/...", HB_TAG('M','L','N',' ')},*/ /* Malinke */
+/*{"man?/myq?/mku?/msc?/...", HB_TAG('M','N','K',' ')},*/ /* Maninka */
/*{"??", HB_TAG('M','O','R',' ')},*/ /* Moroccan */
-/*{"??", HB_TAG('N','A','G',' ')},*/ /* Naga-Assamese */
/*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */
-/*{"??", HB_TAG('N','D','B',' ')},*/ /* Ndebele */
-/*{"??", HB_TAG('N','G','R',' ')},*/ /* Nagari */
/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
-/*{"??", HB_TAG('N','K','L',' ')},*/ /* Nkole */
-/*{"??", HB_TAG('N','T','A',' ')},*/ /* Northern Tai */
-/*{"??", HB_TAG('O','C','R',' ')},*/ /* Oji-Cree */
-/*{"??", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
-/*{"??", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */
-/*{"??", HB_TAG('P','L','G',' ')},*/ /* Palaung */
-/*{"??", HB_TAG('Q','I','N',' ')},*/ /* Chin */
-/*{"??", HB_TAG('R','B','U',' ')},*/ /* Russian Buriat */
+/*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
+/*{"polyton", HB_TAG('P','G','R',' ')},*/ /* Polytonic Greek */
+/*{"??", HB_TAG('Q','I','N',' ')},*/ /* Asho Chin */
/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */
-/*{"??", HB_TAG('R','M','S',' ')},*/ /* Rhaeto-Romanic */
-/*{"??", HB_TAG('R','U','A',' ')},*/ /* Ruanda */
-/*{"??", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
-/*{"??", HB_TAG('S','E','K',' ')},*/ /* Sekota */
-/*{"??", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */
-/*{"??", HB_TAG('S','L','A',' ')},*/ /* Slavey */
-/*{"??", HB_TAG('S','O','G',' ')},*/ /* Sodo Gurage */
-/*{"??", HB_TAG('S','O','T',' ')},*/ /* Sotho */
-/*{"??", HB_TAG('S','W','A',' ')},*/ /* Swadaya Aramaic */
-/*{"??", HB_TAG('S','W','Z',' ')},*/ /* Swazi */
-/*{"??", HB_TAG('S','X','T',' ')},*/ /* Sutu */
-/*{"??", HB_TAG('T','A','B',' ')},*/ /* Tabasaran */
+/*{"chp?", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
+/*{"xan?", HB_TAG('S','E','K',' ')},*/ /* Sekota */
+/*{"stv/wle?/xst?", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */
+/*{"ngo?", HB_TAG('S','X','T',' ')},*/ /* Sutu */
/*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */
-/*{"??", HB_TAG('T','G','N',' ')},*/ /* Tongan */
-/*{"??", HB_TAG('T','M','N',' ')},*/ /* Temne */
-/*{"??", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */
+/*{"tnz?/tog?/toi?", HB_TAG('T','N','G',' ')},*/ /* Tonga */
+/*{"enh?/yrk?", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */
/*{"??", HB_TAG('T','O','D',' ')},*/ /* Todo */
-/*{"??", HB_TAG('T','U','A',' ')},*/ /* Turoyo Aramaic */
-/*{"??", HB_TAG('T','U','V',' ')},*/ /* Tuvin */
/*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */
-/*{"??", HB_TAG('X','B','D',' ')},*/ /* Tai Lue */
/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
-/*{"??", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
+/*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
};
diff --git a/third_party/harfbuzz-ng/src/hb-ot.h b/third_party/harfbuzz-ng/src/hb-ot.h
index 2d750c3..8073906 100644
--- a/third_party/harfbuzz-ng/src/hb-ot.h
+++ b/third_party/harfbuzz-ng/src/hb-ot.h
@@ -35,6 +35,7 @@
HB_BEGIN_DECLS
+/* TODO remove */
void
hb_ot_shape_glyphs_closure (hb_font_t *font,
hb_buffer_t *buffer,
diff --git a/third_party/harfbuzz-ng/src/hb-private.hh b/third_party/harfbuzz-ng/src/hb-private.hh
index 42c0259..be0d505 100644
--- a/third_party/harfbuzz-ng/src/hb-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-private.hh
@@ -62,6 +62,12 @@
#endif
+/* Void! */
+struct _hb_void_t {};
+typedef const _hb_void_t &hb_void_t;
+#define HB_VOID (* (const _hb_void_t *) NULL)
+
+
/* Basics */
@@ -76,7 +82,7 @@ static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
#undef ARRAY_LENGTH
template <typename Type, unsigned int n>
-static inline unsigned int ARRAY_LENGTH (const Type (&a)[n]) { return n; }
+static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; }
/* A const version, but does not detect erratically being called on pointers. */
#define ARRAY_LENGTH_CONST(__array) ((signed int) (sizeof (__array) / sizeof (__array[0])))
@@ -503,6 +509,10 @@ static inline uint32_t hb_uint32_swap (const uint32_t v)
#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3])
#define hb_be_uint32_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])
+#define hb_be_uint24_put(v,V) HB_STMT_START { v[0] = (V>>16); v[1] = (V>>8); v[2] (V); } HB_STMT_END
+#define hb_be_uint24_get(v) (uint32_t) ((v[0] << 16) + (v[1] << 8) + v[2])
+#define hb_be_uint24_eq(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2])
+
/* ASCII tag/character handling */
@@ -582,7 +592,11 @@ _hb_debug_msg_va (const char *what,
} else
fprintf (stderr, " " VRBAR LBAR);
- if (func) {
+ if (func)
+ {
+ /* Skip "typename" */
+ if (0 == strncmp (func, "typename ", 9))
+ func += 9;
/* Skip return type */
const char *space = strchr (func, ' ');
if (space)
@@ -657,10 +671,39 @@ _hb_debug_msg<0> (const char *what HB_UNUSED,
/*
+ * Printer
+ */
+
+template <typename T>
+struct hb_printer_t {};
+
+template <>
+struct hb_printer_t<bool> {
+ const char *print (bool v) { return v ? "true" : "false"; }
+};
+
+template <>
+struct hb_printer_t<hb_void_t> {
+ const char *print (hb_void_t) { return ""; }
+};
+
+
+/*
* Trace
*/
-template <int max_level>
+template <typename T>
+static inline void _hb_warn_no_return (bool returned)
+{
+ if (unlikely (!returned)) {
+ fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report.\n");
+ }
+}
+template <>
+inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
+{}
+
+template <int max_level, typename ret_t>
struct hb_auto_trace_t {
explicit inline hb_auto_trace_t (unsigned int *plevel_,
const char *what_,
@@ -678,23 +721,23 @@ struct hb_auto_trace_t {
}
inline ~hb_auto_trace_t (void)
{
- if (unlikely (!returned)) {
- fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report. Level was %d.\n", plevel ? *plevel : -1);
+ _hb_warn_no_return<ret_t> (returned);
+ if (!returned) {
_hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, " ");
- return;
}
-
if (plevel) --*plevel;
}
- inline bool ret (bool v, unsigned int line = 0)
+ inline ret_t ret (ret_t v, unsigned int line = 0)
{
if (unlikely (returned)) {
fprintf (stderr, "OUCH, double calls to TRACE_RETURN. This is a bug, please report.\n");
return v;
}
- _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1, "return %s (line %d)", v ? "true" : "false", line);
+ _hb_debug_msg<max_level> (what, obj, NULL, true, plevel ? *plevel : 1, -1,
+ "return %s (line %d)",
+ hb_printer_t<ret_t>().print (v), line);
if (plevel) --*plevel;
plevel = NULL;
returned = true;
@@ -703,12 +746,12 @@ struct hb_auto_trace_t {
private:
unsigned int *plevel;
- bool returned;
const char *what;
const void *obj;
+ bool returned;
};
-template <> /* Optimize when tracing is disabled */
-struct hb_auto_trace_t<0> {
+template <typename ret_t> /* Optimize when tracing is disabled */
+struct hb_auto_trace_t<0, ret_t> {
explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED,
const char *what HB_UNUSED,
const void *obj HB_UNUSED,
@@ -716,8 +759,7 @@ struct hb_auto_trace_t<0> {
const char *message HB_UNUSED,
...) {}
- template <typename T>
- inline T ret (T v, unsigned int line = 0) { return v; }
+ inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
};
#define TRACE_RETURN(RET) trace.ret (RET, __LINE__)
diff --git a/third_party/harfbuzz-ng/src/hb-set-private.hh b/third_party/harfbuzz-ng/src/hb-set-private.hh
index 4413579..5e30a7e 100644
--- a/third_party/harfbuzz-ng/src/hb-set-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-set-private.hh
@@ -98,7 +98,7 @@ struct hb_set_digest_lowest_bits_t
private:
- mask_t mask_for (hb_codepoint_t g) const { return ((mask_t) 1) << (g & (sizeof (mask_t) * 8 - 1)); }
+ static inline mask_t mask_for (hb_codepoint_t g) { return ((mask_t) 1) << (g & (sizeof (mask_t) * 8 - 1)); }
mask_t mask;
};
@@ -137,6 +137,7 @@ struct hb_set_t
{
hb_object_header_t header;
ASSERT_POD ();
+ bool in_error;
inline void init (void) {
header.init ();
@@ -145,9 +146,12 @@ struct hb_set_t
inline void fini (void) {
}
inline void clear (void) {
+ if (unlikely (hb_object_is_inert (this)))
+ return;
+ in_error = false;
memset (elts, 0, sizeof elts);
}
- inline bool empty (void) const {
+ inline bool is_empty (void) const {
for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++)
if (elts[i])
return false;
@@ -155,20 +159,31 @@ struct hb_set_t
}
inline void add (hb_codepoint_t g)
{
+ if (unlikely (in_error)) return;
if (unlikely (g == SENTINEL)) return;
if (unlikely (g > MAX_G)) return;
elt (g) |= mask (g);
}
inline void add_range (hb_codepoint_t a, hb_codepoint_t b)
{
+ if (unlikely (in_error)) return;
+ /* TODO Speedup */
for (unsigned int i = a; i < b + 1; i++)
add (i);
}
inline void del (hb_codepoint_t g)
{
+ if (unlikely (in_error)) return;
if (unlikely (g > MAX_G)) return;
elt (g) &= ~mask (g);
}
+ inline void del_range (hb_codepoint_t a, hb_codepoint_t b)
+ {
+ if (unlikely (in_error)) return;
+ /* TODO Speedup */
+ for (unsigned int i = a; i < b + 1; i++)
+ del (i);
+ }
inline bool has (hb_codepoint_t g) const
{
if (unlikely (g > MAX_G)) return false;
@@ -185,7 +200,7 @@ struct hb_set_t
return true;
return false;
}
- inline bool equal (const hb_set_t *other) const
+ inline bool is_equal (const hb_set_t *other) const
{
for (unsigned int i = 0; i < ELTS; i++)
if (elts[i] != other->elts[i])
@@ -194,30 +209,41 @@ struct hb_set_t
}
inline void set (const hb_set_t *other)
{
+ if (unlikely (in_error)) return;
for (unsigned int i = 0; i < ELTS; i++)
elts[i] = other->elts[i];
}
inline void union_ (const hb_set_t *other)
{
+ if (unlikely (in_error)) return;
for (unsigned int i = 0; i < ELTS; i++)
elts[i] |= other->elts[i];
}
inline void intersect (const hb_set_t *other)
{
+ if (unlikely (in_error)) return;
for (unsigned int i = 0; i < ELTS; i++)
elts[i] &= other->elts[i];
}
inline void subtract (const hb_set_t *other)
{
+ if (unlikely (in_error)) return;
for (unsigned int i = 0; i < ELTS; i++)
elts[i] &= ~other->elts[i];
}
inline void symmetric_difference (const hb_set_t *other)
{
+ if (unlikely (in_error)) return;
for (unsigned int i = 0; i < ELTS; i++)
elts[i] ^= other->elts[i];
}
- inline bool next (hb_codepoint_t *codepoint)
+ inline void invert (void)
+ {
+ if (unlikely (in_error)) return;
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] = ~elts[i];
+ }
+ inline bool next (hb_codepoint_t *codepoint) const
{
if (unlikely (*codepoint == SENTINEL)) {
hb_codepoint_t i = get_min ();
@@ -234,6 +260,28 @@ struct hb_set_t
}
return false;
}
+ inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
+ {
+ hb_codepoint_t i;
+
+ i = *last;
+ if (!next (&i))
+ return false;
+
+ *last = *first = i;
+ while (next (&i) && i == *last + 1)
+ (*last)++;
+
+ return true;
+ }
+
+ inline unsigned int get_population (void) const
+ {
+ unsigned int count = 0;
+ for (unsigned int i = 0; i < ELTS; i++)
+ count += _hb_popcount32 (elts[i]);
+ return count;
+ }
inline hb_codepoint_t get_min (void) const
{
for (unsigned int i = 0; i < ELTS; i++)
diff --git a/third_party/harfbuzz-ng/src/hb-set.cc b/third_party/harfbuzz-ng/src/hb-set.cc
index 4225e3c..5f427a5 100644
--- a/third_party/harfbuzz-ng/src/hb-set.cc
+++ b/third_party/harfbuzz-ng/src/hb-set.cc
@@ -32,7 +32,7 @@
hb_set_t *
-hb_set_create ()
+hb_set_create (void)
{
hb_set_t *set;
@@ -49,6 +49,7 @@ hb_set_get_empty (void)
{
static const hb_set_t _hb_set_nil = {
HB_OBJECT_HEADER_STATIC,
+ true, /* in_error */
{0} /* elts */
};
@@ -73,27 +74,27 @@ hb_set_destroy (hb_set_t *set)
}
hb_bool_t
-hb_set_set_user_data (hb_set_t *set,
- hb_user_data_key_t *key,
- void * data,
- hb_destroy_func_t destroy,
- hb_bool_t replace)
+hb_set_set_user_data (hb_set_t *set,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
{
return hb_object_set_user_data (set, key, data, destroy, replace);
}
void *
-hb_set_get_user_data (hb_set_t *set,
- hb_user_data_key_t *key)
+hb_set_get_user_data (hb_set_t *set,
+ hb_user_data_key_t *key)
{
return hb_object_get_user_data (set, key);
}
hb_bool_t
-hb_set_allocation_successful (hb_set_t *set HB_UNUSED)
+hb_set_allocation_successful (const hb_set_t *set HB_UNUSED)
{
- return true;
+ return !set->in_error;
}
void
@@ -103,13 +104,13 @@ hb_set_clear (hb_set_t *set)
}
hb_bool_t
-hb_set_empty (hb_set_t *set)
+hb_set_is_empty (const hb_set_t *set)
{
- return set->empty ();
+ return set->is_empty ();
}
hb_bool_t
-hb_set_has (hb_set_t *set,
+hb_set_has (const hb_set_t *set,
hb_codepoint_t codepoint)
{
return set->has (codepoint);
@@ -123,69 +124,105 @@ hb_set_add (hb_set_t *set,
}
void
+hb_set_add_range (hb_set_t *set,
+ hb_codepoint_t first,
+ hb_codepoint_t last)
+{
+ set->add_range (first, last);
+}
+
+void
hb_set_del (hb_set_t *set,
hb_codepoint_t codepoint)
{
set->del (codepoint);
}
+void
+hb_set_del_range (hb_set_t *set,
+ hb_codepoint_t first,
+ hb_codepoint_t last)
+{
+ set->del_range (first, last);
+}
+
hb_bool_t
-hb_set_equal (hb_set_t *set,
- hb_set_t *other)
+hb_set_is_equal (const hb_set_t *set,
+ const hb_set_t *other)
{
- return set->equal (other);
+ return set->is_equal (other);
}
void
-hb_set_set (hb_set_t *set,
- hb_set_t *other)
+hb_set_set (hb_set_t *set,
+ const hb_set_t *other)
{
set->set (other);
}
void
-hb_set_union (hb_set_t *set,
- hb_set_t *other)
+hb_set_union (hb_set_t *set,
+ const hb_set_t *other)
{
set->union_ (other);
}
void
-hb_set_intersect (hb_set_t *set,
- hb_set_t *other)
+hb_set_intersect (hb_set_t *set,
+ const hb_set_t *other)
{
set->intersect (other);
}
void
-hb_set_subtract (hb_set_t *set,
- hb_set_t *other)
+hb_set_subtract (hb_set_t *set,
+ const hb_set_t *other)
{
set->subtract (other);
}
void
-hb_set_symmetric_difference (hb_set_t *set,
- hb_set_t *other)
+hb_set_symmetric_difference (hb_set_t *set,
+ const hb_set_t *other)
{
set->symmetric_difference (other);
}
+void
+hb_set_invert (hb_set_t *set)
+{
+ set->invert ();
+}
+
+unsigned int
+hb_set_get_population (const hb_set_t *set)
+{
+ return set->get_population ();
+}
+
hb_codepoint_t
-hb_set_min (hb_set_t *set)
+hb_set_get_min (const hb_set_t *set)
{
return set->get_min ();
}
hb_codepoint_t
-hb_set_max (hb_set_t *set)
+hb_set_get_max (const hb_set_t *set)
{
return set->get_max ();
}
hb_bool_t
-hb_set_next (hb_set_t *set,
+hb_set_next (const hb_set_t *set,
hb_codepoint_t *codepoint)
{
return set->next (codepoint);
}
+
+hb_bool_t
+hb_set_next_range (const hb_set_t *set,
+ hb_codepoint_t *first,
+ hb_codepoint_t *last)
+{
+ return set->next_range (first, last);
+}
diff --git a/third_party/harfbuzz-ng/src/hb-set.h b/third_party/harfbuzz-ng/src/hb-set.h
index 1838889..291e249 100644
--- a/third_party/harfbuzz-ng/src/hb-set.h
+++ b/third_party/harfbuzz-ng/src/hb-set.h
@@ -65,16 +65,16 @@ hb_set_get_user_data (hb_set_t *set,
/* Returns false if allocation has failed before */
hb_bool_t
-hb_set_allocation_successful (hb_set_t *set);
+hb_set_allocation_successful (const hb_set_t *set);
void
hb_set_clear (hb_set_t *set);
hb_bool_t
-hb_set_empty (hb_set_t *set);
+hb_set_is_empty (const hb_set_t *set);
hb_bool_t
-hb_set_has (hb_set_t *set,
+hb_set_has (const hb_set_t *set,
hb_codepoint_t codepoint);
/* Right now limited to 16-bit integers. Eventually will do full codepoint range, sans -1
@@ -84,47 +84,67 @@ hb_set_add (hb_set_t *set,
hb_codepoint_t codepoint);
void
+hb_set_add_range (hb_set_t *set,
+ hb_codepoint_t first,
+ hb_codepoint_t last);
+
+void
hb_set_del (hb_set_t *set,
hb_codepoint_t codepoint);
+void
+hb_set_del_range (hb_set_t *set,
+ hb_codepoint_t first,
+ hb_codepoint_t last);
+
hb_bool_t
-hb_set_equal (hb_set_t *set,
- hb_set_t *other);
+hb_set_is_equal (const hb_set_t *set,
+ const hb_set_t *other);
void
-hb_set_set (hb_set_t *set,
- hb_set_t *other);
+hb_set_set (hb_set_t *set,
+ const hb_set_t *other);
void
-hb_set_union (hb_set_t *set,
- hb_set_t *other);
+hb_set_union (hb_set_t *set,
+ const hb_set_t *other);
void
-hb_set_intersect (hb_set_t *set,
- hb_set_t *other);
+hb_set_intersect (hb_set_t *set,
+ const hb_set_t *other);
void
-hb_set_subtract (hb_set_t *set,
- hb_set_t *other);
+hb_set_subtract (hb_set_t *set,
+ const hb_set_t *other);
void
-hb_set_symmetric_difference (hb_set_t *set,
- hb_set_t *other);
+hb_set_symmetric_difference (hb_set_t *set,
+ const hb_set_t *other);
+
+void
+hb_set_invert (hb_set_t *set);
+
+unsigned int
+hb_set_get_population (const hb_set_t *set);
/* Returns -1 if set empty. */
hb_codepoint_t
-hb_set_min (hb_set_t *set);
+hb_set_get_min (const hb_set_t *set);
/* Returns -1 if set empty. */
hb_codepoint_t
-hb_set_max (hb_set_t *set);
+hb_set_get_max (const hb_set_t *set);
/* Pass -1 in to get started. */
hb_bool_t
-hb_set_next (hb_set_t *set,
+hb_set_next (const hb_set_t *set,
hb_codepoint_t *codepoint);
-/* TODO: Add faster iteration API? */
+/* Pass -1 for first and last to get started. */
+hb_bool_t
+hb_set_next_range (const hb_set_t *set,
+ hb_codepoint_t *first,
+ hb_codepoint_t *last);
HB_END_DECLS
diff --git a/third_party/harfbuzz-ng/src/hb-shape-plan-private.hh b/third_party/harfbuzz-ng/src/hb-shape-plan-private.hh
index d6a57d6..dd014e3 100644
--- a/third_party/harfbuzz-ng/src/hb-shape-plan-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-shape-plan-private.hh
@@ -28,9 +28,8 @@
#define HB_SHAPE_PLAN_PRIVATE_HH
#include "hb-private.hh"
-
#include "hb-shape-plan.h"
-
+#include "hb-object-private.hh"
#include "hb-shaper-private.hh"
@@ -44,6 +43,7 @@ struct hb_shape_plan_t
hb_segment_properties_t props;
hb_shape_func_t *shaper_func;
+ const char *shaper_name;
struct hb_shaper_data_t shaper_data;
};
diff --git a/third_party/harfbuzz-ng/src/hb-shape-plan.cc b/third_party/harfbuzz-ng/src/hb-shape-plan.cc
index 038f6af3..22a226f 100644
--- a/third_party/harfbuzz-ng/src/hb-shape-plan.cc
+++ b/third_party/harfbuzz-ng/src/hb-shape-plan.cc
@@ -24,8 +24,6 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-private.hh"
-
#include "hb-shape-plan-private.hh"
#include "hb-shaper-private.hh"
#include "hb-font-private.hh"
@@ -51,6 +49,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
HB_SHAPER_DATA (shaper, shape_plan) = \
HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
shape_plan->shaper_func = _hb_##shaper##_shape; \
+ shape_plan->shaper_name = #shaper; \
return; \
} \
} HB_STMT_END
@@ -119,9 +118,10 @@ hb_shape_plan_get_empty (void)
true, /* default_shaper_list */
NULL, /* face */
- _HB_BUFFER_PROPS_DEFAULT, /* props */
+ HB_SEGMENT_PROPERTIES_DEFAULT, /* props */
NULL, /* shaper_func */
+ NULL, /* shaper_name */
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
@@ -153,9 +153,26 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
free (shape_plan);
}
+hb_bool_t
+hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (shape_plan, key, data, destroy, replace);
+}
+
+void *
+hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (shape_plan, key);
+}
+
hb_bool_t
-hb_shape_plan_execute (hb_shape_plan *shape_plan,
+hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
@@ -283,3 +300,9 @@ retry:
return hb_shape_plan_reference (shape_plan);
}
+
+const char *
+hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
+{
+ return shape_plan->shaper_name;
+}
diff --git a/third_party/harfbuzz-ng/src/hb-shape-plan.h b/third_party/harfbuzz-ng/src/hb-shape-plan.h
index f1a14a9..8f54552 100644
--- a/third_party/harfbuzz-ng/src/hb-shape-plan.h
+++ b/third_party/harfbuzz-ng/src/hb-shape-plan.h
@@ -24,52 +24,66 @@
* Google Author(s): Behdad Esfahbod
*/
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
#ifndef HB_SHAPE_PLAN_H
#define HB_SHAPE_PLAN_H
-/* TODO To become public one day */
-
-#include "hb-private.hh"
-
-#include "hb-buffer-private.hh"
+#include "hb-common.h"
+#include "hb-font.h"
+HB_BEGIN_DECLS
-typedef struct hb_shape_plan_t hb_shape_plan;
-
-/*
- * hb_shape_plan_t
- */
+typedef struct hb_shape_plan_t hb_shape_plan_t;
-HB_INTERNAL hb_shape_plan_t *
+hb_shape_plan_t *
hb_shape_plan_create (hb_face_t *face,
const hb_segment_properties_t *props,
const hb_feature_t *user_features,
unsigned int num_user_features,
const char * const *shaper_list);
-HB_INTERNAL hb_shape_plan_t *
+hb_shape_plan_t *
hb_shape_plan_create_cached (hb_face_t *face,
const hb_segment_properties_t *props,
const hb_feature_t *user_features,
unsigned int num_user_features,
const char * const *shaper_list);
-HB_INTERNAL hb_shape_plan_t *
+hb_shape_plan_t *
hb_shape_plan_get_empty (void);
-HB_INTERNAL hb_shape_plan_t *
+hb_shape_plan_t *
hb_shape_plan_reference (hb_shape_plan_t *shape_plan);
-HB_INTERNAL void
+void
hb_shape_plan_destroy (hb_shape_plan_t *shape_plan);
+hb_bool_t
+hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+void *
+hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
+ hb_user_data_key_t *key);
+
-HB_INTERNAL hb_bool_t
-hb_shape_plan_execute (hb_shape_plan *shape_plan,
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features);
+const char *
+hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan);
+
+
+HB_END_DECLS
#endif /* HB_SHAPE_PLAN_H */
diff --git a/third_party/harfbuzz-ng/src/hb-shape.cc b/third_party/harfbuzz-ng/src/hb-shape.cc
index 4d64823..389ce3e 100644
--- a/third_party/harfbuzz-ng/src/hb-shape.cc
+++ b/third_party/harfbuzz-ng/src/hb-shape.cc
@@ -176,7 +176,7 @@ hb_feature_to_string (hb_feature_t *feature,
len += 4;
while (len && s[len - 1] == ' ')
len--;
- if (feature->start != 0 || feature->start != (unsigned int) -1)
+ if (feature->start != 0 || feature->end != (unsigned int) -1)
{
s[len++] = '[';
if (feature->start)
@@ -255,7 +255,7 @@ hb_shape_full (hb_font_t *font,
assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
- buffer->guess_properties ();
+ buffer->guess_segment_properties ();
hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
diff --git a/third_party/harfbuzz-ng/src/hb-shape.h b/third_party/harfbuzz-ng/src/hb-shape.h
index 90a188d..10a35cb 100644
--- a/third_party/harfbuzz-ng/src/hb-shape.h
+++ b/third_party/harfbuzz-ng/src/hb-shape.h
@@ -52,7 +52,7 @@ hb_bool_t
hb_feature_from_string (const char *str, int len,
hb_feature_t *feature);
-/* something like 128 bytes is more than enough.
+/* Something like 128 bytes is more than enough.
* nul-terminates. */
void
hb_feature_to_string (hb_feature_t *feature,
diff --git a/third_party/harfbuzz-ng/src/hb-shaper-list.hh b/third_party/harfbuzz-ng/src/hb-shaper-list.hh
index 6c02de4..b9c029e 100644
--- a/third_party/harfbuzz-ng/src/hb-shaper-list.hh
+++ b/third_party/harfbuzz-ng/src/hb-shaper-list.hh
@@ -29,15 +29,11 @@
#endif /* HB_SHAPER_LIST_HH */ /* Dummy header guards */
/* v--- Add new shapers in the right place here. */
+
#ifdef HAVE_GRAPHITE2
+/* Only picks up fonts that have a "Silf" table. */
HB_SHAPER_IMPLEMENT (graphite2)
#endif
-#ifdef HAVE_UNISCRIBE
-HB_SHAPER_IMPLEMENT (uniscribe)
-#endif
-#ifdef HAVE_CORETEXT
-HB_SHAPER_IMPLEMENT (coretext)
-#endif
#ifdef HAVE_OT
HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
@@ -46,9 +42,14 @@ HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
#ifdef HAVE_HB_OLD
HB_SHAPER_IMPLEMENT (old)
#endif
-
#ifdef HAVE_ICU_LE
HB_SHAPER_IMPLEMENT (icu_le)
#endif
+#ifdef HAVE_UNISCRIBE
+HB_SHAPER_IMPLEMENT (uniscribe)
+#endif
+#ifdef HAVE_CORETEXT
+HB_SHAPER_IMPLEMENT (coretext)
+#endif
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
diff --git a/third_party/harfbuzz-ng/src/hb-shaper-private.hh b/third_party/harfbuzz-ng/src/hb-shaper-private.hh
index 186318d..9d30c1e 100644
--- a/third_party/harfbuzz-ng/src/hb-shaper-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-shaper-private.hh
@@ -29,8 +29,6 @@
#include "hb-private.hh"
-#include "hb-shape-plan.h" /* TODO remove */
-
typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
hb_font_t *font,
hb_buffer_t *buffer,
diff --git a/third_party/harfbuzz-ng/src/hb-shaper.cc b/third_party/harfbuzz-ng/src/hb-shaper.cc
index a16ffc8..1c1aed9 100644
--- a/third_party/harfbuzz-ng/src/hb-shaper.cc
+++ b/third_party/harfbuzz-ng/src/hb-shaper.cc
@@ -25,8 +25,8 @@
*/
#include "hb-private.hh"
-
#include "hb-shaper-private.hh"
+#include "hb-atomic-private.hh"
static const hb_shaper_pair_t all_shapers[] = {
diff --git a/third_party/harfbuzz-ng/src/hb-tt-font.cc b/third_party/harfbuzz-ng/src/hb-tt-font.cc
index b7198ef..c503a40 100644
--- a/third_party/harfbuzz-ng/src/hb-tt-font.cc
+++ b/third_party/harfbuzz-ng/src/hb-tt-font.cc
@@ -68,7 +68,7 @@ _hb_tt_font_destroy (hb_tt_font_t *tt)
static inline const hhea&
_get_hhea (hb_face_t *face)
{
-// return likely (face->tt && face->tt->hhea) ? *face->tt->hhea : Null(hhea);
+ return likely (face->tt && face->tt->hhea) ? *face->tt->hhea : Null(hhea);
}
diff --git a/third_party/harfbuzz-ng/src/hb-ucdn.cc b/third_party/harfbuzz-ng/src/hb-ucdn.cc
index 3506304..61e6ad3 100644
--- a/third_party/harfbuzz-ng/src/hb-ucdn.cc
+++ b/third_party/harfbuzz-ng/src/hb-ucdn.cc
@@ -129,57 +129,60 @@ static const hb_script_t ucdn_script_translate[] =
static hb_unicode_combining_class_t
hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
- void *user_data)
+ void *user_data HB_UNUSED)
{
return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
}
static unsigned int
hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
- void *user_data)
+ void *user_data HB_UNUSED)
{
int w = ucdn_get_east_asian_width(unicode);
return (w == UCDN_EAST_ASIAN_F || w == UCDN_EAST_ASIAN_W) ? 2 : 1;
}
static hb_unicode_general_category_t
-hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode, void *user_data)
+hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
+ void *user_data HB_UNUSED)
{
return (hb_unicode_general_category_t)ucdn_get_general_category(unicode);
}
static hb_codepoint_t
hb_ucdn_mirroring(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
- void *user_data)
+ void *user_data HB_UNUSED)
{
return ucdn_mirror(unicode);
}
static hb_script_t
hb_ucdn_script(hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode,
- void *user_data)
+ void *user_data HB_UNUSED)
{
return ucdn_script_translate[ucdn_get_script(unicode)];
}
static hb_bool_t
-hb_ucdn_compose(hb_unicode_funcs_t *ufuncs, hb_codepoint_t a,
- hb_codepoint_t b, hb_codepoint_t *ab, void *user_data)
+hb_ucdn_compose(hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab,
+ void *user_data HB_UNUSED)
{
return ucdn_compose(ab, a, b);
}
static hb_bool_t
-hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs, hb_codepoint_t ab,
- hb_codepoint_t *a, hb_codepoint_t *b, void *user_data)
+hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b,
+ void *user_data HB_UNUSED)
{
return ucdn_decompose(ab, a, b);
}
static unsigned int
-hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs, hb_codepoint_t u,
- hb_codepoint_t *decomposed, void *user_data)
+hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t u, hb_codepoint_t *decomposed,
+ void *user_data HB_UNUSED)
{
return ucdn_compat_decompose(u, decomposed);
}
diff --git a/third_party/harfbuzz-ng/src/hb-uniscribe.cc b/third_party/harfbuzz-ng/src/hb-uniscribe.cc
index 18b88b2..2f01c28 100644
--- a/third_party/harfbuzz-ng/src/hb-uniscribe.cc
+++ b/third_party/harfbuzz-ng/src/hb-uniscribe.cc
@@ -188,6 +188,22 @@ _hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_shaper_font_data_t *data)
free (data);
}
+LOGFONTW *
+hb_uniscribe_font_get_logfontw (hb_font_t *font)
+{
+ if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return NULL;
+ hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+ return &font_data->log_font;
+}
+
+HFONT
+hb_uniscribe_font_get_hfont (hb_font_t *font)
+{
+ if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return NULL;
+ hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
+ return font_data->hfont;
+}
+
/*
* shaper shape_plan data
@@ -213,23 +229,6 @@ _hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shaper_shape_plan_dat
* shaper
*/
-LOGFONTW *
-hb_uniscribe_font_get_logfontw (hb_font_t *font)
-{
- if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return NULL;
- return NULL;
- hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
- return &font_data->log_font;
-}
-
-HFONT
-hb_uniscribe_font_get_hfont (hb_font_t *font)
-{
- if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return NULL;
- hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
- return font_data->hfont;
-}
-
hb_bool_t
_hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
diff --git a/third_party/harfbuzz-ng/src/hb-utf-private.hh b/third_party/harfbuzz-ng/src/hb-utf-private.hh
index 8cde827..b9a6519 100644
--- a/third_party/harfbuzz-ng/src/hb-utf-private.hh
+++ b/third_party/harfbuzz-ng/src/hb-utf-private.hh
@@ -77,8 +77,8 @@ hb_utf_prev (const uint8_t *text,
const uint8_t *start,
hb_codepoint_t *unicode)
{
- const uint8_t *end = text;
- while (start < text && (*--text & 0xc0) == 0x80 && end - text < 4)
+ const uint8_t *end = text--;
+ while (start < text && (*text & 0xc0) == 0x80 && end - text < 4)
text--;
hb_codepoint_t c = *text, mask;
@@ -176,7 +176,7 @@ hb_utf_strlen (const uint16_t *text)
static inline const uint32_t *
hb_utf_next (const uint32_t *text,
- const uint32_t *end,
+ const uint32_t *end HB_UNUSED,
hb_codepoint_t *unicode)
{
*unicode = *text++;
@@ -185,7 +185,7 @@ hb_utf_next (const uint32_t *text,
static inline const uint32_t *
hb_utf_prev (const uint32_t *text,
- const uint32_t *start,
+ const uint32_t *start HB_UNUSED,
hb_codepoint_t *unicode)
{
*unicode = *--text;
diff --git a/third_party/harfbuzz-ng/src/hb.h b/third_party/harfbuzz-ng/src/hb.h
index d36040e2..52c479c 100644
--- a/third_party/harfbuzz-ng/src/hb.h
+++ b/third_party/harfbuzz-ng/src/hb.h
@@ -34,6 +34,7 @@
#include "hb-font.h"
#include "hb-set.h"
#include "hb-shape.h"
+#include "hb-shape-plan.h"
#include "hb-unicode.h"
#include "hb-version.h"
diff --git a/third_party/harfbuzz-ng/src/test-size-params.cc b/third_party/harfbuzz-ng/src/test-size-params.cc
new file mode 100644
index 0000000..947b566
--- /dev/null
+++ b/third_party/harfbuzz-ng/src/test-size-params.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2010,2011 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hb.h"
+#include "hb-ot.h"
+
+#ifdef HAVE_GLIB
+#include <glib.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ hb_blob_t *blob = NULL;
+
+ if (argc != 2) {
+ fprintf (stderr, "usage: %s font-file\n", argv[0]);
+ exit (1);
+ }
+
+ /* Create the blob */
+ {
+ const char *font_data;
+ unsigned int len;
+ hb_destroy_func_t destroy;
+ void *user_data;
+ hb_memory_mode_t mm;
+
+#ifdef HAVE_GLIB
+ GMappedFile *mf = g_mapped_file_new (argv[1], false, NULL);
+ font_data = g_mapped_file_get_contents (mf);
+ len = g_mapped_file_get_length (mf);
+ destroy = (hb_destroy_func_t) g_mapped_file_unref;
+ user_data = (void *) mf;
+ mm = HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE;
+#else
+ FILE *f = fopen (argv[1], "rb");
+ fseek (f, 0, SEEK_END);
+ len = ftell (f);
+ fseek (f, 0, SEEK_SET);
+ font_data = (const char *) malloc (len);
+ if (!font_data) len = 0;
+ len = fread ((char *) font_data, 1, len, f);
+ destroy = free;
+ user_data = (void *) font_data;
+ fclose (f);
+ mm = HB_MEMORY_MODE_WRITABLE;
+#endif
+
+ blob = hb_blob_create (font_data, len, mm, user_data, destroy);
+ }
+
+ /* Create the face */
+ hb_face_t *face = hb_face_create (blob, 0 /* first face */);
+ hb_blob_destroy (blob);
+ blob = NULL;
+
+ unsigned int p[5];
+ bool ret = hb_ot_layout_get_size_params (face, p, p+1, p+2, p+3, p+4);
+
+ printf ("%g %u %u %g %g\n", p[0]/10., p[1], p[2], p[3]/10., p[4]/10.);
+
+ return !ret;
+}
diff --git a/third_party/harfbuzz-ng/src/test-would-substitute.cc b/third_party/harfbuzz-ng/src/test-would-substitute.cc
index d15aec4..4731e26 100644
--- a/third_party/harfbuzz-ng/src/test-would-substitute.cc
+++ b/third_party/harfbuzz-ng/src/test-would-substitute.cc
@@ -99,5 +99,5 @@ main (int argc, char **argv)
(argc > 4 &&
!hb_font_glyph_from_string (font, argv[4], -1, &glyphs[1])))
return 2;
- return !hb_ot_layout_would_substitute_lookup (face, strtol (argv[2], NULL, 0), glyphs, len, false);
+ return !hb_ot_layout_lookup_would_substitute (face, strtol (argv[2], NULL, 0), glyphs, len, false);
}