[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 ();
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;

View File

@ -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;

View File

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

View File

@ -772,7 +772,7 @@ 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,
format_options_t::serialize_buffer_of_text (hb_buffer_t *buffer,
unsigned int line_no,
const char *text,
unsigned int text_len,
@ -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');

View File

@ -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,7 +333,17 @@ 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,
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,

View File

@ -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;

View File

@ -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 */

View File

@ -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 finish (const font_options_t *font_opts);
hb_bool_t utf8_clusters)
{
}
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:
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);