assorted fixes and changes

This commit is contained in:
Matthias Clasen 2022-12-14 22:32:40 -05:00 committed by Behdad Esfahbod
parent 5a123e8691
commit c9350838c7
5 changed files with 158 additions and 111 deletions

View File

@ -463,7 +463,7 @@ struct PaintSolid
void paint_glyph (hb_paint_context_t *c) const void paint_glyph (hb_paint_context_t *c) const
{ {
c->funcs->solid (c->data, paletteIndex); c->funcs->solid (c->data, paletteIndex, alpha.to_float ());
} }
HBUINT8 format; /* format = 2(noVar) or 3(Var)*/ HBUINT8 format; /* format = 2(noVar) or 3(Var)*/
@ -614,7 +614,7 @@ struct PaintGlyph
void paint_glyph (hb_paint_context_t *c) const void paint_glyph (hb_paint_context_t *c) const
{ {
c->funcs->push_clip (c->data, gid); c->funcs->push_clip_glyph (c->data, gid);
paint_dispatch (&(this+paint), c); paint_dispatch (&(this+paint), c);
c->funcs->pop_clip (c->data); c->funcs->pop_clip (c->data);
} }

View File

@ -29,63 +29,67 @@
#include "hb-paint.hh" #include "hb-paint.hh"
static void static void
hb_paint_push_transform_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_push_transform_nil (hb_paint_funcs_t *funcs, void *paint_data,
float xx HB_UNUSED, float xy HB_UNUSED, float xx, float xy,
float yx HB_UNUSED, float yy HB_UNUSED, float yx, float yy,
float x0 HB_UNUSED, float y0 HB_UNUSED, float x0, float y0,
void *user_data HB_UNUSED) {} void *user_data) {}
static void static void
hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data,
void *user_data HB_UNUSED) {} void *user_data) {}
static void static void
hb_paint_push_clip_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data,
hb_codepoint_t glyph HB_UNUSED, hb_codepoint_t glyph,
void *user_data HB_UNUSED) {} void *user_data) {}
static void static void
hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_push_clip_rect_nil (hb_paint_funcs_t *funcs, void *paint_data,
void *user_data HB_UNUSED) {} float xmin, float ymin, float xmax, float ymax,
void *user_data) {}
static void static void
hb_paint_solid_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_pop_clip_nil (hb_paint_funcs_t *funcs, void *paint_data,
unsigned int color_index HB_UNUSED, void *user_data) {}
void *user_data HB_UNUSED) {}
static void static void
hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_solid_nil (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line HB_UNUSED, unsigned int color_index,
hb_position_t x0, hb_position_t y0 HB_UNUSED, float alpha,
hb_position_t x1, hb_position_t y1 HB_UNUSED, void *user_data) {}
hb_position_t x2, hb_position_t y2 HB_UNUSED,
void *user_data HB_UNUSED) {}
static void static void
hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_linear_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line HB_UNUSED, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0 HB_UNUSED, float x0, float y0,
float r0 HB_UNUSED, float x1, float y1,
hb_position_t x1 HB_UNUSED, hb_position_t y1 HB_UNUSED, float x2, float y2,
float r1 HB_UNUSED, void *user_data) {}
void *user_data HB_UNUSED) {}
static void static void
hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_radial_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line HB_UNUSED, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0 HB_UNUSED, float x0, float y0, float r0,
float start_angle HB_UNUSED, float x1, float y1, float r1,
float end_angle HB_UNUSED, void *user_data) {}
void *user_data HB_UNUSED) {}
static void static void
hb_paint_push_group_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_sweep_gradient_nil (hb_paint_funcs_t *funcs, void *paint_data,
void *user_data HB_UNUSED) {} hb_color_line_t *color_line,
float x0, float y0,
float start_angle,
float end_angle,
void *user_data) {}
static void static void
hb_paint_pop_group_and_composite_nil (hb_paint_funcs_t *funcs HB_UNUSED, void *paint_data HB_UNUSED, hb_paint_push_group_nil (hb_paint_funcs_t *funcs, void *paint_data,
void *user_data) {}
static void
hb_paint_pop_group_and_composite_nil (hb_paint_funcs_t *funcs, void *paint_data,
hb_paint_composite_mode_t mode, hb_paint_composite_mode_t mode,
void *user_data HB_UNUSED) {} void *user_data) {}
static bool static bool
_hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs, _hb_paint_funcs_set_preamble (hb_paint_funcs_t *funcs,
@ -251,10 +255,17 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data)
} }
void void
hb_paint_push_clip (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data,
hb_codepoint_t glyph) hb_codepoint_t glyph)
{ {
funcs->push_clip (paint_data, glyph); funcs->push_clip_glyph (paint_data, glyph);
}
void
hb_paint_push_clip_rect (hb_paint_funcs_t *funcs, void *paint_data,
float xmin, float ymin, float xmax, float ymax)
{
funcs->push_clip_rect (paint_data, xmin, ymin, xmax, ymax);
} }
void void
@ -265,17 +276,18 @@ hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data)
void void
hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data,
unsigned int color_index) unsigned int color_index,
float alpha)
{ {
funcs->solid (paint_data, color_index); funcs->solid (paint_data, color_index, alpha);
} }
void void
hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
hb_position_t x1, hb_position_t y1, float x1, float y1,
hb_position_t x2, hb_position_t y2) float x2, float y2)
{ {
funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2); funcs->linear_gradient (paint_data, color_line, x0, y0, x1, y1, x2, y2);
} }
@ -283,10 +295,8 @@ hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data,
void void
hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0, float r0,
float r0, float x1, float y1, float r1)
hb_position_t x1, hb_position_t y1,
float r1)
{ {
funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1); funcs->radial_gradient (paint_data, color_line, x0, y0, r0, y1, x1, r1);
} }
@ -294,7 +304,7 @@ hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data,
void void
hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
float start_angle, float end_angle) float start_angle, float end_angle)
{ {
funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle); funcs->sweep_gradient (paint_data, color_line, x0, y0, start_angle, end_angle);

View File

@ -61,11 +61,17 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
void *user_data); void *user_data);
typedef void (*hb_paint_push_clip_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_push_clip_glyph_func_t) (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
hb_codepoint_t glyph, hb_codepoint_t glyph,
void *user_data); void *user_data);
typedef void (*hb_paint_push_clip_rect_func_t) (hb_paint_funcs_t *funcs,
void *paint_data,
float xmin, float ymin,
float xmax, float ymax,
void *user_data);
typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
void *user_data); void *user_data);
@ -73,6 +79,7 @@ typedef void (*hb_paint_pop_clip_func_t) (hb_paint_funcs_t *funcs,
typedef void (*hb_paint_solid_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_solid_func_t) (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
unsigned int color_index, unsigned int color_index,
float alpha,
void *user_data); void *user_data);
@ -101,24 +108,22 @@ hb_color_line_get_extend (hb_color_line_t *color_line);
typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_linear_gradient_func_t) (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
hb_position_t x1, hb_position_t y1, float x1, float y1,
hb_position_t x2, hb_position_t y2, float x2, float y2,
void *user_data); void *user_data);
typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_radial_gradient_func_t) (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0, float r0,
float r0, float x1, float y1, float r1,
hb_position_t x1, hb_position_t y1,
float r1,
void *user_data); void *user_data);
typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_sweep_gradient_func_t) (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
float start_angle, float start_angle,
float end_angle, float end_angle,
void *user_data); void *user_data);
@ -190,15 +195,28 @@ hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs,
hb_destroy_func_t destroy); hb_destroy_func_t destroy);
/** /**
* hb_paint_funcs_set_push_clip_func: * hb_paint_funcs_set_push_clip_glyph_func:
* @funcs: * @funcs:
* @func: (closure user_data) (destroy destroy) (scope notified): * @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data: * @user_data:
* @destroy: (nullable) * @destroy: (nullable)
*/ */
HB_EXTERN void HB_EXTERN void
hb_paint_funcs_set_push_clip_func (hb_paint_funcs_t *funcs, hb_paint_funcs_set_push_clip_glyph_func (hb_paint_funcs_t *funcs,
hb_paint_push_clip_func_t func, hb_paint_push_clip_glyph_func_t func,
void *user_data,
hb_destroy_func_t destroy);
/**
* hb_paint_funcs_set_push_clip_rect_func:
* @funcs:
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy: (nullable)
*/
HB_EXTERN void
hb_paint_funcs_set_push_clip_rect_func (hb_paint_funcs_t *funcs,
hb_paint_push_clip_rect_func_t func,
void *user_data, void *user_data,
hb_destroy_func_t destroy); hb_destroy_func_t destroy);
@ -303,35 +321,38 @@ HB_EXTERN void
hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data);
HB_EXTERN void HB_EXTERN void
hb_paint_push_clip (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data,
hb_codepoint_t glyph); hb_codepoint_t glyph);
HB_EXTERN void
hb_paint_push_clip_rect (hb_paint_funcs_t *funcs, void *paint_data,
float xmin, float ymin, float xmax, float ymax);
HB_EXTERN void HB_EXTERN void
hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data); hb_paint_pop_clip (hb_paint_funcs_t *funcs, void *paint_data);
HB_EXTERN void HB_EXTERN void
hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_solid (hb_paint_funcs_t *funcs, void *paint_data,
unsigned int color_index); unsigned int color_index,
float alpha);
HB_EXTERN void HB_EXTERN void
hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_linear_gradient (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
hb_position_t x1, hb_position_t y1, float x1, float y1,
hb_position_t x2, hb_position_t y2); float x2, float y2);
HB_EXTERN void HB_EXTERN void
hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_radial_gradient (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0, float r0,
float r0, float x1, float y1, float r1);
hb_position_t x1, hb_position_t y1,
float r1);
HB_EXTERN void HB_EXTERN void
hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data, hb_paint_sweep_gradient (hb_paint_funcs_t *funcs, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
float start_angle, float end_angle); float start_angle, float end_angle);
HB_EXTERN void HB_EXTERN void

View File

@ -30,7 +30,8 @@
#define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \
HB_PAINT_FUNC_IMPLEMENT (push_transform) \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \
HB_PAINT_FUNC_IMPLEMENT (pop_transform) \ HB_PAINT_FUNC_IMPLEMENT (pop_transform) \
HB_PAINT_FUNC_IMPLEMENT (push_clip) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \
HB_PAINT_FUNC_IMPLEMENT (push_clip_rect) \
HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ HB_PAINT_FUNC_IMPLEMENT (pop_clip) \
HB_PAINT_FUNC_IMPLEMENT (solid) \ HB_PAINT_FUNC_IMPLEMENT (solid) \
HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \ HB_PAINT_FUNC_IMPLEMENT (linear_gradient) \
@ -72,39 +73,43 @@ struct hb_paint_funcs_t
void pop_transform (void *paint_data) void pop_transform (void *paint_data)
{ func.pop_transform (this, paint_data, { func.pop_transform (this, paint_data,
!user_data ? nullptr : user_data->pop_transform); } !user_data ? nullptr : user_data->pop_transform); }
void push_clip (void *paint_data, void push_clip_glyph (void *paint_data,
hb_codepoint_t glyph) hb_codepoint_t glyph)
{ func.push_clip (this, paint_data, { func.push_clip_glyph (this, paint_data,
glyph, glyph,
!user_data ? nullptr : user_data->push_clip); } !user_data ? nullptr : user_data->push_clip_glyph); }
void push_clip_rect (void *paint_data,
float xmin, float ymin, float xmax, float ymax)
{ func.push_clip_rect (this, paint_data,
xmin, ymin, xmax, ymax,
!user_data ? nullptr : user_data->push_clip_rect); }
void pop_clip (void *paint_data) void pop_clip (void *paint_data)
{ func.pop_clip (this, paint_data, { func.pop_clip (this, paint_data,
!user_data ? nullptr : user_data->pop_clip); } !user_data ? nullptr : user_data->pop_clip); }
void solid (void *paint_data, void solid (void *paint_data,
unsigned int color_index) unsigned int color_index,
float alpha)
{ func.solid (this, paint_data, { func.solid (this, paint_data,
color_index, color_index, alpha,
!user_data ? nullptr : user_data->solid); } !user_data ? nullptr : user_data->solid); }
void linear_gradient (void *paint_data, void linear_gradient (void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
hb_position_t x1, hb_position_t y1, float x1, float y1,
hb_position_t x2, hb_position_t y2) float x2, float y2)
{ func.linear_gradient (this, paint_data, { func.linear_gradient (this, paint_data,
color_line, x0, y0, x1, y1, x2, y2, color_line, x0, y0, x1, y1, x2, y2,
!user_data ? nullptr : user_data->linear_gradient); } !user_data ? nullptr : user_data->linear_gradient); }
void radial_gradient (void *paint_data, void radial_gradient (void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0, float r0,
float r0, float x1, float y1, float r1)
hb_position_t x1, hb_position_t y1,
float r1)
{ func.radial_gradient (this, paint_data, { func.radial_gradient (this, paint_data,
color_line, x0, y0, r0, x1, y1, r1, color_line, x0, y0, r0, x1, y1, r1,
!user_data ? nullptr : user_data->radial_gradient); } !user_data ? nullptr : user_data->radial_gradient); }
void sweep_gradient (void *paint_data, void sweep_gradient (void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
float start_angle, float start_angle,
float end_angle) float end_angle)
{ func.sweep_gradient (this, paint_data, { func.sweep_gradient (this, paint_data,

View File

@ -49,13 +49,24 @@ pop_transform (hb_paint_funcs_t *funcs,
} }
static void static void
push_clip (hb_paint_funcs_t *funcs, push_clip_glyph (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
hb_codepoint_t glyph, hb_codepoint_t glyph,
void *user_data) void *user_data)
{ {
paint_data_t *data = user_data; paint_data_t *data = user_data;
print (data, "start clip %u", glyph); print (data, "start clip glyph %u", glyph);
data->level++;
}
static void
push_clip_rect (hb_paint_funcs_t *funcs,
void *paint_data,
float xmin, float ymin, float xmax, float ymax,
void *user_data)
{
paint_data_t *data = user_data;
print (data, "start clip rect %f %f %f %f", xmin, ymin, xmax, ymax);
data->level++; data->level++;
} }
@ -73,19 +84,20 @@ static void
solid (hb_paint_funcs_t *funcs, solid (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
unsigned int color_index, unsigned int color_index,
float alpha,
void *user_data) void *user_data)
{ {
paint_data_t *data = user_data; paint_data_t *data = user_data;
print (data, "solid %u", color_index); print (data, "solid %u %f", color_index, alpha);
} }
static void static void
linear_gradient (hb_paint_funcs_t *funcs, linear_gradient (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
hb_position_t x1, hb_position_t y1, float x1, float y1,
hb_position_t x2, hb_position_t y2, float x2, float y2,
void *user_data) void *user_data)
{ {
paint_data_t *data = user_data; paint_data_t *data = user_data;
@ -96,10 +108,8 @@ static void
radial_gradient (hb_paint_funcs_t *funcs, radial_gradient (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0, float r0,
float r0, float x1, float y1, float r1,
hb_position_t x1, hb_position_t y1,
float r1,
void *user_data) void *user_data)
{ {
paint_data_t *data = user_data; paint_data_t *data = user_data;
@ -110,7 +120,7 @@ static void
sweep_gradient (hb_paint_funcs_t *funcs, sweep_gradient (hb_paint_funcs_t *funcs,
void *paint_data, void *paint_data,
hb_color_line_t *color_line, hb_color_line_t *color_line,
hb_position_t x0, hb_position_t y0, float x0, float y0,
float start_angle, float start_angle,
float end_angle, float end_angle,
void *user_data) void *user_data)
@ -153,7 +163,8 @@ int main (int argc, char *argv[])
funcs = hb_paint_funcs_create (); funcs = hb_paint_funcs_create ();
hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL); hb_paint_funcs_set_push_transform_func (funcs, push_transform, &data, NULL);
hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL); hb_paint_funcs_set_pop_transform_func (funcs, pop_transform, &data, NULL);
hb_paint_funcs_set_push_clip_func (funcs, push_clip, &data, NULL); hb_paint_funcs_set_push_clip_glyph_func (funcs, push_clip_glyph, &data, NULL);
hb_paint_funcs_set_push_clip_rect_func (funcs, push_clip_rect, &data, NULL);
hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL); hb_paint_funcs_set_pop_clip_func (funcs, pop_clip, &data, NULL);
hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL); hb_paint_funcs_set_push_group_func (funcs, push_group, &data, NULL);
hb_paint_funcs_set_pop_group_and_composite_func (funcs, pop_group_and_composite, &data, NULL); hb_paint_funcs_set_pop_group_and_composite_func (funcs, pop_group_and_composite, &data, NULL);