Implement glyph properties
This commit is contained in:
parent
ead428d7a0
commit
aff831ed67
|
@ -231,6 +231,12 @@ DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4);
|
||||||
struct GDEF {
|
struct GDEF {
|
||||||
static const hb_tag_t Tag = HB_TAG ('G','D','E','F');
|
static const hb_tag_t Tag = HB_TAG ('G','D','E','F');
|
||||||
|
|
||||||
|
static const hb_ot_layout_class_t UnclassifiedGlyph = 0;
|
||||||
|
static const hb_ot_layout_class_t BaseGlyph = 1;
|
||||||
|
static const hb_ot_layout_class_t LigatureGlyph = 2;
|
||||||
|
static const hb_ot_layout_class_t MarkGlyph = 3;
|
||||||
|
static const hb_ot_layout_class_t ComponentGlyph = 4;
|
||||||
|
|
||||||
STATIC_DEFINE_GET_FOR_DATA (GDEF);
|
STATIC_DEFINE_GET_FOR_DATA (GDEF);
|
||||||
/* XXX check version here? */
|
/* XXX check version here? */
|
||||||
|
|
||||||
|
@ -240,12 +246,12 @@ struct GDEF {
|
||||||
DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef);
|
DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef);
|
||||||
|
|
||||||
/* Returns 0 if not found. */
|
/* Returns 0 if not found. */
|
||||||
inline int get_glyph_class (hb_ot_layout_glyph_t glyph_id) const {
|
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);
|
return get_glyph_class_def ().get_class (glyph_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns 0 if not found. */
|
/* Returns 0 if not found. */
|
||||||
inline int get_mark_attachment_type (hb_ot_layout_glyph_t glyph_id) const {
|
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);
|
return get_mark_attach_class_def ().get_class (glyph_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,20 +35,32 @@
|
||||||
#include "hb-ot-layout.h"
|
#include "hb-ot-layout.h"
|
||||||
|
|
||||||
typedef uint16_t hb_ot_layout_class_t;
|
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 */
|
typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */
|
||||||
|
|
||||||
struct GDEF;
|
struct GDEF;
|
||||||
struct GSUB;
|
struct GSUB;
|
||||||
struct GPOS;
|
struct GPOS;
|
||||||
|
|
||||||
HB_BEGIN_DECLS();
|
|
||||||
|
|
||||||
struct _HB_OT_Layout {
|
struct _HB_OT_Layout {
|
||||||
const GDEF *gdef;
|
const GDEF *gdef;
|
||||||
const GSUB *gsub;
|
const GSUB *gsub;
|
||||||
const GPOS *gpos;
|
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_END_DECLS();
|
HB_END_DECLS();
|
||||||
|
|
||||||
#endif /* HB_OT_LAYOUT_PRIVATE_H */
|
#endif /* HB_OT_LAYOUT_PRIVATE_H */
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "hb-ot-layout-gsub-private.h"
|
#include "hb-ot-layout-gsub-private.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
HB_OT_Layout *
|
HB_OT_Layout *
|
||||||
hb_ot_layout_create (const char *font_data,
|
hb_ot_layout_create (const char *font_data,
|
||||||
|
@ -57,18 +59,86 @@ hb_ot_layout_destroy (HB_OT_Layout *layout)
|
||||||
free (layout);
|
free (layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_ot_layout_glyph_properties_t
|
static hb_ot_layout_glyph_properties_t
|
||||||
hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
|
_hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
|
||||||
hb_ot_layout_glyph_t glyph)
|
hb_ot_layout_glyph_t glyph)
|
||||||
{
|
{
|
||||||
|
hb_ot_layout_class_t klass;
|
||||||
|
|
||||||
|
/* TODO old harfbuzz doesn't always parse mark attachments as it says it was
|
||||||
|
* introduced without a version bump, so it may not be safe */
|
||||||
|
klass = layout->gdef->get_mark_attachment_type (glyph);
|
||||||
|
if (klass)
|
||||||
|
return klass << 8;
|
||||||
|
|
||||||
|
klass = layout->gdef->get_glyph_class (glyph);
|
||||||
|
|
||||||
|
if (!klass && glyph < layout->new_gdef.len)
|
||||||
|
klass = layout->new_gdef.klasses[glyph];
|
||||||
|
|
||||||
|
switch (klass) {
|
||||||
|
default:
|
||||||
|
case GDEF::UnclassifiedGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
|
||||||
|
case GDEF::BaseGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
|
||||||
|
case GDEF::LigatureGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE;
|
||||||
|
case GDEF::MarkGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_MARK;
|
||||||
|
case GDEF::ComponentGlyph: return HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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_glyph_properties_t properties;
|
||||||
|
hb_ot_layout_class_t klass;
|
||||||
|
|
||||||
|
properties = _hb_ot_layout_get_glyph_properties (layout, glyph);
|
||||||
|
|
||||||
|
if (properties & 0xFF)
|
||||||
|
return HB_OT_LAYOUT_GLYPH_CLASS_MARK;
|
||||||
|
|
||||||
|
return (hb_ot_layout_glyph_class_t) properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout,
|
hb_ot_layout_set_glyph_class (HB_OT_Layout *layout,
|
||||||
hb_ot_layout_glyph_t glyph,
|
hb_ot_layout_glyph_t glyph,
|
||||||
hb_ot_layout_glyph_properties_t properties)
|
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;
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
if (G_UNLIKELY (!new_klasses))
|
||||||
|
return;
|
||||||
|
|
||||||
|
memset (new_klasses + len, 0, new_len - len);
|
||||||
|
|
||||||
|
layout->new_gdef.klasses = new_klasses;
|
||||||
|
layout->new_gdef.len = new_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (klass) {
|
||||||
|
default:
|
||||||
|
case HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED: gdef_klass = GDEF::UnclassifiedGlyph; break;
|
||||||
|
case HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH: gdef_klass = GDEF::BaseGlyph; break;
|
||||||
|
case HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE: gdef_klass = GDEF::LigatureGlyph; break;
|
||||||
|
case HB_OT_LAYOUT_GLYPH_CLASS_MARK: gdef_klass = GDEF::MarkGlyph; break;
|
||||||
|
case HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT: gdef_klass = GDEF::ComponentGlyph; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->new_gdef.klasses[glyph] = gdef_klass;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,20 @@ typedef uint32_t hb_tag_t;
|
||||||
((const char *) s)[2], \
|
((const char *) s)[2], \
|
||||||
((const char *) s)[3]))
|
((const char *) s)[3]))
|
||||||
|
|
||||||
typedef uint16_t hb_ot_layout_glyph_properties_t;
|
typedef enum {
|
||||||
|
HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED = 0x0000,
|
||||||
|
HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH = 0x0002,
|
||||||
|
HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE = 0x0004,
|
||||||
|
HB_OT_LAYOUT_GLYPH_CLASS_MARK = 0x0008,
|
||||||
|
HB_OT_LAYOUT_GLYPH_CLASS_COMPONENT = 0x0010
|
||||||
|
} hb_ot_layout_glyph_class_t;
|
||||||
|
|
||||||
typedef uint16_t hb_ot_layout_glyph_t;
|
typedef uint16_t hb_ot_layout_glyph_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HB_OT_Layout
|
||||||
|
*/
|
||||||
|
|
||||||
typedef struct _HB_OT_Layout HB_OT_Layout;
|
typedef struct _HB_OT_Layout HB_OT_Layout;
|
||||||
|
|
||||||
HB_OT_Layout *
|
HB_OT_Layout *
|
||||||
|
@ -56,14 +67,14 @@ hb_ot_layout_create_sanitize (char *data,
|
||||||
make_writable_func);
|
make_writable_func);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hb_ot_layout_glyph_properties_t
|
hb_ot_layout_glyph_class_t
|
||||||
hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
|
hb_ot_layout_get_glyph_class (HB_OT_Layout *layout,
|
||||||
hb_ot_layout_glyph_t glyph);
|
hb_ot_layout_glyph_t glyph);
|
||||||
|
|
||||||
void
|
void
|
||||||
hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout,
|
hb_ot_layout_set_glyph_class (HB_OT_Layout *layout,
|
||||||
hb_ot_layout_glyph_t glyph,
|
hb_ot_layout_glyph_t glyph,
|
||||||
hb_ot_layout_glyph_properties_t properties);
|
hb_ot_layout_glyph_class_t klass);
|
||||||
|
|
||||||
HB_END_DECLS();
|
HB_END_DECLS();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue