Merge branch 'master' into cff-subset
This commit is contained in:
commit
8b349040e9
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
19
src/hb-ft.cc
19
src/hb-ft.cc
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 ();
|
|
||||||
// }
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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]
|
||||||
|
|
Loading…
Reference in New Issue