From af5d02a269d55331300df1e382241893928d64e0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 27 Oct 2010 11:54:26 -0400 Subject: [PATCH] Rewrite Cursive joining to act more like other pair lookups Look forward for next character instead of joining to the last character. --- src/hb-ot-layout-gpos-private.hh | 71 ++++++++++++++++++---------------------- src/hb-ot-layout-private.hh | 10 ------ 2 files changed, 31 insertions(+), 50 deletions(-) diff --git a/src/hb-ot-layout-gpos-private.hh b/src/hb-ot-layout-gpos-private.hh index 4e08d4f..5e6abbd 100644 --- a/src/hb-ot-layout-gpos-private.hh +++ b/src/hb-ot-layout-gpos-private.hh @@ -826,57 +826,61 @@ struct CursivePosFormat1 inline bool apply (hb_apply_context_t *c) const { TRACE_APPLY (); - struct hb_ot_layout_context_t::info_t::gpos_t *gpi = &c->layout->info.gpos; - hb_codepoint_t last_pos = gpi->last; - gpi->last = HB_OT_LAYOUT_GPOS_NO_LAST; /* We don't handle mark glyphs here. */ if (c->property == HB_OT_LAYOUT_GLYPH_CLASS_MARK) return false; - unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoint); - if (likely (index == NOT_COVERED)) + unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length); + if (unlikely (c->buffer->i + 2 > end)) return false; - const EntryExitRecord &record = entryExitRecord[index]; + const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->info[c->buffer->i].codepoint)]; + if (!this_record.exitAnchor) + return false; + + unsigned int j = c->buffer->i + 1; + while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, NULL)) + { + if (unlikely (j == end)) + return false; + j++; + } + + const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buffer->info[j].codepoint)]; + if (!next_record.entryAnchor) + return false; - if (last_pos == HB_OT_LAYOUT_GPOS_NO_LAST || !record.entryAnchor) - goto end; + unsigned int i = c->buffer->i; - hb_position_t entry_x, entry_y; - (this+record.entryAnchor).get_anchor (c->layout, c->buffer->info[c->buffer->i].codepoint, &entry_x, &entry_y); + hb_position_t entry_x, entry_y, exit_x, exit_y; + (this+this_record.exitAnchor).get_anchor (c->layout, c->buffer->info[i].codepoint, &exit_x, &exit_y); + (this+next_record.entryAnchor).get_anchor (c->layout, c->buffer->info[j].codepoint, &entry_x, &entry_y); /* TODO vertical */ /* Align the exit anchor of the left glyph with the entry anchor of the right glyph. */ if (c->buffer->props.direction == HB_DIRECTION_RTL) { - c->buffer->pos[c->buffer->i].x_advance = c->buffer->pos[c->buffer->i].x_offset + entry_x - gpi->anchor_x; + c->buffer->pos[j].x_advance = c->buffer->pos[j].x_offset + entry_x - exit_x; } else { - c->buffer->pos[last_pos].x_advance = c->buffer->pos[last_pos].x_advance + gpi->anchor_x - entry_x; + c->buffer->pos[i].x_advance = c->buffer->pos[i].x_offset + exit_x - entry_x; } if (c->lookup_flag & LookupFlag::RightToLeft) { - c->buffer->pos[last_pos].cursive_chain = last_pos - c->buffer->i; - c->buffer->pos[last_pos].y_offset = entry_y - gpi->anchor_y; + c->buffer->pos[i].cursive_chain = i - j; + c->buffer->pos[i].y_offset = entry_y - exit_y; } else { - c->buffer->pos[c->buffer->i].cursive_chain = c->buffer->i - last_pos; - c->buffer->pos[c->buffer->i].y_offset = gpi->anchor_y - entry_y; + c->buffer->pos[j].cursive_chain = j - i; + c->buffer->pos[j].y_offset = exit_y - entry_y; } - end: - if (record.exitAnchor) - { - gpi->last = c->buffer->i; - (this+record.exitAnchor).get_anchor (c->layout, c->buffer->info[c->buffer->i].codepoint, &gpi->anchor_x, &gpi->anchor_y); - } - - c->buffer->i++; + c->buffer->i = j; return true; } @@ -1415,26 +1419,13 @@ struct PosLookup : Lookup if (unlikely (!buffer->len)) return false; - layout->info.gpos.last = HB_OT_LAYOUT_GPOS_NO_LAST; /* no last valid glyph for cursive pos. */ - buffer->i = 0; while (buffer->i < buffer->len) { - bool done; - if (buffer->info[buffer->i].mask & mask) - { - done = apply_once (layout, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL); - ret |= done; - } + if ((buffer->info[buffer->i].mask & mask) && + apply_once (layout, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL)) + ret = true; else - { - done = false; - /* Contrary to properties defined in GDEF, user-defined properties - will always stop a possible cursive positioning. */ - layout->info.gpos.last = HB_OT_LAYOUT_GPOS_NO_LAST; - } - - if (!done) buffer->i++; } diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index fbaff13..4cde089 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -66,16 +66,6 @@ struct hb_ot_layout_context_t hb_face_t *face; hb_font_t *font; - union info_t - { - struct gpos_t - { - unsigned int last; /* the last matched glyph--used with cursive positioning */ - hb_position_t anchor_x; /* the coordinates of the anchor point */ - hb_position_t anchor_y; /* of the last matched glyph */ - } gpos; - } info; - /* Convert from font-space to user-space */ inline hb_position_t scale_x (int16_t v) { return scale (v, this->font->x_scale); } inline hb_position_t scale_y (int16_t v) { return scale (v, this->font->y_scale); } -- 2.7.4