mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-06 05:48:00 +02:00
script: Add support for mesh patterns
Extend CairoScript with operators based on the mesh pattern API.
This commit is contained in:
parent
c243f3ac9c
commit
96426fdf01
2 changed files with 286 additions and 0 deletions
|
|
@ -956,6 +956,87 @@ _emit_radial_pattern (cairo_script_surface_t *surface,
|
|||
return _emit_gradient_color_stops (&radial->base, ctx->stream);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_emit_mesh_pattern (cairo_script_surface_t *surface,
|
||||
const cairo_pattern_t *pattern)
|
||||
{
|
||||
cairo_script_context_t *ctx = to_context (surface);
|
||||
cairo_pattern_t *mesh;
|
||||
cairo_status_t status;
|
||||
unsigned int i, n;
|
||||
|
||||
mesh = (cairo_pattern_t *) pattern;
|
||||
status = cairo_pattern_mesh_get_patch_count (mesh, &n);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_printf (ctx->stream, "mesh");
|
||||
for (i = 0; i < n; i++) {
|
||||
cairo_path_t *path;
|
||||
cairo_path_data_t *data;
|
||||
int j;
|
||||
|
||||
_cairo_output_stream_printf (ctx->stream, "\n mesh-begin-patch");
|
||||
|
||||
path = cairo_pattern_mesh_get_path (mesh, i);
|
||||
if (unlikely (path->status))
|
||||
return path->status;
|
||||
|
||||
for (j = 0; j < path->num_data; j+=data[0].header.length) {
|
||||
data = &path->data[j];
|
||||
switch (data->header.type) {
|
||||
case CAIRO_PATH_MOVE_TO:
|
||||
_cairo_output_stream_printf (ctx->stream,
|
||||
"\n %f %f mesh-move-to",
|
||||
data[1].point.x, data[1].point.y);
|
||||
break;
|
||||
case CAIRO_PATH_LINE_TO:
|
||||
_cairo_output_stream_printf (ctx->stream,
|
||||
"\n %f %f mesh-line-to",
|
||||
data[1].point.x, data[1].point.y);
|
||||
break;
|
||||
case CAIRO_PATH_CURVE_TO:
|
||||
_cairo_output_stream_printf (ctx->stream,
|
||||
"\n %f %f %f %f %f %f mesh-curve-to",
|
||||
data[1].point.x, data[1].point.y,
|
||||
data[2].point.x, data[2].point.y,
|
||||
data[3].point.x, data[3].point.y);
|
||||
break;
|
||||
case CAIRO_PATH_CLOSE_PATH:
|
||||
break;
|
||||
}
|
||||
}
|
||||
cairo_path_destroy (path);
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
double x, y;
|
||||
|
||||
status = cairo_pattern_mesh_get_control_point (mesh, i, j, &x, &y);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
_cairo_output_stream_printf (ctx->stream,
|
||||
"\n %d %f %f mesh-set-control-point",
|
||||
j, x, y);
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
double r, g, b, a;
|
||||
|
||||
status = cairo_pattern_mesh_get_corner_color_rgba (mesh, i, j, &r, &g, &b, &a);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_printf (ctx->stream,
|
||||
"\n %d %f %f %f %f mesh-set-corner-color",
|
||||
j, r, g, b, a);
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (ctx->stream, "\n mesh-end-patch");
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_emit_recording_surface_pattern (cairo_script_surface_t *surface,
|
||||
cairo_recording_surface_t *source)
|
||||
|
|
@ -1465,6 +1546,10 @@ _emit_pattern (cairo_script_surface_t *surface,
|
|||
status = _emit_radial_pattern (surface, pattern);
|
||||
is_default_extend = pattern->extend == CAIRO_EXTEND_GRADIENT_DEFAULT;
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_MESH:
|
||||
status = _emit_mesh_pattern (surface, pattern);
|
||||
is_default_extend = TRUE;
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
status = _emit_surface_pattern (surface, pattern);
|
||||
is_default_extend = pattern->extend == CAIRO_EXTEND_SURFACE_DEFAULT;
|
||||
|
|
|
|||
|
|
@ -3591,6 +3591,199 @@ _matrix (csi_t *ctx)
|
|||
return push (&matrix);
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mesh (csi_t *ctx)
|
||||
{
|
||||
csi_object_t obj;
|
||||
|
||||
obj.type = CSI_OBJECT_TYPE_PATTERN;
|
||||
obj.datum.pattern = cairo_pattern_create_mesh ();
|
||||
return push (&obj);
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mesh_begin_patch (csi_t *ctx)
|
||||
{
|
||||
csi_status_t status;
|
||||
cairo_pattern_t *pattern = NULL; /* silence the compiler */
|
||||
|
||||
check (1);
|
||||
|
||||
status = _csi_ostack_get_pattern (ctx, 0, &pattern);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_pattern_mesh_begin_patch (pattern);
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mesh_curve_to (csi_t *ctx)
|
||||
{
|
||||
csi_status_t status;
|
||||
double x1, y1, x2, y2, x3, y3;
|
||||
cairo_pattern_t *pattern = NULL; /* silence the compiler */
|
||||
|
||||
check (7);
|
||||
|
||||
status = _csi_ostack_get_number (ctx, 0, &y3);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 1, &x3);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 2, &y2);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 3, &x2);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 4, &y1);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 5, &x1);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_pattern (ctx, 6, &pattern);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_pattern_mesh_curve_to (pattern, x1, y1, x2, y2, x3, y3);
|
||||
|
||||
pop (6);
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mesh_end_patch (csi_t *ctx)
|
||||
{
|
||||
csi_status_t status;
|
||||
cairo_pattern_t *pattern = NULL; /* silence the compiler */
|
||||
|
||||
check (1);
|
||||
|
||||
status = _csi_ostack_get_pattern (ctx, 0, &pattern);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_pattern_mesh_end_patch (pattern);
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mesh_line_to (csi_t *ctx)
|
||||
{
|
||||
csi_status_t status;
|
||||
double x, y;
|
||||
cairo_pattern_t *pattern = NULL; /* silence the compiler */
|
||||
|
||||
check (3);
|
||||
|
||||
status = _csi_ostack_get_number (ctx, 0, &y);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 1, &x);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_pattern (ctx, 2, &pattern);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_pattern_mesh_line_to (pattern, x, y);
|
||||
|
||||
pop (2);
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mesh_move_to (csi_t *ctx)
|
||||
{
|
||||
csi_status_t status;
|
||||
double x, y;
|
||||
cairo_pattern_t *pattern = NULL; /* silence the compiler */
|
||||
|
||||
check (3);
|
||||
|
||||
status = _csi_ostack_get_number (ctx, 0, &y);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 1, &x);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_pattern (ctx, 2, &pattern);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_pattern_mesh_move_to (pattern, x, y);
|
||||
|
||||
pop (2);
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mesh_set_control_point (csi_t *ctx)
|
||||
{
|
||||
csi_status_t status;
|
||||
double x, y;
|
||||
csi_integer_t point;
|
||||
cairo_pattern_t *pattern = NULL; /* silence the compiler */
|
||||
|
||||
check (4);
|
||||
|
||||
status = _csi_ostack_get_number (ctx, 0, &y);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 1, &x);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_integer (ctx, 2, &point);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_pattern (ctx, 3, &pattern);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_pattern_mesh_set_control_point (pattern, point, x, y);
|
||||
|
||||
pop (3);
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mesh_set_corner_color (csi_t *ctx)
|
||||
{
|
||||
csi_status_t status;
|
||||
double r, g, b, a;
|
||||
csi_integer_t corner;
|
||||
cairo_pattern_t *pattern = NULL; /* silence the compiler */
|
||||
|
||||
check (6);
|
||||
|
||||
status = _csi_ostack_get_number (ctx, 0, &a);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 1, &b);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 2, &g);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_number (ctx, 3, &r);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_integer (ctx, 4, &corner);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
status = _csi_ostack_get_pattern (ctx, 5, &pattern);
|
||||
if (_csi_unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_pattern_mesh_set_corner_color_rgba (pattern, corner, r, g, b, a);
|
||||
|
||||
pop (5);
|
||||
return CSI_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
_mod (csi_t *ctx)
|
||||
{
|
||||
|
|
@ -6038,6 +6231,14 @@ _defs[] = {
|
|||
{ "mark", _mark },
|
||||
{ "mask", _mask },
|
||||
{ "matrix", _matrix },
|
||||
{ "mesh", _mesh },
|
||||
{ "mesh-begin-patch", _mesh_begin_patch },
|
||||
{ "mesh-curve-to", _mesh_curve_to },
|
||||
{ "mesh-end-patch", _mesh_end_patch },
|
||||
{ "mesh-line-to", _mesh_line_to },
|
||||
{ "mesh-move-to", _mesh_move_to },
|
||||
{ "mesh-set-control-point", _mesh_set_control_point },
|
||||
{ "mesh-set-corner-color", _mesh_set_corner_color },
|
||||
{ "mod", _mod },
|
||||
{ "move-to", _move_to },
|
||||
{ "mul", _mul },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue