Merge pull request #4044 from harfbuzz/custom-palette

Custom palette
pull/4034/merge
Behdad Esfahbod 2 years ago committed by GitHub
commit 0c7d386748
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      docs/harfbuzz-sections.txt
  2. 22
      src/OT/Color/COLR/COLR.hh
  3. 11
      src/hb-font.cc
  4. 6
      src/hb-font.h
  5. 50
      src/hb-ft-colr.hh
  6. 23
      src/hb-paint.cc
  7. 51
      src/hb-paint.h
  8. 6
      src/hb-paint.hh

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

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

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

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

@ -83,10 +83,11 @@ struct hb_ft_paint_context_t
hb_font_t *font, hb_font_t *font,
hb_paint_funcs_t *paint_funcs, void *paint_data, hb_paint_funcs_t *paint_funcs, void *paint_data,
FT_Color *palette, FT_Color *palette,
unsigned palette_index,
hb_color_t foreground) : hb_color_t foreground) :
ft_font (ft_font), font(font), ft_font (ft_font), font(font),
funcs (paint_funcs), data (paint_data), funcs (paint_funcs), data (paint_data),
palette (palette), foreground (foreground) {} palette (palette), palette_index (palette_index), foreground (foreground) {}
void recurse (FT_OpaquePaint paint) void recurse (FT_OpaquePaint paint)
{ {
@ -102,6 +103,7 @@ struct hb_ft_paint_context_t
hb_paint_funcs_t *funcs; hb_paint_funcs_t *funcs;
void *data; void *data;
FT_Color *palette; FT_Color *palette;
unsigned palette_index;
hb_color_t foreground; hb_color_t foreground;
int depth_left = HB_MAX_NESTING_LEVEL; int depth_left = HB_MAX_NESTING_LEVEL;
int edge_count = HB_COLRV1_MAX_EDGE_COUNT; 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); (hb_color_get_alpha (c->foreground) * stop.color.alpha) >> 14);
else else
{ {
FT_Color ft_color = c->palette[stop.color.palette_index]; if (c->palette_index == HB_PAINT_PALETTE_INDEX_CUSTOM)
color_stops->color = HB_COLOR (ft_color.blue, {
ft_color.green, hb_color_t color = c->funcs->custom_palette_color (c->data, stop.color.palette_index);
ft_color.red, color_stops->color = HB_COLOR (hb_color_get_blue (color),
(ft_color.alpha * stop.color.alpha) >> 14); 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++; 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); (hb_color_get_alpha (c->foreground) * paint.u.solid.color.alpha) >> 14);
else else
{ {
FT_Color ft_color = c->palette[paint.u.solid.color.palette_index]; if (c->palette_index == HB_PAINT_PALETTE_INDEX_CUSTOM)
color = HB_COLOR (ft_color.blue, {
ft_color.green, color = c->funcs->custom_palette_color (c->data, paint.u.solid.color.palette_index);
ft_color.red, color = HB_COLOR (hb_color_get_blue (color),
(ft_color.alpha * paint.u.solid.color.alpha) >> 14); 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); 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, hb_ft_paint_context_t c (ft_font, font,
paint_funcs, paint_data, paint_funcs, paint_data,
palette, foreground); palette, palette_index, foreground);
bool is_bounded = true; bool is_bounded = true;
FT_ClipBox clip_box; 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_paint_extents_context_t extents_data;
hb_ft_paint_context_t ce (ft_font, font, hb_ft_paint_context_t ce (ft_font, font,
extents_funcs, &extents_data, extents_funcs, &extents_data,
palette, foreground); palette, palette_index, foreground);
ce.funcs->push_root_transform (ce.data, font); ce.funcs->push_root_transform (ce.data, font);
ce.recurse (paint); ce.recurse (paint);
ce.funcs->pop_transform (ce.data); ce.funcs->pop_transform (ce.data);

@ -117,6 +117,11 @@ hb_paint_pop_group_nil (hb_paint_funcs_t *funcs, void *paint_data,
hb_paint_composite_mode_t mode, hb_paint_composite_mode_t mode,
void *user_data) {} 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 static bool
_hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs, _hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs,
bool func_is_null, 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); 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 #endif

@ -33,6 +33,18 @@
HB_BEGIN_DECLS 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: * 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, hb_paint_composite_mode_t mode,
void *user_data); 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: * hb_paint_funcs_set_push_transform_func:
* @funcs: A paint functions struct * @funcs: A paint functions struct
@ -859,6 +890,22 @@ hb_paint_funcs_set_pop_group_func (hb_paint_funcs_t *funcs,
void *user_data, void *user_data,
hb_destroy_func_t destroy); 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 * Manual API
*/ */
@ -927,6 +974,10 @@ HB_EXTERN void
hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_pop_group (hb_paint_funcs_t *funcs, void *paint_data,
hb_paint_composite_mode_t mode); 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 HB_END_DECLS
#endif /* HB_PAINT_H */ #endif /* HB_PAINT_H */

@ -42,6 +42,7 @@
HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \ HB_PAINT_FUNC_IMPLEMENT (sweep_gradient) \
HB_PAINT_FUNC_IMPLEMENT (push_group) \ HB_PAINT_FUNC_IMPLEMENT (push_group) \
HB_PAINT_FUNC_IMPLEMENT (pop_group) \ HB_PAINT_FUNC_IMPLEMENT (pop_group) \
HB_PAINT_FUNC_IMPLEMENT (custom_palette_color) \
/* ^--- Add new callbacks here */ /* ^--- Add new callbacks here */
struct hb_paint_funcs_t struct hb_paint_funcs_t
@ -137,6 +138,11 @@ struct hb_paint_funcs_t
{ func.pop_group (this, paint_data, { func.pop_group (this, paint_data,
mode, mode,
!user_data ? nullptr : user_data->pop_group); } !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. */ /* Internal specializations. */

Loading…
Cancel
Save