Thanks Jonathan.  Can you test my alternate approach?  Attached.

On 13-09-27 11:22 AM, Jonathan Kew wrote:
> Hi Behdad,
> 
> With the change in variation selector handling, stray (unsupported) VS codes
> are no longer consumed by the get_glyph callback; they remain in the buffer
> and are individually mapped to glyphs. That's all very well; but in most cases
> they'll just map to .notdef.
> 
> Eventually, hb_ot_hide_default_ignorables() will run across these .notdef
> glyphs and replace them with zero-width space glyphs. All's good...
> 
> ...except in the (unlikely) case where the font does not actually support the
> <space> character. This will be almost vanishingly rare, of course - but
> unfortunately it happens with the "MarkA" font that's used for a variety of
> rendering tests.
> 
> This prompted me to look into patching hb_ot_hide_default_ignorables() so that
> it will work even if there's no <space> in the font. ISTM we can fix this by
> simply deleting the ignorable altogether in this case. It'll be a bit less
> performant than the current replace-with-zero-width-space implementation,
> because it requires shifting all the following glyphs up in the buffer, so
> I've retained the existing implementation for the (usual) case where <space>
> is available.
> 
> Suggested patch is attached.
> 
> JK

-- 
behdad
http://behdad.org/
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 15f4461..d6abafc 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -533,22 +533,42 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
   if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
     return;
 
-  hb_codepoint_t space = 0;
+  hb_codepoint_t space;
+  enum {
+    SPACE_DONT_KNOW,
+    SPACE_AVAILABLE,
+    SPACE_UNAVAILABLE
+  } space_status = SPACE_DONT_KNOW;
 
   unsigned int count = c->buffer->len;
+  hb_glyph_info_t *info = c->buffer->info;
+  hb_glyph_position_t *pos = c->buffer->pos;
+  unsigned int j = 0;
   for (unsigned int i = 0; i < count; i++)
-    if (unlikely (!is_a_ligature (c->buffer->info[i]) &&
-		  _hb_glyph_info_is_default_ignorable (&c->buffer->info[i])))
+  {
+    if (unlikely (!is_a_ligature (info[i]) &&
+		  _hb_glyph_info_is_default_ignorable (&info[i])))
     {
-      if (!space) {
-        /* We assume that the space glyph is not gid0. */
-        if (unlikely (!c->font->get_glyph (' ', 0, &space)) || !space)
-	return; /* No point! */
+      if (space_status == SPACE_DONT_KNOW)
+	space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : SPACE_UNAVAILABLE;
+
+      if (space_status == SPACE_AVAILABLE)
+      {
+	info[i].codepoint = space;
+	pos[i].x_advance = 0;
+	pos[i].y_advance = 0;
       }
-      c->buffer->info[i].codepoint = space;
-      c->buffer->pos[i].x_advance = 0;
-      c->buffer->pos[i].y_advance = 0;
+      else
+	continue; /* Delete it. */
+    }
+    j++;
+    if (j != i)
+    {
+      info[j] = info[i];
+      pos[j] = pos[i];
     }
+  }
+  c->buffer->len = j;
 }
 
 
_______________________________________________
HarfBuzz mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/harfbuzz

Reply via email to