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_funcs_set_glyph_func
hb_font_get_glyph_func_t hb_font_get_glyph_func_t
hb_set_invert 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>
<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_from_name_func
hb_font_funcs_set_glyph_h_advance_func hb_font_funcs_set_glyph_h_advance_func
hb_font_funcs_set_glyph_h_advances_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_h_origin_func
hb_font_funcs_set_glyph_name_func hb_font_funcs_set_glyph_name_func
hb_font_funcs_set_glyph_v_advance_func hb_font_funcs_set_glyph_v_advance_func
hb_font_funcs_set_glyph_v_advances_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_glyph_v_origin_func
hb_font_funcs_set_nominal_glyph_func hb_font_funcs_set_nominal_glyph_func
hb_font_funcs_set_user_data 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_advance_func_t
hb_font_get_glyph_h_advances hb_font_get_glyph_h_advances
hb_font_get_glyph_h_advances_func_t 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
hb_font_get_glyph_h_origin_func_t 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
hb_font_get_glyph_name_func_t hb_font_get_glyph_name_func_t
hb_font_get_glyph_origin_for_direction 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_advance_func_t
hb_font_get_glyph_v_advances hb_font_get_glyph_v_advances
hb_font_get_glyph_v_advances_func_t 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
hb_font_get_glyph_v_origin_func_t hb_font_get_glyph_v_origin_func_t
hb_font_get_nominal_glyph hb_font_get_nominal_glyph
@ -613,16 +620,13 @@ hb_shape_plan_t
<SECTION> <SECTION>
<FILE>hb-unicode</FILE> <FILE>hb-unicode</FILE>
HB_UNICODE_MAX HB_UNICODE_MAX
HB_UNICODE_MAX_DECOMPOSITION_LEN
hb_unicode_combining_class hb_unicode_combining_class
hb_unicode_combining_class_func_t hb_unicode_combining_class_func_t
hb_unicode_combining_class_t hb_unicode_combining_class_t
hb_unicode_compose hb_unicode_compose
hb_unicode_compose_func_t hb_unicode_compose_func_t
hb_unicode_decompose hb_unicode_decompose
hb_unicode_decompose_compatibility
hb_unicode_decompose_func_t hb_unicode_decompose_func_t
hb_unicode_eastasian_width
hb_unicode_funcs_create hb_unicode_funcs_create
hb_unicode_funcs_destroy hb_unicode_funcs_destroy
hb_unicode_funcs_get_default hb_unicode_funcs_get_default
@ -634,9 +638,7 @@ hb_unicode_funcs_make_immutable
hb_unicode_funcs_reference hb_unicode_funcs_reference
hb_unicode_funcs_set_combining_class_func hb_unicode_funcs_set_combining_class_func
hb_unicode_funcs_set_compose_func hb_unicode_funcs_set_compose_func
hb_unicode_funcs_set_decompose_compatibility_func
hb_unicode_funcs_set_decompose_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_general_category_func
hb_unicode_funcs_set_mirroring_func hb_unicode_funcs_set_mirroring_func
hb_unicode_funcs_set_script_func hb_unicode_funcs_set_script_func

View File

@ -35,111 +35,6 @@ namespace AAT {
using namespace OT; 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 * Lookup Table
*/ */
@ -213,7 +108,7 @@ struct LookupFormat2
protected: protected:
HBUINT16 format; /* Format identifier--format = 2 */ HBUINT16 format; /* Format identifier--format = 2 */
BinSearchArrayOf<LookupSegmentSingle<T> > VarSizedBinSearchArrayOf<LookupSegmentSingle<T> >
segments; /* The actual segments. These must already be sorted, segments; /* The actual segments. These must already be sorted,
* according to the first word in each one (the last * according to the first word in each one (the last
* glyph in each segment). */ * glyph in each segment). */
@ -270,7 +165,7 @@ struct LookupFormat4
protected: protected:
HBUINT16 format; /* Format identifier--format = 2 */ HBUINT16 format; /* Format identifier--format = 2 */
BinSearchArrayOf<LookupSegmentArray<T> > VarSizedBinSearchArrayOf<LookupSegmentArray<T> >
segments; /* The actual segments. These must already be sorted, segments; /* The actual segments. These must already be sorted,
* according to the first word in each one (the last * according to the first word in each one (the last
* glyph in each segment). */ * glyph in each segment). */
@ -315,7 +210,7 @@ struct LookupFormat6
protected: protected:
HBUINT16 format; /* Format identifier--format = 6 */ HBUINT16 format; /* Format identifier--format = 6 */
BinSearchArrayOf<LookupSingle<T> > VarSizedBinSearchArrayOf<LookupSingle<T> >
entries; /* The actual entries, sorted by glyph index. */ entries; /* The actual entries, sorted by glyph index. */
public: public:
DEFINE_SIZE_ARRAY (8, entries); DEFINE_SIZE_ARRAY (8, entries);

View File

@ -30,6 +30,7 @@
#include "hb-open-type.hh" #include "hb-open-type.hh"
#include "hb-aat-layout-common.hh" #include "hb-aat-layout-common.hh"
#include "hb-ot-kern-table.hh"
/* /*
* kerx -- Extended Kerning * kerx -- Extended Kerning
@ -43,33 +44,17 @@ namespace AAT {
using namespace OT; 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 struct KerxSubTableFormat0
{ {
// TODO(ebraminio) Enable when we got suitable BinSearchArrayOf inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
// inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const {
// { hb_glyph_pair_t pair = {left, right};
// hb_glyph_pair_t pair = {left, right}; int i = pairs.bsearch (pair);
// int i = pairs.bsearch (pair); if (i == -1)
// if (i == -1) return 0;
// return 0; return pairs[i].get_kerning ();
// return pairs[i].get_kerning (); }
// }
inline bool apply (hb_aat_apply_context_t *c) const inline bool apply (hb_aat_apply_context_t *c) const
{ {
TRACE_APPLY (this); TRACE_APPLY (this);
@ -82,23 +67,14 @@ struct KerxSubTableFormat0
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) && return_trace (likely (pairs.sanitize (c)));
recordsZ.sanitize (c, nPairs)));
} }
protected: protected:
// TODO(ebraminio): A custom version of "BinSearchArrayOf<KerxPair> pairs;" is BinSearchArrayOf<KernPair, HBUINT32>
// needed here to use HBUINT32 instead pairs; /* Sorted kern records. */
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 */
public: public:
DEFINE_SIZE_ARRAY (16, recordsZ); DEFINE_SIZE_ARRAY (16, pairs);
}; };
struct KerxSubTableFormat1 struct KerxSubTableFormat1
@ -126,32 +102,14 @@ struct KerxSubTableFormat1
DEFINE_SIZE_STATIC (20); 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 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 l = *(this+leftClassTable).get_value (left, num_glyphs);
unsigned int r = (this+leftClassTable).get_class (left); unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs);
unsigned int offset = l * rowWidth + r * sizeof (FWORD); unsigned int offset = l + r;
const FWORD *arr = &(this+array); const FWORD *arr = &(this+array);
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end)) if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
return 0; return 0;
@ -182,10 +140,10 @@ struct KerxSubTableFormat2
protected: protected:
HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */ 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 leftClassTable; /* Offset from beginning of this subtable to
* left-hand class table. */ * left-hand class table. */
LOffsetTo<KerxClassTable> LOffsetTo<Lookup<HBUINT16> >
rightClassTable;/* Offset from beginning of this subtable to rightClassTable;/* Offset from beginning of this subtable to
* right-hand class table. */ * right-hand class table. */
LOffsetTo<FWORD> LOffsetTo<FWORD>
@ -209,26 +167,14 @@ struct KerxSubTableFormat4
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
rowWidth.sanitize (c) && /* TODO */
leftClassTable.sanitize (c, this) && return_trace (likely (c->check_struct (this)));
rightClassTable.sanitize (c, this) &&
array.sanitize (c, this)));
} }
protected: 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: public:
DEFINE_SIZE_STATIC (16); DEFINE_SIZE_STATIC (1);
}; };
struct KerxSubTableFormat6 struct KerxSubTableFormat6
@ -266,6 +212,8 @@ struct KerxSubTableFormat6
struct KerxTable struct KerxTable
{ {
friend kerx;
inline unsigned int get_size (void) const { return length; } inline unsigned int get_size (void) const { return length; }
inline unsigned int get_type (void) const { return coverage & SubtableType; } inline unsigned int get_type (void) const { return coverage & SubtableType; }
@ -358,7 +306,33 @@ struct kerx
unsigned int count = tableCount; unsigned int count = tableCount;
for (unsigned int i = 0; i < count; i++) 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); 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); table = &StructAfter<KerxTable> (*table);
} }
} }

View File

@ -63,6 +63,15 @@ typedef unsigned __int64 uint64_t;
# include <stdint.h> # include <stdint.h>
#endif #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 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, hb_codepoint_t *glyph,
void *user_data); void *user_data);
HB_EXTERN void HB_EXTERN HB_DEPRECATED void
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs, hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_func_t func, hb_font_get_glyph_func_t func,
void *user_data, hb_destroy_func_t destroy); void *user_data, hb_destroy_func_t destroy);
HB_EXTERN void HB_EXTERN HB_DEPRECATED void
hb_set_invert (hb_set_t *set); 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 #endif
HB_END_DECLS HB_END_DECLS

View File

@ -887,6 +887,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
* Return value: * Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
* Deprecated: REPLACEME
**/ **/
hb_position_t hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font, 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: * Return value:
* *
* Since: 0.9.2 * Since: 0.9.2
* Deprecated: REPLACEME
**/ **/
hb_position_t hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font, 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 * Since: 0.9.2
* Deprecated: REPLACEME
**/ **/
void void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font, 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_h_origin_func_t;
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_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, typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph, 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, hb_font_get_glyph_v_origin_func_t func,
void *user_data, hb_destroy_func_t destroy); 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: * hb_font_funcs_set_glyph_extents_func:
* @ffuncs: font functions. * @ffuncs: font functions.
@ -483,13 +445,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph, hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y); 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_EXTERN hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font, hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph, hb_codepoint_t glyph,
@ -552,12 +507,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
hb_direction_t direction, hb_direction_t direction,
hb_position_t *x, hb_position_t *y); 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_EXTERN hb_bool_t
hb_font_get_glyph_extents_for_origin (hb_font_t *font, hb_font_get_glyph_extents_for_origin (hb_font_t *font,
hb_codepoint_t glyph, hb_codepoint_t glyph,

View File

@ -502,8 +502,8 @@ struct hb_font_t
hb_position_t *x, hb_position_t *y) hb_position_t *x, hb_position_t *y)
{ {
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
*x = get_glyph_h_kerning (first_glyph, second_glyph);
*y = 0; *y = 0;
*x = get_glyph_h_kerning (first_glyph, second_glyph);
} else { } else {
*x = 0; *x = 0;
*y = get_glyph_v_kerning (first_glyph, second_glyph); *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; 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 static hb_bool_t
hb_ft_get_glyph_extents (hb_font_t *font, hb_ft_get_glyph_extents (hb_font_t *font,
void *font_data, 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_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_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_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_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_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); 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); return (hb_unicode_combining_class_t) g_unichar_combining_class (unicode);
} }
static unsigned int #define hb_glib_unicode_eastasian_width nullptr
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;
}
static hb_unicode_general_category_t static hb_unicode_general_category_t
hb_glib_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED, 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; return ret;
} }
static unsigned int #define hb_glib_unicode_decompose_compatibility nullptr
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;
}
#ifdef HB_USE_ATEXIT #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); return (hb_unicode_combining_class_t) u_getCombiningClass (unicode);
} }
static unsigned int #define hb_icu_unicode_eastasian_width nullptr
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;
}
static hb_unicode_general_category_t static hb_unicode_general_category_t
hb_icu_unicode_general_category (hb_unicode_funcs_t *ufuncs HB_UNUSED, 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; return ret;
} }
static unsigned int #define hb_icu_unicode_decompose_compatibility nullptr
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;
/* 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 #ifdef HB_USE_ATEXIT
static void free_static_icu_funcs (void); 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 struct BinSearchHeader
{ {
inline operator uint32_t (void) const { return len; } inline operator uint32_t (void) const { return len; }
@ -725,17 +729,117 @@ struct BinSearchHeader
} }
protected: protected:
HBUINT16 len; LenType len;
HBUINT16 searchRange; LenType searchRange;
HBUINT16 entrySelector; LenType entrySelector;
HBUINT16 rangeShift; LenType rangeShift;
public: public:
DEFINE_SIZE_STATIC (8); 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> 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 */ } /* 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 static hb_bool_t
hb_ot_get_glyph_extents (hb_font_t *font, hb_ot_get_glyph_extents (hb_font_t *font,
void *font_data, 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_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_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_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_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_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); 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 #define HB_OT_KERN_TABLE_HH
#include "hb-open-type.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 * kern -- Kerning
@ -118,7 +193,7 @@ struct KernSubTableFormat2
{ {
unsigned int l = (this+leftClassTable).get_class (left); unsigned int l = (this+leftClassTable).get_class (left);
unsigned int r = (this+rightClassTable).get_class (right); 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); const FWORD *arr = &(this+array);
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end)) if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
return 0; return 0;
@ -190,10 +265,10 @@ struct KernSubTableWrapper
inline const T* thiz (void) const { return static_cast<const T *> (this); } inline const T* thiz (void) const { return static_cast<const T *> (this); }
inline bool is_horizontal (void) const 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 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 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); } { return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
@ -264,16 +339,17 @@ struct KernOT : KernTable<KernOT>
{ {
friend struct KernSubTableWrapper<SubTableWrapper>; friend struct KernSubTableWrapper<SubTableWrapper>;
enum coverage_flags_t { enum Coverage
COVERAGE_DIRECTION_FLAG = 0x01u, {
COVERAGE_MINIMUM_FLAG = 0x02u, Direction = 0x01u,
COVERAGE_CROSSSTREAM_FLAG = 0x04u, Minimum = 0x02u,
COVERAGE_OVERRIDE_FLAG = 0x08u, CrossStream = 0x04u,
Override = 0x08u,
COVERAGE_VARIATION_FLAG = 0x00u, /* Not supported. */ Variation = 0x00u, /* Not supported. */
COVERAGE_CHECK_FLAGS = 0x07u, CheckFlags = 0x07u,
COVERAGE_CHECK_HORIZONTAL = 0x01u CheckHorizontal = 0x01u
}; };
protected: protected:
@ -304,15 +380,16 @@ struct KernAAT : KernTable<KernAAT>
{ {
friend struct KernSubTableWrapper<SubTableWrapper>; friend struct KernSubTableWrapper<SubTableWrapper>;
enum coverage_flags_t { enum Coverage
COVERAGE_DIRECTION_FLAG = 0x80u, {
COVERAGE_CROSSSTREAM_FLAG = 0x40u, Direction = 0x80u,
COVERAGE_VARIATION_FLAG = 0x20u, CrossStream = 0x40u,
Variation = 0x20u,
COVERAGE_OVERRIDE_FLAG = 0x00u, /* Not supported. */ Override = 0x00u, /* Not supported. */
COVERAGE_CHECK_FLAGS = 0xE0u, CheckFlags = 0xE0u,
COVERAGE_CHECK_HORIZONTAL = 0x00u CheckHorizontal = 0x00u
}; };
protected: protected:
@ -338,6 +415,9 @@ struct kern
{ {
static const hb_tag_t tableTag = HB_OT_TAG_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 inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
{ {
switch (u.major) { switch (u.major) {
@ -371,9 +451,27 @@ struct kern
hb_blob_destroy (blob); 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 inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{ return table->get_h_kerning (left, right, table_length); } { 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: private:
hb_blob_t *blob; hb_blob_t *blob;
const kern *table; const kern *table;
@ -383,6 +481,7 @@ struct kern
protected: protected:
union { union {
HBUINT16 major; HBUINT16 major;
HBUINT32 version32;
KernOT ot; KernOT ot;
KernAAT aat; KernAAT aat;
} u; } u;

View File

@ -45,17 +45,15 @@
#include "hb-ot-color-cpal-table.hh" #include "hb-ot-color-cpal-table.hh"
#include "hb-ot-color-sbix-table.hh" #include "hb-ot-color-sbix-table.hh"
#include "hb-ot-color-svg-table.hh" #include "hb-ot-color-svg-table.hh"
#include "hb-ot-kern-table.hh"
#include "hb-ot-name-table.hh" #include "hb-ot-name-table.hh"
// static inline const OT::BASE& static const OT::kern::accelerator_t& _get_kern (hb_face_t *face)
// _get_base (hb_face_t *face) {
// { if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::kern::accelerator_t);
// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE); return *hb_ot_face_data (face)->kern;
// hb_ot_face_data_t *data = hb_ot_face_data (face); }
// return *(data->base.get ());
// }
const OT::GDEF& _get_gdef (hb_face_t *face) const OT::GDEF& _get_gdef (hb_face_t *face)
{ {
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF); 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 * GDEF
*/ */
@ -1306,27 +1323,3 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
{ {
apply_string<GSUBProxy> (c, lookup, accel); 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); 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: */ /* Private API corresponding to hb-ot-layout.h: */
HB_INTERNAL hb_bool_t HB_INTERNAL hb_bool_t

View File

@ -25,7 +25,7 @@
*/ */
#include "hb-ot-shape-fallback.hh" #include "hb-ot-shape-fallback.hh"
#include "hb-ot-layout-gsubgpos.hh" #include "hb-ot-kern-table.hh"
static unsigned int static unsigned int
recategorize_combining_class (hb_codepoint_t u, recategorize_combining_class (hb_codepoint_t u,
@ -162,7 +162,7 @@ recategorize_combining_class (hb_codepoint_t u,
} }
void 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_font_t *font HB_UNUSED,
hb_buffer_t *buffer) hb_buffer_t *buffer)
{ {
@ -417,7 +417,7 @@ position_cluster (const hb_ot_shape_plan_t *plan,
} }
void 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_font_t *font,
hb_buffer_t *buffer) 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 void
_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font, hb_font_t *font,
hb_buffer_t *buffer) hb_buffer_t *buffer)
{ {
if (!plan->kerning_requested) return; struct driver_t
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;)
{ {
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++; hb_position_t kern = 0;
continue; font->get_glyph_kerning_for_direction (first, second,
direction,
&kern, &kern);
return kern;
} }
skippy_iter.reset (idx, 1); hb_font_t *font;
if (!skippy_iter.next ()) hb_direction_t direction;
{ } driver (font, buffer);
idx++;
continue;
}
hb_position_t x_kern, y_kern; hb_kern_machine_t<driver_t> machine (driver);
font->get_glyph_kerning_for_direction (info[idx].codepoint,
info[skippy_iter.idx].codepoint,
buffer->props.direction,
&x_kern, &y_kern);
if (x_kern) machine.kern (font, buffer, plan->kern_mask);
{
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;
}
} }

View File

@ -32,11 +32,11 @@
#include "hb-ot-shape.hh" #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_font_t *font,
hb_buffer_t *buffer); 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_font_t *font,
hb_buffer_t *buffer); 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, /* 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_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 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 && bool disable_gpos = plan.shaper->gpos_tag &&
plan.shaper->gpos_tag != plan.map.chosen_script[1]; plan.shaper->gpos_tag != plan.map.chosen_script[1];
plan.apply_gpos = !disable_gpos && hb_ot_layout_has_positioning (face); plan.apply_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
plan.apply_kern = !plan.apply_gpos && hb_ot_layout_has_kerning (face);
plan.fallback_positioning = !plan.apply_gpos; 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); plan.fallback_glyph_classes = !hb_ot_layout_has_glyph_classes (face);
} }
@ -404,7 +405,7 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
/* Substitute */ /* Substitute */
static inline void 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)) if (HB_DIRECTION_IS_FORWARD (c->target_direction))
return; return;
@ -425,7 +426,7 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
} }
static inline void 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) || if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
!c->plan->has_frac) !c->plan->has_frac)
@ -475,7 +476,7 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
} }
static inline void 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_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
@ -485,7 +486,7 @@ hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c)
} }
static inline void 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_ot_map_t *map = &c->plan->map;
hb_buffer_t *buffer = c->buffer; hb_buffer_t *buffer = c->buffer;
@ -507,7 +508,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
} }
static void 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; hb_buffer_t *buffer = c->buffer;
@ -526,7 +527,7 @@ hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
} }
static void 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; hb_buffer_t *buffer = c->buffer;
@ -609,7 +610,7 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
} }
static inline void 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; unsigned int count = c->buffer->len;
hb_glyph_info_t *info = c->buffer->info; 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 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; 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); hb_ot_shape_setup_masks (c);
/* This is unfortunate to go here, but necessary... */ /* This is unfortunate to go here, but necessary... */
if (c->plan->fallback_positioning) if (c->plan->fallback_mark_positioning)
_hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer); _hb_ot_shape_fallback_mark_position_recategorize_marks (c->plan, c->font, buffer);
hb_ot_map_glyphs_fast (buffer); hb_ot_map_glyphs_fast (buffer);
@ -657,7 +658,7 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
} }
static inline void 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; hb_buffer_t *buffer = c->buffer;
@ -673,7 +674,7 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
} }
static inline void 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); hb_ot_substitute_default (c);
@ -713,7 +714,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
} }
static inline void 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; hb_direction_t direction = c->buffer->props.direction;
unsigned int count = c->buffer->len; unsigned int count = c->buffer->len;
@ -747,7 +748,7 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
} }
static inline void 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; unsigned int count = c->buffer->len;
hb_glyph_info_t *info = c->buffer->info; 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 * If fallback positinoing happens or GPOS is present, we don't
* care. * 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 && !c->plan->shaper->fallback_position &&
HB_DIRECTION_IS_FORWARD (c->buffer->props.direction); 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 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 (); c->buffer->clear_positions ();
@ -826,15 +827,19 @@ hb_ot_position (hb_ot_shape_context_t *c)
hb_ot_position_complex (c); hb_ot_position_complex (c);
if (c->plan->fallback_positioning && c->plan->shaper->fallback_position) if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
_hb_ot_shape_fallback_position (c->plan, c->font, c->buffer); _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction)) if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
hb_buffer_reverse (c->buffer); hb_buffer_reverse (c->buffer);
/* Visual fallback goes here. */ /* 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_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
_hb_buffer_deallocate_gsubgpos_vars (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 has_frac : 1;
bool kerning_requested : 1; bool kerning_requested : 1;
bool has_gpos_mark : 1; bool has_gpos_mark : 1;
bool fallback_positioning : 1;
bool fallback_glyph_classes : 1; bool fallback_glyph_classes : 1;
bool fallback_kerning : 1;
bool fallback_mark_positioning : 1;
bool apply_morx : 1; bool apply_morx : 1;
bool apply_kern : 1;
bool apply_gpos : 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); return (hb_unicode_combining_class_t) ucdn_get_combining_class(unicode);
} }
static unsigned int #define hb_ucdn_eastasian_width nullptr
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;
}
static hb_unicode_general_category_t static hb_unicode_general_category_t
hb_ucdn_general_category(hb_unicode_funcs_t *ufuncs HB_UNUSED, 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); return ucdn_decompose(ab, a, b);
} }
static unsigned int #define hb_ucdn_decompose_compatibility nullptr
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);
}
#ifdef HB_USE_ATEXIT #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, typedef hb_unicode_combining_class_t (*hb_unicode_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode, hb_codepoint_t unicode,
void *user_data); 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, typedef hb_unicode_general_category_t (*hb_unicode_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode, hb_codepoint_t unicode,
void *user_data); 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, hb_codepoint_t *b,
void *user_data); 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 */ /* setters */
/** /**
@ -298,22 +269,6 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_combining_class_func_t func, hb_unicode_combining_class_func_t func,
void *user_data, hb_destroy_func_t destroy); 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: * hb_unicode_funcs_set_general_category_func:
* @ufuncs: a Unicode function structure * @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, hb_unicode_decompose_func_t func,
void *user_data, hb_destroy_func_t destroy); 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 */ /* accessors */
/** /**
@ -421,15 +360,6 @@ HB_EXTERN hb_unicode_combining_class_t
hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs, hb_unicode_combining_class (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode); 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: * hb_unicode_general_category:
* *
@ -469,11 +399,6 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *a, hb_codepoint_t *a,
hb_codepoint_t *b); 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 HB_END_DECLS
#endif /* HB_UNICODE_H */ #endif /* HB_UNICODE_H */

View File

@ -160,69 +160,6 @@ static const test_pair_t combining_class_tests_more[] =
{ 0x111111, 0 } { 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[] = static const test_pair_t general_category_tests[] =
{ {
@ -469,7 +406,6 @@ typedef struct {
static const property_t properties[] = static const property_t properties[] =
{ {
PROPERTY (combining_class, 0), PROPERTY (combining_class, 0),
PROPERTY (eastasian_width, 1),
PROPERTY (general_category, (unsigned int) HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER), PROPERTY (general_category, (unsigned int) HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER),
PROPERTY (mirroring, RETURNS_UNICODE_ITSELF), PROPERTY (mirroring, RETURNS_UNICODE_ITSELF),
PROPERTY (script, (unsigned int) HB_SCRIPT_UNKNOWN) 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; hb_unicode_funcs_t *uf = (hb_unicode_funcs_t *) user_data;
gunichar a, b, ab; gunichar a, b, ab;
hb_codepoint_t decomposed[HB_UNICODE_MAX_DECOMPOSITION_LEN];
/* Test compose() */ /* 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, 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, 0xCE31, &a, &b) && a == 0xCE20 && b == 0x11B8);
g_assert (hb_unicode_decompose (uf, 0xCE20, &a, &b) && a == 0x110E && b == 0x1173); 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 # Non-Unicode cmap
tests/CMAP-3.tests tests/CMAP-3.tests

View File

@ -55,6 +55,7 @@ TESTS = \
tests/MORX-32.tests \ tests/MORX-32.tests \
tests/MORX-33.tests \ tests/MORX-33.tests \
tests/MORX-34.tests \ tests/MORX-34.tests \
tests/MORX-35.tests \
tests/MORX-36.tests \ tests/MORX-36.tests \
tests/MORX-37.tests \ tests/MORX-37.tests \
tests/MORX-38.tests \ tests/MORX-38.tests \
@ -73,7 +74,6 @@ TESTS = \
DISBALED_TESTS = \ DISBALED_TESTS = \
tests/CMAP-3.tests \ tests/CMAP-3.tests \
tests/MORX-35.tests \
tests/SHARAN-1.tests \ tests/SHARAN-1.tests \
tests/SHBALI-1.tests \ tests/SHBALI-1.tests \
tests/SHBALI-2.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+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|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+0058,U+0041,U+0059:[X|A@586,0|B@1225,0|C@1851,0|E@2447,0|Y@3003,0]