mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1157758 - Update harfbuzz to pick up fix for vertical-upright Arabic script (non-)shaping behavior; now at upstream commit f724cc351640ee075a9867ef42df32cf5e0ef3b7. r=jdaggett
This commit is contained in:
parent
0323a0a1b5
commit
218a52280a
@ -1,16 +1,14 @@
|
|||||||
gfx/harfbuzz status as of 2012-08-16:
|
gfx/harfbuzz status as of 2015-04-25:
|
||||||
|
|
||||||
This directory contains the "harfbuzz-ng" source from the 'master' branch of
|
This directory contains the harfbuzz source from the 'master' branch of
|
||||||
git://anongit.freedesktop.org/git/harfbuzz.
|
https://github.com/behdad/harfbuzz.
|
||||||
|
|
||||||
UPDATING:
|
UPDATING:
|
||||||
|
|
||||||
Note that hb-ot-shape-complex-indic-machine.hh and gfx/harfbuzz/src/hb-version.h
|
Note that gfx/harfbuzz/src/hb-version.h is not present in the upstream Git
|
||||||
are not present in the upstream Git repository. These are created at build time
|
repository. It is created at build time by the harfbuzz build system;
|
||||||
by the harfbuzz build system; but as we don't use that build system in mozilla,
|
but as we don't use that build system in mozilla, it is necessary to refresh
|
||||||
it is necessary to refresh these files when updating harfbuzz, and check them in
|
this files when updating harfbuzz, and check them into the mozilla tree.
|
||||||
to the mozilla tree. (This avoids adding the ragel processor to mozilla's build
|
|
||||||
prerequisites.)
|
|
||||||
|
|
||||||
The normal approach to updating harfbuzz, therefore, is to pull the latest HB
|
The normal approach to updating harfbuzz, therefore, is to pull the latest HB
|
||||||
source into a scratch directory and do a local build; then copy the original
|
source into a scratch directory and do a local build; then copy the original
|
||||||
@ -19,5 +17,4 @@ the mozilla tree.
|
|||||||
|
|
||||||
In addition, the src/Makefile.in file here is NOT from upstream, nor is it
|
In addition, the src/Makefile.in file here is NOT from upstream, nor is it
|
||||||
generated from src/Makefile.am (the original harfbuzz version); it is a mozilla-
|
generated from src/Makefile.am (the original harfbuzz version); it is a mozilla-
|
||||||
specific makefile that is maintained by hand. It should only need updating when
|
specific makefile that is maintained by hand.
|
||||||
new source files or exported headers are added in harfbuzz.
|
|
||||||
|
@ -13,6 +13,9 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
|
|||||||
# The following warning options are useful for debugging: -Wpadded
|
# The following warning options are useful for debugging: -Wpadded
|
||||||
#AM_CXXFLAGS =
|
#AM_CXXFLAGS =
|
||||||
|
|
||||||
|
# Convenience targets:
|
||||||
|
lib: libharfbuzz.la
|
||||||
|
|
||||||
lib_LTLIBRARIES = libharfbuzz.la
|
lib_LTLIBRARIES = libharfbuzz.la
|
||||||
|
|
||||||
HBCFLAGS =
|
HBCFLAGS =
|
||||||
|
44
gfx/harfbuzz/src/check-defs.sh
Executable file
44
gfx/harfbuzz/src/check-defs.sh
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
LC_ALL=C
|
||||||
|
export LC_ALL
|
||||||
|
|
||||||
|
test -z "$srcdir" && srcdir=.
|
||||||
|
test -z "$MAKE" && MAKE=make
|
||||||
|
stat=0
|
||||||
|
|
||||||
|
if which nm 2>/dev/null >/dev/null; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo "check-defs.sh: 'nm' not found; skipping test"
|
||||||
|
exit 77
|
||||||
|
fi
|
||||||
|
|
||||||
|
defs="harfbuzz.def"
|
||||||
|
$MAKE $defs > /dev/null
|
||||||
|
tested=false
|
||||||
|
for def in $defs; do
|
||||||
|
lib=`echo "$def" | sed 's/[.]def$//;s@.*/@@'`
|
||||||
|
so=.libs/lib${lib}.so
|
||||||
|
|
||||||
|
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] ' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>\| __gcov_flush\>\| llvm_' | cut -d' ' -f3`"
|
||||||
|
|
||||||
|
if test -f "$so"; then
|
||||||
|
|
||||||
|
echo "Checking that $so has the same symbol list as $def"
|
||||||
|
{
|
||||||
|
echo EXPORTS
|
||||||
|
echo "$EXPORTED_SYMBOLS"
|
||||||
|
# cheat: copy the last line from the def file!
|
||||||
|
tail -n1 "$def"
|
||||||
|
} | diff "$def" - >&2 || stat=1
|
||||||
|
|
||||||
|
tested=true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if ! $tested; then
|
||||||
|
echo "check-defs.sh: libharfbuzz shared library not found; skipping test"
|
||||||
|
exit 77
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $stat
|
@ -19,9 +19,9 @@ for suffix in so dylib; do
|
|||||||
so=.libs/libharfbuzz.$suffix
|
so=.libs/libharfbuzz.$suffix
|
||||||
if ! test -f "$so"; then continue; fi
|
if ! test -f "$so"; then continue; fi
|
||||||
|
|
||||||
echo "Checking that we are not linking to libstdc++"
|
echo "Checking that we are not linking to libstdc++ or libc++"
|
||||||
if ldd $so | grep 'libstdc[+][+]'; then
|
if ldd $so | grep 'libstdc[+][+]\|libc[+][+]'; then
|
||||||
echo "Ouch, linked to libstdc++"
|
echo "Ouch, linked to libstdc++ or libc++"
|
||||||
stat=1
|
stat=1
|
||||||
fi
|
fi
|
||||||
tested=true
|
tested=true
|
||||||
|
@ -209,7 +209,7 @@ for p in sorted(pages):
|
|||||||
for (start,end) in zip (starts, ends):
|
for (start,end) in zip (starts, ends):
|
||||||
if p not in [start>>page_bits, end>>page_bits]: continue
|
if p not in [start>>page_bits, end>>page_bits]: continue
|
||||||
offset = "indic_offset_0x%04xu" % start
|
offset = "indic_offset_0x%04xu" % start
|
||||||
print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end, start, offset)
|
print " if (hb_in_range (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)
|
||||||
for u,d in singles.items ():
|
for u,d in singles.items ():
|
||||||
if p != u>>page_bits: continue
|
if p != u>>page_bits: continue
|
||||||
print " if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
|
print " if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
|
||||||
|
@ -39,7 +39,11 @@
|
|||||||
|
|
||||||
/* We need external help for these */
|
/* 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)
|
||||||
|
|
||||||
|
/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */
|
||||||
|
|
||||||
|
|
||||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||||
@ -58,11 +62,12 @@ static inline void _HBMemoryBarrier (void) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef LONG hb_atomic_int_t;
|
typedef LONG hb_atomic_int_impl_t;
|
||||||
#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
#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_impl_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_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
||||||
|
|
||||||
|
|
||||||
#elif !defined(HB_NO_MT) && defined(__APPLE__)
|
#elif !defined(HB_NO_MT) && defined(__APPLE__)
|
||||||
@ -74,28 +79,31 @@ typedef LONG hb_atomic_int_t;
|
|||||||
#include <Availability.h>
|
#include <Availability.h>
|
||||||
#endif
|
#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)
|
#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
|
#else
|
||||||
#if __ppc64__ || __x86_64__ || __aarch64__
|
#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
|
#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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||||
|
|
||||||
typedef int hb_atomic_int_t;
|
typedef int hb_atomic_int_impl_t;
|
||||||
#define hb_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V))
|
#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_impl_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_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
|
||||||
|
|
||||||
|
|
||||||
#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
|
#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
|
||||||
@ -103,33 +111,54 @@ typedef int hb_atomic_int_t;
|
|||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <mbarrier.h>
|
#include <mbarrier.h>
|
||||||
|
|
||||||
typedef unsigned int hb_atomic_int_t;
|
typedef unsigned int hb_atomic_int_impl_t;
|
||||||
#define hb_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
|
#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_impl_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_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)
|
#elif !defined(HB_NO_MT)
|
||||||
|
|
||||||
#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
|
#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))
|
typedef volatile int hb_atomic_int_impl_t;
|
||||||
#define hb_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
|
#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 */
|
#else /* HB_NO_MT */
|
||||||
|
|
||||||
typedef int hb_atomic_int_t;
|
typedef int hb_atomic_int_impl_t;
|
||||||
#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V))
|
#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
|
#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 */
|
#endif /* HB_ATOMIC_PRIVATE_HH */
|
||||||
|
@ -78,8 +78,8 @@ _hb_blob_destroy_user_data (hb_blob_t *blob)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_blob_create: (Xconstructor)
|
* hb_blob_create: (skip)
|
||||||
* @data: (array length=length) (closure user_data) (destroy destroy) (scope notified) (transfer none): Pointer to blob data.
|
* @data: Pointer to blob data.
|
||||||
* @length: Length of @data in bytes.
|
* @length: Length of @data in bytes.
|
||||||
* @mode: Memory mode for @data.
|
* @mode: Memory mode for @data.
|
||||||
* @user_data: Data parameter to pass to @destroy.
|
* @user_data: Data parameter to pass to @destroy.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 1 "../../src/hb-buffer-deserialize-json.rl"
|
#line 1 "hb-buffer-deserialize-json.rl"
|
||||||
/*
|
/*
|
||||||
* Copyright © 2013 Google, Inc.
|
* Copyright © 2013 Google, Inc.
|
||||||
*
|
*
|
||||||
@ -32,7 +32,7 @@
|
|||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
|
|
||||||
|
|
||||||
#line 36 "hb-buffer-deserialize-json.hh.tmp"
|
#line 36 "hb-buffer-deserialize-json.hh"
|
||||||
static const unsigned char _deserialize_json_trans_keys[] = {
|
static const unsigned char _deserialize_json_trans_keys[] = {
|
||||||
0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
|
0u, 0u, 9u, 123u, 9u, 34u, 97u, 103u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
|
||||||
48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
|
48u, 57u, 9u, 125u, 9u, 125u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u,
|
||||||
@ -435,7 +435,7 @@ static const int deserialize_json_error = 0;
|
|||||||
static const int deserialize_json_en_main = 1;
|
static const int deserialize_json_en_main = 1;
|
||||||
|
|
||||||
|
|
||||||
#line 97 "../../src/hb-buffer-deserialize-json.rl"
|
#line 97 "hb-buffer-deserialize-json.rl"
|
||||||
|
|
||||||
|
|
||||||
static hb_bool_t
|
static hb_bool_t
|
||||||
@ -459,15 +459,15 @@ _hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
|
|||||||
|
|
||||||
const char *tok = NULL;
|
const char *tok = NULL;
|
||||||
int cs;
|
int cs;
|
||||||
hb_glyph_info_t info;
|
hb_glyph_info_t info = {0};
|
||||||
hb_glyph_position_t pos;
|
hb_glyph_position_t pos = {0};
|
||||||
|
|
||||||
#line 466 "hb-buffer-deserialize-json.hh.tmp"
|
#line 466 "hb-buffer-deserialize-json.hh"
|
||||||
{
|
{
|
||||||
cs = deserialize_json_start;
|
cs = deserialize_json_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 471 "hb-buffer-deserialize-json.hh.tmp"
|
#line 471 "hb-buffer-deserialize-json.hh"
|
||||||
{
|
{
|
||||||
int _slen;
|
int _slen;
|
||||||
int _trans;
|
int _trans;
|
||||||
@ -493,14 +493,14 @@ _resume:
|
|||||||
|
|
||||||
switch ( _deserialize_json_trans_actions[_trans] ) {
|
switch ( _deserialize_json_trans_actions[_trans] ) {
|
||||||
case 1:
|
case 1:
|
||||||
#line 38 "../../src/hb-buffer-deserialize-json.rl"
|
#line 38 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
memset (&info, 0, sizeof (info));
|
memset (&info, 0, sizeof (info));
|
||||||
memset (&pos , 0, sizeof (pos ));
|
memset (&pos , 0, sizeof (pos ));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
#line 43 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -510,13 +510,13 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
#line 51 "../../src/hb-buffer-deserialize-json.rl"
|
#line 51 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
tok = p;
|
tok = p;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
#line 55 "../../src/hb-buffer-deserialize-json.rl"
|
#line 55 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
if (!hb_font_glyph_from_string (font,
|
if (!hb_font_glyph_from_string (font,
|
||||||
tok, p - tok,
|
tok, p - tok,
|
||||||
@ -525,33 +525,33 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
#line 62 "../../src/hb-buffer-deserialize-json.rl"
|
#line 62 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
#line 63 "../../src/hb-buffer-deserialize-json.rl"
|
#line 63 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
#line 64 "../../src/hb-buffer-deserialize-json.rl"
|
#line 64 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
#line 65 "../../src/hb-buffer-deserialize-json.rl"
|
#line 65 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
#line 66 "../../src/hb-buffer-deserialize-json.rl"
|
#line 66 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
#line 67 "../../src/hb-buffer-deserialize-json.rl"
|
#line 67 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
#line 62 "../../src/hb-buffer-deserialize-json.rl"
|
#line 62 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
{ if (!parse_uint (tok, p, &info.codepoint)) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
#line 43 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -561,9 +561,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
#line 63 "../../src/hb-buffer-deserialize-json.rl"
|
#line 63 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
#line 43 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -573,9 +573,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
#line 64 "../../src/hb-buffer-deserialize-json.rl"
|
#line 64 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
#line 43 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -585,9 +585,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
#line 65 "../../src/hb-buffer-deserialize-json.rl"
|
#line 65 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
#line 43 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -597,9 +597,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
#line 66 "../../src/hb-buffer-deserialize-json.rl"
|
#line 66 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
#line 43 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -609,9 +609,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
#line 67 "../../src/hb-buffer-deserialize-json.rl"
|
#line 67 "hb-buffer-deserialize-json.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
#line 43 "hb-buffer-deserialize-json.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -620,7 +620,7 @@ _resume:
|
|||||||
*end_ptr = p;
|
*end_ptr = p;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#line 624 "hb-buffer-deserialize-json.hh.tmp"
|
#line 624 "hb-buffer-deserialize-json.hh"
|
||||||
}
|
}
|
||||||
|
|
||||||
_again:
|
_again:
|
||||||
@ -632,7 +632,7 @@ _again:
|
|||||||
_out: {}
|
_out: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 125 "../../src/hb-buffer-deserialize-json.rl"
|
#line 125 "hb-buffer-deserialize-json.rl"
|
||||||
|
|
||||||
|
|
||||||
*end_ptr = p;
|
*end_ptr = p;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 1 "../../src/hb-buffer-deserialize-text.rl"
|
#line 1 "hb-buffer-deserialize-text.rl"
|
||||||
/*
|
/*
|
||||||
* Copyright © 2013 Google, Inc.
|
* Copyright © 2013 Google, Inc.
|
||||||
*
|
*
|
||||||
@ -32,7 +32,7 @@
|
|||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
|
|
||||||
|
|
||||||
#line 36 "hb-buffer-deserialize-text.hh.tmp"
|
#line 36 "hb-buffer-deserialize-text.hh"
|
||||||
static const unsigned char _deserialize_text_trans_keys[] = {
|
static const unsigned char _deserialize_text_trans_keys[] = {
|
||||||
0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
|
0u, 0u, 9u, 122u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
|
||||||
48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
|
48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 9u, 124u, 9u, 124u, 0u, 0u,
|
||||||
@ -312,7 +312,7 @@ static const int deserialize_text_error = 0;
|
|||||||
static const int deserialize_text_en_main = 1;
|
static const int deserialize_text_en_main = 1;
|
||||||
|
|
||||||
|
|
||||||
#line 91 "../../src/hb-buffer-deserialize-text.rl"
|
#line 91 "hb-buffer-deserialize-text.rl"
|
||||||
|
|
||||||
|
|
||||||
static hb_bool_t
|
static hb_bool_t
|
||||||
@ -336,15 +336,15 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
|
|||||||
|
|
||||||
const char *eof = pe, *tok = NULL;
|
const char *eof = pe, *tok = NULL;
|
||||||
int cs;
|
int cs;
|
||||||
hb_glyph_info_t info;
|
hb_glyph_info_t info = {0};
|
||||||
hb_glyph_position_t pos;
|
hb_glyph_position_t pos = {0};
|
||||||
|
|
||||||
#line 343 "hb-buffer-deserialize-text.hh.tmp"
|
#line 343 "hb-buffer-deserialize-text.hh"
|
||||||
{
|
{
|
||||||
cs = deserialize_text_start;
|
cs = deserialize_text_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 348 "hb-buffer-deserialize-text.hh.tmp"
|
#line 348 "hb-buffer-deserialize-text.hh"
|
||||||
{
|
{
|
||||||
int _slen;
|
int _slen;
|
||||||
int _trans;
|
int _trans;
|
||||||
@ -370,13 +370,13 @@ _resume:
|
|||||||
|
|
||||||
switch ( _deserialize_text_trans_actions[_trans] ) {
|
switch ( _deserialize_text_trans_actions[_trans] ) {
|
||||||
case 2:
|
case 2:
|
||||||
#line 51 "../../src/hb-buffer-deserialize-text.rl"
|
#line 51 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
tok = p;
|
tok = p;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
#line 55 "../../src/hb-buffer-deserialize-text.rl"
|
#line 55 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
if (!hb_font_glyph_from_string (font,
|
if (!hb_font_glyph_from_string (font,
|
||||||
tok, p - tok,
|
tok, p - tok,
|
||||||
@ -385,41 +385,41 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
#line 62 "../../src/hb-buffer-deserialize-text.rl"
|
#line 62 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
#line 63 "../../src/hb-buffer-deserialize-text.rl"
|
#line 63 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
{ if (!parse_int (tok, p, &pos.x_offset )) return false; }
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
#line 64 "../../src/hb-buffer-deserialize-text.rl"
|
#line 64 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
#line 65 "../../src/hb-buffer-deserialize-text.rl"
|
#line 65 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
#line 38 "../../src/hb-buffer-deserialize-text.rl"
|
#line 38 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
memset (&info, 0, sizeof (info));
|
memset (&info, 0, sizeof (info));
|
||||||
memset (&pos , 0, sizeof (pos ));
|
memset (&pos , 0, sizeof (pos ));
|
||||||
}
|
}
|
||||||
#line 51 "../../src/hb-buffer-deserialize-text.rl"
|
#line 51 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
tok = p;
|
tok = p;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
#line 55 "../../src/hb-buffer-deserialize-text.rl"
|
#line 55 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
if (!hb_font_glyph_from_string (font,
|
if (!hb_font_glyph_from_string (font,
|
||||||
tok, p - tok,
|
tok, p - tok,
|
||||||
&info.codepoint))
|
&info.codepoint))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -429,9 +429,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
#line 62 "../../src/hb-buffer-deserialize-text.rl"
|
#line 62 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -441,9 +441,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
#line 64 "../../src/hb-buffer-deserialize-text.rl"
|
#line 64 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -453,9 +453,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
#line 65 "../../src/hb-buffer-deserialize-text.rl"
|
#line 65 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -465,9 +465,9 @@ _resume:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
#line 66 "../../src/hb-buffer-deserialize-text.rl"
|
#line 66 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -476,7 +476,7 @@ _resume:
|
|||||||
*end_ptr = p;
|
*end_ptr = p;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#line 480 "hb-buffer-deserialize-text.hh.tmp"
|
#line 480 "hb-buffer-deserialize-text.hh"
|
||||||
}
|
}
|
||||||
|
|
||||||
_again:
|
_again:
|
||||||
@ -489,14 +489,14 @@ _again:
|
|||||||
{
|
{
|
||||||
switch ( _deserialize_text_eof_actions[cs] ) {
|
switch ( _deserialize_text_eof_actions[cs] ) {
|
||||||
case 4:
|
case 4:
|
||||||
#line 55 "../../src/hb-buffer-deserialize-text.rl"
|
#line 55 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
if (!hb_font_glyph_from_string (font,
|
if (!hb_font_glyph_from_string (font,
|
||||||
tok, p - tok,
|
tok, p - tok,
|
||||||
&info.codepoint))
|
&info.codepoint))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -506,9 +506,9 @@ _again:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
#line 62 "../../src/hb-buffer-deserialize-text.rl"
|
#line 62 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
{ if (!parse_uint (tok, p, &info.cluster )) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -518,9 +518,9 @@ _again:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
#line 64 "../../src/hb-buffer-deserialize-text.rl"
|
#line 64 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
{ if (!parse_int (tok, p, &pos.y_offset )) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -530,9 +530,9 @@ _again:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
#line 65 "../../src/hb-buffer-deserialize-text.rl"
|
#line 65 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.x_advance)) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -542,9 +542,9 @@ _again:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
#line 66 "../../src/hb-buffer-deserialize-text.rl"
|
#line 66 "hb-buffer-deserialize-text.rl"
|
||||||
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
{ if (!parse_int (tok, p, &pos.y_advance)) return false; }
|
||||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
#line 43 "hb-buffer-deserialize-text.rl"
|
||||||
{
|
{
|
||||||
buffer->add_info (info);
|
buffer->add_info (info);
|
||||||
if (buffer->in_error)
|
if (buffer->in_error)
|
||||||
@ -553,14 +553,14 @@ _again:
|
|||||||
*end_ptr = p;
|
*end_ptr = p;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#line 557 "hb-buffer-deserialize-text.hh.tmp"
|
#line 557 "hb-buffer-deserialize-text.hh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_out: {}
|
_out: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 119 "../../src/hb-buffer-deserialize-text.rl"
|
#line 119 "hb-buffer-deserialize-text.rl"
|
||||||
|
|
||||||
|
|
||||||
*end_ptr = p;
|
*end_ptr = p;
|
||||||
|
@ -111,8 +111,8 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
|
|||||||
|
|
||||||
const char *eof = pe, *tok = NULL;
|
const char *eof = pe, *tok = NULL;
|
||||||
int cs;
|
int cs;
|
||||||
hb_glyph_info_t info;
|
hb_glyph_info_t info = {0};
|
||||||
hb_glyph_position_t pos;
|
hb_glyph_position_t pos = {0};
|
||||||
%%{
|
%%{
|
||||||
write init;
|
write init;
|
||||||
write exec;
|
write exec;
|
||||||
|
@ -443,7 +443,7 @@ hb_buffer_t::reverse_range (unsigned int start,
|
|||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
if (start == end - 1)
|
if (end - start < 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = start, j = end - 1; i < j; i++, j--) {
|
for (i = start, j = end - 1; i < j; i++, j--) {
|
||||||
@ -454,7 +454,7 @@ hb_buffer_t::reverse_range (unsigned int start,
|
|||||||
info[j] = t;
|
info[j] = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos) {
|
if (have_positions) {
|
||||||
for (i = start, j = end - 1; i < j; i++, j--) {
|
for (i = start, j = end - 1; i < j; i++, j--) {
|
||||||
hb_glyph_position_t t;
|
hb_glyph_position_t t;
|
||||||
|
|
||||||
@ -967,7 +967,7 @@ hb_buffer_set_language (hb_buffer_t *buffer,
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value: (transfer none):
|
||||||
*
|
*
|
||||||
* Since: 1.0
|
* Since: 1.0
|
||||||
**/
|
**/
|
||||||
@ -999,7 +999,7 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
|
|||||||
/**
|
/**
|
||||||
* hb_buffer_get_segment_properties:
|
* hb_buffer_get_segment_properties:
|
||||||
* @buffer: a buffer.
|
* @buffer: a buffer.
|
||||||
* @props:
|
* @props: (out):
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -1328,15 +1328,15 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
|
|||||||
buffer->guess_segment_properties ();
|
buffer->guess_segment_properties ();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <bool validate, typename T>
|
template <typename utf_t>
|
||||||
static inline void
|
static inline void
|
||||||
hb_buffer_add_utf (hb_buffer_t *buffer,
|
hb_buffer_add_utf (hb_buffer_t *buffer,
|
||||||
const T *text,
|
const typename utf_t::codepoint_t *text,
|
||||||
int text_length,
|
int text_length,
|
||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
typedef hb_utf_t<T, true> utf_t;
|
typedef typename utf_t::codepoint_t T;
|
||||||
const hb_codepoint_t replacement = buffer->replacement;
|
const hb_codepoint_t replacement = buffer->replacement;
|
||||||
|
|
||||||
assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
|
assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
|
||||||
@ -1400,7 +1400,7 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
|
|||||||
/**
|
/**
|
||||||
* hb_buffer_add_utf8:
|
* hb_buffer_add_utf8:
|
||||||
* @buffer: a buffer.
|
* @buffer: a buffer.
|
||||||
* @text: (array length=text_length):
|
* @text: (array length=text_length) (element-type uint8_t):
|
||||||
* @text_length:
|
* @text_length:
|
||||||
* @item_offset:
|
* @item_offset:
|
||||||
* @item_length:
|
* @item_length:
|
||||||
@ -1416,7 +1416,7 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
hb_buffer_add_utf<true> (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
|
hb_buffer_add_utf<hb_utf8_t> (buffer, (const uint8_t *) text, text_length, item_offset, item_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1438,7 +1438,7 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length);
|
hb_buffer_add_utf<hb_utf16_t> (buffer, text, text_length, item_offset, item_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1460,7 +1460,29 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
hb_buffer_add_utf<true> (buffer, text, text_length, item_offset, item_length);
|
hb_buffer_add_utf<hb_utf32_t<> > (buffer, text, text_length, item_offset, item_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_buffer_add_latin1:
|
||||||
|
* @buffer: a buffer.
|
||||||
|
* @text: (array length=text_length) (element-type uint8_t):
|
||||||
|
* @text_length:
|
||||||
|
* @item_offset:
|
||||||
|
* @item_length:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
hb_buffer_add_latin1 (hb_buffer_t *buffer,
|
||||||
|
const uint8_t *text,
|
||||||
|
int text_length,
|
||||||
|
unsigned int item_offset,
|
||||||
|
int item_length)
|
||||||
|
{
|
||||||
|
hb_buffer_add_utf<hb_latin1_t> (buffer, text, text_length, item_offset, item_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1482,7 +1504,7 @@ hb_buffer_add_codepoints (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length)
|
int item_length)
|
||||||
{
|
{
|
||||||
hb_buffer_add_utf<false> (buffer, text, text_length, item_offset, item_length);
|
hb_buffer_add_utf<hb_utf32_t<false> > (buffer, text, text_length, item_offset, item_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -253,6 +253,14 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer,
|
|||||||
unsigned int item_offset,
|
unsigned int item_offset,
|
||||||
int item_length);
|
int item_length);
|
||||||
|
|
||||||
|
/* Allows only access to first 256 Unicode codepoints. */
|
||||||
|
void
|
||||||
|
hb_buffer_add_latin1 (hb_buffer_t *buffer,
|
||||||
|
const uint8_t *text,
|
||||||
|
int text_length,
|
||||||
|
unsigned int item_offset,
|
||||||
|
int item_length);
|
||||||
|
|
||||||
/* Like add_utf32 but does NOT check for invalid Unicode codepoints. */
|
/* Like add_utf32 but does NOT check for invalid Unicode codepoints. */
|
||||||
void
|
void
|
||||||
hb_buffer_add_codepoints (hb_buffer_t *buffer,
|
hb_buffer_add_codepoints (hb_buffer_t *buffer,
|
||||||
|
@ -57,7 +57,7 @@ _hb_options_init (void)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_tag_from_string:
|
* hb_tag_from_string:
|
||||||
* @str: (array length=len):
|
* @str: (array length=len) (element-type uint8_t):
|
||||||
* @len:
|
* @len:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -115,7 +115,7 @@ const char direction_strings[][4] = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_direction_from_string:
|
* hb_direction_from_string:
|
||||||
* @str: (array length=len):
|
* @str: (array length=len) (element-type uint8_t):
|
||||||
* @len:
|
* @len:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -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
|
'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,
|
lang_equal (hb_language_t v1,
|
||||||
const void *v2)
|
const void *v2)
|
||||||
{
|
{
|
||||||
@ -235,7 +235,7 @@ struct hb_language_item_t {
|
|||||||
static hb_language_item_t *langs;
|
static hb_language_item_t *langs;
|
||||||
|
|
||||||
#ifdef HB_USE_ATEXIT
|
#ifdef HB_USE_ATEXIT
|
||||||
static inline
|
static
|
||||||
void free_langs (void)
|
void free_langs (void)
|
||||||
{
|
{
|
||||||
while (langs) {
|
while (langs) {
|
||||||
@ -265,6 +265,7 @@ retry:
|
|||||||
*lang = key;
|
*lang = key;
|
||||||
|
|
||||||
if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
|
if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
|
||||||
|
lang->finish ();
|
||||||
free (lang);
|
free (lang);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
@ -280,12 +281,12 @@ retry:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_language_from_string:
|
* hb_language_from_string:
|
||||||
* @str: (array length=len):
|
* @str: (array length=len) (element-type uint8_t):
|
||||||
* @len:
|
* @len:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value: (transfer none):
|
||||||
*
|
*
|
||||||
* Since: 1.0
|
* Since: 1.0
|
||||||
**/
|
**/
|
||||||
@ -345,7 +346,7 @@ hb_language_get_default (void)
|
|||||||
hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language);
|
hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language);
|
||||||
if (unlikely (language == HB_LANGUAGE_INVALID)) {
|
if (unlikely (language == HB_LANGUAGE_INVALID)) {
|
||||||
language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1);
|
language = hb_language_from_string (setlocale (LC_CTYPE, NULL), -1);
|
||||||
hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
|
(void) hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
|
||||||
}
|
}
|
||||||
|
|
||||||
return default_language;
|
return default_language;
|
||||||
@ -400,7 +401,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_script_from_string:
|
* hb_script_from_string:
|
||||||
* @s: (array length=len):
|
* @s: (array length=len) (element-type uint8_t):
|
||||||
* @len:
|
* @len:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -140,6 +140,7 @@ hb_coretext_face_get_cg_font (hb_face_t *face)
|
|||||||
|
|
||||||
struct hb_coretext_shaper_font_data_t {
|
struct hb_coretext_shaper_font_data_t {
|
||||||
CTFontRef ct_font;
|
CTFontRef ct_font;
|
||||||
|
CGFloat x_mult, y_mult; /* From CT space to HB space. */
|
||||||
};
|
};
|
||||||
|
|
||||||
hb_coretext_shaper_font_data_t *
|
hb_coretext_shaper_font_data_t *
|
||||||
@ -154,7 +155,17 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
|
|||||||
hb_face_t *face = font->face;
|
hb_face_t *face = font->face;
|
||||||
hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||||
|
|
||||||
data->ct_font = CTFontCreateWithGraphicsFont (face_data, font->y_scale, NULL, NULL);
|
/* Choose a CoreText font size and calculate multipliers to convert to HarfBuzz space. */
|
||||||
|
CGFloat font_size = 36.; /* Default... */
|
||||||
|
/* No idea if the following is even a good idea. */
|
||||||
|
if (font->y_ppem)
|
||||||
|
font_size = font->y_ppem;
|
||||||
|
|
||||||
|
if (font_size < 0)
|
||||||
|
font_size = -font_size;
|
||||||
|
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);
|
||||||
if (unlikely (!data->ct_font)) {
|
if (unlikely (!data->ct_font)) {
|
||||||
DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
|
DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
|
||||||
free (data);
|
free (data);
|
||||||
@ -776,6 +787,18 @@ retry:
|
|||||||
|
|
||||||
buffer->len = 0;
|
buffer->len = 0;
|
||||||
uint32_t status_and = ~0, status_or = 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);
|
const CFRange range_all = CFRangeMake (0, 0);
|
||||||
|
|
||||||
@ -786,6 +809,10 @@ retry:
|
|||||||
status_or |= run_status;
|
status_or |= run_status;
|
||||||
status_and &= run_status;
|
status_and &= run_status;
|
||||||
DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
|
DEBUG_MSG (CORETEXT, run, "CTRunStatus: %x", run_status);
|
||||||
|
double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL);
|
||||||
|
if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
|
||||||
|
run_advance = -run_advance;
|
||||||
|
DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
|
||||||
|
|
||||||
/* CoreText does automatic font fallback (AKA "cascading") for characters
|
/* CoreText does automatic font fallback (AKA "cascading") for characters
|
||||||
* not supported by the requested font, and provides no way to turn it off,
|
* not supported by the requested font, and provides no way to turn it off,
|
||||||
@ -860,8 +887,14 @@ retry:
|
|||||||
goto resize_and_retry;
|
goto resize_and_retry;
|
||||||
hb_glyph_info_t *info = buffer->info + buffer->len;
|
hb_glyph_info_t *info = buffer->info + buffer->len;
|
||||||
|
|
||||||
CGGlyph notdef = 0;
|
hb_codepoint_t notdef = 0;
|
||||||
double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, ¬def, NULL, 1);
|
hb_direction_t dir = buffer->props.direction;
|
||||||
|
hb_position_t x_advance, y_advance, x_offset, y_offset;
|
||||||
|
hb_font_get_glyph_advance_for_direction (font, notdef, dir, &x_advance, &y_advance);
|
||||||
|
hb_font_get_glyph_origin_for_direction (font, notdef, dir, &x_offset, &y_offset);
|
||||||
|
hb_position_t advance = x_advance + y_advance;
|
||||||
|
x_offset = -x_offset;
|
||||||
|
y_offset = -y_offset;
|
||||||
|
|
||||||
unsigned int old_len = buffer->len;
|
unsigned int old_len = buffer->len;
|
||||||
for (CFIndex j = range.location; j < range.location + range.length; j++)
|
for (CFIndex j = range.location; j < range.location + range.length; j++)
|
||||||
@ -875,19 +908,22 @@ retry:
|
|||||||
* for this one. */
|
* for this one. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (buffer->unicode->is_default_ignorable (ch))
|
||||||
|
continue;
|
||||||
|
|
||||||
info->codepoint = notdef;
|
info->codepoint = notdef;
|
||||||
info->cluster = log_clusters[j];
|
info->cluster = log_clusters[j];
|
||||||
|
|
||||||
info->mask = advance;
|
info->mask = advance;
|
||||||
info->var1.u32 = 0;
|
info->var1.u32 = x_offset;
|
||||||
info->var2.u32 = 0;
|
info->var2.u32 = y_offset;
|
||||||
|
|
||||||
info++;
|
info++;
|
||||||
buffer->len++;
|
buffer->len++;
|
||||||
}
|
}
|
||||||
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
|
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
|
||||||
buffer->reverse_range (old_len, buffer->len);
|
buffer->reverse_range (old_len, buffer->len);
|
||||||
|
advances_so_far += run_advance;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -917,7 +953,7 @@ retry:
|
|||||||
scratch_size = scratch_size_saved; \
|
scratch_size = scratch_size_saved; \
|
||||||
scratch = scratch_saved;
|
scratch = scratch_saved;
|
||||||
|
|
||||||
{
|
{ /* Setup glyphs */
|
||||||
SCRATCH_SAVE();
|
SCRATCH_SAVE();
|
||||||
const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL;
|
const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL;
|
||||||
if (!glyphs) {
|
if (!glyphs) {
|
||||||
@ -941,6 +977,11 @@ retry:
|
|||||||
SCRATCH_RESTORE();
|
SCRATCH_RESTORE();
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
/* Setup positions.
|
||||||
|
* Note that CoreText does not return advances for glyphs. As such,
|
||||||
|
* for all but last glyph, we use the delta position to next glyph as
|
||||||
|
* advance (in the advance direction only), and for last glyph we set
|
||||||
|
* whatever is needed to make the whole run's advance add up. */
|
||||||
SCRATCH_SAVE();
|
SCRATCH_SAVE();
|
||||||
const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL;
|
const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL;
|
||||||
if (!positions) {
|
if (!positions) {
|
||||||
@ -948,33 +989,42 @@ retry:
|
|||||||
CTRunGetPositions (run, range_all, position_buf);
|
CTRunGetPositions (run, range_all, position_buf);
|
||||||
positions = position_buf;
|
positions = position_buf;
|
||||||
}
|
}
|
||||||
double run_advance = CTRunGetTypographicBounds (run, range_all, NULL, NULL, NULL);
|
|
||||||
DEBUG_MSG (CORETEXT, run, "Run advance: %g", run_advance);
|
|
||||||
hb_glyph_info_t *info = run_info;
|
hb_glyph_info_t *info = run_info;
|
||||||
|
CGFloat x_mult = font_data->x_mult, y_mult = font_data->y_mult;
|
||||||
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
|
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
|
||||||
{
|
{
|
||||||
|
hb_position_t x_offset = (positions[0].x - advances_so_far) * x_mult;
|
||||||
for (unsigned int j = 0; j < num_glyphs; j++)
|
for (unsigned int j = 0; j < num_glyphs; j++)
|
||||||
{
|
{
|
||||||
double advance = (j + 1 < num_glyphs ? positions[j + 1].x : positions[0].x + run_advance) - positions[j].x;
|
double advance;
|
||||||
info->mask = advance;
|
if (likely (j + 1 < num_glyphs))
|
||||||
info->var1.u32 = positions[0].x; /* Yes, zero. */
|
advance = positions[j + 1].x - positions[j].x;
|
||||||
info->var2.u32 = positions[j].y;
|
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++;
|
info++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
run_advance = -run_advance;
|
hb_position_t y_offset = (positions[0].y - advances_so_far) * y_mult;
|
||||||
for (unsigned int j = 0; j < num_glyphs; j++)
|
for (unsigned int j = 0; j < num_glyphs; j++)
|
||||||
{
|
{
|
||||||
double advance = (j + 1 < num_glyphs ? positions[j + 1].y : positions[0].y + run_advance) - positions[j].y;
|
double advance;
|
||||||
info->mask = advance;
|
if (likely (j + 1 < num_glyphs))
|
||||||
info->var1.u32 = positions[j].x;
|
advance = positions[j + 1].y - positions[j].y;
|
||||||
info->var2.u32 = positions[0].y; /* Yes, zero. */
|
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++;
|
info++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SCRATCH_RESTORE();
|
SCRATCH_RESTORE();
|
||||||
|
advances_so_far += run_advance;
|
||||||
}
|
}
|
||||||
#undef SCRATCH_RESTORE
|
#undef SCRATCH_RESTORE
|
||||||
#undef SCRATCH_SAVE
|
#undef SCRATCH_SAVE
|
||||||
|
@ -165,8 +165,8 @@ hb_face_create (hb_blob_t *blob,
|
|||||||
{
|
{
|
||||||
hb_face_t *face;
|
hb_face_t *face;
|
||||||
|
|
||||||
if (unlikely (!blob || !hb_blob_get_length (blob)))
|
if (unlikely (!blob))
|
||||||
return hb_face_get_empty ();
|
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);
|
hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
|
||||||
|
|
||||||
|
@ -814,7 +814,7 @@ hb_font_glyph_to_string (hb_font_t *font,
|
|||||||
/**
|
/**
|
||||||
* hb_font_glyph_from_string:
|
* hb_font_glyph_from_string:
|
||||||
* @font: a font.
|
* @font: a font.
|
||||||
* @s: (array length=len):
|
* @s: (array length=len) (element-type uint8_t):
|
||||||
* @len:
|
* @len:
|
||||||
* @glyph: (out):
|
* @glyph: (out):
|
||||||
*
|
*
|
||||||
@ -854,8 +854,6 @@ hb_font_create (hb_face_t *face)
|
|||||||
|
|
||||||
if (unlikely (!face))
|
if (unlikely (!face))
|
||||||
face = hb_face_get_empty ();
|
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> ()))
|
if (!(font = hb_object_create<hb_font_t> ()))
|
||||||
return hb_font_get_empty ();
|
return hb_font_get_empty ();
|
||||||
|
|
||||||
@ -880,7 +878,7 @@ hb_font_t *
|
|||||||
hb_font_create_sub_font (hb_font_t *parent)
|
hb_font_create_sub_font (hb_font_t *parent)
|
||||||
{
|
{
|
||||||
if (unlikely (!parent))
|
if (unlikely (!parent))
|
||||||
return hb_font_get_empty ();
|
parent = hb_font_get_empty ();
|
||||||
|
|
||||||
hb_font_t *font = hb_font_create (parent->face);
|
hb_font_t *font = hb_font_create (parent->face);
|
||||||
|
|
||||||
|
@ -51,6 +51,13 @@
|
|||||||
* In particular, FT_Get_Advance() without the NO_HINTING flag seems to be
|
* In particular, FT_Get_Advance() without the NO_HINTING flag seems to be
|
||||||
* buggy.
|
* buggy.
|
||||||
*
|
*
|
||||||
|
* FreeType works in 26.6 mode. Clients can decide to use that mode, and everything
|
||||||
|
* would work fine. However, we also abuse this API for performing in font-space,
|
||||||
|
* but don't pass the correct flags to FreeType. We just abuse the no-hinting mode
|
||||||
|
* for that, such that no rounding etc happens. As such, we don't set ppem, and
|
||||||
|
* pass NO_HINTING around. This seems to work best, until we go ahead and add a full
|
||||||
|
* load_flags API.
|
||||||
|
*
|
||||||
* - We don't handle / allow for emboldening / obliqueing.
|
* - We don't handle / allow for emboldening / obliqueing.
|
||||||
*
|
*
|
||||||
* - In the future, we should add constructors to create fonts in font space?
|
* - In the future, we should add constructors to create fonts in font space?
|
||||||
@ -70,12 +77,10 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
|
|||||||
{
|
{
|
||||||
FT_Face ft_face = (FT_Face) font_data;
|
FT_Face ft_face = (FT_Face) font_data;
|
||||||
|
|
||||||
#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
|
|
||||||
if (unlikely (variation_selector)) {
|
if (unlikely (variation_selector)) {
|
||||||
*glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
|
*glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
|
||||||
return *glyph != 0;
|
return *glyph != 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
*glyph = FT_Get_Char_Index (ft_face, unicode);
|
*glyph = FT_Get_Char_Index (ft_face, unicode);
|
||||||
return *glyph != 0;
|
return *glyph != 0;
|
||||||
@ -94,6 +99,9 @@ hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
|
|||||||
if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
|
if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (font->x_scale < 0)
|
||||||
|
v = -v;
|
||||||
|
|
||||||
return (v + (1<<9)) >> 10;
|
return (v + (1<<9)) >> 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +118,9 @@ hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
|
|||||||
if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
|
if (unlikely (FT_Get_Advance (ft_face, glyph, load_flags, &v)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (font->y_scale < 0)
|
||||||
|
v = -v;
|
||||||
|
|
||||||
/* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
|
/* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
|
||||||
* have a Y growing upward. Hence the extra negation. */
|
* have a Y growing upward. Hence the extra negation. */
|
||||||
return (-v + (1<<9)) >> 10;
|
return (-v + (1<<9)) >> 10;
|
||||||
@ -146,6 +157,11 @@ hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
|
|||||||
*x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX;
|
*x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX;
|
||||||
*y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
|
*y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY);
|
||||||
|
|
||||||
|
if (font->x_scale < 0)
|
||||||
|
*x = -*x;
|
||||||
|
if (font->y_scale < 0)
|
||||||
|
*y = -*y;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,11 +356,7 @@ hb_ft_face_create (FT_Face ft_face,
|
|||||||
|
|
||||||
blob = hb_blob_create ((const char *) ft_face->stream->base,
|
blob = hb_blob_create ((const char *) ft_face->stream->base,
|
||||||
(unsigned int) ft_face->stream->size,
|
(unsigned int) ft_face->stream->size,
|
||||||
/* TODO: We assume that it's mmap()'ed, but FreeType code
|
HB_MEMORY_MODE_READONLY,
|
||||||
* suggests that there are cases we reach here but font is
|
|
||||||
* not mmapped. For example, when mmap() fails. No idea
|
|
||||||
* how to deal with it better here. */
|
|
||||||
HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
|
|
||||||
ft_face, destroy);
|
ft_face, destroy);
|
||||||
face = hb_face_create (blob, ft_face->face_index);
|
face = hb_face_create (blob, ft_face->face_index);
|
||||||
hb_blob_destroy (blob);
|
hb_blob_destroy (blob);
|
||||||
@ -358,6 +370,22 @@ hb_ft_face_create (FT_Face ft_face,
|
|||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ft_face_create_referenced:
|
||||||
|
* @ft_face:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Return value: (transfer full):
|
||||||
|
* Since: 1.0
|
||||||
|
**/
|
||||||
|
hb_face_t *
|
||||||
|
hb_ft_face_create_referenced (FT_Face ft_face)
|
||||||
|
{
|
||||||
|
FT_Reference_Face (ft_face);
|
||||||
|
return hb_ft_face_create (ft_face, (hb_destroy_func_t) FT_Done_Face);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
hb_ft_face_finalize (FT_Face ft_face)
|
hb_ft_face_finalize (FT_Face ft_face)
|
||||||
{
|
{
|
||||||
@ -420,23 +448,43 @@ hb_ft_font_create (FT_Face ft_face,
|
|||||||
hb_font_set_scale (font,
|
hb_font_set_scale (font,
|
||||||
(int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16),
|
(int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16),
|
||||||
(int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16));
|
(int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16));
|
||||||
|
#if 0 /* hb-ft works in no-hinting model */
|
||||||
hb_font_set_ppem (font,
|
hb_font_set_ppem (font,
|
||||||
ft_face->size->metrics.x_ppem,
|
ft_face->size->metrics.x_ppem,
|
||||||
ft_face->size->metrics.y_ppem);
|
ft_face->size->metrics.y_ppem);
|
||||||
|
#endif
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ft_font_create_referenced:
|
||||||
|
* @ft_face:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Return value: (transfer full):
|
||||||
|
* Since: 1.0
|
||||||
|
**/
|
||||||
|
hb_font_t *
|
||||||
|
hb_ft_font_create_referenced (FT_Face ft_face)
|
||||||
|
{
|
||||||
|
FT_Reference_Face (ft_face);
|
||||||
|
return hb_ft_font_create (ft_face, (hb_destroy_func_t) FT_Done_Face);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Thread-safe, lock-free, FT_Library */
|
/* Thread-safe, lock-free, FT_Library */
|
||||||
|
|
||||||
static FT_Library ft_library;
|
static FT_Library ft_library;
|
||||||
|
|
||||||
static inline
|
#ifdef HB_USE_ATEXIT
|
||||||
|
static
|
||||||
void free_ft_library (void)
|
void free_ft_library (void)
|
||||||
{
|
{
|
||||||
FT_Done_FreeType (ft_library);
|
FT_Done_FreeType (ft_library);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static FT_Library
|
static FT_Library
|
||||||
get_ft_library (void)
|
get_ft_library (void)
|
||||||
@ -493,14 +541,19 @@ hb_ft_font_set_funcs (hb_font_t *font)
|
|||||||
|
|
||||||
FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
|
FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
|
||||||
|
|
||||||
assert (font->y_scale >= 0);
|
|
||||||
FT_Set_Char_Size (ft_face,
|
FT_Set_Char_Size (ft_face,
|
||||||
font->x_scale, font->y_scale,
|
abs (font->x_scale), abs (font->y_scale),
|
||||||
0, 0);
|
0, 0);
|
||||||
#if 0
|
#if 0
|
||||||
font->x_ppem * 72 * 64 / font->x_scale,
|
font->x_ppem * 72 * 64 / font->x_scale,
|
||||||
font->y_ppem * 72 * 64 / font->y_scale);
|
font->y_ppem * 72 * 64 / font->y_scale);
|
||||||
#endif
|
#endif
|
||||||
|
if (font->x_scale < 0 || font->y_scale < 0)
|
||||||
|
{
|
||||||
|
FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0,
|
||||||
|
0, font->y_scale < 0 ? -1 : +1};
|
||||||
|
FT_Set_Transform (ft_face, &matrix, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
ft_face->generic.data = blob;
|
ft_face->generic.data = blob;
|
||||||
ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
|
ft_face->generic.finalizer = (FT_Generic_Finalizer) _release_blob;
|
||||||
|
@ -34,19 +34,76 @@
|
|||||||
|
|
||||||
HB_BEGIN_DECLS
|
HB_BEGIN_DECLS
|
||||||
|
|
||||||
/* Note: FreeType is not thread-safe. Hence, these functions are not either. */
|
/*
|
||||||
|
* Note: FreeType is not thread-safe.
|
||||||
|
* Hence, these functions are not either.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hb-face from ft-face.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This one creates a new hb-face for given ft-face.
|
||||||
|
* When the returned hb-face is destroyed, the destroy
|
||||||
|
* callback is called (if not NULL), with the ft-face passed
|
||||||
|
* to it.
|
||||||
|
*
|
||||||
|
* The client is responsible to make sure that ft-face is
|
||||||
|
* destroyed after hb-face is destroyed.
|
||||||
|
*
|
||||||
|
* Most often you don't want this function. You should use either
|
||||||
|
* hb_ft_face_create_cached(), or hb_ft_face_create_referenced().
|
||||||
|
* In particular, if you are going to pass NULL as destroy, you
|
||||||
|
* probably should use (the more recent) hb_ft_face_create_referenced()
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
hb_face_t *
|
hb_face_t *
|
||||||
hb_ft_face_create (FT_Face ft_face,
|
hb_ft_face_create (FT_Face ft_face,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy);
|
||||||
|
|
||||||
|
/* This version is like hb_ft_face_create(), except that it caches
|
||||||
|
* the hb-face using the generic pointer of the ft-face. This means
|
||||||
|
* that subsequent calls to this function with the same ft-face will
|
||||||
|
* return the same hb-face (correctly referenced).
|
||||||
|
*
|
||||||
|
* Client is still responsible for making sure that ft-face is destroyed
|
||||||
|
* after hb-face is.
|
||||||
|
*/
|
||||||
hb_face_t *
|
hb_face_t *
|
||||||
hb_ft_face_create_cached (FT_Face ft_face);
|
hb_ft_face_create_cached (FT_Face ft_face);
|
||||||
|
|
||||||
|
/* This version is like hb_ft_face_create(), except that it calls
|
||||||
|
* FT_Reference_Face() on ft-face, as such keeping ft-face alive
|
||||||
|
* as long as the hb-face is.
|
||||||
|
*
|
||||||
|
* This is the most convenient version to use. Use it unless you have
|
||||||
|
* very good reasons not to.
|
||||||
|
*/
|
||||||
|
hb_face_t *
|
||||||
|
hb_ft_face_create_referenced (FT_Face ft_face);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hb-font from ft-face.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note:
|
||||||
|
*
|
||||||
|
* Set face size on ft-face before creating hb-font from it.
|
||||||
|
* Otherwise hb-ft would NOT pick up the font size correctly.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* See notes on hb_ft_face_create(). Same issues re lifecycle-management
|
||||||
|
* apply here. Use hb_ft_font_create_referenced() if you can. */
|
||||||
hb_font_t *
|
hb_font_t *
|
||||||
hb_ft_font_create (FT_Face ft_face,
|
hb_ft_font_create (FT_Face ft_face,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy);
|
||||||
|
|
||||||
|
/* See notes on hb_ft_face_create_referenced() re lifecycle-management
|
||||||
|
* issues. */
|
||||||
|
hb_font_t *
|
||||||
|
hb_ft_font_create_referenced (FT_Face ft_face);
|
||||||
|
|
||||||
|
|
||||||
/* Makes an hb_font_t use FreeType internally to implement font functions. */
|
/* Makes an hb_font_t use FreeType internally to implement font functions. */
|
||||||
|
@ -382,3 +382,14 @@ hb_glib_get_unicode_funcs (void)
|
|||||||
return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
|
return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hb_blob_t *
|
||||||
|
hb_glib_blob_create (GBytes *gbytes)
|
||||||
|
{
|
||||||
|
gsize size = 0;
|
||||||
|
gconstpointer data = g_bytes_get_data (gbytes, &size);
|
||||||
|
return hb_blob_create ((const char *) data,
|
||||||
|
size,
|
||||||
|
HB_MEMORY_MODE_READONLY,
|
||||||
|
g_bytes_ref (gbytes),
|
||||||
|
(hb_destroy_func_t) g_bytes_unref);
|
||||||
|
}
|
||||||
|
@ -46,6 +46,9 @@ hb_glib_script_from_script (hb_script_t script);
|
|||||||
hb_unicode_funcs_t *
|
hb_unicode_funcs_t *
|
||||||
hb_glib_get_unicode_funcs (void);
|
hb_glib_get_unicode_funcs (void);
|
||||||
|
|
||||||
|
hb_blob_t *
|
||||||
|
hb_glib_blob_create (GBytes *gbytes);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
||||||
|
@ -363,10 +363,8 @@ hb_icu_get_unicode_funcs (void)
|
|||||||
if (!hb_atomic_ptr_get (&normalizer)) {
|
if (!hb_atomic_ptr_get (&normalizer)) {
|
||||||
UErrorCode icu_err = U_ZERO_ERROR;
|
UErrorCode icu_err = U_ZERO_ERROR;
|
||||||
/* We ignore failure in getNFCInstace(). */
|
/* We ignore failure in getNFCInstace(). */
|
||||||
hb_atomic_ptr_cmpexch (&normalizer, NULL, unorm2_getNFCInstance (&icu_err));
|
(void) hb_atomic_ptr_cmpexch (&normalizer, NULL, unorm2_getNFCInstance (&icu_err));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
|
return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,7 +39,13 @@
|
|||||||
|
|
||||||
/* We need external help for these */
|
/* 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__))
|
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||||
@ -47,7 +53,11 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
typedef CRITICAL_SECTION hb_mutex_impl_t;
|
typedef CRITICAL_SECTION hb_mutex_impl_t;
|
||||||
#define HB_MUTEX_IMPL_INIT {0}
|
#define HB_MUTEX_IMPL_INIT {0}
|
||||||
|
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
|
||||||
|
#define hb_mutex_impl_init(M) InitializeCriticalSectionEx (M, 0, 0)
|
||||||
|
#else
|
||||||
#define hb_mutex_impl_init(M) InitializeCriticalSection (M)
|
#define hb_mutex_impl_init(M) InitializeCriticalSection (M)
|
||||||
|
#endif
|
||||||
#define hb_mutex_impl_lock(M) EnterCriticalSection (M)
|
#define hb_mutex_impl_lock(M) EnterCriticalSection (M)
|
||||||
#define hb_mutex_impl_unlock(M) LeaveCriticalSection (M)
|
#define hb_mutex_impl_unlock(M) LeaveCriticalSection (M)
|
||||||
#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
|
#define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
|
||||||
@ -109,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_unlock(M) HB_STMT_START {} HB_STMT_END
|
||||||
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
|
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT}
|
#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT}
|
||||||
|
|
||||||
struct hb_mutex_t
|
struct hb_mutex_t
|
||||||
{
|
{
|
||||||
/* TODO Add tracing. */
|
/* TODO Add tracing. */
|
||||||
|
@ -47,19 +47,20 @@
|
|||||||
|
|
||||||
/* reference_count */
|
/* reference_count */
|
||||||
|
|
||||||
#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
|
#define HB_REFERENCE_COUNT_INVALID_VALUE -1
|
||||||
#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
|
#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INVALID_VALUE)}
|
||||||
|
|
||||||
struct hb_reference_count_t
|
struct hb_reference_count_t
|
||||||
{
|
{
|
||||||
hb_atomic_int_t ref_count;
|
hb_atomic_int_t ref_count;
|
||||||
|
|
||||||
inline void init (int v) { ref_count = v; }
|
inline void init (int v) { ref_count.set_unsafe (v); }
|
||||||
inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), 1); }
|
inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
|
||||||
inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); }
|
inline int inc (void) { return ref_count.inc (); }
|
||||||
inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; }
|
inline int dec (void) { return ref_count.dec (); }
|
||||||
|
inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_INVALID_VALUE); }
|
||||||
inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; }
|
|
||||||
|
|
||||||
|
inline bool is_invalid (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INVALID_VALUE; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ struct hb_object_header_t
|
|||||||
hb_reference_count_t ref_count;
|
hb_reference_count_t ref_count;
|
||||||
hb_user_data_array_t user_data;
|
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:
|
private:
|
||||||
ASSERT_POD ();
|
ASSERT_POD ();
|
||||||
@ -117,7 +118,7 @@ static inline void hb_object_trace (const Type *obj, const char *function)
|
|||||||
DEBUG_MSG (OBJECT, (void *) obj,
|
DEBUG_MSG (OBJECT, (void *) obj,
|
||||||
"%s refcount=%d",
|
"%s refcount=%d",
|
||||||
function,
|
function,
|
||||||
obj ? obj->header.ref_count.ref_count : 0);
|
obj ? obj->header.ref_count.get_unsafe () : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
@ -53,7 +53,8 @@ struct TTCHeader;
|
|||||||
|
|
||||||
typedef struct TableRecord
|
typedef struct TableRecord
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -102,7 +103,8 @@ typedef struct OffsetTable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
|
return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
|
||||||
}
|
}
|
||||||
@ -130,7 +132,8 @@ struct TTCHeaderVersion1
|
|||||||
inline unsigned int get_face_count (void) const { return table.len; }
|
inline unsigned int get_face_count (void) const { return table.len; }
|
||||||
inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
|
inline const OpenTypeFontFace& get_face (unsigned int i) const { return this+table[i]; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (table.sanitize (c, this));
|
return TRACE_RETURN (table.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -169,7 +172,8 @@ struct TTCHeader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false);
|
if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false);
|
||||||
switch (u.header.version.major) {
|
switch (u.header.version.major) {
|
||||||
@ -233,7 +237,8 @@ struct OpenTypeFontFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false);
|
if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false);
|
||||||
switch (u.tag) {
|
switch (u.tag) {
|
||||||
|
@ -179,10 +179,13 @@ struct hb_sanitize_context_t
|
|||||||
inline const char *get_name (void) { return "SANITIZE"; }
|
inline const char *get_name (void) { return "SANITIZE"; }
|
||||||
static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE;
|
static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE;
|
||||||
typedef bool return_t;
|
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>
|
template <typename T>
|
||||||
inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
|
inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
|
||||||
static return_t default_return_value (void) { return true; }
|
static return_t default_return_value (void) { return true; }
|
||||||
bool stop_sublookup_iteration (const return_t r HB_UNUSED) const { return false; }
|
bool stop_sublookup_iteration (const return_t r) const { return !r; }
|
||||||
|
|
||||||
inline void init (hb_blob_t *b)
|
inline void init (hb_blob_t *b)
|
||||||
{
|
{
|
||||||
@ -270,9 +273,9 @@ struct hb_sanitize_context_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type, typename ValueType>
|
template <typename Type, typename ValueType>
|
||||||
inline bool try_set (Type *obj, const ValueType &v) {
|
inline bool try_set (const Type *obj, const ValueType &v) {
|
||||||
if (this->may_edit (obj, obj->static_size)) {
|
if (this->may_edit (obj, obj->static_size)) {
|
||||||
obj->set (v);
|
const_cast<Type *> (obj)->set (v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -546,12 +549,6 @@ struct BEInt<Type, 2>
|
|||||||
return (v[0] << 8)
|
return (v[0] << 8)
|
||||||
+ (v[1] );
|
+ (v[1] );
|
||||||
}
|
}
|
||||||
inline bool operator == (const BEInt<Type, 2>& o) const
|
|
||||||
{
|
|
||||||
return v[0] == o.v[0]
|
|
||||||
&& v[1] == o.v[1];
|
|
||||||
}
|
|
||||||
inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o); }
|
|
||||||
private: uint8_t v[2];
|
private: uint8_t v[2];
|
||||||
};
|
};
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
@ -570,13 +567,6 @@ struct BEInt<Type, 3>
|
|||||||
+ (v[1] << 8)
|
+ (v[1] << 8)
|
||||||
+ (v[2] );
|
+ (v[2] );
|
||||||
}
|
}
|
||||||
inline bool operator == (const BEInt<Type, 3>& o) const
|
|
||||||
{
|
|
||||||
return v[0] == o.v[0]
|
|
||||||
&& v[1] == o.v[1]
|
|
||||||
&& v[2] == o.v[2];
|
|
||||||
}
|
|
||||||
inline bool operator != (const BEInt<Type, 3>& o) const { return !(*this == o); }
|
|
||||||
private: uint8_t v[3];
|
private: uint8_t v[3];
|
||||||
};
|
};
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
@ -597,14 +587,6 @@ struct BEInt<Type, 4>
|
|||||||
+ (v[2] << 8)
|
+ (v[2] << 8)
|
||||||
+ (v[3] );
|
+ (v[3] );
|
||||||
}
|
}
|
||||||
inline bool operator == (const BEInt<Type, 4>& o) const
|
|
||||||
{
|
|
||||||
return v[0] == o.v[0]
|
|
||||||
&& v[1] == o.v[1]
|
|
||||||
&& v[2] == o.v[2]
|
|
||||||
&& v[3] == o.v[3];
|
|
||||||
}
|
|
||||||
inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o); }
|
|
||||||
private: uint8_t v[4];
|
private: uint8_t v[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -614,12 +596,19 @@ struct IntType
|
|||||||
{
|
{
|
||||||
inline void set (Type i) { v.set (i); }
|
inline void set (Type i) { v.set (i); }
|
||||||
inline operator Type(void) const { return v; }
|
inline operator Type(void) const { return v; }
|
||||||
inline bool operator == (const IntType<Type,Size> &o) const { return v == o.v; }
|
inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
|
||||||
inline bool operator != (const IntType<Type,Size> &o) const { return v != o.v; }
|
inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
|
||||||
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
|
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
|
||||||
inline int cmp (IntType<Type,Size> va) const { Type a = va; Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
|
inline int cmp (Type a) const
|
||||||
inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
Type b = v;
|
||||||
|
if (sizeof (Type) < sizeof (int))
|
||||||
|
return (int) a - (int) b;
|
||||||
|
else
|
||||||
|
return a < b ? -1 : a == b ? 0 : +1;
|
||||||
|
}
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (likely (c->check_struct (this)));
|
return TRACE_RETURN (likely (c->check_struct (this)));
|
||||||
}
|
}
|
||||||
@ -646,7 +635,8 @@ typedef USHORT UFWORD;
|
|||||||
* 1904. The value is represented as a signed 64-bit integer. */
|
* 1904. The value is represented as a signed 64-bit integer. */
|
||||||
struct LONGDATETIME
|
struct LONGDATETIME
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (likely (c->check_struct (this)));
|
return TRACE_RETURN (likely (c->check_struct (this)));
|
||||||
}
|
}
|
||||||
@ -670,7 +660,10 @@ struct Tag : ULONG
|
|||||||
DEFINE_NULL_DATA (Tag, " ");
|
DEFINE_NULL_DATA (Tag, " ");
|
||||||
|
|
||||||
/* Glyph index number, same as uint16 (length = 16 bits) */
|
/* Glyph index number, same as uint16 (length = 16 bits) */
|
||||||
typedef USHORT GlyphID;
|
struct GlyphID : USHORT {
|
||||||
|
static inline int cmp (const GlyphID *a, const GlyphID *b) { return b->USHORT::cmp (*a); }
|
||||||
|
inline int cmp (hb_codepoint_t a) const { return (int) a - (int) *this; }
|
||||||
|
};
|
||||||
|
|
||||||
/* Script/language-system/feature index */
|
/* Script/language-system/feature index */
|
||||||
struct Index : USHORT {
|
struct Index : USHORT {
|
||||||
@ -719,7 +712,8 @@ struct FixedVersion
|
|||||||
{
|
{
|
||||||
inline uint32_t to_int (void) const { return (major << 16) + minor; }
|
inline uint32_t to_int (void) const { return (major << 16) + minor; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -747,33 +741,35 @@ struct OffsetTo : Offset<OffsetType>
|
|||||||
return StructAtOffset<Type> (base, offset);
|
return StructAtOffset<Type> (base, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Type& serialize (hb_serialize_context_t *c, void *base)
|
inline Type& serialize (hb_serialize_context_t *c, const void *base)
|
||||||
{
|
{
|
||||||
Type *t = c->start_embed<Type> ();
|
Type *t = c->start_embed<Type> ();
|
||||||
this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
|
this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
|
||||||
return *t;
|
return *t;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
||||||
unsigned int offset = *this;
|
unsigned int offset = *this;
|
||||||
if (unlikely (!offset)) return TRACE_RETURN (true);
|
if (unlikely (!offset)) return TRACE_RETURN (true);
|
||||||
Type &obj = StructAtOffset<Type> (base, offset);
|
const Type &obj = StructAtOffset<Type> (base, offset);
|
||||||
return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c));
|
return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c));
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
||||||
unsigned int offset = *this;
|
unsigned int offset = *this;
|
||||||
if (unlikely (!offset)) return TRACE_RETURN (true);
|
if (unlikely (!offset)) return TRACE_RETURN (true);
|
||||||
Type &obj = StructAtOffset<Type> (base, offset);
|
const Type &obj = StructAtOffset<Type> (base, offset);
|
||||||
return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
|
return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the offset to Null */
|
/* Set the offset to Null */
|
||||||
inline bool neuter (hb_sanitize_context_t *c) {
|
inline bool neuter (hb_sanitize_context_t *c) const {
|
||||||
return c->try_set (this, 0);
|
return c->try_set (this, 0);
|
||||||
}
|
}
|
||||||
DEFINE_SIZE_STATIC (sizeof(OffsetType));
|
DEFINE_SIZE_STATIC (sizeof(OffsetType));
|
||||||
@ -838,7 +834,8 @@ struct ArrayOf
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||||
|
|
||||||
@ -853,7 +850,8 @@ struct ArrayOf
|
|||||||
|
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||||
unsigned int count = len;
|
unsigned int count = len;
|
||||||
@ -863,7 +861,8 @@ struct ArrayOf
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base, T user_data) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||||
unsigned int count = len;
|
unsigned int count = len;
|
||||||
@ -884,7 +883,8 @@ struct ArrayOf
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len));
|
return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len));
|
||||||
}
|
}
|
||||||
@ -910,12 +910,14 @@ struct OffsetListOf : OffsetArrayOf<Type>
|
|||||||
return this+this->array[i];
|
return this+this->array[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this));
|
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this));
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, T user_data) {
|
inline bool sanitize (hb_sanitize_context_t *c, T user_data) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data));
|
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data));
|
||||||
}
|
}
|
||||||
@ -949,12 +951,14 @@ struct HeadlessArrayOf
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
return c->check_struct (this)
|
return c->check_struct (this)
|
||||||
&& c->check_array (this, Type::static_size, len);
|
&& c->check_array (this, Type::static_size, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||||
|
|
||||||
|
@ -51,7 +51,8 @@ struct CmapSubtableFormat0
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -125,7 +126,7 @@ struct CmapSubtableFormat4
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c)
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!c->check_struct (this)))
|
if (unlikely (!c->check_struct (this)))
|
||||||
@ -183,7 +184,8 @@ struct CmapSubtableLongGroup
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -210,7 +212,8 @@ struct CmapSubtableTrimmed
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c));
|
return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -242,7 +245,8 @@ struct CmapSubtableLongSegmented
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c));
|
return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -288,7 +292,8 @@ struct UnicodeValueRange
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -309,7 +314,8 @@ struct UVSMapping
|
|||||||
return unicodeValue.cmp (codepoint);
|
return unicodeValue.cmp (codepoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -348,7 +354,8 @@ struct VariationSelectorRecord
|
|||||||
return varSelector.cmp (variation_selector);
|
return varSelector.cmp (variation_selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
defaultUVS.sanitize (c, base) &&
|
defaultUVS.sanitize (c, base) &&
|
||||||
@ -373,7 +380,8 @@ struct CmapSubtableFormat14
|
|||||||
return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this);
|
return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
record.sanitize (c, this));
|
record.sanitize (c, this));
|
||||||
@ -418,7 +426,8 @@ struct CmapSubtable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
@ -461,7 +470,8 @@ struct EncodingRecord
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
subtable.sanitize (c, base));
|
subtable.sanitize (c, base));
|
||||||
@ -496,7 +506,8 @@ struct cmap
|
|||||||
return &(this+encodingRecord[result].subtable);
|
return &(this+encodingRecord[result].subtable);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
likely (version == 0) &&
|
likely (version == 0) &&
|
||||||
|
@ -45,9 +45,9 @@ struct hb_ot_face_metrics_accelerator_t
|
|||||||
|
|
||||||
inline void init (hb_face_t *face,
|
inline void init (hb_face_t *face,
|
||||||
hb_tag_t _hea_tag, hb_tag_t _mtx_tag,
|
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 ();
|
this->num_metrics = face->get_num_glyphs ();
|
||||||
|
|
||||||
hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag));
|
hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag));
|
||||||
@ -114,6 +114,7 @@ struct hb_ot_face_cmap_accelerator_t
|
|||||||
if (!subtable) subtable = cmap->find_subtable (0, 2);
|
if (!subtable) subtable = cmap->find_subtable (0, 2);
|
||||||
if (!subtable) subtable = cmap->find_subtable (0, 1);
|
if (!subtable) subtable = cmap->find_subtable (0, 1);
|
||||||
if (!subtable) subtable = cmap->find_subtable (0, 0);
|
if (!subtable) subtable = cmap->find_subtable (0, 0);
|
||||||
|
if (!subtable) subtable = cmap->find_subtable (3, 0);
|
||||||
/* Meh. */
|
/* Meh. */
|
||||||
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
|
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
|
||||||
|
|
||||||
|
@ -45,13 +45,15 @@ struct head
|
|||||||
{
|
{
|
||||||
static const hb_tag_t tableTag = HB_OT_TAG_head;
|
static const hb_tag_t tableTag = HB_OT_TAG_head;
|
||||||
|
|
||||||
inline unsigned int get_upem (void) const {
|
inline unsigned int get_upem (void) const
|
||||||
|
{
|
||||||
unsigned int upem = unitsPerEm;
|
unsigned int upem = unitsPerEm;
|
||||||
/* If no valid head table found, assume 1000, which matches typical Type1 usage. */
|
/* If no valid head table found, assume 1000, which matches typical Type1 usage. */
|
||||||
return 16 <= upem && upem <= 16384 ? upem : 1000;
|
return 16 <= upem && upem <= 16384 ? upem : 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
|
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,8 @@ struct _hea
|
|||||||
static const hb_tag_t hheaTag = HB_OT_TAG_hhea;
|
static const hb_tag_t hheaTag = HB_OT_TAG_hhea;
|
||||||
static const hb_tag_t vheaTag = HB_OT_TAG_vhea;
|
static const hb_tag_t vheaTag = HB_OT_TAG_vhea;
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
|
return TRACE_RETURN (c->check_struct (this) && likely (version.major == 1));
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,8 @@ struct _mtx
|
|||||||
static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx;
|
static const hb_tag_t hmtxTag = HB_OT_TAG_hmtx;
|
||||||
static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx;
|
static const hb_tag_t vmtxTag = HB_OT_TAG_vmtx;
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
/* We don't check for anything specific here. The users of the
|
/* We don't check for anything specific here. The users of the
|
||||||
* struct do all the hard work... */
|
* struct do all the hard work... */
|
||||||
|
@ -37,6 +37,12 @@
|
|||||||
namespace OT {
|
namespace OT {
|
||||||
|
|
||||||
|
|
||||||
|
#define TRACE_DISPATCH(this, format) \
|
||||||
|
hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
|
||||||
|
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||||
|
"format %d", (int) format);
|
||||||
|
|
||||||
|
|
||||||
#define NOT_COVERED ((unsigned int) -1)
|
#define NOT_COVERED ((unsigned int) -1)
|
||||||
#define MAX_NESTING_LEVEL 8
|
#define MAX_NESTING_LEVEL 8
|
||||||
#define MAX_CONTEXT_LENGTH 64
|
#define MAX_CONTEXT_LENGTH 64
|
||||||
@ -63,9 +69,10 @@ struct Record
|
|||||||
|
|
||||||
struct sanitize_closure_t {
|
struct sanitize_closure_t {
|
||||||
hb_tag_t tag;
|
hb_tag_t tag;
|
||||||
void *list_base;
|
const void *list_base;
|
||||||
};
|
};
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
const sanitize_closure_t closure = {tag, base};
|
const sanitize_closure_t closure = {tag, base};
|
||||||
return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure));
|
return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base, &closure));
|
||||||
@ -121,7 +128,8 @@ struct RecordListOf : RecordArrayOf<Type>
|
|||||||
inline const Type& operator [] (unsigned int i) const
|
inline const Type& operator [] (unsigned int i) const
|
||||||
{ return this+RecordArrayOf<Type>::operator [](i).offset; }
|
{ return this+RecordArrayOf<Type>::operator [](i).offset; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this));
|
return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -134,7 +142,8 @@ struct RangeRecord
|
|||||||
return g < start ? -1 : g <= end ? 0 : +1 ;
|
return g < start ? -1 : g <= end ? 0 : +1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -199,7 +208,8 @@ struct LangSys
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c,
|
inline bool sanitize (hb_sanitize_context_t *c,
|
||||||
const Record<LangSys>::sanitize_closure_t * = NULL) {
|
const Record<LangSys>::sanitize_closure_t * = NULL) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c));
|
return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -238,7 +248,8 @@ struct Script
|
|||||||
inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
|
inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c,
|
inline bool sanitize (hb_sanitize_context_t *c,
|
||||||
const Record<Script>::sanitize_closure_t * = NULL) {
|
const Record<Script>::sanitize_closure_t * = NULL) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
|
return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -260,7 +271,8 @@ typedef RecordListOf<Script> ScriptList;
|
|||||||
/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
|
/* http://www.microsoft.com/typography/otspec/features_pt.htm#size */
|
||||||
struct FeatureParamsSize
|
struct FeatureParamsSize
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
||||||
|
|
||||||
@ -371,7 +383,8 @@ struct FeatureParamsSize
|
|||||||
/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */
|
/* http://www.microsoft.com/typography/otspec/features_pt.htm#ssxx */
|
||||||
struct FeatureParamsStylisticSet
|
struct FeatureParamsStylisticSet
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
/* Right now minorVersion is at zero. Which means, any table supports
|
/* Right now minorVersion is at zero. Which means, any table supports
|
||||||
* the uiNameID field. */
|
* the uiNameID field. */
|
||||||
@ -404,7 +417,8 @@ struct FeatureParamsStylisticSet
|
|||||||
/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
|
/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
|
||||||
struct FeatureParamsCharacterVariants
|
struct FeatureParamsCharacterVariants
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
characters.sanitize (c));
|
characters.sanitize (c));
|
||||||
@ -444,7 +458,8 @@ struct FeatureParamsCharacterVariants
|
|||||||
|
|
||||||
struct FeatureParams
|
struct FeatureParams
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) {
|
inline bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (tag == HB_TAG ('s','i','z','e'))
|
if (tag == HB_TAG ('s','i','z','e'))
|
||||||
return TRACE_RETURN (u.size.sanitize (c));
|
return TRACE_RETURN (u.size.sanitize (c));
|
||||||
@ -486,7 +501,8 @@ struct Feature
|
|||||||
{ return this+featureParams; }
|
{ return this+featureParams; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c,
|
inline bool sanitize (hb_sanitize_context_t *c,
|
||||||
const Record<Feature>::sanitize_closure_t *closure) {
|
const Record<Feature>::sanitize_closure_t *closure) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
|
if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
|
||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
@ -561,6 +577,17 @@ struct Lookup
|
|||||||
{
|
{
|
||||||
inline unsigned int get_subtable_count (void) const { return subTable.len; }
|
inline unsigned int get_subtable_count (void) const { return subTable.len; }
|
||||||
|
|
||||||
|
template <typename SubTableType>
|
||||||
|
inline const SubTableType& get_subtable (unsigned int i) const
|
||||||
|
{ return this+CastR<OffsetArrayOf<SubTableType> > (subTable)[i]; }
|
||||||
|
|
||||||
|
template <typename SubTableType>
|
||||||
|
inline const OffsetArrayOf<SubTableType>& get_subtables (void) const
|
||||||
|
{ return CastR<OffsetArrayOf<SubTableType> > (subTable); }
|
||||||
|
template <typename SubTableType>
|
||||||
|
inline OffsetArrayOf<SubTableType>& get_subtables (void)
|
||||||
|
{ return CastR<OffsetArrayOf<SubTableType> > (subTable); }
|
||||||
|
|
||||||
inline unsigned int get_type (void) const { return lookupType; }
|
inline unsigned int get_type (void) const { return lookupType; }
|
||||||
|
|
||||||
/* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
|
/* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
|
||||||
@ -577,6 +604,20 @@ struct Lookup
|
|||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SubTableType, typename context_t>
|
||||||
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
|
{
|
||||||
|
unsigned int lookup_type = get_type ();
|
||||||
|
TRACE_DISPATCH (this, lookup_type);
|
||||||
|
unsigned int count = get_subtable_count ();
|
||||||
|
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_RETURN (c->default_return_value ());
|
||||||
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
unsigned int lookup_type,
|
unsigned int lookup_type,
|
||||||
uint32_t lookup_props,
|
uint32_t lookup_props,
|
||||||
@ -595,18 +636,20 @@ struct Lookup
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
/* Real sanitize of the subtables is done by GSUB/GPOS/... */
|
/* 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_RETURN (false);
|
||||||
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
|
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
|
||||||
{
|
{
|
||||||
USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
|
const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
|
||||||
if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false);
|
if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false);
|
||||||
}
|
}
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
USHORT lookupType; /* Different enumerations for GSUB and GPOS */
|
USHORT lookupType; /* Different enumerations for GSUB and GPOS */
|
||||||
USHORT lookupFlag; /* Lookup qualifiers */
|
USHORT lookupFlag; /* Lookup qualifiers */
|
||||||
ArrayOf<Offset<> >
|
ArrayOf<Offset<> >
|
||||||
@ -651,7 +694,8 @@ struct CoverageFormat1
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (glyphArray.sanitize (c));
|
return TRACE_RETURN (glyphArray.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -737,7 +781,8 @@ struct CoverageFormat2
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (rangeRecord.sanitize (c));
|
return TRACE_RETURN (rangeRecord.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -832,7 +877,8 @@ struct Coverage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
@ -938,12 +984,14 @@ struct ClassDefFormat1
|
|||||||
private:
|
private:
|
||||||
inline unsigned int get_class (hb_codepoint_t glyph_id) const
|
inline unsigned int get_class (hb_codepoint_t glyph_id) const
|
||||||
{
|
{
|
||||||
if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len))
|
unsigned int i = (unsigned int) (glyph_id - startGlyph);
|
||||||
return classValue[glyph_id - startGlyph];
|
if (unlikely (i < classValue.len))
|
||||||
|
return classValue[i];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c));
|
return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -994,12 +1042,13 @@ struct ClassDefFormat2
|
|||||||
inline unsigned int get_class (hb_codepoint_t glyph_id) const
|
inline unsigned int get_class (hb_codepoint_t glyph_id) const
|
||||||
{
|
{
|
||||||
int i = rangeRecord.bsearch (glyph_id);
|
int i = rangeRecord.bsearch (glyph_id);
|
||||||
if (i != -1)
|
if (unlikely (i != -1))
|
||||||
return rangeRecord[i].value;
|
return rangeRecord[i].value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (rangeRecord.sanitize (c));
|
return TRACE_RETURN (rangeRecord.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -1056,7 +1105,8 @@ struct ClassDef
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
@ -1148,7 +1198,8 @@ struct Device
|
|||||||
return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f)));
|
return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ()));
|
return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ()));
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,8 @@ struct AttachList
|
|||||||
return points.len;
|
return points.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -101,7 +102,8 @@ struct CaretValueFormat1
|
|||||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
|
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -127,7 +129,8 @@ struct CaretValueFormat2
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -150,7 +153,8 @@ struct CaretValueFormat3
|
|||||||
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font);
|
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this));
|
return TRACE_RETURN (c->check_struct (this) && deviceTable.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -178,7 +182,8 @@ struct CaretValue
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
@ -219,7 +224,8 @@ struct LigGlyph
|
|||||||
return carets.len;
|
return carets.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (carets.sanitize (c, this));
|
return TRACE_RETURN (carets.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -253,7 +259,8 @@ struct LigCaretList
|
|||||||
return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array);
|
return lig_glyph.get_lig_carets (font, direction, glyph_id, start_offset, caret_count, caret_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -275,7 +282,8 @@ struct MarkGlyphSetsFormat1
|
|||||||
inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||||
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
|
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -299,7 +307,8 @@ struct MarkGlyphSets
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
@ -364,7 +373,8 @@ struct GDEF
|
|||||||
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||||
{ return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
|
{ return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (version.sanitize (c) &&
|
return TRACE_RETURN (version.sanitize (c) &&
|
||||||
likely (version.major == 1) &&
|
likely (version.major == 1) &&
|
||||||
|
@ -146,7 +146,8 @@ struct ValueFormat : USHORT
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline bool sanitize_value_devices (hb_sanitize_context_t *c, void *base, Value *values) {
|
inline bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
|
||||||
|
{
|
||||||
unsigned int format = *this;
|
unsigned int format = *this;
|
||||||
|
|
||||||
if (format & xPlacement) values++;
|
if (format & xPlacement) values++;
|
||||||
@ -177,12 +178,14 @@ struct ValueFormat : USHORT
|
|||||||
return (format & devices) != 0;
|
return (format & devices) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *values) {
|
inline bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
|
return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count) {
|
inline bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
unsigned int len = get_len ();
|
unsigned int len = get_len ();
|
||||||
|
|
||||||
@ -200,7 +203,8 @@ struct ValueFormat : USHORT
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Just sanitize referenced Device tables. Doesn't check the values themselves. */
|
/* Just sanitize referenced Device tables. Doesn't check the values themselves. */
|
||||||
inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count, unsigned int stride) {
|
inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
|
||||||
if (!has_device ()) return TRACE_RETURN (true);
|
if (!has_device ()) return TRACE_RETURN (true);
|
||||||
@ -225,7 +229,8 @@ struct AnchorFormat1
|
|||||||
*y = font->em_scale_y (yCoordinate);
|
*y = font->em_scale_y (yCoordinate);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -254,7 +259,8 @@ struct AnchorFormat2
|
|||||||
*y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate);
|
*y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -282,7 +288,8 @@ struct AnchorFormat3
|
|||||||
*y += (this+yDeviceTable).get_x_delta (font);
|
*y += (this+yDeviceTable).get_x_delta (font);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
|
return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -317,7 +324,8 @@ struct Anchor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
@ -349,7 +357,8 @@ struct AnchorMatrix
|
|||||||
return this+matrixZ[row * cols + col];
|
return this+matrixZ[row * cols + col];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) {
|
inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!c->check_struct (this)) return TRACE_RETURN (false);
|
if (!c->check_struct (this)) return TRACE_RETURN (false);
|
||||||
if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false);
|
if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false);
|
||||||
@ -374,7 +383,8 @@ struct MarkRecord
|
|||||||
{
|
{
|
||||||
friend struct MarkArray;
|
friend struct MarkArray;
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base));
|
return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base));
|
||||||
}
|
}
|
||||||
@ -421,7 +431,8 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this));
|
return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -457,9 +468,12 @@ struct SinglePosFormat1
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values));
|
return TRACE_RETURN (c->check_struct (this)
|
||||||
|
&& coverage.sanitize (c, this)
|
||||||
|
&& valueFormat.sanitize_value (c, this, values));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -506,9 +520,12 @@ struct SinglePosFormat2
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount));
|
return TRACE_RETURN (c->check_struct (this)
|
||||||
|
&& coverage.sanitize (c, this)
|
||||||
|
&& valueFormat.sanitize_values (c, this, values, valueCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -531,6 +548,7 @@ struct SinglePos
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
||||||
@ -538,16 +556,6 @@ struct SinglePos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
case 2: return TRACE_RETURN (u.format2.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -602,12 +610,24 @@ struct PairSet
|
|||||||
unsigned int len2 = valueFormats[1].get_len ();
|
unsigned int len2 = valueFormats[1].get_len ();
|
||||||
unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
|
unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
|
||||||
|
|
||||||
const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
|
const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
|
||||||
unsigned int count = len;
|
unsigned int count = len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
|
||||||
|
/* Hand-coded bsearch. */
|
||||||
|
if (unlikely (!count))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
hb_codepoint_t x = buffer->info[pos].codepoint;
|
||||||
|
int min = 0, max = (int) count - 1;
|
||||||
|
while (min <= max)
|
||||||
{
|
{
|
||||||
/* TODO bsearch */
|
int mid = (min + max) / 2;
|
||||||
if (buffer->info[pos].codepoint == record->secondGlyph)
|
const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_array, record_size * mid);
|
||||||
|
hb_codepoint_t mid_x = record->secondGlyph;
|
||||||
|
if (x < mid_x)
|
||||||
|
max = mid - 1;
|
||||||
|
else if (x > mid_x)
|
||||||
|
min = mid + 1;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
valueFormats[0].apply_value (c->font, c->direction, this,
|
valueFormats[0].apply_value (c->font, c->direction, this,
|
||||||
&record->values[0], buffer->cur_pos());
|
&record->values[0], buffer->cur_pos());
|
||||||
@ -618,26 +638,26 @@ struct PairSet
|
|||||||
buffer->idx = pos;
|
buffer->idx = pos;
|
||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
record = &StructAtOffset<PairValueRecord> (record, record_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sanitize_closure_t {
|
struct sanitize_closure_t {
|
||||||
void *base;
|
const void *base;
|
||||||
ValueFormat *valueFormats;
|
const ValueFormat *valueFormats;
|
||||||
unsigned int len1; /* valueFormats[0].get_len() */
|
unsigned int len1; /* valueFormats[0].get_len() */
|
||||||
unsigned int stride; /* 1 + len1 + len2 */
|
unsigned int stride; /* 1 + len1 + len2 */
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) {
|
inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!(c->check_struct (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_RETURN (false);
|
||||||
|
|
||||||
unsigned int count = len;
|
unsigned int count = len;
|
||||||
PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
|
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)
|
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));
|
&& closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride));
|
||||||
}
|
}
|
||||||
@ -670,18 +690,18 @@ struct PairPosFormat1
|
|||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
hb_buffer_t *buffer = c->buffer;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
|
|
||||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
|
||||||
|
|
||||||
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
|
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_RETURN (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_RETURN (false);
|
||||||
|
|
||||||
return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx));
|
return TRACE_RETURN ((this+pairSet[index]).apply (c, &valueFormat1, skippy_iter.idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
|
||||||
unsigned int len1 = valueFormat1.get_len ();
|
unsigned int len1 = valueFormat1.get_len ();
|
||||||
@ -741,12 +761,11 @@ struct PairPosFormat2
|
|||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
hb_buffer_t *buffer = c->buffer;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
|
|
||||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
|
||||||
|
|
||||||
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
|
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_RETURN (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_RETURN (false);
|
||||||
|
|
||||||
unsigned int len1 = valueFormat1.get_len ();
|
unsigned int len1 = valueFormat1.get_len ();
|
||||||
@ -770,7 +789,8 @@ struct PairPosFormat2
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!(c->check_struct (this)
|
if (!(c->check_struct (this)
|
||||||
&& coverage.sanitize (c, this)
|
&& coverage.sanitize (c, this)
|
||||||
@ -823,6 +843,7 @@ struct PairPos
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
||||||
@ -830,16 +851,6 @@ struct PairPos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
case 2: return TRACE_RETURN (u.format2.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -853,7 +864,8 @@ struct EntryExitRecord
|
|||||||
{
|
{
|
||||||
friend struct CursivePosFormat1;
|
friend struct CursivePosFormat1;
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
|
return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
|
||||||
}
|
}
|
||||||
@ -892,12 +904,11 @@ struct CursivePosFormat1
|
|||||||
/* We don't handle mark glyphs here. */
|
/* 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_RETURN (false);
|
||||||
|
|
||||||
hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, 1);
|
|
||||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
|
||||||
|
|
||||||
const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
|
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_RETURN (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_RETURN (false);
|
||||||
|
|
||||||
const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
|
const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
|
||||||
@ -967,7 +978,8 @@ struct CursivePosFormat1
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -990,21 +1002,13 @@ struct CursivePos
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
default:return TRACE_RETURN (c->default_return_value ());
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -1040,7 +1044,8 @@ struct MarkBasePosFormat1
|
|||||||
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
|
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
|
||||||
|
|
||||||
/* now we search backwards for a non-mark glyph */
|
/* now we search backwards for a non-mark glyph */
|
||||||
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
|
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);
|
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
|
||||||
do {
|
do {
|
||||||
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
|
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
|
||||||
@ -1058,7 +1063,8 @@ struct MarkBasePosFormat1
|
|||||||
return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
|
return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, 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));
|
markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount));
|
||||||
@ -1089,21 +1095,13 @@ struct MarkBasePos
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
default:return TRACE_RETURN (c->default_return_value ());
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -1144,7 +1142,8 @@ struct MarkLigPosFormat1
|
|||||||
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
|
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
|
||||||
|
|
||||||
/* now we search backwards for a non-mark glyph */
|
/* now we search backwards for a non-mark glyph */
|
||||||
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
|
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);
|
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
|
||||||
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
|
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
|
||||||
|
|
||||||
@ -1178,7 +1177,8 @@ struct MarkLigPosFormat1
|
|||||||
return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
|
return TRACE_RETURN ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, j));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, 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));
|
markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount));
|
||||||
@ -1210,21 +1210,13 @@ struct MarkLigPos
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
default:return TRACE_RETURN (c->default_return_value ());
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -1260,7 +1252,8 @@ struct MarkMarkPosFormat1
|
|||||||
if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
|
if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
|
||||||
|
|
||||||
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
|
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
|
||||||
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, buffer->idx, 1);
|
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);
|
skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
|
||||||
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
|
if (!skippy_iter.prev ()) return TRACE_RETURN (false);
|
||||||
|
|
||||||
@ -1295,7 +1288,8 @@ struct MarkMarkPosFormat1
|
|||||||
return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
|
return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) &&
|
return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) &&
|
||||||
mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this)
|
mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this)
|
||||||
@ -1329,21 +1323,13 @@ struct MarkMarkPos
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
default:return TRACE_RETURN (c->default_return_value ());
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -1388,6 +1374,8 @@ struct PosLookupSubTable
|
|||||||
inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
|
inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, lookup_type);
|
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 ());
|
||||||
switch (lookup_type) {
|
switch (lookup_type) {
|
||||||
case Single: return TRACE_RETURN (u.single.dispatch (c));
|
case Single: return TRACE_RETURN (u.single.dispatch (c));
|
||||||
case Pair: return TRACE_RETURN (u.pair.dispatch (c));
|
case Pair: return TRACE_RETURN (u.pair.dispatch (c));
|
||||||
@ -1402,29 +1390,9 @@ struct PosLookupSubTable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.header.sub_format.sanitize (c))
|
|
||||||
return TRACE_RETURN (false);
|
|
||||||
switch (lookup_type) {
|
|
||||||
case Single: return TRACE_RETURN (u.single.sanitize (c));
|
|
||||||
case Pair: return TRACE_RETURN (u.pair.sanitize (c));
|
|
||||||
case Cursive: return TRACE_RETURN (u.cursive.sanitize (c));
|
|
||||||
case MarkBase: return TRACE_RETURN (u.markBase.sanitize (c));
|
|
||||||
case MarkLig: return TRACE_RETURN (u.markLig.sanitize (c));
|
|
||||||
case MarkMark: return TRACE_RETURN (u.markMark.sanitize (c));
|
|
||||||
case Context: return TRACE_RETURN (u.context.sanitize (c));
|
|
||||||
case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c));
|
|
||||||
case Extension: return TRACE_RETURN (u.extension.sanitize (c));
|
|
||||||
default: return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
struct {
|
USHORT sub_format;
|
||||||
USHORT sub_format;
|
|
||||||
} header;
|
|
||||||
SinglePos single;
|
SinglePos single;
|
||||||
PairPos pair;
|
PairPos pair;
|
||||||
CursivePos cursive;
|
CursivePos cursive;
|
||||||
@ -1436,48 +1404,37 @@ struct PosLookupSubTable
|
|||||||
ExtensionPos extension;
|
ExtensionPos extension;
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_UNION (2, header.sub_format);
|
DEFINE_SIZE_UNION (2, sub_format);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct PosLookup : Lookup
|
struct PosLookup : Lookup
|
||||||
{
|
{
|
||||||
inline const PosLookupSubTable& get_subtable (unsigned int i) const
|
inline const PosLookupSubTable& get_subtable (unsigned int i) const
|
||||||
{ return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
|
{ return Lookup::get_subtable<PosLookupSubTable> (i); }
|
||||||
|
|
||||||
inline bool is_reverse (void) const
|
inline bool is_reverse (void) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool apply (hb_apply_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_APPLY (this);
|
||||||
|
return TRACE_RETURN (dispatch (c));
|
||||||
|
}
|
||||||
|
|
||||||
inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
|
inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_COLLECT_GLYPHS (this);
|
TRACE_COLLECT_GLYPHS (this);
|
||||||
c->set_recurse_func (NULL);
|
|
||||||
return TRACE_RETURN (dispatch (c));
|
return TRACE_RETURN (dispatch (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename set_t>
|
template <typename set_t>
|
||||||
inline void add_coverage (set_t *glyphs) const
|
inline void add_coverage (set_t *glyphs) const
|
||||||
{
|
{
|
||||||
hb_get_coverage_context_t c;
|
hb_add_coverage_context_t<set_t> c (glyphs);
|
||||||
const Coverage *last = NULL;
|
dispatch (&c);
|
||||||
unsigned int count = get_subtable_count ();
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
|
||||||
const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ());
|
|
||||||
if (coverage != last) {
|
|
||||||
coverage->add_coverage (glyphs);
|
|
||||||
last = coverage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool apply_once (hb_apply_context_t *c) const
|
|
||||||
{
|
|
||||||
TRACE_APPLY (this);
|
|
||||||
if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
|
|
||||||
return TRACE_RETURN (false);
|
|
||||||
return TRACE_RETURN (dispatch (c));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
|
static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
|
||||||
@ -1487,23 +1444,13 @@ struct PosLookup : Lookup
|
|||||||
|
|
||||||
template <typename context_t>
|
template <typename context_t>
|
||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{ return Lookup::dispatch<PosLookupSubTable> (c); }
|
||||||
unsigned int lookup_type = get_type ();
|
|
||||||
TRACE_DISPATCH (this, lookup_type);
|
|
||||||
unsigned int count = get_subtable_count ();
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
|
||||||
typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type);
|
|
||||||
if (c->stop_sublookup_iteration (r))
|
|
||||||
return TRACE_RETURN (r);
|
|
||||||
}
|
|
||||||
return TRACE_RETURN (c->default_return_value ());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
|
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
|
||||||
OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable);
|
return TRACE_RETURN (dispatch (c));
|
||||||
return TRACE_RETURN (list.sanitize (c, this, get_type ()));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1523,10 +1470,11 @@ struct GPOS : GSUBGPOS
|
|||||||
static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
|
static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
|
||||||
static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer);
|
static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer);
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
|
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
|
||||||
OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
|
const OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
|
||||||
return TRACE_RETURN (list.sanitize (c, this));
|
return TRACE_RETURN (list.sanitize (c, this));
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
@ -1621,8 +1569,8 @@ template <typename context_t>
|
|||||||
const PosLookup &l = gpos.get_lookup (lookup_index);
|
const PosLookup &l = gpos.get_lookup (lookup_index);
|
||||||
unsigned int saved_lookup_props = c->lookup_props;
|
unsigned int saved_lookup_props = c->lookup_props;
|
||||||
c->set_lookup (l);
|
c->set_lookup (l);
|
||||||
bool ret = l.apply_once (c);
|
bool ret = l.dispatch (c);
|
||||||
c->lookup_props = saved_lookup_props;
|
c->set_lookup_props (saved_lookup_props);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,8 @@ struct SingleSubstFormat1
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
|
return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -173,7 +174,8 @@ struct SingleSubstFormat2
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c));
|
return TRACE_RETURN (coverage.sanitize (c, this) && substitute.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -223,6 +225,7 @@ struct SingleSubst
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
||||||
@ -230,16 +233,6 @@ struct SingleSubst
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
case 2: return TRACE_RETURN (u.format2.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -312,7 +305,8 @@ struct Sequence
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (substitute.sanitize (c));
|
return TRACE_RETURN (substitute.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -384,7 +378,8 @@ struct MultipleSubstFormat1
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && sequence.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -423,21 +418,13 @@ struct MultipleSubst
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
default:return TRACE_RETURN (c->default_return_value ());
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -535,7 +522,8 @@ struct AlternateSubstFormat1
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -574,21 +562,13 @@ struct AlternateSubst
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
default:return TRACE_RETURN (c->default_return_value ());
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -686,7 +666,8 @@ struct Ligature
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c));
|
return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c));
|
||||||
}
|
}
|
||||||
@ -764,7 +745,8 @@ struct LigatureSet
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (ligature.sanitize (c, this));
|
return TRACE_RETURN (ligature.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -848,7 +830,8 @@ struct LigatureSubstFormat1
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && ligatureSet.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -890,21 +873,13 @@ struct LigatureSubst
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
default:return TRACE_RETURN (c->default_return_value ());
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -1017,14 +992,15 @@ struct ReverseChainSingleSubstFormat1
|
|||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
|
if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
|
||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
|
||||||
if (!lookahead.sanitize (c, this))
|
if (!lookahead.sanitize (c, this))
|
||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
|
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
|
||||||
return TRACE_RETURN (substitute.sanitize (c));
|
return TRACE_RETURN (substitute.sanitize (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1054,21 +1030,13 @@ struct ReverseChainSingleSubst
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
default:return TRACE_RETURN (c->default_return_value ());
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -1101,6 +1069,8 @@ struct SubstLookupSubTable
|
|||||||
inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
|
inline typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, lookup_type);
|
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 ());
|
||||||
switch (lookup_type) {
|
switch (lookup_type) {
|
||||||
case Single: return TRACE_RETURN (u.single.dispatch (c));
|
case Single: return TRACE_RETURN (u.single.dispatch (c));
|
||||||
case Multiple: return TRACE_RETURN (u.multiple.dispatch (c));
|
case Multiple: return TRACE_RETURN (u.multiple.dispatch (c));
|
||||||
@ -1114,28 +1084,9 @@ struct SubstLookupSubTable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.header.sub_format.sanitize (c))
|
|
||||||
return TRACE_RETURN (false);
|
|
||||||
switch (lookup_type) {
|
|
||||||
case Single: return TRACE_RETURN (u.single.sanitize (c));
|
|
||||||
case Multiple: return TRACE_RETURN (u.multiple.sanitize (c));
|
|
||||||
case Alternate: return TRACE_RETURN (u.alternate.sanitize (c));
|
|
||||||
case Ligature: return TRACE_RETURN (u.ligature.sanitize (c));
|
|
||||||
case Context: return TRACE_RETURN (u.context.sanitize (c));
|
|
||||||
case ChainContext: return TRACE_RETURN (u.chainContext.sanitize (c));
|
|
||||||
case Extension: return TRACE_RETURN (u.extension.sanitize (c));
|
|
||||||
case ReverseChainSingle: return TRACE_RETURN (u.reverseChainContextSingle.sanitize (c));
|
|
||||||
default: return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
struct {
|
USHORT sub_format;
|
||||||
USHORT sub_format;
|
|
||||||
} header;
|
|
||||||
SingleSubst single;
|
SingleSubst single;
|
||||||
MultipleSubst multiple;
|
MultipleSubst multiple;
|
||||||
AlternateSubst alternate;
|
AlternateSubst alternate;
|
||||||
@ -1146,14 +1097,14 @@ struct SubstLookupSubTable
|
|||||||
ReverseChainSingleSubst reverseChainContextSingle;
|
ReverseChainSingleSubst reverseChainContextSingle;
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_UNION (2, header.sub_format);
|
DEFINE_SIZE_UNION (2, sub_format);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct SubstLookup : Lookup
|
struct SubstLookup : Lookup
|
||||||
{
|
{
|
||||||
inline const SubstLookupSubTable& get_subtable (unsigned int i) const
|
inline const SubstLookupSubTable& get_subtable (unsigned int i) const
|
||||||
{ return this+CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i]; }
|
{ return Lookup::get_subtable<SubstLookupSubTable> (i); }
|
||||||
|
|
||||||
inline static bool lookup_type_is_reverse (unsigned int lookup_type)
|
inline static bool lookup_type_is_reverse (unsigned int lookup_type)
|
||||||
{ return lookup_type == SubstLookupSubTable::ReverseChainSingle; }
|
{ return lookup_type == SubstLookupSubTable::ReverseChainSingle; }
|
||||||
@ -1166,6 +1117,12 @@ struct SubstLookup : Lookup
|
|||||||
return lookup_type_is_reverse (type);
|
return lookup_type_is_reverse (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool apply (hb_apply_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_APPLY (this);
|
||||||
|
return TRACE_RETURN (dispatch (c));
|
||||||
|
}
|
||||||
|
|
||||||
inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
|
inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
@ -1183,39 +1140,24 @@ struct SubstLookup : Lookup
|
|||||||
template <typename set_t>
|
template <typename set_t>
|
||||||
inline void add_coverage (set_t *glyphs) const
|
inline void add_coverage (set_t *glyphs) const
|
||||||
{
|
{
|
||||||
hb_get_coverage_context_t c;
|
hb_add_coverage_context_t<set_t> c (glyphs);
|
||||||
const Coverage *last = NULL;
|
dispatch (&c);
|
||||||
unsigned int count = get_subtable_count ();
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
|
||||||
const Coverage *coverage = &get_subtable (i).dispatch (&c, get_type ());
|
|
||||||
if (coverage != last) {
|
|
||||||
coverage->add_coverage (glyphs);
|
|
||||||
last = coverage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const
|
inline bool would_apply (hb_would_apply_context_t *c,
|
||||||
|
const hb_ot_layout_lookup_accelerator_t *accel) const
|
||||||
{
|
{
|
||||||
TRACE_WOULD_APPLY (this);
|
TRACE_WOULD_APPLY (this);
|
||||||
if (unlikely (!c->len)) return TRACE_RETURN (false);
|
if (unlikely (!c->len)) return TRACE_RETURN (false);
|
||||||
if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false);
|
if (!accel->may_have (c->glyphs[0])) return TRACE_RETURN (false);
|
||||||
return TRACE_RETURN (dispatch (c));
|
return TRACE_RETURN (dispatch (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool apply_once (hb_apply_context_t *c) const
|
|
||||||
{
|
|
||||||
TRACE_APPLY (this);
|
|
||||||
if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
|
|
||||||
return TRACE_RETURN (false);
|
|
||||||
return TRACE_RETURN (dispatch (c));
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
|
static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
|
||||||
|
|
||||||
inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
|
inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
|
||||||
unsigned int i)
|
unsigned int i)
|
||||||
{ return CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable)[i].serialize (c, this); }
|
{ return get_subtables<SubstLookupSubTable> ()[i].serialize (c, this); }
|
||||||
|
|
||||||
inline bool serialize_single (hb_serialize_context_t *c,
|
inline bool serialize_single (hb_serialize_context_t *c,
|
||||||
uint32_t lookup_props,
|
uint32_t lookup_props,
|
||||||
@ -1274,24 +1216,13 @@ struct SubstLookup : Lookup
|
|||||||
|
|
||||||
template <typename context_t>
|
template <typename context_t>
|
||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{ return Lookup::dispatch<SubstLookupSubTable> (c); }
|
||||||
unsigned int lookup_type = get_type ();
|
|
||||||
TRACE_DISPATCH (this, lookup_type);
|
|
||||||
unsigned int count = get_subtable_count ();
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
|
||||||
typename context_t::return_t r = get_subtable (i).dispatch (c, lookup_type);
|
|
||||||
if (c->stop_sublookup_iteration (r))
|
|
||||||
return TRACE_RETURN (r);
|
|
||||||
}
|
|
||||||
return TRACE_RETURN (c->default_return_value ());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c)
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
|
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
|
||||||
OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable);
|
if (unlikely (!dispatch (c))) return TRACE_RETURN (false);
|
||||||
if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false);
|
|
||||||
|
|
||||||
if (unlikely (get_type () == SubstLookupSubTable::Extension))
|
if (unlikely (get_type () == SubstLookupSubTable::Extension))
|
||||||
{
|
{
|
||||||
@ -1324,10 +1255,11 @@ struct GSUB : GSUBGPOS
|
|||||||
static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer);
|
static inline void substitute_start (hb_font_t *font, hb_buffer_t *buffer);
|
||||||
static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer);
|
static inline void substitute_finish (hb_font_t *font, hb_buffer_t *buffer);
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
|
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
|
||||||
OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
|
const OffsetTo<SubstLookupList> &list = CastR<OffsetTo<SubstLookupList> > (lookupList);
|
||||||
return TRACE_RETURN (list.sanitize (c, this));
|
return TRACE_RETURN (list.sanitize (c, this));
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
@ -1362,7 +1294,7 @@ GSUB::substitute_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSE
|
|||||||
{
|
{
|
||||||
unsigned int type = get_type ();
|
unsigned int type = get_type ();
|
||||||
if (unlikely (type == SubstLookupSubTable::Extension))
|
if (unlikely (type == SubstLookupSubTable::Extension))
|
||||||
return CastR<ExtensionSubst> (get_subtable<SubstLookupSubTable>()).is_reverse ();
|
return CastR<ExtensionSubst> (get_subtable<LookupSubTable>()).is_reverse ();
|
||||||
return SubstLookup::lookup_type_is_reverse (type);
|
return SubstLookup::lookup_type_is_reverse (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1380,8 +1312,8 @@ template <typename context_t>
|
|||||||
const SubstLookup &l = gsub.get_lookup (lookup_index);
|
const SubstLookup &l = gsub.get_lookup (lookup_index);
|
||||||
unsigned int saved_lookup_props = c->lookup_props;
|
unsigned int saved_lookup_props = c->lookup_props;
|
||||||
c->set_lookup (l);
|
c->set_lookup (l);
|
||||||
bool ret = l.apply_once (c);
|
bool ret = l.dispatch (c);
|
||||||
c->lookup_props = saved_lookup_props;
|
c->set_lookup_props (saved_lookup_props);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,12 +37,6 @@
|
|||||||
namespace OT {
|
namespace OT {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TRACE_DISPATCH(this, format) \
|
|
||||||
hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
|
|
||||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
|
||||||
"format %d", (int) format);
|
|
||||||
|
|
||||||
#ifndef HB_DEBUG_CLOSURE
|
#ifndef HB_DEBUG_CLOSURE
|
||||||
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
|
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
|
||||||
#endif
|
#endif
|
||||||
@ -58,6 +52,8 @@ struct hb_closure_context_t
|
|||||||
static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
|
static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
|
||||||
typedef hb_void_t return_t;
|
typedef hb_void_t return_t;
|
||||||
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
|
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>
|
template <typename T>
|
||||||
inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
|
inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
|
||||||
static return_t default_return_value (void) { return HB_VOID; }
|
static return_t default_return_value (void) { return HB_VOID; }
|
||||||
@ -107,6 +103,8 @@ struct hb_would_apply_context_t
|
|||||||
inline const char *get_name (void) { return "WOULD_APPLY"; }
|
inline const char *get_name (void) { return "WOULD_APPLY"; }
|
||||||
static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
|
static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
|
||||||
typedef bool return_t;
|
typedef bool return_t;
|
||||||
|
template <typename T, typename F>
|
||||||
|
inline bool may_dispatch (const T *obj, const F *format) { return true; }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
|
inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
|
||||||
static return_t default_return_value (void) { return false; }
|
static return_t default_return_value (void) { return false; }
|
||||||
@ -146,6 +144,8 @@ struct hb_collect_glyphs_context_t
|
|||||||
static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
|
static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
|
||||||
typedef hb_void_t return_t;
|
typedef hb_void_t return_t;
|
||||||
typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
|
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>
|
template <typename T>
|
||||||
inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
|
inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
|
||||||
static return_t default_return_value (void) { return HB_VOID; }
|
static return_t default_return_value (void) { return HB_VOID; }
|
||||||
@ -232,18 +232,28 @@ struct hb_collect_glyphs_context_t
|
|||||||
#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
|
#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct hb_get_coverage_context_t
|
template <typename set_t>
|
||||||
|
struct hb_add_coverage_context_t
|
||||||
{
|
{
|
||||||
inline const char *get_name (void) { return "GET_COVERAGE"; }
|
inline const char *get_name (void) { return "GET_COVERAGE"; }
|
||||||
static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE;
|
static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE;
|
||||||
typedef const Coverage &return_t;
|
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>
|
template <typename T>
|
||||||
inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
|
inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
|
||||||
static return_t default_return_value (void) { return Null(Coverage); }
|
static return_t default_return_value (void) { return Null(Coverage); }
|
||||||
|
bool stop_sublookup_iteration (return_t r) const
|
||||||
|
{
|
||||||
|
r.add_coverage (set);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
hb_get_coverage_context_t (void) :
|
hb_add_coverage_context_t (set_t *set_) :
|
||||||
|
set (set_),
|
||||||
debug_depth (0) {}
|
debug_depth (0) {}
|
||||||
|
|
||||||
|
set_t *set;
|
||||||
unsigned int debug_depth;
|
unsigned int debug_depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -260,61 +270,6 @@ struct hb_get_coverage_context_t
|
|||||||
|
|
||||||
struct hb_apply_context_t
|
struct hb_apply_context_t
|
||||||
{
|
{
|
||||||
inline const char *get_name (void) { return "APPLY"; }
|
|
||||||
static const unsigned int max_debug_depth = HB_DEBUG_APPLY;
|
|
||||||
typedef bool return_t;
|
|
||||||
typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
|
|
||||||
template <typename T>
|
|
||||||
inline return_t dispatch (const T &obj) { return obj.apply (this); }
|
|
||||||
static return_t default_return_value (void) { return false; }
|
|
||||||
bool stop_sublookup_iteration (return_t r) const { return r; }
|
|
||||||
return_t recurse (unsigned int lookup_index)
|
|
||||||
{
|
|
||||||
if (unlikely (nesting_level_left == 0 || !recurse_func))
|
|
||||||
return default_return_value ();
|
|
||||||
|
|
||||||
nesting_level_left--;
|
|
||||||
bool ret = recurse_func (this, lookup_index);
|
|
||||||
nesting_level_left++;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int table_index; /* GSUB/GPOS */
|
|
||||||
hb_font_t *font;
|
|
||||||
hb_face_t *face;
|
|
||||||
hb_buffer_t *buffer;
|
|
||||||
hb_direction_t direction;
|
|
||||||
hb_mask_t lookup_mask;
|
|
||||||
bool auto_zwj;
|
|
||||||
recurse_func_t recurse_func;
|
|
||||||
unsigned int nesting_level_left;
|
|
||||||
unsigned int lookup_props;
|
|
||||||
const GDEF &gdef;
|
|
||||||
bool has_glyph_classes;
|
|
||||||
unsigned int debug_depth;
|
|
||||||
|
|
||||||
|
|
||||||
hb_apply_context_t (unsigned int table_index_,
|
|
||||||
hb_font_t *font_,
|
|
||||||
hb_buffer_t *buffer_) :
|
|
||||||
table_index (table_index_),
|
|
||||||
font (font_), face (font->face), buffer (buffer_),
|
|
||||||
direction (buffer_->props.direction),
|
|
||||||
lookup_mask (1),
|
|
||||||
auto_zwj (true),
|
|
||||||
recurse_func (NULL),
|
|
||||||
nesting_level_left (MAX_NESTING_LEVEL),
|
|
||||||
lookup_props (0),
|
|
||||||
gdef (*hb_ot_layout_from_face (face)->gdef),
|
|
||||||
has_glyph_classes (gdef.has_glyph_classes ()),
|
|
||||||
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_props (unsigned int lookup_props_) { lookup_props = lookup_props_; }
|
|
||||||
inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); }
|
|
||||||
|
|
||||||
struct matcher_t
|
struct matcher_t
|
||||||
{
|
{
|
||||||
inline matcher_t (void) :
|
inline matcher_t (void) :
|
||||||
@ -390,29 +345,24 @@ struct hb_apply_context_t
|
|||||||
const void *match_data;
|
const void *match_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct skipping_forward_iterator_t
|
struct skipping_iterator_t
|
||||||
{
|
{
|
||||||
inline skipping_forward_iterator_t (hb_apply_context_t *c_,
|
inline void init (hb_apply_context_t *c_, bool context_match = false)
|
||||||
unsigned int start_index_,
|
|
||||||
unsigned int num_items_,
|
|
||||||
bool context_match = false) :
|
|
||||||
idx (start_index_),
|
|
||||||
c (c_),
|
|
||||||
match_glyph_data (NULL),
|
|
||||||
num_items (num_items_),
|
|
||||||
end (c->buffer->len)
|
|
||||||
{
|
{
|
||||||
|
c = c_;
|
||||||
|
match_glyph_data = NULL,
|
||||||
|
matcher.set_match_func (NULL, NULL);
|
||||||
matcher.set_lookup_props (c->lookup_props);
|
matcher.set_lookup_props (c->lookup_props);
|
||||||
/* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
|
/* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
|
||||||
matcher.set_ignore_zwnj (context_match || c->table_index == 1);
|
matcher.set_ignore_zwnj (context_match || c->table_index == 1);
|
||||||
/* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
|
/* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
|
||||||
matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
|
matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
|
||||||
if (!context_match)
|
matcher.set_mask (context_match ? -1 : c->lookup_mask);
|
||||||
matcher.set_mask (c->lookup_mask);
|
}
|
||||||
matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
|
inline void set_lookup_props (unsigned int lookup_props)
|
||||||
|
{
|
||||||
|
matcher.set_lookup_props (lookup_props);
|
||||||
}
|
}
|
||||||
inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
|
|
||||||
inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
|
|
||||||
inline void set_match_func (matcher_t::match_func_t match_func,
|
inline void set_match_func (matcher_t::match_func_t match_func,
|
||||||
const void *match_data,
|
const void *match_data,
|
||||||
const USHORT glyph_data[])
|
const USHORT glyph_data[])
|
||||||
@ -421,12 +371,21 @@ struct hb_apply_context_t
|
|||||||
match_glyph_data = glyph_data;
|
match_glyph_data = glyph_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool has_no_chance (void) const { return unlikely (num_items && idx + num_items >= end); }
|
inline void reset (unsigned int start_index_,
|
||||||
|
unsigned int num_items_)
|
||||||
|
{
|
||||||
|
idx = start_index_;
|
||||||
|
num_items = num_items_;
|
||||||
|
end = c->buffer->len;
|
||||||
|
matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
|
||||||
|
}
|
||||||
|
|
||||||
inline void reject (void) { num_items++; match_glyph_data--; }
|
inline void reject (void) { num_items++; match_glyph_data--; }
|
||||||
|
|
||||||
inline bool next (void)
|
inline bool next (void)
|
||||||
{
|
{
|
||||||
assert (num_items > 0);
|
assert (num_items > 0);
|
||||||
while (!has_no_chance ())
|
while (idx + num_items < end)
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
const hb_glyph_info_t &info = c->buffer->info[idx];
|
const hb_glyph_info_t &info = c->buffer->info[idx];
|
||||||
@ -450,53 +409,10 @@ struct hb_apply_context_t
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int idx;
|
|
||||||
protected:
|
|
||||||
hb_apply_context_t *c;
|
|
||||||
matcher_t matcher;
|
|
||||||
const USHORT *match_glyph_data;
|
|
||||||
|
|
||||||
unsigned int num_items;
|
|
||||||
unsigned int end;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skipping_backward_iterator_t
|
|
||||||
{
|
|
||||||
inline skipping_backward_iterator_t (hb_apply_context_t *c_,
|
|
||||||
unsigned int start_index_,
|
|
||||||
unsigned int num_items_,
|
|
||||||
bool context_match = false) :
|
|
||||||
idx (start_index_),
|
|
||||||
c (c_),
|
|
||||||
match_glyph_data (NULL),
|
|
||||||
num_items (num_items_)
|
|
||||||
{
|
|
||||||
matcher.set_lookup_props (c->lookup_props);
|
|
||||||
/* Ignore ZWNJ if we are matching GSUB context, or matching GPOS. */
|
|
||||||
matcher.set_ignore_zwnj (context_match || c->table_index == 1);
|
|
||||||
/* Ignore ZWJ if we are matching GSUB context, or matching GPOS, or if asked to. */
|
|
||||||
matcher.set_ignore_zwj (context_match || c->table_index == 1 || c->auto_zwj);
|
|
||||||
if (!context_match)
|
|
||||||
matcher.set_mask (c->lookup_mask);
|
|
||||||
matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
|
|
||||||
}
|
|
||||||
inline void set_lookup_props (unsigned int lookup_props) { matcher.set_lookup_props (lookup_props); }
|
|
||||||
inline void set_syllable (unsigned int syllable) { matcher.set_syllable (syllable); }
|
|
||||||
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);
|
|
||||||
match_glyph_data = glyph_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool has_no_chance (void) const { return unlikely (idx < num_items); }
|
|
||||||
inline void reject (void) { num_items++; }
|
|
||||||
inline bool prev (void)
|
inline bool prev (void)
|
||||||
{
|
{
|
||||||
assert (num_items > 0);
|
assert (num_items > 0);
|
||||||
while (!has_no_chance ())
|
while (idx >= num_items)
|
||||||
{
|
{
|
||||||
idx--;
|
idx--;
|
||||||
const hb_glyph_info_t &info = c->buffer->out_info[idx];
|
const hb_glyph_info_t &info = c->buffer->out_info[idx];
|
||||||
@ -528,44 +444,111 @@ struct hb_apply_context_t
|
|||||||
const USHORT *match_glyph_data;
|
const USHORT *match_glyph_data;
|
||||||
|
|
||||||
unsigned int num_items;
|
unsigned int num_items;
|
||||||
|
unsigned int end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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; }
|
||||||
|
bool stop_sublookup_iteration (return_t r) const { return r; }
|
||||||
|
return_t recurse (unsigned int lookup_index)
|
||||||
|
{
|
||||||
|
if (unlikely (nesting_level_left == 0 || !recurse_func))
|
||||||
|
return default_return_value ();
|
||||||
|
|
||||||
|
nesting_level_left--;
|
||||||
|
bool ret = recurse_func (this, lookup_index);
|
||||||
|
nesting_level_left++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int table_index; /* GSUB/GPOS */
|
||||||
|
hb_font_t *font;
|
||||||
|
hb_face_t *face;
|
||||||
|
hb_buffer_t *buffer;
|
||||||
|
hb_direction_t direction;
|
||||||
|
hb_mask_t lookup_mask;
|
||||||
|
bool auto_zwj;
|
||||||
|
recurse_func_t recurse_func;
|
||||||
|
unsigned int nesting_level_left;
|
||||||
|
unsigned int lookup_props;
|
||||||
|
const GDEF &gdef;
|
||||||
|
bool has_glyph_classes;
|
||||||
|
skipping_iterator_t iter_input, iter_context;
|
||||||
|
unsigned int debug_depth;
|
||||||
|
|
||||||
|
|
||||||
|
hb_apply_context_t (unsigned int table_index_,
|
||||||
|
hb_font_t *font_,
|
||||||
|
hb_buffer_t *buffer_) :
|
||||||
|
table_index (table_index_),
|
||||||
|
font (font_), face (font->face), buffer (buffer_),
|
||||||
|
direction (buffer_->props.direction),
|
||||||
|
lookup_mask (1),
|
||||||
|
auto_zwj (true),
|
||||||
|
recurse_func (NULL),
|
||||||
|
nesting_level_left (MAX_NESTING_LEVEL),
|
||||||
|
lookup_props (0),
|
||||||
|
gdef (*hb_ot_layout_from_face (face)->gdef),
|
||||||
|
has_glyph_classes (gdef.has_glyph_classes ()),
|
||||||
|
iter_input (),
|
||||||
|
iter_context (),
|
||||||
|
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_props (unsigned int lookup_props_)
|
||||||
|
{
|
||||||
|
lookup_props = lookup_props_;
|
||||||
|
iter_input.init (this, false);
|
||||||
|
iter_context.init (this, true);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
match_properties_mark (hb_codepoint_t glyph,
|
match_properties_mark (hb_codepoint_t glyph,
|
||||||
unsigned int glyph_props,
|
unsigned int glyph_props,
|
||||||
unsigned int lookup_props) const
|
unsigned int match_props) const
|
||||||
{
|
{
|
||||||
/* If using mark filtering sets, the high short of
|
/* 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)
|
if (match_props & LookupFlag::UseMarkFilteringSet)
|
||||||
return gdef.mark_set_covers (lookup_props >> 16, glyph);
|
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
|
* "ignore marks of attachment type different than
|
||||||
* the attachment type specified."
|
* the attachment type specified."
|
||||||
*/
|
*/
|
||||||
if (lookup_props & LookupFlag::MarkAttachmentType)
|
if (match_props & LookupFlag::MarkAttachmentType)
|
||||||
return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
|
return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
check_glyph_property (const hb_glyph_info_t *info,
|
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;
|
hb_codepoint_t glyph = info->codepoint;
|
||||||
unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
|
unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
|
||||||
|
|
||||||
/* Not covered, if, for example, glyph class is ligature and
|
/* 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;
|
return false;
|
||||||
|
|
||||||
if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@ -741,9 +724,9 @@ static inline bool match_input (hb_apply_context_t *c,
|
|||||||
|
|
||||||
hb_buffer_t *buffer = c->buffer;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
|
|
||||||
hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, buffer->idx, count - 1);
|
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||||
|
skippy_iter.reset (buffer->idx, count - 1);
|
||||||
skippy_iter.set_match_func (match_func, match_data, input);
|
skippy_iter.set_match_func (match_func, match_data, input);
|
||||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is perhaps the trickiest part of OpenType... Remarks:
|
* This is perhaps the trickiest part of OpenType... Remarks:
|
||||||
@ -910,9 +893,9 @@ static inline bool match_backtrack (hb_apply_context_t *c,
|
|||||||
{
|
{
|
||||||
TRACE_APPLY (NULL);
|
TRACE_APPLY (NULL);
|
||||||
|
|
||||||
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, c->buffer->backtrack_len (), count, true);
|
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
|
||||||
|
skippy_iter.reset (c->buffer->backtrack_len (), count);
|
||||||
skippy_iter.set_match_func (match_func, match_data, backtrack);
|
skippy_iter.set_match_func (match_func, match_data, backtrack);
|
||||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (!skippy_iter.prev ())
|
if (!skippy_iter.prev ())
|
||||||
@ -930,9 +913,9 @@ static inline bool match_lookahead (hb_apply_context_t *c,
|
|||||||
{
|
{
|
||||||
TRACE_APPLY (NULL);
|
TRACE_APPLY (NULL);
|
||||||
|
|
||||||
hb_apply_context_t::skipping_forward_iterator_t skippy_iter (c, c->buffer->idx + offset - 1, count, true);
|
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
|
||||||
|
skippy_iter.reset (c->buffer->idx + offset - 1, count);
|
||||||
skippy_iter.set_match_func (match_func, match_data, lookahead);
|
skippy_iter.set_match_func (match_func, match_data, lookahead);
|
||||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (!skippy_iter.next ())
|
if (!skippy_iter.next ())
|
||||||
@ -945,7 +928,8 @@ static inline bool match_lookahead (hb_apply_context_t *c,
|
|||||||
|
|
||||||
struct LookupRecord
|
struct LookupRecord
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this));
|
||||||
}
|
}
|
||||||
@ -1168,7 +1152,8 @@ struct Rule
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return inputCount.sanitize (c)
|
return inputCount.sanitize (c)
|
||||||
&& lookupCount.sanitize (c)
|
&& lookupCount.sanitize (c)
|
||||||
@ -1232,7 +1217,8 @@ struct RuleSet
|
|||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (rule.sanitize (c, this));
|
return TRACE_RETURN (rule.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -1314,7 +1300,8 @@ struct ContextFormat1
|
|||||||
return TRACE_RETURN (rule_set.apply (c, lookup_context));
|
return TRACE_RETURN (rule_set.apply (c, lookup_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -1406,7 +1393,8 @@ struct ContextFormat2
|
|||||||
return TRACE_RETURN (rule_set.apply (c, lookup_context));
|
return TRACE_RETURN (rule_set.apply (c, lookup_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -1494,7 +1482,8 @@ struct ContextFormat3
|
|||||||
return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
|
return TRACE_RETURN (context_apply_lookup (c, glyphCount, (const USHORT *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!c->check_struct (this)) return TRACE_RETURN (false);
|
if (!c->check_struct (this)) return TRACE_RETURN (false);
|
||||||
unsigned int count = glyphCount;
|
unsigned int count = glyphCount;
|
||||||
@ -1502,7 +1491,7 @@ struct ContextFormat3
|
|||||||
if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false);
|
if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false);
|
||||||
for (unsigned int i = 0; i < count; i++)
|
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_RETURN (false);
|
||||||
LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count);
|
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_RETURN (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1526,6 +1515,7 @@ struct Context
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
||||||
@ -1534,17 +1524,6 @@ struct Context
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
case 2: return TRACE_RETURN (u.format2.sanitize (c));
|
|
||||||
case 3: return TRACE_RETURN (u.format3.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -1726,14 +1705,15 @@ struct ChainRule
|
|||||||
lookup.array, lookup_context));
|
lookup.array, lookup_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!backtrack.sanitize (c)) return TRACE_RETURN (false);
|
if (!backtrack.sanitize (c)) return TRACE_RETURN (false);
|
||||||
HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
|
const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
|
||||||
if (!input.sanitize (c)) return TRACE_RETURN (false);
|
if (!input.sanitize (c)) return TRACE_RETURN (false);
|
||||||
ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
|
const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
|
||||||
if (!lookahead.sanitize (c)) return TRACE_RETURN (false);
|
if (!lookahead.sanitize (c)) return TRACE_RETURN (false);
|
||||||
ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
|
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
|
||||||
return TRACE_RETURN (lookup.sanitize (c));
|
return TRACE_RETURN (lookup.sanitize (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1795,7 +1775,8 @@ struct ChainRuleSet
|
|||||||
return TRACE_RETURN (false);
|
return TRACE_RETURN (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (rule.sanitize (c, this));
|
return TRACE_RETURN (rule.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -1874,7 +1855,8 @@ struct ChainContextFormat1
|
|||||||
return TRACE_RETURN (rule_set.apply (c, lookup_context));
|
return TRACE_RETURN (rule_set.apply (c, lookup_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
|
return TRACE_RETURN (coverage.sanitize (c, this) && ruleSet.sanitize (c, this));
|
||||||
}
|
}
|
||||||
@ -1984,7 +1966,8 @@ struct ChainContextFormat2
|
|||||||
return TRACE_RETURN (rule_set.apply (c, lookup_context));
|
return TRACE_RETURN (rule_set.apply (c, lookup_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) &&
|
return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) &&
|
||||||
inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) &&
|
inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) &&
|
||||||
@ -2105,15 +2088,16 @@ struct ChainContextFormat3
|
|||||||
lookup.len, lookup.array, lookup_context));
|
lookup.len, lookup.array, lookup_context));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false);
|
if (!backtrack.sanitize (c, this)) return TRACE_RETURN (false);
|
||||||
OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
|
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
|
||||||
if (!input.sanitize (c, this)) return TRACE_RETURN (false);
|
if (!input.sanitize (c, this)) return TRACE_RETURN (false);
|
||||||
if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */
|
if (!input.len) return TRACE_RETURN (false); /* To be consistent with Context. */
|
||||||
OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
|
||||||
if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false);
|
if (!lookahead.sanitize (c, this)) return TRACE_RETURN (false);
|
||||||
ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
|
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
|
||||||
return TRACE_RETURN (lookup.sanitize (c));
|
return TRACE_RETURN (lookup.sanitize (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2144,6 +2128,7 @@ struct ChainContext
|
|||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_DISPATCH (this, u.format);
|
TRACE_DISPATCH (this, u.format);
|
||||||
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||||
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
case 2: return TRACE_RETURN (c->dispatch (u.format2));
|
||||||
@ -2152,17 +2137,6 @@ struct ChainContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
|
||||||
case 2: return TRACE_RETURN (u.format2.sanitize (c));
|
|
||||||
case 3: return TRACE_RETURN (u.format3.sanitize (c));
|
|
||||||
default:return TRACE_RETURN (true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
@ -2173,14 +2147,32 @@ struct ChainContext
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
struct ExtensionFormat1
|
struct ExtensionFormat1
|
||||||
{
|
{
|
||||||
inline unsigned int get_type (void) const { return extensionLookupType; }
|
inline unsigned int get_type (void) const { return extensionLookupType; }
|
||||||
inline unsigned int get_offset (void) const { return extensionOffset; }
|
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
template <typename X>
|
||||||
|
inline const X& get_subtable (void) const
|
||||||
|
{
|
||||||
|
unsigned int offset = extensionOffset;
|
||||||
|
if (unlikely (!offset)) return Null(typename T::LookupSubTable);
|
||||||
|
return StructAtOffset<typename T::LookupSubTable> (this, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename context_t>
|
||||||
|
inline typename context_t::return_t 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 ());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is called from may_dispatch() above with hb_sanitize_context_t. */
|
||||||
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this));
|
return TRACE_RETURN (c->check_struct (this) && extensionOffset != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -2204,49 +2196,30 @@ struct Extension
|
|||||||
default:return 0;
|
default:return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline unsigned int get_offset (void) const
|
|
||||||
{
|
|
||||||
switch (u.format) {
|
|
||||||
case 1: return u.format1.get_offset ();
|
|
||||||
default:return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename X>
|
template <typename X>
|
||||||
inline const X& get_subtable (void) const
|
inline const X& get_subtable (void) const
|
||||||
{
|
{
|
||||||
unsigned int offset = get_offset ();
|
switch (u.format) {
|
||||||
if (unlikely (!offset)) return Null(typename T::LookupSubTable);
|
case 1: return u.format1.template get_subtable<typename T::LookupSubTable> ();
|
||||||
return StructAtOffset<typename T::LookupSubTable> (this, offset);
|
default:return Null(typename T::LookupSubTable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename context_t>
|
template <typename context_t>
|
||||||
inline typename context_t::return_t dispatch (context_t *c) const
|
inline typename context_t::return_t dispatch (context_t *c) const
|
||||||
{
|
{
|
||||||
return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ());
|
TRACE_DISPATCH (this, u.format);
|
||||||
}
|
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||||
|
|
||||||
inline bool sanitize_self (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
case 1: return TRACE_RETURN (u.format1.dispatch (c));
|
||||||
default:return TRACE_RETURN (true);
|
default:return TRACE_RETURN (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
if (!sanitize_self (c)) return TRACE_RETURN (false);
|
|
||||||
unsigned int offset = get_offset ();
|
|
||||||
if (unlikely (!offset)) return TRACE_RETURN (true);
|
|
||||||
return TRACE_RETURN (StructAtOffset<typename T::LookupSubTable> (this, offset).sanitize (c, get_type ()));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
USHORT format; /* Format identifier */
|
USHORT format; /* Format identifier */
|
||||||
ExtensionFormat1 format1;
|
ExtensionFormat1<T> format1;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2291,7 +2264,8 @@ struct GSUBGPOS
|
|||||||
inline const Lookup& get_lookup (unsigned int i) const
|
inline const Lookup& get_lookup (unsigned int i) const
|
||||||
{ return (this+lookupList)[i]; }
|
{ return (this+lookupList)[i]; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
|
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
|
||||||
scriptList.sanitize (c, this) &&
|
scriptList.sanitize (c, this) &&
|
||||||
|
@ -54,7 +54,8 @@ typedef OffsetListOf<PosLookup> JstfMax;
|
|||||||
|
|
||||||
struct JstfPriority
|
struct JstfPriority
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
shrinkageEnableGSUB.sanitize (c, this) &&
|
shrinkageEnableGSUB.sanitize (c, this) &&
|
||||||
@ -123,7 +124,8 @@ struct JstfPriority
|
|||||||
struct JstfLangSys : OffsetListOf<JstfPriority>
|
struct JstfLangSys : OffsetListOf<JstfPriority>
|
||||||
{
|
{
|
||||||
inline bool sanitize (hb_sanitize_context_t *c,
|
inline bool sanitize (hb_sanitize_context_t *c,
|
||||||
const Record<JstfLangSys>::sanitize_closure_t * = NULL) {
|
const Record<JstfLangSys>::sanitize_closure_t * = NULL) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (OffsetListOf<JstfPriority>::sanitize (c));
|
return TRACE_RETURN (OffsetListOf<JstfPriority>::sanitize (c));
|
||||||
}
|
}
|
||||||
@ -163,7 +165,8 @@ struct JstfScript
|
|||||||
inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
|
inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c,
|
inline bool sanitize (hb_sanitize_context_t *c,
|
||||||
const Record<JstfScript>::sanitize_closure_t * = NULL) {
|
const Record<JstfScript>::sanitize_closure_t * = NULL) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (extenderGlyphs.sanitize (c, this) &&
|
return TRACE_RETURN (extenderGlyphs.sanitize (c, this) &&
|
||||||
defaultLangSys.sanitize (c, this) &&
|
defaultLangSys.sanitize (c, this) &&
|
||||||
@ -206,7 +209,8 @@ struct JSTF
|
|||||||
inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
|
inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
|
||||||
{ return scriptList.find_index (tag, index); }
|
{ return scriptList.find_index (tag, index); }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
|
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
|
||||||
scriptList.sanitize (c, this));
|
scriptList.sanitize (c, this));
|
||||||
|
@ -126,11 +126,15 @@ struct hb_ot_layout_lookup_accelerator_t
|
|||||||
lookup.add_coverage (&digest);
|
lookup.add_coverage (&digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TLookup>
|
inline void fini (void)
|
||||||
inline void fini (const TLookup &lookup HB_UNUSED)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool may_have (hb_codepoint_t g) const {
|
||||||
|
return digest.may_have (g);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
hb_set_digest_t digest;
|
hb_set_digest_t digest;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,9 +84,9 @@ void
|
|||||||
_hb_ot_layout_destroy (hb_ot_layout_t *layout)
|
_hb_ot_layout_destroy (hb_ot_layout_t *layout)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
|
for (unsigned int i = 0; i < layout->gsub_lookup_count; i++)
|
||||||
layout->gsub_accels[i].fini (layout->gsub->get_lookup (i));
|
layout->gsub_accels[i].fini ();
|
||||||
for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
|
for (unsigned int i = 0; i < layout->gpos_lookup_count; i++)
|
||||||
layout->gpos_accels[i].fini (layout->gpos->get_lookup (i));
|
layout->gpos_accels[i].fini ();
|
||||||
|
|
||||||
free (layout->gsub_accels);
|
free (layout->gsub_accels);
|
||||||
free (layout->gpos_accels);
|
free (layout->gpos_accels);
|
||||||
@ -699,7 +699,7 @@ hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
|
|||||||
|
|
||||||
const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
|
const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
|
||||||
|
|
||||||
return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index].digest);
|
return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -829,26 +829,83 @@ struct GPOSProxy
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename Lookup>
|
template <typename Obj>
|
||||||
static inline bool apply_once (OT::hb_apply_context_t *c,
|
static inline bool
|
||||||
const Lookup &lookup)
|
apply_forward (OT::hb_apply_context_t *c,
|
||||||
|
const Obj &obj,
|
||||||
|
const hb_ot_layout_lookup_accelerator_t &accel)
|
||||||
{
|
{
|
||||||
if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
|
bool ret = false;
|
||||||
return false;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
return lookup.dispatch (c);
|
while (buffer->idx < buffer->len)
|
||||||
|
{
|
||||||
|
if (accel.may_have (buffer->cur().codepoint) &&
|
||||||
|
(buffer->cur().mask & c->lookup_mask) &&
|
||||||
|
c->check_glyph_property (&buffer->cur(), c->lookup_props) &&
|
||||||
|
obj.apply (c))
|
||||||
|
ret = true;
|
||||||
|
else
|
||||||
|
buffer->next_glyph ();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Proxy>
|
template <typename Obj>
|
||||||
static inline bool
|
static inline bool
|
||||||
|
apply_backward (OT::hb_apply_context_t *c,
|
||||||
|
const Obj &obj,
|
||||||
|
const hb_ot_layout_lookup_accelerator_t &accel)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
hb_buffer_t *buffer = c->buffer;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (accel.may_have (buffer->cur().codepoint) &&
|
||||||
|
(buffer->cur().mask & c->lookup_mask) &&
|
||||||
|
c->check_glyph_property (&buffer->cur(), c->lookup_props) &&
|
||||||
|
obj.apply (c))
|
||||||
|
ret = true;
|
||||||
|
/* The reverse lookup doesn't "advance" cursor (for good reason). */
|
||||||
|
buffer->idx--;
|
||||||
|
|
||||||
|
}
|
||||||
|
while ((int) buffer->idx >= 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hb_apply_forward_context_t
|
||||||
|
{
|
||||||
|
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; }
|
||||||
|
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; }
|
||||||
|
bool stop_sublookup_iteration (return_t r HB_UNUSED) const { return true; }
|
||||||
|
|
||||||
|
hb_apply_forward_context_t (OT::hb_apply_context_t *c_,
|
||||||
|
const hb_ot_layout_lookup_accelerator_t &accel_) :
|
||||||
|
c (c_),
|
||||||
|
accel (accel_),
|
||||||
|
debug_depth (0) {}
|
||||||
|
|
||||||
|
OT::hb_apply_context_t *c;
|
||||||
|
const hb_ot_layout_lookup_accelerator_t &accel;
|
||||||
|
unsigned int debug_depth;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Proxy>
|
||||||
|
static inline void
|
||||||
apply_string (OT::hb_apply_context_t *c,
|
apply_string (OT::hb_apply_context_t *c,
|
||||||
const typename Proxy::Lookup &lookup,
|
const typename Proxy::Lookup &lookup,
|
||||||
const hb_ot_layout_lookup_accelerator_t &accel)
|
const hb_ot_layout_lookup_accelerator_t &accel)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
|
||||||
hb_buffer_t *buffer = c->buffer;
|
hb_buffer_t *buffer = c->buffer;
|
||||||
|
|
||||||
if (unlikely (!buffer->len || !c->lookup_mask))
|
if (unlikely (!buffer->len || !c->lookup_mask))
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
c->set_lookup (lookup);
|
c->set_lookup (lookup);
|
||||||
|
|
||||||
@ -859,21 +916,20 @@ apply_string (OT::hb_apply_context_t *c,
|
|||||||
buffer->clear_output ();
|
buffer->clear_output ();
|
||||||
buffer->idx = 0;
|
buffer->idx = 0;
|
||||||
|
|
||||||
while (buffer->idx < buffer->len)
|
bool ret;
|
||||||
|
if (lookup.get_subtable_count () == 1)
|
||||||
{
|
{
|
||||||
if (accel.digest.may_have (buffer->cur().codepoint) &&
|
hb_apply_forward_context_t c_forward (c, accel);
|
||||||
(buffer->cur().mask & c->lookup_mask) &&
|
ret = lookup.dispatch (&c_forward);
|
||||||
apply_once (c, lookup))
|
|
||||||
ret = true;
|
|
||||||
else
|
|
||||||
buffer->next_glyph ();
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ret = apply_forward (c, lookup, accel);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
if (!Proxy::inplace)
|
if (!Proxy::inplace)
|
||||||
buffer->swap_buffers ();
|
buffer->swap_buffers ();
|
||||||
else
|
else
|
||||||
assert (!buffer->has_separate_output ());
|
assert (!buffer->has_separate_output ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -882,20 +938,9 @@ apply_string (OT::hb_apply_context_t *c,
|
|||||||
if (Proxy::table_index == 0)
|
if (Proxy::table_index == 0)
|
||||||
buffer->remove_output ();
|
buffer->remove_output ();
|
||||||
buffer->idx = buffer->len - 1;
|
buffer->idx = buffer->len - 1;
|
||||||
do
|
|
||||||
{
|
|
||||||
if (accel.digest.may_have (buffer->cur().codepoint) &&
|
|
||||||
(buffer->cur().mask & c->lookup_mask) &&
|
|
||||||
apply_once (c, lookup))
|
|
||||||
ret = true;
|
|
||||||
/* The reverse lookup doesn't "advance" cursor (for good reason). */
|
|
||||||
buffer->idx--;
|
|
||||||
|
|
||||||
}
|
apply_backward (c, lookup, accel);
|
||||||
while ((int) buffer->idx >= 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Proxy>
|
template <typename Proxy>
|
||||||
|
@ -43,11 +43,13 @@ struct maxp
|
|||||||
{
|
{
|
||||||
static const hb_tag_t tableTag = HB_OT_TAG_maxp;
|
static const hb_tag_t tableTag = HB_OT_TAG_maxp;
|
||||||
|
|
||||||
inline unsigned int get_num_glyphs (void) const {
|
inline unsigned int get_num_glyphs (void) const
|
||||||
|
{
|
||||||
return numGlyphs;
|
return numGlyphs;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u)));
|
likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u)));
|
||||||
|
@ -56,7 +56,8 @@ struct NameRecord
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
|
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
/* We can check from base all the way up to the end of string... */
|
/* 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_RETURN (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
|
||||||
@ -101,7 +102,7 @@ struct name
|
|||||||
inline unsigned int get_size (void) const
|
inline unsigned int get_size (void) const
|
||||||
{ return min_size + count * nameRecord[0].min_size; }
|
{ return min_size + count * nameRecord[0].min_size; }
|
||||||
|
|
||||||
inline bool sanitize_records (hb_sanitize_context_t *c) {
|
inline bool sanitize_records (hb_sanitize_context_t *c) const {
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
char *string_pool = (char *) this + stringOffset;
|
char *string_pool = (char *) this + stringOffset;
|
||||||
unsigned int _count = count;
|
unsigned int _count = count;
|
||||||
@ -110,7 +111,8 @@ struct name
|
|||||||
return TRACE_RETURN (true);
|
return TRACE_RETURN (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return TRACE_RETURN (c->check_struct (this) &&
|
return TRACE_RETURN (c->check_struct (this) &&
|
||||||
likely (format == 0 || format == 1) &&
|
likely (format == 0 || format == 1) &&
|
||||||
|
@ -327,7 +327,7 @@ arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan)
|
|||||||
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
|
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
|
||||||
if (fallback_plan->lookup_array[i])
|
if (fallback_plan->lookup_array[i])
|
||||||
{
|
{
|
||||||
fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]);
|
fallback_plan->accel_array[i].fini ();
|
||||||
if (fallback_plan->free_lookups)
|
if (fallback_plan->free_lookups)
|
||||||
free (fallback_plan->lookup_array[i]);
|
free (fallback_plan->lookup_array[i]);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define OT_LOOKUP_TYPE_SUBST_SINGLE 1u
|
#define OT_LOOKUP_TYPE_SUBST_SINGLE 1u
|
||||||
#define OT_LOOKUP_TYPE_SUBST_MULTIPLE 2u
|
|
||||||
#define OT_LOOKUP_TYPE_SUBST_LIGATURE 4u
|
#define OT_LOOKUP_TYPE_SUBST_LIGATURE 4u
|
||||||
|
|
||||||
#define OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(Name, FromGlyphs, ToGlyphs) \
|
#define OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(Name, FromGlyphs, ToGlyphs) \
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -861,41 +861,41 @@ hb_indic_get_categories (hb_codepoint_t u)
|
|||||||
switch (u >> 12)
|
switch (u >> 12)
|
||||||
{
|
{
|
||||||
case 0x0u:
|
case 0x0u:
|
||||||
if (hb_in_range (u, 0x0028u, 0x0040u)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
|
if (hb_in_range (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
|
||||||
if (hb_in_range (u, 0x00D0u, 0x00D8u)) return indic_table[u - 0x00D0u + indic_offset_0x00d0u];
|
if (hb_in_range (u, 0x00D0u, 0x00D7u)) return indic_table[u - 0x00D0u + indic_offset_0x00d0u];
|
||||||
if (hb_in_range (u, 0x0900u, 0x0DF8u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
|
if (hb_in_range (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
|
||||||
if (unlikely (u == 0x00A0u)) return _(CP,x);
|
if (unlikely (u == 0x00A0u)) return _(CP,x);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1u:
|
case 0x1u:
|
||||||
if (hb_in_range (u, 0x1000u, 0x10A0u)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
|
if (hb_in_range (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
|
||||||
if (hb_in_range (u, 0x1700u, 0x17F0u)) return indic_table[u - 0x1700u + indic_offset_0x1700u];
|
if (hb_in_range (u, 0x1700u, 0x17EFu)) return indic_table[u - 0x1700u + indic_offset_0x1700u];
|
||||||
if (hb_in_range (u, 0x1900u, 0x1AA0u)) return indic_table[u - 0x1900u + indic_offset_0x1900u];
|
if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return indic_table[u - 0x1900u + indic_offset_0x1900u];
|
||||||
if (hb_in_range (u, 0x1B00u, 0x1C50u)) return indic_table[u - 0x1B00u + indic_offset_0x1b00u];
|
if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return indic_table[u - 0x1B00u + indic_offset_0x1b00u];
|
||||||
if (hb_in_range (u, 0x1CD0u, 0x1CF8u)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
|
if (hb_in_range (u, 0x1CD0u, 0x1CF7u)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2u:
|
case 0x2u:
|
||||||
if (hb_in_range (u, 0x2008u, 0x2018u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
|
if (hb_in_range (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
|
||||||
if (unlikely (u == 0x25CCu)) return _(CP,x);
|
if (unlikely (u == 0x25CCu)) return _(CP,x);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xAu:
|
case 0xAu:
|
||||||
if (hb_in_range (u, 0xA800u, 0xAAF8u)) return indic_table[u - 0xA800u + indic_offset_0xa800u];
|
if (hb_in_range (u, 0xA800u, 0xAAF7u)) return indic_table[u - 0xA800u + indic_offset_0xa800u];
|
||||||
if (hb_in_range (u, 0xABC0u, 0xAC00u)) return indic_table[u - 0xABC0u + indic_offset_0xabc0u];
|
if (hb_in_range (u, 0xABC0u, 0xABFFu)) return indic_table[u - 0xABC0u + indic_offset_0xabc0u];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10u:
|
case 0x10u:
|
||||||
if (hb_in_range (u, 0x10A00u, 0x10A48u)) return indic_table[u - 0x10A00u + indic_offset_0x10a00u];
|
if (hb_in_range (u, 0x10A00u, 0x10A47u)) return indic_table[u - 0x10A00u + indic_offset_0x10a00u];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x11u:
|
case 0x11u:
|
||||||
if (hb_in_range (u, 0x11000u, 0x110C0u)) return indic_table[u - 0x11000u + indic_offset_0x11000u];
|
if (hb_in_range (u, 0x11000u, 0x110BFu)) return indic_table[u - 0x11000u + indic_offset_0x11000u];
|
||||||
if (hb_in_range (u, 0x11100u, 0x11238u)) return indic_table[u - 0x11100u + indic_offset_0x11100u];
|
if (hb_in_range (u, 0x11100u, 0x11237u)) return indic_table[u - 0x11100u + indic_offset_0x11100u];
|
||||||
if (hb_in_range (u, 0x112B0u, 0x11378u)) return indic_table[u - 0x112B0u + indic_offset_0x112b0u];
|
if (hb_in_range (u, 0x112B0u, 0x11377u)) return indic_table[u - 0x112B0u + indic_offset_0x112b0u];
|
||||||
if (hb_in_range (u, 0x11480u, 0x114E0u)) return indic_table[u - 0x11480u + indic_offset_0x11480u];
|
if (hb_in_range (u, 0x11480u, 0x114DFu)) return indic_table[u - 0x11480u + indic_offset_0x11480u];
|
||||||
if (hb_in_range (u, 0x11580u, 0x115C8u)) return indic_table[u - 0x11580u + indic_offset_0x11580u];
|
if (hb_in_range (u, 0x11580u, 0x115C7u)) return indic_table[u - 0x11580u + indic_offset_0x11580u];
|
||||||
if (hb_in_range (u, 0x11600u, 0x116D0u)) return indic_table[u - 0x11600u + indic_offset_0x11600u];
|
if (hb_in_range (u, 0x11600u, 0x116CFu)) return indic_table[u - 0x11600u + indic_offset_0x11600u];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 1 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 1 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
/*
|
/*
|
||||||
* Copyright © 2011,2012 Google, Inc.
|
* Copyright © 2011,2012 Google, Inc.
|
||||||
*
|
*
|
||||||
@ -32,7 +32,7 @@
|
|||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
|
|
||||||
|
|
||||||
#line 36 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
|
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||||
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
|
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
|
||||||
1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
|
1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
|
||||||
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
|
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
|
||||||
@ -261,11 +261,11 @@ static const int myanmar_syllable_machine_error = -1;
|
|||||||
static const int myanmar_syllable_machine_en_main = 0;
|
static const int myanmar_syllable_machine_en_main = 0;
|
||||||
|
|
||||||
|
|
||||||
#line 36 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 36 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#line 93 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 93 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
|
|
||||||
|
|
||||||
#define found_syllable(syllable_type) \
|
#define found_syllable(syllable_type) \
|
||||||
@ -285,7 +285,7 @@ find_syllables (hb_buffer_t *buffer)
|
|||||||
int cs;
|
int cs;
|
||||||
hb_glyph_info_t *info = buffer->info;
|
hb_glyph_info_t *info = buffer->info;
|
||||||
|
|
||||||
#line 289 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
|
#line 289 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||||
{
|
{
|
||||||
cs = myanmar_syllable_machine_start;
|
cs = myanmar_syllable_machine_start;
|
||||||
ts = 0;
|
ts = 0;
|
||||||
@ -293,7 +293,7 @@ find_syllables (hb_buffer_t *buffer)
|
|||||||
act = 0;
|
act = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 114 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
|
|
||||||
|
|
||||||
p = 0;
|
p = 0;
|
||||||
@ -302,7 +302,7 @@ find_syllables (hb_buffer_t *buffer)
|
|||||||
unsigned int last = 0;
|
unsigned int last = 0;
|
||||||
unsigned int syllable_serial = 1;
|
unsigned int syllable_serial = 1;
|
||||||
|
|
||||||
#line 306 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
|
#line 306 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||||
{
|
{
|
||||||
int _slen;
|
int _slen;
|
||||||
int _trans;
|
int _trans;
|
||||||
@ -316,7 +316,7 @@ _resume:
|
|||||||
#line 1 "NONE"
|
#line 1 "NONE"
|
||||||
{ts = p;}
|
{ts = p;}
|
||||||
break;
|
break;
|
||||||
#line 320 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
|
#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||||
}
|
}
|
||||||
|
|
||||||
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
|
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
|
||||||
@ -335,38 +335,38 @@ _eof_trans:
|
|||||||
|
|
||||||
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
|
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
|
||||||
case 7:
|
case 7:
|
||||||
#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
{te = p+1;{ found_syllable (consonant_syllable); }}
|
{te = p+1;{ found_syllable (consonant_syllable); }}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
#line 86 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
|
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
#line 87 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
{te = p+1;{ found_syllable (punctuation_cluster); }}
|
{te = p+1;{ found_syllable (punctuation_cluster); }}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
{te = p+1;{ found_syllable (broken_cluster); }}
|
{te = p+1;{ found_syllable (broken_cluster); }}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
|
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 85 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
{te = p;p--;{ found_syllable (consonant_syllable); }}
|
{te = p;p--;{ found_syllable (consonant_syllable); }}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
{te = p;p--;{ found_syllable (broken_cluster); }}
|
{te = p;p--;{ found_syllable (broken_cluster); }}
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
|
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
|
||||||
break;
|
break;
|
||||||
#line 370 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
|
#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||||
}
|
}
|
||||||
|
|
||||||
_again:
|
_again:
|
||||||
@ -375,7 +375,7 @@ _again:
|
|||||||
#line 1 "NONE"
|
#line 1 "NONE"
|
||||||
{ts = 0;}
|
{ts = 0;}
|
||||||
break;
|
break;
|
||||||
#line 379 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
|
#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ++p != pe )
|
if ( ++p != pe )
|
||||||
@ -391,7 +391,7 @@ _again:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 123 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
#line 123 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,9 +179,12 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
|||||||
case HB_SCRIPT_PSALTER_PAHLAVI:
|
case HB_SCRIPT_PSALTER_PAHLAVI:
|
||||||
|
|
||||||
/* For Arabic script, use the Arabic shaper even if no OT script tag was found.
|
/* 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). */
|
* This is because we do fallback shaping for Arabic script (and not others).
|
||||||
if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
|
* But note that Arabic shaping is applicable only to horizontal layout; for
|
||||||
planner->props.script == HB_SCRIPT_ARABIC)
|
* 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;
|
return &_hb_ot_complex_shaper_arabic;
|
||||||
else
|
else
|
||||||
return &_hb_ot_complex_shaper_default;
|
return &_hb_ot_complex_shaper_default;
|
||||||
@ -259,6 +262,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
|||||||
|
|
||||||
/* Unicode-4.1 additions */
|
/* Unicode-4.1 additions */
|
||||||
case HB_SCRIPT_KHAROSHTHI:
|
case HB_SCRIPT_KHAROSHTHI:
|
||||||
|
case HB_SCRIPT_NEW_TAI_LUE:
|
||||||
case HB_SCRIPT_SYLOTI_NAGRI:
|
case HB_SCRIPT_SYLOTI_NAGRI:
|
||||||
|
|
||||||
/* Unicode-5.1 additions */
|
/* Unicode-5.1 additions */
|
||||||
@ -339,7 +343,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
|||||||
|
|
||||||
/* Unicode-4.1 additions */
|
/* Unicode-4.1 additions */
|
||||||
case HB_SCRIPT_BUGINESE:
|
case HB_SCRIPT_BUGINESE:
|
||||||
case HB_SCRIPT_NEW_TAI_LUE:
|
|
||||||
|
|
||||||
/* Unicode-5.1 additions */
|
/* Unicode-5.1 additions */
|
||||||
case HB_SCRIPT_CHAM:
|
case HB_SCRIPT_CHAM:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 1 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 1 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
/*
|
/*
|
||||||
* Copyright © 2011,2012,2013 Google, Inc.
|
* Copyright © 2011,2012,2013 Google, Inc.
|
||||||
*
|
*
|
||||||
@ -32,7 +32,7 @@
|
|||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
|
|
||||||
|
|
||||||
#line 36 "hb-ot-shape-complex-sea-machine.hh.tmp"
|
#line 36 "hb-ot-shape-complex-sea-machine.hh"
|
||||||
static const unsigned char _sea_syllable_machine_trans_keys[] = {
|
static const unsigned char _sea_syllable_machine_trans_keys[] = {
|
||||||
1u, 1u, 1u, 1u, 1u, 29u, 3u, 29u, 3u, 29u, 1u, 1u, 0
|
1u, 1u, 1u, 1u, 1u, 29u, 3u, 29u, 3u, 29u, 1u, 1u, 0
|
||||||
};
|
};
|
||||||
@ -89,11 +89,11 @@ static const int sea_syllable_machine_error = -1;
|
|||||||
static const int sea_syllable_machine_en_main = 2;
|
static const int sea_syllable_machine_en_main = 2;
|
||||||
|
|
||||||
|
|
||||||
#line 36 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 36 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#line 67 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 67 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
|
|
||||||
|
|
||||||
#define found_syllable(syllable_type) \
|
#define found_syllable(syllable_type) \
|
||||||
@ -113,7 +113,7 @@ find_syllables (hb_buffer_t *buffer)
|
|||||||
int cs;
|
int cs;
|
||||||
hb_glyph_info_t *info = buffer->info;
|
hb_glyph_info_t *info = buffer->info;
|
||||||
|
|
||||||
#line 117 "hb-ot-shape-complex-sea-machine.hh.tmp"
|
#line 117 "hb-ot-shape-complex-sea-machine.hh"
|
||||||
{
|
{
|
||||||
cs = sea_syllable_machine_start;
|
cs = sea_syllable_machine_start;
|
||||||
ts = 0;
|
ts = 0;
|
||||||
@ -121,7 +121,7 @@ find_syllables (hb_buffer_t *buffer)
|
|||||||
act = 0;
|
act = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 88 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 88 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
|
|
||||||
|
|
||||||
p = 0;
|
p = 0;
|
||||||
@ -130,7 +130,7 @@ find_syllables (hb_buffer_t *buffer)
|
|||||||
unsigned int last = 0;
|
unsigned int last = 0;
|
||||||
unsigned int syllable_serial = 1;
|
unsigned int syllable_serial = 1;
|
||||||
|
|
||||||
#line 134 "hb-ot-shape-complex-sea-machine.hh.tmp"
|
#line 134 "hb-ot-shape-complex-sea-machine.hh"
|
||||||
{
|
{
|
||||||
int _slen;
|
int _slen;
|
||||||
int _trans;
|
int _trans;
|
||||||
@ -144,7 +144,7 @@ _resume:
|
|||||||
#line 1 "NONE"
|
#line 1 "NONE"
|
||||||
{ts = p;}
|
{ts = p;}
|
||||||
break;
|
break;
|
||||||
#line 148 "hb-ot-shape-complex-sea-machine.hh.tmp"
|
#line 148 "hb-ot-shape-complex-sea-machine.hh"
|
||||||
}
|
}
|
||||||
|
|
||||||
_keys = _sea_syllable_machine_trans_keys + (cs<<1);
|
_keys = _sea_syllable_machine_trans_keys + (cs<<1);
|
||||||
@ -167,30 +167,30 @@ _eof_trans:
|
|||||||
{te = p+1;}
|
{te = p+1;}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
#line 63 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 63 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
{te = p+1;{ found_syllable (non_sea_cluster); }}
|
{te = p+1;{ found_syllable (non_sea_cluster); }}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
#line 61 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 61 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
{te = p;p--;{ found_syllable (consonant_syllable); }}
|
{te = p;p--;{ found_syllable (consonant_syllable); }}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
#line 62 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 62 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
{te = p;p--;{ found_syllable (broken_cluster); }}
|
{te = p;p--;{ found_syllable (broken_cluster); }}
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
#line 63 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 63 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
{te = p;p--;{ found_syllable (non_sea_cluster); }}
|
{te = p;p--;{ found_syllable (non_sea_cluster); }}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
#line 61 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 61 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
|
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
#line 62 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 62 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
|
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
|
||||||
break;
|
break;
|
||||||
#line 194 "hb-ot-shape-complex-sea-machine.hh.tmp"
|
#line 194 "hb-ot-shape-complex-sea-machine.hh"
|
||||||
}
|
}
|
||||||
|
|
||||||
_again:
|
_again:
|
||||||
@ -199,7 +199,7 @@ _again:
|
|||||||
#line 1 "NONE"
|
#line 1 "NONE"
|
||||||
{ts = 0;}
|
{ts = 0;}
|
||||||
break;
|
break;
|
||||||
#line 203 "hb-ot-shape-complex-sea-machine.hh.tmp"
|
#line 203 "hb-ot-shape-complex-sea-machine.hh"
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ++p != pe )
|
if ( ++p != pe )
|
||||||
@ -215,7 +215,7 @@ _again:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#line 97 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
#line 97 "hb-ot-shape-complex-sea-machine.rl"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,13 +441,15 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
|||||||
OT::hb_apply_context_t c (1, font, buffer);
|
OT::hb_apply_context_t c (1, font, buffer);
|
||||||
c.set_lookup_mask (plan->kern_mask);
|
c.set_lookup_mask (plan->kern_mask);
|
||||||
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
||||||
|
OT::hb_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
|
||||||
|
skippy_iter.init (&c);
|
||||||
|
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
hb_glyph_info_t *info = buffer->info;
|
hb_glyph_info_t *info = buffer->info;
|
||||||
hb_glyph_position_t *pos = buffer->pos;
|
hb_glyph_position_t *pos = buffer->pos;
|
||||||
for (unsigned int idx = 0; idx < count;)
|
for (unsigned int idx = 0; idx < count;)
|
||||||
{
|
{
|
||||||
OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1);
|
skippy_iter.reset (idx, 1);
|
||||||
if (!skippy_iter.next ())
|
if (!skippy_iter.next ())
|
||||||
{
|
{
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -197,16 +197,17 @@ static inline void
|
|||||||
decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest)
|
decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest)
|
||||||
{
|
{
|
||||||
hb_buffer_t * const buffer = c->buffer;
|
hb_buffer_t * const buffer = c->buffer;
|
||||||
|
hb_codepoint_t u = buffer->cur().codepoint;
|
||||||
hb_codepoint_t glyph;
|
hb_codepoint_t glyph;
|
||||||
|
|
||||||
/* Kind of a cute waterfall here... */
|
/* Kind of a cute waterfall here... */
|
||||||
if (shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph))
|
if (shortest && c->font->get_glyph (u, 0, &glyph))
|
||||||
next_char (buffer, glyph);
|
next_char (buffer, glyph);
|
||||||
else if (decompose (c, shortest, buffer->cur().codepoint))
|
else if (decompose (c, shortest, u))
|
||||||
skip_char (buffer);
|
skip_char (buffer);
|
||||||
else if (!shortest && c->font->get_glyph (buffer->cur().codepoint, 0, &glyph))
|
else if (!shortest && c->font->get_glyph (u, 0, &glyph))
|
||||||
next_char (buffer, glyph);
|
next_char (buffer, glyph);
|
||||||
else if (decompose_compatibility (c, buffer->cur().codepoint))
|
else if (decompose_compatibility (c, u))
|
||||||
skip_char (buffer);
|
skip_char (buffer);
|
||||||
else
|
else
|
||||||
next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
|
next_char (buffer, glyph); /* glyph is initialized in earlier branches. */
|
||||||
|
@ -676,7 +676,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
|
|||||||
pos[i].y_advance = 0;
|
pos[i].y_advance = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
continue; /* Delete it. */
|
continue; /* Delete it. XXX Merge clusters? */
|
||||||
}
|
}
|
||||||
if (j != i)
|
if (j != i)
|
||||||
{
|
{
|
||||||
|
@ -94,20 +94,6 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#undef inline
|
|
||||||
#define inline __inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __STRICT_ANSI__
|
|
||||||
#undef inline
|
|
||||||
#define inline __inline__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if __GNUC__ >= 3
|
#if __GNUC__ >= 3
|
||||||
#define HB_FUNC __PRETTY_FUNCTION__
|
#define HB_FUNC __PRETTY_FUNCTION__
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
@ -132,14 +118,21 @@
|
|||||||
# ifndef STRICT
|
# ifndef STRICT
|
||||||
# define STRICT 1
|
# define STRICT 1
|
||||||
# endif
|
# endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32_WCE
|
# if defined(_WIN32_WCE)
|
||||||
/* Some things not defined on Windows CE. */
|
/* Some things not defined on Windows CE. */
|
||||||
#define MemoryBarrier()
|
# define strdup _strdup
|
||||||
#define getenv(Name) NULL
|
# define getenv(Name) NULL
|
||||||
#define setlocale(Category, Locale) "C"
|
# if _WIN32_WCE < 0x800
|
||||||
|
# define setlocale(Category, Locale) "C"
|
||||||
static int errno = 0; /* Use something better? */
|
static int errno = 0; /* Use something better? */
|
||||||
|
# endif
|
||||||
|
# elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
|
||||||
|
# define getenv(Name) NULL
|
||||||
|
# endif
|
||||||
|
# if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
|
# define snprintf _snprintf
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_ATEXIT
|
#if HAVE_ATEXIT
|
||||||
@ -581,6 +574,30 @@ _hb_debug (unsigned int level,
|
|||||||
#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
|
#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
|
||||||
#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
|
#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_hb_print_func (const char *func)
|
||||||
|
{
|
||||||
|
if (func)
|
||||||
|
{
|
||||||
|
unsigned int func_len = strlen (func);
|
||||||
|
/* Skip "static" */
|
||||||
|
if (0 == strncmp (func, "static ", 7))
|
||||||
|
func += 7;
|
||||||
|
/* Skip "typename" */
|
||||||
|
if (0 == strncmp (func, "typename ", 9))
|
||||||
|
func += 9;
|
||||||
|
/* Skip return type */
|
||||||
|
const char *space = strchr (func, ' ');
|
||||||
|
if (space)
|
||||||
|
func = space + 1;
|
||||||
|
/* Skip parameter list */
|
||||||
|
const char *paren = strchr (func, '(');
|
||||||
|
if (paren)
|
||||||
|
func_len = paren - func;
|
||||||
|
fprintf (stderr, "%.*s", func_len, func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <int max_level> static inline void
|
template <int max_level> static inline void
|
||||||
_hb_debug_msg_va (const char *what,
|
_hb_debug_msg_va (const char *what,
|
||||||
const void *obj,
|
const void *obj,
|
||||||
@ -626,27 +643,13 @@ _hb_debug_msg_va (const char *what,
|
|||||||
} else
|
} else
|
||||||
fprintf (stderr, " " VRBAR LBAR);
|
fprintf (stderr, " " VRBAR LBAR);
|
||||||
|
|
||||||
if (func)
|
_hb_print_func (func);
|
||||||
{
|
|
||||||
unsigned int func_len = strlen (func);
|
|
||||||
#ifndef HB_DEBUG_VERBOSE
|
|
||||||
/* Skip "typename" */
|
|
||||||
if (0 == strncmp (func, "typename ", 9))
|
|
||||||
func += 9;
|
|
||||||
/* Skip return type */
|
|
||||||
const char *space = strchr (func, ' ');
|
|
||||||
if (space)
|
|
||||||
func = space + 1;
|
|
||||||
/* Skip parameter list */
|
|
||||||
const char *paren = strchr (func, '(');
|
|
||||||
if (paren)
|
|
||||||
func_len = paren - func;
|
|
||||||
#endif
|
|
||||||
fprintf (stderr, "%.*s: ", func_len, func);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message)
|
if (message)
|
||||||
|
{
|
||||||
|
fprintf (stderr, ": ");
|
||||||
vfprintf (stderr, message, ap);
|
vfprintf (stderr, message, ap);
|
||||||
|
}
|
||||||
|
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
}
|
}
|
||||||
@ -818,7 +821,7 @@ hb_in_range (T u, T lo, T hi)
|
|||||||
/* The sizeof() is here to force template instantiation.
|
/* The sizeof() is here to force template instantiation.
|
||||||
* I'm sure there are better ways to do this but can't think of
|
* I'm sure there are better ways to do this but can't think of
|
||||||
* one right now. Declaring a variable won't work as HB_UNUSED
|
* one right now. Declaring a variable won't work as HB_UNUSED
|
||||||
* is unsable on some platforms and unused types are less likely
|
* is unusable on some platforms and unused types are less likely
|
||||||
* to generate a warning than unused variables. */
|
* to generate a warning than unused variables. */
|
||||||
ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);
|
ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);
|
||||||
|
|
||||||
|
@ -145,6 +145,8 @@ typedef hb_set_digest_combiner_t
|
|||||||
|
|
||||||
struct hb_set_t
|
struct hb_set_t
|
||||||
{
|
{
|
||||||
|
friend struct hb_frozen_set_t;
|
||||||
|
|
||||||
hb_object_header_t header;
|
hb_object_header_t header;
|
||||||
ASSERT_POD ();
|
ASSERT_POD ();
|
||||||
bool in_error;
|
bool in_error;
|
||||||
@ -326,7 +328,7 @@ struct hb_set_t
|
|||||||
static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
|
static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
|
||||||
|
|
||||||
elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
|
elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
|
||||||
elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
|
elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
|
||||||
elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
|
elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
|
||||||
|
|
||||||
elt_t elts[ELTS]; /* XXX 8kb */
|
elt_t elts[ELTS]; /* XXX 8kb */
|
||||||
@ -335,6 +337,58 @@ struct hb_set_t
|
|||||||
ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G);
|
ASSERT_STATIC (sizeof (elt_t) * 8 * ELTS > MAX_G);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct hb_frozen_set_t
|
||||||
|
{
|
||||||
|
static const unsigned int SHIFT = hb_set_t::SHIFT;
|
||||||
|
static const unsigned int BITS = hb_set_t::BITS;
|
||||||
|
static const unsigned int MASK = hb_set_t::MASK;
|
||||||
|
typedef hb_set_t::elt_t elt_t;
|
||||||
|
|
||||||
|
inline void init (const hb_set_t &set)
|
||||||
|
{
|
||||||
|
start = count = 0;
|
||||||
|
elts = NULL;
|
||||||
|
|
||||||
|
unsigned int max = set.get_max ();
|
||||||
|
if (max == set.INVALID)
|
||||||
|
return;
|
||||||
|
unsigned int min = set.get_min ();
|
||||||
|
const elt_t &min_elt = set.elt (min);
|
||||||
|
|
||||||
|
start = min & ~MASK;
|
||||||
|
count = max - start + 1;
|
||||||
|
unsigned int num_elts = (count + BITS - 1) / BITS;
|
||||||
|
unsigned int elts_size = num_elts * sizeof (elt_t);
|
||||||
|
elts = (elt_t *) malloc (elts_size);
|
||||||
|
if (unlikely (!elts))
|
||||||
|
{
|
||||||
|
start = count = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy (elts, &min_elt, elts_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fini (void)
|
||||||
|
{
|
||||||
|
if (elts)
|
||||||
|
free (elts);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool has (hb_codepoint_t g) const
|
||||||
|
{
|
||||||
|
/* hb_codepoint_t is unsigned. */
|
||||||
|
g -= start;
|
||||||
|
if (unlikely (g > count)) return false;
|
||||||
|
return !!(elt (g) & mask (g));
|
||||||
|
}
|
||||||
|
|
||||||
|
elt_t const &elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
|
||||||
|
elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
hb_codepoint_t start, count;
|
||||||
|
elt_t *elts;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* HB_SET_PRIVATE_HH */
|
#endif /* HB_SET_PRIVATE_HH */
|
||||||
|
@ -126,7 +126,7 @@ hb_shape_plan_create (hb_face_t *face,
|
|||||||
|
|
||||||
if (unlikely (!face))
|
if (unlikely (!face))
|
||||||
face = hb_face_get_empty ();
|
face = hb_face_get_empty ();
|
||||||
if (unlikely (!props || hb_object_is_inert (face)))
|
if (unlikely (!props))
|
||||||
return hb_shape_plan_get_empty ();
|
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 *) malloc (num_user_features * sizeof (hb_feature_t))))
|
||||||
return hb_shape_plan_get_empty ();
|
return hb_shape_plan_get_empty ();
|
||||||
@ -294,7 +294,6 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
|
|||||||
shape_plan->shaper_func);
|
shape_plan->shaper_func);
|
||||||
|
|
||||||
if (unlikely (hb_object_is_inert (shape_plan) ||
|
if (unlikely (hb_object_is_inert (shape_plan) ||
|
||||||
hb_object_is_inert (font) ||
|
|
||||||
hb_object_is_inert (buffer)))
|
hb_object_is_inert (buffer)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -453,6 +452,10 @@ retry:
|
|||||||
|
|
||||||
hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
|
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 */
|
/* 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))
|
if (hb_non_global_user_features_present (user_features, num_user_features))
|
||||||
|
@ -198,9 +198,9 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_feature_from_string:
|
* hb_feature_from_string:
|
||||||
* @str: (array length=len):
|
* @str: (array length=len) (element-type uint8_t):
|
||||||
* @len:
|
* @len:
|
||||||
* @feature: (out) (allow-none):
|
* @feature: (out) (optional):
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -279,11 +279,13 @@ hb_feature_to_string (hb_feature_t *feature,
|
|||||||
|
|
||||||
static const char **static_shaper_list;
|
static const char **static_shaper_list;
|
||||||
|
|
||||||
static inline
|
#ifdef HB_USE_ATEXIT
|
||||||
|
static
|
||||||
void free_static_shaper_list (void)
|
void free_static_shaper_list (void)
|
||||||
{
|
{
|
||||||
free (static_shaper_list);
|
free (static_shaper_list);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_shape_list_shapers:
|
* hb_shape_list_shapers:
|
||||||
|
@ -79,10 +79,9 @@ struct hb_shaper_data_t {
|
|||||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data)
|
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data)
|
||||||
|
|
||||||
#define HB_SHAPER_DATA_DESTROY(shaper, object) \
|
#define HB_SHAPER_DATA_DESTROY(shaper, object) \
|
||||||
if (object->shaper_data.shaper && \
|
if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object)) \
|
||||||
object->shaper_data.shaper != HB_SHAPER_DATA_INVALID && \
|
if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
|
||||||
object->shaper_data.shaper != HB_SHAPER_DATA_SUCCEEDED) \
|
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
|
||||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA (shaper, object));
|
|
||||||
|
|
||||||
#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
|
#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
|
||||||
static inline bool \
|
static inline bool \
|
||||||
|
@ -40,12 +40,14 @@ static const hb_shaper_pair_t all_shapers[] = {
|
|||||||
|
|
||||||
static const hb_shaper_pair_t *static_shapers;
|
static const hb_shaper_pair_t *static_shapers;
|
||||||
|
|
||||||
static inline
|
#ifdef HB_USE_ATEXIT
|
||||||
|
static
|
||||||
void free_static_shapers (void)
|
void free_static_shapers (void)
|
||||||
{
|
{
|
||||||
if (unlikely (static_shapers != all_shapers))
|
if (unlikely (static_shapers != all_shapers))
|
||||||
free ((void *) static_shapers);
|
free ((void *) static_shapers);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const hb_shaper_pair_t *
|
const hb_shaper_pair_t *
|
||||||
_hb_shapers_get (void)
|
_hb_shapers_get (void)
|
||||||
|
@ -147,17 +147,17 @@ hb_unicode_funcs_get_default (void)
|
|||||||
|
|
||||||
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
|
#if !defined(HB_NO_UNICODE_FUNCS) && defined(HB_UNICODE_FUNCS_NIL)
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma message("Could not find any Unicode functions implementation, you have to provide your own")
|
#pragma error("Could not find any Unicode functions implementation, you have to provide your own.")
|
||||||
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS")
|
#pragma error("Consider building hb-ucdn.c. If you absolutely want to build without any, check the code.")
|
||||||
#else
|
#else
|
||||||
#warning "Could not find any Unicode functions implementation, you have to provide your own"
|
#error "Could not find any Unicode functions implementation, you have to provide your own"
|
||||||
#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS"
|
#error "Consider building hb-ucdn.c. If you absolutely want to build without any, check the code."
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_unicode_funcs_create: (Xconstructor)
|
* hb_unicode_funcs_create: (Xconstructor)
|
||||||
* @parent: (allow-none):
|
* @parent: (nullable):
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
|
@ -29,14 +29,11 @@
|
|||||||
|
|
||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
|
|
||||||
template <typename T, bool validate=true> struct hb_utf_t;
|
|
||||||
|
|
||||||
|
struct hb_utf8_t
|
||||||
/* UTF-8 */
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct hb_utf_t<uint8_t, true>
|
|
||||||
{
|
{
|
||||||
|
typedef uint8_t codepoint_t;
|
||||||
|
|
||||||
static inline const uint8_t *
|
static inline const uint8_t *
|
||||||
next (const uint8_t *text,
|
next (const uint8_t *text,
|
||||||
const uint8_t *end,
|
const uint8_t *end,
|
||||||
@ -131,11 +128,10 @@ struct hb_utf_t<uint8_t, true>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* UTF-16 */
|
struct hb_utf16_t
|
||||||
|
|
||||||
template <>
|
|
||||||
struct hb_utf_t<uint16_t, true>
|
|
||||||
{
|
{
|
||||||
|
typedef uint16_t codepoint_t;
|
||||||
|
|
||||||
static inline const uint16_t *
|
static inline const uint16_t *
|
||||||
next (const uint16_t *text,
|
next (const uint16_t *text,
|
||||||
const uint16_t *end,
|
const uint16_t *end,
|
||||||
@ -204,11 +200,11 @@ struct hb_utf_t<uint16_t, true>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* UTF-32 */
|
template <bool validate=true>
|
||||||
|
struct hb_utf32_t
|
||||||
template <bool validate>
|
|
||||||
struct hb_utf_t<uint32_t, validate>
|
|
||||||
{
|
{
|
||||||
|
typedef uint32_t codepoint_t;
|
||||||
|
|
||||||
static inline const uint32_t *
|
static inline const uint32_t *
|
||||||
next (const uint32_t *text,
|
next (const uint32_t *text,
|
||||||
const uint32_t *end HB_UNUSED,
|
const uint32_t *end HB_UNUSED,
|
||||||
@ -246,4 +242,37 @@ struct hb_utf_t<uint32_t, validate>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct hb_latin1_t
|
||||||
|
{
|
||||||
|
typedef uint8_t codepoint_t;
|
||||||
|
|
||||||
|
static inline const uint8_t *
|
||||||
|
next (const uint8_t *text,
|
||||||
|
const uint8_t *end HB_UNUSED,
|
||||||
|
hb_codepoint_t *unicode,
|
||||||
|
hb_codepoint_t replacement HB_UNUSED)
|
||||||
|
{
|
||||||
|
*unicode = *text++;
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const uint8_t *
|
||||||
|
prev (const uint8_t *text,
|
||||||
|
const uint8_t *start HB_UNUSED,
|
||||||
|
hb_codepoint_t *unicode,
|
||||||
|
hb_codepoint_t replacement)
|
||||||
|
{
|
||||||
|
*unicode = *--text;
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
strlen (const uint8_t *text)
|
||||||
|
{
|
||||||
|
unsigned int l = 0;
|
||||||
|
while (*text++) l++;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* HB_UTF_PRIVATE_HH */
|
#endif /* HB_UTF_PRIVATE_HH */
|
||||||
|
@ -38,9 +38,9 @@ HB_BEGIN_DECLS
|
|||||||
|
|
||||||
#define HB_VERSION_MAJOR 0
|
#define HB_VERSION_MAJOR 0
|
||||||
#define HB_VERSION_MINOR 9
|
#define HB_VERSION_MINOR 9
|
||||||
#define HB_VERSION_MICRO 37
|
#define HB_VERSION_MICRO 40
|
||||||
|
|
||||||
#define HB_VERSION_STRING "0.9.37"
|
#define HB_VERSION_STRING "0.9.40"
|
||||||
|
|
||||||
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
||||||
((major)*10000+(minor)*100+(micro) <= \
|
((major)*10000+(minor)*100+(micro) <= \
|
||||||
|
@ -30,26 +30,20 @@
|
|||||||
|
|
||||||
#if defined(HB_ATOMIC_INT_NIL)
|
#if defined(HB_ATOMIC_INT_NIL)
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe")
|
#pragma error("Could not find any system to define atomic_int macros, library WILL NOT be thread-safe")
|
||||||
|
#pragma error("Check hb-atomic-private.hh for possible resolutions.")
|
||||||
#else
|
#else
|
||||||
#warning "Could not find any system to define atomic_int macros, library may NOT be thread-safe"
|
#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
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HB_MUTEX_IMPL_NIL)
|
#if defined(HB_MUTEX_IMPL_NIL)
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe")
|
#pragma error("Could not find any system to define mutex macros, library WILL NOT be thread-safe")
|
||||||
|
#pragma error("Check hb-mutex-private.hh for possible resolutions.")
|
||||||
#else
|
#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
|
||||||
#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
|
|
||||||
|
|
||||||
|
|
||||||
|
52
gfx/harfbuzz/src/sample.py
Executable file
52
gfx/harfbuzz/src/sample.py
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
import sys
|
||||||
|
from gi.repository import HarfBuzz as hb
|
||||||
|
from gi.repository import GLib
|
||||||
|
|
||||||
|
# Python 2/3 compatibility
|
||||||
|
try:
|
||||||
|
unicode
|
||||||
|
except NameError:
|
||||||
|
unicode = str
|
||||||
|
|
||||||
|
def tounicode(s, encoding='utf-8'):
|
||||||
|
if not isinstance(s, unicode):
|
||||||
|
return s.decode(encoding)
|
||||||
|
else:
|
||||||
|
return s
|
||||||
|
|
||||||
|
fontdata = open (sys.argv[1], 'rb').read ()
|
||||||
|
text = tounicode(sys.argv[2])
|
||||||
|
# Need to create GLib.Bytes explicitly until this bug is fixed:
|
||||||
|
# https://bugzilla.gnome.org/show_bug.cgi?id=729541
|
||||||
|
blob = hb.glib_blob_create (GLib.Bytes.new (fontdata))
|
||||||
|
face = hb.face_create (blob, 0)
|
||||||
|
del blob
|
||||||
|
font = hb.font_create (face)
|
||||||
|
upem = hb.face_get_upem (face)
|
||||||
|
del face
|
||||||
|
hb.font_set_scale (font, upem, upem)
|
||||||
|
#hb.ft_font_set_funcs (font)
|
||||||
|
hb.ot_font_set_funcs (font)
|
||||||
|
|
||||||
|
buf = hb.buffer_create ()
|
||||||
|
hb.buffer_add_utf8 (buf, text.encode('utf-8'), 0, -1)
|
||||||
|
hb.buffer_guess_segment_properties (buf)
|
||||||
|
|
||||||
|
hb.shape (font, buf, [])
|
||||||
|
del font
|
||||||
|
|
||||||
|
infos = hb.buffer_get_glyph_infos (buf)
|
||||||
|
positions = hb.buffer_get_glyph_positions (buf)
|
||||||
|
|
||||||
|
for info,pos in zip(infos, positions):
|
||||||
|
gid = info.codepoint
|
||||||
|
cluster = info.cluster
|
||||||
|
x_advance = pos.x_advance
|
||||||
|
x_offset = pos.x_offset
|
||||||
|
y_offset = pos.y_offset
|
||||||
|
|
||||||
|
print("gid%d=%d@%d,%d+%d" % (gid, cluster, x_advance, x_offset, y_offset))
|
Loading…
Reference in New Issue
Block a user