summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2013-12-16 08:49:48 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-19 05:49:27 +0100
commit260fe985255c46fd2eb0aff378da8dccb5f2703f (patch)
tree11691b16243276c1b88c23d470cdb48e5f3fa1a2 /src
parent4b2c73b4767bcb512cbc17f65186eac5d004db07 (diff)
Update bundled HarfBuzz sources up to 0.9.25
Most important changes: - Myanmar, Indic, Javanese / Buginese shaper improvements - More aggressive shape-plan caching - Additional OpenType language tags Change-Id: I54ed62cfe936c06c18589d09ac119a0f5881a235 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/harfbuzz-ng/NEWS55
-rw-r--r--src/3rdparty/harfbuzz-ng/TODO8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-blob.cc152
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc71
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.cc446
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.h16
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.cc161
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-common.h4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face-private.hh1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-face.cc172
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font-private.hh15
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.cc517
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-font.h132
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh136
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh95
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh442
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh229
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh403
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc58
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc10
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc21
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh40
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc358
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc35
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc73
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc29
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc156
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc315
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-private.hh3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-private.hh21
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.cc244
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set.h2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc173
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-shape.cc56
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.cc128
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-unicode.h106
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-version.h4
-rw-r--r--src/3rdparty/harfbuzz.pri1
56 files changed, 3945 insertions, 1017 deletions
diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS
index dc89614e07..0a2477268a 100644
--- a/src/3rdparty/harfbuzz-ng/NEWS
+++ b/src/3rdparty/harfbuzz-ng/NEWS
@@ -1,3 +1,58 @@
+Overview of changes leading to 0.9.25
+Wednesday, December 4, 2013
+=====================================
+
+- Myanmar shaper improvements.
+- Avoid font fallback in CoreText backend.
+- Additional OpenType language tag mappiongs.
+- More aggressive shape-plan caching.
+- Build with / require automake 1.13.
+- Build with libtool 2.4.2.418 alpha to support ppc64le.
+
+
+Overview of changes leading to 0.9.24
+Tuesday, November 13, 2013
+=====================================
+
+- Misc compiler warning fixes with clang.
+- No functional changes.
+
+
+Overview of changes leading to 0.9.23
+Monday, October 28, 2013
+=====================================
+
+- "Udupi HarfBuzz Hackfest", Paris, October 14..18 2013.
+- Fix (Chain)Context recursion with non-monotone lookup positions.
+- Misc Indic bug fixes.
+- New Javanese / Buginese shaping, similar to Windows 8.1.
+
+
+Overview of changes leading to 0.9.22
+Thursday, October 3, 2013
+=====================================
+
+- Fix use-after-end-of-scope in hb_language_from_string().
+- Fix hiding of default_ignorables if font doesn't have space glyph.
+- Protect against out-of-range lookup indices.
+
+- API Changes:
+
+ * Added hb_ot_layout_table_get_lookup_count()
+
+
+Overview of changes leading to 0.9.21
+Monday, September 16, 2013
+=====================================
+
+- Rename gobject-introspection library name from harfbuzz to HarfBuzz.
+- Remove (long disabled) hb-old and hb-icu-le test shapers.
+- Misc gtk-doc and gobject-introspection annotations.
+- Misc fixes.
+- API changes:
+
+ * Add HB_SET_VALUE_INVALID
+
Overview of changes leading to 0.9.20
Thursday, August 29, 2013
=====================================
diff --git a/src/3rdparty/harfbuzz-ng/TODO b/src/3rdparty/harfbuzz-ng/TODO
index 4808391b4e..e1aa39c4c0 100644
--- a/src/3rdparty/harfbuzz-ng/TODO
+++ b/src/3rdparty/harfbuzz-ng/TODO
@@ -12,6 +12,8 @@ General fixes:
- Warn at compile time (and runtime with HB_DEBUG?) if no Unicode / font
funcs found / set.
+- Do proper rounding when scaling from font space? May be a non-issue.
+
- Misc features:
* init/medi/fina/isol for non-cursive scripts
@@ -43,11 +45,9 @@ API additions
- Add sanitize API (and a cached version, that saves result on blob user-data)
-- Add glib GBoxedType stuff and introspection
-
- BCP 47 language handling / API (language_matches?)
-- Add hb_font_create_linear()?
+- Add hb_font_create_unscaled()?
- Add query / enumeration API for aalt-like features?
@@ -61,7 +61,7 @@ API additions
hb-view / hb-shape enhancements:
===============================
-- Add --width, --height, --auto-size, --align, etc?
+- Add --width, --height, --auto-size, --ink-box, --align, etc?
Tests to write:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
index 9cc3bc5587..b5d64853ea 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh
@@ -78,7 +78,7 @@ typedef int32_t hb_atomic_int_t;
#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__
+#if __ppc64__ || __x86_64__ || __arm64__
#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))
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
index dfd134b776..d6acca0fca 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc
@@ -29,7 +29,6 @@
#include "hb-private.hh"
-#include "hb-blob.h"
#include "hb-object-private.hh"
#ifdef HAVE_SYS_MMAN_H
@@ -76,6 +75,22 @@ _hb_blob_destroy_user_data (hb_blob_t *blob)
}
}
+/**
+ * hb_blob_create: (Xconstructor)
+ * @data: (array length=length) (closure user_data) (destroy destroy) (scope notified) (transfer none): Pointer to blob data.
+ * @length: Length of @data in bytes.
+ * @mode: Memory mode for @data.
+ * @user_data: Data parameter to pass to @destroy.
+ * @destroy: Callback to call when @data is not needed anymore.
+ *
+ * Creates a new "blob" object wrapping @data. The @mode parameter is used
+ * to negotiate ownership and lifecycle of @data.
+ *
+ * Return value: New blob, or the empty blob if something failed or if @length is
+ * zero. Destroy with hb_blob_destroy().
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_blob_create (const char *data,
unsigned int length,
@@ -109,6 +124,26 @@ hb_blob_create (const char *data,
return blob;
}
+/**
+ * hb_blob_create_sub_blob:
+ * @parent: Parent blob.
+ * @offset: Start offset of sub-blob within @parent, in bytes.
+ * @length: Length of sub-blob.
+ *
+ * Returns a blob that represents a range of bytes in @parent. The new
+ * blob is always created with %HB_MEMORY_MODE_READONLY, meaning that it
+ * will never modify data in the parent blob. The parent data is not
+ * expected to be modified, and will result in undefined behavior if it
+ * is.
+ *
+ * Makes @parent immutable.
+ *
+ * Return value: New blob, or the empty blob if something failed or if
+ * @length is zero or @offset is beyond the end of @parent's data. Destroy
+ * with hb_blob_destroy().
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_blob_create_sub_blob (hb_blob_t *parent,
unsigned int offset,
@@ -130,6 +165,17 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
return blob;
}
+/**
+ * hb_blob_get_empty:
+ *
+ * Returns the singleton empty blob.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Return value: (transfer full): the empty blob.
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_blob_get_empty (void)
{
@@ -149,12 +195,36 @@ hb_blob_get_empty (void)
return const_cast<hb_blob_t *> (&_hb_blob_nil);
}
+/**
+ * hb_blob_reference: (skip)
+ * @blob: a blob.
+ *
+ * Increases the reference count on @blob.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Return value: @blob.
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_blob_reference (hb_blob_t *blob)
{
return hb_object_reference (blob);
}
+/**
+ * hb_blob_destroy: (skip)
+ * @blob: a blob.
+ *
+ * Descreases the reference count on @blob, and if it reaches zero, destroys
+ * @blob, freeing all memory, possibly calling the destroy-callback the blob
+ * was created for if it has not been called already.
+ *
+ * See TODO:link object types for more information.
+ *
+ * Since: 1.0
+ **/
void
hb_blob_destroy (hb_blob_t *blob)
{
@@ -165,6 +235,18 @@ hb_blob_destroy (hb_blob_t *blob)
free (blob);
}
+/**
+ * hb_blob_set_user_data: (skip)
+ * @blob: a blob.
+ * @key: key for data to set.
+ * @data: data to set.
+ * @destroy: callback to call when @data is not needed anymore.
+ * @replace: whether to replace an existing data with the same key.
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_blob_set_user_data (hb_blob_t *blob,
hb_user_data_key_t *key,
@@ -175,6 +257,17 @@ hb_blob_set_user_data (hb_blob_t *blob,
return hb_object_set_user_data (blob, key, data, destroy, replace);
}
+/**
+ * hb_blob_get_user_data: (skip)
+ * @blob: a blob.
+ * @key: key for data to get.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_blob_get_user_data (hb_blob_t *blob,
hb_user_data_key_t *key)
@@ -183,6 +276,14 @@ hb_blob_get_user_data (hb_blob_t *blob,
}
+/**
+ * hb_blob_make_immutable:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_blob_make_immutable (hb_blob_t *blob)
{
@@ -192,6 +293,16 @@ hb_blob_make_immutable (hb_blob_t *blob)
blob->immutable = true;
}
+/**
+ * hb_blob_is_immutable:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Return value: TODO
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_blob_is_immutable (hb_blob_t *blob)
{
@@ -199,12 +310,33 @@ hb_blob_is_immutable (hb_blob_t *blob)
}
+/**
+ * hb_blob_get_length:
+ * @blob: a blob.
+ *
+ *
+ *
+ * Return value: the length of blob data in bytes.
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_blob_get_length (hb_blob_t *blob)
{
return blob->length;
}
+/**
+ * hb_blob_get_data:
+ * @blob: a blob.
+ * @length: (out):
+ *
+ *
+ *
+ * Returns: (transfer none) (array length=length):
+ *
+ * Since: 1.0
+ **/
const char *
hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
{
@@ -214,6 +346,22 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length)
return blob->data;
}
+/**
+ * hb_blob_get_data_writable:
+ * @blob: a blob.
+ * @length: (out): output length of the writable data.
+ *
+ * Tries to make blob data writable (possibly copying it) and
+ * return pointer to data.
+ *
+ * Fails if blob has been made immutable, or if memory allocation
+ * fails.
+ *
+ * Returns: (transfer none) (array length=length): Writable blob data,
+ * or %NULL if failed.
+ *
+ * Since: 1.0
+ **/
char *
hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length)
{
@@ -324,5 +472,3 @@ _try_writable (hb_blob_t *blob)
return true;
}
-
-
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
index a8cf770244..3a2b9ab481 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh
@@ -31,7 +31,6 @@
#define HB_BUFFER_PRIVATE_HH
#include "hb-private.hh"
-#include "hb-buffer.h"
#include "hb-object-private.hh"
#include "hb-unicode-private.hh"
@@ -103,6 +102,8 @@ struct hb_buffer_t {
inline unsigned int backtrack_len (void) const
{ return have_output? out_len : idx; }
+ inline unsigned int lookahead_len (void) const
+ { return len - idx; }
inline unsigned int next_serial (void) { return serial++; }
HB_INTERNAL void allocate_var (unsigned int byte_i, unsigned int count, const char *owner);
@@ -134,6 +135,7 @@ struct hb_buffer_t {
HB_INTERNAL void output_info (const hb_glyph_info_t &glyph_info);
/* Copies glyph at idx to output but doesn't advance idx */
HB_INTERNAL void copy_glyph (void);
+ HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
/* Copies glyph at idx to output and advance idx.
* If there's no output, just advance idx. */
inline void
@@ -178,11 +180,13 @@ struct hb_buffer_t {
HB_INTERNAL bool enlarge (unsigned int size);
inline bool ensure (unsigned int size)
- { return likely (size < allocated) ? true : enlarge (size); }
+ { return likely (!size || size < allocated) ? true : enlarge (size); }
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
+ HB_INTERNAL bool shift_forward (unsigned int count);
- HB_INTERNAL void *get_scratch_buffer (unsigned int *size);
+ typedef long scratch_buffer_t;
+ HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
inline void clear_context (unsigned int side) { context_len[side] = 0; }
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
index eac69000dd..4541db23bd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc
@@ -33,12 +33,32 @@ static const char *serialize_formats[] = {
NULL
};
+/**
+ * hb_buffer_serialize_list_formats:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char **
hb_buffer_serialize_list_formats (void)
{
return serialize_formats;
}
+/**
+ * hb_buffer_serialize_format_from_string:
+ * @str:
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_buffer_serialize_format_t
hb_buffer_serialize_format_from_string (const char *str, int len)
{
@@ -46,6 +66,16 @@ hb_buffer_serialize_format_from_string (const char *str, int len)
return (hb_buffer_serialize_format_t) (hb_tag_from_string (str, len) & ~0x20202020);
}
+/**
+ * hb_buffer_serialize_format_to_string:
+ * @format:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
const char *
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
@@ -116,9 +146,9 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
*p++ = '}';
- if (buf_size > (p - b))
+ unsigned int l = p - b;
+ if (buf_size > l)
{
- unsigned int l = p - b;
memcpy (buf, b, l);
buf += l;
buf_size -= l;
@@ -178,9 +208,9 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
}
- if (buf_size > (p - b))
+ unsigned int l = p - b;
+ if (buf_size > l)
{
- unsigned int l = p - b;
memcpy (buf, b, l);
buf += l;
buf_size -= l;
@@ -194,6 +224,24 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
}
/* Returns number of items, starting at start, that were serialized. */
+/**
+ * hb_buffer_serialize_glyphs:
+ * @buffer: a buffer.
+ * @start:
+ * @end:
+ * @buf: (array length=buf_size):
+ * @buf_size:
+ * @buf_consumed: (out):
+ * @font:
+ * @format:
+ * @flags:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
unsigned int start,
@@ -286,6 +334,21 @@ parse_int (const char *pp, const char *end, int32_t *pv)
#include "hb-buffer-deserialize-json.hh"
#include "hb-buffer-deserialize-text.hh"
+/**
+ * hb_buffer_deserialize_glyphs:
+ * @buffer: a buffer.
+ * @buf: (array length=buf_len):
+ * @buf_len:
+ * @end_ptr: (out):
+ * @font:
+ * @format:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
const char *buf,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
index 340bd5351b..d6c6fcb8e6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
@@ -139,7 +139,20 @@ hb_buffer_t::make_room_for (unsigned int num_in,
return true;
}
-void *
+bool
+hb_buffer_t::shift_forward (unsigned int count)
+{
+ assert (have_output);
+ if (unlikely (!ensure (len + count))) return false;
+
+ memmove (info + idx + count, info + idx, (len - idx) * sizeof (info[0]));
+ len += count;
+ idx += count;
+
+ return true;
+}
+
+hb_buffer_t::scratch_buffer_t *
hb_buffer_t::get_scratch_buffer (unsigned int *size)
{
have_output = false;
@@ -148,8 +161,9 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
out_len = 0;
out_info = info;
- *size = allocated * sizeof (pos[0]);
- return pos;
+ assert ((uintptr_t) pos % sizeof (scratch_buffer_t) == 0);
+ *size = allocated * sizeof (pos[0]) / sizeof (scratch_buffer_t);
+ return (scratch_buffer_t *) (void *) pos;
}
@@ -345,6 +359,44 @@ hb_buffer_t::copy_glyph (void)
out_len++;
}
+bool
+hb_buffer_t::move_to (unsigned int i)
+{
+ if (!have_output)
+ {
+ assert (i <= len);
+ idx = i;
+ return true;
+ }
+
+ assert (i <= out_len + (len - idx));
+
+ if (out_len < i)
+ {
+ unsigned int count = i - out_len;
+ if (unlikely (!make_room_for (count, count))) return false;
+
+ memmove (out_info + out_len, info + idx, count * sizeof (out_info[0]));
+ idx += count;
+ out_len += count;
+ }
+ else if (out_len > i)
+ {
+ /* Tricky part: rewinding... */
+ unsigned int count = out_len - i;
+
+ if (unlikely (idx < count && !shift_forward (count + 32))) return false;
+
+ assert (idx >= count);
+
+ idx -= count;
+ out_len -= count;
+ memmove (info + idx, out_info + out_len, count * sizeof (out_info[0]));
+ }
+
+ return true;
+}
+
void
hb_buffer_t::replace_glyph (hb_codepoint_t glyph_index)
{
@@ -603,6 +655,15 @@ void hb_buffer_t::deallocate_var_all (void)
/* Public API */
+/**
+ * hb_buffer_create: (Xconstructor)
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 1.0
+ **/
hb_buffer_t *
hb_buffer_create (void)
{
@@ -616,6 +677,15 @@ hb_buffer_create (void)
return buffer;
}
+/**
+ * hb_buffer_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_buffer_t *
hb_buffer_get_empty (void)
{
@@ -637,12 +707,30 @@ hb_buffer_get_empty (void)
return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
}
+/**
+ * hb_buffer_reference: (skip)
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_buffer_t *
hb_buffer_reference (hb_buffer_t *buffer)
{
return hb_object_reference (buffer);
}
+/**
+ * hb_buffer_destroy: (skip)
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_destroy (hb_buffer_t *buffer)
{
@@ -656,6 +744,20 @@ hb_buffer_destroy (hb_buffer_t *buffer)
free (buffer);
}
+/**
+ * hb_buffer_set_user_data: (skip)
+ * @buffer: a buffer.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_set_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key,
@@ -666,6 +768,17 @@ hb_buffer_set_user_data (hb_buffer_t *buffer,
return hb_object_set_user_data (buffer, key, data, destroy, replace);
}
+/**
+ * hb_buffer_get_user_data: (skip)
+ * @buffer: a buffer.
+ * @key:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
void *
hb_buffer_get_user_data (hb_buffer_t *buffer,
hb_user_data_key_t *key)
@@ -674,6 +787,15 @@ hb_buffer_get_user_data (hb_buffer_t *buffer,
}
+/**
+ * hb_buffer_set_content_type:
+ * @buffer: a buffer.
+ * @content_type:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_content_type (hb_buffer_t *buffer,
hb_buffer_content_type_t content_type)
@@ -681,6 +803,16 @@ hb_buffer_set_content_type (hb_buffer_t *buffer,
buffer->content_type = content_type;
}
+/**
+ * hb_buffer_get_content_type:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_buffer_content_type_t
hb_buffer_get_content_type (hb_buffer_t *buffer)
{
@@ -688,28 +820,56 @@ hb_buffer_get_content_type (hb_buffer_t *buffer)
}
+/**
+ * hb_buffer_set_unicode_funcs:
+ * @buffer: a buffer.
+ * @unicode_funcs:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_unicode_funcs (hb_buffer_t *buffer,
- hb_unicode_funcs_t *unicode)
+ hb_unicode_funcs_t *unicode_funcs)
{
if (unlikely (hb_object_is_inert (buffer)))
return;
- if (!unicode)
- unicode = hb_unicode_funcs_get_default ();
+ if (!unicode_funcs)
+ unicode_funcs = hb_unicode_funcs_get_default ();
- hb_unicode_funcs_reference (unicode);
+ hb_unicode_funcs_reference (unicode_funcs);
hb_unicode_funcs_destroy (buffer->unicode);
- buffer->unicode = unicode;
+ buffer->unicode = unicode_funcs;
}
+/**
+ * hb_buffer_get_unicode_funcs:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_buffer_get_unicode_funcs (hb_buffer_t *buffer)
{
return buffer->unicode;
}
+/**
+ * hb_buffer_set_direction:
+ * @buffer: a buffer.
+ * @direction:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_direction (hb_buffer_t *buffer,
hb_direction_t direction)
@@ -721,12 +881,31 @@ hb_buffer_set_direction (hb_buffer_t *buffer,
buffer->props.direction = direction;
}
+/**
+ * hb_buffer_get_direction:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_direction_t
hb_buffer_get_direction (hb_buffer_t *buffer)
{
return buffer->props.direction;
}
+/**
+ * hb_buffer_set_script:
+ * @buffer: a buffer.
+ * @script:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_script (hb_buffer_t *buffer,
hb_script_t script)
@@ -737,12 +916,31 @@ hb_buffer_set_script (hb_buffer_t *buffer,
buffer->props.script = script;
}
+/**
+ * hb_buffer_get_script:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_script_t
hb_buffer_get_script (hb_buffer_t *buffer)
{
return buffer->props.script;
}
+/**
+ * hb_buffer_set_language:
+ * @buffer: a buffer.
+ * @language:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_language (hb_buffer_t *buffer,
hb_language_t language)
@@ -753,12 +951,31 @@ hb_buffer_set_language (hb_buffer_t *buffer,
buffer->props.language = language;
}
+/**
+ * hb_buffer_get_language:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_language_t
hb_buffer_get_language (hb_buffer_t *buffer)
{
return buffer->props.language;
}
+/**
+ * hb_buffer_set_segment_properties:
+ * @buffer: a buffer.
+ * @props:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_segment_properties (hb_buffer_t *buffer,
const hb_segment_properties_t *props)
@@ -769,6 +986,15 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
buffer->props = *props;
}
+/**
+ * hb_buffer_get_segment_properties:
+ * @buffer: a buffer.
+ * @props:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_get_segment_properties (hb_buffer_t *buffer,
hb_segment_properties_t *props)
@@ -777,6 +1003,15 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer,
}
+/**
+ * hb_buffer_set_flags:
+ * @buffer: a buffer.
+ * @flags:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_set_flags (hb_buffer_t *buffer,
hb_buffer_flags_t flags)
@@ -787,6 +1022,16 @@ hb_buffer_set_flags (hb_buffer_t *buffer,
buffer->flags = flags;
}
+/**
+ * hb_buffer_get_flags:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_buffer_flags_t
hb_buffer_get_flags (hb_buffer_t *buffer)
{
@@ -794,30 +1039,77 @@ hb_buffer_get_flags (hb_buffer_t *buffer)
}
+/**
+ * hb_buffer_reset:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_reset (hb_buffer_t *buffer)
{
buffer->reset ();
}
+/**
+ * hb_buffer_clear_contents:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_clear_contents (hb_buffer_t *buffer)
{
buffer->clear ();
}
+/**
+ * hb_buffer_pre_allocate:
+ * @buffer: a buffer.
+ * @size:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size)
{
return buffer->ensure (size);
}
+/**
+ * hb_buffer_allocation_successful:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_allocation_successful (hb_buffer_t *buffer)
{
return !buffer->in_error;
}
+/**
+ * hb_buffer_add:
+ * @buffer: a buffer.
+ * @codepoint:
+ * @cluster:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_add (hb_buffer_t *buffer,
hb_codepoint_t codepoint,
@@ -827,6 +1119,17 @@ hb_buffer_add (hb_buffer_t *buffer,
buffer->clear_context (1);
}
+/**
+ * hb_buffer_set_length:
+ * @buffer: a buffer.
+ * @length:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_buffer_set_length (hb_buffer_t *buffer,
unsigned int length)
@@ -847,19 +1150,43 @@ hb_buffer_set_length (hb_buffer_t *buffer,
buffer->len = length;
if (!length)
+ {
+ buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
buffer->clear_context (0);
+ }
buffer->clear_context (1);
return true;
}
+/**
+ * hb_buffer_get_length:
+ * @buffer: a buffer.
+ *
+ * Returns the number of items in the buffer.
+ *
+ * Return value: buffer length.
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_buffer_get_length (hb_buffer_t *buffer)
{
return buffer->len;
}
-/* Return value valid as long as buffer not modified */
+/**
+ * hb_buffer_get_glyph_infos:
+ * @buffer: a buffer.
+ * @length: (out): output array length.
+ *
+ * Returns buffer glyph information array. Returned pointer
+ * is valid as long as buffer contents are not modified.
+ *
+ * Return value: (transfer none) (array length=length): buffer glyph information array.
+ *
+ * Since: 1.0
+ **/
hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
unsigned int *length)
@@ -870,7 +1197,18 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
return (hb_glyph_info_t *) buffer->info;
}
-/* Return value valid as long as buffer not modified */
+/**
+ * hb_buffer_get_glyph_positions:
+ * @buffer: a buffer.
+ * @length: (out): output length.
+ *
+ * Returns buffer glyph position array. Returned pointer
+ * is valid as long as buffer contents are not modified.
+ *
+ * Return value: (transfer none) (array length=length): buffer glyph position array.
+ *
+ * Since: 1.0
+ **/
hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
unsigned int *length)
@@ -884,18 +1222,60 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
return (hb_glyph_position_t *) buffer->pos;
}
+/**
+ * hb_buffer_reverse:
+ * @buffer: a buffer.
+ *
+ * Reverses buffer contents.
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_reverse (hb_buffer_t *buffer)
{
buffer->reverse ();
}
+/**
+ * hb_buffer_reverse_clusters:
+ * @buffer: a buffer.
+ *
+ * Reverses buffer clusters. That is, the buffer contents are
+ * reversed, then each cluster (consecutive items having the
+ * same cluster number) are reversed again.
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_reverse_clusters (hb_buffer_t *buffer)
{
buffer->reverse_clusters ();
}
+/**
+ * hb_buffer_guess_segment_properties:
+ * @buffer: a buffer.
+ *
+ * Sets unset buffer segment properties based on buffer Unicode
+ * contents. If buffer is not empty, it must have content type
+ * %HB_BUFFER_CONTENT_TYPE_UNICODE.
+ *
+ * If buffer script is not set (ie. is %HB_SCRIPT_INVALID), it
+ * will be set to the Unicode script of the first character in
+ * the buffer that has a script other than %HB_SCRIPT_COMMON,
+ * %HB_SCRIPT_INHERITED, and %HB_SCRIPT_UNKNOWN.
+ *
+ * Next, if buffer direction is not set (ie. is %HB_DIRECTION_INVALID),
+ * it will be set to the natural horizontal direction of the
+ * buffer script as returned by hb_script_get_horizontal_direction().
+ *
+ * Finally, if buffer language is not set (ie. is %HB_LANGUAGE_INVALID),
+ * it will be set to the process's default language as returned by
+ * hb_language_get_default(). This may change in the future by
+ * taking buffer script into consideration when choosing a language.
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
{
@@ -968,6 +1348,18 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
}
+/**
+ * hb_buffer_add_utf8:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_add_utf8 (hb_buffer_t *buffer,
const char *text,
@@ -978,16 +1370,40 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
hb_buffer_add_utf (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
}
+/**
+ * hb_buffer_add_utf16:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_add_utf16 (hb_buffer_t *buffer,
const uint16_t *text,
int text_length,
unsigned int item_offset,
- int item_length)
+ int item_length)
{
hb_buffer_add_utf (buffer, text, text_length, item_offset, item_length);
}
+/**
+ * hb_buffer_add_utf32:
+ * @buffer: a buffer.
+ * @text: (array length=text_length):
+ * @text_length:
+ * @item_offset:
+ * @item_length:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_add_utf32 (hb_buffer_t *buffer,
const uint32_t *text,
@@ -1054,6 +1470,14 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
}
}
+/**
+ * hb_buffer_normalize_glyphs:
+ * @buffer: a buffer.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_buffer_normalize_glyphs (hb_buffer_t *buffer)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
index 87c4ce58e8..3086851b01 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h
@@ -172,10 +172,10 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
typedef enum { /*< flags >*/
- HB_BUFFER_FLAG_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_FLAG_DEFAULT = 0x00000000u,
+ HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */
+ HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */
+ HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u
} hb_buffer_flags_t;
void
@@ -275,10 +275,10 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
*/
typedef enum { /*< flags >*/
- HB_BUFFER_SERIALIZE_FLAG_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_FLAG_DEFAULT = 0x00000000u,
+ HB_BUFFER_SERIALIZE_FLAG_NO_CLUSTERS = 0x00000001u,
+ HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u,
+ HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u
} hb_buffer_serialize_flags_t;
typedef enum {
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
index 7c6d26290d..0fd790bc04 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc
@@ -28,8 +28,6 @@
#include "hb-private.hh"
-#include "hb-version.h"
-
#include "hb-mutex-private.hh"
#include "hb-object-private.hh"
@@ -57,25 +55,45 @@ _hb_options_init (void)
/* hb_tag_t */
+/**
+ * hb_tag_from_string:
+ * @str: (array length=len):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_tag_t
-hb_tag_from_string (const char *s, int len)
+hb_tag_from_string (const char *str, int len)
{
char tag[4];
unsigned int i;
- if (!s || !len || !*s)
+ if (!str || !len || !*str)
return HB_TAG_NONE;
if (len < 0 || len > 4)
len = 4;
- for (i = 0; i < (unsigned) len && s[i]; i++)
- tag[i] = s[i];
+ for (i = 0; i < (unsigned) len && str[i]; i++)
+ tag[i] = str[i];
for (; i < 4; i++)
tag[i] = ' ';
return HB_TAG_CHAR4 (tag);
}
+/**
+ * hb_tag_to_string:
+ * @tag:
+ * @buf: (array fixed-size=4):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_tag_to_string (hb_tag_t tag, char *buf)
{
@@ -95,6 +113,17 @@ const char direction_strings[][4] = {
"btt"
};
+/**
+ * hb_direction_from_string:
+ * @str: (array length=len):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_direction_t
hb_direction_from_string (const char *str, int len)
{
@@ -112,6 +141,16 @@ hb_direction_from_string (const char *str, int len)
return HB_DIRECTION_INVALID;
}
+/**
+ * hb_direction_to_string:
+ * @direction:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char *
hb_direction_to_string (hb_direction_t direction)
{
@@ -187,7 +226,7 @@ struct hb_language_item_t {
return *this;
}
- void finish (void) { free (lang); }
+ void finish (void) { free ((void *) lang); }
};
@@ -237,14 +276,27 @@ retry:
}
+/**
+ * hb_language_from_string:
+ * @str: (array length=len):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_language_t
hb_language_from_string (const char *str, int len)
{
+ char strbuf[64];
+
if (!str || !len || !*str)
return HB_LANGUAGE_INVALID;
- if (len >= 0) {
- char strbuf[64];
+ if (len >= 0)
+ {
len = MIN (len, (int) sizeof (strbuf) - 1);
str = (char *) memcpy (strbuf, str, len);
strbuf[len] = '\0';
@@ -255,6 +307,16 @@ hb_language_from_string (const char *str, int len)
return likely (item) ? item->lang : HB_LANGUAGE_INVALID;
}
+/**
+ * hb_language_to_string:
+ * @language:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char *
hb_language_to_string (hb_language_t language)
{
@@ -262,6 +324,15 @@ hb_language_to_string (hb_language_t language)
return language->s;
}
+/**
+ * hb_language_get_default:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_language_t
hb_language_get_default (void)
{
@@ -279,6 +350,16 @@ hb_language_get_default (void)
/* hb_script_t */
+/**
+ * hb_script_from_iso15924_tag:
+ * @tag:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_script_t
hb_script_from_iso15924_tag (hb_tag_t tag)
{
@@ -313,18 +394,49 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
return HB_SCRIPT_UNKNOWN;
}
+/**
+ * hb_script_from_string:
+ * @s: (array length=len):
+ * @len:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_script_t
hb_script_from_string (const char *s, int len)
{
return hb_script_from_iso15924_tag (hb_tag_from_string (s, len));
}
+/**
+ * hb_script_to_iso15924_tag:
+ * @script:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_tag_t
hb_script_to_iso15924_tag (hb_script_t script)
{
return (hb_tag_t) script;
}
+/**
+ * hb_script_get_horizontal_direction:
+ * @script:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_direction_t
hb_script_get_horizontal_direction (hb_script_t script)
{
@@ -409,6 +521,16 @@ hb_user_data_array_t::get (hb_user_data_key_t *key)
/* hb_version */
+/**
+ * hb_version:
+ * @major: (out): Library major version component.
+ * @minor: (out): Library minor version component.
+ * @micro: (out): Library micro version component.
+ *
+ * Returns library version as three integer components.
+ *
+ * Since: 1.0
+ **/
void
hb_version (unsigned int *major,
unsigned int *minor,
@@ -419,12 +541,33 @@ hb_version (unsigned int *major,
*micro = HB_VERSION_MICRO;
}
+/**
+ * hb_version_string:
+ *
+ * Returns library version as a string with three components.
+ *
+ * Return value: library version string.
+ *
+ * Since: 1.0
+ **/
const char *
hb_version_string (void)
{
return HB_VERSION_STRING;
}
+/**
+ * hb_version_check:
+ * @major:
+ * @minor:
+ * @micro:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_version_check (unsigned int major,
unsigned int minor,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h
index 9079b2c046..e445504550 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-common.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h
@@ -90,7 +90,7 @@ typedef union _hb_var_int_t {
typedef uint32_t hb_tag_t;
-#define HB_TAG(a,b,c,d) ((hb_tag_t)((((uint8_t)(a))<<24)|(((uint8_t)(b))<<16)|(((uint8_t)(c))<<8)|((uint8_t)(d))))
+#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
#define HB_TAG_NONE HB_TAG(0,0,0,0)
@@ -131,7 +131,7 @@ hb_direction_to_string (hb_direction_t direction);
/* hb_language_t */
-typedef struct hb_language_impl_t *hb_language_t;
+typedef const struct hb_language_impl_t *hb_language_t;
/* len=-1 means str is NUL-terminated */
hb_language_t
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
index b33be0e5fc..6520d3dbdf 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face-private.hh
@@ -31,7 +31,6 @@
#include "hb-private.hh"
-#include "hb-font.h"
#include "hb-object-private.hh"
#include "hb-shaper-private.hh"
#include "hb-shape-plan-private.hh"
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
index d8b9ed8c3f..71cf49a5bc 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc
@@ -31,7 +31,6 @@
#include "hb-ot-layout-private.hh"
#include "hb-font-private.hh"
-#include "hb-blob.h"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
@@ -68,6 +67,18 @@ const hb_face_t _hb_face_nil = {
};
+/**
+ * hb_face_create_for_tables:
+ * @reference_table_func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
void *user_data,
@@ -137,6 +148,17 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
return blob;
}
+/**
+ * hb_face_create: (Xconstructor)
+ * @blob:
+ * @index:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_face_create (hb_blob_t *blob,
unsigned int index)
@@ -160,6 +182,15 @@ hb_face_create (hb_blob_t *blob,
return face;
}
+/**
+ * hb_face_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_face_get_empty (void)
{
@@ -167,12 +198,30 @@ hb_face_get_empty (void)
}
+/**
+ * hb_face_reference: (skip)
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_face_reference (hb_face_t *face)
{
return hb_object_reference (face);
}
+/**
+ * hb_face_destroy: (skip)
+ * @face: a face.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_destroy (hb_face_t *face)
{
@@ -196,6 +245,20 @@ hb_face_destroy (hb_face_t *face)
free (face);
}
+/**
+ * hb_face_set_user_data: (skip)
+ * @face: a face.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_face_set_user_data (hb_face_t *face,
hb_user_data_key_t *key,
@@ -206,6 +269,17 @@ hb_face_set_user_data (hb_face_t *face,
return hb_object_set_user_data (face, key, data, destroy, replace);
}
+/**
+ * hb_face_get_user_data: (skip)
+ * @face: a face.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key)
@@ -213,6 +287,14 @@ hb_face_get_user_data (hb_face_t *face,
return hb_object_get_user_data (face, key);
}
+/**
+ * hb_face_make_immutable:
+ * @face: a face.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_make_immutable (hb_face_t *face)
{
@@ -222,6 +304,16 @@ hb_face_make_immutable (hb_face_t *face)
face->immutable = true;
}
+/**
+ * hb_face_is_immutable:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_face_is_immutable (hb_face_t *face)
{
@@ -229,6 +321,17 @@ hb_face_is_immutable (hb_face_t *face)
}
+/**
+ * hb_face_reference_table:
+ * @face: a face.
+ * @tag:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_face_reference_table (hb_face_t *face,
hb_tag_t tag)
@@ -236,12 +339,31 @@ hb_face_reference_table (hb_face_t *face,
return face->reference_table (tag);
}
+/**
+ * hb_face_reference_blob:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_blob_t *
hb_face_reference_blob (hb_face_t *face)
{
return face->reference_table (HB_TAG_NONE);
}
+/**
+ * hb_face_set_index:
+ * @face: a face.
+ * @index:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_set_index (hb_face_t *face,
unsigned int index)
@@ -252,12 +374,31 @@ hb_face_set_index (hb_face_t *face,
face->index = index;
}
+/**
+ * hb_face_get_index:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_face_get_index (hb_face_t *face)
{
return face->index;
}
+/**
+ * hb_face_set_upem:
+ * @face: a face.
+ * @upem:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_set_upem (hb_face_t *face,
unsigned int upem)
@@ -268,6 +409,16 @@ hb_face_set_upem (hb_face_t *face,
face->upem = upem;
}
+/**
+ * hb_face_get_upem:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_face_get_upem (hb_face_t *face)
{
@@ -283,6 +434,15 @@ hb_face_t::load_upem (void) const
hb_blob_destroy (head_blob);
}
+/**
+ * hb_face_set_glyph_count:
+ * @face: a face.
+ * @glyph_count:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_face_set_glyph_count (hb_face_t *face,
unsigned int glyph_count)
@@ -293,6 +453,16 @@ hb_face_set_glyph_count (hb_face_t *face,
face->num_glyphs = glyph_count;
}
+/**
+ * hb_face_get_glyph_count:
+ * @face: a face.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_face_get_glyph_count (hb_face_t *face)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
index 1a1fcfbda1..b894a4a47d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-fallback-shape.cc
@@ -95,6 +95,16 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
const hb_feature_t *features HB_UNUSED,
unsigned int num_features HB_UNUSED)
{
+ /* TODO
+ *
+ * - Apply fallback kern.
+ * - Handle Variation Selectors?
+ * - Apply normalization?
+ *
+ * This will make the fallback shaper into a dumb "TrueType"
+ * shaper which many people unfortunately still request.
+ */
+
hb_codepoint_t space;
font->get_glyph (' ', 0, &space);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
index 620d05e8f9..431d0477c2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
@@ -31,7 +31,6 @@
#include "hb-private.hh"
-#include "hb-font.h"
#include "hb-object-private.hh"
#include "hb-face-private.hh"
#include "hb-shaper-private.hh"
@@ -118,12 +117,12 @@ struct hb_font_t {
/* Convert from parent-font user-space to our user-space */
inline hb_position_t parent_scale_x_distance (hb_position_t v) {
if (unlikely (parent && parent->x_scale != x_scale))
- return v * (int64_t) this->x_scale / this->parent->x_scale;
+ return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
return v;
}
inline hb_position_t parent_scale_y_distance (hb_position_t v) {
if (unlikely (parent && parent->y_scale != y_scale))
- return v * (int64_t) this->y_scale / this->parent->y_scale;
+ return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
return v;
}
inline hb_position_t parent_scale_x_position (hb_position_t v) {
@@ -193,10 +192,10 @@ struct hb_font_t {
klass->user_data.glyph_h_kerning);
}
- inline hb_position_t get_glyph_v_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+ inline hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
{
return klass->get.glyph_v_kerning (this, user_data,
- left_glyph, right_glyph,
+ top_glyph, bottom_glyph,
klass->user_data.glyph_v_kerning);
}
@@ -397,11 +396,7 @@ struct hb_font_t {
}
private:
- inline hb_position_t em_scale (int16_t v, int scale)
- {
- unsigned int upem = face->get_upem ();
- return (v * (int64_t) scale + upem / 2) / upem;
- }
+ inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); }
};
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
index c2f6f6ddd5..fc4c8ebf07 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc
@@ -31,7 +31,6 @@
#include "hb-ot-layout-private.hh"
#include "hb-font-private.hh"
-#include "hb-blob.h"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
@@ -230,6 +229,15 @@ static const hb_font_funcs_t _hb_font_funcs_nil = {
};
+/**
+ * hb_font_funcs_create: (Xconstructor)
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_funcs_t *
hb_font_funcs_create (void)
{
@@ -243,18 +251,45 @@ hb_font_funcs_create (void)
return ffuncs;
}
+/**
+ * hb_font_funcs_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_funcs_t *
hb_font_funcs_get_empty (void)
{
return const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil);
}
+/**
+ * hb_font_funcs_reference: (skip)
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_font_funcs_t *
hb_font_funcs_reference (hb_font_funcs_t *ffuncs)
{
return hb_object_reference (ffuncs);
}
+/**
+ * hb_font_funcs_destroy: (skip)
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
{
@@ -268,6 +303,20 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
free (ffuncs);
}
+/**
+ * hb_font_funcs_set_user_data: (skip)
+ * @ffuncs: font functions.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
hb_user_data_key_t *key,
@@ -278,6 +327,17 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs,
return hb_object_set_user_data (ffuncs, key, data, destroy, replace);
}
+/**
+ * hb_font_funcs_get_user_data: (skip)
+ * @ffuncs: font functions.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
hb_user_data_key_t *key)
@@ -286,6 +346,14 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs,
}
+/**
+ * hb_font_funcs_make_immutable:
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
{
@@ -295,6 +363,16 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
ffuncs->immutable = true;
}
+/**
+ * hb_font_funcs_is_immutable:
+ * @ffuncs: font functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
{
@@ -336,6 +414,19 @@ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
/* Public getters */
+/**
+ * hb_font_get_glyph:
+ * @font: a font.
+ * @unicode:
+ * @variation_selector:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
@@ -344,6 +435,17 @@ hb_font_get_glyph (hb_font_t *font,
return font->get_glyph (unicode, variation_selector, glyph);
}
+/**
+ * hb_font_get_glyph_h_advance:
+ * @font: a font.
+ * @glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_position_t
hb_font_get_glyph_h_advance (hb_font_t *font,
hb_codepoint_t glyph)
@@ -351,6 +453,17 @@ hb_font_get_glyph_h_advance (hb_font_t *font,
return font->get_glyph_h_advance (glyph);
}
+/**
+ * hb_font_get_glyph_v_advance:
+ * @font: a font.
+ * @glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_position_t
hb_font_get_glyph_v_advance (hb_font_t *font,
hb_codepoint_t glyph)
@@ -358,6 +471,19 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
return font->get_glyph_v_advance (glyph);
}
+/**
+ * hb_font_get_glyph_h_origin:
+ * @font: a font.
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_h_origin (hb_font_t *font,
hb_codepoint_t glyph,
@@ -366,6 +492,19 @@ hb_font_get_glyph_h_origin (hb_font_t *font,
return font->get_glyph_h_origin (glyph, x, y);
}
+/**
+ * hb_font_get_glyph_v_origin:
+ * @font: a font.
+ * @glyph:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph,
@@ -374,6 +513,18 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
return font->get_glyph_v_origin (glyph, x, y);
}
+/**
+ * hb_font_get_glyph_h_kerning:
+ * @font: a font.
+ * @left_glyph:
+ * @right_glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
@@ -381,13 +532,37 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
return font->get_glyph_h_kerning (left_glyph, right_glyph);
}
+/**
+ * hb_font_get_glyph_v_kerning:
+ * @font: a font.
+ * @top_glyph:
+ * @bottom_glyph:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font,
- hb_codepoint_t left_glyph, hb_codepoint_t right_glyph)
+ hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph)
{
- return font->get_glyph_v_kerning (left_glyph, right_glyph);
+ return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
}
+/**
+ * hb_font_get_glyph_extents:
+ * @font: a font.
+ * @glyph:
+ * @extents: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
@@ -396,6 +571,20 @@ hb_font_get_glyph_extents (hb_font_t *font,
return font->get_glyph_extents (glyph, extents);
}
+/**
+ * hb_font_get_glyph_contour_point:
+ * @font: a font.
+ * @glyph:
+ * @point_index:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_contour_point (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
@@ -404,6 +593,19 @@ hb_font_get_glyph_contour_point (hb_font_t *font,
return font->get_glyph_contour_point (glyph, point_index, x, y);
}
+/**
+ * hb_font_get_glyph_name:
+ * @font: a font.
+ * @glyph:
+ * @name: (array length=size):
+ * @size:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_name (hb_font_t *font,
hb_codepoint_t glyph,
@@ -412,6 +614,19 @@ hb_font_get_glyph_name (hb_font_t *font,
return font->get_glyph_name (glyph, name, size);
}
+/**
+ * hb_font_get_glyph_from_name:
+ * @font: a font.
+ * @name: (array length=len):
+ * @len:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_from_name (hb_font_t *font,
const char *name, int len, /* -1 means nul-terminated */
@@ -423,6 +638,18 @@ hb_font_get_glyph_from_name (hb_font_t *font,
/* A bit higher-level, and with fallback */
+/**
+ * hb_font_get_glyph_advance_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_glyph_advance_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
@@ -432,6 +659,18 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
return font->get_glyph_advance_for_direction (glyph, direction, x, y);
}
+/**
+ * hb_font_get_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
@@ -441,6 +680,18 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font,
return font->get_glyph_origin_for_direction (glyph, direction, x, y);
}
+/**
+ * hb_font_add_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_add_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
@@ -450,6 +701,18 @@ hb_font_add_glyph_origin_for_direction (hb_font_t *font,
return font->add_glyph_origin_for_direction (glyph, direction, x, y);
}
+/**
+ * hb_font_subtract_glyph_origin_for_direction:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
@@ -459,6 +722,19 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
}
+/**
+ * hb_font_get_glyph_kerning_for_direction:
+ * @font: a font.
+ * @first_glyph:
+ * @second_glyph:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
@@ -468,6 +744,19 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
}
+/**
+ * hb_font_get_glyph_extents_for_origin:
+ * @font: a font.
+ * @glyph:
+ * @direction:
+ * @extents: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
hb_codepoint_t glyph,
@@ -477,6 +766,21 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font,
return font->get_glyph_extents_for_origin (glyph, direction, extents);
}
+/**
+ * hb_font_get_glyph_contour_point_for_origin:
+ * @font: a font.
+ * @glyph:
+ * @point_index:
+ * @direction:
+ * @x: (out):
+ * @y: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
@@ -487,6 +791,17 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font,
}
/* Generates gidDDD if glyph has no name. */
+/**
+ * hb_font_glyph_to_string:
+ * @font: a font.
+ * @glyph:
+ * @s: (array length=size):
+ * @size:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_glyph_to_string (hb_font_t *font,
hb_codepoint_t glyph,
@@ -496,6 +811,19 @@ hb_font_glyph_to_string (hb_font_t *font,
}
/* Parses gidDDD and uniUUUU strings automatically. */
+/**
+ * hb_font_glyph_from_string:
+ * @font: a font.
+ * @s: (array length=len):
+ * @len:
+ * @glyph: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_glyph_from_string (hb_font_t *font,
const char *s, int len, /* -1 means nul-terminated */
@@ -509,6 +837,16 @@ hb_font_glyph_from_string (hb_font_t *font,
* hb_font_t
*/
+/**
+ * hb_font_create: (Xconstructor)
+ * @face: a face.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_create (hb_face_t *face)
{
@@ -528,6 +866,16 @@ hb_font_create (hb_face_t *face)
return font;
}
+/**
+ * hb_font_create_sub_font:
+ * @parent: parent font.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_create_sub_font (hb_font_t *parent)
{
@@ -550,6 +898,15 @@ hb_font_create_sub_font (hb_font_t *parent)
return font;
}
+/**
+ * hb_font_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full)
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_get_empty (void)
{
@@ -581,12 +938,30 @@ hb_font_get_empty (void)
return const_cast<hb_font_t *> (&_hb_font_nil);
}
+/**
+ * hb_font_reference: (skip)
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_reference (hb_font_t *font)
{
return hb_object_reference (font);
}
+/**
+ * hb_font_destroy: (skip)
+ * @font: a font.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_destroy (hb_font_t *font)
{
@@ -606,6 +981,20 @@ hb_font_destroy (hb_font_t *font)
free (font);
}
+/**
+ * hb_font_set_user_data: (skip)
+ * @font: a font.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_set_user_data (hb_font_t *font,
hb_user_data_key_t *key,
@@ -616,6 +1005,17 @@ hb_font_set_user_data (hb_font_t *font,
return hb_object_set_user_data (font, key, data, destroy, replace);
}
+/**
+ * hb_font_get_user_data: (skip)
+ * @font: a font.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_font_get_user_data (hb_font_t *font,
hb_user_data_key_t *key)
@@ -623,6 +1023,14 @@ hb_font_get_user_data (hb_font_t *font,
return hb_object_get_user_data (font, key);
}
+/**
+ * hb_font_make_immutable:
+ * @font: a font.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_make_immutable (hb_font_t *font)
{
@@ -632,18 +1040,48 @@ hb_font_make_immutable (hb_font_t *font)
font->immutable = true;
}
+/**
+ * hb_font_is_immutable:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_font_is_immutable (hb_font_t *font)
{
return font->immutable;
}
+/**
+ * hb_font_get_parent:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
hb_font_t *
hb_font_get_parent (hb_font_t *font)
{
return font->parent;
}
+/**
+ * hb_font_get_face:
+ * @font: a font.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
hb_face_t *
hb_font_get_face (hb_font_t *font)
{
@@ -651,15 +1089,26 @@ hb_font_get_face (hb_font_t *font)
}
+/**
+ * hb_font_set_funcs:
+ * @font: a font.
+ * @klass: (closure font_data) (destroy destroy) (scope notified):
+ * @font_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_set_funcs (hb_font_t *font,
hb_font_funcs_t *klass,
- void *user_data,
+ void *font_data,
hb_destroy_func_t destroy)
{
if (font->immutable) {
if (destroy)
- destroy (user_data);
+ destroy (font_data);
return;
}
@@ -672,30 +1121,50 @@ hb_font_set_funcs (hb_font_t *font,
hb_font_funcs_reference (klass);
hb_font_funcs_destroy (font->klass);
font->klass = klass;
- font->user_data = user_data;
+ font->user_data = font_data;
font->destroy = destroy;
}
+/**
+ * hb_font_set_funcs_data:
+ * @font: a font.
+ * @font_data: (destroy destroy) (scope notified):
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_set_funcs_data (hb_font_t *font,
- void *user_data,
+ void *font_data,
hb_destroy_func_t destroy)
{
/* Destroy user_data? */
if (font->immutable) {
if (destroy)
- destroy (user_data);
+ destroy (font_data);
return;
}
if (font->destroy)
font->destroy (font->user_data);
- font->user_data = user_data;
+ font->user_data = font_data;
font->destroy = destroy;
}
+/**
+ * hb_font_set_scale:
+ * @font: a font.
+ * @x_scale:
+ * @y_scale:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_set_scale (hb_font_t *font,
int x_scale,
@@ -708,6 +1177,16 @@ hb_font_set_scale (hb_font_t *font,
font->y_scale = y_scale;
}
+/**
+ * hb_font_get_scale:
+ * @font: a font.
+ * @x_scale: (out):
+ * @y_scale: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_scale (hb_font_t *font,
int *x_scale,
@@ -717,6 +1196,16 @@ hb_font_get_scale (hb_font_t *font,
if (y_scale) *y_scale = font->y_scale;
}
+/**
+ * hb_font_set_ppem:
+ * @font: a font.
+ * @x_ppem:
+ * @y_ppem:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_set_ppem (hb_font_t *font,
unsigned int x_ppem,
@@ -729,6 +1218,16 @@ hb_font_set_ppem (hb_font_t *font,
font->y_ppem = y_ppem;
}
+/**
+ * hb_font_get_ppem:
+ * @font: a font.
+ * @x_ppem: (out):
+ * @y_ppem: (out):
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_get_ppem (hb_font_t *font,
unsigned int *x_ppem,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h
index 3a0c001b98..7273db43ed 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-font.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h
@@ -139,54 +139,180 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *
/* func setters */
+/**
+ * hb_font_funcs_set_glyph_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_func_t glyph_func,
+ hb_font_get_glyph_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_h_advance_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_advance_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_advance_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_advance_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_h_origin_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_origin_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_origin_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_origin_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_h_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_v_kerning_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_extents_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_extents_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_contour_point_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_contour_point_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_font_funcs_set_glyph_name_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_name_func_t glyph_func,
+ hb_font_get_glyph_name_func_t func,
void *user_data, hb_destroy_func_t destroy);
+
+/**
+ * hb_font_funcs_set_glyph_from_name_func:
+ * @ffuncs: font functions.
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs,
- hb_font_get_glyph_from_name_func_t glyph_func,
+ hb_font_get_glyph_from_name_func_t func,
void *user_data, hb_destroy_func_t destroy);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
index ee3a21dc3b..437ecd57f8 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
@@ -31,8 +31,6 @@
#include "hb-private.hh"
-#include "hb-blob.h"
-
namespace OT {
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
index 3a9451295d..0285f0cf31 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh
@@ -43,7 +43,7 @@ namespace OT {
struct head
{
- static const hb_tag_t Tag = HB_OT_TAG_head;
+ static const hb_tag_t tableTag = HB_OT_TAG_head;
inline unsigned int get_upem (void) const {
unsigned int upem = unitsPerEm;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
index 2b89c4e020..611de8a666 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh
@@ -42,7 +42,7 @@ namespace OT {
struct hhea
{
- static const hb_tag_t Tag = HB_OT_TAG_hhea;
+ static const hb_tag_t tableTag = HB_OT_TAG_hhea;
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE (this);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
index b94337d0be..d107cf990a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh
@@ -50,7 +50,7 @@ struct LongHorMetric
struct hmtx
{
- static const hb_tag_t Tag = HB_OT_TAG_hmtx;
+ static const hb_tag_t tableTag = HB_OT_TAG_hmtx;
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE (this);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
index 2f6e80468e..02d0d0f87c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh
@@ -39,6 +39,7 @@ namespace OT {
#define NOT_COVERED ((unsigned int) -1)
#define MAX_NESTING_LEVEL 8
+#define MAX_CONTEXT_LENGTH 64
@@ -376,7 +377,7 @@ struct FeatureParamsStylisticSet
return TRACE_RETURN (c->check_struct (this));
}
- USHORT minorVersion; /* (set to 0): This corresponds to a “minor”
+ USHORT version; /* (set to 0): This corresponds to a “minor”
* version number. Additional data may be
* added to the end of this Feature Parameters
* table in the future. */
@@ -399,6 +400,7 @@ struct FeatureParamsStylisticSet
DEFINE_SIZE_STATIC (4);
};
+/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
struct FeatureParamsCharacterVariants
{
inline bool sanitize (hb_sanitize_context_t *c) {
@@ -1111,7 +1113,7 @@ struct Device
if (!pixels) return 0;
- return pixels * (int64_t) scale / ppem;
+ return (int) (pixels * (int64_t) scale / ppem);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
index ff2d09c51f..389cbb9e39 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh
@@ -324,7 +324,7 @@ struct MarkGlyphSets
struct GDEF
{
- static const hb_tag_t Tag = HB_OT_TAG_GDEF;
+ static const hb_tag_t tableTag = HB_OT_TAG_GDEF;
enum GlyphClasses {
UnclassifiedGlyph = 0,
@@ -383,12 +383,14 @@ struct GDEF
{
unsigned int klass = get_glyph_class (glyph);
+ ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs);
+ ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures);
+ ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks);
+
switch (klass) {
- default:
- case UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED;
+ default: return 0;
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_PROPS_MARK | (klass << 8);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
index 2cf90b7b5f..5e4326ef0c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh
@@ -390,6 +390,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
unsigned int glyph_pos) const
{
TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
unsigned int mark_class = record.klass;
@@ -402,15 +403,15 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
hb_position_t mark_x, mark_y, base_x, base_y;
- mark_anchor.get_anchor (c->font, c->buffer->cur().codepoint, &mark_x, &mark_y);
- glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y);
+ mark_anchor.get_anchor (c->font, buffer->cur().codepoint, &mark_x, &mark_y);
+ glyph_anchor.get_anchor (c->font, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
- hb_glyph_position_t &o = c->buffer->cur_pos();
+ hb_glyph_position_t &o = buffer->cur_pos();
o.x_offset = base_x - mark_x;
o.y_offset = base_y - mark_y;
- o.attach_lookback() = c->buffer->idx - glyph_pos;
+ o.attach_lookback() = buffer->idx - glyph_pos;
- c->buffer->idx++;
+ buffer->idx++;
return TRACE_RETURN (true);
}
@@ -439,13 +440,14 @@ struct SinglePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
valueFormat.apply_value (c->font, c->direction, this,
- values, c->buffer->cur_pos());
+ values, buffer->cur_pos());
- c->buffer->idx++;
+ buffer->idx++;
return TRACE_RETURN (true);
}
@@ -484,16 +486,17 @@ struct SinglePosFormat2
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (likely (index >= valueCount)) return TRACE_RETURN (false);
valueFormat.apply_value (c->font, c->direction, this,
&values[index * valueFormat.get_len ()],
- c->buffer->cur_pos());
+ buffer->cur_pos());
- c->buffer->idx++;
+ buffer->idx++;
return TRACE_RETURN (true);
}
@@ -588,6 +591,7 @@ struct PairSet
unsigned int pos) const
{
TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
@@ -597,15 +601,15 @@ struct PairSet
for (unsigned int i = 0; i < count; i++)
{
/* TODO bsearch */
- if (c->buffer->info[pos].codepoint == record->secondGlyph)
+ if (buffer->info[pos].codepoint == record->secondGlyph)
{
valueFormats[0].apply_value (c->font, c->direction, this,
- &record->values[0], c->buffer->cur_pos());
+ &record->values[0], buffer->cur_pos());
valueFormats[1].apply_value (c->font, c->direction, this,
- &record->values[len1], c->buffer->pos[pos]);
+ &record->values[len1], buffer->pos[pos]);
if (len2)
pos++;
- c->buffer->idx = pos;
+ buffer->idx = pos;
return TRACE_RETURN (true);
}
record = &StructAtOffset<PairValueRecord> (record, record_size);
@@ -659,10 +663,11 @@ struct PairPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_buffer_t *buffer = c->buffer;
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
@@ -729,10 +734,11 @@ struct PairPosFormat2
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_buffer_t *buffer = c->buffer;
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
@@ -741,19 +747,19 @@ struct PairPosFormat2
unsigned int len2 = valueFormat2.get_len ();
unsigned int record_len = len1 + len2;
- 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);
+ unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
+ unsigned int klass2 = (this+classDef2).get_class (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)];
valueFormat1.apply_value (c->font, c->direction, this,
- v, c->buffer->cur_pos());
+ v, buffer->cur_pos());
valueFormat2.apply_value (c->font, c->direction, this,
- v + len1, c->buffer->pos[skippy_iter.idx]);
+ v + len1, buffer->pos[skippy_iter.idx]);
- c->buffer->idx = skippy_iter.idx;
+ buffer->idx = skippy_iter.idx;
if (len2)
- c->buffer->idx++;
+ buffer->idx++;
return TRACE_RETURN (true);
}
@@ -875,29 +881,30 @@ struct CursivePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
+ hb_buffer_t *buffer = c->buffer;
/* We don't handle mark glyphs here. */
- if (c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false);
+ if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->cur().codepoint)];
+ const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (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).get_coverage (c->buffer->info[skippy_iter.idx].codepoint)];
+ const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
if (!next_record.entryAnchor) return TRACE_RETURN (false);
- unsigned int i = c->buffer->idx;
+ unsigned int i = buffer->idx;
unsigned int j = skippy_iter.idx;
hb_position_t entry_x, entry_y, exit_x, exit_y;
- (this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
- (this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, &entry_x, &entry_y);
+ (this+this_record.exitAnchor).get_anchor (c->font, buffer->info[i].codepoint, &exit_x, &exit_y);
+ (this+next_record.entryAnchor).get_anchor (c->font, buffer->info[j].codepoint, &entry_x, &entry_y);
- hb_glyph_position_t *pos = c->buffer->pos;
+ hb_glyph_position_t *pos = buffer->pos;
hb_position_t d;
/* Main-direction adjustment */
@@ -950,7 +957,7 @@ struct CursivePosFormat1
pos[j].x_offset = exit_x - entry_x;
}
- c->buffer->idx = j;
+ buffer->idx = j;
return TRACE_RETURN (true);
}
@@ -1022,23 +1029,24 @@ struct MarkBasePosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
do {
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
/* We only want to attach to the first of a MultipleSubst sequence. Reject others. */
- if (0 == get_lig_comp (c->buffer->info[skippy_iter.idx])) break;
+ if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break;
skippy_iter.reject ();
} while (1);
- /* The following assertion is too strong, so we've disabled it. */
- if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
+ /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
+ if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
- unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint);
+ unsigned int base_index = (this+baseCoverage).get_coverage (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));
@@ -1125,19 +1133,20 @@ struct MarkLigPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
- /* The following assertion is too strong, so we've disabled it. */
- if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
+ /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
+ if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ }
unsigned int j = skippy_iter.idx;
- unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->info[j].codepoint);
+ unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint);
if (lig_index == NOT_COVERED) return TRACE_RETURN (false);
const LigatureArray& lig_array = this+ligatureArray;
@@ -1152,11 +1161,11 @@ struct MarkLigPosFormat1
* can directly use the component index. If not, we attach the mark
* glyph to the last component of the ligature. */
unsigned int comp_index;
- unsigned int lig_id = get_lig_id (c->buffer->info[j]);
- unsigned int mark_id = get_lig_id (c->buffer->cur());
- unsigned int mark_comp = get_lig_comp (c->buffer->cur());
+ unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+ unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
if (lig_id && lig_id == mark_id && mark_comp > 0)
- comp_index = MIN (comp_count, get_lig_comp (c->buffer->cur())) - 1;
+ comp_index = MIN (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
else
comp_index = comp_count - 1;
@@ -1240,22 +1249,23 @@ struct MarkMarkPosFormat1
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY (this);
- unsigned int mark1_index = (this+mark1Coverage).get_coverage (c->buffer->cur().codepoint);
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int mark1_index = (this+mark1Coverage).get_coverage (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 */
- hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
+ hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
- if (!(c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) { return TRACE_RETURN (false); }
+ if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); }
unsigned int j = skippy_iter.idx;
- unsigned int id1 = get_lig_id (c->buffer->cur());
- unsigned int id2 = get_lig_id (c->buffer->info[j]);
- unsigned int comp1 = get_lig_comp (c->buffer->cur());
- unsigned int comp2 = get_lig_comp (c->buffer->info[j]);
+ unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+ unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
if (likely (id1 == id2)) {
if (id1 == 0) /* Marks belonging to the same base. */
@@ -1273,7 +1283,7 @@ struct MarkMarkPosFormat1
return TRACE_RETURN (false);
good:
- unsigned int mark2_index = (this+mark2Coverage).get_coverage (c->buffer->info[j].codepoint);
+ unsigned int mark2_index = (this+mark2Coverage).get_coverage (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));
@@ -1434,12 +1444,6 @@ struct PosLookup : Lookup
return false;
}
- inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
@@ -1505,7 +1509,7 @@ typedef OffsetListOf<PosLookup> PosLookupList;
struct GPOS : GSUBGPOS
{
- static const hb_tag_t Tag = HB_OT_TAG_GPOS;
+ static const hb_tag_t tableTag = HB_OT_TAG_GPOS;
inline const PosLookup& get_lookup (unsigned int i) const
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
@@ -1591,9 +1595,7 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
for (unsigned int i = 0; i < len; i++)
fix_mark_attachment (pos, i, direction);
- HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
- HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
- HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
+ _hb_buffer_deallocate_gsubgpos_vars (buffer);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
index 6ab1a2b921..76b4f33c70 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh
@@ -37,12 +37,6 @@ namespace OT {
struct SingleSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -121,12 +115,6 @@ struct SingleSubstFormat1
struct SingleSubstFormat2
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -263,13 +251,6 @@ struct SingleSubst
struct Sequence
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- /* For len==0 we don't do anything, so it's harmless. */
- return TRACE_RETURN (substitute.len <= 1);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -291,8 +272,8 @@ struct Sequence
TRACE_APPLY (this);
if (unlikely (!substitute.len)) return TRACE_RETURN (false);
- unsigned int klass = c->buffer->cur().glyph_props() &
- HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
+ unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
unsigned int count = substitute.len;
if (count == 1) /* Special-case to make it in-place. */
{
@@ -301,7 +282,7 @@ struct Sequence
else
{
for (unsigned int i = 0; i < count; i++) {
- set_lig_props_for_component (c->buffer->cur(), i);
+ _hb_glyph_info_set_lig_props_for_component (&c->buffer->cur(), i);
c->output_glyph (substitute.array[i], klass);
}
c->buffer->skip_glyph ();
@@ -334,18 +315,6 @@ struct Sequence
struct MultipleSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- /* Some tools generate MultipleSubst with each substitute having length 1!
- * So, check them. */
- unsigned int count = sequence.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+sequence[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -471,12 +440,6 @@ typedef ArrayOf<GlyphID> AlternateSet; /* Array of alternate GlyphIDs--in
struct AlternateSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -663,27 +626,26 @@ struct Ligature
unsigned int count = component.len;
if (unlikely (count < 1)) return TRACE_RETURN (false);
- unsigned int end_offset = 0;
bool is_mark_ligature = false;
unsigned int total_component_count = 0;
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
+
if (likely (!match_input (c, count,
&component[1],
match_glyph,
NULL,
- &end_offset,
+ &match_length,
+ match_positions,
&is_mark_ligature,
&total_component_count)))
return TRACE_RETURN (false);
- /* Deal, we are forming the ligature. */
- c->buffer->merge_clusters (c->buffer->idx, c->buffer->idx + end_offset);
-
ligate_input (c,
count,
- &component[1],
- match_glyph,
- NULL,
+ match_positions,
+ match_length,
ligGlyph,
is_mark_ligature,
total_component_count);
@@ -797,12 +759,6 @@ struct LigatureSet
struct LigatureSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (false);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -951,12 +907,6 @@ struct ExtensionSubst : Extension<ExtensionSubst>
struct ReverseChainSingleSubstFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1038,7 +988,9 @@ struct ReverseChainSingleSubstFormat1
1))
{
c->replace_glyph_inplace (substitute[index]);
- c->buffer->idx--; /* Reverse! */
+ /* Note: We DON'T decrease buffer->idx. The main loop does it
+ * for us. This is useful for preventing surprises if someone
+ * calls us through a Context lookup. */
return TRACE_RETURN (true);
}
@@ -1194,13 +1146,6 @@ struct SubstLookup : Lookup
return lookup_type_is_reverse (type);
}
- inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- c->set_recurse_func (dispatch_recurse_func<hb_is_inplace_context_t>);
- return TRACE_RETURN (dispatch (c));
- }
-
inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1351,7 +1296,7 @@ typedef OffsetListOf<SubstLookup> SubstLookupList;
struct GSUB : GSUBGPOS
{
- static const hb_tag_t Tag = HB_OT_TAG_GSUB;
+ static const hb_tag_t tableTag = HB_OT_TAG_GSUB;
inline const SubstLookup& get_lookup (unsigned int i) const
{ return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
@@ -1373,15 +1318,15 @@ struct GSUB : GSUBGPOS
void
GSUB::substitute_start (hb_font_t *font, hb_buffer_t *buffer)
{
- HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
- HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
- HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+ _hb_buffer_allocate_gsubgpos_vars (buffer);
const GDEF &gdef = *hb_ot_layout_from_face (font->face)->gdef;
unsigned int count = buffer->len;
- for (unsigned int i = 0; i < count; i++) {
- buffer->info[i].lig_props() = buffer->info[i].syllable() = 0;
- buffer->info[i].glyph_props() = gdef.get_glyph_props (buffer->info[i].codepoint);
+ for (unsigned int i = 0; i < count; i++)
+ {
+ _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
+ _hb_glyph_info_clear_lig_props (&buffer->info[i]);
+ buffer->info[i].syllable() = 0;
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
index 316f506f0d..bdd773e36b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh
@@ -43,56 +43,6 @@ namespace OT {
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
"");
-
-
-#ifndef HB_DEBUG_IS_INPLACE
-#define HB_DEBUG_IS_INPLACE (HB_DEBUG+0)
-#endif
-
-#define TRACE_IS_INPLACE(this) \
- hb_auto_trace_t<HB_DEBUG_IS_INPLACE, bool> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "");
-
-struct hb_is_inplace_context_t
-{
- inline const char *get_name (void) { return "IS_INPLACE"; }
- static const unsigned int max_debug_depth = HB_DEBUG_IS_INPLACE;
- typedef bool return_t;
- typedef return_t (*recurse_func_t) (hb_is_inplace_context_t *c, unsigned int lookup_index);
- template <typename T>
- inline return_t dispatch (const T &obj) { return obj.is_inplace (this); }
- static return_t default_return_value (void) { return true; }
- bool stop_sublookup_iteration (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_face_t *face;
- recurse_func_t recurse_func;
- unsigned int nesting_level_left;
- unsigned int debug_depth;
-
- hb_is_inplace_context_t (hb_face_t *face_,
- unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
- face (face_),
- recurse_func (NULL),
- nesting_level_left (nesting_level_left_),
- debug_depth (0) {}
-
- void set_recurse_func (recurse_func_t func) { recurse_func = func; }
-};
-
-
-
#ifndef HB_DEBUG_CLOSURE
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
#endif
@@ -401,7 +351,7 @@ struct hb_apply_context_t
{
unsigned int property;
- property = info.glyph_props();
+ property = _hb_glyph_info_get_glyph_props (&info);
if (!c->match_properties (info.codepoint, property, lookup_props))
return SKIP_YES;
@@ -409,7 +359,7 @@ struct hb_apply_context_t
if (unlikely (_hb_glyph_info_is_default_ignorable (&info) &&
(ignore_zwnj || !_hb_glyph_info_is_zwnj (&info)) &&
(ignore_zwj || !_hb_glyph_info_is_zwj (&info)) &&
- !is_a_ligature (info)))
+ !_hb_glyph_info_ligated (&info)))
return SKIP_MAYBE;
return SKIP_NO;
@@ -610,36 +560,47 @@ struct hb_apply_context_t
{
unsigned int property;
- property = info->glyph_props();
+ property = _hb_glyph_info_get_glyph_props (info);
return match_properties (info->codepoint, property, lookup_props);
}
- inline void set_class (hb_codepoint_t glyph_index, unsigned int class_guess) const
+ inline void _set_glyph_props (hb_codepoint_t glyph_index,
+ unsigned int class_guess = 0,
+ bool ligature = false) const
{
+ unsigned int add_in = _hb_glyph_info_get_glyph_props (&buffer->cur()) &
+ HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
+ if (ligature)
+ add_in |= HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
if (likely (has_glyph_classes))
- buffer->cur().glyph_props() = gdef.get_glyph_props (glyph_index);
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | gdef.get_glyph_props (glyph_index));
else if (class_guess)
- buffer->cur().glyph_props() = class_guess;
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), add_in | class_guess);
}
- inline void output_glyph (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void replace_glyph (hb_codepoint_t glyph_index) const
{
- set_class (glyph_index, class_guess);
- buffer->output_glyph (glyph_index);
+ _set_glyph_props (glyph_index);
+ buffer->replace_glyph (glyph_index);
}
- inline void replace_glyph (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void replace_glyph_inplace (hb_codepoint_t glyph_index) const
{
- set_class (glyph_index, class_guess);
+ _set_glyph_props (glyph_index);
+ buffer->cur().codepoint = glyph_index;
+ }
+ inline void replace_glyph_with_ligature (hb_codepoint_t glyph_index,
+ unsigned int class_guess) const
+ {
+ _set_glyph_props (glyph_index, class_guess, true);
buffer->replace_glyph (glyph_index);
}
- inline void replace_glyph_inplace (hb_codepoint_t glyph_index,
- unsigned int class_guess = 0) const
+ inline void output_glyph (hb_codepoint_t glyph_index,
+ unsigned int class_guess) const
{
- set_class (glyph_index, class_guess);
- buffer->cur().codepoint = glyph_index;
+ _set_glyph_props (glyph_index, class_guess);
+ buffer->output_glyph (glyph_index);
}
};
@@ -752,13 +713,18 @@ static inline bool match_input (hb_apply_context_t *c,
const USHORT input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data,
- unsigned int *end_offset = NULL,
+ unsigned int *end_offset,
+ unsigned int match_positions[MAX_CONTEXT_LENGTH],
bool *p_is_mark_ligature = NULL,
unsigned int *p_total_component_count = NULL)
{
TRACE_APPLY (NULL);
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
+ if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false);
+
+ hb_buffer_t *buffer = c->buffer;
+
+ hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1);
skippy_iter.set_match_func (match_func, match_data, input);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
@@ -780,20 +746,23 @@ static inline bool match_input (hb_apply_context_t *c,
* ligate with a conjunct...)
*/
- bool is_mark_ligature = !!(c->buffer->cur().glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+ bool is_mark_ligature = _hb_glyph_info_is_mark (&buffer->cur());
unsigned int total_component_count = 0;
- total_component_count += get_lig_num_comps (c->buffer->cur());
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
- unsigned int first_lig_id = get_lig_id (c->buffer->cur());
- unsigned int first_lig_comp = get_lig_comp (c->buffer->cur());
+ unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+ match_positions[0] = buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
if (!skippy_iter.next ()) return TRACE_RETURN (false);
- unsigned int this_lig_id = get_lig_id (c->buffer->info[skippy_iter.idx]);
- unsigned int this_lig_comp = get_lig_comp (c->buffer->info[skippy_iter.idx]);
+ match_positions[i] = skippy_iter.idx;
+
+ unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]);
+ unsigned int this_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]);
if (first_lig_id && first_lig_comp) {
/* If first component was attached to a previous ligature component,
@@ -809,12 +778,11 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (false);
}
- is_mark_ligature = is_mark_ligature && (c->buffer->info[skippy_iter.idx].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
- total_component_count += get_lig_num_comps (c->buffer->info[skippy_iter.idx]);
+ is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]);
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->info[skippy_iter.idx]);
}
- if (end_offset)
- *end_offset = skippy_iter.idx - c->buffer->idx + 1;
+ *end_offset = skippy_iter.idx - buffer->idx + 1;
if (p_is_mark_ligature)
*p_is_mark_ligature = is_mark_ligature;
@@ -825,17 +793,18 @@ static inline bool match_input (hb_apply_context_t *c,
return TRACE_RETURN (true);
}
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 */
- match_func_t match_func,
- const void *match_data,
+ unsigned int count, /* Including the first glyph */
+ unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
+ unsigned int match_length,
hb_codepoint_t lig_glyph,
bool is_mark_ligature,
unsigned int total_component_count)
{
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
- skippy_iter.set_match_func (match_func, match_data, input);
- if (skippy_iter.has_no_chance ()) return;
+ TRACE_APPLY (NULL);
+
+ hb_buffer_t *buffer = c->buffer;
+
+ buffer->merge_clusters (buffer->idx, buffer->idx + match_length);
/*
* - If it *is* a mark ligature, we don't allocate a new ligature id, and leave
@@ -866,48 +835,49 @@ static inline void ligate_input (hb_apply_context_t *c,
*/
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());
+ unsigned int lig_id = is_mark_ligature ? 0 : _hb_allocate_lig_id (buffer);
+ unsigned int last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ unsigned int last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
unsigned int components_so_far = last_num_components;
if (!is_mark_ligature)
{
- set_lig_props_for_ligature (c->buffer->cur(), lig_id, total_component_count);
- if (_hb_glyph_info_get_general_category (&c->buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
- _hb_glyph_info_set_general_category (&c->buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+ _hb_glyph_info_set_lig_props_for_ligature (&buffer->cur(), lig_id, total_component_count);
+ if (_hb_glyph_info_get_general_category (&buffer->cur()) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+ {
+ _hb_glyph_info_set_general_category (&buffer->cur(), HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER);
+ _hb_glyph_info_set_modified_combining_class (&buffer->cur(), 0);
+ }
}
- c->replace_glyph (lig_glyph, klass);
+ c->replace_glyph_with_ligature (lig_glyph, klass);
for (unsigned int i = 1; i < count; i++)
{
- if (!skippy_iter.next ()) return;
-
- while (c->buffer->idx < skippy_iter.idx)
+ while (buffer->idx < match_positions[i])
{
if (!is_mark_ligature) {
unsigned int new_lig_comp = components_so_far - last_num_components +
- MIN (MAX (get_lig_comp (c->buffer->cur()), 1u), last_num_components);
- set_lig_props_for_mark (c->buffer->cur(), lig_id, new_lig_comp);
+ MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->cur()), 1u), last_num_components);
+ _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
}
- c->buffer->next_glyph ();
+ buffer->next_glyph ();
}
- last_lig_id = get_lig_id (c->buffer->cur());
- last_num_components = get_lig_num_comps (c->buffer->cur());
+ last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+ last_num_components = _hb_glyph_info_get_lig_num_comps (&buffer->cur());
components_so_far += last_num_components;
/* Skip the base glyph */
- c->buffer->idx++;
+ buffer->idx++;
}
if (!is_mark_ligature && last_lig_id) {
/* Re-adjust components for any marks following. */
- for (unsigned int i = c->buffer->idx; i < c->buffer->len; i++) {
- if (last_lig_id == get_lig_id (c->buffer->info[i])) {
+ for (unsigned int i = buffer->idx; i < buffer->len; i++) {
+ if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
unsigned int new_lig_comp = components_so_far - last_num_components +
- MIN (MAX (get_lig_comp (c->buffer->info[i]), 1u), last_num_components);
- set_lig_props_for_mark (c->buffer->info[i], lig_id, new_lig_comp);
+ MIN (MAX (_hb_glyph_info_get_lig_comp (&buffer->info[i]), 1u), last_num_components);
+ _hb_glyph_info_set_lig_props_for_mark (&buffer->info[i], lig_id, new_lig_comp);
} else
break;
}
@@ -982,99 +952,82 @@ static inline void recurse_lookups (context_t *c,
static inline bool apply_lookup (hb_apply_context_t *c,
unsigned int count, /* Including the first glyph */
- const USHORT input[], /* Array of input values--start with second glyph */
- match_func_t match_func,
- const void *match_data,
+ unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */
unsigned int lookupCount,
- const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
+ const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
+ unsigned int match_length)
{
TRACE_APPLY (NULL);
- unsigned int end = c->buffer->len;
- if (unlikely (count == 0 || c->buffer->idx + count > end))
- return TRACE_RETURN (false);
-
- /* TODO We don't support lookupRecord arrays that are not increasing:
- * Should be easy for in_place ones at least. */
+ hb_buffer_t *buffer = c->buffer;
+ unsigned int end;
- /* Note: If sublookup is reverse, it will underflow after the first loop
- * and we jump out of it. Not entirely disastrous. So we don't check
- * for reverse lookup here.
- */
+ /* All positions are distance from beginning of *output* buffer.
+ * Adjust. */
+ {
+ unsigned int bl = buffer->backtrack_len ();
+ end = bl + match_length;
- hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, count - 1);
- skippy_iter.set_match_func (match_func, match_data, input);
- uint8_t syllable = c->buffer->cur().syllable();
+ int delta = bl - buffer->idx;
+ /* Convert positions to new indexing. */
+ for (unsigned int j = 0; j < count; j++)
+ match_positions[j] += delta;
+ }
- unsigned int i = 0;
- if (lookupCount && 0 == lookupRecord->sequenceIndex)
+ for (unsigned int i = 0; i < lookupCount; i++)
{
- unsigned int old_pos = c->buffer->idx;
+ unsigned int idx = lookupRecord[i].sequenceIndex;
+ if (idx >= count)
+ continue;
- /* Apply a lookup */
- bool done = c->recurse (lookupRecord->lookupListIndex);
+ buffer->move_to (match_positions[idx]);
- lookupRecord++;
- lookupCount--;
- i++;
+ unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
+ if (!c->recurse (lookupRecord[i].lookupListIndex))
+ continue;
- if (!done)
- goto not_applied;
- else
- {
- if (c->table_index == 1)
- c->buffer->idx = old_pos + 1;
- /* Reinitialize iterator. */
- hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
- tmp.set_syllable (syllable);
- skippy_iter = tmp;
- }
- }
- else
- {
- not_applied:
- /* No lookup applied for this index */
- c->buffer->next_glyph ();
- i++;
- }
- while (i < count)
- {
- if (!skippy_iter.next ()) return TRACE_RETURN (true);
- while (c->buffer->idx < skippy_iter.idx)
- c->buffer->next_glyph ();
+ unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len ();
+ int delta = new_len - orig_len;
- if (lookupCount && i == lookupRecord->sequenceIndex)
- {
- unsigned int old_pos = c->buffer->idx;
+ if (!delta)
+ continue;
- /* Apply a lookup */
- bool done = c->recurse (lookupRecord->lookupListIndex);
+ /* Recursed lookup changed buffer len. Adjust. */
- lookupRecord++;
- lookupCount--;
- i++;
+ /* end can't go back past the current match position. */
+ end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
- if (!done)
- goto not_applied2;
- else
- {
- if (c->table_index == 1)
- c->buffer->idx = old_pos + 1;
- /* Reinitialize iterator. */
- hb_apply_context_t::skipping_forward_iterator_t tmp (c, c->buffer->idx - 1, count - i);
- tmp.set_syllable (syllable);
- skippy_iter = tmp;
- }
+ unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
+
+ if (delta > 0)
+ {
+ if (unlikely (delta + count > MAX_CONTEXT_LENGTH))
+ break;
}
else
{
- not_applied2:
- /* No lookup applied for this index */
- c->buffer->next_glyph ();
- i++;
+ /* NOTE: delta is negative. */
+ delta = MAX (delta, (int) next - (int) count);
+ next -= delta;
}
+
+ /* Shift! */
+ memmove (match_positions + next + delta, match_positions + next,
+ (count - next) * sizeof (match_positions[0]));
+ next += delta;
+ count += delta;
+
+ /* Fill in new entries. */
+ for (unsigned int j = idx + 1; j < next; j++)
+ match_positions[j] = match_positions[j - 1] + 1;
+
+ /* And fixup the rest. */
+ for (; next < count; next++)
+ match_positions[next] += delta;
}
+ buffer->move_to (end);
+
return TRACE_RETURN (true);
}
@@ -1146,28 +1099,20 @@ static inline bool context_apply_lookup (hb_apply_context_t *c,
const LookupRecord lookupRecord[],
ContextApplyLookupContext &lookup_context)
{
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
return match_input (c,
inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data)
+ lookup_context.funcs.match, lookup_context.match_data,
+ &match_length, match_positions)
&& apply_lookup (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data,
- lookupCount, lookupRecord);
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_length);
}
struct Rule
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
- unsigned int count = lookupCount;
- for (unsigned int i = 0; i < count; i++)
- if (!c->recurse (lookupRecord[i].lookupListIndex))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
@@ -1227,16 +1172,6 @@ struct Rule
struct RuleSet
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int num_rules = rule.len;
- for (unsigned int i = 0; i < num_rules; i++)
- if (!(this+rule[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
@@ -1293,16 +1228,6 @@ struct RuleSet
struct ContextFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int count = ruleSet.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+ruleSet[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1389,16 +1314,6 @@ struct ContextFormat1
struct ContextFormat2
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int count = ruleSet.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+ruleSet[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1494,17 +1409,6 @@ struct ContextFormat2
struct ContextFormat3
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
- unsigned int count = lookupCount;
- for (unsigned int i = 0; i < count; i++)
- if (!c->recurse (lookupRecord[i].lookupListIndex))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -1726,39 +1630,27 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
const LookupRecord lookupRecord[],
ChainContextApplyLookupContext &lookup_context)
{
- unsigned int lookahead_offset = 0;
+ unsigned int match_length = 0;
+ unsigned int match_positions[MAX_CONTEXT_LENGTH];
return match_input (c,
inputCount, input,
lookup_context.funcs.match, lookup_context.match_data[1],
- &lookahead_offset)
+ &match_length, match_positions)
&& match_backtrack (c,
backtrackCount, backtrack,
lookup_context.funcs.match, lookup_context.match_data[0])
&& match_lookahead (c,
lookaheadCount, lookahead,
lookup_context.funcs.match, lookup_context.match_data[2],
- lookahead_offset)
+ match_length)
&& apply_lookup (c,
- inputCount, input,
- lookup_context.funcs.match, lookup_context.match_data[1],
- lookupCount, lookupRecord);
+ inputCount, match_positions,
+ lookupCount, lookupRecord,
+ match_length);
}
struct ChainRule
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (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);
- unsigned int count = lookup.len;
- for (unsigned int i = 0; i < count; i++)
- if (!c->recurse (lookup.array[i].lookupListIndex))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
@@ -1844,16 +1736,6 @@ struct ChainRule
struct ChainRuleSet
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int num_rules = rule.len;
- for (unsigned int i = 0; i < num_rules; i++)
- if (!(this+rule[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
@@ -1907,16 +1789,6 @@ struct ChainRuleSet
struct ChainContextFormat1
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int count = ruleSet.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+ruleSet[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -2000,16 +1872,6 @@ struct ChainContextFormat1
struct ChainContextFormat2
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (this);
- unsigned int count = ruleSet.len;
- for (unsigned int i = 0; i < count; i++)
- if (!(this+ruleSet[i]).is_inplace (c))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
@@ -2134,20 +1996,6 @@ struct ChainContextFormat2
struct ChainContextFormat3
{
- inline bool is_inplace (hb_is_inplace_context_t *c) const
- {
- TRACE_IS_INPLACE (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);
-
- unsigned int count = lookup.len;
- for (unsigned int i = 0; i < count; i++)
- if (!c->recurse (lookup.array[i].lookupListIndex))
- return TRACE_RETURN (false);
- return TRACE_RETURN (true);
- }
-
inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE (this);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
new file mode 100644
index 0000000000..79eb859566
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
@@ -0,0 +1,229 @@
+/*
+ * Copyright © 2013 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_JSTF_TABLE_HH
+#define HB_OT_LAYOUT_JSTF_TABLE_HH
+
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-gpos-table.hh"
+
+
+namespace OT {
+
+
+/*
+ * JstfModList -- Justification Modification List Tables
+ */
+
+typedef IndexArray JstfModList;
+
+
+/*
+ * JstfMax -- Justification Maximum Table
+ */
+
+typedef OffsetListOf<PosLookup> JstfMax;
+
+
+/*
+ * JstfPriority -- Justification Priority Table
+ */
+
+struct JstfPriority
+{
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (c->check_struct (this) &&
+ shrinkageEnableGSUB.sanitize (c, this) &&
+ shrinkageDisableGSUB.sanitize (c, this) &&
+ shrinkageEnableGPOS.sanitize (c, this) &&
+ shrinkageDisableGPOS.sanitize (c, this) &&
+ shrinkageJstfMax.sanitize (c, this) &&
+ extensionEnableGSUB.sanitize (c, this) &&
+ extensionDisableGSUB.sanitize (c, this) &&
+ extensionEnableGPOS.sanitize (c, this) &&
+ extensionDisableGPOS.sanitize (c, this) &&
+ extensionJstfMax.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<JstfModList>
+ shrinkageEnableGSUB; /* Offset to Shrinkage Enable GSUB
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ shrinkageDisableGSUB; /* Offset to Shrinkage Disable GSUB
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ shrinkageEnableGPOS; /* Offset to Shrinkage Enable GPOS
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ shrinkageDisableGPOS; /* Offset to Shrinkage Disable GPOS
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfMax>
+ shrinkageJstfMax; /* Offset to Shrinkage JstfMax table--
+ * from beginning of JstfPriority table
+ * --may be NULL */
+ OffsetTo<JstfModList>
+ extensionEnableGSUB; /* Offset to Extension Enable GSUB
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ extensionDisableGSUB; /* Offset to Extension Disable GSUB
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ extensionEnableGPOS; /* Offset to Extension Enable GPOS
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfModList>
+ extensionDisableGPOS; /* Offset to Extension Disable GPOS
+ * JstfModList table--from beginning of
+ * JstfPriority table--may be NULL */
+ OffsetTo<JstfMax>
+ extensionJstfMax; /* Offset to Extension JstfMax table--
+ * from beginning of JstfPriority table
+ * --may be NULL */
+
+ public:
+ DEFINE_SIZE_STATIC (20);
+};
+
+
+/*
+ * JstfLangSys -- Justification Language System Table
+ */
+
+struct JstfLangSys : OffsetListOf<JstfPriority>
+{
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<JstfLangSys>::sanitize_closure_t * = NULL) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (OffsetListOf<JstfPriority>::sanitize (c));
+ }
+};
+
+
+/*
+ * ExtenderGlyphs -- Extender Glyph Table
+ */
+
+typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
+
+
+/*
+ * JstfScript -- The Justification Table
+ */
+
+struct JstfScript
+{
+ inline unsigned int get_lang_sys_count (void) const
+ { return langSys.len; }
+ inline const Tag& get_lang_sys_tag (unsigned int i) const
+ { return langSys.get_tag (i); }
+ inline unsigned int get_lang_sys_tags (unsigned int start_offset,
+ unsigned int *lang_sys_count /* IN/OUT */,
+ hb_tag_t *lang_sys_tags /* OUT */) const
+ { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
+ inline const JstfLangSys& get_lang_sys (unsigned int i) const
+ {
+ if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
+ return this+langSys[i].offset;
+ }
+ inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
+ { return langSys.find_index (tag, index); }
+
+ inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
+ inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
+
+ inline bool sanitize (hb_sanitize_context_t *c,
+ const Record<JstfScript>::sanitize_closure_t * = NULL) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (extenderGlyphs.sanitize (c, this) &&
+ defaultLangSys.sanitize (c, this) &&
+ langSys.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<ExtenderGlyphs>
+ extenderGlyphs; /* Offset to ExtenderGlyph table--from beginning
+ * of JstfScript table-may be NULL */
+ OffsetTo<JstfLangSys>
+ defaultLangSys; /* Offset to DefaultJstfLangSys table--from
+ * beginning of JstfScript table--may be Null */
+ RecordArrayOf<JstfLangSys>
+ langSys; /* Array of JstfLangSysRecords--listed
+ * alphabetically by LangSysTag */
+ public:
+ DEFINE_SIZE_ARRAY (6, langSys);
+};
+
+
+/*
+ * JSTF -- The Justification Table
+ */
+
+struct JSTF
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_JSTF;
+
+ inline unsigned int get_script_count (void) const
+ { return scriptList.len; }
+ inline const Tag& get_script_tag (unsigned int i) const
+ { return scriptList.get_tag (i); }
+ inline unsigned int get_script_tags (unsigned int start_offset,
+ unsigned int *script_count /* IN/OUT */,
+ hb_tag_t *script_tags /* OUT */) const
+ { return scriptList.get_tags (start_offset, script_count, script_tags); }
+ inline const JstfScript& get_script (unsigned int i) const
+ { return this+scriptList[i].offset; }
+ inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
+ { return scriptList.find_index (tag, index); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) {
+ TRACE_SANITIZE (this);
+ return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
+ scriptList.sanitize (c, this));
+ }
+
+ protected:
+ FixedVersion version; /* Version of the JSTF table--initially set
+ * to 0x00010000 */
+ RecordArrayOf<JstfScript>
+ scriptList; /* Array of JstfScripts--listed
+ * alphabetically by ScriptTag */
+ public:
+ DEFINE_SIZE_ARRAY (6, scriptList);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_LAYOUT_JSTF_TABLE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
index c5ba8b4b4d..0a0a54b25d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
@@ -1,6 +1,6 @@
/*
* Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2012 Google, Inc.
+ * Copyright © 2012,2013 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -31,47 +31,184 @@
#include "hb-private.hh"
-#include "hb-ot-layout.h"
-
#include "hb-font-private.hh"
#include "hb-buffer-private.hh"
#include "hb-set-private.hh"
-/* buffer var allocations, used during the GSUB/GPOS processing */
-#define glyph_props() var1.u16[0] /* GDEF glyph properties */
-#define syllable() var1.u8[2] /* GSUB/GPOS shaping boundaries */
-#define lig_props() var1.u8[3] /* GSUB/GPOS ligature tracking */
+/*
+ * GDEF
+ */
+
+typedef enum
+{
+ /* The following three match LookupFlags::Ignore* numbers. */
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 0x02u,
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 0x04u,
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK = 0x08u,
+
+ /* The following are used internally; not derived from GDEF. */
+ HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED = 0x10u,
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATED = 0x20u,
+
+ HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
+ HB_OT_LAYOUT_GLYPH_PROPS_LIGATED
+} hb_ot_layout_glyph_class_mask_t;
+
+
+/*
+ * GSUB/GPOS
+ */
+
+HB_INTERNAL hb_bool_t
+hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
+ unsigned int lookup_index,
+ const hb_codepoint_t *glyphs,
+ unsigned int glyphs_length,
+ hb_bool_t zero_context);
+
+
+/* Should be called before all the substitute_lookup's are done. */
+HB_INTERNAL void
+hb_ot_layout_substitute_start (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+struct hb_ot_layout_lookup_accelerator_t;
+
+namespace OT {
+ struct hb_apply_context_t;
+ struct SubstLookup;
+}
+
+HB_INTERNAL void
+hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
+ const OT::SubstLookup &lookup,
+ const hb_ot_layout_lookup_accelerator_t &accel);
+
+
+/* Should be called after all the substitute_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_substitute_finish (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+/* Should be called before all the position_lookup's are done. Resets positions to zero. */
+HB_INTERNAL void
+hb_ot_layout_position_start (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+/* Should be called after all the position_lookup's are done */
+HB_INTERNAL void
+hb_ot_layout_position_finish (hb_font_t *font,
+ hb_buffer_t *buffer);
+
+
+
+/*
+ * hb_ot_layout_t
+ */
+
+namespace OT {
+ struct GDEF;
+ struct GSUB;
+ struct GPOS;
+}
+
+struct hb_ot_layout_lookup_accelerator_t
+{
+ template <typename TLookup>
+ inline void init (const TLookup &lookup)
+ {
+ digest.init ();
+ lookup.add_coverage (&digest);
+ }
+
+ template <typename TLookup>
+ inline void fini (const TLookup &lookup)
+ {
+ }
+
+ hb_set_digest_t digest;
+};
+
+struct hb_ot_layout_t
+{
+ hb_blob_t *gdef_blob;
+ hb_blob_t *gsub_blob;
+ hb_blob_t *gpos_blob;
+
+ const struct OT::GDEF *gdef;
+ const struct OT::GSUB *gsub;
+ const struct OT::GPOS *gpos;
+
+ unsigned int gsub_lookup_count;
+ unsigned int gpos_lookup_count;
+
+ hb_ot_layout_lookup_accelerator_t *gsub_accels;
+ hb_ot_layout_lookup_accelerator_t *gpos_accels;
+};
+
+
+HB_INTERNAL hb_ot_layout_t *
+_hb_ot_layout_create (hb_face_t *face);
+
+HB_INTERNAL void
+_hb_ot_layout_destroy (hb_ot_layout_t *layout);
+
+
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
+
+
+/*
+ * Buffer var routines.
+ */
/* buffer var allocations, used during the entire shaping process */
#define unicode_props0() var2.u8[0]
#define unicode_props1() var2.u8[1]
+/* buffer var allocations, used during the GSUB/GPOS processing */
+#define glyph_props() var1.u16[0] /* GDEF glyph properties */
+#define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */
+#define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */
+
+/* unicode_props */
+
+enum {
+ MASK0_ZWJ = 0x20u,
+ MASK0_ZWNJ = 0x40u,
+ MASK0_IGNORABLE = 0x80u,
+ MASK0_GEN_CAT = 0x1Fu
+};
inline void
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
{
+ /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */
info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
- (unicode->is_default_ignorable (info->codepoint) ? 0x80 : 0) |
- (info->codepoint == 0x200C ? 0x40 : 0) |
- (info->codepoint == 0x200D ? 0x20 : 0);
+ (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
+ (info->codepoint == 0x200C ? MASK0_ZWNJ : 0) |
+ (info->codepoint == 0x200D ? MASK0_ZWJ : 0);
info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
}
inline void
-_hb_glyph_info_set_general_category (hb_glyph_info_t *info, hb_unicode_general_category_t gen_cat)
+_hb_glyph_info_set_general_category (hb_glyph_info_t *info,
+ hb_unicode_general_category_t gen_cat)
{
- info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~0x1F);
+ info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
}
inline hb_unicode_general_category_t
_hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
{
- return (hb_unicode_general_category_t) (info->unicode_props0() & 0x1F);
+ return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT);
}
inline void
-_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
+_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
+ unsigned int modified_class)
{
info->unicode_props1() = modified_class;
}
@@ -85,43 +222,28 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
inline hb_bool_t
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
{
- return !!(info->unicode_props0() & 0x80);
+ return !!(info->unicode_props0() & MASK0_IGNORABLE);
}
inline hb_bool_t
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
{
- return !!(info->unicode_props0() & 0x40);
+ return !!(info->unicode_props0() & MASK0_ZWNJ);
}
inline hb_bool_t
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
{
- return !!(info->unicode_props0() & 0x20);
+ return !!(info->unicode_props0() & MASK0_ZWJ);
}
+inline void
+_hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
+{
+ info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
+}
-#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
-
-/*
- * GDEF
- */
-
-typedef enum {
- HB_OT_LAYOUT_GLYPH_PROPS_UNCLASSIFIED = 1 << HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED,
- HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH = 1 << HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH,
- HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE = 1 << HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE,
- HB_OT_LAYOUT_GLYPH_PROPS_MARK = 1 << HB_OT_LAYOUT_GLYPH_CLASS_MARK,
- HB_OT_LAYOUT_GLYPH_PROPS_COMPONENT = 1 << HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT
-} hb_ot_layout_glyph_class_mask_t;
-
-
-
-/*
- * GSUB/GPOS
- */
-
-/* lig_id / lig_comp
+/* lig_props: aka lig_id / lig_comp
*
* When a ligature is formed:
*
@@ -131,7 +253,9 @@ typedef enum {
* - The marks get lig_comp > 0, reflecting which component of the ligature
* they were applied to.
* - This is used in GPOS to attach marks to the right component of a ligature
- * in MarkLigPos.
+ * in MarkLigPos,
+ * - Note that when marks are ligated together, much of the above is skipped
+ * and the current lig_id reused.
*
* When a multiple-substitution is done:
*
@@ -141,156 +265,159 @@ typedef enum {
* multiple substitution in MarkBasePos.
*
* The numbers are also used in GPOS to do mark-to-mark positioning only
- * to marks that belong to the same component of a ligature in MarkMarPos.
+ * to marks that belong to the same component of the same ligature.
*/
+
+static inline void
+_hb_glyph_info_clear_lig_props (hb_glyph_info_t *info)
+{
+ info->lig_props() = 0;
+}
+
#define IS_LIG_BASE 0x10
+
static inline void
-set_lig_props_for_ligature (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_num_comps)
+_hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info,
+ unsigned int lig_id,
+ unsigned int lig_num_comps)
{
- info.lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
+ info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
}
+
static inline void
-set_lig_props_for_mark (hb_glyph_info_t &info, unsigned int lig_id, unsigned int lig_comp)
+_hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
+ unsigned int lig_id,
+ unsigned int lig_comp)
{
- info.lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
+ info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
}
+
static inline void
-set_lig_props_for_component (hb_glyph_info_t &info, unsigned int comp)
+_hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
{
- set_lig_props_for_mark (info, 0, comp);
+ _hb_glyph_info_set_lig_props_for_mark (info, 0, comp);
}
static inline unsigned int
-get_lig_id (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
{
- return info.lig_props() >> 5;
+ return info->lig_props() >> 5;
}
+
static inline bool
-is_a_ligature (const hb_glyph_info_t &info)
+_hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
{
- return !!(info.lig_props() & IS_LIG_BASE);
+ return !!(info->lig_props() & IS_LIG_BASE);
}
+
static inline unsigned int
-get_lig_comp (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
{
- if (is_a_ligature (info))
+ if (_hb_glyph_info_ligated_internal (info))
return 0;
else
- return info.lig_props() & 0x0F;
+ return info->lig_props() & 0x0F;
}
+
static inline unsigned int
-get_lig_num_comps (const hb_glyph_info_t &info)
+_hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
{
- if ((info.glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) && is_a_ligature (info))
- return info.lig_props() & 0x0F;
+ if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) &&
+ _hb_glyph_info_ligated_internal (info))
+ return info->lig_props() & 0x0F;
else
return 1;
}
-static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
+static inline uint8_t
+_hb_allocate_lig_id (hb_buffer_t *buffer) {
uint8_t lig_id = buffer->next_serial () & 0x07;
if (unlikely (!lig_id))
- lig_id = allocate_lig_id (buffer); /* in case of overflow */
+ lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
return lig_id;
}
+/* glyph_props: */
-HB_INTERNAL hb_bool_t
-hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
- unsigned int lookup_index,
- const hb_codepoint_t *glyphs,
- unsigned int glyphs_length,
- hb_bool_t zero_context);
-
-
-/* Should be called before all the substitute_lookup's are done. */
-HB_INTERNAL void
-hb_ot_layout_substitute_start (hb_font_t *font,
- hb_buffer_t *buffer);
-
-
-struct hb_ot_layout_lookup_accelerator_t;
-
-namespace OT {
- struct hb_apply_context_t;
- struct SubstLookup;
+inline void
+_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
+{
+ info->glyph_props() = props;
}
-HB_INTERNAL void
-hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
- const OT::SubstLookup &lookup,
- const hb_ot_layout_lookup_accelerator_t &accel);
-
-
-/* Should be called after all the substitute_lookup's are done */
-HB_INTERNAL void
-hb_ot_layout_substitute_finish (hb_font_t *font,
- hb_buffer_t *buffer);
-
-
-/* Should be called before all the position_lookup's are done. Resets positions to zero. */
-HB_INTERNAL void
-hb_ot_layout_position_start (hb_font_t *font,
- hb_buffer_t *buffer);
-
-/* Should be called after all the position_lookup's are done */
-HB_INTERNAL void
-hb_ot_layout_position_finish (hb_font_t *font,
- hb_buffer_t *buffer);
-
-
-
-/*
- * hb_ot_layout_t
- */
-
-namespace OT {
- struct GDEF;
- struct GSUB;
- struct GPOS;
+inline unsigned int
+_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
+{
+ return info->glyph_props();
}
-struct hb_ot_layout_lookup_accelerator_t
+inline bool
+_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
{
- template <typename TLookup>
- inline void init (const TLookup &lookup)
- {
- digest.init ();
- lookup.add_coverage (&digest);
- }
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
+}
- template <typename TLookup>
- inline void fini (const TLookup &lookup)
- {
- }
+inline bool
+_hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
+{
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
+}
- hb_set_digest_t digest;
-};
+inline bool
+_hb_glyph_info_is_mark (const hb_glyph_info_t *info)
+{
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+}
-struct hb_ot_layout_t
+static inline bool
+_hb_glyph_info_substituted (const hb_glyph_info_t *info)
{
- hb_blob_t *gdef_blob;
- hb_blob_t *gsub_blob;
- hb_blob_t *gpos_blob;
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
+}
- const struct OT::GDEF *gdef;
- const struct OT::GSUB *gsub;
- const struct OT::GPOS *gpos;
+static inline bool
+_hb_glyph_info_ligated (const hb_glyph_info_t *info)
+{
+ return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
+}
- unsigned int gsub_lookup_count;
- unsigned int gpos_lookup_count;
+/* Allocation / deallocation. */
- hb_ot_layout_lookup_accelerator_t *gsub_accels;
- hb_ot_layout_lookup_accelerator_t *gpos_accels;
-};
+inline void
+_hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
+ HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
+}
+inline void
+_hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
+{
+ HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
+}
-HB_INTERNAL hb_ot_layout_t *
-_hb_ot_layout_create (hb_face_t *face);
+inline void
+_hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
+{
+ HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
+ HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
+ HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
+}
-HB_INTERNAL void
-_hb_ot_layout_destroy (hb_ot_layout_t *layout);
+inline void
+_hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
+{
+ HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
+}
+/* Make sure no one directly touches our props... */
+#undef unicode_props0
+#undef unicode_props1
+#undef lig_props
+#undef glyph_props
#endif /* HB_OT_LAYOUT_PRIVATE_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
index 520deff710..183726e63c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
@@ -33,6 +33,7 @@
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
+#include "hb-ot-layout-jstf-table.hh"
#include "hb-ot-map-private.hh"
@@ -413,6 +414,24 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
}
+unsigned int
+hb_ot_layout_table_get_lookup_count (hb_face_t *face,
+ hb_tag_t table_tag)
+{
+ switch (table_tag)
+ {
+ case HB_OT_TAG_GSUB:
+ {
+ return hb_ot_layout_from_face (face)->gsub_lookup_count;
+ }
+ case HB_OT_TAG_GPOS:
+ {
+ return hb_ot_layout_from_face (face)->gpos_lookup_count;
+ }
+ }
+ return 0;
+}
+
static void
_hb_ot_layout_collect_lookups_lookups (hb_face_t *face,
hb_tag_t table_tag,
@@ -764,6 +783,7 @@ hb_ot_layout_get_size_params (hb_face_t *face,
struct GSUBProxy
{
static const unsigned int table_index = 0;
+ static const bool inplace = false;
typedef OT::SubstLookup Lookup;
GSUBProxy (hb_face_t *face) :
@@ -777,6 +797,7 @@ struct GSUBProxy
struct GPOSProxy
{
static const unsigned int table_index = 1;
+ static const bool inplace = true;
typedef OT::PosLookup Lookup;
GPOSProxy (hb_face_t *face) :
@@ -804,10 +825,9 @@ apply_string (OT::hb_apply_context_t *c,
const hb_ot_layout_lookup_accelerator_t &accel)
{
bool ret = false;
- OT::hb_is_inplace_context_t inplace_c (c->face);
- bool inplace = lookup.is_inplace (&inplace_c);
+ hb_buffer_t *buffer = c->buffer;
- if (unlikely (!c->buffer->len || !c->lookup_mask))
+ if (unlikely (!buffer->len || !c->lookup_mask))
return false;
c->set_lookup (lookup);
@@ -816,43 +836,43 @@ apply_string (OT::hb_apply_context_t *c,
{
/* in/out forward substitution/positioning */
if (Proxy::table_index == 0)
- c->buffer->clear_output ();
- c->buffer->idx = 0;
+ buffer->clear_output ();
+ buffer->idx = 0;
- while (c->buffer->idx < c->buffer->len)
+ while (buffer->idx < buffer->len)
{
- if (accel.digest.may_have (c->buffer->cur().codepoint) &&
- (c->buffer->cur().mask & c->lookup_mask) &&
+ if (accel.digest.may_have (buffer->cur().codepoint) &&
+ (buffer->cur().mask & c->lookup_mask) &&
apply_once (c, lookup))
ret = true;
else
- c->buffer->next_glyph ();
+ buffer->next_glyph ();
}
if (ret)
{
- if (!inplace)
- c->buffer->swap_buffers ();
+ if (!Proxy::inplace)
+ buffer->swap_buffers ();
else
- assert (!c->buffer->has_separate_output ());
+ assert (!buffer->has_separate_output ());
}
}
else
{
/* in-place backward substitution/positioning */
if (Proxy::table_index == 0)
- c->buffer->remove_output ();
- c->buffer->idx = c->buffer->len - 1;
+ buffer->remove_output ();
+ buffer->idx = buffer->len - 1;
do
{
- if (accel.digest.may_have (c->buffer->cur().codepoint) &&
- (c->buffer->cur().mask & c->lookup_mask) &&
+ if (accel.digest.may_have (buffer->cur().codepoint) &&
+ (buffer->cur().mask & c->lookup_mask) &&
apply_once (c, lookup))
ret = true;
- else
- c->buffer->idx--;
+ /* The reverse lookup doesn't "advance" cursor (for good reason). */
+ buffer->idx--;
}
- while ((int) c->buffer->idx >= 0);
+ while ((int) buffer->idx >= 0);
}
return ret;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
index 134f1a6c16..dfc7f2446f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
@@ -41,6 +41,7 @@ HB_BEGIN_DECLS
#define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
+#define HB_OT_TAG_JSTF HB_TAG('J','S','T','F')
/*
@@ -179,6 +180,11 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_indexes /* OUT */);
+unsigned int
+hb_ot_layout_table_get_lookup_count (hb_face_t *face,
+ hb_tag_t table_tag);
+
+
void
hb_ot_layout_collect_lookups (hb_face_t *face,
hb_tag_t table_tag,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
index 43856fa37e..559193c1ba 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
@@ -40,6 +40,9 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
{
unsigned int lookup_indices[32];
unsigned int offset, len;
+ unsigned int table_lookup_count;
+
+ table_lookup_count = hb_ot_layout_table_get_lookup_count (face, table_tags[table_index]);
offset = 0;
do {
@@ -50,7 +53,10 @@ hb_ot_map_t::add_lookups (hb_face_t *face,
offset, &len,
lookup_indices);
- for (unsigned int i = 0; i < len; i++) {
+ for (unsigned int i = 0; i < len; i++)
+ {
+ if (lookup_indices[i] >= table_lookup_count)
+ continue;
hb_ot_map_t::lookup_map_t *lookup = lookups[table_index].push ();
if (unlikely (!lookup))
return;
@@ -175,7 +181,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m)
continue; /* Feature disabled, or not enough bits. */
- bool found = false;
+ hb_bool_t found = false;
unsigned int feature_index[2];
for (unsigned int table_index = 0; table_index < 2; table_index++)
found |= hb_ot_layout_language_find_feature (face,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
index 0ce3ebcc2a..e6d255579c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh
@@ -41,7 +41,7 @@ namespace OT {
struct maxp
{
- static const hb_tag_t Tag = HB_OT_TAG_maxp;
+ static const hb_tag_t tableTag = HB_OT_TAG_maxp;
inline unsigned int get_num_glyphs (void) const {
return numGlyphs;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
index e36b0f7c97..07dc0565ca 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh
@@ -74,7 +74,7 @@ struct NameRecord
struct name
{
- static const hb_tag_t Tag = HB_OT_TAG_name;
+ static const hb_tag_t tableTag = HB_OT_TAG_name;
inline unsigned int get_name (unsigned int platform_id,
unsigned int encoding_id,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
index a57e81a5ec..4f6c86e8ee 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc
@@ -157,6 +157,11 @@ static const struct arabic_state_table_entry {
static void
+nuke_joiners (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+
+static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@@ -176,6 +181,8 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
* TODO: Add test cases for these two.
*/
+ map->add_gsub_pause (nuke_joiners);
+
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
@@ -273,7 +280,8 @@ arabic_joining (hb_buffer_t *buffer)
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;
+ for (; prev < i; prev++)
+ buffer->info[prev].arabic_shaping_action() = entry->prev_action;
buffer->info[i].arabic_shaping_action() = entry->curr_action;
@@ -314,6 +322,17 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
static void
+nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if (_hb_glyph_info_is_zwj (&buffer->info[i]))
+ _hb_glyph_info_flip_joiners (&buffer->info[i]);
+}
+
+static void
arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
index 39268b1453..3de5c203fa 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh
@@ -43,23 +43,25 @@
* Not sure how to avoid duplication. */
enum indic_category_t {
OT_X = 0,
- OT_C,
- OT_V,
- OT_N,
- OT_H,
- OT_ZWNJ,
- OT_ZWJ,
- OT_M,
- OT_SM,
- OT_VD,
- OT_A,
- OT_NBSP,
- OT_DOTTEDCIRCLE, /* Not in the spec, but special in Uniscribe. /Very very/ special! */
- 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_CM
+ OT_C = 1,
+ OT_V = 2,
+ OT_N = 3,
+ OT_H = 4,
+ OT_ZWNJ = 5,
+ OT_ZWJ = 6,
+ OT_M = 7,
+ OT_SM = 8,
+ OT_VD = 9,
+ OT_A = 10,
+ OT_NBSP = 11,
+ OT_DOTTEDCIRCLE = 12,
+ OT_RS = 13, /* Register Shifter, used in Khmer OT spec. */
+ OT_Coeng = 14, /* Khmer-style Virama. */
+ OT_Repha = 15, /* Atomically-encoded logical or visual repha. */
+ OT_Ra = 16,
+ OT_CM = 17, /* Consonant-Medial. */
+ OT_Avag = 18, /* Avagraha. */
+ OT_CM2 = 31 /* Consonant-Medial, second slot. */
};
/* Visual positions in a syllable from left to right. */
@@ -93,7 +95,7 @@ enum indic_position_t {
enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
- INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_X,
+ INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_Avag,
INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
@@ -101,7 +103,7 @@ enum indic_syllabic_category_t {
INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = 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_SUBJOINED = OT_CM,
INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_Repha,
INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
index d3c475b6ab..9edefe305d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc
@@ -128,14 +128,6 @@ static const hb_codepoint_t ra_chars[] = {
0x179A, /* Khmer */ /* No Reph, Visual Repha */
};
-static inline indic_position_t
-consonant_position (hb_codepoint_t u)
-{
- if ((u & ~0x007F) == 0x1780)
- return POS_BELOW_C; /* In Khmer coeng model, post and below forms should not be reordered. */
- return POS_BASE_C; /* Will recategorize later based on font lookups. */
-}
-
static inline bool
is_ra (hb_codepoint_t u)
{
@@ -149,7 +141,7 @@ static inline bool
is_one_of (const hb_glyph_info_t &info, unsigned int flags)
{
/* If it ligated, all bets are off. */
- if (is_a_ligature (info)) return false;
+ if (_hb_glyph_info_ligated (&info)) return false;
return !!(FLAG (info.indic_category()) & flags);
}
@@ -160,12 +152,14 @@ is_joiner (const hb_glyph_info_t &info)
return is_one_of (info, JOINER_FLAGS);
}
+#define MEDIAL_FLAGS (FLAG (OT_CM) | FLAG (OT_CM2))
+
/* Note:
*
* 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_CM) | FLAG (OT_Ra) | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
+#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_NBSP) | FLAG (OT_DOTTEDCIRCLE))
static inline bool
is_consonant (const hb_glyph_info_t &info)
{
@@ -194,15 +188,15 @@ set_indic_properties (hb_glyph_info_t &info)
/* The spec says U+0952 is OT_A. However, testing shows that Uniscribe
- * treats U+0951..U+0952 all as OT_VD.
+ * treats U+0951..U+0954 all behave similarly.
* TESTS:
* U+092E,U+0947,U+0952
* U+092E,U+0952,U+0947
* U+092E,U+0947,U+0951
* U+092E,U+0951,U+0947
- * */
+ */
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x0951, 0x0954)))
- cat = OT_VD;
+ cat = OT_A;
if (unlikely (u == 0x17D1))
cat = OT_X;
@@ -220,7 +214,10 @@ set_indic_properties (hb_glyph_info_t &info)
else if (unlikely (u == 0x200C)) cat = OT_ZWNJ;
else if (unlikely (u == 0x200D)) cat = OT_ZWJ;
else if (unlikely (u == 0x25CC)) cat = OT_DOTTEDCIRCLE;
- else if (unlikely (u == 0x0A71)) cat = OT_SM; /* GURMUKHI ADDAK. More like consonant medial. like 0A75. */
+ else if (unlikely (u == 0x0A71)) cat = OT_SM; /* GURMUKHI ADDAK. Move it to the end. */
+ else if (unlikely (u == 0xA982)) cat = OT_SM; /* Javanese repha. */
+ else if (unlikely (u == 0xA9BE)) cat = OT_CM2; /* Javanese medial ya. */
+ else if (unlikely (u == 0xA9BD)) { cat = OT_M; pos = POS_POST_C; } /* Javanese vocalic r. */
if (cat == OT_Repha) {
/* There are two kinds of characters marked as Repha:
@@ -241,7 +238,7 @@ set_indic_properties (hb_glyph_info_t &info)
if ((FLAG (cat) & CONSONANT_FLAGS))
{
- pos = consonant_position (u);
+ pos = POS_BASE_C;
if (is_ra (u))
cat = OT_Ra;
}
@@ -249,7 +246,7 @@ set_indic_properties (hb_glyph_info_t &info)
{
pos = matra_position (u, pos);
}
- else if (cat == OT_SM || cat == OT_VD)
+ else if ((FLAG (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Avag))))
{
pos = POS_SMVD;
}
@@ -277,16 +274,16 @@ set_indic_properties (hb_glyph_info_t &info)
enum base_position_t {
BASE_POS_FIRST,
+ BASE_POS_LAST_SINHALA,
BASE_POS_LAST
};
enum reph_position_t {
- REPH_POS_DEFAULT = POS_BEFORE_POST,
-
REPH_POS_AFTER_MAIN = POS_AFTER_MAIN,
REPH_POS_BEFORE_SUB = POS_BEFORE_SUB,
REPH_POS_AFTER_SUB = POS_AFTER_SUB,
REPH_POS_BEFORE_POST = POS_BEFORE_POST,
- REPH_POS_AFTER_POST = POS_AFTER_POST
+ REPH_POS_AFTER_POST = POS_AFTER_POST,
+ REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH
};
enum reph_mode_t {
REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */
@@ -294,6 +291,15 @@ enum reph_mode_t {
REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */
REPH_MODE_LOG_REPHA /* Encoded Repha character, needs reordering. */
};
+enum blwf_mode_t {
+ BLWF_MODE_PRE_AND_POST, /* Below-forms feature applied to pre-base and post-base. */
+ BLWF_MODE_POST_ONLY /* Below-forms feature applied to post-base only. */
+};
+enum pref_len_t {
+ PREF_LEN_1 = 1,
+ PREF_LEN_2 = 2,
+ PREF_LEN_DONT_CARE = PREF_LEN_2
+};
struct indic_config_t
{
hb_script_t script;
@@ -302,24 +308,27 @@ struct indic_config_t
base_position_t base_pos;
reph_position_t reph_pos;
reph_mode_t reph_mode;
+ blwf_mode_t blwf_mode;
+ pref_len_t pref_len;
};
static const indic_config_t indic_configs[] =
{
/* Default. Should be first. */
- {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
- {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT},
- {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
- {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT},
- {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT},
- {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},
- {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_LAST, REPH_POS_DEFAULT, REPH_MODE_IMPLICIT},
+ {HB_SCRIPT_INVALID, false, 0,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
+ {HB_SCRIPT_DEVANAGARI,true, 0x094D,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_BENGALI, true, 0x09CD,BASE_POS_LAST, REPH_POS_AFTER_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_GURMUKHI, true, 0x0A4D,BASE_POS_LAST, REPH_POS_BEFORE_SUB, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_GUJARATI, true, 0x0ACD,BASE_POS_LAST, REPH_POS_BEFORE_POST,REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_ORIYA, true, 0x0B4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_TAMIL, true, 0x0BCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+ {HB_SCRIPT_TELUGU, true, 0x0C4D,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_EXPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
+ {HB_SCRIPT_KANNADA, true, 0x0CCD,BASE_POS_LAST, REPH_POS_AFTER_POST, REPH_MODE_IMPLICIT, BLWF_MODE_POST_ONLY, PREF_LEN_2},
+ {HB_SCRIPT_MALAYALAM, true, 0x0D4D,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+ {HB_SCRIPT_SINHALA, false,0x0DCA,BASE_POS_LAST_SINHALA,
+ REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST, PREF_LEN_DONT_CARE},
+ {HB_SCRIPT_KHMER, false,0x17D2,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_2},
+ {HB_SCRIPT_JAVANESE, false,0xA9C0,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST, PREF_LEN_1},
};
@@ -346,15 +355,17 @@ indic_features[] =
{HB_TAG('r','k','r','f'), F_GLOBAL},
{HB_TAG('p','r','e','f'), F_NONE},
{HB_TAG('b','l','w','f'), F_NONE},
- {HB_TAG('h','a','l','f'), F_NONE},
{HB_TAG('a','b','v','f'), F_NONE},
+ {HB_TAG('h','a','l','f'), F_NONE},
{HB_TAG('p','s','t','f'), F_NONE},
- {HB_TAG('c','f','a','r'), F_NONE},
{HB_TAG('v','a','t','u'), F_GLOBAL},
{HB_TAG('c','j','c','t'), F_GLOBAL},
+ {HB_TAG('c','f','a','r'), F_NONE},
/*
* Other features.
* These features are applied all at once, after final_reordering.
+ * Default Bengali font in Windows for example has intermixed
+ * lookups for init,pres,abvs,blws features.
*/
{HB_TAG('i','n','i','t'), F_NONE},
{HB_TAG('p','r','e','s'), F_GLOBAL},
@@ -378,12 +389,12 @@ enum {
_RKRF,
PREF,
BLWF,
- HALF,
ABVF,
+ HALF,
PSTF,
- CFAR,
_VATU,
_CJCT,
+ CFAR,
INIT,
_PRES,
@@ -411,6 +422,10 @@ static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
static void
collect_features_indic (hb_ot_shape_planner_t *plan)
@@ -436,14 +451,26 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
for (; i < INDIC_NUM_FEATURES; i++) {
map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ);
}
+
+ map->add_global_bool_feature (HB_TAG('c','a','l','t'));
+ map->add_global_bool_feature (HB_TAG('c','l','i','g'));
+
+ map->add_gsub_pause (clear_syllables);
}
static void
override_features_indic (hb_ot_shape_planner_t *plan)
{
- /* Uniscribe does not apply 'kern'. */
+ /* Uniscribe does not apply 'kern' in Khmer. */
if (hb_options ().uniscribe_bug_compatible)
- plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+ {
+ switch ((hb_tag_t) plan->props.script)
+ {
+ case HB_SCRIPT_KHMER:
+ plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
+ break;
+ }
+ }
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
}
@@ -451,8 +478,9 @@ override_features_indic (hb_ot_shape_planner_t *plan)
struct would_substitute_feature_t
{
- inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag)
+ inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
+ zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
@@ -460,7 +488,6 @@ struct would_substitute_feature_t
inline bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
- bool zero_context,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
@@ -472,6 +499,7 @@ struct would_substitute_feature_t
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
+ bool zero_context;
};
struct indic_shape_plan_t
@@ -527,10 +555,13 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
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'));
+ /* Use zero-context would_substitute() matching for new-spec of the main
+ * Indic scripts, but not for old-spec or scripts with one spec only. */
+ bool zero_context = indic_plan->config->has_old_spec || !indic_plan->is_old_spec;
+ indic_plan->rphf.init (&plan->map, HB_TAG('r','p','h','f'), zero_context);
+ indic_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), zero_context);
+ indic_plan->blwf.init (&plan->map, HB_TAG('b','l','w','f'), zero_context);
+ indic_plan->pstf.init (&plan->map, HB_TAG('p','s','t','f'), zero_context);
for (unsigned int i = 0; i < ARRAY_LENGTH (indic_plan->mask_array); i++)
indic_plan->mask_array[i] = (indic_features[i].flags & F_GLOBAL) ?
@@ -547,7 +578,8 @@ data_destroy_indic (void *data)
static indic_position_t
consonant_position_from_face (const indic_shape_plan_t *indic_plan,
- const hb_codepoint_t glyphs[2],
+ const hb_codepoint_t consonant,
+ const hb_codepoint_t virama,
hb_face_t *face)
{
/* For old-spec, the order of glyphs is Consonant,Virama,
@@ -560,16 +592,19 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
* 930,94D in 'blwf', not the expected 94D,930 (with new-spec
* table). As such, we simply match both sequences. Seems
* to work. */
- bool zero_context = indic_plan->is_old_spec ? false : true;
- hb_codepoint_t glyphs_r[2] = {glyphs[1], glyphs[0]};
- if (indic_plan->pref.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->pref.would_substitute (glyphs_r, 2, zero_context, face))
- return POS_POST_C;
- if (indic_plan->blwf.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->blwf.would_substitute (glyphs_r, 2, zero_context, face))
+ hb_codepoint_t glyphs[3] = {virama, consonant, virama};
+ if (indic_plan->blwf.would_substitute (glyphs , 2, face) ||
+ indic_plan->blwf.would_substitute (glyphs+1, 2, face))
return POS_BELOW_C;
- if (indic_plan->pstf.would_substitute (glyphs , 2, zero_context, face) ||
- indic_plan->pstf.would_substitute (glyphs_r, 2, zero_context, face))
+ if (indic_plan->pstf.would_substitute (glyphs , 2, face) ||
+ indic_plan->pstf.would_substitute (glyphs+1, 2, face))
+ return POS_POST_C;
+ unsigned int pref_len = indic_plan->config->pref_len;
+ if ((pref_len == PREF_LEN_2 &&
+ (indic_plan->pref.would_substitute (glyphs , 2, face) ||
+ indic_plan->pref.would_substitute (glyphs+1, 2, face)))
+ || (pref_len == PREF_LEN_1 &&
+ indic_plan->pref.would_substitute (glyphs+1, 1, face)))
return POS_POST_C;
return POS_BASE_C;
}
@@ -579,6 +614,7 @@ enum syllable_type_t {
consonant_syllable,
vowel_syllable,
standalone_cluster,
+ avagraha_cluster,
broken_cluster,
non_indic_cluster,
};
@@ -628,15 +664,18 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
- hb_codepoint_t glyphs[2];
- if (indic_plan->get_virama_glyph (font, &glyphs[0]))
+ if (indic_plan->config->base_pos != BASE_POS_LAST)
+ return;
+
+ hb_codepoint_t virama;
+ if (indic_plan->get_virama_glyph (font, &virama))
{
hb_face_t *face = font->face;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
if (buffer->info[i].indic_position() == POS_BASE_C) {
- glyphs[1] = buffer->info[i].codepoint;
- buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, glyphs, face);
+ hb_codepoint_t consonant = buffer->info[i].codepoint;
+ buffer->info[i].indic_position() = consonant_position_from_face (indic_plan, consonant, virama, face);
}
}
}
@@ -677,7 +716,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* and has more than one consonant, Ra is excluded from candidates for
* base consonants. */
unsigned int limit = start;
- if (indic_plan->mask_array[RPHF] &&
+ if (indic_plan->config->reph_pos != REPH_POS_DONT_CARE &&
+ indic_plan->mask_array[RPHF] &&
start + 3 <= end &&
(
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
@@ -686,7 +726,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
{
/* 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))
+ if (indic_plan->rphf.would_substitute (glyphs, ARRAY_LENGTH (glyphs), face))
{
limit += 2;
while (limit < end && is_joiner (info[limit]))
@@ -758,9 +798,12 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
break;
- case BASE_POS_FIRST:
+ case BASE_POS_LAST_SINHALA:
{
- /* In scripts without half forms (eg. Khmer), the first consonant is always the base. */
+ /* Sinhala base positioning is slightly different from main Indic, in that:
+ * 1. It's ZWJ behavior is different,
+ * 2. We don't need to look into the font for consonant positions.
+ */
if (!has_reph)
base = limit;
@@ -768,7 +811,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Find the last base consonant that is not blocked by ZWJ. If there is
* a ZWJ right before a base consonant, that would request a subjoined form. */
for (unsigned int i = limit; i < end; i++)
- if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
+ if (is_consonant (info[i]))
{
if (limit < i && info[i - 1].indic_category() == OT_ZWJ)
break;
@@ -778,7 +821,23 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Mark all subsequent consonants as below. */
for (unsigned int i = base + 1; i < end; i++)
- if (is_consonant (info[i]) && info[i].indic_position() == POS_BASE_C)
+ if (is_consonant (info[i]))
+ info[i].indic_position() = POS_BELOW_C;
+ }
+ break;
+
+ case BASE_POS_FIRST:
+ {
+ /* The first consonant is always the base. */
+
+ assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA);
+ assert (!has_reph);
+
+ base = start;
+
+ /* Mark all subsequent consonants as below. */
+ for (unsigned int i = base + 1; i < end; i++)
+ if (is_consonant (info[i]))
info[i].indic_position() = POS_BELOW_C;
}
break;
@@ -877,7 +936,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
indic_position_t last_pos = POS_START;
for (unsigned int i = start; i < end; i++)
{
- if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | HALANT_OR_COENG_FLAGS)))
+ if ((FLAG (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS)))
{
info[i].indic_position() = last_pos;
if (unlikely (info[i].indic_category() == OT_H &&
@@ -903,33 +962,68 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
}
}
- /* Re-attach ZWJ, ZWNJ, and halant to next char, for after-base consonants. */
+ /* For post-base consonants let them own anything before them
+ * since the last consonant or matra. */
{
- unsigned int last_halant = end;
+ unsigned int last = base;
for (unsigned int i = base + 1; i < end; i++)
- if (is_halant_or_coeng (info[i]))
- last_halant = i;
- else if (is_consonant (info[i])) {
- for (unsigned int j = last_halant; j < i; j++)
- if (info[j].indic_position() != POS_SMVD)
+ if (is_consonant (info[i]))
+ {
+ for (unsigned int j = last + 1; j < i; j++)
+ if (info[j].indic_position() < POS_SMVD)
info[j].indic_position() = info[i].indic_position();
- }
+ last = i;
+ } else if (info[i].indic_category() == OT_M)
+ last = i;
}
+
{
- /* Things are out-of-control for post base positions, they may shuffle
- * around like crazy, so merge clusters. For pre-base stuff, we handle
- * cluster issues in final reordering. */
- buffer->merge_clusters (base, end);
+ /* Use syllable() for sort accounting temporarily. */
+ unsigned int syllable = info[start].syllable();
+ for (unsigned int i = start; i < end; i++)
+ info[i].syllable() = i - start;
+
/* Sit tight, rock 'n roll! */
hb_bubble_sort (info + start, end - start, compare_indic_order);
/* Find base again */
base = end;
for (unsigned int i = start; i < end; i++)
- if (info[i].indic_position() == POS_BASE_C) {
- base = i;
+ if (info[i].indic_position() == POS_BASE_C)
+ {
+ base = i;
break;
}
+ /* Things are out-of-control for post base positions, they may shuffle
+ * around like crazy. In old-spec mode, we move halants around, so in
+ * that case merge all clusters after base. Otherwise, check the sort
+ * order and merge as needed.
+ * For pre-base stuff, we handle cluster issues in final reordering. */
+ if (indic_plan->is_old_spec || end - base > 127)
+ buffer->merge_clusters (base, end);
+ else
+ {
+ /* Note! syllable() is a one-byte field. */
+ for (unsigned int i = base; i < end; i++)
+ if (info[i].syllable() != 255)
+ {
+ unsigned int max = i;
+ unsigned int j = start + info[i].syllable();
+ while (j != i)
+ {
+ max = MAX (max, j);
+ unsigned int next = start + info[j].syllable();
+ info[j].syllable() = 255; /* So we don't process j later again. */
+ j = next;
+ }
+ if (i != max)
+ buffer->merge_clusters (i, max + 1);
+ }
+ }
+
+ /* Put syllable back in. */
+ for (unsigned int i = start; i < end; i++)
+ info[i].syllable() = syllable;
}
/* Setup masks now */
@@ -943,6 +1037,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Pre-base */
mask = indic_plan->mask_array[HALF];
+ if (!indic_plan->is_old_spec &&
+ indic_plan->config->blwf_mode == BLWF_MODE_PRE_AND_POST)
+ mask |= indic_plan->mask_array[BLWF];
for (unsigned int i = start; i < base; i++)
info[i].mask |= mask;
/* Base */
@@ -987,15 +1084,19 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
}
- if (indic_plan->mask_array[PREF] && base + 2 < end)
+ unsigned int pref_len = indic_plan->config->pref_len;
+ if (indic_plan->mask_array[PREF] && base + pref_len < end)
{
+ assert (1 <= pref_len && pref_len <= 2);
/* Find a Halant,Ra sequence and mark it for pre-base reordering processing. */
- for (unsigned int i = base + 1; i + 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))
+ for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
+ hb_codepoint_t glyphs[2];
+ for (unsigned int j = 0; j < pref_len; j++)
+ glyphs[j] = info[i + j].codepoint;
+ if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
{
- info[i++].mask |= indic_plan->mask_array[PREF];
- info[i++].mask |= indic_plan->mask_array[PREF];
+ for (unsigned int j = 0; j < pref_len; j++)
+ info[i++].mask |= indic_plan->mask_array[PREF];
/* Mark the subsequent stuff with 'cfar'. Used in Khmer.
* Read the feature spec.
@@ -1003,8 +1104,9 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* U+1784,U+17D2,U+179A,U+17D2,U+1782
* U+1784,U+17D2,U+1782,U+17D2,U+179A
*/
- for (; i < end; i++)
- info[i].mask |= indic_plan->mask_array[CFAR];
+ if (indic_plan->mask_array[CFAR])
+ for (; i < end; i++)
+ info[i].mask |= indic_plan->mask_array[CFAR];
break;
}
@@ -1075,6 +1177,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
}
static void
+initial_reordering_avagraha_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)
+{
+ /* Nothing to do right now. If we ever switch to using the output
+ * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+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,
@@ -1096,6 +1208,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
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 avagraha_cluster: initial_reordering_avagraha_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;
}
@@ -1265,9 +1378,9 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
info[new_pos] = tmp;
if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */
base--;
+ buffer->merge_clusters (new_pos, MIN (end, base + 1));
new_pos--;
}
- buffer->merge_clusters (new_pos, MIN (end, base + 1));
} else {
for (unsigned int i = start; i < base; i++)
if (info[i].indic_position () == POS_PRE_M) {
@@ -1287,17 +1400,24 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* before post-base consonant forms, and after post-base consonant forms.
*/
- /* If there's anything after the Ra that has the REPH pos, it ought to be halant.
- * Which means that the font has failed to ligate the Reph. In which case, we
- * shouldn't move. */
+ /* Two cases:
+ *
+ * - If repha is encoded as a sequence of characters (Ra,H or Ra,H,ZWJ), then
+ * we should only move it if the sequence ligated to the repha form.
+ *
+ * - If repha is encoded separately and in the logical position, we should only
+ * move it if it did NOT ligate. If it ligated, it's probably the font trying
+ * to make it work without the reordering.
+ */
if (start + 1 < end &&
info[start].indic_position() == POS_RA_TO_BECOME_REPH &&
- info[start + 1].indic_position() != POS_RA_TO_BECOME_REPH)
+ ((info[start].indic_category() == OT_Repha) ^
+ _hb_glyph_info_ligated (&info[start])))
{
unsigned int new_reph_pos;
reph_position_t reph_pos = indic_plan->config->reph_pos;
- /* XXX Figure out old behavior too */
+ assert (reph_pos != REPH_POS_DONT_CARE);
/* 1. If reph should be positioned after post-base consonant forms,
* proceed to step 5.
@@ -1339,7 +1459,6 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (reph_pos == REPH_POS_AFTER_MAIN)
{
new_reph_pos = base;
- /* XXX Skip potential pre-base reordering Ra. */
while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN)
new_reph_pos++;
if (new_reph_pos < end)
@@ -1412,8 +1531,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
reph_move:
{
- /* Yay, one big cluster! Merge before moving. */
- buffer->merge_clusters (start, end);
+ buffer->merge_clusters (start, new_reph_pos + 1);
/* Move */
hb_glyph_info_t reph = info[start];
@@ -1433,6 +1551,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (indic_plan->mask_array[PREF] && base + 1 < end) /* Otherwise there can't be any pre-base reordering Ra. */
{
+ unsigned int pref_len = indic_plan->config->pref_len;
for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & indic_plan->mask_array[PREF]) != 0)
{
@@ -1440,7 +1559,13 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* of the <pref> feature. (Note that a font may shape a Ra consonant with
* the feature generally but block it in certain contexts.)
*/
- if (i + 1 == end || (info[i + 1].mask & indic_plan->mask_array[PREF]) == 0)
+ /* Note: We just check that something got substituted. We don't check that
+ * the <pref> feature actually did it...
+ *
+ * If pref len is longer than one, then only reorder if it ligated. If
+ * pref len is one, only reorder if it didn't ligate with other things. */
+ if (_hb_glyph_info_substituted (&info[i]) &&
+ ((pref_len == 1) ^ _hb_glyph_info_ligated (&info[i])))
{
/*
* 2. Try to find a target position the same way as for pre-base matra.
@@ -1461,7 +1586,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
!(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS)))
new_pos--;
- /* In Khmer coeng model, a V,Ra can go *after* matras. If it goes after a
+ /* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a
* split matra, it should be reordered to *before* the left part of such matra. */
if (new_pos > start && info[new_pos - 1].indic_category() == OT_M)
{
@@ -1511,11 +1636,20 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
*/
if (hb_options ().uniscribe_bug_compatible)
{
- /* Uniscribe merges the entire cluster.
- * This means, half forms are submerged into the main consonants cluster.
- * This is unnecessary, and makes cursor positioning harder, but that's what
- * Uniscribe does. */
- buffer->merge_clusters (start, end);
+ switch ((hb_tag_t) plan->props.script)
+ {
+ case HB_SCRIPT_TAMIL:
+ case HB_SCRIPT_SINHALA:
+ break;
+
+ default:
+ /* Uniscribe merges the entire cluster... Except for Tamil & Sinhala.
+ * This means, half forms are submerged into the main consonants cluster.
+ * This is unnecessary, and makes cursor positioning harder, but that's what
+ * Uniscribe does. */
+ buffer->merge_clusters (start, end);
+ break;
+ }
}
}
@@ -1539,15 +1673,23 @@ final_reordering (const hb_ot_shape_plan_t *plan,
}
final_reordering_syllable (plan, buffer, last, count);
- /* Zero syllables now... */
- for (unsigned int i = 0; i < count; i++)
- info[i].syllable() = 0;
-
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position);
}
+static void
+clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ hb_glyph_info_t *info = buffer->info;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ info[i].syllable() = 0;
+}
+
+
static hb_ot_shape_normalization_mode_t
normalization_preference_indic (const hb_segment_properties_t *props HB_UNUSED)
{
@@ -1627,7 +1769,7 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
if (hb_options ().uniscribe_bug_compatible ||
(c->font->get_glyph (ab, 0, &glyph) &&
- indic_plan->pstf.would_substitute (&glyph, 1, true, c->font->face)))
+ indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
{
/* Ok, safe to use Uniscribe-style decomposition. */
*a = 0x0DD9;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
index 29f29bb556..25ba7264ca 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc
@@ -60,6 +60,16 @@ other_features[] =
HB_TAG('p','s','t','s'),
/* Positioning features, though we don't care about the types. */
HB_TAG('d','i','s','t'),
+ /* Pre-release version of Windows 8 Myanmar font had abvm,blwm
+ * features. The released Windows 8 version of the font (as well
+ * as the released spec) used 'mark' instead. The Windows 8
+ * shaper however didn't apply 'mark' but did apply 'mkmk'.
+ * Perhaps it applied abvm/blwm. This was fixed in a Windows 8
+ * update, so now it applies mark/mkmk. We are guessing that
+ * it still applies abvm/blwm too.
+ */
+ HB_TAG('a','b','v','m'),
+ HB_TAG('b','l','w','m'),
};
static void
@@ -109,6 +119,7 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
enum syllable_type_t {
consonant_syllable,
+ punctuation_cluster,
broken_cluster,
non_myanmar_cluster,
};
@@ -133,7 +144,8 @@ enum myanmar_category_t {
OT_VBlw = 27,
OT_VPre = 28,
OT_VPst = 29,
- OT_VS = 30 /* Variation selectors */
+ OT_VS = 30, /* Variation selectors */
+ OT_P = 31 /* Punctuation */
};
@@ -141,7 +153,7 @@ static inline bool
is_one_of (const hb_glyph_info_t &info, unsigned int flags)
{
/* If it ligated, all bets are off. */
- if (is_a_ligature (info)) return false;
+ if (_hb_glyph_info_ligated (&info)) return false;
return !!(FLAG (info.myanmar_category()) & flags);
}
@@ -176,6 +188,10 @@ set_myanmar_properties (hb_glyph_info_t &info)
switch (u)
{
+ case 0x104E:
+ cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
+ break;
+
case 0x002D: case 0x00A0: case 0x00D7: case 0x2012:
case 0x2013: case 0x2014: case 0x2015: case 0x2022:
case 0x25CC: case 0x25FB: case 0x25FC: case 0x25FD:
@@ -233,6 +249,10 @@ set_myanmar_properties (hb_glyph_info_t &info)
case 0x108F: case 0x109A: case 0x109B: case 0x109C:
cat = (indic_category_t) OT_SM;
break;
+
+ case 0x104A: case 0x104B:
+ cat = (indic_category_t) OT_P;
+ break;
}
if (cat == OT_M)
@@ -396,6 +416,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
}
static void
+initial_reordering_punctuation_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)
+{
+ /* Nothing to do right now. If we ever switch to using the output
+ * buffer in the reordering process, we'd need to next_glyph() here. */
+}
+
+static void
initial_reordering_non_myanmar_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_face_t *face HB_UNUSED,
hb_buffer_t *buffer HB_UNUSED,
@@ -415,6 +445,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type) {
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
+ case punctuation_cluster: initial_reordering_punctuation_cluster (plan, face, buffer, start, end); return;
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
case non_myanmar_cluster: initial_reordering_non_myanmar_cluster (plan, face, buffer, start, end); return;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
index a099e05d74..ac0072ba56 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh
@@ -279,9 +279,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
/* Unicode-3.0 additions */
case HB_SCRIPT_SINHALA:
- /* Unicode-4.1 additions */
- case HB_SCRIPT_BUGINESE:
-
/* Unicode-5.0 additions */
case HB_SCRIPT_BALINESE:
@@ -336,6 +333,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
return &_hb_ot_complex_shaper_default;
/* Unicode-4.1 additions */
+ case HB_SCRIPT_BUGINESE:
case HB_SCRIPT_NEW_TAI_LUE:
/* Unicode-5.1 additions */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
index 9c0c303e3d..da687ed646 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc
@@ -266,7 +266,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
switch (syllable_type) {
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
- case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return;
+ case non_sea_cluster: initial_reordering_non_sea_cluster (plan, face, buffer, start, end); return;
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
index 284d030d5f..449b64e5ca 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc
@@ -260,7 +260,13 @@ position_mark (const hb_ot_shape_plan_t *plan,
case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT:
case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW:
- pos.y_offset += base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
+ pos.y_offset = base_extents.y_bearing + base_extents.height - mark_extents.y_bearing;
+ /* Never shift up "below" marks. */
+ if ((y_gap > 0) == (pos.y_offset > 0))
+ {
+ base_extents.height -= pos.y_offset;
+ pos.y_offset = 0;
+ }
base_extents.height += mark_extents.height;
break;
@@ -274,7 +280,15 @@ position_mark (const hb_ot_shape_plan_t *plan,
case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE:
case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT:
- pos.y_offset += base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
+ pos.y_offset = base_extents.y_bearing - (mark_extents.y_bearing + mark_extents.height);
+ /* Don't shift down "above" marks too much. */
+ if ((y_gap > 0) != (pos.y_offset > 0))
+ {
+ unsigned int correction = -pos.y_offset / 2;
+ base_extents.y_bearing += correction;
+ base_extents.height -= correction;
+ pos.y_offset += correction;
+ }
base_extents.y_bearing -= mark_extents.height;
base_extents.height += mark_extents.height;
break;
@@ -300,8 +314,8 @@ position_around_base (const hb_ot_shape_plan_t *plan,
base_extents.x_bearing += buffer->pos[base].x_offset;
base_extents.y_bearing += buffer->pos[base].y_offset;
- unsigned int lig_id = get_lig_id (buffer->info[base]);
- unsigned int num_lig_components = get_lig_num_comps (buffer->info[base]);
+ unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[base]);
+ unsigned int num_lig_components = _hb_glyph_info_get_lig_num_comps (&buffer->info[base]);
hb_position_t x_offset = 0, y_offset = 0;
if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
@@ -317,8 +331,8 @@ position_around_base (const hb_ot_shape_plan_t *plan,
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
{
if (num_lig_components > 1) {
- unsigned int this_lig_id = get_lig_id (buffer->info[i]);
- unsigned int this_lig_component = get_lig_comp (buffer->info[i]) - 1;
+ unsigned int this_lig_id = _hb_glyph_info_get_lig_id (&buffer->info[i]);
+ unsigned int this_lig_component = _hb_glyph_info_get_lig_comp (&buffer->info[i]) - 1;
/* Conditions for attaching to the last component. */
if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
this_lig_component = num_lig_components - 1;
@@ -416,41 +430,52 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
- unsigned int count = buffer->len;
hb_mask_t kern_mask = plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
+ if (!kern_mask) return;
+
+ unsigned int count = buffer->len;
OT::hb_apply_context_t c (1, font, buffer);
c.set_lookup_mask (kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
- for (buffer->idx = 0; buffer->idx < count;)
+ hb_glyph_info_t *info = buffer->info;
+ hb_glyph_position_t *pos = buffer->pos;
+
+ for (unsigned int idx = 0; idx < count;)
{
- OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, buffer->idx, 1);
+ OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1);
if (!skippy_iter.next ())
{
- buffer->idx++;
+ idx++;
continue;
}
- hb_position_t x_kern, y_kern, kern1, kern2;
- font->get_glyph_kerning_for_direction (buffer->info[buffer->idx].codepoint,
- buffer->info[skippy_iter.idx].codepoint,
+ hb_position_t x_kern, y_kern;
+ font->get_glyph_kerning_for_direction (info[idx].codepoint,
+ info[skippy_iter.idx].codepoint,
buffer->props.direction,
&x_kern, &y_kern);
- kern1 = x_kern >> 1;
- kern2 = x_kern - kern1;
- buffer->pos[buffer->idx].x_advance += kern1;
- buffer->pos[skippy_iter.idx].x_advance += kern2;
- buffer->pos[skippy_iter.idx].x_offset += kern2;
+ if (x_kern)
+ {
+ hb_position_t kern1 = x_kern >> 1;
+ hb_position_t kern2 = x_kern - kern1;
+ pos[idx].x_advance += kern1;
+ pos[skippy_iter.idx].x_advance += kern2;
+ pos[skippy_iter.idx].x_offset += kern2;
+ }
- kern1 = y_kern >> 1;
- kern2 = y_kern - kern1;
- buffer->pos[buffer->idx].y_advance += kern1;
- buffer->pos[skippy_iter.idx].y_advance += kern2;
- buffer->pos[skippy_iter.idx].y_offset += kern2;
+ if (y_kern)
+ {
+ hb_position_t kern1 = y_kern >> 1;
+ hb_position_t kern2 = y_kern - kern1;
+ pos[idx].y_advance += kern1;
+ pos[skippy_iter.idx].y_advance += kern2;
+ pos[skippy_iter.idx].y_offset += kern2;
+ }
- buffer->idx = skippy_iter.idx;
+ idx = skippy_iter.idx;
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
index 085d48511d..fb8048caa2 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize-private.hh
@@ -29,8 +29,6 @@
#include "hb-private.hh"
-#include "hb-font.h"
-#include "hb-buffer.h"
/* buffer var allocations, used during the normalization process */
#define glyph_index() var1.u32
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
index 3fee809cf9..6531e1b215 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -132,17 +132,19 @@ static inline unsigned int
decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint_t ab)
{
hb_codepoint_t a, b, a_glyph, b_glyph;
+ hb_buffer_t * const buffer = c->buffer;
+ hb_font_t * const font = c->font;
if (!c->decompose (c, ab, &a, &b) ||
- (b && !c->font->get_glyph (b, 0, &b_glyph)))
+ (b && !font->get_glyph (b, 0, &b_glyph)))
return 0;
- bool has_a = c->font->get_glyph (a, 0, &a_glyph);
+ bool has_a = font->get_glyph (a, 0, &a_glyph);
if (shortest && has_a) {
/* Output a and b */
- output_char (c->buffer, a, a_glyph);
+ output_char (buffer, a, a_glyph);
if (likely (b)) {
- output_char (c->buffer, b, b_glyph);
+ output_char (buffer, b, b_glyph);
return 2;
}
return 1;
@@ -151,16 +153,16 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint
unsigned int ret;
if ((ret = decompose (c, shortest, a))) {
if (b) {
- output_char (c->buffer, b, b_glyph);
+ output_char (buffer, b, b_glyph);
return ret + 1;
}
return ret;
}
if (has_a) {
- output_char (c->buffer, a, a_glyph);
+ output_char (buffer, a, a_glyph);
if (likely (b)) {
- output_char (c->buffer, b, b_glyph);
+ output_char (buffer, b, b_glyph);
return 2;
}
return 1;
@@ -214,34 +216,35 @@ static inline void
handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end)
{
hb_buffer_t * const buffer = c->buffer;
+ hb_font_t * const font = c->font;
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. */
- if (c->font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
+ if (font->get_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
{
buffer->replace_glyphs (2, 1, &buffer->cur().codepoint);
}
else
{
/* Just pass on the two characters separately, let GSUB do its magic. */
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
}
/* Skip any further variation selectors. */
while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
{
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
}
} else {
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
}
}
if (likely (buffer->idx < end)) {
- set_glyph (buffer->cur(), c->font);
+ set_glyph (buffer->cur(), font);
buffer->next_glyph ();
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
index 817147199f..cbfab5b40c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-private.hh
@@ -66,7 +66,7 @@ struct hb_ot_shape_planner_t
hb_ot_map_builder_t map;
hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
- face (master_plan->face),
+ face (master_plan->face_unsafe),
props (master_plan->props),
shaper (NULL),
map (face, &props) {}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
index c23240c80c..63c36f936f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
@@ -290,16 +290,18 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
if (HB_DIRECTION_IS_FORWARD (c->target_direction))
return;
- hb_unicode_funcs_t *unicode = c->buffer->unicode;
+ hb_buffer_t *buffer = c->buffer;
+ hb_unicode_funcs_t *unicode = buffer->unicode;
hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
- unsigned int count = c->buffer->len;
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++) {
- hb_codepoint_t codepoint = unicode->mirroring (c->buffer->info[i].codepoint);
- if (likely (codepoint == c->buffer->info[i].codepoint))
- c->buffer->info[i].mask |= rtlm_mask;
+ hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
+ if (likely (codepoint == info[i].codepoint))
+ info[i].mask |= rtlm_mask;
else
- c->buffer->info[i].codepoint = codepoint;
+ info[i].codepoint = codepoint;
}
}
@@ -307,12 +309,13 @@ static inline void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
+ hb_buffer_t *buffer = c->buffer;
hb_mask_t global_mask = map->get_global_mask ();
- c->buffer->reset_masks (global_mask);
+ buffer->reset_masks (global_mask);
if (c->plan->shaper->setup_masks)
- c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
+ c->plan->shaper->setup_masks (c->plan, buffer, c->font);
for (unsigned int i = 0; i < c->num_user_features; i++)
{
@@ -320,7 +323,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
unsigned int shift;
hb_mask_t mask = map->get_mask (feature->tag, &shift);
- c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
+ buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
}
}
}
@@ -338,46 +341,53 @@ static inline void
hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
{
unsigned int count = c->buffer->len;
+ hb_glyph_info_t *info = c->buffer->info;
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_PROPS_MARK :
- HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+ _hb_glyph_info_set_glyph_props (&info[i],
+ _hb_glyph_info_get_general_category (&info[i])
+ == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
+ HB_OT_LAYOUT_GLYPH_PROPS_MARK :
+ HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
}
static inline void
hb_ot_substitute_default (hb_ot_shape_context_t *c)
{
+ hb_buffer_t *buffer = c->buffer;
+
if (c->plan->shaper->preprocess_text)
- c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
+ c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
hb_ot_mirror_chars (c);
- HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);
+ HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
- _hb_ot_shape_normalize (c->plan, c->buffer, c->font);
+ _hb_ot_shape_normalize (c->plan, buffer, c->font);
hb_ot_shape_setup_masks (c);
/* This is unfortunate to go here, but necessary... */
if (!hb_ot_layout_has_positioning (c->face))
- _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, c->buffer);
+ _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
- hb_ot_map_glyphs_fast (c->buffer);
+ hb_ot_map_glyphs_fast (buffer);
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index);
+ HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index);
}
static inline void
hb_ot_substitute_complex (hb_ot_shape_context_t *c)
{
- hb_ot_layout_substitute_start (c->font, c->buffer);
+ hb_buffer_t *buffer = c->buffer;
+
+ hb_ot_layout_substitute_start (c->font, buffer);
if (!hb_ot_layout_has_glyph_classes (c->face))
hb_synthesize_glyph_classes (c);
- c->plan->substitute (c->font, c->buffer);
+ c->plan->substitute (c->font, buffer);
- hb_ot_layout_substitute_finish (c->font, c->buffer);
+ hb_ot_layout_substitute_finish (c->font, buffer);
return;
}
@@ -408,7 +418,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
- if ((buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
+ if (_hb_glyph_info_is_mark (&buffer->info[i]))
{
buffer->pos[i].x_advance = 0;
buffer->pos[i].y_advance = 0;
@@ -418,21 +428,29 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer)
static inline void
hb_ot_position_default (hb_ot_shape_context_t *c)
{
- hb_ot_layout_position_start (c->font, c->buffer);
-
+ hb_direction_t direction = c->buffer->props.direction;
unsigned int count = c->buffer->len;
+ hb_glyph_info_t *info = c->buffer->info;
+ hb_glyph_position_t *pos = c->buffer->pos;
for (unsigned int i = 0; i < count; i++)
{
- c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
- c->buffer->props.direction,
- &c->buffer->pos[i].x_advance,
- &c->buffer->pos[i].y_advance);
- c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
- c->buffer->props.direction,
- &c->buffer->pos[i].x_offset,
- &c->buffer->pos[i].y_offset);
+ c->font->get_glyph_advance_for_direction (info[i].codepoint,
+ direction,
+ &pos[i].x_advance,
+ &pos[i].y_advance);
+ c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
+ direction,
+ &pos[i].x_offset,
+ &pos[i].y_offset);
}
+}
+
+static inline bool
+hb_ot_position_complex (hb_ot_shape_context_t *c)
+{
+ bool ret = false;
+ unsigned int count = c->buffer->len;
switch (c->plan->shaper->zero_width_marks)
{
@@ -452,32 +470,28 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
break;
}
-}
-
-static inline bool
-hb_ot_position_complex (hb_ot_shape_context_t *c)
-{
- bool ret = false;
- unsigned int count = c->buffer->len;
if (hb_ot_layout_has_positioning (c->face))
{
+ hb_glyph_info_t *info = c->buffer->info;
+ hb_glyph_position_t *pos = c->buffer->pos;
+
/* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
for (unsigned int i = 0; i < count; i++) {
- c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+ c->font->add_glyph_origin_for_direction (info[i].codepoint,
HB_DIRECTION_LTR,
- &c->buffer->pos[i].x_offset,
- &c->buffer->pos[i].y_offset);
+ &pos[i].x_offset,
+ &pos[i].y_offset);
}
c->plan->position (c->font, c->buffer);
for (unsigned int i = 0; i < count; i++) {
- c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
+ c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
HB_DIRECTION_LTR,
- &c->buffer->pos[i].x_offset,
- &c->buffer->pos[i].y_offset);
+ &pos[i].x_offset,
+ &pos[i].y_offset);
}
ret = true;
@@ -500,18 +514,20 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
break;
}
- hb_ot_layout_position_finish (c->font, c->buffer);
-
return ret;
}
static inline void
hb_ot_position (hb_ot_shape_context_t *c)
{
+ hb_ot_layout_position_start (c->font, c->buffer);
+
hb_ot_position_default (c);
hb_bool_t fallback = !hb_ot_position_complex (c);
+ hb_ot_layout_position_finish (c->font, c->buffer);
+
if (fallback && c->plan->shaper->fallback_position)
_hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
@@ -533,22 +549,42 @@ 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;
+ hb_codepoint_t space;
+ enum {
+ SPACE_DONT_KNOW,
+ SPACE_AVAILABLE,
+ SPACE_UNAVAILABLE
+ } space_status = SPACE_DONT_KNOW;
unsigned int count = c->buffer->len;
+ hb_glyph_info_t *info = c->buffer->info;
+ hb_glyph_position_t *pos = c->buffer->pos;
+ unsigned int j = 0;
for (unsigned int i = 0; i < count; i++)
- if (unlikely (!is_a_ligature (c->buffer->info[i]) &&
- _hb_glyph_info_is_default_ignorable (&c->buffer->info[i])))
+ {
+ if (unlikely (!_hb_glyph_info_ligated (&info[i]) &&
+ _hb_glyph_info_is_default_ignorable (&info[i])))
{
- if (!space) {
- /* We assume that the space glyph is not gid0. */
- if (unlikely (!c->font->get_glyph (' ', 0, &space)) || !space)
- return; /* No point! */
+ if (space_status == SPACE_DONT_KNOW)
+ space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : SPACE_UNAVAILABLE;
+
+ if (space_status == SPACE_AVAILABLE)
+ {
+ info[i].codepoint = space;
+ pos[i].x_advance = 0;
+ pos[i].y_advance = 0;
}
- c->buffer->info[i].codepoint = space;
- c->buffer->pos[i].x_advance = 0;
- c->buffer->pos[i].y_advance = 0;
+ else
+ continue; /* Delete it. */
}
+ if (j != i)
+ {
+ info[j] = info[i];
+ pos[j] = pos[i];
+ }
+ j++;
+ }
+ c->buffer->len = j;
}
@@ -562,8 +598,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
/* Save the original direction, we use it later. */
c->target_direction = c->buffer->props.direction;
- HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0);
- HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1);
+ _hb_buffer_allocate_unicode_vars (c->buffer);
c->buffer->clear_output ();
@@ -578,8 +613,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
hb_ot_hide_default_ignorables (c);
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
- HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
+ _hb_buffer_deallocate_unicode_vars (c->buffer);
c->buffer->props.direction = c->target_direction;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
index 91ebec76ee..5594ef5074 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
@@ -27,7 +27,6 @@
*/
#include "hb-private.hh"
-#include "hb-ot.h"
#include <string.h>
@@ -167,9 +166,12 @@ typedef struct {
*
* Generated by intersecting the OpenType language tag list from
* Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
- * 2008/08/04, matching on name, and finally adjusted manually.
+ * 2008-08-04, matching on name, and finally adjusted manually.
*
- * Updated on 2012/12/07 with more research into remaining codes.
+ * Updated on 2012-12-07 with more research into remaining codes.
+ *
+ * Updated on 2013-11-23 based on usage in SIL and Microsoft fonts,
+ * the new proposal from Microsoft, and latest ISO 639-3 names.
*
* Some items still missing. Those are commented out at the end.
* Keep sorted for bsearch.
@@ -179,57 +181,90 @@ 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 */
+ {"ach", HB_TAG('A','C','H',' ')}, /* Acoli */
{"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 */
+ {"aio", HB_TAG('A','I','O',' ')}, /* Aiton */
{"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
+ {"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] */
{"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 */
+ {"an", HB_TAG('A','R','G',' ')}, /* Aragonese */
+ {"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) */
+ {"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */
+ {"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic */
{"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
+ {"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic */
{"as", HB_TAG('A','S','M',' ')}, /* Assamese */
+ {"ast", HB_TAG('A','S','T',' ')}, /* Asturian/Asturleonese/Bable/Leonese */
{"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */
{"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 */
+ {"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */
+ {"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */
+ {"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani */
+ {"azj", HB_TAG('A','Z','E',' ')}, /* North 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 */
+ {"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolangauge] */
+ {"ban", HB_TAG('B','A','N',' ')}, /* Balinese */
+ {"bar", HB_TAG('B','A','R',' ')}, /* Bavarian */
+ {"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */
+ {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */
+ {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */
{"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
- {"be", HB_TAG('B','E','L',' ')}, /* Belarussian */
+ {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */
{"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
{"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */
{"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
{"bft", HB_TAG('B','L','T',' ')}, /* Balti */
{"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */
{"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
+ {"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */
+ {"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */
{"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
+ {"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) */
{"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
- {"bik", HB_TAG('B','I','K',' ')}, /* Bikol */
+ {"bi", HB_TAG('B','I','S',' ')}, /* Bislama */
+ {"bik", HB_TAG('B','I','K',' ')}, /* Bikol [macrolanguage] */
{"bin", HB_TAG('E','D','O',' ')}, /* Bini */
+ {"bjj", HB_TAG('B','J','J',' ')}, /* Kanauji */
{"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */
{"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */
{"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */
+ {"blk", HB_TAG('B','L','K',' ')}, /* Pa'O/Pa'o Karen */
+ {"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol */
{"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
{"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
{"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
+ {"bpy", HB_TAG('B','P','Y',' ')}, /* Bishnupriya */
+ {"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari */
{"br", HB_TAG('B','R','E',' ')}, /* Breton */
{"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */
{"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
+ {"brx", HB_TAG('B','R','X',' ')}, /* Bodo (India) */
{"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
{"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
+ {"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol */
+ {"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */
+ {"bug", HB_TAG('B','U','G',' ')}, /* Buginese */
{"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */
{"byn", HB_TAG('B','I','L',' ')}, /* Bilen */
{"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
+ {"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
{"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
+ {"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */
+ {"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */
+ {"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
{"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
+ {"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */
+ {"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */
{"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
{"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
{"cr", HB_TAG('C','R','E',' ')}, /* Cree */
@@ -239,6 +274,9 @@ static const LangTag ot_languages[] = {
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
+ {"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */
+ {"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */
+ {"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */
{"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
{"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
{"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
@@ -247,34 +285,42 @@ static const LangTag ot_languages[] = {
{"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
{"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 */
+ {"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */
+ {"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari */
+ {"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */
+ {"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */
+ {"dje", HB_TAG('D','J','R',' ')}, /* Zarma */
{"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
- {"doi", HB_TAG('D','G','R',' ')}, /* Dogri */
+ {"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */
{"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
- {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */
+ {"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi/Divehi/Maldivian */
{"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 */
+ {"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian */
{"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */
+ {"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan */
{"en", HB_TAG('E','N','G',' ')}, /* English */
{"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
{"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */
{"es", HB_TAG('E','S','P',' ')}, /* Spanish */
- {"et", HB_TAG('E','T','I',' ')}, /* Estonian */
+ {"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */
{"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
{"eve", HB_TAG('E','V','N',' ')}, /* Even */
{"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
- {"fa", HB_TAG('F','A','R',' ')}, /* Persian */
- {"ff", HB_TAG('F','U','L',' ')}, /* Fulah */
+ {"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */
+ {"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */
{"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
{"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
{"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
{"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
{"fon", HB_TAG('F','O','N',' ')}, /* Fon */
{"fr", HB_TAG('F','R','A',' ')}, /* French */
+ {"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */
+ {"frp", HB_TAG('F','R','P',' ')}, /* Arpitan/Francoprovençal */
{"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
+ {"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */
{"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */
{"ga", HB_TAG('I','R','I',' ')}, /* Irish */
{"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
@@ -282,113 +328,167 @@ static const LangTag ot_languages[] = {
{"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
{"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
{"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */
+ {"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi */
{"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 */
+ {"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */
+ {"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */
+ {"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi */
+ {"gog", HB_TAG('G','O','G',' ')}, /* Gogo */
+ {"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */
{"grt", HB_TAG('G','R','O',' ')}, /* Garo */
{"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */
{"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
+ {"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */
{"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
- {"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */
+/*{"guk", HB_TAG('G','U','K',' ')},*/ /* Gumuz (in SIL fonts) */
+ {"guz", HB_TAG('G','U','Z',' ')}, /* Ekegusii/Gusii */
+ {"gv", HB_TAG('M','N','X',' ')}, /* Manx */
{"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
{"har", HB_TAG('H','R','I',' ')}, /* Harari */
- {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiin */
+ {"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */
+ {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */
+ {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */
{"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
+ {"hz", HB_TAG('H','E','R',' ')}, /* Herero */
{"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
{"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
{"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */
{"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */
{"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */
+ {"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */
{"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 */
+ {"ht", HB_TAG('H','A','I',' ')}, /* Haitian/Haitian Creole */
{"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
{"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
+ {"hz", HB_TAG('H','E','R',' ')}, /* Herero */
+ {"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */
+ {"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */
{"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
+ {"ie", HB_TAG('I','L','E',' ')}, /* Interlingue/Occidental */
{"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
{"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
+ {"ijc", HB_TAG('I','J','O',' ')}, /* Izon */
{"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */
+ {"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] */
{"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */
{"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
+ {"io", HB_TAG('I','D','O',' ')}, /* Ido */
{"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
{"it", HB_TAG('I','T','A',' ')}, /* Italian */
- {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut */
+ {"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */
{"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
+ {"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English */
+ {"jbo", HB_TAG('J','B','O',' ')}, /* Lojban */
{"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
{"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
{"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */
+ {"kab", HB_TAG('K','A','B',' ')}, /* Kabyle */
{"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
{"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
{"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
+ {"kde", HB_TAG('K','D','E',' ')}, /* Makonde */
{"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
{"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
{"kex", HB_TAG('K','K','N',' ')}, /* Kokni */
{"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
{"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
+ {"kg", HB_TAG('K','O','N',' ')}, /* Kongo [macrolanguage] */
{"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
- {"khb", HB_TAG('X','B','D',' ')}, /* Tai Lue */
+ {"khb", HB_TAG('X','B','D',' ')}, /* Lü */
+ {"kht", HB_TAG('K','H','N',' ')}, /* Khamti (Microsoft fonts) */
+/*{"kht", HB_TAG('K','H','T',' ')},*/ /* Khamti (OpenType spec and SIL fonts) */
{"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
- {"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */
+ {"ki", HB_TAG('K','I','K',' ')}, /* Gikuyu/Kikuyu */
+ {"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama/Kwanyama */
{"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */
+ {"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen */
{"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 */
+ {"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu */
{"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
{"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
+ {"knn", HB_TAG('K','O','K',' ')}, /* Konkani */
{"ko", HB_TAG('K','O','R',' ')}, /* Korean */
{"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
- {"kok", HB_TAG('K','O','K',' ')}, /* Konkani */
- {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle */
+ {"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */
+ {"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */
{"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
{"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
{"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
- {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri */
+ {"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */
{"kri", HB_TAG('K','R','I',' ')}, /* Krio */
{"krl", HB_TAG('K','R','L',' ')}, /* Karelian */
{"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
{"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
- {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */
+ {"ksh", HB_TAG('K','S','H',' ')}, /* Kölsch */
+/*{"ksw", HB_TAG('K','R','N',' ')},*/ /* S'gaw Karen (Microsoft fonts?) */
+ {"ksw", HB_TAG('K','S','W',' ')}, /* S'gaw Karen (OpenType spec and SIL fonts) */
+ {"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */
{"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
+ {"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */
{"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
+ {"kw", HB_TAG('C','O','R',' ')}, /* Cornish */
{"kxc", HB_TAG('K','M','S',' ')}, /* Komso */
{"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
- {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */
+ {"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz/Kyrgyz */
+ {"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */
{"la", HB_TAG('L','A','T',' ')}, /* Latin */
{"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
{"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 */
+ {"lg", HB_TAG('L','U','G',' ')}, /* Ganda */
+ {"li", HB_TAG('L','I','M',' ')}, /* Limburgan/Limburger/Limburgish */
{"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
+ {"lij", HB_TAG('L','I','J',' ')}, /* Ligurian */
+ {"lis", HB_TAG('L','I','S',' ')}, /* Lisu */
+ {"ljp", HB_TAG('L','J','P',' ')}, /* Lampung Api */
+ {"lki", HB_TAG('L','K','I',' ')}, /* Laki */
{"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
{"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */
+ {"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */
{"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
{"lo", HB_TAG('L','A','O',' ')}, /* Lao */
+ {"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri */
{"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) */
{"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */
- {"luy", HB_TAG('L','U','H',' ')}, /* Luhya [macrolanguage] */
+ {"luy", HB_TAG('L','U','H',' ')}, /* Luyia/Oluluyia [macrolanguage] */
+ {"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri */
{"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
{"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
+ {"mad", HB_TAG('M','A','D',' ')}, /* Madurese */
+ {"mag", HB_TAG('M','A','G',' ')}, /* Magahi */
{"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
+ {"mak", HB_TAG('M','K','R',' ')}, /* Makasar */
+ {"man", HB_TAG('M','N','K',' ')}, /* Manding/Mandingo [macrolanguage] */
{"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */
{"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
+ {"mdr", HB_TAG('M','D','R',' ')}, /* Mandar */
{"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
{"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
- {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */
+ {"mer", HB_TAG('M','E','R',' ')}, /* Meru */
+ {"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */
+ {"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */
+ {"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */
{"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */
{"mi", HB_TAG('M','R','I',' ')}, /* Maori */
+ {"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */
{"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
+ {"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka */
+ {"mkw", HB_TAG('M','K','W',' ')}, /* Kituba (Congo) */
{"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
- {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian */
+ {"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan */
+ {"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */
{"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
{"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */
{"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
@@ -396,72 +496,119 @@ static const LangTag ot_languages[] = {
{"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
{"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */
{"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
+ {"mos", HB_TAG('M','O','S',' ')}, /* Mossi */
{"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 */
+ {"ms", HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */
+ {"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka */
{"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
- {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */
+ {"mtr", HB_TAG('M','A','W',' ')}, /* Mewari */
+ {"mus", HB_TAG('M','U','S',' ')}, /* Creek */
+ {"mve", HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */
+ {"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan */
+ {"mwl", HB_TAG('M','W','L',' ')}, /* Mirandese */
+ {"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */
+ {"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */
{"my", HB_TAG('B','R','M',' ')}, /* Burmese */
{"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
+ {"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) */
{"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
+ {"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */
+ {"na", HB_TAG('N','A','U',' ')}, /* Nauru */
{"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */
+ {"nah", HB_TAG('N','A','H',' ')}, /* Nahuatl [family] */
+ {"nap", HB_TAG('N','A','P',' ')}, /* Neapolitan */
{"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
{"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
{"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */
+ {"ndc", HB_TAG('N','D','C',' ')}, /* Ndau */
+ {"nds", HB_TAG('N','D','S',' ')}, /* Low German/Low Saxon */
{"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
{"new", HB_TAG('N','E','W',' ')}, /* Newari */
{"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
+ {"nga", HB_TAG('N','G','A',' ')}, /* Ngabaka */
{"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
{"niu", HB_TAG('N','I','U',' ')}, /* Niuean */
{"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
{"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 */
+ {"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */
+ {"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai */
+ {"noe", HB_TAG('N','O','E',' ')}, /* Nimadi */
{"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
+ {"nov", HB_TAG('N','O','V',' ')}, /* Novial */
{"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 */
+ {"ny", HB_TAG('C','H','I',' ')}, /* Chewa/Chichwa/Nyanja */
+ {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */
+ {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */
{"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
- {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */
+ {"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] */
{"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */
- {"om", HB_TAG('O','R','O',' ')}, /* Oromo */
+ {"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */
{"or", HB_TAG('O','R','I',' ')}, /* Oriya */
{"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
{"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
+ {"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */
+ {"pam", HB_TAG('P','A','M',' ')}, /* Kapampangan/Pampanga */
+ {"pap", HB_TAG('P','A','P',' ')}, /* Papiamento */
+ {"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */
+ {"pcd", HB_TAG('P','C','D',' ')}, /* Picard */
{"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */
+ {"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */
+ {"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian */
+ {"phk", HB_TAG('P','H','K',' ')}, /* Phake */
{"pi", HB_TAG('P','A','L',' ')}, /* Pali */
+ {"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk */
{"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 */
+ {"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */
+ {"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */
+ {"prs", HB_TAG('D','R','I',' ')}, /* Afghan Persian/Dari */
+ {"ps", HB_TAG('P','A','S',' ')}, /* Pashto/Pushto [macrolanguage] */
{"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
- {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */
- {"rbb", HB_TAG('P','L','G',' ')}, /* [Rumai] Palaung */
+ {"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen */
+ {"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */
+ {"quc", HB_TAG('Q','U','C',' ')}, /* K'iche'/Quiché */
+ {"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua */
+ {"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */
+ {"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung */
+ {"rej", HB_TAG('R','E','J',' ')}, /* Rejang */
{"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 */
+ {"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */
+ {"rm", HB_TAG('R','M','S',' ')}, /* Romansh */
+ {"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */
+ {"rn", HB_TAG('R','U','N',' ')}, /* Rundi */
{"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
- {"rom", HB_TAG('R','O','Y',' ')}, /* Romany */
+ {"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */
{"ru", HB_TAG('R','U','S',' ')}, /* Russian */
{"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
- {"rw", HB_TAG('R','U','A',' ')}, /* Ruanda */
+ {"rup", HB_TAG('R','U','P',' ')}, /* Aromanian/Arumanian/Macedo-Romanian */
+ {"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */
+ {"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */
{"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
{"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
+ {"sas", HB_TAG('S','A','S',' ')}, /* Sasak */
{"sat", HB_TAG('S','A','T',' ')}, /* Santali */
{"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
+ {"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */
+ {"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */
+ {"sco", HB_TAG('S','C','O',' ')}, /* Scots */
{"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 */
{"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
{"sg", HB_TAG('S','G','O',' ')}, /* Sango */
+ {"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */
+ {"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */
+ {"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage */
+/*{"sgw", HB_TAG('S','G','W',' ')},*/ /* Sebat Bet Gurage (in SIL fonts) */
{"shn", HB_TAG('S','H','N',' ')}, /* Shan */
{"si", HB_TAG('S','N','H',' ')}, /* Sinhala */
{"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */
@@ -474,60 +621,98 @@ static const LangTag ot_languages[] = {
{"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
{"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
{"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
+ {"sn", HB_TAG('S','N','A',' ')}, /* Shona */
{"snk", HB_TAG('S','N','K',' ')}, /* Soninke */
{"so", HB_TAG('S','M','L',' ')}, /* Somali */
- {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */
+ {"sop", HB_TAG('S','O','P',' ')}, /* Songe */
+ {"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */
{"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
{"srr", HB_TAG('S','R','R',' ')}, /* Serer */
- {"ss", HB_TAG('S','W','Z',' ')}, /* Swazi */
+ {"ss", HB_TAG('S','W','Z',' ')}, /* Swati */
{"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */
+ {"stq", HB_TAG('S','T','Q',' ')}, /* Saterfriesisch */
+ {"stv", HB_TAG('S','I','G',' ')}, /* Silt'e */
+ {"su", HB_TAG('S','U','N',' ')}, /* Sundanese */
+ {"suk", HB_TAG('S','U','K',' ')}, /* Sukama */
{"suq", HB_TAG('S','U','R',' ')}, /* Suri */
{"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
{"sva", HB_TAG('S','V','A',' ')}, /* Svan */
- {"sw", HB_TAG('S','W','K',' ')}, /* Swahili */
+ {"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */
{"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
- {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */
+ {"swh", HB_TAG('S','W','K',' ')}, /* Kiswahili/Swahili */
+ {"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati */
+ {"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */
+ {"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */
+ {"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */
+ {"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */
{"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
{"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */
{"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
+ {"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa */
{"te", HB_TAG('T','E','L',' ')}, /* Telugu */
{"tem", HB_TAG('T','M','N',' ')}, /* Temne */
+ {"tet", HB_TAG('T','E','T',' ')}, /* Tetum */
{"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 */
+ {"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */
{"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
+ {"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */
+ {"tmh", HB_TAG('t','m','h',' ')}, /* Tamashek [macrolanguage] */
{"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
{"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */
+ {"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */
{"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
{"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */
{"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
{"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
+ {"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka */
{"tw", HB_TAG('T','W','I',' ')}, /* Twi */
{"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
{"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */
+ {"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */
+ {"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight */
{"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 */
+ {"umb", HB_TAG('U','M','B',' ')}, /* Umbundu */
{"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
{"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
- {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */
+ {"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */
+ {"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek */
+ {"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek */
{"ve", HB_TAG('V','E','N',' ')}, /* Venda */
+ {"vec", HB_TAG('V','E','C',' ')}, /* Venetian */
+ {"vls", HB_TAG('F','L','E',' ')}, /* Vlaams */
{"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
- {"vmw", HB_TAG('M','A','K',' ')}, /* Makua */
+ {"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */
+ {"vo", HB_TAG('V','O','L',' ')}, /* Volapük */
+ {"vro", HB_TAG('V','R','O',' ')}, /* Võro */
+ {"wa", HB_TAG('W','L','N',' ')}, /* Walloon */
+ {"war", HB_TAG('W','A','R',' ')}, /* Waray (Philippines) */
{"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
{"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
+ {"wle", HB_TAG('S','I','G',' ')}, /* Wolane */
+ {"wry", HB_TAG('M','A','W',' ')}, /* Merwari */
+ {"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */
{"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
{"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
{"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
+ {"xog", HB_TAG('X','O','G',' ')}, /* Soga */
{"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */
{"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
- {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish */
+ {"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) */
+ {"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat (Todo) */
+ {"yao", HB_TAG('Y','A','O',' ')}, /* Yao */
+ {"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */
{"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
{"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
+ {"za", HB_TAG('Z','H','A',' ')}, /* Chuang/Zhuang [macrolanguage] */
+ {"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws */
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
- {"zu", HB_TAG('Z','U','L',' ')} /* Zulu */
+ {"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */
+ {"zum", HB_TAG('L','R','C',' ')} /* Kumzari */
/* The corresponding languages IDs for the following IDs are unclear,
* overlap, or are architecturally weird. Needs more research. */
@@ -536,13 +721,13 @@ static const LangTag ot_languages[] = {
/*{"gsw?/gsw-FR?", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
/*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */
/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
-/*{"sgw?", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
+/*{"zh?", HB_TAG('C','H','N',' ')},*/ /* Chinese (seen in Microsoft fonts) */
/*{"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 */
+/*{"fonipa", HB_TAG('I','P','P','H')},*/ /* Phonetic transcription—IPA conventions */
/*{"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 */
@@ -559,8 +744,6 @@ static const LangTag ot_languages[] = {
/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */
/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
/*{"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','C','R',' ')},*/ /* N-Cree */
/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
/*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
@@ -569,14 +752,12 @@ static const LangTag ot_languages[] = {
/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */
/*{"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 */
/*{"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('W','C','R',' ')},*/ /* West-Cree */
-/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
+/*{"cre?", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
/*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
index 4152e27552..4b72260ed5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh
@@ -79,6 +79,9 @@ static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
template <typename Type>
static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
+static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
+{ return (a + (b - 1)) / b; }
+
#undef ARRAY_LENGTH
template <typename Type, unsigned int n>
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
index adfa88f18e..705f554ce6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
@@ -28,7 +28,6 @@
#define HB_SET_PRIVATE_HH
#include "hb-private.hh"
-#include "hb-set.h"
#include "hb-object-private.hh"
@@ -171,7 +170,7 @@ struct hb_set_t
inline void add (hb_codepoint_t g)
{
if (unlikely (in_error)) return;
- if (unlikely (g == SENTINEL)) return;
+ if (unlikely (g == INVALID)) return;
if (unlikely (g > MAX_G)) return;
elt (g) |= mask (g);
}
@@ -256,19 +255,22 @@ struct hb_set_t
}
inline bool next (hb_codepoint_t *codepoint) const
{
- if (unlikely (*codepoint == SENTINEL)) {
+ if (unlikely (*codepoint == INVALID)) {
hb_codepoint_t i = get_min ();
- if (i != SENTINEL) {
+ if (i != INVALID) {
*codepoint = i;
return true;
- } else
+ } else {
+ *codepoint = INVALID;
return false;
+ }
}
for (hb_codepoint_t i = *codepoint + 1; i < MAX_G + 1; i++)
if (has (i)) {
*codepoint = i;
return true;
}
+ *codepoint = INVALID;
return false;
}
inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
@@ -277,7 +279,10 @@ struct hb_set_t
i = *last;
if (!next (&i))
+ {
+ *last = *first = INVALID;
return false;
+ }
*last = *first = i;
while (next (&i) && i == *last + 1)
@@ -300,7 +305,7 @@ struct hb_set_t
for (unsigned int j = 0; j < BITS; j++)
if (elts[i] & (1 << j))
return i * BITS + j;
- return SENTINEL;
+ return INVALID;
}
inline hb_codepoint_t get_max (void) const
{
@@ -309,7 +314,7 @@ struct hb_set_t
for (unsigned int j = BITS; j; j--)
if (elts[i - 1] & (1 << (j - 1)))
return (i - 1) * BITS + (j - 1);
- return SENTINEL;
+ return INVALID;
}
typedef uint32_t elt_t;
@@ -318,7 +323,7 @@ struct hb_set_t
static const unsigned int BITS = (1 << SHIFT);
static const unsigned int MASK = BITS - 1;
static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
- static const hb_codepoint_t SENTINEL = (hb_codepoint_t) -1;
+ static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.cc b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
index 3c9573fbce..59a0af46ed 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.cc
@@ -30,6 +30,13 @@
/* Public API */
+/**
+ * hb_set_create: (Xconstructor)
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_set_t *
hb_set_create (void)
{
@@ -43,6 +50,13 @@ hb_set_create (void)
return set;
}
+/**
+ * hb_set_get_empty:
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_set_t *
hb_set_get_empty (void)
{
@@ -56,12 +70,26 @@ hb_set_get_empty (void)
return const_cast<hb_set_t *> (&_hb_set_nil);
}
+/**
+ * hb_set_reference: (skip)
+ * @set: a set.
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_set_t *
hb_set_reference (hb_set_t *set)
{
return hb_object_reference (set);
}
+/**
+ * hb_set_destroy: (skip)
+ * @set: a set.
+ *
+ * Since: 1.0
+ **/
void
hb_set_destroy (hb_set_t *set)
{
@@ -72,6 +100,18 @@ hb_set_destroy (hb_set_t *set)
free (set);
}
+/**
+ * hb_set_set_user_data: (skip)
+ * @set: a set.
+ * @key:
+ * @data:
+ * @destroy (closure data):
+ * @replace:
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_set_user_data (hb_set_t *set,
hb_user_data_key_t *key,
@@ -82,6 +122,15 @@ hb_set_set_user_data (hb_set_t *set,
return hb_object_set_user_data (set, key, data, destroy, replace);
}
+/**
+ * hb_set_get_user_data: (skip)
+ * @set: a set.
+ * @key:
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_set_get_user_data (hb_set_t *set,
hb_user_data_key_t *key)
@@ -90,24 +139,63 @@ hb_set_get_user_data (hb_set_t *set,
}
+/**
+ * hb_set_allocation_successful:
+ * @set: a set.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_allocation_successful (const hb_set_t *set HB_UNUSED)
{
return !set->in_error;
}
+/**
+ * hb_set_clear:
+ * @set: a set.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_clear (hb_set_t *set)
{
set->clear ();
}
+/**
+ * hb_set_is_empty:
+ * @set: a set.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_is_empty (const hb_set_t *set)
{
return set->is_empty ();
}
+/**
+ * hb_set_has:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_has (const hb_set_t *set,
hb_codepoint_t codepoint)
@@ -115,6 +203,15 @@ hb_set_has (const hb_set_t *set,
return set->has (codepoint);
}
+/**
+ * hb_set_add:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_add (hb_set_t *set,
hb_codepoint_t codepoint)
@@ -122,6 +219,16 @@ hb_set_add (hb_set_t *set,
set->add (codepoint);
}
+/**
+ * hb_set_add_range:
+ * @set: a set.
+ * @first:
+ * @last:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_add_range (hb_set_t *set,
hb_codepoint_t first,
@@ -130,6 +237,15 @@ hb_set_add_range (hb_set_t *set,
set->add_range (first, last);
}
+/**
+ * hb_set_del:
+ * @set: a set.
+ * @codepoint:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_del (hb_set_t *set,
hb_codepoint_t codepoint)
@@ -137,6 +253,16 @@ hb_set_del (hb_set_t *set,
set->del (codepoint);
}
+/**
+ * hb_set_del_range:
+ * @set: a set.
+ * @first:
+ * @last:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_del_range (hb_set_t *set,
hb_codepoint_t first,
@@ -145,6 +271,17 @@ hb_set_del_range (hb_set_t *set,
set->del_range (first, last);
}
+/**
+ * hb_set_is_equal:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_is_equal (const hb_set_t *set,
const hb_set_t *other)
@@ -152,6 +289,15 @@ hb_set_is_equal (const hb_set_t *set,
return set->is_equal (other);
}
+/**
+ * hb_set_set:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_set (hb_set_t *set,
const hb_set_t *other)
@@ -159,6 +305,15 @@ hb_set_set (hb_set_t *set,
set->set (other);
}
+/**
+ * hb_set_union:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_union (hb_set_t *set,
const hb_set_t *other)
@@ -166,6 +321,15 @@ hb_set_union (hb_set_t *set,
set->union_ (other);
}
+/**
+ * hb_set_intersect:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_intersect (hb_set_t *set,
const hb_set_t *other)
@@ -173,6 +337,15 @@ hb_set_intersect (hb_set_t *set,
set->intersect (other);
}
+/**
+ * hb_set_subtract:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_subtract (hb_set_t *set,
const hb_set_t *other)
@@ -180,6 +353,15 @@ hb_set_subtract (hb_set_t *set,
set->subtract (other);
}
+/**
+ * hb_set_symmetric_difference:
+ * @set: a set.
+ * @other:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_symmetric_difference (hb_set_t *set,
const hb_set_t *other)
@@ -187,30 +369,79 @@ hb_set_symmetric_difference (hb_set_t *set,
set->symmetric_difference (other);
}
+/**
+ * hb_set_invert:
+ * @set: a set.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_set_invert (hb_set_t *set)
{
set->invert ();
}
+/**
+ * hb_set_get_population:
+ * @set: a set.
+ *
+ * Returns the number of numbers in the set.
+ *
+ * Return value: set population.
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_set_get_population (const hb_set_t *set)
{
return set->get_population ();
}
+/**
+ * hb_set_get_min:
+ * @set: a set.
+ *
+ * Finds the minimum number in the set.
+ *
+ * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
+ *
+ * Since: 1.0
+ **/
hb_codepoint_t
hb_set_get_min (const hb_set_t *set)
{
return set->get_min ();
}
+/**
+ * hb_set_get_max:
+ * @set: a set.
+ *
+ * Finds the maximum number in the set.
+ *
+ * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty.
+ *
+ * Since: 1.0
+ **/
hb_codepoint_t
hb_set_get_max (const hb_set_t *set)
{
return set->get_max ();
}
+/**
+ * hb_set_next:
+ * @set: a set.
+ * @codepoint: (inout):
+ *
+ *
+ *
+ * Return value: whether there was a next value.
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_next (const hb_set_t *set,
hb_codepoint_t *codepoint)
@@ -218,6 +449,19 @@ hb_set_next (const hb_set_t *set,
return set->next (codepoint);
}
+/**
+ * hb_set_next_range:
+ * @set: a set.
+ * @first: (out): output first codepoint in the range.
+ * @last: (inout): input current last and output last codepoint in the range.
+ *
+ * Gets the next consecutive range of numbers in @set that
+ * are greater than current value of @last.
+ *
+ * Return value: whether there was a next range.
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_set_next_range (const hb_set_t *set,
hb_codepoint_t *first,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.h b/src/3rdparty/harfbuzz-ng/src/hb-set.h
index 291e24974e..bafdae9633 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set.h
@@ -36,6 +36,8 @@
HB_BEGIN_DECLS
+#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
+
typedef struct hb_set_t hb_set_t;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
index dd014e38d0..607da5e779 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan-private.hh
@@ -28,7 +28,6 @@
#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"
@@ -39,12 +38,15 @@ struct hb_shape_plan_t
ASSERT_POD ();
hb_bool_t default_shaper_list;
- hb_face_t *face;
+ hb_face_t *face_unsafe; /* We don't carry a reference to face. */
hb_segment_properties_t props;
hb_shape_func_t *shaper_func;
const char *shaper_name;
+ hb_feature_t *user_features;
+ unsigned int num_user_features;
+
struct hb_shaper_data_t shaper_data;
};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
index a6d2d26210..e354f29176 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
@@ -46,7 +46,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
#define HB_SHAPER_PLAN(shaper) \
HB_STMT_START { \
- if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \
+ if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
HB_SHAPER_DATA (shaper, shape_plan) = \
HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
shape_plan->shaper_func = _hb_##shaper##_shape; \
@@ -83,6 +83,20 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
* hb_shape_plan_t
*/
+/**
+ * hb_shape_plan_create: (Xconstructor)
+ * @face:
+ * @props:
+ * @user_features: (array length=num_user_features):
+ * @num_user_features:
+ * @shaper_list: (array zero-terminated=1):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_shape_plan_t *
hb_shape_plan_create (hb_face_t *face,
const hb_segment_properties_t *props,
@@ -93,24 +107,42 @@ hb_shape_plan_create (hb_face_t *face,
assert (props->direction != HB_DIRECTION_INVALID);
hb_shape_plan_t *shape_plan;
+ hb_feature_t *features = NULL;
if (unlikely (!face))
face = hb_face_get_empty ();
if (unlikely (!props || hb_object_is_inert (face)))
return hb_shape_plan_get_empty ();
- if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
+ if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t))))
return hb_shape_plan_get_empty ();
+ if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) {
+ free (features);
+ return hb_shape_plan_get_empty ();
+ }
hb_face_make_immutable (face);
shape_plan->default_shaper_list = shaper_list == NULL;
- shape_plan->face = hb_face_reference (face);
+ shape_plan->face_unsafe = face;
shape_plan->props = *props;
+ shape_plan->num_user_features = num_user_features;
+ shape_plan->user_features = features;
+ if (num_user_features)
+ memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
return shape_plan;
}
+/**
+ * hb_shape_plan_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_shape_plan_t *
hb_shape_plan_get_empty (void)
{
@@ -124,6 +156,9 @@ hb_shape_plan_get_empty (void)
NULL, /* shaper_func */
NULL, /* shaper_name */
+ NULL, /* user_features */
+ 0, /* num_user_featurs */
+
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
#include "hb-shaper-list.hh"
@@ -134,12 +169,30 @@ hb_shape_plan_get_empty (void)
return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
}
+/**
+ * hb_shape_plan_reference: (skip)
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_shape_plan_t *
hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
{
return hb_object_reference (shape_plan);
}
+/**
+ * hb_shape_plan_destroy: (skip)
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
{
@@ -149,11 +202,25 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
- hb_face_destroy (shape_plan->face);
+ free (shape_plan->user_features);
free (shape_plan);
}
+/**
+ * hb_shape_plan_set_user_data: (skip)
+ * @shape_plan: a shape plan.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
hb_user_data_key_t *key,
@@ -164,6 +231,17 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
return hb_object_set_user_data (shape_plan, key, data, destroy, replace);
}
+/**
+ * hb_shape_plan_get_user_data: (skip)
+ * @shape_plan: a shape plan.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
hb_user_data_key_t *key)
@@ -172,6 +250,20 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
}
+/**
+ * hb_shape_plan_execute:
+ * @shape_plan: a shape plan.
+ * @font: a font.
+ * @buffer: a buffer.
+ * @features: (array length=num_features):
+ * @num_features:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
hb_font_t *font,
@@ -184,7 +276,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
hb_object_is_inert (buffer)))
return false;
- assert (shape_plan->face == font->face);
+ assert (shape_plan->face_unsafe == font->face);
assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
#define HB_SHAPER_EXECUTE(shaper) \
@@ -221,23 +313,69 @@ hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
}
#endif
-/* TODO no user-feature caching for now. */
+/* User-feature caching is currently somewhat dumb:
+ * it only finds matches where the feature array is identical,
+ * not cases where the feature lists would be compatible for plan purposes
+ * but have different ranges, for example.
+ */
struct hb_shape_plan_proposal_t
{
const hb_segment_properties_t props;
const char * const *shaper_list;
+ const hb_feature_t *user_features;
+ unsigned int num_user_features;
hb_shape_func_t *shaper_func;
};
+static inline hb_bool_t
+hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan,
+ const hb_shape_plan_proposal_t *proposal)
+{
+ if (proposal->num_user_features != shape_plan->num_user_features) return false;
+ for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
+ if (proposal->user_features[i].tag != shape_plan->user_features[i].tag ||
+ proposal->user_features[i].value != shape_plan->user_features[i].value ||
+ proposal->user_features[i].start != shape_plan->user_features[i].start ||
+ proposal->user_features[i].end != shape_plan->user_features[i].end) return false;
+ return true;
+}
+
static hb_bool_t
hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
const hb_shape_plan_proposal_t *proposal)
{
return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
+ hb_shape_plan_user_features_match (shape_plan, proposal) &&
((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
(shape_plan->shaper_func == proposal->shaper_func));
}
+static inline hb_bool_t
+hb_non_global_user_features_present (const hb_feature_t *user_features,
+ unsigned int num_user_features)
+{
+ while (num_user_features)
+ if (user_features->start != 0 || user_features->end != (unsigned int) -1)
+ return true;
+ else
+ num_user_features--, user_features++;
+ return false;
+}
+
+/**
+ * hb_shape_plan_create_cached:
+ * @face:
+ * @props:
+ * @user_features: (array length=num_user_features):
+ * @num_user_features:
+ * @shaper_list: (array zero-terminated=1):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_shape_plan_t *
hb_shape_plan_create_cached (hb_face_t *face,
const hb_segment_properties_t *props,
@@ -245,12 +383,11 @@ hb_shape_plan_create_cached (hb_face_t *face,
unsigned int num_user_features,
const char * const *shaper_list)
{
- if (num_user_features)
- return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
-
hb_shape_plan_proposal_t proposal = {
*props,
shaper_list,
+ user_features,
+ num_user_features,
NULL
};
@@ -288,6 +425,11 @@ retry:
hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
+ /* Don't add the plan to the cache if there were user features with non-global ranges */
+
+ if (hb_non_global_user_features_present (user_features, num_user_features))
+ return shape_plan;
+
hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
if (unlikely (!node))
return shape_plan;
@@ -301,12 +443,19 @@ retry:
goto retry;
}
- /* Release our reference on face. */
- hb_face_destroy (face);
-
return hb_shape_plan_reference (shape_plan);
}
+/**
+ * hb_shape_plan_get_shaper:
+ * @shape_plan: a shape plan.
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char *
hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
index 80d8c1306b..c1b752405e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc
@@ -153,6 +153,18 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
*pp == end;
}
+/**
+ * hb_feature_from_string:
+ * @str: (array length=len):
+ * @len:
+ * @feature: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_feature_from_string (const char *str, int len,
hb_feature_t *feature)
@@ -163,6 +175,16 @@ hb_feature_from_string (const char *str, int len,
return parse_one_feature (&str, str + len, feature);
}
+/**
+ * hb_feature_to_string:
+ * @feature:
+ * @buf: (array length=size):
+ * @size:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_feature_to_string (hb_feature_t *feature,
char *buf, unsigned int size)
@@ -209,6 +231,15 @@ void free_static_shaper_list (void)
free (static_shaper_list);
}
+/**
+ * hb_shape_list_shapers:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
const char **
hb_shape_list_shapers (void)
{
@@ -244,6 +275,20 @@ retry:
}
+/**
+ * hb_shape_full:
+ * @font: a font.
+ * @buffer: a buffer.
+ * @features: (array length=num_features):
+ * @num_features:
+ * @shaper_list: (array zero-terminated=1):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_shape_full (hb_font_t *font,
hb_buffer_t *buffer,
@@ -265,6 +310,17 @@ hb_shape_full (hb_font_t *font,
return res;
}
+/**
+ * hb_shape:
+ * @font: a font.
+ * @buffer: a buffer.
+ * @features: (array length=num_features):
+ * @num_features:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_shape (hb_font_t *font,
hb_buffer_t *buffer,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
index dd4d00138e..779d8ae229 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh
@@ -32,8 +32,6 @@
#define HB_UNICODE_PRIVATE_HH
#include "hb-private.hh"
-
-#include "hb-unicode.h"
#include "hb-object-private.hh"
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
index b7e098737c..5b44913bd3 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
@@ -150,6 +150,16 @@ hb_unicode_funcs_get_default (void)
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS.")
#endif
+/**
+ * hb_unicode_funcs_create: (Xconstructor)
+ * @parent: (allow-none):
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
{
@@ -187,18 +197,45 @@ const hb_unicode_funcs_t _hb_unicode_funcs_nil = {
}
};
+/**
+ * hb_unicode_funcs_get_empty:
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_get_empty (void)
{
return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
}
+/**
+ * hb_unicode_funcs_reference: (skip)
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value: (transfer full):
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
{
return hb_object_reference (ufuncs);
}
+/**
+ * hb_unicode_funcs_destroy: (skip)
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
{
@@ -214,6 +251,20 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
free (ufuncs);
}
+/**
+ * hb_unicode_funcs_set_user_data: (skip)
+ * @ufuncs: Unicode functions.
+ * @key:
+ * @data:
+ * @destroy:
+ * @replace:
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
hb_user_data_key_t *key,
@@ -224,6 +275,17 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
}
+/**
+ * hb_unicode_funcs_get_user_data: (skip)
+ * @ufuncs: Unicode functions.
+ * @key:
+ *
+ *
+ *
+ * Return value: (transfer none):
+ *
+ * Since: 1.0
+ **/
void *
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
hb_user_data_key_t *key)
@@ -232,6 +294,14 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
}
+/**
+ * hb_unicode_funcs_make_immutable:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
{
@@ -241,12 +311,32 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
ufuncs->immutable = true;
}
+/**
+ * hb_unicode_funcs_is_immutable:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
{
return ufuncs->immutable;
}
+/**
+ * hb_unicode_funcs_get_parent:
+ * @ufuncs: Unicode functions.
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_unicode_funcs_t *
hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
{
@@ -294,6 +384,19 @@ hb_unicode_##name (hb_unicode_funcs_t *ufuncs, \
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
#undef HB_UNICODE_FUNC_IMPLEMENT
+/**
+ * hb_unicode_compose:
+ * @ufuncs: Unicode functions.
+ * @a:
+ * @b:
+ * @ab: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t a,
@@ -303,6 +406,19 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
return ufuncs->compose (a, b, ab);
}
+/**
+ * hb_unicode_decompose:
+ * @ufuncs: Unicode functions.
+ * @ab:
+ * @a: (out):
+ * @b: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
hb_bool_t
hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t ab,
@@ -312,6 +428,18 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
return ufuncs->decompose (ab, a, b);
}
+/**
+ * hb_unicode_decompose_compatibility:
+ * @ufuncs: Unicode functions.
+ * @u:
+ * @decomposed: (out):
+ *
+ *
+ *
+ * Return value:
+ *
+ * Since: 1.0
+ **/
unsigned int
hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t u,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
index 2e10d98a3b..1c4e097b92 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h
@@ -248,7 +248,7 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
/**
* hb_unicode_decompose_compatibility_func_t:
- * @ufuncs: Unicode function structure
+ * @ufuncs: a Unicode function structure
* @u: codepoint to decompose
* @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
* @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
@@ -274,44 +274,132 @@ typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_
/* setters */
+/**
+ * hb_unicode_funcs_set_combining_class_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_combining_class_func_t combining_class_func,
+ hb_unicode_combining_class_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_eastasian_width_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_eastasian_width_func_t eastasian_width_func,
+ hb_unicode_eastasian_width_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_general_category_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_general_category_func_t general_category_func,
+ hb_unicode_general_category_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_mirroring_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_mirroring_func_t mirroring_func,
+ hb_unicode_mirroring_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_script_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_script_func_t script_func,
+ hb_unicode_script_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_compose_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_compose_func_t compose_func,
+ hb_unicode_compose_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_decompose_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_decompose_func_t decompose_func,
+ hb_unicode_decompose_func_t func,
void *user_data, hb_destroy_func_t destroy);
+/**
+ * hb_unicode_funcs_set_decompose_compatibility_func:
+ * @ufuncs: a Unicode function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified):
+ * @user_data:
+ * @destroy:
+ *
+ *
+ *
+ * Since: 1.0
+ **/
void
hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_decompose_compatibility_func_t decompose_compatibility_func,
+ hb_unicode_decompose_compatibility_func_t func,
void *user_data, hb_destroy_func_t destroy);
/* accessors */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h
index dc07ef794a..790e0ecbae 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-version.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h
@@ -38,9 +38,9 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 0
#define HB_VERSION_MINOR 9
-#define HB_VERSION_MICRO 20
+#define HB_VERSION_MICRO 25
-#define HB_VERSION_STRING "0.9.20"
+#define HB_VERSION_STRING "0.9.25"
#define HB_VERSION_CHECK(major,minor,micro) \
((major)*10000+(minor)*100+(micro) >= \
diff --git a/src/3rdparty/harfbuzz.pri b/src/3rdparty/harfbuzz.pri
index bc8d49c625..0d55867c74 100644
--- a/src/3rdparty/harfbuzz.pri
+++ b/src/3rdparty/harfbuzz.pri
@@ -79,6 +79,7 @@ contains(QT_CONFIG, harfbuzz) {
$$QT_HARFBUZZ_DIR/src/hb-ot-layout-gpos-table.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-layout-gsubgpos-private.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-layout-gsub-table.hh \
+ $$QT_HARFBUZZ_DIR/src/hb-ot-layout-jstf-table.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-layout-private.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-map-private.hh \
$$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic-fallback.hh \