From 2bed4f46fb09f338fd0959d233d16a40db08cf4e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 2 Feb 2022 21:42:48 -0600 Subject: [PATCH] [draw] Fix draw signatures --- src/hb-draw-glyph.cc | 2 +- src/hb-draw.cc | 141 +++++++------- src/hb-draw.h | 54 +++--- src/hb-draw.hh | 97 ++++++++-- src/hb-font.h | 2 +- src/main.cc | 65 ++++--- test/api/test-draw.c | 327 +++++++++++++++++---------------- test/fuzzing/hb-draw-fuzzer.cc | 105 ++++++----- 8 files changed, 448 insertions(+), 345 deletions(-) diff --git a/src/hb-draw-glyph.cc b/src/hb-draw-glyph.cc index 5d5136147..1ff7293fb 100644 --- a/src/hb-draw-glyph.cc +++ b/src/hb-draw-glyph.cc @@ -45,7 +45,7 @@ void hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph, - const hb_draw_funcs_t *funcs, + hb_draw_funcs_t *funcs, void *user_data) { if (unlikely (funcs == &Null (hb_draw_funcs_t) || diff --git a/src/hb-draw.cc b/src/hb-draw.cc index aaefcf4aa..e342553c3 100644 --- a/src/hb-draw.cc +++ b/src/hb-draw.cc @@ -28,6 +28,63 @@ #include "hb-draw.hh" +static void +hb_draw_move_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, + float to_x HB_UNUSED, float to_y HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_draw_line_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, + float to_x HB_UNUSED, float to_y HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, + float control_x HB_UNUSED, float control_y HB_UNUSED, + float to_x HB_UNUSED, float to_y HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_draw_cubic_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, + float control1_x HB_UNUSED, float control1_y HB_UNUSED, + float control2_x HB_UNUSED, float control2_y HB_UNUSED, + float to_x HB_UNUSED, float to_y HB_UNUSED, + void *user_data HB_UNUSED) {} + +static void +hb_draw_close_path_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED, + void *user_data HB_UNUSED) {} + + +#define HB_DRAW_FUNC_IMPLEMENT(name) \ + \ +void \ +hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \ + hb_draw_##name##_func_t func, \ + void *user_data, \ + hb_destroy_func_t destroy) \ +{ \ + if (hb_object_is_immutable (dfuncs)) \ + return; \ + \ + if (dfuncs->destroy.name) \ + dfuncs->destroy.name (dfuncs->user_data.name); \ + \ + if (func) { \ + dfuncs->func.name = func; \ + dfuncs->user_data.name = user_data; \ + dfuncs->destroy.name = destroy; \ + } else { \ + dfuncs->func.name = hb_draw_##name##_nil; \ + dfuncs->user_data.name = nullptr; \ + dfuncs->destroy.name = nullptr; \ + } \ +} + +HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_DRAW_FUNC_IMPLEMENT + + /** * hb_draw_funcs_set_move_to_func: * @funcs: draw functions object @@ -37,13 +94,6 @@ * * Since: REPLACEME **/ -void -hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs, - hb_draw_move_to_func_t move_to) -{ - if (unlikely (hb_object_is_immutable (funcs))) return; - funcs->move_to = move_to; -} /** * hb_draw_funcs_set_line_to_func: @@ -54,13 +104,6 @@ hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs, * * Since: REPLACEME **/ -void -hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs, - hb_draw_line_to_func_t line_to) -{ - if (unlikely (hb_object_is_immutable (funcs))) return; - funcs->line_to = line_to; -} /** * hb_draw_funcs_set_quadratic_to_func: @@ -71,14 +114,6 @@ hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs, * * Since: REPLACEME **/ -void -hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs, - hb_draw_quadratic_to_func_t quadratic_to) -{ - if (unlikely (hb_object_is_immutable (funcs))) return; - funcs->quadratic_to = quadratic_to; - funcs->is_quadratic_to_set = true; -} /** * hb_draw_funcs_set_cubic_to_func: @@ -89,13 +124,6 @@ hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs, * * Since: REPLACEME **/ -void -hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs, - hb_draw_cubic_to_func_t cubic_to) -{ - if (unlikely (hb_object_is_immutable (funcs))) return; - funcs->cubic_to = cubic_to; -} /** * hb_draw_funcs_set_close_path_func: @@ -106,33 +134,6 @@ hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs, * * Since: REPLACEME **/ -void -hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *funcs, - hb_draw_close_path_func_t close_path) -{ - if (unlikely (hb_object_is_immutable (funcs))) return; - funcs->close_path = close_path; -} - -static void -_move_to_nil (float to_x HB_UNUSED, float to_y HB_UNUSED, void *user_data HB_UNUSED) {} - -static void -_line_to_nil (float to_x HB_UNUSED, float to_y HB_UNUSED, void *user_data HB_UNUSED) {} - -static void -_quadratic_to_nil (float control_x HB_UNUSED, float control_y HB_UNUSED, - float to_x HB_UNUSED, float to_y HB_UNUSED, - void *user_data HB_UNUSED) {} - -static void -_cubic_to_nil (float control1_x HB_UNUSED, float control1_y HB_UNUSED, - float control2_x HB_UNUSED, float control2_y HB_UNUSED, - float to_x HB_UNUSED, float to_y HB_UNUSED, - void *user_data HB_UNUSED) {} - -static void -_close_path_nil (void *user_data HB_UNUSED) {} /** * hb_draw_funcs_create: @@ -148,15 +149,31 @@ hb_draw_funcs_create () if (unlikely (!(funcs = hb_object_create ()))) return const_cast (&Null (hb_draw_funcs_t)); - funcs->move_to = (hb_draw_move_to_func_t) _move_to_nil; - funcs->line_to = (hb_draw_line_to_func_t) _line_to_nil; - funcs->quadratic_to = (hb_draw_quadratic_to_func_t) _quadratic_to_nil; - funcs->is_quadratic_to_set = false; - funcs->cubic_to = (hb_draw_cubic_to_func_t) _cubic_to_nil; - funcs->close_path = (hb_draw_close_path_func_t) _close_path_nil; + /* XXX Clean up. Use nil object. */ + funcs->func.move_to = hb_draw_move_to_nil; + funcs->func.line_to = hb_draw_line_to_nil; + funcs->func.quadratic_to = hb_draw_quadratic_to_nil; + funcs->func.cubic_to = hb_draw_cubic_to_nil; + funcs->func.close_path = hb_draw_close_path_nil; return funcs; } +DEFINE_NULL_INSTANCE (hb_draw_funcs_t) = +{ + HB_OBJECT_HEADER_STATIC, + + { +#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_nil, + HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_DRAW_FUNC_IMPLEMENT + } +}; + +/* XXX Remove. */ + +bool +hb_draw_funcs_t::quadratic_to_is_set () { return func.quadratic_to != hb_draw_quadratic_to_nil; } + /** * hb_draw_funcs_reference: * @funcs: draw functions diff --git a/src/hb-draw.h b/src/hb-draw.h index 305e6ce74..6d8856025 100644 --- a/src/hb-draw.h +++ b/src/hb-draw.h @@ -33,26 +33,6 @@ HB_BEGIN_DECLS -typedef void (*hb_draw_move_to_func_t) (float to_x, - float to_y, - void *user_data); -typedef void (*hb_draw_line_to_func_t) (float to_x, - float to_y, - void *user_data); -typedef void (*hb_draw_quadratic_to_func_t) (float control_x, - float control_y, - float to_x, - float to_y, - void *user_data); -typedef void (*hb_draw_cubic_to_func_t) (float control1_x, - float control1_y, - float control2_x, - float control2_y, - float to_x, - float to_y, - void *user_data); -typedef void (*hb_draw_close_path_func_t) (void *user_data); - /** * hb_draw_funcs_t: * @@ -63,27 +43,51 @@ typedef void (*hb_draw_close_path_func_t) (void *user_data); * * Since: REPLACEME **/ + typedef struct hb_draw_funcs_t hb_draw_funcs_t; +typedef void (*hb_draw_move_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data, + float to_x, float to_y, + void *user_data); +typedef void (*hb_draw_line_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data, + float to_x, float to_y, + void *user_data); +typedef void (*hb_draw_quadratic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data, + float control_x, float control_y, + float to_x, float to_y, + void *user_data); +typedef void (*hb_draw_cubic_to_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y, + void *user_data); +typedef void (*hb_draw_close_path_func_t) (hb_draw_funcs_t *dfuncs, void *draw_data, + void *user_data); + HB_EXTERN void hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs, - hb_draw_move_to_func_t move_to); + hb_draw_move_to_func_t move_to, + void *user_data, hb_destroy_func_t destroy); HB_EXTERN void hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs, - hb_draw_line_to_func_t line_to); + hb_draw_line_to_func_t line_to, + void *user_data, hb_destroy_func_t destroy); HB_EXTERN void hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs, - hb_draw_quadratic_to_func_t quadratic_to); + hb_draw_quadratic_to_func_t quadratic_to, + void *user_data, hb_destroy_func_t destroy); HB_EXTERN void hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs, - hb_draw_cubic_to_func_t cubic_to); + hb_draw_cubic_to_func_t cubic_to, + void *user_data, hb_destroy_func_t destroy); HB_EXTERN void hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *funcs, - hb_draw_close_path_func_t close_path); + hb_draw_close_path_func_t close_path, + void *user_data, hb_destroy_func_t destroy); HB_EXTERN hb_draw_funcs_t * hb_draw_funcs_create (void); diff --git a/src/hb-draw.hh b/src/hb-draw.hh index 8b2dfbcd3..98b45943e 100644 --- a/src/hb-draw.hh +++ b/src/hb-draw.hh @@ -27,24 +27,82 @@ #include "hb.hh" + +/* + * hb_draw_funcs_t + */ + +#define HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS \ + HB_DRAW_FUNC_IMPLEMENT (move_to) \ + HB_DRAW_FUNC_IMPLEMENT (line_to) \ + HB_DRAW_FUNC_IMPLEMENT (quadratic_to) \ + HB_DRAW_FUNC_IMPLEMENT (cubic_to) \ + HB_DRAW_FUNC_IMPLEMENT (close_path) \ + /* ^--- Add new callbacks here */ + struct hb_draw_funcs_t { hb_object_header_t header; - hb_draw_move_to_func_t move_to; - hb_draw_line_to_func_t line_to; - hb_draw_quadratic_to_func_t quadratic_to; - bool is_quadratic_to_set; - hb_draw_cubic_to_func_t cubic_to; - hb_draw_close_path_func_t close_path; + struct { +#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_func_t name; + HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_DRAW_FUNC_IMPLEMENT + } func; + + struct { +#define HB_DRAW_FUNC_IMPLEMENT(name) void *name; + HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_DRAW_FUNC_IMPLEMENT + } user_data; + + struct { +#define HB_DRAW_FUNC_IMPLEMENT(name) hb_destroy_func_t name; + HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS +#undef HB_DRAW_FUNC_IMPLEMENT + } destroy; + + void move_to (void *draw_data, + float to_x, float to_y) + { func.move_to (this, draw_data, + to_x, to_y, + user_data.move_to); } + void line_to (void *draw_data, + float to_x, float to_y) + { func.line_to (this, draw_data, + to_x, to_y, + user_data.line_to); } + void quadratic_to (void *draw_data, + float control_x, float control_y, + float to_x, float to_y) + { func.quadratic_to (this, draw_data, + control_x, control_y, + to_x, to_y, + user_data.quadratic_to); } + void cubic_to (void *draw_data, + float control1_x, float control1_y, + float control2_x, float control2_y, + float to_x, float to_y) + { func.cubic_to (this, draw_data, + control1_x, control1_y, + control2_x, control2_y, + to_x, to_y, + user_data.cubic_to); } + void close_path (void *draw_data) + { func.close_path (this, draw_data, + user_data.close_path); } + + /* XXX Remove */ + HB_INTERNAL bool quadratic_to_is_set (); }; +DECLARE_NULL_INSTANCE (hb_draw_funcs_t); struct draw_helper_t { - draw_helper_t (const hb_draw_funcs_t *funcs_, void *user_data_) + draw_helper_t (hb_draw_funcs_t *funcs_, void *draw_data_) { funcs = funcs_; - user_data = user_data_; + draw_data = draw_data_; path_open = false; path_start_x = current_x = path_start_y = current_y = 0; } @@ -61,7 +119,7 @@ struct draw_helper_t { if (equal_to_current (x, y)) return; if (!path_open) start_path (); - funcs->line_to (x, y, user_data); + funcs->line_to (draw_data, x, y); current_x = x; current_y = y; } @@ -73,14 +131,15 @@ struct draw_helper_t if (equal_to_current (control_x, control_y) && equal_to_current (to_x, to_y)) return; if (!path_open) start_path (); - if (funcs->is_quadratic_to_set) - funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data); + if (funcs->quadratic_to_is_set ()) + funcs->quadratic_to (draw_data, control_x, control_y, to_x, to_y); else - funcs->cubic_to (roundf ((current_x + 2.f * control_x) / 3.f), + funcs->cubic_to (draw_data, + roundf ((current_x + 2.f * control_x) / 3.f), roundf ((current_y + 2.f * control_y) / 3.f), roundf ((to_x + 2.f * control_x) / 3.f), roundf ((to_y + 2.f * control_y) / 3.f), - to_x, to_y, user_data); + to_x, to_y); current_x = to_x; current_y = to_y; } @@ -95,7 +154,7 @@ struct draw_helper_t equal_to_current (to_x, to_y)) return; if (!path_open) start_path (); - funcs->cubic_to (control1_x, control1_y, control2_x, control2_y, to_x, to_y, user_data); + funcs->cubic_to (draw_data, control1_x, control1_y, control2_x, control2_y, to_x, to_y); current_x = to_x; current_y = to_y; } @@ -105,8 +164,8 @@ struct draw_helper_t if (path_open) { if ((path_start_x != current_x) || (path_start_y != current_y)) - funcs->line_to (path_start_x, path_start_y, user_data); - funcs->close_path (user_data); + funcs->line_to (draw_data, path_start_x, path_start_y); + funcs->close_path (draw_data); } path_open = false; path_start_x = current_x = path_start_y = current_y = 0; @@ -120,7 +179,7 @@ struct draw_helper_t { if (path_open) end_path (); path_open = true; - funcs->move_to (path_start_x, path_start_y, user_data); + funcs->move_to (draw_data, path_start_x, path_start_y); } float path_start_x; @@ -130,8 +189,8 @@ struct draw_helper_t float current_y; bool path_open; - const hb_draw_funcs_t *funcs; - void *user_data; + hb_draw_funcs_t *funcs; + void *draw_data; }; #endif /* HB_DRAW_HH */ diff --git a/src/hb-font.h b/src/hb-font.h index 865ebcc88..528d5014e 100644 --- a/src/hb-font.h +++ b/src/hb-font.h @@ -1059,7 +1059,7 @@ hb_font_set_var_named_instance (hb_font_t *font, HB_EXTERN void hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph, - const hb_draw_funcs_t *funcs, + hb_draw_funcs_t *funcs, void *user_data); HB_END_DECLS diff --git a/src/main.cc b/src/main.cc index c708a970e..a3d123783 100644 --- a/src/main.cc +++ b/src/main.cc @@ -129,48 +129,55 @@ png_dump (hb_face_t *face, unsigned face_index) hb_font_destroy (font); } -struct user_data_t +struct draw_data_t { FILE *f; hb_position_t ascender; }; static void -move_to (float to_x, float to_y, user_data_t *user_data) +move_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + float to_x, float to_y, + void *) { - fprintf (user_data->f, "M%g,%g", to_x, user_data->ascender - to_y); + fprintf (draw_data->f, "M%g,%g", to_x, draw_data->ascender - to_y); } static void -line_to (float to_x, float to_y, user_data_t *user_data) +line_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + float to_x, float to_y, + void *) { - fprintf (user_data->f, "L%g,%g", to_x, user_data->ascender - to_y); + fprintf (draw_data->f, "L%g,%g", to_x, draw_data->ascender - to_y); } static void -quadratic_to (float control_x, float control_y, +quadratic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + float control_x, float control_y, float to_x, float to_y, - user_data_t *user_data) + void *) { - fprintf (user_data->f, "Q%g,%g %g,%g", control_x, user_data->ascender - control_y, - to_x, user_data->ascender - to_y); + fprintf (draw_data->f, "Q%g,%g %g,%g", control_x, draw_data->ascender - control_y, + to_x, draw_data->ascender - to_y); } static void -cubic_to (float control1_x, float control1_y, +cubic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + float control1_x, float control1_y, float control2_x, float control2_y, float to_x, float to_y, - user_data_t *user_data) + void *) { - fprintf (user_data->f, "C%g,%g %g,%g %g,%g", control1_x, user_data->ascender - control1_y, - control2_x, user_data->ascender - control2_y, - to_x, user_data->ascender - to_y); + fprintf (draw_data->f, "C%g,%g %g,%g %g,%g", control1_x, draw_data->ascender - control1_y, + control2_x, draw_data->ascender - control2_y, + to_x, draw_data->ascender - to_y); } static void -close_path (user_data_t *user_data) +close_path (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + void *) { - fprintf (user_data->f, "Z"); + fprintf (draw_data->f, "Z"); } static void @@ -218,9 +225,9 @@ layered_glyph_dump (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index " viewBox=\"%d %d %d %d\">\n", extents.x_bearing, 0, extents.x_bearing + extents.width, -extents.height); - user_data_t user_data; - user_data.ascender = extents.y_bearing; - user_data.f = f; + draw_data_t draw_data; + draw_data.ascender = extents.y_bearing; + draw_data.f = f; for (unsigned layer = 0; layer < num_layers; ++layer) { @@ -232,7 +239,7 @@ layered_glyph_dump (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index if (hb_color_get_alpha (color) != 255) fprintf (f, "fill-opacity=\"%.3f\"", (double) hb_color_get_alpha (color) / 255.); fprintf (f, "d=\""); - hb_font_draw_glyph (font, layers[layer].glyph, funcs, &user_data); + hb_font_draw_glyph (font, layers[layer].glyph, funcs, &draw_data); fprintf (f, "\"/>\n"); } @@ -268,10 +275,10 @@ dump_glyphs (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index) " viewBox=\"%d %d %d %d\">"); fclose (f); } @@ -298,11 +305,11 @@ dump_glyphs (hb_blob_t *blob, const char *font_name) fclose (font_name_file); hb_draw_funcs_t *funcs = hb_draw_funcs_create (); - hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to); - hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to); - hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to); - hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to); - hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path); + hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, nullptr, nullptr); + hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, nullptr, nullptr); unsigned num_faces = hb_face_count (blob); for (unsigned face_index = 0; face_index < num_faces; ++face_index) diff --git a/test/api/test-draw.c b/test/api/test-draw.c index e1b736ac3..97daa041b 100644 --- a/test/api/test-draw.c +++ b/test/api/test-draw.c @@ -27,12 +27,12 @@ #include -typedef struct user_data_t +typedef struct draw_data_t { char *str; unsigned size; unsigned consumed; -} user_data_t; +} draw_data_t; /* Our modified itoa, why not using libc's? it is going to be used in harfbuzzjs where libc isn't available */ @@ -96,69 +96,76 @@ test_itoa (void) } static void -move_to (float to_x, float to_y, user_data_t *user_data) +move_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + float to_x, float to_y, + void *user_data) { /* 4 = command character space + comma + array starts with 0 index + nul character space */ - if (user_data->consumed + 2 * ITOA_BUF_SIZE + 4 > user_data->size) return; - user_data->str[user_data->consumed++] = 'M'; - user_data->consumed += _hb_itoa (to_x, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ','; - user_data->consumed += _hb_itoa (to_y, user_data->str + user_data->consumed); + if (draw_data->consumed + 2 * ITOA_BUF_SIZE + 4 > draw_data->size) return; + draw_data->str[draw_data->consumed++] = 'M'; + draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ','; + draw_data->consumed += _hb_itoa (to_y, draw_data->str + draw_data->consumed); } static void -line_to (float to_x, float to_y, user_data_t *user_data) +line_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + float to_x, float to_y, + void *user_data) { - if (user_data->consumed + 2 * ITOA_BUF_SIZE + 4 > user_data->size) return; - user_data->str[user_data->consumed++] = 'L'; - user_data->consumed += _hb_itoa (to_x, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ','; - user_data->consumed += _hb_itoa (to_y, user_data->str + user_data->consumed); + if (draw_data->consumed + 2 * ITOA_BUF_SIZE + 4 > draw_data->size) return; + draw_data->str[draw_data->consumed++] = 'L'; + draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ','; + draw_data->consumed += _hb_itoa (to_y, draw_data->str + draw_data->consumed); } static void -quadratic_to (float control_x, float control_y, +quadratic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + float control_x, float control_y, float to_x, float to_y, - user_data_t *user_data) + void *user_data) { - if (user_data->consumed + 4 * ITOA_BUF_SIZE + 6 > user_data->size) return; - user_data->str[user_data->consumed++] = 'Q'; - user_data->consumed += _hb_itoa (control_x, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ','; - user_data->consumed += _hb_itoa (control_y, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ' '; - user_data->consumed += _hb_itoa (to_x, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ','; - user_data->consumed += _hb_itoa (to_y, user_data->str + user_data->consumed); + if (draw_data->consumed + 4 * ITOA_BUF_SIZE + 6 > draw_data->size) return; + draw_data->str[draw_data->consumed++] = 'Q'; + draw_data->consumed += _hb_itoa (control_x, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ','; + draw_data->consumed += _hb_itoa (control_y, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ' '; + draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ','; + draw_data->consumed += _hb_itoa (to_y, draw_data->str + draw_data->consumed); } static void -cubic_to (float control1_x, float control1_y, +cubic_to (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + float control1_x, float control1_y, float control2_x, float control2_y, float to_x, float to_y, - user_data_t *user_data) + void *user_data) { - if (user_data->consumed + 6 * ITOA_BUF_SIZE + 8 > user_data->size) return; - user_data->str[user_data->consumed++] = 'C'; - user_data->consumed += _hb_itoa (control1_x, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ','; - user_data->consumed += _hb_itoa (control1_y, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ' '; - user_data->consumed += _hb_itoa (control2_x, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ','; - user_data->consumed += _hb_itoa (control2_y, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ' '; - user_data->consumed += _hb_itoa (to_x, user_data->str + user_data->consumed); - user_data->str[user_data->consumed++] = ','; - user_data->consumed += _hb_itoa (to_y, user_data->str + user_data->consumed); + if (draw_data->consumed + 6 * ITOA_BUF_SIZE + 8 > draw_data->size) return; + draw_data->str[draw_data->consumed++] = 'C'; + draw_data->consumed += _hb_itoa (control1_x, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ','; + draw_data->consumed += _hb_itoa (control1_y, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ' '; + draw_data->consumed += _hb_itoa (control2_x, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ','; + draw_data->consumed += _hb_itoa (control2_y, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ' '; + draw_data->consumed += _hb_itoa (to_x, draw_data->str + draw_data->consumed); + draw_data->str[draw_data->consumed++] = ','; + draw_data->consumed += _hb_itoa (to_y, draw_data->str + draw_data->consumed); } static void -close_path (user_data_t *user_data) +close_path (hb_draw_funcs_t *dfuncs, draw_data_t *draw_data, + void *user_data) { - if (user_data->consumed + 2 > user_data->size) return; - user_data->str[user_data->consumed++] = 'Z'; + if (draw_data->consumed + 2 > draw_data->size) return; + draw_data->str[draw_data->consumed++] = 'Z'; } static hb_draw_funcs_t *funcs; @@ -178,17 +185,17 @@ test_hb_draw_glyf (void) hb_face_destroy (face); char str[1024]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str), .consumed = 0 }; - user_data.consumed = 0; - hb_font_draw_glyph (font, 4, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 4, funcs, &draw_data); - user_data.consumed = 0; - hb_font_draw_glyph (font, 3, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected[] = "M275,442Q232,442 198,420Q164,397 145,353Q126,309 126,245" "Q126,182 147,139Q167,95 204,73Q240,50 287,50Q330,50 367,70" "Q404,90 427,128L451,116Q431,54 384,21Q336,-13 266,-13" @@ -196,11 +203,11 @@ test_hb_draw_glyf (void) "Q108,427 160,457Q212,487 272,487Q316,487 354,470Q392,453 417,424" "Q442,395 448,358Q441,321 403,321Q378,321 367,334" "Q355,347 350,366L325,454L371,417Q346,430 321,436Q296,442 275,442Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); /* Test translating quadratic calls to cubic by a _draw_funcs_t that doesn't set the callback */ - user_data.consumed = 0; - hb_font_draw_glyph (font, 3, funcs2, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 3, funcs2, &draw_data); char expected2[] = "M275,442C246,442 221,435 198,420C175,405 158,382 145,353" "C132,324 126,288 126,245C126,203 133,168 147,139C160,110 179,88 204,73" "C228,58 256,50 287,50C316,50 342,57 367,70C392,83 412,103 427,128" @@ -210,15 +217,15 @@ test_hb_draw_glyf (void) "C379,459 400,443 417,424C434,405 444,383 448,358C443,333 428,321 403,321" "C386,321 374,325 367,334C359,343 353,353 350,366L325,454L371,417" "C354,426 338,432 321,436C304,440 289,442 275,442Z"; - g_assert_cmpmem (str, user_data.consumed, expected2, sizeof (expected2) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); hb_variation_t var; var.tag = HB_TAG ('w','g','h','t'); var.value = 800; hb_font_set_variations (font, &var, 1); - user_data.consumed = 0; - hb_font_draw_glyph (font, 3, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected3[] = "M323,448Q297,448 271,430Q244,412 226,371Q209,330 209,261" "Q209,204 225,166Q242,127 272,107Q303,86 344,86Q378,86 404,101" "Q430,115 451,137L488,103Q458,42 404,13Q350,-16 279,-16" @@ -226,7 +233,7 @@ test_hb_draw_glyf (void) "Q99,440 163,470Q226,501 303,501Q357,501 399,480Q440,460 464,426" "Q488,392 492,352Q475,297 420,297Q390,297 366,319Q342,342 339,401" "L333,469L411,427Q387,438 367,443Q348,448 323,448Z"; - g_assert_cmpmem (str, user_data.consumed, expected3, sizeof (expected3) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected3, sizeof (expected3) - 1); hb_font_destroy (font); } @@ -239,16 +246,16 @@ test_hb_draw_cff1 (void) hb_face_destroy (face); char str[1024]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str), .consumed = 0 }; - hb_font_draw_glyph (font, 3, funcs, &user_data); + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected[] = "M203,367C227,440 248,512 268,588L272,588C293,512 314,440 338,367L369,267L172,267L203,367Z" "M3,0L88,0L151,200L390,200L452,0L541,0L319,656L225,656L3,0Z" "M300,653L342,694L201,861L143,806L300,653Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -262,18 +269,18 @@ test_hb_draw_cff1_rline (void) hb_face_destroy (face); char str[1024]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str), .consumed = 0 }; - hb_font_draw_glyph (font, 1, funcs, &user_data); + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M775,400C705,400 650,343 650,274L650,250L391,250L713,572L392,893" "L287,1000C311,942 296,869 250,823C250,823 286,858 321,823L571,572" "L150,150L750,150L750,276C750,289 761,300 775,300C789,300 800,289 800,276" "L800,100L150,100C100,100 100,150 100,150C100,85 58,23 0,0L900,0L900,274" "C900,343 844,400 775,400Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -286,33 +293,33 @@ test_hb_draw_cff2 (void) hb_face_destroy (face); char str[1024]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str) }; - user_data.consumed = 0; - hb_font_draw_glyph (font, 3, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected[] = "M275,442C303,442 337,435 371,417L325,454L350,366" "C357,341 370,321 403,321C428,321 443,333 448,358" "C435,432 361,487 272,487C153,487 43,393 43,236" "C43,83 129,-13 266,-13C360,-13 424,33 451,116L427,128" "C396,78 345,50 287,50C193,50 126,119 126,245C126,373 188,442 275,442Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_variation_t var; var.tag = HB_TAG ('w','g','h','t'); var.value = 800; hb_font_set_variations (font, &var, 1); - user_data.consumed = 0; - hb_font_draw_glyph (font, 3, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 3, funcs, &draw_data); char expected2[] = "M323,448C356,448 380,441 411,427L333,469L339,401" "C343,322 379,297 420,297C458,297 480,314 492,352" "C486,433 412,501 303,501C148,501 25,406 25,241" "C25,70 143,-16 279,-16C374,-16 447,22 488,103L451,137" "C423,107 390,86 344,86C262,86 209,148 209,261C209,398 271,448 323,448Z"; - g_assert_cmpmem (str, user_data.consumed, expected2, sizeof (expected2) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); hb_font_destroy (font); } @@ -322,7 +329,7 @@ test_hb_draw_ttf_parser_tests (void) { /* https://github.com/RazrFalcon/ttf-parser/blob/337e7d1c/tests/tests.rs#L50-L133 */ char str[1024]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str) }; @@ -331,20 +338,20 @@ test_hb_draw_ttf_parser_tests (void) hb_font_t *font = hb_font_create (face); hb_face_destroy (face); { - user_data.consumed = 0; - hb_font_draw_glyph (font, 0, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 0, funcs, &draw_data); char expected[] = "M50,0L50,750L450,750L450,0L50,0Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { - user_data.consumed = 0; - hb_font_draw_glyph (font, 1, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M56,416L56,487L514,487L514,416L56,416ZM56,217L56,288L514,288L514,217L56,217Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { - user_data.consumed = 0; - hb_font_draw_glyph (font, 4, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 4, funcs, &draw_data); char expected[] = "M332,468L197,468L197,0L109,0L109,468L15,468L15,509L109,539" "L109,570Q109,674 155,720Q201,765 283,765Q315,765 342,760" "Q368,754 387,747L364,678Q348,683 327,688Q306,693 284,693" @@ -352,22 +359,22 @@ test_hb_draw_ttf_parser_tests (void) "M474,737Q494,737 510,724Q525,710 525,681Q525,653 510,639" "Q494,625 474,625Q452,625 437,639Q422,653 422,681" "Q422,710 437,724Q452,737 474,737ZM517,536L517,0L429,0L429,536L517,536Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { - user_data.consumed = 0; - hb_font_draw_glyph (font, 5, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 5, funcs, &draw_data); char expected[] = ""; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { - user_data.consumed = 0; - hb_font_draw_glyph (font, 6, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 6, funcs, &draw_data); char expected[] = "M346,468L211,468L211,0L123,0L123,468L29,468L29,509L123,539" "L123,570Q123,674 169,720Q215,765 297,765Q329,765 356,760" "Q382,754 401,747L378,678Q362,683 341,688Q320,693 298,693" "Q254,693 233,664Q211,634 211,571L211,536L346,536L346,468Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } hb_font_destroy (font); @@ -377,15 +384,15 @@ test_hb_draw_ttf_parser_tests (void) hb_font_t *font = hb_font_create (face); hb_face_destroy (face); - user_data.consumed = 0; - hb_font_draw_glyph (font, 1, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M0,0C100,0 150,-20 250,-20C350,-20 400,0 500,0C500,100 520,150 520,250" "C520,350 500,400 500,500C400,500 350,520 250,520C150,520 100,500 0,500" "C0,400 -20,350 -20,250C-20,150 0,100 0,0ZM50,50C50,130 34,170 34,250" "C34,330 50,370 50,450C130,450 170,466 250,466C330,466 370,450 450,450" "C450,370 466,330 466,250C466,170 450,130 450,50C370,50 330,34 250,34" "C170,34 130,50 50,50Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -394,12 +401,12 @@ test_hb_draw_ttf_parser_tests (void) hb_font_t *font = hb_font_create (face); hb_face_destroy (face); - user_data.consumed = 0; - hb_font_draw_glyph (font, 1, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M82,0L164,0L164,486L82,486L82,0Z" "M124,586C156,586 181,608 181,639C181,671 156,692 124,692" "C92,692 67,671 67,639C67,608 92,586 124,586Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -410,7 +417,7 @@ test_hb_draw_font_kit_glyphs_tests (void) { /* https://github.com/foliojs/fontkit/blob/master/test/glyphs.js */ char str[2048]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str) }; @@ -421,26 +428,26 @@ test_hb_draw_font_kit_glyphs_tests (void) hb_face_destroy (face); /* should get a path for the glyph */ - user_data.consumed = 0; - hb_font_draw_glyph (font, 37, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 37, funcs, &draw_data); char expected[] = "M201,1462L614,1462Q905,1462 1035,1375Q1165,1288 1165,1100" "Q1165,970 1093,886Q1020,801 881,776L881,766Q1214,709 1214,416" "Q1214,220 1082,110Q949,0 711,0L201,0L201,1462ZM371,836L651,836" "Q831,836 910,893Q989,949 989,1083Q989,1206 901,1261" "Q813,1315 621,1315L371,1315L371,836ZM371,692L371,145L676,145" "Q853,145 943,214Q1032,282 1032,428Q1032,564 941,628Q849,692 662,692L371,692Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); /* should get a path for the glyph */ - user_data.consumed = 0; - hb_font_draw_glyph (font, 171, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 171, funcs, &draw_data); char expected2[] = "M639,-20Q396,-20 256,128Q115,276 115,539Q115,804 246,960Q376,1116 596,1116" "Q802,1116 922,981Q1042,845 1042,623L1042,518L287,518Q292,325 385,225" "Q477,125 645,125Q822,125 995,199L995,51Q907,13 829,-3Q750,-20 639,-20Z" "M594,977Q462,977 384,891Q305,805 291,653L864,653Q864,810 794,894" "Q724,977 594,977ZM471,1266Q519,1328 575,1416Q630,1504 662,1569" "L864,1569L864,1548Q820,1483 733,1388Q646,1293 582,1241L471,1241L471,1266Z"; - g_assert_cmpmem (str, user_data.consumed, expected2, sizeof (expected2) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); hb_font_destroy (font); } @@ -458,8 +465,8 @@ test_hb_draw_font_kit_glyphs_tests (void) hb_buffer_destroy (buffer); /* should resolve composite glyphs recursively */ - user_data.consumed = 0; - hb_font_draw_glyph (font, codepoint, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M581,274L443,274Q409,274 384,259Q359,243 348,219Q336,194 340,166" "Q343,138 365,111L468,-13Q470,-10 473,-6Q475,-3 477,0L253,0Q225,0 203,8" "Q180,15 168,32Q155,48 155,73L155,269L50,269L50,73Q50,24 69,-10" @@ -471,16 +478,16 @@ test_hb_draw_font_kit_glyphs_tests (void) "M360,-194Q360,-216 375,-231Q390,-246 412,-246Q434,-246 449,-231" "Q464,-216 464,-194Q464,-172 449,-157Q434,-142 412,-142" "Q390,-142 375,-157Q360,-172 360,-194Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); /* should transform points of a composite glyph */ - user_data.consumed = 0; - hb_font_draw_glyph (font, 2, funcs, &user_data); /* 2 == arAlef.fina */ + draw_data.consumed = 0; + hb_font_draw_glyph (font, 2, funcs, &draw_data); /* 2 == arAlef.fina */ char expected2[] = "M155,624L155,84Q150,90 146,95Q141,99 136,105" "L292,105L292,0L156,0Q128,0 104,14Q79,27 65,51" "Q50,74 50,104L50,624L155,624ZM282,105L312,105" "L312,0L282,0L282,105Z"; - g_assert_cmpmem (str, user_data.consumed, expected2, sizeof (expected2) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); hb_font_destroy (font); } @@ -490,11 +497,11 @@ test_hb_draw_font_kit_glyphs_tests (void) hb_font_t *font = hb_font_create (face); hb_face_destroy (face); - user_data.consumed = 0; - hb_font_draw_glyph (font, 5, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 5, funcs, &draw_data); char expected[] = "M90,0L258,0C456,0 564,122 564,331C564,539 456,656 254,656L90,656L90,0Z" "M173,68L173,588L248,588C401,588 478,496 478,331C478,165 401,68 248,68L173,68Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -505,12 +512,12 @@ test_hb_draw_font_kit_glyphs_tests (void) hb_font_t *font = hb_font_create (face); hb_face_destroy (face); - user_data.consumed = 0; - hb_font_draw_glyph (font, 1, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 1, funcs, &draw_data); char expected[] = "M139,390C175,390 205,419 205,459C205,501 175,530 139,530C103,530 73,501 73,459" "C73,419 103,390 139,390ZM139,-13C175,-13 205,15 205,56C205,97 175,127 139,127" "C103,127 73,97 73,56C73,15 103,-13 139,-13Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -522,7 +529,7 @@ test_hb_draw_font_kit_variations_tests (void) { /* https://github.com/foliojs/fontkit/blob/b310db5/test/variations.js */ char str[2048]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str) }; @@ -550,8 +557,8 @@ test_hb_draw_font_kit_variations_tests (void) codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint; hb_buffer_destroy (buffer); - user_data.consumed = 0; - hb_font_draw_glyph (font, codepoint, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102" "Q796,-102 755,-98L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504" "L414,504L414,-102L371,-102ZM203,-94Q138,-94 86,-90L74,-52" @@ -572,7 +579,7 @@ test_hb_draw_font_kit_variations_tests (void) "Q754,410 775,381Q794,407 813,453L848,434Q826,387 801,352Q823,321 848,281" "L813,262Q791,301 775,323Q749,288 715,258ZM348,719L348,754L941,754L941,719" "L348,719ZM936,570Q870,602 817,622Q764,641 727,652L749,688Q852,655 957,605L936,570Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -595,8 +602,8 @@ test_hb_draw_font_kit_variations_tests (void) codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint; hb_buffer_destroy (buffer); - user_data.consumed = 0; - hb_font_draw_glyph (font, codepoint, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102Q796,-102 755,-98" "L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504L414,504L414,-102" "L371,-102ZM203,-94Q138,-94 86,-90L74,-52Q137,-59 188,-59Q211,-59 222,-46" @@ -616,7 +623,7 @@ test_hb_draw_font_kit_variations_tests (void) "L848,434Q826,387 801,352Q823,321 848,281L813,262Q791,301 775,323Q749,288 715,258Z" "M348,719L348,754L941,754L941,719L348,719ZM936,570Q870,602 817,622" "Q764,641 727,652L749,688Q852,655 957,605L936,570Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -639,8 +646,8 @@ test_hb_draw_font_kit_variations_tests (void) codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint; hb_buffer_destroy (buffer); - user_data.consumed = 0; - hb_font_draw_glyph (font, codepoint, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M371,-102L371,539L914,539L914,-27Q914,-102 840,-102Q796,-102 755,-98" "L742,-59Q790,-66 836,-66Q871,-66 871,-31L871,504L414,504L414,-102" "L371,-102ZM203,-94Q138,-94 86,-90L74,-52Q137,-59 188,-59Q211,-59 222,-46" @@ -660,7 +667,7 @@ test_hb_draw_font_kit_variations_tests (void) "Q823,321 848,281L813,262Q791,301 775,323Q749,288 715,258ZM348,719L348,754" "L941,754L941,719L348,719ZM936,570Q870,602 817,622" "Q764,641 727,652L749,688Q852,655 957,605L936,570Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); hb_font_destroy (font); } @@ -686,8 +693,8 @@ test_hb_draw_font_kit_variations_tests (void) codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint; hb_buffer_destroy (buffer); - user_data.consumed = 0; - hb_font_draw_glyph (font, codepoint, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M246,15C188,15 147,27 101,68L142,23L117,117C111,143 96,149 81,149" "C65,149 56,141 52,126C71,40 137,-13 244,-13C348,-13 436,46 436,156" "C436,229 405,295 271,349L247,359C160,393 119,439 119,506" @@ -696,7 +703,7 @@ test_hb_draw_font_kit_variations_tests (void) "C161,665 78,606 78,500C78,414 128,361 224,321L261,305C367,259 395,217 395,152" "C395,65 334,15 246,15ZM267,331L267,759L240,759L240,331L267,331ZM240,-115" "L267,-115L267,331L240,331L240,-115Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } { var.value = 500; @@ -710,8 +717,8 @@ test_hb_draw_font_kit_variations_tests (void) codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint; hb_buffer_destroy (buffer); - user_data.consumed = 0; - hb_font_draw_glyph (font, codepoint, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M251,36C206,36 165,42 118,61L176,21L161,99C151,152 129,167 101,167" "C78,167 61,155 51,131C54,43 133,-14 247,-14C388,-14 474,64 474,171" "C474,258 430,321 294,370L257,383C188,406 150,438 150,499" @@ -720,7 +727,7 @@ test_hb_draw_font_kit_variations_tests (void) "C450,597 370,656 264,656C140,656 57,576 57,474C57,373 119,318 227,279" "L263,266C345,236 379,208 379,145C379,76 329,36 251,36ZM289,320" "L289,746L242,746L242,320L289,320ZM240,-115L286,-115L286,320L240,320L240,-115Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } /* substitutes GSUB features depending on variations */ { @@ -735,8 +742,8 @@ test_hb_draw_font_kit_variations_tests (void) codepoint = hb_buffer_get_glyph_infos (buffer, NULL)[0].codepoint; hb_buffer_destroy (buffer); - user_data.consumed = 0; - hb_font_draw_glyph (font, codepoint, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, codepoint, funcs, &draw_data); char expected[] = "M258,38C197,38 167,48 118,71L192,19L183,103C177,155 155,174 115,174" "C89,174 64,161 51,125C52,36 124,-16 258,-16C417,-16 513,67 513,175" "C513,278 457,328 322,388L289,403C232,429 203,452 203,500C203,562 244,589 301,589" @@ -744,7 +751,7 @@ test_hb_draw_font_kit_variations_tests (void) "C491,590 408,643 290,643C141,643 57,563 57,460C57,357 122,307 233,256L265,241" "C334,209 363,186 363,130C363,77 320,38 258,38ZM318,616L318,734L252,734L252,616" "L318,616ZM253,-115L319,-115L319,14L253,14L253,-115Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); } hb_font_destroy (font); @@ -756,7 +763,7 @@ test_hb_draw_estedad_vf (void) { /* https://github.com/harfbuzz/harfbuzz/issues/2215 */ char str[2048]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str) }; @@ -770,18 +777,18 @@ test_hb_draw_estedad_vf (void) hb_variation_from_string ("wght=100", -1, &var); hb_font_set_variations (font, &var, 1); - user_data.consumed = 0; - hb_font_draw_glyph (font, 156, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 156, funcs, &draw_data); /* Skip empty path where all the points of a path are equal */ char expected[] = "M150,1158L182,1158Q256,1158 317,1170Q377,1182 421,1213L421,430L521,430" "L521,1490L421,1490L421,1320Q393,1279 344,1262Q294,1244 182,1244L150,1244" "L150,1158ZM1815,-122L1669,-122L1669,642L1552,642L1055,-117L1055,-206" "L1569,-206L1569,-458L1669,-458L1669,-206L1815,-206L1815,-122ZM1569,-122" "L1166,-122L1569,494L1569,-122ZM609,-79L1639,1288L1555,1334L525,-33L609,-79Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); - user_data.consumed = 0; - hb_font_draw_glyph (font, 180, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 180, funcs, &draw_data); /* Skip empty path where all the points of a path are equal */ char expected2[] = "M120,693Q120,545 177,414Q233,282 333,182Q433,81 567,24" "Q701,-33 856,-33Q1010,-33 1144,24Q1277,81 1377,182Q1477,282 1534,414" @@ -798,17 +805,17 @@ test_hb_draw_estedad_vf (void) "M1165,334L973,568Q1065,591 1126,658Q1187,725 1187,819" "Q1187,896 1147,956Q1106,1015 1037,1049Q969,1083 886,1083" "L590,1083L590,310L690,310L690,557L860,557L1083,286L1165,334Z"; - g_assert_cmpmem (str, user_data.consumed, expected2, sizeof (expected2) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); - user_data.consumed = 0; - hb_font_draw_glyph (font, 262, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 262, funcs, &draw_data); /* Skip empty path where all the points of a path are equal */ char expected3[] = "M422,598Q495,598 545,548Q595,498 595,426Q595,353 545,303Q494,252 422,252" "Q350,252 300,303Q250,353 250,426Q250,499 300,549Q349,598 422,598ZM422,698" "Q347,698 285,662Q223,625 187,564Q150,502 150,426Q150,351 187,289" "Q223,226 285,189Q346,152 422,152Q498,152 560,189Q622,226 658,288" "Q695,351 695,426Q695,502 658,563Q621,625 559,661Q498,698 422,698Z"; - g_assert_cmpmem (str, user_data.consumed, expected3, sizeof (expected3) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected3, sizeof (expected3) - 1); hb_font_destroy (font); } @@ -820,7 +827,7 @@ test_hb_draw_stroking (void) /* https://skia-review.googlesource.com/c/skia/+/266945 https://savannah.nongnu.org/bugs/index.php?57701 */ char str[2048]; - user_data_t user_data = { + draw_data_t draw_data = { .str = str, .size = sizeof (str) }; @@ -830,8 +837,8 @@ test_hb_draw_stroking (void) hb_font_t *font = hb_font_create (face); hb_face_destroy (face); - user_data.consumed = 0; - hb_font_draw_glyph (font, 6, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 6, funcs, &draw_data); /* Skip empty path where all the points of a path are equal */ char expected[] = "M436,1522Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427Q1384,332 1626,332" "Q1868,332 2089,427Q2309,521 2468,680Q2627,839 2722,1060Q2816,1280 2816,1522" @@ -843,10 +850,10 @@ test_hb_draw_stroking (void) "Q2996,1342 2947,1165Q2897,987 2809,837Q2721,686 2595,560Q2468,433 2318,345" "Q2167,257 1990,208Q1812,158 1626,158Q1440,158 1263,208Q1085,257 935,345" "Q784,433 658,560Q531,686 443,837Q355,987 306,1165Q256,1342 256,1528Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); - user_data.consumed = 0; - hb_font_draw_glyph (font, 7, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 7, funcs, &draw_data); char expected2[] = "M436,1522Q436,1280 531,1060Q625,839 784,680Q943,521 1164,427" "Q1384,332 1626,332Q1868,332 2089,427Q2309,521 2468,680" "Q2627,839 2722,1060Q2816,1280 2816,1522Q2816,1764 2722,1985" @@ -861,7 +868,7 @@ test_hb_draw_stroking (void) "Q1812,158 1626,158Q1440,158 1263,208Q1085,257 935,345" "Q784,433 658,560Q531,686 443,837Q355,987 306,1165" "Q256,1342 256,1528Z"; - g_assert_cmpmem (str, user_data.consumed, expected2, sizeof (expected2) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); hb_font_destroy (font); } @@ -871,21 +878,21 @@ test_hb_draw_stroking (void) hb_font_t *font = hb_font_create (face); hb_face_destroy (face); - user_data.consumed = 0; - hb_font_draw_glyph (font, 4, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 4, funcs, &draw_data); /* Skip empty path in CFF */ char expected[] = "M106,372C106,532 237,662 397,662C557,662 688,532 688,372C688,212 557,81 397,81C237,81 106,212 106,372Z" "M62,373C62,188 212,39 397,39C582,39 731,188 731,373C731,558 582,708 397,708C212,708 62,558 62,373Z"; - g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected, sizeof (expected) - 1); - user_data.consumed = 0; - hb_font_draw_glyph (font, 5, funcs, &user_data); + draw_data.consumed = 0; + hb_font_draw_glyph (font, 5, funcs, &draw_data); /* Fold consequent move-to commands */ char expected2[] = "M106,372C106,532 237,662 397,662C557,662 688,532 688,372" "C688,212 557,81 397,81C237,81 106,212 106,372ZM62,373" "C62,188 212,39 397,39C582,39 731,188 731,373" "C731,558 582,708 397,708C212,708 62,558 62,373Z"; - g_assert_cmpmem (str, user_data.consumed, expected2, sizeof (expected2) - 1); + g_assert_cmpmem (str, draw_data.consumed, expected2, sizeof (expected2) - 1); hb_font_destroy (font); } @@ -905,18 +912,18 @@ int main (int argc, char **argv) { funcs = hb_draw_funcs_create (); - hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to); - hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to); - hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to); - hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to); - hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path); + hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, NULL, NULL); + hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, NULL, NULL); + hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, NULL, NULL); + hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL); + hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, NULL, NULL); hb_draw_funcs_make_immutable (funcs); funcs2 = hb_draw_funcs_create (); - hb_draw_funcs_set_move_to_func (funcs2, (hb_draw_move_to_func_t) move_to); - hb_draw_funcs_set_line_to_func (funcs2, (hb_draw_line_to_func_t) line_to); - hb_draw_funcs_set_cubic_to_func (funcs2, (hb_draw_cubic_to_func_t) cubic_to); - hb_draw_funcs_set_close_path_func (funcs2, (hb_draw_close_path_func_t) close_path); + hb_draw_funcs_set_move_to_func (funcs2, (hb_draw_move_to_func_t) move_to, NULL, NULL); + hb_draw_funcs_set_line_to_func (funcs2, (hb_draw_line_to_func_t) line_to, NULL, NULL); + hb_draw_funcs_set_cubic_to_func (funcs2, (hb_draw_cubic_to_func_t) cubic_to, NULL, NULL); + hb_draw_funcs_set_close_path_func (funcs2, (hb_draw_close_path_func_t) close_path, NULL, NULL); hb_draw_funcs_make_immutable (funcs2); hb_test_init (&argc, &argv); diff --git a/test/fuzzing/hb-draw-fuzzer.cc b/test/fuzzing/hb-draw-fuzzer.cc index 65c864df9..deac28ff4 100644 --- a/test/fuzzing/hb-draw-fuzzer.cc +++ b/test/fuzzing/hb-draw-fuzzer.cc @@ -5,7 +5,7 @@ #include "hb-fuzzer.hh" -struct _user_data_t +struct _draw_data_t { bool is_open; unsigned path_len; @@ -16,63 +16,72 @@ struct _user_data_t }; static void -_move_to (float to_x, float to_y, void *user_data_) +_move_to (hb_draw_funcs_t *dfuncs, void *draw_data_, + float to_x, float to_y, + void *user_data) { - _user_data_t *user_data = (_user_data_t *) user_data_; - assert (!user_data->is_open); - user_data->is_open = true; - user_data->path_start_x = user_data->path_last_x = to_x; - user_data->path_start_y = user_data->path_last_y = to_y; + _draw_data_t *draw_data = (_draw_data_t *) draw_data_; + assert (!draw_data->is_open); + draw_data->is_open = true; + draw_data->path_start_x = draw_data->path_last_x = to_x; + draw_data->path_start_y = draw_data->path_last_y = to_y; } static void -_line_to (float to_x, float to_y, void *user_data_) +_line_to (hb_draw_funcs_t *dfuncs, void *draw_data_, + float to_x, float to_y, + void *user_data) { - _user_data_t *user_data = (_user_data_t *) user_data_; - assert (user_data->is_open); - assert (user_data->path_last_x != to_x || user_data->path_last_y != to_y); - ++user_data->path_len; - user_data->path_last_x = to_x; - user_data->path_last_y = to_y; + _draw_data_t *draw_data = (_draw_data_t *) draw_data_; + assert (draw_data->is_open); + assert (draw_data->path_last_x != to_x || draw_data->path_last_y != to_y); + ++draw_data->path_len; + draw_data->path_last_x = to_x; + draw_data->path_last_y = to_y; } static void -_quadratic_to (float control_x, float control_y, - float to_x, float to_y, void *user_data_) +_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data_, + float control_x, float control_y, + float to_x, float to_y, + void *user_data) { - _user_data_t *user_data = (_user_data_t *) user_data_; - assert (user_data->is_open); - assert (user_data->path_last_x != control_x || user_data->path_last_y != control_y || - user_data->path_last_x != to_x || user_data->path_last_y != to_y); - ++user_data->path_len; - user_data->path_last_x = to_x; - user_data->path_last_y = to_y; + _draw_data_t *draw_data = (_draw_data_t *) draw_data_; + assert (draw_data->is_open); + assert (draw_data->path_last_x != control_x || draw_data->path_last_y != control_y || + draw_data->path_last_x != to_x || draw_data->path_last_y != to_y); + ++draw_data->path_len; + draw_data->path_last_x = to_x; + draw_data->path_last_y = to_y; } static void -_cubic_to (float control1_x, float control1_y, +_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data_, + float control1_x, float control1_y, float control2_x, float control2_y, - float to_x, float to_y, void *user_data_) + float to_x, float to_y, + void *user_data) { - _user_data_t *user_data = (_user_data_t *) user_data_; - assert (user_data->is_open); - assert (user_data->path_last_x != control1_x || user_data->path_last_y != control1_y || - user_data->path_last_x != control2_x || user_data->path_last_y != control2_y || - user_data->path_last_x != to_x || user_data->path_last_y != to_y); - ++user_data->path_len; - user_data->path_last_x = to_x; - user_data->path_last_y = to_y; + _draw_data_t *draw_data = (_draw_data_t *) draw_data_; + assert (draw_data->is_open); + assert (draw_data->path_last_x != control1_x || draw_data->path_last_y != control1_y || + draw_data->path_last_x != control2_x || draw_data->path_last_y != control2_y || + draw_data->path_last_x != to_x || draw_data->path_last_y != to_y); + ++draw_data->path_len; + draw_data->path_last_x = to_x; + draw_data->path_last_y = to_y; } static void -_close_path (void *user_data_) +_close_path (hb_draw_funcs_t *dfuncs, void *draw_data_, + void *user_data) { - _user_data_t *user_data = (_user_data_t *) user_data_; - assert (user_data->is_open && user_data->path_len != 0); - user_data->path_len = 0; - user_data->is_open = false; - assert (user_data->path_start_x == user_data->path_last_x && - user_data->path_start_y == user_data->path_last_y); + _draw_data_t *draw_data = (_draw_data_t *) draw_data_; + assert (draw_data->is_open && draw_data->path_len != 0); + draw_data->path_len = 0; + draw_data->is_open = false; + assert (draw_data->path_start_x == draw_data->path_last_x && + draw_data->path_start_y == draw_data->path_last_y); } /* Similar to test-ot-face.c's #test_font() */ @@ -133,20 +142,20 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) unsigned glyph_count = hb_face_get_glyph_count (face); glyph_count = glyph_count > 16 ? 16 : glyph_count; - _user_data_t user_data = {false, 0, 0, 0, 0, 0}; + _draw_data_t draw_data = {false, 0, 0, 0, 0, 0}; hb_draw_funcs_t *funcs = hb_draw_funcs_create (); - hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) _move_to); - hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) _line_to); - hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) _quadratic_to); - hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) _cubic_to); - hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) _close_path); + hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) _move_to, nullptr, nullptr); + hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) _line_to, nullptr, nullptr); + hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) _quadratic_to, nullptr, nullptr); + hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) _cubic_to, nullptr, nullptr); + hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) _close_path, nullptr, nullptr); volatile unsigned counter = !glyph_count; hb_set_t *set = hb_set_create (); for (unsigned gid = 0; gid < glyph_count; ++gid) { - hb_font_draw_glyph (font, gid, funcs, &user_data); - assert (!user_data.is_open); + hb_font_draw_glyph (font, gid, funcs, &draw_data); + assert (!draw_data.is_open); /* Glyph extents also may practices the similar path, call it now that is related */ hb_glyph_extents_t extents;