Merge branch 'master' into cff-subset
This commit is contained in:
commit
e2fd49e477
8
NEWS
8
NEWS
|
@ -1,3 +1,11 @@
|
|||
Overview of changes leading to 1.8.5
|
||||
Wednesday, August 1, 2018
|
||||
====================================
|
||||
- Major Khmer shaper improvements to better match Microsoft.
|
||||
- Indic bug fixes.
|
||||
- Internal improvements to atomic operations.
|
||||
|
||||
|
||||
Overview of changes leading to 1.8.4
|
||||
Tuesday, July 17, 2018
|
||||
====================================
|
||||
|
|
|
@ -44,6 +44,7 @@ build_script:
|
|||
- 'if "%compiler%"=="msvc" msbuild harfbuzz.sln /p:Configuration=%configuration% /p:Platform=%platform%'
|
||||
- 'if "%compiler%"=="msvc" if not "%platform%"=="ARM" ctest --output-on-failure -C %configuration%'
|
||||
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syyu mingw-w64-$MSYS2_ARCH-gcc"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S --needed mingw-w64-$MSYS2_ARCH-{freetype,cairo,icu,gettext,gobject-introspection,gcc,gcc-libs,glib2,graphite2,pkg-config,python2}"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "curl https://raw.githubusercontent.com/mirror/mingw-w64/023eb04c396d4e8d8fcf604cfababc53dae13398/mingw-w64-headers/include/dwrite_1.h > %MINGW_PREFIX%/%MINGW_CHOST%/include/dwrite_1.h"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make; make check || .ci/fail.sh"'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
AC_PREREQ([2.64])
|
||||
AC_INIT([HarfBuzz],
|
||||
[1.8.4],
|
||||
[1.8.5],
|
||||
[https://github.com/harfbuzz/harfbuzz/issues/new],
|
||||
[harfbuzz],
|
||||
[http://harfbuzz.org/])
|
||||
|
|
|
@ -327,6 +327,7 @@ HB_GOBJECT_TYPE_FACE
|
|||
HB_GOBJECT_TYPE_FONT
|
||||
HB_GOBJECT_TYPE_FONT_FUNCS
|
||||
HB_GOBJECT_TYPE_GLYPH_FLAGS
|
||||
HB_GOBJECT_TYPE_MAP
|
||||
HB_GOBJECT_TYPE_MEMORY_MODE
|
||||
HB_GOBJECT_TYPE_OT_LAYOUT_GLYPH_CLASS
|
||||
HB_GOBJECT_TYPE_OT_MATH_CONSTANT
|
||||
|
@ -358,6 +359,7 @@ hb_gobject_face_get_type
|
|||
hb_gobject_font_funcs_get_type
|
||||
hb_gobject_font_get_type
|
||||
hb_gobject_glyph_flags_get_type
|
||||
hb_gobject_map_get_type
|
||||
hb_gobject_memory_mode_get_type
|
||||
hb_gobject_ot_layout_glyph_class_get_type
|
||||
hb_gobject_ot_math_constant_get_type
|
||||
|
@ -447,10 +449,10 @@ HB_OT_TAG_GPOS
|
|||
HB_OT_TAG_GSUB
|
||||
HB_OT_TAG_JSTF
|
||||
hb_ot_layout_collect_lookups
|
||||
hb_ot_layout_collect_features
|
||||
hb_ot_layout_feature_get_lookups
|
||||
hb_ot_layout_feature_with_variations_get_lookups
|
||||
hb_ot_layout_get_attach_points
|
||||
hb_ot_layout_get_feature_name_ids
|
||||
hb_ot_layout_get_glyph_class
|
||||
hb_ot_layout_get_glyphs_in_class
|
||||
hb_ot_layout_get_ligature_carets
|
||||
|
|
|
@ -233,10 +233,10 @@ int main (int argc, char **argv)
|
|||
svg.dump (svg_callback);
|
||||
svg.fini ();
|
||||
|
||||
hb_blob_t* colr_blob = OT::hb_sanitize_context_t().reference_table<OT::COLR> (face);
|
||||
hb_blob_t* colr_blob = hb_sanitize_context_t ().reference_table<OT::COLR> (face);
|
||||
const OT::COLR *colr = colr_blob->as<OT::COLR> ();
|
||||
|
||||
hb_blob_t* cpal_blob = OT::hb_sanitize_context_t().reference_table<OT::CPAL> (face);
|
||||
hb_blob_t* cpal_blob = hb_sanitize_context_t ().reference_table<OT::CPAL> (face);
|
||||
const OT::CPAL *cpal = cpal_blob->as<OT::CPAL> ();
|
||||
|
||||
cairo_font_face_t *cairo_face;
|
||||
|
|
|
@ -61,7 +61,7 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
|
|||
// static inline void
|
||||
// _hb_aat_layout_create (hb_face_t *face)
|
||||
// {
|
||||
// hb_blob_t *morx_blob = OT::hb_sanitize_context_t().reference_table<AAT::morx> (face);
|
||||
// hb_blob_t *morx_blob = hb_sanitize_context_t ().reference_table<AAT::morx> (face);
|
||||
// morx_blob->as<AAT::morx> ();
|
||||
|
||||
// if (0)
|
||||
|
|
|
@ -46,21 +46,23 @@
|
|||
/* Defined externally, i.e. in config.h; must have typedef'ed hb_atomic_int_impl_t as well. */
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE)
|
||||
#elif !defined(HB_NO_MT) && defined(__ATOMIC_CONSUME)
|
||||
|
||||
/* C++11-style GCC primitives. */
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) __atomic_fetch_add (&(AI), (V), __ATOMIC_ACQ_REL)
|
||||
#define hb_atomic_int_impl_add(AI, V) __atomic_fetch_add ((AI), (V), __ATOMIC_ACQ_REL)
|
||||
#define hb_atomic_int_impl_set_relaxed(AI, V) __atomic_store_n ((AI), (V), __ATOMIC_RELAXED)
|
||||
#define hb_atomic_int_impl_get_relaxed(AI) __atomic_load_n ((AI), __ATOMIC_RELAXED)
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_ACQUIRE)
|
||||
#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_CONSUME)
|
||||
static inline bool
|
||||
_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
|
||||
{
|
||||
const void *O = O_; // Need lvalue
|
||||
return __atomic_compare_exchange_n ((void **) P, (void **) &O, (void *) N, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED);
|
||||
}
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
|
||||
|
||||
#elif !defined(HB_NO_MT) && __cplusplus >= 201103L
|
||||
|
||||
|
@ -69,47 +71,49 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
|
|||
#include <atomic>
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast<std::atomic<int> *> (&AI)->fetch_add ((V), std::memory_order_acq_rel))
|
||||
#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
|
||||
#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_relaxed))
|
||||
#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast<std::atomic<int> *> (AI)->load (std::memory_order_relaxed))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_acquire))
|
||||
#define hb_atomic_ptr_impl_get(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_consume))
|
||||
static inline bool
|
||||
_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
|
||||
{
|
||||
const void *O = O_; // Need lvalue
|
||||
return reinterpret_cast<std::atomic<const void*> *> (P)->compare_exchange_weak (O, N, std::memory_order_acq_rel, std::memory_order_relaxed);
|
||||
}
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (_hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && (defined(_WIN32) || defined(__CYGWIN__))
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* MinGW has a convoluted history of supporting MemoryBarrier
|
||||
* properly. As such, define a function to wrap the whole
|
||||
* thing. */
|
||||
static inline void _HBMemoryBarrier (void) {
|
||||
static inline void _hb_memory_barrier (void)
|
||||
{
|
||||
#if !defined(MemoryBarrier)
|
||||
/* MinGW has a convoluted history of supporting MemoryBarrier. */
|
||||
long dummy = 0;
|
||||
InterlockedExchange (&dummy, 1);
|
||||
#else
|
||||
MemoryBarrier ();
|
||||
#endif
|
||||
}
|
||||
#define _hb_memory_barrier() _hb_memory_barrier ()
|
||||
|
||||
typedef LONG hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd (&(AI), (V))
|
||||
#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((AI), (V))
|
||||
|
||||
#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(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V))
|
||||
#define _hb_memory_barrier() __sync_synchronize ()
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add ((AI), (V))
|
||||
|
||||
#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))
|
||||
|
||||
|
||||
|
@ -118,11 +122,30 @@ typedef int hb_atomic_int_impl_t;
|
|||
#include <atomic.h>
|
||||
#include <mbarrier.h>
|
||||
|
||||
typedef unsigned int hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
|
||||
#define _hb_memory_r_barrier() __machine_r_barrier ()
|
||||
#define _hb_memory_w_barrier() __machine_w_barrier ()
|
||||
#define _hb_memory_barrier() __machine_rw_barrier ()
|
||||
|
||||
#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)
|
||||
typedef unsigned int hb_atomic_int_impl_t;
|
||||
|
||||
static inline int _hb_fetch_and_add (hb_atomic_int_impl_t *AI, int V)
|
||||
{
|
||||
_hb_memory_w_barrier ();
|
||||
int result = atomic_add_int_nv (AI, V);
|
||||
_hb_memory_r_barrier ();
|
||||
return result;
|
||||
}
|
||||
static inline bool _hb_compare_and_swap_ptr (const void **P, const void *O, const void *N)
|
||||
{
|
||||
_hb_memory_w_barrier ();
|
||||
int result = atomic_cas_ptr ((void **) P, (void *) O, (void *) N) == (void *) O;
|
||||
_hb_memory_r_barrier ();
|
||||
return result;
|
||||
}
|
||||
|
||||
#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((const void **) (P), (O), (N))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(__APPLE__)
|
||||
|
@ -134,11 +157,11 @@ typedef unsigned int hb_atomic_int_impl_t;
|
|||
#include <Availability.h>
|
||||
#endif
|
||||
|
||||
#define _hb_memory_barrier() OSMemoryBarrier ()
|
||||
|
||||
typedef int32_t hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), &(AI)) - (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_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
||||
#else
|
||||
|
@ -154,65 +177,88 @@ typedef int32_t hb_atomic_int_impl_t;
|
|||
|
||||
#include <builtins.h>
|
||||
|
||||
|
||||
static inline int _hb_fetch_and_add(volatile int* AI, unsigned int V) {
|
||||
__lwsync();
|
||||
int result = __fetch_and_add(AI, V);
|
||||
__isync();
|
||||
return result;
|
||||
}
|
||||
static inline int _hb_compare_and_swaplp(volatile long* P, long O, long N) {
|
||||
__sync();
|
||||
int result = __compare_and_swaplp (P, &O, N);
|
||||
__sync();
|
||||
return result;
|
||||
}
|
||||
#define _hb_memory_barrier() __lwsync ()
|
||||
|
||||
typedef int hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add (&(AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_get(P) (__sync(), (void *) *(P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long*)(P), (long)(O), (long)(N))
|
||||
static inline int _hb_fetch_and_add (hb_atomic_int_impl_t *AI, int V)
|
||||
{
|
||||
_hb_memory_barrier ();
|
||||
int result = __fetch_and_add (AI, V);
|
||||
_hb_memory_barrier ();
|
||||
return result;
|
||||
}
|
||||
static inline bool _hb_compare_and_swaplp (long *P, long O, long N)
|
||||
{
|
||||
_hb_memory_barrier ();
|
||||
bool result = __compare_and_swaplp (P, &O, N);
|
||||
_hb_memory_barrier ();
|
||||
return result;
|
||||
}
|
||||
|
||||
#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swaplp ((long *) (P), (long) (O), (long) (N))
|
||||
static_assert ((sizeof (long) == sizeof (void *)), "");
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT)
|
||||
|
||||
#define HB_ATOMIC_INT_NIL 1 /* Warn that fallback implementation is in use. */
|
||||
|
||||
typedef volatile int hb_atomic_int_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V))
|
||||
#define _hb_memory_barrier()
|
||||
|
||||
typedef volatile int hb_atomic_int_impl_t;
|
||||
#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_impl_t;
|
||||
#define hb_atomic_int_impl_add(AI, V) (((AI) += (V)) - (V))
|
||||
#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V))
|
||||
|
||||
#define _hb_memory_barrier()
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _hb_memory_r_barrier
|
||||
#define _hb_memory_r_barrier() _hb_memory_barrier ()
|
||||
#endif
|
||||
#ifndef _hb_memory_w_barrier
|
||||
#define _hb_memory_w_barrier() _hb_memory_barrier ()
|
||||
#endif
|
||||
#ifndef HB_ATOMIC_INT_INIT
|
||||
#define HB_ATOMIC_INT_INIT(V) {V}
|
||||
#endif
|
||||
#ifndef hb_atomic_int_impl_set_relaxed
|
||||
#define hb_atomic_int_impl_set_relaxed(AI, V) (*(AI) = (V))
|
||||
#endif
|
||||
#ifndef hb_atomic_int_impl_get_relaxed
|
||||
#define hb_atomic_int_impl_get_relaxed(AI) (*(AI))
|
||||
#endif
|
||||
#ifndef hb_atomic_ptr_impl_get
|
||||
inline void *hb_atomic_ptr_impl_get (void **P) { void *v = *P; _hb_memory_r_barrier (); return v; }
|
||||
#endif
|
||||
|
||||
|
||||
struct hb_atomic_int_t
|
||||
{
|
||||
mutable 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 (v, 1); }
|
||||
inline int dec (void) { return hb_atomic_int_impl_add (v, -1); }
|
||||
inline void set_relaxed (int v_) { hb_atomic_int_impl_set_relaxed (&v, v_); }
|
||||
inline int get_relaxed (void) const { return hb_atomic_int_impl_get_relaxed (&v); }
|
||||
inline int inc (void) { return hb_atomic_int_impl_add (&v, 1); }
|
||||
inline int dec (void) { return hb_atomic_int_impl_add (&v, -1); }
|
||||
};
|
||||
|
||||
|
||||
#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get(P)
|
||||
#define hb_atomic_ptr_get(P) hb_atomic_ptr_impl_get((void **) P)
|
||||
#define hb_atomic_ptr_cmpexch(P,O,N) hb_atomic_ptr_impl_cmpexch((P),(O),(N))
|
||||
|
||||
|
||||
|
|
|
@ -57,11 +57,6 @@ struct hb_blob_t
|
|||
HB_INTERNAL bool try_make_writable_inplace (void);
|
||||
HB_INTERNAL bool try_make_writable_inplace_unix (void);
|
||||
|
||||
inline void lock (void)
|
||||
{
|
||||
hb_blob_make_immutable (this);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
inline const Type* as (void) const
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
/* hb_options_t */
|
||||
|
||||
hb_options_union_t _hb_options;
|
||||
hb_atomic_int_t _hb_options;
|
||||
|
||||
void
|
||||
_hb_options_init (void)
|
||||
|
@ -50,7 +50,7 @@ _hb_options_init (void)
|
|||
u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
|
||||
|
||||
/* This is idempotent and threadsafe. */
|
||||
_hb_options = u;
|
||||
_hb_options.set_relaxed (u.i);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
|
|||
return ct_font;
|
||||
}
|
||||
|
||||
hb_coretext_shaper_face_data_t *
|
||||
hb_coretext_face_data_t *
|
||||
_hb_coretext_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
CGFontRef cg_font = create_cg_font (face);
|
||||
|
@ -280,11 +280,11 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return (hb_coretext_shaper_face_data_t *) cg_font;
|
||||
return (hb_coretext_face_data_t *) cg_font;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_coretext_shaper_face_data_destroy (hb_coretext_shaper_face_data_t *data)
|
||||
_hb_coretext_shaper_face_data_destroy (hb_coretext_face_data_t *data)
|
||||
{
|
||||
CFRelease ((CGFontRef) data);
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ hb_coretext_face_get_cg_font (hb_face_t *face)
|
|||
}
|
||||
|
||||
|
||||
hb_coretext_shaper_font_data_t *
|
||||
hb_coretext_font_data_t *
|
||||
_hb_coretext_shaper_font_data_create (hb_font_t *font)
|
||||
{
|
||||
hb_face_t *face = font->face;
|
||||
|
@ -321,11 +321,11 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return (hb_coretext_shaper_font_data_t *) ct_font;
|
||||
return (hb_coretext_font_data_t *) ct_font;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_coretext_shaper_font_data_destroy (hb_coretext_shaper_font_data_t *data)
|
||||
_hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data)
|
||||
{
|
||||
CFRelease ((CTFontRef) data);
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ hb_coretext_font_create (CTFontRef ct_font)
|
|||
hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
|
||||
|
||||
/* Let there be dragons here... */
|
||||
HB_SHAPER_DATA_GET (font) = (hb_coretext_shaper_font_data_t *) CFRetain (ct_font);
|
||||
HB_SHAPER_DATA_GET (font) = (hb_coretext_font_data_t *) CFRetain (ct_font);
|
||||
|
||||
return font;
|
||||
}
|
||||
|
@ -366,20 +366,20 @@ hb_coretext_font_get_ct_font (hb_font_t *font)
|
|||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_coretext_shaper_shape_plan_data_t {};
|
||||
struct hb_coretext_shape_plan_data_t {};
|
||||
|
||||
hb_coretext_shaper_shape_plan_data_t *
|
||||
hb_coretext_shape_plan_data_t *
|
||||
_hb_coretext_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_coretext_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_coretext_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
_hb_coretext_shaper_shape_plan_data_destroy (hb_coretext_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1329,9 +1329,9 @@ HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font)
|
|||
* shaper face data
|
||||
*/
|
||||
|
||||
struct hb_coretext_aat_shaper_face_data_t {};
|
||||
struct hb_coretext_aat_face_data_t {};
|
||||
|
||||
hb_coretext_aat_shaper_face_data_t *
|
||||
hb_coretext_aat_face_data_t *
|
||||
_hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
static const hb_tag_t tags[] = {HB_CORETEXT_TAG_MORX, HB_CORETEXT_TAG_MORT, HB_CORETEXT_TAG_KERX};
|
||||
|
@ -1342,7 +1342,7 @@ _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
|
|||
if (hb_blob_get_length (blob))
|
||||
{
|
||||
hb_blob_destroy (blob);
|
||||
return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
|
||||
return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
|
||||
}
|
||||
hb_blob_destroy (blob);
|
||||
}
|
||||
|
@ -1351,7 +1351,7 @@ _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
|
|||
}
|
||||
|
||||
void
|
||||
_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *data HB_UNUSED)
|
||||
_hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_face_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1360,16 +1360,16 @@ _hb_coretext_aat_shaper_face_data_destroy (hb_coretext_aat_shaper_face_data_t *d
|
|||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_coretext_aat_shaper_font_data_t {};
|
||||
struct hb_coretext_aat_font_data_t {};
|
||||
|
||||
hb_coretext_aat_shaper_font_data_t *
|
||||
hb_coretext_aat_font_data_t *
|
||||
_hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
|
||||
{
|
||||
return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
|
||||
return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *data HB_UNUSED)
|
||||
_hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_font_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1378,20 +1378,20 @@ _hb_coretext_aat_shaper_font_data_destroy (hb_coretext_aat_shaper_font_data_t *d
|
|||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_coretext_aat_shaper_shape_plan_data_t {};
|
||||
struct hb_coretext_aat_shape_plan_data_t {};
|
||||
|
||||
hb_coretext_aat_shaper_shape_plan_data_t *
|
||||
hb_coretext_aat_shape_plan_data_t *
|
||||
_hb_coretext_aat_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_coretext_aat_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_coretext_aat_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
_hb_coretext_aat_shaper_shape_plan_data_destroy (hb_coretext_aat_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define HB_DEBUG_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-atomic-private.hh"
|
||||
#include "hb-dsalgs.hh"
|
||||
|
||||
|
||||
|
@ -35,6 +36,47 @@
|
|||
#define HB_DEBUG 0
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Global runtime options.
|
||||
*/
|
||||
|
||||
struct hb_options_t
|
||||
{
|
||||
unsigned int unused : 1; /* In-case sign bit is here. */
|
||||
unsigned int initialized : 1;
|
||||
unsigned int uniscribe_bug_compatible : 1;
|
||||
};
|
||||
|
||||
union hb_options_union_t {
|
||||
int i;
|
||||
hb_options_t opts;
|
||||
};
|
||||
static_assert ((sizeof (hb_atomic_int_t) >= sizeof (hb_options_union_t)), "");
|
||||
|
||||
HB_INTERNAL void
|
||||
_hb_options_init (void);
|
||||
|
||||
extern HB_INTERNAL hb_atomic_int_t _hb_options;
|
||||
|
||||
static inline hb_options_t
|
||||
hb_options (void)
|
||||
{
|
||||
/* Make a local copy, so we can access bitfield threadsafely. */
|
||||
hb_options_union_t u;
|
||||
u.i = _hb_options.get_relaxed ();
|
||||
|
||||
if (unlikely (!u.i))
|
||||
_hb_options_init ();
|
||||
|
||||
return u.opts;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Debug output (needs enabling at compile time.)
|
||||
*/
|
||||
|
||||
static inline bool
|
||||
_hb_debug (unsigned int level,
|
||||
unsigned int max_level)
|
||||
|
|
|
@ -133,7 +133,7 @@ public:
|
|||
* shaper face data
|
||||
*/
|
||||
|
||||
struct hb_directwrite_shaper_face_data_t
|
||||
struct hb_directwrite_face_data_t
|
||||
{
|
||||
IDWriteFactory *dwriteFactory;
|
||||
IDWriteFontFile *fontFile;
|
||||
|
@ -143,10 +143,10 @@ struct hb_directwrite_shaper_face_data_t
|
|||
hb_blob_t *faceBlob;
|
||||
};
|
||||
|
||||
hb_directwrite_shaper_face_data_t *
|
||||
hb_directwrite_face_data_t *
|
||||
_hb_directwrite_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
hb_directwrite_shaper_face_data_t *data = new hb_directwrite_shaper_face_data_t;
|
||||
hb_directwrite_face_data_t *data = new hb_directwrite_face_data_t;
|
||||
if (unlikely (!data))
|
||||
return nullptr;
|
||||
|
||||
|
@ -206,7 +206,7 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
|
|||
}
|
||||
|
||||
void
|
||||
_hb_directwrite_shaper_face_data_destroy (hb_directwrite_shaper_face_data_t *data)
|
||||
_hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data)
|
||||
{
|
||||
if (data->fontFace)
|
||||
data->fontFace->Release ();
|
||||
|
@ -233,16 +233,16 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_shaper_face_data_t *dat
|
|||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_directwrite_shaper_font_data_t
|
||||
struct hb_directwrite_font_data_t
|
||||
{
|
||||
};
|
||||
|
||||
hb_directwrite_shaper_font_data_t *
|
||||
hb_directwrite_font_data_t *
|
||||
_hb_directwrite_shaper_font_data_create (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return nullptr;
|
||||
|
||||
hb_directwrite_shaper_font_data_t *data = new hb_directwrite_shaper_font_data_t;
|
||||
hb_directwrite_font_data_t *data = new hb_directwrite_font_data_t;
|
||||
if (unlikely (!data))
|
||||
return nullptr;
|
||||
|
||||
|
@ -250,7 +250,7 @@ _hb_directwrite_shaper_font_data_create (hb_font_t *font)
|
|||
}
|
||||
|
||||
void
|
||||
_hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *data)
|
||||
_hb_directwrite_shaper_font_data_destroy (hb_directwrite_font_data_t *data)
|
||||
{
|
||||
delete data;
|
||||
}
|
||||
|
@ -260,20 +260,20 @@ _hb_directwrite_shaper_font_data_destroy (hb_directwrite_shaper_font_data_t *dat
|
|||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_directwrite_shaper_shape_plan_data_t {};
|
||||
struct hb_directwrite_shape_plan_data_t {};
|
||||
|
||||
hb_directwrite_shaper_shape_plan_data_t *
|
||||
hb_directwrite_shape_plan_data_t *
|
||||
_hb_directwrite_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_directwrite_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_directwrite_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
_hb_directwrite_shaper_shape_plan_data_destroy (hb_directwrite_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -555,8 +555,8 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
|||
float lineWidth)
|
||||
{
|
||||
hb_face_t *face = font->face;
|
||||
hb_directwrite_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||
hb_directwrite_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
hb_directwrite_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||
hb_directwrite_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
IDWriteFactory *dwriteFactory = face_data->dwriteFactory;
|
||||
IDWriteFontFace *fontFace = face_data->fontFace;
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "hb-open-file-private.hh"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* hb_face_count: Get number of faces on the blob
|
||||
* @blob:
|
||||
|
@ -51,7 +50,8 @@ hb_face_count (hb_blob_t *blob)
|
|||
return 0;
|
||||
|
||||
/* TODO We shouldn't be sanitizing blob. Port to run sanitizer and return if not sane. */
|
||||
hb_blob_t *sanitized = OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob));
|
||||
/* Make API signature const after. */
|
||||
hb_blob_t *sanitized = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob));
|
||||
const OT::OpenTypeFontFile& ot = *sanitized->as<OT::OpenTypeFontFile> ();
|
||||
unsigned int ret = ot.get_face_count ();
|
||||
hb_blob_destroy (sanitized);
|
||||
|
@ -189,7 +189,7 @@ hb_face_create (hb_blob_t *blob,
|
|||
if (unlikely (!blob))
|
||||
blob = hb_blob_get_empty ();
|
||||
|
||||
hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob)), index);
|
||||
hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (hb_blob_reference (blob)), index);
|
||||
|
||||
if (unlikely (!closure))
|
||||
return hb_face_get_empty ();
|
||||
|
@ -302,7 +302,7 @@ hb_face_set_user_data (hb_face_t *face,
|
|||
* Since: 0.9.2
|
||||
**/
|
||||
void *
|
||||
hb_face_get_user_data (hb_face_t *face,
|
||||
hb_face_get_user_data (const hb_face_t *face,
|
||||
hb_user_data_key_t *key)
|
||||
{
|
||||
return hb_object_get_user_data (face, key);
|
||||
|
@ -336,7 +336,7 @@ hb_face_make_immutable (hb_face_t *face)
|
|||
* Since: 0.9.2
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_face_is_immutable (hb_face_t *face)
|
||||
hb_face_is_immutable (const hb_face_t *face)
|
||||
{
|
||||
return face->immutable;
|
||||
}
|
||||
|
@ -354,8 +354,8 @@ hb_face_is_immutable (hb_face_t *face)
|
|||
* Since: 0.9.2
|
||||
**/
|
||||
hb_blob_t *
|
||||
hb_face_reference_table (hb_face_t *face,
|
||||
hb_tag_t tag)
|
||||
hb_face_reference_table (const hb_face_t *face,
|
||||
hb_tag_t tag)
|
||||
{
|
||||
return face->reference_table (tag);
|
||||
}
|
||||
|
@ -406,7 +406,7 @@ hb_face_set_index (hb_face_t *face,
|
|||
* Since: 0.9.2
|
||||
**/
|
||||
unsigned int
|
||||
hb_face_get_index (hb_face_t *face)
|
||||
hb_face_get_index (const hb_face_t *face)
|
||||
{
|
||||
return face->index;
|
||||
}
|
||||
|
@ -441,7 +441,7 @@ hb_face_set_upem (hb_face_t *face,
|
|||
* Since: 0.9.2
|
||||
**/
|
||||
unsigned int
|
||||
hb_face_get_upem (hb_face_t *face)
|
||||
hb_face_get_upem (const hb_face_t *face)
|
||||
{
|
||||
return face->get_upem ();
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ hb_face_set_glyph_count (hb_face_t *face,
|
|||
* Since: 0.9.7
|
||||
**/
|
||||
unsigned int
|
||||
hb_face_get_glyph_count (hb_face_t *face)
|
||||
hb_face_get_glyph_count (const hb_face_t *face)
|
||||
{
|
||||
return face->get_num_glyphs ();
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ hb_face_get_glyph_count (hb_face_t *face)
|
|||
* Since: 1.6.0
|
||||
**/
|
||||
unsigned int
|
||||
hb_face_get_table_tags (hb_face_t *face,
|
||||
hb_face_get_table_tags (const hb_face_t *face,
|
||||
unsigned int start_offset,
|
||||
unsigned int *table_count, /* IN/OUT */
|
||||
hb_tag_t *table_tags /* OUT */)
|
||||
|
|
|
@ -76,19 +76,19 @@ hb_face_set_user_data (hb_face_t *face,
|
|||
hb_bool_t replace);
|
||||
|
||||
HB_EXTERN void *
|
||||
hb_face_get_user_data (hb_face_t *face,
|
||||
hb_face_get_user_data (const hb_face_t *face,
|
||||
hb_user_data_key_t *key);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_face_make_immutable (hb_face_t *face);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_face_is_immutable (hb_face_t *face);
|
||||
hb_face_is_immutable (const hb_face_t *face);
|
||||
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_face_reference_table (hb_face_t *face,
|
||||
hb_tag_t tag);
|
||||
hb_face_reference_table (const hb_face_t *face,
|
||||
hb_tag_t tag);
|
||||
|
||||
HB_EXTERN hb_blob_t *
|
||||
hb_face_reference_blob (hb_face_t *face);
|
||||
|
@ -98,24 +98,24 @@ hb_face_set_index (hb_face_t *face,
|
|||
unsigned int index);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_face_get_index (hb_face_t *face);
|
||||
hb_face_get_index (const hb_face_t *face);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_face_set_upem (hb_face_t *face,
|
||||
unsigned int upem);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_face_get_upem (hb_face_t *face);
|
||||
hb_face_get_upem (const hb_face_t *face);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_face_set_glyph_count (hb_face_t *face,
|
||||
unsigned int glyph_count);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_face_get_glyph_count (hb_face_t *face);
|
||||
hb_face_get_glyph_count (const hb_face_t *face);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_face_get_table_tags (hb_face_t *face,
|
||||
hb_face_get_table_tags (const hb_face_t *face,
|
||||
unsigned int start_offset,
|
||||
unsigned int *table_count, /* IN/OUT */
|
||||
hb_tag_t *table_tags /* OUT */);
|
||||
|
|
|
@ -36,16 +36,16 @@ HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font)
|
|||
* shaper face data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_face_data_t {};
|
||||
struct hb_fallback_face_data_t {};
|
||||
|
||||
hb_fallback_shaper_face_data_t *
|
||||
hb_fallback_face_data_t *
|
||||
_hb_fallback_shaper_face_data_create (hb_face_t *face HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_fallback_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_UNUSED)
|
||||
_hb_fallback_shaper_face_data_destroy (hb_fallback_face_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -54,16 +54,16 @@ _hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data HB_U
|
|||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_font_data_t {};
|
||||
struct hb_fallback_font_data_t {};
|
||||
|
||||
hb_fallback_shaper_font_data_t *
|
||||
hb_fallback_font_data_t *
|
||||
_hb_fallback_shaper_font_data_create (hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_fallback_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_UNUSED)
|
||||
_hb_fallback_shaper_font_data_destroy (hb_fallback_font_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -72,20 +72,20 @@ _hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data HB_U
|
|||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_fallback_shaper_shape_plan_data_t {};
|
||||
struct hb_fallback_shape_plan_data_t {};
|
||||
|
||||
hb_fallback_shaper_shape_plan_data_t *
|
||||
hb_fallback_shape_plan_data_t *
|
||||
_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_fallback_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ HB_DEFINE_OBJECT_TYPE (face)
|
|||
HB_DEFINE_OBJECT_TYPE (font)
|
||||
HB_DEFINE_OBJECT_TYPE (font_funcs)
|
||||
HB_DEFINE_OBJECT_TYPE (set)
|
||||
HB_DEFINE_OBJECT_TYPE (map)
|
||||
HB_DEFINE_OBJECT_TYPE (shape_plan)
|
||||
HB_DEFINE_OBJECT_TYPE (unicode_funcs)
|
||||
HB_DEFINE_VALUE_TYPE (feature)
|
||||
|
|
|
@ -89,6 +89,10 @@ HB_EXTERN GType
|
|||
hb_gobject_set_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_SET (hb_gobject_set_get_type ())
|
||||
|
||||
HB_EXTERN GType
|
||||
hb_gobject_map_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_MAP (hb_gobject_map_get_type ())
|
||||
|
||||
HB_EXTERN GType
|
||||
hb_gobject_shape_plan_get_type (void);
|
||||
#define HB_GOBJECT_TYPE_SHAPE_PLAN (hb_gobject_shape_plan_get_type ())
|
||||
|
|
|
@ -48,7 +48,7 @@ typedef struct hb_graphite2_tablelist_t {
|
|||
unsigned int tag;
|
||||
} hb_graphite2_tablelist_t;
|
||||
|
||||
struct hb_graphite2_shaper_face_data_t {
|
||||
struct hb_graphite2_face_data_t {
|
||||
hb_face_t *face;
|
||||
gr_face *grface;
|
||||
hb_graphite2_tablelist_t *tlist;
|
||||
|
@ -56,7 +56,7 @@ struct hb_graphite2_shaper_face_data_t {
|
|||
|
||||
static const void *hb_graphite2_get_table (const void *data, unsigned int tag, size_t *len)
|
||||
{
|
||||
hb_graphite2_shaper_face_data_t *face_data = (hb_graphite2_shaper_face_data_t *) data;
|
||||
hb_graphite2_face_data_t *face_data = (hb_graphite2_face_data_t *) data;
|
||||
hb_graphite2_tablelist_t *tlist = face_data->tlist;
|
||||
|
||||
hb_blob_t *blob = nullptr;
|
||||
|
@ -93,7 +93,7 @@ retry:
|
|||
return d;
|
||||
}
|
||||
|
||||
hb_graphite2_shaper_face_data_t *
|
||||
hb_graphite2_face_data_t *
|
||||
_hb_graphite2_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
hb_blob_t *silf_blob = face->reference_table (HB_GRAPHITE2_TAG_SILF);
|
||||
|
@ -106,7 +106,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face)
|
|||
}
|
||||
hb_blob_destroy (silf_blob);
|
||||
|
||||
hb_graphite2_shaper_face_data_t *data = (hb_graphite2_shaper_face_data_t *) calloc (1, sizeof (hb_graphite2_shaper_face_data_t));
|
||||
hb_graphite2_face_data_t *data = (hb_graphite2_face_data_t *) calloc (1, sizeof (hb_graphite2_face_data_t));
|
||||
if (unlikely (!data))
|
||||
return nullptr;
|
||||
|
||||
|
@ -122,7 +122,7 @@ _hb_graphite2_shaper_face_data_create (hb_face_t *face)
|
|||
}
|
||||
|
||||
void
|
||||
_hb_graphite2_shaper_face_data_destroy (hb_graphite2_shaper_face_data_t *data)
|
||||
_hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data)
|
||||
{
|
||||
hb_graphite2_tablelist_t *tlist = data->tlist;
|
||||
|
||||
|
@ -154,16 +154,16 @@ hb_graphite2_face_get_gr_face (hb_face_t *face)
|
|||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_graphite2_shaper_font_data_t {};
|
||||
struct hb_graphite2_font_data_t {};
|
||||
|
||||
hb_graphite2_shaper_font_data_t *
|
||||
hb_graphite2_font_data_t *
|
||||
_hb_graphite2_shaper_font_data_create (hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
return (hb_graphite2_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_graphite2_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_graphite2_shaper_font_data_destroy (hb_graphite2_shaper_font_data_t *data HB_UNUSED)
|
||||
_hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -181,20 +181,20 @@ hb_graphite2_font_get_gr_font (hb_font_t *font)
|
|||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_graphite2_shaper_shape_plan_data_t {};
|
||||
struct hb_graphite2_shape_plan_data_t {};
|
||||
|
||||
hb_graphite2_shaper_shape_plan_data_t *
|
||||
hb_graphite2_shape_plan_data_t *
|
||||
_hb_graphite2_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_graphite2_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_graphite2_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
_hb_graphite2_shaper_shape_plan_data_destroy (hb_graphite2_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -30,12 +30,11 @@
|
|||
#define HB_MACHINERY_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-blob-private.hh"
|
||||
|
||||
#include "hb-iter-private.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* Casts
|
||||
*/
|
||||
|
@ -188,7 +187,7 @@ struct hb_sanitize_context_t :
|
|||
|
||||
inline void start_processing (void)
|
||||
{
|
||||
this->start = hb_blob_get_data (this->blob, nullptr);
|
||||
this->start = this->blob->data;
|
||||
this->end = this->start + this->blob->length;
|
||||
assert (this->start <= this->end); /* Must not overflow. */
|
||||
this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
|
||||
|
@ -336,7 +335,7 @@ struct hb_sanitize_context_t :
|
|||
DEBUG_MSG_FUNC (SANITIZE, start, sane ? "PASSED" : "FAILED");
|
||||
if (sane)
|
||||
{
|
||||
blob->lock ();
|
||||
hb_blob_make_immutable (blob);
|
||||
return blob;
|
||||
}
|
||||
else
|
||||
|
@ -350,8 +349,8 @@ struct hb_sanitize_context_t :
|
|||
inline hb_blob_t *reference_table (const hb_face_t *face, hb_tag_t tableTag = Type::tableTag)
|
||||
{
|
||||
if (!num_glyphs_set)
|
||||
set_num_glyphs (face->get_num_glyphs ());
|
||||
return sanitize_blob<Type> (face->reference_table (tableTag));
|
||||
set_num_glyphs (hb_face_get_glyph_count (face));
|
||||
return sanitize_blob<Type> (hb_face_reference_table (face, tableTag));
|
||||
}
|
||||
|
||||
mutable unsigned int debug_depth;
|
||||
|
@ -467,12 +466,6 @@ struct hb_serialize_context_t
|
|||
return reinterpret_cast<Type *> (&obj);
|
||||
}
|
||||
|
||||
inline void truncate (void *new_head)
|
||||
{
|
||||
assert (this->start < new_head && new_head <= this->head);
|
||||
this->head = (char *) new_head;
|
||||
}
|
||||
|
||||
unsigned int debug_depth;
|
||||
char *start, *end, *head;
|
||||
bool ran_out_of_room;
|
||||
|
@ -594,109 +587,117 @@ struct BEInt<Type, 4>
|
|||
|
||||
|
||||
/*
|
||||
* Lazy struct and blob loaders.
|
||||
* Lazy loaders.
|
||||
*/
|
||||
|
||||
/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
|
||||
template <typename T>
|
||||
struct hb_lazy_loader_t
|
||||
template <unsigned int WheresFace,
|
||||
typename Subclass,
|
||||
typename Returned,
|
||||
typename Stored = Returned>
|
||||
struct hb_base_lazy_loader_t
|
||||
{
|
||||
inline void init (hb_face_t *face_)
|
||||
static_assert (WheresFace > 0, "");
|
||||
|
||||
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
|
||||
inline const Subclass* thiz (void) const { return static_cast<const Subclass *> (this); }
|
||||
inline Subclass* thiz (void) { return static_cast<Subclass *> (this); }
|
||||
|
||||
inline void init (void)
|
||||
{
|
||||
face = face_;
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
inline void fini (void)
|
||||
{
|
||||
if (instance && instance != &Null(T))
|
||||
{
|
||||
instance->fini();
|
||||
free (instance);
|
||||
}
|
||||
if (instance)
|
||||
thiz ()->destroy (instance);
|
||||
}
|
||||
|
||||
inline const T* get (void) const
|
||||
inline const Returned * operator-> (void) const
|
||||
{
|
||||
return thiz ()->get ();
|
||||
}
|
||||
|
||||
inline Stored * get_stored (void) const
|
||||
{
|
||||
retry:
|
||||
T *p = (T *) hb_atomic_ptr_get (&instance);
|
||||
Stored *p = (Stored *) hb_atomic_ptr_get (&this->instance);
|
||||
if (unlikely (!p))
|
||||
{
|
||||
p = (T *) calloc (1, sizeof (T));
|
||||
if (unlikely (!p))
|
||||
p = const_cast<T *> (&Null(T));
|
||||
else
|
||||
p->init (face);
|
||||
if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
|
||||
hb_face_t *face = *(((hb_face_t **) this) - WheresFace);
|
||||
p = thiz ()->create (face);
|
||||
if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<Stored **>(&this->instance), nullptr, p)))
|
||||
{
|
||||
if (p != &Null(T))
|
||||
p->fini ();
|
||||
thiz ()->destroy (p);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
inline const T* operator-> (void) const
|
||||
inline const Returned * get (void) const
|
||||
{
|
||||
return get ();
|
||||
return thiz ()->convert (get_stored ());
|
||||
}
|
||||
|
||||
static inline const Returned* convert (const Stored *p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
hb_face_t *face;
|
||||
mutable T *instance;
|
||||
/* Must only have one pointer. */
|
||||
mutable Stored *instance;
|
||||
};
|
||||
|
||||
/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
|
||||
template <typename T>
|
||||
struct hb_table_lazy_loader_t
|
||||
{
|
||||
inline void init (hb_face_t *face_)
|
||||
{
|
||||
face = face_;
|
||||
blob = nullptr;
|
||||
}
|
||||
/* Specializations. */
|
||||
|
||||
inline void fini (void)
|
||||
template <unsigned int WheresFace, typename T>
|
||||
struct hb_lazy_loader_t : hb_base_lazy_loader_t<WheresFace, hb_lazy_loader_t<WheresFace, T>, T>
|
||||
{
|
||||
static inline T *create (hb_face_t *face)
|
||||
{
|
||||
hb_blob_destroy (blob);
|
||||
if (unlikely (!face))
|
||||
return const_cast<T *> (&Null(T));
|
||||
T *p = (T *) calloc (1, sizeof (T));
|
||||
if (unlikely (!p))
|
||||
p = const_cast<T *> (&Null(T));
|
||||
else
|
||||
p->init (face);
|
||||
return p;
|
||||
}
|
||||
static inline void destroy (T *p)
|
||||
{
|
||||
if (p != &Null(T))
|
||||
{
|
||||
p->fini();
|
||||
free (p);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int WheresFace, typename T>
|
||||
struct hb_table_lazy_loader_t : hb_base_lazy_loader_t<WheresFace, hb_table_lazy_loader_t<WheresFace, T>, T, hb_blob_t>
|
||||
{
|
||||
static inline hb_blob_t *create (hb_face_t *face)
|
||||
{
|
||||
if (unlikely (!face))
|
||||
return hb_blob_get_empty ();
|
||||
return hb_sanitize_context_t ().reference_table<T> (face);
|
||||
}
|
||||
static inline void destroy (hb_blob_t *p)
|
||||
{
|
||||
hb_blob_destroy (p);
|
||||
}
|
||||
static inline const T* convert (const hb_blob_t *blob)
|
||||
{
|
||||
return blob->as<T> ();
|
||||
}
|
||||
|
||||
inline hb_blob_t* get_blob (void) const
|
||||
{
|
||||
retry:
|
||||
hb_blob_t *b = (hb_blob_t *) hb_atomic_ptr_get (&blob);
|
||||
if (unlikely (!b))
|
||||
{
|
||||
b = OT::hb_sanitize_context_t().reference_table<T> (face);
|
||||
if (!hb_atomic_ptr_cmpexch (&blob, nullptr, b))
|
||||
{
|
||||
hb_blob_destroy (b);
|
||||
goto retry;
|
||||
}
|
||||
blob = b;
|
||||
}
|
||||
return b;
|
||||
return this->get_stored ();
|
||||
}
|
||||
|
||||
inline const T* get (void) const
|
||||
{
|
||||
hb_blob_t *b = get_blob ();
|
||||
return b->as<T> ();
|
||||
}
|
||||
|
||||
inline const T* operator-> (void) const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
private:
|
||||
hb_face_t *face;
|
||||
mutable hb_blob_t *blob;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_MACHINERY_PRIVATE_HH */
|
||||
|
|
|
@ -157,8 +157,6 @@ hb_map_allocation_successful (const hb_map_t *map)
|
|||
*
|
||||
*
|
||||
*
|
||||
* Return value:
|
||||
*
|
||||
* Since: 1.7.7
|
||||
**/
|
||||
void
|
||||
|
@ -188,7 +186,7 @@ hb_map_get (const hb_map_t *map,
|
|||
/**
|
||||
* hb_map_del:
|
||||
* @map: a map.
|
||||
* @codepoint:
|
||||
* @key:
|
||||
*
|
||||
*
|
||||
*
|
||||
|
@ -204,7 +202,7 @@ hb_map_del (hb_map_t *map,
|
|||
/**
|
||||
* hb_map_has:
|
||||
* @map: a map.
|
||||
* @codepoint:
|
||||
* @key:
|
||||
*
|
||||
*
|
||||
*
|
||||
|
|
|
@ -47,14 +47,14 @@ struct hb_reference_count_t
|
|||
{
|
||||
hb_atomic_int_t ref_count;
|
||||
|
||||
inline void init (int v) { ref_count.set_unsafe (v); }
|
||||
inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
|
||||
inline void init (int v) { ref_count.set_relaxed (v); }
|
||||
inline int get_relaxed (void) const { return ref_count.get_relaxed (); }
|
||||
inline int inc (void) { return ref_count.inc (); }
|
||||
inline int dec (void) { return ref_count.dec (); }
|
||||
inline void fini (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
|
||||
inline void fini (void) { ref_count.set_relaxed (HB_REFERENCE_COUNT_POISON_VALUE); }
|
||||
|
||||
inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
|
||||
inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; }
|
||||
inline bool is_inert (void) const { return ref_count.get_relaxed () == HB_REFERENCE_COUNT_INERT_VALUE; }
|
||||
inline bool is_valid (void) const { return ref_count.get_relaxed () > 0; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -111,7 +111,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.get_unsafe () : 0);
|
||||
obj ? obj->header.ref_count.get_relaxed () : 0);
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
|
|
|
@ -421,7 +421,7 @@ struct cff2
|
|||
}
|
||||
}
|
||||
|
||||
globalSubrs = &OT::StructAtOffset<Subrs> (cff2, cff2->topDict + cff2->topDictSize);
|
||||
globalSubrs = &StructAtOffset<Subrs> (cff2, cff2->topDict + cff2->topDictSize);
|
||||
varStore = &top.vstoreOffset (cff2);
|
||||
charStrings = &top.charStringsOffset (cff2);
|
||||
fdArray = &top.FDArrayOffset (cff2);
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
*/
|
||||
#define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
|
||||
|
||||
#ifndef HB_MAX_UNICODE_CODEPOINT_VALUE
|
||||
#define HB_MAX_UNICODE_CODEPOINT_VALUE 0x10FFFF
|
||||
#endif
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
@ -437,8 +440,10 @@ struct CmapSubtableLongSegmented
|
|||
{
|
||||
for (unsigned int i = 0; i < this->groups.len; i++) {
|
||||
hb_set_add_range (out,
|
||||
this->groups[i].startCharCode,
|
||||
this->groups[i].endCharCode);
|
||||
MIN ((unsigned int) this->groups[i].startCharCode,
|
||||
(unsigned int) HB_MAX_UNICODE_CODEPOINT_VALUE),
|
||||
MIN ((unsigned int) this->groups[i].endCharCode,
|
||||
(unsigned int) HB_MAX_UNICODE_CODEPOINT_VALUE));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,11 +45,13 @@ struct hb_ot_font_t
|
|||
OT::cmap::accelerator_t cmap;
|
||||
OT::hmtx::accelerator_t h_metrics;
|
||||
OT::vmtx::accelerator_t v_metrics;
|
||||
OT::hb_lazy_loader_t<OT::glyf::accelerator_t> glyf;
|
||||
OT::hb_lazy_loader_t<OT::cff2::accelerator_t> cff2;
|
||||
OT::hb_lazy_loader_t<OT::CBDT::accelerator_t> cbdt;
|
||||
OT::hb_lazy_loader_t<OT::post::accelerator_t> post;
|
||||
OT::hb_lazy_loader_t<OT::kern::accelerator_t> kern;
|
||||
|
||||
hb_face_t *face; /* MUST be before the lazy loaders. */
|
||||
hb_lazy_loader_t<1, OT::glyf::accelerator_t> glyf;
|
||||
hb_lazy_loader_t<2, OT::CBDT::accelerator_t> cbdt;
|
||||
hb_lazy_loader_t<3, OT::post::accelerator_t> post;
|
||||
hb_lazy_loader_t<4, OT::kern::accelerator_t> kern;
|
||||
hb_lazy_loader_t<5, OT::kern::accelerator_t> cff2;
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,10 +66,11 @@ _hb_ot_font_create (hb_face_t *face)
|
|||
ot_font->cmap.init (face);
|
||||
ot_font->h_metrics.init (face);
|
||||
ot_font->v_metrics.init (face, ot_font->h_metrics.ascender - ot_font->h_metrics.descender); /* TODO Can we do this lazily? */
|
||||
ot_font->glyf.init (face);
|
||||
ot_font->cbdt.init (face);
|
||||
ot_font->post.init (face);
|
||||
ot_font->kern.init (face);
|
||||
ot_font->face = face;
|
||||
ot_font->glyf.init ();
|
||||
ot_font->cbdt.init ();
|
||||
ot_font->post.init ();
|
||||
ot_font->kern.init ();
|
||||
|
||||
return ot_font;
|
||||
}
|
||||
|
|
|
@ -45,8 +45,10 @@
|
|||
/*
|
||||
* The maximum number of times a lookup can be applied during shaping.
|
||||
* Used to limit the number of iterations of the closure algorithm.
|
||||
* This must be larger than the number of times add_pause() is
|
||||
* called in a collect_features call of any shaper.
|
||||
*/
|
||||
#define HB_CLOSURE_MAX_STAGES 8
|
||||
#define HB_CLOSURE_MAX_STAGES 32
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -188,6 +190,11 @@ struct IndexArray : ArrayOf<Index>
|
|||
}
|
||||
return this->len;
|
||||
}
|
||||
|
||||
inline void add_indexes_to (hb_set_t* output /* OUT */) const
|
||||
{
|
||||
output->add_array (arrayZ, len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -206,6 +213,8 @@ struct LangSys
|
|||
unsigned int *feature_count /* IN/OUT */,
|
||||
unsigned int *feature_indexes /* OUT */) const
|
||||
{ return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
|
||||
inline void add_feature_indexes_to (hb_set_t *feature_indexes) const
|
||||
{ featureIndex.add_indexes_to (feature_indexes); }
|
||||
|
||||
inline bool has_required_feature (void) const { return reqFeatureIndex != 0xFFFFu; }
|
||||
inline unsigned int get_required_feature_index (void) const
|
||||
|
@ -485,20 +494,6 @@ struct FeatureParams
|
|||
return Null(FeatureParamsSize);
|
||||
}
|
||||
|
||||
inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
|
||||
{
|
||||
if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
|
||||
return u.stylisticSet;
|
||||
return Null(FeatureParamsStylisticSet);
|
||||
}
|
||||
|
||||
inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
|
||||
{
|
||||
if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
|
||||
return u.characterVariants;
|
||||
return Null(FeatureParamsCharacterVariants);
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
FeatureParamsSize size;
|
||||
|
|
|
@ -171,18 +171,18 @@ struct hb_ot_layout_t
|
|||
const struct OT::GSUB *gsub;
|
||||
const struct OT::GPOS *gpos;
|
||||
|
||||
/* TODO Move the following out of this struct. */
|
||||
OT::hb_table_lazy_loader_t<struct OT::BASE> base;
|
||||
OT::hb_table_lazy_loader_t<struct OT::MATH> math;
|
||||
OT::hb_table_lazy_loader_t<struct OT::fvar> fvar;
|
||||
OT::hb_table_lazy_loader_t<struct OT::avar> avar;
|
||||
OT::hb_table_lazy_loader_t<struct AAT::morx> morx;
|
||||
|
||||
unsigned int gsub_lookup_count;
|
||||
unsigned int gpos_lookup_count;
|
||||
|
||||
hb_ot_layout_lookup_accelerator_t *gsub_accels;
|
||||
hb_ot_layout_lookup_accelerator_t *gpos_accels;
|
||||
|
||||
/* TODO Move the following out of this struct. */
|
||||
hb_face_t *face; /* MUST be before the lazy loaders. */
|
||||
hb_table_lazy_loader_t<1, struct OT::MATH> math;
|
||||
hb_table_lazy_loader_t<2, struct OT::fvar> fvar;
|
||||
hb_table_lazy_loader_t<3, struct OT::avar> avar;
|
||||
hb_table_lazy_loader_t<4, struct AAT::morx> morx;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -54,19 +54,20 @@ _hb_ot_layout_create (hb_face_t *face)
|
|||
if (unlikely (!layout))
|
||||
return nullptr;
|
||||
|
||||
layout->gdef_blob = OT::hb_sanitize_context_t().reference_table<OT::GDEF> (face);
|
||||
layout->gdef_blob = hb_sanitize_context_t ().reference_table<OT::GDEF> (face);
|
||||
layout->gdef = layout->gdef_blob->as<OT::GDEF> ();
|
||||
|
||||
layout->gsub_blob = OT::hb_sanitize_context_t().reference_table<OT::GSUB> (face);
|
||||
layout->gsub_blob = hb_sanitize_context_t ().reference_table<OT::GSUB> (face);
|
||||
layout->gsub = layout->gsub_blob->as<OT::GSUB> ();
|
||||
|
||||
layout->gpos_blob = OT::hb_sanitize_context_t().reference_table<OT::GPOS> (face);
|
||||
layout->gpos_blob = hb_sanitize_context_t ().reference_table<OT::GPOS> (face);
|
||||
layout->gpos = layout->gpos_blob->as<OT::GPOS> ();
|
||||
|
||||
layout->math.init (face);
|
||||
layout->fvar.init (face);
|
||||
layout->avar.init (face);
|
||||
layout->morx.init (face);
|
||||
layout->face = face;
|
||||
layout->math.init ();
|
||||
layout->fvar.init ();
|
||||
layout->avar.init ();
|
||||
layout->morx.init ();
|
||||
|
||||
{
|
||||
/*
|
||||
|
@ -520,6 +521,19 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face,
|
|||
return l.has_required_feature ();
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ot_layout_language_add_feature_indexes_to (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
hb_set_t *feature_indexes /* OUT */)
|
||||
{
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
|
||||
l.add_feature_indexes_to (feature_indexes);
|
||||
}
|
||||
|
||||
|
||||
unsigned int
|
||||
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
|
@ -658,13 +672,12 @@ _hb_ot_layout_collect_lookups_lookups (hb_face_t *face,
|
|||
}
|
||||
|
||||
static void
|
||||
_hb_ot_layout_collect_lookups_features (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *visited_features,
|
||||
hb_set_t *lookup_indexes /* OUT */)
|
||||
_hb_ot_layout_collect_features_features (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_index,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *feature_indexes /* OUT */)
|
||||
{
|
||||
if (!features)
|
||||
{
|
||||
|
@ -674,42 +687,15 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face,
|
|||
script_index,
|
||||
language_index,
|
||||
&required_feature_index,
|
||||
nullptr)
|
||||
&& !visited_features->has (required_feature_index))
|
||||
{
|
||||
_hb_ot_layout_collect_lookups_lookups (face,
|
||||
table_tag,
|
||||
required_feature_index,
|
||||
lookup_indexes);
|
||||
visited_features->add (required_feature_index);
|
||||
}
|
||||
nullptr))
|
||||
feature_indexes->add (required_feature_index);
|
||||
|
||||
/* All features */
|
||||
unsigned int feature_indices[32];
|
||||
unsigned int offset, len;
|
||||
|
||||
offset = 0;
|
||||
do {
|
||||
len = ARRAY_LENGTH (feature_indices);
|
||||
hb_ot_layout_language_get_feature_indexes (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
offset, &len,
|
||||
feature_indices);
|
||||
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
{
|
||||
if (visited_features->has (feature_indices[i])) continue;
|
||||
_hb_ot_layout_collect_lookups_lookups (face,
|
||||
table_tag,
|
||||
feature_indices[i],
|
||||
lookup_indexes);
|
||||
visited_features->add (feature_indices[i]);
|
||||
}
|
||||
|
||||
offset += len;
|
||||
} while (len == ARRAY_LENGTH (feature_indices));
|
||||
_hb_ot_layout_language_add_feature_indexes_to (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
feature_indexes);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -722,30 +708,25 @@ _hb_ot_layout_collect_lookups_features (hb_face_t *face,
|
|||
language_index,
|
||||
*features,
|
||||
&feature_index))
|
||||
_hb_ot_layout_collect_lookups_lookups (face,
|
||||
table_tag,
|
||||
feature_index,
|
||||
lookup_indexes);
|
||||
feature_indexes->add (feature_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_hb_ot_layout_collect_lookups_languages (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *visited_features,
|
||||
hb_set_t *lookup_indexes /* OUT */)
|
||||
_hb_ot_layout_collect_features_languages (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *feature_indexes /* OUT */)
|
||||
{
|
||||
_hb_ot_layout_collect_lookups_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
|
||||
features,
|
||||
visited_features,
|
||||
lookup_indexes);
|
||||
_hb_ot_layout_collect_features_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX,
|
||||
features,
|
||||
feature_indexes);
|
||||
|
||||
if (!languages)
|
||||
{
|
||||
|
@ -755,13 +736,12 @@ _hb_ot_layout_collect_lookups_languages (hb_face_t *face,
|
|||
script_index,
|
||||
0, nullptr, nullptr);
|
||||
for (unsigned int language_index = 0; language_index < count; language_index++)
|
||||
_hb_ot_layout_collect_lookups_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
features,
|
||||
visited_features,
|
||||
lookup_indexes);
|
||||
_hb_ot_layout_collect_features_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
features,
|
||||
feature_indexes);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -773,13 +753,58 @@ _hb_ot_layout_collect_lookups_languages (hb_face_t *face,
|
|||
script_index,
|
||||
*languages,
|
||||
&language_index))
|
||||
_hb_ot_layout_collect_lookups_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
features,
|
||||
visited_features,
|
||||
lookup_indexes);
|
||||
_hb_ot_layout_collect_features_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
language_index,
|
||||
features,
|
||||
feature_indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_layout_collect_features:
|
||||
*
|
||||
* Since: 1.8.5
|
||||
**/
|
||||
void
|
||||
hb_ot_layout_collect_features (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *scripts,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *feature_indexes /* OUT */)
|
||||
{
|
||||
if (!scripts)
|
||||
{
|
||||
/* All scripts */
|
||||
unsigned int count = hb_ot_layout_table_get_script_tags (face,
|
||||
table_tag,
|
||||
0, nullptr, nullptr);
|
||||
for (unsigned int script_index = 0; script_index < count; script_index++)
|
||||
_hb_ot_layout_collect_features_languages (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
languages,
|
||||
features,
|
||||
feature_indexes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; *scripts; scripts++)
|
||||
{
|
||||
unsigned int script_index;
|
||||
if (hb_ot_layout_table_find_script (face,
|
||||
table_tag,
|
||||
*scripts,
|
||||
&script_index))
|
||||
_hb_ot_layout_collect_features_languages (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
languages,
|
||||
features,
|
||||
feature_indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -797,40 +822,10 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
|
|||
const hb_tag_t *features,
|
||||
hb_set_t *lookup_indexes /* OUT */)
|
||||
{
|
||||
hb_auto_t<hb_set_t> visited_features;
|
||||
if (!scripts)
|
||||
{
|
||||
/* All scripts */
|
||||
unsigned int count = hb_ot_layout_table_get_script_tags (face,
|
||||
table_tag,
|
||||
0, nullptr, nullptr);
|
||||
for (unsigned int script_index = 0; script_index < count; script_index++)
|
||||
_hb_ot_layout_collect_lookups_languages (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
languages,
|
||||
features,
|
||||
&visited_features,
|
||||
lookup_indexes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; *scripts; scripts++)
|
||||
{
|
||||
unsigned int script_index;
|
||||
if (hb_ot_layout_table_find_script (face,
|
||||
table_tag,
|
||||
*scripts,
|
||||
&script_index))
|
||||
_hb_ot_layout_collect_lookups_languages (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
languages,
|
||||
features,
|
||||
&visited_features,
|
||||
lookup_indexes);
|
||||
}
|
||||
}
|
||||
hb_auto_t<hb_set_t> feature_indexes;
|
||||
hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes);
|
||||
for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID; hb_set_next (&feature_indexes, &feature_index);)
|
||||
_hb_ot_layout_collect_lookups_lookups (face, table_tag, feature_index, lookup_indexes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1035,24 +1030,6 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
|
|||
OT::GPOS::position_finish_offsets (font, buffer);
|
||||
}
|
||||
|
||||
static const OT::FeatureParams&
|
||||
_get_gsubgpos_matched_feature_params (hb_face_t *face, hb_tag_t feature)
|
||||
{
|
||||
const OT::GSUB &gsub = _get_gsub (face);
|
||||
unsigned int gsub_num_features = gsub.get_feature_count ();
|
||||
for (unsigned int i = 0; i < gsub_num_features; i++)
|
||||
if (feature == gsub.get_feature_tag (i))
|
||||
return gsub.get_feature (i).get_feature_params ();
|
||||
|
||||
const OT::GPOS &gpos = _get_gpos (face);
|
||||
unsigned int gpos_num_features = gpos.get_feature_count ();
|
||||
for (unsigned int i = 0; i < gpos_num_features; i++)
|
||||
if (feature == gpos.get_feature_tag (i))
|
||||
return gpos.get_feature (i).get_feature_params ();
|
||||
|
||||
return Null (OT::FeatureParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_layout_get_size_params:
|
||||
*
|
||||
|
@ -1103,74 +1080,6 @@ hb_ot_layout_get_size_params (hb_face_t *face,
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_layout_get_feature_name_ids:
|
||||
* @face: #hb_face_t to work upon
|
||||
* @feature: ssXX and cvXX tag
|
||||
* @label_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
|
||||
* for a user-interface label for this feature. (May be NULL.)
|
||||
* @tooltip_id: (out) (allow-none): The ‘name’ table name ID that specifies a string
|
||||
* that an application can use for tooltip text for this
|
||||
* feature. (May be NULL.)
|
||||
* @sample_id: (out) (allow-none): The ‘name’ table name ID that specifies sample text
|
||||
* that illustrates the effect of this feature. (May be NULL.)
|
||||
* @num_named_parameters: (out) (allow-none): Number of named parameters. (May be zero.)
|
||||
* @first_param_id: (out) (allow-none): The first ‘name’ table name ID used to specify
|
||||
* strings for user-interface labels for the feature
|
||||
* parameters. (Must be zero if numParameters is zero.)
|
||||
*
|
||||
* Return value: true if could find any feature with the tag, false otherwise
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_ot_layout_get_feature_name_ids (hb_face_t *face,
|
||||
hb_tag_t feature,
|
||||
unsigned int *label_id, /* OUT. May be nullptr */
|
||||
unsigned int *tooltip_id, /* OUT. May be nullptr */
|
||||
unsigned int *sample_id, /* OUT. May be nullptr */
|
||||
unsigned int *num_named_parameters, /* OUT. May be nullptr */
|
||||
unsigned int *first_param_id /* OUT. May be nullptr */)
|
||||
{
|
||||
const OT::FeatureParams &feature_params =
|
||||
_get_gsubgpos_matched_feature_params (face, feature);
|
||||
if (&feature_params != &Null (OT::FeatureParams))
|
||||
{
|
||||
const OT::FeatureParamsStylisticSet& ss_params =
|
||||
feature_params.get_stylistic_set_params (feature);
|
||||
if (&ss_params != &Null (OT::FeatureParamsStylisticSet)) /* ssXX */
|
||||
{
|
||||
#define PARAM(a, A) if (a) *a = A
|
||||
PARAM(label_id, ss_params.uiNameID);
|
||||
// ssXX features don't have the rest
|
||||
PARAM(tooltip_id, 0);
|
||||
PARAM(sample_id, 0);
|
||||
PARAM(num_named_parameters, 0);
|
||||
PARAM(first_param_id, 0);
|
||||
return true;
|
||||
}
|
||||
const OT::FeatureParamsCharacterVariants& cv_params =
|
||||
feature_params.get_character_variants_params (feature);
|
||||
if (&cv_params != &Null (OT::FeatureParamsCharacterVariants)) /* cvXX */
|
||||
{
|
||||
PARAM(label_id, cv_params.featUILableNameID);
|
||||
PARAM(tooltip_id, cv_params.featUITooltipTextNameID);
|
||||
PARAM(sample_id, cv_params.sampleTextNameID);
|
||||
PARAM(num_named_parameters, cv_params.numNamedParameters);
|
||||
PARAM(first_param_id, cv_params.firstParamUILabelNameID);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
PARAM(label_id, 0);
|
||||
PARAM(tooltip_id, 0);
|
||||
PARAM(sample_id, 0);
|
||||
PARAM(num_named_parameters, 0);
|
||||
PARAM(first_param_id, 0);
|
||||
#undef PARAM
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parts of different types are implemented here such that they have direct
|
||||
|
@ -1208,7 +1117,7 @@ struct GPOSProxy
|
|||
|
||||
|
||||
struct hb_get_subtables_context_t :
|
||||
OT::hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
|
||||
hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
|
||||
{
|
||||
template <typename Type>
|
||||
static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
|
||||
|
|
|
@ -194,6 +194,13 @@ HB_EXTERN unsigned int
|
|||
hb_ot_layout_table_get_lookup_count (hb_face_t *face,
|
||||
hb_tag_t table_tag);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_layout_collect_features (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *scripts,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *feature_indexes /* OUT */);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_layout_collect_lookups (hb_face_t *face,
|
||||
|
@ -322,14 +329,6 @@ hb_ot_layout_get_size_params (hb_face_t *face,
|
|||
unsigned int *range_start, /* OUT. May be NULL */
|
||||
unsigned int *range_end /* OUT. May be NULL */);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_get_feature_name_ids (hb_face_t *face,
|
||||
hb_tag_t feature,
|
||||
unsigned int *label_id /* OUT. May be NULL */,
|
||||
unsigned int *tooltip_id /* OUT. May be NULL */,
|
||||
unsigned int *sample_id /* OUT. May be NULL */,
|
||||
unsigned int *num_named_parameters /* OUT. May be NULL */,
|
||||
unsigned int *first_param_id /* OUT. May be NULL */);
|
||||
|
||||
/*
|
||||
* BASE
|
||||
|
|
|
@ -79,12 +79,12 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
|
|||
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
||||
hb_stable_sort (&glyphs[0], num_glyphs, (int(*)(const OT::GlyphID*, const OT::GlyphID *)) OT::GlyphID::cmp, &substitutes[0]);
|
||||
|
||||
OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs);
|
||||
OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
|
||||
Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs);
|
||||
Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
|
||||
|
||||
/* Each glyph takes four bytes max, and there's some overhead. */
|
||||
char buf[(SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1) * 4 + 128];
|
||||
OT::hb_serialize_context_t c (buf, sizeof (buf));
|
||||
hb_serialize_context_t c (buf, sizeof (buf));
|
||||
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
|
||||
bool ret = lookup->serialize_single (&c,
|
||||
OT::LookupFlag::IgnoreMarks,
|
||||
|
@ -155,15 +155,15 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
|
|||
if (!num_ligatures)
|
||||
return nullptr;
|
||||
|
||||
OT::Supplier<OT::GlyphID> first_glyphs_supplier (first_glyphs, num_first_glyphs);
|
||||
OT::Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligature_per_first_glyph_count_list, num_first_glyphs);
|
||||
OT::Supplier<OT::GlyphID> ligatures_supplier (ligature_list, num_ligatures);
|
||||
OT::Supplier<unsigned int > component_count_supplier (component_count_list, num_ligatures);
|
||||
OT::Supplier<OT::GlyphID> component_supplier (component_list, num_ligatures);
|
||||
Supplier<OT::GlyphID> first_glyphs_supplier (first_glyphs, num_first_glyphs);
|
||||
Supplier<unsigned int > ligature_per_first_glyph_count_supplier (ligature_per_first_glyph_count_list, num_first_glyphs);
|
||||
Supplier<OT::GlyphID> ligatures_supplier (ligature_list, num_ligatures);
|
||||
Supplier<unsigned int > component_count_supplier (component_count_list, num_ligatures);
|
||||
Supplier<OT::GlyphID> component_supplier (component_list, num_ligatures);
|
||||
|
||||
/* 16 bytes per ligature ought to be enough... */
|
||||
char buf[ARRAY_LENGTH_CONST (ligature_list) * 16 + 128];
|
||||
OT::hb_serialize_context_t c (buf, sizeof (buf));
|
||||
hb_serialize_context_t c (buf, sizeof (buf));
|
||||
OT::SubstLookup *lookup = c.start_serialize<OT::SubstLookup> ();
|
||||
bool ret = lookup->serialize_ligature (&c,
|
||||
OT::LookupFlag::IgnoreMarks,
|
||||
|
|
|
@ -300,7 +300,9 @@ static const hb_codepoint_t ra_chars[] = {
|
|||
0x0CB0u, /* Kannada */
|
||||
0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */
|
||||
|
||||
0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */
|
||||
0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */
|
||||
|
||||
0x179Au, /* Khmer */
|
||||
};
|
||||
|
||||
static inline bool
|
||||
|
|
|
@ -251,10 +251,10 @@ struct indic_shape_plan_t
|
|||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
|
||||
inline bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
|
||||
{
|
||||
hb_codepoint_t glyph = virama_glyph;
|
||||
if (unlikely (virama_glyph == (hb_codepoint_t) -1))
|
||||
hb_codepoint_t glyph = virama_glyph.get_relaxed ();
|
||||
if (unlikely (glyph == (hb_codepoint_t) -1))
|
||||
{
|
||||
if (!config->virama || !font->get_nominal_glyph (config->virama, &glyph))
|
||||
glyph = 0;
|
||||
|
@ -262,8 +262,8 @@ struct indic_shape_plan_t
|
|||
* Maybe one day... */
|
||||
|
||||
/* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph
|
||||
* during shape planning... Instead, overwrite it here. It's safe. Don't worry! */
|
||||
virama_glyph = glyph;
|
||||
* during shape planning... Instead, overwrite it here. */
|
||||
virama_glyph.set_relaxed ((int) glyph);
|
||||
}
|
||||
|
||||
*pglyph = glyph;
|
||||
|
@ -273,7 +273,7 @@ struct indic_shape_plan_t
|
|||
const indic_config_t *config;
|
||||
|
||||
bool is_old_spec;
|
||||
mutable hb_codepoint_t virama_glyph;
|
||||
mutable hb_atomic_int_t virama_glyph;
|
||||
|
||||
would_substitute_feature_t rphf;
|
||||
would_substitute_feature_t pref;
|
||||
|
@ -298,7 +298,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
|
|||
}
|
||||
|
||||
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
|
||||
indic_plan->virama_glyph = (hb_codepoint_t) -1;
|
||||
indic_plan->virama_glyph.set_relaxed (-1);
|
||||
|
||||
/* Use zero-context would_substitute() matching for new-spec of the main
|
||||
* Indic scripts, and scripts with one spec only, but not for old-specs.
|
||||
|
@ -419,7 +419,7 @@ update_consonant_positions (const hb_ot_shape_plan_t *plan,
|
|||
return;
|
||||
|
||||
hb_codepoint_t virama;
|
||||
if (indic_plan->get_virama_glyph (font, &virama))
|
||||
if (indic_plan->load_virama_glyph (font, &virama))
|
||||
{
|
||||
hb_face_t *face = font->face;
|
||||
unsigned int count = buffer->len;
|
||||
|
@ -667,10 +667,10 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* last consonant.
|
||||
*
|
||||
* Reports suggest that in some scripts Uniscribe does this only if there
|
||||
* is *not* a Halant after last consonant already (eg. Kannada), while it
|
||||
* does it unconditionally in other scripts (eg. Malayalam, Bengali). We
|
||||
* don't currently know about other scripts, so we whitelist Malayalam and
|
||||
* Bengali for now.
|
||||
* is *not* a Halant after last consonant already. We know that is the
|
||||
* case for Kannada, while it reorders unconditionally in other scripts,
|
||||
* eg. Malayalam, Bengali, and Devanagari. We don't currently know about
|
||||
* other scripts, so we blacklist Kannada.
|
||||
*
|
||||
* Kannada test case:
|
||||
* U+0C9A,U+0CCD,U+0C9A,U+0CCD
|
||||
|
@ -681,15 +681,19 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D
|
||||
* With lohit-ttf-20121122/Lohit-Malayalam.ttf
|
||||
*
|
||||
* Bengali test case
|
||||
* Bengali test case:
|
||||
* U+0998,U+09CD,U+09AF,U+09CD
|
||||
* With Windows XP vrinda.ttf
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/1073
|
||||
*
|
||||
* Devanagari test case:
|
||||
* U+091F,U+094D,U+0930,U+094D
|
||||
* With chandas.ttf
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/1071
|
||||
*/
|
||||
if (indic_plan->is_old_spec)
|
||||
{
|
||||
bool disallow_double_halants = buffer->props.script != HB_SCRIPT_MALAYALAM &&
|
||||
buffer->props.script != HB_SCRIPT_BENGALI;
|
||||
bool disallow_double_halants = buffer->props.script == HB_SCRIPT_KANNADA;
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if (info[i].indic_category() == OT_H)
|
||||
{
|
||||
|
@ -1036,9 +1040,11 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* phase, and that might have messed up our properties. Recover
|
||||
* from a particular case of that where we're fairly sure that a
|
||||
* class of OT_H is desired but has been lost. */
|
||||
if (indic_plan->virama_glyph)
|
||||
/* We don't call load_virama_glyph(), since we know it's already
|
||||
* loaded. */
|
||||
hb_codepoint_t virama_glyph = indic_plan->virama_glyph.get_relaxed ();
|
||||
if (virama_glyph)
|
||||
{
|
||||
unsigned int virama_glyph = indic_plan->virama_glyph;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
if (info[i].codepoint == virama_glyph &&
|
||||
_hb_glyph_info_ligated (&info[i]) &&
|
||||
|
|
|
@ -42,7 +42,7 @@ khmer_features[] =
|
|||
{
|
||||
/*
|
||||
* Basic features.
|
||||
* These features are applied in order, one at a time, after initial_reordering.
|
||||
* These features are applied in order, one at a time, after reordering.
|
||||
*/
|
||||
{HB_TAG('p','r','e','f'), F_NONE},
|
||||
{HB_TAG('b','l','w','f'), F_NONE},
|
||||
|
@ -51,9 +51,7 @@ khmer_features[] =
|
|||
{HB_TAG('c','f','a','r'), F_NONE},
|
||||
/*
|
||||
* Other features.
|
||||
* These features are applied all at once, after final_reordering.
|
||||
* Default Bengali font in Windows for example has intermixed
|
||||
* lookups for init,pres,abvs,blws features.
|
||||
* These features are applied all at once.
|
||||
*/
|
||||
{HB_TAG('p','r','e','s'), F_GLOBAL},
|
||||
{HB_TAG('a','b','v','s'), F_GLOBAL},
|
||||
|
@ -92,13 +90,9 @@ setup_syllables (const hb_ot_shape_plan_t *plan,
|
|||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
initial_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
reorder (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
|
@ -111,20 +105,28 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
|
|||
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
map->add_gsub_pause (reorder);
|
||||
|
||||
/* Testing suggests that Uniscribe does NOT pause between basic
|
||||
* features. Test with KhmerUI.ttf and the following three
|
||||
* sequences:
|
||||
*
|
||||
* U+1789,U+17BC
|
||||
* U+1789,U+17D2,U+1789
|
||||
* U+1789,U+17D2,U+1789,U+17BC
|
||||
*
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/974
|
||||
*/
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
/* The Indic specs do not require ccmp, but we apply it here since if
|
||||
* there is a use of it, it's typically at the beginning. */
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
|
||||
|
||||
unsigned int i = 0;
|
||||
map->add_gsub_pause (initial_reordering);
|
||||
for (; i < KHMER_BASIC_FEATURES; i++) {
|
||||
map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
|
||||
map->add_gsub_pause (nullptr);
|
||||
}
|
||||
map->add_gsub_pause (final_reordering);
|
||||
|
||||
map->add_gsub_pause (clear_syllables);
|
||||
|
||||
for (; i < KHMER_NUM_FEATURES; i++) {
|
||||
map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
|
||||
}
|
||||
|
@ -132,7 +134,6 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
|
|||
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
|
||||
map->add_global_bool_feature (HB_TAG('c','l','i','g'));
|
||||
|
||||
map->add_gsub_pause (clear_syllables);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -264,162 +265,58 @@ setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
buffer->unsafe_to_break (start, end);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_khmer_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
|
||||
{
|
||||
int a = pa->khmer_position();
|
||||
int b = pb->khmer_position();
|
||||
|
||||
return a < b ? -1 : a == b ? 0 : +1;
|
||||
}
|
||||
|
||||
|
||||
/* Rules from:
|
||||
* https://docs.microsoft.com/en-us/typography/script-development/devanagari */
|
||||
|
||||
static void
|
||||
initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
reorder_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_face_t *face,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
/* 1. Khmer shaping assumes that a syllable will begin with a Cons, IndV, or Number. */
|
||||
|
||||
/* The first consonant is always the base. */
|
||||
unsigned int base = start;
|
||||
info[base].khmer_position() = POS_BASE_C;
|
||||
|
||||
/* Mark all subsequent consonants as below. */
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if (is_consonant_or_vowel (info[i]))
|
||||
info[i].khmer_position() = POS_BELOW_C;
|
||||
|
||||
/* Mark final consonants. A final consonant is one appearing after a matra,
|
||||
* like in Khmer. */
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if (info[i].khmer_category() == OT_M) {
|
||||
for (unsigned int j = i + 1; j < end; j++)
|
||||
if (is_consonant_or_vowel (info[j])) {
|
||||
info[j].khmer_position() = POS_FINAL_C;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Attach misc marks to previous char to move with them. */
|
||||
/* Setup masks. */
|
||||
{
|
||||
khmer_position_t last_pos = POS_START;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
{
|
||||
if ((FLAG_UNSAFE (info[i].khmer_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_Coeng))))
|
||||
{
|
||||
info[i].khmer_position() = last_pos;
|
||||
if (unlikely (info[i].khmer_category() == OT_Coeng &&
|
||||
info[i].khmer_position() == POS_PRE_M))
|
||||
{
|
||||
/*
|
||||
* Uniscribe doesn't move the Halant with Left Matra.
|
||||
* TEST: U+092B,U+093F,U+094DE
|
||||
* We follow. This is important for the Sinhala
|
||||
* U+0DDA split matra since it decomposes to U+0DD9,U+0DCA
|
||||
* where U+0DD9 is a left matra and U+0DCA is the virama.
|
||||
* We don't want to move the virama with the left matra.
|
||||
* TEST: U+0D9A,U+0DDA
|
||||
*/
|
||||
for (unsigned int j = i; j > start; j--)
|
||||
if (info[j - 1].khmer_position() != POS_PRE_M) {
|
||||
info[i].khmer_position() = info[j - 1].khmer_position();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (info[i].khmer_position() != POS_SMVD) {
|
||||
last_pos = (khmer_position_t) info[i].khmer_position();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* For post-base consonants let them own anything before them
|
||||
* since the last consonant or matra. */
|
||||
{
|
||||
unsigned int last = base;
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if (is_consonant_or_vowel (info[i]))
|
||||
{
|
||||
for (unsigned int j = last + 1; j < i; j++)
|
||||
if (info[j].khmer_position() < POS_SMVD)
|
||||
info[j].khmer_position() = info[i].khmer_position();
|
||||
last = i;
|
||||
} else if (info[i].khmer_category() == OT_M)
|
||||
last = i;
|
||||
}
|
||||
|
||||
{
|
||||
/* Use syllable() for sort accounting temporarily. */
|
||||
unsigned int syllable = info[start].syllable();
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
info[i].syllable() = i - start;
|
||||
|
||||
/* Sit tight, rock 'n roll! */
|
||||
hb_stable_sort (info + start, end - start, compare_khmer_order);
|
||||
/* Find base again */
|
||||
base = end;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
if (info[i].khmer_position() == POS_BASE_C)
|
||||
{
|
||||
base = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely (end - start >= 127))
|
||||
buffer->merge_clusters (start, end);
|
||||
else
|
||||
/* Note! syllable() is a one-byte field. */
|
||||
for (unsigned int i = base; i < end; i++)
|
||||
if (info[i].syllable() != 255)
|
||||
{
|
||||
unsigned int max = i;
|
||||
unsigned int j = start + info[i].syllable();
|
||||
while (j != i)
|
||||
{
|
||||
max = MAX (max, j);
|
||||
unsigned int next = start + info[j].syllable();
|
||||
info[j].syllable() = 255; /* So we don't process j later again. */
|
||||
j = next;
|
||||
}
|
||||
if (i != max)
|
||||
buffer->merge_clusters (i, max + 1);
|
||||
}
|
||||
|
||||
/* Put syllable back in. */
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
info[i].syllable() = syllable;
|
||||
}
|
||||
|
||||
/* Setup masks now */
|
||||
|
||||
{
|
||||
hb_mask_t mask;
|
||||
|
||||
/* Post-base */
|
||||
mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF];
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
hb_mask_t mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF];
|
||||
for (unsigned int i = start + 1; i < end; i++)
|
||||
info[i].mask |= mask;
|
||||
}
|
||||
|
||||
unsigned int pref_len = 2;
|
||||
if (khmer_plan->mask_array[PREF] && base + pref_len < end)
|
||||
unsigned int num_coengs = 0;
|
||||
for (unsigned int i = start + 1; i < end; i++)
|
||||
{
|
||||
/* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */
|
||||
for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
|
||||
hb_codepoint_t glyphs[2];
|
||||
for (unsigned int j = 0; j < pref_len; j++)
|
||||
glyphs[j] = info[i + j].codepoint;
|
||||
if (khmer_plan->pref.would_substitute (glyphs, pref_len, face))
|
||||
/* """
|
||||
* When a COENG + (Cons | IndV) combination are found (and subscript count
|
||||
* is less than two) the character combination is handled according to the
|
||||
* subscript type of the character following the COENG.
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* Subscript Type 2 - The COENG + RO characters are reordered to immediately
|
||||
* before the base glyph. Then the COENG + RO characters are assigned to have
|
||||
* the 'pref' OpenType feature applied to them.
|
||||
* """
|
||||
*/
|
||||
if (info[i].khmer_category() == OT_Coeng && num_coengs <= 2 && i + 1 < end)
|
||||
{
|
||||
num_coengs++;
|
||||
|
||||
if (info[i + 1].khmer_category() == OT_Ra)
|
||||
{
|
||||
for (unsigned int j = 0; j < pref_len; j++)
|
||||
info[i++].mask |= khmer_plan->mask_array[PREF];
|
||||
for (unsigned int j = 0; j < 2; j++)
|
||||
info[i + j].mask |= khmer_plan->mask_array[PREF];
|
||||
|
||||
/* Move the Coeng,Ro sequence to the start. */
|
||||
buffer->merge_clusters (start, i + 2);
|
||||
hb_glyph_info_t t0 = info[i];
|
||||
hb_glyph_info_t t1 = info[i + 1];
|
||||
memmove (&info[start + 2], &info[start], (i - start) * sizeof (info[0]));
|
||||
info[start] = t0;
|
||||
info[start + 1] = t1;
|
||||
|
||||
/* Mark the subsequent stuff with 'cfar'. Used in Khmer.
|
||||
* Read the feature spec.
|
||||
|
@ -428,12 +325,22 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* U+1784,U+17D2,U+1782,U+17D2,U+179A
|
||||
*/
|
||||
if (khmer_plan->mask_array[CFAR])
|
||||
for (; i < end; i++)
|
||||
info[i].mask |= khmer_plan->mask_array[CFAR];
|
||||
for (unsigned int j = i + 2; j < end; j++)
|
||||
info[j].mask |= khmer_plan->mask_array[CFAR];
|
||||
|
||||
break;
|
||||
num_coengs = 2; /* Done. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Reorder left matra piece. */
|
||||
else if (info[i].khmer_position() == POS_PRE_M)
|
||||
{
|
||||
/* Move to the start. */
|
||||
buffer->merge_clusters (start, i + 1);
|
||||
hb_glyph_info_t t = info[i];
|
||||
memmove (&info[start + 1], &info[start], (i - start) * sizeof (info[0]));
|
||||
info[start] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -448,7 +355,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
{
|
||||
case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
|
||||
case consonant_syllable:
|
||||
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
|
||||
reorder_consonant_syllable (plan, face, buffer, start, end);
|
||||
break;
|
||||
|
||||
case non_khmer_cluster:
|
||||
|
@ -518,263 +425,26 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||
}
|
||||
|
||||
static void
|
||||
initial_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
reorder (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
insert_dotted_circles (plan, font, buffer);
|
||||
|
||||
foreach_syllable (buffer, start, end)
|
||||
initial_reordering_syllable (plan, font->face, buffer, start, end);
|
||||
}
|
||||
|
||||
static void
|
||||
final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
||||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
|
||||
/* This function relies heavily on halant glyphs. Lots of ligation
|
||||
* and possibly multiple substitutions happened prior to this
|
||||
* phase, and that might have messed up our properties. Recover
|
||||
* from a particular case of that where we're fairly sure that a
|
||||
* class of OT_Coeng is desired but has been lost. */
|
||||
if (khmer_plan->virama_glyph)
|
||||
{
|
||||
unsigned int virama_glyph = khmer_plan->virama_glyph;
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
if (info[i].codepoint == virama_glyph &&
|
||||
_hb_glyph_info_ligated (&info[i]) &&
|
||||
_hb_glyph_info_multiplied (&info[i]))
|
||||
{
|
||||
/* This will make sure that this glyph passes is_coeng() test. */
|
||||
info[i].khmer_category() = OT_Coeng;
|
||||
_hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 4. Final reordering:
|
||||
*
|
||||
* After the localized forms and basic shaping forms GSUB features have been
|
||||
* applied (see below), the shaping engine performs some final glyph
|
||||
* reordering before applying all the remaining font features to the entire
|
||||
* syllable.
|
||||
*/
|
||||
|
||||
bool try_pref = !!khmer_plan->mask_array[PREF];
|
||||
|
||||
/* Find base again */
|
||||
unsigned int base;
|
||||
for (base = start; base < end; base++)
|
||||
if (info[base].khmer_position() >= POS_BASE_C)
|
||||
{
|
||||
if (try_pref && base + 1 < end)
|
||||
{
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0)
|
||||
{
|
||||
if (!(_hb_glyph_info_substituted (&info[i]) &&
|
||||
_hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
|
||||
{
|
||||
/* Ok, this was a 'pref' candidate but didn't form any.
|
||||
* Base is around here... */
|
||||
base = i;
|
||||
while (base < end && is_coeng (info[base]))
|
||||
base++;
|
||||
info[base].khmer_position() = POS_BASE_C;
|
||||
|
||||
try_pref = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (start < base && info[base].khmer_position() > POS_BASE_C)
|
||||
base--;
|
||||
break;
|
||||
}
|
||||
if (base == end && start < base &&
|
||||
is_one_of (info[base - 1], FLAG (OT_ZWJ)))
|
||||
base--;
|
||||
if (base < end)
|
||||
while (start < base &&
|
||||
is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_Coeng))))
|
||||
base--;
|
||||
|
||||
|
||||
/* o Reorder matras:
|
||||
*
|
||||
* If a pre-base matra character had been reordered before applying basic
|
||||
* features, the glyph can be moved closer to the main consonant based on
|
||||
* whether half-forms had been formed. Actual position for the matra is
|
||||
* defined as “after last standalone halant glyph, after initial matra
|
||||
* position and before the main consonant”. If ZWJ or ZWNJ follow this
|
||||
* halant, position is moved after it.
|
||||
*/
|
||||
|
||||
if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */
|
||||
{
|
||||
/* If we lost track of base, alas, position before last thingy. */
|
||||
unsigned int new_pos = base == end ? base - 2 : base - 1;
|
||||
|
||||
while (new_pos > start &&
|
||||
!(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_Coeng)))))
|
||||
new_pos--;
|
||||
|
||||
/* If we found no Halant we are done.
|
||||
* Otherwise only proceed if the Halant does
|
||||
* not belong to the Matra itself! */
|
||||
if (is_coeng (info[new_pos]) &&
|
||||
info[new_pos].khmer_position() != POS_PRE_M)
|
||||
{
|
||||
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
|
||||
if (new_pos + 1 < end && is_joiner (info[new_pos + 1]))
|
||||
new_pos++;
|
||||
}
|
||||
else
|
||||
new_pos = start; /* No move. */
|
||||
|
||||
if (start < new_pos && info[new_pos].khmer_position () != POS_PRE_M)
|
||||
{
|
||||
/* Now go see if there's actually any matras... */
|
||||
for (unsigned int i = new_pos; i > start; i--)
|
||||
if (info[i - 1].khmer_position () == POS_PRE_M)
|
||||
{
|
||||
unsigned int old_pos = i - 1;
|
||||
if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */
|
||||
base--;
|
||||
|
||||
hb_glyph_info_t tmp = info[old_pos];
|
||||
memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0]));
|
||||
info[new_pos] = tmp;
|
||||
|
||||
/* Note: this merge_clusters() is intentionally *after* the reordering.
|
||||
* Indic matra reordering is special and tricky... */
|
||||
buffer->merge_clusters (new_pos, MIN (end, base + 1));
|
||||
|
||||
new_pos--;
|
||||
}
|
||||
} else {
|
||||
for (unsigned int i = start; i < base; i++)
|
||||
if (info[i].khmer_position () == POS_PRE_M) {
|
||||
buffer->merge_clusters (i, MIN (end, base + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* o Reorder pre-base-reordering consonants:
|
||||
*
|
||||
* If a pre-base-reordering consonant is found, reorder it according to
|
||||
* the following rules:
|
||||
*/
|
||||
|
||||
if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */
|
||||
{
|
||||
for (unsigned int i = base + 1; i < end; i++)
|
||||
if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0)
|
||||
{
|
||||
/* 1. Only reorder a glyph produced by substitution during application
|
||||
* of the <pref> feature. (Note that a font may shape a Ra consonant with
|
||||
* the feature generally but block it in certain contexts.)
|
||||
*/
|
||||
/* Note: We just check that something got substituted. We don't check that
|
||||
* the <pref> feature actually did it...
|
||||
*
|
||||
* Reorder pref only if it ligated. */
|
||||
if (_hb_glyph_info_ligated_and_didnt_multiply (&info[i]))
|
||||
{
|
||||
/*
|
||||
* 2. Try to find a target position the same way as for pre-base matra.
|
||||
* If it is found, reorder pre-base consonant glyph.
|
||||
*
|
||||
* 3. If position is not found, reorder immediately before main
|
||||
* consonant.
|
||||
*/
|
||||
|
||||
unsigned int new_pos = base;
|
||||
while (new_pos > start &&
|
||||
!(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_Coeng))))
|
||||
new_pos--;
|
||||
|
||||
/* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a
|
||||
* split matra, it should be reordered to *before* the left part of such matra. */
|
||||
if (new_pos > start && info[new_pos - 1].khmer_category() == OT_M)
|
||||
{
|
||||
unsigned int old_pos = i;
|
||||
for (unsigned int j = base + 1; j < old_pos; j++)
|
||||
if (info[j].khmer_category() == OT_M)
|
||||
{
|
||||
new_pos--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_pos > start && is_coeng (info[new_pos - 1]))
|
||||
{
|
||||
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
|
||||
if (new_pos < end && is_joiner (info[new_pos]))
|
||||
new_pos++;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int old_pos = i;
|
||||
|
||||
buffer->merge_clusters (new_pos, old_pos + 1);
|
||||
hb_glyph_info_t tmp = info[old_pos];
|
||||
memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0]));
|
||||
info[new_pos] = tmp;
|
||||
|
||||
if (new_pos <= base && base < old_pos)
|
||||
base++;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Finish off the clusters and go home!
|
||||
*/
|
||||
if (hb_options ().uniscribe_bug_compatible)
|
||||
{
|
||||
/* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
|
||||
* This means, half forms are submerged into the main consonant's cluster.
|
||||
* This is unnecessary, and makes cursor positioning harder, but that's what
|
||||
* Uniscribe does. */
|
||||
buffer->merge_clusters (start, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
if (unlikely (!count)) return;
|
||||
|
||||
foreach_syllable (buffer, start, end)
|
||||
final_reordering_syllable (plan, buffer, start, end);
|
||||
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
|
||||
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_position);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
/* TODO: In USE, we clear syllables right after reorder. Figure out
|
||||
* what Uniscribe does. */
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
|
|
|
@ -279,20 +279,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
|||
return &_hb_ot_complex_shaper_indic;
|
||||
|
||||
case HB_SCRIPT_KHMER:
|
||||
/* A number of Khmer fonts in the wild don't have a 'pref' feature,
|
||||
* and as such won't shape properly via the Indic shaper;
|
||||
* however, they typically have 'liga' / 'clig' features that implement
|
||||
* the necessary "reordering" by means of ligature substitutions.
|
||||
* So we send such pref-less fonts through the generic shaper instead. */
|
||||
if (planner->map.found_script[0] &&
|
||||
hb_ot_layout_language_find_feature (planner->face, HB_OT_TAG_GSUB,
|
||||
planner->map.script_index[0],
|
||||
planner->map.language_index[0],
|
||||
HB_TAG ('p','r','e','f'),
|
||||
nullptr))
|
||||
return &_hb_ot_complex_shaper_khmer;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
|
||||
case HB_SCRIPT_MYANMAR:
|
||||
if (planner->map.chosen_script[0] == HB_TAG ('m','y','m','2'))
|
||||
|
|
|
@ -27,8 +27,8 @@
|
|||
*/
|
||||
|
||||
#define HB_SHAPER ot
|
||||
#define hb_ot_shaper_face_data_t hb_ot_layout_t
|
||||
#define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
|
||||
#define hb_ot_face_data_t hb_ot_layout_t
|
||||
#define hb_ot_shape_plan_data_t hb_ot_shape_plan_t
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
#include "hb-ot-shape-private.hh"
|
||||
|
@ -132,14 +132,14 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
|||
|
||||
HB_SHAPER_DATA_ENSURE_DEFINE(ot, face)
|
||||
|
||||
hb_ot_shaper_face_data_t *
|
||||
hb_ot_face_data_t *
|
||||
_hb_ot_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
return _hb_ot_layout_create (face);
|
||||
}
|
||||
|
||||
void
|
||||
_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
|
||||
_hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data)
|
||||
{
|
||||
_hb_ot_layout_destroy (data);
|
||||
}
|
||||
|
@ -151,16 +151,16 @@ _hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
|
|||
|
||||
HB_SHAPER_DATA_ENSURE_DEFINE(ot, font)
|
||||
|
||||
struct hb_ot_shaper_font_data_t {};
|
||||
struct hb_ot_font_data_t {};
|
||||
|
||||
hb_ot_shaper_font_data_t *
|
||||
hb_ot_font_data_t *
|
||||
_hb_ot_shaper_font_data_create (hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_ot_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
|
||||
_hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ _hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
|
|||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
hb_ot_shaper_shape_plan_data_t *
|
||||
hb_ot_shape_plan_data_t *
|
||||
_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
||||
const hb_feature_t *user_features,
|
||||
unsigned int num_user_features,
|
||||
|
@ -204,7 +204,7 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
|||
}
|
||||
|
||||
void
|
||||
_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *plan)
|
||||
_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shape_plan_data_t *plan)
|
||||
{
|
||||
if (plan->shaper->data_destroy)
|
||||
plan->shaper->data_destroy (const_cast<void *> (plan->data));
|
||||
|
|
|
@ -525,34 +525,6 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
|
|||
#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x))
|
||||
|
||||
|
||||
/* Global runtime options. */
|
||||
|
||||
struct hb_options_t
|
||||
{
|
||||
unsigned int initialized : 1;
|
||||
unsigned int uniscribe_bug_compatible : 1;
|
||||
};
|
||||
|
||||
union hb_options_union_t {
|
||||
unsigned int i;
|
||||
hb_options_t opts;
|
||||
};
|
||||
static_assert ((sizeof (int) == sizeof (hb_options_union_t)), "");
|
||||
|
||||
HB_INTERNAL void
|
||||
_hb_options_init (void);
|
||||
|
||||
extern HB_INTERNAL hb_options_union_t _hb_options;
|
||||
|
||||
static inline hb_options_t
|
||||
hb_options (void)
|
||||
{
|
||||
if (unlikely (!_hb_options.i))
|
||||
_hb_options_init ();
|
||||
|
||||
return _hb_options.opts;
|
||||
}
|
||||
|
||||
/* Size signifying variable-sized array */
|
||||
#define VAR 1
|
||||
|
||||
|
|
|
@ -49,23 +49,12 @@ HB_INTERNAL const hb_shaper_pair_t *
|
|||
_hb_shapers_get (void);
|
||||
|
||||
|
||||
/* For embedding in face / font / ... */
|
||||
struct hb_shaper_data_t {
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
};
|
||||
|
||||
#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
|
||||
|
||||
/* Means: succeeded, but don't need to keep any data. */
|
||||
#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
|
||||
|
||||
/* Means: tried but failed to create. */
|
||||
#define HB_SHAPER_DATA_INVALID ((void *) -1)
|
||||
#define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID)
|
||||
|
||||
#define HB_SHAPER_DATA_TYPE_NAME(shaper, object) hb_##shaper##_shaper_##object##_data_t
|
||||
#define HB_SHAPER_DATA_TYPE_NAME(shaper, object) hb_##shaper##_##object##_data_t
|
||||
#define HB_SHAPER_DATA_TYPE(shaper, object) struct HB_SHAPER_DATA_TYPE_NAME(shaper, object)
|
||||
#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(instance)->shaper_data.shaper)
|
||||
#define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE(shaper, object, object)
|
||||
|
@ -100,7 +89,13 @@ HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
|
|||
/* Note that evaluating condition above can be dangerous if another thread \
|
||||
* got here first and destructed data. That's, as always, bad use pattern. \
|
||||
* If you modify the font (change font size), other threads must not be \
|
||||
* using it at the same time. */ \
|
||||
* using it at the same time. However, since this check is delayed to \
|
||||
* when one actually tries to shape something, this is a XXX race condition \
|
||||
* (and the only know we have that I know of) right now. Ie. you modify the \
|
||||
* font size in one thread, then (supposedly safely) try to use it from two \
|
||||
* or more threads and BOOM! I'm not sure how to fix this. We want RCU. \
|
||||
* Maybe when it doesn't matter when we finally implement AAT shaping, as
|
||||
* this (condition) is currently only used by hb-coretext. */ \
|
||||
/* Drop and recreate. */ \
|
||||
/* If someone dropped it in the mean time, throw it away and don't touch it. \
|
||||
* Otherwise, destruct it. */ \
|
||||
|
@ -121,8 +116,17 @@ HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
|
|||
goto retry; \
|
||||
} \
|
||||
} \
|
||||
return data != nullptr && !HB_SHAPER_DATA_IS_INVALID (data); \
|
||||
return data != nullptr && (void *) data != HB_SHAPER_DATA_INVALID; \
|
||||
}
|
||||
|
||||
|
||||
/* For embedding in face / font / ... */
|
||||
struct hb_shaper_data_t {
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
|
||||
#include "hb-shaper-list.hh"
|
||||
#undef HB_SHAPER_IMPLEMENT
|
||||
};
|
||||
#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
|
||||
|
||||
|
||||
#endif /* HB_SHAPER_PRIVATE_HH */
|
||||
|
|
|
@ -38,7 +38,7 @@ hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_
|
|||
void
|
||||
hb_face_t::load_num_glyphs (void) const
|
||||
{
|
||||
OT::hb_sanitize_context_t c = OT::hb_sanitize_context_t();
|
||||
hb_sanitize_context_t c = hb_sanitize_context_t ();
|
||||
c.set_num_glyphs (0); /* So we don't recurse ad infinitum. */
|
||||
hb_blob_t *maxp_blob = c.reference_table<OT::maxp> (this);
|
||||
const OT::maxp *maxp_table = maxp_blob->as<OT::maxp> ();
|
||||
|
@ -49,7 +49,7 @@ hb_face_t::load_num_glyphs (void) const
|
|||
void
|
||||
hb_face_t::load_upem (void) const
|
||||
{
|
||||
hb_blob_t *head_blob = OT::hb_sanitize_context_t().reference_table<OT::head> (this);
|
||||
hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<OT::head> (this);
|
||||
const OT::head *head_table = head_blob->as<OT::head> ();
|
||||
upem = head_table->get_upem ();
|
||||
hb_blob_destroy (head_blob);
|
||||
|
|
|
@ -398,7 +398,7 @@ bool
|
|||
hb_subset_cff2 (hb_subset_plan_t *plan,
|
||||
hb_blob_t **prime /* OUT */)
|
||||
{
|
||||
hb_blob_t *cff2_blob = OT::hb_sanitize_context_t().reference_table<CFF::cff2> (plan->source);
|
||||
hb_blob_t *cff2_blob = hb_sanitize_context_t().reference_table<CFF::cff2> (plan->source);
|
||||
const char *data = hb_blob_get_data(cff2_blob, nullptr);
|
||||
|
||||
OT::cff2::accelerator_t acc;
|
||||
|
|
|
@ -292,7 +292,7 @@ hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
|
|||
hb_blob_t **glyf_prime, /* OUT */
|
||||
hb_blob_t **loca_prime /* OUT */)
|
||||
{
|
||||
hb_blob_t *glyf_blob = OT::hb_sanitize_context_t().reference_table<OT::glyf> (plan->source);
|
||||
hb_blob_t *glyf_blob = hb_sanitize_context_t ().reference_table<OT::glyf> (plan->source);
|
||||
const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr);
|
||||
|
||||
OT::glyf::accelerator_t glyf;
|
||||
|
|
|
@ -79,7 +79,7 @@ template<typename TableType>
|
|||
static bool
|
||||
_subset (hb_subset_plan_t *plan)
|
||||
{
|
||||
hb_blob_t *source_blob = OT::hb_sanitize_context_t().reference_table<TableType> (plan->source);
|
||||
hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
|
||||
const TableType *table = source_blob->as<TableType> ();
|
||||
|
||||
hb_tag_t tag = TableType::tableTag;
|
||||
|
@ -158,14 +158,14 @@ _hb_subset_face_data_reference_blob (hb_subset_face_data_t *data)
|
|||
if (unlikely (!buf))
|
||||
return nullptr;
|
||||
|
||||
OT::hb_serialize_context_t c (buf, face_length);
|
||||
hb_serialize_context_t c (buf, face_length);
|
||||
OT::OpenTypeFontFile *f = c.start_serialize<OT::OpenTypeFontFile> ();
|
||||
|
||||
bool is_cff = data->tables.lsearch (HB_TAG ('C','F','F',' ')) || data->tables.lsearch (HB_TAG ('C','F','F','2'));
|
||||
hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag;
|
||||
|
||||
OT::Supplier<hb_tag_t> tags_supplier (&data->tables[0].tag, table_count, sizeof (data->tables[0]));
|
||||
OT::Supplier<hb_blob_t *> blobs_supplier (&data->tables[0].blob, table_count, sizeof (data->tables[0]));
|
||||
Supplier<hb_tag_t> tags_supplier (&data->tables[0].tag, table_count, sizeof (data->tables[0]));
|
||||
Supplier<hb_blob_t *> blobs_supplier (&data->tables[0].blob, table_count, sizeof (data->tables[0]));
|
||||
bool ret = f->serialize_single (&c,
|
||||
sfnt_tag,
|
||||
tags_supplier,
|
||||
|
|
|
@ -309,7 +309,7 @@ HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, font)
|
|||
* shaper face data
|
||||
*/
|
||||
|
||||
struct hb_uniscribe_shaper_face_data_t {
|
||||
struct hb_uniscribe_face_data_t {
|
||||
HANDLE fh;
|
||||
hb_uniscribe_shaper_funcs_t *funcs;
|
||||
wchar_t face_name[LF_FACESIZE];
|
||||
|
@ -358,7 +358,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
|
|||
* full, PS. All of them point to the same name data with our unique name.
|
||||
*/
|
||||
|
||||
blob = OT::hb_sanitize_context_t().sanitize_blob<OT::OpenTypeFontFile> (blob);
|
||||
blob = hb_sanitize_context_t ().sanitize_blob<OT::OpenTypeFontFile> (blob);
|
||||
|
||||
unsigned int length, new_length, name_str_len;
|
||||
const char *orig_sfnt_data = hb_blob_get_data (blob, &length);
|
||||
|
@ -383,7 +383,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
|
|||
|
||||
memcpy(new_sfnt_data, orig_sfnt_data, length);
|
||||
|
||||
OT::name &name = OT::StructAtOffset<OT::name> (new_sfnt_data, name_table_offset);
|
||||
OT::name &name = StructAtOffset<OT::name> (new_sfnt_data, name_table_offset);
|
||||
name.format.set (0);
|
||||
name.count.set (ARRAY_LENGTH (name_IDs));
|
||||
name.stringOffset.set (name.get_size ());
|
||||
|
@ -399,7 +399,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
|
|||
}
|
||||
|
||||
/* Copy string data from new_name, converting wchar_t to UTF16BE. */
|
||||
unsigned char *p = &OT::StructAfter<unsigned char> (name);
|
||||
unsigned char *p = &StructAfter<unsigned char> (name);
|
||||
for (unsigned int i = 0; i < name_str_len; i++)
|
||||
{
|
||||
*p++ = new_name[i] >> 8;
|
||||
|
@ -439,10 +439,10 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
|
|||
HB_MEMORY_MODE_WRITABLE, nullptr, free);
|
||||
}
|
||||
|
||||
hb_uniscribe_shaper_face_data_t *
|
||||
hb_uniscribe_face_data_t *
|
||||
_hb_uniscribe_shaper_face_data_create (hb_face_t *face)
|
||||
{
|
||||
hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_face_data_t));
|
||||
hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) calloc (1, sizeof (hb_uniscribe_face_data_t));
|
||||
if (unlikely (!data))
|
||||
return nullptr;
|
||||
|
||||
|
@ -479,7 +479,7 @@ _hb_uniscribe_shaper_face_data_create (hb_face_t *face)
|
|||
}
|
||||
|
||||
void
|
||||
_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_shaper_face_data_t *data)
|
||||
_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_face_data_t *data)
|
||||
{
|
||||
RemoveFontMemResourceEx (data->fh);
|
||||
free (data);
|
||||
|
@ -490,7 +490,7 @@ _hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_shaper_face_data_t *data)
|
|||
* shaper font data
|
||||
*/
|
||||
|
||||
struct hb_uniscribe_shaper_font_data_t {
|
||||
struct hb_uniscribe_font_data_t {
|
||||
HDC hdc;
|
||||
LOGFONTW log_font;
|
||||
HFONT hfont;
|
||||
|
@ -508,19 +508,19 @@ populate_log_font (LOGFONTW *lf,
|
|||
lf->lfCharSet = DEFAULT_CHARSET;
|
||||
|
||||
hb_face_t *face = font->face;
|
||||
hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||
hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||
|
||||
memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hb_uniscribe_shaper_font_data_t *
|
||||
hb_uniscribe_font_data_t *
|
||||
_hb_uniscribe_shaper_font_data_create (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (!hb_uniscribe_shaper_face_data_ensure (font->face))) return nullptr;
|
||||
|
||||
hb_uniscribe_shaper_font_data_t *data = (hb_uniscribe_shaper_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t));
|
||||
hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t));
|
||||
if (unlikely (!data))
|
||||
return nullptr;
|
||||
|
||||
|
@ -559,7 +559,7 @@ _hb_uniscribe_shaper_font_data_create (hb_font_t *font)
|
|||
}
|
||||
|
||||
void
|
||||
_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_shaper_font_data_t *data)
|
||||
_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data)
|
||||
{
|
||||
if (data->hdc)
|
||||
ReleaseDC (nullptr, data->hdc);
|
||||
|
@ -574,7 +574,7 @@ LOGFONTW *
|
|||
hb_uniscribe_font_get_logfontw (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
|
||||
hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
return &font_data->log_font;
|
||||
}
|
||||
|
||||
|
@ -582,7 +582,7 @@ HFONT
|
|||
hb_uniscribe_font_get_hfont (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
|
||||
hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
return font_data->hfont;
|
||||
}
|
||||
|
||||
|
@ -591,20 +591,20 @@ hb_uniscribe_font_get_hfont (hb_font_t *font)
|
|||
* shaper shape_plan data
|
||||
*/
|
||||
|
||||
struct hb_uniscribe_shaper_shape_plan_data_t {};
|
||||
struct hb_uniscribe_shape_plan_data_t {};
|
||||
|
||||
hb_uniscribe_shaper_shape_plan_data_t *
|
||||
hb_uniscribe_shape_plan_data_t *
|
||||
_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||
const hb_feature_t *user_features HB_UNUSED,
|
||||
unsigned int num_user_features HB_UNUSED,
|
||||
const int *coords HB_UNUSED,
|
||||
unsigned int num_coords HB_UNUSED)
|
||||
{
|
||||
return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
return (hb_uniscribe_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
|
||||
}
|
||||
|
||||
void
|
||||
_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shaper_shape_plan_data_t *data HB_UNUSED)
|
||||
_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shape_plan_data_t *data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -622,8 +622,8 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
|
|||
unsigned int num_features)
|
||||
{
|
||||
hb_face_t *face = font->face;
|
||||
hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||
hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
||||
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
||||
hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs;
|
||||
|
||||
/*
|
||||
|
|
|
@ -38,9 +38,9 @@ HB_BEGIN_DECLS
|
|||
|
||||
#define HB_VERSION_MAJOR 1
|
||||
#define HB_VERSION_MINOR 8
|
||||
#define HB_VERSION_MICRO 4
|
||||
#define HB_VERSION_MICRO 5
|
||||
|
||||
#define HB_VERSION_STRING "1.8.4"
|
||||
#define HB_VERSION_STRING "1.8.5"
|
||||
|
||||
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
||||
((major)*10000+(minor)*100+(micro) <= \
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,2 +1,4 @@
|
|||
../fonts/57a9d9f83020155cbb1d2be1f43d82388cbecc88.ttf::U+0C9A,U+0CCD,U+0C9A,U+0CCD:[U0C9A_U0CCD.haln=0+1066|U0C9A_0CCD.blwf=0+0]
|
||||
../fonts/270b89df543a7e48e206a2d830c0e10e5265c630.ttf::U+0D38,U+0D4D,U+0D31,U+0D4D,U+0D31,U+0D4D:[glyph201=0+1183|U0D4D=0+0]
|
||||
../fonts/b722a7d09e60421f3efbc706ad348ab47b88567b.ttf::U+091F,U+094D,U+0930,U+094D,U+0020:[Tra=0+550|virAma=0@-73,-110+0|space=4+500]
|
||||
../fonts/b722a7d09e60421f3efbc706ad348ab47b88567b.ttf::U+091F,U+094D,U+0930,U+0942:[Tra=0+550|UT=0@42,-150+0]
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1781,U+17D2,U+1798,U+17C2:[uni17C2=0+288|uni1781=0+635|uni17D21798=0@22,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1787,U+17B6:[uni178717B6=0+923]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1790,U+17D2,U+1784,U+17C3:[uni17C3=0+288|uni1790=0+635|uni17D21784=0@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1798,U+17B6:[uni179817B6=0+923]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1798,U+17D2,U+1796,U+17BB:[uni1798=0+635|uni17D21796=0@-1,-26+0|uni17BB=0@-22,-296+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179A:[uni179A=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179A,U+17B8:[uni179A=0+288|uni17B8.r=0@76,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179A,U+17CD:[uni179A=0+288|uni17CD.r=0@18,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17C5:[uni17C1=0+288|uni179F17C5=0+1216]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179A,U+17D2,U+17A5:[uni179A=0+288|uni17D2=0+0|uni17A5=2+635]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1784,U+17B9,U+17D2,U+1788:[uni1784=0+635|uni17B9=0@-46,30+0|uni17D21788=0+234]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1784,U+17D2,U+1788,U+17B9:[uni1784=0+635|uni17D21788=0+234|uni17B9=0@8,30+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1784,U+17D2,U+1782,U+17D2,U+179A:[uni17D2179A.low=0+287|uni1784=0+635|uni17D21782=0@0,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1784,U+17D2,U+179A,U+17D2,U+1782:[uni17D2179A.low=0+287|uni1784=0+635|uni17D21782=0@0,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1798,U+17C9,U+17D2,U+179B,U+17C1,U+17C7:[uni17C1=0+288|uni1798=0+635|uni17C9=0@-46,-29+0|uni17D2179B=0@-1,-26+0|uni17C7=0+386]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1798,U+200C,U+17C9,U+17D2,U+179B,U+17C1,U+17C7:[uni17C1=0+288|uni1798=0+635|space=0+0|uni17C9=0@-46,-29+0|uni17D2179B=0@-1,-26+0|uni17C7=0+386]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1794,U+17CA,U+17D0:[uni1794=0+635|uni17CA=0@-46,-29+0|uni17D0=0@-46,113+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1793,U+17C2,U+17CE:[uni17C2=0+288|uni1793=0+635|uni17CE=0@-36,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17C1,U+17D2,U+179A:[uni17D2179A=0+287|uni17C1=0+288|uni1780=0+636]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17C0,U+17D2,U+179A:[uni17D2179A=0+287|uni17C1=0+288|uni1780=0+636|uni17C0.right1=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17C4,U+17D2,U+179A:[uni17D2179A=0+287|uni17C1=0+288|uni178017B6=0+924]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17C5,U+17D2,U+179A:[uni17D2179A=0+287|uni17C1=0+288|uni178017C5=0+924]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1796,U+17D1,U+17B6:[uni179617B6=0+923|uni17D1=0@-311,-19+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+1793,U+17D2,U+178F,U+17D2,U+179A,U+17B6,U+1780,U+17CB:[uni1780=0+636|uni17D2179A.low=1+287|uni179317B6=1+924|uni17D2178F=1@-290,-26+0|uni1780=7+636|uni17CB=7@-23,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+1793,U+17D2,U+179A,U+17D2,U+179F,U+17B7,U+1780,U+17CB:[uni1780=0+636|uni17D2179A=1+287|uni1793=1+635|uni17D2179F=1+302|uni17B7=1@-4,30+0|uni1780=7+636|uni17CB=7@-23,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+1793,U+17D2,U+179A,U+17D2,U+179F,U+17B8,U+1780,U+17CB:[uni1780=0+636|uni17D2179A=1+287|uni1793=1+635|uni17D2179F=1+302|uni17B8=1@-4,30+0|uni1780=7+636|uni17CB=7@-23,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17B6,U+1793,U+17D2,U+178F:[uni1780=0+636|uni17D2179F17B6=0+584|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17B7,U+1793,U+17D2,U+178F:[uni1780=0+636|uni17D2179F=0+302|uni17B7=0@-4,30+0|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17B8,U+1793,U+17D2,U+178F:[uni1780=0+636|uni17D2179F=0+302|uni17B8=0@-4,30+0|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17B9,U+1793,U+17D2,U+178F:[uni1780=0+636|uni17D2179F=0+302|uni17B9=0@-4,30+0|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17BA,U+1793,U+17D2,U+178F:[uni1780=0+636|uni17D2179F=0+302|uni17BA=0@-4,30+0|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17BB,U+1793,U+17D2,U+178F:[uni1780=0+636|uni17D2179F=0+302|uni17BB=0@1,-260+0|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17BC,U+1793,U+17D2,U+178F:[uni1780=0+636|uni17D2179F=0+302|uni17BC=0@1,-260+0|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17BD,U+1793,U+17D2,U+178F:[uni1780=0+636|uni17D2179F=0+302|uni17BD=0@1,-260+0|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1780,U+17D2,U+179F,U+17BF,U+1793,U+17D2,U+178F:[uni17C1=0+288|uni1780=0+636|uni17D2179F=0+302|uni17BF.right2=0+288|uni1793=4+635|uni17D2178F=4@-1,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1783,U+17D2,U+179B,U+17D2,U+179F,U+17B6,U+17C6:[uni1783=0+928|uni17D2179B=0@15,-26+0|uni17D2179F17B6.low=0+584|uni17C6=0@39,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1783,U+17D2,U+179B,U+17D2,U+179F,U+17B7,U+17C7:[uni1783=0+928|uni17D2179B=0@15,-26+0|uni17D2179F.low=0+302|uni17B7=0@-4,30+0|uni17C7=0+386]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1783,U+17D2,U+179B,U+17D2,U+179F,U+17BB,U+17C6:[uni1783=0+928|uni17D2179B=0@15,-26+0|uni17D2179F.low=0+302|uni17BB=0+0|uni17C6=0@-4,30+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1783,U+17D2,U+179B,U+17D2,U+179F,U+17BB,U+17C7:[uni1783=0+928|uni17D2179B=0@15,-26+0|uni17D2179F.low=0+302|uni17BB=0+0|uni17C7=0+386]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1783,U+17D2,U+179B,U+17D2,U+179F,U+17C1,U+17C7:[uni17C1=0+288|uni1783=0+928|uni17D2179B=0@15,-26+0|uni17D2179F.low=0+302|uni17C7=0+386]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1783,U+17D2,U+179B,U+17D2,U+179F,U+17C4,U+17C7:[uni17C1=0+288|uni1783=0+928|uni17D2179B=0@15,-26+0|uni17D2179F17B6.low=0+584|uni17C7=0+386]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1783,U+17D2,U+179B,U+17D2,U+179F,U+17C6:[uni1783=0+928|uni17D2179B=0@15,-26+0|uni17D2179F.low=0+302|uni17C6=0@-4,30+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1783,U+17D2,U+179B,U+17D2,U+179F,U+17C7:[uni1783=0+928|uni17D2179B=0@15,-26+0|uni17D2179F.low=0+302|uni17C7=0+386]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1789,U+17BC:[uni1789=0+952|uni17BC=0@-173,-260+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1789,U+17D2,U+1789:[uni1789.a=0+952|uni17D21789.a=0@19,-22+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1789,U+17D2,U+1789,U+17BB:[uni1789.a=0+952|uni17D21789.a=0@19,-22+0|uni17BB=0@-160,-296+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1789,U+17D2,U+1789,U+17BC:[uni1789.a=0+952|uni17D21789.a=0@19,-22+0|uni17BC=0@-160,-296+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1789,U+17D2,U+1789,U+17BD:[uni1789.a=0+952|uni17D21789.a=0@19,-22+0|uni17BD=0@-160,-296+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+178F,U+17D2,U+179A,U+17D2,U+179F,U+17C0:[uni17C1=0+288|uni17D2179A=0+287|uni178F=0+635|uni17D2179F=0+302|uni17C0.right2=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+178F,U+17D2,U+179A,U+17D2,U+179F,U+17C1:[uni17C1=0+288|uni17D2179A=0+287|uni178F=0+635|uni17D2179F=0+302]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+178F,U+17D2,U+179A,U+17D2,U+179F,U+17C2:[uni17C2=0+288|uni17D2179A=0+287|uni178F=0+635|uni17D2179F=0+302]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+178F,U+17D2,U+179A,U+17D2,U+179F,U+17C3:[uni17C3=0+288|uni17D2179A=0+287|uni178F=0+635|uni17D2179F=0+302]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+178F,U+17D2,U+179A,U+17D2,U+179F,U+17C4:[uni17C1=0+288|uni17D2179A=0+287|uni178F=0+635|uni17D2179F17B6=0+584]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+178F,U+17D2,U+179A,U+17D2,U+179F,U+17C5:[uni17C1=0+288|uni17D2179A=0+287|uni178F=0+635|uni17D2179F17C5=0+584]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1792,U+17D2,U+179B,U+17BB,U+17C6,U+1780,U+17CB:[uni1792=0+635|uni17D2179B=0@-2,-26+0|uni17BB=0@-19,-296+0|uni17C6=0@-46,-29+0|uni1780=5+636|uni17CB=5@-23,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1792,U+17D2,U+179B,U+17C4,U+1780,U+17CB:[uni17C1=0+288|uni179217B6=0+923|uni17D2179B=0@-290,-26+0|uni1780=4+636|uni17CB=4@-23,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1792,U+17D2,U+179B,U+17C5,U+1780,U+17CB:[uni17C1=0+288|uni179217C5=0+923|uni17D2179B=0@-290,-26+0|uni1780=4+636|uni17CB=4@-23,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1792,U+17D2,U+179B,U+17C6,U+1780,U+17CB:[uni1792=0+635|uni17D2179B=0@-2,-26+0|uni17C6=0@-46,-29+0|uni1780=4+636|uni17CB=4@-23,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1798,U+17D2,U+178F,U+17D2,U+179B,U+17C9,U+17B6:[uni179817B6=0+923|uni17D2178F=0@-289,-26+0|uni17D2179B=0@-289,-296+0|uni17C9=0@-334,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1798,U+17D2,U+178F,U+17D2,U+179B,U+17C9,U+17BB:[uni1798=0+635|uni17D2178F=0@-1,-26+0|uni17D2179B=0@-1,-296+0|uni17C9=0@-46,-29+0|uni17BB=0@-18,-566+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1798,U+17D2,U+178F,U+17D2,U+179B,U+17C9,U+17BF:[uni17C1=0+288|uni1798=0+635|uni17D2178F=0@-1,-26+0|uni17D2179B=0@-1,-296+0|uni17C9=0@-46,-29+0|uni17BF.right1=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1798,U+17D2,U+178F,U+17D2,U+179B,U+17C9,U+17C0:[uni17C1=0+288|uni1798=0+635|uni17D2178F=0@-1,-26+0|uni17D2179B=0@-1,-296+0|uni17C9=0@-46,-29+0|uni17C0.right1=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+1799,U+17D2,U+1799,U+17BE,U+17A0,U+17D2,U+179C,U+17D2,U+179B,U+17C3:[uni17C1=0+288|uni1799=0+953|uni17D21799=0+298|uni17B8=0@1,30+0|uni17C3=4+288|uni17A0=4+928|uni17D2179C=4@20,-26+0|uni17D2179B=4@19,-296+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179A,U+17D2,U+179A:[uni17D2179A=0+287|uni179A=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17B6,U+179F,U+17D2,U+178F,U+17D2,U+179A,U+1783,U+17D2,U+1788,U+1784,U+17B6:[uni179F17B6=0+1216|uni17D2179A=2+287|uni179F=2+928|uni17D2178F=2@14,-26+0|uni1783=7+928|uni17D21788=7+234|uni178417B6=10+923]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17B6,U+179F,U+17D2,U+178F,U+17D2,U+179A,U+1783,U+17D2,U+1788,U+1784,U+17B7:[uni179F17B6=0+1216|uni17D2179A=2+287|uni179F=2+928|uni17D2178F=2@14,-26+0|uni1783=7+928|uni17D21788=7+234|uni1784=10+635|uni17B7=10@-46,30+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17B6,U+179F,U+17D2,U+178F,U+17D2,U+179A,U+1783,U+17D2,U+1788,U+1784,U+17B8:[uni179F17B6=0+1216|uni17D2179A=2+287|uni179F=2+928|uni17D2178F=2@14,-26+0|uni1783=7+928|uni17D21788=7+234|uni1784=10+635|uni17B8=10@-46,30+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+178F,U+17D2,U+179A,U+17B8,U+179C,U+17D0,U+1781,U+17D2,U+1789,U+17D2,U+179F,U+17B6:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17B8=0@-32,-29+0|uni179C=6+326|uni17D0=6@139,40+0|uni1781=8+635|uni17D21789=8@-4,-26+0|uni17D2179F17B6.low=8+584]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17B6:[uni17D2179A=0+287|uni179F17B6=0+1216|uni17D2178F=0@-274,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17B7:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17B7=0@-32,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17B8:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17B8=0@-32,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17B9:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17B9=0@-32,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17BA:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17BA=0@-32,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17BB:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17BB=0@-6,-296+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17BC:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17BC=0@-6,-296+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17BD:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17BD=0@-6,-296+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17BE:[uni17C1=0+288|uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17B8=0@-32,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17BF:[uni17C1=0+288|uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17BF.right2=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17CA,U+17BF:[uni17C1=0+288|uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17CA=0@-32,-29+0|uni17BF.right1=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17CA,U+17C0:[uni17C1=0+288|uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17CA=0@-32,-29+0|uni17C0.right1.high=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17CA,U+17C1:[uni17C1=0+288|uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17CA=0@-32,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17CA,U+17C2:[uni17C2=0+288|uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17CA=0@-32,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17CA,U+17C3:[uni17C3=0+288|uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17CA=0@-32,-29+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+179F,U+17D2,U+179A,U+17D2,U+178F,U+17CA,U+17C6:[uni17D2179A=0+287|uni179F=0+928|uni17D2178F=0@14,-26+0|uni17CA=0@-32,-29+0|uni17C6=0@-32,113+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+17A0,U+17D2,U+1782,U+17D2,U+179F,U+17CA,U+17BE:[uni17C1=0+288|uni17A0=0+928|uni17D21782=0@20,-26+0|uni17D2179F.low=0+302|uni17BB=0+0|uni17B8=0@-4,30+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+17A0,U+17D2,U+1782,U+17D2,U+179F,U+17CA,U+17BF:[uni17C1=0+288|uni17A0=0+928|uni17D21782=0@20,-26+0|uni17D2179F.low=0+302|uni17CA=0@-4,30+0|uni17BF.right1=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+17A0,U+17D2,U+1782,U+17D2,U+179F,U+17CA,U+17C0:[uni17C1=0+288|uni17A0=0+928|uni17D21782=0@20,-26+0|uni17D2179F.low=0+302|uni17CA=0@-4,30+0|uni17C0.right1.high=0+288]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+17A0,U+17D2,U+179A,U+17D2,U+179C,U+1784,U+17D2,U+1780:[uni17D2179A=0+287|uni17A0=0+928|uni17D2179C=0@20,-26+0|uni1784=5+635|uni17D21780=5@0,-26+0]
|
||||
../fonts/3998336402905b8be8301ef7f47cf7e050cbb1bd.ttf::U+17A0,U+17D2,U+179A,U+17D2,U+179C,U+17B6,U+17C6,U+1784:[uni17D2179A=0+287|uni17A017B6=0+1216|uni17D2179C=0@-268,-26+0|uni17C6=0@47,-29+0|uni1784=7+635]
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue