[hb-cairo] Lazy-load funcs thread-safe

This commit is contained in:
Behdad Esfahbod 2022-12-25 17:09:43 -07:00
parent 49a6aa97d9
commit 9e61fd7705
2 changed files with 56 additions and 19 deletions

View File

@ -30,8 +30,10 @@
#include "hb-cairo-utils.hh" #include "hb-cairo-utils.hh"
#include "hb-machinery.hh"
#include "hb-utf.hh" #include "hb-utf.hh"
static void static void
hb_cairo_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED, hb_cairo_move_to (hb_draw_funcs_t *dfuncs HB_UNUSED,
void *draw_data, void *draw_data,
@ -84,23 +86,40 @@ hb_cairo_close_path (hb_draw_funcs_t *dfuncs HB_UNUSED,
cairo_close_path (cr); cairo_close_path (cr);
} }
static hb_draw_funcs_t * static inline void free_static_cairo_draw_funcs ();
get_cairo_draw_funcs (void)
{
static hb_draw_funcs_t *funcs;
if (!funcs) static struct hb_cairo_draw_funcs_lazy_loader_t : hb_draw_funcs_lazy_loader_t<hb_cairo_draw_funcs_lazy_loader_t>
{
static hb_draw_funcs_t *create ()
{ {
funcs = hb_draw_funcs_create (); hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
hb_draw_funcs_set_move_to_func (funcs, hb_cairo_move_to, nullptr, nullptr); hb_draw_funcs_set_move_to_func (funcs, hb_cairo_move_to, nullptr, nullptr);
hb_draw_funcs_set_line_to_func (funcs, hb_cairo_line_to, nullptr, nullptr); hb_draw_funcs_set_line_to_func (funcs, hb_cairo_line_to, nullptr, nullptr);
hb_draw_funcs_set_cubic_to_func (funcs, hb_cairo_cubic_to, nullptr, nullptr); hb_draw_funcs_set_cubic_to_func (funcs, hb_cairo_cubic_to, nullptr, nullptr);
hb_draw_funcs_set_close_path_func (funcs, hb_cairo_close_path, nullptr, nullptr); hb_draw_funcs_set_close_path_func (funcs, hb_cairo_close_path, nullptr, nullptr);
}
hb_draw_funcs_make_immutable (funcs);
hb_atexit (free_static_cairo_draw_funcs);
return funcs; return funcs;
}
} static_cairo_draw_funcs;
static inline
void free_static_cairo_draw_funcs ()
{
static_cairo_draw_funcs.free_instance ();
} }
static hb_draw_funcs_t *
hb_cairo_draw_get_funcs ()
{
return static_cairo_draw_funcs.get_unconst ();
}
#ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC #ifdef HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC
static void static void
@ -142,7 +161,7 @@ hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED,
cairo_save (cr); cairo_save (cr);
cairo_new_path (cr); cairo_new_path (cr);
hb_font_draw_glyph (font, glyph, get_cairo_draw_funcs (), cr); hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr);
cairo_close_path (cr); cairo_close_path (cr);
cairo_clip (cr); cairo_clip (cr);
} }
@ -271,14 +290,13 @@ hb_cairo_paint_sweep_gradient (hb_paint_funcs_t *pfuncs HB_UNUSED,
hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle); hb_cairo_paint_sweep_gradient (cr, color_line, x0, y0, start_angle, end_angle);
} }
static hb_paint_funcs_t * static inline void free_static_cairo_paint_funcs ();
get_cairo_paint_funcs ()
{
static hb_paint_funcs_t *funcs;
if (!funcs) static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t<hb_cairo_paint_funcs_lazy_loader_t>
{
static hb_paint_funcs_t *create ()
{ {
funcs = hb_paint_funcs_create (); hb_paint_funcs_t *funcs = hb_paint_funcs_create ();
hb_paint_funcs_set_push_transform_func (funcs, hb_cairo_push_transform, nullptr, nullptr); hb_paint_funcs_set_push_transform_func (funcs, hb_cairo_push_transform, nullptr, nullptr);
hb_paint_funcs_set_pop_transform_func (funcs, hb_cairo_pop_transform, nullptr, nullptr); hb_paint_funcs_set_pop_transform_func (funcs, hb_cairo_pop_transform, nullptr, nullptr);
@ -292,9 +310,25 @@ get_cairo_paint_funcs ()
hb_paint_funcs_set_linear_gradient_func (funcs, hb_cairo_paint_linear_gradient, nullptr, nullptr); hb_paint_funcs_set_linear_gradient_func (funcs, hb_cairo_paint_linear_gradient, nullptr, nullptr);
hb_paint_funcs_set_radial_gradient_func (funcs, hb_cairo_paint_radial_gradient, nullptr, nullptr); hb_paint_funcs_set_radial_gradient_func (funcs, hb_cairo_paint_radial_gradient, nullptr, nullptr);
hb_paint_funcs_set_sweep_gradient_func (funcs, hb_cairo_paint_sweep_gradient, nullptr, nullptr); hb_paint_funcs_set_sweep_gradient_func (funcs, hb_cairo_paint_sweep_gradient, nullptr, nullptr);
}
hb_paint_funcs_make_immutable (funcs);
hb_atexit (free_static_cairo_paint_funcs);
return funcs; return funcs;
}
} static_cairo_paint_funcs;
static inline
void free_static_cairo_paint_funcs ()
{
static_cairo_paint_funcs.free_instance ();
}
static hb_paint_funcs_t *
hb_cairo_paint_get_funcs ()
{
return static_cairo_paint_funcs.get_unconst ();
} }
static cairo_status_t static cairo_status_t
@ -321,7 +355,7 @@ render_glyph (cairo_scaled_font_t *scaled_font,
hb_font_get_scale (font, &x_scale, &y_scale); hb_font_get_scale (font, &x_scale, &y_scale);
cairo_scale (cr, +1./x_scale, -1./y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale);
hb_font_draw_glyph (font, glyph, get_cairo_draw_funcs (), cr); hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr);
cairo_fill (cr); cairo_fill (cr);
@ -364,7 +398,7 @@ render_color_glyph (cairo_scaled_font_t *scaled_font,
hb_font_get_scale (font, &x_scale, &y_scale); hb_font_get_scale (font, &x_scale, &y_scale);
cairo_scale (cr, +1./x_scale, -1./y_scale); cairo_scale (cr, +1./x_scale, -1./y_scale);
hb_font_paint_glyph (font, glyph, get_cairo_paint_funcs (), cr, palette, color); hb_font_paint_glyph (font, glyph, hb_cairo_paint_get_funcs (), cr, palette, color);
return CAIRO_STATUS_SUCCESS; return CAIRO_STATUS_SUCCESS;
} }

View File

@ -24,9 +24,12 @@
#include "hb.hh" #include "hb.hh"
#include "hb-paint-extents.hh" #include "hb-paint-extents.hh"
#include "hb-draw.h" #include "hb-draw.h"
#include "hb-machinery.hh" #include "hb-machinery.hh"
/* /*
* This file implements bounds-extraction as well as boundedness * This file implements bounds-extraction as well as boundedness
* computation of COLRv1 fonts as described in: * computation of COLRv1 fonts as described in: