[GDEF] Finish public API
This commit is contained in:
parent
aff831ed67
commit
590d55cbb9
|
@ -37,4 +37,15 @@
|
|||
# define HB_END_DECLS() extern int hb_dummy_prototype (int)
|
||||
# endif /* !__cplusplus */
|
||||
|
||||
typedef int hb_bool_t;
|
||||
|
||||
typedef uint32_t hb_tag_t;
|
||||
#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d))
|
||||
#define HB_TAG_STR(s) (HB_TAG(((const char *) s)[0], \
|
||||
((const char *) s)[1], \
|
||||
((const char *) s)[2], \
|
||||
((const char *) s)[3]))
|
||||
|
||||
typedef uint16_t hb_glyph_t;
|
||||
|
||||
#endif /* HB_COMMON_H */
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
|
||||
#define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \
|
||||
inline const Type& name (hb_ot_layout_glyph_t glyph_id) { \
|
||||
inline const Type& name (hb_glyph_t glyph_id) { \
|
||||
const Coverage &c = get_coverage (); \
|
||||
hb_ot_layout_coverage_t c_index = c.get_coverage (glyph_id); \
|
||||
return (*this)[c_index]; \
|
||||
|
@ -72,13 +72,13 @@ struct AttachList {
|
|||
friend struct GDEF;
|
||||
|
||||
private:
|
||||
/* const AttachPoint& get_attach_points (hb_ot_layout_glyph_t glyph_id); */
|
||||
/* const AttachPoint& get_attach_points (hb_glyph_t glyph_id); */
|
||||
DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points);
|
||||
|
||||
private:
|
||||
/* AttachPoint tables, in Coverage Index order */
|
||||
DEFINE_OFFSET_ARRAY_TYPE (AttachPoint, attachPoint, glyphCount);
|
||||
DEFINE_ACCESSOR (Coverage, get_coverage, coverage);
|
||||
DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
|
||||
|
||||
private:
|
||||
Offset coverage; /* Offset to Coverage table -- from
|
||||
|
@ -205,13 +205,13 @@ struct LigCaretList {
|
|||
friend struct GDEF;
|
||||
|
||||
private:
|
||||
/* const LigGlyph& get_lig_glyph (hb_ot_layout_glyph_t glyph_id); */
|
||||
/* const LigGlyph& get_lig_glyph (hb_glyph_t glyph_id); */
|
||||
DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph);
|
||||
|
||||
private:
|
||||
/* AttachPoint tables, in Coverage Index order */
|
||||
DEFINE_OFFSET_ARRAY_TYPE (LigGlyph, ligGlyph, ligGlyphCount);
|
||||
DEFINE_ACCESSOR (Coverage, get_coverage, coverage);
|
||||
DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
|
||||
|
||||
private:
|
||||
Offset coverage; /* Offset to Coverage table--from
|
||||
|
@ -240,19 +240,17 @@ struct GDEF {
|
|||
STATIC_DEFINE_GET_FOR_DATA (GDEF);
|
||||
/* XXX check version here? */
|
||||
|
||||
DEFINE_ACCESSOR (ClassDef, get_glyph_class_def, glyphClassDef);
|
||||
DEFINE_ACCESSOR (AttachList, get_attach_list, attachList);
|
||||
DEFINE_ACCESSOR (LigCaretList, get_lig_caret_list, ligCaretList);
|
||||
DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef);
|
||||
DEFINE_GET_HAS_ACCESSOR (ClassDef, glyph_classes, glyphClassDef);
|
||||
DEFINE_GET_HAS_ACCESSOR (AttachList, attach_list, attachList);
|
||||
DEFINE_GET_HAS_ACCESSOR (LigCaretList, lig_caret_list, ligCaretList);
|
||||
DEFINE_GET_HAS_ACCESSOR (ClassDef, mark_attachment_types, markAttachClassDef);
|
||||
|
||||
/* Returns 0 if not found. */
|
||||
inline hb_ot_layout_class_t get_glyph_class (hb_ot_layout_glyph_t glyph_id) const {
|
||||
return get_glyph_class_def ().get_class (glyph_id);
|
||||
inline hb_ot_layout_class_t get_glyph_class (hb_glyph_t glyph_id) const {
|
||||
return get_glyph_classes ().get_class (glyph_id);
|
||||
}
|
||||
|
||||
/* Returns 0 if not found. */
|
||||
inline hb_ot_layout_class_t get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const {
|
||||
return get_mark_attach_class_def ().get_class (glyph_id);
|
||||
inline hb_ot_layout_class_t get_mark_attachment_type (hb_glyph_t glyph_id) const {
|
||||
return get_mark_attachment_types ().get_class (glyph_id);
|
||||
}
|
||||
|
||||
/* TODO get_attach and get_lig_caret */
|
||||
|
|
|
@ -186,11 +186,16 @@
|
|||
}
|
||||
|
||||
|
||||
#define DEFINE_ACCESSOR(Type, name, Name) \
|
||||
inline const Type& name (void) const { \
|
||||
#define DEFINE_GET_ACCESSOR(Type, name, Name) \
|
||||
inline const Type& get_##name (void) const { \
|
||||
if (HB_UNLIKELY (!Name)) return Null##Type; \
|
||||
return *(const Type*)((const char*)this + Name); \
|
||||
}
|
||||
#define DEFINE_GET_HAS_ACCESSOR(Type, name, Name) \
|
||||
DEFINE_GET_ACCESSOR (Type, name, Name); \
|
||||
inline bool has_##name (void) const { \
|
||||
return Name != 0; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -633,7 +638,7 @@ struct CoverageFormat1 {
|
|||
/* GlyphIDs, in sorted numerical order */
|
||||
DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount);
|
||||
|
||||
inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const {
|
||||
inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const {
|
||||
GlyphID gid;
|
||||
gid = glyph_id;
|
||||
// TODO: bsearch
|
||||
|
@ -655,7 +660,7 @@ struct CoverageRangeRecord {
|
|||
friend struct CoverageFormat2;
|
||||
|
||||
private:
|
||||
inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const {
|
||||
inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const {
|
||||
if (glyph_id >= start && glyph_id <= end)
|
||||
return startCoverageIndex + (glyph_id - start);
|
||||
return -1;
|
||||
|
@ -677,7 +682,7 @@ struct CoverageFormat2 {
|
|||
/* CoverageRangeRecords, in sorted numerical start order */
|
||||
DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount);
|
||||
|
||||
inline hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const {
|
||||
inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const {
|
||||
// TODO: bsearch
|
||||
for (unsigned int i = 0; i < rangeCount; i++) {
|
||||
int coverage = rangeRecord[i].get_coverage (glyph_id);
|
||||
|
@ -707,7 +712,7 @@ struct Coverage {
|
|||
}
|
||||
}
|
||||
|
||||
hb_ot_layout_coverage_t get_coverage (hb_ot_layout_glyph_t glyph_id) const {
|
||||
hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const {
|
||||
switch (u.coverageFormat) {
|
||||
case 1: return u.format1.get_coverage(glyph_id);
|
||||
case 2: return u.format2.get_coverage(glyph_id);
|
||||
|
@ -736,7 +741,7 @@ struct ClassDefFormat1 {
|
|||
/* GlyphIDs, in sorted numerical order */
|
||||
DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount);
|
||||
|
||||
inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const {
|
||||
inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const {
|
||||
if (glyph_id >= startGlyph && glyph_id - startGlyph < glyphCount)
|
||||
return classValueArray[glyph_id - startGlyph];
|
||||
return 0;
|
||||
|
@ -755,7 +760,7 @@ struct ClassRangeRecord {
|
|||
friend struct ClassDefFormat2;
|
||||
|
||||
private:
|
||||
inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const {
|
||||
inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const {
|
||||
if (glyph_id >= start && glyph_id <= end)
|
||||
return classValue;
|
||||
return 0;
|
||||
|
@ -776,7 +781,7 @@ struct ClassDefFormat2 {
|
|||
/* ClassRangeRecords, in sorted numerical start order */
|
||||
DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount);
|
||||
|
||||
inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const {
|
||||
inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const {
|
||||
// TODO: bsearch
|
||||
for (int i = 0; i < rangeCount; i++) {
|
||||
int classValue = rangeRecord[i].get_class (glyph_id);
|
||||
|
@ -805,7 +810,7 @@ struct ClassDef {
|
|||
}
|
||||
}
|
||||
|
||||
inline hb_ot_layout_class_t get_class (hb_ot_layout_glyph_t glyph_id) const {
|
||||
hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const {
|
||||
switch (u.classFormat) {
|
||||
case 1: return u.format1.get_class(glyph_id);
|
||||
case 2: return u.format2.get_class(glyph_id);
|
||||
|
|
|
@ -38,28 +38,15 @@ typedef uint16_t hb_ot_layout_class_t;
|
|||
typedef uint16_t hb_ot_layout_glyph_properties_t;
|
||||
typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */
|
||||
|
||||
struct GDEF;
|
||||
struct GSUB;
|
||||
struct GPOS;
|
||||
|
||||
struct _HB_OT_Layout {
|
||||
const GDEF *gdef;
|
||||
const GSUB *gsub;
|
||||
const GPOS *gpos;
|
||||
|
||||
struct {
|
||||
uint8_t *klasses;
|
||||
unsigned int len;
|
||||
} new_gdef;
|
||||
|
||||
};
|
||||
|
||||
|
||||
HB_BEGIN_DECLS();
|
||||
|
||||
static hb_ot_layout_glyph_properties_t
|
||||
_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
|
||||
hb_ot_layout_glyph_t glyph);
|
||||
_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
|
||||
hb_glyph_t glyph);
|
||||
|
||||
static hb_bool_t
|
||||
_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout);
|
||||
|
||||
HB_END_DECLS();
|
||||
|
||||
|
|
|
@ -37,6 +37,18 @@
|
|||
#include <string.h>
|
||||
|
||||
|
||||
struct _HB_OT_Layout {
|
||||
const GDEF *gdef;
|
||||
const GSUB *gsub;
|
||||
//const GPOS *gpos;
|
||||
|
||||
struct {
|
||||
unsigned char *klasses;
|
||||
unsigned int len;
|
||||
} new_gdef;
|
||||
|
||||
};
|
||||
|
||||
HB_OT_Layout *
|
||||
hb_ot_layout_create (const char *font_data,
|
||||
int face_index)
|
||||
|
@ -59,9 +71,25 @@ hb_ot_layout_destroy (HB_OT_Layout *layout)
|
|||
free (layout);
|
||||
}
|
||||
|
||||
/*
|
||||
* GDEF
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout)
|
||||
{
|
||||
return layout->gdef->has_glyph_classes ();
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
_hb_ot_layout_has_new_glyph_classes (HB_OT_Layout *layout)
|
||||
{
|
||||
return layout->new_gdef.len > 0;
|
||||
}
|
||||
|
||||
static hb_ot_layout_glyph_properties_t
|
||||
_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
|
||||
hb_ot_layout_glyph_t glyph)
|
||||
_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
|
||||
hb_glyph_t glyph)
|
||||
{
|
||||
hb_ot_layout_class_t klass;
|
||||
|
||||
|
@ -86,9 +114,68 @@ _hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool
|
||||
_hb_ot_layout_check_glyph_properties (HB_OT_Layout *layout,
|
||||
HB_GlyphItem gitem,
|
||||
HB_UShort flags,
|
||||
HB_UShort* property)
|
||||
{
|
||||
HB_Error error;
|
||||
|
||||
if ( gdef )
|
||||
{
|
||||
HB_UShort basic_glyph_class;
|
||||
HB_UShort desired_attachment_class;
|
||||
|
||||
if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN )
|
||||
{
|
||||
error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
|
||||
if ( error )
|
||||
return error;
|
||||
}
|
||||
|
||||
*property = gitem->gproperties;
|
||||
|
||||
/* If the glyph was found in the MarkAttachmentClass table,
|
||||
* then that class value is the high byte of the result,
|
||||
* otherwise the low byte contains the basic type of the glyph
|
||||
* as defined by the GlyphClassDef table.
|
||||
*/
|
||||
if ( *property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
|
||||
basic_glyph_class = HB_GDEF_MARK;
|
||||
else
|
||||
basic_glyph_class = *property;
|
||||
|
||||
/* Return Not_Covered, if, for example, basic_glyph_class
|
||||
* is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES
|
||||
*/
|
||||
if ( flags & basic_glyph_class )
|
||||
return HB_Err_Not_Covered;
|
||||
|
||||
/* The high byte of LookupFlags has the meaning
|
||||
* "ignore marks of attachment type different than
|
||||
* the attachment type specified."
|
||||
*/
|
||||
desired_attachment_class = flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS;
|
||||
if ( desired_attachment_class )
|
||||
{
|
||||
if ( basic_glyph_class == HB_GDEF_MARK &&
|
||||
*property != desired_attachment_class )
|
||||
return HB_Err_Not_Covered;
|
||||
}
|
||||
} else {
|
||||
*property = 0;
|
||||
}
|
||||
|
||||
return HB_Err_Ok;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
hb_ot_layout_glyph_class_t
|
||||
hb_ot_layout_get_glyph_class (HB_OT_Layout *layout,
|
||||
hb_ot_layout_glyph_t glyph)
|
||||
hb_ot_layout_get_glyph_class (HB_OT_Layout *layout,
|
||||
hb_glyph_t glyph)
|
||||
{
|
||||
hb_ot_layout_glyph_properties_t properties;
|
||||
hb_ot_layout_class_t klass;
|
||||
|
@ -103,23 +190,22 @@ hb_ot_layout_get_glyph_class (HB_OT_Layout *layout,
|
|||
|
||||
void
|
||||
hb_ot_layout_set_glyph_class (HB_OT_Layout *layout,
|
||||
hb_ot_layout_glyph_t glyph,
|
||||
hb_glyph_t glyph,
|
||||
hb_ot_layout_glyph_class_t klass)
|
||||
{
|
||||
/* TODO optimize this, similar to old harfbuzz code for example */
|
||||
/* TODO our semantics are a bit different from old harfbuzz code too */
|
||||
|
||||
hb_ot_layout_class_t gdef_klass;
|
||||
int len = layout->new_gdef.len;
|
||||
|
||||
if (glyph >= len) {
|
||||
int new_len;
|
||||
uint8_t *new_klasses;
|
||||
unsigned char *new_klasses;
|
||||
|
||||
new_len = len == 0 ? 120 : 2 * len;
|
||||
if (new_len > 65535)
|
||||
new_len = 65535;
|
||||
new_klasses = (uint8_t *) realloc (layout->new_gdef.klasses, new_len * sizeof (uint8_t));
|
||||
new_klasses = (unsigned char *) realloc (layout->new_gdef.klasses, new_len * sizeof (unsigned char));
|
||||
|
||||
if (G_UNLIKELY (!new_klasses))
|
||||
return;
|
||||
|
@ -142,3 +228,24 @@ hb_ot_layout_set_glyph_class (HB_OT_Layout *layout,
|
|||
layout->new_gdef.klasses[glyph] = gdef_klass;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
hb_ot_layout_build_glyph_classes (HB_OT_Layout *layout,
|
||||
uint16_t num_total_glyphs,
|
||||
hb_glyph_t *glyphs,
|
||||
unsigned char *klasses,
|
||||
uint16_t count)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (G_UNLIKELY (!count || !glyphs || !klasses))
|
||||
return;
|
||||
|
||||
if (layout->new_gdef.len == 0) {
|
||||
layout->new_gdef.klasses = (unsigned char *) calloc (num_total_glyphs, sizeof (unsigned char));
|
||||
layout->new_gdef.len = count;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
hb_ot_layout_set_glyph_class (layout, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]);
|
||||
}
|
||||
|
|
|
@ -31,13 +31,6 @@
|
|||
|
||||
HB_BEGIN_DECLS();
|
||||
|
||||
typedef uint32_t hb_tag_t;
|
||||
#define HB_TAG(a,b,c,d) ((hb_tag_t)(((uint8_t)a<<24)|((uint8_t)b<<16)|((uint8_t)c<<8)|(uint8_t)d))
|
||||
#define HB_TAG_STR(s) (HB_TAG(((const char *) s)[0], \
|
||||
((const char *) s)[1], \
|
||||
((const char *) s)[2], \
|
||||
((const char *) s)[3]))
|
||||
|
||||
typedef enum {
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0000,
|
||||
HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002,
|
||||
|
@ -46,8 +39,6 @@ typedef enum {
|
|||
HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010
|
||||
} hb_ot_layout_glyph_class_t;
|
||||
|
||||
typedef uint16_t hb_ot_layout_glyph_t;
|
||||
|
||||
/*
|
||||
* HB_OT_Layout
|
||||
*/
|
||||
|
@ -67,15 +58,29 @@ hb_ot_layout_create_sanitize (char *data,
|
|||
make_writable_func);
|
||||
*/
|
||||
|
||||
/*
|
||||
* GDEF
|
||||
*/
|
||||
|
||||
hb_bool_t
|
||||
hb_ot_layout_has_font_glyph_classes (HB_OT_Layout *layout);
|
||||
|
||||
hb_ot_layout_glyph_class_t
|
||||
hb_ot_layout_get_glyph_class (HB_OT_Layout *layout,
|
||||
hb_ot_layout_glyph_t glyph);
|
||||
hb_ot_layout_get_glyph_class (HB_OT_Layout *layout,
|
||||
hb_glyph_t glyph);
|
||||
|
||||
void
|
||||
hb_ot_layout_set_glyph_class (HB_OT_Layout *layout,
|
||||
hb_ot_layout_glyph_t glyph,
|
||||
hb_glyph_t glyph,
|
||||
hb_ot_layout_glyph_class_t klass);
|
||||
|
||||
void
|
||||
hb_ot_layout_build_glyph_classes (HB_OT_Layout *layout,
|
||||
uint16_t num_total_glyphs,
|
||||
hb_glyph_t *glyphs,
|
||||
unsigned char *klasses,
|
||||
uint16_t count);
|
||||
|
||||
HB_END_DECLS();
|
||||
|
||||
#endif /* HB_OT_LAYOUT_H */
|
||||
|
|
Loading…
Reference in New Issue