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

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

    /* Check visibility */
    v = intersect_interval (top, bottom, 0, height);
    if (v == OUTSIDE)
	return;

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

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

    steps_sq = bezier_steps_sq (p);
    if (steps_sq >= (v == INSIDE ? STEPS_MAX_U * STEPS_MAX_U : STEPS_CLIP_U * STEPS_CLIP_U)) {
	/*
	 * 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
	 */
	cairo_point_double_t first[4], second[4];
	double midc[4];
	split_bezier (p, first, second);
	midc[0] = (c0[0] + c3[0]) * 0.5;
	midc[1] = (c0[1] + c3[1]) * 0.5;
	midc[2] = (c0[2] + c3[2]) * 0.5;
	midc[3] = (c0[3] + c3[3]) * 0.5;
	draw_bezier_curve (data, width, height, stride, first, c0, midc);
	draw_bezier_curve (data, width, height, stride, second, midc, c3);
    } else {
	double xu[4], yu[4];
	int ushift = sqsteps2shift (steps_sq), k;

	fd_init (p[0].x, p[1].x, p[2].x, p[3].x, xu);
	fd_init (p[0].y, p[1].y, p[2].y, p[3].y, yu);

	for (k = 0; k < ushift; ++k) {
	    fd_down (xu);
	    fd_down (yu);
	}

	rasterize_bezier_curve (data, width, height, stride, ushift,
				xu, yu,
				_cairo_color_double_to_short (c0[0]),
				_cairo_color_double_to_short (c0[1]),
				_cairo_color_double_to_short (c0[2]),
				_cairo_color_double_to_short (c0[3]),
				_cairo_color_double_to_short (c3[0]),
				_cairo_color_double_to_short (c3[1]),
				_cairo_color_double_to_short (c3[2]),
				_cairo_color_double_to_short (c3[3]));

	/* Draw the end point, to make sure that we didn't leave it
	 * out because of rounding */
	draw_pixel (data, width, height, stride,
		    _cairo_fixed_integer_floor (_cairo_fixed_from_double (p[3].x)),
		    _cairo_fixed_integer_floor (_cairo_fixed_from_double (p[3].y)),
		    _cairo_color_double_to_short (c3[0]),
		    _cairo_color_double_to_short (c3[1]),
		    _cairo_color_double_to_short (c3[2]),
		    _cairo_color_double_to_short (c3[3]));
    }
}
/*
 * Clip, split and rasterize a Bezier curve.
 *
 * 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] is the i-th node of the Bezier curve
 *        c0[i] is the i-th color component at the start point
 *        c3[i] is the i-th color component at the end point
 *
 * Output: data will be changed to have the requested curve drawn in
 *         the specified colors
 *
 * 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).
 *
 * The color components are red, green, blue and alpha, in this order.
 *
 * The function guarantees that it will draw the curve with a step
 * small enough to never have a distance above 1/sqrt(2) between two
 * consecutive points (which is needed to ensure that no hole can
 * appear when using this function to rasterize a patch).
 */
Clip, split and rasterize a Bezier curve.
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] is the i-th node of the Bezier curve
c0[i] is the i-th color component at the start point
c3[i] is the i-th color component at the end point

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

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).

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

The function guarantees that it will draw the curve with a step
small enough to never have a distance above 1/sqrt(2) between two
consecutive points (which is needed to ensure that no hole can
appear when using this function to rasterize a patch).
Clip split and rasterize a Bezier curve . 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 ] is the i - th node of the Bezier curve c0 [ i ] is the i - th color component at the start point c3 [ i ] is the i - th color component at the end point data will be changed to have the requested curve drawn in the specified colors 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 ) . The color components are red green blue and alpha in this order . The function guarantees that it will draw the curve with a step small enough to never have a distance above 1 / sqrt ( 2 ) between two consecutive points ( which is needed to ensure that no hole can appear when using this function to rasterize a patch ) .
static void
draw_bezier_curve (unsigned char *data, int width, int height, int stride,
		   cairo_point_double_t p[4], double c0[4], double c3[4])
{
    double top, bottom, left, right, steps_sq;
    int i, v;
    top = bottom = p[0].y;
    for (i = 1; i < 4; ++i) {
	top    = MIN (top,    p[i].y);
	bottom = MAX (bottom, p[i].y);
    }
    v = intersect_interval (top, bottom, 0, height);
    if (v == OUTSIDE)
	return;
    left = right = p[0].x;
    for (i = 1; i < 4; ++i) {
	left  = MIN (left,  p[i].x);
	right = MAX (right, p[i].x);
    }
    v &= intersect_interval (left, right, 0, width);
    if (v == OUTSIDE)
	return;
    steps_sq = bezier_steps_sq (p);
    if (steps_sq >= (v == INSIDE ? STEPS_MAX_U * STEPS_MAX_U : STEPS_CLIP_U * STEPS_CLIP_U)) {
	cairo_point_double_t first[4], second[4];
	double midc[4];
	split_bezier (p, first, second);
	midc[0] = (c0[0] + c3[0]) * 0.5;
	midc[1] = (c0[1] + c3[1]) * 0.5;
	midc[2] = (c0[2] + c3[2]) * 0.5;
	midc[3] = (c0[3] + c3[3]) * 0.5;
	draw_bezier_curve (data, width, height, stride, first, c0, midc);
	draw_bezier_curve (data, width, height, stride, second, midc, c3);
    } else {
	double xu[4], yu[4];
	int ushift = sqsteps2shift (steps_sq), k;
	fd_init (p[0].x, p[1].x, p[2].x, p[3].x, xu);
	fd_init (p[0].y, p[1].y, p[2].y, p[3].y, yu);
	for (k = 0; k < ushift; ++k) {
	    fd_down (xu);
	    fd_down (yu);
	}
	rasterize_bezier_curve (data, width, height, stride, ushift,
				xu, yu,
				_cairo_color_double_to_short (c0[0]),
				_cairo_color_double_to_short (c0[1]),
				_cairo_color_double_to_short (c0[2]),
				_cairo_color_double_to_short (c0[3]),
				_cairo_color_double_to_short (c3[0]),
				_cairo_color_double_to_short (c3[1]),
				_cairo_color_double_to_short (c3[2]),
				_cairo_color_double_to_short (c3[3]));
	draw_pixel (data, width, height, stride,
		    _cairo_fixed_integer_floor (_cairo_fixed_from_double (p[3].x)),
		    _cairo_fixed_integer_floor (_cairo_fixed_from_double (p[3].y)),
		    _cairo_color_double_to_short (c3[0]),
		    _cairo_color_double_to_short (c3[1]),
		    _cairo_color_double_to_short (c3[2]),
		    _cairo_color_double_to_short (c3[3]));
    }
}
static void draw_bezier_curve ( unsigned char * data , int width , int height , int stride , cairo_point_double_t p [ 4 ] , double c0 [ 4 ] , double c3 [ 4 ] ) { double top , bottom , left , right , steps_sq ; int i , v ; top = bottom = p [ 0 ] . y ; for ( i = 1 ; i < 4 ; ++ i ) { top = MIN ( top , p [ i ] . y ) ; bottom = MAX ( bottom , p [ i ] . y ) ; } v = intersect_interval ( top , bottom , 0 , height ) ; if ( v == OUTSIDE ) return ; left = right = p [ 0 ] . x ; for ( i = 1 ; i < 4 ; ++ i ) { left = MIN ( left , p [ i ] . x ) ; right = MAX ( right , p [ i ] . x ) ; } v &= intersect_interval ( left , right , 0 , width ) ; if ( v == OUTSIDE ) return ; steps_sq = bezier_steps_sq ( p ) ; if ( steps_sq >= ( v == INSIDE ? STEPS_MAX_U * STEPS_MAX_U : STEPS_CLIP_U * STEPS_CLIP_U ) ) { cairo_point_double_t first [ 4 ] , second [ 4 ] ; double midc [ 4 ] ; split_bezier ( p , first , second ) ; midc [ 0 ] = ( c0 [ 0 ] + c3 [ 0 ] ) * 0.5 ; midc [ 1 ] = ( c0 [ 1 ] + c3 [ 1 ] ) * 0.5 ; midc [ 2 ] = ( c0 [ 2 ] + c3 [ 2 ] ) * 0.5 ; midc [ 3 ] = ( c0 [ 3 ] + c3 [ 3 ] ) * 0.5 ; draw_bezier_curve ( data , width , height , stride , first , c0 , midc ) ; draw_bezier_curve ( data , width , height , stride , second , midc , c3 ) ; } else { double xu [ 4 ] , yu [ 4 ] ; int ushift = sqsteps2shift ( steps_sq ) , k ; fd_init ( p [ 0 ] . x , p [ 1 ] . x , p [ 2 ] . x , p [ 3 ] . x , xu ) ; fd_init ( p [ 0 ] . y , p [ 1 ] . y , p [ 2 ] . y , p [ 3 ] . y , yu ) ; for ( k = 0 ; k < ushift ; ++ k ) { fd_down ( xu ) ; fd_down ( yu ) ; } rasterize_bezier_curve ( data , width , height , stride , ushift , xu , yu , _cairo_color_double_to_short ( c0 [ 0 ] ) , _cairo_color_double_to_short ( c0 [ 1 ] ) , _cairo_color_double_to_short ( c0 [ 2 ] ) , _cairo_color_double_to_short ( c0 [ 3 ] ) , _cairo_color_double_to_short ( c3 [ 0 ] ) , _cairo_color_double_to_short ( c3 [ 1 ] ) , _cairo_color_double_to_short ( c3 [ 2 ] ) , _cairo_color_double_to_short ( c3 [ 3 ] ) ) ; draw_pixel ( data , width , height , stride , _cairo_fixed_integer_floor ( _cairo_fixed_from_double ( p [ 3 ] . x ) ) , _cairo_fixed_integer_floor ( _cairo_fixed_from_double ( p [ 3 ] . y ) ) , _cairo_color_double_to_short ( c3 [ 0 ] ) , _cairo_color_double_to_short ( c3 [ 1 ] ) , _cairo_color_double_to_short ( c3 [ 2 ] ) , _cairo_color_double_to_short ( c3 [ 3 ] ) ) ; } }
Clip, split and rasterize a Bezier curve.
Clip split and rasterize a Bezier curve .
/* Check visibility */ /*
	 * 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
	 */ /* Draw the end point, to make sure that we didn't leave it
	 * out because of rounding */