diff --git a/util/hb-ot-shape-closure.cc b/util/hb-ot-shape-closure.cc index 2a4fdcf99..6dce7a172 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 3758be0db..d459b8927 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 1a9739f1f..1dbaaff69 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 c404b8a3b..4cc8a862a 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 5a79cef80..849a046bd 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 d395b24a4..da14c617e 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 5d8ead7c3..666013ec1 100644 --- a/util/view-cairo.cc +++ b/util/view-cairo.cc @@ -26,37 +26,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 eec90ea80..31c7ade28 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);