[HarfBuzz] harfbuzz: Branch 'master' - 2 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Thu Sep 6 14:26:20 PDT 2012


 src/hb-ot-shape-fallback.cc |   54 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 45 insertions(+), 9 deletions(-)

New commits:
commit f67917161bbe317a33d6407fbc62ebffcafe7154
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Sep 6 17:22:31 2012 -0400

    [OT] Do per-ligature-component fallback mark positioning
    
    With this in place, you can remove GDEF/GSUB/GPOS tables from Arabic
    fonts and still get per-component marks positioned on
    oh-yeah-fallback-formed LAM-ALEF ligatures with marks in between the LAM
    and ALEF.
    
    Now *that*'s pretty cool, if a bit anachronistic...

diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index a532e20..eb7777e 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -287,6 +287,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
 		      unsigned int base,
 		      unsigned int end)
 {
+  hb_direction_t horiz_dir = HB_DIRECTION_INVALID;
   hb_glyph_extents_t base_extents;
   if (!font->get_glyph_extents (buffer->info[base].codepoint,
 				&base_extents))
@@ -298,22 +299,53 @@ position_around_base (const hb_ot_shape_plan_t *plan,
   base_extents.x_bearing += buffer->pos[base].x_offset;
   base_extents.y_bearing += buffer->pos[base].y_offset;
 
-  /* XXX Handle ligature component positioning... */
-  HB_UNUSED bool is_ligature = is_a_ligature (buffer->info[base]);
+  unsigned int lig_id = get_lig_id (buffer->info[base]);
+  unsigned int num_lig_components = get_lig_num_comps (buffer->info[base]);
 
   hb_position_t x_offset = 0, y_offset = 0;
   if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
     x_offset -= buffer->pos[base].x_advance;
     y_offset -= buffer->pos[base].y_advance;
   }
+
+  hb_glyph_extents_t component_extents = base_extents;
+  unsigned int last_lig_component = (unsigned int) -1;
   unsigned int last_combining_class = 255;
   hb_glyph_extents_t cluster_extents;
   for (unsigned int i = base + 1; i < end; i++)
     if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]))
     {
+      if (num_lig_components > 1) {
+	unsigned int this_lig_id = get_lig_id (buffer->info[i]);
+	unsigned int this_lig_component = get_lig_comp (buffer->info[i]) - 1;
+	/* Conditions for attaching to the last component. */
+	if (!lig_id || lig_id != this_lig_id || this_lig_component >= num_lig_components)
+	  this_lig_component = num_lig_components - 1;
+	if (last_lig_component != this_lig_component)
+	{
+	  last_lig_component = this_lig_component;
+	  last_combining_class = 255;
+	  component_extents = base_extents;
+	  if (unlikely (horiz_dir == HB_DIRECTION_INVALID)) {
+	    if (HB_DIRECTION_IS_HORIZONTAL (plan->props.direction))
+	      horiz_dir = plan->props.direction;
+	    else
+	      horiz_dir = hb_script_get_horizontal_direction (plan->props.script);
+	  }
+	  if (horiz_dir == HB_DIRECTION_LTR)
+	    component_extents.x_bearing += (this_lig_component * component_extents.width) / num_lig_components;
+	  else
+	    component_extents.x_bearing += ((num_lig_components - 1 - this_lig_component) * component_extents.width) / num_lig_components;
+	  component_extents.width /= num_lig_components;
+	}
+      }
+
       unsigned int this_combining_class = _hb_glyph_info_get_modified_combining_class (&buffer->info[i]);
-      if (this_combining_class != last_combining_class)
-        cluster_extents = base_extents;
+      if (last_combining_class != this_combining_class)
+      {
+	last_combining_class = this_combining_class;
+        cluster_extents = component_extents;
+      }
 
       position_mark (plan, font, buffer, cluster_extents, i, this_combining_class);
 
@@ -322,7 +354,6 @@ position_around_base (const hb_ot_shape_plan_t *plan,
       buffer->pos[i].x_offset += x_offset;
       buffer->pos[i].y_offset += y_offset;
 
-      last_combining_class = this_combining_class;
     } else {
       if (HB_DIRECTION_IS_FORWARD (buffer->props.direction)) {
 	x_offset -= buffer->pos[i].x_advance;
@@ -332,8 +363,6 @@ position_around_base (const hb_ot_shape_plan_t *plan,
 	y_offset += buffer->pos[i].y_advance;
       }
     }
-
-
 }
 
 static inline void
commit 525c6855783a018d52867b9ece2ee90868ff1f91
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Sep 6 16:02:07 2012 -0400

    [OT] Make fallback mark positioning more robust
    
    ...with clusters spanning multiple base characters.

diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc
index e8b41f7..a532e20 100644
--- a/src/hb-ot-shape-fallback.cc
+++ b/src/hb-ot-shape-fallback.cc
@@ -350,8 +350,15 @@ position_cluster (const hb_ot_shape_plan_t *plan,
   for (unsigned int i = start; i < end; i++)
     if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
     {
-      position_around_base (plan, font, buffer, i, end);
-      break;
+      /* Find mark glyphs */
+      unsigned int j;
+      for (j = i + 1; j < end; j++)
+	if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[j])))
+	  break;
+
+      position_around_base (plan, font, buffer, i, j);
+
+      i = j - 1;
     }
 }
 



More information about the HarfBuzz mailing list