Start implementing collect_glyphs() operation

Not functional yet.
This commit is contained in:
Behdad Esfahbod 2012-11-16 19:07:06 -08:00
parent 7d52e6601f
commit e8cfdd7fa8
4 changed files with 272 additions and 3 deletions

View File

@ -52,6 +52,16 @@ struct SingleSubstFormat1
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
hb_codepoint_t glyph_id = iter.get_glyph ();
c->input.add (glyph_id);
c->output.add ((glyph_id + deltaGlyphID) & 0xFFFF);
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
return this+coverage; return this+coverage;
@ -116,6 +126,15 @@ struct SingleSubstFormat2
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
c->input.add (iter.get_glyph ());
c->output.add (substitute[iter.get_coverage ()]);
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
return this+coverage; return this+coverage;
@ -182,6 +201,16 @@ struct SingleSubst
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_CLOSURE ();
switch (u.format) {
case 1: u.format1.collect_glyphs (c); break;
case 2: u.format2.collect_glyphs (c); break;
default: break;
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
switch (u.format) { switch (u.format) {
@ -261,6 +290,13 @@ struct Sequence
c->glyphs->add (substitute[i]); c->glyphs->add (substitute[i]);
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
unsigned int count = substitute.len;
for (unsigned int i = 0; i < count; i++)
c->output.add (substitute[i]);
}
inline bool apply (hb_apply_context_t *c) const inline bool apply (hb_apply_context_t *c) const
{ {
TRACE_APPLY (); TRACE_APPLY ();
@ -316,6 +352,14 @@ struct MultipleSubstFormat1
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
(this+coverage).add_coverage (&c->input);
unsigned int count = sequence.len;
for (unsigned int i = 0; i < count; i++)
(this+sequence[i]).collect_glyphs (c);
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
return this+coverage; return this+coverage;
@ -382,6 +426,14 @@ struct MultipleSubst
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
switch (u.format) {
case 1: u.format1.collect_glyphs (c); break;
default: break;
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
switch (u.format) { switch (u.format) {
@ -455,6 +507,18 @@ struct AlternateSubstFormat1
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
c->input.add (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++)
c->output.add (alt_set[i]);
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
return this+coverage; return this+coverage;
@ -539,6 +603,14 @@ struct AlternateSubst
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
switch (u.format) {
case 1: u.format1.collect_glyphs (c); break;
default: break;
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
switch (u.format) { switch (u.format) {
@ -605,6 +677,14 @@ struct Ligature
c->glyphs->add (ligGlyph); c->glyphs->add (ligGlyph);
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
unsigned int count = component.len;
for (unsigned int i = 1; i < count; i++)
c->input.add (component[i]);
c->output.add (ligGlyph);
}
inline bool would_apply (hb_would_apply_context_t *c) const inline bool would_apply (hb_would_apply_context_t *c) const
{ {
if (c->len != component.len) if (c->len != component.len)
@ -693,6 +773,13 @@ struct LigatureSet
(this+ligature[i]).closure (c); (this+ligature[i]).closure (c);
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
unsigned int num_ligs = ligature.len;
for (unsigned int i = 0; i < num_ligs; i++)
(this+ligature[i]).collect_glyphs (c);
}
inline bool would_apply (hb_would_apply_context_t *c) const inline bool would_apply (hb_would_apply_context_t *c) const
{ {
unsigned int num_ligs = ligature.len; unsigned int num_ligs = ligature.len;
@ -767,6 +854,15 @@ struct LigatureSubstFormat1
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
c->input.add (iter.get_glyph ());
(this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
return this+coverage; return this+coverage;
@ -844,6 +940,14 @@ struct LigatureSubst
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
switch (u.format) {
case 1: u.format1.collect_glyphs (c); break;
default: break;
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
switch (u.format) { switch (u.format) {
@ -907,6 +1011,7 @@ struct LigatureSubst
static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index); static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index);
static inline void 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);
static inline void collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
struct ContextSubst : Context struct ContextSubst : Context
{ {
@ -920,6 +1025,11 @@ struct ContextSubst : Context
return Context::closure (c, closure_lookup); return Context::closure (c, closure_lookup);
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
return Context::collect_glyphs (c, collect_glyphs_lookup);
}
inline bool apply (hb_apply_context_t *c) const inline bool apply (hb_apply_context_t *c) const
{ {
TRACE_APPLY (); TRACE_APPLY ();
@ -939,6 +1049,11 @@ struct ChainContextSubst : ChainContext
return ChainContext::closure (c, closure_lookup); return ChainContext::closure (c, closure_lookup);
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
return ChainContext::collect_glyphs (c, collect_glyphs_lookup);
}
inline bool apply (hb_apply_context_t *c) const inline bool apply (hb_apply_context_t *c) const
{ {
TRACE_APPLY (); TRACE_APPLY ();
@ -962,6 +1077,8 @@ struct ExtensionSubst : Extension
inline void closure (hb_closure_context_t *c) const; inline void closure (hb_closure_context_t *c) const;
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const;
inline const Coverage &get_coverage (void) const; inline const Coverage &get_coverage (void) const;
inline bool would_apply (hb_would_apply_context_t *c) const; inline bool would_apply (hb_would_apply_context_t *c) const;
@ -1005,6 +1122,28 @@ struct ReverseChainSingleSubstFormat1
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
unsigned int count;
(this+coverage).add_coverage (&c->input);
count = backtrack.len;
for (unsigned int i = 0; i < count; i++)
(this+backtrack[i]).add_coverage (&c->before);
count = lookahead.len;
for (unsigned int i = 0; i < count; i++)
(this+lookahead[i]).add_coverage (&c->after);
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
count = substitute.len;
for (unsigned int i = 0; i < count; i++)
c->output.add (substitute[i]);
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
return this+coverage; return this+coverage;
@ -1084,6 +1223,14 @@ struct ReverseChainSingleSubst
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
switch (u.format) {
case 1: u.format1.collect_glyphs (c); break;
default: break;
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
switch (u.format) { switch (u.format) {
@ -1155,6 +1302,22 @@ struct SubstLookupSubTable
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c,
unsigned int lookup_type) const
{
switch (lookup_type) {
case Single: u.single.collect_glyphs (c); break;
case Multiple: u.multiple.collect_glyphs (c); break;
case Alternate: u.alternate.collect_glyphs (c); break;
case Ligature: u.ligature.collect_glyphs (c); break;
case Context: u.context.collect_glyphs (c); break;
case ChainContext: u.chainContext.collect_glyphs (c); break;
case Extension: u.extension.collect_glyphs (c); break;
case ReverseChainSingle: u.reverseChainContextSingle.collect_glyphs (c); break;
default: break;
}
}
inline const Coverage &get_coverage (unsigned int lookup_type) const inline const Coverage &get_coverage (unsigned int lookup_type) const
{ {
switch (lookup_type) { switch (lookup_type) {
@ -1286,6 +1449,14 @@ struct SubstLookup : Lookup
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
unsigned int lookup_type = get_type ();
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++)
get_subtable (i).collect_glyphs (c, lookup_type);
}
inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const
{ {
if (unlikely (!c->len)) return false; if (unlikely (!c->len)) return false;
@ -1506,6 +1677,11 @@ inline void ExtensionSubst::closure (hb_closure_context_t *c) const
get_subtable ().closure (c, get_type ()); get_subtable ().closure (c, get_type ());
} }
inline void ExtensionSubst::collect_glyphs (hb_collect_glyphs_context_t *c) const
{
get_subtable ().collect_glyphs (c, get_type ());
}
inline const Coverage & ExtensionSubst::get_coverage (void) const inline const Coverage & ExtensionSubst::get_coverage (void) const
{ {
return get_subtable ().get_coverage (get_type ()); return get_subtable ().get_coverage (get_type ());
@ -1552,6 +1728,15 @@ static inline void closure_lookup (hb_closure_context_t *c, unsigned int lookup_
c->nesting_level_left++; c->nesting_level_left++;
} }
static inline void collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int lookup_index)
{
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
const SubstLookup &l = gsub.get_lookup (lookup_index);
/* XXX TODO */
l.collect_glyphs (c);
}
static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index) static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index)
{ {
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub); const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);

View File

@ -93,6 +93,40 @@ struct hb_would_apply_context_t
}; };
/* TODO Add TRACE_RETURN annotation to gsub. */
#ifndef HB_DEBUG_COLLECT_GLYPHS
#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0)
#endif
#define TRACE_COLLECT_GLYPHS() \
hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS> trace (&c->debug_depth, "COLLECT_GLYPHS", this, HB_FUNC, "");
struct hb_collect_glyphs_context_t
{
hb_face_t *face;
hb_set_t &before;
hb_set_t &input;
hb_set_t &after;
hb_set_t &output;
unsigned int debug_depth;
hb_collect_glyphs_context_t (hb_face_t *face_,
hb_set_t *glyphs_before, /* OUT. May be NULL */
hb_set_t *glyphs_input, /* OUT. May be NULL */
hb_set_t *glyphs_after, /* OUT. May be NULL */
hb_set_t *glyphs_output /* OUT. May be NULL */) :
face (face_),
before (glyphs_before ? *glyphs_before : *hb_set_get_empty ()),
input (glyphs_input ? *glyphs_input : *hb_set_get_empty ()),
after (glyphs_after ? *glyphs_after : *hb_set_get_empty ()),
output (glyphs_output ? *glyphs_output : *hb_set_get_empty ()),
debug_depth (0) {};
};
#ifndef HB_DEBUG_APPLY #ifndef HB_DEBUG_APPLY
#define HB_DEBUG_APPLY (HB_DEBUG+0) #define HB_DEBUG_APPLY (HB_DEBUG+0)
#endif #endif
@ -341,6 +375,7 @@ struct hb_apply_context_t
typedef bool (*intersects_func_t) (hb_set_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 (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
typedef void (*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 void (*collect_glyphs_lookup_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_index); typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
struct ContextClosureFuncs struct ContextClosureFuncs
@ -1105,6 +1140,17 @@ struct Context
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c, collect_glyphs_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
switch (u.format) {
// case 1: u.format1.collect_glyphs (c); break;
// case 2: u.format2.collect_glyphs (c); break;
// case 3: u.format2.collect_glyphs (c); break;
default: break;
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
switch (u.format) { switch (u.format) {
@ -1648,6 +1694,17 @@ struct ChainContext
} }
} }
inline void collect_glyphs (hb_collect_glyphs_context_t *c, collect_glyphs_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
switch (u.format) {
// case 1: u.format1.collect_glyphs (c); break;
// case 2: u.format2.collect_glyphs (c); break;
// case 3: u.format2.collect_glyphs (c); break;
default: break;
}
}
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const
{ {
switch (u.format) { switch (u.format) {

View File

@ -401,6 +401,35 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes); return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
} }
void
hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
hb_tag_t table_tag,
unsigned int lookup_index,
hb_set_t *glyphs_before, /* OUT. May be NULL */
hb_set_t *glyphs_input, /* OUT. May be NULL */
hb_set_t *glyphs_after, /* OUT. May be NULL */
hb_set_t *glyphs_output /* OUT. May be NULL */)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return;
OT::hb_collect_glyphs_context_t c (face, glyphs_before, glyphs_input, glyphs_after, glyphs_output);
switch (table_tag) {
case HB_OT_TAG_GSUB:
{
const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index);
l.collect_glyphs (&c);
return;
}
case HB_OT_TAG_GPOS:
{
const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index);
// l.collect_glyphs (&c);
return;
}
}
}
/* /*
* OT::GSUB * OT::GSUB

View File

@ -194,16 +194,14 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
hb_tag_t table_tag, hb_tag_t table_tag,
hb_set_t *lookup_indexes /* OUT */); hb_set_t *lookup_indexes /* OUT */);
#ifdef HB_NOT_IMPLEMENTED
void void
Xhb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
hb_tag_t table_tag, hb_tag_t table_tag,
unsigned int lookup_index, unsigned int lookup_index,
hb_set_t *glyphs_before, /* OUT. May be NULL */ hb_set_t *glyphs_before, /* OUT. May be NULL */
hb_set_t *glyphs_input, /* OUT. May be NULL */ hb_set_t *glyphs_input, /* OUT. May be NULL */
hb_set_t *glyphs_after, /* OUT. May be NULL */ hb_set_t *glyphs_after, /* OUT. May be NULL */
hb_set_t *glyphs_output /* OUT. May be NULL */); hb_set_t *glyphs_output /* OUT. May be NULL */);
#endif
#ifdef HB_NOT_IMPLEMENTED #ifdef HB_NOT_IMPLEMENTED
typedef struct typedef struct