diff --git a/src/cairo-device.c b/src/cairo-device.c index 15b048477..a32b97124 100644 --- a/src/cairo-device.c +++ b/src/cairo-device.c @@ -156,6 +156,7 @@ _cairo_device_create_in_error (cairo_status_t status) case CAIRO_STATUS_INVALID_WEIGHT: case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: case CAIRO_STATUS_INVALID_CONTENT: + case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: default: _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_device_t *) &_nil_device; diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c index 109e99b12..5057fa639 100644 --- a/src/cairo-gl-composite.c +++ b/src/cairo-gl-composite.c @@ -291,6 +291,7 @@ _cairo_gl_operand_init (cairo_gl_operand_t *operand, /* fall through */ default: + case CAIRO_PATTERN_TYPE_MESH: case CAIRO_PATTERN_TYPE_SURFACE: return _cairo_gl_pattern_texture_setup (operand, pattern, dst, diff --git a/src/cairo-misc.c b/src/cairo-misc.c index 603725955..87cabcbf6 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -150,6 +150,8 @@ cairo_status_to_string (cairo_status_t status) return "the device type is not appropriate for the operation"; case CAIRO_STATUS_DEVICE_ERROR: return "an operation to the device caused an unspecified error"; + case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: + return "invalid operation during mesh pattern construction"; default: case CAIRO_STATUS_LAST_STATUS: return ""; diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index c67eac30c..ad7a9edf4 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -52,7 +52,7 @@ */ #if HAS_FREED_POOL -static freed_pool_t freed_pattern_pool[4]; +static freed_pool_t freed_pattern_pool[5]; #endif static const cairo_solid_pattern_t _cairo_pattern_nil = { @@ -156,6 +156,9 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type) case CAIRO_PATTERN_TYPE_RADIAL: VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_radial_pattern_t)); break; + case CAIRO_PATTERN_TYPE_MESH: + VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_mesh_pattern_t)); + break; } #endif @@ -221,6 +224,19 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, return CAIRO_STATUS_SUCCESS; } +static cairo_status_t +_cairo_mesh_pattern_init_copy (cairo_mesh_pattern_t *pattern, + const cairo_mesh_pattern_t *other) +{ + *pattern = *other; + + _cairo_array_init (&pattern->patches, sizeof (cairo_mesh_patch_t)); + + return _cairo_array_append_multiple (&pattern->patches, + _cairo_array_index_const (&other->patches, 0), + _cairo_array_num_elements (&other->patches)); +} + cairo_status_t _cairo_pattern_init_copy (cairo_pattern_t *pattern, const cairo_pattern_t *other) @@ -262,6 +278,18 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern, if (unlikely (status)) return status; + } break; + case CAIRO_PATTERN_TYPE_MESH: { + cairo_mesh_pattern_t *dst = (cairo_mesh_pattern_t *) pattern; + cairo_mesh_pattern_t *src = (cairo_mesh_pattern_t *) other; + cairo_status_t status; + + VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_mesh_pattern_t))); + + status = _cairo_mesh_pattern_init_copy (dst, src); + if (unlikely (status)) + return status; + } break; } @@ -295,6 +323,9 @@ _cairo_pattern_init_static_copy (cairo_pattern_t *pattern, case CAIRO_PATTERN_TYPE_RADIAL: size = sizeof (cairo_radial_pattern_t); break; + case CAIRO_PATTERN_TYPE_MESH: + size = sizeof (cairo_mesh_pattern_t); + break; } memcpy (pattern, other, size); @@ -355,6 +386,12 @@ _cairo_pattern_fini (cairo_pattern_t *pattern) if (gradient->stops && gradient->stops != gradient->stops_embedded) free (gradient->stops); } break; + case CAIRO_PATTERN_TYPE_MESH: { + cairo_mesh_pattern_t *mesh = + (cairo_mesh_pattern_t *) pattern; + + _cairo_array_fini (&mesh->patches); + } break; } #if HAVE_VALGRIND @@ -371,6 +408,9 @@ _cairo_pattern_fini (cairo_pattern_t *pattern) case CAIRO_PATTERN_TYPE_RADIAL: VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_radial_pattern_t)); break; + case CAIRO_PATTERN_TYPE_MESH: + VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_mesh_pattern_t)); + break; } #endif } @@ -398,6 +438,9 @@ _cairo_pattern_create_copy (cairo_pattern_t **pattern_out, case CAIRO_PATTERN_TYPE_RADIAL: pattern = malloc (sizeof (cairo_radial_pattern_t)); break; + case CAIRO_PATTERN_TYPE_MESH: + pattern = malloc (sizeof (cairo_mesh_pattern_t)); + break; default: ASSERT_NOT_REACHED; return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); @@ -2444,6 +2487,26 @@ _cairo_pattern_alpha_range (const cairo_pattern_t *pattern, break; } + case CAIRO_PATTERN_TYPE_MESH: { + const cairo_mesh_pattern_t *mesh = (const cairo_mesh_pattern_t *) pattern; + const cairo_mesh_patch_t *patch = _cairo_array_index_const (&mesh->patches, 0); + unsigned int i, j, n = _cairo_array_num_elements (&mesh->patches); + + assert (n >= 1); + + alpha_min = alpha_max = patch[0].colors[0].alpha; + for (i = 0; i < n; i++) { + for (j = 0; j < 4; j++) { + if (patch[i].colors[j].alpha < alpha_min) + alpha_min = patch[i].colors[j].alpha; + else if (patch[i].colors[j].alpha > alpha_max) + alpha_max = patch[i].colors[j].alpha; + } + } + + break; + } + default: ASSERT_NOT_REACHED; /* fall through */ @@ -2460,6 +2523,63 @@ _cairo_pattern_alpha_range (const cairo_pattern_t *pattern, *out_max = alpha_max; } +/** + * _cairo_mesh_pattern_coord_box + * + * Convenience function to determine the range of the coordinates of + * the points used to define the patches of the mesh. + * + * This is guaranteed to contain the pattern extents, but might not be + * tight, just like a Bezier curve is always inside the convex hull of + * the control points. + * + * This function cannot be used while the mesh is being constructed. + * + * The function returns TRUE and sets the output parametes to define + * the coodrinate range if the mesh pattern contains at least one + * patch, otherwise it returns FALSE. + **/ +cairo_bool_t +_cairo_mesh_pattern_coord_box (const cairo_mesh_pattern_t *mesh, + double *out_xmin, + double *out_ymin, + double *out_xmax, + double *out_ymax) +{ + const cairo_mesh_patch_t *patch; + unsigned int num_patches, i, j, k; + double x0, y0, x1, y1; + + assert (mesh->current_patch == NULL); + + num_patches = _cairo_array_num_elements (&mesh->patches); + + if (num_patches == 0) + return FALSE; + + patch = _cairo_array_index_const (&mesh->patches, 0); + x0 = x1 = patch->points[0][0].x; + y0 = y1 = patch->points[0][0].y; + + for (i = 0; i < num_patches; i++) { + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) { + x0 = MIN (x0, patch[i].points[j][k].x); + y0 = MIN (y0, patch[i].points[j][k].y); + x1 = MAX (x1, patch[i].points[j][k].x); + y1 = MAX (y1, patch[i].points[j][k].y); + } + } + } + + *out_xmin = x0; + *out_ymin = y0; + *out_xmax = x1; + *out_ymax = y1; + + return TRUE; +} + /** * _cairo_gradient_pattern_is_solid * @@ -2527,6 +2647,22 @@ _cairo_gradient_pattern_is_solid (const cairo_gradient_pattern_t *gradient, return TRUE; } +static cairo_bool_t +_mesh_is_clear (const cairo_mesh_pattern_t *mesh) +{ + double x1, y1, x2, y2; + cairo_bool_t is_valid; + + is_valid = _cairo_mesh_pattern_coord_box (mesh, &x1, &y1, &x2, &y2); + if (!is_valid) + return TRUE; + + if (x2 - x1 < DBL_EPSILON || y2 - y1 < DBL_EPSILON) + return TRUE; + + return FALSE; +} + /** * _cairo_pattern_is_opaque_solid * @@ -2665,6 +2801,8 @@ _cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern, case CAIRO_PATTERN_TYPE_LINEAR: case CAIRO_PATTERN_TYPE_RADIAL: return _gradient_is_opaque (&pattern->gradient.base, extents); + case CAIRO_PATTERN_TYPE_MESH: + return FALSE; } ASSERT_NOT_REACHED; @@ -2688,6 +2826,8 @@ _cairo_pattern_is_clear (const cairo_pattern_t *abstract_pattern) case CAIRO_PATTERN_TYPE_LINEAR: case CAIRO_PATTERN_TYPE_RADIAL: return _gradient_is_clear (&pattern->gradient.base, NULL); + case CAIRO_PATTERN_TYPE_MESH: + return _mesh_is_clear (&pattern->mesh); } ASSERT_NOT_REACHED; @@ -3306,6 +3446,29 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern, } break; + case CAIRO_PATTERN_TYPE_MESH: + { + const cairo_mesh_pattern_t *mesh = + (const cairo_mesh_pattern_t *) pattern; + double padx, pady; + cairo_bool_t is_valid; + + is_valid = _cairo_mesh_pattern_coord_box (mesh, &x1, &y1, &x2, &y2); + if (!is_valid) + goto EMPTY; + + padx = pady = 1.; + cairo_matrix_transform_distance (&pattern->matrix, &padx, &pady); + padx = fabs (padx); + pady = fabs (pady); + + x1 -= padx; + y1 -= pady; + x2 += padx; + y2 += pady; + } + break; + default: ASSERT_NOT_REACHED; } @@ -3409,6 +3572,18 @@ _cairo_radial_pattern_hash (unsigned long hash, return _cairo_gradient_color_stops_hash (hash, &radial->base); } +static unsigned long +_cairo_mesh_pattern_hash (unsigned long hash, const cairo_mesh_pattern_t *mesh) +{ + const cairo_mesh_patch_t *patch = _cairo_array_index_const (&mesh->patches, 0); + unsigned int i, n = _cairo_array_num_elements (&mesh->patches); + + for (i = 0; i < n; i++) + hash = _cairo_hash_bytes (hash, patch + i, sizeof (cairo_mesh_patch_t)); + + return hash; +} + static unsigned long _cairo_surface_pattern_hash (unsigned long hash, const cairo_surface_pattern_t *surface) @@ -3446,6 +3621,8 @@ _cairo_pattern_hash (const cairo_pattern_t *pattern) return _cairo_linear_pattern_hash (hash, (cairo_linear_pattern_t *) pattern); case CAIRO_PATTERN_TYPE_RADIAL: return _cairo_radial_pattern_hash (hash, (cairo_radial_pattern_t *) pattern); + case CAIRO_PATTERN_TYPE_MESH: + return _cairo_mesh_pattern_hash (hash, (cairo_mesh_pattern_t *) pattern); case CAIRO_PATTERN_TYPE_SURFACE: return _cairo_surface_pattern_hash (hash, (cairo_surface_pattern_t *) pattern); default: @@ -3483,6 +3660,9 @@ _cairo_pattern_size (const cairo_pattern_t *pattern) case CAIRO_PATTERN_TYPE_RADIAL: return sizeof (cairo_radial_pattern_t) + _cairo_gradient_pattern_color_stops_size (pattern); + case CAIRO_PATTERN_TYPE_MESH: + return sizeof (cairo_mesh_pattern_t) + + _cairo_gradient_pattern_color_stops_size (pattern); default: ASSERT_NOT_REACHED; return 0; @@ -3560,6 +3740,29 @@ _cairo_radial_pattern_equal (const cairo_radial_pattern_t *a, return _cairo_gradient_color_stops_equal (&a->base, &b->base); } +static cairo_bool_t +_cairo_mesh_pattern_equal (const cairo_mesh_pattern_t *a, + const cairo_mesh_pattern_t *b) +{ + const cairo_mesh_patch_t *patch_a, *patch_b; + unsigned int i, num_patches_a, num_patches_b; + + num_patches_a = _cairo_array_num_elements (&a->patches); + num_patches_b = _cairo_array_num_elements (&b->patches); + + if (num_patches_a != num_patches_b) + return FALSE; + + for (i = 0; i < num_patches_a; i++) { + patch_a = _cairo_array_index_const (&a->patches, i); + patch_b = _cairo_array_index_const (&a->patches, i); + if (memcmp (patch_a, patch_b, sizeof(cairo_mesh_patch_t)) != 0) + return FALSE; + } + + return TRUE; +} + static cairo_bool_t _cairo_surface_pattern_equal (const cairo_surface_pattern_t *a, const cairo_surface_pattern_t *b) @@ -3603,6 +3806,9 @@ _cairo_pattern_equal (const cairo_pattern_t *a, const cairo_pattern_t *b) case CAIRO_PATTERN_TYPE_RADIAL: return _cairo_radial_pattern_equal ((cairo_radial_pattern_t *) a, (cairo_radial_pattern_t *) b); + case CAIRO_PATTERN_TYPE_MESH: + return _cairo_mesh_pattern_equal ((cairo_mesh_pattern_t *) a, + (cairo_mesh_pattern_t *) b); case CAIRO_PATTERN_TYPE_SURFACE: return _cairo_surface_pattern_equal ((cairo_surface_pattern_t *) a, (cairo_surface_pattern_t *) b); diff --git a/src/cairo-region.c b/src/cairo-region.c index 112b1d824..b15f15166 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -104,6 +104,7 @@ _cairo_region_create_in_error (cairo_status_t status) case CAIRO_STATUS_INVALID_SLANT: case CAIRO_STATUS_INVALID_WEIGHT: case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: + case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: default: _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_region_t *) &_cairo_region_nil; diff --git a/src/cairo-spans.c b/src/cairo-spans.c index a187b8998..bffbdebc4 100644 --- a/src/cairo-spans.c +++ b/src/cairo-spans.c @@ -204,6 +204,7 @@ _cairo_scan_converter_create_in_error (cairo_status_t status) case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: RETURN_NIL; case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: RETURN_NIL; case CAIRO_STATUS_DEVICE_ERROR: RETURN_NIL; + case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: RETURN_NIL; default: break; } @@ -314,6 +315,7 @@ _cairo_span_renderer_create_in_error (cairo_status_t status) case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: RETURN_NIL; case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: RETURN_NIL; case CAIRO_STATUS_DEVICE_ERROR: RETURN_NIL; + case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: RETURN_NIL; default: break; } diff --git a/src/cairo-surface.c b/src/cairo-surface.c index b5ed334ac..71b7e45e0 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -3022,6 +3022,7 @@ _cairo_surface_create_in_error (cairo_status_t status) case CAIRO_STATUS_INVALID_SLANT: case CAIRO_STATUS_INVALID_WEIGHT: case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: + case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: default: _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t *) &_cairo_surface_nil; diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index ab0f0c7db..89e13d0e2 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -934,6 +934,9 @@ _cairo_svg_surface_analyze_operation (cairo_svg_surface_t *surface, return CAIRO_INT_STATUS_UNSUPPORTED; } + if (pattern->type == CAIRO_PATTERN_TYPE_MESH) + return CAIRO_INT_STATUS_UNSUPPORTED; + /* SVG doesn't support extend reflect for image pattern */ if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE && pattern->extend == CAIRO_EXTEND_REFLECT) @@ -2035,6 +2038,9 @@ _cairo_svg_surface_emit_pattern (cairo_svg_surface_t *surface, case CAIRO_PATTERN_TYPE_RADIAL: return _cairo_svg_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern, output, is_stroke, parent_matrix); + + case CAIRO_PATTERN_TYPE_MESH: + ASSERT_NOT_REACHED; } return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); } diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index 1282b3ff0..a09b410b2 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -442,6 +442,51 @@ typedef union { cairo_radial_pattern_t radial; } cairo_gradient_pattern_union_t; +/* + * A mesh patch is a tensor-product patch (bicubic Bezier surface + * patch). It has 16 control points. Each set of 4 points along the + * sides of the 4x4 grid of control points is a Bezier curve that + * defines one side of the patch. A color is assigned to each + * corner. The inner 4 points provide additional control over the + * shape and the color mapping. + * + * Cairo uses the same convention as the PDF Reference for numbering + * the points and side of the patch. + * + * + * Side 1 + * + * p[0][3] p[1][3] p[2][3] p[3][3] + * Side 0 p[0][2] p[1][2] p[2][2] p[3][2] Side 2 + * p[0][1] p[1][1] p[2][1] p[3][1] + * p[0][0] p[1][0] p[2][0] p[3][0] + * + * Side 3 + * + * + * Point Color + * ------------------------- + * points[0][0] colors[0] + * points[0][3] colors[1] + * points[3][3] colors[2] + * points[3][0] colors[3] + */ + +typedef struct _cairo_mesh_patch { + cairo_point_double_t points[4][4]; + cairo_color_t colors[4]; +} cairo_mesh_patch_t; + +typedef struct _cairo_mesh_pattern { + cairo_pattern_t base; + + cairo_array_t patches; + cairo_mesh_patch_t *current_patch; + int current_side; + cairo_bool_t has_control_point[4]; + cairo_bool_t has_color[4]; +} cairo_mesh_pattern_t; + typedef union { cairo_pattern_type_t type; cairo_pattern_t base; @@ -449,6 +494,7 @@ typedef union { cairo_solid_pattern_t solid; cairo_surface_pattern_t surface; cairo_gradient_pattern_union_t gradient; + cairo_mesh_pattern_t mesh; } cairo_pattern_union_t; /* diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c index 4d472b0dd..dabeece7f 100644 --- a/src/cairo-win32-printing-surface.c +++ b/src/cairo-win32-printing-surface.c @@ -971,6 +971,9 @@ _cairo_win32_printing_surface_paint_pattern (cairo_win32_surface_t *surface, case CAIRO_PATTERN_TYPE_RADIAL: return CAIRO_INT_STATUS_UNSUPPORTED; break; + + case CAIRO_PATTERN_TYPE_MESH: + ASSERT_NOT_REACHED; } return CAIRO_STATUS_SUCCESS; diff --git a/src/cairo-xcb-surface-core.c b/src/cairo-xcb-surface-core.c index f12d7354d..4bcbd8fe6 100644 --- a/src/cairo-xcb-surface-core.c +++ b/src/cairo-xcb-surface-core.c @@ -446,6 +446,7 @@ _cairo_xcb_pixmap_for_pattern (cairo_xcb_surface_t *target, /* fallthrough */ case CAIRO_PATTERN_TYPE_LINEAR: case CAIRO_PATTERN_TYPE_RADIAL: + case CAIRO_PATTERN_TYPE_MESH: return _render_to_pixmap (target, pattern, extents); default: diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c index 6a42225e1..e3d1ac477 100644 --- a/src/cairo-xcb-surface-render.c +++ b/src/cairo-xcb-surface-render.c @@ -425,7 +425,7 @@ _pattern_is_supported (uint32_t flags, return FALSE; } - return TRUE; + return pattern->type != CAIRO_PATTERN_TYPE_MESH; } static double @@ -1445,6 +1445,7 @@ _cairo_xcb_picture_for_pattern (cairo_xcb_surface_t *target, return _cairo_xcb_surface_picture (target, (cairo_surface_pattern_t *) pattern, extents); + case CAIRO_PATTERN_TYPE_MESH: default: ASSERT_NOT_REACHED; return _render_to_picture (target, pattern, extents); diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 6d593c047..76cf5d157 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2230,6 +2230,7 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_display_t *display, ASSERT_NOT_REACHED; case CAIRO_PATTERN_TYPE_SOLID: case CAIRO_PATTERN_TYPE_SURFACE: + case CAIRO_PATTERN_TYPE_MESH: break; } diff --git a/src/cairo.h b/src/cairo.h index a45bf1489..74129699e 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -270,6 +270,10 @@ typedef struct _cairo_user_data_key { * @CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: user-font method not implemented (Since 1.10) * @CAIRO_STATUS_DEVICE_TYPE_MISMATCH: the device type is not appropriate for the operation (Since 1.10) * @CAIRO_STATUS_DEVICE_ERROR: an operation to the device caused an unspecified error (Since 1.10) + * @CAIRO_STATUS_INVALID_MESH_CONSTRUCTION: a mesh pattern + * construction operation was used outside of a + * cairo_pattern_mesh_begin_patch()/cairo_pattern_mesh_end_patch() + * pair (Since 1.12) * @CAIRO_STATUS_LAST_STATUS: this is a special value indicating the number of * status values defined in this enumeration. When using this value, note * that the version of cairo at run-time may have additional status values @@ -321,6 +325,7 @@ typedef enum _cairo_status { CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, CAIRO_STATUS_DEVICE_TYPE_MISMATCH, CAIRO_STATUS_DEVICE_ERROR, + CAIRO_STATUS_INVALID_MESH_CONSTRUCTION, CAIRO_STATUS_LAST_STATUS } cairo_status_t; @@ -2360,6 +2365,7 @@ cairo_pattern_set_user_data (cairo_pattern_t *pattern, * @CAIRO_PATTERN_TYPE_SURFACE: The pattern is a based on a surface (an image). * @CAIRO_PATTERN_TYPE_LINEAR: The pattern is a linear gradient. * @CAIRO_PATTERN_TYPE_RADIAL: The pattern is a radial gradient. + * @CAIRO_PATTERN_TYPE_MESH: The pattern is a mesh. * * #cairo_pattern_type_t is used to describe the type of a given pattern. * @@ -2387,7 +2393,8 @@ typedef enum _cairo_pattern_type { CAIRO_PATTERN_TYPE_SOLID, CAIRO_PATTERN_TYPE_SURFACE, CAIRO_PATTERN_TYPE_LINEAR, - CAIRO_PATTERN_TYPE_RADIAL + CAIRO_PATTERN_TYPE_RADIAL, + CAIRO_PATTERN_TYPE_MESH } cairo_pattern_type_t; cairo_public cairo_pattern_type_t diff --git a/src/cairoint.h b/src/cairoint.h index db2836ccf..7cbe0fd30 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2213,6 +2213,13 @@ cairo_private void _cairo_pattern_transform (cairo_pattern_t *pattern, const cairo_matrix_t *ctm_inverse); +cairo_private cairo_bool_t +_cairo_mesh_pattern_coord_box (const cairo_mesh_pattern_t *mesh, + double *out_xmin, + double *out_ymin, + double *out_xmax, + double *out_ymax); + cairo_private void _cairo_pattern_alpha_range (const cairo_pattern_t *gradient, double *out_min, double *out_max); diff --git a/util/cairo-gobject/cairo-gobject-enums.c b/util/cairo-gobject/cairo-gobject-enums.c index 1fcd3d031..152bfd772 100644 --- a/util/cairo-gobject/cairo-gobject-enums.c +++ b/util/cairo-gobject/cairo-gobject-enums.c @@ -49,6 +49,7 @@ cairo_gobject_status_get_type (void) { CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, "CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED", "user-font-not-implemented" }, { CAIRO_STATUS_DEVICE_TYPE_MISMATCH, "CAIRO_STATUS_DEVICE_TYPE_MISMATCH", "device-type-mismatch" }, { CAIRO_STATUS_DEVICE_ERROR, "CAIRO_STATUS_DEVICE_ERROR", "device-error" }, + { CAIRO_STATUS_INVALID_MESH_CONSTRUCTION, "CAIRO_STATUS_INVALID_MESH_CONSTRUCTION", "invalid-mesh-construction" }, { CAIRO_STATUS_LAST_STATUS, "CAIRO_STATUS_LAST_STATUS", "last-status" }, { 0, NULL, NULL } }; @@ -431,6 +432,7 @@ cairo_gobject_pattern_type_get_type (void) { CAIRO_PATTERN_TYPE_SURFACE, "CAIRO_PATTERN_TYPE_SURFACE", "surface" }, { CAIRO_PATTERN_TYPE_LINEAR, "CAIRO_PATTERN_TYPE_LINEAR", "linear" }, { CAIRO_PATTERN_TYPE_RADIAL, "CAIRO_PATTERN_TYPE_RADIAL", "radial" }, + { CAIRO_PATTERN_TYPE_MESH, "CAIRO_PATTERN_TYPE_MESH", "mesh" }, { 0, NULL, NULL } }; GType type = g_enum_register_static (g_intern_static_string ("cairo_pattern_type_t"), values); diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c index acdde937b..b9305060e 100644 --- a/util/cairo-trace/trace.c +++ b/util/cairo-trace/trace.c @@ -1501,6 +1501,7 @@ _status_to_string (cairo_status_t status) f(USER_FONT_NOT_IMPLEMENTED); f(DEVICE_TYPE_MISMATCH); f(DEVICE_ERROR); + f(INVALID_MESH_CONSTRUCTION); case CAIRO_STATUS_LAST_STATUS: break; }