[util] Make hb-shape continue shaping other lines if shapers failed
This commit is contained in:
parent
96a9ef0c9f
commit
5db0683a82
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -66,7 +66,7 @@ struct main_font_text_t
|
|||
|
||||
consumer.finish (&font_opts);
|
||||
|
||||
return 0;
|
||||
return consumer.failed ? 1 : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue