From 74527670fc5b0517e1d2cba2c26e3695547302e1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 14 Aug 2023 15:57:24 -0600 Subject: [PATCH] [COLR/cairo] Add paint_color_glyph func Implement in cairo to use scaled-font's glyph cache. --- src/OT/Color/COLR/COLR.hh | 4 +++ src/hb-cairo.cc | 19 +++++++++++++++ src/hb-paint.cc | 25 +++++++++++++++++++ src/hb-paint.h | 51 +++++++++++++++++++++++++++++++++++++++ src/hb-paint.hh | 8 ++++++ 5 files changed, 107 insertions(+) diff --git a/src/OT/Color/COLR/COLR.hh b/src/OT/Color/COLR/COLR.hh index a762959f1..717d2b4e8 100644 --- a/src/OT/Color/COLR/COLR.hh +++ b/src/OT/Color/COLR/COLR.hh @@ -2436,6 +2436,10 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); + + if (c->funcs->color_glyph (c->data, gid, c->font)) + return; + const COLR *colr_table = c->get_colr_table (); const Paint *paint = colr_table->get_base_glyph_paint (gid); diff --git a/src/hb-cairo.cc b/src/hb-cairo.cc index 68c7bc064..6c80dd55a 100644 --- a/src/hb-cairo.cc +++ b/src/hb-cairo.cc @@ -166,6 +166,24 @@ hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED, cairo_restore (cr); } +static hb_bool_t +hb_cairo_paint_color_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data HB_UNUSED) +{ + hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data; + cairo_t *cr = c->cr; + + cairo_glyph_t cairo_glyph = { glyph, 0, 0 }; + cairo_set_scaled_font (cr, c->scaled_font); + cairo_set_font_size (cr, hb_face_get_upem (hb_font_get_face (font))); + cairo_show_glyphs (cr, &cairo_glyph, 1); + + return true; +} + static void hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, void *paint_data, @@ -397,6 +415,7 @@ static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t< 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_color_glyph_func (funcs, hb_cairo_paint_color_glyph, nullptr, nullptr); hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_cairo_push_clip_glyph, nullptr, nullptr); hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_cairo_push_clip_rectangle, nullptr, nullptr); hb_paint_funcs_set_pop_clip_func (funcs, hb_cairo_pop_clip, nullptr, nullptr); diff --git a/src/hb-paint.cc b/src/hb-paint.cc index 28150f163..0a5384552 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -54,6 +54,12 @@ static void hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, void *user_data) {} +static hb_bool_t +hb_paint_color_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data) { return false; } + static void hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, @@ -473,6 +479,25 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) funcs->pop_transform (paint_data); } +/** + * hb_paint_color_glyph: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @glyph: the glyph ID + * @font: the font + * + * Perform a "color-glyph" paint operation. + * + * XSince: REPLACEME + */ +hb_bool_t +hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font) +{ + return funcs->color_glyph (paint_data, glyph, font); +} + /** * hb_paint_push_clip_glyph: * @funcs: paint functions diff --git a/src/hb-paint.h b/src/hb-paint.h index 543382780..1a7e14d62 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -136,6 +136,35 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, void *paint_data, void *user_data); +/** + * hb_paint_color_glyph_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @glyph: the glyph ID + * @font: the font + * @user_data: User data pointer passed to hb_paint_funcs_set_color_glyph_func() + * + * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index. + * + * XXX + * + * The coordinates of the glyph outline are interpreted according + * to the current transform. + * + * This clip is applied in addition to the current clip, + * and remains in effect until a matching call to + * the #hb_paint_funcs_pop_clip_func_t vfunc. + * + * Return value: %true if the glyph was painted, %false otherwise. + * + * XSince: REPLACEME + */ +typedef hb_bool_t (*hb_paint_color_glyph_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data); + /** * hb_paint_push_clip_glyph_func_t: * @funcs: paint functions object @@ -723,6 +752,23 @@ hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, void *user_data, hb_destroy_func_t destroy); +/** + * hb_paint_funcs_set_color_glyph_func: + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The color-glyph callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the color-glyph callback on the paint functions struct. + * + * Since: 7.0.0 + */ +HB_EXTERN void +hb_paint_funcs_set_color_glyph_func (hb_paint_funcs_t *funcs, + hb_paint_color_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy); + /** * hb_paint_funcs_set_push_clip_glyph_func: * @funcs: A paint functions struct @@ -922,6 +968,11 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); +HB_EXTERN hb_bool_t +hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font); + HB_EXTERN void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, diff --git a/src/hb-paint.hh b/src/hb-paint.hh index d291a4b97..56b790dbe 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -32,6 +32,7 @@ #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ HB_PAINT_FUNC_IMPLEMENT (pop_transform) \ + HB_PAINT_FUNC_IMPLEMENT (color_glyph) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \ HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ @@ -77,6 +78,13 @@ struct hb_paint_funcs_t void pop_transform (void *paint_data) { func.pop_transform (this, paint_data, !user_data ? nullptr : user_data->pop_transform); } + bool color_glyph (void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font) + { return func.color_glyph (this, paint_data, + glyph, + font, + !user_data ? nullptr : user_data->push_clip_glyph); } void push_clip_glyph (void *paint_data, hb_codepoint_t glyph, hb_font_t *font)