((const char *) s)[2], \
((const char *) s)[3]))
-typedef uint16_t hb_glyph_t;
+typedef uint32_t hb_codepoint_t;
+
+/* XXX */
+typedef struct HB_BufferRec_ hb_buffer_t;
#endif /* HB_COMMON_H */
#define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \
- inline const Type& name (hb_glyph_t glyph_id) { \
+ inline const Type& name (hb_codepoint_t glyph) { \
const Coverage &c = get_coverage (); \
- hb_ot_layout_coverage_t c_index = c.get_coverage (glyph_id); \
+ hb_ot_layout_coverage_t c_index = c.get_coverage (glyph); \
return (*this)[c_index]; \
}
struct GlyphClassDef : ClassDef {
- static const uint16_t BaseGlyph = 0x0001u;
- static const uint16_t LigatureGlyph = 0x0002u;
- static const uint16_t MarkGlyph = 0x0003u;
- static const uint16_t ComponentGlyph = 0x0004u;
+ static const unsigned int BaseGlyph = 0x0001u;
+ static const unsigned int LigatureGlyph = 0x0002u;
+ static const unsigned int MarkGlyph = 0x0003u;
+ static const unsigned int ComponentGlyph = 0x0004u;
};
/*
friend struct GDEF;
private:
- /* const AttachPoint& get_attach_points (hb_glyph_t glyph_id); */
+ /* const AttachPoint& get_attach_points (hb_codepoint_t glyph); */
DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (AttachPoint, get_attach_points);
private:
friend struct GDEF;
private:
- /* const LigGlyph& get_lig_glyph (hb_glyph_t glyph_id); */
+ /* const LigGlyph& get_lig_glyph (hb_codepoint_t glyph); */
DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph);
private:
DEFINE_GET_HAS_ACCESSOR (LigCaretList, lig_caret_list, ligCaretList);
DEFINE_GET_HAS_ACCESSOR (ClassDef, mark_attachment_types, markAttachClassDef);
- inline hb_ot_layout_class_t get_glyph_class (hb_glyph_t glyph_id) const {
- return get_glyph_classes ().get_class (glyph_id);
+ inline hb_ot_layout_class_t get_glyph_class (hb_codepoint_t glyph) const {
+ return get_glyph_classes ().get_class (glyph);
}
- 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);
+ inline hb_ot_layout_class_t get_mark_attachment_type (hb_codepoint_t glyph) const {
+ return get_mark_attachment_types ().get_class (glyph);
}
/* TODO get_attach and get_lig_caret */
struct SingleSubstFormat1 {
- /* TODO */
+
+ friend struct SingleSubst;
+
+ private:
+ inline bool substitute (hb_ot_layout_t *layout,
+ hb_buffer_t *buffer,
+ unsigned int context_length,
+ unsigned int nesting_level_left) const {
+// if (get_coverage (IN_CURGLYPH()))
+// return ;
+ }
private:
USHORT substFormat; /* Format identifier--format = 1 */
ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10);
/*
+ * SubstLookup
+ */
+
+struct SubstLookupSubTable {
+ DEFINE_NON_INSTANTIABLE(SubstLookupSubTable);
+
+ friend struct SubstLookup;
+
+ unsigned int get_size (unsigned int lookup_type) const {
+ switch (lookup_type) {
+// case 1: return u.format1.get_size ();
+// case 2: return u.format2.get_size ();
+ /*
+ case Single:
+ case Multiple:
+ case Alternate:
+ case Ligature:
+ case Context:
+ case ChainingContext:
+ case Extension:
+ case ReverseChainingContextSingle:
+ */
+ default:return sizeof (LookupSubTable);
+ }
+ }
+
+ inline bool substitute (hb_ot_layout_t *layout,
+ hb_buffer_t *buffer,
+ unsigned int context_length,
+ unsigned int nesting_level_left,
+ unsigned int lookup_type) const {
+ }
+
+ private:
+ union {
+ USHORT substFormat;
+ CoverageFormat1 format1;
+ CoverageFormat2 format2;
+ } u;
+};
+
+struct SubstLookup : Lookup {
+
+ DEFINE_NON_INSTANTIABLE(SubstLookup);
+
+ static const unsigned int Single = 1;
+ static const unsigned int Multiple = 2;
+ static const unsigned int Alternate = 3;
+ static const unsigned int Ligature = 4;
+ static const unsigned int Context = 5;
+ static const unsigned int ChainingContext = 6;
+ static const unsigned int Extension = 7;
+ static const unsigned int ReverseChainingContextSingle = 8;
+
+ inline const SubstLookupSubTable& get_subtable (unsigned int i) const {
+ return *(SubstLookupSubTable*)&(((Lookup *)this)->get_subtable (i));
+ }
+
+ /* Like get_type(), but looks through extension lookups.
+ * Never returns SubstLookup::Extension */
+ inline unsigned int get_effective_type (void) const {
+ unsigned int type = get_type ();
+
+ if (HB_UNLIKELY (type == Extension)) {
+ /* Return lookup type of first extension subtable.
+ * The spec says all of them should have the same type.
+ * XXX check for that somehow */
+//XXX type = get_subtable(0).v.extension.get_type ();
+ }
+
+ return type;
+ }
+
+ inline bool is_reverse (void) const {
+ switch (get_effective_type ()) {
+ case ReverseChainingContextSingle: return true;
+ default: return false;
+ }
+ }
+
+ inline bool substitute (hb_ot_layout_t *layout,
+ hb_buffer_t *buffer,
+ unsigned int context_length,
+ unsigned int nesting_level_left) const {
+ unsigned int lookup_type = get_type ();
+
+ if (HB_UNLIKELY (nesting_level_left == 0))
+ return false;
+ nesting_level_left--;
+
+ for (unsigned int i = 0; i < get_subtable_count (); i++)
+ if (get_subtable (i).substitute (layout, buffer,
+ context_length, nesting_level_left,
+ lookup_type))
+ return true;
+
+ return false;
+ }
+};
+DEFINE_NULL_ALIAS (SubstLookup, Lookup);
+
+/*
* GSUB
*/
STATIC_DEFINE_GET_FOR_DATA (GSUB);
/* XXX check version here? */
+
+ inline const SubstLookup& get_lookup (unsigned int i) const {
+ return *(SubstLookup*)&(((GSUBGPOS *)this)->get_lookup (i));
+ }
+
+
};
DEFINE_NULL_ALIAS (GSUB, GSUBGPOS);
#define NO_INDEX ((unsigned int) 0xFFFF)
+#define NO_CONTEXT ((unsigned int) -1)
/*
* Int types
/* makes class uninstantiable. should be used for union classes that don't
* contain any complete type */
#define DEFINE_NON_INSTANTIABLE(Type) \
- private: inline Type() {} /* cannot be instantiated */ \
+ protected: inline Type() {} /* cannot be instantiated */ \
public:
// TODO use a global nul-array for most Null's
+
/*
*
* The OpenType Font File
DEFINE_NULL_ASSERT_SIZE (FeatureList, 2);
struct LookupFlag : USHORT {
- static const uint16_t RightToLeft = 0x0001u;
- static const uint16_t IgnoreBaseGlyphs = 0x0002u;
- static const uint16_t IgnoreLigatures = 0x0004u;
- static const uint16_t IgnoreMarks = 0x0008u;
- static const uint16_t Reserved = 0x00F0u;
- static const uint16_t MarkAttachmentType = 0xFF00u;
+ static const unsigned int RightToLeft = 0x0001u;
+ static const unsigned int IgnoreBaseGlyphs = 0x0002u;
+ static const unsigned int IgnoreLigatures = 0x0004u;
+ static const unsigned int IgnoreMarks = 0x0008u;
+ static const unsigned int Reserved = 0x00F0u;
+ static const unsigned int MarkAttachmentType = 0xFF00u;
};
DEFINE_NULL_ASSERT_SIZE (LookupFlag, 2);
struct Lookup {
- /* SubTables, in the desired order */
- DEFINE_OFFSET_ARRAY_TYPE (LookupSubTable, subTableOffset, subTableCount);
+ DEFINE_NON_INSTANTIABLE(Lookup);
+
+ DEFINE_ARRAY_INTERFACE (LookupSubTable, subtable); /* get_subtable_count(), get_subtable(i) */
inline bool is_right_to_left (void) const { return lookupFlag & LookupFlag::RightToLeft; }
inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; }
inline bool ignore_marks (void) const { return lookupFlag & LookupFlag::IgnoreMarks; }
inline bool get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; }
- inline uint16_t get_type (void) const { return lookupType; }
- inline uint16_t get_flag (void) const { return lookupFlag; }
+ inline unsigned int get_type (void) const { return lookupType; }
+ inline unsigned int get_flag (void) const { return lookupFlag; }
private:
+ /* SubTables, in the desired order */
+ DEFINE_OFFSET_ARRAY_TYPE (LookupSubTable, subTableOffset, subTableCount);
+
+ protected:
USHORT lookupType; /* Different enumerations for GSUB and GPOS */
USHORT lookupFlag; /* Lookup qualifiers */
USHORT subTableCount; /* Number of SubTables for this lookup */
/* GlyphIDs, in sorted numerical order */
DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount);
- inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const {
+ inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const {
GlyphID gid;
+ if (HB_UNLIKELY (glyph_id > 65535))
+ return -1;
gid = glyph_id;
// TODO: bsearch
for (unsigned int i = 0; i < glyphCount; i++)
friend struct CoverageFormat2;
private:
- inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const {
+ inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const {
if (glyph_id >= start && glyph_id <= end)
return startCoverageIndex + (glyph_id - start);
return -1;
/* CoverageRangeRecords, in sorted numerical start order */
DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount);
- inline hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const {
+ inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const {
// TODO: bsearch
for (unsigned int i = 0; i < rangeCount; i++) {
int coverage = rangeRecord[i].get_coverage (glyph_id);
}
}
- hb_ot_layout_coverage_t get_coverage (hb_glyph_t glyph_id) const {
+ hb_ot_layout_coverage_t get_coverage (hb_codepoint_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);
/* GlyphIDs, in sorted numerical order */
DEFINE_ARRAY_TYPE (USHORT, classValueArray, glyphCount);
- inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const {
+ inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
if (glyph_id >= startGlyph && glyph_id - startGlyph < glyphCount)
return classValueArray[glyph_id - startGlyph];
return 0;
friend struct ClassDefFormat2;
private:
- inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const {
+ inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
if (glyph_id >= start && glyph_id <= end)
return classValue;
return 0;
/* ClassRangeRecords, in sorted numerical start order */
DEFINE_ARRAY_TYPE (ClassRangeRecord, rangeRecord, rangeCount);
- inline hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const {
+ inline hb_ot_layout_class_t get_class (hb_codepoint_t glyph_id) const {
// TODO: bsearch
- for (int i = 0; i < rangeCount; i++) {
+ for (unsigned int i = 0; i < rangeCount; i++) {
int classValue = rangeRecord[i].get_class (glyph_id);
if (classValue > 0)
return classValue;
}
}
- hb_ot_layout_class_t get_class (hb_glyph_t glyph_id) const {
+ hb_ot_layout_class_t get_class (hb_codepoint_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);
* GSUB/GPOS Common
*/
-typedef struct GSUBGPOS {
+struct GSUBGPOS {
static const hb_tag_t GSUBTag = HB_TAG ('G','S','U','B');
static const hb_tag_t GPOSTag = HB_TAG ('G','P','O','S');
HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t
_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout,
- hb_glyph_t glyph);
+ hb_codepoint_t glyph);
HB_OT_LAYOUT_INTERNAL hb_bool_t
_hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout,
#include "hb-ot-layout-gdef-private.h"
#include "hb-ot-layout-gsub-private.h"
+/* XXX */
+#include "harfbuzz-buffer-private.h"
#include <stdlib.h>
#include <string.h>
unsigned int len;
} new_gdef;
+ /* TODO add max-nesting-level here? */
};
hb_ot_layout_t *
HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t
_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout,
- hb_glyph_t glyph)
+ hb_codepoint_t glyph)
{
hb_ot_layout_class_t klass;
hb_ot_layout_glyph_class_t
hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout,
- hb_glyph_t glyph)
+ hb_codepoint_t glyph)
{
hb_ot_layout_glyph_properties_t properties;
hb_ot_layout_class_t klass;
void
hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout,
- hb_glyph_t glyph,
+ hb_codepoint_t glyph,
hb_ot_layout_glyph_class_t klass)
{
/* TODO optimize this, similar to old harfbuzz code for example */
void
hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout,
uint16_t num_total_glyphs,
- hb_glyph_t *glyphs,
+ hb_codepoint_t *glyphs,
unsigned char *klasses,
uint16_t count)
{
return f.get_lookup_index (num_lookup);
}
+
+/*
+ * GSUB
+ */
+
+hb_bool_t
+hb_ot_layout_substitute_lookup (hb_ot_layout_t *layout,
+ hb_buffer_t *buffer,
+ unsigned int lookup_index,
+ hb_ot_layout_feature_mask_t mask)
+{
+ const GSUB &gsub = *(layout->gsub);
+ const SubstLookup &l = gsub.get_lookup (lookup_index);
+ unsigned int lookup_type = l.get_type ();
+ unsigned int nesting_level_left = HB_OT_LAYOUT_MAX_NESTING_LEVEL;
+ unsigned int context_length = NO_CONTEXT;
+ bool handled, ret = false;
+
+ if (!l.is_reverse ()) {
+
+ /* in/out forward substitution */
+ _hb_buffer_clear_output (buffer);
+ buffer->in_pos = 0;
+ while (buffer->in_pos < buffer->in_length) {
+
+ if ((~IN_PROPERTIES (buffer->in_pos) & mask) &&
+ l.substitute (layout, buffer, context_length, nesting_level_left))
+ ret = true;
+ else
+ _hb_buffer_copy_output_glyph (buffer);
+
+ }
+ _hb_buffer_swap (buffer);
+
+ } else {
+
+ /* in-place backward substitution */
+ buffer->in_pos = buffer->in_length - 1;
+ do {
+
+ if ((~IN_PROPERTIES (buffer->in_pos) & mask) &&
+ l.substitute (layout, buffer, context_length, nesting_level_left))
+ ret = true;
+ else
+ buffer->in_pos--;
+
+ } while (buffer->in_pos);
+
+ }
+
+ return ret;
+}
hb_ot_layout_glyph_class_t
hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout,
- hb_glyph_t glyph);
+ hb_codepoint_t glyph);
void
hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout,
- hb_glyph_t glyph,
+ hb_codepoint_t glyph,
hb_ot_layout_glyph_class_t klass);
void
hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout,
uint16_t num_total_glyphs,
- hb_glyph_t *glyphs,
+ hb_codepoint_t *glyphs,
unsigned char *klasses,
uint16_t count);
HB_OT_LAYOUT_TABLE_TYPE_NONE
} hb_ot_layout_table_type_t;
+typedef uint16_t hb_ot_layout_feature_mask_t;
+
+#define HB_OT_LAYOUT_MAX_NESTING_LEVEL 100
+
#define HB_OT_LAYOUT_NO_SCRIPT_INDEX ((unsigned int) 0xFFFF)
#define HB_OT_LAYOUT_NO_FEATURE_INDEX ((unsigned int) 0xFFFF)
#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX ((unsigned int) 0xFFFF)
unsigned int feature_index,
unsigned int num_lookup);
+/*
+ * GSUB
+ */
+
+hb_bool_t
+hb_ot_layout_substitute_lookup (hb_ot_layout_t *layout,
+ hb_buffer_t *buffer,
+ unsigned int lookup_index,
+ hb_ot_layout_feature_mask_t mask);
+
+
+
+
+
+
+
+
+
+
/*
#define PANGO_OT_ALL_GLYPHS ((guint) 0xFFFF)
feature.get_lookup_count());
int num_lookups = feature.get_lookup_count ();
- printf (" %d lookup(s) found in language system\n", num_lookups);
+ printf (" %d lookup(s) found in feature\n", num_lookups);
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
unsigned int lookup_index = feature.get_lookup_index (n_lookup);
- printf (" Feature index %2d of %2d: %d\n", n_lookup, num_lookups,
+ printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups,
feature.get_lookup_index (n_lookup));
}
}