third_party/cairo/src/cairo-mesh-pattern-rasterizer.c
static void
draw_bezier_patch (unsigned char *data, int width, int height, int stride,
		     cairo_point_double_t p[4][4], double c[4][4])
{
    double top, bottom, left, right, steps_sq;
    int i, j, v;

    top = bottom = p[0][0].y;
    for (i = 0; i < 4; ++i) {
	for (j= 0; j < 4; ++j) {
	    top    = MIN (top,    p[i][j].y);
	    bottom = MAX (bottom, p[i][j].y);
	}
    }

    v = intersect_interval (top, bottom, 0, height);
    if (v == OUTSIDE)
	return;

    left = right = p[0][0].x;
    for (i = 0; i < 4; ++i) {
	for (j= 0; j < 4; ++j) {
	    left  = MIN (left,  p[i][j].x);
	    right = MAX (right, p[i][j].x);
	}
    }

    v &= intersect_interval (left, right, 0, width);
    if (v == OUTSIDE)
	return;

    steps_sq = 0;
    for (i = 0; i < 4; ++i)
	steps_sq = MAX (steps_sq, bezier_steps_sq (p[i]));

    if (steps_sq >= (v == INSIDE ? STEPS_MAX_V * STEPS_MAX_V : STEPS_CLIP_V * STEPS_CLIP_V)) {
	/* The number of steps is greater than the threshold. This
	 * means that either the error would become too big if we
	 * directly rasterized it or that we can probably save some
	 * time by splitting the curve and clipping part of it. The
	 * patch is only split in the v direction to guarantee that
	 * rasterizing each part will overwrite parts with low v with
	 * overlapping parts with higher v. */

	cairo_point_double_t first[4][4], second[4][4];
	double subc[4][4];

	for (i = 0; i < 4; ++i)
	    split_bezier (p[i], first[i], second[i]);

	for (i = 0; i < 4; ++i) {
	    subc[0][i] = c[0][i];
	    subc[1][i] = c[1][i];
	    subc[2][i] = 0.5 * (c[0][i] + c[2][i]);
	    subc[3][i] = 0.5 * (c[1][i] + c[3][i]);
	}

	draw_bezier_patch (data, width, height, stride, first, subc);

	for (i = 0; i < 4; ++i) {
	    subc[0][i] = subc[2][i];
	    subc[1][i] = subc[3][i];
	    subc[2][i] = c[2][i];
	    subc[3][i] = c[3][i];
	}
	draw_bezier_patch (data, width, height, stride, second, subc);
    } else {
	rasterize_bezier_patch (data, width, height, stride, sqsteps2shift (steps_sq), p, c);
    }
}
/*
 * Clip, split and rasterize a Bezier cubic patch.
 *
 * Input: data is the base pointer of the image
 *        width, height are the dimensions of the image
 *        stride is the stride in bytes between adjacent rows
 *        p[i][j], p[i][j] are the nodes of the patch
 *        col[i][j] is the j-th color component of the i-th corner
 *
 * Output: data will be changed to have the requested patch drawn in
 *         the specified colors
 *
 * The nodes of the patch are as follows:
 *
 * u\v 0    - >    1
 * 0  p00 p01 p02 p03
 * |  p10 p11 p12 p13
 * v  p20 p21 p22 p23
 * 1  p30 p31 p32 p33
 *
 * i.e. u varies along the first component (rows), v varies along the
 * second one (columns).
 *
 * The color components are red, green, blue and alpha, in this order.
 * c[0..3] are the colors in p00, p30, p03, p33 respectively
 *
 * The input color components are not premultiplied, but the data
 * stored in the image is assumed to be in CAIRO_FORMAT_ARGB32 (8 bpc,
 * premultiplied).
 *
 * If the patch folds over itself, the part with the highest v
 * parameter is considered above. If both have the same v, the one
 * with the highest u parameter is above.
 *
 * The function guarantees that it will draw the patch with a step
 * small enough to never have a distance above 1/sqrt(2) between two
 * adjacent points (which guarantees that no hole can appear).
 *
 * This function can be used to rasterize a tile of PDF type 7
 * shadings (see http://www.adobe.com/devnet/pdf/pdf_reference.html).
 */
Clip, split and rasterize a Bezier cubic patch.
Input: data is the base pointer of the image
width, height are the dimensions of the image
stride is the stride in bytes between adjacent rows
p[i][j], p[i][j] are the nodes of the patch
col[i][j] is the j-th color component of the i-th corner

data will be changed to have the requested patch drawn in
the specified colors

The nodes of the patch are as follows.





The color components are red, green, blue and alpha, in this order.

The input color components are not premultiplied, but the data
stored in the image is assumed to be in CAIRO_FORMAT_ARGB32 (8 bpc,
premultiplied).

If the patch folds over itself, the part with the highest v
parameter is considered above. If both have the same v, the one
with the highest u parameter is above.

The function guarantees that it will draw the patch with a step
small enough to never have a distance above 1/sqrt(2) between two
adjacent points (which guarantees that no hole can appear).

This function can be used to rasterize a tile of PDF type 7
shadings .
Clip split and rasterize a Bezier cubic patch . Input : data is the base pointer of the image width height are the dimensions of the image stride is the stride in bytes between adjacent rows p [ i ] [ j ] p [ i ] [ j ] are the nodes of the patch col [ i ] [ j ] is the j - th color component of the i - th corner data will be changed to have the requested patch drawn in the specified colors The nodes of the patch are as follows . The color components are red green blue and alpha in this order . The input color components are not premultiplied but the data stored in the image is assumed to be in CAIRO_FORMAT_ARGB32 ( 8 bpc premultiplied ) . If the patch folds over itself the part with the highest v parameter is considered above . If both have the same v the one with the highest u parameter is above . The function guarantees that it will draw the patch with a step small enough to never have a distance above 1 / sqrt ( 2 ) between two adjacent points ( which guarantees that no hole can appear ) . This function can be used to rasterize a tile of PDF type 7 shadings .
static void
draw_bezier_patch (unsigned char *data, int width, int height, int stride,
		     cairo_point_double_t p[4][4], double c[4][4])
{
    double top, bottom, left, right, steps_sq;
    int i, j, v;
    top = bottom = p[0][0].y;
    for (i = 0; i < 4; ++i) {
	for (j= 0; j < 4; ++j) {
	    top    = MIN (top,    p[i][j].y);
	    bottom = MAX (bottom, p[i][j].y);
	}
    }
    v = intersect_interval (top, bottom, 0, height);
    if (v == OUTSIDE)
	return;
    left = right = p[0][0].x;
    for (i = 0; i < 4; ++i) {
	for (j= 0; j < 4; ++j) {
	    left  = MIN (left,  p[i][j].x);
	    right = MAX (right, p[i][j].x);
	}
    }
    v &= intersect_interval (left, right, 0, width);
    if (v == OUTSIDE)
	return;
    steps_sq = 0;
    for (i = 0; i < 4; ++i)
	steps_sq = MAX (steps_sq, bezier_steps_sq (p[i]));
    if (steps_sq >= (v == INSIDE ? STEPS_MAX_V * STEPS_MAX_V : STEPS_CLIP_V * STEPS_CLIP_V)) {
	cairo_point_double_t first[4][4], second[4][4];
	double subc[4][4];
	for (i = 0; i < 4; ++i)
	    split_bezier (p[i], first[i], second[i]);
	for (i = 0; i < 4; ++i) {
	    subc[0][i] = c[0][i];
	    subc[1][i] = c[1][i];
	    subc[2][i] = 0.5 * (c[0][i] + c[2][i]);
	    subc[3][i] = 0.5 * (c[1][i] + c[3][i]);
	}
	draw_bezier_patch (data, width, height, stride, first, subc);
	for (i = 0; i < 4; ++i) {
	    subc[0][i] = subc[2][i];
	    subc[1][i] = subc[3][i];
	    subc[2][i] = c[2][i];
	    subc[3][i] = c[3][i];
	}
	draw_bezier_patch (data, width, height, stride, second, subc);
    } else {
	rasterize_bezier_patch (data, width, height, stride, sqsteps2shift (steps_sq), p, c);
    }
}
static void draw_bezier_patch ( unsigned char * data , int width , int height , int stride , cairo_point_double_t p [ 4 ] [ 4 ] , double c [ 4 ] [ 4 ] ) { double top , bottom , left , right , steps_sq ; int i , j , v ; top = bottom = p [ 0 ] [ 0 ] . y ; for ( i = 0 ; i < 4 ; ++ i ) { for ( j = 0 ; j < 4 ; ++ j ) { top = MIN ( top , p [ i ] [ j ] . y ) ; bottom = MAX ( bottom , p [ i ] [ j ] . y ) ; } } v = intersect_interval ( top , bottom , 0 , height ) ; if ( v == OUTSIDE ) return ; left = right = p [ 0 ] [ 0 ] . x ; for ( i = 0 ; i < 4 ; ++ i ) { for ( j = 0 ; j < 4 ; ++ j ) { left = MIN ( left , p [ i ] [ j ] . x ) ; right = MAX ( right , p [ i ] [ j ] . x ) ; } } v &= intersect_interval ( left , right , 0 , width ) ; if ( v == OUTSIDE ) return ; steps_sq = 0 ; for ( i = 0 ; i < 4 ; ++ i ) steps_sq = MAX ( steps_sq , bezier_steps_sq ( p [ i ] ) ) ; if ( steps_sq >= ( v == INSIDE ? STEPS_MAX_V * STEPS_MAX_V : STEPS_CLIP_V * STEPS_CLIP_V ) ) { cairo_point_double_t first [ 4 ] [ 4 ] , second [ 4 ] [ 4 ] ; double subc [ 4 ] [ 4 ] ; for ( i = 0 ; i < 4 ; ++ i ) split_bezier ( p [ i ] , first [ i ] , second [ i ] ) ; for ( i = 0 ; i < 4 ; ++ i ) { subc [ 0 ] [ i ] = c [ 0 ] [ i ] ; subc [ 1 ] [ i ] = c [ 1 ] [ i ] ; subc [ 2 ] [ i ] = 0.5 * ( c [ 0 ] [ i ] + c [ 2 ] [ i ] ) ; subc [ 3 ] [ i ] = 0.5 * ( c [ 1 ] [ i ] + c [ 3 ] [ i ] ) ; } draw_bezier_patch ( data , width , height , stride , first , subc ) ; for ( i = 0 ; i < 4 ; ++ i ) { subc [ 0 ] [ i ] = subc [ 2 ] [ i ] ; subc [ 1 ] [ i ] = subc [ 3 ] [ i ] ; subc [ 2 ] [ i ] = c [ 2 ] [ i ] ; subc [ 3 ] [ i ] = c [ 3 ] [ i ] ; } draw_bezier_patch ( data , width , height , stride , second , subc ) ; } else { rasterize_bezier_patch ( data , width , height , stride , sqsteps2shift ( steps_sq ) , p , c ) ; } }
Clip, split and rasterize a Bezier cubic patch.
Clip split and rasterize a Bezier cubic patch .
/* The number of steps is greater than the threshold. This
	 * means that either the error would become too big if we
	 * directly rasterized it or that we can probably save some
	 * time by splitting the curve and clipping part of it. The
	 * patch is only split in the v direction to guarantee that
	 * rasterizing each part will overwrite parts with low v with
	 * overlapping parts with higher v. */