script: Add support for mesh patterns

Extend CairoScript with operators based on the mesh pattern API.
This commit is contained in:
Andrea Canciani 2010-12-21 11:20:50 +01:00
parent c243f3ac9c
commit 96426fdf01
2 changed files with 286 additions and 0 deletions

View file

@ -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;

View file

@ -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 },