From 357ccde36bba01a405d59b7da061fc5048cdc7b4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 21 May 2009 06:32:01 -0400 Subject: [PATCH] [GPOS] MarkBasePosFormat1 --- src/TODO | 1 + src/hb-ot-layout-gpos-private.h | 62 ++++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/TODO b/src/TODO index 2646ecbff..865e91ef8 100644 --- a/src/TODO +++ b/src/TODO @@ -3,3 +3,4 @@ - Implement is_simple() - Static assert PangoOTGlyph vs hb */ - Face index > 0 and dfont fonts +- assert static HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH diff --git a/src/hb-ot-layout-gpos-private.h b/src/hb-ot-layout-gpos-private.h index 2208d7901..4b706ea0e 100644 --- a/src/hb-ot-layout-gpos-private.h +++ b/src/hb-ot-layout-gpos-private.h @@ -240,8 +240,8 @@ ASSERT_SIZE (MarkRecord, 4); struct MarkArray { - inline unsigned int get_class (unsigned int index) { return markRecord[index].klass; } - inline const Anchor& get_anchor (unsigned int index) { return this+markRecord[index].markAnchor; } + inline unsigned int get_class (unsigned int index) const { return markRecord[index].klass; } + inline const Anchor& get_anchor (unsigned int index) const { return this+markRecord[index].markAnchor; } private: ArrayOf @@ -774,9 +774,61 @@ struct MarkBasePosFormat1 private: inline bool apply (APPLY_ARG_DEF) const { - /* TODO */ - /* XXXXXXXXXXXXXXX */ - return false; + if (lookup_flag & LookupFlag::IgnoreBaseGlyphs) + return false; + + unsigned int mark_index = (this+markCoverage) (IN_CURGLYPH ()); + if (HB_LIKELY (mark_index == NOT_COVERED)) + return false; + + /* now we search backwards for a non-mark glyph */ + + unsigned int count = buffer->in_pos; + unsigned int i = 1, j = count - 1; + while (i <= count) + { + property = _hb_ot_layout_get_glyph_property (layout, IN_GLYPH (j)); + if (!(property == LookupFlag::IgnoreMarks || property & LookupFlag::MarkAttachmentType)) + break; + i++, j--; + } + + if (HB_UNLIKELY (i > buffer->in_pos)) + return false; + + /* The following assertion is too strong -- at least for mangal.ttf. */ + if (property != HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH) + return false; + + unsigned int base_index = (this+baseCoverage) (IN_GLYPH (j)); + if (HB_LIKELY (base_index == NOT_COVERED)) + return false; + + const MarkArray& mark_array = this+markArray; + const BaseArray& base_array = this+baseArray; + + unsigned int mark_class = mark_array.get_class (mark_index); + const Anchor& mark_anchor = mark_array.get_anchor (mark_index); + + if (HB_UNLIKELY (mark_class >= classCount || base_index >= base_array.len)) + return false; + + hb_position_t mark_x, mark_y, base_x, base_y; + + mark_anchor.get_anchor (layout, IN_CURGLYPH (), &mark_x, &mark_y); + unsigned int index = base_index * classCount + mark_class; + (&base_array+base_array.matrix[index]).get_anchor (layout, IN_GLYPH (j), &base_x, &base_y); + + /* anchor points are not cumulative */ + HB_Position o = POSITION (buffer->in_pos); + o->x_pos = base_x - mark_x; + o->y_pos = base_y - mark_y; + o->x_advance = 0; + o->y_advance = 0; + o->back = i; + + buffer->in_pos++; + return true; } private: