Adjust mark advance-width zeroing logic for Myanmar
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 12 Feb 2013 14:44:57 +0000 (09:44 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 12 Feb 2013 14:44:57 +0000 (09:44 -0500)
Before, we were zeroing advance width of attached marks for
non-Indic scripts, and not doing it for Indic.

We have now three different behaviors, which seem to better
reflect what Uniscribe is doing:

  - For Indic, no explicit zeroing happens whatsoever, which
    is the same as before,

  - For Myanmar, zero advance width of glyphs marked as marks
    *in GDEF*, and do that *before* applying GPOS.  This seems
    to be what the new Win8 Myanmar shaper does,

  - For everything else, zero advance width of glyphs that are
    from General_Category=Mn Unicode characters, and do so
    before applying GPOS.  This seems to be what Uniscribe does
    for Latin at least.

With these changes, positioning of all tests matches for Myanmar,
except for the glitch in Uniscribe not applying 'mark'.  See preivous
commit.

src/hb-ot-layout-gpos-table.hh
src/hb-ot-layout-private.hh
src/hb-ot-layout.cc
src/hb-ot-shape-complex-arabic.cc
src/hb-ot-shape-complex-default.cc
src/hb-ot-shape-complex-indic.cc
src/hb-ot-shape-complex-myanmar.cc
src/hb-ot-shape-complex-private.hh
src/hb-ot-shape-complex-thai.cc
src/hb-ot-shape.cc

index 148a57c..59d818e 100644 (file)
@@ -1528,7 +1528,7 @@ struct GPOS : GSUBGPOS
   { return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
 
   static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
-  static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attahced_marks);
+  static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer);
 
   inline bool sanitize (hb_sanitize_context_t *c) {
     TRACE_SANITIZE (this);
@@ -1561,17 +1561,13 @@ fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction
 }
 
 static void
-fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, hb_bool_t zero_width_attached_marks)
+fix_mark_attachment (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
 {
   if (likely (!(pos[i].attach_lookback())))
     return;
 
   unsigned int j = i - pos[i].attach_lookback();
 
-  if (zero_width_attached_marks) {
-    pos[i].x_advance = 0;
-    pos[i].y_advance = 0;
-  }
   pos[i].x_offset += pos[j].x_offset;
   pos[i].y_offset += pos[j].y_offset;
 
@@ -1598,7 +1594,7 @@ GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
 }
 
 void
-GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks)
+GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
 {
   unsigned int len;
   hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
@@ -1610,7 +1606,7 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t
 
   /* Handle attachments */
   for (unsigned int i = 0; i < len; i++)
-    fix_mark_attachment (pos, i, direction, zero_width_attached_marks);
+    fix_mark_attachment (pos, i, direction);
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
   HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
index 49093de..b550fa8 100644 (file)
@@ -176,8 +176,7 @@ hb_ot_layout_position_lookup (hb_font_t    *font,
 /* Should be called after all the position_lookup's are done */
 HB_INTERNAL void
 hb_ot_layout_position_finish (hb_font_t    *font,
-                             hb_buffer_t  *buffer,
-                             hb_bool_t     zero_width_attached_marks);
+                             hb_buffer_t  *buffer);
 
 
 
index 3ff6fc8..291ff9a 100644 (file)
@@ -727,9 +727,9 @@ hb_ot_layout_position_lookup (hb_font_t    *font,
 }
 
 void
-hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attached_marks)
+hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer)
 {
-  OT::GPOS::position_finish (font, buffer, zero_width_attached_marks);
+  OT::GPOS::position_finish (font, buffer);
 }
 
 hb_bool_t
index 35356fe..3374cfc 100644 (file)
@@ -354,6 +354,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
   NULL, /* decompose */
   NULL, /* compose */
   setup_masks_arabic,
-  true, /* zero_width_attached_marks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE,
   true, /* fallback_position */
 };
index 5340293..d406f8c 100644 (file)
@@ -221,6 +221,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
   NULL, /* decompose */
   compose_default,
   NULL, /* setup_masks */
-  true, /* zero_width_attached_marks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE,
   true, /* fallback_position */
 };
index 573443f..9c704fb 100644 (file)
@@ -1404,6 +1404,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
   decompose_indic,
   compose_indic,
   setup_masks_indic,
-  false, /* zero_width_attached_marks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
   false, /* fallback_position */
 };
index 7cae6ff..5adcdfc 100644 (file)
@@ -635,6 +635,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
   NULL, /* decompose */
   NULL, /* compose */
   setup_masks_myanmar,
-  false, /* zero_width_attached_marks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF,
   false, /* fallback_position */
 };
index a0d4e4b..6b562fc 100644 (file)
 #define complex_var_u8_1()     var2.u8[3]
 
 
+enum hb_ot_shape_zero_width_marks_type_t {
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE,
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF
+};
+
 
 /* Master OT shaper list */
 #define HB_COMPLEX_SHAPERS_IMPLEMENT_SHAPERS \
@@ -131,7 +137,8 @@ struct hb_ot_complex_shaper_t
                       hb_buffer_t              *buffer,
                       hb_font_t                *font);
 
-  bool zero_width_attached_marks;
+  hb_ot_shape_zero_width_marks_type_t zero_width_marks;
+
   bool fallback_position;
 };
 
index 24d476a..5cbb6e3 100644 (file)
@@ -373,6 +373,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
   NULL, /* decompose */
   NULL, /* compose */
   NULL, /* setup_masks */
-  true, /* zero_width_attached_marks */
+  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE,
   false,/* fallback_position */
 };
index 96461d7..ce13139 100644 (file)
@@ -405,7 +405,8 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
   hb_ot_layout_position_start (c->font, c->buffer);
 
   unsigned int count = c->buffer->len;
-  for (unsigned int i = 0; i < count; i++) {
+  for (unsigned int i = 0; i < count; i++)
+  {
     c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
                                              c->buffer->props.direction,
                                              &c->buffer->pos[i].x_advance,
@@ -414,6 +415,32 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
                                                  c->buffer->props.direction,
                                                  &c->buffer->pos[i].x_offset,
                                                  &c->buffer->pos[i].y_offset);
+
+  }
+
+  switch (c->plan->shaper->zero_width_marks)
+  {
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE:
+      for (unsigned int i = 0; i < count; i++)
+       if (_hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
+       {
+         c->buffer->pos[i].x_advance = 0;
+         c->buffer->pos[i].y_advance = 0;
+       }
+      break;
+
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF:
+      for (unsigned int i = 0; i < count; i++)
+       if ((c->buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
+       {
+         c->buffer->pos[i].x_advance = 0;
+         c->buffer->pos[i].y_advance = 0;
+       }
+      break;
+
+    default:
+    case HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE:
+      break;
   }
 }
 
@@ -446,7 +473,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
     ret = true;
   }
 
-  hb_ot_layout_position_finish (c->font, c->buffer, c->plan->shaper->zero_width_attached_marks);
+  hb_ot_layout_position_finish (c->font, c->buffer);
 
   return ret;
 }