[pango/harfbuzz-ng: 3/17] [harfbuzz/GSUB] towards a partially working GSUB
- From: Behdad Esfahbod <behdad src gnome org>
- To: svn-commits-list gnome org
- Subject: [pango/harfbuzz-ng: 3/17] [harfbuzz/GSUB] towards a partially working GSUB
- Date: Tue, 12 May 2009 03:30:33 -0400 (EDT)
commit 25f2af64013f6d88289d526315d2d0c91b77e3a1
Author: Behdad Esfahbod <behdad behdad org>
Date: Thu Apr 16 04:45:30 2009 -0400
[harfbuzz/GSUB] towards a partially working GSUB
---
pango/opentype/harfbuzz-buffer.c | 2 +-
pango/opentype/harfbuzz-impl.h | 2 +-
pango/opentype/harfbuzz.c | 1 -
pango/opentype/hb-ot-layout-gdef-private.h | 4 +-
pango/opentype/hb-ot-layout-gsub-private.h | 383 ++++++++++++++++++++-------
pango/opentype/hb-ot-layout-open-private.h | 31 ++-
pango/opentype/hb-ot-layout-private.h | 6 +-
pango/opentype/hb-ot-layout.cc | 94 +++++--
pango/opentype/hb-ot-layout.h | 2 -
9 files changed, 381 insertions(+), 144 deletions(-)
diff --git a/pango/opentype/harfbuzz-buffer.c b/pango/opentype/harfbuzz-buffer.c
index 3008c93..1a39dc1 100644
--- a/pango/opentype/harfbuzz-buffer.c
+++ b/pango/opentype/harfbuzz-buffer.c
@@ -59,7 +59,7 @@
/* Internal API */
-static HB_Error
+/*static XXX */ HB_Error
hb_buffer_ensure( HB_Buffer buffer,
HB_UInt size )
{
diff --git a/pango/opentype/harfbuzz-impl.h b/pango/opentype/harfbuzz-impl.h
index 29101f8..60508ed 100644
--- a/pango/opentype/harfbuzz-impl.h
+++ b/pango/opentype/harfbuzz-impl.h
@@ -78,7 +78,7 @@ HB_BEGIN_HEADER
#define ALLOC(_ptr,_size) \
- ( (_ptr) = _hb_alloc( _size, &error ), error != 0 )
+ ( *(void**)&(_ptr) = _hb_alloc( _size, &error ), error != 0 )
#define REALLOC(_ptr,_newsz) \
( (_ptr) = _hb_realloc( (_ptr), (_newsz), &error ), error != 0 )
diff --git a/pango/opentype/harfbuzz.c b/pango/opentype/harfbuzz.c
index b7e64bc..a0415f5 100644
--- a/pango/opentype/harfbuzz.c
+++ b/pango/opentype/harfbuzz.c
@@ -24,7 +24,6 @@
#define HB_INTERNAL static
#include "harfbuzz-buffer.c"
-#include "harfbuzz-gdef.c"
#include "harfbuzz-gsub.c"
#include "harfbuzz-gpos.c"
#include "harfbuzz-impl.c"
diff --git a/pango/opentype/hb-ot-layout-gdef-private.h b/pango/opentype/hb-ot-layout-gdef-private.h
index 5418d8b..7730ac0 100644
--- a/pango/opentype/hb-ot-layout-gdef-private.h
+++ b/pango/opentype/hb-ot-layout-gdef-private.h
@@ -35,7 +35,7 @@
#define DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP(Type, name) \
inline const Type& name (hb_codepoint_t glyph) { \
const Coverage &c = get_coverage (); \
- hb_ot_layout_coverage_t c_index = c.get_coverage (glyph); \
+ unsigned int c_index = c.get_coverage (glyph); \
return (*this)[c_index]; \
}
@@ -209,7 +209,7 @@ struct LigCaretList {
DEFINE_INDIRECT_GLYPH_ARRAY_LOOKUP (LigGlyph, get_lig_glyph);
private:
- /* AttachPoint tables, in Coverage Index order */
+ /* LigGlyph tables, in Coverage Index order */
DEFINE_OFFSET_ARRAY_TYPE (LigGlyph, ligGlyph, ligGlyphCount);
DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
diff --git a/pango/opentype/hb-ot-layout-gsub-private.h b/pango/opentype/hb-ot-layout-gsub-private.h
index d8c1d8d..968dd4a 100644
--- a/pango/opentype/hb-ot-layout-gsub-private.h
+++ b/pango/opentype/hb-ot-layout-gsub-private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007,2008 Red Hat, Inc.
+ * Copyright (C) 2007,2008,2009 Red Hat, Inc.
*
* This is part of HarfBuzz, an OpenType Layout engine library.
*
@@ -35,7 +35,7 @@
#include "harfbuzz-buffer-private.h" /* XXX */
#define DEFINE_GET_GLYPH_COVERAGE(name) \
- inline hb_ot_layout_coverage_t get_##name (hb_codepoint_t glyph) const { \
+ inline unsigned int get_##name (hb_codepoint_t glyph) const { \
const Coverage &c = get_coverage (); \
return c.get_coverage (glyph); \
}
@@ -46,6 +46,12 @@
unsigned int context_length, \
unsigned int nesting_level_left, \
unsigned int lookup_flag) const
+#define SUBTABLE_SUBSTITUTE_CHAIN(obj) \
+ obj.substitute (layout, \
+ buffer, \
+ context_length, \
+ nesting_level_left, \
+ lookup_flag)
struct SingleSubstFormat1 {
@@ -55,47 +61,21 @@ struct SingleSubstFormat1 {
DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
- inline SUBTABLE_SUBSTITUTE {
- hb_codepoint_t glyph_id;
- hb_ot_layout_coverage_t index;
- unsigned int property;
-
- HB_UNUSED (nesting_level_left);
-
- if (HB_UNLIKELY (context_length < 1))
- return false;
+ inline bool single_substitute (hb_codepoint_t &glyph_id) const {
- if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
- return false;
-
- glyph_id = IN_CURGLYPH ();
+ unsigned int index;
index = get_glyph_coverage (glyph_id);
- if (-1 == index)
+ if (NOT_COVERED == index)
return false;
glyph_id += deltaGlyphID;
- _hb_buffer_replace_output_glyph (buffer, glyph_id, context_length == NO_CONTEXT);
-
- if ( _hb_ot_layout_has_new_glyph_classes (layout) )
- {
- /* we inherit the old glyph class to the substituted glyph */
- _hb_ot_layout_set_glyph_property (layout, glyph_id, property);
- }
return true;
-}
+ }
#if 0
- switch ( ss->SubstFormat )
- {
- case 1:
- value = (IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
- if ( REPLACE_Glyph( buffer, value, nesting_level ) )
- return error;
- break;
-
case 2:
if ( index >= ss->ssf.ssf2.GlyphCount )
return ERR(HB_Err_Invalid_SubTable);
@@ -103,17 +83,6 @@ struct SingleSubstFormat1 {
if ( REPLACE_Glyph( buffer, value, nesting_level ) )
return error;
break;
-
- default:
- return ERR(HB_Err_Invalid_SubTable);
- }
-
- if ( _hb_ot_layout_has_new_glyph_classes (layout) )
- {
- /* we inherit the old glyph class to the substituted glyph */
-
- hb_ot_layout_set_glyph_class (layout, value, properties);
- }
#endif
private:
@@ -126,7 +95,25 @@ struct SingleSubstFormat1 {
ASSERT_SIZE (SingleSubstFormat1, 6);
struct SingleSubstFormat2 {
- /* TODO */
+
+ friend struct SingleSubst;
+
+ private:
+ DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
+ DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
+
+ inline bool single_substitute (hb_codepoint_t &glyph_id) const {
+
+ unsigned int index;
+
+ index = get_glyph_coverage (glyph_id);
+
+ if (index >= glyphCount)
+ return false;
+
+ glyph_id = substitute[index];
+ return true;
+ }
private:
USHORT substFormat; /* Format identifier--format = 2 */
@@ -139,24 +126,75 @@ struct SingleSubstFormat2 {
};
ASSERT_SIZE (SingleSubstFormat2, 6);
-struct MultipleSubstFormat1 {
- /* TODO */
+struct SingleSubst {
+
+ friend struct SubstLookupSubTable;
+
+ unsigned int get_size (void) const {
+ switch (u.substFormat) {
+ case 1: return sizeof (u.format1);
+ case 2: return sizeof (u.format2);
+ default:return sizeof (u.substFormat);
+ }
+ }
private:
- USHORT substFormat; /* Format identifier--format = 1 */
- Offset coverage; /* Offset to Coverage table--from
- * beginning of Substitution table */
- USHORT sequenceCount; /* Number of Sequence table offsets in
- * the Sequence array */
- Offset sequence[]; /* Array of offsets to Sequence
- * tables--from beginning of
- * Substitution table--ordered by
- * Coverage Index */
+ inline SUBTABLE_SUBSTITUTE {
+
+ hb_codepoint_t glyph_id;
+ unsigned int property;
+
+ HB_UNUSED (nesting_level_left);
+
+ if (HB_UNLIKELY (context_length < 1))
+ return false;
+
+ if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
+ return false;
+
+ glyph_id = IN_CURGLYPH ();
+
+ switch (u.substFormat) {
+ case 1: if (!u.format1.single_substitute (glyph_id)) return false;
+ case 2: if (!u.format2.single_substitute (glyph_id)) return false;
+ default:return false;
+ }
+
+ _hb_buffer_replace_output_glyph (buffer, glyph_id, context_length == NO_CONTEXT);
+
+ if ( _hb_ot_layout_has_new_glyph_classes (layout) )
+ {
+ /* we inherit the old glyph class to the substituted glyph */
+ _hb_ot_layout_set_glyph_property (layout, glyph_id, property);
+ }
+
+ return true;
+ }
+
+ private:
+ union {
+ USHORT substFormat; /* Format identifier */
+ SingleSubstFormat1 format1;
+ SingleSubstFormat2 format2;
+ } u;
};
-ASSERT_SIZE (MultipleSubstFormat1, 6);
+DEFINE_NULL (SingleSubst, 2);
+
struct Sequence {
- /* TODO */
+
+ friend struct MultipleSubstFormat1;
+
+ private:
+ /* GlyphID tables, in Coverage Index order */
+ DEFINE_OFFSET_ARRAY_TYPE (GlyphID, substitute, glyphCount);
+
+ inline void set_glyph_class (hb_ot_layout_t *layout, unsigned int property) const {
+ unsigned int n, count = glyphCount;
+
+ for (n = 0; n < count; n++)
+ _hb_ot_layout_set_glyph_property (layout, substitute[n], property);
+ }
private:
USHORT glyphCount; /* Number of GlyphIDs in the Substitute
@@ -166,20 +204,92 @@ struct Sequence {
};
DEFINE_NULL_ASSERT_SIZE (Sequence, 2);
-struct AlternateSubstFormat1 {
- /* TODO */
+struct MultipleSubstFormat1 {
+
+ friend struct MultipleSubst;
+
+ private:
+ /* Sequence tables, in Coverage Index order */
+ DEFINE_OFFSET_ARRAY_TYPE (Sequence, sequence, sequenceCount);
+ DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
+ DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
+
+ inline SUBTABLE_SUBSTITUTE {
+
+ hb_codepoint_t glyph_id;
+ unsigned int index;
+ unsigned int property;
+
+ HB_UNUSED (nesting_level_left);
+
+ if (HB_UNLIKELY (context_length < 1))
+ return false;
+
+ if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
+ return false;
+
+ glyph_id = IN_CURGLYPH ();
+
+ index = get_glyph_coverage (glyph_id);
+ if (index >= sequenceCount)
+ return false;
+
+ const Sequence &seq = (*this)[index];
+ _hb_buffer_add_output_glyph_ids (buffer, 1,
+ seq.glyphCount, seq.substitute,
+ 0xFFFF, 0xFFFF);
+
+ if ( _hb_ot_layout_has_new_glyph_classes (layout) )
+ {
+ /* this is a guess only ... */
+
+ if ( property == HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE )
+ property = HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH;
+
+ seq.set_glyph_class (layout, property);
+ }
+
+ return true;
+ }
private:
USHORT substFormat; /* Format identifier--format = 1 */
Offset coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- USHORT alternateSetCount; /* Number of AlternateSet tables */
- Offset alternateSet[]; /* Array of offsets to AlternateSet
+ USHORT sequenceCount; /* Number of Sequence table offsets in
+ * the Sequence array */
+ Offset sequence[]; /* Array of offsets to Sequence
* tables--from beginning of
* Substitution table--ordered by
* Coverage Index */
};
-ASSERT_SIZE (AlternateSubstFormat1, 6);
+ASSERT_SIZE (MultipleSubstFormat1, 6);
+
+struct MultipleSubst {
+
+ unsigned int get_size (void) const {
+ switch (u.substFormat) {
+ case 1: return sizeof (u.format1);
+ default:return sizeof (u.substFormat);
+ }
+ }
+
+ private:
+ inline SUBTABLE_SUBSTITUTE {
+ switch (u.substFormat) {
+ case 1: return SUBTABLE_SUBSTITUTE_CHAIN(u.format1);
+ default:return false;
+ }
+ }
+
+ private:
+ union {
+ USHORT substFormat; /* Format identifier */
+ MultipleSubstFormat1 format1;
+ } u;
+};
+DEFINE_NULL (MultipleSubst, 2);
+
struct AlternateSet {
/* TODO */
@@ -192,20 +302,33 @@ struct AlternateSet {
};
DEFINE_NULL_ASSERT_SIZE (AlternateSet, 2);
-struct LigatureSubstFormat1 {
+struct AlternateSubstFormat1 {
/* TODO */
private:
USHORT substFormat; /* Format identifier--format = 1 */
Offset coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
- USHORT ligSetCount; /* Number of LigatureSet tables */
- Offset ligatureSet[]; /* Array of offsets to LigatureSet
+ USHORT alternateSetCount; /* Number of AlternateSet tables */
+ Offset alternateSet[]; /* Array of offsets to AlternateSet
* tables--from beginning of
* Substitution table--ordered by
* Coverage Index */
};
-ASSERT_SIZE (LigatureSubstFormat1, 6);
+ASSERT_SIZE (AlternateSubstFormat1, 6);
+
+
+struct Ligature {
+ /* TODO */
+
+ private:
+ GlyphID ligGlyph; /* GlyphID of ligature to substitute */
+ USHORT compCount; /* Number of components in the ligature */
+ GlyphID component[]; /* Array of component GlyphIDs--start
+ * with the second component--ordered
+ * in writing direction */
+};
+DEFINE_NULL_ASSERT_SIZE (Ligature, 4);
struct LigatureSet {
/* TODO */
@@ -219,17 +342,21 @@ struct LigatureSet {
};
DEFINE_NULL_ASSERT_SIZE (LigatureSet, 2);
-struct Ligature {
+struct LigatureSubstFormat1 {
/* TODO */
private:
- GlyphID ligGlyph; /* GlyphID of ligature to substitute */
- USHORT compCount; /* Number of components in the ligature */
- GlyphID component[]; /* Array of component GlyphIDs--start
- * with the second component--ordered
- * in writing direction */
+ USHORT substFormat; /* Format identifier--format = 1 */
+ Offset coverage; /* Offset to Coverage table--from
+ * beginning of Substitution table */
+ USHORT ligSetCount; /* Number of LigatureSet tables */
+ Offset ligatureSet[]; /* Array of offsets to LigatureSet
+ * tables--from beginning of
+ * Substitution table--ordered by
+ * Coverage Index */
};
-DEFINE_NULL_ASSERT_SIZE (Ligature, 4);
+ASSERT_SIZE (LigatureSubstFormat1, 6);
+
struct SubstLookupRecord {
/* TODO */
@@ -533,6 +660,17 @@ ASSERT_SIZE (ReverseChainSingleSubstFormat1, 10);
* SubstLookup
*/
+enum {
+ GSUB_Single = 1,
+ GSUB_Multiple = 2,
+ GSUB_Alternate = 3,
+ GSUB_Ligature = 4,
+ GSUB_Context = 5,
+ GSUB_ChainingContext = 6,
+ GSUB_Extension = 7,
+ GSUB_ReverseChainingContextSingle = 8,
+};
+
struct SubstLookupSubTable {
DEFINE_NON_INSTANTIABLE(SubstLookupSubTable);
@@ -543,14 +681,14 @@ struct SubstLookupSubTable {
// 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:
+ case GSUB_Single:
+ case GSUB_Multiple:
+ case GSUB_Alternate:
+ case GSUB_Ligature:
+ case GSUB_Context:
+ case GSUB_ChainingContext:
+ case GSUB_Extension:
+ case GSUB_ReverseChainingContextSingle:
*/
default:return sizeof (LookupSubTable);
}
@@ -562,13 +700,25 @@ struct SubstLookupSubTable {
unsigned int nesting_level_left,
unsigned int lookup_type,
unsigned int lookup_flag) const {
+ switch (lookup_type) {
+ case GSUB_Single: return SUBTABLE_SUBSTITUTE_CHAIN (u.singleSubst);
+ /*
+ case GSUB_Multiple:
+ case GSUB_Alternate:
+ case GSUB_Ligature:
+ case GSUB_Context:
+ case GSUB_ChainingContext:
+ case GSUB_Extension:
+ case GSUB_ReverseChainingContextSingle:
+ */
+ default:return false;
+ }
}
private:
union {
USHORT substFormat;
- CoverageFormat1 format1;
- CoverageFormat2 format2;
+ SingleSubst singleSubst;
} u;
};
@@ -576,25 +726,16 @@ 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 */
+ * Never returns Extension */
inline unsigned int get_effective_type (void) const {
unsigned int type = get_type ();
- if (HB_UNLIKELY (type == Extension)) {
+ if (HB_UNLIKELY (type == GSUB_Extension)) {
/* Return lookup type of first extension subtable.
* The spec says all of them should have the same type.
* XXX check for that somehow */
@@ -606,15 +747,16 @@ struct SubstLookup : Lookup {
inline bool is_reverse (void) const {
switch (get_effective_type ()) {
- case ReverseChainingContextSingle: return true;
- default: return false;
+ case GSUB_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 {
+ inline bool substitute_once (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 ();
unsigned int lookup_flag = get_flag ();
@@ -630,6 +772,47 @@ struct SubstLookup : Lookup {
return false;
}
+
+ inline bool substitute_string (hb_ot_layout_t *layout,
+ hb_buffer_t *buffer,
+ hb_ot_layout_feature_mask_t mask) const {
+
+ bool ret = false;
+
+ if (!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) &&
+ substitute_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL))
+ ret = true;
+ else
+ _hb_buffer_copy_output_glyph (buffer);
+
+ }
+ if (ret)
+ _hb_buffer_swap (buffer);
+
+ } else {
+
+ /* in-place backward substitution */
+ buffer->in_pos = buffer->in_length - 1;
+ do {
+
+ if ((~IN_PROPERTIES (buffer->in_pos) & mask) &&
+ substitute_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL))
+ ret = true;
+ else
+ buffer->in_pos--;
+
+ } while (buffer->in_pos);
+ }
+
+ return ret;
+ }
};
DEFINE_NULL_ALIAS (SubstLookup, Lookup);
diff --git a/pango/opentype/hb-ot-layout-open-private.h b/pango/opentype/hb-ot-layout-open-private.h
index 4123a43..ecd1c08 100644
--- a/pango/opentype/hb-ot-layout-open-private.h
+++ b/pango/opentype/hb-ot-layout-open-private.h
@@ -36,6 +36,9 @@
#define NO_INDEX ((unsigned int) 0xFFFF)
#define NO_CONTEXT ((unsigned int) -1)
+#define NOT_COVERED ((unsigned int) -1)
+#define MAX_NESTING_LEVEL 32
+
/*
* Int types
@@ -717,16 +720,16 @@ struct CoverageFormat1 {
/* GlyphIDs, in sorted numerical order */
DEFINE_ARRAY_TYPE (GlyphID, glyphArray, glyphCount);
- inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const {
+ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const {
GlyphID gid;
if (HB_UNLIKELY (glyph_id > 65535))
- return -1;
+ return NOT_COVERED;
gid = glyph_id;
// TODO: bsearch
for (unsigned int i = 0; i < glyphCount; i++)
if (gid == glyphArray[i])
return i;
- return -1;
+ return NOT_COVERED;
}
private:
@@ -741,10 +744,10 @@ struct CoverageRangeRecord {
friend struct CoverageFormat2;
private:
- inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const {
+ inline unsigned int get_coverage (hb_codepoint_t glyph_id) const {
if (glyph_id >= start && glyph_id <= end)
return startCoverageIndex + (glyph_id - start);
- return -1;
+ return NOT_COVERED;
}
private:
@@ -763,14 +766,14 @@ struct CoverageFormat2 {
/* CoverageRangeRecords, in sorted numerical start order */
DEFINE_ARRAY_TYPE (CoverageRangeRecord, rangeRecord, rangeCount);
- inline hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const {
+ inline unsigned int 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);
if (coverage >= 0)
return coverage;
}
- return -1;
+ return NOT_COVERED;
}
private:
@@ -793,11 +796,11 @@ struct Coverage {
}
}
- hb_ot_layout_coverage_t get_coverage (hb_codepoint_t glyph_id) const {
+ unsigned int 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);
- default:return -1;
+ default:return NOT_COVERED;
}
}
@@ -990,4 +993,14 @@ struct GSUBGPOS {
};
DEFINE_NULL_ASSERT_SIZE (GSUBGPOS, 10);
+/* XXX */
+#include "harfbuzz-impl.h"
+HB_INTERNAL HB_Error
+_hb_buffer_add_output_glyph_ids( HB_Buffer buffer,
+ HB_UShort num_in,
+ HB_UShort num_out,
+ const GlyphID *glyph_data,
+ HB_UShort component,
+ HB_UShort ligID );
+
#endif /* HB_OT_LAYOUT_OPEN_PRIVATE_H */
diff --git a/pango/opentype/hb-ot-layout-private.h b/pango/opentype/hb-ot-layout-private.h
index ae728eb..c152edc 100644
--- a/pango/opentype/hb-ot-layout-private.h
+++ b/pango/opentype/hb-ot-layout-private.h
@@ -35,7 +35,6 @@
typedef unsigned int hb_ot_layout_class_t;
-typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */
/* XXX #define HB_OT_LAYOUT_INTERNAL static */
#define HB_OT_LAYOUT_INTERNAL
@@ -64,6 +63,11 @@ _hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout,
unsigned int lookup_flags,
unsigned int *property);
+/* XXX */
+HB_Error
+hb_buffer_ensure( HB_Buffer buffer,
+ HB_UInt size );
+
HB_END_DECLS();
#endif /* HB_OT_LAYOUT_PRIVATE_H */
diff --git a/pango/opentype/hb-ot-layout.cc b/pango/opentype/hb-ot-layout.cc
index 5a5e176..6b7d47b 100644
--- a/pango/opentype/hb-ot-layout.cc
+++ b/pango/opentype/hb-ot-layout.cc
@@ -544,42 +544,82 @@ hb_ot_layout_substitute_lookup (hb_ot_layout_t *layout,
{
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 ()) {
+ return l.substitute_string (layout, buffer, mask);
+}
+
+
+
+/* XXX dupped, until he old code can be removed */
- /* in/out forward substitution */
- _hb_buffer_clear_output (buffer);
- buffer->in_pos = 0;
- while (buffer->in_pos < buffer->in_length) {
+static HB_Error
+hb_buffer_duplicate_out_buffer( HB_Buffer buffer )
+{
+ if ( !buffer->alt_string )
+ {
+ HB_Error error;
+
+ if ( ALLOC_ARRAY( buffer->alt_string, buffer->allocated, HB_GlyphItemRec ) )
+ return error;
+ }
- 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);
+ buffer->out_string = buffer->alt_string;
+ memcpy( buffer->out_string, buffer->in_string, buffer->out_length * sizeof (buffer->out_string[0]) );
+ buffer->separate_out = TRUE;
- }
- _hb_buffer_swap (buffer);
+ return HB_Err_Ok;
+}
- } 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--;
+HB_INTERNAL HB_Error
+_hb_buffer_add_output_glyph_ids( HB_Buffer buffer,
+ HB_UShort num_in,
+ HB_UShort num_out,
+ const GlyphID *glyph_data,
+ HB_UShort component,
+ HB_UShort ligID )
+{
+ HB_Error error;
+ HB_UShort i;
+ HB_UInt properties;
+ HB_UInt cluster;
+
+ error = hb_buffer_ensure( buffer, buffer->out_pos + num_out );
+ if ( error )
+ return error;
+
+ if ( !buffer->separate_out )
+ {
+ error = hb_buffer_duplicate_out_buffer( buffer );
+ if ( error )
+ return error;
+ }
- } while (buffer->in_pos);
+ properties = buffer->in_string[buffer->in_pos].properties;
+ cluster = buffer->in_string[buffer->in_pos].cluster;
+ if ( component == 0xFFFF )
+ component = buffer->in_string[buffer->in_pos].component;
+ if ( ligID == 0xFFFF )
+ ligID = buffer->in_string[buffer->in_pos].ligID;
+ for ( i = 0; i < num_out; i++ )
+ {
+ HB_GlyphItem item = &buffer->out_string[buffer->out_pos + i];
+
+ item->gindex = glyph_data[i];
+ item->properties = properties;
+ item->cluster = cluster;
+ item->component = component;
+ item->ligID = ligID;
+ item->gproperty = HB_GLYPH_PROPERTY_UNKNOWN;
}
- return ret;
+ buffer->in_pos += num_in;
+ buffer->out_pos += num_out;
+
+ buffer->out_length = buffer->out_pos;
+
+ return HB_Err_Ok;
}
+
diff --git a/pango/opentype/hb-ot-layout.h b/pango/opentype/hb-ot-layout.h
index a6b9d37..2fc9089 100644
--- a/pango/opentype/hb-ot-layout.h
+++ b/pango/opentype/hb-ot-layout.h
@@ -93,8 +93,6 @@ typedef enum {
typedef uint32_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)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]