[draw] Pass draw_helper_t itself around instead recreating it

Specially helpful if we want to change the design
This commit is contained in:
Ebrahim Byagowi 2020-02-26 17:40:44 +03:30
parent 1b8b863898
commit 9fe0dc3464
7 changed files with 60 additions and 67 deletions

View File

@ -246,10 +246,11 @@ hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
glyph >= font->face->get_num_glyphs ())) glyph >= font->face->get_num_glyphs ()))
return false; return false;
if (font->face->table.glyf->get_path (font, glyph, funcs, user_data)) return true; draw_helper_t draw_helper (funcs, user_data);
if (font->face->table.glyf->get_path (font, glyph, draw_helper)) return true;
#ifndef HB_NO_CFF #ifndef HB_NO_CFF
if (font->face->table.cff1->get_path (font, glyph, funcs, user_data)) return true; if (font->face->table.cff1->get_path (font, glyph, draw_helper)) return true;
if (font->face->table.cff2->get_path (font, glyph, funcs, user_data)) return true; if (font->face->table.cff2->get_path (font, glyph, draw_helper)) return true;
#endif #endif
return false; return false;

View File

@ -41,14 +41,14 @@ struct hb_draw_funcs_t
struct draw_helper_t struct draw_helper_t
{ {
void init (const hb_draw_funcs_t *funcs_, void *user_data_) draw_helper_t (const hb_draw_funcs_t *funcs_, void *user_data_)
{ {
funcs = funcs_; funcs = funcs_;
user_data = user_data_; user_data = user_data_;
path_open = false; path_open = false;
path_start_x = current_x = path_start_y = current_y = 0; path_start_x = current_x = path_start_y = current_y = 0;
} }
void fini () { end_path (); } ~draw_helper_t () { end_path (); }
void move_to (hb_position_t x, hb_position_t y) void move_to (hb_position_t x, hb_position_t y)
{ {

View File

@ -346,31 +346,26 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph
struct cff1_path_param_t struct cff1_path_param_t
{ {
cff1_path_param_t (const OT::cff1::accelerator_t *cff_, hb_font_t *font_, cff1_path_param_t (const OT::cff1::accelerator_t *cff_, hb_font_t *font_,
const hb_draw_funcs_t *funcs_, void *user_data_, draw_helper_t &draw_helper_, point_t *delta_)
point_t *delta_)
{ {
draw_helper = draw_helper_t (); draw_helper = &draw_helper_;
draw_helper.init (funcs_, user_data_);
funcs = funcs_;
user_data = user_data_;
cff = cff_; cff = cff_;
font = font_; font = font_;
delta = delta_; delta = delta_;
} }
~cff1_path_param_t () { draw_helper.fini (); }
void move_to (const point_t &p) void move_to (const point_t &p)
{ {
point_t point = p; point_t point = p;
if (delta) point.move (*delta); if (delta) point.move (*delta);
draw_helper.move_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ())); draw_helper->move_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
} }
void line_to (const point_t &p) void line_to (const point_t &p)
{ {
point_t point = p; point_t point = p;
if (delta) point.move (*delta); if (delta) point.move (*delta);
draw_helper.line_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ())); draw_helper->line_to (font->em_scalef_x (point.x.to_real ()), font->em_scalef_y (point.y.to_real ()));
} }
void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3) void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
@ -382,17 +377,17 @@ struct cff1_path_param_t
point2.move (*delta); point2.move (*delta);
point3.move (*delta); point3.move (*delta);
} }
draw_helper.cubic_to (font->em_scalef_x (point1.x.to_real ()), font->em_scalef_y (point1.y.to_real ()), draw_helper->cubic_to (font->em_scalef_x (point1.x.to_real ()), font->em_scalef_y (point1.y.to_real ()),
font->em_scalef_x (point2.x.to_real ()), font->em_scalef_y (point2.y.to_real ()), font->em_scalef_x (point2.x.to_real ()), font->em_scalef_y (point2.y.to_real ()),
font->em_scalef_x (point3.x.to_real ()), font->em_scalef_y (point3.y.to_real ())); font->em_scalef_x (point3.x.to_real ()), font->em_scalef_y (point3.y.to_real ()));
} }
void end_path () { draw_helper.end_path (); } void end_path () { draw_helper->end_path (); }
hb_font_t *font; hb_font_t *font;
const hb_draw_funcs_t *funcs; const hb_draw_funcs_t *funcs;
void *user_data; void *user_data;
draw_helper_t draw_helper; draw_helper_t *draw_helper;
point_t *delta; point_t *delta;
const OT::cff1::accelerator_t *cff; const OT::cff1::accelerator_t *cff;
@ -420,8 +415,7 @@ struct cff1_path_procs_path_t : path_procs_t<cff1_path_procs_path_t, cff1_cs_int
}; };
static bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph, static bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
const hb_draw_funcs_t *funcs, void *user_data, draw_helper_t &draw_helper, bool in_seac = false, point_t *delta = nullptr);
bool in_seac = false, point_t *delta = nullptr);
struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t> struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t>
{ {
@ -438,14 +432,14 @@ struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_pa
hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ()); hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
if (unlikely (!(!env.in_seac && base && accent if (unlikely (!(!env.in_seac && base && accent
&& _get_path (param.cff, param.font, base, param.funcs, param.user_data, true) && _get_path (param.cff, param.font, base, *param.draw_helper, true)
&& _get_path (param.cff, param.font, accent, param.funcs, param.user_data, true, &delta)))) && _get_path (param.cff, param.font, accent, *param.draw_helper, true, &delta))))
env.set_error (); env.set_error ();
} }
}; };
bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph, bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoint_t glyph,
const hb_draw_funcs_t *funcs, void *user_data, bool in_seac, point_t *delta) draw_helper_t &draw_helper, bool in_seac, point_t *delta)
{ {
if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false; if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
@ -454,20 +448,23 @@ bool _get_path (const OT::cff1::accelerator_t *cff, hb_font_t *font, hb_codepoin
const byte_str_t str = (*cff->charStrings)[glyph]; const byte_str_t str = (*cff->charStrings)[glyph];
interp.env.init (str, *cff, fd); interp.env.init (str, *cff, fd);
interp.env.set_in_seac (in_seac); interp.env.set_in_seac (in_seac);
cff1_path_param_t param (cff, font, funcs, user_data, delta); cff1_path_param_t param (cff, font, draw_helper, delta);
if (unlikely (!interp.interpret (param))) return false; if (unlikely (!interp.interpret (param))) return false;
/* Let's end the path specially since it is called inside seac also */
param.end_path ();
return true; return true;
} }
bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
const hb_draw_funcs_t *funcs, void *user_data) const
{ {
#ifdef HB_NO_OT_FONT_CFF #ifdef HB_NO_OT_FONT_CFF
/* XXX Remove check when this code moves to .hh file. */ /* XXX Remove check when this code moves to .hh file. */
return true; return true;
#endif #endif
return _get_path (this, font, glyph, funcs, user_data); return _get_path (this, font, glyph, draw_helper);
} }
struct get_seac_param_t struct get_seac_param_t

View File

@ -29,6 +29,7 @@
#include "hb-ot-cff-common.hh" #include "hb-ot-cff-common.hh"
#include "hb-subset-cff1.hh" #include "hb-subset-cff1.hh"
#include "hb-draw.hh"
#define HB_STRING_ARRAY_NAME cff1_std_strings #define HB_STRING_ARRAY_NAME cff1_std_strings
#define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh" #define HB_STRING_ARRAY_LIST "hb-ot-cff1-std-str.hh"
@ -1346,8 +1347,7 @@ struct cff1
HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const;
const hb_draw_funcs_t *funcs, void *user_data) const;
private: private:
struct gname_t struct gname_t

View File

@ -145,29 +145,27 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
struct cff2_path_param_t struct cff2_path_param_t
{ {
cff2_path_param_t (hb_font_t *font_, const hb_draw_funcs_t *funcs, void *user_data) cff2_path_param_t (hb_font_t *font_, draw_helper_t &draw_helper_)
{ {
draw_helper = draw_helper_t (); draw_helper = &draw_helper_;
draw_helper.init (funcs, user_data);
font = font_; font = font_;
} }
~cff2_path_param_t () { draw_helper.fini (); }
void move_to (const point_t &p) void move_to (const point_t &p)
{ draw_helper.move_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); } { draw_helper->move_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
void line_to (const point_t &p) void line_to (const point_t &p)
{ draw_helper.line_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); } { draw_helper->line_to (font->em_scalef_x (p.x.to_real ()), font->em_scalef_y (p.y.to_real ())); }
void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3) void cubic_to (const point_t &p1, const point_t &p2, const point_t &p3)
{ {
draw_helper.cubic_to (font->em_scalef_x (p1.x.to_real ()), font->em_scalef_y (p1.y.to_real ()), draw_helper->cubic_to (font->em_scalef_x (p1.x.to_real ()), font->em_scalef_y (p1.y.to_real ()),
font->em_scalef_x (p2.x.to_real ()), font->em_scalef_y (p2.y.to_real ()), font->em_scalef_x (p2.x.to_real ()), font->em_scalef_y (p2.y.to_real ()),
font->em_scalef_x (p3.x.to_real ()), font->em_scalef_y (p3.y.to_real ())); font->em_scalef_x (p3.x.to_real ()), font->em_scalef_y (p3.y.to_real ()));
} }
protected: protected:
draw_helper_t draw_helper; draw_helper_t *draw_helper;
hb_font_t *font; hb_font_t *font;
}; };
@ -194,8 +192,7 @@ struct cff2_path_procs_path_t : path_procs_t<cff2_path_procs_path_t, cff2_cs_int
struct cff2_cs_opset_path_t : cff2_cs_opset_t<cff2_cs_opset_path_t, cff2_path_param_t, cff2_path_procs_path_t> {}; struct cff2_cs_opset_path_t : cff2_cs_opset_t<cff2_cs_opset_path_t, cff2_path_param_t, cff2_path_procs_path_t> {};
bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const
const hb_draw_funcs_t *funcs, void *user_data) const
{ {
#ifdef HB_NO_OT_FONT_CFF #ifdef HB_NO_OT_FONT_CFF
/* XXX Remove check when this code moves to .hh file. */ /* XXX Remove check when this code moves to .hh file. */
@ -208,7 +205,7 @@ bool OT::cff2::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph,
cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t> interp; cff2_cs_interpreter_t<cff2_cs_opset_path_t, cff2_path_param_t> interp;
const byte_str_t str = (*charStrings)[glyph]; const byte_str_t str = (*charStrings)[glyph];
interp.env.init (str, *this, fd, font->coords, font->num_coords); interp.env.init (str, *this, fd, font->coords, font->num_coords);
cff2_path_param_t param (font, funcs, user_data); cff2_path_param_t param (font, draw_helper);
if (unlikely (!interp.interpret (param))) return false; if (unlikely (!interp.interpret (param))) return false;
return true; return true;
} }

View File

@ -29,6 +29,7 @@
#include "hb-ot-cff-common.hh" #include "hb-ot-cff-common.hh"
#include "hb-subset-cff2.hh" #include "hb-subset-cff2.hh"
#include "hb-draw.hh"
namespace CFF { namespace CFF {
@ -532,8 +533,7 @@ struct cff2
HB_INTERNAL bool get_extents (hb_font_t *font, HB_INTERNAL bool get_extents (hb_font_t *font,
hb_codepoint_t glyph, hb_codepoint_t glyph,
hb_glyph_extents_t *extents) const; hb_glyph_extents_t *extents) const;
HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, draw_helper_t &draw_helper) const;
const hb_draw_funcs_t *funcs, void *user_data) const;
}; };
typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t; typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t;

View File

@ -1032,7 +1032,7 @@ struct glyf
struct path_builder_t struct path_builder_t
{ {
hb_font_t *font; hb_font_t *font;
draw_helper_t draw_helper; draw_helper_t *draw_helper;
struct optional_point_t struct optional_point_t
{ {
@ -1047,11 +1047,10 @@ struct glyf
{ return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); } { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
} first_oncurve, first_offcurve, last_offcurve; } first_oncurve, first_offcurve, last_offcurve;
path_builder_t (hb_font_t *font_, const hb_draw_funcs_t *funcs, void *user_data) path_builder_t (hb_font_t *font_, draw_helper_t &draw_helper_)
{ {
font = font_; font = font_;
draw_helper = draw_helper_t (); draw_helper = &draw_helper_;
draw_helper.init (funcs, user_data);
first_oncurve = first_offcurve = last_offcurve = optional_point_t (); first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
} }
@ -1069,7 +1068,7 @@ struct glyf
if (is_on_curve) if (is_on_curve)
{ {
first_oncurve = p; first_oncurve = p;
draw_helper.move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y)); draw_helper->move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
} }
else else
{ {
@ -1078,7 +1077,7 @@ struct glyf
optional_point_t mid = first_offcurve.lerp (p, .5f); optional_point_t mid = first_offcurve.lerp (p, .5f);
first_oncurve = mid; first_oncurve = mid;
last_offcurve = p; last_offcurve = p;
draw_helper.move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); draw_helper->move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
} }
else else
first_offcurve = p; first_offcurve = p;
@ -1090,22 +1089,22 @@ struct glyf
{ {
if (is_on_curve) if (is_on_curve)
{ {
draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
font->em_scalef_x (p.x), font->em_scalef_y (p.y)); font->em_scalef_x (p.x), font->em_scalef_y (p.y));
last_offcurve = optional_point_t (); last_offcurve = optional_point_t ();
} }
else else
{ {
optional_point_t mid = last_offcurve.lerp (p, .5f); optional_point_t mid = last_offcurve.lerp (p, .5f);
draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
last_offcurve = p; last_offcurve = p;
} }
} }
else else
{ {
if (is_on_curve) if (is_on_curve)
draw_helper.line_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y)); draw_helper->line_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
else else
last_offcurve = p; last_offcurve = p;
} }
@ -1116,8 +1115,8 @@ struct glyf
if (!first_offcurve.is_null && !last_offcurve.is_null) if (!first_offcurve.is_null && !last_offcurve.is_null)
{ {
optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f); optional_point_t mid = last_offcurve.lerp (first_offcurve, .5f);
draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
font->em_scalef_x (mid.x), font->em_scalef_y (mid.y)); font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
last_offcurve = optional_point_t (); last_offcurve = optional_point_t ();
/* now check the rest */ /* now check the rest */
} }
@ -1125,21 +1124,21 @@ struct glyf
if (!first_offcurve.is_null && last_offcurve.is_null) if (!first_offcurve.is_null && last_offcurve.is_null)
{ {
if (!first_oncurve.is_null) if (!first_oncurve.is_null)
draw_helper.quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y), draw_helper->quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y),
font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
} }
else if (first_offcurve.is_null && !last_offcurve.is_null) else if (first_offcurve.is_null && !last_offcurve.is_null)
{ {
if (!first_oncurve.is_null) if (!first_oncurve.is_null)
draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y), draw_helper->quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
} }
else /* first_offcurve.is_null && last_offcurve.is_null */ else /* first_offcurve.is_null && last_offcurve.is_null */
if (!first_oncurve.is_null) if (!first_oncurve.is_null)
draw_helper.line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y)); draw_helper->line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
first_oncurve = first_offcurve = last_offcurve = optional_point_t (); first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
draw_helper.end_path (); draw_helper->end_path ();
} }
} }
void points_end () {} void points_end () {}
@ -1149,9 +1148,8 @@ struct glyf
}; };
bool bool
get_path (hb_font_t *font, hb_codepoint_t gid, get_path (hb_font_t *font, hb_codepoint_t gid, draw_helper_t &draw_helper) const
const hb_draw_funcs_t *funcs, void *user_data) const { return get_points (font, gid, path_builder_t (font, draw_helper)); }
{ return get_points (font, gid, path_builder_t (font, funcs, user_data)); }
private: private:
bool short_offset; bool short_offset;