Implement glyph properties

This commit is contained in:
Behdad Esfahbod 2008-01-24 06:03:45 -05:00
parent ead428d7a0
commit aff831ed67
4 changed files with 117 additions and 18 deletions

View File

@ -231,6 +231,12 @@ DEFINE_NULL_ASSERT_SIZE (LigCaretList, 4);
struct GDEF {
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);
/* XXX check version here? */
@ -240,12 +246,12 @@ struct GDEF {
DEFINE_ACCESSOR (ClassDef, get_mark_attach_class_def, markAttachClassDef);
/* 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);
}
/* 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);
}

View File

@ -35,20 +35,32 @@
#include "hb-ot-layout.h"
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;
HB_BEGIN_DECLS();
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_END_DECLS();
#endif /* HB_OT_LAYOUT_PRIVATE_H */

View File

@ -34,6 +34,8 @@
#include "hb-ot-layout-gsub-private.h"
#include <stdlib.h>
#include <string.h>
HB_OT_Layout *
hb_ot_layout_create (const char *font_data,
@ -57,18 +59,86 @@ hb_ot_layout_destroy (HB_OT_Layout *layout)
free (layout);
}
hb_ot_layout_glyph_properties_t
hb_ot_layout_get_glyph_properties (HB_OT_Layout *layout,
hb_ot_layout_glyph_t glyph)
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_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
hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout,
hb_ot_layout_glyph_t glyph,
hb_ot_layout_glyph_properties_t properties)
hb_ot_layout_set_glyph_class (HB_OT_Layout *layout,
hb_ot_layout_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;
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;
}

View File

@ -38,9 +38,20 @@ typedef uint32_t hb_tag_t;
((const char *) s)[2], \
((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;
/*
* HB_OT_Layout
*/
typedef struct _HB_OT_Layout HB_OT_Layout;
HB_OT_Layout *
@ -56,14 +67,14 @@ hb_ot_layout_create_sanitize (char *data,
make_writable_func);
*/
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_glyph_class_t
hb_ot_layout_get_glyph_class (HB_OT_Layout *layout,
hb_ot_layout_glyph_t glyph);
void
hb_ot_layout_set_glyph_properties (HB_OT_Layout *layout,
hb_ot_layout_glyph_t glyph,
hb_ot_layout_glyph_properties_t properties);
hb_ot_layout_set_glyph_class (HB_OT_Layout *layout,
hb_ot_layout_glyph_t glyph,
hb_ot_layout_glyph_class_t klass);
HB_END_DECLS();