diff options
Diffstat (limited to 'src')
74 files changed, 4353 insertions, 2101 deletions
diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS index c4950e2620..f2b0a32401 100644 --- a/src/3rdparty/harfbuzz-ng/NEWS +++ b/src/3rdparty/harfbuzz-ng/NEWS @@ -1,3 +1,118 @@ +Overview of changes leading to 1.0.6 +Thursday, October 15, 2015 +==================================== + +- Reduce max nesting level in OT lookups from 8 to 6. + Should not affect any real font as far as I know. +- Fix memory access issue in ot-font. +- Revert default load-flags of fonts created using hb_ft_font_create() + back to FT_LOAD_DEFAULT|FT_LOAD_NO_HINTING. This was changed in + last release (1.0.5), but caused major issues, so revert. + https://github.com/behdad/harfbuzz/issues/143 + + +Overview of changes leading to 1.0.5 +Tuesday, October 13, 2015 +==================================== + +- Fix multiple memory access bugs discovered using libFuzzer. + https://github.com/behdad/harfbuzz/issues/139 + Everyone should upgrade to this version as soon as possible. + We now have continuous fuzzing set up, to avoid issues like + these creeping in again. +- Misc fixes. + +- New API: + * hb_font_set_parent(). + * hb_ft_font_[sg]et_load_flags() + The default flags for fonts created using hb_ft_font_create() + has changed to default to FT_LOAD_DEFAULT now. Previously it + was defaulting to FT_LOAD_DFEAULT|FT_LOAD_NO_HINTING. + +- API changes: + * Fonts now default to units-per-EM as their scale, instead of 0. + * hb_font_create_sub_font() does NOT make parent font immutable + anymore. hb_font_make_immutable() does. + + +Overview of changes leading to 1.0.4 +Wednesday, September 30, 2015 +==================================== + +- Fix minor out-of-bounds read error. + + +Overview of changes leading to 1.0.3 +Tuesday, September 1, 2015 +==================================== + +- Start of user documentation, from Simon Cozens! +- Implement glyph_extents() for TrueType fonts in hb-ot-font. +- Improve GPOS cursive attachments with conflicting lookups. +- More fixes for cluster-level = 1. +- Uniscribe positioning fix. + + +Overview of changes leading to 1.0.2 +Wednesday, August 19, 2015 +==================================== + +- Fix shaping with cluster-level > 0. +- Fix Uniscribe backend font-size scaling. +- Declare dependencies in harfbuzz.pc. + FreeType is not declared though, to avoid bugs in pkg-config + 0.26 with recursive dependencies. +- Slightly improved debug infrastructure. More to come later. +- Misc build fixes. + + +Overview of changes leading to 1.0.1 +Monday, July 27, 2015 +==================================== + +- Fix out-of-bounds access in USE shaper. + + +Overview of changes leading to 1.0.0 +Sunday, July 26, 2015 +==================================== + +- Implement Universal Shaping Engine: + https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + http://blogs.windows.com/bloggingwindows/2015/02/23/windows-shapes-the-worlds-languages/ +- Bump version to 1.0.0. The soname was NOT bumped. + + +Overview of changes leading to 0.9.42 +Thursday, July 26, 2015 +===================================== + +- New API to allow for retrieving finer-grained cluster + mappings if the client desires to handle them. Default + behavior is unchanged. +- Fix cluster merging when removing default-ignorables. +- Update to Unicode 8.0 +- hb-graphite2 fixes. +- Misc fixes. +- Removed HB_NO_MERGE_CLUSTERS hack. +- New API: + hb_buffer_cluster_level_t enum + hb_buffer_get_cluster_level() + hb_buffer_set_cluster_level() + hb-shape / hb-view --cluster-level + + +Overview of changes leading to 0.9.41 +Thursday, June 18, 2015 +===================================== + +- Fix hb-coretext with trailing whitespace in right-to-left. +- New API: hb_buffer_reverse_range(). +- Allow implementing atomic ops in config.h. +- Fix hb_language_t in language bindings. +- Misc fixes. + + Overview of changes leading to 0.9.40 Friday, March 20, 2015 ===================================== diff --git a/src/3rdparty/harfbuzz-ng/README b/src/3rdparty/harfbuzz-ng/README index d34bc74f99..dea10688f3 100644 --- a/src/3rdparty/harfbuzz-ng/README +++ b/src/3rdparty/harfbuzz-ng/README @@ -1,5 +1,6 @@ [![Build Status](https://travis-ci.org/behdad/harfbuzz.svg)](https://travis-ci.org/behdad/harfbuzz) [![Coverage Status](https://img.shields.io/coveralls/behdad/harfbuzz.svg)](https://coveralls.io/r/behdad/harfbuzz) +[![Coverity Scan](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/5450) This is HarfBuzz, a text shaping library. diff --git a/src/3rdparty/harfbuzz-ng/config.h b/src/3rdparty/harfbuzz-ng/config.h new file mode 100644 index 0000000000..b8b6b3c0fe --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/config.h @@ -0,0 +1,47 @@ +/* +* Copyright (C) 2015 The Qt Company Ltd. +* Copyright (C) 2015 Konstantin Ritt +* +* 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. +* +*/ + +#include <QtCore/qatomic.h> + +QT_USE_NAMESPACE + +namespace { + +// We need to cast hb_atomic_int_t to QAtomicInt and pointers to +// QAtomicPointer instead of using QAtomicOps, otherwise we get a failed +// overload resolution of the template arguments for testAndSetOrdered. +template <typename T> +inline QAtomicPointer<T> *makeAtomicPointer(T * const &ptr) +{ + return reinterpret_cast<QAtomicPointer<T> *>(const_cast<T **>(&ptr)); +} + +} // namespace + +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) reinterpret_cast<QAtomicInt &>(AI).fetchAndAddOrdered(V) + +#define hb_atomic_ptr_impl_get(P) makeAtomicPointer(*(P))->loadAcquire() +#define hb_atomic_ptr_impl_cmpexch(P,O,N) makeAtomicPointer(*(P))->testAndSetOrdered((O), (N)) diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index fb6771759b..031f7ecd58 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -7,7 +7,8 @@ CONFIG += \ load(qt_helper_lib) -DEFINES += HAVE_OT HAVE_QT5_ATOMICS HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED +DEFINES += HAVE_CONFIG_H +DEFINES += HAVE_OT HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED # platform/compiler specific definitions DEFINES += HAVE_ATEXIT @@ -45,6 +46,7 @@ HEADERS += \ $$PWD/src/hb-open-file-private.hh \ $$PWD/src/hb-open-type-private.hh \ $$PWD/src/hb-ot-cmap-table.hh \ + $$PWD/src/hb-ot-glyf-table.hh \ $$PWD/src/hb-ot-head-table.hh \ $$PWD/src/hb-ot-hhea-table.hh \ $$PWD/src/hb-ot-hmtx-table.hh \ @@ -86,9 +88,10 @@ SOURCES += \ $$PWD/src/hb-ot-shape-complex-indic.cc \ $$PWD/src/hb-ot-shape-complex-indic-table.cc \ $$PWD/src/hb-ot-shape-complex-myanmar.cc \ - $$PWD/src/hb-ot-shape-complex-sea.cc \ $$PWD/src/hb-ot-shape-complex-thai.cc \ $$PWD/src/hb-ot-shape-complex-tibetan.cc \ + $$PWD/src/hb-ot-shape-complex-use.cc \ + $$PWD/src/hb-ot-shape-complex-use-table.cc \ $$PWD/src/hb-ot-shape-fallback.cc \ $$PWD/src/hb-ot-shape-normalize.cc @@ -102,12 +105,14 @@ HEADERS += \ $$PWD/src/hb-ot-layout-private.hh \ $$PWD/src/hb-ot-map-private.hh \ $$PWD/src/hb-ot-shape-complex-arabic-fallback.hh \ + $$PWD/src/hb-ot-shape-complex-arabic-private.hh \ $$PWD/src/hb-ot-shape-complex-arabic-table.hh \ $$PWD/src/hb-ot-shape-complex-indic-machine.hh \ $$PWD/src/hb-ot-shape-complex-indic-private.hh \ $$PWD/src/hb-ot-shape-complex-myanmar-machine.hh \ $$PWD/src/hb-ot-shape-complex-private.hh \ - $$PWD/src/hb-ot-shape-complex-sea-machine.hh \ + $$PWD/src/hb-ot-shape-complex-use-machine.hh \ + $$PWD/src/hb-ot-shape-complex-use-private.hh \ $$PWD/src/hb-ot-shape-fallback-private.hh \ $$PWD/src/hb-ot-shape-normalize-private.hh \ $$PWD/src/hb-ot-shape-private.hh diff --git a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh index 48eb56141f..8179571ad2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-atomic-private.hh @@ -39,27 +39,12 @@ /* We need external help for these */ -#if 0 +#if defined(hb_atomic_int_impl_add) \ + && defined(hb_atomic_ptr_impl_get) \ + && defined(hb_atomic_ptr_impl_cmpexch) -#elif !defined(HB_NO_MT) && defined(HAVE_QT5_ATOMICS) -#include <QtCore/qatomic.h> +/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */ -QT_USE_NAMESPACE - -namespace { -// We need to cast hb_atomic_int_t to QAtomicInt and pointers to -// QAtomicPointer instead of using QAtomicOps, otherwise we get a failed -// overload resolution of the template arguments for testAndSetOrdered. -template <typename T> QAtomicPointer<T> *makeAtomicPointer(T * const &ptr) -{ - return reinterpret_cast<QAtomicPointer<T> *>(const_cast<T **>(&ptr)); -} -} - -typedef int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) reinterpret_cast<QAtomicInt &>(AI).fetchAndAddOrdered(V) -#define hb_atomic_ptr_get(P) makeAtomicPointer(*P)->loadAcquire() -#define hb_atomic_ptr_cmpexch(P,O,N) makeAtomicPointer(*P)->testAndSetOrdered((O), (N)) #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) @@ -77,11 +62,12 @@ static inline void _HBMemoryBarrier (void) { #endif } -typedef LONG hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) +typedef LONG hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V)) -#define hb_atomic_ptr_get(P) (_HBMemoryBarrier (), (void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) +#define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O)) #elif !defined(HB_NO_MT) && defined(__APPLE__) @@ -93,28 +79,31 @@ typedef LONG hb_atomic_int_t; #include <Availability.h> #endif -typedef int32_t hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) -#define hb_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P)) +typedef int32_t hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V)) + +#define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P)) #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100) -#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P)) #else #if __ppc64__ || __x86_64__ || __aarch64__ -#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P)) +#define hb_atomic_ptr_impl_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)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P)) #endif #endif #elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES) -typedef int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V)) +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V)) -#define hb_atomic_ptr_get(P) (void *) (__sync_synchronize (), *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) +#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N)) #elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS) @@ -122,33 +111,54 @@ typedef int hb_atomic_int_t; #include <atomic.h> #include <mbarrier.h> -typedef unsigned int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) +typedef unsigned int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V)) -#define hb_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) +#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false) #elif !defined(HB_NO_MT) #define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */ -typedef volatile int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) -#define hb_atomic_ptr_get(P) ((void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) +typedef volatile int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) + +#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false) #else /* HB_NO_MT */ -typedef int hb_atomic_int_t; -#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V)) +typedef int hb_atomic_int_impl_t; +#define HB_ATOMIC_INT_IMPL_INIT(V) (V) +#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V)) + +#define hb_atomic_ptr_impl_get(P) ((void *) *(P)) +#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) -#define hb_atomic_ptr_get(P) ((void *) *(P)) -#define hb_atomic_ptr_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) #endif -/* TODO Add tracing. */ + +#define HB_ATOMIC_INT_INIT(V) {HB_ATOMIC_INT_IMPL_INIT(V)} + +struct hb_atomic_int_t +{ + hb_atomic_int_impl_t v; + + inline void set_unsafe (int v_) { v = v_; } + inline int get_unsafe (void) const { return v; } + inline int inc (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), 1); } + inline int dec (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), -1); } +}; + + +#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P) +#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N)) + #endif /* HB_ATOMIC_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc index 8759a252a5..a6870dc06e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-blob.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-blob.cc @@ -91,7 +91,7 @@ _hb_blob_destroy_user_data (hb_blob_t *blob) * Return value: New blob, or the empty blob if something failed or if @length is * zero. Destroy with hb_blob_destroy(). * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_blob_create (const char *data, @@ -147,7 +147,7 @@ hb_blob_create (const char *data, * @length is zero or @offset is beyond the end of @parent's data. Destroy * with hb_blob_destroy(). * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_blob_create_sub_blob (hb_blob_t *parent, @@ -179,7 +179,7 @@ hb_blob_create_sub_blob (hb_blob_t *parent, * * Return value: (transfer full): the empty blob. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_blob_get_empty (void) @@ -210,7 +210,7 @@ hb_blob_get_empty (void) * * Return value: @blob. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_blob_reference (hb_blob_t *blob) @@ -228,7 +228,7 @@ hb_blob_reference (hb_blob_t *blob) * * See TODO:link object types for more information. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_blob_destroy (hb_blob_t *blob) @@ -250,7 +250,7 @@ hb_blob_destroy (hb_blob_t *blob) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_blob_set_user_data (hb_blob_t *blob, @@ -271,7 +271,7 @@ hb_blob_set_user_data (hb_blob_t *blob, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_blob_get_user_data (hb_blob_t *blob, @@ -287,7 +287,7 @@ hb_blob_get_user_data (hb_blob_t *blob, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_blob_make_immutable (hb_blob_t *blob) @@ -306,7 +306,7 @@ hb_blob_make_immutable (hb_blob_t *blob) * * Return value: TODO * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_blob_is_immutable (hb_blob_t *blob) @@ -323,7 +323,7 @@ hb_blob_is_immutable (hb_blob_t *blob) * * Return value: the length of blob data in bytes. * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_blob_get_length (hb_blob_t *blob) @@ -340,7 +340,7 @@ hb_blob_get_length (hb_blob_t *blob) * * Returns: (transfer none) (array length=length): * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_blob_get_data (hb_blob_t *blob, unsigned int *length) @@ -365,7 +365,7 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length) * Returns: (transfer none) (array length=length): Writable blob data, * or %NULL if failed. * - * Since: 1.0 + * Since: 0.9.2 **/ char * hb_blob_get_data_writable (hb_blob_t *blob, unsigned int *length) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh index 7a46ab278b..d2d8daae7e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-deserialize-text.hh @@ -336,8 +336,8 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer, const char *eof = pe, *tok = NULL; int cs; - hb_glyph_info_t info; - hb_glyph_position_t pos; + hb_glyph_info_t info = {0}; + hb_glyph_position_t pos = {0}; #line 343 "hb-buffer-deserialize-text.hh" { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh index 069f925581..7fed7386b0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-private.hh @@ -50,6 +50,7 @@ struct hb_buffer_t { /* Information about how the text in the buffer should be treated */ hb_unicode_funcs_t *unicode; /* Unicode functions */ hb_buffer_flags_t flags; /* BOT / EOT / etc. */ + hb_buffer_cluster_level_t cluster_level; hb_codepoint_t replacement; /* U+FFFD or something else. */ /* Buffer contents */ @@ -171,9 +172,18 @@ struct hb_buffer_t { unsigned int cluster_end); HB_INTERNAL void merge_clusters (unsigned int start, - unsigned int end); + unsigned int end) + { + if (end - start < 2) + return; + merge_clusters_impl (start, end); + } + HB_INTERNAL void merge_clusters_impl (unsigned int start, + unsigned int end); HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); + /* Merge clusters for deleting current glyph, and skip it. */ + HB_INTERNAL void delete_glyph (void); /* Internal methods */ HB_INTERNAL bool enlarge (unsigned int size); @@ -191,6 +201,8 @@ struct hb_buffer_t { HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size); inline void clear_context (unsigned int side) { context_len[side] = 0; } + + HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc index 406d69db75..7839cbc3f0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer-serialize.cc @@ -40,7 +40,7 @@ static const char *serialize_formats[] = { * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ const char ** hb_buffer_serialize_list_formats (void) @@ -57,7 +57,7 @@ hb_buffer_serialize_list_formats (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_buffer_serialize_format_t hb_buffer_serialize_format_from_string (const char *str, int len) @@ -74,7 +74,7 @@ hb_buffer_serialize_format_from_string (const char *str, int len) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format) @@ -99,7 +99,8 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, hb_buffer_serialize_flags_t flags) { hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); - hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); + hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? + NULL : hb_buffer_get_glyph_positions (buffer, NULL); *buf_consumed = 0; for (unsigned int i = start; i < end; i++) @@ -144,6 +145,16 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer, pos[i].x_advance, pos[i].y_advance); } + if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) + { + hb_glyph_extents_t extents; + hb_font_get_glyph_extents(font, info[i].codepoint, &extents); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"xb\":%d,\"yb\":%d", + extents.x_bearing, extents.y_bearing)); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"w\":%d,\"h\":%d", + extents.width, extents.height)); + } + *p++ = '}'; unsigned int l = p - b; @@ -172,7 +183,8 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, hb_buffer_serialize_flags_t flags) { hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, NULL); - hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, NULL); + hb_glyph_position_t *pos = (flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS) ? + NULL : hb_buffer_get_glyph_positions (buffer, NULL); *buf_consumed = 0; for (unsigned int i = start; i < end; i++) @@ -208,6 +220,13 @@ _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 (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS) + { + hb_glyph_extents_t extents; + hb_font_get_glyph_extents(font, info[i].codepoint, &extents); + p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "<%d,%d,%d,%d>", extents.x_bearing, extents.y_bearing, extents.width, extents.height)); + } + unsigned int l = p - b; if (buf_size > l) { @@ -240,7 +259,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_buffer_serialize_glyphs (hb_buffer_t *buffer, @@ -347,7 +366,7 @@ parse_int (const char *pp, const char *end, int32_t *pv) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc index b9fe263ce5..50710dd23e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc @@ -36,6 +36,9 @@ #endif +/** + * Since: 0.9.7 + **/ hb_bool_t hb_segment_properties_equal (const hb_segment_properties_t *a, const hb_segment_properties_t *b) @@ -48,6 +51,9 @@ hb_segment_properties_equal (const hb_segment_properties_t *a, } +/** + * Since: 0.9.7 + **/ unsigned int hb_segment_properties_hash (const hb_segment_properties_t *p) { @@ -498,14 +504,10 @@ hb_buffer_t::reverse_clusters (void) } void -hb_buffer_t::merge_clusters (unsigned int start, - unsigned int end) +hb_buffer_t::merge_clusters_impl (unsigned int start, + unsigned int end) { -#ifdef HB_NO_MERGE_CLUSTERS - return; -#endif - - if (unlikely (end - start < 2)) + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) return; unsigned int cluster = info[start].cluster; @@ -523,7 +525,7 @@ hb_buffer_t::merge_clusters (unsigned int start, /* If we hit the start of buffer, continue in out-buffer. */ if (idx == start) - for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) + for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) out_info[i - 1].cluster = cluster; for (unsigned int i = start; i < end; i++) @@ -533,9 +535,8 @@ void hb_buffer_t::merge_out_clusters (unsigned int start, unsigned int end) { -#ifdef HB_NO_MERGE_CLUSTERS - return; -#endif + if (cluster_level == HB_BUFFER_CLUSTER_LEVEL_CHARACTERS) + return; if (unlikely (end - start < 2)) return; @@ -555,12 +556,44 @@ hb_buffer_t::merge_out_clusters (unsigned int start, /* If we hit the end of out-buffer, continue in buffer. */ if (end == out_len) - for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) + for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) info[i].cluster = cluster; for (unsigned int i = start; i < end; i++) out_info[i].cluster = cluster; } +void +hb_buffer_t::delete_glyph () +{ + unsigned int cluster = info[idx].cluster; + if (idx + 1 < len && cluster == info[idx + 1].cluster) + { + /* Cluster survives; do nothing. */ + goto done; + } + + if (out_len) + { + /* Merge cluster backward. */ + if (cluster < out_info[out_len - 1].cluster) + { + unsigned int old_cluster = out_info[out_len - 1].cluster; + for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--) + out_info[i - 1].cluster = cluster; + } + goto done; + } + + if (idx + 1 < len) + { + /* Merge cluster forward. */ + merge_clusters (idx, idx + 2); + goto done; + } + +done: + skip_glyph (); +} void hb_buffer_t::guess_segment_properties (void) @@ -671,7 +704,7 @@ void hb_buffer_t::deallocate_var_all (void) * * Return value: (transfer full) * - * Since: 1.0 + * Since: 0.9.2 **/ hb_buffer_t * hb_buffer_create (void) @@ -693,7 +726,7 @@ hb_buffer_create (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_buffer_t * hb_buffer_get_empty (void) @@ -703,6 +736,7 @@ hb_buffer_get_empty (void) const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), HB_BUFFER_FLAG_DEFAULT, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, HB_BUFFER_CONTENT_TYPE_INVALID, @@ -725,7 +759,7 @@ hb_buffer_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_buffer_t * hb_buffer_reference (hb_buffer_t *buffer) @@ -739,7 +773,7 @@ hb_buffer_reference (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_destroy (hb_buffer_t *buffer) @@ -766,7 +800,7 @@ hb_buffer_destroy (hb_buffer_t *buffer) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_set_user_data (hb_buffer_t *buffer, @@ -787,7 +821,7 @@ hb_buffer_set_user_data (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_buffer_get_user_data (hb_buffer_t *buffer, @@ -804,7 +838,7 @@ hb_buffer_get_user_data (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.5 **/ void hb_buffer_set_content_type (hb_buffer_t *buffer, @@ -821,7 +855,7 @@ hb_buffer_set_content_type (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.5 **/ hb_buffer_content_type_t hb_buffer_get_content_type (hb_buffer_t *buffer) @@ -837,7 +871,7 @@ hb_buffer_get_content_type (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, @@ -863,7 +897,7 @@ hb_buffer_set_unicode_funcs (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_unicode_funcs_t * hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) @@ -878,7 +912,7 @@ hb_buffer_get_unicode_funcs (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_set_direction (hb_buffer_t *buffer, @@ -899,7 +933,7 @@ hb_buffer_set_direction (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_direction_t hb_buffer_get_direction (hb_buffer_t *buffer) @@ -914,7 +948,7 @@ hb_buffer_get_direction (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_set_script (hb_buffer_t *buffer, @@ -934,7 +968,7 @@ hb_buffer_set_script (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_script_t hb_buffer_get_script (hb_buffer_t *buffer) @@ -949,7 +983,7 @@ hb_buffer_get_script (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_set_language (hb_buffer_t *buffer, @@ -967,9 +1001,9 @@ hb_buffer_set_language (hb_buffer_t *buffer, * * * - * Return value: + * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_language_t hb_buffer_get_language (hb_buffer_t *buffer) @@ -984,7 +1018,7 @@ hb_buffer_get_language (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_set_segment_properties (hb_buffer_t *buffer, @@ -999,11 +1033,11 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer, /** * hb_buffer_get_segment_properties: * @buffer: a buffer. - * @props: + * @props: (out): * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_get_segment_properties (hb_buffer_t *buffer, @@ -1020,7 +1054,7 @@ hb_buffer_get_segment_properties (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_set_flags (hb_buffer_t *buffer, @@ -1040,7 +1074,7 @@ hb_buffer_set_flags (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer) @@ -1048,6 +1082,41 @@ hb_buffer_get_flags (hb_buffer_t *buffer) return buffer->flags; } +/** + * hb_buffer_set_cluster_level: + * @buffer: a buffer. + * @cluster_level: + * + * + * + * Since: 0.9.42 + **/ +void +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level) +{ + if (unlikely (hb_object_is_inert (buffer))) + return; + + buffer->cluster_level = cluster_level; +} + +/** + * hb_buffer_get_cluster_level: + * @buffer: a buffer. + * + * + * + * Return value: + * + * Since: 0.9.42 + **/ +hb_buffer_cluster_level_t +hb_buffer_get_cluster_level (hb_buffer_t *buffer) +{ + return buffer->cluster_level; +} + /** * hb_buffer_set_replacement_codepoint: @@ -1056,7 +1125,7 @@ hb_buffer_get_flags (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.31 **/ void hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, @@ -1076,7 +1145,7 @@ hb_buffer_set_replacement_codepoint (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.31 **/ hb_codepoint_t hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) @@ -1091,7 +1160,7 @@ hb_buffer_get_replacement_codepoint (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_reset (hb_buffer_t *buffer) @@ -1105,7 +1174,7 @@ hb_buffer_reset (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.11 **/ void hb_buffer_clear_contents (hb_buffer_t *buffer) @@ -1122,7 +1191,7 @@ hb_buffer_clear_contents (hb_buffer_t *buffer) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) @@ -1138,7 +1207,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_allocation_successful (hb_buffer_t *buffer) @@ -1154,7 +1223,7 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer) * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_add (hb_buffer_t *buffer, @@ -1174,7 +1243,7 @@ hb_buffer_add (hb_buffer_t *buffer, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_buffer_set_length (hb_buffer_t *buffer, @@ -1213,7 +1282,7 @@ hb_buffer_set_length (hb_buffer_t *buffer, * * Return value: buffer length. * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_buffer_get_length (hb_buffer_t *buffer) @@ -1231,7 +1300,7 @@ hb_buffer_get_length (hb_buffer_t *buffer) * * Return value: (transfer none) (array length=length): buffer glyph information array. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_glyph_info_t * hb_buffer_get_glyph_infos (hb_buffer_t *buffer, @@ -1253,7 +1322,7 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer, * * Return value: (transfer none) (array length=length): buffer glyph position array. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_glyph_position_t * hb_buffer_get_glyph_positions (hb_buffer_t *buffer, @@ -1274,7 +1343,7 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer, * * Reverses buffer contents. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_reverse (hb_buffer_t *buffer) @@ -1283,6 +1352,23 @@ hb_buffer_reverse (hb_buffer_t *buffer) } /** + * hb_buffer_reverse_range: + * @buffer: a buffer. + * @start: start index. + * @end: end index. + * + * Reverses buffer contents between start to end. + * + * Since: 0.9.41 + **/ +void +hb_buffer_reverse_range (hb_buffer_t *buffer, + unsigned int start, unsigned int end) +{ + buffer->reverse_range (start, end); +} + +/** * hb_buffer_reverse_clusters: * @buffer: a buffer. * @@ -1290,7 +1376,7 @@ hb_buffer_reverse (hb_buffer_t *buffer) * reversed, then each cluster (consecutive items having the * same cluster number) are reversed again. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_reverse_clusters (hb_buffer_t *buffer) @@ -1320,7 +1406,7 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer) * hb_language_get_default(). This may change in the future by * taking buffer script into consideration when choosing a language. * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_buffer_guess_segment_properties (hb_buffer_t *buffer) @@ -1407,7 +1493,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_add_utf8 (hb_buffer_t *buffer, @@ -1429,7 +1515,7 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_add_utf16 (hb_buffer_t *buffer, @@ -1451,7 +1537,7 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_add_utf32 (hb_buffer_t *buffer, @@ -1473,7 +1559,7 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.39 **/ void hb_buffer_add_latin1 (hb_buffer_t *buffer, @@ -1495,7 +1581,7 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.31 **/ void hb_buffer_add_codepoints (hb_buffer_t *buffer, @@ -1550,7 +1636,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, pos[end - 1].x_advance = total_x_advance; pos[end - 1].y_advance = total_y_advance; - hb_bubble_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start); + hb_stable_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start); } else { /* Transfer all cluster advance to the first glyph. */ pos[start].x_advance += total_x_advance; @@ -1559,7 +1645,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, pos[i].x_offset -= total_x_advance; pos[i].y_offset -= total_y_advance; } - hb_bubble_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1); + hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1); } } @@ -1569,7 +1655,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_buffer_normalize_glyphs (hb_buffer_t *buffer) @@ -1592,3 +1678,24 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer) } normalize_glyphs_cluster (buffer, start, end, backward); } + +void +hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)) +{ + assert (!have_positions); + for (unsigned int i = start + 1; i < end; i++) + { + unsigned int j = i; + while (j > start && compar (&info[j - 1], &info[i]) > 0) + j--; + if (i == j) + continue; + /* Move item i to occupy place for item j, shift what's in between. */ + merge_clusters (j, i + 1); + { + hb_glyph_info_t t = info[i]; + memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t)); + info[j] = t; + } + } +} diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h index e5b46d867a..bb89dc3de7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.h @@ -171,6 +171,9 @@ void hb_buffer_guess_segment_properties (hb_buffer_t *buffer); +/* + * Since: 0.9.20 + */ typedef enum { /*< flags >*/ HB_BUFFER_FLAG_DEFAULT = 0x00000000u, HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */ @@ -185,7 +188,22 @@ hb_buffer_set_flags (hb_buffer_t *buffer, hb_buffer_flags_t hb_buffer_get_flags (hb_buffer_t *buffer); +/* + * Since: 0.9.42 + */ +typedef enum { + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0, + HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1, + HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES +} hb_buffer_cluster_level_t; +void +hb_buffer_set_cluster_level (hb_buffer_t *buffer, + hb_buffer_cluster_level_t cluster_level); + +hb_buffer_cluster_level_t +hb_buffer_get_cluster_level (hb_buffer_t *buffer); #define HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT 0xFFFDu @@ -222,6 +240,10 @@ void hb_buffer_reverse (hb_buffer_t *buffer); void +hb_buffer_reverse_range (hb_buffer_t *buffer, + unsigned int start, unsigned int end); + +void hb_buffer_reverse_clusters (hb_buffer_t *buffer); @@ -303,11 +325,15 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer); * Serialize */ +/* + * Since: 0.9.20 + */ typedef enum { /*< flags >*/ 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_FLAG_NO_GLYPH_NAMES = 0x00000004u, + HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u } hb_buffer_serialize_flags_t; typedef enum { diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.cc b/src/3rdparty/harfbuzz-ng/src/hb-common.cc index 1516211e96..e67059d10b 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.cc @@ -64,7 +64,7 @@ _hb_options_init (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_tag_t hb_tag_from_string (const char *str, int len) @@ -92,7 +92,7 @@ hb_tag_from_string (const char *str, int len) * * * - * Since: 1.0 + * Since: 0.9.5 **/ void hb_tag_to_string (hb_tag_t tag, char *buf) @@ -122,7 +122,7 @@ const char direction_strings[][4] = { * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_direction_t hb_direction_from_string (const char *str, int len) @@ -149,7 +149,7 @@ hb_direction_from_string (const char *str, int len) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_direction_to_string (hb_direction_t direction) @@ -179,7 +179,7 @@ static const char canon_map[256] = { 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0 }; -static hb_bool_t +static bool lang_equal (hb_language_t v1, const void *v2) { @@ -286,28 +286,28 @@ retry: * * * - * Return value: + * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_language_t hb_language_from_string (const char *str, int len) { - char strbuf[64]; - if (!str || !len || !*str) return HB_LANGUAGE_INVALID; + hb_language_item_t *item = NULL; if (len >= 0) { /* NUL-terminate it. */ + char strbuf[64]; len = MIN (len, (int) sizeof (strbuf) - 1); memcpy (strbuf, str, len); strbuf[len] = '\0'; - str = strbuf; + item = lang_find_or_insert (strbuf); } - - hb_language_item_t *item = lang_find_or_insert (str); + else + item = lang_find_or_insert (str); return likely (item) ? item->lang : HB_LANGUAGE_INVALID; } @@ -320,7 +320,7 @@ hb_language_from_string (const char *str, int len) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_language_to_string (hb_language_t language) @@ -334,9 +334,9 @@ hb_language_to_string (hb_language_t language) * * * - * Return value: + * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_language_t hb_language_get_default (void) @@ -363,7 +363,7 @@ hb_language_get_default (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_script_t hb_script_from_iso15924_tag (hb_tag_t tag) @@ -408,7 +408,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_script_t hb_script_from_string (const char *s, int len) @@ -424,7 +424,7 @@ hb_script_from_string (const char *s, int len) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_tag_t hb_script_to_iso15924_tag (hb_script_t script) @@ -440,7 +440,7 @@ hb_script_to_iso15924_tag (hb_script_t script) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_direction_t hb_script_get_horizontal_direction (hb_script_t script) @@ -493,6 +493,9 @@ hb_script_get_horizontal_direction (hb_script_t script) case HB_SCRIPT_PALMYRENE: case HB_SCRIPT_PSALTER_PAHLAVI: + /* Unicode-8.0 additions */ + case HB_SCRIPT_OLD_HUNGARIAN: + return HB_DIRECTION_RTL; } @@ -542,7 +545,7 @@ hb_user_data_array_t::get (hb_user_data_key_t *key) * * Returns library version as three integer components. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_version (unsigned int *major, @@ -561,7 +564,7 @@ hb_version (unsigned int *major, * * Return value: library version string. * - * Since: 1.0 + * Since: 0.9.2 **/ const char * hb_version_string (void) @@ -579,7 +582,7 @@ hb_version_string (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.30 **/ hb_bool_t hb_version_atleast (unsigned int major, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-common.h b/src/3rdparty/harfbuzz-ng/src/hb-common.h index b6ce3f724d..c291dbbe94 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-common.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-common.h @@ -272,6 +272,9 @@ typedef enum /*6.1*/ HB_SCRIPT_SORA_SOMPENG = HB_TAG ('S','o','r','a'), /*6.1*/ HB_SCRIPT_TAKRI = HB_TAG ('T','a','k','r'), + /* + * Since: 0.9.30 + */ /*7.0*/ HB_SCRIPT_BASSA_VAH = HB_TAG ('B','a','s','s'), /*7.0*/ HB_SCRIPT_CAUCASIAN_ALBANIAN = HB_TAG ('A','g','h','b'), /*7.0*/ HB_SCRIPT_DUPLOYAN = HB_TAG ('D','u','p','l'), @@ -296,6 +299,13 @@ typedef enum /*7.0*/ HB_SCRIPT_TIRHUTA = HB_TAG ('T','i','r','h'), /*7.0*/ HB_SCRIPT_WARANG_CITI = HB_TAG ('W','a','r','a'), + /*8.0*/ HB_SCRIPT_AHOM = HB_TAG ('A','h','o','m'), + /*8.0*/ HB_SCRIPT_ANATOLIAN_HIEROGLYPHS = HB_TAG ('H','l','u','w'), + /*8.0*/ HB_SCRIPT_HATRAN = HB_TAG ('H','a','t','r'), + /*8.0*/ HB_SCRIPT_MULTANI = HB_TAG ('M','u','l','t'), + /*8.0*/ HB_SCRIPT_OLD_HUNGARIAN = HB_TAG ('H','u','n','g'), + /*8.0*/ HB_SCRIPT_SIGNWRITING = HB_TAG ('S','g','n','w'), + /* No script set. */ HB_SCRIPT_INVALID = HB_TAG_NONE, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc index ab9e1d4a93..13ba5d94ef 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc @@ -38,19 +38,6 @@ #endif -typedef bool (*qt_get_font_table_func_t) (void *user_data, unsigned int tag, unsigned char *buffer, unsigned int *length); - -struct FontEngineFaceData { - void *user_data; - qt_get_font_table_func_t get_font_table; -}; - -struct CoreTextFontEngineData { - CTFontRef ctFont; - CGFontRef cgFont; -}; - - static void release_table_data (void *user_data) { @@ -104,7 +91,7 @@ hb_coretext_shaper_face_data_t * _hb_coretext_shaper_face_data_create (hb_face_t *face) { hb_coretext_shaper_face_data_t *data = NULL; -#if 0 + if (face->destroy == (hb_destroy_func_t) CGFontRelease) { data = CGFontRetain ((CGFontRef) face->user_data); @@ -124,11 +111,7 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face) CGDataProviderRelease (provider); } } -#else - FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; - CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; - data = CGFontRetain (coreTextFontEngineData->cgFont); -#endif + if (unlikely (!data)) { DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed"); } @@ -142,6 +125,9 @@ _hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data) CFRelease (data); } +/* + * Since: 0.9.10 + */ CGFontRef hb_coretext_face_get_cg_font (hb_face_t *face) { @@ -170,10 +156,10 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) return NULL; hb_face_t *face = font->face; -#if 0 hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face); /* Choose a CoreText font size and calculate multipliers to convert to HarfBuzz space. */ + /* TODO: use upem instead of 36? */ CGFloat font_size = 36.; /* Default... */ /* No idea if the following is even a good idea. */ if (font->y_ppem) @@ -184,12 +170,6 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font) data->x_mult = (CGFloat) font->x_scale / font_size; data->y_mult = (CGFloat) font->y_scale / font_size; data->ct_font = CTFontCreateWithGraphicsFont (face_data, font_size, NULL, NULL); -#else - data->x_mult = data->y_mult = (CGFloat) 64.0f; - FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data; - CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data; - data->ct_font = (CTFontRef) CFRetain (coreTextFontEngineData->ctFont); -#endif if (unlikely (!data->ct_font)) { DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed"); free (data); @@ -812,6 +792,17 @@ retry: buffer->len = 0; uint32_t status_and = ~0, status_or = 0; double advances_so_far = 0; + /* For right-to-left runs, CoreText returns the glyphs positioned such that + * any trailing whitespace is to the left of (0,0). Adjust coordinate system + * to fix for that. Test with any RTL string with trailing spaces. + * https://code.google.com/p/chromium/issues/detail?id=469028 + */ + if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction)) + { + advances_so_far -= CTLineGetTrailingWhitespaceWidth (line); + if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction)) + advances_so_far = -advances_so_far; + } const CFRange range_all = CFRangeMake (0, 0); @@ -827,8 +818,6 @@ retry: run_advance = -run_advance; DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance); - CFRange range = CTRunGetStringRange (run); - /* CoreText does automatic font fallback (AKA "cascading") for characters * not supported by the requested font, and provides no way to turn it off, * so we must detect if the returned run uses a font other than the requested @@ -895,6 +884,7 @@ retry: } if (!matched) { + CFRange range = CTRunGetStringRange (run); DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld", range.location, range.location + range.length); if (!buffer->ensure_inplace (buffer->len + range.length)) @@ -929,8 +919,8 @@ retry: info->cluster = log_clusters[j]; info->mask = advance; - info->var1.u32 = x_offset; - info->var2.u32 = y_offset; + info->var1.i32 = x_offset; + info->var2.i32 = y_offset; info++; buffer->len++; @@ -946,13 +936,7 @@ retry: if (num_glyphs == 0) continue; - /* ### temporary fix for QTBUG-38113 */ - /* CoreText throws away the PDF token, while the OpenType backend will add a zero-advance - * glyph for this. We need to make sure the two produce the same output. */ - UniChar endGlyph = CFStringGetCharacterAtIndex (string_ref, range.location + range.length - 1); - bool endsWithPDF = endGlyph == 0x202c; - - if (!buffer->ensure_inplace (buffer->len + num_glyphs + (endsWithPDF ? 1 : 0))) + if (!buffer->ensure_inplace (buffer->len + num_glyphs)) goto resize_and_retry; hb_glyph_info_t *run_info = buffer->info + buffer->len; @@ -1022,8 +1006,8 @@ retry: else /* last glyph */ advance = run_advance - (positions[j].x - positions[0].x); info->mask = advance * x_mult; - info->var1.u32 = x_offset; - info->var2.u32 = positions[j].y * y_mult; + info->var1.i32 = x_offset; + info->var2.i32 = positions[j].y * y_mult; info++; } } @@ -1038,25 +1022,11 @@ retry: else /* last glyph */ advance = run_advance - (positions[j].y - positions[0].y); info->mask = advance * y_mult; - info->var1.u32 = positions[j].x * x_mult; - info->var2.u32 = y_offset; + info->var1.i32 = positions[j].x * x_mult; + info->var2.i32 = y_offset; info++; } } - if (endsWithPDF) { - /* Ensure a zero-advance glyph the PDF token */ - if (unlikely (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))) { - memmove (run_info + 1, run_info, num_glyphs * sizeof (hb_glyph_info_t)); - info = run_info; - } - info->codepoint = 0xffff; - info->cluster = log_clusters[range.location + range.length - 1]; - info->mask = 0; - info->var1.u32 = 0; - info->var2.u32 = 0; - - buffer->len++; - } SCRATCH_RESTORE(); advances_so_far += run_advance; } @@ -1068,10 +1038,20 @@ retry: buffer->len += num_glyphs; } - /* Make sure all runs had the expected direction. */ - bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); - assert (bool (status_and & kCTRunStatusRightToLeft) == backward); - assert (bool (status_or & kCTRunStatusRightToLeft) == backward); + /* Mac OS 10.6 doesn't have kCTTypesetterOptionForcedEmbeddingLevel, + * or if it does, it doesn't resepct it. So we get runs with wrong + * directions. As such, disable the assert... It wouldn't crash, but + * cursoring will be off... + * + * http://crbug.com/419769 + */ + if (0) + { + /* Make sure all runs had the expected direction. */ + bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction); + assert (bool (status_and & kCTRunStatusRightToLeft) == backward); + assert (bool (status_or & kCTRunStatusRightToLeft) == backward); + } buffer->clear_positions (); @@ -1082,16 +1062,16 @@ retry: for (unsigned int i = 0; i < count; i++) { pos->x_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; + pos->x_offset = info->var1.i32; + pos->y_offset = info->var2.i32; info++, pos++; } else for (unsigned int i = 0; i < count; i++) { pos->y_advance = info->mask; - pos->x_offset = info->var1.u32; - pos->y_offset = info->var2.u32; + pos->x_offset = info->var1.i32; + pos->y_offset = info->var2.i32; info++, pos++; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-face.cc b/src/3rdparty/harfbuzz-ng/src/hb-face.cc index 9348af7bf8..9effc41c88 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-face.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-face.cc @@ -77,7 +77,7 @@ const hb_face_t _hb_face_nil = { * * Return value: (transfer full) * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_face_create_for_tables (hb_reference_table_func_t reference_table_func, @@ -113,7 +113,7 @@ _hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index) { hb_face_for_data_closure_t *closure; - closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t)); + closure = (hb_face_for_data_closure_t *) calloc (1, sizeof (hb_face_for_data_closure_t)); if (unlikely (!closure)) return NULL; @@ -157,7 +157,7 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_face_create (hb_blob_t *blob, @@ -165,8 +165,8 @@ hb_face_create (hb_blob_t *blob, { hb_face_t *face; - if (unlikely (!blob || !hb_blob_get_length (blob))) - return hb_face_get_empty (); + if (unlikely (!blob)) + blob = hb_blob_get_empty (); hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index); @@ -189,7 +189,7 @@ hb_face_create (hb_blob_t *blob, * * Return value: (transfer full) * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_face_get_empty (void) @@ -206,7 +206,7 @@ hb_face_get_empty (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_face_reference (hb_face_t *face) @@ -220,7 +220,7 @@ hb_face_reference (hb_face_t *face) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_destroy (hb_face_t *face) @@ -257,7 +257,7 @@ hb_face_destroy (hb_face_t *face) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_face_set_user_data (hb_face_t *face, @@ -278,7 +278,7 @@ hb_face_set_user_data (hb_face_t *face, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_face_get_user_data (hb_face_t *face, @@ -293,7 +293,7 @@ hb_face_get_user_data (hb_face_t *face, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_make_immutable (hb_face_t *face) @@ -312,7 +312,7 @@ hb_face_make_immutable (hb_face_t *face) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_face_is_immutable (hb_face_t *face) @@ -330,7 +330,7 @@ hb_face_is_immutable (hb_face_t *face) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_face_reference_table (hb_face_t *face, @@ -347,7 +347,7 @@ hb_face_reference_table (hb_face_t *face, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_blob_t * hb_face_reference_blob (hb_face_t *face) @@ -362,7 +362,7 @@ hb_face_reference_blob (hb_face_t *face) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_set_index (hb_face_t *face, @@ -382,7 +382,7 @@ hb_face_set_index (hb_face_t *face, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_face_get_index (hb_face_t *face) @@ -397,7 +397,7 @@ hb_face_get_index (hb_face_t *face) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_face_set_upem (hb_face_t *face, @@ -417,7 +417,7 @@ hb_face_set_upem (hb_face_t *face, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_face_get_upem (hb_face_t *face) @@ -441,7 +441,7 @@ hb_face_t::load_upem (void) const * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_face_set_glyph_count (hb_face_t *face, @@ -461,7 +461,7 @@ hb_face_set_glyph_count (hb_face_t *face, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ unsigned int hb_face_get_glyph_count (hb_face_t *face) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh index 33bbf7143a..c05499d4c2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-font-private.hh @@ -268,7 +268,7 @@ struct hb_font_t { { *x = get_glyph_h_advance (glyph) / 2; - /* TODO use font_metics.ascent */ + /* TODO use font_metrics.ascent */ *y = y_scale; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-font.cc index d42db59855..6a69cae313 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.cc @@ -236,7 +236,7 @@ static const hb_font_funcs_t _hb_font_funcs_nil = { * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_funcs_t * hb_font_funcs_create (void) @@ -258,7 +258,7 @@ hb_font_funcs_create (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_funcs_t * hb_font_funcs_get_empty (void) @@ -274,7 +274,7 @@ hb_font_funcs_get_empty (void) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_funcs_t * hb_font_funcs_reference (hb_font_funcs_t *ffuncs) @@ -288,7 +288,7 @@ hb_font_funcs_reference (hb_font_funcs_t *ffuncs) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) @@ -315,7 +315,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, @@ -336,7 +336,7 @@ hb_font_funcs_set_user_data (hb_font_funcs_t *ffuncs, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, @@ -352,7 +352,7 @@ hb_font_funcs_get_user_data (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) @@ -371,7 +371,7 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs) @@ -425,7 +425,7 @@ HB_FONT_FUNCS_IMPLEMENT_CALLBACKS * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph (hb_font_t *font, @@ -444,7 +444,7 @@ hb_font_get_glyph (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_position_t hb_font_get_glyph_h_advance (hb_font_t *font, @@ -462,7 +462,7 @@ hb_font_get_glyph_h_advance (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_position_t hb_font_get_glyph_v_advance (hb_font_t *font, @@ -482,7 +482,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_h_origin (hb_font_t *font, @@ -503,7 +503,7 @@ hb_font_get_glyph_h_origin (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_v_origin (hb_font_t *font, @@ -523,7 +523,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_position_t hb_font_get_glyph_h_kerning (hb_font_t *font, @@ -542,7 +542,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_position_t hb_font_get_glyph_v_kerning (hb_font_t *font, @@ -561,7 +561,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_extents (hb_font_t *font, @@ -583,7 +583,7 @@ hb_font_get_glyph_extents (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_contour_point (hb_font_t *font, @@ -604,7 +604,7 @@ hb_font_get_glyph_contour_point (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_name (hb_font_t *font, @@ -625,7 +625,7 @@ hb_font_get_glyph_name (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_from_name (hb_font_t *font, @@ -648,7 +648,7 @@ hb_font_get_glyph_from_name (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_glyph_advance_for_direction (hb_font_t *font, @@ -669,7 +669,7 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_glyph_origin_for_direction (hb_font_t *font, @@ -690,7 +690,7 @@ hb_font_get_glyph_origin_for_direction (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_add_glyph_origin_for_direction (hb_font_t *font, @@ -711,7 +711,7 @@ hb_font_add_glyph_origin_for_direction (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, @@ -733,7 +733,7 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_glyph_kerning_for_direction (hb_font_t *font, @@ -755,7 +755,7 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_extents_for_origin (hb_font_t *font, @@ -779,7 +779,7 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, @@ -800,7 +800,7 @@ hb_font_get_glyph_contour_point_for_origin (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_glyph_to_string (hb_font_t *font, @@ -822,7 +822,7 @@ hb_font_glyph_to_string (hb_font_t *font, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_glyph_from_string (hb_font_t *font, @@ -845,7 +845,7 @@ hb_font_glyph_from_string (hb_font_t *font, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_create (hb_face_t *face) @@ -854,8 +854,6 @@ hb_font_create (hb_face_t *face) if (unlikely (!face)) face = hb_face_get_empty (); - if (unlikely (hb_object_is_inert (face))) - return hb_font_get_empty (); if (!(font = hb_object_create<hb_font_t> ())) return hb_font_get_empty (); @@ -863,6 +861,8 @@ hb_font_create (hb_face_t *face) font->face = hb_face_reference (face); font->klass = hb_font_funcs_get_empty (); + font->x_scale = font->y_scale = hb_face_get_upem (face); + return font; } @@ -874,20 +874,19 @@ hb_font_create (hb_face_t *face) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_create_sub_font (hb_font_t *parent) { if (unlikely (!parent)) - return hb_font_get_empty (); + parent = hb_font_get_empty (); hb_font_t *font = hb_font_create (parent->face); if (unlikely (hb_object_is_inert (font))) return font; - hb_font_make_immutable (parent); font->parent = hb_font_reference (parent); font->x_scale = parent->x_scale; @@ -905,7 +904,7 @@ hb_font_create_sub_font (hb_font_t *parent) * * Return value: (transfer full) * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_get_empty (void) @@ -946,7 +945,7 @@ hb_font_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_reference (hb_font_t *font) @@ -960,7 +959,7 @@ hb_font_reference (hb_font_t *font) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_destroy (hb_font_t *font) @@ -993,7 +992,7 @@ hb_font_destroy (hb_font_t *font) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_set_user_data (hb_font_t *font, @@ -1014,7 +1013,7 @@ hb_font_set_user_data (hb_font_t *font, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_font_get_user_data (hb_font_t *font, @@ -1029,7 +1028,7 @@ hb_font_get_user_data (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_make_immutable (hb_font_t *font) @@ -1037,6 +1036,9 @@ hb_font_make_immutable (hb_font_t *font) if (unlikely (hb_object_is_inert (font))) return; + if (font->parent) + hb_font_make_immutable (font->parent); + font->immutable = true; } @@ -1048,7 +1050,7 @@ hb_font_make_immutable (hb_font_t *font) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_font_is_immutable (hb_font_t *font) @@ -1057,6 +1059,32 @@ hb_font_is_immutable (hb_font_t *font) } /** + * hb_font_set_parent: + * @font: a font. + * @parent: new parent. + * + * Sets parent font of @font. + * + * Since: 1.0.5 + **/ +void +hb_font_set_parent (hb_font_t *font, + hb_font_t *parent) +{ + if (font->immutable) + return; + + if (!parent) + parent = hb_font_get_empty (); + + hb_font_t *old = font->parent; + + font->parent = hb_font_reference (parent); + + hb_font_destroy (old); +} + +/** * hb_font_get_parent: * @font: a font. * @@ -1064,7 +1092,7 @@ hb_font_is_immutable (hb_font_t *font) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_font_t * hb_font_get_parent (hb_font_t *font) @@ -1080,7 +1108,7 @@ hb_font_get_parent (hb_font_t *font) * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_face_t * hb_font_get_face (hb_font_t *font) @@ -1098,7 +1126,7 @@ hb_font_get_face (hb_font_t *font) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_funcs (hb_font_t *font, @@ -1133,7 +1161,7 @@ hb_font_set_funcs (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_funcs_data (hb_font_t *font, @@ -1163,7 +1191,7 @@ hb_font_set_funcs_data (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_scale (hb_font_t *font, @@ -1185,7 +1213,7 @@ hb_font_set_scale (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_scale (hb_font_t *font, @@ -1204,7 +1232,7 @@ hb_font_get_scale (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_set_ppem (hb_font_t *font, @@ -1226,7 +1254,7 @@ hb_font_set_ppem (hb_font_t *font, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_get_ppem (hb_font_t *font, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-font.h b/src/3rdparty/harfbuzz-ng/src/hb-font.h index 7273db43ed..fb4a0eab5a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-font.h @@ -80,12 +80,13 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs); /* glyph extents */ +/* Note that height is negative in coordinate systems that grow up. */ typedef struct hb_glyph_extents_t { - hb_position_t x_bearing; - hb_position_t y_bearing; - hb_position_t width; - hb_position_t height; + hb_position_t x_bearing; /* left side of glyph from origin. */ + hb_position_t y_bearing; /* top side of glyph from origin. */ + hb_position_t width; /* distance from left to right side. */ + hb_position_t height; /* distance from top to bottom side. */ } hb_glyph_extents_t; @@ -148,7 +149,7 @@ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void * * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, @@ -164,7 +165,7 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, @@ -180,7 +181,7 @@ hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, @@ -196,7 +197,7 @@ hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, @@ -212,7 +213,7 @@ hb_font_funcs_set_glyph_h_origin_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, @@ -228,7 +229,7 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, @@ -244,7 +245,7 @@ hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, @@ -260,7 +261,7 @@ hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, @@ -276,7 +277,7 @@ hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, @@ -292,7 +293,7 @@ hb_font_funcs_set_glyph_contour_point_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, @@ -308,7 +309,7 @@ hb_font_funcs_set_glyph_name_func (hb_font_funcs_t *ffuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_font_funcs_set_glyph_from_name_func (hb_font_funcs_t *ffuncs, @@ -458,6 +459,10 @@ hb_font_make_immutable (hb_font_t *font); hb_bool_t hb_font_is_immutable (hb_font_t *font); +void +hb_font_set_parent (hb_font_t *font, + hb_font_t *parent); + hb_font_t * hb_font_get_parent (hb_font_t *font); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh index a8ea39ccfd..ed2703571c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-mutex-private.hh @@ -39,7 +39,13 @@ /* We need external help for these */ -#if 0 +#if defined(HB_MUTEX_IMPL_INIT) \ + && defined(hb_mutex_impl_init) \ + && defined(hb_mutex_impl_lock) \ + && defined(hb_mutex_impl_unlock) \ + && defined(hb_mutex_impl_finish) + +/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */ #elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__)) @@ -113,10 +119,12 @@ typedef int hb_mutex_impl_t; #define hb_mutex_impl_unlock(M) HB_STMT_START {} HB_STMT_END #define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END + #endif #define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} + struct hb_mutex_t { /* TODO Add tracing. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh index 7bd0f1624b..6b73ff92d0 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-object-private.hh @@ -47,19 +47,22 @@ /* reference_count */ -#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) -#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} +#define HB_REFERENCE_COUNT_INERT_VALUE -1 +#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD +#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)} + struct hb_reference_count_t { hb_atomic_int_t ref_count; - inline void init (int v) { ref_count = v; } - inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), 1); } - inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); } - inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; } - - inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; } + inline void init (int v) { ref_count.set_unsafe (v); } + inline int get_unsafe (void) const { return ref_count.get_unsafe (); } + inline int inc (void) { return ref_count.inc (); } + inline int dec (void) { return ref_count.dec (); } + inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); } + inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; } + inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; } }; @@ -102,7 +105,7 @@ struct hb_object_header_t hb_reference_count_t ref_count; hb_user_data_array_t user_data; -#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT} +#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT} private: ASSERT_POD (); @@ -117,7 +120,7 @@ static inline void hb_object_trace (const Type *obj, const char *function) DEBUG_MSG (OBJECT, (void *) obj, "%s refcount=%d", function, - obj ? obj->header.ref_count.ref_count : 0); + obj ? obj->header.ref_count.get_unsafe () : 0); } template <typename Type> @@ -141,7 +144,12 @@ static inline void hb_object_init (Type *obj) template <typename Type> static inline bool hb_object_is_inert (const Type *obj) { - return unlikely (obj->header.ref_count.is_invalid ()); + return unlikely (obj->header.ref_count.is_inert ()); +} +template <typename Type> +static inline bool hb_object_is_valid (const Type *obj) +{ + return likely (obj->header.ref_count.is_valid ()); } template <typename Type> static inline Type *hb_object_reference (Type *obj) @@ -149,6 +157,7 @@ static inline Type *hb_object_reference (Type *obj) hb_object_trace (obj, HB_FUNC); if (unlikely (!obj || hb_object_is_inert (obj))) return obj; + assert (hb_object_is_valid (obj)); obj->header.ref_count.inc (); return obj; } @@ -158,6 +167,7 @@ static inline bool hb_object_destroy (Type *obj) hb_object_trace (obj, HB_FUNC); if (unlikely (!obj || hb_object_is_inert (obj))) return false; + assert (hb_object_is_valid (obj)); if (obj->header.ref_count.dec () != 1) return false; @@ -174,6 +184,7 @@ static inline bool hb_object_set_user_data (Type *obj, { if (unlikely (!obj || hb_object_is_inert (obj))) return false; + assert (hb_object_is_valid (obj)); return obj->header.user_data.set (key, data, destroy, replace); } @@ -183,6 +194,7 @@ static inline void *hb_object_get_user_data (Type *obj, { if (unlikely (!obj || hb_object_is_inert (obj))) return NULL; + assert (hb_object_is_valid (obj)); return obj->header.user_data.get (key); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh index 178bc7ccb8..152230a0e5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-file-private.hh @@ -56,7 +56,7 @@ typedef struct TableRecord inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } Tag tag; /* 4-byte identifier. */ @@ -106,7 +106,7 @@ typedef struct OffsetTable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); + return_trace (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables)); } protected: @@ -135,7 +135,7 @@ struct TTCHeaderVersion1 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (table.sanitize (c, this)); + return_trace (table.sanitize (c, this)); } protected: @@ -175,11 +175,11 @@ struct TTCHeader inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false); + if (unlikely (!u.header.version.sanitize (c))) return_trace (false); switch (u.header.version.major) { case 2: /* version 2 is compatible with version 1 */ - case 1: return TRACE_RETURN (u.version1.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return_trace (u.version1.sanitize (c)); + default:return_trace (true); } } @@ -240,14 +240,14 @@ struct OpenTypeFontFile inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false); + if (unlikely (!u.tag.sanitize (c))) return_trace (false); switch (u.tag) { case CFFTag: /* All the non-collection tags */ case TrueTag: case Typ1Tag: - case TrueTypeTag: return TRACE_RETURN (u.fontFace.sanitize (c)); - case TTCTag: return TRACE_RETURN (u.ttcHeader.sanitize (c)); - default: return TRACE_RETURN (true); + case TrueTypeTag: return_trace (u.fontFace.sanitize (c)); + case TTCTag: return_trace (u.ttcHeader.sanitize (c)); + default: return_trace (true); } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh index 75a0f568d1..f053502ded 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh @@ -154,6 +154,20 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) #define Null(Type) Null<Type>() +/* + * Dispatch + */ + +template <typename Context, typename Return, unsigned int MaxDebugDepth> +struct hb_dispatch_context_t +{ + static const unsigned int max_debug_depth = MaxDebugDepth; + typedef Return return_t; + template <typename T, typename F> + inline bool may_dispatch (const T *obj, const F *format) { return true; } + static return_t no_dispatch_return_value (void) { return Context::default_return_value (); } +}; + /* * Sanitize @@ -174,17 +188,23 @@ ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) #define HB_SANITIZE_MAX_EDITS 100 #endif -struct hb_sanitize_context_t +struct hb_sanitize_context_t : + hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> { + inline hb_sanitize_context_t (void) : + debug_depth (0), + start (NULL), end (NULL), + writable (false), edit_count (0), + blob (NULL) {} + inline const char *get_name (void) { return "SANITIZE"; } - static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; - typedef bool return_t; template <typename T, typename F> inline bool may_dispatch (const T *obj, const F *format) { return format->sanitize (this); } template <typename T> inline return_t dispatch (const T &obj) { return obj.sanitize (this); } static return_t default_return_value (void) { return true; } + static return_t no_dispatch_return_value (void) { return false; } bool stop_sublookup_iteration (const return_t r) const { return !r; } inline void init (hb_blob_t *b) @@ -295,7 +315,7 @@ template <typename Type> struct Sanitizer { static hb_blob_t *sanitize (hb_blob_t *blob) { - hb_sanitize_context_t c[1] = {{0, NULL, NULL, false, 0, NULL}}; + hb_sanitize_context_t c[1]; bool sane; /* TODO is_sane() stuff */ @@ -379,9 +399,9 @@ struct Sanitizer struct hb_serialize_context_t { - inline hb_serialize_context_t (void *start, unsigned int size) + inline hb_serialize_context_t (void *start_, unsigned int size) { - this->start = (char *) start; + this->start = (char *) start_; this->end = this->start + size; this->ran_out_of_room = false; @@ -475,10 +495,10 @@ struct hb_serialize_context_t return reinterpret_cast<Type *> (&obj); } - inline void truncate (void *head) + inline void truncate (void *new_head) { - assert (this->start < head && head <= this->head); - this->head = (char *) head; + assert (this->start < new_head && new_head <= this->head); + this->head = (char *) new_head; } unsigned int debug_depth; @@ -536,6 +556,20 @@ struct Supplier template <typename Type, int Bytes> struct BEInt; template <typename Type> +struct BEInt<Type, 1> +{ + public: + inline void set (Type V) + { + v = V; + } + inline operator Type (void) const + { + return v; + } + private: uint8_t v; +}; +template <typename Type> struct BEInt<Type, 2> { public: @@ -610,7 +644,7 @@ struct IntType inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (likely (c->check_struct (this))); + return_trace (likely (c->check_struct (this))); } protected: BEInt<Type, Size> v; @@ -618,7 +652,7 @@ struct IntType DEFINE_SIZE_STATIC (Size); }; -typedef uint8_t BYTE; /* 8-bit unsigned integer. */ +typedef IntType<uint8_t , 1> BYTE; /* 8-bit unsigned integer. */ typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ @@ -638,7 +672,7 @@ struct LONGDATETIME inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (likely (c->check_struct (this))); + return_trace (likely (c->check_struct (this))); } protected: LONG major; @@ -715,7 +749,7 @@ struct FixedVersion inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } USHORT major; @@ -751,21 +785,21 @@ struct OffsetTo : Offset<OffsetType> inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); + if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; - if (unlikely (!offset)) return TRACE_RETURN (true); + if (unlikely (!offset)) return_trace (true); const Type &obj = StructAtOffset<Type> (base, offset); - return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); + return_trace (likely (obj.sanitize (c)) || neuter (c)); } template <typename T> inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); + if (unlikely (!c->check_struct (this))) return_trace (false); unsigned int offset = *this; - if (unlikely (!offset)) return TRACE_RETURN (true); + if (unlikely (!offset)) return_trace (true); const Type &obj = StructAtOffset<Type> (base, offset); - return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); + return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); } /* Set the offset to Null */ @@ -816,10 +850,10 @@ struct ArrayOf unsigned int items_len) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); len.set (items_len); /* TODO(serialize) Overflow? */ - if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (unlikely (!c->extend (*this))) return_trace (false); + return_trace (true); } inline bool serialize (hb_serialize_context_t *c, @@ -827,17 +861,17 @@ struct ArrayOf unsigned int items_len) { TRACE_SERIALIZE (this); - if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false); + if (unlikely (!serialize (c, items_len))) return_trace (false); for (unsigned int i = 0; i < items_len; i++) array[i] = items[i]; items.advance (items_len); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); + if (unlikely (!sanitize_shallow (c))) return_trace (false); /* Note: for structs that do not reference other structs, * we do not need to call their sanitize() as we already did @@ -848,28 +882,28 @@ struct ArrayOf */ (void) (false && array[0].sanitize (c)); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); + if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!array[i].sanitize (c, base))) - return TRACE_RETURN (false); - return TRACE_RETURN (true); + return_trace (false); + return_trace (true); } template <typename T> inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); + if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) if (unlikely (!array[i].sanitize (c, base, user_data))) - return TRACE_RETURN (false); - return TRACE_RETURN (true); + return_trace (false); + return_trace (true); } template <typename SearchType> @@ -886,7 +920,7 @@ struct ArrayOf inline bool sanitize_shallow (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len)); + return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len)); } public: @@ -913,13 +947,13 @@ struct OffsetListOf : OffsetArrayOf<Type> inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this)); + return_trace (OffsetArrayOf<Type>::sanitize (c, this)); } template <typename T> inline bool sanitize (hb_sanitize_context_t *c, T user_data) const { TRACE_SANITIZE (this); - return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data)); + return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data)); } }; @@ -941,14 +975,14 @@ struct HeadlessArrayOf unsigned int items_len) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); len.set (items_len); /* TODO(serialize) Overflow? */ - if (unlikely (!items_len)) return TRACE_RETURN (true); - if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); + if (unlikely (!items_len)) return_trace (true); + if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items_len - 1; i++) array[i] = items[i]; items.advance (items_len - 1); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize_shallow (hb_sanitize_context_t *c) const @@ -960,7 +994,7 @@ struct HeadlessArrayOf inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); + if (unlikely (!sanitize_shallow (c))) return_trace (false); /* Note: for structs that do not reference other structs, * we do not need to call their sanitize() as we already did @@ -971,7 +1005,7 @@ struct HeadlessArrayOf */ (void) (false && array[0].sanitize (c)); - return TRACE_RETURN (true); + return_trace (true); } LenType len; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh index 0482312553..c9161f0ef4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cmap-table.hh @@ -54,7 +54,7 @@ struct CmapSubtableFormat0 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } protected: @@ -130,7 +130,7 @@ struct CmapSubtableFormat4 { TRACE_SANITIZE (this); if (unlikely (!c->check_struct (this))) - return TRACE_RETURN (false); + return_trace (false); if (unlikely (!c->check_range (this, length))) { @@ -141,10 +141,10 @@ struct CmapSubtableFormat4 (uintptr_t) (c->end - (char *) this)); if (!c->try_set (&length, new_length)) - return TRACE_RETURN (false); + return_trace (false); } - return TRACE_RETURN (16 + 4 * (unsigned int) segCountX2 <= length); + return_trace (16 + 4 * (unsigned int) segCountX2 <= length); } protected: @@ -187,7 +187,7 @@ struct CmapSubtableLongGroup inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } private: @@ -215,7 +215,7 @@ struct CmapSubtableTrimmed inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c)); + return_trace (c->check_struct (this) && glyphIdArray.sanitize (c)); } protected: @@ -248,7 +248,7 @@ struct CmapSubtableLongSegmented inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c)); + return_trace (c->check_struct (this) && groups.sanitize (c)); } protected: @@ -295,7 +295,7 @@ struct UnicodeValueRange inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } UINT24 startUnicodeValue; /* First value in this range. */ @@ -317,7 +317,7 @@ struct UVSMapping inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } UINT24 unicodeValue; /* Base Unicode value of the UVS */ @@ -357,9 +357,9 @@ struct VariationSelectorRecord inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - defaultUVS.sanitize (c, base) && - nonDefaultUVS.sanitize (c, base)); + return_trace (c->check_struct (this) && + defaultUVS.sanitize (c, base) && + nonDefaultUVS.sanitize (c, base)); } UINT24 varSelector; /* Variation selector. */ @@ -383,8 +383,8 @@ struct CmapSubtableFormat14 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - record.sanitize (c, this)); + return_trace (c->check_struct (this) && + record.sanitize (c, this)); } protected: @@ -429,16 +429,16 @@ struct CmapSubtable inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { - case 0: return TRACE_RETURN (u.format0 .sanitize (c)); - case 4: return TRACE_RETURN (u.format4 .sanitize (c)); - case 6: return TRACE_RETURN (u.format6 .sanitize (c)); - case 10: return TRACE_RETURN (u.format10.sanitize (c)); - case 12: return TRACE_RETURN (u.format12.sanitize (c)); - case 13: return TRACE_RETURN (u.format13.sanitize (c)); - case 14: return TRACE_RETURN (u.format14.sanitize (c)); - default:return TRACE_RETURN (true); + case 0: return_trace (u.format0 .sanitize (c)); + case 4: return_trace (u.format4 .sanitize (c)); + case 6: return_trace (u.format6 .sanitize (c)); + case 10: return_trace (u.format10.sanitize (c)); + case 12: return_trace (u.format12.sanitize (c)); + case 13: return_trace (u.format13.sanitize (c)); + case 14: return_trace (u.format14.sanitize (c)); + default:return_trace (true); } } @@ -473,8 +473,8 @@ struct EncodingRecord inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - subtable.sanitize (c, base)); + return_trace (c->check_struct (this) && + subtable.sanitize (c, base)); } USHORT platformID; /* Platform ID. */ @@ -509,9 +509,9 @@ struct cmap inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - likely (version == 0) && - encodingRecord.sanitize (c, this)); + return_trace (c->check_struct (this) && + likely (version == 0) && + encodingRecord.sanitize (c, this)); } USHORT version; /* Table version number (0). */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc index 2af2f54a75..69d2503abb 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc @@ -31,6 +31,8 @@ #include "hb-font-private.hh" #include "hb-ot-cmap-table.hh" +#include "hb-ot-glyf-table.hh" +#include "hb-ot-head-table.hh" #include "hb-ot-hhea-table.hh" #include "hb-ot-hmtx-table.hh" @@ -45,9 +47,9 @@ struct hb_ot_face_metrics_accelerator_t inline void init (hb_face_t *face, hb_tag_t _hea_tag, hb_tag_t _mtx_tag, - unsigned int default_advance) + unsigned int default_advance_) { - this->default_advance = default_advance; + this->default_advance = default_advance_; this->num_metrics = face->get_num_glyphs (); hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag)); @@ -57,7 +59,7 @@ struct hb_ot_face_metrics_accelerator_t this->blob = OT::Sanitizer<OT::_mtx>::sanitize (face->reference_table (_mtx_tag)); if (unlikely (!this->num_advances || - 2 * (this->num_advances + this->num_metrics) < hb_blob_get_length (this->blob))) + 2 * (this->num_advances + this->num_metrics) > hb_blob_get_length (this->blob))) { this->num_metrics = this->num_advances = 0; hb_blob_destroy (this->blob); @@ -76,8 +78,8 @@ struct hb_ot_face_metrics_accelerator_t if (unlikely (glyph >= this->num_metrics)) { /* If this->num_metrics is zero, it means we don't have the metrics table - * for this direction: return one EM. Otherwise, it means that the glyph - * index is out of bound: return zero. */ + * for this direction: return default advance. Otherwise, it means that the + * glyph index is out of bound: return zero. */ if (this->num_metrics) return 0; else @@ -91,6 +93,79 @@ struct hb_ot_face_metrics_accelerator_t } }; +struct hb_ot_face_glyf_accelerator_t +{ + bool short_offset; + unsigned int num_glyphs; + const OT::loca *loca; + const OT::glyf *glyf; + hb_blob_t *loca_blob; + hb_blob_t *glyf_blob; + unsigned int glyf_len; + + inline void init (hb_face_t *face) + { + hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (face->reference_table (HB_OT_TAG_head)); + const OT::head *head = OT::Sanitizer<OT::head>::lock_instance (head_blob); + if ((unsigned int) head->indexToLocFormat > 1 || head->glyphDataFormat != 0) + { + /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + hb_blob_destroy (head_blob); + return; + } + this->short_offset = 0 == head->indexToLocFormat; + hb_blob_destroy (head_blob); + + this->loca_blob = OT::Sanitizer<OT::loca>::sanitize (face->reference_table (HB_OT_TAG_loca)); + this->loca = OT::Sanitizer<OT::loca>::lock_instance (this->loca_blob); + this->glyf_blob = OT::Sanitizer<OT::glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf)); + this->glyf = OT::Sanitizer<OT::glyf>::lock_instance (this->glyf_blob); + + this->num_glyphs = MAX (1u, hb_blob_get_length (this->loca_blob) / (this->short_offset ? 2 : 4)) - 1; + this->glyf_len = hb_blob_get_length (this->glyf_blob); + } + + inline void fini (void) + { + hb_blob_destroy (this->loca_blob); + hb_blob_destroy (this->glyf_blob); + } + + inline bool get_extents (hb_codepoint_t glyph, + hb_glyph_extents_t *extents) const + { + if (unlikely (glyph >= this->num_glyphs)) + return false; + + unsigned int start_offset, end_offset; + if (this->short_offset) + { + start_offset = 2 * this->loca->u.shortsZ[glyph]; + end_offset = 2 * this->loca->u.shortsZ[glyph + 1]; + } + else + { + start_offset = this->loca->u.longsZ[glyph]; + end_offset = this->loca->u.longsZ[glyph + 1]; + } + + if (start_offset > end_offset || end_offset > this->glyf_len) + return false; + + if (end_offset - start_offset < OT::glyfGlyphHeader::static_size) + return true; /* Empty glyph; zero extents. */ + + const OT::glyfGlyphHeader &glyph_header = OT::StructAtOffset<OT::glyfGlyphHeader> (this->glyf, start_offset); + + extents->x_bearing = MIN (glyph_header.xMin, glyph_header.xMax); + extents->y_bearing = MAX (glyph_header.yMin, glyph_header.yMax); + extents->width = MAX (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing; + extents->height = MIN (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing; + + return true; + } +}; + struct hb_ot_face_cmap_accelerator_t { const OT::CmapSubtable *table; @@ -114,6 +189,7 @@ struct hb_ot_face_cmap_accelerator_t if (!subtable) subtable = cmap->find_subtable (0, 2); if (!subtable) subtable = cmap->find_subtable (0, 1); if (!subtable) subtable = cmap->find_subtable (0, 0); + if (!subtable) subtable = cmap->find_subtable (3, 0); /* Meh. */ if (!subtable) subtable = &OT::Null(OT::CmapSubtable); @@ -157,14 +233,14 @@ struct hb_ot_font_t hb_ot_face_cmap_accelerator_t cmap; hb_ot_face_metrics_accelerator_t h_metrics; hb_ot_face_metrics_accelerator_t v_metrics; + hb_ot_face_glyf_accelerator_t glyf; }; static hb_ot_font_t * -_hb_ot_font_create (hb_font_t *font) +_hb_ot_font_create (hb_face_t *face) { hb_ot_font_t *ot_font = (hb_ot_font_t *) calloc (1, sizeof (hb_ot_font_t)); - hb_face_t *face = font->face; if (unlikely (!ot_font)) return NULL; @@ -174,6 +250,7 @@ _hb_ot_font_create (hb_font_t *font) ot_font->cmap.init (face); ot_font->h_metrics.init (face, HB_OT_TAG_hhea, HB_OT_TAG_hmtx, upem>>1); ot_font->v_metrics.init (face, HB_OT_TAG_vhea, HB_OT_TAG_vmtx, upem); /* TODO Can we do this lazily? */ + ot_font->glyf.init (face); return ot_font; } @@ -184,6 +261,7 @@ _hb_ot_font_destroy (hb_ot_font_t *ot_font) ot_font->cmap.fini (); ot_font->h_metrics.fini (); ot_font->v_metrics.fini (); + ot_font->glyf.fini (); free (ot_font); } @@ -219,7 +297,7 @@ hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED, void *user_data HB_UNUSED) { const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; - return font->em_scale_y (-ot_font->v_metrics.get_advance (glyph)); + return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph)); } static hb_bool_t @@ -275,8 +353,13 @@ hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED, hb_glyph_extents_t *extents, void *user_data HB_UNUSED) { - /* TODO */ - return false; + const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data; + bool ret = ot_font->glyf.get_extents (glyph, extents); + extents->x_bearing = font->em_scale_x (extents->x_bearing); + extents->y_bearing = font->em_scale_y (extents->y_bearing); + extents->width = font->em_scale_x (extents->width); + extents->height = font->em_scale_y (extents->height); + return ret; } static hb_bool_t @@ -334,10 +417,13 @@ _hb_ot_get_font_funcs (void) } +/** + * Since: 0.9.28 + **/ void hb_ot_font_set_funcs (hb_font_t *font) { - hb_ot_font_t *ot_font = _hb_ot_font_create (font); + hb_ot_font_t *ot_font = _hb_ot_font_create (font->face); if (unlikely (!ot_font)) return; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h index 7a8c04ac33..b9947a16bc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.h @@ -24,6 +24,10 @@ * Google Author(s): Behdad Esfahbod, Roozbeh Pournader */ +#ifndef HB_OT_H_IN +#error "Include <hb-ot.h> instead." +#endif + #ifndef HB_OT_FONT_H #define HB_OT_FONT_H diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh new file mode 100644 index 0000000000..9e5af6d10d --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-glyf-table.hh @@ -0,0 +1,104 @@ +/* + * Copyright © 2015 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_GLYF_TABLE_HH +#define HB_OT_GLYF_TABLE_HH + +#include "hb-open-type-private.hh" + + +namespace OT { + + +/* + * loca -- Index to Location + */ + +#define HB_OT_TAG_loca HB_TAG('l','o','c','a') + + +struct loca +{ + static const hb_tag_t tableTag = HB_OT_TAG_loca; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (true); + } + + public: + union { + USHORT shortsZ[VAR]; /* Location offset divided by 2. */ + ULONG longsZ[VAR]; /* Location offset. */ + } u; + DEFINE_SIZE_ARRAY (0, u.longsZ); +}; + + +/* + * glyf -- TrueType Glyph Data + */ + +#define HB_OT_TAG_glyf HB_TAG('g','l','y','f') + + +struct glyf +{ + static const hb_tag_t tableTag = HB_OT_TAG_glyf; + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + /* We don't check for anything specific here. The users of the + * struct do all the hard work... */ + return_trace (true); + } + + public: + BYTE dataX[VAR]; /* Glyphs data. */ + + DEFINE_SIZE_ARRAY (0, dataX); +}; + +struct glyfGlyphHeader +{ + SHORT numberOfContours; /* If the number of contours is + * greater than or equal to zero, + * this is a simple glyph; if negative, + * this is a composite glyph. */ + SHORT xMin; /* Minimum x for coordinate data. */ + SHORT yMin; /* Minimum y for coordinate data. */ + SHORT xMax; /* Maximum x for coordinate data. */ + SHORT yMax; /* Maximum y for coordinate data. */ + + DEFINE_SIZE_STATIC (10); +}; + +} /* namespace OT */ + + +#endif /* HB_OT_GLYF_TABLE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh index 268f133408..fc351cfb48 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-head-table.hh @@ -55,7 +55,7 @@ struct head inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && likely (version.major == 1)); } protected: @@ -138,9 +138,10 @@ struct head * 2: Like 1 but also contains neutrals; * -1: Only strongly right to left; * -2: Like -1 but also contains neutrals. */ + public: SHORT indexToLocFormat; /* 0 for short offsets, 1 for long. */ SHORT glyphDataFormat; /* 0 for current format. */ - public: + DEFINE_SIZE_STATIC (54); }; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh index 992fe55202..24114534a7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hhea-table.hh @@ -52,7 +52,7 @@ struct _hea inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1)); + return_trace (c->check_struct (this) && likely (version.major == 1)); } public: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh index a0e3855a84..49056e6769 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-hmtx-table.hh @@ -62,7 +62,7 @@ struct _mtx TRACE_SANITIZE (this); /* We don't check for anything specific here. The users of the * struct do all the hard work... */ - return TRACE_RETURN (true); + return_trace (true); } public: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh index 3db7f57ab4..ea61f5c1bd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common-private.hh @@ -44,7 +44,7 @@ namespace OT { #define NOT_COVERED ((unsigned int) -1) -#define MAX_NESTING_LEVEL 8 +#define MAX_NESTING_LEVEL 6 #define MAX_CONTEXT_LENGTH 64 @@ -75,7 +75,7 @@ struct Record { TRACE_SANITIZE (this); const sanitize_closure_t closure = {tag, base}; - return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure)); + return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure)); } Tag tag; /* 4-byte Tag identifier */ @@ -131,7 +131,7 @@ struct RecordListOf : RecordArrayOf<Type> inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); + return_trace (RecordArrayOf<Type>::sanitize (c, this)); } }; @@ -145,7 +145,7 @@ struct RangeRecord inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } inline bool intersects (const hb_set_t *glyphs) const { @@ -211,7 +211,7 @@ struct LangSys const Record<LangSys>::sanitize_closure_t * = NULL) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); + return_trace (c->check_struct (this) && featureIndex.sanitize (c)); } Offset<> lookupOrderZ; /* = Null (reserved for an offset to a @@ -251,7 +251,7 @@ struct Script const Record<Script>::sanitize_closure_t * = NULL) const { TRACE_SANITIZE (this); - return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); + return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); } protected: @@ -274,7 +274,7 @@ struct FeatureParamsSize inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); + if (unlikely (!c->check_struct (this))) return_trace (false); /* This subtable has some "history", if you will. Some earlier versions of * Adobe tools calculated the offset of the FeatureParams sutable from the @@ -326,19 +326,19 @@ struct FeatureParamsSize */ if (!designSize) - return TRACE_RETURN (false); + return_trace (false); else if (subfamilyID == 0 && subfamilyNameID == 0 && rangeStart == 0 && rangeEnd == 0) - return TRACE_RETURN (true); + return_trace (true); else if (designSize < rangeStart || designSize > rangeEnd || subfamilyNameID < 256 || subfamilyNameID > 32767) - return TRACE_RETURN (false); + return_trace (false); else - return TRACE_RETURN (true); + return_trace (true); } USHORT designSize; /* Represents the design size in 720/inch @@ -388,7 +388,7 @@ struct FeatureParamsStylisticSet TRACE_SANITIZE (this); /* Right now minorVersion is at zero. Which means, any table supports * the uiNameID field. */ - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } USHORT version; /* (set to 0): This corresponds to a “minor” @@ -420,8 +420,8 @@ struct FeatureParamsCharacterVariants inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - characters.sanitize (c)); + return_trace (c->check_struct (this) && + characters.sanitize (c)); } USHORT format; /* Format number is set to 0. */ @@ -462,12 +462,12 @@ struct FeatureParams { TRACE_SANITIZE (this); if (tag == HB_TAG ('s','i','z','e')) - return TRACE_RETURN (u.size.sanitize (c)); + return_trace (u.size.sanitize (c)); if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */ - return TRACE_RETURN (u.stylisticSet.sanitize (c)); + return_trace (u.stylisticSet.sanitize (c)); if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */ - return TRACE_RETURN (u.characterVariants.sanitize (c)); - return TRACE_RETURN (true); + return_trace (u.characterVariants.sanitize (c)); + return_trace (true); } inline const FeatureParamsSize& get_size_params (hb_tag_t tag) const @@ -505,7 +505,7 @@ struct Feature { TRACE_SANITIZE (this); if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c)))) - return TRACE_RETURN (false); + return_trace (false); /* Some earlier versions of Adobe tools calculated the offset of the * FeatureParams subtable from the beginning of the FeatureList table! @@ -520,10 +520,10 @@ struct Feature OffsetTo<FeatureParams> orig_offset = featureParams; if (unlikely (!featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE))) - return TRACE_RETURN (false); + return_trace (false); if (likely (orig_offset.is_null ())) - return TRACE_RETURN (true); + return_trace (true); if (featureParams == 0 && closure && closure->tag == HB_TAG ('s','i','z','e') && @@ -538,10 +538,10 @@ struct Feature if (new_offset == new_offset_int && c->try_set (&featureParams, new_offset) && !featureParams.sanitize (c, this, closure ? closure->tag : HB_TAG_NONE)) - return TRACE_RETURN (false); + return_trace (false); } - return TRACE_RETURN (true); + return_trace (true); } OffsetTo<FeatureParams> @@ -613,9 +613,9 @@ struct Lookup for (unsigned int i = 0; i < count; i++) { typename context_t::return_t r = get_subtable<SubTableType> (i).dispatch (c, lookup_type); if (c->stop_sublookup_iteration (r)) - return TRACE_RETURN (r); + return_trace (r); } - return TRACE_RETURN (c->default_return_value ()); + return_trace (c->default_return_value ()); } inline bool serialize (hb_serialize_context_t *c, @@ -624,29 +624,29 @@ struct Lookup unsigned int num_subtables) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); lookupType.set (lookup_type); lookupFlag.set (lookup_props & 0xFFFFu); - if (unlikely (!subTable.serialize (c, num_subtables))) return TRACE_RETURN (false); + if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { USHORT &markFilteringSet = StructAfter<USHORT> (subTable); markFilteringSet.set (lookup_props >> 16); } - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); /* Real sanitize of the subtables is done by GSUB/GPOS/... */ - if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false); + if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); if (lookupFlag & LookupFlag::UseMarkFilteringSet) { const USHORT &markFilteringSet = StructAfter<USHORT> (subTable); - if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); + if (!markFilteringSet.sanitize (c)) return_trace (false); } - return TRACE_RETURN (true); + return_trace (true); } private: @@ -685,19 +685,19 @@ struct CoverageFormat1 unsigned int num_glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); glyphArray.len.set (num_glyphs); - if (unlikely (!c->extend (glyphArray))) return TRACE_RETURN (false); + if (unlikely (!c->extend (glyphArray))) return_trace (false); for (unsigned int i = 0; i < num_glyphs; i++) glyphArray[i] = glyphs[i]; glyphs.advance (num_glyphs); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (glyphArray.sanitize (c)); + return_trace (glyphArray.sanitize (c)); } inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { @@ -754,16 +754,16 @@ struct CoverageFormat2 unsigned int num_glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); - if (unlikely (!num_glyphs)) return TRACE_RETURN (true); + if (unlikely (!num_glyphs)) return_trace (true); unsigned int num_ranges = 1; for (unsigned int i = 1; i < num_glyphs; i++) if (glyphs[i - 1] + 1 != glyphs[i]) num_ranges++; rangeRecord.len.set (num_ranges); - if (unlikely (!c->extend (rangeRecord))) return TRACE_RETURN (false); + if (unlikely (!c->extend (rangeRecord))) return_trace (false); unsigned int range = 0; rangeRecord[range].start = glyphs[0]; @@ -778,13 +778,13 @@ struct CoverageFormat2 rangeRecord[range].end = glyphs[i]; } glyphs.advance (num_glyphs); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (rangeRecord.sanitize (c)); + return_trace (rangeRecord.sanitize (c)); } inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { @@ -864,27 +864,27 @@ struct Coverage unsigned int num_glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); unsigned int num_ranges = 1; for (unsigned int i = 1; i < num_glyphs; i++) if (glyphs[i - 1] + 1 != glyphs[i]) num_ranges++; u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs)); - case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, num_glyphs)); - default:return TRACE_RETURN (false); + case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs)); + case 2: return_trace (u.format2.serialize (c, glyphs, num_glyphs)); + default:return_trace (false); } } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + default:return_trace (true); } } @@ -993,7 +993,7 @@ struct ClassDefFormat1 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); + return_trace (c->check_struct (this) && classValue.sanitize (c)); } template <typename set_t> @@ -1050,7 +1050,7 @@ struct ClassDefFormat2 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (rangeRecord.sanitize (c)); + return_trace (rangeRecord.sanitize (c)); } template <typename set_t> @@ -1108,11 +1108,11 @@ struct ClassDef inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + default:return_trace (true); } } @@ -1201,7 +1201,7 @@ struct Device inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ())); + return_trace (c->check_struct (this) && c->check_range (this, this->get_size ())); } protected: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh index 7a6c04d170..bc36436be7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gdef-table.hh @@ -74,7 +74,7 @@ struct AttachList inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this)); } protected: @@ -105,7 +105,7 @@ struct CaretValueFormat1 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } protected: @@ -132,7 +132,7 @@ struct CaretValueFormat2 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } protected: @@ -156,7 +156,7 @@ struct CaretValueFormat3 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this)); + return_trace (c->check_struct (this) && deviceTable.sanitize (c, this)); } protected: @@ -185,12 +185,12 @@ struct CaretValue inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - case 3: return TRACE_RETURN (u.format3.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); + default:return_trace (true); } } @@ -227,7 +227,7 @@ struct LigGlyph inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (carets.sanitize (c, this)); + return_trace (carets.sanitize (c, this)); } protected: @@ -262,7 +262,7 @@ struct LigCaretList inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this)); } protected: @@ -285,7 +285,7 @@ struct MarkGlyphSetsFormat1 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this)); + return_trace (coverage.sanitize (c, this)); } protected: @@ -310,10 +310,10 @@ struct MarkGlyphSets inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return_trace (u.format1.sanitize (c)); + default:return_trace (true); } } @@ -376,13 +376,13 @@ struct GDEF inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (version.sanitize (c) && - likely (version.major == 1) && - glyphClassDef.sanitize (c, this) && - attachList.sanitize (c, this) && - ligCaretList.sanitize (c, this) && - markAttachClassDef.sanitize (c, this) && - (version.to_int () < 0x00010002u || markGlyphSetsDef[0].sanitize (c, this))); + return_trace (version.sanitize (c) && + likely (version.major == 1) && + glyphClassDef.sanitize (c, this) && + attachList.sanitize (c, this) && + ligCaretList.sanitize (c, this) && + markAttachClassDef.sanitize (c, this) && + (version.to_int () < 0x00010002u || markGlyphSetsDef[0].sanitize (c, this))); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh index d88f7876e0..568b5f63a9 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gpos-table.hh @@ -181,7 +181,7 @@ struct ValueFormat : USHORT inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); + return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values))); } inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const @@ -189,17 +189,17 @@ struct ValueFormat : USHORT TRACE_SANITIZE (this); unsigned int len = get_len (); - if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false); + if (!c->check_array (values, get_size (), count)) return_trace (false); - if (!has_device ()) return TRACE_RETURN (true); + if (!has_device ()) return_trace (true); for (unsigned int i = 0; i < count; i++) { if (!sanitize_value_devices (c, base, values)) - return TRACE_RETURN (false); + return_trace (false); values += len; } - return TRACE_RETURN (true); + return_trace (true); } /* Just sanitize referenced Device tables. Doesn't check the values themselves. */ @@ -207,15 +207,15 @@ struct ValueFormat : USHORT { TRACE_SANITIZE (this); - if (!has_device ()) return TRACE_RETURN (true); + if (!has_device ()) return_trace (true); for (unsigned int i = 0; i < count; i++) { if (!sanitize_value_devices (c, base, values)) - return TRACE_RETURN (false); + return_trace (false); values += stride; } - return TRACE_RETURN (true); + return_trace (true); } }; @@ -232,7 +232,7 @@ struct AnchorFormat1 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } protected: @@ -262,7 +262,7 @@ struct AnchorFormat2 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } protected: @@ -291,7 +291,7 @@ struct AnchorFormat3 inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); + return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); } protected: @@ -327,12 +327,12 @@ struct Anchor inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return TRACE_RETURN (false); + if (!u.format.sanitize (c)) return_trace (false); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.sanitize (c)); - case 2: return TRACE_RETURN (u.format2.sanitize (c)); - case 3: return TRACE_RETURN (u.format3.sanitize (c)); - default:return TRACE_RETURN (true); + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); + case 3: return_trace (u.format3.sanitize (c)); + default:return_trace (true); } } @@ -360,13 +360,13 @@ struct AnchorMatrix inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const { TRACE_SANITIZE (this); - if (!c->check_struct (this)) return TRACE_RETURN (false); - if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false); + if (!c->check_struct (this)) return_trace (false); + if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return_trace (false); unsigned int count = rows * cols; - if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return TRACE_RETURN (false); + if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (!matrixZ[i].sanitize (c, this)) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (!matrixZ[i].sanitize (c, this)) return_trace (false); + return_trace (true); } USHORT rows; /* Number of rows */ @@ -386,7 +386,7 @@ struct MarkRecord inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base)); + return_trace (c->check_struct (this) && markAnchor.sanitize (c, base)); } protected: @@ -415,7 +415,7 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found); /* If this subtable doesn't have an anchor for this base and this class, * return false such that the subsequent subtables have a chance at it. */ - if (unlikely (!found)) return TRACE_RETURN (false); + if (unlikely (!found)) return_trace (false); hb_position_t mark_x, mark_y, base_x, base_y; @@ -428,13 +428,13 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde o.attach_lookback() = buffer->idx - glyph_pos; buffer->idx++; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this)); + return_trace (ArrayOf<MarkRecord>::sanitize (c, this)); } }; @@ -459,21 +459,21 @@ struct SinglePosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); valueFormat.apply_value (c->font, c->direction, this, values, buffer->cur_pos()); buffer->idx++; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) - && coverage.sanitize (c, this) - && valueFormat.sanitize_value (c, this, values)); + return_trace (c->check_struct (this) && + coverage.sanitize (c, this) && + valueFormat.sanitize_value (c, this, values)); } protected: @@ -508,24 +508,24 @@ struct SinglePosFormat2 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); - if (likely (index >= valueCount)) return TRACE_RETURN (false); + if (likely (index >= valueCount)) return_trace (false); valueFormat.apply_value (c->font, c->direction, this, &values[index * valueFormat.get_len ()], buffer->cur_pos()); buffer->idx++; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) - && coverage.sanitize (c, this) - && valueFormat.sanitize_values (c, this, values, valueCount)); + return_trace (c->check_struct (this) && + coverage.sanitize (c, this) && + valueFormat.sanitize_values (c, this, values, valueCount)); } protected: @@ -548,11 +548,11 @@ struct SinglePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - case 2: return TRACE_RETURN (c->dispatch (u.format2)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + case 2: return_trace (c->dispatch (u.format2)); + default:return_trace (c->default_return_value ()); } } @@ -615,7 +615,7 @@ struct PairSet /* Hand-coded bsearch. */ if (unlikely (!count)) - return TRACE_RETURN (false); + return_trace (false); hb_codepoint_t x = buffer->info[pos].codepoint; int min = 0, max = (int) count - 1; while (min <= max) @@ -636,11 +636,11 @@ struct PairSet if (len2) pos++; buffer->idx = pos; - return TRACE_RETURN (true); + return_trace (true); } } - return TRACE_RETURN (false); + return_trace (false); } struct sanitize_closure_t { @@ -654,12 +654,12 @@ struct PairSet { TRACE_SANITIZE (this); if (!(c->check_struct (this) - && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false); + && c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return_trace (false); unsigned int count = len; const PairValueRecord *record = CastP<PairValueRecord> (arrayZ); - return TRACE_RETURN (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) - && closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); + return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) && + closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride)); } protected: @@ -691,19 +691,21 @@ struct PairPosFormat1 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); - if (!skippy_iter.next ()) return TRACE_RETURN (false); + if (!skippy_iter.next ()) return_trace (false); - return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); + return_trace ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); + if (!c->check_struct (this)) return_trace (false); + unsigned int len1 = valueFormat1.get_len (); unsigned int len2 = valueFormat2.get_len (); PairSet::sanitize_closure_t closure = { @@ -713,7 +715,7 @@ struct PairPosFormat1 1 + len1 + len2 }; - return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); + return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); } protected: @@ -762,11 +764,11 @@ struct PairPosFormat2 TRACE_APPLY (this); hb_buffer_t *buffer = c->buffer; unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); - if (!skippy_iter.next ()) return TRACE_RETURN (false); + if (!skippy_iter.next ()) return_trace (false); unsigned int len1 = valueFormat1.get_len (); unsigned int len2 = valueFormat2.get_len (); @@ -774,7 +776,7 @@ struct PairPosFormat2 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); + if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; valueFormat1.apply_value (c->font, c->direction, this, @@ -786,7 +788,7 @@ struct PairPosFormat2 if (len2) buffer->idx++; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -795,16 +797,16 @@ struct PairPosFormat2 if (!(c->check_struct (this) && coverage.sanitize (c, this) && classDef1.sanitize (c, this) - && classDef2.sanitize (c, this))) return TRACE_RETURN (false); + && classDef2.sanitize (c, this))) return_trace (false); unsigned int len1 = valueFormat1.get_len (); unsigned int len2 = valueFormat2.get_len (); unsigned int stride = len1 + len2; unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size (); unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count; - return TRACE_RETURN (c->check_array (values, record_size, count) && - valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && - valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); + return_trace (c->check_array (values, record_size, count) && + valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) && + valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride)); } protected: @@ -843,11 +845,11 @@ struct PairPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - case 2: return TRACE_RETURN (c->dispatch (u.format2)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + case 2: return_trace (c->dispatch (u.format2)); + default:return_trace (c->default_return_value ()); } } @@ -867,7 +869,7 @@ struct EntryExitRecord inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); - return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); + return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base)); } protected: @@ -883,6 +885,9 @@ struct EntryExitRecord DEFINE_SIZE_STATIC (4); }; +static void +reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent); + struct CursivePosFormat1 { inline void collect_glyphs (hb_collect_glyphs_context_t *c) const @@ -902,17 +907,17 @@ struct CursivePosFormat1 hb_buffer_t *buffer = c->buffer; /* We don't handle mark glyphs here. */ - if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return TRACE_RETURN (false); + if (unlikely (_hb_glyph_info_is_mark (&buffer->cur()))) return_trace (false); const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)]; - if (!this_record.exitAnchor) return TRACE_RETURN (false); + if (!this_record.exitAnchor) return_trace (false); hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); - if (!skippy_iter.next ()) return TRACE_RETURN (false); + if (!skippy_iter.next ()) return_trace (false); const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)]; - if (!next_record.entryAnchor) return TRACE_RETURN (false); + if (!next_record.entryAnchor) return_trace (false); unsigned int i = buffer->idx; unsigned int j = skippy_iter.idx; @@ -960,28 +965,47 @@ struct CursivePosFormat1 } /* Cross-direction adjustment */ - if (c->lookup_props & LookupFlag::RightToLeft) { - pos[i].cursive_chain() = j - i; - if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) - pos[i].y_offset = entry_y - exit_y; - else - pos[i].x_offset = entry_x - exit_x; - } else { - pos[j].cursive_chain() = i - j; - if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) - pos[j].y_offset = exit_y - entry_y; - else - pos[j].x_offset = exit_x - entry_x; + + /* We attach child to parent (think graph theory and rooted trees whereas + * the root stays on baseline and each node aligns itself against its + * parent. + * + * Optimize things for the case of RightToLeft, as that's most common in + * Arabinc. */ + unsigned int child = i; + unsigned int parent = j; + hb_position_t x_offset = entry_x - exit_x; + hb_position_t y_offset = entry_y - exit_y; + if (!(c->lookup_props & LookupFlag::RightToLeft)) + { + unsigned int k = child; + child = parent; + parent = k; + x_offset = -x_offset; + y_offset = -y_offset; } + /* If child was already connected to someone else, walk through its old + * chain and reverse the link direction, such that the whole tree of its + * previous connection now attaches to new parent. Watch out for case + * where new parent is on the path from old chain... + */ + reverse_cursive_minor_offset (pos, child, c->direction, parent); + + pos[child].cursive_chain() = parent - child; + if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) + pos[child].y_offset = y_offset; + else + pos[child].x_offset = x_offset; + buffer->idx = j; - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this)); } protected: @@ -1002,10 +1026,10 @@ struct CursivePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1041,33 +1065,36 @@ struct MarkBasePosFormat1 TRACE_APPLY (this); 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); + if (likely (mark_index == NOT_COVERED)) return_trace (false); /* now we search backwards for a non-mark glyph */ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); do { - if (!skippy_iter.prev ()) return TRACE_RETURN (false); + if (!skippy_iter.prev ()) return_trace (false); /* We only want to attach to the first of a MultipleSubst sequence. Reject others. */ if (0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx])) break; skippy_iter.reject (); } while (1); /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */ - if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } + if (!_hb_glyph_info_is_base_glyph (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[skippy_iter.idx].codepoint); - if (base_index == NOT_COVERED) return TRACE_RETURN (false); + if (base_index == NOT_COVERED) return_trace (false); - return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); + return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) && - markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount)); + return_trace (c->check_struct (this) && + markCoverage.sanitize (c, this) && + baseCoverage.sanitize (c, this) && + markArray.sanitize (c, this) && + baseArray.sanitize (c, this, (unsigned int) classCount)); } protected: @@ -1095,10 +1122,10 @@ struct MarkBasePos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1139,27 +1166,27 @@ struct MarkLigPosFormat1 TRACE_APPLY (this); 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); + if (likely (mark_index == NOT_COVERED)) return_trace (false); /* now we search backwards for a non-mark glyph */ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks); - if (!skippy_iter.prev ()) return TRACE_RETURN (false); + if (!skippy_iter.prev ()) return_trace (false); /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */ - if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return TRACE_RETURN (false);*/ } + if (!_hb_glyph_info_is_ligature (&buffer->info[skippy_iter.idx])) { /*return_trace (false);*/ } unsigned int j = skippy_iter.idx; unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[j].codepoint); - if (lig_index == NOT_COVERED) return TRACE_RETURN (false); + if (lig_index == NOT_COVERED) return_trace (false); const LigatureArray& lig_array = this+ligatureArray; const LigatureAttach& lig_attach = lig_array[lig_index]; /* Find component to attach to */ unsigned int comp_count = lig_attach.rows; - if (unlikely (!comp_count)) return TRACE_RETURN (false); + if (unlikely (!comp_count)) return_trace (false); /* We must now check whether the ligature ID of the current mark glyph * is identical to the ligature ID of the found ligature. If yes, we @@ -1174,14 +1201,17 @@ struct MarkLigPosFormat1 else comp_index = comp_count - 1; - return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); + return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) && - markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount)); + return_trace (c->check_struct (this) && + markCoverage.sanitize (c, this) && + ligatureCoverage.sanitize (c, this) && + markArray.sanitize (c, this) && + ligatureArray.sanitize (c, this, (unsigned int) classCount)); } protected: @@ -1210,10 +1240,10 @@ struct MarkLigPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1249,15 +1279,15 @@ struct MarkMarkPosFormat1 TRACE_APPLY (this); 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); + if (likely (mark1_index == NOT_COVERED)) return_trace (false); /* now we search backwards for a suitable mark glyph until a non-mark glyph */ hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, 1); skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); - if (!skippy_iter.prev ()) return TRACE_RETURN (false); + if (!skippy_iter.prev ()) return_trace (false); - if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return TRACE_RETURN (false); } + if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])) { return_trace (false); } unsigned int j = skippy_iter.idx; @@ -1279,21 +1309,23 @@ struct MarkMarkPosFormat1 } /* Didn't match. */ - return TRACE_RETURN (false); + return_trace (false); good: unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint); - if (mark2_index == NOT_COVERED) return TRACE_RETURN (false); + if (mark2_index == NOT_COVERED) return_trace (false); - return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); + return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) && - mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this) - && mark2Array.sanitize (c, this, (unsigned int) classCount)); + return_trace (c->check_struct (this) && + mark1Coverage.sanitize (c, this) && + mark2Coverage.sanitize (c, this) && + mark1Array.sanitize (c, this) && + mark2Array.sanitize (c, this, (unsigned int) classCount)); } protected: @@ -1323,10 +1355,10 @@ struct MarkMarkPos inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1374,19 +1406,18 @@ struct PosLookupSubTable inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { TRACE_DISPATCH (this, lookup_type); - /* The sub_format passed to may_dispatch is unnecessary but harmless. */ - if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ()); switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.dispatch (c)); - case Pair: return TRACE_RETURN (u.pair.dispatch (c)); - case Cursive: return TRACE_RETURN (u.cursive.dispatch (c)); - case MarkBase: return TRACE_RETURN (u.markBase.dispatch (c)); - case MarkLig: return TRACE_RETURN (u.markLig.dispatch (c)); - case MarkMark: return TRACE_RETURN (u.markMark.dispatch (c)); - case Context: return TRACE_RETURN (u.context.dispatch (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); - case Extension: return TRACE_RETURN (u.extension.dispatch (c)); - default: return TRACE_RETURN (c->default_return_value ()); + case Single: return_trace (u.single.dispatch (c)); + case Pair: return_trace (u.pair.dispatch (c)); + case Cursive: return_trace (u.cursive.dispatch (c)); + case MarkBase: return_trace (u.markBase.dispatch (c)); + case MarkLig: return_trace (u.markLig.dispatch (c)); + case MarkMark: return_trace (u.markMark.dispatch (c)); + case Context: return_trace (u.context.dispatch (c)); + case ChainContext: return_trace (u.chainContext.dispatch (c)); + case Extension: return_trace (u.extension.dispatch (c)); + default: return_trace (c->default_return_value ()); } } @@ -1421,13 +1452,13 @@ struct PosLookup : Lookup inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - return TRACE_RETURN (dispatch (c)); + return_trace (dispatch (c)); } inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); - return TRACE_RETURN (dispatch (c)); + return_trace (dispatch (c)); } template <typename set_t> @@ -1449,9 +1480,8 @@ struct PosLookup : Lookup inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); - const OffsetArrayOf<PosLookupSubTable> &list = get_subtables<PosLookupSubTable> (); - return TRACE_RETURN (dispatch (c)); + if (unlikely (!Lookup::sanitize (c))) return_trace (false); + return_trace (dispatch (c)); } }; @@ -1474,9 +1504,9 @@ struct GPOS : GSUBGPOS inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); + if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList); - return TRACE_RETURN (list.sanitize (c, this)); + return_trace (list.sanitize (c, this)); } public: DEFINE_SIZE_STATIC (10); @@ -1484,6 +1514,30 @@ struct GPOS : GSUBGPOS static void +reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) +{ + unsigned int j = pos[i].cursive_chain(); + if (likely (!j)) + return; + + j += i; + + pos[i].cursive_chain() = 0; + + /* Stop if we see new parent in the chain. */ + if (j == new_parent) + return; + + reverse_cursive_minor_offset (pos, j, direction, new_parent); + + if (HB_DIRECTION_IS_HORIZONTAL (direction)) + pos[j].y_offset = -pos[i].y_offset; + else + pos[j].x_offset = -pos[i].x_offset; + + pos[j].cursive_chain() = i - j; +} +static void fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction) { unsigned int j = pos[i].cursive_chain(); @@ -1569,8 +1623,11 @@ template <typename context_t> const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos); const PosLookup &l = gpos.get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; - c->set_lookup (l); + unsigned int saved_lookup_index = c->lookup_index; + c->set_lookup_index (lookup_index); + c->set_lookup_props (l.get_props ()); bool ret = l.dispatch (c); + c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); return ret; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh index ebe4c9ec4e..eebc87b4c5 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsub-table.hh @@ -67,7 +67,7 @@ struct SingleSubstFormat1 inline bool would_apply (hb_would_apply_context_t *c) const { TRACE_WOULD_APPLY (this); - return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); + return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } inline bool apply (hb_apply_context_t *c) const @@ -75,14 +75,14 @@ struct SingleSubstFormat1 TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; unsigned int index = (this+coverage).get_coverage (glyph_id); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); /* According to the Adobe Annotated OpenType Suite, result is always * limited to 16bit. */ glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu; c->replace_glyph (glyph_id); - return TRACE_RETURN (true); + return_trace (true); } inline bool serialize (hb_serialize_context_t *c, @@ -91,16 +91,16 @@ struct SingleSubstFormat1 int delta) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); - if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); deltaGlyphID.set (delta); /* TODO(serilaize) overflow? */ - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); + return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); } protected: @@ -144,7 +144,7 @@ struct SingleSubstFormat2 inline bool would_apply (hb_would_apply_context_t *c) const { TRACE_WOULD_APPLY (this); - return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); + return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } inline bool apply (hb_apply_context_t *c) const @@ -152,14 +152,14 @@ struct SingleSubstFormat2 TRACE_APPLY (this); hb_codepoint_t glyph_id = c->buffer->cur().codepoint; unsigned int index = (this+coverage).get_coverage (glyph_id); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); - if (unlikely (index >= substitute.len)) return TRACE_RETURN (false); + if (unlikely (index >= substitute.len)) return_trace (false); glyph_id = substitute[index]; c->replace_glyph (glyph_id); - return TRACE_RETURN (true); + return_trace (true); } inline bool serialize (hb_serialize_context_t *c, @@ -168,16 +168,16 @@ struct SingleSubstFormat2 unsigned int num_glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); - if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return TRACE_RETURN (false); - if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!substitute.serialize (c, substitutes, num_glyphs))) return_trace (false); + if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c)); + return_trace (coverage.sanitize (c, this) && substitute.sanitize (c)); } protected: @@ -200,7 +200,7 @@ struct SingleSubst unsigned int num_glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (u.format))) return_trace (false); unsigned int format = 2; int delta = 0; if (num_glyphs) { @@ -215,9 +215,9 @@ struct SingleSubst } u.format.set (format); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, num_glyphs, delta)); - case 2: return TRACE_RETURN (u.format2.serialize (c, glyphs, substitutes, num_glyphs)); - default:return TRACE_RETURN (false); + case 1: return_trace (u.format1.serialize (c, glyphs, num_glyphs, delta)); + case 2: return_trace (u.format2.serialize (c, glyphs, substitutes, num_glyphs)); + default:return_trace (false); } } @@ -225,11 +225,11 @@ struct SingleSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - case 2: return TRACE_RETURN (c->dispatch (u.format2)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + case 2: return_trace (c->dispatch (u.format2)); + default:return_trace (c->default_return_value ()); } } @@ -273,14 +273,14 @@ struct Sequence * buffer->move_to() makes assumptions about this too. Perhaps fix * in the future after figuring out what to do with the clusters. */ - if (unlikely (!count)) return TRACE_RETURN (false); + if (unlikely (!count)) return_trace (false); /* Special-case to make it in-place and not consider this * as a "multiplied" substitution. */ if (unlikely (count == 1)) { c->replace_glyph (substitute.array[0]); - return TRACE_RETURN (true); + return_trace (true); } unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ? @@ -292,7 +292,7 @@ struct Sequence } c->buffer->skip_glyph (); - return TRACE_RETURN (true); + return_trace (true); } inline bool serialize (hb_serialize_context_t *c, @@ -300,15 +300,15 @@ struct Sequence unsigned int num_glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); - if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!substitute.serialize (c, glyphs, num_glyphs))) return_trace (false); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (substitute.sanitize (c)); + return_trace (substitute.sanitize (c)); } protected: @@ -347,7 +347,7 @@ struct MultipleSubstFormat1 inline bool would_apply (hb_would_apply_context_t *c) const { TRACE_WOULD_APPLY (this); - return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); + return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } inline bool apply (hb_apply_context_t *c) const @@ -355,9 +355,9 @@ struct MultipleSubstFormat1 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); - return TRACE_RETURN ((this+sequence[index]).apply (c)); + return_trace ((this+sequence[index]).apply (c)); } inline bool serialize (hb_serialize_context_t *c, @@ -367,21 +367,21 @@ struct MultipleSubstFormat1 Supplier<GlyphID> &substitute_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); - if (unlikely (!sequence.serialize (c, num_glyphs))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!sequence.serialize (c, num_glyphs))) return_trace (false); for (unsigned int i = 0; i < num_glyphs; i++) if (unlikely (!sequence[i].serialize (c, this).serialize (c, substitute_glyphs_list, - substitute_len_list[i]))) return TRACE_RETURN (false); + substitute_len_list[i]))) return_trace (false); substitute_len_list.advance (num_glyphs); - if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && sequence.sanitize (c, this)); } protected: @@ -405,12 +405,12 @@ struct MultipleSubst Supplier<GlyphID> &substitute_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (u.format))) return_trace (false); unsigned int format = 1; u.format.set (format); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list)); - default:return TRACE_RETURN (false); + case 1: return_trace (u.format1.serialize (c, glyphs, substitute_len_list, num_glyphs, substitute_glyphs_list)); + default:return_trace (false); } } @@ -418,10 +418,10 @@ struct MultipleSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -473,7 +473,7 @@ struct AlternateSubstFormat1 inline bool would_apply (hb_would_apply_context_t *c) const { TRACE_WOULD_APPLY (this); - return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); + return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } inline bool apply (hb_apply_context_t *c) const @@ -482,11 +482,11 @@ struct AlternateSubstFormat1 hb_codepoint_t glyph_id = c->buffer->cur().codepoint; unsigned int index = (this+coverage).get_coverage (glyph_id); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const AlternateSet &alt_set = this+alternateSet[index]; - if (unlikely (!alt_set.len)) return TRACE_RETURN (false); + if (unlikely (!alt_set.len)) return_trace (false); hb_mask_t glyph_mask = c->buffer->cur().mask; hb_mask_t lookup_mask = c->lookup_mask; @@ -495,13 +495,13 @@ struct AlternateSubstFormat1 unsigned int shift = _hb_ctz (lookup_mask); unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift); - if (unlikely (alt_index > alt_set.len || alt_index == 0)) return TRACE_RETURN (false); + if (unlikely (alt_index > alt_set.len || alt_index == 0)) return_trace (false); glyph_id = alt_set[alt_index - 1]; c->replace_glyph (glyph_id); - return TRACE_RETURN (true); + return_trace (true); } inline bool serialize (hb_serialize_context_t *c, @@ -511,21 +511,21 @@ struct AlternateSubstFormat1 Supplier<GlyphID> &alternate_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); - if (unlikely (!alternateSet.serialize (c, num_glyphs))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!alternateSet.serialize (c, num_glyphs))) return_trace (false); for (unsigned int i = 0; i < num_glyphs; i++) if (unlikely (!alternateSet[i].serialize (c, this).serialize (c, alternate_glyphs_list, - alternate_len_list[i]))) return TRACE_RETURN (false); + alternate_len_list[i]))) return_trace (false); alternate_len_list.advance (num_glyphs); - if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs, num_glyphs))) return_trace (false); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this)); } protected: @@ -549,12 +549,12 @@ struct AlternateSubst Supplier<GlyphID> &alternate_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (u.format))) return_trace (false); unsigned int format = 1; u.format.set (format); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list)); - default:return TRACE_RETURN (false); + case 1: return_trace (u.format1.serialize (c, glyphs, alternate_len_list, num_glyphs, alternate_glyphs_list)); + default:return_trace (false); } } @@ -562,10 +562,10 @@ struct AlternateSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -602,13 +602,13 @@ struct Ligature { TRACE_WOULD_APPLY (this); if (c->len != component.len) - return TRACE_RETURN (false); + return_trace (false); for (unsigned int i = 1; i < c->len; i++) if (likely (c->glyphs[i] != component[i])) - return TRACE_RETURN (false); + return_trace (false); - return TRACE_RETURN (true); + return_trace (true); } inline bool apply (hb_apply_context_t *c) const @@ -616,14 +616,14 @@ struct Ligature TRACE_APPLY (this); unsigned int count = component.len; - if (unlikely (!count)) return TRACE_RETURN (false); + if (unlikely (!count)) return_trace (false); /* Special-case to make it in-place and not consider this * as a "ligated" substitution. */ if (unlikely (count == 1)) { c->replace_glyph (ligGlyph); - return TRACE_RETURN (true); + return_trace (true); } bool is_mark_ligature = false; @@ -640,7 +640,7 @@ struct Ligature match_positions, &is_mark_ligature, &total_component_count))) - return TRACE_RETURN (false); + return_trace (false); ligate_input (c, count, @@ -650,7 +650,7 @@ struct Ligature is_mark_ligature, total_component_count); - return TRACE_RETURN (true); + return_trace (true); } inline bool serialize (hb_serialize_context_t *c, @@ -659,17 +659,17 @@ struct Ligature unsigned int num_components /* Including first component */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); ligGlyph = ligature; - if (unlikely (!component.serialize (c, components, num_components))) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (unlikely (!component.serialize (c, components, num_components))) return_trace (false); + return_trace (true); } public: inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c)); + return_trace (ligGlyph.sanitize (c) && component.sanitize (c)); } protected: @@ -708,9 +708,9 @@ struct LigatureSet { const Ligature &lig = this+ligature[i]; if (lig.would_apply (c)) - return TRACE_RETURN (true); + return_trace (true); } - return TRACE_RETURN (false); + return_trace (false); } inline bool apply (hb_apply_context_t *c) const @@ -720,10 +720,10 @@ struct LigatureSet for (unsigned int i = 0; i < num_ligs; i++) { const Ligature &lig = this+ligature[i]; - if (lig.apply (c)) return TRACE_RETURN (true); + if (lig.apply (c)) return_trace (true); } - return TRACE_RETURN (false); + return_trace (false); } inline bool serialize (hb_serialize_context_t *c, @@ -733,22 +733,22 @@ struct LigatureSet Supplier<GlyphID> &component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); - if (unlikely (!ligature.serialize (c, num_ligatures))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!ligature.serialize (c, num_ligatures))) return_trace (false); for (unsigned int i = 0; i < num_ligatures; i++) if (unlikely (!ligature[i].serialize (c, this).serialize (c, ligatures[i], component_list, - component_count_list[i]))) return TRACE_RETURN (false); + component_count_list[i]))) return_trace (false); ligatures.advance (num_ligatures); component_count_list.advance (num_ligatures); - return TRACE_RETURN (true); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (ligature.sanitize (c, this)); + return_trace (ligature.sanitize (c, this)); } protected: @@ -790,10 +790,10 @@ struct LigatureSubstFormat1 { TRACE_WOULD_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->glyphs[0]); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const LigatureSet &lig_set = this+ligatureSet[index]; - return TRACE_RETURN (lig_set.would_apply (c)); + return_trace (lig_set.would_apply (c)); } inline bool apply (hb_apply_context_t *c) const @@ -802,10 +802,10 @@ struct LigatureSubstFormat1 hb_codepoint_t glyph_id = c->buffer->cur().codepoint; unsigned int index = (this+coverage).get_coverage (glyph_id); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const LigatureSet &lig_set = this+ligatureSet[index]; - return TRACE_RETURN (lig_set.apply (c)); + return_trace (lig_set.apply (c)); } inline bool serialize (hb_serialize_context_t *c, @@ -817,23 +817,23 @@ struct LigatureSubstFormat1 Supplier<GlyphID> &component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); - if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (*this))) return_trace (false); + if (unlikely (!ligatureSet.serialize (c, num_first_glyphs))) return_trace (false); for (unsigned int i = 0; i < num_first_glyphs; i++) if (unlikely (!ligatureSet[i].serialize (c, this).serialize (c, ligatures_list, component_count_list, ligature_per_first_glyph_count_list[i], - component_list))) return TRACE_RETURN (false); + component_list))) return_trace (false); ligature_per_first_glyph_count_list.advance (num_first_glyphs); - if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (unlikely (!coverage.serialize (c, this).serialize (c, first_glyphs, num_first_glyphs))) return_trace (false); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this)); } protected: @@ -859,13 +859,18 @@ struct LigatureSubst Supplier<GlyphID> &component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (u.format))) return TRACE_RETURN (false); + if (unlikely (!c->extend_min (u.format))) return_trace (false); unsigned int format = 1; u.format.set (format); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs, - ligatures_list, component_count_list, component_list)); - default:return TRACE_RETURN (false); + case 1: return_trace (u.format1.serialize (c, + first_glyphs, + ligature_per_first_glyph_count_list, + num_first_glyphs, + ligatures_list, + component_count_list, + component_list)); + default:return_trace (false); } } @@ -873,10 +878,10 @@ struct LigatureSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -959,17 +964,17 @@ struct ReverseChainSingleSubstFormat1 inline bool would_apply (hb_would_apply_context_t *c) const { TRACE_WOULD_APPLY (this); - return TRACE_RETURN (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); + return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED); } inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); if (unlikely (c->nesting_level_left != MAX_NESTING_LEVEL)) - return TRACE_RETURN (false); /* No chaining to this type */ + return_trace (false); /* No chaining to this type */ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); @@ -986,22 +991,22 @@ struct ReverseChainSingleSubstFormat1 /* 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); + return_trace (true); } - return TRACE_RETURN (false); + return_trace (false); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) - return TRACE_RETURN (false); + return_trace (false); const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack); if (!lookahead.sanitize (c, this)) - return TRACE_RETURN (false); + return_trace (false); const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead); - return TRACE_RETURN (substitute.sanitize (c)); + return_trace (substitute.sanitize (c)); } protected: @@ -1030,10 +1035,10 @@ struct ReverseChainSingleSubst inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + default:return_trace (c->default_return_value ()); } } @@ -1069,18 +1074,17 @@ struct SubstLookupSubTable inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const { TRACE_DISPATCH (this, lookup_type); - /* The sub_format passed to may_dispatch is unnecessary but harmless. */ - if (unlikely (!c->may_dispatch (this, &u.sub_format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.sub_format))) return_trace (c->no_dispatch_return_value ()); switch (lookup_type) { - case Single: return TRACE_RETURN (u.single.dispatch (c)); - case Multiple: return TRACE_RETURN (u.multiple.dispatch (c)); - case Alternate: return TRACE_RETURN (u.alternate.dispatch (c)); - case Ligature: return TRACE_RETURN (u.ligature.dispatch (c)); - case Context: return TRACE_RETURN (u.context.dispatch (c)); - case ChainContext: return TRACE_RETURN (u.chainContext.dispatch (c)); - case Extension: return TRACE_RETURN (u.extension.dispatch (c)); - case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.dispatch (c)); - default: return TRACE_RETURN (c->default_return_value ()); + case Single: return_trace (u.single.dispatch (c)); + case Multiple: return_trace (u.multiple.dispatch (c)); + case Alternate: return_trace (u.alternate.dispatch (c)); + case Ligature: return_trace (u.ligature.dispatch (c)); + case Context: return_trace (u.context.dispatch (c)); + case ChainContext: return_trace (u.chainContext.dispatch (c)); + case Extension: return_trace (u.extension.dispatch (c)); + case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c)); + default: return_trace (c->default_return_value ()); } } @@ -1120,21 +1124,21 @@ struct SubstLookup : Lookup inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (this); - return TRACE_RETURN (dispatch (c)); + return_trace (dispatch (c)); } inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); c->set_recurse_func (dispatch_recurse_func<hb_closure_context_t>); - return TRACE_RETURN (dispatch (c)); + return_trace (dispatch (c)); } inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); c->set_recurse_func (dispatch_recurse_func<hb_collect_glyphs_context_t>); - return TRACE_RETURN (dispatch (c)); + return_trace (dispatch (c)); } template <typename set_t> @@ -1148,9 +1152,9 @@ struct SubstLookup : Lookup const hb_ot_layout_lookup_accelerator_t *accel) const { TRACE_WOULD_APPLY (this); - if (unlikely (!c->len)) return TRACE_RETURN (false); - if (!accel->may_have (c->glyphs[0])) return TRACE_RETURN (false); - return TRACE_RETURN (dispatch (c)); + if (unlikely (!c->len)) return_trace (false); + if (!accel->may_have (c->glyphs[0])) return_trace (false); + return_trace (dispatch (c)); } static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); @@ -1166,8 +1170,8 @@ struct SubstLookup : Lookup unsigned int num_glyphs) { TRACE_SERIALIZE (this); - if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return TRACE_RETURN (false); - return TRACE_RETURN (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs)); + if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Single, lookup_props, 1))) return_trace (false); + return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes, num_glyphs)); } inline bool serialize_multiple (hb_serialize_context_t *c, @@ -1178,9 +1182,12 @@ struct SubstLookup : Lookup Supplier<GlyphID> &substitute_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return TRACE_RETURN (false); - return TRACE_RETURN (serialize_subtable (c, 0).u.multiple.serialize (c, glyphs, substitute_len_list, num_glyphs, - substitute_glyphs_list)); + if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Multiple, lookup_props, 1))) return_trace (false); + return_trace (serialize_subtable (c, 0).u.multiple.serialize (c, + glyphs, + substitute_len_list, + num_glyphs, + substitute_glyphs_list)); } inline bool serialize_alternate (hb_serialize_context_t *c, @@ -1191,9 +1198,12 @@ struct SubstLookup : Lookup Supplier<GlyphID> &alternate_glyphs_list) { TRACE_SERIALIZE (this); - if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return TRACE_RETURN (false); - return TRACE_RETURN (serialize_subtable (c, 0).u.alternate.serialize (c, glyphs, alternate_len_list, num_glyphs, - alternate_glyphs_list)); + if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Alternate, lookup_props, 1))) return_trace (false); + return_trace (serialize_subtable (c, 0).u.alternate.serialize (c, + glyphs, + alternate_len_list, + num_glyphs, + alternate_glyphs_list)); } inline bool serialize_ligature (hb_serialize_context_t *c, @@ -1206,9 +1216,14 @@ struct SubstLookup : Lookup Supplier<GlyphID> &component_list /* Starting from second for each ligature */) { TRACE_SERIALIZE (this); - if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return TRACE_RETURN (false); - return TRACE_RETURN (serialize_subtable (c, 0).u.ligature.serialize (c, first_glyphs, ligature_per_first_glyph_count_list, num_first_glyphs, - ligatures_list, component_count_list, component_list)); + if (unlikely (!Lookup::serialize (c, SubstLookupSubTable::Ligature, lookup_props, 1))) return_trace (false); + return_trace (serialize_subtable (c, 0).u.ligature.serialize (c, + first_glyphs, + ligature_per_first_glyph_count_list, + num_first_glyphs, + ligatures_list, + component_count_list, + component_list)); } template <typename context_t> @@ -1221,9 +1236,8 @@ struct SubstLookup : Lookup inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false); - const OffsetArrayOf<SubstLookupSubTable> &list = get_subtables<SubstLookupSubTable> (); - if (unlikely (!dispatch (c))) return TRACE_RETURN (false); + if (unlikely (!Lookup::sanitize (c))) return_trace (false); + if (unlikely (!dispatch (c))) return_trace (false); if (unlikely (get_type () == SubstLookupSubTable::Extension)) { @@ -1234,9 +1248,9 @@ struct SubstLookup : Lookup unsigned int count = get_subtable_count (); for (unsigned int i = 1; i < count; i++) if (get_subtable (i).u.extension.get_type () != type) - return TRACE_RETURN (false); + return_trace (false); } - return TRACE_RETURN (true); + return_trace (true); } }; @@ -1259,9 +1273,9 @@ struct GSUB : GSUBGPOS inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false); + if (unlikely (!GSUBGPOS::sanitize (c))) return_trace (false); const OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList); - return TRACE_RETURN (list.sanitize (c, this)); + return_trace (list.sanitize (c, this)); } public: DEFINE_SIZE_STATIC (10); @@ -1312,8 +1326,11 @@ template <typename context_t> const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); const SubstLookup &l = gsub.get_lookup (lookup_index); unsigned int saved_lookup_props = c->lookup_props; - c->set_lookup (l); + unsigned int saved_lookup_index = c->lookup_index; + c->set_lookup_index (lookup_index); + c->set_lookup_props (l.get_props ()); bool ret = l.dispatch (c); + c->set_lookup_index (saved_lookup_index); c->set_lookup_props (saved_lookup_props); return ret; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh index cbc6840bc8..230b3b6851 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos-private.hh @@ -46,14 +46,11 @@ namespace OT { (&c->debug_depth, c->get_name (), this, HB_FUNC, \ ""); -struct hb_closure_context_t +struct hb_closure_context_t : + hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE> { inline const char *get_name (void) { return "CLOSURE"; } - static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE; - typedef hb_void_t return_t; typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index); - template <typename T, typename F> - inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; } static return_t default_return_value (void) { return HB_VOID; } @@ -98,13 +95,10 @@ struct hb_closure_context_t (&c->debug_depth, c->get_name (), this, HB_FUNC, \ "%d glyphs", c->len); -struct hb_would_apply_context_t +struct hb_would_apply_context_t : + hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY> { inline const char *get_name (void) { return "WOULD_APPLY"; } - static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY; - typedef bool return_t; - template <typename T, typename F> - inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { return obj.would_apply (this); } static return_t default_return_value (void) { return false; } @@ -138,14 +132,11 @@ struct hb_would_apply_context_t (&c->debug_depth, c->get_name (), this, HB_FUNC, \ ""); -struct hb_collect_glyphs_context_t +struct hb_collect_glyphs_context_t : + hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS> { inline const char *get_name (void) { return "COLLECT_GLYPHS"; } - static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS; - typedef hb_void_t return_t; typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index); - template <typename T, typename F> - inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; } static return_t default_return_value (void) { return HB_VOID; } @@ -232,14 +223,14 @@ struct hb_collect_glyphs_context_t #define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0) #endif +/* XXX Can we remove this? */ + template <typename set_t> -struct hb_add_coverage_context_t +struct hb_add_coverage_context_t : + hb_dispatch_context_t<hb_add_coverage_context_t<set_t>, const Coverage &, HB_DEBUG_GET_COVERAGE> { inline const char *get_name (void) { return "GET_COVERAGE"; } - static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE; typedef const Coverage &return_t; - template <typename T, typename F> - inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { return obj.get_coverage (); } static return_t default_return_value (void) { return Null(Coverage); } @@ -266,9 +257,11 @@ struct hb_add_coverage_context_t #define TRACE_APPLY(this) \ hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \ (&c->debug_depth, c->get_name (), this, HB_FUNC, \ - "idx %d codepoint %u", c->buffer->idx, c->buffer->cur().codepoint); + "idx %d gid %u lookup %d", \ + c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index); -struct hb_apply_context_t +struct hb_apply_context_t : + hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY> { struct matcher_t { @@ -328,8 +321,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)) && - !_hb_glyph_info_ligated (&info))) + (ignore_zwj || !_hb_glyph_info_is_zwj (&info)))) return SKIP_MAYBE; return SKIP_NO; @@ -363,11 +355,11 @@ struct hb_apply_context_t { matcher.set_lookup_props (lookup_props); } - inline void set_match_func (matcher_t::match_func_t match_func, - const void *match_data, + inline void set_match_func (matcher_t::match_func_t match_func_, + const void *match_data_, const USHORT glyph_data[]) { - matcher.set_match_func (match_func, match_data); + matcher.set_match_func (match_func_, match_data_); match_glyph_data = glyph_data; } @@ -449,11 +441,7 @@ struct hb_apply_context_t inline const char *get_name (void) { return "APPLY"; } - static const unsigned int max_debug_depth = HB_DEBUG_APPLY; - typedef bool return_t; typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index); - template <typename T, typename F> - inline bool may_dispatch (const T *obj, const F *format) { return true; } template <typename T> inline return_t dispatch (const T &obj) { return obj.apply (this); } static return_t default_return_value (void) { return false; } @@ -482,6 +470,7 @@ struct hb_apply_context_t const GDEF &gdef; bool has_glyph_classes; skipping_iterator_t iter_input, iter_context; + unsigned int lookup_index; unsigned int debug_depth; @@ -500,12 +489,13 @@ struct hb_apply_context_t has_glyph_classes (gdef.has_glyph_classes ()), iter_input (), iter_context (), + lookup_index ((unsigned int) -1), debug_depth (0) {} inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } - inline void set_lookup (const Lookup &l) { set_lookup_props (l.get_props ()); } + inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; } inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; @@ -516,39 +506,39 @@ struct hb_apply_context_t inline bool match_properties_mark (hb_codepoint_t glyph, unsigned int glyph_props, - unsigned int lookup_props) const + unsigned int match_props) const { /* If using mark filtering sets, the high short of - * lookup_props has the set index. + * match_props has the set index. */ - if (lookup_props & LookupFlag::UseMarkFilteringSet) - return gdef.mark_set_covers (lookup_props >> 16, glyph); + if (match_props & LookupFlag::UseMarkFilteringSet) + return gdef.mark_set_covers (match_props >> 16, glyph); - /* The second byte of lookup_props has the meaning + /* The second byte of match_props has the meaning * "ignore marks of attachment type different than * the attachment type specified." */ - if (lookup_props & LookupFlag::MarkAttachmentType) - return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); + if (match_props & LookupFlag::MarkAttachmentType) + return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType); return true; } inline bool check_glyph_property (const hb_glyph_info_t *info, - unsigned int lookup_props) const + unsigned int match_props) const { hb_codepoint_t glyph = info->codepoint; unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info); /* Not covered, if, for example, glyph class is ligature and - * lookup_props includes LookupFlags::IgnoreLigatures + * match_props includes LookupFlags::IgnoreLigatures */ - if (glyph_props & lookup_props & LookupFlag::IgnoreFlags) + if (glyph_props & match_props & LookupFlag::IgnoreFlags) return false; if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) - return match_properties_mark (glyph, glyph_props, lookup_props); + return match_properties_mark (glyph, glyph_props, match_props); return true; } @@ -720,7 +710,7 @@ static inline bool match_input (hb_apply_context_t *c, { TRACE_APPLY (NULL); - if (unlikely (count > MAX_CONTEXT_LENGTH)) TRACE_RETURN (false); + if (unlikely (count > MAX_CONTEXT_LENGTH)) return_trace (false); hb_buffer_t *buffer = c->buffer; @@ -757,7 +747,7 @@ static inline bool match_input (hb_apply_context_t *c, match_positions[0] = buffer->idx; for (unsigned int i = 1; i < count; i++) { - if (!skippy_iter.next ()) return TRACE_RETURN (false); + if (!skippy_iter.next ()) return_trace (false); match_positions[i] = skippy_iter.idx; @@ -769,13 +759,13 @@ static inline bool match_input (hb_apply_context_t *c, * all subsequent components should be attached to the same ligature * component, otherwise we shouldn't ligate them. */ if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp) - return TRACE_RETURN (false); + return_trace (false); } else { /* If first component was NOT attached to a previous ligature component, * all subsequent components should also NOT be attached to any ligature * component, unless they are attached to the first component itself! */ if (this_lig_id && this_lig_comp && (this_lig_id != first_lig_id)) - return TRACE_RETURN (false); + return_trace (false); } is_mark_ligature = is_mark_ligature && _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]); @@ -790,9 +780,9 @@ static inline bool match_input (hb_apply_context_t *c, if (p_total_component_count) *p_total_component_count = total_component_count; - return TRACE_RETURN (true); + return_trace (true); } -static inline void ligate_input (hb_apply_context_t *c, +static inline bool ligate_input (hb_apply_context_t *c, unsigned int count, /* Including the first glyph */ unsigned int match_positions[MAX_CONTEXT_LENGTH], /* Including the first glyph */ unsigned int match_length, @@ -882,7 +872,7 @@ static inline void ligate_input (hb_apply_context_t *c, break; } } - TRACE_RETURN (true); + return_trace (true); } static inline bool match_backtrack (hb_apply_context_t *c, @@ -899,9 +889,9 @@ static inline bool match_backtrack (hb_apply_context_t *c, for (unsigned int i = 0; i < count; i++) if (!skippy_iter.prev ()) - return TRACE_RETURN (false); + return_trace (false); - return TRACE_RETURN (true); + return_trace (true); } static inline bool match_lookahead (hb_apply_context_t *c, @@ -919,9 +909,9 @@ static inline bool match_lookahead (hb_apply_context_t *c, for (unsigned int i = 0; i < count; i++) if (!skippy_iter.next ()) - return TRACE_RETURN (false); + return_trace (false); - return TRACE_RETURN (true); + return_trace (true); } @@ -931,7 +921,7 @@ struct LookupRecord inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this)); + return_trace (c->check_struct (this)); } USHORT sequenceIndex; /* Index into current glyph @@ -1032,7 +1022,7 @@ static inline bool apply_lookup (hb_apply_context_t *c, buffer->move_to (end); - return TRACE_RETURN (true); + return_trace (true); } @@ -1141,14 +1131,14 @@ struct Rule { TRACE_WOULD_APPLY (this); const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); - return TRACE_RETURN (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); + return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); } inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0)); - return TRACE_RETURN (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); + return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context)); } public: @@ -1200,9 +1190,9 @@ struct RuleSet for (unsigned int i = 0; i < num_rules; i++) { if ((this+rule[i]).would_apply (c, lookup_context)) - return TRACE_RETURN (true); + return_trace (true); } - return TRACE_RETURN (false); + return_trace (false); } inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const @@ -1212,15 +1202,15 @@ struct RuleSet for (unsigned int i = 0; i < num_rules; i++) { if ((this+rule[i]).apply (c, lookup_context)) - return TRACE_RETURN (true); + return_trace (true); } - return TRACE_RETURN (false); + return_trace (false); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (rule.sanitize (c, this)); + return_trace (rule.sanitize (c, this)); } protected: @@ -1277,7 +1267,7 @@ struct ContextFormat1 {match_glyph}, NULL }; - return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); + return_trace (rule_set.would_apply (c, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1290,20 +1280,20 @@ struct ContextFormat1 TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) - return TRACE_RETURN (false); + return_trace (false); const RuleSet &rule_set = this+ruleSet[index]; struct ContextApplyLookupContext lookup_context = { {match_glyph}, NULL }; - return TRACE_RETURN (rule_set.apply (c, lookup_context)); + return_trace (rule_set.apply (c, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); } protected: @@ -1369,7 +1359,7 @@ struct ContextFormat2 {match_class}, &class_def }; - return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); + return_trace (rule_set.would_apply (c, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1381,7 +1371,7 @@ struct ContextFormat2 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const ClassDef &class_def = this+classDef; index = class_def.get_class (c->buffer->cur().codepoint); @@ -1390,13 +1380,13 @@ struct ContextFormat2 {match_class}, &class_def }; - return TRACE_RETURN (rule_set.apply (c, lookup_context)); + return_trace (rule_set.apply (c, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this)); } protected: @@ -1460,7 +1450,7 @@ struct ContextFormat3 {match_coverage}, this }; - return TRACE_RETURN (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_would_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1472,27 +1462,27 @@ struct ContextFormat3 { TRACE_APPLY (this); unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount); struct ContextApplyLookupContext lookup_context = { {match_coverage}, this }; - return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); + return_trace (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!c->check_struct (this)) return TRACE_RETURN (false); + if (!c->check_struct (this)) return_trace (false); unsigned int count = glyphCount; - if (!count) return TRACE_RETURN (false); /* We want to access coverageZ[0] freely. */ - if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false); + if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */ + if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (!coverageZ[i].sanitize (c, this)) return TRACE_RETURN (false); + if (!coverageZ[i].sanitize (c, this)) return_trace (false); const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count); - return TRACE_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); + return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount)); } protected: @@ -1515,12 +1505,12 @@ struct Context inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - case 2: return TRACE_RETURN (c->dispatch (u.format2)); - case 3: return TRACE_RETURN (c->dispatch (u.format3)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + case 2: return_trace (c->dispatch (u.format2)); + case 3: return_trace (c->dispatch (u.format3)); + default:return_trace (c->default_return_value ()); } } @@ -1685,11 +1675,11 @@ struct ChainRule const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); - return TRACE_RETURN (chain_context_would_apply_lookup (c, - backtrack.len, backtrack.array, - input.len, input.array, - lookahead.len, lookahead.array, lookup.len, - lookup.array, lookup_context)); + return_trace (chain_context_would_apply_lookup (c, + backtrack.len, backtrack.array, + input.len, input.array, + lookahead.len, lookahead.array, lookup.len, + lookup.array, lookup_context)); } inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const @@ -1698,23 +1688,23 @@ struct ChainRule const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); - return TRACE_RETURN (chain_context_apply_lookup (c, - backtrack.len, backtrack.array, - input.len, input.array, - lookahead.len, lookahead.array, lookup.len, - lookup.array, lookup_context)); + return_trace (chain_context_apply_lookup (c, + backtrack.len, backtrack.array, + input.len, input.array, + lookahead.len, lookahead.array, lookup.len, + lookup.array, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!backtrack.sanitize (c)) return TRACE_RETURN (false); + if (!backtrack.sanitize (c)) return_trace (false); const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack); - if (!input.sanitize (c)) return TRACE_RETURN (false); + if (!input.sanitize (c)) return_trace (false); const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input); - if (!lookahead.sanitize (c)) return TRACE_RETURN (false); + if (!lookahead.sanitize (c)) return_trace (false); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); - return TRACE_RETURN (lookup.sanitize (c)); + return_trace (lookup.sanitize (c)); } protected: @@ -1759,9 +1749,9 @@ struct ChainRuleSet unsigned int num_rules = rule.len; for (unsigned int i = 0; i < num_rules; i++) if ((this+rule[i]).would_apply (c, lookup_context)) - return TRACE_RETURN (true); + return_trace (true); - return TRACE_RETURN (false); + return_trace (false); } inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const @@ -1770,15 +1760,15 @@ struct ChainRuleSet unsigned int num_rules = rule.len; for (unsigned int i = 0; i < num_rules; i++) if ((this+rule[i]).apply (c, lookup_context)) - return TRACE_RETURN (true); + return_trace (true); - return TRACE_RETURN (false); + return_trace (false); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (rule.sanitize (c, this)); + return_trace (rule.sanitize (c, this)); } protected: @@ -1833,7 +1823,7 @@ struct ChainContextFormat1 {match_glyph}, {NULL, NULL, NULL} }; - return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); + return_trace (rule_set.would_apply (c, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1845,20 +1835,20 @@ struct ChainContextFormat1 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const ChainRuleSet &rule_set = this+ruleSet[index]; struct ChainContextApplyLookupContext lookup_context = { {match_glyph}, {NULL, NULL, NULL} }; - return TRACE_RETURN (rule_set.apply (c, lookup_context)); + return_trace (rule_set.apply (c, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && ruleSet.sanitize (c, this)); } protected: @@ -1937,7 +1927,7 @@ struct ChainContextFormat2 &input_class_def, &lookahead_class_def} }; - return TRACE_RETURN (rule_set.would_apply (c, lookup_context)); + return_trace (rule_set.would_apply (c, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -1949,7 +1939,7 @@ struct ChainContextFormat2 { TRACE_APPLY (this); unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; @@ -1963,15 +1953,17 @@ struct ChainContextFormat2 &input_class_def, &lookahead_class_def} }; - return TRACE_RETURN (rule_set.apply (c, lookup_context)); + return_trace (rule_set.apply (c, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) && - inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) && - ruleSet.sanitize (c, this)); + return_trace (coverage.sanitize (c, this) && + backtrackClassDef.sanitize (c, this) && + inputClassDef.sanitize (c, this) && + lookaheadClassDef.sanitize (c, this) && + ruleSet.sanitize (c, this)); } protected: @@ -2054,11 +2046,11 @@ struct ChainContextFormat3 {match_coverage}, {this, this, this} }; - return TRACE_RETURN (chain_context_would_apply_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, - lookup.len, lookup.array, lookup_context)); + return_trace (chain_context_would_apply_lookup (c, + backtrack.len, (const USHORT *) backtrack.array, + input.len, (const USHORT *) input.array + 1, + lookahead.len, (const USHORT *) lookahead.array, + lookup.len, lookup.array, lookup_context)); } inline const Coverage &get_coverage (void) const @@ -2073,7 +2065,7 @@ struct ChainContextFormat3 const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); - if (likely (index == NOT_COVERED)) return TRACE_RETURN (false); + if (likely (index == NOT_COVERED)) return_trace (false); const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); @@ -2081,24 +2073,24 @@ struct ChainContextFormat3 {match_coverage}, {this, this, this} }; - return TRACE_RETURN (chain_context_apply_lookup (c, - backtrack.len, (const USHORT *) backtrack.array, - input.len, (const USHORT *) input.array + 1, - lookahead.len, (const USHORT *) lookahead.array, - lookup.len, lookup.array, lookup_context)); + return_trace (chain_context_apply_lookup (c, + backtrack.len, (const USHORT *) backtrack.array, + input.len, (const USHORT *) input.array + 1, + lookahead.len, (const USHORT *) lookahead.array, + lookup.len, lookup.array, lookup_context)); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false); + if (!backtrack.sanitize (c, this)) return_trace (false); const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack); - if (!input.sanitize (c, this)) return TRACE_RETURN (false); - if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */ + if (!input.sanitize (c, this)) return_trace (false); + if (!input.len) return_trace (false); /* To be consistent with Context. */ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input); - if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false); + if (!lookahead.sanitize (c, this)) return_trace (false); const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead); - return TRACE_RETURN (lookup.sanitize (c)); + return_trace (lookup.sanitize (c)); } protected: @@ -2128,12 +2120,12 @@ struct ChainContext inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (c->dispatch (u.format1)); - case 2: return TRACE_RETURN (c->dispatch (u.format2)); - case 3: return TRACE_RETURN (c->dispatch (u.format3)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (c->dispatch (u.format1)); + case 2: return_trace (c->dispatch (u.format2)); + case 3: return_trace (c->dispatch (u.format3)); + default:return_trace (c->default_return_value ()); } } @@ -2164,15 +2156,15 @@ struct ExtensionFormat1 inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, format); - if (unlikely (!c->may_dispatch (this, this))) TRACE_RETURN (c->default_return_value ()); - return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ()); + if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ()); + return_trace (get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ())); } /* This is called from may_dispatch() above with hb_sanitize_context_t. */ inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && extensionOffset != 0); + return_trace (c->check_struct (this) && extensionOffset != 0); } protected: @@ -2209,10 +2201,10 @@ struct Extension inline typename context_t::return_t dispatch (context_t *c) const { TRACE_DISPATCH (this, u.format); - if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ()); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { - case 1: return TRACE_RETURN (u.format1.dispatch (c)); - default:return TRACE_RETURN (c->default_return_value ()); + case 1: return_trace (u.format1.dispatch (c)); + default:return_trace (c->default_return_value ()); } } @@ -2267,10 +2259,11 @@ struct GSUBGPOS inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && - scriptList.sanitize (c, this) && - featureList.sanitize (c, this) && - lookupList.sanitize (c, this)); + return_trace (version.sanitize (c) && + likely (version.major == 1) && + scriptList.sanitize (c, this) && + featureList.sanitize (c, this) && + lookupList.sanitize (c, this)); } protected: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh index 739dfd9106..7e199c2e14 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-jstf-table.hh @@ -57,17 +57,17 @@ struct JstfPriority inline bool sanitize (hb_sanitize_context_t *c) const { 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)); + return_trace (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: @@ -127,7 +127,7 @@ struct JstfLangSys : OffsetListOf<JstfPriority> const Record<JstfLangSys>::sanitize_closure_t * = NULL) const { TRACE_SANITIZE (this); - return TRACE_RETURN (OffsetListOf<JstfPriority>::sanitize (c)); + return_trace (OffsetListOf<JstfPriority>::sanitize (c)); } }; @@ -168,9 +168,9 @@ struct JstfScript const Record<JstfScript>::sanitize_closure_t * = NULL) const { TRACE_SANITIZE (this); - return TRACE_RETURN (extenderGlyphs.sanitize (c, this) && - defaultLangSys.sanitize (c, this) && - langSys.sanitize (c, this)); + return_trace (extenderGlyphs.sanitize (c, this) && + defaultLangSys.sanitize (c, this) && + langSys.sanitize (c, this)); } protected: @@ -212,8 +212,9 @@ struct JSTF inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) && - scriptList.sanitize (c, this)); + return_trace (version.sanitize (c) && + likely (version.major == 1) && + scriptList.sanitize (c, this)); } protected: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh index 47fecd216d..d168e27f53 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-private.hh @@ -36,6 +36,15 @@ #include "hb-set-private.hh" +/* Private API corresponding to hb-ot-layout.h: */ + +HB_INTERNAL hb_bool_t +hb_ot_layout_table_find_feature (hb_face_t *face, + hb_tag_t table_tag, + hb_tag_t feature_tag, + unsigned int *feature_index); + + /* * GDEF */ @@ -179,6 +188,30 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout); #define lig_props() var1.u8[2] /* GSUB/GPOS ligature tracking */ #define syllable() var1.u8[3] /* GSUB/GPOS shaping boundaries */ + +/* loop over syllables */ + +#define foreach_syllable(buffer, start, end) \ + for (unsigned int \ + _count = buffer->len, \ + start = 0, end = _count ? _next_syllable (buffer, 0) : 0; \ + start < _count; \ + start = end, end = _next_syllable (buffer, start)) + +static inline unsigned int +_next_syllable (hb_buffer_t *buffer, unsigned int start) +{ + hb_glyph_info_t *info = buffer->info; + unsigned int count = buffer->len; + + unsigned int syllable = info[start].syllable(); + while (++start < count && syllable == info[start].syllable()) + ; + + return start; +} + + /* unicode_props */ enum { @@ -225,10 +258,12 @@ _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info) return info->unicode_props1(); } +static inline bool _hb_glyph_info_ligated (const hb_glyph_info_t *info); + static inline hb_bool_t _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info) { - return !!(info->unicode_props0() & MASK0_IGNORABLE); + return (info->unicode_props0() & MASK0_IGNORABLE) && !_hb_glyph_info_ligated (info); } static inline hb_bool_t @@ -406,6 +441,14 @@ _hb_glyph_info_clear_ligated_and_multiplied (hb_glyph_info_t *info) HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); } +static inline void +_hb_glyph_info_clear_substituted_and_ligated_and_multiplied (hb_glyph_info_t *info) +{ + info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED | + HB_OT_LAYOUT_GLYPH_PROPS_LIGATED | + HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED); +} + /* Allocation / deallocation. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc index b1e69e89f4..275a960d58 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc @@ -28,6 +28,7 @@ * Google Author(s): Behdad Esfahbod */ +#include "hb-open-type-private.hh" #include "hb-ot-layout-private.hh" #include "hb-ot-layout-gdef-table.hh" @@ -128,6 +129,9 @@ hb_ot_layout_has_glyph_classes (hb_face_t *face) return _get_gdef (face).has_glyph_classes (); } +/** + * Since: 0.9.7 + **/ hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_face_t *face, hb_codepoint_t glyph) @@ -135,6 +139,9 @@ hb_ot_layout_get_glyph_class (hb_face_t *face, return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph); } +/** + * Since: 0.9.7 + **/ void hb_ot_layout_get_glyphs_in_class (hb_face_t *face, hb_ot_layout_glyph_class_t klass, @@ -285,6 +292,28 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, return g.get_feature_tags (start_offset, feature_count, feature_tags); } +hb_bool_t +hb_ot_layout_table_find_feature (hb_face_t *face, + hb_tag_t table_tag, + hb_tag_t feature_tag, + unsigned int *feature_index) +{ + ASSERT_STATIC (OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX); + const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag); + + unsigned int num_features = g.get_feature_count (); + for (unsigned int i = 0; i < num_features; i++) + { + if (feature_tag == g.get_feature_tag (i)) { + if (feature_index) *feature_index = i; + return true; + } + } + + if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX; + return false; +} + unsigned int hb_ot_layout_script_get_language_tags (hb_face_t *face, @@ -335,6 +364,9 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, NULL); } +/** + * Since: 0.9.30 + **/ hb_bool_t hb_ot_layout_language_get_required_feature (hb_face_t *face, hb_tag_t table_tag, @@ -419,6 +451,9 @@ hb_ot_layout_language_find_feature (hb_face_t *face, return false; } +/** + * Since: 0.9.7 + **/ unsigned int hb_ot_layout_feature_get_lookups (hb_face_t *face, hb_tag_t table_tag, @@ -433,6 +468,9 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face, return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); } +/** + * Since: 0.9.22 + **/ unsigned int hb_ot_layout_table_get_lookup_count (hb_face_t *face, hb_tag_t table_tag) @@ -590,6 +628,9 @@ _hb_ot_layout_collect_lookups_languages (hb_face_t *face, } } +/** + * Since: 0.9.8 + **/ void hb_ot_layout_collect_lookups (hb_face_t *face, hb_tag_t table_tag, @@ -631,6 +672,9 @@ hb_ot_layout_collect_lookups (hb_face_t *face, } } +/** + * Since: 0.9.7 + **/ void hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_tag_t table_tag, @@ -676,6 +720,9 @@ hb_ot_layout_has_substitution (hb_face_t *face) return &_get_gsub (face) != &OT::Null(OT::GSUB); } +/** + * Since: 0.9.7 + **/ hb_bool_t hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int lookup_index, @@ -714,6 +761,9 @@ hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) OT::GSUB::substitute_finish (font, buffer); } +/** + * Since: 0.9.7 + **/ void hb_ot_layout_lookup_substitute_closure (hb_face_t *face, unsigned int lookup_index, @@ -748,6 +798,9 @@ hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) OT::GPOS::position_finish (font, buffer); } +/** + * Since: 0.9.10 + **/ hb_bool_t hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *design_size, /* OUT. May be NULL */ @@ -873,13 +926,10 @@ apply_backward (OT::hb_apply_context_t *c, return ret; } -struct hb_apply_forward_context_t +struct hb_apply_forward_context_t : + OT::hb_dispatch_context_t<hb_apply_forward_context_t, bool, HB_DEBUG_APPLY> { - inline const char *get_name (void) { return "APPLY_FORWARD"; } - static const unsigned int max_debug_depth = HB_DEBUG_APPLY; - typedef bool return_t; - template <typename T, typename F> - inline bool may_dispatch (const T *obj, const F *format) { return true; } + inline const char *get_name (void) { return "APPLY_FWD"; } template <typename T> inline return_t dispatch (const T &obj) { return apply_forward (c, obj, accel); } static return_t default_return_value (void) { return false; } @@ -907,7 +957,7 @@ apply_string (OT::hb_apply_context_t *c, if (unlikely (!buffer->len || !c->lookup_mask)) return; - c->set_lookup (lookup); + c->set_lookup_props (lookup.get_props ()); if (likely (!lookup.is_reverse ())) { @@ -958,7 +1008,20 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, const stage_map_t *stage = &stages[table_index][stage_index]; for (; i < stage->last_lookup; i++) { +#if 0 + char buf[4096]; + hb_buffer_serialize_glyphs (buffer, 0, buffer->len, + buf, sizeof (buf), NULL, + font, + HB_BUFFER_SERIALIZE_FORMAT_TEXT, + Proxy::table_index == 0 ? + HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS : + HB_BUFFER_SERIALIZE_FLAG_DEFAULT); + printf ("buf: [%s]\n", buf); +#endif + unsigned int lookup_index = lookups[table_index][i].index; + c.set_lookup_index (lookup_index); c.set_lookup_mask (lookups[table_index][i].mask); c.set_auto_zwj (lookups[table_index][i].auto_zwj); apply_string<Proxy> (&c, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh index 86b7e9fafe..f9538af183 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map-private.hh @@ -154,9 +154,10 @@ struct hb_ot_map_t enum hb_ot_map_feature_flags_t { F_NONE = 0x0000u, - F_GLOBAL = 0x0001u, - F_HAS_FALLBACK = 0x0002u, - F_MANUAL_ZWJ = 0x0004u + F_GLOBAL = 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */ + F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */ + F_MANUAL_ZWJ = 0x0004u, /* Don't skip over ZWJ when matching. */ + F_GLOBAL_SEARCH = 0x0008u /* If feature not found in LangSys, look for it in global feature list and pick one. */ }; /* Macro version for where const is desired. */ #define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r))) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc index 4985eb22b2..95bd04ee8e 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-map.cc @@ -216,6 +216,16 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m) info->tag, &feature_index[table_index]); } + if (!found && (info->flags & F_GLOBAL_SEARCH)) + { + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + found |= hb_ot_layout_table_find_feature (face, + table_tags[table_index], + info->tag, + &feature_index[table_index]); + } + } if (!found && !(info->flags & F_HAS_FALLBACK)) continue; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh index 0d9a0fa1d8..27105af132 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-maxp-table.hh @@ -51,8 +51,9 @@ struct maxp inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u))); + return_trace (c->check_struct (this) && + likely (version.major == 1 || + (version.major == 0 && version.minor == 0x5000u))); } /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh index 21450c6138..870f123325 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-name-table.hh @@ -60,7 +60,7 @@ struct NameRecord { TRACE_SANITIZE (this); /* We can check from base all the way up to the end of string... */ - return TRACE_RETURN (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset)); + return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset)); } USHORT platformID; /* Platform ID. */ @@ -107,17 +107,17 @@ struct name char *string_pool = (char *) this + stringOffset; unsigned int _count = count; for (unsigned int i = 0; i < _count; i++) - if (!nameRecord[i].sanitize (c, string_pool)) return TRACE_RETURN (false); - return TRACE_RETURN (true); + if (!nameRecord[i].sanitize (c, string_pool)) return_trace (false); + return_trace (true); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - likely (format == 0 || format == 1) && - c->check_array (nameRecord, nameRecord[0].static_size, count) && - sanitize_records (c)); + return_trace (c->check_struct (this) && + likely (format == 0 || format == 1) && + c->check_array (nameRecord, nameRecord[0].static_size, count) && + sanitize_records (c)); } /* We only implement format 0 for now. */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh index a77f24ec84..d97d285210 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-fallback.hh @@ -75,9 +75,9 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS if (!num_glyphs) return NULL; - /* Bubble-sort! + /* Bubble-sort or something equally good! * May not be good-enough for presidential candidate interviews, but good-enough for us... */ - hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]); + hb_stable_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]); OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs); OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs); @@ -126,7 +126,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN first_glyphs_indirection[num_first_glyphs] = first_glyph_idx; num_first_glyphs++; } - hb_bubble_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]); + hb_stable_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]); /* Now that the first-glyphs are sorted, walk again, populate ligatures. */ for (unsigned int i = 0; i < num_first_glyphs; i++) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh new file mode 100644 index 0000000000..fcedc7d742 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-private.hh @@ -0,0 +1,50 @@ +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH +#define HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-ot-shape-complex-private.hh" + + +struct arabic_shape_plan_t; + +HB_INTERNAL void * +data_create_arabic (const hb_ot_shape_plan_t *plan); + +HB_INTERNAL void +data_destroy_arabic (void *data); + +HB_INTERNAL void +setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, + hb_buffer_t *buffer, + hb_script_t script); + +#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh index 17100497ec..80d5044354 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-7.0.0.txt - * # Date: 2014-02-14, 21:00:00 GMT [RP, KW, LI] - * # Blocks-7.0.0.txt - * # Date: 2014-04-03, 23:23:00 GMT [RP, KW] + * # ArabicShaping-8.0.0.txt + * # Date: 2015-02-17, 23:33:00 GMT [RP] + * # Blocks-8.0.0.txt + * # Date: 2014-11-10, 23:04:00 GMT [KW] * UnicodeData.txt does not have a header. */ @@ -76,9 +76,9 @@ static const uint8_t joining_table[] = /* Arabic Extended-A */ - /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R, + /* 08A0 */ D,D,D,D,D,D,D,D,D,D,R,R,R,U,R,D,D,R,R,D,D, -#define joining_offset_0x1806u 691 +#define joining_offset_0x1806u 693 /* Mongolian */ @@ -89,40 +89,40 @@ static const uint8_t joining_table[] = /* 1880 */ U,U,U,U,U,U,U,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* 18A0 */ D,D,D,D,D,D,D,D,D,X,D, -#define joining_offset_0x200cu 856 +#define joining_offset_0x200cu 858 /* General Punctuation */ /* 2000 */ U,C, -#define joining_offset_0x2066u 858 +#define joining_offset_0x2066u 860 /* General Punctuation */ /* 2060 */ U,U,U,U, -#define joining_offset_0xa840u 862 +#define joining_offset_0xa840u 864 /* Phags-pa */ /* A840 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D, /* A860 */ D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,D,L,U, -#define joining_offset_0x10ac0u 914 +#define joining_offset_0x10ac0u 916 /* Manichaean */ /* 10AC0 */ D,D,D,D,D,R,U,R,U,R,R,U,U,L,R,R,R,R,R,D,D,D,D,L,D,D,D,D,D,R,D,D, /* 10AE0 */ D,R,U,U,R,X,X,X,X,X,X,D,D,D,D,R, -#define joining_offset_0x10b80u 962 +#define joining_offset_0x10b80u 964 /* Psalter Pahlavi */ /* 10B80 */ D,R,D,R,R,R,D,D,D,R,D,D,R,D,R,R,D,R,X,X,X,X,X,X,X,X,X,X,X,X,X,X, /* 10BA0 */ X,X,X,X,X,X,X,X,X,R,R,R,R,D,D,U, -}; /* Table items: 1010; occupancy: 57% */ +}; /* Table items: 1012; occupancy: 57% */ static unsigned int @@ -131,7 +131,7 @@ joining_type (hb_codepoint_t u) switch (u >> 12) { case 0x0u: - if (hb_in_range (u, 0x0600u, 0x08B2u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; + if (hb_in_range (u, 0x0600u, 0x08B4u)) return joining_table[u - 0x0600u + joining_offset_0x0600u]; break; case 0x1u: diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc index ae90864127..cde02e0a56 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-arabic.cc @@ -24,7 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#include "hb-ot-shape-complex-private.hh" +#include "hb-ot-shape-complex-arabic-private.hh" #include "hb-ot-shape-private.hh" @@ -33,9 +33,13 @@ /* + * Joining types: + */ + +/* * Bits used in the joining tables */ -enum { +enum hb_arabic_joining_type_t { JOINING_TYPE_U = 0, JOINING_TYPE_L = 1, JOINING_TYPE_R = 2, @@ -49,10 +53,6 @@ enum { JOINING_TYPE_X = 8 /* means: use general-category to choose between U or T. */ }; -/* - * Joining types: - */ - #include "hb-ot-shape-complex-arabic-table.hh" static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat) @@ -61,7 +61,7 @@ static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_categ if (likely (j_type != JOINING_TYPE_X)) return j_type; - return (FLAG(gen_cat) & + return (FLAG_SAFE(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT)) @@ -212,7 +212,7 @@ struct arabic_shape_plan_t arabic_fallback_plan_t *fallback_plan; }; -static void * +void * data_create_arabic (const hb_ot_shape_plan_t *plan) { arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) calloc (1, sizeof (arabic_shape_plan_t)); @@ -230,7 +230,7 @@ data_create_arabic (const hb_ot_shape_plan_t *plan) return arabic_plan; } -static void +void data_destroy_arabic (void *data) { arabic_shape_plan_t *arabic_plan = (arabic_shape_plan_t *) data; @@ -305,17 +305,15 @@ mongolian_variation_selectors (hb_buffer_t *buffer) info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action(); } -static void -setup_masks_arabic (const hb_ot_shape_plan_t *plan, - hb_buffer_t *buffer, - hb_font_t *font HB_UNUSED) +void +setup_masks_arabic_plan (const arabic_shape_plan_t *arabic_plan, + hb_buffer_t *buffer, + hb_script_t script) { HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action); - const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; - arabic_joining (buffer); - if (plan->props.script == HB_SCRIPT_MONGOLIAN) + if (script == HB_SCRIPT_MONGOLIAN) mongolian_variation_selectors (buffer); unsigned int count = buffer->len; @@ -326,6 +324,15 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan, HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); } +static void +setup_masks_arabic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font HB_UNUSED) +{ + const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; + setup_masks_arabic_plan (arabic_plan, buffer, plan->props.script); +} + static void nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc index 6ac18b08bf..1fa79ce6d4 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-hangul.cc @@ -205,17 +205,12 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, buffer->next_glyph (); if (!is_zero_width_char (font, u)) { + buffer->merge_out_clusters (start, end + 1); hb_glyph_info_t *info = buffer->out_info; hb_glyph_info_t tone = info[end]; memmove (&info[start + 1], &info[start], (end - start) * sizeof (hb_glyph_info_t)); info[start] = tone; } - /* Merge clusters across the (possibly reordered) syllable+tone. - * We want to merge even in the zero-width tone mark case here, - * so that clustering behavior isn't dependent on how the tone mark - * is handled by the font. - */ - buffer->merge_out_clusters (start, end + 1); } else { @@ -296,7 +291,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, } else end = start + 2; - buffer->merge_out_clusters (start, end); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + buffer->merge_out_clusters (start, end); continue; } } @@ -368,7 +364,8 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan, info[i++].hangul_shaping_feature() = VJMO; if (i < end) info[i++].hangul_shaping_feature() = TJMO; - buffer->merge_out_clusters (start, end); + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + buffer->merge_out_clusters (start, end); continue; } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh index d8dfc6507d..559ebe4986 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic-private.hh @@ -161,8 +161,6 @@ enum indic_matra_category_t { INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = POS_PRE_M }; -/* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation - * because gcc fails to optimize the latter and fills the table in at runtime. */ #define INDIC_COMBINE_CATEGORIES(S,M) \ (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || \ ( \ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc index 7723600410..44481dbb4c 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-indic.cc @@ -142,7 +142,7 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags) { /* If it ligated, all bets are off. */ if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG (info.indic_category()) & flags); + return !!(FLAG_SAFE (info.indic_category()) & flags); } static inline bool @@ -237,7 +237,7 @@ set_indic_properties (hb_glyph_info_t &info) * Re-assign position. */ - if ((FLAG (cat) & CONSONANT_FLAGS)) + if ((FLAG_SAFE (cat) & CONSONANT_FLAGS)) { pos = POS_BASE_C; if (is_ra (u)) @@ -247,7 +247,7 @@ set_indic_properties (hb_glyph_info_t &info) { pos = matra_position (u, pos); } - else if ((FLAG (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol)))) + else if ((FLAG_SAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol)))) { pos = POS_SMVD; } @@ -756,7 +756,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, { default: assert (false); - /* fallthrough */ + HB_FALLTHROUGH; case BASE_POS_LAST: { @@ -963,7 +963,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) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS))) + if ((FLAG_SAFE (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 && @@ -1012,7 +1012,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, info[i].syllable() = i - start; /* Sit tight, rock 'n roll! */ - hb_bubble_sort (info + start, end - start, compare_indic_order); + hb_stable_sort (info + start, end - start, compare_indic_order); /* Find base again */ base = end; for (unsigned int i = start; i < end; i++) @@ -1025,7 +1025,11 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, * 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. */ + * For pre-base stuff, we handle cluster issues in final reordering. + * + * We could use buffer->sort() for this, if there was no special + * reordering of pre-base stuff happening later... + */ if (indic_plan->is_old_spec || end - base > 127) buffer->merge_clusters (base, end); else @@ -1161,17 +1165,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, } } - -static void -initial_reordering_vowel_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - /* We made the vowels look like consonants. So let's call the consonant logic! */ - initial_reordering_consonant_syllable (plan, face, buffer, start, end); -} - static void initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, hb_face_t *face, @@ -1194,50 +1187,27 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan, } static void -initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - /* We already inserted dotted-circles, so just call the standalone_cluster. */ - initial_reordering_standalone_cluster (plan, face, buffer, start, end); -} - -static void -initial_reordering_symbol_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_face_t *face HB_UNUSED, - hb_buffer_t *buffer HB_UNUSED, - unsigned int start HB_UNUSED, unsigned int end HB_UNUSED) -{ - /* Nothing to do right now. If we ever switch to using the output - * buffer in the reordering process, we'd need to next_glyph() here. */ -} - -static void -initial_reordering_non_indic_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_face_t *face HB_UNUSED, - hb_buffer_t *buffer HB_UNUSED, - 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_syllable (const hb_ot_shape_plan_t *plan, hb_face_t *face, hb_buffer_t *buffer, unsigned int start, unsigned int end) { syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); - switch (syllable_type) { - case consonant_syllable: initial_reordering_consonant_syllable (plan, 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 symbol_cluster: initial_reordering_symbol_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; + switch (syllable_type) + { + case vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */ + case consonant_syllable: + initial_reordering_consonant_syllable (plan, face, buffer, start, end); + break; + + case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */ + case standalone_cluster: + initial_reordering_standalone_cluster (plan, face, buffer, start, end); + break; + + case symbol_cluster: + case non_indic_cluster: + break; } } @@ -1281,10 +1251,10 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, { last_syllable = syllable; - hb_glyph_info_t info = dottedcircle; - info.cluster = buffer->cur().cluster; - info.mask = buffer->cur().mask; - info.syllable() = buffer->cur().syllable(); + hb_glyph_info_t ginfo = dottedcircle; + ginfo.cluster = buffer->cur().cluster; + ginfo.mask = buffer->cur().mask; + ginfo.syllable() = buffer->cur().syllable(); /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ @@ -1293,7 +1263,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->cur().indic_category() == OT_Repha) buffer->next_glyph (); - buffer->output_info (info); + buffer->output_info (ginfo); } else buffer->next_glyph (); @@ -1310,18 +1280,8 @@ initial_reordering (const hb_ot_shape_plan_t *plan, update_consonant_positions (plan, font, buffer); insert_dotted_circles (plan, font, buffer); - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - initial_reordering_syllable (plan, font->face, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - initial_reordering_syllable (plan, font->face, buffer, last, count); + foreach_syllable (buffer, start, end) + initial_reordering_syllable (plan, font->face, buffer, start, end); } static void @@ -1448,12 +1408,17 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, if (info[i - 1].indic_position () == POS_PRE_M) { unsigned int old_pos = i - 1; + if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */ + base--; + hb_glyph_info_t tmp = info[old_pos]; memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0])); info[new_pos] = tmp; - if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */ - base--; + + /* Note: this merge_clusters() is intentionally *after* the reordering. + * Indic matra reordering is special and tricky... */ buffer->merge_clusters (new_pos, MIN (end, base + 1)); + new_pos--; } } else { @@ -1550,7 +1515,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, { new_reph_pos = base; while (new_reph_pos < end && - !( FLAG (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD)))) + !( FLAG_SAFE (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD)))) new_reph_pos++; if (new_reph_pos < end) goto reph_move; @@ -1606,12 +1571,12 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, reph_move: { - buffer->merge_clusters (start, new_reph_pos + 1); - /* Move */ + buffer->merge_clusters (start, new_reph_pos + 1); hb_glyph_info_t reph = info[start]; memmove (&info[start], &info[start + 1], (new_reph_pos - start) * sizeof (info[0])); info[new_reph_pos] = reph; + if (start < base && base <= new_reph_pos) base--; } @@ -1666,8 +1631,8 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, if (new_pos > start && info[new_pos - 1].indic_category() == OT_M) { unsigned int old_pos = i; - for (unsigned int i = base + 1; i < old_pos; i++) - if (info[i].indic_category() == OT_M) + for (unsigned int j = base + 1; j < old_pos; j++) + if (info[j].indic_category() == OT_M) { new_pos--; break; @@ -1684,10 +1649,12 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, { unsigned int old_pos = i; + buffer->merge_clusters (new_pos, old_pos + 1); hb_glyph_info_t tmp = info[old_pos]; memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0])); info[new_pos] = tmp; + if (new_pos <= base && base < old_pos) base++; } @@ -1701,7 +1668,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan, /* Apply 'init' to the Left Matra if it's a word start. */ if (info[start].indic_position () == POS_PRE_M && (!start || - !(FLAG (_hb_glyph_info_get_general_category (&info[start - 1])) & + !(FLAG_SAFE (_hb_glyph_info_get_general_category (&info[start - 1])) & FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))) info[start].mask |= indic_plan->mask_array[INIT]; @@ -1737,16 +1704,8 @@ final_reordering (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; if (unlikely (!count)) return; - hb_glyph_info_t *info = buffer->info; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - final_reordering_syllable (plan, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - final_reordering_syllable (plan, buffer, last, count); + foreach_syllable (buffer, start, end) + final_reordering_syllable (plan, buffer, start, end); HB_BUFFER_DEALLOCATE_VAR (buffer, indic_category); HB_BUFFER_DEALLOCATE_VAR (buffer, indic_position); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc index d016380cc6..7f74f2df82 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-myanmar.cc @@ -154,7 +154,7 @@ is_one_of (const hb_glyph_info_t &info, unsigned int flags) { /* If it ligated, all bets are off. */ if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG (info.myanmar_category()) & flags); + return !!(FLAG_SAFE (info.myanmar_category()) & flags); } static inline bool @@ -304,9 +304,7 @@ compare_myanmar_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm */ static void -initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, +initial_reordering_consonant_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) { hb_glyph_info_t *info = buffer->info; @@ -393,43 +391,11 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, } } - buffer->merge_clusters (start, end); /* Sit tight, rock 'n roll! */ - hb_bubble_sort (info + start, end - start, compare_myanmar_order); + buffer->sort (start, end, compare_myanmar_order); } static void -initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - /* We already inserted dotted-circles, so just call the consonant_syllable. */ - 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, - 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_syllable (const hb_ot_shape_plan_t *plan, hb_face_t *face, hb_buffer_t *buffer, @@ -437,10 +403,15 @@ 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; + + case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */ + case consonant_syllable: + initial_reordering_consonant_syllable (buffer, start, end); + break; + + case punctuation_cluster: + case non_myanmar_cluster: + break; } } @@ -484,12 +455,12 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, { last_syllable = syllable; - hb_glyph_info_t info = dottedcircle; - info.cluster = buffer->cur().cluster; - info.mask = buffer->cur().mask; - info.syllable() = buffer->cur().syllable(); + hb_glyph_info_t ginfo = dottedcircle; + ginfo.cluster = buffer->cur().cluster; + ginfo.mask = buffer->cur().mask; + ginfo.syllable() = buffer->cur().syllable(); - buffer->output_info (info); + buffer->output_info (ginfo); } else buffer->next_glyph (); @@ -505,18 +476,8 @@ initial_reordering (const hb_ot_shape_plan_t *plan, { insert_dotted_circles (plan, font, buffer); - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - initial_reordering_syllable (plan, font->face, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - initial_reordering_syllable (plan, font->face, buffer, last, count); + foreach_syllable (buffer, start, end) + initial_reordering_syllable (plan, font->face, buffer, start, end); } static void diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh index e268933ce4..8d03dee51f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-private.hh @@ -59,9 +59,9 @@ enum hb_ot_shape_zero_width_marks_type_t { HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \ HB_COMPLEX_SHAPER_IMPLEMENT (indic) \ HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \ - HB_COMPLEX_SHAPER_IMPLEMENT (sea) \ HB_COMPLEX_SHAPER_IMPLEMENT (thai) \ HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \ + HB_COMPLEX_SHAPER_IMPLEMENT (use) \ /* ^--- Add new shapers here */ @@ -179,9 +179,12 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) case HB_SCRIPT_PSALTER_PAHLAVI: /* For Arabic script, use the Arabic shaper even if no OT script tag was found. - * This is because we do fallback shaping for Arabic script (and not others). */ - if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || - planner->props.script == HB_SCRIPT_ARABIC) + * This is because we do fallback shaping for Arabic script (and not others). + * But note that Arabic shaping is applicable only to horizontal layout; for + * vertical text, just use the generic shaper instead. */ + if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT || + planner->props.script == HB_SCRIPT_ARABIC) && + HB_DIRECTION_IS_HORIZONTAL(planner->props.direction)) return &_hb_ot_complex_shaper_arabic; else return &_hb_ot_complex_shaper_default; @@ -214,61 +217,9 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* ^--- Add new shapers here */ - #if 0 - /* Note: - * - * These disabled scripts are listed in ucd/IndicSyllabicCategory.txt, but according - * to Martin Hosken and Jonathan Kew do not require complex shaping. - * - * TODO We should automate figuring out which scripts do not need complex shaping - * - * TODO We currently keep data for these scripts in our indic table. Need to fix the - * generator to not do that. - */ - - - /* Simple? */ - - /* Unicode-3.2 additions */ - case HB_SCRIPT_BUHID: - case HB_SCRIPT_HANUNOO: - - /* Unicode-5.1 additions */ - case HB_SCRIPT_SAURASHTRA: - - /* Unicode-6.0 additions */ - case HB_SCRIPT_BATAK: - case HB_SCRIPT_BRAHMI: - - - /* Simple */ - - /* Unicode-1.1 additions */ - /* These have their own shaper now. */ - case HB_SCRIPT_LAO: - case HB_SCRIPT_THAI: - - /* Unicode-3.2 additions */ - case HB_SCRIPT_TAGALOG: - case HB_SCRIPT_TAGBANWA: - - /* Unicode-4.0 additions */ - case HB_SCRIPT_LIMBU: - case HB_SCRIPT_TAI_LE: - /* Unicode-4.1 additions */ - case HB_SCRIPT_KHAROSHTHI: case HB_SCRIPT_NEW_TAI_LUE: - case HB_SCRIPT_SYLOTI_NAGRI: - - /* Unicode-5.1 additions */ - case HB_SCRIPT_KAYAH_LI: - - /* Unicode-5.2 additions */ - case HB_SCRIPT_TAI_VIET: - - #endif /* Unicode-1.1 additions */ @@ -285,28 +236,11 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) /* Unicode-3.0 additions */ case HB_SCRIPT_SINHALA: - /* Unicode-5.0 additions */ - case HB_SCRIPT_BALINESE: - - /* Unicode-5.1 additions */ - case HB_SCRIPT_LEPCHA: - case HB_SCRIPT_REJANG: - case HB_SCRIPT_SUNDANESE: - /* Unicode-5.2 additions */ case HB_SCRIPT_JAVANESE: - case HB_SCRIPT_KAITHI: - case HB_SCRIPT_MEETEI_MAYEK: - - /* Unicode-6.0 additions */ - - /* Unicode-6.1 additions */ - case HB_SCRIPT_CHAKMA: - case HB_SCRIPT_SHARADA: - case HB_SCRIPT_TAKRI: /* If the designer designed the font for the 'DFLT' script, - * use the default shaper. Otherwise, use the Indic shaper. + * use the default shaper. Otherwise, use the specific shaper. * Note that for some simple scripts, there may not be *any* * GSUB/GPOS needed, so there may be no scripts found! */ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) @@ -338,23 +272,82 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner) else return &_hb_ot_complex_shaper_default; + + /* Unicode-2.0 additions */ + //case HB_SCRIPT_TIBETAN: + + /* Unicode-3.0 additions */ + //case HB_SCRIPT_MONGOLIAN: + //case HB_SCRIPT_SINHALA: + + /* Unicode-3.2 additions */ + case HB_SCRIPT_BUHID: + case HB_SCRIPT_HANUNOO: + case HB_SCRIPT_TAGALOG: + case HB_SCRIPT_TAGBANWA: + + /* Unicode-4.0 additions */ + case HB_SCRIPT_LIMBU: + case HB_SCRIPT_TAI_LE: + /* Unicode-4.1 additions */ case HB_SCRIPT_BUGINESE: + case HB_SCRIPT_KHAROSHTHI: + case HB_SCRIPT_SYLOTI_NAGRI: + case HB_SCRIPT_TIFINAGH: + + /* Unicode-5.0 additions */ + case HB_SCRIPT_BALINESE: + //case HB_SCRIPT_NKO: + //case HB_SCRIPT_PHAGS_PA: /* Unicode-5.1 additions */ case HB_SCRIPT_CHAM: + case HB_SCRIPT_KAYAH_LI: + case HB_SCRIPT_LEPCHA: + case HB_SCRIPT_REJANG: + case HB_SCRIPT_SAURASHTRA: + case HB_SCRIPT_SUNDANESE: /* Unicode-5.2 additions */ + case HB_SCRIPT_EGYPTIAN_HIEROGLYPHS: + //case HB_SCRIPT_JAVANESE: + case HB_SCRIPT_KAITHI: + case HB_SCRIPT_MEETEI_MAYEK: case HB_SCRIPT_TAI_THAM: + case HB_SCRIPT_TAI_VIET: + + /* Unicode-6.0 additions */ + case HB_SCRIPT_BATAK: + case HB_SCRIPT_BRAHMI: + //case HB_SCRIPT_MANDAIC: + + /* Unicode-6.1 additions */ + case HB_SCRIPT_CHAKMA: + case HB_SCRIPT_SHARADA: + case HB_SCRIPT_TAKRI: + + /* Unicode-7.0 additions */ + case HB_SCRIPT_DUPLOYAN: + case HB_SCRIPT_GRANTHA: + case HB_SCRIPT_KHOJKI: + case HB_SCRIPT_KHUDAWADI: + case HB_SCRIPT_MAHAJANI: + //case HB_SCRIPT_MANICHAEAN: + case HB_SCRIPT_MODI: + case HB_SCRIPT_PAHAWH_HMONG: + //case HB_SCRIPT_PSALTER_PAHLAVI: + case HB_SCRIPT_SIDDHAM: + case HB_SCRIPT_TIRHUTA: /* If the designer designed the font for the 'DFLT' script, - * use the default shaper. Otherwise, use the Indic shaper. + * use the default shaper. Otherwise, use the specific shaper. * Note that for some simple scripts, there may not be *any* * GSUB/GPOS needed, so there may be no scripts found! */ if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T')) return &_hb_ot_complex_shaper_default; else - return &_hb_ot_complex_shaper_sea; + return &_hb_ot_complex_shaper_use; } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh deleted file mode 100644 index 15b862f5a1..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea-machine.hh +++ /dev/null @@ -1,224 +0,0 @@ - -#line 1 "hb-ot-shape-complex-sea-machine.rl" -/* - * Copyright © 2011,2012,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_SHAPE_COMPLEX_SEA_MACHINE_HH -#define HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH - -#include "hb-private.hh" - - -#line 36 "hb-ot-shape-complex-sea-machine.hh" -static const unsigned char _sea_syllable_machine_trans_keys[] = { - 1u, 1u, 1u, 1u, 1u, 29u, 3u, 29u, 3u, 29u, 1u, 1u, 0 -}; - -static const char _sea_syllable_machine_key_spans[] = { - 1, 1, 29, 27, 27, 1 -}; - -static const char _sea_syllable_machine_index_offsets[] = { - 0, 2, 4, 34, 62, 90 -}; - -static const char _sea_syllable_machine_indicies[] = { - 1, 0, 3, 2, 1, 1, 3, 5, - 4, 4, 4, 4, 4, 3, 4, 1, - 4, 4, 4, 4, 3, 4, 4, 4, - 4, 3, 4, 4, 4, 3, 3, 3, - 3, 4, 1, 7, 6, 6, 6, 6, - 6, 1, 6, 6, 6, 6, 6, 6, - 1, 6, 6, 6, 6, 1, 6, 6, - 6, 1, 1, 1, 1, 6, 3, 9, - 8, 8, 8, 8, 8, 3, 8, 8, - 8, 8, 8, 8, 3, 8, 8, 8, - 8, 3, 8, 8, 8, 3, 3, 3, - 3, 8, 3, 10, 0 -}; - -static const char _sea_syllable_machine_trans_targs[] = { - 2, 3, 2, 4, 2, 5, 2, 0, - 2, 1, 2 -}; - -static const char _sea_syllable_machine_trans_actions[] = { - 1, 2, 3, 2, 6, 0, 7, 0, - 8, 0, 9 -}; - -static const char _sea_syllable_machine_to_state_actions[] = { - 0, 0, 4, 0, 0, 0 -}; - -static const char _sea_syllable_machine_from_state_actions[] = { - 0, 0, 5, 0, 0, 0 -}; - -static const char _sea_syllable_machine_eof_trans[] = { - 1, 3, 0, 7, 9, 11 -}; - -static const int sea_syllable_machine_start = 2; -static const int sea_syllable_machine_first_final = 2; -static const int sea_syllable_machine_error = -1; - -static const int sea_syllable_machine_en_main = 2; - - -#line 36 "hb-ot-shape-complex-sea-machine.rl" - - - -#line 67 "hb-ot-shape-complex-sea-machine.rl" - - -#define found_syllable(syllable_type) \ - HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ - for (unsigned int i = last; i < p+1; i++) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - last = p+1; \ - syllable_serial++; \ - if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ - } HB_STMT_END - -static void -find_syllables (hb_buffer_t *buffer) -{ - unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; - int cs; - hb_glyph_info_t *info = buffer->info; - -#line 117 "hb-ot-shape-complex-sea-machine.hh" - { - cs = sea_syllable_machine_start; - ts = 0; - te = 0; - act = 0; - } - -#line 88 "hb-ot-shape-complex-sea-machine.rl" - - - p = 0; - pe = eof = buffer->len; - - unsigned int last = 0; - unsigned int syllable_serial = 1; - -#line 134 "hb-ot-shape-complex-sea-machine.hh" - { - int _slen; - int _trans; - const unsigned char *_keys; - const char *_inds; - if ( p == pe ) - goto _test_eof; -_resume: - switch ( _sea_syllable_machine_from_state_actions[cs] ) { - case 5: -#line 1 "NONE" - {ts = p;} - break; -#line 148 "hb-ot-shape-complex-sea-machine.hh" - } - - _keys = _sea_syllable_machine_trans_keys + (cs<<1); - _inds = _sea_syllable_machine_indicies + _sea_syllable_machine_index_offsets[cs]; - - _slen = _sea_syllable_machine_key_spans[cs]; - _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].sea_category()) && - ( info[p].sea_category()) <= _keys[1] ? - ( info[p].sea_category()) - _keys[0] : _slen ]; - -_eof_trans: - cs = _sea_syllable_machine_trans_targs[_trans]; - - if ( _sea_syllable_machine_trans_actions[_trans] == 0 ) - goto _again; - - switch ( _sea_syllable_machine_trans_actions[_trans] ) { - case 2: -#line 1 "NONE" - {te = p+1;} - break; - case 6: -#line 63 "hb-ot-shape-complex-sea-machine.rl" - {te = p+1;{ found_syllable (non_sea_cluster); }} - break; - case 7: -#line 61 "hb-ot-shape-complex-sea-machine.rl" - {te = p;p--;{ found_syllable (consonant_syllable); }} - break; - case 8: -#line 62 "hb-ot-shape-complex-sea-machine.rl" - {te = p;p--;{ found_syllable (broken_cluster); }} - break; - case 9: -#line 63 "hb-ot-shape-complex-sea-machine.rl" - {te = p;p--;{ found_syllable (non_sea_cluster); }} - break; - case 1: -#line 61 "hb-ot-shape-complex-sea-machine.rl" - {{p = ((te))-1;}{ found_syllable (consonant_syllable); }} - break; - case 3: -#line 62 "hb-ot-shape-complex-sea-machine.rl" - {{p = ((te))-1;}{ found_syllable (broken_cluster); }} - break; -#line 194 "hb-ot-shape-complex-sea-machine.hh" - } - -_again: - switch ( _sea_syllable_machine_to_state_actions[cs] ) { - case 4: -#line 1 "NONE" - {ts = 0;} - break; -#line 203 "hb-ot-shape-complex-sea-machine.hh" - } - - if ( ++p != pe ) - goto _resume; - _test_eof: {} - if ( p == eof ) - { - if ( _sea_syllable_machine_eof_trans[cs] > 0 ) { - _trans = _sea_syllable_machine_eof_trans[cs] - 1; - goto _eof_trans; - } - } - - } - -#line 97 "hb-ot-shape-complex-sea-machine.rl" - -} - -#undef found_syllable - -#endif /* HB_OT_SHAPE_COMPLEX_SEA_MACHINE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc deleted file mode 100644 index f08b7ccb9f..0000000000 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-sea.cc +++ /dev/null @@ -1,380 +0,0 @@ -/* - * Copyright © 2011,2012,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 - */ - -#include "hb-ot-shape-complex-indic-private.hh" - -/* buffer var allocations */ -#define sea_category() complex_var_u8_0() /* indic_category_t */ -#define sea_position() complex_var_u8_1() /* indic_position_t */ - - -/* - * South-East Asian shaper. - * Loosely based on the Myanmar spec / shaper. - * There is no OpenType spec for this. - */ - -static const hb_tag_t -basic_features[] = -{ - /* - * Basic features. - * These features are applied in order, one at a time, after initial_reordering. - */ - HB_TAG('p','r','e','f'), - HB_TAG('a','b','v','f'), - HB_TAG('b','l','w','f'), - HB_TAG('p','s','t','f'), -}; -static const hb_tag_t -other_features[] = -{ - /* - * Other features. - * These features are applied all at once, after final_reordering. - */ - HB_TAG('p','r','e','s'), - HB_TAG('a','b','v','s'), - HB_TAG('b','l','w','s'), - HB_TAG('p','s','t','s'), - /* Positioning features, though we don't care about the types. */ - HB_TAG('d','i','s','t'), -}; - -static void -setup_syllables (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); -static void -initial_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); -static void -final_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer); - -static void -collect_features_sea (hb_ot_shape_planner_t *plan) -{ - hb_ot_map_builder_t *map = &plan->map; - - /* Do this before any lookups have been applied. */ - map->add_gsub_pause (setup_syllables); - - map->add_global_bool_feature (HB_TAG('l','o','c','l')); - /* The Indic specs do not require ccmp, but we apply it here since if - * there is a use of it, it's typically at the beginning. */ - map->add_global_bool_feature (HB_TAG('c','c','m','p')); - - map->add_gsub_pause (initial_reordering); - for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) - { - map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); - map->add_gsub_pause (NULL); - } - map->add_gsub_pause (final_reordering); - for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) - map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); -} - -static void -override_features_sea (hb_ot_shape_planner_t *plan) -{ - plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL); -} - - -enum syllable_type_t { - consonant_syllable, - broken_cluster, - non_sea_cluster, -}; - -#include "hb-ot-shape-complex-sea-machine.hh" - - -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum sea_category_t { -// OT_C = 1, - OT_GB = 12, /* Generic Base XXX DOTTED CIRCLE only for now */ -// OT_H = 4, /* Halant */ - OT_IV = 2, /* Independent Vowel */ - OT_MR = 22, /* Medial Ra */ -// OT_CM = 17, /* Consonant Medial */ - OT_VAbv = 26, - OT_VBlw = 27, - OT_VPre = 28, - OT_VPst = 29, - OT_T = 3, /* Tone Marks */ -// OT_A = 10, /* Anusvara */ -}; - -static inline void -set_sea_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); - indic_position_t pos = (indic_position_t) (type >> 8); - - /* Medial Ra */ - if (u == 0x1A55u || u == 0xAA34u) - cat = (indic_category_t) OT_MR; - - if (cat == OT_M) - { - switch ((int) pos) - { - case POS_PRE_C: cat = (indic_category_t) OT_VPre; break; - case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; - case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; - case POS_POST_C: cat = (indic_category_t) OT_VPst; break; - } - } - - info.sea_category() = (sea_category_t) cat; - info.sea_position() = pos; -} - - -static void -setup_masks_sea (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_buffer_t *buffer, - hb_font_t *font HB_UNUSED) -{ - HB_BUFFER_ALLOCATE_VAR (buffer, sea_category); - HB_BUFFER_ALLOCATE_VAR (buffer, sea_position); - - /* We cannot setup masks here. We save information about characters - * and setup masks later on in a pause-callback. */ - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - set_sea_properties (info[i]); -} - -static void -setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) -{ - find_syllables (buffer); -} - -static int -compare_sea_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb) -{ - int a = pa->sea_position(); - int b = pb->sea_position(); - - return a < b ? -1 : a == b ? 0 : +1; -} - - -static void -initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int base = start; - - /* Reorder! */ - unsigned int i = start; - for (; i < base; i++) - info[i].sea_position() = POS_PRE_C; - if (i < end) - { - info[i].sea_position() = POS_BASE_C; - i++; - } - for (; i < end; i++) - { - if (info[i].sea_category() == OT_MR) /* Pre-base reordering */ - { - info[i].sea_position() = POS_PRE_C; - continue; - } - if (info[i].sea_category() == OT_VPre) /* Left matra */ - { - info[i].sea_position() = POS_PRE_M; - continue; - } - - info[i].sea_position() = POS_AFTER_MAIN; - } - - buffer->merge_clusters (start, end); - /* Sit tight, rock 'n roll! */ - hb_bubble_sort (info + start, end - start, compare_sea_order); -} - -static void -initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - /* We already inserted dotted-circles, so just call the consonant_syllable. */ - initial_reordering_consonant_syllable (plan, face, buffer, start, end); -} - -static void -initial_reordering_non_sea_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_syllable (const hb_ot_shape_plan_t *plan, - hb_face_t *face, - hb_buffer_t *buffer, - unsigned int start, unsigned int end) -{ - syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); - switch (syllable_type) { - case consonant_syllable: initial_reordering_consonant_syllable (plan, 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; - } -} - -static inline void -insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_font_t *font, - hb_buffer_t *buffer) -{ - /* Note: This loop is extra overhead, but should not be measurable. */ - bool has_broken_syllables = false; - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - for (unsigned int i = 0; i < count; i++) - if ((info[i].syllable() & 0x0F) == broken_cluster) - { - has_broken_syllables = true; - break; - } - if (likely (!has_broken_syllables)) - return; - - - hb_codepoint_t dottedcircle_glyph; - if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) - return; - - hb_glyph_info_t dottedcircle = {0}; - dottedcircle.codepoint = 0x25CCu; - set_sea_properties (dottedcircle); - dottedcircle.codepoint = dottedcircle_glyph; - - buffer->clear_output (); - - buffer->idx = 0; - unsigned int last_syllable = 0; - while (buffer->idx < buffer->len) - { - unsigned int syllable = buffer->cur().syllable(); - syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); - if (unlikely (last_syllable != syllable && syllable_type == broken_cluster)) - { - last_syllable = syllable; - - hb_glyph_info_t info = dottedcircle; - info.cluster = buffer->cur().cluster; - info.mask = buffer->cur().mask; - info.syllable() = buffer->cur().syllable(); - - buffer->output_info (info); - } - else - buffer->next_glyph (); - } - - buffer->swap_buffers (); -} - -static void -initial_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) -{ - insert_dotted_circles (plan, font, buffer); - - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - if (unlikely (!count)) return; - unsigned int last = 0; - unsigned int last_syllable = info[0].syllable(); - for (unsigned int i = 1; i < count; i++) - if (last_syllable != info[i].syllable()) { - initial_reordering_syllable (plan, font->face, buffer, last, i); - last = i; - last_syllable = info[last].syllable(); - } - initial_reordering_syllable (plan, font->face, buffer, last, count); -} - -static void -final_reordering (const hb_ot_shape_plan_t *plan, - hb_font_t *font HB_UNUSED, - hb_buffer_t *buffer) -{ - hb_glyph_info_t *info = buffer->info; - unsigned int count = buffer->len; - - /* Zero syllables now... */ - for (unsigned int i = 0; i < count; i++) - info[i].syllable() = 0; - - HB_BUFFER_DEALLOCATE_VAR (buffer, sea_category); - HB_BUFFER_DEALLOCATE_VAR (buffer, sea_position); -} - - -const hb_ot_complex_shaper_t _hb_ot_complex_shaper_sea = -{ - "sea", - collect_features_sea, - override_features_sea, - NULL, /* data_create */ - NULL, /* data_destroy */ - NULL, /* preprocess_text */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, - NULL, /* decompose */ - NULL, /* compose */ - setup_masks_sea, - HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, - false, /* fallback_position */ -}; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc index feb7fc7a14..8a8f2f7991 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-thai.cc @@ -139,7 +139,7 @@ thai_pua_shape (hb_codepoint_t u, thai_action_t action, hb_font_t *font) }; switch (action) { - default: assert (false); /* Fallthrough */ + default: assert (false); HB_FALLTHROUGH; case NOP: return u; case SD: pua_mappings = SD_mappings; break; case SDL: pua_mappings = SDL_mappings; break; @@ -353,7 +353,7 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan, { /* Since we decomposed, and NIKHAHIT is combining, merge clusters with the * previous cluster. */ - if (start) + if (start && buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) buffer->merge_out_clusters (start - 1, end); } } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh new file mode 100644 index 0000000000..ced9d97f28 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-machine.hh @@ -0,0 +1,548 @@ + +#line 1 "hb-ot-shape-complex-use-machine.rl" +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH +#define HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH + +#include "hb-private.hh" + + +#line 38 "hb-ot-shape-complex-use-machine.hh" +static const unsigned char _use_syllable_machine_trans_keys[] = { + 0u, 0u, 4u, 4u, 1u, 1u, 0u, 39u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, + 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, + 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, + 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, + 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, + 8u, 39u, 12u, 21u, 12u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, + 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, + 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u, + 42u, 42u, 0 +}; + +static const char _use_syllable_machine_key_spans[] = { + 0, 1, 1, 40, 1, 32, 32, 1, + 32, 32, 32, 19, 19, 19, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 1, 32, 32, 19, 19, + 19, 32, 32, 32, 32, 32, 32, 32, + 32, 10, 2, 32, 32, 32, 32, 19, + 19, 19, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 39, 32, 22, 2, + 1 +}; + +static const short _use_syllable_machine_index_offsets[] = { + 0, 0, 2, 4, 45, 47, 80, 113, + 115, 148, 181, 214, 234, 254, 274, 307, + 340, 373, 406, 439, 472, 505, 538, 571, + 604, 637, 670, 703, 705, 738, 771, 791, + 811, 831, 864, 897, 930, 963, 996, 1029, + 1062, 1095, 1106, 1109, 1142, 1175, 1208, 1241, + 1261, 1281, 1301, 1334, 1367, 1400, 1433, 1466, + 1499, 1532, 1565, 1598, 1631, 1671, 1704, 1727, + 1730 +}; + +static const char _use_syllable_machine_indicies[] = { + 1, 0, 3, 2, 4, 5, 6, + 4, 1, 5, 8, 8, 7, 8, 8, + 3, 9, 8, 8, 8, 4, 4, 10, + 11, 8, 8, 12, 13, 14, 15, 16, + 17, 18, 12, 19, 20, 21, 22, 23, + 24, 8, 25, 26, 27, 8, 29, 28, + 31, 30, 30, 32, 33, 30, 30, 30, + 30, 30, 30, 30, 30, 34, 35, 36, + 37, 38, 39, 40, 41, 35, 42, 34, + 43, 44, 45, 46, 30, 47, 48, 49, + 30, 31, 30, 30, 32, 33, 30, 30, + 30, 30, 30, 30, 30, 30, 50, 35, + 36, 37, 38, 39, 40, 41, 35, 42, + 43, 43, 44, 45, 46, 30, 47, 48, + 49, 30, 32, 51, 31, 30, 30, 32, + 33, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 35, 36, 37, 38, 39, 40, + 41, 35, 42, 43, 43, 44, 45, 46, + 30, 47, 48, 49, 30, 31, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 35, 36, 37, 38, 39, + 30, 30, 30, 30, 30, 30, 44, 45, + 46, 30, 47, 48, 49, 30, 31, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 36, 37, 38, + 39, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 47, 48, 49, 30, 31, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 37, + 38, 39, 30, 31, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 38, 39, 30, 31, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 39, 30, 31, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 37, 38, 39, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 47, 48, 49, 30, 31, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 37, 38, 39, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 48, 49, 30, 31, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 37, 38, 39, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 49, 30, 31, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 36, 37, 38, + 39, 30, 30, 30, 30, 30, 30, 44, + 45, 46, 30, 47, 48, 49, 30, 31, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 36, 37, + 38, 39, 30, 30, 30, 30, 30, 30, + 30, 45, 46, 30, 47, 48, 49, 30, + 31, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 36, + 37, 38, 39, 30, 30, 30, 30, 30, + 30, 30, 30, 46, 30, 47, 48, 49, + 30, 31, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 35, + 36, 37, 38, 39, 30, 41, 35, 30, + 30, 30, 44, 45, 46, 30, 47, 48, + 49, 30, 31, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 35, 36, 37, 38, 39, 30, 30, 35, + 30, 30, 30, 44, 45, 46, 30, 47, + 48, 49, 30, 31, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 35, 36, 37, 38, 39, 40, 41, + 35, 30, 30, 30, 44, 45, 46, 30, + 47, 48, 49, 30, 31, 30, 30, 32, + 33, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 35, 36, 37, 38, 39, 40, + 41, 35, 42, 30, 43, 44, 45, 46, + 30, 47, 48, 49, 30, 31, 30, 30, + 32, 33, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 35, 36, 37, 38, 39, + 40, 41, 35, 42, 34, 43, 44, 45, + 46, 30, 47, 48, 49, 30, 53, 52, + 52, 54, 55, 52, 52, 52, 52, 52, + 52, 52, 52, 56, 52, 57, 58, 59, + 60, 61, 62, 57, 63, 56, 64, 52, + 52, 52, 52, 65, 66, 67, 52, 53, + 52, 52, 54, 55, 52, 52, 52, 52, + 52, 52, 52, 52, 68, 52, 57, 58, + 59, 60, 61, 62, 57, 63, 64, 64, + 52, 52, 52, 52, 65, 66, 67, 52, + 54, 51, 53, 52, 52, 54, 55, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 57, 58, 59, 60, 61, 62, 57, + 63, 64, 64, 52, 52, 52, 52, 65, + 66, 67, 52, 53, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 57, 58, 59, 60, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 65, 66, 67, 52, 53, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 58, 59, 60, 52, + 53, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 59, 60, 52, 53, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 60, 52, + 53, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 58, 59, 60, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 65, 66, 67, + 52, 53, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 58, 59, 60, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 66, + 67, 52, 53, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 58, 59, 60, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 67, 52, 53, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 57, 58, 59, 60, 52, 62, + 57, 52, 52, 52, 52, 52, 52, 52, + 65, 66, 67, 52, 53, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 57, 58, 59, 60, 52, + 52, 57, 52, 52, 52, 52, 52, 52, + 52, 65, 66, 67, 52, 53, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 57, 58, 59, 60, + 61, 62, 57, 52, 52, 52, 52, 52, + 52, 52, 65, 66, 67, 52, 53, 52, + 52, 54, 55, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 57, 58, 59, + 60, 61, 62, 57, 63, 52, 64, 52, + 52, 52, 52, 65, 66, 67, 52, 53, + 52, 52, 54, 55, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 57, 58, + 59, 60, 61, 62, 57, 63, 56, 64, + 52, 52, 52, 52, 65, 66, 67, 52, + 70, 71, 69, 69, 69, 69, 69, 69, + 69, 72, 69, 70, 71, 69, 7, 73, + 73, 3, 9, 73, 73, 73, 73, 73, + 73, 73, 73, 74, 12, 13, 14, 15, + 16, 17, 18, 12, 19, 21, 21, 22, + 23, 24, 73, 25, 26, 27, 73, 7, + 73, 73, 3, 9, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 12, 13, 14, + 15, 16, 17, 18, 12, 19, 21, 21, + 22, 23, 24, 73, 25, 26, 27, 73, + 7, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 12, 13, + 14, 15, 16, 73, 73, 73, 73, 73, + 73, 22, 23, 24, 73, 25, 26, 27, + 73, 7, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 13, 14, 15, 16, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 25, 26, + 27, 73, 7, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 14, 15, 16, 73, 7, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 15, + 16, 73, 7, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 16, 73, 7, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 14, 15, + 16, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 25, 26, 27, 73, 7, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 14, + 15, 16, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 26, 27, 73, + 7, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 14, 15, 16, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 27, + 73, 7, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 13, 14, 15, 16, 73, 73, 73, 73, + 73, 73, 22, 23, 24, 73, 25, 26, + 27, 73, 7, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 13, 14, 15, 16, 73, 73, 73, + 73, 73, 73, 73, 23, 24, 73, 25, + 26, 27, 73, 7, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 13, 14, 15, 16, 73, 73, + 73, 73, 73, 73, 73, 73, 24, 73, + 25, 26, 27, 73, 7, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 12, 13, 14, 15, 16, 73, + 18, 12, 73, 73, 73, 22, 23, 24, + 73, 25, 26, 27, 73, 7, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 12, 13, 14, 15, 16, + 73, 73, 12, 73, 73, 73, 22, 23, + 24, 73, 25, 26, 27, 73, 7, 73, + 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 12, 13, 14, 15, + 16, 17, 18, 12, 73, 73, 73, 22, + 23, 24, 73, 25, 26, 27, 73, 7, + 73, 73, 3, 9, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 12, 13, 14, + 15, 16, 17, 18, 12, 19, 73, 21, + 22, 23, 24, 73, 25, 26, 27, 73, + 5, 6, 73, 73, 5, 73, 73, 7, + 73, 73, 3, 9, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 12, 13, 14, + 15, 16, 17, 18, 12, 19, 20, 21, + 22, 23, 24, 73, 25, 26, 27, 73, + 7, 73, 73, 3, 9, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 12, 13, + 14, 15, 16, 17, 18, 12, 19, 20, + 21, 22, 23, 24, 73, 25, 26, 27, + 73, 76, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 76, 77, 75, + 76, 77, 75, 77, 75, 0 +}; + +static const char _use_syllable_machine_trans_targs[] = { + 3, 41, 3, 43, 4, 5, 25, 3, + 0, 2, 60, 62, 45, 46, 47, 48, + 49, 56, 57, 58, 61, 59, 53, 54, + 55, 50, 51, 52, 3, 3, 3, 3, + 6, 7, 24, 9, 10, 11, 12, 13, + 20, 21, 22, 23, 17, 18, 19, 14, + 15, 16, 8, 3, 3, 3, 26, 27, + 40, 29, 30, 31, 32, 36, 37, 38, + 39, 33, 34, 35, 28, 3, 3, 1, + 42, 3, 44, 3, 63, 64 +}; + +static const char _use_syllable_machine_trans_actions[] = { + 1, 2, 3, 4, 0, 0, 0, 7, + 0, 0, 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 0, 0, + 0, 0, 0, 0, 8, 9, 10, 11, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 12, 13, 14, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 16, 0, + 2, 17, 4, 18, 0, 0 +}; + +static const char _use_syllable_machine_to_state_actions[] = { + 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const char _use_syllable_machine_from_state_actions[] = { + 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const short _use_syllable_machine_eof_trans[] = { + 0, 1, 3, 0, 29, 31, 31, 52, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 53, 53, 52, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, + 53, 70, 70, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 76, 76, + 76 +}; + +static const int use_syllable_machine_start = 3; +static const int use_syllable_machine_first_final = 3; +static const int use_syllable_machine_error = 0; + +static const int use_syllable_machine_en_main = 3; + + +#line 38 "hb-ot-shape-complex-use-machine.rl" + + + +#line 145 "hb-ot-shape-complex-use-machine.rl" + + +#define found_syllable(syllable_type) \ + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \ + for (unsigned int i = last; i < p+1; i++) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + last = p+1; \ + syllable_serial++; \ + if (unlikely (syllable_serial == 16)) syllable_serial = 1; \ + } HB_STMT_END + +static void +find_syllables (hb_buffer_t *buffer) +{ + unsigned int p, pe, eof, ts HB_UNUSED, te HB_UNUSED, act HB_UNUSED; + int cs; + hb_glyph_info_t *info = buffer->info; + +#line 388 "hb-ot-shape-complex-use-machine.hh" + { + cs = use_syllable_machine_start; + ts = 0; + te = 0; + act = 0; + } + +#line 166 "hb-ot-shape-complex-use-machine.rl" + + + p = 0; + pe = eof = buffer->len; + + unsigned int last = 0; + unsigned int syllable_serial = 1; + +#line 405 "hb-ot-shape-complex-use-machine.hh" + { + int _slen; + int _trans; + const unsigned char *_keys; + const char *_inds; + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + switch ( _use_syllable_machine_from_state_actions[cs] ) { + case 6: +#line 1 "NONE" + {ts = p;} + break; +#line 421 "hb-ot-shape-complex-use-machine.hh" + } + + _keys = _use_syllable_machine_trans_keys + (cs<<1); + _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs]; + + _slen = _use_syllable_machine_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=( info[p].use_category()) && + ( info[p].use_category()) <= _keys[1] ? + ( info[p].use_category()) - _keys[0] : _slen ]; + +_eof_trans: + cs = _use_syllable_machine_trans_targs[_trans]; + + if ( _use_syllable_machine_trans_actions[_trans] == 0 ) + goto _again; + + switch ( _use_syllable_machine_trans_actions[_trans] ) { + case 2: +#line 1 "NONE" + {te = p+1;} + break; + case 9: +#line 134 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (independent_cluster); }} + break; + case 11: +#line 136 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (consonant_cluster); }} + break; + case 14: +#line 137 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (vowel_cluster); }} + break; + case 16: +#line 138 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (number_joiner_terminated_cluster); }} + break; + case 7: +#line 141 "hb-ot-shape-complex-use-machine.rl" + {te = p+1;{ found_syllable (broken_cluster); }} + break; + case 8: +#line 134 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (independent_cluster); }} + break; + case 12: +#line 135 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (virama_terminated_cluster); }} + break; + case 10: +#line 136 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (consonant_cluster); }} + break; + case 13: +#line 137 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (vowel_cluster); }} + break; + case 15: +#line 139 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (numeral_cluster); }} + break; + case 18: +#line 140 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (symbol_cluster); }} + break; + case 17: +#line 141 "hb-ot-shape-complex-use-machine.rl" + {te = p;p--;{ found_syllable (broken_cluster); }} + break; + case 1: +#line 139 "hb-ot-shape-complex-use-machine.rl" + {{p = ((te))-1;}{ found_syllable (numeral_cluster); }} + break; + case 3: +#line 1 "NONE" + { switch( act ) { + case 0: + {{cs = 0; goto _again;}} + break; + case 8: + {{p = ((te))-1;} found_syllable (broken_cluster); } + break; + } + } + break; + case 4: +#line 1 "NONE" + {te = p+1;} +#line 141 "hb-ot-shape-complex-use-machine.rl" + {act = 8;} + break; +#line 513 "hb-ot-shape-complex-use-machine.hh" + } + +_again: + switch ( _use_syllable_machine_to_state_actions[cs] ) { + case 5: +#line 1 "NONE" + {ts = 0;} +#line 1 "NONE" + {act = 0;} + break; +#line 524 "hb-ot-shape-complex-use-machine.hh" + } + + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _use_syllable_machine_eof_trans[cs] > 0 ) { + _trans = _use_syllable_machine_eof_trans[cs] - 1; + goto _eof_trans; + } + } + + _out: {} + } + +#line 175 "hb-ot-shape-complex-use-machine.rl" + +} + +#undef found_syllable + +#endif /* HB_OT_SHAPE_COMPLEX_USE_MACHINE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh new file mode 100644 index 0000000000..a143736211 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-private.hh @@ -0,0 +1,97 @@ +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH +#define HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH + +#include "hb-private.hh" + + +#include "hb-ot-shape-complex-private.hh" + + +#define USE_TABLE_ELEMENT_TYPE uint8_t + +/* Cateories used in the Universal Shaping Engine spec: + * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + */ +/* Note: This enum is duplicated in the -machine.rl source file. + * Not sure how to avoid duplication. */ +enum use_category_t { + USE_O = 0, /* OTHER */ + + USE_B = 1, /* BASE */ + USE_IV = 2, /* BASE_VOWEL */ + USE_IND = 3, /* BASE_IND */ + USE_N = 4, /* BASE_NUM */ + USE_GB = 5, /* BASE_OTHER */ + USE_CGJ = 6, /* CGJ */ +// USE_F = 7, /* CONS_FINAL */ + USE_FM = 8, /* CONS_FINAL_MOD */ +// USE_M = 9, /* CONS_MED */ +// USE_CM = 10, /* CONS_MOD */ + USE_SUB = 11, /* CONS_SUB */ + USE_H = 12, /* HALANT */ + + USE_HN = 13, /* HALANT_NUM */ + USE_ZWNJ = 14, /* Zero width non-joiner */ + USE_ZWJ = 15, /* Zero width joiner */ + USE_WJ = 16, /* Word joiner */ + USE_Rsv = 17, /* Reserved characters */ + USE_R = 18, /* REPHA */ + USE_S = 19, /* SYM */ +// USE_SM = 20, /* SYM_MOD */ + USE_VS = 21, /* VARIATION_SELECTOR */ +// USE_V = 36, /* VOWEL */ +// USE_VM = 40, /* VOWEL_MOD */ + + USE_FAbv = 24, /* CONS_FINAL_ABOVE */ + USE_FBlw = 25, /* CONS_FINAL_BELOW */ + USE_FPst = 26, /* CONS_FINAL_POST */ + USE_MAbv = 27, /* CONS_MED_ABOVE */ + USE_MBlw = 28, /* CONS_MED_BELOW */ + USE_MPst = 29, /* CONS_MED_POST */ + USE_MPre = 30, /* CONS_MED_PRE */ + USE_CMAbv = 31, /* CONS_MOD_ABOVE */ + USE_CMBlw = 32, /* CONS_MOD_BELOW */ + USE_VAbv = 33, /* VOWEL_ABOVE / VOWEL_ABOVE_BELOW / VOWEL_ABOVE_BELOW_POST / VOWEL_ABOVE_POST */ + USE_VBlw = 34, /* VOWEL_BELOW / VOWEL_BELOW_POST */ + USE_VPst = 35, /* VOWEL_POST UIPC = Right */ + USE_VPre = 22, /* VOWEL_PRE / VOWEL_PRE_ABOVE / VOWEL_PRE_ABOVE_POST / VOWEL_PRE_POST */ + USE_VMAbv = 37, /* VOWEL_MOD_ABOVE */ + USE_VMBlw = 38, /* VOWEL_MOD_BELOW */ + USE_VMPst = 39, /* VOWEL_MOD_POST */ + USE_VMPre = 23, /* VOWEL_MOD_PRE */ + USE_SMAbv = 41, /* SYM_MOD_ABOVE */ + USE_SMBlw = 42 /* SYM_MOD_BELOW */ +}; + +HB_INTERNAL USE_TABLE_ELEMENT_TYPE +hb_use_get_categories (hb_codepoint_t u); + +#endif /* HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc new file mode 100644 index 0000000000..6cd1c5db75 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use-table.cc @@ -0,0 +1,696 @@ +/* == Start of generated table == */ +/* + * The following table is generated by running: + * + * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt + * + * on files with these headers: + * + * # IndicSyllabicCategory-8.0.0.txt + * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI] + * # IndicPositionalCategory-8.0.0.txt + * # Date: 2015-05-12, 10:00:00 GMT [RP, KW, LI] + * # Blocks-8.0.0.txt + * # Date: 2014-11-10, 23:04:00 GMT [KW] + * UnicodeData.txt does not have a header. + */ + +#include "hb-ot-shape-complex-use-private.hh" + +#define B USE_B /* BASE */ +#define CGJ USE_CGJ /* CGJ */ +#define FM USE_FM /* CONS_FINAL_MOD */ +#define GB USE_GB /* BASE_OTHER */ +#define H USE_H /* HALANT */ +#define HN USE_HN /* HALANT_NUM */ +#define IND USE_IND /* BASE_IND */ +#define IV USE_IV /* BASE_VOWEL */ +#define N USE_N /* BASE_NUM */ +#define O USE_O /* OTHER */ +#define R USE_R /* REPHA */ +#define Rsv USE_Rsv /* Reserved */ +#define S USE_S /* SYM */ +#define SUB USE_SUB /* CONS_SUB */ +#define VS USE_VS /* VARIATION_SELECTOR */ +#define WJ USE_WJ /* Word_Joiner */ +#define ZWJ USE_ZWJ /* ZWJ */ +#define ZWNJ USE_ZWNJ /* ZWNJ */ +#define CMBlw USE_CMBlw +#define CMAbv USE_CMAbv +#define FBlw USE_FBlw +#define FPst USE_FPst +#define FAbv USE_FAbv +#define MPre USE_MPre +#define MBlw USE_MBlw +#define MPst USE_MPst +#define MAbv USE_MAbv +#define SMBlw USE_SMBlw +#define SMAbv USE_SMAbv +#define VPre USE_VPre +#define VBlw USE_VBlw +#define VPst USE_VPst +#define VAbv USE_VAbv +#define VMPre USE_VMPre +#define VMBlw USE_VMBlw +#define VMPst USE_VMPst +#define VMAbv USE_VMAbv + +static const USE_TABLE_ELEMENT_TYPE use_table[] = { + + +#define use_offset_0x0028u 0 + + + /* Basic Latin */ + O, O, O, O, O, GB, O, O, + /* 0030 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0x00a0u 24 + + + /* Latin-1 Supplement */ + + /* 00A0 */ GB, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00B0 */ O, O, FM, FM, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 00D0 */ O, O, O, O, O, O, O, GB, + +#define use_offset_0x0900u 80 + + + /* Devanagari */ + + /* 0900 */ VMAbv, VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 0910 */ IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0930 */ B, B, B, B, B, B, B, B, B, B, VAbv, VPst, CMBlw, B, VPst, VPre, + /* 0940 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst, + /* 0950 */ O, VMAbv, VMBlw, O, O, VAbv, VBlw, VBlw, B, B, B, B, B, B, B, B, + /* 0960 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0970 */ O, O, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, + + /* Bengali */ + + /* 0980 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 0990 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre, + /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, IND, O, + /* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B, + /* 09E0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Gurmukhi */ + + /* 0A00 */ O, VMAbv, VMAbv, VMPst, O, IV, IV, IV, IV, IV, IV, O, O, O, O, IV, + /* 0A10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0A20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0A30 */ B, O, B, B, O, B, B, O, B, B, O, O, CMBlw, O, VPst, VPre, + /* 0A40 */ VPst, VBlw, VBlw, O, O, O, O, VAbv, VAbv, O, O, VAbv, VAbv, H, O, O, + /* 0A50 */ O, O, O, O, O, O, O, O, O, B, B, B, B, O, B, O, + /* 0A60 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0A70 */ VMAbv, CMAbv, GB, GB, O, MBlw, O, O, O, O, O, O, O, O, O, O, + + /* Gujarati */ + + /* 0A80 */ O, VMAbv, VMAbv, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, + /* 0A90 */ IV, IV, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0AA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0AB0 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPre, + /* 0AC0 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, O, VAbv, VAbv, VAbv, O, VPst, VPst, H, O, O, + /* 0AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 0AE0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0AF0 */ O, O, O, O, O, O, O, O, O, B, O, O, O, O, O, O, + + /* Oriya */ + + /* 0B00 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 0B10 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv, + /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, + /* 0B50 */ O, O, O, O, O, O, VAbv, VAbv, O, O, O, O, B, B, O, B, + /* 0B60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Tamil */ + + /* 0B80 */ O, O, VMAbv, IND, O, IV, IV, IV, IV, IV, IV, O, O, O, IV, IV, + /* 0B90 */ IV, O, IV, IV, IV, B, O, O, O, B, B, O, B, O, B, B, + /* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B, + /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst, + /* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O, + /* 0BD0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O, + /* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Telugu */ + + /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0C10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0C20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0C30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, VAbv, VAbv, + /* 0C40 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O, + /* 0C50 */ O, O, O, O, O, VAbv, VBlw, O, B, B, B, O, O, O, O, O, + /* 0C60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0C70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Kannada */ + + /* 0C80 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0C90 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0CA0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 0CB0 */ B, B, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv, + /* 0CC0 */ VAbv, VPst, VPst, VPst, VPst, O, VAbv, VAbv, VAbv, O, VAbv, VAbv, VAbv, H, O, O, + /* 0CD0 */ O, O, O, O, O, VPst, VPst, O, O, O, O, O, O, O, B, O, + /* 0CE0 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0CF0 */ O, R, R, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Malayalam */ + + /* 0D00 */ O, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, IV, IV, + /* 0D10 */ IV, O, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, O, O, B, VPst, VPst, + /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O, + /* 0D50 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, IV, + /* 0D60 */ IV, IV, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND, + + /* Sinhala */ + + /* 0D80 */ O, O, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 0D90 */ IV, IV, IV, IV, IV, IV, IV, O, O, O, B, B, B, B, B, B, + /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O, + /* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst, + /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, + /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + /* 0DF0 */ O, O, VPst, VPst, O, O, O, O, + +#define use_offset_0x1000u 1352 + + + /* Myanmar */ + + /* 1000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1020 */ B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, VPst, VPst, VAbv, VAbv, VBlw, + /* 1030 */ VBlw, VPre, VAbv, VAbv, VAbv, VAbv, VMAbv, VMBlw, VMPst, H, VAbv, MPst, MPre, MBlw, MBlw, B, + /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, GB, O, + /* 1050 */ B, B, IV, IV, IV, IV, VPst, VPst, VBlw, VBlw, B, B, B, B, MBlw, MBlw, + /* 1060 */ MBlw, B, VPst, VMPst, VMPst, B, B, VPst, VPst, VMPst, VMPst, VMPst, VMPst, VMPst, B, B, + /* 1070 */ B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, B, B, B, B, B, B, + /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, + /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, + +#define use_offset_0x1700u 1512 + + + /* Tagalog */ + + /* 1700 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, + /* 1710 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O, + + /* Hanunoo */ + + /* 1720 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1730 */ B, B, VAbv, VBlw, VBlw, O, O, O, O, O, O, O, O, O, O, O, + + /* Buhid */ + + /* 1740 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1750 */ B, B, VAbv, VBlw, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Tagbanwa */ + + /* 1760 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, O, B, B, + /* 1770 */ B, O, VAbv, VBlw, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Khmer */ + + /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 17A0 */ B, B, B, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 17B0 */ IV, IV, IV, IV, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, + /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FM, FAbv, CMAbv, FM, FM, + /* 17D0 */ FM, VAbv, H, FM, O, O, O, O, O, O, O, O, B, VAbv, O, O, + /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0x1900u 1752 + + + /* Limbu */ + + /* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, + /* 1920 */ VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, O, O, O, O, + /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VAbv, FM, O, O, O, O, + /* 1940 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, + + /* Tai Le */ + + /* 1950 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1960 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, O, + /* 1970 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, + + /* New Tai Lue */ + + /* 1980 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 19A0 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, + /* 19B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 19C0 */ B, B, B, B, B, B, B, B, VMPst, VMPst, O, O, O, O, O, O, + /* 19D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 19E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 19F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Buginese */ + + /* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A10 */ B, B, B, B, B, B, B, VAbv, VBlw, VPre, VPst, VAbv, O, O, O, O, + + /* Tai Tham */ + + /* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, IV, + /* 1A50 */ IV, IV, IV, B, B, MPre, MBlw, FPst, FAbv, FAbv, FAbv, FBlw, FBlw, FBlw, FBlw, O, + /* 1A60 */ H, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, + /* 1A70 */ VPre, VPre, VPre, VAbv, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, FM, FM, FM, O, O, FM, + /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0x1b00u 2168 + + + /* Balinese */ + + /* 1B00 */ VMAbv, VMAbv, VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 1B10 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, + /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, + /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, + /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Sundanese */ + + /* 1B80 */ VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 1B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BA0 */ B, SUB, SUB, SUB, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, H, SUB, SUB, B, B, + /* 1BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + + /* Batak */ + + /* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1BE0 */ B, B, B, B, IV, IV, CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, + /* 1BF0 */ FAbv, FAbv, VPst, VPst, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Lepcha */ + + /* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv, + /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FM, CMBlw, O, O, O, O, O, O, O, O, + /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, + +#define use_offset_0x1cd0u 2504 + + + /* Vedic Extensions */ + + /* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw, + /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, + /* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, O, VMAbv, VMAbv, O, O, O, O, O, O, + +#define use_offset_0x2008u 2552 + + + /* General Punctuation */ + O, O, O, O, ZWNJ, ZWJ, O, O, + /* 2010 */ GB, GB, GB, GB, GB, O, O, O, + +#define use_offset_0x2060u 2568 + + /* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Superscripts and Subscripts */ + + /* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O, + /* 2080 */ O, O, FM, FM, FM, O, O, O, + +#define use_offset_0xa800u 2608 + + + /* Syloti Nagri */ + + /* A800 */ IV, IV, O, IV, IV, IV, VAbv, B, B, B, B, VMAbv, B, B, B, B, + /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A820 */ B, B, B, VPst, VPst, VBlw, VAbv, VPst, O, O, O, O, O, O, O, O, + /* A830 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Phags-pa */ + + /* A840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A870 */ B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Saurashtra */ + + /* A880 */ VMPst, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* A890 */ IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A8A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A8B0 */ B, B, B, B, FPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, + /* A8C0 */ VPst, VPst, VPst, VPst, H, O, O, O, O, O, O, O, O, O, O, O, + /* A8D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + + /* Devanagari Extended */ + + /* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, + /* A8F0 */ VMAbv, VMAbv, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Kayah Li */ + + /* A900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A920 */ B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VAbv, VMBlw, VMBlw, VMBlw, O, O, + + /* Rejang */ + + /* A930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A940 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VBlw, VBlw, VBlw, VBlw, FAbv, + /* A950 */ FAbv, FAbv, FPst, VPst, O, O, O, O, O, O, O, O, O, O, O, O, + /* A960 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A970 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Javanese */ + + /* A980 */ VMAbv, VMAbv, FAbv, VMPst, IV, IV, IV, IV, IV, B, B, B, IV, IV, IV, B, + /* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, SUB, MPst, MPst, + /* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* A9D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + + /* Myanmar Extended-B */ + + /* A9E0 */ B, B, B, B, B, VAbv, O, B, B, B, B, B, B, B, B, B, + /* A9F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, + + /* Cham */ + + /* AA00 */ IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, B, + /* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA20 */ B, B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, + /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MBlw, MBlw, O, O, O, O, O, O, O, O, O, + /* AA40 */ B, B, B, FAbv, B, B, B, B, B, B, B, B, FAbv, FPst, O, O, + /* AA50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + + /* Myanmar Extended-A */ + + /* AA60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA70 */ O, B, B, B, O, O, O, O, O, O, B, VMPst, VMAbv, VMPst, B, B, + + /* Tai Viet */ + + /* AA80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AA90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AAA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* AAB0 */ VAbv, B, VAbv, VAbv, VBlw, B, B, VAbv, VAbv, B, B, B, B, B, VAbv, VMAbv, + /* AAC0 */ B, VMAbv, B, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* AAD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Meetei Mayek Extensions */ + + /* AAE0 */ IV, IV, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, + /* AAF0 */ O, O, O, O, O, VMPst, H, O, + +#define use_offset_0xabc0u 3368 + + + /* Meetei Mayek */ + + /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, IV, IV, + /* ABD0 */ B, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, + /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0xfe00u 3432 + + + /* Variation Selectors */ + + /* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, + +#define use_offset_0x10a00u 3448 + + + /* Kharoshthi */ + + /* 10A00 */ B, VBlw, VBlw, VBlw, O, VAbv, VBlw, O, O, O, O, O, VBlw, VBlw, VMBlw, VMAbv, + /* 10A10 */ B, B, B, B, O, B, B, B, O, B, B, B, B, B, B, B, + /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 10A30 */ B, B, B, B, O, O, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, + /* 10A40 */ B, B, B, B, B, B, B, B, + +#define use_offset_0x11000u 3520 + + + /* Brahmi */ + + /* 11000 */ VMPst, VMAbv, VMPst, R, R, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 11010 */ IV, IV, IV, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, + /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O, + /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N, + /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, + /* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Kaithi */ + + /* 11080 */ VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, + /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, + +#define use_offset_0x11100u 3712 + + + /* Chakma */ + + /* 11100 */ VMAbv, VMAbv, VMAbv, IV, IV, IV, IV, B, B, B, B, B, B, B, B, B, + /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11120 */ B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv, + /* 11130 */ VAbv, VBlw, VBlw, H, VAbv, O, B, B, B, B, B, B, B, B, B, B, + /* 11140 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Mahajani */ + + /* 11150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11170 */ B, B, B, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Sharada */ + + /* 11180 */ VMAbv, VMAbv, VMPst, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, + /* 11190 */ IV, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, + /* 111C0 */ H, B, R, R, O, O, O, O, O, O, CMBlw, VAbv, VBlw, O, O, O, + /* 111D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + + /* Sinhala Archaic Numbers */ + + /* 111E0 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 111F0 */ B, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O, + + /* Khojki */ + + /* 11200 */ IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, B, B, + /* 11210 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, + /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, + +#define use_offset_0x11280u 4024 + + + /* Multani */ + + /* 11280 */ IV, IV, IV, IV, B, B, B, O, B, O, B, B, B, B, O, B, + /* 11290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, O, B, + /* 112A0 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, + + /* Khudawadi */ + + /* 112B0 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 112C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 112D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, + /* 112E0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, CMBlw, VBlw, O, O, O, O, O, + /* 112F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + + /* Grantha */ + + /* 11300 */ VMAbv, VMAbv, VMPst, VMPst, O, IV, IV, IV, IV, IV, IV, IV, IV, O, O, IV, + /* 11310 */ IV, O, O, IV, IV, B, B, B, B, B, B, B, B, B, B, B, + /* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, + /* 11330 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VPst, + /* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O, + /* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O, + /* 11360 */ IV, IV, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, + /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, + +#define use_offset_0x11480u 4272 + + + /* Tirhuta */ + + /* 11480 */ O, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, + /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv, + /* 114C0 */ VMAbv, VMPst, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, + /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + +#define use_offset_0x11580u 4368 + + + /* Siddham */ + + /* 11580 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, + /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, + /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H, + /* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 115D0 */ O, O, O, O, O, O, O, O, IV, IV, IV, IV, VBlw, VBlw, O, O, + /* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 115F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Modi */ + + /* 11600 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, + /* 11610 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11620 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11630 */ VPst, VPst, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPst, VPst, VMAbv, VMPst, H, + /* 11640 */ VAbv, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11650 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 11660 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 11670 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Takri */ + + /* 11680 */ IV, IV, IV, IV, IV, IV, IV, IV, IV, IV, B, B, B, B, B, B, + /* 11690 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 116A0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMPst, VAbv, VPre, VPst, + /* 116B0 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, CMBlw, O, O, O, O, O, O, O, O, + /* 116C0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, + /* 116D0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 116E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + /* 116F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, + + /* Ahom */ + + /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, + /* 11710 */ B, B, B, B, B, B, B, B, B, B, O, O, O, MBlw, MPre, MAbv, + /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O, + /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, + +}; /* Table items: 4816; occupancy: 72% */ + +USE_TABLE_ELEMENT_TYPE +hb_use_get_categories (hb_codepoint_t u) +{ + switch (u >> 12) + { + case 0x0u: + if (hb_in_range (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; + if (hb_in_range (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; + if (hb_in_range (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; + if (unlikely (u == 0x034Fu)) return CGJ; + break; + + case 0x1u: + if (hb_in_range (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u]; + if (hb_in_range (u, 0x1700u, 0x17EFu)) return use_table[u - 0x1700u + use_offset_0x1700u]; + if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u]; + if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u]; + if (hb_in_range (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u]; + break; + + case 0x2u: + if (hb_in_range (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u]; + if (hb_in_range (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u]; + if (unlikely (u == 0x25CCu)) return GB; + break; + + case 0xAu: + if (hb_in_range (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u]; + if (hb_in_range (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; + break; + + case 0xFu: + if (hb_in_range (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u]; + break; + + case 0x10u: + if (hb_in_range (u, 0x10A00u, 0x10A47u)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; + break; + + case 0x11u: + if (hb_in_range (u, 0x11000u, 0x110BFu)) return use_table[u - 0x11000u + use_offset_0x11000u]; + if (hb_in_range (u, 0x11100u, 0x11237u)) return use_table[u - 0x11100u + use_offset_0x11100u]; + if (hb_in_range (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; + if (hb_in_range (u, 0x11480u, 0x114DFu)) return use_table[u - 0x11480u + use_offset_0x11480u]; + if (hb_in_range (u, 0x11580u, 0x1173Fu)) return use_table[u - 0x11580u + use_offset_0x11580u]; + if (unlikely (u == 0x1107Fu)) return HN; + break; + + default: + break; + } + return USE_O; +} + +#undef B +#undef CGJ +#undef FM +#undef GB +#undef H +#undef HN +#undef IND +#undef IV +#undef N +#undef O +#undef R +#undef Rsv +#undef S +#undef SUB +#undef VS +#undef WJ +#undef ZWJ +#undef ZWNJ +#undef CMBlw +#undef CMAbv +#undef FBlw +#undef FPst +#undef FAbv +#undef MPre +#undef MBlw +#undef MPst +#undef MAbv +#undef SMBlw +#undef SMAbv +#undef VPre +#undef VBlw +#undef VPst +#undef VAbv +#undef VMPre +#undef VMBlw +#undef VMPst +#undef VMAbv + +/* == End of generated table == */ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc new file mode 100644 index 0000000000..779a9cb1d0 --- /dev/null +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-complex-use.cc @@ -0,0 +1,585 @@ +/* + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 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. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-ot-shape-complex-use-private.hh" +#include "hb-ot-shape-complex-arabic-private.hh" + +/* buffer var allocations */ +#define use_category() complex_var_u8_0() + + +/* + * Universal Shaping Engine. + * https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm + */ + +static const hb_tag_t +basic_features[] = +{ + /* + * Basic features. + * These features are applied all at once, before reordering. + */ + HB_TAG('r','k','r','f'), + HB_TAG('a','b','v','f'), + HB_TAG('b','l','w','f'), + HB_TAG('h','a','l','f'), + HB_TAG('p','s','t','f'), + HB_TAG('v','a','t','u'), + HB_TAG('c','j','c','t'), +}; +static const hb_tag_t +arabic_features[] = +{ + HB_TAG('i','s','o','l'), + HB_TAG('i','n','i','t'), + HB_TAG('m','e','d','i'), + HB_TAG('f','i','n','a'), + /* The spec doesn't specify these but we apply anyway, since our Arabic shaper + * does. These are only used in Syriac spec. */ + HB_TAG('m','e','d','2'), + HB_TAG('f','i','n','2'), + HB_TAG('f','i','n','3'), +}; +/* Same order as arabic_features. Don't need Syriac stuff.*/ +enum joining_form_t { + ISOL, + INIT, + MEDI, + FINA, + _NONE +}; +static const hb_tag_t +other_features[] = +{ + /* + * Other features. + * These features are applied all at once, after reordering. + */ + HB_TAG('a','b','v','s'), + HB_TAG('b','l','w','s'), + HB_TAG('h','a','l','n'), + HB_TAG('p','r','e','s'), + HB_TAG('p','s','t','s'), + /* Positioning features, though we don't care about the types. */ + HB_TAG('d','i','s','t'), + HB_TAG('a','b','v','m'), + HB_TAG('b','l','w','m'), +}; + +static void +setup_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +clear_substitution_flags (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +record_rphf (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +record_pref (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); +static void +reorder (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); + +static void +collect_features_use (hb_ot_shape_planner_t *plan) +{ + hb_ot_map_builder_t *map = &plan->map; + + /* Do this before any lookups have been applied. */ + map->add_gsub_pause (setup_syllables); + + /* "Default glyph pre-processing group" */ + map->add_global_bool_feature (HB_TAG('l','o','c','l')); + map->add_global_bool_feature (HB_TAG('c','c','m','p')); + map->add_global_bool_feature (HB_TAG('n','u','k','t')); + map->add_global_bool_feature (HB_TAG('a','k','h','n')); + + /* "Reordering group" */ + map->add_gsub_pause (clear_substitution_flags); + map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ); + map->add_gsub_pause (record_rphf); + map->add_gsub_pause (clear_substitution_flags); + map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); + map->add_gsub_pause (record_pref); + + /* "Orthographic unit shaping group" */ + for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) + map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + + map->add_gsub_pause (reorder); + + /* "Topographical features" */ + for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++) + map->add_feature (arabic_features[i], 1, F_NONE); + map->add_gsub_pause (NULL); + + /* "Standard typographic presentation" and "Positional feature application" */ + for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) + map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); +} + +struct use_shape_plan_t +{ + ASSERT_POD (); + + hb_mask_t rphf_mask; + + arabic_shape_plan_t *arabic_plan; +}; + +static bool +has_arabic_joining (hb_script_t script) +{ + /* List of scripts that have data in arabic-table. */ + switch ((int) script) + { + /* Unicode-1.1 additions */ + case HB_SCRIPT_ARABIC: + + /* Unicode-3.0 additions */ + case HB_SCRIPT_MONGOLIAN: + case HB_SCRIPT_SYRIAC: + + /* Unicode-5.0 additions */ + case HB_SCRIPT_NKO: + case HB_SCRIPT_PHAGS_PA: + + /* Unicode-6.0 additions */ + case HB_SCRIPT_MANDAIC: + + /* Unicode-7.0 additions */ + case HB_SCRIPT_MANICHAEAN: + case HB_SCRIPT_PSALTER_PAHLAVI: + + return true; + + default: + return false; + } +} + +static void * +data_create_use (const hb_ot_shape_plan_t *plan) +{ + use_shape_plan_t *use_plan = (use_shape_plan_t *) calloc (1, sizeof (use_shape_plan_t)); + if (unlikely (!use_plan)) + return NULL; + + use_plan->rphf_mask = plan->map.get_1_mask (HB_TAG('r','p','h','f')); + + if (has_arabic_joining (plan->props.script)) + { + use_plan->arabic_plan = (arabic_shape_plan_t *) data_create_arabic (plan); + if (unlikely (!use_plan->arabic_plan)) + { + free (use_plan); + return NULL; + } + } + + return use_plan; +} + +static void +data_destroy_use (void *data) +{ + use_shape_plan_t *use_plan = (use_shape_plan_t *) data; + + if (use_plan->arabic_plan) + data_destroy_arabic (use_plan->arabic_plan); + + free (data); +} + +enum syllable_type_t { + independent_cluster, + virama_terminated_cluster, + consonant_cluster, + vowel_cluster, + number_joiner_terminated_cluster, + numeral_cluster, + symbol_cluster, + broken_cluster, +}; + +#include "hb-ot-shape-complex-use-machine.hh" + + +static void +setup_masks_use (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font HB_UNUSED) +{ + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; + + /* Do this before allocating use_category(). */ + if (use_plan->arabic_plan) + { + setup_masks_arabic_plan (use_plan->arabic_plan, buffer, plan->props.script); + } + + HB_BUFFER_ALLOCATE_VAR (buffer, use_category); + + /* We cannot setup masks here. We save information about characters + * and setup masks later on in a pause-callback. */ + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + info[i].use_category() = hb_use_get_categories (info[i].codepoint); +} + +static void +setup_rphf_mask (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer) +{ + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; + + hb_mask_t mask = use_plan->rphf_mask; + if (!mask) return; + + hb_glyph_info_t *info = buffer->info; + + foreach_syllable (buffer, start, end) + { + unsigned int limit = info[start].use_category() == USE_R ? 1 : MIN (3u, end - start); + for (unsigned int i = start; i < start + limit; i++) + info[i].mask |= mask; + } +} + +static void +setup_topographical_masks (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer) +{ + + ASSERT_STATIC (INIT < 4 && ISOL < 4 && MEDI < 4 && FINA < 4); + hb_mask_t masks[4], all_masks = 0; + for (unsigned int i = 0; i < 4; i++) + { + masks[i] = plan->map.get_1_mask (arabic_features[i]); + if (masks[i] == plan->map.get_global_mask ()) + masks[i] = 0; + all_masks |= masks[i]; + } + if (!all_masks) + return; + hb_mask_t other_masks = ~all_masks; + + unsigned int last_start = 0; + joining_form_t last_form = _NONE; + hb_glyph_info_t *info = buffer->info; + foreach_syllable (buffer, start, end) + { + syllable_type_t syllable_type = (syllable_type_t) (info[start].syllable() & 0x0F); + switch (syllable_type) + { + case independent_cluster: + case symbol_cluster: + /* These don't join. Nothing to do. */ + last_form = _NONE; + break; + + case virama_terminated_cluster: + case consonant_cluster: + case vowel_cluster: + case number_joiner_terminated_cluster: + case numeral_cluster: + case broken_cluster: + + bool join = last_form == FINA || last_form == ISOL; + + if (join) + { + /* Fixup previous syllable's form. */ + last_form = last_form == FINA ? MEDI : INIT; + for (unsigned int i = last_start; i < start; i++) + info[i].mask = (info[i].mask & other_masks) | masks[last_form]; + } + + /* Form for this syllable. */ + last_form = join ? FINA : ISOL; + for (unsigned int i = start; i < end; i++) + info[i].mask = (info[i].mask & other_masks) | masks[last_form]; + + break; + } + + last_start = start; + } +} + +static void +setup_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + find_syllables (buffer); + setup_rphf_mask (plan, buffer); + setup_topographical_masks (plan, buffer); +} + +static void +clear_substitution_flags (const hb_ot_shape_plan_t *plan, + 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++) + _hb_glyph_info_clear_substituted_and_ligated_and_multiplied (&info[i]); +} + +static void +record_rphf (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; + + hb_mask_t mask = use_plan->rphf_mask; + if (!mask) return; + hb_glyph_info_t *info = buffer->info; + + foreach_syllable (buffer, start, end) + { + /* Mark a substituted repha as USE_R. */ + for (unsigned int i = start; i < end && (info[i].mask & mask); i++) + if (_hb_glyph_info_substituted (&info[i])) + { + info[i].use_category() = USE_R; + break; + } + } +} + +static void +record_pref (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; + + foreach_syllable (buffer, start, end) + { + /* Mark a substituted pref as VPre, as they behave the same way. */ + for (unsigned int i = start; i < end; i++) + if (_hb_glyph_info_substituted (&info[i])) + { + info[i].use_category() = USE_VPre; + break; + } + } +} + +static void +reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end) +{ + syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F); + /* Only a few syllable types need reordering. */ + if (unlikely (!(FLAG_SAFE (syllable_type) & + (FLAG (virama_terminated_cluster) | + FLAG (consonant_cluster) | + FLAG (vowel_cluster) | + FLAG (broken_cluster) | + 0)))) + return; + + hb_glyph_info_t *info = buffer->info; + +#define HALANT_FLAGS FLAG(USE_H) +#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB) | FLAG (USE_IV)) + + /* Move things forward. */ + if (info[start].use_category() == USE_R && end - start > 1) + { + /* Got a repha. Reorder it to after first base, before first halant. */ + for (unsigned int i = start + 1; i < end; i++) + if (FLAG_UNSAFE (info[i].use_category()) & (HALANT_FLAGS | BASE_FLAGS)) + { + /* If we hit a halant, move before it; otherwise it's a base: move to it's + * place, and shift things in between backward. */ + + if (info[i].use_category() == USE_H) + i--; + + buffer->merge_clusters (start, i + 1); + hb_glyph_info_t t = info[start]; + memmove (&info[start], &info[start + 1], (i - start) * sizeof (info[0])); + info[i] = t; + + break; + } + } + + /* Move things back. */ + unsigned int j = end; + for (unsigned int i = start; i < end; i++) + { + uint32_t flag = FLAG_UNSAFE (info[i].use_category()); + if (flag & (HALANT_FLAGS | BASE_FLAGS)) + { + /* If we hit a halant, move before it; otherwise it's a base: move to it's + * place, and shift things in between backward. */ + if (info[i].use_category() == USE_H) + j = i + 1; + else + j = i; + } + else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && + /* Only move the first component of a MultipleSubst. */ + 0 == _hb_glyph_info_get_lig_comp (&info[i]) && + j < i) + { + buffer->merge_clusters (j, i + 1); + hb_glyph_info_t t = info[i]; + memmove (&info[j + 1], &info[j], (i - j) * sizeof (info[0])); + info[j] = t; + } + } +} + +static inline void +insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font, + hb_buffer_t *buffer) +{ + /* Note: This loop is extra overhead, but should not be measurable. */ + bool has_broken_syllables = false; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + if ((info[i].syllable() & 0x0F) == broken_cluster) + { + has_broken_syllables = true; + break; + } + if (likely (!has_broken_syllables)) + return; + + + hb_codepoint_t dottedcircle_glyph; + if (!font->get_glyph (0x25CCu, 0, &dottedcircle_glyph)) + return; + + hb_glyph_info_t dottedcircle = {0}; + if (!font->get_glyph (0x25CCu, 0, &dottedcircle.codepoint)) + return; + dottedcircle.use_category() = hb_use_get_categories (0x25CC); + + buffer->clear_output (); + + buffer->idx = 0; + + unsigned int last_syllable = 0; + while (buffer->idx < buffer->len) + { + unsigned int syllable = buffer->cur().syllable(); + syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F); + if (unlikely (last_syllable != syllable && syllable_type == broken_cluster)) + { + last_syllable = syllable; + + hb_glyph_info_t ginfo = dottedcircle; + ginfo.cluster = buffer->cur().cluster; + ginfo.mask = buffer->cur().mask; + ginfo.syllable() = buffer->cur().syllable(); + /* TODO Set glyph_props? */ + + /* Insert dottedcircle after possible Repha. */ + while (buffer->idx < buffer->len && + last_syllable == buffer->cur().syllable() && + buffer->cur().use_category() == USE_R) + buffer->next_glyph (); + + buffer->output_info (ginfo); + } + else + buffer->next_glyph (); + } + + buffer->swap_buffers (); +} + +static void +reorder (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) +{ + insert_dotted_circles (plan, font, buffer); + + hb_glyph_info_t *info = buffer->info; + + foreach_syllable (buffer, start, end) + reorder_syllable (buffer, start, end); + + /* Zero syllables now... */ + unsigned int count = buffer->len; + for (unsigned int i = 0; i < count; i++) + info[i].syllable() = 0; + + HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); +} + +static bool +compose_use (const hb_ot_shape_normalize_context_t *c, + hb_codepoint_t a, + hb_codepoint_t b, + hb_codepoint_t *ab) +{ + /* Avoid recomposing split matras. */ + if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a))) + return false; + + return c->unicode->compose (a, b, ab); +} + + +const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use = +{ + "use", + collect_features_use, + NULL, /* override_features */ + data_create_use, + data_destroy_use, + NULL, /* preprocess_text */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, + NULL, /* decompose */ + compose_use, + setup_masks_use, + HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, + false, /* fallback_position */ +}; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc index 53274b502a..3cb3456f1a 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-fallback.cc @@ -224,7 +224,7 @@ position_mark (const hb_ot_shape_plan_t *plan, pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing; break; } - /* Fall through */ + HB_FALLTHROUGH; default: case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: @@ -259,6 +259,7 @@ position_mark (const hb_ot_shape_plan_t *plan, case HB_UNICODE_COMBINING_CLASS_BELOW_RIGHT: /* Add gap, fall-through. */ base_extents.height -= y_gap; + HB_FALLTHROUGH; case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW_LEFT: case HB_UNICODE_COMBINING_CLASS_ATTACHED_BELOW: @@ -279,6 +280,7 @@ position_mark (const hb_ot_shape_plan_t *plan, /* Add gap, fall-through. */ base_extents.y_bearing += y_gap; base_extents.height -= y_gap; + HB_FALLTHROUGH; case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE: case HB_UNICODE_COMBINING_CLASS_ATTACHED_ABOVE_RIGHT: @@ -418,13 +420,12 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan, _hb_buffer_assert_gsubgpos_vars (buffer); unsigned int start = 0; - unsigned int last_cluster = buffer->info[0].cluster; unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (buffer->info[i].cluster != last_cluster) { + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) { position_cluster (plan, font, buffer, start, i); start = i; - last_cluster = buffer->info[i].cluster; } position_cluster (plan, font, buffer, start, count); } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc index 8cc64af014..0a4d40499f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc @@ -62,24 +62,12 @@ * with previous base, use that. This needs the itemizer to have this * knowledge too. We need to provide assistance to the itemizer. * - * - When a font does not support a character but supports its decomposition, - * well, use the decomposition (preferring the canonical decomposition, but - * falling back to the compatibility decomposition if necessary). The - * compatibility decomposition is really nice to have, for characters like - * ellipsis, or various-sized space characters. + * - When a font does not support a character but supports its canonical + * decomposition, well, use the decomposition. * * - The complex shapers can customize the compose and decompose functions to * offload some of their requirements to the normalizer. For example, the * Indic shaper may want to disallow recomposing of two matras. - * - * - We try compatibility decomposition if decomposing through canonical - * decomposition alone failed to find a sequence that the font supports. - * We don't try compatibility decomposition recursively during the canonical - * decomposition phase. This has minimal impact. There are only a handful - * of Greek letter that have canonical decompositions that include characters - * with compatibility decomposition. Those can be found using this command: - * - * egrep "`echo -n ';('; grep ';<' UnicodeData.txt | cut -d';' -f1 | tr '\n' '|'; echo ') '`" UnicodeData.txt */ static bool @@ -171,28 +159,6 @@ decompose (const hb_ot_shape_normalize_context_t *c, bool shortest, hb_codepoint return 0; } -/* Returns 0 if didn't decompose, number of resulting characters otherwise. */ -static inline unsigned int -decompose_compatibility (const hb_ot_shape_normalize_context_t *c, hb_codepoint_t u) -{ - unsigned int len, i; - hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN]; - hb_codepoint_t glyphs[HB_UNICODE_MAX_DECOMPOSITION_LEN]; - - len = c->buffer->unicode->decompose_compatibility (u, decomposed); - if (!len) - return 0; - - for (i = 0; i < len; i++) - if (!c->font->get_glyph (decomposed[i], 0, &glyphs[i])) - return 0; - - for (i = 0; i < len; i++) - output_char (c->buffer, decomposed[i], glyphs[i]); - - return len; -} - static inline void decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest) { @@ -207,8 +173,6 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor skip_char (buffer); else if (!shortest && c->font->get_glyph (u, 0, &glyph)) next_char (buffer, glyph); - else if (decompose_compatibility (c, u)) - skip_char (buffer); else next_char (buffer, glyph); /* glyph is initialized in earlier branches. */ } @@ -290,6 +254,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, hb_font_t *font) { + if (unlikely (!buffer->len)) return; + _hb_buffer_assert_unicode_vars (buffer); hb_ot_shape_normalization_mode_t mode = plan->shaper->normalization_preference; @@ -323,7 +289,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, { unsigned int end; for (end = buffer->idx + 1; end < count; end++) - if (buffer->cur().cluster != buffer->info[end].cluster) + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end])))) break; decompose_cluster (&c, end, might_short_circuit, always_short_circuit); @@ -344,15 +310,13 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0) break; - /* We are going to do a bubble-sort. Only do this if the - * sequence is short. Doing it on long sequences can result - * in an O(n^2) DoS. */ + /* We are going to do a O(n^2). Only do this if the sequence is short. */ if (end - i > 10) { i = end; continue; } - hb_bubble_sort (buffer->info + i, end - i, compare_combining_class); + buffer->sort (i, end, compare_combining_class); i = end; } diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc index 07adb04f67..40332d69f1 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc @@ -59,10 +59,6 @@ static hb_tag_t horizontal_features[] = { HB_TAG('r','c','l','t'), }; -static hb_tag_t vertical_features[] = { - HB_TAG('v','e','r','t'), -}; - static void @@ -105,10 +101,13 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, (horizontal_features[i] == HB_TAG('k','e','r','n') ? F_HAS_FALLBACK : F_NONE)); else - for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++) - map->add_feature (vertical_features[i], 1, F_GLOBAL | - (vertical_features[i] == HB_TAG('v','k','r','n') ? - F_HAS_FALLBACK : F_NONE)); + { + /* We really want to find a 'vert' feature if there's any in the font, no + * matter which script/langsys it is listed (or not) under. + * See various bugs referenced from: + * https://github.com/behdad/harfbuzz/issues/63 */ + map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH); + } if (planner->shaper->override_features) planner->shaper->override_features (planner); @@ -264,11 +263,22 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) static void hb_form_clusters (hb_buffer_t *buffer) { + if (buffer->cluster_level != HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES) + return; + + /* Loop duplicated in hb_ensure_native_direction(). */ + unsigned int base = 0; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 1; i < count; i++) - if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i]))) - buffer->merge_clusters (i - 1, i + 1); + { + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) + { + buffer->merge_clusters (base, i); + base = i; + } + } + buffer->merge_clusters (base, count); } static void @@ -283,7 +293,28 @@ hb_ensure_native_direction (hb_buffer_t *buffer) if ((HB_DIRECTION_IS_HORIZONTAL (direction) && direction != hb_script_get_horizontal_direction (buffer->props.script)) || (HB_DIRECTION_IS_VERTICAL (direction) && direction != HB_DIRECTION_TTB)) { - hb_buffer_reverse_clusters (buffer); + /* Same loop as hb_form_clusters(). + * Since form_clusters() merged clusters already, we don't merge. */ + unsigned int base = 0; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 1; i < count; i++) + { + if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))) + { + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + buffer->merge_clusters (base, i); + buffer->reverse_range (base, i); + + base = i; + } + } + if (buffer->cluster_level == HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS) + buffer->merge_clusters (base, count); + buffer->reverse_range (base, count); + + buffer->reverse (); + buffer->props.direction = HB_DIRECTION_REVERSE (buffer->props.direction); } } @@ -305,7 +336,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c) hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) { hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint); - if (likely (codepoint == info[i].codepoint)) + if (likely (codepoint == info[i].codepoint || !c->font->has_glyph (codepoint))) info[i].mask |= rtlm_mask; else info[i].codepoint = codepoint; @@ -380,6 +411,101 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) } } +static void +hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c) +{ + hb_buffer_t *buffer = c->buffer; + + if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) + return; + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + unsigned int i = 0; + for (i = 0; i < count; i++) + if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) + pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; +} + +static void +hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) +{ + hb_buffer_t *buffer = c->buffer; + + if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) + return; + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + unsigned int i = 0; + for (i = 0; i < count; i++) + { + if (unlikely (_hb_glyph_info_is_default_ignorable (&info[i]))) + break; + } + + /* No default-ignorables found; return. */ + if (i == count) + return; + + hb_codepoint_t space; + if (c->font->get_glyph (' ', 0, &space)) + { + /* Replace default-ignorables with a zero-advance space glyph. */ + for (/*continue*/; i < count; i++) + { + if (_hb_glyph_info_is_default_ignorable (&info[i])) + info[i].codepoint = space; + } + } + else + { + /* Merge clusters and delete default-ignorables. + * NOTE! We can't use out-buffer as we have positioning data. */ + unsigned int j = i; + for (; i < count; i++) + { + if (_hb_glyph_info_is_default_ignorable (&info[i])) + { + /* Merge clusters. + * Same logic as buffer->delete_glyph(), but for in-place removal. */ + + unsigned int cluster = info[i].cluster; + if (i + 1 < count && cluster == info[i + 1].cluster) + continue; /* Cluster survives; do nothing. */ + + if (j) + { + /* Merge cluster backward. */ + if (cluster < info[j - 1].cluster) + { + unsigned int old_cluster = info[j - 1].cluster; + for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--) + info[k - 1].cluster = cluster; + } + continue; + } + + if (i + 1 < count) + buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */ + + continue; + } + + if (j != i) + { + info[j] = info[i]; + pos[j] = pos[i]; + } + j++; + } + buffer->len = j; + } +} + + static inline void hb_ot_map_glyphs_fast (hb_buffer_t *buffer) { @@ -388,6 +514,8 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer) hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) info[i].codepoint = info[i].glyph_index(); + + buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS; } static inline void @@ -625,6 +753,8 @@ hb_ot_position (hb_ot_shape_context_t *c) hb_bool_t fallback = !hb_ot_position_complex (c); + hb_ot_zero_width_default_ignorables (c); + hb_ot_layout_position_finish (c->font, c->buffer); if (fallback && c->plan->shaper->fallback_position) @@ -642,53 +772,6 @@ hb_ot_position (hb_ot_shape_context_t *c) } -/* Post-process */ - -static void -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; - 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 (!_hb_glyph_info_ligated (&info[i]) && - _hb_glyph_info_is_default_ignorable (&info[i]))) - { - 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; - } - else - continue; /* Delete it. XXX Merge clusters? */ - } - if (j != i) - { - info[j] = info[i]; - pos[j] = pos[i]; - } - j++; - } - c->buffer->len = j; -} - - /* Pull it all together! */ static void @@ -736,6 +819,9 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan, } +/** + * Since: 0.9.7 + **/ void hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan, hb_tag_t table_tag, @@ -766,6 +852,9 @@ add_char (hb_font_t *font, } +/** + * Since: 0.9.2 + **/ void hb_ot_shape_glyphs_closure (hb_font_t *font, hb_buffer_t *buffer, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc index 878dd79b62..a2e5728fcd 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-tag.cc @@ -175,6 +175,11 @@ typedef struct { * * Some items still missing. Those are commented out at the end. * Keep sorted for bsearch. + * + * Updated as of 2015-05-06: OT1.7 on MS website has some newer + * items that we don't have here, eg. Zazaki. This is the new + * items in OpenType 1.7 (red items), most of which we have: + * http://www.microsoft.com/typography/otspec170/languagetags.htm */ static const LangTag ot_languages[] = { @@ -217,9 +222,9 @@ static const LangTag ot_languages[] = { {"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */ {"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */ {"bcq", HB_TAG('B','C','H',' ')}, /* Bench */ - {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */ + {"be", HB_TAG('B','E','L',' ')}, /* Belarusian */ {"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */ - {"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */ + {"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 */ @@ -346,9 +351,9 @@ static const LangTag ot_languages[] = { {"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',' ')}, /* Hawaiian */ - {"hay", HB_TAG('H','A','Y',' ')}, /* Haya */ - {"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */ + {"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 */ @@ -542,6 +547,7 @@ static const LangTag ot_languages[] = { {"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */ {"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */ {"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */ + {"nv", HB_TAG('N','A','V',' ')}, /* Navajo */ {"ny", HB_TAG('C','H','I',' ')}, /* Chewa/Chichwa/Nyanja */ {"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */ {"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */ @@ -727,7 +733,6 @@ static const LangTag ot_languages[] = { /*{"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 */ @@ -826,6 +831,14 @@ hb_ot_tag_from_language (hb_language_t language) } } + /* + * The International Phonetic Alphabet is a variant tag in BCP-47, + * which can be applied to any language. + */ + if (strstr (lang_str, "-fonipa")) { + return HB_TAG('I','P','P','H'); /* Phonetic transcription—IPA conventions */ + } + /* Find a language matching in the first component */ { const LangTag *lang_tag; @@ -864,6 +877,15 @@ hb_ot_tag_from_language (hb_language_t language) return HB_OT_TAG_DEFAULT_LANGUAGE; } +/** + * hb_ot_tag_to_language: + * + * + * + * Return value: (transfer none): + * + * Since: 0.9.2 + **/ hb_language_t hb_ot_tag_to_language (hb_tag_t tag) { @@ -886,6 +908,12 @@ hb_ot_tag_to_language (hb_tag_t tag) } } + /* struct LangTag has only room for 3-letter language tags. */ + switch (tag) { + case HB_TAG('I','P','P','H'): /* Phonetic transcription—IPA conventions */ + return hb_language_from_string ("und-fonipa", -1); + } + /* Else return a custom language in the form of "x-hbotABCD" */ { unsigned char buf[11] = "x-hbot"; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-private.hh index 06d7f228a7..53e0510a92 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-private.hh @@ -54,6 +54,23 @@ #include <stdarg.h> +/* Compile-time custom allocator support. */ + +#if defined(hb_malloc_impl) \ + && defined(hb_calloc_impl) \ + && defined(hb_realloc_impl) \ + && defined(hb_free_impl) +extern "C" void* hb_malloc_impl(size_t size); +extern "C" void* hb_calloc_impl(size_t nmemb, size_t size); +extern "C" void* hb_realloc_impl(void *ptr, size_t size); +extern "C" void hb_free_impl(void *ptr); +#define malloc hb_malloc_impl +#define calloc hb_calloc_impl +#define realloc hb_realloc_impl +#define free hb_free_impl +#endif + + /* Compiler attributes */ @@ -102,6 +119,36 @@ #define HB_FUNC __func__ #endif +/* + * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411 + * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch + * cases that fall through without a break or return statement. HB_FALLTHROUGH + * is only needed on cases that have code: + * + * switch (foo) { + * case 1: // These cases have no code. No fallthrough annotations are needed. + * case 2: + * case 3: + * foo = 4; // This case has code, so a fallthrough annotation is needed: + * HB_FALLTHROUGH; + * default: + * return foo; + * } + */ +#if defined(__clang__) && __cplusplus >= 201103L + /* clang's fallthrough annotations are only available starting in C++11. */ +# define HB_FALLTHROUGH [[clang::fallthrough]] +#elif defined(_MSC_VER) + /* + * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis): + * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx + */ +# include <sal.h> +# define HB_FALLTHROUGH __fallthrough +#else +# define HB_FALLTHROUGH /* FALLTHROUGH */ +#endif + #if defined(_WIN32) || defined(__CYGWIN__) /* We need Windows Vista for both Uniscribe backend and for * MemoryBarrier. We don't support compiling on Windows XP, @@ -193,8 +240,9 @@ static inline unsigned int ARRAY_LENGTH (const Type (&)[n]) { return n; } #define _ASSERT_STATIC0(_line, _cond) _ASSERT_STATIC1 (_line, (_cond)) #define ASSERT_STATIC(_cond) _ASSERT_STATIC0 (__LINE__, (_cond)) -#define ASSERT_STATIC_EXPR(_cond)((void) sizeof (char[(_cond) ? 1 : -1])) -#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * sizeof (char[(_cond) ? 1 : -1])) +template <unsigned int cond> class hb_assert_constant_t {}; + +#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) #define _PASTE1(a,b) a##b #define PASTE(a,b) _PASTE1(a,b) @@ -247,8 +295,8 @@ ASSERT_STATIC (sizeof (hb_var_int_t) == 4); /* Void! */ struct _hb_void_t {}; -typedef const _hb_void_t &hb_void_t; -#define HB_VOID (* (const _hb_void_t *) NULL) +typedef const _hb_void_t *hb_void_t; +#define HB_VOID ((const _hb_void_t *) NULL) /* Return the number of 1 bits in mask. */ static inline HB_CONST_FUNC unsigned int @@ -739,7 +787,7 @@ template <typename T> static inline void _hb_warn_no_return (bool returned) { if (unlikely (!returned)) { - fprintf (stderr, "OUCH, returned with no call to TRACE_RETURN. This is a bug, please report.\n"); + fprintf (stderr, "OUCH, returned with no call to return_trace(). This is a bug, please report.\n"); } } template <> @@ -774,7 +822,7 @@ struct hb_auto_trace_t { inline ret_t ret (ret_t v, unsigned int line = 0) { if (unlikely (returned)) { - fprintf (stderr, "OUCH, double calls to TRACE_RETURN. This is a bug, please report.\n"); + fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n"); return v; } @@ -805,7 +853,7 @@ struct hb_auto_trace_t<0, ret_t> { inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; } }; -#define TRACE_RETURN(RET) trace.ret (RET, __LINE__) +#define return_trace(RET) return trace.ret (RET, __LINE__) /* Misc */ @@ -845,49 +893,43 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) /* Useful for set-operations on small enums. * For example, for testing "x ∈ {x1, x2, x3}" use: - * (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) + * (FLAG_SAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) */ -#define FLAG(x) (1<<(x)) +#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((x) < 32) + (1U << (x))) +#define FLAG_SAFE(x) (1U << (x)) +#define FLAG_UNSAFE(x) ((x) < 32 ? FLAG_SAFE(x) : 0) #define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) template <typename T, typename T2> static inline void -hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2) +hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2) { - if (unlikely (!len)) - return; - - unsigned int k = len - 1; - do { - unsigned int new_k = 0; - - for (unsigned int j = 0; j < k; j++) - if (compar (&array[j], &array[j+1]) > 0) - { - { - T t; - t = array[j]; - array[j] = array[j + 1]; - array[j + 1] = t; - } - if (array2) - { - T2 t; - t = array2[j]; - array2[j] = array2[j + 1]; - array2[j + 1] = t; - } - - new_k = j; - } - k = new_k; - } while (k); + for (unsigned int i = 1; i < len; i++) + { + unsigned int j = i; + while (j && compar (&array[j - 1], &array[i]) > 0) + j--; + if (i == j) + continue; + /* Move item i to occupy place for item j, shift what's in between. */ + { + T t = array[i]; + memmove (&array[j + 1], &array[j], (i - j) * sizeof (T)); + array[j] = t; + } + if (array2) + { + T2 t = array2[i]; + memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2)); + array2[j] = t; + } + } } template <typename T> static inline void -hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) +hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *)) { - hb_bubble_sort (array, len, compar, (int *) NULL); + hb_stable_sort (array, len, compar, (int *) NULL); } static inline hb_bool_t diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh index acba4e946b..3c302b1daf 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-set-private.hh @@ -36,7 +36,15 @@ * "approximate member query". Conceptually these are like Bloom * Filter and Quotient Filter, however, much smaller, faster, and * designed to fit the requirements of our uses for glyph coverage - * queries. As a result, our filters have much higher. + * queries. + * + * Our filters are highly accurate if the lookup covers fairly local + * set of glyphs, but fully flooded and ineffective if coverage is + * all over the place. + * + * The frozen-set can be used instead of a digest, to trade more + * memory for 100% accuracy, but in practice, that doesn't look like + * an attractive trade-off. */ template <typename mask_t, unsigned int shift> @@ -354,7 +362,6 @@ struct hb_frozen_set_t return; unsigned int min = set.get_min (); const elt_t &min_elt = set.elt (min); - const elt_t &max_elt = set.elt (max); start = min & ~MASK; count = max - start + 1; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.cc b/src/3rdparty/harfbuzz-ng/src/hb-set.cc index 59a0af46ed..cb7fcdbf64 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-set.cc @@ -35,7 +35,7 @@ * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_set_t * hb_set_create (void) @@ -55,7 +55,7 @@ hb_set_create (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_set_t * hb_set_get_empty (void) @@ -76,7 +76,7 @@ hb_set_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_set_t * hb_set_reference (hb_set_t *set) @@ -88,7 +88,7 @@ hb_set_reference (hb_set_t *set) * hb_set_destroy: (skip) * @set: a set. * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_destroy (hb_set_t *set) @@ -110,7 +110,7 @@ hb_set_destroy (hb_set_t *set) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_set_set_user_data (hb_set_t *set, @@ -129,7 +129,7 @@ hb_set_set_user_data (hb_set_t *set, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_set_get_user_data (hb_set_t *set, @@ -147,7 +147,7 @@ hb_set_get_user_data (hb_set_t *set, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_set_allocation_successful (const hb_set_t *set HB_UNUSED) @@ -161,7 +161,7 @@ hb_set_allocation_successful (const hb_set_t *set HB_UNUSED) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_clear (hb_set_t *set) @@ -177,7 +177,7 @@ hb_set_clear (hb_set_t *set) * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_set_is_empty (const hb_set_t *set) @@ -194,7 +194,7 @@ hb_set_is_empty (const hb_set_t *set) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_set_has (const hb_set_t *set, @@ -210,7 +210,7 @@ hb_set_has (const hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_add (hb_set_t *set, @@ -227,7 +227,7 @@ hb_set_add (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_set_add_range (hb_set_t *set, @@ -244,7 +244,7 @@ hb_set_add_range (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_del (hb_set_t *set, @@ -261,7 +261,7 @@ hb_set_del (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_set_del_range (hb_set_t *set, @@ -280,7 +280,7 @@ hb_set_del_range (hb_set_t *set, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_set_is_equal (const hb_set_t *set, @@ -296,7 +296,7 @@ hb_set_is_equal (const hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_set (hb_set_t *set, @@ -312,7 +312,7 @@ hb_set_set (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_union (hb_set_t *set, @@ -328,7 +328,7 @@ hb_set_union (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_intersect (hb_set_t *set, @@ -344,7 +344,7 @@ hb_set_intersect (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_subtract (hb_set_t *set, @@ -360,7 +360,7 @@ hb_set_subtract (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_set_symmetric_difference (hb_set_t *set, @@ -375,7 +375,7 @@ hb_set_symmetric_difference (hb_set_t *set, * * * - * Since: 1.0 + * Since: 0.9.10 **/ void hb_set_invert (hb_set_t *set) @@ -391,7 +391,7 @@ hb_set_invert (hb_set_t *set) * * Return value: set population. * - * Since: 1.0 + * Since: 0.9.7 **/ unsigned int hb_set_get_population (const hb_set_t *set) @@ -407,7 +407,7 @@ hb_set_get_population (const hb_set_t *set) * * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty. * - * Since: 1.0 + * Since: 0.9.7 **/ hb_codepoint_t hb_set_get_min (const hb_set_t *set) @@ -423,7 +423,7 @@ hb_set_get_min (const hb_set_t *set) * * Return value: minimum of the set, or %HB_SET_VALUE_INVALID if set is empty. * - * Since: 1.0 + * Since: 0.9.7 **/ hb_codepoint_t hb_set_get_max (const hb_set_t *set) @@ -440,7 +440,7 @@ hb_set_get_max (const hb_set_t *set) * * Return value: whether there was a next value. * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_set_next (const hb_set_t *set, @@ -460,7 +460,7 @@ hb_set_next (const hb_set_t *set, * * Return value: whether there was a next range. * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_set_next_range (const hb_set_t *set, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set.h b/src/3rdparty/harfbuzz-ng/src/hb-set.h index bafdae9633..29bf6556ab 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-set.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-set.h @@ -36,6 +36,9 @@ HB_BEGIN_DECLS +/* + * Since: 0.9.21 + */ #define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1) typedef struct hb_set_t hb_set_t; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc index 2166173f9e..56e2ea5c19 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape-plan.cc @@ -106,7 +106,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_create (hb_face_t *face, @@ -126,9 +126,9 @@ hb_shape_plan_create (hb_face_t *face, if (unlikely (!face)) face = hb_face_get_empty (); - if (unlikely (!props || hb_object_is_inert (face))) + if (unlikely (!props)) return hb_shape_plan_get_empty (); - if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t)))) + if (num_user_features && !(features = (hb_feature_t *) calloc (num_user_features, sizeof (hb_feature_t)))) return hb_shape_plan_get_empty (); if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) { free (features); @@ -158,7 +158,7 @@ hb_shape_plan_create (hb_face_t *face, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_get_empty (void) @@ -194,7 +194,7 @@ hb_shape_plan_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_reference (hb_shape_plan_t *shape_plan) @@ -208,7 +208,7 @@ hb_shape_plan_reference (hb_shape_plan_t *shape_plan) * * * - * Since: 1.0 + * Since: 0.9.7 **/ void hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) @@ -236,7 +236,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, @@ -257,7 +257,7 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.7 **/ void * hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, @@ -279,7 +279,7 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan, * * Return value: * - * Since: 1.0 + * Since: 0.9.7 **/ hb_bool_t hb_shape_plan_execute (hb_shape_plan_t *shape_plan, @@ -293,9 +293,13 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan, num_features, shape_plan->shaper_func); - if (unlikely (hb_object_is_inert (shape_plan) || - hb_object_is_inert (font) || - hb_object_is_inert (buffer))) + if (unlikely (!buffer->len)) + return true; + + assert (!hb_object_is_inert (buffer)); + assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE); + + if (unlikely (hb_object_is_inert (shape_plan))) return false; assert (shape_plan->face_unsafe == font->face); @@ -396,7 +400,7 @@ hb_non_global_user_features_present (const hb_feature_t *user_features, * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.7 **/ hb_shape_plan_t * hb_shape_plan_create_cached (hb_face_t *face, @@ -453,6 +457,10 @@ retry: hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list); + /* Don't add to the cache if face is inert. */ + if (unlikely (hb_object_is_inert (face))) + return shape_plan; + /* Don't add the plan to the cache if there were user features with non-global ranges */ if (hb_non_global_user_features_present (user_features, num_user_features)) @@ -483,7 +491,7 @@ retry: * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.7 **/ const char * hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc index 4e22c61862..8a98583989 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.cc @@ -33,6 +33,17 @@ #include "hb-buffer-private.hh" #include "hb-font-private.hh" +/** + * SECTION:hb-shape + * @title: Shaping + * @short_description: Conversion of text strings into positioned glyphs + * @include: hb.h + * + * Shaping is the central operation of HarfBuzz. Shaping operates on buffers, + * which are sequences of Unicode characters that use the same font and have + * the same text direction, script and language. After shaping the buffer + * contains the output glyphs and their positions. + **/ static bool parse_space (const char **pp, const char *end) @@ -198,15 +209,16 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) /** * hb_feature_from_string: - * @str: (array length=len) (element-type uint8_t): - * @len: - * @feature: (out) (optional): + * @str: (array length=len) (element-type uint8_t): a string to parse + * @len: length of @str, or -1 if string is nul-terminated + * @feature: (out): the #hb_feature_t to initialize with the parsed values * - * + * Parses a string into a #hb_feature_t. If @len is -1 then @str is + * %NULL-terminated. * - * Return value: + * Return value: %TRUE if @str is successfully parsed, %FALSE otherwise * - * Since: 1.0 + * Since: 0.9.5 **/ hb_bool_t hb_feature_from_string (const char *str, int len, @@ -231,13 +243,15 @@ hb_feature_from_string (const char *str, int len, /** * hb_feature_to_string: - * @feature: - * @buf: (array length=size): - * @size: + * @feature: an #hb_feature_t to convert + * @buf: (array length=size) (out): output string + * @size: the allocated size of @buf * - * + * Converts a #hb_feature_t into a %NULL-terminated string in the format + * understood by hb_feature_from_string(). The client in responsible for + * allocating big enough size for @buf, 128 bytes is more than enough. * - * Since: 1.0 + * Since: 0.9.5 **/ void hb_feature_to_string (hb_feature_t *feature, @@ -290,11 +304,12 @@ void free_static_shaper_list (void) /** * hb_shape_list_shapers: * - * + * Retrieves the list of shapers supported by HarfBuzz. * - * Return value: (transfer none): + * Return value: (transfer none) (array zero-terminated=1): an array of + * constant strings * - * Since: 1.0 + * Since: 0.9.2 **/ const char ** hb_shape_list_shapers (void) @@ -333,17 +348,21 @@ retry: /** * hb_shape_full: - * @font: a font. - * @buffer: a buffer. - * @features: (array length=num_features): - * @num_features: - * @shaper_list: (array zero-terminated=1): + * @font: an #hb_font_t to use for shaping + * @buffer: an #hb_buffer_t to shape + * @features: (array length=num_features) (allow-none): an array of user + * specified #hb_feature_t or %NULL + * @num_features: the length of @features array + * @shaper_list: (array zero-terminated=1) (allow-none): a %NULL-terminated + * array of shapers to use or %NULL * - * + * See hb_shape() for details. If @shaper_list is not %NULL, the specified + * shapers will be used in the given order, otherwise the default shapers list + * will be used. * - * Return value: + * Return value: %FALSE if all shapers failed, %TRUE otherwise * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_shape_full (hb_font_t *font, @@ -352,11 +371,6 @@ hb_shape_full (hb_font_t *font, unsigned int num_features, const char * const *shaper_list) { - if (unlikely (!buffer->len)) - return true; - - assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE); - hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list); hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features); hb_shape_plan_destroy (shape_plan); @@ -368,14 +382,19 @@ hb_shape_full (hb_font_t *font, /** * hb_shape: - * @font: a font. - * @buffer: a buffer. - * @features: (array length=num_features): - * @num_features: + * @font: an #hb_font_t to use for shaping + * @buffer: an #hb_buffer_t to shape + * @features: (array length=num_features) (allow-none): an array of user + * specified #hb_feature_t or %NULL + * @num_features: the length of @features array + * + * Shapes @buffer using @font turning its Unicode characters content to + * positioned glyphs. If @features is not %NULL, it will be used to control the + * features applied during shaping. * - * + * Return value: %FALSE if all shapers failed, %TRUE otherwise * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_shape (hb_font_t *font, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shape.h b/src/3rdparty/harfbuzz-ng/src/hb-shape.h index 10a35cb517..b665509a0d 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shape.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-shape.h @@ -47,13 +47,10 @@ typedef struct hb_feature_t { unsigned int end; } hb_feature_t; -/* len=-1 means str is NUL-terminated */ hb_bool_t hb_feature_from_string (const char *str, int len, hb_feature_t *feature); -/* Something like 128 bytes is more than enough. - * nul-terminates. */ void hb_feature_to_string (hb_feature_t *feature, char *buf, unsigned int size); diff --git a/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc b/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc index 580b95c84b..b25566d8a7 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-shaper.cc @@ -64,7 +64,7 @@ retry: } /* Not found; allocate one. */ - shapers = (hb_shaper_pair_t *) malloc (sizeof (all_shapers)); + shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers)); if (unlikely (!shapers)) { (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]); return (const hb_shaper_pair_t *) all_shapers; diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh index a2c59da274..968bca5567 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode-private.hh @@ -308,7 +308,7 @@ extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; /* Misc */ #define HB_UNICODE_GENERAL_CATEGORY_IS_MARK(gen_cat) \ - (FLAG (gen_cat) & \ + (FLAG_SAFE (gen_cat) & \ (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \ FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \ FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))) diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc index fc19006d3e..487d10b939 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.cc @@ -146,13 +146,8 @@ hb_unicode_funcs_get_default (void) } #if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL) -#ifdef _MSC_VER -#pragma message("Could not find any Unicode functions implementation, you have to provide your own") -#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS") -#else -#warning "Could not find any Unicode functions implementation, you have to provide your own" -#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS" -#endif +#error "Could not find any Unicode functions implementation, you have to provide your own" +#error "Consider building hb-ucdn.c. If you absolutely want to build without any, check the code." #endif /** @@ -163,7 +158,7 @@ hb_unicode_funcs_get_default (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_unicode_funcs_t * hb_unicode_funcs_create (hb_unicode_funcs_t *parent) @@ -209,7 +204,7 @@ const hb_unicode_funcs_t _hb_unicode_funcs_nil = { * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_unicode_funcs_t * hb_unicode_funcs_get_empty (void) @@ -225,7 +220,7 @@ hb_unicode_funcs_get_empty (void) * * Return value: (transfer full): * - * Since: 1.0 + * Since: 0.9.2 **/ hb_unicode_funcs_t * hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs) @@ -239,7 +234,7 @@ hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs) * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) @@ -268,7 +263,7 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, @@ -289,7 +284,7 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs, * * Return value: (transfer none): * - * Since: 1.0 + * Since: 0.9.2 **/ void * hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, @@ -305,7 +300,7 @@ hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) @@ -324,7 +319,7 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs) @@ -340,7 +335,7 @@ hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs) * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_unicode_funcs_t * hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs) @@ -400,7 +395,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_unicode_compose (hb_unicode_funcs_t *ufuncs, @@ -422,7 +417,7 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ hb_bool_t hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, @@ -443,7 +438,7 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, * * Return value: * - * Since: 1.0 + * Since: 0.9.2 **/ unsigned int hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h index 1c4e097b92..3a12e2f9a2 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-unicode.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-unicode.h @@ -283,7 +283,7 @@ typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_ * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, @@ -299,7 +299,7 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, @@ -315,7 +315,7 @@ hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, @@ -331,7 +331,7 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, @@ -347,7 +347,7 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, @@ -363,7 +363,7 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, @@ -379,7 +379,7 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, @@ -395,7 +395,7 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs, * * * - * Since: 1.0 + * Since: 0.9.2 **/ void hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, @@ -404,37 +404,62 @@ hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs, /* accessors */ +/** + * Since: 0.9.2 + **/ hb_unicode_combining_class_t hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ unsigned int hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ hb_unicode_general_category_t hb_unicode_general_category (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ hb_codepoint_t hb_unicode_mirroring (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ hb_script_t hb_unicode_script (hb_unicode_funcs_t *ufuncs, hb_codepoint_t unicode); +/** + * Since: 0.9.2 + **/ hb_bool_t hb_unicode_compose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t a, hb_codepoint_t b, hb_codepoint_t *ab); + +/** + * Since: 0.9.2 + **/ hb_bool_t hb_unicode_decompose (hb_unicode_funcs_t *ufuncs, hb_codepoint_t ab, hb_codepoint_t *a, hb_codepoint_t *b); +/** + * Since: 0.9.2 + **/ unsigned int hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs, hb_codepoint_t u, diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h index 648a46fde7..bd9ac3d1fc 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-version.h +++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h @@ -36,11 +36,11 @@ HB_BEGIN_DECLS -#define HB_VERSION_MAJOR 0 -#define HB_VERSION_MINOR 9 -#define HB_VERSION_MICRO 40 +#define HB_VERSION_MAJOR 1 +#define HB_VERSION_MINOR 0 +#define HB_VERSION_MICRO 6 -#define HB_VERSION_STRING "0.9.40" +#define HB_VERSION_STRING "1.0.6" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ diff --git a/src/3rdparty/harfbuzz-ng/src/hb-warning.cc b/src/3rdparty/harfbuzz-ng/src/hb-warning.cc index e0f88e2d4a..8f322bcb10 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-warning.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-warning.cc @@ -29,27 +29,11 @@ #if defined(HB_ATOMIC_INT_NIL) -#ifdef _MSC_VER -#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe") -#else -#warning "Could not find any system to define atomic_int macros, library may NOT be thread-safe" -#endif +#error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe" +#error "Check hb-atomic-private.hh for possible resolutions." #endif #if defined(HB_MUTEX_IMPL_NIL) -#ifdef _MSC_VER -#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe") -#else -#warning "Could not find any system to define mutex macros, library may NOT be thread-safe" -#endif -#endif - -#if defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL) -#ifdef _MSC_VER -#pragma message("To suppress these warnings, define HB_NO_MT") -#else -#warning "To suppress these warnings, define HB_NO_MT" +#error "Could not find any system to define mutex macros, library WILL NOT be thread-safe" +#error "Check hb-mutex-private.hh for possible resolutions." #endif -#endif - - |