[HarfBuzz] Placement of arabic diacritics over 3 component ligature is incorrent

2012-07-28 Thread Khaled Hosny
Going through old Pango bugs to see if there is anything HarfBuzz
related, I found this one which is still reproducible with HarfBuzz
(marks over 2nd component of لله are placed over the 3rd one, marks over
the other two components are placed correctly):

https://bugzilla.gnome.org/show_bug.cgi?id=437633

Regards,
 Khaled
___
HarfBuzz mailing list
HarfBuzz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/harfbuzz


[HarfBuzz] harfbuzz-ng: Branch 'master'

2012-07-28 Thread Behdad Esfahbod
 src/hb-ot-layout-gpos-table.hh 
  |   27 +++---
 src/hb-ot-layout-private.hh
  |5 +
 test/shaping/texts/in-tree/shaper-indic/MANIFEST   
  |1 
 test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/MANIFEST 
  |1 
 test/shaping/texts/in-tree/shaper-indic/south-asian/MANIFEST   
  |1 
 test/shaping/texts/in-tree/shaper-indic/south-asian/script-tibetan/MANIFEST
  |1 
 
test/shaping/texts/in-tree/shaper-indic/south-asian/script-tibetan/misc/MANIFEST
 |1 
 
test/shaping/texts/in-tree/shaper-indic/south-asian/script-tibetan/misc/misc.txt
 |1 
 8 files changed, 29 insertions(+), 9 deletions(-)

New commits:
commit 5d874d566fe5d2cc4cfaf02c79b663d8a626ca1e
Author: Behdad Esfahbod 
Date:   Sat Jul 28 21:05:25 2012 -0400

[GPOS] Fix mark-to-mark positioning when one of the marks is a ligature

This commit: a3313e54008167e415b72c780ca7b9cda958d07e broke MarkMarkPos
when one of the marks itself is a ligature.  That regressed 26 Tibetan
tests (up from zero!).  Fix that.  Tibetan back to zero.

diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 3b1ae2a..83252c1 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1263,14 +1263,27 @@ struct MarkMarkPosFormat1
 
 unsigned int j = skippy_iter.idx;
 
-/* Two marks match only if they belong to the same base, or same component
- * of the same ligature.  That is, the lig_id numbers must match, and
- * if those are non-zero, the lig_comp number should also match. */
-if ((get_lig_id (c->buffer->info[j]) != get_lig_id (c->buffer->cur())) ||
-   (get_lig_id (c->buffer->info[j]) > 0 &&
-get_lig_comp (c->buffer->info[j]) != get_lig_comp (c->buffer->cur(
-  return TRACE_RETURN (false);
+unsigned int id1 = get_lig_id (c->buffer->cur());
+unsigned int id2 = get_lig_id (c->buffer->info[j]);
+unsigned int comp1 = get_lig_comp (c->buffer->cur());
+unsigned int comp2 = get_lig_comp (c->buffer->info[j]);
+
+if (likely (id1 == id2)) {
+  if (id1 == 0) /* Marks belonging to the same base. */
+   goto good;
+  else if (comp1 == comp2) /* Marks belonging to the same ligature 
component. */
+goto good;
+} else {
+  /* If ligature ids don't match, it may be the case that one of the marks
+   * itself is a ligature.  In which case match. */
+  if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
+   goto good;
+}
+
+/* Didn't match. */
+return TRACE_RETURN (false);
 
+good:
 unsigned int mark2_index = (this+mark2Coverage) 
(c->buffer->info[j].codepoint);
 if (mark2_index == NOT_COVERED) return TRACE_RETURN (false);
 
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 294c359..1c108e0 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -73,7 +73,8 @@ _hb_ot_layout_skip_mark (hb_face_t*face,
  *
  * When a ligature is formed:
  *
- *   - The ligature glyph and any marks in between all get a unique lig_id,
+ *   - The ligature glyph and any marks in between all the same newly allocated
+ * lig_id,
  *   - The ligature glyph will get lig_comp = 0
  *   - The marks get lig_comp > 0, reflecting which component of the ligature
  * they were applied to.
@@ -84,7 +85,7 @@ _hb_ot_layout_skip_mark (hb_face_t*face,
  *
  *   - All resulting glyphs will have lig_id = 0,
  *   - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
- *   - This is used in GPOS to attack marks to the first component of a
+ *   - This is used in GPOS to attach marks to the first component of a
  * multiple substitution in MarkBasePos.
  *
  * The numbers are also used in GPOS to do mark-to-mark positioning only
diff --git a/test/shaping/texts/in-tree/shaper-indic/MANIFEST 
b/test/shaping/texts/in-tree/shaper-indic/MANIFEST
index 3f2011f..5e0651b 100644
--- a/test/shaping/texts/in-tree/shaper-indic/MANIFEST
+++ b/test/shaping/texts/in-tree/shaper-indic/MANIFEST
@@ -1,2 +1,3 @@
 indic
+south-asian
 south-east-asian
diff --git 
a/test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/MANIFEST 
b/test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/MANIFEST
index 3c2a4fb..7eff9e1 100644
--- a/test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/MANIFEST
+++ b/test/shaping/texts/in-tree/shaper-indic/indic/script-sinhala/misc/MANIFEST
@@ -1,2 +1,3 @@
+extensive.txt
 misc.txt
 reph.txt
diff --git a/test/shaping/texts/in-tree/shaper-indic/south-asian/MANIFEST 
b/test/shaping/texts/in-tree/shaper-indic/south-asian/MANIFEST
new file mode 100644
index 000..3ed6c85
--- /dev/null
+++ b/test/shaping/texts/in-tree/shaper-indic/south-asian/MANIFEST
@@ -0,0 +1 @@
+script-tibetan
diff --git 
a/test/shaping/texts/in-tree/shaper-i

[HarfBuzz] And more optimizations

2012-07-28 Thread Behdad Esfahbod
I pushed another set of optimizations.  This gives me over 20% improvement on
Indic.

To recap, with my Indic wordlist test case (which is, admittedly, not
representative of most usecases), since last week, HarfBuzz has become twice
faster.  Before it was taking 45 seconds, now it does 23 seconds.  That's
faster than the hb-old backend (25s).

behdad
___
HarfBuzz mailing list
HarfBuzz@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/harfbuzz


[HarfBuzz] harfbuzz-ng: Branch 'master' - 6 commits

2012-07-28 Thread Behdad Esfahbod
 src/hb-ot-layout-common-private.hh   |8 -
 src/hb-ot-layout-gpos-table.hh   |  179 +
 src/hb-ot-layout-gsub-table.hh   |  188 ++-
 src/hb-ot-layout-gsubgpos-private.hh |   52 ++---
 4 files changed, 313 insertions(+), 114 deletions(-)

New commits:
commit 338fe662b50f9309bf0050dd99becb644874195b
Author: Behdad Esfahbod 
Date:   Sat Jul 28 18:53:01 2012 -0400

[GSUB] Minor

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index d95b691..03244b5 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1106,22 +1106,6 @@ struct SubstLookup : Lookup
 if (!_hb_ot_layout_check_glyph_property (c->face, &c->buffer->cur(), 
c->lookup_props, &c->property))
   return false;
 
-/* TODO: For the most common case this can move out of the main
- * loop, but it's not a big deal for now. */
-if (unlikely (lookup_type == SubstLookupSubTable::Extension))
-{
-  /* The spec says all subtables should have the same type.
-   * This is specially important if one has a reverse type!
-   *
-   * This is rather slow to do this here for every glyph,
-   * but it's easiest, and who uses extension lookups anyway?!*/
-  unsigned int type = get_subtable(0).u.extension.get_type ();
-  unsigned int count = get_subtable_count ();
-  for (unsigned int i = 1; i < count; i++)
-if (get_subtable(i).u.extension.get_type () != type)
- return false;
-}
-
 unsigned int count = get_subtable_count ();
 for (unsigned int i = 0; i < count; i++)
   if (get_subtable (i).apply (c, lookup_type))
@@ -1191,7 +1175,22 @@ struct SubstLookup : Lookup
 TRACE_SANITIZE ();
 if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
 OffsetArrayOf &list = 
CastR > (subTable);
-return TRACE_RETURN (list.sanitize (c, this, get_type ()));
+if (unlikely (!list.sanitize (c, this, get_type ( return TRACE_RETURN 
(false);
+
+if (unlikely (get_type () == SubstLookupSubTable::Extension))
+{
+  /* The spec says all subtables of an Extension lookup should
+   * have the same type.  This is specially important if one has
+   * a reverse type!
+   *
+   * We just check that they are all either forward, or reverse. */
+  unsigned int type = get_subtable (0).u.extension.get_type ();
+  unsigned int count = get_subtable_count ();
+  for (unsigned int i = 1; i < count; i++)
+if (get_subtable (i).u.extension.get_type () != type)
+ return TRACE_RETURN (false);
+}
+return TRACE_RETURN (true);
   }
 };
 
commit e6f7479fe34fb4a7cada61d84c2ed70d1fd565c8
Author: Behdad Esfahbod 
Date:   Sat Jul 28 18:34:58 2012 -0400

[GSUB] Simplify would-apply

diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 2cbab32..d95b691 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -55,11 +55,6 @@ struct SingleSubstFormat1
 return this+coverage;
   }
 
-  inline bool would_apply (hb_would_apply_context_t *c) const
-  {
-return c->len == 1 && (this+coverage) (c->first) != NOT_COVERED;
-  }
-
   inline bool apply (hb_apply_context_t *c) const
   {
 TRACE_APPLY ();
@@ -112,11 +107,6 @@ struct SingleSubstFormat2
 return this+coverage;
   }
 
-  inline bool would_apply (hb_would_apply_context_t *c) const
-  {
-return c->len == 1 && (this+coverage) (c->first) != NOT_COVERED;
-  }
-
   inline bool apply (hb_apply_context_t *c) const
   {
 TRACE_APPLY ();
@@ -174,15 +164,6 @@ struct SingleSubst
 }
   }
 
-  inline bool would_apply (hb_would_apply_context_t *c) const
-  {
-switch (u.format) {
-case 1: return u.format1.would_apply (c);
-case 2: return u.format2.would_apply (c);
-default:return false;
-}
-  }
-
   inline bool apply (hb_apply_context_t *c) const
   {
 TRACE_APPLY ();
@@ -276,11 +257,6 @@ struct MultipleSubstFormat1
 return this+coverage;
   }
 
-  inline bool would_apply (hb_would_apply_context_t *c) const
-  {
-return c->len == 1 && (this+coverage) (c->first) != NOT_COVERED;
-  }
-
   inline bool apply (hb_apply_context_t *c) const
   {
 TRACE_APPLY ();
@@ -331,14 +307,6 @@ struct MultipleSubst
 }
   }
 
-  inline bool would_apply (hb_would_apply_context_t *c) const
-  {
-switch (u.format) {
-case 1: return u.format1.would_apply (c);
-default:return false;
-}
-  }
-
   inline bool apply (hb_apply_context_t *c) const
   {
 TRACE_APPLY ();
@@ -393,11 +361,6 @@ struct AlternateSubstFormat1
 return this+coverage;
   }
 
-  inline bool would_apply (hb_would_apply_context_t *c) const
-  {
-return c->len == 1 && (this+coverage) (c->first) != NOT_COVERED;
-  }
-
   inline bool apply (hb_apply_context_t *c) const
   {
 TRACE_APPLY ();
@@ -466,14 +429,6 @@ struct AlternateSubst
 }
   }
 
-  inline bool would_apply (hb_would