[pango/harfbuzz-ng] [GPOS] MarkLigPosFormat1



commit 191cfb73b04955d9af757d47dc85b1ae0ab6c6c5
Author: Behdad Esfahbod <behdad behdad org>
Date:   Fri May 22 18:29:45 2009 -0400

    [GPOS] MarkLigPosFormat1
    
    GPOS is complete now!  Yay!
---
 pango/opentype/hb-ot-layout-gpos-private.h |  128 ++++++++++++++++++++--------
 1 files changed, 92 insertions(+), 36 deletions(-)

diff --git a/pango/opentype/hb-ot-layout-gpos-private.h b/pango/opentype/hb-ot-layout-gpos-private.h
index 3d15853..9519678 100644
--- a/pango/opentype/hb-ot-layout-gpos-private.h
+++ b/pango/opentype/hb-ot-layout-gpos-private.h
@@ -867,45 +867,26 @@ struct MarkBasePos
 ASSERT_SIZE (MarkBasePos, 2);
 
 
-struct ComponentRecord
-{
-  /* TODO */
-
-  private:
-  OffsetTo<Anchor>
-		ligatureAnchor[];	/* Array of offsets (one per class)
-					 * to Anchor tables--from beginning
-					 * of LigatureAttach table--ordered
-					 * by class--NULL if a component
-					 * does not have an attachment for a
-					 * class--zero--based array */
-};
-ASSERT_SIZE (ComponentRecord, 0);
-
 struct LigatureAttach
 {
-  /* TODO */
+  friend struct MarkLigPosFormat1;
 
   private:
-    /* XXXXXXXXXXXXX */
-  USHORT	componentCount;		/* Number of ComponentRecords in this
-					 * ligature */
-  ComponentRecord
-		componentRecord[];	/* Array of ComponentRecords--ordered
-					 * in writing direction */
+  USHORT	len;			/* Number of ComponentRecords in this
+					 * ligature, ie. number of rows */
+  OffsetTo<Anchor>
+		matrix[];		/* Matrix of offsets to Anchor tables--
+					 * from beginning of LigatureAttach table--
+					 * component-major--in order of
+					 * writing direction--, mark-minor--
+					 * ordered by class--zero-based. */
 };
 ASSERT_SIZE (LigatureAttach, 2);
 
-struct LigatureArray
-{
-  /* TODO */
-
-  private:
-  OffsetArrayOf<LigatureAttach>
-		ligatureAttach;		/* Array of LigatureAttach
+typedef OffsetArrayOf<LigatureAttach> LigatureArray;
+					/* Array of LigatureAttach
 					 * tables ordered by
 					 * LigatureCoverage Index */
-};
 ASSERT_SIZE (LigatureArray, 2);
 
 struct MarkLigPosFormat1
@@ -915,21 +896,96 @@ struct MarkLigPosFormat1
   private:
   inline bool apply (APPLY_ARG_DEF) const
   {
-    /* TODO */
-    return false;
+    if  (lookup_flag & LookupFlag::IgnoreLigatures)
+      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 == HB_OT_LAYOUT_GLYPH_CLASS_MARK || 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 0
+    if (property != HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)
+      return false;
+#endif
+
+    unsigned int lig_index = (this+ligatureCoverage) (IN_GLYPH (j));
+    if (lig_index == NOT_COVERED)
+      return false;
+
+    const MarkArray& mark_array = this+markArray;
+    const LigatureArray& lig_array = this+ligatureArray;
+
+    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 || lig_index >= lig_array.len))
+      return false;
+
+    const LigatureAttach& lig_attach = &lig_array+lig_array[lig_index];
+    count = lig_attach.len;
+    if (HB_UNLIKELY (!count))
+      return false;
+
+    unsigned int comp_index;
+    /* We must now check whether the ligature ID of the current mark glyph
+     * is identical to the ligature ID of the found ligature.  If yes, we
+     * can directly use the component index.  If not, we attach the mark
+     * glyph to the last component of the ligature. */
+    if (IN_LIGID (j) == IN_LIGID (buffer->in_pos))
+    {
+      comp_index = IN_COMPONENT (buffer->in_pos);
+      if (comp_index >= count)
+	comp_index = count - 1;
+    }
+    else
+      comp_index = count - 1;
+
+    hb_position_t mark_x, mark_y, lig_x, lig_y;
+
+    mark_anchor.get_anchor (layout, IN_CURGLYPH (), &mark_x, &mark_y);
+    unsigned int index = comp_index * classCount + mark_class;
+    (&lig_attach+lig_attach.matrix[index]).get_anchor (layout, IN_GLYPH (j), &lig_x, &lig_y);
+
+    HB_Position o = POSITION (buffer->in_pos);
+    o->x_pos     = lig_x - mark_x;
+    o->y_pos     = lig_y - mark_y;
+    o->x_advance = 0;
+    o->y_advance = 0;
+    o->back      = i;
+
+    buffer->in_pos++;
+    return true;
   }
 
   private:
   USHORT	format;			/* Format identifier--format = 1 */
-  Offset	markCoverage;		/* Offset to Mark Coverage table--from
+  OffsetTo<Coverage>
+		markCoverage;		/* Offset to Mark Coverage table--from
 					 * beginning of MarkLigPos subtable */
-  Offset	ligatureCoverage;	/* Offset to Ligature Coverage
+  OffsetTo<Coverage>
+		ligatureCoverage;	/* Offset to Ligature Coverage
 					 * table--from beginning of MarkLigPos
 					 * subtable */
   USHORT	classCount;		/* Number of defined mark classes */
-  Offset	markArray;		/* Offset to MarkArray table--from
+  OffsetTo<MarkArray>
+		markArray;		/* Offset to MarkArray table--from
 					 * beginning of MarkLigPos subtable */
-  Offset	ligatureArray;		/* Offset to LigatureArray table--from
+  OffsetTo<LigatureArray>
+		ligatureArray;		/* Offset to LigatureArray table--from
 					 * beginning of MarkLigPos subtable */
 };
 ASSERT_SIZE (MarkLigPosFormat1, 12);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]