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

This commit is contained in:
Behdad Esfahbod 2012-06-02 12:13:08 -04:00
parent 96a9ef0c9f
commit 5db0683a82
8 changed files with 143 additions and 81 deletions

View File

@ -57,6 +57,7 @@ struct shape_closure_consumer_t : option_group_t
{ {
glyphs = hb_set_create (); glyphs = hb_set_create ();
font = hb_font_reference (font_opts->get_font ()); font = hb_font_reference (font_opts->get_font ());
failed = false;
} }
void consume_line (hb_buffer_t *buffer, void consume_line (hb_buffer_t *buffer,
const char *text, const char *text,
@ -93,6 +94,8 @@ struct shape_closure_consumer_t : option_group_t
glyphs = NULL; glyphs = NULL;
} }
bool failed;
protected: protected:
shape_options_t shaper; shape_options_t shaper;
hb_bool_t show_glyph_names; hb_bool_t show_glyph_names;

View File

@ -28,28 +28,49 @@
#include "main-font-text.hh" #include "main-font-text.hh"
#include "shape-consumer.hh" #include "shape-consumer.hh"
struct output_buffer_t : output_options_t struct output_buffer_t
{ {
output_buffer_t (option_parser_t *parser) output_buffer_t (option_parser_t *parser)
: output_options_t (parser), : options (parser),
format (parser) {} format (parser) {}
void init (const font_options_t *font_opts) void init (const font_options_t *font_opts)
{ {
get_file_handle (); options.get_file_handle ();
gs = g_string_new (NULL); gs = g_string_new (NULL);
line_no = 0; line_no = 0;
font = hb_font_reference (font_opts->get_font ()); 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, const char *text,
unsigned int text_len, unsigned int text_len,
hb_bool_t utf8_clusters) hb_bool_t utf8_clusters)
{ {
line_no++;
g_string_set_size (gs, 0); g_string_set_size (gs, 0);
format.serialize_line (buffer, line_no, text, text_len, font, utf8_clusters, gs); format.serialize_buffer_of_text (buffer, line_no, text, text_len, font, utf8_clusters, gs);
fprintf (fp, "%s", gs->str); 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) void finish (const font_options_t *font_opts)
{ {
@ -60,6 +81,7 @@ struct output_buffer_t : output_options_t
} }
protected: protected:
output_options_t options;
format_options_t format; format_options_t format;
GString *gs; GString *gs;

View File

@ -66,7 +66,7 @@ struct main_font_text_t
consumer.finish (&font_opts); consumer.finish (&font_opts);
return 0; return consumer.failed ? 1 : 0;
} }
protected: protected:

View File

@ -772,13 +772,13 @@ format_options_t::serialize_line_no (unsigned int line_no,
g_string_append_printf (gs, "%d: ", line_no); g_string_append_printf (gs, "%d: ", line_no);
} }
void void
format_options_t::serialize_line (hb_buffer_t *buffer, format_options_t::serialize_buffer_of_text (hb_buffer_t *buffer,
unsigned int line_no, unsigned int line_no,
const char *text, const char *text,
unsigned int text_len, unsigned int text_len,
hb_font_t *font, hb_font_t *font,
hb_bool_t utf8_clusters, hb_bool_t utf8_clusters,
GString *gs) GString *gs)
{ {
if (show_text) { if (show_text) {
serialize_line_no (line_no, gs); serialize_line_no (line_no, gs);
@ -795,7 +795,25 @@ format_options_t::serialize_line (hb_buffer_t *buffer,
serialize_unicode (scratch, gs); serialize_unicode (scratch, gs);
g_string_append_c (gs, '\n'); 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_line_no (line_no, gs);
serialize_glyphs (buffer, font, utf8_clusters, gs); serialize_glyphs (buffer, font, utf8_clusters, gs);
g_string_append_c (gs, '\n'); g_string_append_c (gs, '\n');

View File

@ -300,18 +300,9 @@ struct output_options_t : option_group_t
FILE *get_file_handle (void); 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_file;
const char *output_format; const char *output_format;
protected:
mutable FILE *fp; mutable FILE *fp;
}; };
@ -342,13 +333,23 @@ struct format_options_t : option_group_t
GString *gs); GString *gs);
void serialize_line_no (unsigned int line_no, void serialize_line_no (unsigned int line_no,
GString *gs); GString *gs);
void serialize_line (hb_buffer_t *buffer, void serialize_buffer_of_text (hb_buffer_t *buffer,
unsigned int line_no, unsigned int line_no,
const char *text, const char *text,
unsigned int text_len, unsigned int text_len,
hb_font_t *font, hb_font_t *font,
hb_bool_t utf8_clusters, hb_bool_t utf8_clusters,
GString *gs); 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: protected:

View File

@ -41,15 +41,23 @@ struct shape_consumer_t
{ {
font = hb_font_reference (font_opts->get_font ()); font = hb_font_reference (font_opts->get_font ());
output.init (font_opts); output.init (font_opts);
failed = false;
} }
void consume_line (hb_buffer_t *buffer, void consume_line (hb_buffer_t *buffer,
const char *text, const char *text,
unsigned int text_len) unsigned int text_len)
{ {
if (!shaper.shape (text, text_len, font, buffer)) output.new_line ();
fail (FALSE, "All shapers failed"); 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) void finish (const font_options_t *font_opts)
{ {
@ -58,6 +66,9 @@ struct shape_consumer_t
font = NULL; font = NULL;
} }
public:
bool failed;
protected: protected:
shape_options_t shaper; shape_options_t shaper;
output_t output; output_t output;

View File

@ -26,37 +26,6 @@
#include "view-cairo.hh" #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 void
view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font, view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font,
double *w, double *h) 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); cairo_scaled_font_extents (scaled_font, &font_extents);
bool vertical = HB_DIRECTION_IS_VERTICAL (direction); 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; (vertical ? *h : *w) = 0;
for (unsigned int i = 0; i < lines->len; i++) { for (unsigned int i = 0; i < lines->len; i++) {
helper_cairo_line_t &line = g_array_index (lines, helper_cairo_line_t, 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 = MAX (*w, x_advance);
} }
*w += margin.l + margin.r; *w += view_options.margin.l + view_options.margin.r;
*h += margin.t + margin.b; *h += view_options.margin.t + view_options.margin.b;
} }
void void
view_cairo_t::render (const font_options_t *font_opts) 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; double w, h;
get_surface_size (scaled_font, &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_set_scaled_font (cr, scaled_font);
cairo_scaled_font_destroy (scaled_font); cairo_scaled_font_destroy (scaled_font);
@ -107,7 +76,7 @@ view_cairo_t::draw (cairo_t *cr)
int h = vertical ? 0 : 1; int h = vertical ? 0 : 1;
cairo_font_extents_t font_extents; cairo_font_extents_t font_extents;
cairo_font_extents (cr, &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; double descent;
if (vertical) if (vertical)
descent = font_extents.height * (lines->len + .5); 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); helper_cairo_line_t &l = g_array_index (lines, helper_cairo_line_t, i);
if (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); cairo_translate (cr, v * -font_extents.height, h * font_extents.height);
if (annotate) { if (view_options.annotate) {
cairo_save (cr); cairo_save (cr);
/* Draw actual glyph origins */ /* Draw actual glyph origins */

View File

@ -31,24 +31,62 @@
#define VIEW_CAIRO_HH #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) view_cairo_t (option_parser_t *parser)
: output_options_t (parser), : output_options (parser),
view_options_t (parser) {} view_options (parser) {}
~view_cairo_t (void) { ~view_cairo_t (void) {
if (debug) if (debug)
cairo_debug_reset_static_data (); cairo_debug_reset_static_data ();
} }
void init (const font_options_t *font_opts); void init (const font_options_t *font_opts)
void consume_line (hb_buffer_t *buffer, {
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, const char *text,
unsigned int text_len, unsigned int text_len,
hb_bool_t utf8_clusters); hb_bool_t utf8_clusters)
void finish (const font_options_t *font_opts); {
}
void shape_failed (hb_buffer_t *buffer,
const char *text,
unsigned int text_len,
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: protected:
output_options_t output_options;
view_options_t view_options;
void render (const font_options_t *font_opts); void render (const font_options_t *font_opts);
void get_surface_size (cairo_scaled_font_t *scaled_font, double *w, double *h); void get_surface_size (cairo_scaled_font_t *scaled_font, double *w, double *h);
void draw (cairo_t *cr); void draw (cairo_t *cr);