[GSUB/GPOS] Add more buffer messages

Behind HB_BUFFER_MESSAGE_MORE.

https://github.com/harfbuzz/harfbuzz/pull/3495
diff --git a/src/OT/Layout/GPOS/CursivePosFormat1.hh b/src/OT/Layout/GPOS/CursivePosFormat1.hh
index 7c34bb3..7f58fac 100644
--- a/src/OT/Layout/GPOS/CursivePosFormat1.hh
+++ b/src/OT/Layout/GPOS/CursivePosFormat1.hh
@@ -140,6 +140,13 @@
     unsigned int i = skippy_iter.idx;
     unsigned int j = buffer->idx;
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "cursive attaching glyph at %d to glyph at %d",
+			  i, j);
+    }
+
     buffer->unsafe_to_break (i, j + 1);
     float entry_x, entry_y, exit_x, exit_y;
     (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
@@ -231,6 +238,13 @@
 	pos[parent].x_offset = 0;
     }
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "cursive attached glyph at %d to glyph at %d",
+			  i, j);
+    }
+
     buffer->idx++;
     return_trace (true);
   }
diff --git a/src/OT/Layout/GPOS/MarkArray.hh b/src/OT/Layout/GPOS/MarkArray.hh
index f8cddd1..be50738 100644
--- a/src/OT/Layout/GPOS/MarkArray.hh
+++ b/src/OT/Layout/GPOS/MarkArray.hh
@@ -39,6 +39,13 @@
     mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
     glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "attaching mark glyph at %d to glyph at %d",
+			  c->buffer->idx, glyph_pos);
+    }
+
     hb_glyph_position_t &o = buffer->cur_pos();
     o.x_offset = roundf (base_x - mark_x);
     o.y_offset = roundf (base_y - mark_y);
@@ -46,6 +53,13 @@
     o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
     buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "attached mark glyph at %d to glyph at %d",
+			  c->buffer->idx, glyph_pos);
+    }
+
     buffer->idx++;
     return_trace (true);
   }
diff --git a/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/OT/Layout/GPOS/PairPosFormat2.hh
index f58bcb1..a80fe0c 100644
--- a/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -217,10 +217,23 @@
     }
     bail:
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "kerning glyphs at %d,%d",
+			  c->buffer->idx, skippy_iter.idx);
+    }
 
     applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
     applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "kerned glyphs at %d,%d",
+			  c->buffer->idx, skippy_iter.idx);
+    }
+
     success:
     if (applied_first || applied_second)
       buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
diff --git a/src/OT/Layout/GPOS/PairSet.hh b/src/OT/Layout/GPOS/PairSet.hh
index 58ba4de..4578fbd 100644
--- a/src/OT/Layout/GPOS/PairSet.hh
+++ b/src/OT/Layout/GPOS/PairSet.hh
@@ -109,12 +109,28 @@
                                                 record_size);
     if (record)
     {
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->message (c->font,
+			    "kerning glyphs at %d,%d",
+			    c->buffer->idx, pos);
+      }
+
       bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
       bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->message (c->font,
+			    "kerned glyphs at %d,%d",
+			    c->buffer->idx, pos);
+      }
+
       if (applied_first || applied_second)
         buffer->unsafe_to_break (buffer->idx, pos + 1);
       if (len2)
         pos++;
+
       buffer->idx = pos;
       return_trace (true);
     }
diff --git a/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/OT/Layout/GPOS/SinglePosFormat1.hh
index c0e7d29..0dacd10 100644
--- a/src/OT/Layout/GPOS/SinglePosFormat1.hh
+++ b/src/OT/Layout/GPOS/SinglePosFormat1.hh
@@ -62,8 +62,22 @@
     unsigned int index = (this+coverage).get_coverage  (buffer->cur().codepoint);
     if (likely (index == NOT_COVERED)) return_trace (false);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "positioning glyph at %d",
+			  c->buffer->idx);
+    }
+
     valueFormat.apply_value (c, this, values, buffer->cur_pos());
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "positioned glyph at %d",
+			  c->buffer->idx);
+    }
+
     buffer->idx++;
     return_trace (true);
   }
diff --git a/src/OT/Layout/GPOS/SinglePosFormat2.hh b/src/OT/Layout/GPOS/SinglePosFormat2.hh
index 0d038b4..518fa9d 100644
--- a/src/OT/Layout/GPOS/SinglePosFormat2.hh
+++ b/src/OT/Layout/GPOS/SinglePosFormat2.hh
@@ -70,10 +70,24 @@
 
     if (likely (index >= valueCount)) return_trace (false);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "positioning glyph at %d",
+			  c->buffer->idx);
+    }
+
     valueFormat.apply_value (c, this,
                              &values[index * valueFormat.get_len ()],
                              buffer->cur_pos());
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "positioned glyph at %d",
+			  c->buffer->idx);
+    }
+
     buffer->idx++;
     return_trace (true);
   }
diff --git a/src/OT/Layout/GSUB/AlternateSet.hh b/src/OT/Layout/GSUB/AlternateSet.hh
index a5dcb65..4a9e967 100644
--- a/src/OT/Layout/GSUB/AlternateSet.hh
+++ b/src/OT/Layout/GSUB/AlternateSet.hh
@@ -57,8 +57,23 @@
 
     if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->sync_so_far ();
+      c->buffer->message (c->font,
+			  "replacing glyph at %d (alternate substitution)",
+			  c->buffer->idx);
+    }
+
     c->replace_glyph (alternates[alt_index - 1]);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "replaced glyph at %d (alternate substitution)",
+			  c->buffer->idx - 1);
+    }
+
     return_trace (true);
   }
 
diff --git a/src/OT/Layout/GSUB/Ligature.hh b/src/OT/Layout/GSUB/Ligature.hh
index 22ed65f..f373d92 100644
--- a/src/OT/Layout/GSUB/Ligature.hh
+++ b/src/OT/Layout/GSUB/Ligature.hh
@@ -64,7 +64,24 @@
      * as a "ligated" substitution. */
     if (unlikely (count == 1))
     {
+
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->sync_so_far ();
+	c->buffer->message (c->font,
+			    "replacing glyph at %d (ligature substitution)",
+			    c->buffer->idx);
+      }
+
       c->replace_glyph (ligGlyph);
+
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->message (c->font,
+			    "replaced glyph at %d (ligature substitution)",
+			    c->buffer->idx - 1);
+      }
+
       return_trace (true);
     }
 
@@ -85,6 +102,31 @@
       return_trace (false);
     }
 
+    unsigned pos = 0;
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      unsigned delta = c->buffer->sync_so_far ();
+
+      pos = c->buffer->idx;
+
+      char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0};
+      char *p = buf;
+
+      match_end += delta;
+      for (unsigned i = 0; i < count; i++)
+      {
+	match_positions[i] += delta;
+	if (i)
+	  *p++ = ',';
+	sprintf (p, "%u", match_positions[i]);
+	p += strlen(p);
+      }
+
+      c->buffer->message (c->font,
+			  "ligating glyphs at %s",
+			  buf);
+    }
+
     ligate_input (c,
                   count,
                   match_positions,
@@ -92,6 +134,14 @@
                   ligGlyph,
                   total_component_count);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->sync_so_far ();
+      c->buffer->message (c->font,
+			  "ligated glyph at %d",
+			  pos);
+    }
+
     return_trace (true);
   }
 
diff --git a/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
index 1d27df9..a23e920 100644
--- a/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
+++ b/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
@@ -131,7 +131,23 @@
                          c->buffer->idx + 1, &end_index))
     {
       c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index);
+
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->message (c->font,
+			    "replacing glyph at %d (reverse chaining substitution)",
+			    c->buffer->idx);
+      }
+
       c->replace_glyph_inplace (substitute[index]);
+
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->message (c->font,
+			    "replaced glyph at %d (reverse chaining substitution)",
+			    c->buffer->idx);
+      }
+
       /* Note: We DON'T decrease buffer->idx.  The main loop does it
        * for us.  This is useful for preventing surprises if someone
        * calls us through a Context lookup. */
diff --git a/src/OT/Layout/GSUB/Sequence.hh b/src/OT/Layout/GSUB/Sequence.hh
index c5cd15b..3d84a5e 100644
--- a/src/OT/Layout/GSUB/Sequence.hh
+++ b/src/OT/Layout/GSUB/Sequence.hh
@@ -40,17 +40,58 @@
      * as a "multiplied" substitution. */
     if (unlikely (count == 1))
     {
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->sync_so_far ();
+	c->buffer->message (c->font,
+			    "replacing glyph at %d (multiple substitution)",
+			    c->buffer->idx);
+      }
+
       c->replace_glyph (substitute.arrayZ[0]);
+
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->message (c->font,
+			    "replaced glyph at %d (multiple subtitution)",
+			    c->buffer->idx - 1);
+      }
+
       return_trace (true);
     }
     /* Spec disallows this, but Uniscribe allows it.
      * https://github.com/harfbuzz/harfbuzz/issues/253 */
     else if (unlikely (count == 0))
     {
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->sync_so_far ();
+	c->buffer->message (c->font,
+			    "deleting glyph at %d (multiple substitution)",
+			    c->buffer->idx);
+      }
+
       c->buffer->delete_glyph ();
+
+      if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+      {
+	c->buffer->sync_so_far ();
+	c->buffer->message (c->font,
+			    "deleted glyph at %d (multiple substitution)",
+			    c->buffer->idx);
+      }
+
       return_trace (true);
     }
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->sync_so_far ();
+      c->buffer->message (c->font,
+			  "multiplying glyph at %d",
+			  c->buffer->idx);
+    }
+
     unsigned int klass = _hb_glyph_info_is_ligature (&c->buffer->cur()) ?
                          HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH : 0;
     unsigned lig_id = _hb_glyph_info_get_lig_id (&c->buffer->cur());
@@ -65,6 +106,26 @@
     }
     c->buffer->skip_glyph ();
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->sync_so_far ();
+
+      char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0};
+      char *p = buf;
+
+      for (unsigned i = c->buffer->idx - count; i < c->buffer->idx; i++)
+      {
+	if (buf < p)
+	  *p++ = ',';
+	sprintf (p, "%u", i);
+	p += strlen(p);
+      }
+
+      c->buffer->message (c->font,
+			  "multiplied glyphs at %s",
+			  buf);
+    }
+
     return_trace (true);
   }
 
diff --git a/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/OT/Layout/GSUB/SingleSubstFormat1.hh
index dd44595..d46bba2 100644
--- a/src/OT/Layout/GSUB/SingleSubstFormat1.hh
+++ b/src/OT/Layout/GSUB/SingleSubstFormat1.hh
@@ -82,8 +82,23 @@
 
     glyph_id = (glyph_id + d) & mask;
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->sync_so_far ();
+      c->buffer->message (c->font,
+			  "replacing glyph at %d (single substitution)",
+			  c->buffer->idx);
+    }
+
     c->replace_glyph (glyph_id);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "replaced glyph at %d (single substitution)",
+			  c->buffer->idx - 1);
+    }
+
     return_trace (true);
   }
 
diff --git a/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/src/OT/Layout/GSUB/SingleSubstFormat2.hh
index 386419a..fb1e90d 100644
--- a/src/OT/Layout/GSUB/SingleSubstFormat2.hh
+++ b/src/OT/Layout/GSUB/SingleSubstFormat2.hh
@@ -68,8 +68,23 @@
 
     if (unlikely (index >= substitute.len)) return_trace (false);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->sync_so_far ();
+      c->buffer->message (c->font,
+			  "replacing glyph at %d (single substitution)",
+			  c->buffer->idx);
+    }
+
     c->replace_glyph (substitute[index]);
 
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "replaced glyph at %d (single substitution)",
+			  c->buffer->idx - 1);
+    }
+
     return_trace (true);
   }
 
diff --git a/src/hb-debug.hh b/src/hb-debug.hh
index 3ac7440..905a46a 100644
--- a/src/hb-debug.hh
+++ b/src/hb-debug.hh
@@ -460,4 +460,9 @@
 #endif
 
 
+#ifndef HB_BUFFER_MESSAGE_MORE
+#define HB_BUFFER_MESSAGE_MORE (HB_DEBUG+1)
+#endif
+
+
 #endif /* HB_DEBUG_HH */