Beispiel #1
0
cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t		*pixman_image,
					      pixman_format_code_t	 pixman_format)
{
    cairo_image_surface_t *surface;

    surface = malloc (sizeof (cairo_image_surface_t));
    if (surface == NULL)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    _cairo_surface_init (&surface->base, &_cairo_image_surface_backend,
			 _cairo_content_from_pixman_format (pixman_format));

    surface->pixman_image = pixman_image;

    surface->pixman_format = pixman_format;
    surface->format = _cairo_format_from_pixman_format (pixman_format);
    surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
    surface->owns_data = FALSE;
    surface->has_clip = FALSE;
    surface->transparency = CAIRO_IMAGE_UNKNOWN;

    surface->width = pixman_image_get_width (pixman_image);
    surface->height = pixman_image_get_height (pixman_image);
    surface->stride = pixman_image_get_stride (pixman_image);
    surface->depth = pixman_image_get_depth (pixman_image);

    return &surface->base;
}
cairo_surface_t *
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
					      cairo_format_t  format)
{
    cairo_image_surface_t *surface;

    surface = malloc (sizeof (cairo_image_surface_t));
    if (surface == NULL) {
	_cairo_error (CAIRO_STATUS_NO_MEMORY);
	return (cairo_surface_t*) &_cairo_surface_nil;
    }

    _cairo_surface_init (&surface->base, &cairo_image_surface_backend);

    surface->pixman_image = pixman_image;

    surface->format = format;
    surface->data = (unsigned char *) pixman_image_get_data (pixman_image);
    surface->owns_data = FALSE;
    surface->has_clip = FALSE;

    surface->width = pixman_image_get_width (pixman_image);
    surface->height = pixman_image_get_height (pixman_image);
    surface->stride = pixman_image_get_stride (pixman_image);
    surface->depth = pixman_image_get_depth (pixman_image);

    return &surface->base;
}
static void
fill (pixman_image_t *image, uint32_t pixel)
{
    uint8_t *data = (uint8_t *)pixman_image_get_data (image);
    int bytes_per_pixel = PIXMAN_FORMAT_BPP (pixman_image_get_format (image)) / 8;
    int n_bytes = pixman_image_get_stride (image) * pixman_image_get_height (image);
    int i;

    switch (bytes_per_pixel)
    {
    case 4:
	for (i = 0; i < n_bytes / 4; ++i)
	    ((uint32_t *)data)[i] = pixel;
	break;

    case 2:
	pixel &= 0xffff;
	for (i = 0; i < n_bytes / 2; ++i)
	    ((uint16_t *)data)[i] = pixel;
	break;

    case 1:
	pixel &= 0xff;
	for (i = 0; i < n_bytes; ++i)
	    ((uint8_t *)data)[i] = pixel;
	break;

    default:
	assert (0);
	break;
    }
}
Beispiel #4
0
pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
                                          pixman_image_t *image)
{
    return pixman_image_create_bits(format,
                                    pixman_image_get_width(image),
                                    pixman_image_get_height(image),
                                    NULL,
                                    pixman_image_get_stride(image));
}
Beispiel #5
0
static inline void copy_to_gldrawable_from_pixmap(const RedDrawable_p* dest,
                                                  const SpiceRect& area,
                                                  const SpicePoint& offset,
                                                  const PixelsSource_p* source,
                                                  int src_x, int src_y)
{
    uint8_t *addr;
    GLXContext context = NULL;
    GLXPbuffer pbuffer;
    RenderType rendertype;
    Window win;

    rendertype = dest->source.x_drawable.rendertype;
    if (rendertype == RENDER_TYPE_FBO) {
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
        glBindTexture(GL_TEXTURE_2D, 0);
    } else {
        context = dest->source.x_drawable.context;
        win = dest->source.x_drawable.drawable;
        glXMakeCurrent(XPlatform::get_display(), win, context);
        glDisable(GL_TEXTURE_2D);
    }

    glPixelStorei(GL_UNPACK_ROW_LENGTH, pixman_image_get_stride(source->pixmap.pixman_image) / 4);

    glPixelZoom(1, -1);
    addr = (uint8_t *)pixman_image_get_data(source->pixmap.pixman_image);
    addr += (src_x * 4 + src_y * pixman_image_get_stride(source->pixmap.pixman_image));
    glWindowPos2i(area.left + offset.x, dest->source.x_drawable.height -
                  (area.top + offset.y));  //+ (area.bottom - area.top)));
    glDrawPixels(area.right - area.left, area.bottom - area.top,
                 GL_BGRA, GL_UNSIGNED_BYTE, addr);

    if (rendertype == RENDER_TYPE_FBO) {
        GLuint fbo;

        fbo = dest->source.x_drawable.fbo;
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
    } else {
        pbuffer = dest->source.x_drawable.pbuff;
        glXMakeCurrent(XPlatform::get_display(), pbuffer, context);
    }
}
Beispiel #6
0
static inline void copy_to_pixmap_from_gltexture(const RedDrawable_p* dest,
                                                 const SpiceRect& area,
                                                 const SpicePoint& offset,
                                                 const PixelsSource_p* source,
                                                 int src_x, int src_y)
{
    int y, height;
    GLXContext context = NULL;
    GLXPbuffer pbuffer;
    Window win;
    RenderType rendertype;

    y = source->gl.height - src_y;
    height = area.bottom - area.top;

    rendertype = source->gl.rendertype;
    if (rendertype == RENDER_TYPE_FBO) {
        glBindFramebuffer(GL_FRAMEBUFFER_EXT, source->gl.fbo);
        glBindTexture(GL_TEXTURE_2D, 0);
    } else {
        context = source->gl.context;
        pbuffer = source->gl.pbuff;
        glXMakeCurrent(XPlatform::get_display(), pbuffer, context);
        glDisable(GL_TEXTURE_2D);
    }
    glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
    glPixelStorei(GL_PACK_ROW_LENGTH,
                  pixman_image_get_stride(dest->source.pixmap.pixman_image) / 4);

    while (height > 0) {
        glReadPixels(src_x, y - height, area.right - area.left, 1,
                     GL_BGRA, GL_UNSIGNED_BYTE,
                     (uint8_t *)pixman_image_get_data(dest->source.pixmap.pixman_image) +
                     (area.left + offset.x) * 4 +
                     (area.top + offset.y + height - 1) *
                     pixman_image_get_stride(dest->source.pixmap.pixman_image));
        height--;
    }
    if (rendertype != RENDER_TYPE_FBO) {
        win = source->gl.win;
        glXMakeCurrent(XPlatform::get_display(), win, context);
    }
}
Beispiel #7
0
static void qemu_spice_create_update(SimpleSpiceDisplay *ssd)
{
    static const int blksize = 32;
    int blocks = (surface_width(ssd->ds) + blksize - 1) / blksize;
    int dirty_top[blocks];
    int y, yoff1, yoff2, x, xoff, blk, bw;
    int bpp = surface_bytes_per_pixel(ssd->ds);
    uint8_t *guest, *mirror;

    if (qemu_spice_rect_is_empty(&ssd->dirty)) {
        return;
    };

    for (blk = 0; blk < blocks; blk++) {
        dirty_top[blk] = -1;
    }

    guest = surface_data(ssd->ds);
    mirror = (void *)pixman_image_get_data(ssd->mirror);
    for (y = ssd->dirty.top; y < ssd->dirty.bottom; y++) {
        yoff1 = y * surface_stride(ssd->ds);
        yoff2 = y * pixman_image_get_stride(ssd->mirror);
        for (x = ssd->dirty.left; x < ssd->dirty.right; x += blksize) {
            xoff = x * bpp;
            blk = x / blksize;
            bw = MIN(blksize, ssd->dirty.right - x);
            if (memcmp(guest + yoff1 + xoff,
                       mirror + yoff2 + xoff,
                       bw * bpp) == 0) {
                if (dirty_top[blk] != -1) {
                    QXLRect update = {
                        .top    = dirty_top[blk],
                        .bottom = y,
                        .left   = x,
                        .right  = x + bw,
                    };
                    qemu_spice_create_one_update(ssd, &update);
                    dirty_top[blk] = -1;
                }
            } else {
                if (dirty_top[blk] == -1) {
                    dirty_top[blk] = y;
                }
            }
        }
    }
Beispiel #8
0
/* Free random image, and optionally update crc32 based on its data */
static uint32_t
free_random_image (uint32_t initcrc,
		   pixman_image_t *img,
		   pixman_format_code_t fmt)
{
    uint32_t crc32 = 0;
    int stride = pixman_image_get_stride (img);
    uint32_t *data = pixman_image_get_data (img);
    int height = pixman_image_get_height (img);

    if (fmt != PIXMAN_null)
    {
	/* mask unused 'x' part */
	if (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt) &&
	    PIXMAN_FORMAT_DEPTH (fmt) != 0)
	{
	    int i;
	    uint32_t *data = pixman_image_get_data (img);
	    uint32_t mask = (1 << PIXMAN_FORMAT_DEPTH (fmt)) - 1;

	    if (PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_BGRA ||
		PIXMAN_FORMAT_TYPE (fmt) == PIXMAN_TYPE_RGBA)
	    {
		mask <<= (PIXMAN_FORMAT_BPP (fmt) - PIXMAN_FORMAT_DEPTH (fmt));
	    }

	    for (i = 0; i < 32; i++)
		mask |= mask << (i * PIXMAN_FORMAT_BPP (fmt));

	    for (i = 0; i < stride * height / 4; i++)
		data[i] &= mask;
	}

	/* swap endiannes in order to provide identical results on both big
	 * and litte endian systems
	 */
	image_endian_swap (img);
	crc32 = compute_crc32 (initcrc, data, stride * height);
    }

    pixman_image_unref (img);
    free (data);

    return crc32;
}
void
_cairo_image_surface_init (cairo_image_surface_t *surface,
			   pixman_image_t	*pixman_image,
			   pixman_format_code_t	 pixman_format)
{
    surface->parent = NULL;
    surface->pixman_image = pixman_image;

    surface->pixman_format = pixman_format;
    surface->format = _cairo_format_from_pixman_format (pixman_format);
    surface->data = (uint8_t *) pixman_image_get_data (pixman_image);
    surface->owns_data = FALSE;
    surface->transparency = CAIRO_IMAGE_UNKNOWN;
    surface->color = CAIRO_IMAGE_UNKNOWN_COLOR;

    surface->width = pixman_image_get_width (pixman_image);
    surface->height = pixman_image_get_height (pixman_image);
    surface->stride = pixman_image_get_stride (pixman_image);
    surface->depth = pixman_image_get_depth (pixman_image);

    surface->base.is_clear = surface->width == 0 || surface->height == 0;

    surface->compositor = _cairo_image_spans_compositor_get ();
}
/*
 * Composite operation with pseudorandom images
 */
uint32_t
test_composite (int testnum, int verbose)
{
    int i;
    pixman_image_t *src_img = NULL;
    pixman_image_t *dst_img = NULL;
    pixman_image_t *mask_img = NULL;
    int src_width, src_height;
    int dst_width, dst_height;
    int src_stride, dst_stride;
    int src_x, src_y;
    int dst_x, dst_y;
    int mask_x, mask_y;
    int w, h;
    pixman_op_t op;
    pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
    uint32_t *dstbuf, *srcbuf, *maskbuf;
    uint32_t crc32;
    int max_width, max_height, max_extra_stride;
    FLOAT_REGS_CORRUPTION_DETECTOR_START ();

    max_width = max_height = 24 + testnum / 10000;
    max_extra_stride = 4 + testnum / 1000000;

    if (max_width > 256)
	max_width = 256;

    if (max_height > 16)
	max_height = 16;

    if (max_extra_stride > 8)
	max_extra_stride = 8;

    lcg_srand (testnum);

    op = op_list[lcg_rand_n (sizeof (op_list) / sizeof (op_list[0]))];

    if (lcg_rand_n (8))
    {
	/* normal image */
	src_img = create_random_image (img_fmt_list, max_width, max_height,
				       max_extra_stride, &src_fmt);
    }
    else
    {
	/* solid case */
	src_img = create_random_image (img_fmt_list, 1, 1,
				       max_extra_stride, &src_fmt);

	pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
    }

    dst_img = create_random_image (img_fmt_list, max_width, max_height,
				   max_extra_stride, &dst_fmt);

    src_width = pixman_image_get_width (src_img);
    src_height = pixman_image_get_height (src_img);
    src_stride = pixman_image_get_stride (src_img);

    dst_width = pixman_image_get_width (dst_img);
    dst_height = pixman_image_get_height (dst_img);
    dst_stride = pixman_image_get_stride (dst_img);

    dstbuf = pixman_image_get_data (dst_img);
    srcbuf = pixman_image_get_data (src_img);

    src_x = lcg_rand_n (src_width);
    src_y = lcg_rand_n (src_height);
    dst_x = lcg_rand_n (dst_width);
    dst_y = lcg_rand_n (dst_height);

    mask_img = NULL;
    mask_fmt = PIXMAN_null;
    mask_x = 0;
    mask_y = 0;
    maskbuf = NULL;

    if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
	(lcg_rand_n (4) == 0))
    {
	/* PIXBUF */
	mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
	mask_img = pixman_image_create_bits (mask_fmt,
	                                     src_width,
	                                     src_height,
	                                     srcbuf,
	                                     src_stride);
	mask_x = src_x;
	mask_y = src_y;
	maskbuf = srcbuf;
    }
    else if (lcg_rand_n (2))
    {
	if (lcg_rand_n (2))
	{
	    mask_img = create_random_image (mask_fmt_list, max_width, max_height,
					   max_extra_stride, &mask_fmt);
	}
	else
	{
	    /* solid case */
	    mask_img = create_random_image (mask_fmt_list, 1, 1,
					   max_extra_stride, &mask_fmt);
	    pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
	}

	if (lcg_rand_n (2))
	    pixman_image_set_component_alpha (mask_img, 1);

	mask_x = lcg_rand_n (pixman_image_get_width (mask_img));
	mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
    }


    w = lcg_rand_n (dst_width - dst_x + 1);
    h = lcg_rand_n (dst_height - dst_y + 1);

    if (verbose)
    {
	printf ("op=%d, src_fmt=%08X, dst_fmt=%08X, mask_fmt=%08X\n",
	    op, src_fmt, dst_fmt, mask_fmt);
	printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
	    src_width, src_height, dst_width, dst_height);
	printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
	    src_x, src_y, dst_x, dst_y);
	printf ("src_stride=%d, dst_stride=%d\n",
	    src_stride, dst_stride);
	printf ("w=%d, h=%d\n", w, h);
    }

    pixman_image_composite (op, src_img, mask_img, dst_img,
			    src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);

    if (verbose)
    {
	int j;

	printf ("---\n");
	for (i = 0; i < dst_height; i++)
	{
	    for (j = 0; j < dst_stride; j++)
	    {
		if (j == (dst_width * PIXMAN_FORMAT_BPP (dst_fmt) + 7) / 8)
		    printf ("| ");

		printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j));
	    }
	    printf ("\n");
	}
	printf ("---\n");
    }

    free_random_image (0, src_img, PIXMAN_null);
    crc32 = free_random_image (0, dst_img, dst_fmt);

    if (mask_img)
    {
	if (srcbuf == maskbuf)
	    pixman_image_unref(mask_img);
	else
	    free_random_image (0, mask_img, PIXMAN_null);
    }

    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
    return crc32;
}
/*
 * Composite operation with pseudorandom images
 */
uint32_t
test_composite (int testnum, int verbose)
{
    pixman_image_t *src_img = NULL;
    pixman_image_t *dst_img = NULL;
    pixman_image_t *mask_img = NULL;
    int src_width, src_height;
    int dst_width, dst_height;
    int src_stride, dst_stride;
    int src_x, src_y;
    int dst_x, dst_y;
    int mask_x, mask_y;
    int w, h;
    pixman_op_t op;
    pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
    uint32_t *srcbuf, *maskbuf;
    uint32_t crc32;
    int max_width, max_height, max_extra_stride;
    FLOAT_REGS_CORRUPTION_DETECTOR_START ();

    max_width = max_height = 24 + testnum / 10000;
    max_extra_stride = 4 + testnum / 1000000;

    if (max_width > 256)
	max_width = 256;

    if (max_height > 16)
	max_height = 16;

    if (max_extra_stride > 8)
	max_extra_stride = 8;

    prng_srand (testnum);

    op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))];

    if (prng_rand_n (8))
    {
	/* normal image */
	src_img = create_random_image (img_fmt_list, max_width, max_height,
				       max_extra_stride, &src_fmt);
    }
    else
    {
	/* solid case */
	src_img = create_random_image (img_fmt_list, 1, 1,
				       max_extra_stride, &src_fmt);

	pixman_image_set_repeat (src_img, PIXMAN_REPEAT_NORMAL);
    }

    dst_img = create_random_image (img_fmt_list, max_width, max_height,
				   max_extra_stride, &dst_fmt);

    src_width = pixman_image_get_width (src_img);
    src_height = pixman_image_get_height (src_img);
    src_stride = pixman_image_get_stride (src_img);

    dst_width = pixman_image_get_width (dst_img);
    dst_height = pixman_image_get_height (dst_img);
    dst_stride = pixman_image_get_stride (dst_img);

    srcbuf = pixman_image_get_data (src_img);

    src_x = prng_rand_n (src_width);
    src_y = prng_rand_n (src_height);
    dst_x = prng_rand_n (dst_width);
    dst_y = prng_rand_n (dst_height);

    mask_img = NULL;
    mask_fmt = PIXMAN_null;
    mask_x = 0;
    mask_y = 0;
    maskbuf = NULL;

    if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
	(prng_rand_n (4) == 0))
    {
	/* PIXBUF */
	mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
	mask_img = pixman_image_create_bits (mask_fmt,
	                                     src_width,
	                                     src_height,
	                                     srcbuf,
	                                     src_stride);
	mask_x = src_x;
	mask_y = src_y;
	maskbuf = srcbuf;
    }
    else if (prng_rand_n (2))
    {
	if (prng_rand_n (2))
	{
	    mask_img = create_random_image (mask_fmt_list, max_width, max_height,
					   max_extra_stride, &mask_fmt);
	}
	else
	{
	    /* solid case */
	    mask_img = create_random_image (mask_fmt_list, 1, 1,
					   max_extra_stride, &mask_fmt);
	    pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
	}

	if (prng_rand_n (2))
	    pixman_image_set_component_alpha (mask_img, 1);

	mask_x = prng_rand_n (pixman_image_get_width (mask_img));
	mask_y = prng_rand_n (pixman_image_get_height (mask_img));
    }


    w = prng_rand_n (dst_width - dst_x + 1);
    h = prng_rand_n (dst_height - dst_y + 1);

    if (verbose)
    {
        printf ("op=%s\n", operator_name (op));
	printf ("src_fmt=%s, dst_fmt=%s, mask_fmt=%s\n",
	    format_name (src_fmt), format_name (dst_fmt),
	    format_name (mask_fmt));
	printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n",
	    src_width, src_height, dst_width, dst_height);
	printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n",
	    src_x, src_y, dst_x, dst_y);
	printf ("src_stride=%d, dst_stride=%d\n",
	    src_stride, dst_stride);
	printf ("w=%d, h=%d\n", w, h);
    }

    pixman_image_composite (op, src_img, mask_img, dst_img,
			    src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);

    if (verbose)
	print_image (dst_img);

    free_random_image (0, src_img, PIXMAN_null);
    crc32 = free_random_image (0, dst_img, dst_fmt);

    if (mask_img)
    {
	if (srcbuf == maskbuf)
	    pixman_image_unref(mask_img);
	else
	    free_random_image (0, mask_img, PIXMAN_null);
    }

    FLOAT_REGS_CORRUPTION_DETECTOR_FINISH ();
    return crc32;
}
static void
uxa_check_glyphs(CARD8 op,
		 PicturePtr src,
		 PicturePtr dst,
		 PictFormatPtr maskFormat,
		 INT16 xSrc,
		 INT16 ySrc, int nlist, GlyphListPtr list, GlyphPtr * glyphs)
{
	pixman_image_t *image;
	PixmapPtr scratch;
	PicturePtr mask, mask_src = NULL, mask_dst = NULL, white = NULL;
	int width = 0, height = 0;
	int x, y, n;
	int xDst = list->xOff, yDst = list->yOff;
	BoxRec extents = { 0, 0, 0, 0 };
	CARD8 mask_op = 0;

	if (maskFormat) {
		pixman_format_code_t format;
		CARD32 component_alpha;
		xRenderColor color;
		int error;

		uxa_glyph_extents(nlist, list, glyphs, &extents);
		if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
			return;

		width = extents.x2 - extents.x1;
		height = extents.y2 - extents.y1;

		format = maskFormat->format |
			(BitsPerPixel(maskFormat->depth) << 24);
		image =
			pixman_image_create_bits(format, width, height, NULL, 0);
		if (!image)
			return;

		scratch = GetScratchPixmapHeader(dst->pDrawable->pScreen, width, height,
						 PIXMAN_FORMAT_DEPTH(format),
						 PIXMAN_FORMAT_BPP(format),
						 pixman_image_get_stride(image),
						 pixman_image_get_data(image));

		if (!scratch) {
			pixman_image_unref(image);
			return;
		}

		component_alpha = NeedsComponent(maskFormat->format);
		mask = CreatePicture(0, &scratch->drawable,
				     maskFormat, CPComponentAlpha,
				     &component_alpha, serverClient, &error);
		if (!mask) {
			FreeScratchPixmapHeader(scratch);
			pixman_image_unref(image);
			return;
		}
		ValidatePicture(mask);

		x = -extents.x1;
		y = -extents.y1;

		color.red = color.green = color.blue = color.alpha = 0xffff;
		white = CreateSolidPicture(0, &color, &error);

		mask_op = op;
		op = PictOpAdd;

		mask_src = src;
		src = white;

		mask_dst = dst;
		dst = mask;
	} else {
		mask = dst;
		x = 0;
		y = 0;
	}

	while (nlist--) {
		x += list->xOff;
		y += list->yOff;
		n = list->len;
		while (n--) {
			GlyphPtr glyph = *glyphs++;
			PicturePtr g = GetGlyphPicture(glyph, dst->pDrawable->pScreen);
			if (g) {
				CompositePicture(op, src, g, dst,
						 xSrc + (x - glyph->info.x) - xDst,
						 ySrc + (y - glyph->info.y) - yDst,
						 0, 0,
						 x - glyph->info.x,
						 y - glyph->info.y,
						 glyph->info.width,
						 glyph->info.height);
			}

			x += glyph->info.xOff;
			y += glyph->info.yOff;
		}
		list++;
	}

	if (white)
		FreePicture(white, 0);

	if (maskFormat) {
		x = extents.x1;
		y = extents.y1;
		CompositePicture(mask_op, mask_src, mask, mask_dst,
				 xSrc + x - xDst,
				 ySrc + y - yDst,
				 0, 0,
				 x, y,
				 width, height);
		FreePicture(mask, 0);
		FreeScratchPixmapHeader(scratch);
		pixman_image_unref(image);
	}
}
Beispiel #13
0
static void
composite_clipped(pixman_image_t *src,
		  pixman_image_t *mask,
		  pixman_image_t *dest,
		  const pixman_transform_t *transform,
		  pixman_filter_t filter,
		  pixman_region32_t *src_clip)
{
	int n_box;
	pixman_box32_t *boxes;
	int32_t dest_width;
	int32_t dest_height;
	int src_stride;
	int bitspp;
	pixman_format_code_t src_format;
	void *src_data;
	int i;

	/* Hardcoded to use PIXMAN_OP_OVER, because sampling outside of
	 * a Pixman image produces (0,0,0,0) instead of discarding the
	 * fragment.
	 */

	dest_width = pixman_image_get_width(dest);
	dest_height = pixman_image_get_height(dest);
	src_format = pixman_image_get_format(src);
	src_stride = pixman_image_get_stride(src);
	bitspp = PIXMAN_FORMAT_BPP(src_format);
	src_data = pixman_image_get_data(src);

	assert(src_format);

	/* This would be massive overdraw, except when n_box is 1. */
	boxes = pixman_region32_rectangles(src_clip, &n_box);
	for (i = 0; i < n_box; i++) {
		uint8_t *ptr = src_data;
		pixman_image_t *boximg;
		pixman_transform_t adj = *transform;

		ptr += boxes[i].y1 * src_stride;
		ptr += boxes[i].x1 * bitspp / 8;
		boximg = pixman_image_create_bits_no_clear(src_format,
					boxes[i].x2 - boxes[i].x1,
					boxes[i].y2 - boxes[i].y1,
					(uint32_t *)ptr, src_stride);

		pixman_transform_translate(&adj, NULL,
					   pixman_int_to_fixed(-boxes[i].x1),
					   pixman_int_to_fixed(-boxes[i].y1));
		pixman_image_set_transform(boximg, &adj);

		pixman_image_set_filter(boximg, filter, NULL, 0);
		pixman_image_composite32(PIXMAN_OP_OVER, boximg, mask, dest,
					 0, 0, /* src_x, src_y */
					 0, 0, /* mask_x, mask_y */
					 0, 0, /* dest_x, dest_y */
					 dest_width, dest_height);

		pixman_image_unref(boximg);
	}

	if (n_box > 1) {
		static bool warned = false;

		if (!warned)
			weston_log("Pixman-renderer warning: %dx overdraw\n",
				   n_box);
		warned = true;
	}
}
Beispiel #14
0
uint16 PixmanBitmap::pitch() const {
	return pixman_image_get_stride(bitmap);
}