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>
This commit is contained in:
parent
4b2c73b476
commit
260fe98525
55
src/3rdparty/harfbuzz-ng/NEWS
vendored
55
src/3rdparty/harfbuzz-ng/NEWS
vendored
@ -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
|
||||
=====================================
|
||||
|
8
src/3rdparty/harfbuzz-ng/TODO
vendored
8
src/3rdparty/harfbuzz-ng/TODO
vendored
@ -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:
|
||||
|
@ -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))
|
||||
|
152
src/3rdparty/harfbuzz-ng/src/hb-blob.cc
vendored
152
src/3rdparty/harfbuzz-ng/src/hb-blob.cc
vendored
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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; }
|
||||
};
|
||||
|
@ -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,
|
||||
|
446
src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
vendored
446
src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
vendored
@ -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)
|
||||
{
|
||||
|
16
src/3rdparty/harfbuzz-ng/src/hb-buffer.h
vendored
16
src/3rdparty/harfbuzz-ng/src/hb-buffer.h
vendored
@ -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 {
|
||||
|
161
src/3rdparty/harfbuzz-ng/src/hb-common.cc
vendored
161
src/3rdparty/harfbuzz-ng/src/hb-common.cc
vendored
@ -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,
|
||||
|
4
src/3rdparty/harfbuzz-ng/src/hb-common.h
vendored
4
src/3rdparty/harfbuzz-ng/src/hb-common.h
vendored
@ -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
|
||||
|
@ -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"
|
||||
|
172
src/3rdparty/harfbuzz-ng/src/hb-face.cc
vendored
172
src/3rdparty/harfbuzz-ng/src/hb-face.cc
vendored
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
15
src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
vendored
15
src/3rdparty/harfbuzz-ng/src/hb-font-private.hh
vendored
@ -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
|
||||
|
517
src/3rdparty/harfbuzz-ng/src/hb-font.cc
vendored
517
src/3rdparty/harfbuzz-ng/src/hb-font.cc
vendored
@ -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,
|
||||
|
132
src/3rdparty/harfbuzz-ng/src/hb-font.h
vendored
132
src/3rdparty/harfbuzz-ng/src/hb-font.h
vendored
@ -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);
|
||||
|
||||
|
||||
|
@ -31,8 +31,6 @@
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-blob.h"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,37 +560,48 @@ 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);
|
||||
}
|
||||
inline void replace_glyph (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess = 0) const
|
||||
{
|
||||
set_class (glyph_index, class_guess);
|
||||
_set_glyph_props (glyph_index);
|
||||
buffer->replace_glyph (glyph_index);
|
||||
}
|
||||
inline void replace_glyph_inplace (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 output_glyph (hb_codepoint_t glyph_index,
|
||||
unsigned int class_guess) const
|
||||
{
|
||||
_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);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
unsigned int end;
|
||||
|
||||
/* TODO We don't support lookupRecord arrays that are not increasing:
|
||||
* Should be easy for in_place ones at least. */
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
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();
|
||||
|
||||
unsigned int i = 0;
|
||||
if (lookupCount && 0 == lookupRecord->sequenceIndex)
|
||||
/* All positions are distance from beginning of *output* buffer.
|
||||
* Adjust. */
|
||||
{
|
||||
unsigned int old_pos = c->buffer->idx;
|
||||
unsigned int bl = buffer->backtrack_len ();
|
||||
end = bl + match_length;
|
||||
|
||||
/* Apply a lookup */
|
||||
bool done = c->recurse (lookupRecord->lookupListIndex);
|
||||
|
||||
lookupRecord++;
|
||||
lookupCount--;
|
||||
i++;
|
||||
|
||||
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;
|
||||
}
|
||||
int delta = bl - buffer->idx;
|
||||
/* Convert positions to new indexing. */
|
||||
for (unsigned int j = 0; j < count; j++)
|
||||
match_positions[j] += delta;
|
||||
}
|
||||
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 ();
|
||||
|
||||
if (lookupCount && i == lookupRecord->sequenceIndex)
|
||||
for (unsigned int i = 0; i < lookupCount; i++)
|
||||
{
|
||||
unsigned int idx = lookupRecord[i].sequenceIndex;
|
||||
if (idx >= count)
|
||||
continue;
|
||||
|
||||
buffer->move_to (match_positions[idx]);
|
||||
|
||||
unsigned int orig_len = buffer->backtrack_len () + buffer->lookahead_len ();
|
||||
if (!c->recurse (lookupRecord[i].lookupListIndex))
|
||||
continue;
|
||||
|
||||
unsigned int new_len = buffer->backtrack_len () + buffer->lookahead_len ();
|
||||
int delta = new_len - orig_len;
|
||||
|
||||
if (!delta)
|
||||
continue;
|
||||
|
||||
/* Recursed lookup changed buffer len. Adjust. */
|
||||
|
||||
/* end can't go back past the current match position. */
|
||||
end = MAX ((int) match_positions[idx] + 1, int (end) + delta);
|
||||
|
||||
unsigned int next = idx + 1; /* next now is the position after the recursed lookup. */
|
||||
|
||||
if (delta > 0)
|
||||
{
|
||||
unsigned int old_pos = c->buffer->idx;
|
||||
|
||||
/* Apply a lookup */
|
||||
bool done = c->recurse (lookupRecord->lookupListIndex);
|
||||
|
||||
lookupRecord++;
|
||||
lookupCount--;
|
||||
i++;
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
|
229
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
vendored
Normal file
229
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh
vendored
Normal file
@ -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 */
|
425
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
vendored
425
src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh
vendored
@ -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,170 +31,35 @@
|
||||
|
||||
#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 */
|
||||
|
||||
/* buffer var allocations, used during the entire shaping process */
|
||||
#define unicode_props0() var2.u8[0]
|
||||
#define unicode_props1() var2.u8[1]
|
||||
|
||||
|
||||
inline void
|
||||
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~0x1F);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
inline void
|
||||
_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info, unsigned int modified_class)
|
||||
{
|
||||
info->unicode_props1() = modified_class;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
|
||||
{
|
||||
return info->unicode_props1();
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->unicode_props0() & 0x80);
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
_hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->unicode_props0() & 0x40);
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->unicode_props0() & 0x20);
|
||||
}
|
||||
|
||||
|
||||
#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;
|
||||
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
|
||||
*/
|
||||
|
||||
/* lig_id / lig_comp
|
||||
*
|
||||
* When a ligature is formed:
|
||||
*
|
||||
* - The ligature glyph and any marks in between all the same newly allocated
|
||||
* lig_id,
|
||||
* - The ligature glyph will get lig_num_comps set to the number of components
|
||||
* - 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.
|
||||
*
|
||||
* When a multiple-substitution is done:
|
||||
*
|
||||
* - All resulting glyphs will have lig_id = 0,
|
||||
* - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
|
||||
* - This is used in GPOS to attach marks to the first component of a
|
||||
* 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.
|
||||
*/
|
||||
#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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
set_lig_props_for_mark (info, 0, comp);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
get_lig_id (const hb_glyph_info_t &info)
|
||||
{
|
||||
return info.lig_props() >> 5;
|
||||
}
|
||||
static inline bool
|
||||
is_a_ligature (const hb_glyph_info_t &info)
|
||||
{
|
||||
return !!(info.lig_props() & IS_LIG_BASE);
|
||||
}
|
||||
static inline unsigned int
|
||||
get_lig_comp (const hb_glyph_info_t &info)
|
||||
{
|
||||
if (is_a_ligature (info))
|
||||
return 0;
|
||||
else
|
||||
return info.lig_props() & 0x0F;
|
||||
}
|
||||
static inline unsigned int
|
||||
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;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline uint8_t 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 */
|
||||
return lig_id;
|
||||
}
|
||||
|
||||
|
||||
HB_INTERNAL hb_bool_t
|
||||
hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
@ -292,5 +157,267 @@ 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) ? 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)
|
||||
{
|
||||
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() & MASK0_GEN_CAT);
|
||||
}
|
||||
|
||||
inline void
|
||||
_hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
|
||||
unsigned int modified_class)
|
||||
{
|
||||
info->unicode_props1() = modified_class;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
_hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
|
||||
{
|
||||
return info->unicode_props1();
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
_hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
|
||||
{
|
||||
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() & MASK0_ZWNJ);
|
||||
}
|
||||
|
||||
inline hb_bool_t
|
||||
_hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* lig_props: aka lig_id / lig_comp
|
||||
*
|
||||
* When a ligature is formed:
|
||||
*
|
||||
* - The ligature glyph and any marks in between all the same newly allocated
|
||||
* lig_id,
|
||||
* - The ligature glyph will get lig_num_comps set to the number of components
|
||||
* - 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,
|
||||
* - 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:
|
||||
*
|
||||
* - All resulting glyphs will have lig_id = 0,
|
||||
* - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
|
||||
* - This is used in GPOS to attach marks to the first component of a
|
||||
* 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 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
|
||||
_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);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_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);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
|
||||
{
|
||||
_hb_glyph_info_set_lig_props_for_mark (info, 0, comp);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
_hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
|
||||
{
|
||||
return info->lig_props() >> 5;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->lig_props() & IS_LIG_BASE);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
_hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
|
||||
{
|
||||
if (_hb_glyph_info_ligated_internal (info))
|
||||
return 0;
|
||||
else
|
||||
return info->lig_props() & 0x0F;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
_hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
|
||||
{
|
||||
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
|
||||
_hb_allocate_lig_id (hb_buffer_t *buffer) {
|
||||
uint8_t lig_id = buffer->next_serial () & 0x07;
|
||||
if (unlikely (!lig_id))
|
||||
lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
|
||||
return lig_id;
|
||||
}
|
||||
|
||||
/* glyph_props: */
|
||||
|
||||
inline void
|
||||
_hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
|
||||
{
|
||||
info->glyph_props() = props;
|
||||
}
|
||||
|
||||
inline unsigned int
|
||||
_hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
|
||||
{
|
||||
return info->glyph_props();
|
||||
}
|
||||
|
||||
inline bool
|
||||
_hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
|
||||
}
|
||||
|
||||
inline bool
|
||||
_hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
|
||||
}
|
||||
|
||||
inline bool
|
||||
_hb_glyph_info_is_mark (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_substituted (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
_hb_glyph_info_ligated (const hb_glyph_info_t *info)
|
||||
{
|
||||
return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
|
||||
}
|
||||
|
||||
/* Allocation / deallocation. */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 */
|
||||
|
58
src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
vendored
58
src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
vendored
@ -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;
|
||||
|
6
src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
vendored
6
src/3rdparty/harfbuzz-ng/src/hb-ot-layout.h
vendored
@ -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,
|
||||
|
10
src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
vendored
10
src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc
vendored
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -156,6 +156,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,
|
||||
@ -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;
|
||||
|
||||
@ -313,6 +321,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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
@ -1074,6 +1176,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
|
||||
initial_reordering_standalone_cluster (plan, face, buffer, start, end);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -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;
|
||||
|
@ -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)
|
||||
@ -395,6 +415,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
|
||||
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
|
||||
}
|
||||
|
||||
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,
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
}
|
||||
}
|
||||
|
@ -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) {}
|
||||
|
156
src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
vendored
156
src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
vendored
@ -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;
|
||||
|
||||
|
315
src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
vendored
315
src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc
vendored
@ -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 */
|
||||
|
3
src/3rdparty/harfbuzz-ng/src/hb-private.hh
vendored
3
src/3rdparty/harfbuzz-ng/src/hb-private.hh
vendored
@ -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>
|
||||
|
21
src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
vendored
21
src/3rdparty/harfbuzz-ng/src/hb-set-private.hh
vendored
@ -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]; }
|
||||
|
244
src/3rdparty/harfbuzz-ng/src/hb-set.cc
vendored
244
src/3rdparty/harfbuzz-ng/src/hb-set.cc
vendored
@ -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,
|
||||
|
2
src/3rdparty/harfbuzz-ng/src/hb-set.h
vendored
2
src/3rdparty/harfbuzz-ng/src/hb-set.h
vendored
@ -36,6 +36,8 @@
|
||||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
|
||||
|
||||
typedef struct hb_set_t hb_set_t;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
173
src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
vendored
173
src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc
vendored
@ -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)
|
||||
{
|
||||
|
56
src/3rdparty/harfbuzz-ng/src/hb-shape.cc
vendored
56
src/3rdparty/harfbuzz-ng/src/hb-shape.cc
vendored
@ -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,
|
||||
|
@ -32,8 +32,6 @@
|
||||
#define HB_UNICODE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb-unicode.h"
|
||||
#include "hb-object-private.hh"
|
||||
|
||||
|
||||
|
128
src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
vendored
128
src/3rdparty/harfbuzz-ng/src/hb-unicode.cc
vendored
@ -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,
|
||||
|
106
src/3rdparty/harfbuzz-ng/src/hb-unicode.h
vendored
106
src/3rdparty/harfbuzz-ng/src/hb-unicode.h
vendored
@ -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 */
|
||||
|
4
src/3rdparty/harfbuzz-ng/src/hb-version.h
vendored
4
src/3rdparty/harfbuzz-ng/src/hb-version.h
vendored
@ -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) >= \
|
||||
|
1
src/3rdparty/harfbuzz.pri
vendored
1
src/3rdparty/harfbuzz.pri
vendored
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user