[paint] Add push_font_transform() / push_inverse_font_transform()

Fixes https://github.com/harfbuzz/harfbuzz/issues/5146
This commit is contained in:
Behdad Esfahbod 2025-03-15 14:37:44 -06:00
parent e6519fcb2b
commit 000a0ad7a6
7 changed files with 63 additions and 62 deletions

View file

@ -292,6 +292,8 @@ hb_paint_custom_palette_color_func_t
hb_paint_funcs_set_custom_palette_color_func
hb_paint_push_transform
hb_paint_push_font_transform
hb_paint_push_inverse_font_transform
hb_paint_pop_transform
hb_paint_color_glyph
hb_paint_push_clip_glyph

View file

@ -938,9 +938,9 @@ struct PaintGlyph
void paint_glyph (hb_paint_context_t *c) const
{
TRACE_PAINT (this);
c->funcs->push_inverse_root_transform (c->data, c->font);
c->funcs->push_inverse_font_transform (c->data, c->font);
c->funcs->push_clip_glyph (c->data, gid, c->font);
c->funcs->push_root_transform (c->data, 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);
@ -2727,7 +2727,7 @@ struct COLR
}
}
c.funcs->push_root_transform (c.data, font);
c.funcs->push_font_transform (c.data, font);
if (is_bounded)
c.recurse (*paint);
@ -2817,7 +2817,7 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
if (unlikely (!node.visit (gid)))
return;
c->funcs->push_inverse_root_transform (c->data, c->font);
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);

View file

@ -413,53 +413,6 @@ struct HbColorPainter<'a> {
}
impl HbColorPainter<'_> {
fn push_root_transform(&mut self) {
let font = self.font;
let face = unsafe { hb_font_get_face(font) };
let upem = unsafe { hb_face_get_upem(face) };
let mut x_scale: i32 = 0;
let mut y_scale: i32 = 0;
unsafe {
hb_font_get_scale(font, &mut x_scale, &mut y_scale);
}
let slant = unsafe { hb_font_get_synthetic_slant(font) };
let slant = if y_scale != 0 {
slant as f32 * x_scale as f32 / y_scale as f32
} else {
0.
};
self.push_transform(Transform {
xx: x_scale as f32 / upem as f32,
yx: 0.0,
xy: slant * y_scale as f32 / upem as f32,
yy: y_scale as f32 / upem as f32,
dx: 0.0,
dy: 0.0,
});
}
fn push_inverse_root_transform(&mut self) {
let font = self.font;
let face = unsafe { hb_font_get_face(font) };
let upem = unsafe { hb_face_get_upem(face) };
let mut x_scale: i32 = 0;
let mut y_scale: i32 = 0;
unsafe {
hb_font_get_scale(font, &mut x_scale, &mut y_scale);
}
let slant = unsafe { hb_font_get_synthetic_slant(font) };
self.push_transform(Transform {
xx: upem as f32 / x_scale as f32,
yx: 0.0,
xy: -slant * upem as f32 / x_scale as f32,
yy: upem as f32 / y_scale as f32,
dx: 0.0,
dy: 0.0,
});
}
fn lookup_color(&self, color_index: u16, alpha: f32) -> hb_color_t {
if color_index == 0xFFFF {
// Apply alpha to foreground color
@ -587,16 +540,16 @@ impl ColorPainter for HbColorPainter<'_> {
fn push_clip_glyph(&mut self, glyph: GlyphId) {
let gid = u32::from(glyph);
self.clip_transform_stack.push(true);
self.push_inverse_root_transform();
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);
}
self.push_root_transform();
}
fn push_clip_box(&mut self, bbox: BoundingBox) {
self.clip_transform_stack.push(false);
@ -809,7 +762,9 @@ extern "C" fn _hb_fontations_paint_glyph(
composite_mode: Vec::new(),
clip_transform_stack: Vec::new(),
};
painter.push_root_transform();
unsafe {
hb_paint_push_font_transform(paint_funcs, paint_data, font);
}
let _ = color_glyph.paint(location, &mut painter);
}

View file

@ -316,11 +316,11 @@ _hb_ft_paint (hb_ft_paint_context_t *c,
break;
case FT_COLR_PAINTFORMAT_GLYPH:
{
c->funcs->push_inverse_root_transform (c->data, c->font);
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_root_transform (c->data, c->font);
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);
@ -335,7 +335,7 @@ _hb_ft_paint (hb_ft_paint_context_t *c,
if (unlikely (!node.visit (gid)))
return;
c->funcs->push_inverse_root_transform (c->data, c->font);
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))
{
@ -536,7 +536,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font,
palette_array, palette_index, foreground);
hb_decycler_node_t node2 (ce.glyphs_decycler);
node2.visit (gid);
ce.funcs->push_root_transform (ce.data, font);
ce.funcs->push_font_transform (ce.data, font);
ce.recurse (paint);
ce.funcs->pop_transform (ce.data);
hb_extents_t extents = extents_data.get_extents ();
@ -549,7 +549,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font,
extents.ymax);
}
c.funcs->push_root_transform (c.data, font);
c.funcs->push_font_transform (c.data, font);
if (is_bounded)
{

View file

@ -464,6 +464,42 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data,
funcs->push_transform (paint_data, xx, yx, xy, yy, dx, dy);
}
/**
* hb_paint_push_font_transform:
* @funcs: paint functions
* @paint_data: associated data passed by the caller
* @font: a font
*
* Push the transform reflecting the font's scale and slant
* settings onto the paint functions.
*
* XSince: REPLACEME
*/
void
hb_paint_push_font_transform (hb_paint_funcs_t *funcs, void *paint_data,
const hb_font_t *font)
{
funcs->push_font_transform (paint_data, font);
}
/**
* hb_paint_push_inverse_font_transform:
* @funcs: paint functions
* @paint_data: associated data passed by the caller
* @font: a font
*
* Push the inverse of the transform reflecting the font's
* scale and slant settings onto the paint functions.
*
* XSince: REPLACEME
*/
void
hb_paint_push_inverse_font_transform (hb_paint_funcs_t *funcs, void *paint_data,
const hb_font_t *font)
{
funcs->push_inverse_font_transform (paint_data, font);
}
/**
* hb_paint_pop_transform:
* @funcs: paint functions

View file

@ -956,6 +956,14 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data,
float xy, float yy,
float dx, float dy);
HB_EXTERN void
hb_paint_push_font_transform (hb_paint_funcs_t *funcs, void *paint_data,
const hb_font_t *font);
HB_EXTERN void
hb_paint_push_inverse_font_transform (hb_paint_funcs_t *funcs, void *paint_data,
const hb_font_t *font);
HB_EXTERN void
hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data);

View file

@ -157,7 +157,7 @@ struct hb_paint_funcs_t
/* Internal specializations. */
void push_root_transform (void *paint_data,
void push_font_transform (void *paint_data,
const hb_font_t *font)
{
float upem = font->face->get_upem ();
@ -168,8 +168,8 @@ struct hb_paint_funcs_t
xscale/upem, 0, slant * yscale/upem, yscale/upem, 0, 0);
}
void push_inverse_root_transform (void *paint_data,
hb_font_t *font)
void push_inverse_font_transform (void *paint_data,
const hb_font_t *font)
{
float upem = font->face->get_upem ();
int xscale = font->x_scale ? font->x_scale : upem;