[COLRv1] Implement recursive clip boxes

Tests need update.

hb-view test_glyphs-glyf_colr_1_variable.ttf -u f0c00
This commit is contained in:
Behdad Esfahbod 2023-01-16 16:27:04 -07:00
parent f02c4ebb40
commit e4a41f5e16
2 changed files with 40 additions and 15 deletions

View File

@ -1991,9 +1991,7 @@ struct COLR
this+varIdxMap,
hb_array (font->coords, font->num_coords));
if ((this+clipList).get_extents (glyph,
extents,
instancer))
if (get_clip (glyph, extents, instancer))
{
font->scale_glyph_extents (extents);
return true;
@ -2025,6 +2023,15 @@ struct COLR
return false;
}
bool get_clip (hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
const VarStoreInstancer instancer) const
{
return (this+clipList).get_extents (glyph,
extents,
instancer);
}
bool
paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette, hb_color_t foreground, bool clip = true) const
{
@ -2048,9 +2055,7 @@ struct COLR
if (clip)
{
hb_glyph_extents_t extents;
if ((this+clipList).get_extents (glyph,
&extents,
instancer))
if (get_clip (glyph, &extents, instancer))
{
font->scale_glyph_extents (&extents);
c.funcs->push_clip_rectangle (c.data,
@ -2163,9 +2168,21 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
const COLR *colr_table = c->get_colr_table ();
const Paint *paint = colr_table->get_base_glyph_paint (gid);
// TODO apply clipbox
hb_glyph_extents_t extents = {0};
bool has_clip_box = colr_table->get_clip (gid, &extents, c->instancer);
if (has_clip_box)
c->funcs->push_clip_rectangle (c->data,
extents.x_bearing,
extents.y_bearing + extents.height,
extents.x_bearing + extents.width,
extents.y_bearing);
if (paint)
c->recurse (*paint);
if (has_clip_box)
c->funcs->pop_clip (c->data);
}
} /* namespace OT */

View File

@ -306,17 +306,25 @@ _hb_ft_paint (hb_ft_paint_context_t *c,
FT_ClipBox clip_box;
has_clip_box = FT_Get_Color_Glyph_ClipBox (ft_face, paint.u.colr_glyph.glyphID, &clip_box);
/* The FreeType ClipBox is in scaled coordinates, whereas we need
* unscaled clipbox here. Oh well... */
has_clip_box = false;
if (has_clip_box)
{
/* The FreeType ClipBox is in scaled coordinates, whereas we need
* unscaled clipbox here. Oh well...
*/
float upem = c->font->face->get_upem ();
float xscale = upem / (c->font->x_scale ? c->font->x_scale : upem);
float yscale = upem / (c->font->y_scale ? c->font->y_scale : upem);
c->funcs->push_clip_rectangle (c->data,
clip_box.bottom_left.x / 64.f,
clip_box.bottom_left.y / 64.f,
clip_box.top_right.x / 64.f,
clip_box.top_right.y / 64.f);
clip_box.bottom_left.x * xscale,
clip_box.bottom_left.y * yscale,
clip_box.top_right.x * xscale,
clip_box.top_right.y * yscale);
}
c->recurse (other_paint);
if (has_clip_box)
c->funcs->pop_clip (c->data);
}