From 24a00e7f84a9b07b9e1460a6966e13d930684b3e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Mar 2025 02:11:38 -0600 Subject: [PATCH] [COLRv1] Push font transform trickery to hb-cairo This simplifies the renderers but pushes the burdon to clients of the paint API. I am ambivalent about this change. All paint clients need to be updated. This reduces one vector of allocations from hb-fontations paint implementation however. --- src/OT/Color/COLR/COLR.hh | 9 --------- src/fontations/lib.rs | 13 ------------- src/hb-cairo.cc | 6 +++++- src/hb-ft-colr.hh | 7 ------- 4 files changed, 5 insertions(+), 30 deletions(-) diff --git a/src/OT/Color/COLR/COLR.hh b/src/OT/Color/COLR/COLR.hh index 16cd96e32..55bb68d1c 100644 --- a/src/OT/Color/COLR/COLR.hh +++ b/src/OT/Color/COLR/COLR.hh @@ -938,13 +938,9 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { TRACE_PAINT (this); - c->funcs->push_inverse_font_transform (c->data, c->font); c->funcs->push_clip_glyph (c->data, gid, c->font); - c->funcs->push_font_transform (c->data, c->font); c->recurse (this+paint); - c->funcs->pop_transform (c->data); c->funcs->pop_clip (c->data); - c->funcs->pop_transform (c->data); } HBUINT8 format; /* format = 10 */ @@ -2819,13 +2815,8 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (unlikely (!node.visit (gid))) return; - c->funcs->push_inverse_font_transform (c->data, c->font); if (c->funcs->color_glyph (c->data, gid, c->font)) - { - c->funcs->pop_transform (c->data); return; - } - c->funcs->pop_transform (c->data); const COLR *colr_table = c->get_colr_table (); const Paint *paint = colr_table->get_base_glyph_paint (gid); diff --git a/src/fontations/lib.rs b/src/fontations/lib.rs index c9ba7d705..8dd6b5860 100644 --- a/src/fontations/lib.rs +++ b/src/fontations/lib.rs @@ -416,7 +416,6 @@ struct HbColorPainter<'a> { color_records: &'a [ColorRecord], foreground: hb_color_t, composite_mode: Vec, - clip_transform_stack: Vec, } impl HbColorPainter<'_> { @@ -546,20 +545,16 @@ impl ColorPainter for HbColorPainter<'_> { } fn push_clip_glyph(&mut self, glyph: GlyphId) { let gid = u32::from(glyph); - self.clip_transform_stack.push(true); unsafe { - hb_paint_push_inverse_font_transform(self.paint_funcs, self.paint_data, self.font); hb_paint_push_clip_glyph( self.paint_funcs, self.paint_data, gid as hb_codepoint_t, self.font, ); - hb_paint_push_font_transform(self.paint_funcs, self.paint_data, self.font); } } fn push_clip_box(&mut self, bbox: BoundingBox) { - self.clip_transform_stack.push(false); unsafe { hb_paint_push_clip_rectangle( self.paint_funcs, @@ -572,16 +567,9 @@ impl ColorPainter for HbColorPainter<'_> { } } fn pop_clip(&mut self) { - let pop_transforms = self.clip_transform_stack.pop().unwrap_or(false); - if pop_transforms { - self.pop_transform(); - } unsafe { hb_paint_pop_clip(self.paint_funcs, self.paint_data); } - if pop_transforms { - self.pop_transform(); - } } fn fill(&mut self, brush: Brush) { match brush { @@ -767,7 +755,6 @@ extern "C" fn _hb_fontations_paint_glyph( color_records, foreground, composite_mode: Vec::new(), - clip_transform_stack: Vec::new(), }; unsafe { hb_paint_push_font_transform(paint_funcs, paint_data, font); diff --git a/src/hb-cairo.cc b/src/hb-cairo.cc index 89332d715..35c941cdf 100644 --- a/src/hb-cairo.cc +++ b/src/hb-cairo.cc @@ -193,7 +193,7 @@ hb_cairo_paint_color_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, } static void -hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, +hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs, void *paint_data, hb_codepoint_t glyph, hb_font_t *font, @@ -204,7 +204,11 @@ hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, cairo_save (cr); cairo_new_path (cr); + + hb_paint_push_inverse_font_transform (pfuncs, paint_data, font); hb_font_draw_glyph (font, glyph, hb_cairo_draw_get_funcs (), cr); + hb_paint_push_font_transform (pfuncs, paint_data, font); + cairo_close_path (cr); cairo_clip (cr); } diff --git a/src/hb-ft-colr.hh b/src/hb-ft-colr.hh index b41d55553..c41ec8470 100644 --- a/src/hb-ft-colr.hh +++ b/src/hb-ft-colr.hh @@ -316,15 +316,11 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_GLYPH: { - c->funcs->push_inverse_font_transform (c->data, c->font); c->ft_font->lock.unlock (); c->funcs->push_clip_glyph (c->data, paint.u.glyph.glyphID, c->font); c->ft_font->lock.lock (); - c->funcs->push_font_transform (c->data, c->font); c->recurse (paint.u.glyph.paint); - c->funcs->pop_transform (c->data); c->funcs->pop_clip (c->data); - c->funcs->pop_transform (c->data); } break; case FT_COLR_PAINTFORMAT_COLR_GLYPH: @@ -335,16 +331,13 @@ _hb_ft_paint (hb_ft_paint_context_t *c, if (unlikely (!node.visit (gid))) return; - c->funcs->push_inverse_font_transform (c->data, c->font); c->ft_font->lock.unlock (); if (c->funcs->color_glyph (c->data, gid, c->font)) { c->ft_font->lock.lock (); - c->funcs->pop_transform (c->data); return; } c->ft_font->lock.lock (); - c->funcs->pop_transform (c->data); FT_OpaquePaint other_paint = {0}; if (FT_Get_Color_Glyph_Paint (ft_face, gid,