Update bundled HarfBuzz-NG to 1.0.6
- Unicode 8.0 support - Universal Shaping Engine - Various fixes, improvements, optimizations, etc. Change-Id: Ib6f8c92fa275c2a6575b9ae09068c92aecac7b4e Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com> Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>bb10
parent
dbb013d984
commit
4f8c75acbd
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include <harfbuzz/hb.h>
|
||||
|
||||
#if !HB_VERSION_ATLEAST(0, 9, 31)
|
||||
#if !HB_VERSION_ATLEAST(0, 9, 42)
|
||||
# error "This version of harfbuzz is too old."
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
=====================================
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[](https://travis-ci.org/behdad/harfbuzz)
|
||||
[](https://coveralls.io/r/behdad/harfbuzz)
|
||||
[](https://scan.coverity.com/projects/5450)
|
||||
|
||||
This is HarfBuzz, a text shaping library.
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 *));
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -1282,6 +1351,23 @@ hb_buffer_reverse (hb_buffer_t *buffer)
|
|||
buffer->reverse ();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -221,6 +239,10 @@ hb_buffer_allocation_successful (hb_buffer_t *buffer);
|
|||
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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -1056,6 +1058,32 @@ hb_font_is_immutable (hb_font_t *font)
|
|||
return font->immutable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -535,6 +555,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>
|
||||
{
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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). */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,15 +1504,39 @@ 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);
|
||||
};
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
@ -32,10 +32,14 @@
|
|||
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
|
||||
|
||||
|
||||
/*
|
||||
* 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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 || \
|
||||
( \
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -1193,37 +1186,6 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
|
|||
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
|
||||
}
|
||||
|
||||
static void
|
||||
initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
/* We already inserted dotted-circles, so just call the standalone_cluster. */
|
||||
initial_reordering_standalone_cluster (plan, 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,
|
||||
|
|
@ -1231,13 +1193,21 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -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,42 +391,10 @@ 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,
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 == */
|
||||
|
|
@ -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 */
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
* Since: 1.0
|
||||
* Return value: %FALSE if all shapers failed, %TRUE otherwise
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
void
|
||||
hb_shape (hb_font_t *font,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) <= \
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
#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
|
||||
|
||||
#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"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue