[HarfBuzz] New release?
Jonathan Kew
jfkthame at googlemail.com
Wed Jan 2 14:03:39 PST 2013
On 2/1/13 21:45, Behdad Esfahbod wrote:
> On 13-01-02 05:20 AM, Khaled Hosny wrote:
>> Hi Behdad,
>>
>> Any estimates for when next HarfBuzz will be released? (for integrating
>> new XeTeX into TeX Live).
>
> Just ask! I'll roll one today. I'll see if I can fix the issues Jonathan
> reported first.
>
FWIW, here's the patch I've been using for now to handle the problem of
(incorrectly) using the global empty set as a "throwaway" destination
for collecting glyph sets. This (in addition to the other fixes I've
posted) has allowed me to experiment with the collect_glyphs feature,
though it hasn't had a huge amount of testing yet so there may still be
additional places where checks are needed.
JK
-------------- next part --------------
diff --git a/gfx/harfbuzz/src/hb-ot-layout-common-private.hh b/gfx/harfbuzz/src/hb-ot-layout-common-private.hh
--- a/gfx/harfbuzz/src/hb-ot-layout-common-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-common-private.hh
@@ -139,17 +139,17 @@ struct RangeRecord
}
inline bool intersects (const hb_set_t *glyphs) const {
return glyphs->intersects (start, end);
}
template <typename set_t>
inline void add_coverage (set_t *glyphs) const {
- glyphs->add_range (start, end);
+ if (glyphs) glyphs->add_range (start, end);
}
GlyphID start; /* First GlyphID in the range */
GlyphID end; /* Last GlyphID in the range */
USHORT value; /* Value */
public:
DEFINE_SIZE_STATIC (6);
};
@@ -855,20 +855,22 @@ struct Coverage
case 1: return u.format1.intersects_coverage (glyphs, index);
case 2: return u.format2.intersects_coverage (glyphs, index);
default:return false;
}
}
template <typename set_t>
inline void add_coverage (set_t *glyphs) const {
- switch (u.format) {
- case 1: u.format1.add_coverage (glyphs); break;
- case 2: u.format2.add_coverage (glyphs); break;
- default: break;
+ if (glyphs) {
+ switch (u.format) {
+ case 1: u.format1.add_coverage (glyphs); break;
+ case 2: u.format2.add_coverage (glyphs); break;
+ default: break;
+ }
}
}
struct Iter {
Iter (void) : format (0) {};
inline void init (const Coverage &c_) {
format = c_.u.format;
switch (format) {
@@ -1031,20 +1033,22 @@ struct ClassDef
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
case 2: return TRACE_RETURN (u.format2.sanitize (c));
default:return TRACE_RETURN (true);
}
}
inline void add_class (hb_set_t *glyphs, unsigned int klass) const {
- switch (u.format) {
- case 1: u.format1.add_class (glyphs, klass); return;
- case 2: u.format2.add_class (glyphs, klass); return;
- default:return;
+ if (glyphs) {
+ switch (u.format) {
+ case 1: u.format1.add_class (glyphs, klass); return;
+ case 2: u.format2.add_class (glyphs, klass); return;
+ default:return;
+ }
}
}
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);
default:return false;
diff --git a/gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh b/gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh
--- a/gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-gpos-table.hh
@@ -559,26 +559,28 @@ struct PairValueRecord
struct PairSet
{
friend struct PairPosFormat1;
inline void collect_glyphs (hb_collect_glyphs_context_t *c,
const ValueFormat *valueFormats) const
{
TRACE_COLLECT_GLYPHS (this);
- unsigned int len1 = valueFormats[0].get_len ();
- unsigned int len2 = valueFormats[1].get_len ();
- unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
+ if (c->input) {
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
- const PairValueRecord *record = CastP<PairValueRecord> (array);
- unsigned int count = len;
- for (unsigned int i = 0; i < count; i++)
- {
- c->input->add (record->secondGlyph);
- record = &StructAtOffset<PairValueRecord> (record, record_size);
+ const PairValueRecord *record = CastP<PairValueRecord> (array);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ c->input->add (record->secondGlyph);
+ record = &StructAtOffset<PairValueRecord> (record, record_size);
+ }
}
}
inline bool apply (hb_apply_context_t *c,
const ValueFormat *valueFormats,
unsigned int pos) const
{
TRACE_APPLY (this);
@@ -700,25 +702,27 @@ struct PairPosFormat2
{
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
/* (this+coverage).add_coverage (c->input); // Don't need this. */
/* TODO only add values for pairs that have nonzero adjustments. */
- unsigned int count1 = class1Count;
- const ClassDef &klass1 = this+classDef1;
- for (unsigned int i = 0; i < count1; i++)
- klass1.add_class (c->input, i);
+ if (c->input) {
+ unsigned int count1 = class1Count;
+ const ClassDef &klass1 = this+classDef1;
+ for (unsigned int i = 0; i < count1; i++)
+ klass1.add_class (c->input, i);
- unsigned int count2 = class2Count;
- const ClassDef &klass2 = this+classDef2;
- for (unsigned int i = 0; i < count2; i++)
- klass2.add_class (c->input, i);
+ unsigned int count2 = class2Count;
+ const ClassDef &klass2 = this+classDef2;
+ for (unsigned int i = 0; i < count2; i++)
+ klass2.add_class (c->input, i);
+ }
}
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
diff --git a/gfx/harfbuzz/src/hb-ot-layout-gsub-table.hh b/gfx/harfbuzz/src/hb-ot-layout-gsub-table.hh
--- a/gfx/harfbuzz/src/hb-ot-layout-gsub-table.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-gsub-table.hh
@@ -49,18 +49,18 @@ struct SingleSubstFormat1
}
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
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);
+ if (c->input) c->input->add (glyph_id);
+ if (c->output) c->output->add ((glyph_id + deltaGlyphID) & 0xFFFF);
}
}
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
@@ -125,18 +125,18 @@ struct SingleSubstFormat2
}
}
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
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 ()]);
+ if (c->input) c->input->add (iter.get_glyph ());
+ if (c->output) c->output->add (substitute[iter.get_coverage ()]);
}
}
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
@@ -257,19 +257,21 @@ struct Sequence
unsigned int count = substitute.len;
for (unsigned int i = 0; i < count; i++)
c->glyphs->add (substitute[i]);
}
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
- unsigned int count = substitute.len;
- for (unsigned int i = 0; i < count; i++)
- c->output->add (substitute[i]);
+ if (c->output) {
+ 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
{
TRACE_APPLY (this);
if (unlikely (!substitute.len)) return TRACE_RETURN (false);
unsigned int klass = c->property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE ? HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
@@ -446,21 +448,22 @@ struct AlternateSubstFormat1
}
}
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
- c->input->add (iter.get_glyph ());
+ if (c->input) 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]);
+ if (c->output)
+ for (unsigned int i = 0; i < count; i++)
+ c->output->add (alt_set[i]);
}
}
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
@@ -589,19 +592,20 @@ struct Ligature
return;
c->glyphs->add (ligGlyph);
}
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
unsigned int count = component.len;
- for (unsigned int i = 1; i < count; i++)
- c->input->add (component[i]);
- c->output->add (ligGlyph);
+ if (c->input)
+ for (unsigned int i = 1; i < count; i++)
+ c->input->add (component[i]);
+ if (c->output) c->output->add (ligGlyph);
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
TRACE_WOULD_APPLY (this);
if (c->len != component.len)
return TRACE_RETURN (false);
@@ -762,17 +766,17 @@ struct LigatureSubstFormat1
}
}
inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
TRACE_COLLECT_GLYPHS (this);
Coverage::Iter iter;
for (iter.init (this+coverage); iter.more (); iter.next ()) {
- c->input->add (iter.get_glyph ());
+ if (c->input) c->input->add (iter.get_glyph ());
(this+ligatureSet[iter.get_coverage ()]).collect_glyphs (c);
}
}
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
@@ -940,18 +944,19 @@ struct ReverseChainSingleSubstFormat1
(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]);
+ if (c->output)
+ for (unsigned int i = 0; i < count; i++)
+ c->output->add (substitute[i]);
}
inline const Coverage &get_coverage (void) const
{
return this+coverage;
}
inline bool would_apply (hb_would_apply_context_t *c) const
diff --git a/gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh b/gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh
--- a/gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh
+++ b/gfx/harfbuzz/src/hb-ot-layout-gsubgpos-private.hh
@@ -161,17 +161,17 @@ struct hb_collect_glyphs_context_t
* glyphs in the recursion. If output is not requested, we can go home now. */
if (output == hb_set_get_empty ())
return HB_VOID;
hb_set_t *old_before = before;
hb_set_t *old_input = input;
hb_set_t *old_after = after;
- before = input = after = hb_set_get_empty ();
+ before = input = after = NULL;
nesting_level_left--;
recurse_func (this, lookup_index);
nesting_level_left++;
before = old_before;
input = old_input;
after = old_after;
@@ -190,20 +190,20 @@ struct hb_collect_glyphs_context_t
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 */
unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
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 ()),
+ before (glyphs_before),
+ input (glyphs_input),
+ after (glyphs_after),
+ output (glyphs_output),
recurse_func (NULL),
nesting_level_left (nesting_level_left_),
debug_depth (0) {}
void set_recurse_func (recurse_func_t func) { recurse_func = func; }
};
@@ -551,18 +551,19 @@ static inline void collect_coverage (hb_
}
static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
hb_set_t *glyphs,
unsigned int count,
const USHORT values[],
collect_glyphs_func_t collect_func,
const void *collect_data)
{
- for (unsigned int i = 0; i < count; i++)
- collect_func (glyphs, values[i], collect_data);
+ if (glyphs)
+ for (unsigned int i = 0; i < count; i++)
+ collect_func (glyphs, values[i], collect_data);
}
static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED)
{
return glyph_id == value;
}
static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
More information about the HarfBuzz
mailing list