diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 010aa3259..7820f571c 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -1075,7 +1075,9 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern, pixman_gradient_stop_t pixman_stops_static[2]; pixman_gradient_stop_t *pixman_stops = pixman_stops_static; pixman_transform_t pixman_transform; - cairo_matrix_t matrix = pattern->base.matrix; + cairo_matrix_t matrix; + cairo_circle_double_t extremes[2]; + pixman_point_fixed_t p1, p2; unsigned int i; cairo_status_t status; @@ -1094,66 +1096,24 @@ _pixman_image_for_gradient (const cairo_gradient_pattern_t *pattern, pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short; } + _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes); + + p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); + p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); + p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); + p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); + if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) { - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern; - pixman_point_fixed_t p1, p2; - cairo_fixed_t xdim, ydim; - - xdim = fabs (linear->p2.x - linear->p1.x); - ydim = fabs (linear->p2.y - linear->p1.y); - - /* - * Transform the matrix to avoid overflow when converting between - * cairo_fixed_t and pixman_fixed_t (without incurring performance - * loss when the transformation is unnecessary). - * - * XXX: Consider converting out-of-range co-ordinates and transforms. - * Having a function to compute the required transformation to - * "normalize" a given bounding box would be generally useful - - * cf linear patterns, gradient patterns, surface patterns... - */ - if (_cairo_fixed_integer_ceil (xdim) > PIXMAN_MAX_INT || - _cairo_fixed_integer_ceil (ydim) > PIXMAN_MAX_INT) - { - double sf; - - if (xdim > ydim) - sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (xdim); - else - sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (ydim); - - p1.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.x) * sf); - p1.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.y) * sf); - p2.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.x) * sf); - p2.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.y) * sf); - - cairo_matrix_scale (&matrix, sf, sf); - } - else - { - p1.x = _cairo_fixed_to_16_16 (linear->p1.x); - p1.y = _cairo_fixed_to_16_16 (linear->p1.y); - p2.x = _cairo_fixed_to_16_16 (linear->p2.x); - p2.y = _cairo_fixed_to_16_16 (linear->p2.y); - } - pixman_image = pixman_image_create_linear_gradient (&p1, &p2, pixman_stops, pattern->n_stops); } else { - cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern; - pixman_point_fixed_t c1, c2; pixman_fixed_t r1, r2; - c1.x = _cairo_fixed_to_16_16 (radial->c1.x); - c1.y = _cairo_fixed_to_16_16 (radial->c1.y); - r1 = _cairo_fixed_to_16_16 (radial->r1); + r1 = _cairo_fixed_16_16_from_double (extremes[0].radius); + r2 = _cairo_fixed_16_16_from_double (extremes[1].radius); - c2.x = _cairo_fixed_to_16_16 (radial->c2.x); - c2.y = _cairo_fixed_to_16_16 (radial->c2.y); - r2 = _cairo_fixed_to_16_16 (radial->r2); - - pixman_image = pixman_image_create_radial_gradient (&c1, &c2, r1, r2, + pixman_image = pixman_image_create_radial_gradient (&p1, &p2, r1, r2, pixman_stops, pattern->n_stops); } diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index c69e70bad..13bf99dab 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -35,6 +35,8 @@ #include +#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ + /** * SECTION:cairo-pattern * @Title: cairo_pattern_t @@ -2124,6 +2126,8 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat cairo_image_surface_t *image; pixman_image_t *pixman_image; pixman_transform_t pixman_transform; + cairo_circle_double_t extremes[2]; + pixman_point_fixed_t p1, p2; cairo_status_t status; cairo_bool_t repeat = FALSE; int ix, iy; @@ -2151,71 +2155,24 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short; } - if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) - { - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern; - pixman_point_fixed_t p1, p2; - cairo_fixed_t xdim, ydim; + _cairo_gradient_pattern_fit_to_range (pattern, PIXMAN_MAX_INT >> 1, &matrix, extremes); - xdim = linear->p2.x - linear->p1.x; - ydim = linear->p2.y - linear->p1.y; - - /* - * Transform the matrix to avoid overflow when converting between - * cairo_fixed_t and pixman_fixed_t (without incurring performance - * loss when the transformation is unnecessary). - * - * XXX: Consider converting out-of-range co-ordinates and transforms. - * Having a function to compute the required transformation to - * "normalize" a given bounding box would be generally useful - - * cf linear patterns, gradient patterns, surface patterns... - */ -#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ - if (_cairo_fixed_integer_ceil (xdim) > PIXMAN_MAX_INT || - _cairo_fixed_integer_ceil (ydim) > PIXMAN_MAX_INT) - { - double sf; - - if (xdim > ydim) - sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (xdim); - else - sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (ydim); - - p1.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.x) * sf); - p1.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.y) * sf); - p2.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.x) * sf); - p2.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.y) * sf); - - cairo_matrix_scale (&matrix, sf, sf); - } - else - { - p1.x = _cairo_fixed_to_16_16 (linear->p1.x); - p1.y = _cairo_fixed_to_16_16 (linear->p1.y); - p2.x = _cairo_fixed_to_16_16 (linear->p2.x); - p2.y = _cairo_fixed_to_16_16 (linear->p2.y); - } + p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); + p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); + p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); + p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); + if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) { pixman_image = pixman_image_create_linear_gradient (&p1, &p2, pixman_stops, pattern->n_stops); - } - else - { - cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern; - pixman_point_fixed_t c1, c2; + } else { pixman_fixed_t r1, r2; - c1.x = _cairo_fixed_to_16_16 (radial->c1.x); - c1.y = _cairo_fixed_to_16_16 (radial->c1.y); - r1 = _cairo_fixed_to_16_16 (radial->r1); + r1 = _cairo_fixed_16_16_from_double (extremes[0].radius); + r2 = _cairo_fixed_16_16_from_double (extremes[1].radius); - c2.x = _cairo_fixed_to_16_16 (radial->c2.x); - c2.y = _cairo_fixed_to_16_16 (radial->c2.y); - r2 = _cairo_fixed_to_16_16 (radial->r2); - - pixman_image = pixman_image_create_radial_gradient (&c1, &c2, - r1, r2, + pixman_image = pixman_image_create_radial_gradient (&p1, &p2, r1, r2, pixman_stops, pattern->n_stops); } @@ -3078,6 +3035,91 @@ _cairo_gradient_pattern_interpolate (const cairo_gradient_pattern_t *gradient, #undef lerp } + +/** + * _cairo_gradient_pattern_fit_to_range + * + * Scale the extremes of a gradient to guarantee that the coordinates + * and their deltas are within the range (-max_value, max_value). The + * new extremes are stored in out_circle. + * + * The pattern matrix is scaled to guarantee that the aspect of the + * gradient is the same and the result is stored in out_matrix. + * + **/ +void +_cairo_gradient_pattern_fit_to_range (const cairo_gradient_pattern_t *gradient, + double max_value, + cairo_matrix_t *out_matrix, + cairo_circle_double_t out_circle[2]) +{ + double dim; + + assert (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR || + gradient->base.type == CAIRO_PATTERN_TYPE_RADIAL); + + if (gradient->base.type == CAIRO_PATTERN_TYPE_LINEAR) { + cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) gradient; + + out_circle[0].center.x = _cairo_fixed_to_double (linear->p1.x); + out_circle[0].center.y = _cairo_fixed_to_double (linear->p1.y); + out_circle[0].radius = 0; + out_circle[1].center.x = _cairo_fixed_to_double (linear->p2.x); + out_circle[1].center.y = _cairo_fixed_to_double (linear->p2.y); + out_circle[1].radius = 0; + + dim = fabs (_cairo_fixed_to_double (linear->p1.x)); + dim = MAX (dim, fabs (_cairo_fixed_to_double (linear->p1.y))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (linear->p2.x))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (linear->p2.y))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (linear->p1.x) - + _cairo_fixed_to_double (linear->p2.x))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (linear->p1.y) - + _cairo_fixed_to_double (linear->p2.y))); + } else { + cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) gradient; + + out_circle[0].center.x = _cairo_fixed_to_double (radial->c1.x); + out_circle[0].center.y = _cairo_fixed_to_double (radial->c1.y); + out_circle[0].radius = _cairo_fixed_to_double (radial->r1); + + out_circle[1].center.x = _cairo_fixed_to_double (radial->c2.x); + out_circle[1].center.y = _cairo_fixed_to_double (radial->c2.y); + out_circle[1].radius = _cairo_fixed_to_double (radial->r2); + + dim = fabs (_cairo_fixed_to_double (radial->c1.x)); + dim = MAX (dim, fabs (_cairo_fixed_to_double (radial->c1.y))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (radial->r1))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (radial->c2.x))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (radial->c2.y))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (radial->r2))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (radial->c1.x) - + _cairo_fixed_to_double (radial->c2.x))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (radial->c1.y) - + _cairo_fixed_to_double (radial->c2.y))); + dim = MAX (dim, fabs (_cairo_fixed_to_double (radial->r1) - + _cairo_fixed_to_double (radial->r2))); + } + + if (unlikely (dim > max_value)) { + cairo_matrix_t scale; + + dim = max_value / dim; + + out_circle[0].center.x *= dim; + out_circle[0].center.y *= dim; + out_circle[0].radius *= dim; + out_circle[1].center.x *= dim; + out_circle[1].center.y *= dim; + out_circle[1].radius *= dim; + + cairo_matrix_init_scale (&scale, dim, dim); + cairo_matrix_multiply (out_matrix, &gradient->base.matrix, &scale); + } else { + *out_matrix = gradient->base.matrix; + } +} + static cairo_bool_t _gradient_is_clear (const cairo_gradient_pattern_t *gradient, const cairo_rectangle_int_t *extents) diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c index 068ab3d33..fb23fbee6 100644 --- a/src/cairo-xcb-surface-render.c +++ b/src/cairo-xcb-surface-render.c @@ -879,14 +879,16 @@ _cairo_xcb_linear_picture (cairo_xcb_surface_t *target, const cairo_rectangle_int_t *extents) { char buf[CAIRO_STACK_BUFFER_SIZE]; - cairo_fixed_t xdim, ydim; xcb_render_fixed_t *stops; xcb_render_color_t *colors; xcb_render_pointfix_t p1, p2; - cairo_matrix_t matrix = pattern->base.base.matrix; + cairo_matrix_t matrix; + cairo_circle_double_t extremes[2]; cairo_xcb_picture_t *picture; cairo_status_t status; + _cairo_gradient_pattern_fit_to_range (&pattern->base, PIXMAN_MAX_INT >> 1, &matrix, extremes); + picture = (cairo_xcb_picture_t *) _cairo_xcb_screen_lookup_linear_picture (target->screen, pattern); if (picture != NULL) @@ -907,46 +909,13 @@ _cairo_xcb_linear_picture (cairo_xcb_surface_t *target, } picture->filter = CAIRO_FILTER_DEFAULT; - xdim = pattern->p2.x - pattern->p1.x; - ydim = pattern->p2.y - pattern->p1.y; - - /* - * Transform the matrix to avoid overflow when converting between - * cairo_fixed_t and pixman_fixed_t (without incurring performance - * loss when the transformation is unnecessary). - * - * XXX: Consider converting out-of-range co-ordinates and transforms. - * Having a function to compute the required transformation to - * "normalize" a given bounding box would be generally useful - - * cf linear patterns, gradient patterns, surface patterns... - */ -#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ - if (unlikely (_cairo_fixed_integer_ceil (xdim) > PIXMAN_MAX_INT || - _cairo_fixed_integer_ceil (ydim) > PIXMAN_MAX_INT)) - { - double sf; - - if (xdim > ydim) - sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (xdim); - else - sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (ydim); - - p1.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (pattern->p1.x) * sf); - p1.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (pattern->p1.y) * sf); - p2.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (pattern->p2.x) * sf); - p2.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (pattern->p2.y) * sf); - - cairo_matrix_scale (&matrix, sf, sf); - } - else - { - p1.x = _cairo_fixed_to_16_16 (pattern->p1.x); - p1.y = _cairo_fixed_to_16_16 (pattern->p1.y); - p2.x = _cairo_fixed_to_16_16 (pattern->p2.x); - p2.y = _cairo_fixed_to_16_16 (pattern->p2.y); - } - colors = (xcb_render_color_t *) (stops + pattern->base.n_stops); + + p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); + p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); + p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); + p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); + _cairo_xcb_connection_render_create_linear_gradient (target->connection, picture->picture, p1, p2, @@ -985,11 +954,15 @@ _cairo_xcb_radial_picture (cairo_xcb_surface_t *target, char buf[CAIRO_STACK_BUFFER_SIZE]; xcb_render_fixed_t *stops; xcb_render_color_t *colors; - xcb_render_pointfix_t c1, c2; + xcb_render_pointfix_t p1, p2; xcb_render_fixed_t r1, r2; + cairo_matrix_t matrix; + cairo_circle_double_t extremes[2]; cairo_xcb_picture_t *picture; cairo_status_t status; + _cairo_gradient_pattern_fit_to_range (&pattern->base, PIXMAN_MAX_INT >> 1, &matrix, extremes); + picture = (cairo_xcb_picture_t *) _cairo_xcb_screen_lookup_radial_picture (target->screen, pattern); if (picture != NULL) @@ -1010,17 +983,19 @@ _cairo_xcb_radial_picture (cairo_xcb_surface_t *target, } picture->filter = CAIRO_FILTER_DEFAULT; - c1.x = _cairo_fixed_to_16_16 (pattern->c1.x); - c1.y = _cairo_fixed_to_16_16 (pattern->c1.y); - r1 = _cairo_fixed_to_16_16 (pattern->r1); - c2.x = _cairo_fixed_to_16_16 (pattern->c2.x); - c2.y = _cairo_fixed_to_16_16 (pattern->c2.y); - r2 = _cairo_fixed_to_16_16 (pattern->r2); - colors = (xcb_render_color_t *) (stops + pattern->base.n_stops); + + p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); + p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); + p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); + p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); + + r1 = _cairo_fixed_16_16_from_double (extremes[0].radius); + r2 = _cairo_fixed_16_16_from_double (extremes[1].radius); + _cairo_xcb_connection_render_create_radial_gradient (target->connection, picture->picture, - c1, c2, r1, r2, + p1, p2, r1, r2, pattern->base.n_stops, stops, colors); @@ -1036,7 +1011,7 @@ _cairo_xcb_radial_picture (cairo_xcb_surface_t *target, } setup_picture: - _cairo_xcb_picture_set_matrix (picture, &pattern->base.base.matrix, + _cairo_xcb_picture_set_matrix (picture, &matrix, pattern->base.base.filter, extents->x + extents->width/2., extents->y + extents->height/2.); diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index f59b61b28..693ece2c7 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -59,6 +59,7 @@ #include /* for XDestroyImage */ #define XLIB_COORD_MAX 32767 +#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ #define DEBUG 0 @@ -2094,6 +2095,7 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_display_t *display, cairo_matrix_t matrix = pattern->matrix; cairo_xlib_surface_t *surface; char buf[CAIRO_STACK_BUFFER_SIZE]; + cairo_circle_double_t extremes[2]; XFixed *stops; XRenderColor *colors; XRenderPictFormat *format; @@ -2143,70 +2145,32 @@ _cairo_xlib_surface_acquire_pattern_surface (cairo_xlib_display_t *display, XSync (display->display, False); #endif + _cairo_gradient_pattern_fit_to_range (gradient, PIXMAN_MAX_INT >> 1, &matrix, extremes); + if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) { - cairo_linear_pattern_t *linear = (cairo_linear_pattern_t *) pattern; XLinearGradient grad; - cairo_fixed_t xdim, ydim; - - xdim = linear->p2.x - linear->p1.x; - ydim = linear->p2.y - linear->p1.y; - - /* - * Transform the matrix to avoid overflow when converting between - * cairo_fixed_t and pixman_fixed_t (without incurring performance - * loss when the transformation is unnecessary). - * - * XXX: Consider converting out-of-range co-ordinates and transforms. - * Having a function to compute the required transformation to - * "normalize" a given bounding box would be generally useful - - * cf linear patterns, gradient patterns, surface patterns... - */ -#define PIXMAN_MAX_INT ((pixman_fixed_1 >> 1) - pixman_fixed_e) /* need to ensure deltas also fit */ - if (_cairo_fixed_integer_ceil (xdim) > PIXMAN_MAX_INT || - _cairo_fixed_integer_ceil (ydim) > PIXMAN_MAX_INT) - { - double sf; - - if (xdim > ydim) - sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (xdim); - else - sf = PIXMAN_MAX_INT / _cairo_fixed_to_double (ydim); - - grad.p1.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.x) * sf); - grad.p1.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p1.y) * sf); - grad.p2.x = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.x) * sf); - grad.p2.y = _cairo_fixed_16_16_from_double (_cairo_fixed_to_double (linear->p2.y) * sf); - - cairo_matrix_scale (&matrix, sf, sf); - } - else - { - grad.p1.x = _cairo_fixed_to_16_16 (linear->p1.x); - grad.p1.y = _cairo_fixed_to_16_16 (linear->p1.y); - grad.p2.x = _cairo_fixed_to_16_16 (linear->p2.x); - grad.p2.y = _cairo_fixed_to_16_16 (linear->p2.y); - } + grad.p1.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); + grad.p1.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); + grad.p2.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); + grad.p2.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); picture = XRenderCreateLinearGradient (display->display, &grad, stops, colors, gradient->n_stops); } else { - cairo_radial_pattern_t *radial = (cairo_radial_pattern_t *) pattern; XRadialGradient grad; - grad.inner.x = _cairo_fixed_to_16_16 (radial->c1.x); - grad.inner.y = _cairo_fixed_to_16_16 (radial->c1.y); - grad.inner.radius = _cairo_fixed_to_16_16 (radial->r1); - - grad.outer.x = _cairo_fixed_to_16_16 (radial->c2.x); - grad.outer.y = _cairo_fixed_to_16_16 (radial->c2.y); - grad.outer.radius = _cairo_fixed_to_16_16 (radial->r2); + grad.inner.x = _cairo_fixed_16_16_from_double (extremes[0].center.x); + grad.inner.y = _cairo_fixed_16_16_from_double (extremes[0].center.y); + grad.inner.radius = _cairo_fixed_16_16_from_double (extremes[0].radius); + grad.outer.x = _cairo_fixed_16_16_from_double (extremes[1].center.x); + grad.outer.y = _cairo_fixed_16_16_from_double (extremes[1].center.y); + grad.outer.radius = _cairo_fixed_16_16_from_double (extremes[1].radius); picture = XRenderCreateRadialGradient (display->display, &grad, stops, colors, gradient->n_stops); - } if (stops != (XFixed *) buf) diff --git a/src/cairoint.h b/src/cairoint.h index 6c34c5b73..f8e13b24d 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2241,6 +2241,12 @@ _cairo_gradient_pattern_interpolate (const cairo_gradient_pattern_t *gradient, double t, cairo_circle_double_t *out_circle); +cairo_private void +_cairo_gradient_pattern_fit_to_range (const cairo_gradient_pattern_t *gradient, + double max_value, + cairo_matrix_t *out_matrix, + cairo_circle_double_t out_circle[2]); + cairo_private cairo_bool_t _cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern);