Bitmap* PixmanBitmap::Resample(int scale_w, int scale_h, const Rect& src_rect) {
	PixmanBitmap *dst = new PixmanBitmap(scale_w, scale_h, GetTransparent());

	double zoom_x = (double)src_rect.width  / scale_w;
	double zoom_y = (double)src_rect.height / scale_h;

	pixman_transform_t xform;
	pixman_transform_init_scale(&xform,
								pixman_double_to_fixed(zoom_x),
								pixman_double_to_fixed(zoom_y));
	
	pixman_image_set_transform(bitmap, &xform);

	pixman_image_composite32(PIXMAN_OP_SRC,
							 bitmap, (pixman_image_t*) NULL, dst->bitmap,
							 src_rect.x, src_rect.y,
							 0, 0,
							 0, 0,
							 scale_w, scale_h);

	pixman_transform_init_identity(&xform);
	pixman_image_set_transform(bitmap, &xform);

	return dst;
}
Exemple #2
0
void
joy_filter_gaussian_set_radius(JoyFilter *self, gdouble radius)
{
	g_return_if_fail(JOY_IS_FILTER_GAUSSIAN(self));
	struct Private *priv = GET_PRIVATE(self);
	g_free(priv->kernel);
	gdouble fradius = fabs(radius) + 1.;
	gdouble sigma = sqrt(-(fradius * fradius) / (2. * log(1. / 255.)));
	const gdouble s2 = 2. * sigma * sigma;
	const gdouble s1 = 1. / (G_PI * s2);
	const gint size = 2 * radius + 1;
	gint n = size * size;
	gdouble kernel[n], sum;
	gint i, x, y;
	for (i = 0, sum = 0, x = -radius; x <= radius; ++x) {
		for (y = -radius; y <= radius; ++y, ++i) {
			const gdouble u = x * x;
			const gdouble v = y * y;
			kernel[i] = s1 * exp(-(u + v) / s2);
			sum += kernel[i];
		}
	}
	priv->kernel = g_new(pixman_fixed_t, n + 2);
	priv->kernel[0] = priv->kernel[1] = pixman_int_to_fixed(size);
	for (i = 2; i < n; ++i) {
		priv->kernel[i] = pixman_double_to_fixed(kernel[i] / sum);
	}
	priv->n = n + 2;
	priv->radius = radius;
}
Exemple #3
0
int
parse_fixed_argument (char *arg, pixman_fixed_t *value)
{
    char *tailptr;

    *value = pixman_double_to_fixed (strtod (arg, &tailptr));

    return *tailptr == '\0';
}
Exemple #4
0
static void
weston_matrix_to_pixman_transform(pixman_transform_t *pt,
				  const struct weston_matrix *wm)
{
	/* Pixman supports only 2D transform matrix, but Weston uses 3D, *
	 * so we're omitting Z coordinate here. */
	pt->matrix[0][0] = pixman_double_to_fixed(wm->d[0]);
	pt->matrix[0][1] = pixman_double_to_fixed(wm->d[4]);
	pt->matrix[0][2] = pixman_double_to_fixed(wm->d[12]);
	pt->matrix[1][0] = pixman_double_to_fixed(wm->d[1]);
	pt->matrix[1][1] = pixman_double_to_fixed(wm->d[5]);
	pt->matrix[1][2] = pixman_double_to_fixed(wm->d[13]);
	pt->matrix[2][0] = pixman_double_to_fixed(wm->d[3]);
	pt->matrix[2][1] = pixman_double_to_fixed(wm->d[7]);
	pt->matrix[2][2] = pixman_double_to_fixed(wm->d[15]);
}
void PixmanBitmap::Blit2x(Rect dst_rect, Bitmap* _src, Rect src_rect) {
	PixmanBitmap* src = (PixmanBitmap*) _src;

	pixman_transform_t xform;
	pixman_transform_init_scale(&xform,
								pixman_double_to_fixed(0.5),
								pixman_double_to_fixed(0.5));

	pixman_image_set_transform(src->bitmap, &xform);

	pixman_image_composite32(PIXMAN_OP_SRC,
							 src->bitmap, (pixman_image_t*) NULL, bitmap,
							 src_rect.x, src_rect.y,
							 0, 0,
							 dst_rect.x, dst_rect.y,
							 dst_rect.width, dst_rect.height);

	pixman_transform_init_identity(&xform);
	pixman_image_set_transform(src->bitmap, &xform);

	RefreshCallback();
}
void PixmanBitmap::StretchBlit(Rect dst_rect, Bitmap* _src, Rect src_rect, int opacity) {
	if (opacity < 0)
		return;

	PixmanBitmap* src = (PixmanBitmap*) _src;

	pixman_image_t* mask = (pixman_image_t*) NULL;
	if (opacity < 255) {
		pixman_color_t tcolor = {0, 0, 0, opacity << 8};
		mask = pixman_image_create_solid_fill(&tcolor);
	}

	double zoom_x = (double)src_rect.width  / dst_rect.width;
	double zoom_y = (double)src_rect.height / dst_rect.height;

	pixman_transform_t xform;
	pixman_transform_init_scale(&xform,
								pixman_double_to_fixed(zoom_x),
								pixman_double_to_fixed(zoom_y));

	pixman_image_set_transform(src->bitmap, &xform);

	pixman_image_composite32(PIXMAN_OP_OVER,
							 src->bitmap, mask, bitmap,
							 src_rect.x / zoom_x, src_rect.y / zoom_y,
							 0, 0,
							 dst_rect.x, dst_rect.y,
							 dst_rect.width, dst_rect.height);

	pixman_transform_init_identity(&xform);
	pixman_image_set_transform(src->bitmap, &xform);

	if (mask != NULL)
		pixman_image_unref(mask);

	RefreshCallback();
}
void PixmanBitmap::TransformBlit(Rect dst_rect, Bitmap* _src, Rect src_rect, const Matrix& inv, int opacity) {
	PixmanBitmap* src = (PixmanBitmap*) _src;
	pixman_transform_t xform = {{
		{ pixman_double_to_fixed(inv.xx), pixman_double_to_fixed(inv.xy), pixman_double_to_fixed(inv.x0) },
		{ pixman_double_to_fixed(inv.yx), pixman_double_to_fixed(inv.yy), pixman_double_to_fixed(inv.y0) },
		{ pixman_double_to_fixed(0.0),    pixman_double_to_fixed(0.0),    pixman_double_to_fixed(1.0) }
		}};

	pixman_image_set_transform(src->bitmap, &xform);

	pixman_image_composite32(PIXMAN_OP_OVER,
							 src->bitmap, (pixman_image_t*) NULL, bitmap,
							 dst_rect.x, dst_rect.y,
							 0, 0,
							 dst_rect.x, dst_rect.y,
							 dst_rect.width, dst_rect.height);

	pixman_transform_init_identity(&xform);
	pixman_image_set_transform(src->bitmap, &xform);
}
Exemple #8
0
/* This test demonstrates that clipping is done totally different depending
 * on whether the source is transformed or not.
 */
int
main (int argc, char **argv)
{
#define WIDTH 200
#define HEIGHT 200

#define SMALL 25
    
    uint32_t *sbits = malloc (SMALL * SMALL * 4);
    uint32_t *bits = malloc (WIDTH * HEIGHT * 4);
    pixman_transform_t trans = {
    {
	{ pixman_double_to_fixed (1.0), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.1), },
	{ pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.1), },
	{ pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) }
    } };
	  
    pixman_image_t *src_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, SMALL, SMALL, sbits, 4 * SMALL);
    pixman_image_t *dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, bits, 4 * WIDTH);

    memset (bits, 0xff, WIDTH * HEIGHT * 4);
    memset (sbits, 0x00, SMALL * SMALL * 4);

    pixman_image_composite (PIXMAN_OP_IN,
			    src_img, NULL, dest_img,
			    0, 0, 0, 0, SMALL, SMALL, 200, 200);
    
    pixman_image_set_transform (src_img, &trans);
    
    pixman_image_composite (PIXMAN_OP_IN,
			    src_img, NULL, dest_img,
			    0, 0, 0, 0, SMALL * 2, SMALL * 2, 200, 200);
    
    show_image (dest_img);
    
    pixman_image_unref (src_img);
    pixman_image_unref (dest_img);
    free (bits);
    
    return 0;
}
Exemple #9
0
static void process_image_data(struct fp_img_dev *dev, char **output, int *output_height)
{
    //pixman stuff taken from libfprint/pixman.c, adapted for my purposes.
    pixman_image_t *orig, *resized;
    pixman_transform_t transform;
    struct vfs0050_dev *vfs_dev = dev->priv;
    struct vfs0050_line *line, *calibration_line;
    char *buf = malloc(vfs_dev->scanbuf_idx);
    int lines = vfs_dev->scanbuf_idx / VFS0050_FRAME_SIZE;
    int i, x, sum, last_sum, diff;
    int new_height;
    //just grab one around middle, there should be 100
    calibration_line = (struct vfs0050_line *) ((char *) vfs_dev->calbuf + (50 * VFS0050_FRAME_SIZE));

    new_height = 0;
    for (i = 0; i < lines; i++) {
        line = (struct vfs0050_line *) ((char *) vfs_dev->scanbuf + (i * VFS0050_FRAME_SIZE));
        if (!is_noise(line))
            memcpy(buf + (new_height++ * VFS0050_IMG_WIDTH), line->row, VFS0050_IMG_WIDTH);
        else
            fp_dbg("removed noise at line: %d\n", i);
    }

    orig = pixman_image_create_bits(PIXMAN_a8, VFS0050_IMG_WIDTH, new_height, (uint32_t *) buf, VFS0050_IMG_WIDTH);
    new_height *= VFS0050_SCALE_FACTOR; //scale for resized image
    resized = pixman_image_create_bits(PIXMAN_a8, VFS0050_IMG_WIDTH, new_height, NULL, VFS0050_IMG_WIDTH);
    pixman_transform_init_identity(&transform);
    pixman_transform_scale(NULL, &transform, pixman_int_to_fixed(1), pixman_double_to_fixed(0.2));
    pixman_image_set_transform(orig, &transform);
    pixman_image_set_filter(orig, PIXMAN_FILTER_BEST, NULL, 0);
    pixman_image_composite32(PIXMAN_OP_SRC,
                             orig,
                             NULL,
                             resized,
                             0, 0,
                             0, 0,
                             0, 0,
                             VFS0050_IMG_WIDTH, new_height
                            );
    memcpy(buf, pixman_image_get_data(resized), VFS0050_IMG_WIDTH * new_height);

    pixman_image_unref(orig);
    pixman_image_unref(resized);

    *output_height = new_height;
    *output = buf;
}
Exemple #10
0
pixman_fixed_t*
create_gaussian_blur_kernel (gint    radius,
                             gdouble sigma,
                             gint*   length)
{
	const gdouble   scale2 = 2.0f * sigma * sigma;
	const gdouble   scale1 = 1.0f / (G_PI * scale2);
	const gint      size = 2 * radius + 1;
	const gint      n_params = size * size;
	pixman_fixed_t* params;
	gdouble*        tmp;
	gdouble         sum;
	gint            x;
	gint            y;
	gint            i;

        tmp = g_newa (double, n_params);

        // caluclate gaussian kernel in floating point format
        for (i = 0, sum = 0, x = -radius; x <= radius; ++x) {
                for (y = -radius; y <= radius; ++y, ++i) {
                        const gdouble u = x * x;
                        const gdouble v = y * y;

                        tmp[i] = scale1 * exp (-(u+v)/scale2);

                        sum += tmp[i];
                }
        }

        // normalize gaussian kernel and convert to fixed point format
        params = g_new (pixman_fixed_t, n_params + 2);

        params[0] = pixman_int_to_fixed (size);
        params[1] = pixman_int_to_fixed (size);

        for (i = 0; i < n_params; ++i)
                params[2 + i] = pixman_double_to_fixed (tmp[i] / sum);

        if (length)
                *length = n_params + 2;

        return params;
}
Exemple #11
0
static pixman_image_t *
create_radial (int index)
{
    pixman_point_fixed_t p0, p1;
    pixman_fixed_t r0, r1;
    double x0, x1, radius0, radius1, left, right, center;

    x0 = 0;
    x1 = 1;
    radius0 = radiuses[index];
    radius1 = radiuses[NUM_GRADIENTS - index - 1];

    /* center the gradient */
    left = MIN (x0 - radius0, x1 - radius1);
    right = MAX (x0 + radius0, x1 + radius1);
    center = (left + right) * 0.5;
    x0 -= center;
    x1 -= center;

    /* scale to make it fit within a 1x1 rect centered in (0,0) */
    x0 *= 0.25;
    x1 *= 0.25;
    radius0 *= 0.25;
    radius1 *= 0.25;

    p0.x = pixman_double_to_fixed (x0);
    p0.y = pixman_double_to_fixed (0);

    p1.x = pixman_double_to_fixed (x1);
    p1.y = pixman_double_to_fixed (0);

    r0 = pixman_double_to_fixed (radius0);
    r1 = pixman_double_to_fixed (radius1);

    return pixman_image_create_radial_gradient (&p0, &p1,
						r0, r1,
						stops, NUM_STOPS);
}
Exemple #12
0
int
main (int argc, char **argv)
{
    pixman_image_t *gradient_img;
    pixman_image_t *src_img, *dst_img;
    pixman_gradient_stop_t stops[2] =
	{
	    { pixman_int_to_fixed (0), { 0xffff, 0x0000, 0x0000, 0xffff } },
	    { pixman_int_to_fixed (1), { 0xffff, 0xffff, 0x0000, 0xffff } }
	};
    pixman_point_fixed_t p1 = { 0, 0 };
    pixman_point_fixed_t p2 = { pixman_int_to_fixed (WIDTH),
				pixman_int_to_fixed (HEIGHT) };
    pixman_point_fixed_t c_inner;
    pixman_point_fixed_t c_outer;
    pixman_fixed_t r_inner;
    pixman_fixed_t r_outer;
    pixman_region32_t clip_region;
    pixman_transform_t trans = {
	{ { pixman_double_to_fixed (1.3), pixman_double_to_fixed (0), pixman_double_to_fixed (-0.5), },
	  { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (-0.5), },
	  { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (1.0) } 
	}
    };
    
    src_img = create_solid_bits (0xff0000ff);
    
    c_inner.x = pixman_double_to_fixed (100.0);
    c_inner.y = pixman_double_to_fixed (100.0);
    c_outer.x = pixman_double_to_fixed (100.0);
    c_outer.y = pixman_double_to_fixed (100.0);
    r_inner = 0;
    r_outer = pixman_double_to_fixed (100.0);
    
    gradient_img = pixman_image_create_radial_gradient (&c_inner, &c_outer,
							r_inner, r_outer,
							stops, 2);

#if 0
    gradient_img = pixman_image_create_linear_gradient  (&p1, &p2,
							 stops, 2);
    
#endif

    pixman_image_composite (PIXMAN_OP_OVER, gradient_img, NULL, src_img,
			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
    
    pixman_region32_init_rect (&clip_region, 50, 0, 100, 200);
    pixman_image_set_clip_region32 (src_img, &clip_region);
    pixman_image_set_source_clipping (src_img, TRUE);
    pixman_image_set_has_client_clip (src_img, TRUE);
    pixman_image_set_transform (src_img, &trans);
    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
    
    dst_img = create_solid_bits (0xffff0000);
    pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dst_img,
			    0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
    

#if 0
    printf ("0, 0: %x\n", src[0]);
    printf ("10, 10: %x\n", src[10 * 10 + 10]);
    printf ("w, h: %x\n", src[(HEIGHT - 1) * 100 + (WIDTH - 1)]);
#endif
    
    show_image (dst_img);
    
    pixman_image_unref (gradient_img);
    pixman_image_unref (src_img);
    
    return 0;
}
static uint32_t *
conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
{
    pixman_image_t *image = iter->image;
    int x = iter->x;
    int y = iter->y;
    int width = iter->width;
    uint32_t *buffer = iter->buffer;

    gradient_t *gradient = (gradient_t *)image;
    conical_gradient_t *conical = (conical_gradient_t *)image;
    uint32_t       *end = buffer + width;
    pixman_gradient_walker_t walker;
    pixman_bool_t affine = TRUE;
    double cx = 1.;
    double cy = 0.;
    double cz = 0.;
    double rx = x + 0.5;
    double ry = y + 0.5;
    double rz = 1.;

    _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);

    if (image->common.transform)
    {
        pixman_vector_t v;

        /* reference point is the center of the pixel */
        v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
        v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
        v.vector[2] = pixman_fixed_1;

        if (!pixman_transform_point_3d (image->common.transform, &v))
            return iter->buffer;

        cx = image->common.transform->matrix[0][0] / 65536.;
        cy = image->common.transform->matrix[1][0] / 65536.;
        cz = image->common.transform->matrix[2][0] / 65536.;

        rx = v.vector[0] / 65536.;
        ry = v.vector[1] / 65536.;
        rz = v.vector[2] / 65536.;

        affine =
            image->common.transform->matrix[2][0] == 0 &&
            v.vector[2] == pixman_fixed_1;
    }

    if (affine)
    {
        rx -= conical->center.x / 65536.;
        ry -= conical->center.y / 65536.;

        while (buffer < end)
        {
            if (!mask || *mask++)
            {
                double t = coordinates_to_parameter (rx, ry, conical->angle);

                *buffer = _pixman_gradient_walker_pixel (
                              &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
            }

            ++buffer;

            rx += cx;
            ry += cy;
        }
    }
    else
    {
        while (buffer < end)
        {
            double x, y;

            if (!mask || *mask++)
            {
                double t;

                if (rz != 0)
                {
                    x = rx / rz;
                    y = ry / rz;
                }
                else
                {
                    x = y = 0.;
                }

                x -= conical->center.x / 65536.;
                y -= conical->center.y / 65536.;

                t = coordinates_to_parameter (x, y, conical->angle);

                *buffer = _pixman_gradient_walker_pixel (
                              &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
            }

            ++buffer;

            rx += cx;
            ry += cy;
            rz += cz;
        }
    }

    iter->y++;
    return iter->buffer;
}
int
main (int argc, char **argv)
{
#define WIDTH 400
#define HEIGHT 200
    
    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
    pixman_image_t *src_img;
    pixman_image_t *dest_img;
    int i, j, k, p;

    typedef struct
    {
	pixman_point_fixed_t p0;
	pixman_point_fixed_t p1;
    } point_pair_t;
    
    pixman_gradient_stop_t onestop[1] =
	{
	    { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } },
	};

    pixman_gradient_stop_t subsetstops[2] =
	{
	    { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } },
	    { pixman_int_to_fixed (1), { 0xffff, 0xeeee, 0xeeee, 0xeeee } },
	};

    pixman_gradient_stop_t stops01[2] =
	{
	    { pixman_int_to_fixed (0), { 0xffff, 0xeeee, 0xeeee, 0xeeee } },
	    { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0x1111 } }
	};

    point_pair_t point_pairs [] =
	{ { { pixman_double_to_fixed (0), 0 },
	    { pixman_double_to_fixed (WIDTH / 8.), pixman_int_to_fixed (0) } },
	  { { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) },
	    { pixman_double_to_fixed (WIDTH / 2.0), pixman_double_to_fixed (HEIGHT / 2.0) } }
	};
    
    pixman_transform_t transformations[] = {
	{
	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), },
	      { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 
	    }
	},
	{
	    { { pixman_double_to_fixed (1), pixman_double_to_fixed (0), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (0), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 
	    }
	},
	{
	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (2), pixman_double_to_fixed (1.000), pixman_double_to_fixed (1.0) } 
	    }
	},
	{
	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (0), pixman_double_to_fixed (0), pixman_double_to_fixed (0) } 
	    }
	},
	{
	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) } 
	    }
	},
	{
	    { { pixman_double_to_fixed (2), pixman_double_to_fixed (1), pixman_double_to_fixed (3), },
	      { pixman_double_to_fixed (1), pixman_double_to_fixed (1), pixman_double_to_fixed (0), },
	      { pixman_double_to_fixed (2), pixman_double_to_fixed (-1), pixman_double_to_fixed (0) } 
	    }
	},
    };
    
    pixman_fixed_t r_inner;
    pixman_fixed_t r_outer;

    enable_divbyzero_exceptions();
    
    for (i = 0; i < WIDTH * HEIGHT; ++i)
	dest[i] = 0x4f00004f; /* pale blue */
    
    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
					 WIDTH, HEIGHT, 
					 dest,
					 WIDTH * 4);

    r_inner = 0;
    r_outer = pixman_double_to_fixed (50.0);
    
    for (i = 0; i < 3; ++i)
    {
	pixman_gradient_stop_t *stops;
        int num_stops;

	if (i == 0)
	{
	    stops = onestop;
	    num_stops = ARRAY_LENGTH (onestop);
	}
	else if (i == 1)
	{
	    stops = subsetstops;
	    num_stops = ARRAY_LENGTH (subsetstops);
	}
	else
	{
	    stops = stops01;
	    num_stops = ARRAY_LENGTH (stops01);
	}
	
	for (j = 0; j < 3; ++j)
	{
	    for (p = 0; p < ARRAY_LENGTH (point_pairs); ++p)
	    {
		point_pair_t *pair = &(point_pairs[p]);

		if (j == 0)
		    src_img = pixman_image_create_conical_gradient (&(pair->p0), r_inner,
								    stops, num_stops);
		else if (j == 1)
		    src_img = pixman_image_create_radial_gradient  (&(pair->p0), &(pair->p1),
								    r_inner, r_outer,
								    stops, num_stops);
		else
		    src_img = pixman_image_create_linear_gradient  (&(pair->p0), &(pair->p1),
								    stops, num_stops);
		
		for (k = 0; k < ARRAY_LENGTH (transformations); ++k)
		{
		    pixman_image_set_transform (src_img, &transformations[k]);
		    
		    pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NONE);
		    pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img,
					    0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
		}

		pixman_image_unref (src_img);
	    }

	}
    }

    pixman_image_unref (dest_img);
    free (dest);
    
    return 0;
}
Exemple #15
0
int
main (int argc, char **argv)
{
#define WIDTH 400
#define HEIGHT 200
    
    uint32_t *alpha = malloc (WIDTH * HEIGHT * 4);
    uint32_t *dest = malloc (WIDTH * HEIGHT * 4);
    uint32_t *src = malloc (WIDTH * HEIGHT * 4);
    pixman_image_t *grad_img;
    pixman_image_t *alpha_img;
    pixman_image_t *dest_img;
    pixman_image_t *src_img;
    int i;
    pixman_gradient_stop_t stops[2] =
	{
	    { pixman_int_to_fixed (0), { 0x0000, 0x0000, 0x0000, 0x0000 } },
	    { pixman_int_to_fixed (1), { 0xffff, 0x0000, 0x1111, 0xffff } }
	};
    pixman_point_fixed_t p1 = { pixman_double_to_fixed (0), 0 };
    pixman_point_fixed_t p2 = { pixman_double_to_fixed (WIDTH),
				pixman_int_to_fixed (0) };
#if 0
    pixman_transform_t trans = {
	{ { pixman_double_to_fixed (2), pixman_double_to_fixed (0.5), pixman_double_to_fixed (-100), },
	  { pixman_double_to_fixed (0), pixman_double_to_fixed (3), pixman_double_to_fixed (0), },
	  { pixman_double_to_fixed (0), pixman_double_to_fixed (0.000), pixman_double_to_fixed (1.0) } 
	}
    };
#else
    pixman_transform_t trans = {
	{ { pixman_fixed_1, 0, 0 },
	  { 0, pixman_fixed_1, 0 },
	  { 0, 0, pixman_fixed_1 } }
    };
#endif

    pixman_point_fixed_t c_inner;
    pixman_point_fixed_t c_outer;
    pixman_fixed_t r_inner;
    pixman_fixed_t r_outer;
    
    for (i = 0; i < WIDTH * HEIGHT; ++i)
	alpha[i] = 0x4f00004f; /* pale blue */
    
    alpha_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
					 WIDTH, HEIGHT, 
					  alpha,
					 WIDTH * 4);

    for (i = 0; i < WIDTH * HEIGHT; ++i)
	dest[i] = 0xffffff00;		/* yellow */
    
    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
					 WIDTH, HEIGHT, 
					 dest,
					 WIDTH * 4);

    for (i = 0; i < WIDTH * HEIGHT; ++i)
	src[i] = 0xffff0000;

    src_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
					WIDTH, HEIGHT,
					src,
					WIDTH * 4);
    
    c_inner.x = pixman_double_to_fixed (50.0);
    c_inner.y = pixman_double_to_fixed (50.0);
    c_outer.x = pixman_double_to_fixed (50.0);
    c_outer.y = pixman_double_to_fixed (50.0);
    r_inner = 0;
    r_outer = pixman_double_to_fixed (50.0);
    
#if 0
    grad_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
						    stops, 2);
#endif
#if 0
    grad_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
						    stops, 2);
    grad_img = pixman_image_create_linear_gradient (&c_inner, &c_outer,
						   r_inner, r_outer,
						   stops, 2);
#endif
    
    grad_img = pixman_image_create_linear_gradient  (&p1, &p2,
						    stops, 2);

    pixman_image_set_transform (grad_img, &trans);
    pixman_image_set_repeat (grad_img, PIXMAN_REPEAT_PAD);
    
    pixman_image_composite (PIXMAN_OP_OVER, grad_img, NULL, alpha_img,
			    0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);

    pixman_image_set_alpha_map (src_img, alpha_img, 10, 10);
    
    pixman_image_composite (PIXMAN_OP_OVER, src_img, NULL, dest_img,
			    0, 0, 0, 0, 0, 0, 10 * WIDTH, HEIGHT);
    
    printf ("0, 0: %x\n", dest[0]);
    printf ("10, 10: %x\n", dest[10 * 10 + 10]);
    printf ("w, h: %x\n", dest[(HEIGHT - 1) * 100 + (WIDTH - 1)]);
    
    show_image (dest_img);

    pixman_image_unref (src_img);
    pixman_image_unref (grad_img);
    pixman_image_unref (alpha_img);
    free (dest);
    
    return 0;
}
static void
repaint_region(struct weston_view *ev, struct weston_output *output,
	       pixman_region32_t *region, pixman_region32_t *surf_region,
	       pixman_op_t pixman_op)
{
	struct pixman_renderer *pr =
		(struct pixman_renderer *) output->compositor->renderer;
	struct pixman_surface_state *ps = get_surface_state(ev->surface);
	struct pixman_output_state *po = get_output_state(output);
	pixman_region32_t final_region;
	float view_x, view_y;
	pixman_transform_t transform;
	pixman_fixed_t fw, fh;

	/* The final region to be painted is the intersection of
	 * 'region' and 'surf_region'. However, 'region' is in the global
	 * coordinates, and 'surf_region' is in the surface-local
	 * coordinates
	 */
	pixman_region32_init(&final_region);
	if (surf_region) {
		pixman_region32_copy(&final_region, surf_region);

		/* Convert from surface to global coordinates */
		if (!ev->transform.enabled) {
			pixman_region32_translate(&final_region, ev->geometry.x, ev->geometry.y);
		} else {
			weston_view_to_global_float(ev, 0, 0, &view_x, &view_y);
			pixman_region32_translate(&final_region, (int)view_x, (int)view_y);
		}

		/* We need to paint the intersection */
		pixman_region32_intersect(&final_region, &final_region, region);
	} else {
		/* If there is no surface region, just use the global region */
		pixman_region32_copy(&final_region, region);
	}

	/* Convert from global to output coord */
	region_global_to_output(output, &final_region);

	/* And clip to it */
	pixman_image_set_clip_region32 (po->shadow_image, &final_region);

	/* Set up the source transformation based on the surface
	   position, the output position/transform/scale and the client
	   specified buffer transform/scale */
	pixman_transform_init_identity(&transform);
	pixman_transform_scale(&transform, NULL,
			       pixman_double_to_fixed ((double)1.0/output->current_scale),
			       pixman_double_to_fixed ((double)1.0/output->current_scale));

	fw = pixman_int_to_fixed(output->width);
	fh = pixman_int_to_fixed(output->height);
	switch (output->transform) {
	default:
	case WL_OUTPUT_TRANSFORM_NORMAL:
	case WL_OUTPUT_TRANSFORM_FLIPPED:
		break;
	case WL_OUTPUT_TRANSFORM_90:
	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
		pixman_transform_rotate(&transform, NULL, 0, -pixman_fixed_1);
		pixman_transform_translate(&transform, NULL, 0, fh);
		break;
	case WL_OUTPUT_TRANSFORM_180:
	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
		pixman_transform_rotate(&transform, NULL, -pixman_fixed_1, 0);
		pixman_transform_translate(&transform, NULL, fw, fh);
		break;
	case WL_OUTPUT_TRANSFORM_270:
	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
		pixman_transform_rotate(&transform, NULL, 0, pixman_fixed_1);
		pixman_transform_translate(&transform, NULL, fw, 0);
		break;
	}

	switch (output->transform) {
	case WL_OUTPUT_TRANSFORM_FLIPPED:
	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
		pixman_transform_scale(&transform, NULL,
				       pixman_int_to_fixed (-1),
				       pixman_int_to_fixed (1));
		pixman_transform_translate(&transform, NULL, fw, 0);
		break;
	}

        pixman_transform_translate(&transform, NULL,
				   pixman_double_to_fixed (output->x),
				   pixman_double_to_fixed (output->y));

	if (ev->transform.enabled) {
		/* Pixman supports only 2D transform matrix, but Weston uses 3D,
		 * so we're omitting Z coordinate here
		 */
		pixman_transform_t surface_transform = {{
				{ D2F(ev->transform.matrix.d[0]),
				  D2F(ev->transform.matrix.d[4]),
				  D2F(ev->transform.matrix.d[12]),
				},
				{ D2F(ev->transform.matrix.d[1]),
				  D2F(ev->transform.matrix.d[5]),
				  D2F(ev->transform.matrix.d[13]),
				},
				{ D2F(ev->transform.matrix.d[3]),
				  D2F(ev->transform.matrix.d[7]),
				  D2F(ev->transform.matrix.d[15]),
				}
			}};

		pixman_transform_invert(&surface_transform, &surface_transform);
		pixman_transform_multiply (&transform, &surface_transform, &transform);
	} else {
		pixman_transform_translate(&transform, NULL,
					   pixman_double_to_fixed ((double)-ev->geometry.x),
					   pixman_double_to_fixed ((double)-ev->geometry.y));
	}

	if (ev->surface->buffer_viewport.scaler_set) {
		double scaler_x, scaler_y, scaler_width, scaler_height;
		double ratio_x, ratio_y;

		scaler_x = wl_fixed_to_double(ev->surface->buffer_viewport.src_x);
		scaler_y = wl_fixed_to_double(ev->surface->buffer_viewport.src_y);
		scaler_width = wl_fixed_to_double(ev->surface->buffer_viewport.src_width);
		scaler_height = wl_fixed_to_double(ev->surface->buffer_viewport.src_height);

		ratio_x = scaler_width / ev->surface->buffer_viewport.dst_width;
		ratio_y = scaler_height / ev->surface->buffer_viewport.dst_height;

		pixman_transform_scale(&transform, NULL,
				       pixman_double_to_fixed(ratio_x),
				       pixman_double_to_fixed(ratio_y));
		pixman_transform_translate(&transform, NULL, pixman_double_to_fixed(scaler_x),
							     pixman_double_to_fixed(scaler_y));
	}

	pixman_transform_scale(&transform, NULL,
			       pixman_double_to_fixed(ev->surface->buffer_viewport.scale),
			       pixman_double_to_fixed(ev->surface->buffer_viewport.scale));

	fw = pixman_int_to_fixed(pixman_image_get_width(ps->image));
	fh = pixman_int_to_fixed(pixman_image_get_height(ps->image));

	switch (ev->surface->buffer_viewport.transform) {
	case WL_OUTPUT_TRANSFORM_FLIPPED:
	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
		pixman_transform_scale(&transform, NULL,
				       pixman_int_to_fixed (-1),
				       pixman_int_to_fixed (1));
		pixman_transform_translate(&transform, NULL, fw, 0);
		break;
	}

	switch (ev->surface->buffer_viewport.transform) {
	default:
	case WL_OUTPUT_TRANSFORM_NORMAL:
	case WL_OUTPUT_TRANSFORM_FLIPPED:
		break;
	case WL_OUTPUT_TRANSFORM_90:
	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
		pixman_transform_rotate(&transform, NULL, 0, pixman_fixed_1);
		pixman_transform_translate(&transform, NULL, fh, 0);
		break;
	case WL_OUTPUT_TRANSFORM_180:
	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
		pixman_transform_rotate(&transform, NULL, -pixman_fixed_1, 0);
		pixman_transform_translate(&transform, NULL, fw, fh);
		break;
	case WL_OUTPUT_TRANSFORM_270:
	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
		pixman_transform_rotate(&transform, NULL, 0, -pixman_fixed_1);
		pixman_transform_translate(&transform, NULL, 0, fw);
		break;
	}

	pixman_image_set_transform(ps->image, &transform);

	if (ev->transform.enabled || output->current_scale != ev->surface->buffer_viewport.scale)
		pixman_image_set_filter(ps->image, PIXMAN_FILTER_BILINEAR, NULL, 0);
	else
		pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST, NULL, 0);

	if (ps->buffer_ref.buffer)
		wl_shm_buffer_begin_access(ps->buffer_ref.buffer->shm_buffer);

	pixman_image_composite32(pixman_op,
				 ps->image, /* src */
				 NULL /* mask */,
				 po->shadow_image, /* dest */
				 0, 0, /* src_x, src_y */
				 0, 0, /* mask_x, mask_y */
				 0, 0, /* dest_x, dest_y */
				 pixman_image_get_width (po->shadow_image), /* width */
				 pixman_image_get_height (po->shadow_image) /* height */);

	if (ps->buffer_ref.buffer)
		wl_shm_buffer_end_access(ps->buffer_ref.buffer->shm_buffer);

	if (pr->repaint_debug)
		pixman_image_composite32(PIXMAN_OP_OVER,
					 pr->debug_color, /* src */
					 NULL /* mask */,
					 po->shadow_image, /* dest */
					 0, 0, /* src_x, src_y */
					 0, 0, /* mask_x, mask_y */
					 0, 0, /* dest_x, dest_y */
					 pixman_image_get_width (po->shadow_image), /* width */
					 pixman_image_get_height (po->shadow_image) /* height */);

	pixman_image_set_clip_region32 (po->shadow_image, NULL);

	pixman_region32_fini(&final_region);
}
Exemple #17
0
int
main (int argc, char **argv)
{
    pixman_transform_t transform;
    pixman_image_t *src_img, *dest_img;
    int i, j;

    enable_fp_exceptions ();

    dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
					 WIDTH, HEIGHT,
					 NULL, 0);

    pixman_transform_init_identity (&transform);

    /*
     * The create_radial() function returns gradients centered in the
     * origin and whose interesting part fits a 1x1 square. We want to
     * paint these gradients on a SIZExSIZE square and to make things
     * easier we want the origin in the top-left corner of the square
     * we want to see.
     */
    pixman_transform_translate (NULL, &transform,
				pixman_double_to_fixed (0.5),
				pixman_double_to_fixed (0.5));

    pixman_transform_scale (NULL, &transform,
			    pixman_double_to_fixed (SIZE),
			    pixman_double_to_fixed (SIZE));

    /*
     * Gradients are evaluated at the center of each pixel, so we need
     * to translate by half a pixel to trigger some interesting
     * cornercases. In particular, the original implementation of PDF
     * radial gradients tried to divide by 0 when using this transform
     * on the "tangent circles" cases.
     */
    pixman_transform_translate (NULL, &transform,
				pixman_double_to_fixed (0.5),
				pixman_double_to_fixed (0.5));

    for (i = 0; i < NUM_GRADIENTS; i++)
    {
	src_img = create_radial (i);
	pixman_image_set_transform (src_img, &transform);

	for (j = 0; j < NUM_REPEAT; j++)
	{
	    pixman_image_set_repeat (src_img, repeat[j]);

	    pixman_image_composite32 (PIXMAN_OP_OVER,
				      src_img,
				      NULL,
				      dest_img,
				      0, 0,
				      0, 0,
				      i * SIZE, j * SIZE,
				      SIZE, SIZE);

	}

	pixman_image_unref (src_img);
    }

    show_image (dest_img);

    pixman_image_unref (dest_img);

    return 0;
}