Oops, actually set global mask
[framework/uifw/harfbuzz.git] / src / hb-ot-layout-gsub-private.hh
index f5b3593..f09b4d2 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "hb-ot-layout-gsubgpos-private.hh"
 
+HB_BEGIN_DECLS
+
 
 struct SingleSubstFormat1
 {
@@ -39,7 +41,7 @@ struct SingleSubstFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY ();
-    hb_codepoint_t glyph_id = c->buffer->info[c->buffer->in_pos].codepoint;
+    hb_codepoint_t glyph_id = c->buffer->info[c->buffer->i].codepoint;
     unsigned int index = (this+coverage) (glyph_id);
     if (likely (index == NOT_COVERED))
       return false;
@@ -80,7 +82,7 @@ struct SingleSubstFormat2
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY ();
-    hb_codepoint_t glyph_id = c->buffer->info[c->buffer->in_pos].codepoint;
+    hb_codepoint_t glyph_id = c->buffer->info[c->buffer->i].codepoint;
     unsigned int index = (this+coverage) (glyph_id);
     if (likely (index == NOT_COVERED))
       return false;
@@ -163,8 +165,8 @@ struct Sequence
       return false;
 
     c->buffer->add_output_glyphs_be16 (1,
-                                            substitute.len, (const uint16_t *) substitute.array,
-                                            0xFFFF, 0xFFFF);
+                                      substitute.len, (const uint16_t *) substitute.array,
+                                      0xFFFF, 0xFFFF);
 
     /* This is a guess only ... */
     if (_hb_ot_layout_has_new_glyph_classes (c->layout->face))
@@ -204,7 +206,7 @@ struct MultipleSubstFormat1
   {
     TRACE_APPLY ();
 
-    unsigned int index = (this+coverage) (c->buffer->info[c->buffer->in_pos].codepoint);
+    unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoint);
     if (likely (index == NOT_COVERED))
       return false;
 
@@ -273,7 +275,9 @@ struct AlternateSubstFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY ();
-    hb_codepoint_t glyph_id = c->buffer->info[c->buffer->in_pos].codepoint;
+    hb_codepoint_t glyph_id = c->buffer->info[c->buffer->i].codepoint;
+    hb_mask_t glyph_mask = c->buffer->info[c->buffer->i].mask;
+    hb_mask_t lookup_mask = c->lookup_mask;
 
     unsigned int index = (this+coverage) (glyph_id);
     if (likely (index == NOT_COVERED))
@@ -284,19 +288,14 @@ struct AlternateSubstFormat1
     if (unlikely (!alt_set.len))
       return false;
 
-    unsigned int alt_index = 0;
-
-    /* XXX callback to user to choose alternate
-    if (c->layout->face->altfunc)
-      alt_index = (c->layout->face->altfunc)(c->layout->layout, c->buffer,
-                                   c->buffer->out_length, glyph_id,
-                                   alt_set.len, alt_set.array);
-                                  */
+    /* Note: This breaks badly if two features enabled this lookup together. */
+    unsigned int shift = _hb_ctz (lookup_mask);
+    unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
 
-    if (unlikely (alt_index >= alt_set.len))
+    if (unlikely (alt_index > alt_set.len || alt_index == 0))
       return false;
 
-    glyph_id = alt_set[alt_index];
+    glyph_id = alt_set[alt_index - 1];
 
     c->buffer->replace_glyph (glyph_id);
 
@@ -367,11 +366,11 @@ struct Ligature
     TRACE_APPLY ();
     unsigned int i, j;
     unsigned int count = component.len;
-    unsigned int end = MIN (c->buffer->in_length, c->buffer->in_pos + c->context_length);
-    if (unlikely (c->buffer->in_pos + count > end))
+    unsigned int end = MIN (c->buffer->len, c->buffer->i + c->context_length);
+    if (unlikely (c->buffer->i + count > end))
       return false;
 
-    for (i = 1, j = c->buffer->in_pos + 1; i < count; i++, j++)
+    for (i = 1, j = c->buffer->i + 1; i < count; i++, j++)
     {
       unsigned int property;
       while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[j], c->lookup_flag, &property))
@@ -393,14 +392,14 @@ struct Ligature
                                     is_mark ? HB_OT_LAYOUT_GLYPH_CLASS_MARK
                                             : HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE);
 
-    if (j == c->buffer->in_pos + i) /* No input glyphs skipped */
+    if (j == c->buffer->i + i) /* No input glyphs skipped */
       /* We don't use a new ligature ID if there are no skipped
         glyphs and the ligature already has an ID. */
       c->buffer->add_output_glyphs_be16 (i,
-                                              1, (const uint16_t *) &ligGlyph,
-                                              0,
-                                              c->buffer->info[c->buffer->in_pos].lig_id && !c->buffer->info[c->buffer->in_pos].component ?
-                                              0xFFFF : c->buffer->allocate_lig_id ());
+                                        1, (const uint16_t *) &ligGlyph,
+                                        0,
+                                        c->buffer->info[c->buffer->i].lig_id && !c->buffer->info[c->buffer->i].component ?
+                                        0xFFFF : c->buffer->allocate_lig_id ());
     else
     {
       unsigned int lig_id = c->buffer->allocate_lig_id ();
@@ -415,10 +414,10 @@ struct Ligature
 
       for ( i = 1; i < count; i++ )
       {
-       while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->in_pos], c->lookup_flag, NULL))
-         c->buffer->add_output_glyph (c->buffer->info[c->buffer->in_pos].codepoint, i, lig_id);
+       while (_hb_ot_layout_skip_mark (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_flag, NULL))
+         c->buffer->add_output_glyph (c->buffer->info[c->buffer->i].codepoint, i, lig_id);
 
-       (c->buffer->in_pos)++;
+       (c->buffer->i)++;
       }
     }
 
@@ -483,7 +482,7 @@ struct LigatureSubstFormat1
   inline bool apply (hb_apply_context_t *c) const
   {
     TRACE_APPLY ();
-    hb_codepoint_t glyph_id = c->buffer->info[c->buffer->in_pos].codepoint;
+    hb_codepoint_t glyph_id = c->buffer->info[c->buffer->i].codepoint;
 
     bool first_is_mark = !!(c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK);
 
@@ -544,8 +543,9 @@ struct LigatureSubst
 };
 
 
-
+HB_BEGIN_DECLS
 static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index);
+HB_END_DECLS
 
 struct ContextSubst : Context
 {
@@ -604,7 +604,7 @@ struct ReverseChainSingleSubstFormat1
     if (unlikely (c->context_length != NO_CONTEXT))
       return false; /* No chaining to this type */
 
-    unsigned int index = (this+coverage) (c->buffer->info[c->buffer->in_pos].codepoint);
+    unsigned int index = (this+coverage) (c->buffer->info[c->buffer->i].codepoint);
     if (likely (index == NOT_COVERED))
       return false;
 
@@ -619,8 +619,8 @@ struct ReverseChainSingleSubstFormat1
                         match_coverage, this,
                         1))
     {
-      c->buffer->info[c->buffer->in_pos].codepoint = substitute[index];
-      c->buffer->in_pos--; /* Reverse! */
+      c->buffer->info[c->buffer->i].codepoint = substitute[index];
+      c->buffer->i--; /* Reverse! */
       return true;
     }
 
@@ -777,6 +777,7 @@ struct SubstLookup : Lookup
 
   inline bool apply_once (hb_ot_layout_context_t *layout,
                          hb_buffer_t *buffer,
+                         hb_mask_t lookup_mask,
                          unsigned int context_length,
                          unsigned int nesting_level_left) const
   {
@@ -785,11 +786,12 @@ struct SubstLookup : Lookup
 
     c->layout = layout;
     c->buffer = buffer;
+    c->lookup_mask = lookup_mask;
     c->context_length = context_length;
     c->nesting_level_left = nesting_level_left;
     c->lookup_flag = get_flag ();
 
-    if (!_hb_ot_layout_check_glyph_property (c->layout->face, &c->buffer->info[c->buffer->in_pos], c->lookup_flag, &c->property))
+    if (!_hb_ot_layout_check_glyph_property (c->layout->face, &c->buffer->info[c->buffer->i], c->lookup_flag, &c->property))
       return false;
 
     if (unlikely (lookup_type == SubstLookupSubTable::Extension))
@@ -820,18 +822,18 @@ struct SubstLookup : Lookup
   {
     bool ret = false;
 
-    if (unlikely (!buffer->in_length))
+    if (unlikely (!buffer->len))
       return false;
 
     if (likely (!is_reverse ()))
     {
        /* in/out forward substitution */
        buffer->clear_output ();
-       buffer->in_pos = 0;
-       while (buffer->in_pos < buffer->in_length)
+       buffer->i = 0;
+       while (buffer->i < buffer->len)
        {
-         if ((~buffer->info[buffer->in_pos].mask & mask) &&
-             apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL))
+         if ((buffer->info[buffer->i].mask & mask) &&
+             apply_once (layout, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL))
            ret = true;
          else
            buffer->next_glyph ();
@@ -843,17 +845,17 @@ struct SubstLookup : Lookup
     else
     {
        /* in-place backward substitution */
-       buffer->in_pos = buffer->in_length - 1;
+       buffer->i = buffer->len - 1;
        do
        {
-         if ((~buffer->info[buffer->in_pos].mask & mask) &&
-             apply_once (layout, buffer, NO_CONTEXT, MAX_NESTING_LEVEL))
+         if ((buffer->info[buffer->i].mask & mask) &&
+             apply_once (layout, buffer, mask, NO_CONTEXT, MAX_NESTING_LEVEL))
            ret = true;
          else
-           buffer->in_pos--;
+           buffer->i--;
 
        }
-       while ((int) buffer->in_pos >= 0);
+       while ((int) buffer->i >= 0);
     }
 
     return ret;
@@ -924,7 +926,7 @@ inline bool ExtensionSubst::is_reverse (void) const
 
 static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index)
 {
-  const GSUB &gsub = *(c->layout->face->ot_layout.gsub);
+  const GSUB &gsub = *(c->layout->face->ot_layout->gsub);
   const SubstLookup &l = gsub.get_lookup (lookup_index);
 
   if (unlikely (c->nesting_level_left == 0))
@@ -933,8 +935,10 @@ static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup
   if (unlikely (c->context_length < 1))
     return false;
 
-  return l.apply_once (c->layout, c->buffer, c->context_length, c->nesting_level_left - 1);
+  return l.apply_once (c->layout, c->buffer, c->lookup_mask, c->context_length, c->nesting_level_left - 1);
 }
 
 
+HB_END_DECLS
+
 #endif /* HB_OT_LAYOUT_GSUB_PRIVATE_HH */