[draw] Port glyf path extract to draw_helper_t
This commit is contained in:
parent
0ebf3a4e62
commit
073d4954e0
|
@ -43,30 +43,43 @@ struct draw_helper_t
|
||||||
{
|
{
|
||||||
void init (const hb_draw_funcs_t *funcs_, void *user_data_)
|
void init (const hb_draw_funcs_t *funcs_, void *user_data_)
|
||||||
{
|
{
|
||||||
path_open = false;
|
|
||||||
funcs = funcs_;
|
funcs = funcs_;
|
||||||
user_data = user_data_;
|
user_data = user_data_;
|
||||||
path_start_x = 0;
|
path_open = false;
|
||||||
path_start_y = 0;
|
path_start_x = current_x = path_start_y = current_y = 0;
|
||||||
path_last_x = 0;
|
|
||||||
path_last_y = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
void fini () { end_path (); }
|
void fini () { end_path (); }
|
||||||
|
|
||||||
void move_to (hb_position_t x, hb_position_t y)
|
void move_to (hb_position_t x, hb_position_t y)
|
||||||
{
|
{
|
||||||
if (path_open) end_path ();
|
if (path_open) end_path ();
|
||||||
path_last_x = path_start_x = x;
|
current_x = path_start_x = x;
|
||||||
path_last_y = path_start_y = y;
|
current_y = path_start_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void line_to (hb_position_t x, hb_position_t y)
|
void line_to (hb_position_t x, hb_position_t y)
|
||||||
{
|
{
|
||||||
if (!path_open) start_path ();
|
if (!path_open) start_path ();
|
||||||
funcs->line_to (x, y, user_data);
|
funcs->line_to (x, y, user_data);
|
||||||
path_last_x = x;
|
current_x = x;
|
||||||
path_last_y = y;
|
current_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
quadratic_to (hb_position_t control_x, hb_position_t control_y,
|
||||||
|
hb_position_t to_x, hb_position_t to_y)
|
||||||
|
{
|
||||||
|
if (!path_open) start_path ();
|
||||||
|
if (funcs->is_quadratic_to_set)
|
||||||
|
funcs->quadratic_to (control_x, control_y, to_x, to_y, user_data);
|
||||||
|
else
|
||||||
|
funcs->cubic_to (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);
|
||||||
|
current_x = to_x;
|
||||||
|
current_y = to_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -76,19 +89,20 @@ struct draw_helper_t
|
||||||
{
|
{
|
||||||
if (!path_open) start_path ();
|
if (!path_open) start_path ();
|
||||||
funcs->cubic_to (x1, y1, x2, y2, x3, y3, user_data);
|
funcs->cubic_to (x1, y1, x2, y2, x3, y3, user_data);
|
||||||
path_last_x = x3;
|
current_x = x3;
|
||||||
path_last_y = y3;
|
current_y = y3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_path ()
|
void end_path ()
|
||||||
{
|
{
|
||||||
if (path_open)
|
if (path_open)
|
||||||
{
|
{
|
||||||
if ((path_start_x != path_last_x) || (path_start_y != path_last_y))
|
if ((path_start_x != current_x) || (path_start_y != current_y))
|
||||||
funcs->line_to (path_start_x, path_start_y, user_data);
|
funcs->line_to (path_start_x, path_start_y, user_data);
|
||||||
funcs->close_path (user_data);
|
funcs->close_path (user_data);
|
||||||
}
|
}
|
||||||
path_open = false;
|
path_open = false;
|
||||||
|
path_start_x = current_x = path_start_y = current_y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -102,8 +116,8 @@ struct draw_helper_t
|
||||||
hb_position_t path_start_x;
|
hb_position_t path_start_x;
|
||||||
hb_position_t path_start_y;
|
hb_position_t path_start_y;
|
||||||
|
|
||||||
hb_position_t path_last_x;
|
hb_position_t current_x;
|
||||||
hb_position_t path_last_y;
|
hb_position_t current_y;
|
||||||
|
|
||||||
bool path_open;
|
bool path_open;
|
||||||
const hb_draw_funcs_t *funcs;
|
const hb_draw_funcs_t *funcs;
|
||||||
|
|
|
@ -1032,11 +1032,7 @@ struct glyf
|
||||||
struct path_builder_t
|
struct path_builder_t
|
||||||
{
|
{
|
||||||
hb_font_t *font;
|
hb_font_t *font;
|
||||||
const hb_draw_funcs_t *funcs;
|
draw_helper_t draw_helper;
|
||||||
void *user_data;
|
|
||||||
void (*quad_to) (hb_font_t *, const hb_draw_funcs_t *,
|
|
||||||
float, float, float, float, float, float,
|
|
||||||
void *);
|
|
||||||
|
|
||||||
struct optional_point_t
|
struct optional_point_t
|
||||||
{
|
{
|
||||||
|
@ -1049,55 +1045,23 @@ struct glyf
|
||||||
|
|
||||||
optional_point_t lerp (optional_point_t p, float t)
|
optional_point_t lerp (optional_point_t p, float t)
|
||||||
{ 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, current;
|
} 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_, const hb_draw_funcs_t *funcs, void *user_data)
|
||||||
{
|
{
|
||||||
font = font_;
|
font = font_;
|
||||||
funcs = funcs_;
|
draw_helper = draw_helper_t ();
|
||||||
user_data = user_data_;
|
draw_helper.init (funcs, user_data);
|
||||||
quad_to = funcs->is_quadratic_to_set
|
first_oncurve = first_offcurve = last_offcurve = optional_point_t ();
|
||||||
? _normal_quadratic_to_call
|
|
||||||
: _translate_quadratic_to_cubic;
|
|
||||||
end_of_contour ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_of_contour ()
|
void end_of_contour ()
|
||||||
{ first_oncurve = first_offcurve = last_offcurve = current = optional_point_t (); }
|
{ first_oncurve = first_offcurve = last_offcurve = optional_point_t (); }
|
||||||
|
|
||||||
static void
|
|
||||||
_normal_quadratic_to_call (hb_font_t *font, const hb_draw_funcs_t *funcs,
|
|
||||||
float from_x HB_UNUSED, float from_y HB_UNUSED,
|
|
||||||
float control_x, float control_y,
|
|
||||||
float to_x, float to_y,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
funcs->quadratic_to (font->em_scalef_x (control_x), font->em_scalef_y (control_y),
|
|
||||||
font->em_scalef_x (to_x), font->em_scalef_y (to_y),
|
|
||||||
user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_translate_quadratic_to_cubic (hb_font_t *font, const hb_draw_funcs_t *funcs,
|
|
||||||
float from_x, float from_y,
|
|
||||||
float control_x, float control_y,
|
|
||||||
float to_x, float to_y,
|
|
||||||
void *user_data)
|
|
||||||
{
|
|
||||||
funcs->cubic_to (font->em_scalef_x ((from_x + 2.f * control_x) / 3.f),
|
|
||||||
font->em_scalef_y ((from_y + 2.f * control_y) / 3.f),
|
|
||||||
font->em_scalef_x ((to_x + 2.f * control_x) / 3.f),
|
|
||||||
font->em_scalef_y ((to_y + 2.f * control_y) / 3.f),
|
|
||||||
font->em_scalef_x (to_x),
|
|
||||||
font->em_scalef_y (to_y),
|
|
||||||
user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* based on https://github.com/RazrFalcon/ttf-parser/blob/master/src/glyf.rs#L292 */
|
/* based on https://github.com/RazrFalcon/ttf-parser/blob/master/src/glyf.rs#L292 */
|
||||||
void consume_point (const contour_point_t &point)
|
void consume_point (const contour_point_t &point)
|
||||||
{
|
{
|
||||||
/* Skip empty contours */
|
/* Skip empty contours */
|
||||||
if (unlikely (point.is_end_point && current.is_null && first_offcurve.is_null))
|
if (unlikely (point.is_end_point && first_oncurve.is_null && first_offcurve.is_null))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE;
|
bool is_on_curve = point.flag & Glyph::FLAG_ON_CURVE;
|
||||||
|
@ -1107,10 +1071,7 @@ struct glyf
|
||||||
if (is_on_curve)
|
if (is_on_curve)
|
||||||
{
|
{
|
||||||
first_oncurve = p;
|
first_oncurve = p;
|
||||||
funcs->move_to (font->em_scalef_x (p.x),
|
draw_helper.move_to (font->em_scalef_x (p.x), font->em_scalef_y (p.y));
|
||||||
font->em_scalef_y (p.y),
|
|
||||||
user_data);
|
|
||||||
current = p;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1119,10 +1080,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;
|
||||||
funcs->move_to (font->em_scalef_x (mid.x),
|
draw_helper.move_to (font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
|
||||||
font->em_scalef_y (mid.y),
|
|
||||||
user_data);
|
|
||||||
current = mid;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
first_offcurve = p;
|
first_offcurve = p;
|
||||||
|
@ -1134,30 +1092,22 @@ struct glyf
|
||||||
{
|
{
|
||||||
if (is_on_curve)
|
if (is_on_curve)
|
||||||
{
|
{
|
||||||
quad_to (font, funcs, current.x, current.y,
|
draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
|
||||||
last_offcurve.x, last_offcurve.y,
|
font->em_scalef_x (p.x), font->em_scalef_y (p.y));
|
||||||
p.x, p.y, user_data);
|
|
||||||
current = p;
|
|
||||||
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);
|
||||||
quad_to (font, funcs, current.x, current.y,
|
draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
|
||||||
last_offcurve.x, last_offcurve.y,
|
font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
|
||||||
mid.x, mid.y, user_data);
|
|
||||||
last_offcurve = p;
|
last_offcurve = p;
|
||||||
current = mid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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));
|
||||||
funcs->line_to (font->em_scalef_x (p.x),
|
|
||||||
font->em_scalef_y (p.y), user_data);
|
|
||||||
current = p;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
last_offcurve = p;
|
last_offcurve = p;
|
||||||
}
|
}
|
||||||
|
@ -1170,41 +1120,33 @@ 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);
|
||||||
quad_to (font, funcs, current.x, current.y,
|
draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
|
||||||
last_offcurve.x, last_offcurve.y, mid.x, mid.y,
|
font->em_scalef_x (mid.x), font->em_scalef_y (mid.y));
|
||||||
user_data);
|
|
||||||
current = mid;
|
|
||||||
last_offcurve = optional_point_t ();
|
last_offcurve = optional_point_t ();
|
||||||
}
|
}
|
||||||
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)
|
||||||
quad_to (font, funcs, current.x, current.y,
|
draw_helper.quadratic_to (font->em_scalef_x (first_offcurve.x), font->em_scalef_y (first_offcurve.y),
|
||||||
first_offcurve.x, first_offcurve.y,
|
font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
|
||||||
first_oncurve.x, first_oncurve.y,
|
|
||||||
user_data);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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)
|
||||||
quad_to (font, funcs, current.x, current.y,
|
draw_helper.quadratic_to (font->em_scalef_x (last_offcurve.x), font->em_scalef_y (last_offcurve.y),
|
||||||
last_offcurve.x, last_offcurve.y,
|
font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
|
||||||
first_oncurve.x, first_oncurve.y,
|
|
||||||
user_data);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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)
|
||||||
funcs->line_to (font->em_scalef_x (first_oncurve.x),
|
draw_helper.line_to (font->em_scalef_x (first_oncurve.x), font->em_scalef_y (first_oncurve.y));
|
||||||
font->em_scalef_y (first_oncurve.y),
|
|
||||||
user_data);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end_of_contour ();
|
end_of_contour ();
|
||||||
funcs->close_path (user_data);
|
draw_helper.end_path ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void points_end () {}
|
void points_end () {}
|
||||||
|
|
Loading…
Reference in New Issue