Merge branch 'master' into cff-subset

This commit is contained in:
Michiharu Ariza 2018-10-08 21:46:23 -07:00
commit 8b349040e9
27 changed files with 575 additions and 728 deletions

View File

@ -156,6 +156,21 @@ HB_SCRIPT_CANADIAN_ABORIGINAL
hb_font_funcs_set_glyph_func
hb_font_get_glyph_func_t
hb_set_invert
hb_unicode_eastasian_width_func_t
hb_unicode_eastasian_width
hb_unicode_funcs_set_eastasian_width_func
HB_UNICODE_MAX_DECOMPOSITION_LEN
hb_unicode_decompose_compatibility_func_t
hb_unicode_decompose_compatibility
hb_unicode_funcs_set_decompose_compatibility_func
hb_font_funcs_set_glyph_h_kerning_func
hb_font_funcs_set_glyph_v_kerning_func
hb_font_get_glyph_h_kerning
hb_font_get_glyph_h_kerning_func_t
hb_font_get_glyph_kerning_for_direction
hb_font_get_glyph_kerning_func_t
hb_font_get_glyph_v_kerning
hb_font_get_glyph_v_kerning_func_t
</SECTION>
<SECTION>
@ -216,12 +231,10 @@ hb_font_funcs_set_glyph_extents_func
hb_font_funcs_set_glyph_from_name_func
hb_font_funcs_set_glyph_h_advance_func
hb_font_funcs_set_glyph_h_advances_func
hb_font_funcs_set_glyph_h_kerning_func
hb_font_funcs_set_glyph_h_origin_func
hb_font_funcs_set_glyph_name_func
hb_font_funcs_set_glyph_v_advance_func
hb_font_funcs_set_glyph_v_advances_func
hb_font_funcs_set_glyph_v_kerning_func
hb_font_funcs_set_glyph_v_origin_func
hb_font_funcs_set_nominal_glyph_func
hb_font_funcs_set_user_data
@ -246,12 +259,8 @@ hb_font_get_glyph_h_advance
hb_font_get_glyph_h_advance_func_t
hb_font_get_glyph_h_advances
hb_font_get_glyph_h_advances_func_t
hb_font_get_glyph_h_kerning
hb_font_get_glyph_h_kerning_func_t
hb_font_get_glyph_h_origin
hb_font_get_glyph_h_origin_func_t
hb_font_get_glyph_kerning_for_direction
hb_font_get_glyph_kerning_func_t
hb_font_get_glyph_name
hb_font_get_glyph_name_func_t
hb_font_get_glyph_origin_for_direction
@ -260,8 +269,6 @@ hb_font_get_glyph_v_advance
hb_font_get_glyph_v_advance_func_t
hb_font_get_glyph_v_advances
hb_font_get_glyph_v_advances_func_t
hb_font_get_glyph_v_kerning
hb_font_get_glyph_v_kerning_func_t
hb_font_get_glyph_v_origin
hb_font_get_glyph_v_origin_func_t
hb_font_get_nominal_glyph
@ -613,16 +620,13 @@ hb_shape_plan_t
<SECTION>
<FILE>hb-unicode</FILE>
HB_UNICODE_MAX
HB_UNICODE_MAX_DECOMPOSITION_LEN
hb_unicode_combining_class
hb_unicode_combining_class_func_t
hb_unicode_combining_class_t
hb_unicode_compose
hb_unicode_compose_func_t
hb_unicode_decompose
hb_unicode_decompose_compatibility
hb_unicode_decompose_func_t
hb_unicode_eastasian_width
hb_unicode_funcs_create
hb_unicode_funcs_destroy
hb_unicode_funcs_get_default
@ -634,9 +638,7 @@ hb_unicode_funcs_make_immutable
hb_unicode_funcs_reference
hb_unicode_funcs_set_combining_class_func
hb_unicode_funcs_set_compose_func
hb_unicode_funcs_set_decompose_compatibility_func
hb_unicode_funcs_set_decompose_func
hb_unicode_funcs_set_eastasian_width_func
hb_unicode_funcs_set_general_category_func
hb_unicode_funcs_set_mirroring_func
hb_unicode_funcs_set_script_func

View File

@ -35,111 +35,6 @@ namespace AAT {
using namespace OT;
/*
* Binary Searching Tables
*/
struct BinSearchHeader
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */
HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */
HBUINT16 searchRange; /* The value of unitSize times the largest power of 2
* that is less than or equal to the value of nUnits. */
HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than
* or equal to the value of nUnits. */
HBUINT16 rangeShift; /* The value of unitSize times the difference of the
* value of nUnits minus the largest power of 2 less
* than or equal to the value of nUnits. */
public:
DEFINE_SIZE_STATIC (10);
};
template <typename Type>
struct BinSearchArrayOf
{
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= header.nUnits)) return Null(Type);
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
}
inline Type& operator [] (unsigned int i)
{
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
}
inline unsigned int get_size (void) const
{ return header.static_size + header.nUnits * header.unitSize; }
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
/* Note: for structs that do not reference other structs,
* we do not need to call their sanitize() as we already did
* a bound check on the aggregate array size. We just include
* a small unreachable expression to make sure the structs
* pointed to do have a simple sanitize(), ie. they do not
* reference other structs via offsets.
*/
(void) (false && StructAtOffset<Type> (&bytesZ, 0).sanitize (c));
return_trace (true);
}
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
unsigned int count = header.nUnits;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(*this)[i].sanitize (c, base)))
return_trace (false);
return_trace (true);
}
template <typename T>
inline const Type *bsearch (const T &key) const
{
unsigned int size = header.unitSize;
int min = 0, max = (int) header.nUnits - 1;
while (min <= max)
{
int mid = (min + max) / 2;
const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
int c = p->cmp (key);
if (c < 0)
max = mid - 1;
else if (c > 0)
min = mid + 1;
else
return p;
}
return nullptr;
}
private:
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (header.sanitize (c) &&
Type::static_size >= header.unitSize &&
c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize));
}
protected:
BinSearchHeader header;
UnsizedArrayOf<HBUINT8> bytesZ;
public:
DEFINE_SIZE_ARRAY (10, bytesZ);
};
/*
* Lookup Table
*/
@ -213,7 +108,7 @@ struct LookupFormat2
protected:
HBUINT16 format; /* Format identifier--format = 2 */
BinSearchArrayOf<LookupSegmentSingle<T> >
VarSizedBinSearchArrayOf<LookupSegmentSingle<T> >
segments; /* The actual segments. These must already be sorted,
* according to the first word in each one (the last
* glyph in each segment). */
@ -270,7 +165,7 @@ struct LookupFormat4
protected:
HBUINT16 format; /* Format identifier--format = 2 */
BinSearchArrayOf<LookupSegmentArray<T> >
VarSizedBinSearchArrayOf<LookupSegmentArray<T> >
segments; /* The actual segments. These must already be sorted,
* according to the first word in each one (the last
* glyph in each segment). */
@ -315,7 +210,7 @@ struct LookupFormat6
protected:
HBUINT16 format; /* Format identifier--format = 6 */
BinSearchArrayOf<LookupSingle<T> >
VarSizedBinSearchArrayOf<LookupSingle<T> >
entries; /* The actual entries, sorted by glyph index. */
public:
DEFINE_SIZE_ARRAY (8, entries);

View File

@ -30,6 +30,7 @@
#include "hb-open-type.hh"
#include "hb-aat-layout-common.hh"
#include "hb-ot-kern-table.hh"
/*
* kerx -- Extended Kerning
@ -43,33 +44,17 @@ namespace AAT {
using namespace OT;
struct KerxFormat0Records
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this)));
}
protected:
GlyphID left;
GlyphID right;
FWORD value;
public:
DEFINE_SIZE_STATIC (6);
};
struct KerxSubTableFormat0
{
// TODO(ebraminio) Enable when we got suitable BinSearchArrayOf
// inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
// {
// hb_glyph_pair_t pair = {left, right};
// int i = pairs.bsearch (pair);
// if (i == -1)
// return 0;
// return pairs[i].get_kerning ();
// }
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
hb_glyph_pair_t pair = {left, right};
int i = pairs.bsearch (pair);
if (i == -1)
return 0;
return pairs[i].get_kerning ();
}
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
@ -82,23 +67,14 @@ struct KerxSubTableFormat0
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
recordsZ.sanitize (c, nPairs)));
return_trace (likely (pairs.sanitize (c)));
}
protected:
// TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is
// needed here to use HBUINT32 instead
HBUINT32 nPairs; /* The number of kerning pairs in this subtable */
HBUINT32 searchRange; /* The largest power of two less than or equal to the value of nPairs,
* multiplied by the size in bytes of an entry in the subtable. */
HBUINT32 entrySelector; /* This is calculated as log2 of the largest power of two less
* than or equal to the value of nPairs. */
HBUINT32 rangeShift; /* The value of nPairs minus the largest power of two less than or equal to nPairs. */
UnsizedArrayOf<KerxFormat0Records>
recordsZ; /* VAR=nPairs */
BinSearchArrayOf<KernPair, HBUINT32>
pairs; /* Sorted kern records. */
public:
DEFINE_SIZE_ARRAY (16, recordsZ);
DEFINE_SIZE_ARRAY (16, pairs);
};
struct KerxSubTableFormat1
@ -126,32 +102,14 @@ struct KerxSubTableFormat1
DEFINE_SIZE_STATIC (20);
};
// TODO(ebraminio): Maybe this can be replaced with Lookup<HBUINT16>?
struct KerxClassTable
{
inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (firstGlyph.sanitize (c) &&
classes.sanitize (c)));
}
protected:
HBUINT16 firstGlyph; /* First glyph in class range. */
ArrayOf<HBUINT16> classes; /* Glyph classes. */
public:
DEFINE_SIZE_ARRAY (4, classes);
};
struct KerxSubTableFormat2
{
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right,
const char *end, unsigned int num_glyphs) const
{
unsigned int l = (this+leftClassTable).get_class (left);
unsigned int r = (this+leftClassTable).get_class (left);
unsigned int offset = l * rowWidth + r * sizeof (FWORD);
unsigned int l = *(this+leftClassTable).get_value (left, num_glyphs);
unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs);
unsigned int offset = l + r;
const FWORD *arr = &(this+array);
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
return 0;
@ -182,10 +140,10 @@ struct KerxSubTableFormat2
protected:
HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */
LOffsetTo<KerxClassTable>
LOffsetTo<Lookup<HBUINT16> >
leftClassTable; /* Offset from beginning of this subtable to
* left-hand class table. */
LOffsetTo<KerxClassTable>
LOffsetTo<Lookup<HBUINT16> >
rightClassTable;/* Offset from beginning of this subtable to
* right-hand class table. */
LOffsetTo<FWORD>
@ -209,26 +167,14 @@ struct KerxSubTableFormat4
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
rowWidth.sanitize (c) &&
leftClassTable.sanitize (c, this) &&
rightClassTable.sanitize (c, this) &&
array.sanitize (c, this)));
/* TODO */
return_trace (likely (c->check_struct (this)));
}
protected:
HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */
LOffsetTo<KerxClassTable>
leftClassTable; /* Offset from beginning of this subtable to
* left-hand class table. */
LOffsetTo<KerxClassTable>
rightClassTable;/* Offset from beginning of this subtable to
* right-hand class table. */
LOffsetTo<FWORD>
array; /* Offset from beginning of this subtable to
* the start of the kerning array. */
public:
DEFINE_SIZE_STATIC (16);
DEFINE_SIZE_STATIC (1);
};
struct KerxSubTableFormat6
@ -266,6 +212,8 @@ struct KerxSubTableFormat6
struct KerxTable
{
friend kerx;
inline unsigned int get_size (void) const { return length; }
inline unsigned int get_type (void) const { return coverage & SubtableType; }
@ -358,7 +306,33 @@ struct kerx
unsigned int count = tableCount;
for (unsigned int i = 0; i < count; i++)
{
bool reverse;
if (HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
bool (table->coverage & KerxTable::Vertical))
goto skip;
if (table->coverage & KerxTable::CrossStream)
goto skip; /* We do NOT handle cross-stream kerning. */
reverse = bool (table->coverage & KerxTable::ProcessDirection) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
goto skip;
if (reverse)
c->buffer->reverse ();
/* XXX Reverse-kern is not working yet... */
table->dispatch (c);
if (reverse)
c->buffer->reverse ();
(void) c->buffer->message (c->font, "end kerx subtable %d", c->lookup_index);
skip:
table = &StructAfter<KerxTable> (*table);
}
}

View File

@ -63,6 +63,15 @@ typedef unsigned __int64 uint64_t;
# include <stdint.h>
#endif
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
#define HB_DEPRECATED __attribute__((__deprecated__))
#elif defined(_MSC_VER) && (_MSC_VER >= 1300)
#define HB_DEPRECATED __declspec(deprecated)
#else
#define HB_DEPRECATED
#endif
HB_BEGIN_DECLS

View File

@ -50,14 +50,168 @@ typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t *glyph,
void *user_data);
HB_EXTERN void
HB_EXTERN HB_DEPRECATED void
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_func_t func,
void *user_data, hb_destroy_func_t destroy);
HB_EXTERN void
HB_EXTERN HB_DEPRECATED void
hb_set_invert (hb_set_t *set);
/**
* hb_unicode_eastasian_width_func_t:
*
* Deprecated: REPLACEME
*/
typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
/**
* hb_unicode_funcs_set_eastasian_width_func:
* @ufuncs: a Unicode function structure
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
* Deprecated: REPLACEME
**/
HB_EXTERN HB_DEPRECATED void
hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_eastasian_width_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_unicode_eastasian_width:
*
* Since: 0.9.2
* Deprecated: REPLACEME
**/
HB_EXTERN HB_DEPRECATED unsigned int
hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode);
/**
* hb_unicode_decompose_compatibility_func_t:
* @ufuncs: a Unicode function structure
* @u: codepoint to decompose
* @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
* @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
*
* Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
* The complete length of the decomposition will be returned.
*
* If @u has no compatibility decomposition, zero should be returned.
*
* The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
* compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations
* of this function type must ensure that they do not write past the provided array.
*
* Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
*
* Deprecated: REPLACEME
*/
typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t u,
hb_codepoint_t *decomposed,
void *user_data);
/**
* HB_UNICODE_MAX_DECOMPOSITION_LEN:
*
* See Unicode 6.1 for details on the maximum decomposition length.
*
* Deprecated: REPLACEME
*/
#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
/**
* hb_unicode_funcs_set_decompose_compatibility_func:
* @ufuncs: a Unicode function structure
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
* Deprecated: REPLACEME
**/
HB_EXTERN HB_DEPRECATED void
hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_decompose_compatibility_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_unicode_decompose_compatibility:
*
*
* Deprecated: REPLACEME
**/
HB_EXTERN HB_DEPRECATED unsigned int
hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t u,
hb_codepoint_t *decomposed);
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
void *user_data);
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
/**
* hb_font_funcs_set_glyph_h_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
* Deprecated: REPLACEME
**/
HB_EXTERN void
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_v_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
* Deprecated: REPLACEME
**/
HB_EXTERN void
hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
HB_EXTERN hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
HB_EXTERN hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font,
hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
HB_EXTERN void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
#endif
HB_END_DECLS

View File

@ -887,6 +887,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
* Return value:
*
* Since: 0.9.2
* Deprecated: REPLACEME
**/
hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
@ -906,6 +907,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
* Return value:
*
* Since: 0.9.2
* Deprecated: REPLACEME
**/
hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font,
@ -1134,6 +1136,7 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
*
*
* Since: 0.9.2
* Deprecated: REPLACEME
**/
void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,

View File

@ -149,12 +149,6 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
void *user_data);
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
@ -338,38 +332,6 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_origin_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_h_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
**/
HB_EXTERN void
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_v_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
**/
HB_EXTERN void
hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_extents_func:
* @ffuncs: font functions.
@ -483,13 +445,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y);
HB_EXTERN hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
HB_EXTERN hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font,
hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
@ -552,12 +507,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
HB_EXTERN void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
hb_codepoint_t glyph,

View File

@ -502,8 +502,8 @@ struct hb_font_t
hb_position_t *x, hb_position_t *y)
{
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
*x = get_glyph_h_kerning (first_glyph, second_glyph);
*y = 0;
*x = get_glyph_h_kerning (first_glyph, second_glyph);
} else {
*x = 0;
*y = get_glyph_v_kerning (first_glyph, second_glyph);

View File

@ -305,23 +305,6 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
return true;
}
static hb_position_t
hb_ft_get_glyph_h_kerning (hb_font_t *font,
void *font_data,
hb_codepoint_t left_glyph,
hb_codepoint_t right_glyph,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
FT_Vector kerningv;
FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
return 0;
return kerningv.x;
}
static hb_bool_t
hb_ft_get_glyph_extents (hb_font_t *font,
void *font_data,
@ -466,8 +449,6 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr);
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr);
hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr);
//hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr);
hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr);
hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr);
hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr);

View File

@ -202,13 +202,7 @@ hb_glib_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return (hb_unicode_combining_class_t) g_unichar_combining_class (unicode);
}
static unsigned int
hb_glib_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode,
void *user_data HB_UNUSED)
{
return g_unichar_iswide (unicode) ? 2 : 1;
}
#define hb_glib_unicode_eastasian_width nullptr
static hb_unicode_general_category_t
hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
@ -334,36 +328,7 @@ hb_glib_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return ret;
}
static unsigned int
hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t u,
hb_codepoint_t *decomposed,
void *user_data HB_UNUSED)
{
#if GLIB_CHECK_VERSION(2,29,12)
return g_unichar_fully_decompose (u, true, decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN);
#endif
/* If the user doesn't have GLib >= 2.29.12 we have to perform
* a round trip to UTF-8 and the associated memory management dance. */
gchar utf8[6];
gchar *utf8_decomposed, *c;
gsize utf8_len, utf8_decomposed_len, i;
/* Convert @u to UTF-8 and normalise it in NFKD mode. This performs the compatibility decomposition. */
utf8_len = g_unichar_to_utf8 (u, utf8);
utf8_decomposed = g_utf8_normalize (utf8, utf8_len, G_NORMALIZE_NFKD);
utf8_decomposed_len = g_utf8_strlen (utf8_decomposed, -1);
assert (utf8_decomposed_len <= HB_UNICODE_MAX_DECOMPOSITION_LEN);
for (i = 0, c = utf8_decomposed; i < utf8_decomposed_len; i++, c = g_utf8_next_char (c))
*decomposed++ = g_utf8_get_char (c);
g_free (utf8_decomposed);
return utf8_decomposed_len;
}
#define hb_glib_unicode_decompose_compatibility nullptr
#ifdef HB_USE_ATEXIT

View File

@ -73,24 +73,7 @@ hb_icu_unicode_combining_class (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return (hb_unicode_combining_class_t) u_getCombiningClass (unicode);
}
static unsigned int
hb_icu_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode,
void *user_data HB_UNUSED)
{
switch (u_getIntPropertyValue(unicode, UCHAR_EAST_ASIAN_WIDTH))
{
case U_EA_WIDE:
case U_EA_FULLWIDTH:
return 2;
case U_EA_NEUTRAL:
case U_EA_AMBIGUOUS:
case U_EA_HALFWIDTH:
case U_EA_NARROW:
return 1;
}
return 1;
}
#define hb_icu_unicode_eastasian_width nullptr
static hb_unicode_general_category_t
hb_icu_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED,
@ -309,39 +292,8 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return ret;
}
static unsigned int
hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t u,
hb_codepoint_t *decomposed,
void *user_data HB_UNUSED)
{
UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
unsigned int len;
int32_t utf32_len;
hb_bool_t err;
UErrorCode icu_err;
#define hb_icu_unicode_decompose_compatibility nullptr
/* Copy @u into a UTF-16 array to be passed to ICU. */
len = 0;
err = false;
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), u, err);
if (err)
return 0;
/* Normalise the codepoint using NFKD mode. */
icu_err = U_ZERO_ERROR;
len = unorm2_normalize (unorm2_getNFKDInstance (&icu_err), utf16, len, normalized, ARRAY_LENGTH (normalized), &icu_err);
if (U_FAILURE (icu_err))
return 0;
/* Convert the decomposed form from UTF-16 to UTF-32. */
icu_err = U_ZERO_ERROR;
u_strToUTF32 ((UChar32*) decomposed, HB_UNICODE_MAX_DECOMPOSITION_LEN, &utf32_len, normalized, len, &icu_err);
if (U_FAILURE (icu_err))
return 0;
return utf32_len;
}
#ifdef HB_USE_ATEXIT
static void free_static_icu_funcs (void);

View File

@ -702,7 +702,11 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
}
};
/* Binary-search arrays */
/*
* Binary-search arrays
*/
template <typename LenType=HBUINT16>
struct BinSearchHeader
{
inline operator uint32_t (void) const { return len; }
@ -725,17 +729,117 @@ struct BinSearchHeader
}
protected:
HBUINT16 len;
HBUINT16 searchRange;
HBUINT16 entrySelector;
HBUINT16 rangeShift;
LenType len;
LenType searchRange;
LenType entrySelector;
LenType rangeShift;
public:
DEFINE_SIZE_STATIC (8);
};
template <typename Type, typename LenType=HBUINT16>
struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader<LenType> > {};
struct VarSizedBinSearchHeader
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */
HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */
HBUINT16 searchRange; /* The value of unitSize times the largest power of 2
* that is less than or equal to the value of nUnits. */
HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than
* or equal to the value of nUnits. */
HBUINT16 rangeShift; /* The value of unitSize times the difference of the
* value of nUnits minus the largest power of 2 less
* than or equal to the value of nUnits. */
public:
DEFINE_SIZE_STATIC (10);
};
template <typename Type>
struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
struct VarSizedBinSearchArrayOf
{
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= header.nUnits)) return Null(Type);
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
}
inline Type& operator [] (unsigned int i)
{
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
}
inline unsigned int get_size (void) const
{ return header.static_size + header.nUnits * header.unitSize; }
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
/* Note: for structs that do not reference other structs,
* we do not need to call their sanitize() as we already did
* a bound check on the aggregate array size. We just include
* a small unreachable expression to make sure the structs
* pointed to do have a simple sanitize(), ie. they do not
* reference other structs via offsets.
*/
(void) (false && StructAtOffset<Type> (&bytesZ, 0).sanitize (c));
return_trace (true);
}
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
unsigned int count = header.nUnits;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(*this)[i].sanitize (c, base)))
return_trace (false);
return_trace (true);
}
template <typename T>
inline const Type *bsearch (const T &key) const
{
unsigned int size = header.unitSize;
int min = 0, max = (int) header.nUnits - 1;
while (min <= max)
{
int mid = (min + max) / 2;
const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
int c = p->cmp (key);
if (c < 0)
max = mid - 1;
else if (c > 0)
min = mid + 1;
else
return p;
}
return nullptr;
}
private:
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (header.sanitize (c) &&
Type::static_size >= header.unitSize &&
c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize));
}
protected:
VarSizedBinSearchHeader header;
UnsizedArrayOf<HBUINT8> bytesZ;
public:
DEFINE_SIZE_ARRAY (10, bytesZ);
};
} /* namespace OT */

View File

@ -105,17 +105,6 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
}
}
static hb_position_t
hb_ot_get_glyph_h_kerning (hb_font_t *font,
void *font_data,
hb_codepoint_t left_glyph,
hb_codepoint_t right_glyph,
void *user_data HB_UNUSED)
{
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
return font->em_scale_x (ot_face->kern->get_h_kerning (left_glyph, right_glyph));
}
static hb_bool_t
hb_ot_get_glyph_extents (hb_font_t *font,
void *font_data,
@ -211,8 +200,6 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
//hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr);
//hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr);
hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
//hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);

View File

@ -28,6 +28,81 @@
#define HB_OT_KERN_TABLE_HH
#include "hb-open-type.hh"
#include "hb-ot-shape.hh"
#include "hb-ot-layout-gsubgpos.hh"
template <typename Driver>
struct hb_kern_machine_t
{
hb_kern_machine_t (const Driver &driver_) : driver (driver_) {}
inline void kern (hb_font_t *font,
hb_buffer_t *buffer,
hb_mask_t kern_mask) const
{
OT::hb_ot_apply_context_t c (1, font, buffer);
c.set_lookup_mask (kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
skippy_iter.init (&c);
bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction);
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
for (unsigned int idx = 0; idx < count;)
{
if (!(info[idx].mask & kern_mask))
{
idx++;
continue;
}
skippy_iter.reset (idx, 1);
if (!skippy_iter.next ())
{
idx++;
continue;
}
unsigned int i = idx;
unsigned int j = skippy_iter.idx;
hb_position_t kern1, kern2;
hb_position_t kern = driver.get_kerning (info[i].codepoint,
info[j].codepoint);
if (likely (!kern))
goto skip;
kern1 = kern >> 1;
kern2 = kern - kern1;
if (horizontal)
{
pos[i].x_advance += kern1;
pos[j].x_advance += kern2;
pos[j].x_offset += kern2;
}
else
{
pos[i].y_advance += kern1;
pos[j].y_advance += kern2;
pos[j].y_offset += kern2;
}
buffer->unsafe_to_break (i, j + 1);
skip:
idx = skippy_iter.idx;
}
}
const Driver &driver;
};
/*
* kern -- Kerning
@ -118,7 +193,7 @@ struct KernSubTableFormat2
{
unsigned int l = (this+leftClassTable).get_class (left);
unsigned int r = (this+rightClassTable).get_class (right);
unsigned int offset = l * rowWidth + r * sizeof (FWORD);
unsigned int offset = l + r;
const FWORD *arr = &(this+array);
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
return 0;
@ -190,10 +265,10 @@ struct KernSubTableWrapper
inline const T* thiz (void) const { return static_cast<const T *> (this); }
inline bool is_horizontal (void) const
{ return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; }
{ return (thiz()->coverage & T::CheckFlags) == T::CheckHorizontal; }
inline bool is_override (void) const
{ return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); }
{ return bool (thiz()->coverage & T::Override); }
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
{ return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
@ -264,16 +339,17 @@ struct KernOT : KernTable<KernOT>
{
friend struct KernSubTableWrapper<SubTableWrapper>;
enum coverage_flags_t {
COVERAGE_DIRECTION_FLAG = 0x01u,
COVERAGE_MINIMUM_FLAG = 0x02u,
COVERAGE_CROSSSTREAM_FLAG = 0x04u,
COVERAGE_OVERRIDE_FLAG = 0x08u,
enum Coverage
{
Direction = 0x01u,
Minimum = 0x02u,
CrossStream = 0x04u,
Override = 0x08u,
COVERAGE_VARIATION_FLAG = 0x00u, /* Not supported. */
Variation = 0x00u, /* Not supported. */
COVERAGE_CHECK_FLAGS = 0x07u,
COVERAGE_CHECK_HORIZONTAL = 0x01u
CheckFlags = 0x07u,
CheckHorizontal = 0x01u
};
protected:
@ -304,15 +380,16 @@ struct KernAAT : KernTable<KernAAT>
{
friend struct KernSubTableWrapper<SubTableWrapper>;
enum coverage_flags_t {
COVERAGE_DIRECTION_FLAG = 0x80u,
COVERAGE_CROSSSTREAM_FLAG = 0x40u,
COVERAGE_VARIATION_FLAG = 0x20u,
enum Coverage
{
Direction = 0x80u,
CrossStream = 0x40u,
Variation = 0x20u,
COVERAGE_OVERRIDE_FLAG = 0x00u, /* Not supported. */
Override = 0x00u, /* Not supported. */
COVERAGE_CHECK_FLAGS = 0xE0u,
COVERAGE_CHECK_HORIZONTAL = 0x00u
CheckFlags = 0xE0u,
CheckHorizontal = 0x00u
};
protected:
@ -338,6 +415,9 @@ struct kern
{
static const hb_tag_t tableTag = HB_OT_TAG_kern;
inline bool has_data (void) const
{ return u.version32 != 0; }
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
{
switch (u.major) {
@ -371,9 +451,27 @@ struct kern
hb_blob_destroy (blob);
}
inline bool has_data (void) const
{ return table->has_data (); }
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{ return table->get_h_kerning (left, right, table_length); }
inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
{ return get_h_kerning (first, second); }
inline void apply (hb_font_t *font,
hb_buffer_t *buffer,
hb_mask_t kern_mask) const
{
if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
return;
hb_kern_machine_t<accelerator_t> machine (*this);
machine.kern (font, buffer, kern_mask);
}
private:
hb_blob_t *blob;
const kern *table;
@ -383,6 +481,7 @@ struct kern
protected:
union {
HBUINT16 major;
HBUINT32 version32;
KernOT ot;
KernAAT aat;
} u;

View File

@ -45,17 +45,15 @@
#include "hb-ot-color-cpal-table.hh"
#include "hb-ot-color-sbix-table.hh"
#include "hb-ot-color-svg-table.hh"
#include "hb-ot-kern-table.hh"
#include "hb-ot-name-table.hh"
// static inline const OT::BASE&
// _get_base (hb_face_t *face)
// {
// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE);
// hb_ot_face_data_t *data = hb_ot_face_data (face);
// return *(data->base.get ());
// }
static const OT::kern::accelerator_t& _get_kern (hb_face_t *face)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t);
return *hb_ot_face_data (face)->kern;
}
const OT::GDEF& _get_gdef (hb_face_t *face)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF);
@ -91,6 +89,25 @@ const OT::GPOS& _get_gpos_relaxed (hb_face_t *face)
}
/*
* kern
*/
hb_bool_t
hb_ot_layout_has_kerning (hb_face_t *face)
{
return _get_kern (face).has_data ();
}
void
hb_ot_layout_kern (hb_font_t *font,
hb_buffer_t *buffer,
hb_mask_t kern_mask)
{
_get_kern (font->face).apply (font, buffer, kern_mask);
}
/*
* GDEF
*/
@ -1306,27 +1323,3 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
{
apply_string<GSUBProxy> (c, lookup, accel);
}
/*
* OT::BASE
*/
// /**
// * hb_ot_base_has_data:
// * @face: #hb_face_t to test
// *
// * This function allows to verify the presence of an OpenType BASE table on the
// * face.
// *
// * Return value: true if face has a BASE table, false otherwise
// *
// * Since: XXX
// **/
// hb_bool_t
// hb_ot_base_has_data (hb_face_t *face)
// {
// return _get_base (face).has_data ();
// }

View File

@ -49,6 +49,19 @@ HB_INTERNAL const OT::GSUB& _get_gsub_relaxed (hb_face_t *face);
HB_INTERNAL const OT::GPOS& _get_gpos_relaxed (hb_face_t *face);
/*
* kern
*/
HB_INTERNAL hb_bool_t
hb_ot_layout_has_kerning (hb_face_t *face);
HB_INTERNAL void
hb_ot_layout_kern (hb_font_t *font,
hb_buffer_t *buffer,
hb_mask_t kern_mask);
/* Private API corresponding to hb-ot-layout.h: */
HB_INTERNAL hb_bool_t

View File

@ -25,7 +25,7 @@
*/
#include "hb-ot-shape-fallback.hh"
#include "hb-ot-layout-gsubgpos.hh"
#include "hb-ot-kern-table.hh"
static unsigned int
recategorize_combining_class (hb_codepoint_t u,
@ -162,7 +162,7 @@ recategorize_combining_class (hb_codepoint_t u,
}
void
_hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
_hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
@ -417,7 +417,7 @@ position_cluster (const hb_ot_shape_plan_t *plan,
}
void
_hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
_hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
@ -435,67 +435,34 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
}
/* Performs old-style TrueType kerning. */
/* Performs font-assisted kerning. */
void
_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
if (!plan->kerning_requested) return;
OT::hb_ot_apply_context_t c (1, font, buffer);
hb_mask_t kern_mask = plan->kern_mask;
c.set_lookup_mask (kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
skippy_iter.init (&c);
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
for (unsigned int idx = 0; idx < count;)
struct driver_t
{
if (!(info[idx].mask & kern_mask))
driver_t (hb_font_t *font_,
hb_buffer_t *buffer) :
font (font_), direction (buffer->props.direction) {}
hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
{
idx++;
continue;
hb_position_t kern = 0;
font->get_glyph_kerning_for_direction (first, second,
direction,
&kern, &kern);
return kern;
}
skippy_iter.reset (idx, 1);
if (!skippy_iter.next ())
{
idx++;
continue;
}
hb_font_t *font;
hb_direction_t direction;
} driver (font, buffer);
hb_position_t x_kern, y_kern;
font->get_glyph_kerning_for_direction (info[idx].codepoint,
info[skippy_iter.idx].codepoint,
buffer->props.direction,
&x_kern, &y_kern);
hb_kern_machine_t<driver_t> machine (driver);
if (x_kern)
{
hb_position_t kern1 = x_kern >> 1;
hb_position_t kern2 = x_kern - kern1;
pos[idx].x_advance += kern1;
pos[skippy_iter.idx].x_advance += kern2;
pos[skippy_iter.idx].x_offset += kern2;
buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
}
if (y_kern)
{
hb_position_t kern1 = y_kern >> 1;
hb_position_t kern2 = y_kern - kern1;
pos[idx].y_advance += kern1;
pos[skippy_iter.idx].y_advance += kern2;
pos[skippy_iter.idx].y_offset += kern2;
buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
}
idx = skippy_iter.idx;
}
machine.kern (font, buffer, plan->kern_mask);
}

View File

@ -32,11 +32,11 @@
#include "hb-ot-shape.hh"
HB_INTERNAL void _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
HB_INTERNAL void _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
HB_INTERNAL void _hb_ot_shape_fallback_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
HB_INTERNAL void _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);

View File

@ -41,7 +41,7 @@ enum hb_ot_shape_normalization_mode_t {
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS, /* Never composes base-to-base */
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, /* Always fully decomposes and then recompose back */
HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* Choose decomposed if GPOS mark feature available, compose otherwise. */
HB_OT_SHAPE_NORMALIZATION_MODE_AUTO, /* See hb-ot-shape-normalize.cc for logic. */
HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT = HB_OT_SHAPE_NORMALIZATION_MODE_AUTO
};

View File

@ -69,8 +69,9 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
bool disable_gpos = plan.shaper->gpos_tag &&
plan.shaper->gpos_tag != plan.map.chosen_script[1];
plan.apply_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
plan.fallback_positioning = !plan.apply_gpos;
plan.apply_kern = !plan.apply_gpos && hb_ot_layout_has_kerning (face);
plan.fallback_kerning = !plan.apply_gpos && !plan.apply_kern;
plan.fallback_mark_positioning = !plan.apply_gpos;
plan.fallback_glyph_classes = !hb_ot_layout_has_glyph_classes (face);
}
@ -404,7 +405,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
/* Substitute */
static inline void
hb_ot_mirror_chars (hb_ot_shape_context_t *c)
hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
{
if (HB_DIRECTION_IS_FORWARD (c->target_direction))
return;
@ -425,7 +426,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
{
if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
!c->plan->has_frac)
@ -475,7 +476,7 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
hb_ot_shape_initialize_masks (const hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer;
@ -485,7 +486,7 @@ hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c)
{
hb_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer;
@ -507,7 +508,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
}
static void
hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c)
{
hb_buffer_t *buffer = c->buffer;
@ -526,7 +527,7 @@ hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
}
static void
hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c)
{
hb_buffer_t *buffer = c->buffer;
@ -609,7 +610,7 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
}
static inline void
hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
hb_synthesize_glyph_classes (const hb_ot_shape_context_t *c)
{
unsigned int count = c->buffer->len;
hb_glyph_info_t *info = c->buffer->info;
@ -635,7 +636,7 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_substitute_default (hb_ot_shape_context_t *c)
hb_ot_substitute_default (const hb_ot_shape_context_t *c)
{
hb_buffer_t *buffer = c->buffer;
@ -648,8 +649,8 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
hb_ot_shape_setup_masks (c);
/* This is unfortunate to go here, but necessary... */
if (c->plan->fallback_positioning)
_hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
if (c->plan->fallback_mark_positioning)
_hb_ot_shape_fallback_mark_position_recategorize_marks (c->plan, c->font, buffer);
hb_ot_map_glyphs_fast (buffer);
@ -657,7 +658,7 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_substitute_complex (hb_ot_shape_context_t *c)
hb_ot_substitute_complex (const hb_ot_shape_context_t *c)
{
hb_buffer_t *buffer = c->buffer;
@ -673,7 +674,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_substitute (hb_ot_shape_context_t *c)
hb_ot_substitute (const hb_ot_shape_context_t *c)
{
hb_ot_substitute_default (c);
@ -713,7 +714,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
}
static inline void
hb_ot_position_default (hb_ot_shape_context_t *c)
hb_ot_position_default (const hb_ot_shape_context_t *c)
{
hb_direction_t direction = c->buffer->props.direction;
unsigned int count = c->buffer->len;
@ -747,7 +748,7 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_position_complex (hb_ot_shape_context_t *c)
hb_ot_position_complex (const hb_ot_shape_context_t *c)
{
unsigned int count = c->buffer->len;
hb_glyph_info_t *info = c->buffer->info;
@ -762,7 +763,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
* If fallback positinoing happens or GPOS is present, we don't
* care.
*/
bool adjust_offsets_when_zeroing = c->plan->fallback_positioning &&
bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning &&
!c->plan->shaper->fallback_position &&
HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
@ -818,7 +819,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
}
static inline void
hb_ot_position (hb_ot_shape_context_t *c)
hb_ot_position (const hb_ot_shape_context_t *c)
{
c->buffer->clear_positions ();
@ -826,15 +827,19 @@ hb_ot_position (hb_ot_shape_context_t *c)
hb_ot_position_complex (c);
if (c->plan->fallback_positioning && c->plan->shaper->fallback_position)
_hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
_hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
hb_buffer_reverse (c->buffer);
/* Visual fallback goes here. */
if (c->plan->fallback_positioning)
if (!c->plan->kerning_requested)
;
else if (c->plan->apply_kern)
hb_ot_layout_kern (c->font, c->buffer, c->plan->kern_mask);
else if (c->plan->fallback_kerning)
_hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);

View File

@ -46,11 +46,12 @@ struct hb_ot_shape_plan_t
bool has_frac : 1;
bool kerning_requested : 1;
bool has_gpos_mark : 1;
bool fallback_positioning : 1;
bool fallback_glyph_classes : 1;
bool fallback_kerning : 1;
bool fallback_mark_positioning : 1;
bool apply_morx : 1;
bool apply_kern : 1;
bool apply_gpos : 1;

View File

@ -182,14 +182,7 @@ hb_ucdn_combining_class(hb_unicode_funcs_t *ufuncs HB_UNUSED,
return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
}
static unsigned int
hb_ucdn_eastasian_width(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode,
void *user_data HB_UNUSED)
{
int w = ucdn_get_east_asian_width(unicode);
return (w == UCDN_EAST_ASIAN_F || w == UCDN_EAST_ASIAN_W) ? 2 : 1;
}
#define hb_ucdn_eastasian_width nullptr
static hb_unicode_general_category_t
hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED,
@ -231,13 +224,7 @@ hb_ucdn_decompose(hb_unicode_funcs_t *ufuncs HB_UNUSED,
return ucdn_decompose(ab, a, b);
}
static unsigned int
hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t u, hb_codepoint_t *decomposed,
void *user_data HB_UNUSED)
{
return ucdn_compat_decompose(u, decomposed);
}
#define hb_ucdn_decompose_compatibility nullptr
#ifdef HB_USE_ATEXIT

View File

@ -230,9 +230,6 @@ hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs);
typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
typedef unsigned int (*hb_unicode_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
@ -254,32 +251,6 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *b,
void *user_data);
/**
* hb_unicode_decompose_compatibility_func_t:
* @ufuncs: a Unicode function structure
* @u: codepoint to decompose
* @decomposed: address of codepoint array (of length %HB_UNICODE_MAX_DECOMPOSITION_LEN) to write decomposition into
* @user_data: user data pointer as passed to hb_unicode_funcs_set_decompose_compatibility_func()
*
* Fully decompose @u to its Unicode compatibility decomposition. The codepoints of the decomposition will be written to @decomposed.
* The complete length of the decomposition will be returned.
*
* If @u has no compatibility decomposition, zero should be returned.
*
* The Unicode standard guarantees that a buffer of length %HB_UNICODE_MAX_DECOMPOSITION_LEN codepoints will always be sufficient for any
* compatibility decomposition plus an terminating value of 0. Consequently, @decompose must be allocated by the caller to be at least this length. Implementations
* of this function type must ensure that they do not write past the provided array.
*
* Return value: number of codepoints in the full compatibility decomposition of @u, or 0 if no decomposition available.
*/
typedef unsigned int (*hb_unicode_decompose_compatibility_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t u,
hb_codepoint_t *decomposed,
void *user_data);
/* See Unicode 6.1 for details on the maximum decomposition length. */
#define HB_UNICODE_MAX_DECOMPOSITION_LEN (18+1) /* codepoints */
/* setters */
/**
@ -298,22 +269,6 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_combining_class_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_unicode_funcs_set_eastasian_width_func:
* @ufuncs: a Unicode function structure
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
**/
HB_EXTERN void
hb_unicode_funcs_set_eastasian_width_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_eastasian_width_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_unicode_funcs_set_general_category_func:
* @ufuncs: a Unicode function structure
@ -394,22 +349,6 @@ hb_unicode_funcs_set_decompose_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_decompose_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_unicode_funcs_set_decompose_compatibility_func:
* @ufuncs: a Unicode function structure
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
**/
HB_EXTERN void
hb_unicode_funcs_set_decompose_compatibility_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_decompose_compatibility_func_t func,
void *user_data, hb_destroy_func_t destroy);
/* accessors */
/**
@ -421,15 +360,6 @@ HB_EXTERN hb_unicode_combining_class_t
hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode);
/**
* hb_unicode_eastasian_width:
*
* Since: 0.9.2
**/
HB_EXTERN unsigned int
hb_unicode_eastasian_width (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode);
/**
* hb_unicode_general_category:
*
@ -469,11 +399,6 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *a,
hb_codepoint_t *b);
HB_EXTERN unsigned int
hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t u,
hb_codepoint_t *decomposed);
HB_END_DECLS
#endif /* HB_UNICODE_H */

View File

@ -160,69 +160,6 @@ static const test_pair_t combining_class_tests_more[] =
{ 0x111111, 0 }
};
static const test_pair_t eastasian_width_tests[] =
{
/* Neutral */
{ 0x0000, 1 },
{ 0x0483, 1 },
{ 0x0641, 1 },
{ 0xFFFC, 1 },
{ 0x10000, 1 },
{ 0xE0001, 1 },
/* Narrow */
{ 0x0020, 1 },
{ 0x0041, 1 },
{ 0x27E6, 1 },
/* Halfwidth */
{ 0x20A9, 1 },
{ 0xFF61, 1 },
{ 0xFF69, 1 },
{ 0xFFEE, 1 },
/* Ambiguous */
{ 0x00A1, 1 },
{ 0x00D8, 1 },
{ 0x02DD, 1 },
{ 0xE0100, 1 },
{ 0x100000, 1 },
/* Fullwidth */
{ 0x3000, 2 },
{ 0xFF60, 2 },
/* Wide */
{ 0x2329, 2 },
{ 0x3001, 2 },
{ 0xFE69, 2 },
{ 0x30000, 2 },
{ 0x3FFFD, 2 },
{ 0x111111, 1 }
};
static const test_pair_t eastasian_width_tests_more[] =
{
/* Default Wide blocks */
{ 0x4DBF, 2 },
{ 0x9FFF, 2 },
{ 0xFAFF, 2 },
{ 0x2A6DF, 2 },
{ 0x2B73F, 2 },
{ 0x2B81F, 2 },
{ 0x2FA1F, 2 },
/* Uniode-5.2 character additions */
/* Wide */
{ 0x115F, 2 },
/* Uniode-6.0 character additions */
/* Wide */
{ 0x2B740, 2 },
{ 0x1B000, 2 },
{ 0x111111, 1 }
};
static const test_pair_t general_category_tests[] =
{
@ -469,7 +406,6 @@ typedef struct {
static const property_t properties[] =
{
PROPERTY (combining_class, 0),
PROPERTY (eastasian_width, 1),
PROPERTY (general_category, (unsigned int) HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER),
PROPERTY (mirroring, RETURNS_UNICODE_ITSELF),
PROPERTY (script, (unsigned int) HB_SCRIPT_UNKNOWN)
@ -786,7 +722,6 @@ test_unicode_normalization (gconstpointer user_data)
{
hb_unicode_funcs_t *uf = (hb_unicode_funcs_t *) user_data;
gunichar a, b, ab;
hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
/* Test compose() */
@ -849,56 +784,6 @@ test_unicode_normalization (gconstpointer user_data)
g_assert (hb_unicode_decompose (uf, 0xD4CC, &a, &b) && a == 0x1111 && b == 0x1171);
g_assert (hb_unicode_decompose (uf, 0xCE31, &a, &b) && a == 0xCE20 && b == 0x11B8);
g_assert (hb_unicode_decompose (uf, 0xCE20, &a, &b) && a == 0x110E && b == 0x1173);
/* Test decompose_compatibility() */
/* Not decomposable */
g_assert (hb_unicode_decompose_compatibility (uf, 0x0041, decomposed) == 0);
g_assert (hb_unicode_decompose_compatibility (uf, 0x1F632, decomposed) == 0);
/* Singletons */
g_assert (hb_unicode_decompose_compatibility (uf, 0x00B5, decomposed) == 1 && decomposed[0] == 0x03BC);
g_assert (hb_unicode_decompose_compatibility (uf, 0x03D6, decomposed) == 1 && decomposed[0] == 0x03C0);
/* Arabic compatibility */
g_assert (hb_unicode_decompose_compatibility (uf, 0xFB54, decomposed) == 1 && decomposed[0] == 0x067B);
/* Longest decomposition ever */
g_assert (18 <= HB_UNICODE_MAX_DECOMPOSITION_LEN);
g_assert (hb_unicode_decompose_compatibility (uf, 0xFDFA, decomposed) == 18 && decomposed[17] == 0x0645);
/* Note: we deliberately don't test characters that have canonical decompositions but no
* compatibility decomposition against the decompose_compatibility() function as that we
* leave up to implementations (for now). */
/* Spaces */
g_assert (hb_unicode_decompose_compatibility (uf, 0x2002, decomposed) == 1 && decomposed[0] == 0x0020);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2003, decomposed) == 1 && decomposed[0] == 0x0020);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2004, decomposed) == 1 && decomposed[0] == 0x0020);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2005, decomposed) == 1 && decomposed[0] == 0x0020);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2006, decomposed) == 1 && decomposed[0] == 0x0020);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2008, decomposed) == 1 && decomposed[0] == 0x0020);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2009, decomposed) == 1 && decomposed[0] == 0x0020);
g_assert (hb_unicode_decompose_compatibility (uf, 0x200A, decomposed) == 1 && decomposed[0] == 0x0020);
/* Pairs */
g_assert (hb_unicode_decompose_compatibility (uf, 0x0587, decomposed) == 2 &&
decomposed[0] == 0x0565 && decomposed[1] == 0x0582);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2017, decomposed) == 2 &&
decomposed[0] == 0x0020 && decomposed[1] == 0x0333);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2025, decomposed) == 2 &&
decomposed[0] == 0x002E && decomposed[1] == 0x002E);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2033, decomposed) == 2 &&
decomposed[0] == 0x2032 && decomposed[1] == 0x2032);
/* Triples */
g_assert (hb_unicode_decompose_compatibility (uf, 0x2026, decomposed) == 3 &&
decomposed[0] == 0x002E && decomposed[1] == 0x002E && decomposed[2] == 0x002E);
g_assert (hb_unicode_decompose_compatibility (uf, 0x2034, decomposed) == 3 &&
decomposed[0] == 0x2032 && decomposed[1] == 0x2032 && decomposed[2] == 0x2032);
g_assert (hb_unicode_decompose_compatibility (uf, 0x213B, decomposed) == 3 &&
decomposed[0] == 0x0046 && decomposed[1] == 0x0041 && decomposed[2] == 0x0058);
}

View File

@ -1,6 +1,3 @@
# https://github.com/harfbuzz/harfbuzz/issues/1224
tests/MORX-35.tests
# Non-Unicode cmap
tests/CMAP-3.tests

View File

@ -55,6 +55,7 @@ TESTS = \
tests/MORX-32.tests \
tests/MORX-33.tests \
tests/MORX-34.tests \
tests/MORX-35.tests \
tests/MORX-36.tests \
tests/MORX-37.tests \
tests/MORX-38.tests \
@ -73,7 +74,6 @@ TESTS = \
DISBALED_TESTS = \
tests/CMAP-3.tests \
tests/MORX-35.tests \
tests/SHARAN-1.tests \
tests/SHBALI-1.tests \
tests/SHBALI-2.tests \

View File

@ -1,2 +1,2 @@
../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A|B@639,0|E@1265,0|C@1821,0|E@2417,0]
../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[X|A@586,0|B@1225,0|E@1851,0|C@2407,0|E@3003,0|Y@3559,0]
../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A|B@639,0|C@1265,0|E@1861,0]
../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[X|A@586,0|B@1225,0|C@1851,0|E@2447,0|Y@3003,0]