Merge pull request #4044 from harfbuzz/custom-palette

Custom palette
This commit is contained in:
Behdad Esfahbod 2023-01-18 21:50:10 -07:00 committed by GitHub
commit 0c7d386748
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 145 additions and 29 deletions

View File

@ -225,6 +225,8 @@ hb_draw_state_t
<SECTION>
<FILE>hb-paint</FILE>
HB_PAINT_PALETTE_INDEX_CUSTOM
hb_paint_funcs_t
hb_paint_funcs_create
hb_paint_funcs_get_empty
@ -270,6 +272,8 @@ hb_paint_push_group_func_t
hb_paint_funcs_set_push_group_func
hb_paint_pop_group_func_t
hb_paint_funcs_set_pop_group_func
hb_paint_custom_palette_color_func_t
hb_paint_funcs_set_custom_palette_color_func
hb_paint_push_transform
hb_paint_pop_transform
@ -283,6 +287,7 @@ hb_paint_radial_gradient
hb_paint_sweep_gradient
hb_paint_push_group
hb_paint_pop_group
hb_paint_custom_palette_color
</SECTION>
<SECTION>

View File

@ -67,7 +67,7 @@ public:
hb_paint_funcs_t *funcs;
void *data;
hb_font_t *font;
unsigned int palette;
unsigned int palette_index;
hb_color_t foreground;
VarStoreInstancer &instancer;
int depth_left = HB_MAX_NESTING_LEVEL;
@ -84,7 +84,7 @@ public:
funcs (funcs_),
data (data_),
font (font_),
palette (palette_),
palette_index (palette_),
foreground (foreground_),
instancer (instancer_)
{ }
@ -97,10 +97,16 @@ public:
if (color_index != 0xffff)
{
unsigned int clen = 1;
hb_face_t *face = hb_font_get_face (font);
if (palette_index != HB_PAINT_PALETTE_INDEX_CUSTOM)
{
unsigned int clen = 1;
hb_face_t *face = hb_font_get_face (font);
hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
}
else
color = funcs->custom_palette_color (data, color_index);
hb_ot_color_palette_get_colors (face, palette, color_index, &clen, &color);
*is_foreground = false;
}
@ -2033,12 +2039,12 @@ struct COLR
}
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
paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
{
VarStoreInstancer instancer (this+varStore,
this+varIdxMap,
hb_array (font->coords, font->num_coords));
hb_paint_context_t c (this, funcs, data, font, palette, foreground, instancer);
hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
if (version == 1)
{
@ -2071,7 +2077,7 @@ struct COLR
paint_glyph (font, glyph,
extents_funcs, &extents_data,
palette, foreground,
palette_index, foreground,
false);
hb_extents_t extents = extents_data.get_extents ();

View File

@ -1429,7 +1429,7 @@ hb_font_draw_glyph (hb_font_t *font,
* @glyph: The glyph ID
* @pfuncs: #hb_paint_funcs_t to paint with
* @paint_data: User data to pass to paint callbacks
* @palette: The index of the font's color palette to use
* @palette_index: The index of the font's color palette to use
* @foreground: The foreground color, unpremultipled
*
* Paints the glyph.
@ -1439,8 +1439,9 @@ hb_font_draw_glyph (hb_font_t *font,
* to them.
*
* If the font has color palettes (see hb_ot_color_has_palettes()),
* then @palette selects the palette to use. If the font doesn't
* have palettes, passing 0 is fine.
* then @palette_index selects the palette to use. If the font only
* has one palette, this will be 0. Use %HB_PAINT_PALETTE_INDEX_CUSTOM
* for custom palette.
*
* Since: REPLACEME
*/
@ -1448,10 +1449,10 @@ void
hb_font_paint_glyph (hb_font_t *font,
hb_codepoint_t glyph,
hb_paint_funcs_t *pfuncs, void *paint_data,
unsigned int palette,
unsigned int palette_index,
hb_color_t foreground)
{
font->paint_glyph (glyph, pfuncs, paint_data, palette, foreground);
font->paint_glyph (glyph, pfuncs, paint_data, palette_index, foreground);
}
/* A bit higher-level, and with fallback */

View File

@ -531,7 +531,7 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data,
* @glyph: The glyph ID to query
* @paint_funcs: The paint functions to use
* @paint_data: The data accompanying the paint functions
* @palette: The color palette to use
* @palette_index: The color palette to use
* @foreground: The foreground color
* @user_data: User data pointer passed by the caller
*
@ -542,7 +542,7 @@ typedef void (*hb_font_draw_glyph_func_t) (hb_font_t *font, void *font_data,
typedef void (*hb_font_paint_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_paint_funcs_t *paint_funcs, void *paint_data,
unsigned int palette,
unsigned int palette_index,
hb_color_t foreground,
void *user_data);
@ -950,7 +950,7 @@ HB_EXTERN void
hb_font_paint_glyph (hb_font_t *font,
hb_codepoint_t glyph,
hb_paint_funcs_t *pfuncs, void *paint_data,
unsigned int palette,
unsigned int palette_index,
hb_color_t foreground);
/* high-level funcs, with fallback */

View File

@ -83,10 +83,11 @@ struct hb_ft_paint_context_t
hb_font_t *font,
hb_paint_funcs_t *paint_funcs, void *paint_data,
FT_Color *palette,
unsigned palette_index,
hb_color_t foreground) :
ft_font (ft_font), font(font),
funcs (paint_funcs), data (paint_data),
palette (palette), foreground (foreground) {}
palette (palette), palette_index (palette_index), foreground (foreground) {}
void recurse (FT_OpaquePaint paint)
{
@ -102,6 +103,7 @@ struct hb_ft_paint_context_t
hb_paint_funcs_t *funcs;
void *data;
FT_Color *palette;
unsigned palette_index;
hb_color_t foreground;
int depth_left = HB_MAX_NESTING_LEVEL;
int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
@ -154,11 +156,22 @@ _hb_ft_color_line_get_color_stops (hb_color_line_t *color_line,
(hb_color_get_alpha (c->foreground) * stop.color.alpha) >> 14);
else
{
FT_Color ft_color = c->palette[stop.color.palette_index];
color_stops->color = HB_COLOR (ft_color.blue,
ft_color.green,
ft_color.red,
(ft_color.alpha * stop.color.alpha) >> 14);
if (c->palette_index == HB_PAINT_PALETTE_INDEX_CUSTOM)
{
hb_color_t color = c->funcs->custom_palette_color (c->data, stop.color.palette_index);
color_stops->color = HB_COLOR (hb_color_get_blue (color),
hb_color_get_green (color),
hb_color_get_red (color),
(hb_color_get_alpha (color) * stop.color.alpha) >> 14);
}
else
{
FT_Color ft_color = c->palette[stop.color.palette_index];
color_stops->color = HB_COLOR (ft_color.blue,
ft_color.green,
ft_color.red,
(ft_color.alpha * stop.color.alpha) >> 14);
}
}
color_stops++;
@ -224,11 +237,22 @@ _hb_ft_paint (hb_ft_paint_context_t *c,
(hb_color_get_alpha (c->foreground) * paint.u.solid.color.alpha) >> 14);
else
{
FT_Color ft_color = c->palette[paint.u.solid.color.palette_index];
color = HB_COLOR (ft_color.blue,
ft_color.green,
ft_color.red,
(ft_color.alpha * paint.u.solid.color.alpha) >> 14);
if (c->palette_index == HB_PAINT_PALETTE_INDEX_CUSTOM)
{
color = c->funcs->custom_palette_color (c->data, paint.u.solid.color.palette_index);
color = HB_COLOR (hb_color_get_blue (color),
hb_color_get_green (color),
hb_color_get_red (color),
(hb_color_get_alpha (color) * paint.u.solid.color.alpha) >> 14);
}
else
{
FT_Color ft_color = c->palette[paint.u.solid.color.palette_index];
color = HB_COLOR (ft_color.blue,
ft_color.green,
ft_color.red,
(ft_color.alpha * paint.u.solid.color.alpha) >> 14);
}
}
c->funcs->color (c->data, is_foreground, color);
}
@ -450,7 +474,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font,
{
hb_ft_paint_context_t c (ft_font, font,
paint_funcs, paint_data,
palette, foreground);
palette, palette_index, foreground);
bool is_bounded = true;
FT_ClipBox clip_box;
@ -473,7 +497,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font,
hb_paint_extents_context_t extents_data;
hb_ft_paint_context_t ce (ft_font, font,
extents_funcs, &extents_data,
palette, foreground);
palette, palette_index, foreground);
ce.funcs->push_root_transform (ce.data, font);
ce.recurse (paint);
ce.funcs->pop_transform (ce.data);

View File

@ -117,6 +117,11 @@ hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data,
hb_paint_composite_mode_t mode,
void *user_data) {}
static hb_color_t
hb_paint_custom_palette_color_nil (hb_paint_funcs_t *funcs, void *paint_data,
unsigned int color_index,
void *user_data) { return HB_COLOR(0,0,0,0); }
static bool
_hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs,
bool func_is_null,
@ -673,5 +678,23 @@ hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data,
funcs->pop_group (paint_data, mode);
}
/**
* hb_paint_custom_palette_color:
* @funcs: paint functions
* @paint_data: associated data passed by the caller
* @color_index: color index
*
* Gets the custom palette color for @color_index.
*
* Return value: the custom color
*
* Since: REPLACEME
*/
hb_color_t
hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data,
unsigned int color_index)
{
return funcs->custom_palette_color (paint_data, color_index);
}
#endif

View File

@ -33,6 +33,18 @@
HB_BEGIN_DECLS
/**
* HB_PAINT_PALETTE_INDEX_CUSTOM
*
* A palette index signifying that custom colors are in use.
* Such colors are fetched from the client using the
* custom-palette-color callback of the paint functions.
*
* Since: REPLACEME
**/
#define HB_PAINT_PALETTE_INDEX_CUSTOM 0xFFFFFFFF
/**
* hb_paint_funcs_t:
*
@ -655,6 +667,25 @@ typedef void (*hb_paint_pop_group_func_t) (hb_paint_funcs_t *funcs,
hb_paint_composite_mode_t mode,
void *user_data);
/**
* hb_paint_custom_palette_color_func_t:
* @funcs: paint functions object
* @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
* @color_index: the color index
* @user_data: User data pointer passed to hb_paint_funcs_set_pop_group_func()
*
* A virtual method for the #hb_paint_funcs_t to fetch a color from the custom
* color palette.
*
* Return value: the color
* Since: REPLACEME
*/
typedef hb_color_t (*hb_paint_custom_palette_color_func_t) (hb_paint_funcs_t *funcs,
void *paint_data,
unsigned int color_index,
void *user_data);
/**
* hb_paint_funcs_set_push_transform_func:
* @funcs: A paint functions struct
@ -859,6 +890,22 @@ hb_paint_funcs_set_pop_group_func (hb_paint_funcs_t *funcs,
void *user_data,
hb_destroy_func_t destroy);
/**
* hb_paint_funcs_set_custom_palette_color_func:
* @funcs: A paint functions struct
* @func: (closure user_data) (destroy destroy) (scope notified): The custom-palette-color callback
* @user_data: Data to pass to @func
* @destroy: (nullable): Function to call when @user_data is no longer needed
*
* Sets the custom-palette-color callback on the paint functions struct.
*
* Since: REPLACEME
*/
HB_EXTERN void
hb_paint_funcs_set_custom_palette_color_func (hb_paint_funcs_t *funcs,
hb_paint_custom_palette_color_func_t func,
void *user_data,
hb_destroy_func_t destroy);
/*
* Manual API
*/
@ -927,6 +974,10 @@ HB_EXTERN void
hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data,
hb_paint_composite_mode_t mode);
HB_EXTERN hb_color_t
hb_paint_custom_palette_color (hb_paint_funcs_t *funcs, void *paint_data,
unsigned int color_index);
HB_END_DECLS
#endif /* HB_PAINT_H */

View File

@ -42,6 +42,7 @@
HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \
HB_PAINT_FUNC_IMPLEMENT (push_group) \
HB_PAINT_FUNC_IMPLEMENT (pop_group) \
HB_PAINT_FUNC_IMPLEMENT (custom_palette_color) \
/* ^--- Add new callbacks here */
struct hb_paint_funcs_t
@ -137,6 +138,11 @@ struct hb_paint_funcs_t
{ func.pop_group (this, paint_data,
mode,
!user_data ? nullptr : user_data->pop_group); }
hb_color_t custom_palette_color (void *paint_data,
unsigned int color_index)
{ return func.custom_palette_color (this, paint_data,
color_index,
!user_data ? nullptr : user_data->custom_palette_color); }
/* Internal specializations. */