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
|
||||
git://anongit.freedesktop.org/git/harfbuzz.
|
||||
This directory contains the harfbuzz source from the 'master' branch of
|
||||
https://github.com/behdad/harfbuzz.
|
||||
|
||||
UPDATING:
|
||||
|
||||
Note that hb-ot-shape-complex-indic-machine.hh and gfx/harfbuzz/src/hb-version.h
|
||||
are not present in the upstream Git repository. These are created at build time
|
||||
by the harfbuzz build system; but as we don't use that build system in mozilla,
|
||||
it is necessary to refresh these files when updating harfbuzz, and check them in
|
||||
to the mozilla tree. (This avoids adding the ragel processor to mozilla's build
|
||||
prerequisites.)
|
||||
Note that gfx/harfbuzz/src/hb-version.h is not present in the upstream Git
|
||||
repository. It is created at build time by the harfbuzz build system;
|
||||
but as we don't use that build system in mozilla, it is necessary to refresh
|
||||
this files when updating harfbuzz, and check them into the mozilla tree.
|
||||
|
||||
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
|
||||
@ -19,5 +17,4 @@ the mozilla tree.
|
||||
|
||||
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-
|
||||
specific makefile that is maintained by hand. It should only need updating when
|
||||
new source files or exported headers are added in harfbuzz.
|
||||
specific makefile that is maintained by hand.
|
||||
|
@ -13,6 +13,9 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
|
||||
# The following warning options are useful for debugging: -Wpadded
|
||||
#AM_CXXFLAGS =
|
||||
|
||||
# Convenience targets:
|
||||
lib: libharfbuzz.la
|
||||
|
||||
lib_LTLIBRARIES = libharfbuzz.la
|
||||
|
||||
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
|
||||
if ! test -f "$so"; then continue; fi
|
||||
|
||||
echo "Checking that we are not linking to libstdc++"
|
||||
if ldd $so | grep 'libstdc[+][+]'; then
|
||||
echo "Ouch, linked to libstdc++"
|
||||
echo "Checking that we are not linking to libstdc++ or libc++"
|
||||
if ldd $so | grep 'libstdc[+][+]\|libc[+][+]'; then
|
||||
echo "Ouch, linked to libstdc++ or libc++"
|
||||
stat=1
|
||||
fi
|
||||
tested=true
|
||||
|
@ -209,7 +209,7 @@ for p in sorted(pages):
|
||||
for (start,end) in zip (starts, ends):
|
||||
if p not in [start>>page_bits, end>>page_bits]: continue
|
||||
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 ():
|
||||
if p != u>>page_bits: continue
|
||||
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 */
|
||||
|
||||
#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__))
|
||||
@ -58,11 +62,12 @@ static inline void _HBMemoryBarrier (void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef LONG hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
||||
typedef LONG hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) (_HBMemoryBarrier (), (void *) *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
||||
#define hb_atomic_ptr_impl_get(P) (_HBMemoryBarrier (), (void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(__APPLE__)
|
||||
@ -74,28 +79,31 @@ typedef LONG hb_atomic_int_t;
|
||||
#include <Availability.h>
|
||||
#endif
|
||||
|
||||
typedef int32_t hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) (OSMemoryBarrier (), (void *) *(P))
|
||||
typedef int32_t hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) (OSMemoryBarrier (), (void *) *(P))
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
||||
#else
|
||||
#if __ppc64__ || __x86_64__ || __aarch64__
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
|
||||
#else
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
|
||||
typedef int hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) __sync_fetch_and_add (&(AI), (V))
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) (void *) (__sync_synchronize (), *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
|
||||
#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
|
||||
@ -103,33 +111,54 @@ typedef int hb_atomic_int_t;
|
||||
#include <atomic.h>
|
||||
#include <mbarrier.h>
|
||||
|
||||
typedef unsigned int hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
|
||||
typedef unsigned int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
|
||||
#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT)
|
||||
|
||||
#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
|
||||
typedef volatile int hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_get(P) ((void *) *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
|
||||
typedef volatile int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) ((void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void * volatile *) (P) == (void *) (O) ? (* (void * volatile *) (P) = (void *) (N), true) : false)
|
||||
|
||||
|
||||
#else /* HB_NO_MT */
|
||||
|
||||
typedef int hb_atomic_int_t;
|
||||
#define hb_atomic_int_add(AI, V) (((AI) += (V)) - (V))
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
|
||||
#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) ((void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
|
||||
|
||||
#define hb_atomic_ptr_get(P) ((void *) *(P))
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
|
||||
|
||||
#endif
|
||||
|
||||
/* TODO Add tracing. */
|
||||
|
||||
#define HB_ATOMIC_INT_INIT(V) {HB_ATOMIC_INT_IMPL_INIT(V)}
|
||||
|
||||
struct hb_atomic_int_t
|
||||
{
|
||||
hb_atomic_int_impl_t v;
|
||||
|
||||
inline void set_unsafe (int v_) { v = v_; }
|
||||
inline int get_unsafe (void) const { return v; }
|
||||
inline int inc (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), 1); }
|
||||
inline int dec (void) { return hb_atomic_int_impl_add (const_cast<hb_atomic_int_impl_t &> (v), -1); }
|
||||
};
|
||||
|
||||
|
||||
#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P)
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N))
|
||||
|
||||
|
||||
#endif /* HB_ATOMIC_PRIVATE_HH */
|
||||
|
@ -78,8 +78,8 @@ _hb_blob_destroy_user_data (hb_blob_t *blob)
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_blob_create: (Xconstructor)
|
||||
* @data: (array length=length) (closure user_data) (destroy destroy) (scope notified) (transfer none): Pointer to blob data.
|
||||
* hb_blob_create: (skip)
|
||||
* @data: Pointer to blob data.
|
||||
* @length: Length of @data in bytes.
|
||||
* @mode: Memory mode for @data.
|
||||
* @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.
|
||||
*
|
||||
@ -32,7 +32,7 @@
|
||||
#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[] = {
|
||||
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,
|
||||
@ -435,7 +435,7 @@ static const int deserialize_json_error = 0;
|
||||
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
|
||||
@ -459,15 +459,15 @@ _hb_buffer_deserialize_glyphs_json (hb_buffer_t *buffer,
|
||||
|
||||
const char *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info;
|
||||
hb_glyph_position_t pos;
|
||||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
|
||||
#line 466 "hb-buffer-deserialize-json.hh.tmp"
|
||||
#line 466 "hb-buffer-deserialize-json.hh"
|
||||
{
|
||||
cs = deserialize_json_start;
|
||||
}
|
||||
|
||||
#line 471 "hb-buffer-deserialize-json.hh.tmp"
|
||||
#line 471 "hb-buffer-deserialize-json.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
@ -493,14 +493,14 @@ _resume:
|
||||
|
||||
switch ( _deserialize_json_trans_actions[_trans] ) {
|
||||
case 1:
|
||||
#line 38 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 38 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
memset (&info, 0, sizeof (info));
|
||||
memset (&pos , 0, sizeof (pos ));
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -510,13 +510,13 @@ _resume:
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
#line 51 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 51 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 14:
|
||||
#line 55 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 55 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
@ -525,33 +525,33 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -561,9 +561,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -573,9 +573,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -585,9 +585,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -597,9 +597,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -609,9 +609,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 43 "hb-buffer-deserialize-json.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -620,7 +620,7 @@ _resume:
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 624 "hb-buffer-deserialize-json.hh.tmp"
|
||||
#line 624 "hb-buffer-deserialize-json.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
@ -632,7 +632,7 @@ _again:
|
||||
_out: {}
|
||||
}
|
||||
|
||||
#line 125 "../../src/hb-buffer-deserialize-json.rl"
|
||||
#line 125 "hb-buffer-deserialize-json.rl"
|
||||
|
||||
|
||||
*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.
|
||||
*
|
||||
@ -32,7 +32,7 @@
|
||||
#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[] = {
|
||||
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,
|
||||
@ -312,7 +312,7 @@ static const int deserialize_text_error = 0;
|
||||
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
|
||||
@ -336,15 +336,15 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
|
||||
|
||||
const char *eof = pe, *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info;
|
||||
hb_glyph_position_t pos;
|
||||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
|
||||
#line 343 "hb-buffer-deserialize-text.hh.tmp"
|
||||
#line 343 "hb-buffer-deserialize-text.hh"
|
||||
{
|
||||
cs = deserialize_text_start;
|
||||
}
|
||||
|
||||
#line 348 "hb-buffer-deserialize-text.hh.tmp"
|
||||
#line 348 "hb-buffer-deserialize-text.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
@ -370,13 +370,13 @@ _resume:
|
||||
|
||||
switch ( _deserialize_text_trans_actions[_trans] ) {
|
||||
case 2:
|
||||
#line 51 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 51 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 55 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
@ -385,41 +385,41 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
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; }
|
||||
break;
|
||||
case 1:
|
||||
#line 38 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 38 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
memset (&info, 0, sizeof (info));
|
||||
memset (&pos , 0, sizeof (pos ));
|
||||
}
|
||||
#line 51 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 51 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
tok = p;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
#line 55 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -429,9 +429,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -441,9 +441,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -453,9 +453,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -465,9 +465,9 @@ _resume:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -476,7 +476,7 @@ _resume:
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 480 "hb-buffer-deserialize-text.hh.tmp"
|
||||
#line 480 "hb-buffer-deserialize-text.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
@ -489,14 +489,14 @@ _again:
|
||||
{
|
||||
switch ( _deserialize_text_eof_actions[cs] ) {
|
||||
case 4:
|
||||
#line 55 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 55 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
if (!hb_font_glyph_from_string (font,
|
||||
tok, p - tok,
|
||||
&info.codepoint))
|
||||
return false;
|
||||
}
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -506,9 +506,9 @@ _again:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -518,9 +518,9 @@ _again:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -530,9 +530,9 @@ _again:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -542,9 +542,9 @@ _again:
|
||||
}
|
||||
break;
|
||||
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; }
|
||||
#line 43 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 43 "hb-buffer-deserialize-text.rl"
|
||||
{
|
||||
buffer->add_info (info);
|
||||
if (buffer->in_error)
|
||||
@ -553,14 +553,14 @@ _again:
|
||||
*end_ptr = p;
|
||||
}
|
||||
break;
|
||||
#line 557 "hb-buffer-deserialize-text.hh.tmp"
|
||||
#line 557 "hb-buffer-deserialize-text.hh"
|
||||
}
|
||||
}
|
||||
|
||||
_out: {}
|
||||
}
|
||||
|
||||
#line 119 "../../src/hb-buffer-deserialize-text.rl"
|
||||
#line 119 "hb-buffer-deserialize-text.rl"
|
||||
|
||||
|
||||
*end_ptr = p;
|
||||
|
@ -111,8 +111,8 @@ _hb_buffer_deserialize_glyphs_text (hb_buffer_t *buffer,
|
||||
|
||||
const char *eof = pe, *tok = NULL;
|
||||
int cs;
|
||||
hb_glyph_info_t info;
|
||||
hb_glyph_position_t pos;
|
||||
hb_glyph_info_t info = {0};
|
||||
hb_glyph_position_t pos = {0};
|
||||
%%{
|
||||
write init;
|
||||
write exec;
|
||||
|
@ -443,7 +443,7 @@ hb_buffer_t::reverse_range (unsigned int start,
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
if (start == end - 1)
|
||||
if (end - start < 2)
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (pos) {
|
||||
if (have_positions) {
|
||||
for (i = start, j = end - 1; i < j; i++, j--) {
|
||||
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
|
||||
**/
|
||||
@ -999,7 +999,7 @@ hb_buffer_set_segment_properties (hb_buffer_t *buffer,
|
||||
/**
|
||||
* hb_buffer_get_segment_properties:
|
||||
* @buffer: a buffer.
|
||||
* @props:
|
||||
* @props: (out):
|
||||
*
|
||||
*
|
||||
*
|
||||
@ -1328,15 +1328,15 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer)
|
||||
buffer->guess_segment_properties ();
|
||||
}
|
||||
|
||||
template <bool validate, typename T>
|
||||
template <typename utf_t>
|
||||
static inline void
|
||||
hb_buffer_add_utf (hb_buffer_t *buffer,
|
||||
const T *text,
|
||||
const typename utf_t::codepoint_t *text,
|
||||
int text_length,
|
||||
unsigned int item_offset,
|
||||
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;
|
||||
|
||||
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:
|
||||
* @buffer: a buffer.
|
||||
* @text: (array length=text_length):
|
||||
* @text: (array length=text_length) (element-type uint8_t):
|
||||
* @text_length:
|
||||
* @item_offset:
|
||||
* @item_length:
|
||||
@ -1416,7 +1416,7 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer,
|
||||
unsigned int item_offset,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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. */
|
||||
void
|
||||
hb_buffer_add_codepoints (hb_buffer_t *buffer,
|
||||
|
@ -57,7 +57,7 @@ _hb_options_init (void)
|
||||
|
||||
/**
|
||||
* hb_tag_from_string:
|
||||
* @str: (array length=len):
|
||||
* @str: (array length=len) (element-type uint8_t):
|
||||
* @len:
|
||||
*
|
||||
*
|
||||
@ -115,7 +115,7 @@ const char direction_strings[][4] = {
|
||||
|
||||
/**
|
||||
* hb_direction_from_string:
|
||||
* @str: (array length=len):
|
||||
* @str: (array length=len) (element-type uint8_t):
|
||||
* @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
|
||||
};
|
||||
|
||||
static hb_bool_t
|
||||
static bool
|
||||
lang_equal (hb_language_t v1,
|
||||
const void *v2)
|
||||
{
|
||||
@ -235,7 +235,7 @@ struct hb_language_item_t {
|
||||
static hb_language_item_t *langs;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static inline
|
||||
static
|
||||
void free_langs (void)
|
||||
{
|
||||
while (langs) {
|
||||
@ -265,6 +265,7 @@ retry:
|
||||
*lang = key;
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
|
||||
lang->finish ();
|
||||
free (lang);
|
||||
goto retry;
|
||||
}
|
||||
@ -280,12 +281,12 @@ retry:
|
||||
|
||||
/**
|
||||
* hb_language_from_string:
|
||||
* @str: (array length=len):
|
||||
* @str: (array length=len) (element-type uint8_t):
|
||||
* @len:
|
||||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
* Return value: (transfer none):
|
||||
*
|
||||
* 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);
|
||||
if (unlikely (language == HB_LANGUAGE_INVALID)) {
|
||||
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;
|
||||
@ -400,7 +401,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag)
|
||||
|
||||
/**
|
||||
* hb_script_from_string:
|
||||
* @s: (array length=len):
|
||||
* @s: (array length=len) (element-type uint8_t):
|
||||
* @len:
|
||||
*
|
||||
*
|
||||
|
@ -140,6 +140,7 @@ hb_coretext_face_get_cg_font (hb_face_t *face)
|
||||
|
||||
struct hb_coretext_shaper_font_data_t {
|
||||
CTFontRef ct_font;
|
||||
CGFloat x_mult, y_mult; /* From CT space to HB space. */
|
||||
};
|
||||
|
||||
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_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)) {
|
||||
DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
|
||||
free (data);
|
||||
@ -776,6 +787,18 @@ retry:
|
||||
|
||||
buffer->len = 0;
|
||||
uint32_t status_and = ~0, status_or = 0;
|
||||
double advances_so_far = 0;
|
||||
/* For right-to-left runs, CoreText returns the glyphs positioned such that
|
||||
* any trailing whitespace is to the left of (0,0). Adjust coordinate system
|
||||
* to fix for that. Test with any RTL string with trailing spaces.
|
||||
* https://code.google.com/p/chromium/issues/detail?id=469028
|
||||
*/
|
||||
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
|
||||
{
|
||||
advances_so_far -= CTLineGetTrailingWhitespaceWidth (line);
|
||||
if (HB_DIRECTION_IS_VERTICAL (buffer->props.direction))
|
||||
advances_so_far = -advances_so_far;
|
||||
}
|
||||
|
||||
const CFRange range_all = CFRangeMake (0, 0);
|
||||
|
||||
@ -786,6 +809,10 @@ retry:
|
||||
status_or |= run_status;
|
||||
status_and &= 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
|
||||
* not supported by the requested font, and provides no way to turn it off,
|
||||
@ -860,8 +887,14 @@ retry:
|
||||
goto resize_and_retry;
|
||||
hb_glyph_info_t *info = buffer->info + buffer->len;
|
||||
|
||||
CGGlyph notdef = 0;
|
||||
double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, ¬def, NULL, 1);
|
||||
hb_codepoint_t notdef = 0;
|
||||
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;
|
||||
for (CFIndex j = range.location; j < range.location + range.length; j++)
|
||||
@ -875,19 +908,22 @@ retry:
|
||||
* for this one. */
|
||||
continue;
|
||||
}
|
||||
if (buffer->unicode->is_default_ignorable (ch))
|
||||
continue;
|
||||
|
||||
info->codepoint = notdef;
|
||||
info->cluster = log_clusters[j];
|
||||
|
||||
info->mask = advance;
|
||||
info->var1.u32 = 0;
|
||||
info->var2.u32 = 0;
|
||||
info->var1.u32 = x_offset;
|
||||
info->var2.u32 = y_offset;
|
||||
|
||||
info++;
|
||||
buffer->len++;
|
||||
}
|
||||
if (HB_DIRECTION_IS_BACKWARD (buffer->props.direction))
|
||||
buffer->reverse_range (old_len, buffer->len);
|
||||
advances_so_far += run_advance;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -917,7 +953,7 @@ retry:
|
||||
scratch_size = scratch_size_saved; \
|
||||
scratch = scratch_saved;
|
||||
|
||||
{
|
||||
{ /* Setup glyphs */
|
||||
SCRATCH_SAVE();
|
||||
const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : NULL;
|
||||
if (!glyphs) {
|
||||
@ -941,6 +977,11 @@ retry:
|
||||
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();
|
||||
const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : NULL;
|
||||
if (!positions) {
|
||||
@ -948,33 +989,42 @@ retry:
|
||||
CTRunGetPositions (run, range_all, 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;
|
||||
CGFloat x_mult = font_data->x_mult, y_mult = font_data->y_mult;
|
||||
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++)
|
||||
{
|
||||
double advance = (j + 1 < num_glyphs ? positions[j + 1].x : positions[0].x + run_advance) - positions[j].x;
|
||||
info->mask = advance;
|
||||
info->var1.u32 = positions[0].x; /* Yes, zero. */
|
||||
info->var2.u32 = positions[j].y;
|
||||
double advance;
|
||||
if (likely (j + 1 < num_glyphs))
|
||||
advance = positions[j + 1].x - positions[j].x;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
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++)
|
||||
{
|
||||
double advance = (j + 1 < num_glyphs ? positions[j + 1].y : positions[0].y + run_advance) - positions[j].y;
|
||||
info->mask = advance;
|
||||
info->var1.u32 = positions[j].x;
|
||||
info->var2.u32 = positions[0].y; /* Yes, zero. */
|
||||
double advance;
|
||||
if (likely (j + 1 < num_glyphs))
|
||||
advance = positions[j + 1].y - positions[j].y;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
SCRATCH_RESTORE();
|
||||
advances_so_far += run_advance;
|
||||
}
|
||||
#undef SCRATCH_RESTORE
|
||||
#undef SCRATCH_SAVE
|
||||
|
@ -165,8 +165,8 @@ hb_face_create (hb_blob_t *blob,
|
||||
{
|
||||
hb_face_t *face;
|
||||
|
||||
if (unlikely (!blob || !hb_blob_get_length (blob)))
|
||||
return hb_face_get_empty ();
|
||||
if (unlikely (!blob))
|
||||
blob = hb_blob_get_empty ();
|
||||
|
||||
hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
|
||||
|
||||
|
@ -814,7 +814,7 @@ hb_font_glyph_to_string (hb_font_t *font,
|
||||
/**
|
||||
* hb_font_glyph_from_string:
|
||||
* @font: a font.
|
||||
* @s: (array length=len):
|
||||
* @s: (array length=len) (element-type uint8_t):
|
||||
* @len:
|
||||
* @glyph: (out):
|
||||
*
|
||||
@ -854,8 +854,6 @@ hb_font_create (hb_face_t *face)
|
||||
|
||||
if (unlikely (!face))
|
||||
face = hb_face_get_empty ();
|
||||
if (unlikely (hb_object_is_inert (face)))
|
||||
return hb_font_get_empty ();
|
||||
if (!(font = hb_object_create<hb_font_t> ()))
|
||||
return hb_font_get_empty ();
|
||||
|
||||
@ -880,7 +878,7 @@ hb_font_t *
|
||||
hb_font_create_sub_font (hb_font_t *parent)
|
||||
{
|
||||
if (unlikely (!parent))
|
||||
return hb_font_get_empty ();
|
||||
parent = hb_font_get_empty ();
|
||||
|
||||
hb_font_t *font = hb_font_create (parent->face);
|
||||
|
||||
|
@ -51,6 +51,13 @@
|
||||
* In particular, FT_Get_Advance() without the NO_HINTING flag seems to be
|
||||
* 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.
|
||||
*
|
||||
* - 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;
|
||||
|
||||
#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
|
||||
if (unlikely (variation_selector)) {
|
||||
*glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
|
||||
return *glyph != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
*glyph = FT_Get_Char_Index (ft_face, unicode);
|
||||
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)))
|
||||
return 0;
|
||||
|
||||
if (font->x_scale < 0)
|
||||
v = -v;
|
||||
|
||||
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)))
|
||||
return 0;
|
||||
|
||||
if (font->y_scale < 0)
|
||||
v = -v;
|
||||
|
||||
/* Note: FreeType's vertical metrics grows downward while other FreeType coordinates
|
||||
* have a Y growing upward. Hence the extra negation. */
|
||||
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;
|
||||
*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;
|
||||
}
|
||||
|
||||
@ -340,11 +356,7 @@ hb_ft_face_create (FT_Face ft_face,
|
||||
|
||||
blob = hb_blob_create ((const char *) ft_face->stream->base,
|
||||
(unsigned int) ft_face->stream->size,
|
||||
/* TODO: We assume that it's mmap()'ed, but FreeType code
|
||||
* 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,
|
||||
HB_MEMORY_MODE_READONLY,
|
||||
ft_face, destroy);
|
||||
face = hb_face_create (blob, ft_face->face_index);
|
||||
hb_blob_destroy (blob);
|
||||
@ -358,6 +370,22 @@ hb_ft_face_create (FT_Face ft_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
|
||||
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,
|
||||
(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));
|
||||
#if 0 /* hb-ft works in no-hinting model */
|
||||
hb_font_set_ppem (font,
|
||||
ft_face->size->metrics.x_ppem,
|
||||
ft_face->size->metrics.y_ppem);
|
||||
#endif
|
||||
|
||||
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 */
|
||||
|
||||
static FT_Library ft_library;
|
||||
|
||||
static inline
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_ft_library (void)
|
||||
{
|
||||
FT_Done_FreeType (ft_library);
|
||||
}
|
||||
#endif
|
||||
|
||||
static FT_Library
|
||||
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);
|
||||
|
||||
assert (font->y_scale >= 0);
|
||||
FT_Set_Char_Size (ft_face,
|
||||
font->x_scale, font->y_scale,
|
||||
abs (font->x_scale), abs (font->y_scale),
|
||||
0, 0);
|
||||
#if 0
|
||||
font->x_ppem * 72 * 64 / font->x_scale,
|
||||
font->y_ppem * 72 * 64 / font->y_scale);
|
||||
#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.finalizer = (FT_Generic_Finalizer) _release_blob;
|
||||
|
@ -34,19 +34,76 @@
|
||||
|
||||
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_ft_face_create (FT_Face ft_face,
|
||||
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_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_ft_font_create (FT_Face ft_face,
|
||||
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. */
|
||||
|
@ -382,3 +382,14 @@ hb_glib_get_unicode_funcs (void)
|
||||
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_glib_get_unicode_funcs (void);
|
||||
|
||||
hb_blob_t *
|
||||
hb_glib_blob_create (GBytes *gbytes);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
|
@ -363,10 +363,8 @@ hb_icu_get_unicode_funcs (void)
|
||||
if (!hb_atomic_ptr_get (&normalizer)) {
|
||||
UErrorCode icu_err = U_ZERO_ERROR;
|
||||
/* 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
|
||||
return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,7 +39,13 @@
|
||||
|
||||
/* We need external help for these */
|
||||
|
||||
#if 0
|
||||
#if defined(HB_MUTEX_IMPL_INIT) \
|
||||
&& defined(hb_mutex_impl_init) \
|
||||
&& defined(hb_mutex_impl_lock) \
|
||||
&& defined(hb_mutex_impl_unlock) \
|
||||
&& defined(hb_mutex_impl_finish)
|
||||
|
||||
/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
@ -47,7 +53,11 @@
|
||||
#include <windows.h>
|
||||
typedef CRITICAL_SECTION hb_mutex_impl_t;
|
||||
#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)
|
||||
#endif
|
||||
#define hb_mutex_impl_lock(M) EnterCriticalSection (M)
|
||||
#define hb_mutex_impl_unlock(M) LeaveCriticalSection (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_finish(M) HB_STMT_START {} HB_STMT_END
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT}
|
||||
|
||||
struct hb_mutex_t
|
||||
{
|
||||
/* TODO Add tracing. */
|
||||
|
@ -47,19 +47,20 @@
|
||||
|
||||
/* reference_count */
|
||||
|
||||
#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1)
|
||||
#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE}
|
||||
#define HB_REFERENCE_COUNT_INVALID_VALUE -1
|
||||
#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INVALID_VALUE)}
|
||||
|
||||
struct hb_reference_count_t
|
||||
{
|
||||
hb_atomic_int_t ref_count;
|
||||
|
||||
inline void init (int v) { ref_count = v; }
|
||||
inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), 1); }
|
||||
inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), -1); }
|
||||
inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; }
|
||||
|
||||
inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; }
|
||||
inline void init (int v) { ref_count.set_unsafe (v); }
|
||||
inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
|
||||
inline int inc (void) { return ref_count.inc (); }
|
||||
inline int dec (void) { return ref_count.dec (); }
|
||||
inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_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_user_data_array_t user_data;
|
||||
|
||||
#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_INIT}
|
||||
#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INIT, HB_USER_DATA_ARRAY_INIT}
|
||||
|
||||
private:
|
||||
ASSERT_POD ();
|
||||
@ -117,7 +118,7 @@ static inline void hb_object_trace (const Type *obj, const char *function)
|
||||
DEBUG_MSG (OBJECT, (void *) obj,
|
||||
"%s refcount=%d",
|
||||
function,
|
||||
obj ? obj->header.ref_count.ref_count : 0);
|
||||
obj ? obj->header.ref_count.get_unsafe () : 0);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
|
@ -53,7 +53,8 @@ struct TTCHeader;
|
||||
|
||||
typedef struct TableRecord
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -102,7 +103,8 @@ typedef struct OffsetTable
|
||||
}
|
||||
|
||||
public:
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
|
||||
}
|
||||
@ -130,7 +132,8 @@ struct TTCHeaderVersion1
|
||||
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 bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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);
|
||||
if (unlikely (!u.header.version.sanitize (c))) return TRACE_RETURN (false);
|
||||
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);
|
||||
if (unlikely (!u.tag.sanitize (c))) return TRACE_RETURN (false);
|
||||
switch (u.tag) {
|
||||
|
@ -179,10 +179,13 @@ struct hb_sanitize_context_t
|
||||
inline const char *get_name (void) { return "SANITIZE"; }
|
||||
static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE;
|
||||
typedef bool return_t;
|
||||
template <typename T, typename F>
|
||||
inline bool may_dispatch (const T *obj, const F *format)
|
||||
{ return format->sanitize (this); }
|
||||
template <typename T>
|
||||
inline return_t dispatch (const T &obj) { return obj.sanitize (this); }
|
||||
static return_t default_return_value (void) { return true; }
|
||||
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)
|
||||
{
|
||||
@ -270,9 +273,9 @@ struct hb_sanitize_context_t
|
||||
}
|
||||
|
||||
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)) {
|
||||
obj->set (v);
|
||||
const_cast<Type *> (obj)->set (v);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -546,12 +549,6 @@ struct BEInt<Type, 2>
|
||||
return (v[0] << 8)
|
||||
+ (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];
|
||||
};
|
||||
template <typename Type>
|
||||
@ -570,13 +567,6 @@ struct BEInt<Type, 3>
|
||||
+ (v[1] << 8)
|
||||
+ (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];
|
||||
};
|
||||
template <typename Type>
|
||||
@ -597,14 +587,6 @@ struct BEInt<Type, 4>
|
||||
+ (v[2] << 8)
|
||||
+ (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];
|
||||
};
|
||||
|
||||
@ -614,12 +596,19 @@ struct IntType
|
||||
{
|
||||
inline void set (Type i) { v.set (i); }
|
||||
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 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 !(*this == o); }
|
||||
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 { Type b = v; return a < b ? -1 : a == b ? 0 : +1; }
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline int cmp (Type a) const
|
||||
{
|
||||
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);
|
||||
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. */
|
||||
struct LONGDATETIME
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (likely (c->check_struct (this)));
|
||||
}
|
||||
@ -670,7 +660,10 @@ struct Tag : ULONG
|
||||
DEFINE_NULL_DATA (Tag, " ");
|
||||
|
||||
/* 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 */
|
||||
struct Index : USHORT {
|
||||
@ -719,7 +712,8 @@ struct FixedVersion
|
||||
{
|
||||
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);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -747,33 +741,35 @@ struct OffsetTo : Offset<OffsetType>
|
||||
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> ();
|
||||
this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
|
||||
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);
|
||||
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
||||
unsigned int offset = *this;
|
||||
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));
|
||||
}
|
||||
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);
|
||||
if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false);
|
||||
unsigned int offset = *this;
|
||||
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));
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
DEFINE_SIZE_STATIC (sizeof(OffsetType));
|
||||
@ -838,7 +834,8 @@ struct ArrayOf
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||
|
||||
@ -853,7 +850,8 @@ struct ArrayOf
|
||||
|
||||
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);
|
||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||
unsigned int count = len;
|
||||
@ -863,7 +861,8 @@ struct ArrayOf
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
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);
|
||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||
unsigned int count = len;
|
||||
@ -884,7 +883,8 @@ struct ArrayOf
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::static_size, len));
|
||||
}
|
||||
@ -910,12 +910,14 @@ struct OffsetListOf : OffsetArrayOf<Type>
|
||||
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);
|
||||
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this));
|
||||
}
|
||||
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);
|
||||
return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data));
|
||||
}
|
||||
@ -949,12 +951,14 @@ struct HeadlessArrayOf
|
||||
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)
|
||||
&& 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);
|
||||
if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false);
|
||||
|
||||
|
@ -51,7 +51,8 @@ struct CmapSubtableFormat0
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -125,7 +126,7 @@ struct CmapSubtableFormat4
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c)
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_struct (this)))
|
||||
@ -183,7 +184,8 @@ struct CmapSubtableLongGroup
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -210,7 +212,8 @@ struct CmapSubtableTrimmed
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && glyphIdArray.sanitize (c));
|
||||
}
|
||||
@ -242,7 +245,8 @@ struct CmapSubtableLongSegmented
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && groups.sanitize (c));
|
||||
}
|
||||
@ -288,7 +292,8 @@ struct UnicodeValueRange
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -309,7 +314,8 @@ struct UVSMapping
|
||||
return unicodeValue.cmp (codepoint);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -348,7 +354,8 @@ struct VariationSelectorRecord
|
||||
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);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
defaultUVS.sanitize (c, base) &&
|
||||
@ -373,7 +380,8 @@ struct CmapSubtableFormat14
|
||||
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);
|
||||
return TRACE_RETURN (c->check_struct (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);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
switch (u.format) {
|
||||
@ -461,7 +470,8 @@ struct EncodingRecord
|
||||
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);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
subtable.sanitize (c, base));
|
||||
@ -496,7 +506,8 @@ struct cmap
|
||||
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);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
likely (version == 0) &&
|
||||
|
@ -45,9 +45,9 @@ struct hb_ot_face_metrics_accelerator_t
|
||||
|
||||
inline void init (hb_face_t *face,
|
||||
hb_tag_t _hea_tag, hb_tag_t _mtx_tag,
|
||||
unsigned int default_advance)
|
||||
unsigned int default_advance_)
|
||||
{
|
||||
this->default_advance = default_advance;
|
||||
this->default_advance = default_advance_;
|
||||
this->num_metrics = face->get_num_glyphs ();
|
||||
|
||||
hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (face->reference_table (_hea_tag));
|
||||
@ -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, 1);
|
||||
if (!subtable) subtable = cmap->find_subtable (0, 0);
|
||||
if (!subtable) subtable = cmap->find_subtable (3, 0);
|
||||
/* Meh. */
|
||||
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
|
||||
|
||||
|
@ -45,13 +45,15 @@ struct 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;
|
||||
/* If no valid head table found, assume 1000, which matches typical Type1 usage. */
|
||||
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);
|
||||
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 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);
|
||||
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 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);
|
||||
/* We don't check for anything specific here. The users of the
|
||||
* struct do all the hard work... */
|
||||
|
@ -37,6 +37,12 @@
|
||||
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 MAX_NESTING_LEVEL 8
|
||||
#define MAX_CONTEXT_LENGTH 64
|
||||
@ -63,9 +69,10 @@ struct Record
|
||||
|
||||
struct sanitize_closure_t {
|
||||
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);
|
||||
const sanitize_closure_t closure = {tag, base};
|
||||
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
|
||||
{ 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);
|
||||
return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this));
|
||||
}
|
||||
@ -134,7 +142,8 @@ struct RangeRecord
|
||||
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);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -199,7 +208,8 @@ struct LangSys
|
||||
}
|
||||
|
||||
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);
|
||||
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 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);
|
||||
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 */
|
||||
struct FeatureParamsSize
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
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 */
|
||||
struct FeatureParamsStylisticSet
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* Right now minorVersion is at zero. Which means, any table supports
|
||||
* the uiNameID field. */
|
||||
@ -404,7 +417,8 @@ struct FeatureParamsStylisticSet
|
||||
/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
|
||||
struct FeatureParamsCharacterVariants
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
characters.sanitize (c));
|
||||
@ -444,7 +458,8 @@ struct FeatureParamsCharacterVariants
|
||||
|
||||
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);
|
||||
if (tag == HB_TAG ('s','i','z','e'))
|
||||
return TRACE_RETURN (u.size.sanitize (c));
|
||||
@ -486,7 +501,8 @@ struct Feature
|
||||
{ return this+featureParams; }
|
||||
|
||||
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);
|
||||
if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))
|
||||
return TRACE_RETURN (false);
|
||||
@ -561,6 +577,17 @@ struct Lookup
|
||||
{
|
||||
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; }
|
||||
|
||||
/* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
|
||||
@ -577,6 +604,20 @@ struct Lookup
|
||||
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,
|
||||
unsigned int lookup_type,
|
||||
uint32_t lookup_props,
|
||||
@ -595,18 +636,20 @@ struct Lookup
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
/* Real sanitize of the subtables is done by GSUB/GPOS/... */
|
||||
if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false);
|
||||
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
|
||||
{
|
||||
USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
|
||||
const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
|
||||
if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false);
|
||||
}
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
private:
|
||||
USHORT lookupType; /* Different enumerations for GSUB and GPOS */
|
||||
USHORT lookupFlag; /* Lookup qualifiers */
|
||||
ArrayOf<Offset<> >
|
||||
@ -651,7 +694,8 @@ struct CoverageFormat1
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (glyphArray.sanitize (c));
|
||||
}
|
||||
@ -737,7 +781,8 @@ struct CoverageFormat2
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
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);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
switch (u.format) {
|
||||
@ -938,12 +984,14 @@ struct ClassDefFormat1
|
||||
private:
|
||||
inline unsigned int get_class (hb_codepoint_t glyph_id) const
|
||||
{
|
||||
if (unlikely ((unsigned int) (glyph_id - startGlyph) < classValue.len))
|
||||
return classValue[glyph_id - startGlyph];
|
||||
unsigned int i = (unsigned int) (glyph_id - startGlyph);
|
||||
if (unlikely (i < classValue.len))
|
||||
return classValue[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
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
|
||||
{
|
||||
int i = rangeRecord.bsearch (glyph_id);
|
||||
if (i != -1)
|
||||
if (unlikely (i != -1))
|
||||
return rangeRecord[i].value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
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);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
switch (u.format) {
|
||||
@ -1148,7 +1198,8 @@ struct Device
|
||||
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);
|
||||
return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ()));
|
||||
}
|
||||
|
@ -71,7 +71,8 @@ struct AttachList
|
||||
return points.len;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -127,7 +129,8 @@ struct CaretValueFormat2
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
switch (u.format) {
|
||||
@ -219,7 +224,8 @@ struct LigGlyph
|
||||
return carets.len;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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
|
||||
{ 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);
|
||||
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);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
switch (u.format) {
|
||||
@ -364,7 +373,8 @@ struct GDEF
|
||||
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); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (version.sanitize (c) &&
|
||||
likely (version.major == 1) &&
|
||||
|
@ -146,7 +146,8 @@ struct ValueFormat : USHORT
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (format & xPlacement) values++;
|
||||
@ -177,12 +178,14 @@ struct ValueFormat : USHORT
|
||||
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);
|
||||
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);
|
||||
unsigned int len = get_len ();
|
||||
|
||||
@ -200,7 +203,8 @@ struct ValueFormat : USHORT
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
if (!has_device ()) return TRACE_RETURN (true);
|
||||
@ -225,7 +229,8 @@ struct AnchorFormat1
|
||||
*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);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -254,7 +259,8 @@ struct AnchorFormat2
|
||||
*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);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -282,7 +288,8 @@ struct AnchorFormat3
|
||||
*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);
|
||||
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);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
switch (u.format) {
|
||||
@ -349,7 +357,8 @@ struct AnchorMatrix
|
||||
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);
|
||||
if (!c->check_struct (this)) 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;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this));
|
||||
}
|
||||
@ -457,9 +468,12 @@ struct SinglePosFormat1
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values));
|
||||
return TRACE_RETURN (c->check_struct (this)
|
||||
&& coverage.sanitize (c, this)
|
||||
&& valueFormat.sanitize_value (c, this, values));
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -506,9 +520,12 @@ struct SinglePosFormat2
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount));
|
||||
return TRACE_RETURN (c->check_struct (this)
|
||||
&& coverage.sanitize (c, this)
|
||||
&& valueFormat.sanitize_values (c, this, values, valueCount));
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -531,6 +548,7 @@ struct SinglePos
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -602,12 +610,24 @@ struct PairSet
|
||||
unsigned int len2 = valueFormats[1].get_len ();
|
||||
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;
|
||||
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 */
|
||||
if (buffer->info[pos].codepoint == record->secondGlyph)
|
||||
int mid = (min + max) / 2;
|
||||
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,
|
||||
&record->values[0], buffer->cur_pos());
|
||||
@ -618,26 +638,26 @@ struct PairSet
|
||||
buffer->idx = pos;
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
record = &StructAtOffset<PairValueRecord> (record, record_size);
|
||||
}
|
||||
|
||||
return TRACE_RETURN (false);
|
||||
}
|
||||
|
||||
struct sanitize_closure_t {
|
||||
void *base;
|
||||
ValueFormat *valueFormats;
|
||||
const void *base;
|
||||
const ValueFormat *valueFormats;
|
||||
unsigned int len1; /* valueFormats[0].get_len() */
|
||||
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);
|
||||
if (!(c->check_struct (this)
|
||||
&& c->check_array (arrayZ, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false);
|
||||
|
||||
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)
|
||||
&& 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);
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
unsigned int len1 = valueFormat1.get_len ();
|
||||
@ -741,12 +761,11 @@ struct PairPosFormat2
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
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);
|
||||
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);
|
||||
|
||||
unsigned int len1 = valueFormat1.get_len ();
|
||||
@ -770,7 +789,8 @@ struct PairPosFormat2
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!(c->check_struct (this)
|
||||
&& coverage.sanitize (c, this)
|
||||
@ -823,6 +843,7 @@ struct PairPos
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -853,7 +864,8 @@ struct EntryExitRecord
|
||||
{
|
||||
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);
|
||||
return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
|
||||
}
|
||||
@ -892,12 +904,11 @@ struct CursivePosFormat1
|
||||
/* We don't handle mark glyphs here. */
|
||||
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)];
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -1040,7 +1044,8 @@ struct MarkBasePosFormat1
|
||||
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
|
||||
|
||||
/* now we search backwards for a non-mark glyph */
|
||||
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, 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);
|
||||
do {
|
||||
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));
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) &&
|
||||
markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount));
|
||||
@ -1089,21 +1095,13 @@ struct MarkBasePos
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -1144,7 +1142,8 @@ struct MarkLigPosFormat1
|
||||
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
|
||||
|
||||
/* now we search backwards for a non-mark glyph */
|
||||
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, 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);
|
||||
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));
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) &&
|
||||
markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount));
|
||||
@ -1210,21 +1210,13 @@ struct MarkLigPos
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -1260,7 +1252,8 @@ struct MarkMarkPosFormat1
|
||||
if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
|
||||
|
||||
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
|
||||
hb_apply_context_t::skipping_backward_iterator_t skippy_iter (c, 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);
|
||||
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));
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) &&
|
||||
mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this)
|
||||
@ -1329,21 +1323,13 @@ struct MarkMarkPos
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
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
|
||||
{
|
||||
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) {
|
||||
case Single: return TRACE_RETURN (u.single.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:
|
||||
union {
|
||||
struct {
|
||||
USHORT sub_format;
|
||||
} header;
|
||||
SinglePos single;
|
||||
PairPos pair;
|
||||
CursivePos cursive;
|
||||
@ -1436,48 +1404,37 @@ struct PosLookupSubTable
|
||||
ExtensionPos extension;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, header.sub_format);
|
||||
DEFINE_SIZE_UNION (2, sub_format);
|
||||
};
|
||||
|
||||
|
||||
struct PosLookup : Lookup
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
TRACE_COLLECT_GLYPHS (this);
|
||||
c->set_recurse_func (NULL);
|
||||
return TRACE_RETURN (dispatch (c));
|
||||
}
|
||||
|
||||
template <typename set_t>
|
||||
inline void add_coverage (set_t *glyphs) const
|
||||
{
|
||||
hb_get_coverage_context_t c;
|
||||
const Coverage *last = NULL;
|
||||
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));
|
||||
hb_add_coverage_context_t<set_t> c (glyphs);
|
||||
dispatch (&c);
|
||||
}
|
||||
|
||||
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>
|
||||
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 (i).dispatch (c, lookup_type);
|
||||
if (c->stop_sublookup_iteration (r))
|
||||
return TRACE_RETURN (r);
|
||||
}
|
||||
return TRACE_RETURN (c->default_return_value ());
|
||||
}
|
||||
{ return Lookup::dispatch<PosLookupSubTable> (c); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
|
||||
OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable);
|
||||
return TRACE_RETURN (list.sanitize (c, this, get_type ()));
|
||||
return TRACE_RETURN (dispatch (c));
|
||||
}
|
||||
};
|
||||
|
||||
@ -1523,10 +1470,11 @@ struct GPOS : GSUBGPOS
|
||||
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);
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
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));
|
||||
}
|
||||
public:
|
||||
@ -1621,8 +1569,8 @@ template <typename context_t>
|
||||
const PosLookup &l = gpos.get_lookup (lookup_index);
|
||||
unsigned int saved_lookup_props = c->lookup_props;
|
||||
c->set_lookup (l);
|
||||
bool ret = l.apply_once (c);
|
||||
c->lookup_props = saved_lookup_props;
|
||||
bool ret = l.dispatch (c);
|
||||
c->set_lookup_props (saved_lookup_props);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,8 @@ struct SingleSubstFormat1
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
|
||||
}
|
||||
@ -173,7 +174,8 @@ struct SingleSubstFormat2
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
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
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -312,7 +305,8 @@ struct Sequence
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (substitute.sanitize (c));
|
||||
}
|
||||
@ -384,7 +378,8 @@ struct MultipleSubstFormat1
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -535,7 +522,8 @@ struct AlternateSubstFormat1
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -686,7 +666,8 @@ struct Ligature
|
||||
}
|
||||
|
||||
public:
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (ligGlyph.sanitize (c) && component.sanitize (c));
|
||||
}
|
||||
@ -764,7 +745,8 @@ struct LigatureSet
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (ligature.sanitize (c, this));
|
||||
}
|
||||
@ -848,7 +830,8 @@ struct LigatureSubstFormat1
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (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
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -1017,14 +992,15 @@ struct ReverseChainSingleSubstFormat1
|
||||
return TRACE_RETURN (false);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this)))
|
||||
return TRACE_RETURN (false);
|
||||
OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
|
||||
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
|
||||
if (!lookahead.sanitize (c, this))
|
||||
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));
|
||||
}
|
||||
|
||||
@ -1054,21 +1030,13 @@ struct ReverseChainSingleSubst
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
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
|
||||
{
|
||||
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) {
|
||||
case Single: return TRACE_RETURN (u.single.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:
|
||||
union {
|
||||
struct {
|
||||
USHORT sub_format;
|
||||
} header;
|
||||
SingleSubst single;
|
||||
MultipleSubst multiple;
|
||||
AlternateSubst alternate;
|
||||
@ -1146,14 +1097,14 @@ struct SubstLookupSubTable
|
||||
ReverseChainSingleSubst reverseChainContextSingle;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, header.sub_format);
|
||||
DEFINE_SIZE_UNION (2, sub_format);
|
||||
};
|
||||
|
||||
|
||||
struct SubstLookup : Lookup
|
||||
{
|
||||
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)
|
||||
{ return lookup_type == SubstLookupSubTable::ReverseChainSingle; }
|
||||
@ -1166,6 +1117,12 @@ struct SubstLookup : Lookup
|
||||
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
|
||||
{
|
||||
TRACE_CLOSURE (this);
|
||||
@ -1183,31 +1140,16 @@ struct SubstLookup : Lookup
|
||||
template <typename set_t>
|
||||
inline void add_coverage (set_t *glyphs) const
|
||||
{
|
||||
hb_get_coverage_context_t c;
|
||||
const Coverage *last = NULL;
|
||||
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;
|
||||
}
|
||||
}
|
||||
hb_add_coverage_context_t<set_t> c (glyphs);
|
||||
dispatch (&c);
|
||||
}
|
||||
|
||||
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);
|
||||
if (unlikely (!c->len)) return TRACE_RETURN (false);
|
||||
if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false);
|
||||
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);
|
||||
if (!accel->may_have (c->glyphs[0])) return TRACE_RETURN (false);
|
||||
return TRACE_RETURN (dispatch (c));
|
||||
}
|
||||
|
||||
@ -1215,7 +1157,7 @@ struct SubstLookup : Lookup
|
||||
|
||||
inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
|
||||
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,
|
||||
uint32_t lookup_props,
|
||||
@ -1274,24 +1216,13 @@ struct SubstLookup : Lookup
|
||||
|
||||
template <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 (i).dispatch (c, lookup_type);
|
||||
if (c->stop_sublookup_iteration (r))
|
||||
return TRACE_RETURN (r);
|
||||
}
|
||||
return TRACE_RETURN (c->default_return_value ());
|
||||
}
|
||||
{ return Lookup::dispatch<SubstLookupSubTable> (c); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c)
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
|
||||
OffsetArrayOf<SubstLookupSubTable> &list = CastR<OffsetArrayOf<SubstLookupSubTable> > (subTable);
|
||||
if (unlikely (!list.sanitize (c, this, get_type ()))) return TRACE_RETURN (false);
|
||||
if (unlikely (!dispatch (c))) return TRACE_RETURN (false);
|
||||
|
||||
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_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);
|
||||
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));
|
||||
}
|
||||
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 ();
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1380,8 +1312,8 @@ template <typename context_t>
|
||||
const SubstLookup &l = gsub.get_lookup (lookup_index);
|
||||
unsigned int saved_lookup_props = c->lookup_props;
|
||||
c->set_lookup (l);
|
||||
bool ret = l.apply_once (c);
|
||||
c->lookup_props = saved_lookup_props;
|
||||
bool ret = l.dispatch (c);
|
||||
c->set_lookup_props (saved_lookup_props);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,6 @@
|
||||
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
|
||||
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
|
||||
#endif
|
||||
@ -58,6 +52,8 @@ struct hb_closure_context_t
|
||||
static const unsigned int max_debug_depth = HB_DEBUG_CLOSURE;
|
||||
typedef hb_void_t return_t;
|
||||
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
|
||||
template <typename T, typename F>
|
||||
inline bool may_dispatch (const T *obj, const F *format) { return true; }
|
||||
template <typename T>
|
||||
inline return_t dispatch (const T &obj) { obj.closure (this); return HB_VOID; }
|
||||
static return_t default_return_value (void) { return HB_VOID; }
|
||||
@ -107,6 +103,8 @@ struct hb_would_apply_context_t
|
||||
inline const char *get_name (void) { return "WOULD_APPLY"; }
|
||||
static const unsigned int max_debug_depth = HB_DEBUG_WOULD_APPLY;
|
||||
typedef bool return_t;
|
||||
template <typename T, typename F>
|
||||
inline bool may_dispatch (const T *obj, const F *format) { return true; }
|
||||
template <typename T>
|
||||
inline return_t dispatch (const T &obj) { return obj.would_apply (this); }
|
||||
static return_t default_return_value (void) { return false; }
|
||||
@ -146,6 +144,8 @@ struct hb_collect_glyphs_context_t
|
||||
static const unsigned int max_debug_depth = HB_DEBUG_COLLECT_GLYPHS;
|
||||
typedef hb_void_t return_t;
|
||||
typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
|
||||
template <typename T, typename F>
|
||||
inline bool may_dispatch (const T *obj, const F *format) { return true; }
|
||||
template <typename T>
|
||||
inline return_t dispatch (const T &obj) { obj.collect_glyphs (this); return HB_VOID; }
|
||||
static return_t default_return_value (void) { return HB_VOID; }
|
||||
@ -232,18 +232,28 @@ struct hb_collect_glyphs_context_t
|
||||
#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
|
||||
#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"; }
|
||||
static const unsigned int max_debug_depth = HB_DEBUG_GET_COVERAGE;
|
||||
typedef const Coverage &return_t;
|
||||
template <typename T, typename F>
|
||||
inline bool may_dispatch (const T *obj, const F *format) { return true; }
|
||||
template <typename T>
|
||||
inline return_t dispatch (const T &obj) { return obj.get_coverage (); }
|
||||
static return_t default_return_value (void) { return Null(Coverage); }
|
||||
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) {}
|
||||
|
||||
set_t *set;
|
||||
unsigned int debug_depth;
|
||||
};
|
||||
|
||||
@ -260,61 +270,6 @@ struct hb_get_coverage_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
|
||||
{
|
||||
inline matcher_t (void) :
|
||||
@ -390,29 +345,24 @@ struct hb_apply_context_t
|
||||
const void *match_data;
|
||||
};
|
||||
|
||||
struct skipping_forward_iterator_t
|
||||
struct skipping_iterator_t
|
||||
{
|
||||
inline skipping_forward_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_),
|
||||
end (c->buffer->len)
|
||||
inline void init (hb_apply_context_t *c_, bool context_match = false)
|
||||
{
|
||||
c = c_;
|
||||
match_glyph_data = NULL,
|
||||
matcher.set_match_func (NULL, NULL);
|
||||
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);
|
||||
matcher.set_mask (context_match ? -1 : c->lookup_mask);
|
||||
}
|
||||
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,
|
||||
const void *match_data,
|
||||
const USHORT glyph_data[])
|
||||
@ -421,12 +371,21 @@ struct hb_apply_context_t
|
||||
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 bool next (void)
|
||||
{
|
||||
assert (num_items > 0);
|
||||
while (!has_no_chance ())
|
||||
while (idx + num_items < end)
|
||||
{
|
||||
idx++;
|
||||
const hb_glyph_info_t &info = c->buffer->info[idx];
|
||||
@ -450,53 +409,10 @@ struct hb_apply_context_t
|
||||
}
|
||||
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)
|
||||
{
|
||||
assert (num_items > 0);
|
||||
while (!has_no_chance ())
|
||||
while (idx >= num_items)
|
||||
{
|
||||
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;
|
||||
|
||||
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
|
||||
match_properties_mark (hb_codepoint_t glyph,
|
||||
unsigned int glyph_props,
|
||||
unsigned int lookup_props) const
|
||||
unsigned int match_props) const
|
||||
{
|
||||
/* If using mark filtering sets, the high short of
|
||||
* lookup_props has the set index.
|
||||
* match_props has the set index.
|
||||
*/
|
||||
if (lookup_props & LookupFlag::UseMarkFilteringSet)
|
||||
return gdef.mark_set_covers (lookup_props >> 16, glyph);
|
||||
if (match_props & LookupFlag::UseMarkFilteringSet)
|
||||
return gdef.mark_set_covers (match_props >> 16, glyph);
|
||||
|
||||
/* The second byte of lookup_props has the meaning
|
||||
/* The second byte of match_props has the meaning
|
||||
* "ignore marks of attachment type different than
|
||||
* the attachment type specified."
|
||||
*/
|
||||
if (lookup_props & LookupFlag::MarkAttachmentType)
|
||||
return (lookup_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
|
||||
if (match_props & LookupFlag::MarkAttachmentType)
|
||||
return (match_props & LookupFlag::MarkAttachmentType) == (glyph_props & LookupFlag::MarkAttachmentType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
check_glyph_property (const hb_glyph_info_t *info,
|
||||
unsigned int lookup_props) const
|
||||
unsigned int match_props) const
|
||||
{
|
||||
hb_codepoint_t glyph = info->codepoint;
|
||||
unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
|
||||
|
||||
/* Not covered, if, for example, glyph class is ligature and
|
||||
* lookup_props includes LookupFlags::IgnoreLigatures
|
||||
* match_props includes LookupFlags::IgnoreLigatures
|
||||
*/
|
||||
if (glyph_props & lookup_props & LookupFlag::IgnoreFlags)
|
||||
if (glyph_props & match_props & LookupFlag::IgnoreFlags)
|
||||
return false;
|
||||
|
||||
if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
|
||||
return match_properties_mark (glyph, glyph_props, lookup_props);
|
||||
return match_properties_mark (glyph, glyph_props, match_props);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -741,9 +724,9 @@ static inline bool match_input (hb_apply_context_t *c,
|
||||
|
||||
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);
|
||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
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);
|
||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!skippy_iter.prev ())
|
||||
@ -930,9 +913,9 @@ static inline bool match_lookahead (hb_apply_context_t *c,
|
||||
{
|
||||
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);
|
||||
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!skippy_iter.next ())
|
||||
@ -945,7 +928,8 @@ static inline bool match_lookahead (hb_apply_context_t *c,
|
||||
|
||||
struct LookupRecord
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
}
|
||||
@ -1168,7 +1152,8 @@ struct Rule
|
||||
}
|
||||
|
||||
public:
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return inputCount.sanitize (c)
|
||||
&& lookupCount.sanitize (c)
|
||||
@ -1232,7 +1217,8 @@ struct RuleSet
|
||||
return TRACE_RETURN (false);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (rule.sanitize (c, this));
|
||||
}
|
||||
@ -1314,7 +1300,8 @@ struct ContextFormat1
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (coverage.sanitize (c, this) && classDef.sanitize (c, this) && ruleSet.sanitize (c, this));
|
||||
}
|
||||
@ -1494,7 +1482,8 @@ struct ContextFormat3
|
||||
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);
|
||||
if (!c->check_struct (this)) return TRACE_RETURN (false);
|
||||
unsigned int count = glyphCount;
|
||||
@ -1502,7 +1491,7 @@ struct ContextFormat3
|
||||
if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return TRACE_RETURN (false);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
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));
|
||||
}
|
||||
|
||||
@ -1526,6 +1515,7 @@ struct Context
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -1726,14 +1705,15 @@ struct ChainRule
|
||||
lookup.array, lookup_context));
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
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);
|
||||
ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
|
||||
const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
|
||||
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));
|
||||
}
|
||||
|
||||
@ -1795,7 +1775,8 @@ struct ChainRuleSet
|
||||
return TRACE_RETURN (false);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (rule.sanitize (c, this));
|
||||
}
|
||||
@ -1874,7 +1855,8 @@ struct ChainContextFormat1
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (coverage.sanitize (c, this) && backtrackClassDef.sanitize (c, this) &&
|
||||
inputClassDef.sanitize (c, this) && lookaheadClassDef.sanitize (c, this) &&
|
||||
@ -2105,15 +2088,16 @@ struct ChainContextFormat3
|
||||
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);
|
||||
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.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);
|
||||
ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
|
||||
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
|
||||
return TRACE_RETURN (lookup.sanitize (c));
|
||||
}
|
||||
|
||||
@ -2144,6 +2128,7 @@ struct ChainContext
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (c->dispatch (u.format1));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
@ -2173,14 +2147,32 @@ struct ChainContext
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct ExtensionFormat1
|
||||
{
|
||||
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);
|
||||
return TRACE_RETURN (c->check_struct (this));
|
||||
return TRACE_RETURN (c->check_struct (this) && extensionOffset != 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -2204,49 +2196,30 @@ struct Extension
|
||||
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>
|
||||
inline const X& get_subtable (void) const
|
||||
{
|
||||
unsigned int offset = get_offset ();
|
||||
if (unlikely (!offset)) return Null(typename T::LookupSubTable);
|
||||
return StructAtOffset<typename T::LookupSubTable> (this, offset);
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.template get_subtable<typename T::LookupSubTable> ();
|
||||
default:return Null(typename T::LookupSubTable);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename context_t>
|
||||
inline typename context_t::return_t dispatch (context_t *c) const
|
||||
{
|
||||
return get_subtable<typename T::LookupSubTable> ().dispatch (c, get_type ());
|
||||
}
|
||||
|
||||
inline bool sanitize_self (hb_sanitize_context_t *c) {
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) TRACE_RETURN (c->default_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return TRACE_RETURN (u.format1.sanitize (c));
|
||||
default:return TRACE_RETURN (true);
|
||||
case 1: return TRACE_RETURN (u.format1.dispatch (c));
|
||||
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:
|
||||
union {
|
||||
USHORT format; /* Format identifier */
|
||||
ExtensionFormat1 format1;
|
||||
ExtensionFormat1<T> format1;
|
||||
} u;
|
||||
};
|
||||
|
||||
@ -2291,7 +2264,8 @@ struct GSUBGPOS
|
||||
inline const Lookup& get_lookup (unsigned int i) const
|
||||
{ return (this+lookupList)[i]; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
|
||||
scriptList.sanitize (c, this) &&
|
||||
|
@ -54,7 +54,8 @@ typedef OffsetListOf<PosLookup> JstfMax;
|
||||
|
||||
struct JstfPriority
|
||||
{
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
shrinkageEnableGSUB.sanitize (c, this) &&
|
||||
@ -123,7 +124,8 @@ struct JstfPriority
|
||||
struct JstfLangSys : OffsetListOf<JstfPriority>
|
||||
{
|
||||
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);
|
||||
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 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);
|
||||
return TRACE_RETURN (extenderGlyphs.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
|
||||
{ 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);
|
||||
return TRACE_RETURN (version.sanitize (c) && likely (version.major == 1) &&
|
||||
scriptList.sanitize (c, this));
|
||||
|
@ -126,11 +126,15 @@ struct hb_ot_layout_lookup_accelerator_t
|
||||
lookup.add_coverage (&digest);
|
||||
}
|
||||
|
||||
template <typename TLookup>
|
||||
inline void fini (const TLookup &lookup HB_UNUSED)
|
||||
inline void fini (void)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool may_have (hb_codepoint_t g) const {
|
||||
return digest.may_have (g);
|
||||
}
|
||||
|
||||
private:
|
||||
hb_set_digest_t digest;
|
||||
};
|
||||
|
||||
|
@ -84,9 +84,9 @@ void
|
||||
_hb_ot_layout_destroy (hb_ot_layout_t *layout)
|
||||
{
|
||||
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++)
|
||||
layout->gpos_accels[i].fini (layout->gpos->get_lookup (i));
|
||||
layout->gpos_accels[i].fini ();
|
||||
|
||||
free (layout->gsub_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);
|
||||
|
||||
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
|
||||
@ -829,26 +829,83 @@ struct GPOSProxy
|
||||
};
|
||||
|
||||
|
||||
template <typename Lookup>
|
||||
static inline bool apply_once (OT::hb_apply_context_t *c,
|
||||
const Lookup &lookup)
|
||||
{
|
||||
if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props))
|
||||
return false;
|
||||
return lookup.dispatch (c);
|
||||
}
|
||||
|
||||
template <typename Proxy>
|
||||
template <typename Obj>
|
||||
static inline bool
|
||||
apply_string (OT::hb_apply_context_t *c,
|
||||
const typename Proxy::Lookup &lookup,
|
||||
apply_forward (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;
|
||||
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 Obj>
|
||||
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,
|
||||
const typename Proxy::Lookup &lookup,
|
||||
const hb_ot_layout_lookup_accelerator_t &accel)
|
||||
{
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
|
||||
if (unlikely (!buffer->len || !c->lookup_mask))
|
||||
return false;
|
||||
return;
|
||||
|
||||
c->set_lookup (lookup);
|
||||
|
||||
@ -859,15 +916,14 @@ apply_string (OT::hb_apply_context_t *c,
|
||||
buffer->clear_output ();
|
||||
buffer->idx = 0;
|
||||
|
||||
while (buffer->idx < buffer->len)
|
||||
bool ret;
|
||||
if (lookup.get_subtable_count () == 1)
|
||||
{
|
||||
if (accel.digest.may_have (buffer->cur().codepoint) &&
|
||||
(buffer->cur().mask & c->lookup_mask) &&
|
||||
apply_once (c, lookup))
|
||||
ret = true;
|
||||
else
|
||||
buffer->next_glyph ();
|
||||
hb_apply_forward_context_t c_forward (c, accel);
|
||||
ret = lookup.dispatch (&c_forward);
|
||||
}
|
||||
else
|
||||
ret = apply_forward (c, lookup, accel);
|
||||
if (ret)
|
||||
{
|
||||
if (!Proxy::inplace)
|
||||
@ -882,20 +938,9 @@ apply_string (OT::hb_apply_context_t *c,
|
||||
if (Proxy::table_index == 0)
|
||||
buffer->remove_output ();
|
||||
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>
|
||||
|
@ -43,11 +43,13 @@ struct 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;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
likely (version.major == 1 || (version.major == 0 && version.minor == 0x5000u)));
|
||||
|
@ -56,7 +56,8 @@ struct NameRecord
|
||||
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);
|
||||
/* 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));
|
||||
@ -101,7 +102,7 @@ struct name
|
||||
inline unsigned int get_size (void) const
|
||||
{ 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);
|
||||
char *string_pool = (char *) this + stringOffset;
|
||||
unsigned int _count = count;
|
||||
@ -110,7 +111,8 @@ struct name
|
||||
return TRACE_RETURN (true);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) {
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return TRACE_RETURN (c->check_struct (this) &&
|
||||
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++)
|
||||
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)
|
||||
free (fallback_plan->lookup_array[i]);
|
||||
}
|
||||
|
@ -133,7 +133,6 @@
|
||||
*/
|
||||
|
||||
#define OT_LOOKUP_TYPE_SUBST_SINGLE 1u
|
||||
#define OT_LOOKUP_TYPE_SUBST_MULTIPLE 2u
|
||||
#define OT_LOOKUP_TYPE_SUBST_LIGATURE 4u
|
||||
|
||||
#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)
|
||||
{
|
||||
case 0x0u:
|
||||
if (hb_in_range (u, 0x0028u, 0x0040u)) 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, 0x0900u, 0x0DF8u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
|
||||
if (hb_in_range (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
|
||||
if (hb_in_range (u, 0x00D0u, 0x00D7u)) return indic_table[u - 0x00D0u + indic_offset_0x00d0u];
|
||||
if (hb_in_range (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
|
||||
if (unlikely (u == 0x00A0u)) return _(CP,x);
|
||||
break;
|
||||
|
||||
case 0x1u:
|
||||
if (hb_in_range (u, 0x1000u, 0x10A0u)) 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, 0x1900u, 0x1AA0u)) 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, 0x1CD0u, 0x1CF8u)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
|
||||
if (hb_in_range (u, 0x1000u, 0x109Fu)) return indic_table[u - 0x1000u + indic_offset_0x1000u];
|
||||
if (hb_in_range (u, 0x1700u, 0x17EFu)) return indic_table[u - 0x1700u + indic_offset_0x1700u];
|
||||
if (hb_in_range (u, 0x1900u, 0x1A9Fu)) return indic_table[u - 0x1900u + indic_offset_0x1900u];
|
||||
if (hb_in_range (u, 0x1B00u, 0x1C4Fu)) return indic_table[u - 0x1B00u + indic_offset_0x1b00u];
|
||||
if (hb_in_range (u, 0x1CD0u, 0x1CF7u)) return indic_table[u - 0x1CD0u + indic_offset_0x1cd0u];
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
case 0xAu:
|
||||
if (hb_in_range (u, 0xA800u, 0xAAF8u)) 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, 0xA800u, 0xAAF7u)) return indic_table[u - 0xA800u + indic_offset_0xa800u];
|
||||
if (hb_in_range (u, 0xABC0u, 0xABFFu)) return indic_table[u - 0xABC0u + indic_offset_0xabc0u];
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case 0x11u:
|
||||
if (hb_in_range (u, 0x11000u, 0x110C0u)) 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, 0x112B0u, 0x11378u)) 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, 0x11580u, 0x115C8u)) 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, 0x11000u, 0x110BFu)) return indic_table[u - 0x11000u + indic_offset_0x11000u];
|
||||
if (hb_in_range (u, 0x11100u, 0x11237u)) return indic_table[u - 0x11100u + indic_offset_0x11100u];
|
||||
if (hb_in_range (u, 0x112B0u, 0x11377u)) return indic_table[u - 0x112B0u + indic_offset_0x112b0u];
|
||||
if (hb_in_range (u, 0x11480u, 0x114DFu)) return indic_table[u - 0x11480u + indic_offset_0x11480u];
|
||||
if (hb_in_range (u, 0x11580u, 0x115C7u)) return indic_table[u - 0x11580u + indic_offset_0x11580u];
|
||||
if (hb_in_range (u, 0x11600u, 0x116CFu)) return indic_table[u - 0x11600u + indic_offset_0x11600u];
|
||||
break;
|
||||
|
||||
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.
|
||||
*
|
||||
@ -32,7 +32,7 @@
|
||||
#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[] = {
|
||||
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,
|
||||
@ -261,11 +261,11 @@ static const int myanmar_syllable_machine_error = -1;
|
||||
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) \
|
||||
@ -285,7 +285,7 @@ find_syllables (hb_buffer_t *buffer)
|
||||
int cs;
|
||||
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;
|
||||
ts = 0;
|
||||
@ -293,7 +293,7 @@ find_syllables (hb_buffer_t *buffer)
|
||||
act = 0;
|
||||
}
|
||||
|
||||
#line 114 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
|
||||
#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
|
||||
|
||||
|
||||
p = 0;
|
||||
@ -302,7 +302,7 @@ find_syllables (hb_buffer_t *buffer)
|
||||
unsigned int last = 0;
|
||||
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 _trans;
|
||||
@ -316,7 +316,7 @@ _resume:
|
||||
#line 1 "NONE"
|
||||
{ts = p;}
|
||||
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);
|
||||
@ -335,38 +335,38 @@ _eof_trans:
|
||||
|
||||
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
#line 370 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
|
||||
#line 370 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
@ -375,7 +375,7 @@ _again:
|
||||
#line 1 "NONE"
|
||||
{ts = 0;}
|
||||
break;
|
||||
#line 379 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
|
||||
#line 379 "hb-ot-shape-complex-myanmar-machine.hh"
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
/* For Arabic script, use the Arabic shaper even if no OT script tag was found.
|
||||
* This is because we do fallback shaping for Arabic script (and not others). */
|
||||
if (planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
|
||||
planner->props.script == HB_SCRIPT_ARABIC)
|
||||
* This is because we do fallback shaping for Arabic script (and not others).
|
||||
* But note that Arabic shaping is applicable only to horizontal layout; for
|
||||
* vertical text, just use the generic shaper instead. */
|
||||
if ((planner->map.chosen_script[0] != HB_OT_TAG_DEFAULT_SCRIPT ||
|
||||
planner->props.script == HB_SCRIPT_ARABIC) &&
|
||||
HB_DIRECTION_IS_HORIZONTAL(planner->props.direction))
|
||||
return &_hb_ot_complex_shaper_arabic;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
@ -259,6 +262,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
||||
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_KHAROSHTHI:
|
||||
case HB_SCRIPT_NEW_TAI_LUE:
|
||||
case HB_SCRIPT_SYLOTI_NAGRI:
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
@ -339,7 +343,6 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
||||
|
||||
/* Unicode-4.1 additions */
|
||||
case HB_SCRIPT_BUGINESE:
|
||||
case HB_SCRIPT_NEW_TAI_LUE:
|
||||
|
||||
/* Unicode-5.1 additions */
|
||||
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.
|
||||
*
|
||||
@ -32,7 +32,7 @@
|
||||
#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[] = {
|
||||
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;
|
||||
|
||||
|
||||
#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) \
|
||||
@ -113,7 +113,7 @@ find_syllables (hb_buffer_t *buffer)
|
||||
int cs;
|
||||
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;
|
||||
ts = 0;
|
||||
@ -121,7 +121,7 @@ find_syllables (hb_buffer_t *buffer)
|
||||
act = 0;
|
||||
}
|
||||
|
||||
#line 88 "../../src/hb-ot-shape-complex-sea-machine.rl"
|
||||
#line 88 "hb-ot-shape-complex-sea-machine.rl"
|
||||
|
||||
|
||||
p = 0;
|
||||
@ -130,7 +130,7 @@ find_syllables (hb_buffer_t *buffer)
|
||||
unsigned int last = 0;
|
||||
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 _trans;
|
||||
@ -144,7 +144,7 @@ _resume:
|
||||
#line 1 "NONE"
|
||||
{ts = p;}
|
||||
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);
|
||||
@ -167,30 +167,30 @@ _eof_trans:
|
||||
{te = p+1;}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
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); }}
|
||||
break;
|
||||
#line 194 "hb-ot-shape-complex-sea-machine.hh.tmp"
|
||||
#line 194 "hb-ot-shape-complex-sea-machine.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
@ -199,7 +199,7 @@ _again:
|
||||
#line 1 "NONE"
|
||||
{ts = 0;}
|
||||
break;
|
||||
#line 203 "hb-ot-shape-complex-sea-machine.hh.tmp"
|
||||
#line 203 "hb-ot-shape-complex-sea-machine.hh"
|
||||
}
|
||||
|
||||
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);
|
||||
c.set_lookup_mask (plan->kern_mask);
|
||||
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;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
for (unsigned int idx = 0; idx < count;)
|
||||
{
|
||||
OT::hb_apply_context_t::skipping_forward_iterator_t skippy_iter (&c, idx, 1);
|
||||
skippy_iter.reset (idx, 1);
|
||||
if (!skippy_iter.next ())
|
||||
{
|
||||
idx++;
|
||||
|
@ -197,16 +197,17 @@ static inline void
|
||||
decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shortest)
|
||||
{
|
||||
hb_buffer_t * const buffer = c->buffer;
|
||||
hb_codepoint_t u = buffer->cur().codepoint;
|
||||
hb_codepoint_t glyph;
|
||||
|
||||
/* 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);
|
||||
else if (decompose (c, shortest, buffer->cur().codepoint))
|
||||
else if (decompose (c, shortest, u))
|
||||
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);
|
||||
else if (decompose_compatibility (c, buffer->cur().codepoint))
|
||||
else if (decompose_compatibility (c, u))
|
||||
skip_char (buffer);
|
||||
else
|
||||
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;
|
||||
}
|
||||
else
|
||||
continue; /* Delete it. */
|
||||
continue; /* Delete it. XXX Merge clusters? */
|
||||
}
|
||||
if (j != i)
|
||||
{
|
||||
|
@ -94,20 +94,6 @@
|
||||
# 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
|
||||
#define HB_FUNC __PRETTY_FUNCTION__
|
||||
#elif defined(_MSC_VER)
|
||||
@ -132,14 +118,21 @@
|
||||
# ifndef STRICT
|
||||
# define STRICT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
/* Some things not defined on Windows CE. */
|
||||
#define MemoryBarrier()
|
||||
#define getenv(Name) NULL
|
||||
#define setlocale(Category, Locale) "C"
|
||||
# if defined(_WIN32_WCE)
|
||||
/* Some things not defined on Windows CE. */
|
||||
# define strdup _strdup
|
||||
# define getenv(Name) NULL
|
||||
# if _WIN32_WCE < 0x800
|
||||
# define setlocale(Category, Locale) "C"
|
||||
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
|
||||
|
||||
#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_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
|
||||
_hb_debug_msg_va (const char *what,
|
||||
const void *obj,
|
||||
@ -626,27 +643,13 @@ _hb_debug_msg_va (const char *what,
|
||||
} else
|
||||
fprintf (stderr, " " VRBAR LBAR);
|
||||
|
||||
if (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);
|
||||
}
|
||||
_hb_print_func (func);
|
||||
|
||||
if (message)
|
||||
{
|
||||
fprintf (stderr, ": ");
|
||||
vfprintf (stderr, message, ap);
|
||||
}
|
||||
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
@ -818,7 +821,7 @@ hb_in_range (T u, T lo, T hi)
|
||||
/* The sizeof() is here to force template instantiation.
|
||||
* 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
|
||||
* 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. */
|
||||
ASSERT_STATIC (sizeof (hb_assert_unsigned_t<T>) >= 0);
|
||||
|
||||
|
@ -145,6 +145,8 @@ typedef hb_set_digest_combiner_t
|
||||
|
||||
struct hb_set_t
|
||||
{
|
||||
friend struct hb_frozen_set_t;
|
||||
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
bool in_error;
|
||||
@ -326,7 +328,7 @@ struct hb_set_t
|
||||
static const hb_codepoint_t INVALID = HB_SET_VALUE_INVALID;
|
||||
|
||||
elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
|
||||
elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
|
||||
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 elts[ELTS]; /* XXX 8kb */
|
||||
@ -335,6 +337,58 @@ struct hb_set_t
|
||||
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 */
|
||||
|
@ -126,7 +126,7 @@ hb_shape_plan_create (hb_face_t *face,
|
||||
|
||||
if (unlikely (!face))
|
||||
face = hb_face_get_empty ();
|
||||
if (unlikely (!props || hb_object_is_inert (face)))
|
||||
if (unlikely (!props))
|
||||
return hb_shape_plan_get_empty ();
|
||||
if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t))))
|
||||
return hb_shape_plan_get_empty ();
|
||||
@ -294,7 +294,6 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
|
||||
shape_plan->shaper_func);
|
||||
|
||||
if (unlikely (hb_object_is_inert (shape_plan) ||
|
||||
hb_object_is_inert (font) ||
|
||||
hb_object_is_inert (buffer)))
|
||||
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);
|
||||
|
||||
/* Don't add to the cache if face is inert. */
|
||||
if (unlikely (hb_object_is_inert (face)))
|
||||
return shape_plan;
|
||||
|
||||
/* Don't add the plan to the cache if there were user features with non-global ranges */
|
||||
|
||||
if (hb_non_global_user_features_present (user_features, num_user_features))
|
||||
|
@ -198,9 +198,9 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature)
|
||||
|
||||
/**
|
||||
* hb_feature_from_string:
|
||||
* @str: (array length=len):
|
||||
* @str: (array length=len) (element-type uint8_t):
|
||||
* @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 inline
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_shaper_list (void)
|
||||
{
|
||||
free (static_shaper_list);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
#define HB_SHAPER_DATA_DESTROY(shaper, object) \
|
||||
if (object->shaper_data.shaper && \
|
||||
object->shaper_data.shaper != HB_SHAPER_DATA_INVALID && \
|
||||
object->shaper_data.shaper != HB_SHAPER_DATA_SUCCEEDED) \
|
||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA (shaper, object));
|
||||
if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object)) \
|
||||
if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
|
||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
|
||||
|
||||
#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
|
||||
static inline bool \
|
||||
|
@ -40,12 +40,14 @@ static const hb_shaper_pair_t all_shapers[] = {
|
||||
|
||||
static const hb_shaper_pair_t *static_shapers;
|
||||
|
||||
static inline
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_shapers (void)
|
||||
{
|
||||
if (unlikely (static_shapers != all_shapers))
|
||||
free ((void *) static_shapers);
|
||||
}
|
||||
#endif
|
||||
|
||||
const hb_shaper_pair_t *
|
||||
_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)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message("Could not find any Unicode functions implementation, you have to provide your own")
|
||||
#pragma message("To suppress this warnings, define HB_NO_UNICODE_FUNCS")
|
||||
#pragma error("Could not find any Unicode functions implementation, you have to provide your own.")
|
||||
#pragma error("Consider building hb-ucdn.c. If you absolutely want to build without any, check the code.")
|
||||
#else
|
||||
#warning "Could not find any Unicode functions implementation, you have to provide your own"
|
||||
#warning "To suppress this warning, define HB_NO_UNICODE_FUNCS"
|
||||
#error "Could not find any Unicode functions implementation, you have to provide your own"
|
||||
#error "Consider building hb-ucdn.c. If you absolutely want to build without any, check the code."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hb_unicode_funcs_create: (Xconstructor)
|
||||
* @parent: (allow-none):
|
||||
* @parent: (nullable):
|
||||
*
|
||||
*
|
||||
*
|
||||
|
@ -29,14 +29,11 @@
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
template <typename T, bool validate=true> struct hb_utf_t;
|
||||
|
||||
|
||||
/* UTF-8 */
|
||||
|
||||
template <>
|
||||
struct hb_utf_t<uint8_t, true>
|
||||
struct hb_utf8_t
|
||||
{
|
||||
typedef uint8_t codepoint_t;
|
||||
|
||||
static inline const uint8_t *
|
||||
next (const uint8_t *text,
|
||||
const uint8_t *end,
|
||||
@ -131,11 +128,10 @@ struct hb_utf_t<uint8_t, true>
|
||||
};
|
||||
|
||||
|
||||
/* UTF-16 */
|
||||
|
||||
template <>
|
||||
struct hb_utf_t<uint16_t, true>
|
||||
struct hb_utf16_t
|
||||
{
|
||||
typedef uint16_t codepoint_t;
|
||||
|
||||
static inline const uint16_t *
|
||||
next (const uint16_t *text,
|
||||
const uint16_t *end,
|
||||
@ -204,11 +200,11 @@ struct hb_utf_t<uint16_t, true>
|
||||
};
|
||||
|
||||
|
||||
/* UTF-32 */
|
||||
|
||||
template <bool validate>
|
||||
struct hb_utf_t<uint32_t, validate>
|
||||
template <bool validate=true>
|
||||
struct hb_utf32_t
|
||||
{
|
||||
typedef uint32_t codepoint_t;
|
||||
|
||||
static inline const uint32_t *
|
||||
next (const uint32_t *text,
|
||||
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 */
|
||||
|
@ -38,9 +38,9 @@ HB_BEGIN_DECLS
|
||||
|
||||
#define HB_VERSION_MAJOR 0
|
||||
#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) \
|
||||
((major)*10000+(minor)*100+(micro) <= \
|
||||
|
@ -30,26 +30,20 @@
|
||||
|
||||
#if defined(HB_ATOMIC_INT_NIL)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message("Could not find any system to define atomic_int macros, library may NOT be thread-safe")
|
||||
#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
|
||||
#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
|
||||
|
||||
#if defined(HB_MUTEX_IMPL_NIL)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message("Could not find any system to define mutex macros, library may NOT be thread-safe")
|
||||
#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
|
||||
#warning "Could not find any system to define mutex macros, library may NOT be thread-safe"
|
||||
#error "Could not find any system to define mutex macros, library WILL NOT be thread-safe"
|
||||
#error "Check hb-mutex-private.hh for possible resolutions."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HB_ATOMIC_INT_NIL) || defined(HB_MUTEX_IMPL_NIL)
|
||||
#ifdef _MSC_VER
|
||||
#pragma message("To suppress these warnings, define HB_NO_MT")
|
||||
#else
|
||||
#warning "To suppress these warnings, define HB_NO_MT"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
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