[HarfBuzz] harfbuzz-ng: Branch 'master'

Behdad Esfahbod behdad at kemper.freedesktop.org
Sat Jun 2 09:13:30 PDT 2012


 util/hb-ot-shape-closure.cc |    3 ++
 util/hb-shape.cc            |   36 ++++++++++++++++++++++++------
 util/main-font-text.hh      |    2 -
 util/options.cc             |   34 ++++++++++++++++++++++------
 util/options.hh             |   33 ++++++++++++++-------------
 util/shape-consumer.hh      |   17 +++++++++++---
 util/view-cairo.cc          |   47 ++++++---------------------------------
 util/view-cairo.hh          |   52 ++++++++++++++++++++++++++++++++++++++------
 8 files changed, 143 insertions(+), 81 deletions(-)

New commits:
commit 5db0683a822f70c914468430cda6487cee740ae3
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Jun 2 12:13:08 2012 -0400

    [util] Make hb-shape continue shaping other lines if shapers failed

diff --git a/util/hb-ot-shape-closure.cc b/util/hb-ot-shape-closure.cc
index 2a4fdcf..6dce7a1 100644
--- a/util/hb-ot-shape-closure.cc
+++ b/util/hb-ot-shape-closure.cc
@@ -57,6 +57,7 @@ struct shape_closure_consumer_t : option_group_t
   {
     glyphs = hb_set_create ();
     font = hb_font_reference (font_opts->get_font ());
+    failed = false;
   }
   void consume_line (hb_buffer_t  *buffer,
 		     const char   *text,
@@ -93,6 +94,8 @@ struct shape_closure_consumer_t : option_group_t
     glyphs = NULL;
   }
 
+  bool failed;
+
   protected:
   shape_options_t shaper;
   hb_bool_t show_glyph_names;
diff --git a/util/hb-shape.cc b/util/hb-shape.cc
index 3758be0..d459b89 100644
--- a/util/hb-shape.cc
+++ b/util/hb-shape.cc
@@ -28,28 +28,49 @@
 #include "main-font-text.hh"
 #include "shape-consumer.hh"
 
-struct output_buffer_t : output_options_t
+struct output_buffer_t
 {
   output_buffer_t (option_parser_t *parser)
-		  : output_options_t (parser),
+		  : options (parser),
 		    format (parser) {}
 
   void init (const font_options_t *font_opts)
   {
-    get_file_handle ();
+    options.get_file_handle ();
     gs = g_string_new (NULL);
     line_no = 0;
     font = hb_font_reference (font_opts->get_font ());
   }
-  void consume_line (hb_buffer_t  *buffer,
+  void new_line (void)
+  {
+    line_no++;
+  }
+  void consume_text (hb_buffer_t  *buffer,
 		     const char   *text,
 		     unsigned int  text_len,
 		     hb_bool_t     utf8_clusters)
   {
-    line_no++;
     g_string_set_size (gs, 0);
-    format.serialize_line (buffer, line_no, text, text_len, font, utf8_clusters, gs);
-    fprintf (fp, "%s", gs->str);
+    format.serialize_buffer_of_text (buffer, line_no, text, text_len, font, utf8_clusters, gs);
+    fprintf (options.fp, "%s", gs->str);
+  }
+  void shape_failed (hb_buffer_t  *buffer,
+		     const char   *text,
+		     unsigned int  text_len,
+		     hb_bool_t     utf8_clusters)
+  {
+    g_string_set_size (gs, 0);
+    format.serialize_message (line_no, "msg: all shapers failed", gs);
+    fprintf (options.fp, "%s", gs->str);
+  }
+  void consume_glyphs (hb_buffer_t  *buffer,
+		       const char   *text,
+		       unsigned int  text_len,
+		       hb_bool_t     utf8_clusters)
+  {
+    g_string_set_size (gs, 0);
+    format.serialize_buffer_of_glyphs (buffer, line_no, text, text_len, font, utf8_clusters, gs);
+    fprintf (options.fp, "%s", gs->str);
   }
   void finish (const font_options_t *font_opts)
   {
@@ -60,6 +81,7 @@ struct output_buffer_t : output_options_t
   }
 
   protected:
+  output_options_t options;
   format_options_t format;
 
   GString *gs;
diff --git a/util/main-font-text.hh b/util/main-font-text.hh
index 1a9739f..1dbaaff 100644
--- a/util/main-font-text.hh
+++ b/util/main-font-text.hh
@@ -66,7 +66,7 @@ struct main_font_text_t
 
     consumer.finish (&font_opts);
 
-    return 0;
+    return consumer.failed ? 1 : 0;
   }
 
   protected:
diff --git a/util/options.cc b/util/options.cc
index c404b8a..4cc8a86 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -772,13 +772,13 @@ format_options_t::serialize_line_no (unsigned int  line_no,
     g_string_append_printf (gs, "%d: ", line_no);
 }
 void
-format_options_t::serialize_line (hb_buffer_t  *buffer,
-				  unsigned int  line_no,
-				  const char   *text,
-				  unsigned int  text_len,
-				  hb_font_t    *font,
-				  hb_bool_t     utf8_clusters,
-				  GString      *gs)
+format_options_t::serialize_buffer_of_text (hb_buffer_t  *buffer,
+					    unsigned int  line_no,
+					    const char   *text,
+					    unsigned int  text_len,
+					    hb_font_t    *font,
+					    hb_bool_t     utf8_clusters,
+					    GString      *gs)
 {
   if (show_text) {
     serialize_line_no (line_no, gs);
@@ -795,7 +795,25 @@ format_options_t::serialize_line (hb_buffer_t  *buffer,
     serialize_unicode (scratch, gs);
     g_string_append_c (gs, '\n');
   }
-
+}
+void
+format_options_t::serialize_message (unsigned int  line_no,
+				     const char   *msg,
+				     GString      *gs)
+{
+  serialize_line_no (line_no, gs);
+  g_string_append_printf (gs, "%s", msg);
+  g_string_append_c (gs, '\n');
+}
+void
+format_options_t::serialize_buffer_of_glyphs (hb_buffer_t  *buffer,
+					      unsigned int  line_no,
+					      const char   *text,
+					      unsigned int  text_len,
+					      hb_font_t    *font,
+					      hb_bool_t     utf8_clusters,
+					      GString      *gs)
+{
   serialize_line_no (line_no, gs);
   serialize_glyphs (buffer, font, utf8_clusters, gs);
   g_string_append_c (gs, '\n');
diff --git a/util/options.hh b/util/options.hh
index 5a79cef..849a046 100644
--- a/util/options.hh
+++ b/util/options.hh
@@ -300,18 +300,9 @@ struct output_options_t : option_group_t
 
   FILE *get_file_handle (void);
 
-  virtual void init (const font_options_t *font_opts) = 0;
-  virtual void consume_line (hb_buffer_t  *buffer,
-			     const char   *text,
-			     unsigned int  text_len,
-			     hb_bool_t     utf8_clusters) = 0;
-  virtual void finish (const font_options_t *font_opts) = 0;
-
   const char *output_file;
   const char *output_format;
 
-  protected:
-
   mutable FILE *fp;
 };
 
@@ -342,13 +333,23 @@ struct format_options_t : option_group_t
 			 GString      *gs);
   void serialize_line_no (unsigned int  line_no,
 			  GString      *gs);
-  void serialize_line (hb_buffer_t  *buffer,
-		       unsigned int  line_no,
-		       const char   *text,
-		       unsigned int  text_len,
-		       hb_font_t    *font,
-		       hb_bool_t     utf8_clusters,
-		       GString      *gs);
+  void serialize_buffer_of_text (hb_buffer_t  *buffer,
+				 unsigned int  line_no,
+				 const char   *text,
+				 unsigned int  text_len,
+				 hb_font_t    *font,
+				 hb_bool_t     utf8_clusters,
+				 GString      *gs);
+  void serialize_message (unsigned int  line_no,
+			  const char   *msg,
+			  GString      *gs);
+  void serialize_buffer_of_glyphs (hb_buffer_t  *buffer,
+				   unsigned int  line_no,
+				   const char   *text,
+				   unsigned int  text_len,
+				   hb_font_t    *font,
+				   hb_bool_t     utf8_clusters,
+				   GString      *gs);
 
 
   protected:
diff --git a/util/shape-consumer.hh b/util/shape-consumer.hh
index d395b24..da14c61 100644
--- a/util/shape-consumer.hh
+++ b/util/shape-consumer.hh
@@ -41,15 +41,23 @@ struct shape_consumer_t
   {
     font = hb_font_reference (font_opts->get_font ());
     output.init (font_opts);
+    failed = false;
   }
   void consume_line (hb_buffer_t  *buffer,
 		     const char   *text,
 		     unsigned int  text_len)
   {
-    if (!shaper.shape (text, text_len, font, buffer))
-      fail (FALSE, "All shapers failed");
+    output.new_line ();
+    output.consume_text (buffer, text, text_len, shaper.utf8_clusters);
 
-    output.consume_line (buffer, text, text_len, shaper.utf8_clusters);
+    if (!shaper.shape (text, text_len, font, buffer)) {
+      failed = true;
+      hb_buffer_set_length (buffer, 0);
+      output.shape_failed (buffer, text, text_len, shaper.utf8_clusters);
+      return;
+    }
+
+    output.consume_glyphs (buffer, text, text_len, shaper.utf8_clusters);
   }
   void finish (const font_options_t *font_opts)
   {
@@ -58,6 +66,9 @@ struct shape_consumer_t
     font = NULL;
   }
 
+  public:
+  bool failed;
+
   protected:
   shape_options_t shaper;
   output_t output;
diff --git a/util/view-cairo.cc b/util/view-cairo.cc
index 5d8ead7..666013e 100644
--- a/util/view-cairo.cc
+++ b/util/view-cairo.cc
@@ -27,37 +27,6 @@
 #include "view-cairo.hh"
 
 void
-view_cairo_t::init (const font_options_t *font_opts)
-{
-  lines = g_array_new (FALSE, FALSE, sizeof (helper_cairo_line_t));
-  scale = double (font_size) / hb_face_get_upem (hb_font_get_face (font_opts->get_font ()));
-}
-
-void
-view_cairo_t::consume_line (hb_buffer_t  *buffer,
-			    const char   *text,
-			    unsigned int  text_len,
-			    hb_bool_t     utf8_clusters)
-{
-  direction = hb_buffer_get_direction (buffer);
-  helper_cairo_line_t l;
-  helper_cairo_line_from_buffer (&l, buffer, text, text_len, scale, utf8_clusters);
-  g_array_append_val (lines, l);
-}
-
-void
-view_cairo_t::finish (const font_options_t *font_opts)
-{
-  render (font_opts);
-
-  for (unsigned int i = 0; i < lines->len; i++) {
-    helper_cairo_line_t &line = g_array_index (lines, helper_cairo_line_t, i);
-    line.finish ();
-  }
-  g_array_unref (lines);
-}
-
-void
 view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font,
 				double *w, double *h)
 {
@@ -66,7 +35,7 @@ view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font,
   cairo_scaled_font_extents (scaled_font, &font_extents);
 
   bool vertical = HB_DIRECTION_IS_VERTICAL (direction);
-  (vertical ? *w : *h) = (int) lines->len * (font_extents.height + line_space) - line_space;
+  (vertical ? *w : *h) = (int) lines->len * (font_extents.height + view_options.line_space) - view_options.line_space;
   (vertical ? *h : *w) = 0;
   for (unsigned int i = 0; i < lines->len; i++) {
     helper_cairo_line_t &line = g_array_index (lines, helper_cairo_line_t, i);
@@ -78,17 +47,17 @@ view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font,
       *w =  MAX (*w, x_advance);
   }
 
-  *w += margin.l + margin.r;
-  *h += margin.t + margin.b;
+  *w += view_options.margin.l + view_options.margin.r;
+  *h += view_options.margin.t + view_options.margin.b;
 }
 
 void
 view_cairo_t::render (const font_options_t *font_opts)
 {
-  cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts, font_size);
+  cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts, view_options.font_size);
   double w, h;
   get_surface_size (scaled_font, &w, &h);
-  cairo_t *cr = helper_cairo_create_context (w, h, this, this);
+  cairo_t *cr = helper_cairo_create_context (w, h, &view_options, &output_options);
   cairo_set_scaled_font (cr, scaled_font);
   cairo_scaled_font_destroy (scaled_font);
 
@@ -107,7 +76,7 @@ view_cairo_t::draw (cairo_t *cr)
   int h = vertical ? 0 : 1;
   cairo_font_extents_t font_extents;
   cairo_font_extents (cr, &font_extents);
-  cairo_translate (cr, margin.l, margin.t);
+  cairo_translate (cr, view_options.margin.l, view_options.margin.t);
   double descent;
   if (vertical)
     descent = font_extents.height * (lines->len + .5);
@@ -119,11 +88,11 @@ view_cairo_t::draw (cairo_t *cr)
     helper_cairo_line_t &l = g_array_index (lines, helper_cairo_line_t, i);
 
     if (i)
-      cairo_translate (cr, v * -line_space, h * line_space);
+      cairo_translate (cr, v * -view_options.line_space, h * view_options.line_space);
 
     cairo_translate (cr, v * -font_extents.height, h * font_extents.height);
 
-    if (annotate) {
+    if (view_options.annotate) {
       cairo_save (cr);
 
       /* Draw actual glyph origins */
diff --git a/util/view-cairo.hh b/util/view-cairo.hh
index eec90ea..31c7ade 100644
--- a/util/view-cairo.hh
+++ b/util/view-cairo.hh
@@ -31,24 +31,62 @@
 #define VIEW_CAIRO_HH
 
 
-struct view_cairo_t : output_options_t, view_options_t {
+struct view_cairo_t {
   view_cairo_t (option_parser_t *parser)
-	       : output_options_t (parser),
-	         view_options_t (parser) {}
+	       : output_options (parser),
+	         view_options (parser) {}
   ~view_cairo_t (void) {
     if (debug)
       cairo_debug_reset_static_data ();
   }
 
-  void init (const font_options_t *font_opts);
-  void consume_line (hb_buffer_t  *buffer,
+  void init (const font_options_t *font_opts)
+  {
+    lines = g_array_new (FALSE, FALSE, sizeof (helper_cairo_line_t));
+    scale = double (view_options.font_size) / hb_face_get_upem (hb_font_get_face (font_opts->get_font ()));
+  }
+  void new_line (void)
+  {
+  }
+  void consume_text (hb_buffer_t  *buffer,
+		     const char   *text,
+		     unsigned int  text_len,
+		     hb_bool_t     utf8_clusters)
+  {
+  }
+  void shape_failed (hb_buffer_t  *buffer,
 		     const char   *text,
 		     unsigned int  text_len,
-		     hb_bool_t     utf8_clusters);
-  void finish (const font_options_t *font_opts);
+		     hb_bool_t     utf8_clusters)
+  {
+    consume_glyphs (buffer, text, text_len, utf8_clusters);
+  }
+  void consume_glyphs (hb_buffer_t  *buffer,
+		       const char   *text,
+		       unsigned int  text_len,
+		       hb_bool_t     utf8_clusters)
+  {
+    direction = hb_buffer_get_direction (buffer);
+    helper_cairo_line_t l;
+    helper_cairo_line_from_buffer (&l, buffer, text, text_len, scale, utf8_clusters);
+    g_array_append_val (lines, l);
+  }
+  void finish (const font_options_t *font_opts)
+  {
+    render (font_opts);
+
+    for (unsigned int i = 0; i < lines->len; i++) {
+      helper_cairo_line_t &line = g_array_index (lines, helper_cairo_line_t, i);
+      line.finish ();
+    }
+    g_array_unref (lines);
+  }
 
   protected:
 
+  output_options_t output_options;
+  view_options_t view_options;
+
   void render (const font_options_t *font_opts);
   void get_surface_size (cairo_scaled_font_t *scaled_font, double *w, double *h);
   void draw (cairo_t *cr);



More information about the HarfBuzz mailing list