[HarfBuzz] harfbuzz-ng: Branch 'master' - 8 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Tue Apr 24 11:23:09 PDT 2012
TODO | 2
src/Makefile.am | 3
src/hb-buffer-private.hh | 2
src/hb-buffer.cc | 2
src/hb-graphite2.cc | 5
src/hb-ot-layout-common-private.hh | 19 +--
src/hb-ot-layout-gpos-table.hh | 2
src/hb-ot-layout-gsub-table.hh | 144 +++++++++++-----------------
src/hb-ot-layout-gsubgpos-private.hh | 179 +++++++++++++++++------------------
src/hb-ot-layout-private.hh | 47 ---------
src/hb-ot-layout.cc | 10 -
src/hb-ot-layout.h | 10 -
src/hb-ot-map-private.hh | 3
src/hb-ot-map.cc | 15 ++
src/hb-ot-shape-complex-arabic.cc | 4
src/hb-ot-shape-complex-misc.cc | 4
src/hb-ot-shape.cc | 5
src/hb-set-private.hh | 139 +++++++++++++++++++++++++++
src/hb-set.cc | 175 ++++++++++++++++++++++++++++++++++
src/hb-set.h | 119 +++++++++++++++++++++++
src/hb.h | 1
21 files changed, 637 insertions(+), 253 deletions(-)
New commits:
commit 6c6ccaf575392f6e6bb9a15534026e4ea462705b
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Apr 24 14:21:15 2012 -0400
Add a few more set operations
TODO: Tests for hb_set_t.
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index a6239e4..660aaee 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -38,6 +38,12 @@ struct _hb_set_t
inline void clear (void) {
memset (elts, 0, sizeof elts);
}
+ inline bool empty (void) const {
+ for (unsigned int i = 0; i < ARRAY_LENGTH (elts); i++)
+ if (elts[i])
+ return false;
+ return true;
+ }
inline void add (hb_codepoint_t g)
{
if (unlikely (g > MAX_G)) return;
@@ -64,19 +70,65 @@ struct _hb_set_t
return true;
return false;
}
+ inline bool equal (const hb_set_t *other) const
+ {
+ for (unsigned int i = 0; i < ELTS; i++)
+ if (elts[i] != other->elts[i])
+ return false;
+ return true;
+ }
+ inline void set (const hb_set_t *other)
+ {
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] = other->elts[i];
+ }
+ inline void union_ (const hb_set_t *other)
+ {
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] |= other->elts[i];
+ }
+ inline void intersect (const hb_set_t *other)
+ {
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] &= other->elts[i];
+ }
+ inline void subtract (const hb_set_t *other)
+ {
+ for (unsigned int i = 0; i < ELTS; i++)
+ elts[i] &= ~other->elts[i];
+ }
+ inline hb_codepoint_t min (void) const
+ {
+ for (unsigned int i = 0; i < ELTS; i++)
+ if (elts[i])
+ for (unsigned int j = 0; i < BITS; j++)
+ if (elts[i] & (1 << j))
+ return i * BITS + j;
+ return 0;
+ }
+ inline hb_codepoint_t max (void) const
+ {
+ for (unsigned int i = ELTS; i; i--)
+ if (elts[i - 1])
+ for (unsigned int j = BITS; j; j--)
+ if (elts[i - 1] & (1 << (j - 1)))
+ return (i - 1) * BITS + (j - 1);
+ return 0;
+ }
typedef uint32_t elt_t;
static const unsigned int MAX_G = 65536 - 1;
static const unsigned int SHIFT = 5;
static const unsigned int BITS = (1 << SHIFT);
static const unsigned int MASK = BITS - 1;
+ static const unsigned int ELTS = (MAX_G + 1 + (BITS - 1)) / BITS;
elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
hb_object_header_t header;
- elt_t elts[(MAX_G + 1 + (BITS - 1)) / BITS]; /* 8kb */
+ elt_t elts[ELTS]; /* 8kb */
ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
ASSERT_STATIC (sizeof (elts) * 8 > MAX_G);
diff --git a/src/hb-set.cc b/src/hb-set.cc
index 353489b..3b1c5bd 100644
--- a/src/hb-set.cc
+++ b/src/hb-set.cc
@@ -28,6 +28,8 @@
+/* Public API */
+
static hb_set_t _hb_set_nil = {
HB_OBJECT_HEADER_STATIC,
@@ -99,6 +101,12 @@ hb_set_clear (hb_set_t *set)
}
hb_bool_t
+hb_set_empty (hb_set_t *set)
+{
+ return set->empty ();
+}
+
+hb_bool_t
hb_set_has (hb_set_t *set,
hb_codepoint_t codepoint)
{
@@ -118,3 +126,50 @@ hb_set_del (hb_set_t *set,
{
set->del (codepoint);
}
+
+hb_bool_t
+hb_set_equal (hb_set_t *set,
+ hb_set_t *other)
+{
+ return set->equal (other);
+}
+
+void
+hb_set_set (hb_set_t *set,
+ hb_set_t *other)
+{
+ set->set (other);
+}
+
+void
+hb_set_union (hb_set_t *set,
+ hb_set_t *other)
+{
+ set->union_ (other);
+}
+
+void
+hb_set_intersect (hb_set_t *set,
+ hb_set_t *other)
+{
+ set->intersect (other);
+}
+
+void
+hb_set_subtract (hb_set_t *set,
+ hb_set_t *other)
+{
+ set->subtract (other);
+}
+
+hb_codepoint_t
+hb_set_min (hb_set_t *set)
+{
+ return set->min ();
+}
+
+hb_codepoint_t
+hb_set_max (hb_set_t *set)
+{
+ return set->max ();
+}
diff --git a/src/hb-set.h b/src/hb-set.h
index a9c734b..35c77b8 100644
--- a/src/hb-set.h
+++ b/src/hb-set.h
@@ -52,14 +52,14 @@ void
hb_set_destroy (hb_set_t *set);
hb_bool_t
-hb_set_set_user_data (hb_set_t *set,
+hb_set_set_user_data (hb_set_t *set,
hb_user_data_key_t *key,
void * data,
hb_destroy_func_t destroy,
hb_bool_t replace);
void *
-hb_set_get_user_data (hb_set_t *set,
+hb_set_get_user_data (hb_set_t *set,
hb_user_data_key_t *key);
@@ -71,6 +71,9 @@ void
hb_set_clear (hb_set_t *set);
hb_bool_t
+hb_set_empty (hb_set_t *set);
+
+hb_bool_t
hb_set_has (hb_set_t *set,
hb_codepoint_t codepoint);
@@ -82,8 +85,33 @@ void
hb_set_del (hb_set_t *set,
hb_codepoint_t codepoint);
-/* TODO: add union, intersect, subtract, equal, empty, min, max, iter, etc */
+hb_bool_t
+hb_set_equal (hb_set_t *set,
+ hb_set_t *other);
+
+void
+hb_set_set (hb_set_t *set,
+ hb_set_t *other);
+
+void
+hb_set_union (hb_set_t *set,
+ hb_set_t *other);
+
+void
+hb_set_intersect (hb_set_t *set,
+ hb_set_t *other);
+
+void
+hb_set_subtract (hb_set_t *set,
+ hb_set_t *other);
+
+hb_codepoint_t
+hb_set_min (hb_set_t *set);
+
+hb_codepoint_t
+hb_set_max (hb_set_t *set);
+/* TODO: Add faster iteration API? */
HB_END_DECLS
commit 5caece67ab9eee322bdcdf6f4b607eadde297e56
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 23:03:12 2012 -0400
Make closure() return void
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index e4e631a..371672a 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -39,17 +39,15 @@ struct SingleSubstFormat1
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- bool ret = false;
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
hb_codepoint_t glyph_id = iter.get_glyph ();
if (c->glyphs->has (glyph_id))
- ret = c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFF) || ret;
+ c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFF);
}
- return ret;
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -96,16 +94,14 @@ struct SingleSubstFormat2
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- bool ret = false;
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ()))
- ret = c->glyphs->add (substitute[iter.get_coverage ()]) || ret;
+ c->glyphs->add (substitute[iter.get_coverage ()]);
}
- return ret;
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -154,13 +150,13 @@ struct SingleSubst
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
switch (u.format) {
- case 1: return u.format1.closure (c);
- case 2: return u.format2.closure (c);
- default:return false;
+ case 1: u.format1.closure (c); break;
+ case 2: u.format2.closure (c); break;
+ default: break;
}
}
@@ -208,14 +204,12 @@ struct Sequence
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
unsigned int count = substitute.len;
- bool ret = false;
for (unsigned int i = 0; i < count; i++)
- ret = c->glyphs->add (substitute[i]) || ret;
- return ret;
+ c->glyphs->add (substitute[i]);
}
inline bool apply (hb_apply_context_t *c) const
@@ -250,16 +244,14 @@ struct MultipleSubstFormat1
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- bool ret = false;
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ()))
- ret = (this+sequence[iter.get_coverage ()]).closure (c) || ret;
+ (this+sequence[iter.get_coverage ()]).closure (c);
}
- return ret;
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -302,12 +294,12 @@ struct MultipleSubst
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
switch (u.format) {
- case 1: return u.format1.closure (c);
- default:return false;
+ case 1: u.format1.closure (c); break;
+ default: break;
}
}
@@ -354,20 +346,18 @@ struct AlternateSubstFormat1
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- bool ret = false;
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ())) {
const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
unsigned int count = alt_set.len;
for (unsigned int i = 0; i < count; i++)
- ret = c->glyphs->add (alt_set[i]) || ret;
+ c->glyphs->add (alt_set[i]);
}
}
- return ret;
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -430,12 +420,12 @@ struct AlternateSubst
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
switch (u.format) {
- case 1: return u.format1.closure (c);
- default:return false;
+ case 1: u.format1.closure (c); break;
+ default: break;
}
}
@@ -479,14 +469,14 @@ struct Ligature
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
unsigned int count = component.len;
for (unsigned int i = 1; i < count; i++)
if (!c->glyphs->has (component[i]))
- return false;
- return c->glyphs->add (ligGlyph);
+ return;
+ c->glyphs->add (ligGlyph);
}
inline bool would_apply (hb_codepoint_t second) const
@@ -584,17 +574,12 @@ struct LigatureSet
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- bool ret = false;
unsigned int num_ligs = ligature.len;
for (unsigned int i = 0; i < num_ligs; i++)
- {
- const Ligature &lig = this+ligature[i];
- ret = lig.closure (c) || ret;
- }
- return ret;
+ (this+ligature[i]).closure (c);
}
inline bool would_apply (hb_codepoint_t second) const
@@ -643,17 +628,14 @@ struct LigatureSubstFormat1
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- bool ret = false;
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ()))
- ret = (this+ligatureSet[iter.get_coverage ()]).closure (c) || ret;
+ (this+ligatureSet[iter.get_coverage ()]).closure (c);
}
- return ret;
- return false;
}
inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const
@@ -700,12 +682,12 @@ struct LigatureSubst
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
switch (u.format) {
- case 1: return u.format1.closure (c);
- default:return false;
+ case 1: u.format1.closure (c); break;
+ default: break;
}
}
@@ -744,7 +726,7 @@ struct LigatureSubst
static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index);
-static inline bool closure_lookup (hb_closure_context_t *c, unsigned int lookup_index);
+static inline void closure_lookup (hb_closure_context_t *c, unsigned int lookup_index);
struct ContextSubst : Context
{
@@ -752,7 +734,7 @@ struct ContextSubst : Context
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
return Context::closure (c, closure_lookup);
@@ -771,7 +753,7 @@ struct ChainContextSubst : ChainContext
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
return ChainContext::closure (c, closure_lookup);
@@ -798,7 +780,7 @@ struct ExtensionSubst : Extension
return StructAtOffset<SubstLookupSubTable> (this, offset);
}
- inline bool closure (hb_closure_context_t *c) const;
+ inline void closure (hb_closure_context_t *c) const;
inline bool would_apply (hb_codepoint_t glyph_id) const;
inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const;
@@ -816,7 +798,7 @@ struct ReverseChainSingleSubstFormat1
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
@@ -826,21 +808,19 @@ struct ReverseChainSingleSubstFormat1
count = backtrack.len;
for (unsigned int i = 0; i < count; i++)
if (!(this+backtrack[i]).intersects (c->glyphs))
- return false;
+ return;
count = lookahead.len;
for (unsigned int i = 0; i < count; i++)
if (!(this+lookahead[i]).intersects (c->glyphs))
- return false;
+ return;
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
- bool ret = false;
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
if (c->glyphs->has (iter.get_glyph ()))
- ret = c->glyphs->add (substitute[iter.get_coverage ()]) || ret;
+ c->glyphs->add (substitute[iter.get_coverage ()]);
}
- return false;
}
inline bool apply (hb_apply_context_t *c) const
@@ -910,12 +890,12 @@ struct ReverseChainSingleSubst
private:
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
switch (u.format) {
- case 1: return u.format1.closure (c);
- default:return false;
+ case 1: u.format1.closure (c); break;
+ default: break;
}
}
@@ -965,20 +945,20 @@ struct SubstLookupSubTable
ReverseChainSingle = 8
};
- inline bool closure (hb_closure_context_t *c,
+ inline void closure (hb_closure_context_t *c,
unsigned int lookup_type) const
{
TRACE_CLOSURE ();
switch (lookup_type) {
- case Single: return u.single.closure (c);
- case Multiple: return u.multiple.closure (c);
- case Alternate: return u.alternate.closure (c);
- case Ligature: return u.ligature.closure (c);
- case Context: return u.c.closure (c);
- case ChainContext: return u.chainContext.closure (c);
- case Extension: return u.extension.closure (c);
- case ReverseChainSingle: return u.reverseChainContextSingle.closure (c);
- default:return false;
+ case Single: u.single.closure (c); break;
+ case Multiple: u.multiple.closure (c); break;
+ case Alternate: u.alternate.closure (c); break;
+ case Ligature: u.ligature.closure (c); break;
+ case Context: u.c.closure (c); break;
+ case ChainContext: u.chainContext.closure (c); break;
+ case Extension: u.extension.closure (c); break;
+ case ReverseChainSingle: u.reverseChainContextSingle.closure (c); break;
+ default: break;
}
}
@@ -1068,14 +1048,12 @@ struct SubstLookup : Lookup
return lookup_type_is_reverse (type);
}
- inline bool closure (hb_closure_context_t *c) const
+ inline void closure (hb_closure_context_t *c) const
{
unsigned int lookup_type = get_type ();
- bool ret = false;
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++)
- ret = get_subtable (i).closure (c, lookup_type) || ret;
- return ret;
+ get_subtable (i).closure (c, lookup_type);
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -1196,7 +1174,7 @@ struct GSUB : GSUBGPOS
static inline void substitute_start (hb_buffer_t *buffer);
static inline void substitute_finish (hb_buffer_t *buffer);
- inline bool closure_lookup (hb_closure_context_t *c,
+ inline void closure_lookup (hb_closure_context_t *c,
unsigned int lookup_index) const
{ return get_lookup (lookup_index).closure (c); }
@@ -1231,9 +1209,9 @@ GSUB::substitute_finish (hb_buffer_t *buffer)
/* Out-of-class implementation for methods recursing */
-inline bool ExtensionSubst::closure (hb_closure_context_t *c) const
+inline void ExtensionSubst::closure (hb_closure_context_t *c) const
{
- return get_subtable ().closure (c, get_type ());
+ get_subtable ().closure (c, get_type ());
}
inline bool ExtensionSubst::would_apply (hb_codepoint_t glyph_id) const
@@ -1269,19 +1247,17 @@ inline bool ExtensionSubst::is_reverse (void) const
return SubstLookup::lookup_type_is_reverse (type);
}
-static inline bool closure_lookup (hb_closure_context_t *c, unsigned int lookup_index)
+static inline void closure_lookup (hb_closure_context_t *c, unsigned int lookup_index)
{
const GSUB &gsub = *(c->face->ot_layout->gsub);
const SubstLookup &l = gsub.get_lookup (lookup_index);
if (unlikely (c->nesting_level_left == 0))
- return false;
+ return;
c->nesting_level_left--;
- bool ret = l.closure (c);
+ l.closure (c);
c->nesting_level_left++;
-
- return ret;
}
static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index)
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index d40b2ce..1d12db1 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -229,7 +229,7 @@ struct hb_apply_context_t
typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
-typedef bool (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
+typedef void (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
struct ContextClosureFuncs
@@ -375,15 +375,13 @@ struct LookupRecord
};
-static inline bool closure_lookup (hb_closure_context_t *c,
+static inline void closure_lookup (hb_closure_context_t *c,
unsigned int lookupCount,
const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
closure_lookup_func_t closure_func)
{
- bool ret = false;
for (unsigned int i = 0; i < lookupCount; i++)
- ret = closure_func (c, lookupRecord->lookupListIndex) || ret;
- return ret;
+ closure_func (c, lookupRecord->lookupListIndex);
}
static inline bool apply_lookup (hb_apply_context_t *c,
@@ -460,19 +458,19 @@ struct ContextApplyLookupContext
const void *match_data;
};
-static inline bool context_closure_lookup (hb_closure_context_t *c,
+static inline void context_closure_lookup (hb_closure_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
const USHORT input[], /* Array of input values--start with second glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ContextClosureLookupContext &lookup_context)
{
- return intersects_array (c,
- inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.intersects, lookup_context.intersects_data)
- && closure_lookup (c,
- lookupCount, lookupRecord,
- lookup_context.funcs.closure);
+ if (intersects_array (c,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data))
+ closure_lookup (c,
+ lookupCount, lookupRecord,
+ lookup_context.funcs.closure);
}
@@ -500,14 +498,14 @@ struct Rule
private:
- inline bool closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+ inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE ();
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
- return context_closure_lookup (c,
- inputCount, input,
- lookupCount, lookupRecord,
- lookup_context);
+ context_closure_lookup (c,
+ inputCount, input,
+ lookupCount, lookupRecord,
+ lookup_context);
}
inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
@@ -545,14 +543,12 @@ struct Rule
struct RuleSet
{
- inline bool closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+ inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE ();
- bool ret = false;
unsigned int num_rules = rule.len;
for (unsigned int i = 0; i < num_rules; i++)
- ret = (this+rule[i]).closure (c, lookup_context) || ret;
- return ret;
+ (this+rule[i]).closure (c, lookup_context);
}
inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
@@ -587,7 +583,7 @@ struct ContextFormat1
private:
- inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
@@ -598,14 +594,12 @@ struct ContextFormat1
NULL
};
- bool ret = false;
unsigned int count = ruleSet.len;
for (unsigned int i = 0; i < count; i++)
if (cov.intersects_coverage (c->glyphs, i)) {
const RuleSet &rule_set = this+ruleSet[i];
- ret = rule_set.closure (c, lookup_context) || ret;
+ rule_set.closure (c, lookup_context);
}
- return ret;
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -648,11 +642,11 @@ struct ContextFormat2
private:
- inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
if (!(this+coverage).intersects (c->glyphs))
- return false;
+ return;
const ClassDef &class_def = this+classDef;
@@ -661,14 +655,12 @@ struct ContextFormat2
NULL
};
- bool ret = false;
unsigned int count = ruleSet.len;
for (unsigned int i = 0; i < count; i++)
if (class_def.intersects_class (c->glyphs, i)) {
const RuleSet &rule_set = this+ruleSet[i];
- ret = rule_set.closure (c, lookup_context) || ret;
+ rule_set.closure (c, lookup_context);
}
- return ret;
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -717,21 +709,21 @@ struct ContextFormat3
private:
- inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
if (!(this+coverage[0]).intersects (c->glyphs))
- return false;
+ return;
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
struct ContextClosureLookupContext lookup_context = {
{intersects_coverage, closure_func},
this
};
- return context_closure_lookup (c,
- glyphCount, (const USHORT *) (coverage + 1),
- lookupCount, lookupRecord,
- lookup_context);
+ context_closure_lookup (c,
+ glyphCount, (const USHORT *) (coverage + 1),
+ lookupCount, lookupRecord,
+ lookup_context);
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -781,14 +773,14 @@ struct Context
{
protected:
- inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
switch (u.format) {
- case 1: return u.format1.closure (c, closure_func);
- case 2: return u.format2.closure (c, closure_func);
- case 3: return u.format3.closure (c, closure_func);
- default:return false;
+ case 1: u.format1.closure (c, closure_func); break;
+ case 2: u.format2.closure (c, closure_func); break;
+ case 3: u.format3.closure (c, closure_func); break;
+ default: break;
}
}
@@ -838,7 +830,7 @@ struct ChainContextApplyLookupContext
const void *match_data[3];
};
-static inline bool chain_context_closure_lookup (hb_closure_context_t *c,
+static inline void chain_context_closure_lookup (hb_closure_context_t *c,
unsigned int backtrackCount,
const USHORT backtrack[],
unsigned int inputCount, /* Including the first glyph (not matched) */
@@ -849,18 +841,18 @@ static inline bool chain_context_closure_lookup (hb_closure_context_t *c,
const LookupRecord lookupRecord[],
ChainContextClosureLookupContext &lookup_context)
{
- return intersects_array (c,
- backtrackCount, backtrack,
- lookup_context.funcs.intersects, lookup_context.intersects_data[0])
- && intersects_array (c,
- inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.intersects, lookup_context.intersects_data[1])
- && intersects_array (c,
- lookaheadCount, lookahead,
- lookup_context.funcs.intersects, lookup_context.intersects_data[2])
- && closure_lookup (c,
- lookupCount, lookupRecord,
- lookup_context.funcs.closure);
+ if (intersects_array (c,
+ backtrackCount, backtrack,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[0])
+ && intersects_array (c,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[1])
+ && intersects_array (c,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[2]))
+ closure_lookup (c,
+ lookupCount, lookupRecord,
+ lookup_context.funcs.closure);
}
static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
@@ -904,18 +896,18 @@ struct ChainRule
private:
- inline bool closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+ inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE ();
const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
- return chain_context_closure_lookup (c,
- backtrack.len, backtrack.array,
- input.len, input.array,
- lookahead.len, lookahead.array,
- lookup.len, lookup.array,
- lookup_context);
+ chain_context_closure_lookup (c,
+ backtrack.len, backtrack.array,
+ input.len, input.array,
+ lookahead.len, lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
}
inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
@@ -964,14 +956,12 @@ struct ChainRule
struct ChainRuleSet
{
- inline bool closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+ inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE ();
- bool ret = false;
unsigned int num_rules = rule.len;
for (unsigned int i = 0; i < num_rules; i++)
- ret = (this+rule[i]).closure (c, lookup_context) || ret;
- return ret;
+ (this+rule[i]).closure (c, lookup_context);
}
inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
@@ -1006,7 +996,7 @@ struct ChainContextFormat1
private:
- inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
const Coverage &cov = (this+coverage);
@@ -1016,14 +1006,12 @@ struct ChainContextFormat1
{NULL, NULL, NULL}
};
- bool ret = false;
unsigned int count = ruleSet.len;
for (unsigned int i = 0; i < count; i++)
if (cov.intersects_coverage (c->glyphs, i)) {
const ChainRuleSet &rule_set = this+ruleSet[i];
- ret = rule_set.closure (c, lookup_context) || ret;
+ rule_set.closure (c, lookup_context);
}
- return ret;
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -1065,11 +1053,11 @@ struct ChainContextFormat2
private:
- inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
if (!(this+coverage).intersects (c->glyphs))
- return false;
+ return;
const ClassDef &backtrack_class_def = this+backtrackClassDef;
const ClassDef &input_class_def = this+inputClassDef;
@@ -1082,14 +1070,12 @@ struct ChainContextFormat2
&lookahead_class_def}
};
- bool ret = false;
unsigned int count = ruleSet.len;
for (unsigned int i = 0; i < count; i++)
if (input_class_def.intersects_class (c->glyphs, i)) {
const ChainRuleSet &rule_set = this+ruleSet[i];
- ret = rule_set.closure (c, lookup_context) || ret;
+ rule_set.closure (c, lookup_context);
}
- return ret;
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -1153,11 +1139,26 @@ struct ChainContextFormat3
private:
- inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ if (!(this+input[0]).intersects (c->glyphs))
+ return;
+
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_coverage, closure_func},
+ {this, this, this}
+ };
+ chain_context_closure_lookup (c,
+ backtrack.len, (const USHORT *) backtrack.array,
+ input.len, (const USHORT *) input.array + 1,
+ lookahead.len, (const USHORT *) lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -1219,14 +1220,14 @@ struct ChainContext
{
protected:
- inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ inline void closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
switch (u.format) {
- case 1: return u.format1.closure (c, closure_func);
- case 2: return u.format2.closure (c, closure_func);
- case 3: return u.format3.closure (c, closure_func);
- default:return false;
+ case 1: u.format1.closure (c, closure_func); break;
+ case 2: u.format2.closure (c, closure_func); break;
+ case 3: u.format3.closure (c, closure_func); break;
+ default: break;
}
}
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 95ed9c6..ded3dcc 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -470,13 +470,13 @@ hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED)
GSUB::substitute_finish (buffer);
}
-hb_bool_t
-hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
- hb_set_t *glyphs,
- unsigned int lookup_index)
+void
+hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
+ hb_set_t *glyphs,
+ unsigned int lookup_index)
{
hb_closure_context_t c (face, glyphs);
- return _get_gsub (face).closure_lookup (&c, lookup_index);
+ _get_gsub (face).closure_lookup (&c, lookup_index);
}
/*
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index f6890b6..b8b5baf 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -183,10 +183,10 @@ void
hb_ot_layout_substitute_finish (hb_buffer_t *buffer);
-hb_bool_t
-hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
- hb_set_t *glyphs,
- unsigned int lookup_index);
+void
+hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
+ hb_set_t *glyphs,
+ unsigned int lookup_index);
/*
* GPOS
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index 4b24370..a6239e4 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -38,23 +38,15 @@ struct _hb_set_t
inline void clear (void) {
memset (elts, 0, sizeof elts);
}
- inline bool add (hb_codepoint_t g)
+ inline void add (hb_codepoint_t g)
{
- if (unlikely (g > MAX_G)) return false;
- elt_t &e = elt (g);
- elt_t m = mask (g);
- bool ret = !(e & m);
- e |= m;
- return ret;
+ if (unlikely (g > MAX_G)) return;
+ elt (g) |= mask (g);
}
- inline bool del (hb_codepoint_t g)
+ inline void del (hb_codepoint_t g)
{
- if (unlikely (g > MAX_G)) return false;
- elt_t &e = elt (g);
- elt_t m = mask (g);
- bool ret = !!(e & m);
- e &= ~m;
- return ret;
+ if (unlikely (g > MAX_G)) return;
+ elt (g) &= ~mask (g);
}
inline bool has (hb_codepoint_t g) const
{
commit 0b08adb3539f2ec29682456b89c69e89ff5e9c03
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 22:41:09 2012 -0400
Add hb_set_t
diff --git a/TODO b/TODO
index d763c30..56eac54 100644
--- a/TODO
+++ b/TODO
@@ -85,6 +85,8 @@ Tests to write:
- GObject, FreeType, etc
+- hb_set_t
+
Optimizations:
=============
diff --git a/src/Makefile.am b/src/Makefile.am
index f53505e..63d4e31 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -34,6 +34,8 @@ HBSOURCES = \
hb-ot-name-table.hh \
hb-ot-tag.cc \
hb-private.hh \
+ hb-set-private.hh \
+ hb-set.cc \
hb-shape.cc \
hb-tt-font.cc \
hb-unicode-private.hh \
@@ -46,6 +48,7 @@ HBHEADERS = \
hb-buffer.h \
hb-common.h \
hb-font.h \
+ hb-set.h \
hb-shape.h \
hb-unicode.h \
hb-version.h \
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 8158df1..142eb5c 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -31,6 +31,7 @@
#include "hb-ot-layout-private.hh"
#include "hb-open-type-private.hh"
+#include "hb-set-private.hh"
#define NO_CONTEXT ((unsigned int) 0x110000)
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 32da46d..bf7e43b 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -95,51 +95,4 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout);
-struct _hb_set_t
-{
- void clear (void) {
- memset (elts, 0, sizeof elts);
- }
- bool add (hb_codepoint_t g)
- {
- if (unlikely (g > MAX_G)) return false;
- elt_t &e = elt (g);
- elt_t m = mask (g);
- bool ret = !!(e & m);
- e |= m;
- return ret;
- }
- bool has (hb_codepoint_t g) const
- {
- if (unlikely (g > MAX_G)) return false;
- return !!(elt (g) & mask (g));
- }
- bool intersects (hb_codepoint_t first,
- hb_codepoint_t last) const
- {
- if (unlikely (first > MAX_G)) return false;
- if (unlikely (last > MAX_G)) last = MAX_G;
- unsigned int end = last + 1;
- for (hb_codepoint_t i = first; i < end; i++)
- if (has (i))
- return true;
- return false;
- }
-
- private:
- typedef uint32_t elt_t;
- static const unsigned int MAX_G = 65536 - 1;
- static const unsigned int SHIFT = 5;
- static const unsigned int BITS = (1 << SHIFT);
- static const unsigned int MASK = BITS - 1;
-
- elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
- elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
- elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
-
- elt_t elts[(MAX_G + 1 + (BITS - 1)) / BITS]; /* 8kb */
- ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
- ASSERT_STATIC (sizeof (elts) * 8 > MAX_G);
-};
-
#endif /* HB_OT_LAYOUT_PRIVATE_HH */
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 1c1e7d9..f6890b6 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -183,8 +183,6 @@ void
hb_ot_layout_substitute_finish (hb_buffer_t *buffer);
-typedef struct _hb_set_t hb_set_t;
-
hb_bool_t
hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
hb_set_t *glyphs,
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
new file mode 100644
index 0000000..4b24370
--- /dev/null
+++ b/src/hb-set-private.hh
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SET_PRIVATE_HH
+#define HB_SET_PRIVATE_HH
+
+#include "hb-private.hh"
+#include "hb-set.h"
+#include "hb-object-private.hh"
+
+
+
+struct _hb_set_t
+{
+ inline void clear (void) {
+ memset (elts, 0, sizeof elts);
+ }
+ inline bool add (hb_codepoint_t g)
+ {
+ if (unlikely (g > MAX_G)) return false;
+ elt_t &e = elt (g);
+ elt_t m = mask (g);
+ bool ret = !(e & m);
+ e |= m;
+ return ret;
+ }
+ inline bool del (hb_codepoint_t g)
+ {
+ if (unlikely (g > MAX_G)) return false;
+ elt_t &e = elt (g);
+ elt_t m = mask (g);
+ bool ret = !!(e & m);
+ e &= ~m;
+ return ret;
+ }
+ inline bool has (hb_codepoint_t g) const
+ {
+ if (unlikely (g > MAX_G)) return false;
+ return !!(elt (g) & mask (g));
+ }
+ inline bool intersects (hb_codepoint_t first,
+ hb_codepoint_t last) const
+ {
+ if (unlikely (first > MAX_G)) return false;
+ if (unlikely (last > MAX_G)) last = MAX_G;
+ unsigned int end = last + 1;
+ for (hb_codepoint_t i = first; i < end; i++)
+ if (has (i))
+ return true;
+ return false;
+ }
+
+ typedef uint32_t elt_t;
+ static const unsigned int MAX_G = 65536 - 1;
+ static const unsigned int SHIFT = 5;
+ static const unsigned int BITS = (1 << SHIFT);
+ static const unsigned int MASK = BITS - 1;
+
+ elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
+ elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
+ elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
+
+ hb_object_header_t header;
+ elt_t elts[(MAX_G + 1 + (BITS - 1)) / BITS]; /* 8kb */
+
+ ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
+ ASSERT_STATIC (sizeof (elts) * 8 > MAX_G);
+};
+
+
+
+#endif /* HB_SET_PRIVATE_HH */
diff --git a/src/hb-set.cc b/src/hb-set.cc
new file mode 100644
index 0000000..353489b
--- /dev/null
+++ b/src/hb-set.cc
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-set-private.hh"
+
+
+
+static hb_set_t _hb_set_nil = {
+ HB_OBJECT_HEADER_STATIC,
+
+ {0} /* elts */
+};
+
+
+hb_set_t *
+hb_set_create ()
+{
+ hb_set_t *set;
+
+ if (!(set = hb_object_create<hb_set_t> ()))
+ return &_hb_set_nil;
+
+ set->clear ();
+
+ return set;
+}
+
+hb_set_t *
+hb_set_get_empty (void)
+{
+ return &_hb_set_nil;
+}
+
+hb_set_t *
+hb_set_reference (hb_set_t *set)
+{
+ return hb_object_reference (set);
+}
+
+void
+hb_set_destroy (hb_set_t *set)
+{
+ if (!hb_object_destroy (set)) return;
+
+ free (set);
+}
+
+hb_bool_t
+hb_set_set_user_data (hb_set_t *set,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace)
+{
+ return hb_object_set_user_data (set, key, data, destroy, replace);
+}
+
+void *
+hb_set_get_user_data (hb_set_t *set,
+ hb_user_data_key_t *key)
+{
+ return hb_object_get_user_data (set, key);
+}
+
+
+hb_bool_t
+hb_set_allocation_successful (hb_set_t *set)
+{
+ return TRUE;
+}
+
+void
+hb_set_clear (hb_set_t *set)
+{
+ set->clear ();
+}
+
+hb_bool_t
+hb_set_has (hb_set_t *set,
+ hb_codepoint_t codepoint)
+{
+ return set->has (codepoint);
+}
+
+void
+hb_set_add (hb_set_t *set,
+ hb_codepoint_t codepoint)
+{
+ set->add (codepoint);
+}
+
+void
+hb_set_del (hb_set_t *set,
+ hb_codepoint_t codepoint)
+{
+ set->del (codepoint);
+}
diff --git a/src/hb-set.h b/src/hb-set.h
new file mode 100644
index 0000000..a9c734b
--- /dev/null
+++ b/src/hb-set.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_H_IN
+#error "Include <hb.h> instead."
+#endif
+
+#ifndef HB_SET_H
+#define HB_SET_H
+
+#include "hb-common.h"
+
+HB_BEGIN_DECLS
+
+
+typedef struct _hb_set_t hb_set_t;
+
+
+hb_set_t *
+hb_set_create (void);
+
+hb_set_t *
+hb_set_get_empty (void);
+
+hb_set_t *
+hb_set_reference (hb_set_t *set);
+
+void
+hb_set_destroy (hb_set_t *set);
+
+hb_bool_t
+hb_set_set_user_data (hb_set_t *set,
+ hb_user_data_key_t *key,
+ void * data,
+ hb_destroy_func_t destroy,
+ hb_bool_t replace);
+
+void *
+hb_set_get_user_data (hb_set_t *set,
+ hb_user_data_key_t *key);
+
+
+/* Returns FALSE if allocation has failed before */
+hb_bool_t
+hb_set_allocation_successful (hb_set_t *set);
+
+void
+hb_set_clear (hb_set_t *set);
+
+hb_bool_t
+hb_set_has (hb_set_t *set,
+ hb_codepoint_t codepoint);
+
+void
+hb_set_add (hb_set_t *set,
+ hb_codepoint_t codepoint);
+
+void
+hb_set_del (hb_set_t *set,
+ hb_codepoint_t codepoint);
+
+/* TODO: add union, intersect, subtract, equal, empty, min, max, iter, etc */
+
+
+
+HB_END_DECLS
+
+#endif /* HB_SET_H */
diff --git a/src/hb.h b/src/hb.h
index 996dc91..d36040e 100644
--- a/src/hb.h
+++ b/src/hb.h
@@ -32,6 +32,7 @@
#include "hb-buffer.h"
#include "hb-common.h"
#include "hb-font.h"
+#include "hb-set.h"
#include "hb-shape.h"
#include "hb-unicode.h"
#include "hb-version.h"
commit 5b93e8d94fb4c2474816304ae3f52e1c704882de
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 22:26:13 2012 -0400
Update copyright headers
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index d104a44..8158df1 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -1,6 +1,6 @@
/*
* Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2010 Google, Inc.
+ * Copyright © 2010,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 6e5b85e..c51e89a 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1,6 +1,6 @@
/*
* Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * Copyright © 2010 Google, Inc.
+ * Copyright © 2010,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 1feb3c8..e4e631a 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1,6 +1,6 @@
/*
* Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * Copyright © 2010 Google, Inc.
+ * Copyright © 2010,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index aa3b268..d40b2ce 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -1,6 +1,6 @@
/*
* Copyright © 2007,2008,2009,2010 Red Hat, Inc.
- * Copyright © 2010 Google, Inc.
+ * Copyright © 2010,2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
commit 6a9be5bd3524dc3eb1e88d1063bde2e4d8b57011
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 22:23:17 2012 -0400
Rename hb_glyph_map_t to hb_set_t
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index cec339b..d104a44 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -131,7 +131,7 @@ struct RangeRecord
return c->check_struct (this);
}
- inline bool intersects (const hb_glyph_map_t *glyphs) const {
+ inline bool intersects (const hb_set_t *glyphs) const {
return glyphs->intersects (start, end);
}
@@ -358,7 +358,7 @@ struct CoverageFormat1
return glyphArray.sanitize (c);
}
- inline bool intersects_coverage (const hb_glyph_map_t *glyphs, unsigned int index) const {
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
return glyphs->has (glyphArray[index]);
}
@@ -402,7 +402,7 @@ struct CoverageFormat2
return rangeRecord.sanitize (c);
}
- inline bool intersects_coverage (const hb_glyph_map_t *glyphs, unsigned int index) const {
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
unsigned int i;
unsigned int count = rangeRecord.len;
for (i = 0; i < count; i++) {
@@ -476,7 +476,7 @@ struct Coverage
}
}
- inline bool intersects (const hb_glyph_map_t *glyphs) const {
+ inline bool intersects (const hb_set_t *glyphs) const {
/* TODO speed this up */
Coverage::Iter iter;
for (iter.init (*this); iter.more (); iter.next ()) {
@@ -486,7 +486,7 @@ struct Coverage
return false;
}
- inline bool intersects_coverage (const hb_glyph_map_t *glyphs, unsigned int index) const {
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const {
switch (u.format) {
case 1: return u.format1.intersects_coverage (glyphs, index);
case 2: return u.format2.intersects_coverage (glyphs, index);
@@ -574,7 +574,7 @@ struct ClassDefFormat1
&& classValue.sanitize (c);
}
- inline bool intersects_class (const hb_glyph_map_t *glyphs, unsigned int klass) const {
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
unsigned int count = classValue.len;
for (unsigned int i = 0; i < count; i++)
if (classValue[i] == klass && glyphs->has (startGlyph + i))
@@ -608,7 +608,7 @@ struct ClassDefFormat2
return rangeRecord.sanitize (c);
}
- inline bool intersects_class (const hb_glyph_map_t *glyphs, unsigned int klass) const {
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
unsigned int count = rangeRecord.len;
for (unsigned int i = 0; i < count; i++)
if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
@@ -647,7 +647,7 @@ struct ClassDef
}
}
- inline bool intersects_class (const hb_glyph_map_t *glyphs, unsigned int klass) const {
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
switch (u.format) {
case 1: return u.format1.intersects_class (glyphs, klass);
case 2: return u.format2.intersects_class (glyphs, klass);
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 10cfd34..aa3b268 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -58,13 +58,13 @@ static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
struct hb_closure_context_t
{
hb_face_t *face;
- hb_glyph_map_t *glyphs;
+ hb_set_t *glyphs;
unsigned int nesting_level_left;
unsigned int debug_depth;
hb_closure_context_t (hb_face_t *face_,
- hb_glyph_map_t *glyphs_,
+ hb_set_t *glyphs_,
unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
face (face_), glyphs (glyphs_),
nesting_level_left (nesting_level_left_),
@@ -227,7 +227,7 @@ struct hb_apply_context_t
-typedef bool (*intersects_func_t) (hb_glyph_map_t *glyphs, const USHORT &value, const void *data);
+typedef bool (*intersects_func_t) (hb_set_t *glyphs, const USHORT &value, const void *data);
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
typedef bool (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
@@ -243,16 +243,16 @@ struct ContextApplyFuncs
apply_lookup_func_t apply;
};
-static inline bool intersects_glyph (hb_glyph_map_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+static inline bool intersects_glyph (hb_set_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
{
return glyphs->has (value);
}
-static inline bool intersects_class (hb_glyph_map_t *glyphs, const USHORT &value, const void *data)
+static inline bool intersects_class (hb_set_t *glyphs, const USHORT &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
return class_def.intersects_class (glyphs, value);
}
-static inline bool intersects_coverage (hb_glyph_map_t *glyphs, const USHORT &value, const void *data)
+static inline bool intersects_coverage (hb_set_t *glyphs, const USHORT &value, const void *data)
{
const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
return (data+coverage).intersects (glyphs);
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 92f3c26..32da46d 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -95,7 +95,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout);
-struct _hb_glyph_map_t
+struct _hb_set_t
{
void clear (void) {
memset (elts, 0, sizeof elts);
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 4441a7e..95ed9c6 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -472,7 +472,7 @@ hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED)
hb_bool_t
hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
- hb_glyph_map_t *glyphs,
+ hb_set_t *glyphs,
unsigned int lookup_index)
{
hb_closure_context_t c (face, glyphs);
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index a9db04f..1c1e7d9 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -183,11 +183,11 @@ void
hb_ot_layout_substitute_finish (hb_buffer_t *buffer);
-typedef struct _hb_glyph_map_t hb_glyph_map_t;
+typedef struct _hb_set_t hb_set_t;
hb_bool_t
hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
- hb_glyph_map_t *glyphs,
+ hb_set_t *glyphs,
unsigned int lookup_index);
/*
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 5675d37..d5fc4ce 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -126,7 +126,7 @@ struct hb_ot_map_t
hb_buffer_t *buffer) const;
HB_INTERNAL void substitute_closure (hb_face_t *face,
- hb_glyph_map_t *glyphs) const;
+ hb_set_t *glyphs) const;
hb_mask_t global_mask;
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index a0efe90..bebf3ed 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -96,7 +96,7 @@ void hb_ot_map_t::apply (unsigned int table_index,
}
void hb_ot_map_t::substitute_closure (hb_face_t *face,
- hb_glyph_map_t *glyphs) const
+ hb_set_t *glyphs) const
{
unsigned int table_index = 0;
unsigned int i = 0;
commit a4385f0b0a6949e2ce49e6a147ad4beaa724f6c3
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 22:20:14 2012 -0400
Improve clustering
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 66b1461..b31cdc5 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -193,7 +193,7 @@ hb_form_clusters (hb_buffer_t *buffer)
(FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) |
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
- buffer->info[i].cluster = buffer->info[i - 1].cluster;
+ buffer->info[i].cluster = buffer->info[i - 1].cluster; /* XXX do the min() here */
}
static void
@@ -251,8 +251,7 @@ hb_map_glyphs (hb_font_t *font,
for (buffer->idx = 0; buffer->idx < count;) {
if (unlikely (_hb_unicode_is_variation_selector (buffer->info[buffer->idx + 1].codepoint))) {
hb_font_get_glyph (font, buffer->info[buffer->idx].codepoint, buffer->info[buffer->idx + 1].codepoint, &glyph);
- buffer->replace_glyph (glyph);
- buffer->skip_glyph ();
+ buffer->replace_glyphs (2, 1, &glyph);
} else {
hb_font_get_glyph (font, buffer->info[buffer->idx].codepoint, 0, &glyph);
buffer->replace_glyph (glyph);
commit 8e3715f8a16b315c1c7dd4b256e7f68a36c53e7c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 22:18:54 2012 -0400
Minor
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 06d4912..6296608 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -104,7 +104,7 @@ struct _hb_buffer_t {
const uint16_t *glyph_data_be);
HB_INTERNAL void replace_glyphs (unsigned int num_in,
unsigned int num_out,
- const uint16_t *glyph_data);
+ const hb_codepoint_t *glyph_data);
HB_INTERNAL void replace_glyph (hb_codepoint_t glyph_index);
/* Makes a copy of the glyph at idx to output and replace glyph_index */
HB_INTERNAL void output_glyph (hb_codepoint_t glyph_index);
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 4a37e66..c566a4a 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -271,7 +271,7 @@ hb_buffer_t::replace_glyphs_be16 (unsigned int num_in,
void
hb_buffer_t::replace_glyphs (unsigned int num_in,
unsigned int num_out,
- const uint16_t *glyph_data)
+ const uint32_t *glyph_data)
{
if (!make_room_for (num_in, num_out)) return;
diff --git a/src/hb-graphite2.cc b/src/hb-graphite2.cc
index fa07ae9..eab2eae 100644
--- a/src/hb-graphite2.cc
+++ b/src/hb-graphite2.cc
@@ -247,11 +247,10 @@ _hb_graphite_shape (hb_font_t *font,
features++;
}
- unsigned short *gids = NULL;
+ hb_codepoint_t *gids = NULL, *pg;
hb_gr_cluster_t *clusters = NULL;
gr_segment *seg = NULL;
uint32_t *text = NULL;
- unsigned short *pg;
const gr_slot *is;
unsigned int ci = 0, ic = 0;
float curradvx = 0., curradvy = 0.;
@@ -280,7 +279,7 @@ _hb_graphite_shape (hb_font_t *font,
clusters = (hb_gr_cluster_t *) calloc (charlen, sizeof (hb_gr_cluster_t));
if (!glyphlen || !clusters) goto dieout;
- gids = (uint16_t *) malloc (glyphlen * sizeof (uint16_t));
+ gids = (hb_codepoint_t *) malloc (glyphlen * sizeof (hb_codepoint_t));
if (!gids) goto dieout;
pg = gids;
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index a56d161..880a6b9 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -221,8 +221,8 @@ arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
/* Mandatory ligatures */
buffer->clear_output ();
for (buffer->idx = 0; buffer->idx + 1 < count;) {
- uint16_t ligature = get_ligature (buffer->info[buffer->idx].codepoint,
- buffer->info[buffer->idx + 1].codepoint);
+ hb_codepoint_t ligature = get_ligature (buffer->info[buffer->idx].codepoint,
+ buffer->info[buffer->idx + 1].codepoint);
if (likely (!ligature) || !(hb_font_get_glyph (font, ligature, 0, &glyph))) {
buffer->next_glyph ();
continue;
diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc
index 76cb3a3..c95749a 100644
--- a/src/hb-ot-shape-complex-misc.cc
+++ b/src/hb-ot-shape-complex-misc.cc
@@ -148,8 +148,8 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map, hb_buffer_t *buffer, hb
}
/* Is SARA AM. Decompose and reorder. */
- uint16_t decomposed[2] = {uint16_t (NIKHAHIT_FROM_SARA_AM (u)),
- uint16_t (SARA_AA_FROM_SARA_AM (u))};
+ hb_codepoint_t decomposed[2] = {hb_codepoint_t (NIKHAHIT_FROM_SARA_AM (u)),
+ hb_codepoint_t (SARA_AA_FROM_SARA_AM (u))};
buffer->replace_glyphs (1, 2, decomposed);
if (unlikely (buffer->in_error))
return;
commit d2984a241e4819474d827b1dd5d4b6d76596b3a5
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 17:21:14 2012 -0400
Add map->substitute_closure()
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index 710cc0a..5675d37 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -125,6 +125,9 @@ struct hb_ot_map_t
void *face_or_font,
hb_buffer_t *buffer) const;
+ HB_INTERNAL void substitute_closure (hb_face_t *face,
+ hb_glyph_map_t *glyphs) const;
+
hb_mask_t global_mask;
hb_tag_t chosen_script[2];
diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc
index a54e306..a0efe90 100644
--- a/src/hb-ot-map.cc
+++ b/src/hb-ot-map.cc
@@ -95,6 +95,21 @@ void hb_ot_map_t::apply (unsigned int table_index,
apply_lookup_func (face_or_font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask);
}
+void hb_ot_map_t::substitute_closure (hb_face_t *face,
+ hb_glyph_map_t *glyphs) const
+{
+ unsigned int table_index = 0;
+ unsigned int i = 0;
+
+ for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) {
+ const pause_map_t *pause = &pauses[table_index][pause_index];
+ for (; i < pause->num_lookups; i++)
+ hb_ot_layout_substitute_closure_lookup (face, glyphs, lookups[table_index][i].index);
+ }
+
+ for (; i < lookups[table_index].len; i++)
+ hb_ot_layout_substitute_closure_lookup (face, glyphs, lookups[table_index][i].index);
+}
void hb_ot_map_builder_t::add_pause (unsigned int table_index, hb_ot_map_t::pause_func_t pause_func, void *user_data)
{
More information about the HarfBuzz
mailing list