void PixmanBitmap::Blit(int x, int y, Bitmap* _src, Rect src_rect, int opacity) { if (opacity < 0) return; PixmanBitmap* src = (PixmanBitmap*) _src; if (opacity > 255) opacity = 255; pixman_image_t* mask; if (opacity < 255) { pixman_color_t tcolor = {0, 0, 0, opacity << 8}; mask = pixman_image_create_solid_fill(&tcolor); } else mask = (pixman_image_t*) NULL; pixman_image_composite32(PIXMAN_OP_OVER, src->bitmap, mask, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); if (mask != NULL) pixman_image_unref(mask); RefreshCallback(); }
void PixmanBitmap::BlendBlit(int x, int y, Bitmap* _src, Rect src_rect, const Color& color) { PixmanBitmap* src = (PixmanBitmap*) _src; if (color.alpha == 0) { if (_src != this) Blit(x, y, _src, src_rect, 255); return; } if (src != this) pixman_image_composite32(PIXMAN_OP_SRC, src->bitmap, (pixman_image_t*) NULL, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_color_t tcolor = PixmanColor(color); pixman_image_t* timage = pixman_image_create_solid_fill(&tcolor); pixman_image_composite32(PIXMAN_OP_OVER, timage, src->bitmap, bitmap, 0, 0, src_rect.x, src_rect.y, x, y, src_rect.width, src_rect.height); pixman_image_unref(timage); RefreshCallback(); }
void PixmanBitmap::OpacityBlit(int x, int y, Bitmap* _src, Rect src_rect, int opacity) { PixmanBitmap* src = (PixmanBitmap*) _src; if (opacity == 255) { if (_src != this) Blit(x, y, _src, src_rect, opacity); return; } if (src == this) { pixman_color_t pcolor = {0, 0, 0, opacity << 8}; pixman_rectangle16_t rect = {src_rect.x, src_rect.y, src_rect.width, src_rect.height}; pixman_image_fill_rectangles(PIXMAN_OP_IN_REVERSE, bitmap, &pcolor, 1, &rect); } else { if (opacity > 255) opacity = 255; pixman_color_t tcolor = {0, 0, 0, opacity << 8}; pixman_image_t* mask = pixman_image_create_solid_fill(&tcolor); pixman_image_composite32(PIXMAN_OP_OVER, src->bitmap, mask, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_image_unref(mask); } RefreshCallback(); }
void PixmanBitmap::WaverBlit(int x, int y, Bitmap* _src, Rect src_rect, int depth, double phase, int opacity) { if (opacity < 0) return; PixmanBitmap* src = (PixmanBitmap*) _src; if (opacity > 255) opacity = 255; pixman_image_t* mask; if (opacity < 255) { pixman_color_t tcolor = {0, 0, 0, opacity << 8}; mask = pixman_image_create_solid_fill(&tcolor); } else mask = (pixman_image_t*) NULL; for (int i = 0; i < src_rect.height; i++) { int offset = (int) (depth * (1 + sin((phase + i * 20) * 3.14159 / 180))); pixman_image_composite32(PIXMAN_OP_OVER, src->bitmap, mask, bitmap, src_rect.x, src_rect.y + i, 0, 0, x + offset, y + i, src_rect.width, 1); } if (mask != NULL) pixman_image_unref(mask); RefreshCallback(); }
static pixman_image_t * create_solid_fill_image(PicturePtr pict) { PictSolidFill *solid = &pict->pSourcePict->solidFill; /* pixman_color_t and xRenderColor have the same layout */ pixman_color_t *color = (pixman_color_t *)&solid->fullcolor; return pixman_image_create_solid_fill(color); }
int main () { static const pixman_point_fixed_t inner = { 0x0000, 0x0000 }; static const pixman_point_fixed_t outer = { 0x0000, 0x0000 }; static const pixman_fixed_t r_inner = 0; static const pixman_fixed_t r_outer = 64 << 16; static const pixman_gradient_stop_t stops[] = { { 0x00000, { 0x6666, 0x6666, 0x6666, 0xffff } }, { 0x10000, { 0x0000, 0x0000, 0x0000, 0xffff } } }; static const pixman_transform_t transform = { { { 0x0, 0x26ee, 0x0}, { 0xffffeeef, 0x0, 0x0}, { 0x0, 0x0, 0x10000} } }; static const pixman_color_t z = { 0x0000, 0x0000, 0x0000, 0x0000 }; pixman_image_t *dest, *radial, *zero; int i; double before, after; dest = pixman_image_create_bits ( PIXMAN_x8r8g8b8, 640, 429, NULL, -1); zero = pixman_image_create_solid_fill (&z); radial = pixman_image_create_radial_gradient ( &inner, &outer, r_inner, r_outer, stops, ARRAY_LENGTH (stops)); pixman_image_set_transform (radial, &transform); pixman_image_set_repeat (radial, PIXMAN_REPEAT_PAD); #define N_COMPOSITE 500 before = gettime(); for (i = 0; i < N_COMPOSITE; ++i) { before -= gettime(); pixman_image_composite ( PIXMAN_OP_SRC, zero, NULL, dest, 0, 0, 0, 0, 0, 0, 640, 429); before += gettime(); pixman_image_composite32 ( PIXMAN_OP_OVER, radial, NULL, dest, - 150, -158, 0, 0, 0, 0, 640, 361); } after = gettime(); write_png (dest, "radial.png"); printf ("Average time to composite: %f\n", (after - before) / N_COMPOSITE); return 0; }
void qemu_pixman_glyph_render(pixman_image_t *glyph, pixman_image_t *surface, pixman_color_t *fgcol, pixman_color_t *bgcol, int x, int y, int cw, int ch) { pixman_image_t *ifg = pixman_image_create_solid_fill(fgcol); pixman_image_t *ibg = pixman_image_create_solid_fill(bgcol); pixman_image_composite(PIXMAN_OP_SRC, ibg, NULL, surface, 0, 0, 0, 0, cw * x, ch * y, cw, ch); pixman_image_composite(PIXMAN_OP_OVER, ifg, glyph, surface, 0, 0, 0, 0, cw * x, ch * y, cw, ch); pixman_image_unref(ifg); pixman_image_unref(ibg); }
void PixmanBitmap::TiledBlit(int ox, int oy, Rect src_rect, Bitmap* src, Rect dst_rect, int opacity) { if (opacity < 0) return; if (opacity > 255) opacity = 255; if (ox >= src_rect.width) ox %= src_rect.width; if (oy >= src_rect.height) ox %= src_rect.height; if (ox < 0) ox += src_rect.width * ((-ox + src_rect.width - 1) / src_rect.width); if (oy < 0) oy += src_rect.height * ((-oy + src_rect.height - 1) / src_rect.height); pixman_image_t* src_bm = GetSubimage(src, src_rect); pixman_image_t* mask; if (opacity < 255) { pixman_color_t tcolor = {0, 0, 0, opacity << 8}; mask = pixman_image_create_solid_fill(&tcolor); } else mask = (pixman_image_t*) NULL; pixman_image_set_repeat(src_bm, PIXMAN_REPEAT_NORMAL); pixman_transform_t xform; pixman_transform_init_translate(&xform, pixman_int_to_fixed(ox), pixman_int_to_fixed(oy)); pixman_image_set_transform(src_bm, &xform); pixman_image_composite32(PIXMAN_OP_OVER, src_bm, mask, bitmap, 0, 0, 0, 0, dst_rect.x, dst_rect.y, dst_rect.width, dst_rect.height); pixman_image_unref(src_bm); if (mask != NULL) pixman_image_unref(mask); RefreshCallback(); }
static pixman_image_t * create_solid_fill_image(PicturePtr pict) { PictSolidFill *solid = &pict->pSourcePict->solidFill; pixman_color_t color; CARD32 a, r, g, b; a = (solid->color & 0xff000000) >> 24; r = (solid->color & 0x00ff0000) >> 16; g = (solid->color & 0x0000ff00) >> 8; b = (solid->color & 0x000000ff) >> 0; color.alpha = (a << 8) | a; color.red = (r << 8) | r; color.green = (g << 8) | g; color.blue = (b << 8) | b; return pixman_image_create_solid_fill(&color); }
static void pixman_renderer_surface_set_color(struct weston_surface *es, float red, float green, float blue, float alpha) { struct pixman_surface_state *ps = get_surface_state(es); pixman_color_t color; color.red = red * 0xffff; color.green = green * 0xffff; color.blue = blue * 0xffff; color.alpha = alpha * 0xffff; if (ps->image) { pixman_image_unref(ps->image); ps->image = NULL; } ps->image = pixman_image_create_solid_fill(&color); }
static void debug_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data) { struct weston_compositor *ec = data; struct pixman_renderer *pr = (struct pixman_renderer *) ec->renderer; pr->repaint_debug ^= 1; if (pr->repaint_debug) { pixman_color_t red = { 0x3fff, 0x0000, 0x0000, 0x3fff }; pr->debug_color = pixman_image_create_solid_fill(&red); } else { pixman_image_unref(pr->debug_color); weston_compositor_damage_all(ec); } }
EAPI void evas_common_draw_context_set_color(RGBA_Draw_Context *dc, int r, int g, int b, int a) { R_VAL(&(dc->col.col)) = (DATA8)r; G_VAL(&(dc->col.col)) = (DATA8)g; B_VAL(&(dc->col.col)) = (DATA8)b; A_VAL(&(dc->col.col)) = (DATA8)a; #ifdef HAVE_PIXMAN if (dc && dc->col.pixman_color_image) pixman_image_unref(dc->col.pixman_color_image); pixman_color_t pixman_color; pixman_color.alpha = (dc->col.col & 0xff000000) >> 16; pixman_color.red = (dc->col.col & 0x00ff0000) >> 8; pixman_color.green = (dc->col.col & 0x0000ff00); pixman_color.blue = (dc->col.col & 0x000000ff) << 8; dc->col.pixman_color_image = pixman_image_create_solid_fill(&pixman_color); #endif }
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(); }
/* * Composite operation with pseudorandom images */ uint32_t test_composite (int testnum, int verbose) { int i; pixman_image_t * src_img; pixman_image_t * dst_img; pixman_region16_t clip; int dst_width, dst_height; int dst_stride; int dst_x, dst_y; int dst_bpp; pixman_op_t op; uint32_t * dst_bits; uint32_t crc32; pixman_format_code_t mask_format, dst_format; pixman_trapezoid_t *traps; int src_x, src_y; int n_traps; static pixman_color_t colors[] = { { 0xffff, 0xffff, 0xffff, 0xffff }, { 0x0000, 0x0000, 0x0000, 0x0000 }, { 0xabcd, 0xabcd, 0x0000, 0xabcd }, { 0x0000, 0x0000, 0x0000, 0xffff }, { 0x0101, 0x0101, 0x0101, 0x0101 }, { 0x7777, 0x6666, 0x5555, 0x9999 }, }; FLOAT_REGS_CORRUPTION_DETECTOR_START (); lcg_srand (testnum); op = RANDOM_ELT (operators); mask_format = RANDOM_ELT (mask_formats); /* Create source image */ if (lcg_rand_n (4) == 0) { src_img = pixman_image_create_solid_fill ( &(colors[lcg_rand_n (ARRAY_LENGTH (colors))])); src_x = 10; src_y = 234; } else { pixman_format_code_t src_format = RANDOM_ELT(formats); int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8; int src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1; int src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1; int src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp; uint32_t *bits; src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2); src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2); src_stride = (src_stride + 3) & ~3; bits = (uint32_t *)make_random_bytes (src_stride * src_height); src_img = pixman_image_create_bits ( src_format, src_width, src_height, bits, src_stride); pixman_image_set_destroy_function (src_img, destroy_bits, bits); if (lcg_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; int n = lcg_rand_n (2) + 1; for (i = 0; i < n; i++) { clip_boxes[i].x1 = lcg_rand_n (src_width); clip_boxes[i].y1 = lcg_rand_n (src_height); clip_boxes[i].x2 = clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1); clip_boxes[i].y2 = clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1); if (verbose) { printf ("source clip box: [%d,%d-%d,%d]\n", clip_boxes[i].x1, clip_boxes[i].y1, clip_boxes[i].x2, clip_boxes[i].y2); } } pixman_region_init_rects (&clip, clip_boxes, n); pixman_image_set_clip_region (src_img, &clip); pixman_image_set_source_clipping (src_img, 1); pixman_region_fini (&clip); } image_endian_swap (src_img); } /* Create destination image */ { dst_format = RANDOM_ELT(formats); dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8; dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1; dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1; dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp; dst_stride = (dst_stride + 3) & ~3; dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height); dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2); dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2); dst_img = pixman_image_create_bits ( dst_format, dst_width, dst_height, dst_bits, dst_stride); image_endian_swap (dst_img); } /* Create traps */ { int i; n_traps = lcg_rand_n (25); traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t)); for (i = 0; i < n_traps; ++i) { pixman_trapezoid_t *t = &(traps[i]); t->top = random_fixed (MAX_DST_HEIGHT) - MAX_DST_HEIGHT / 2; t->bottom = t->top + random_fixed (MAX_DST_HEIGHT); t->left.p1.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2; t->left.p1.y = t->top - random_fixed (50); t->left.p2.x = random_fixed (MAX_DST_WIDTH) - MAX_DST_WIDTH / 2; t->left.p2.y = t->bottom + random_fixed (50); t->right.p1.x = t->left.p1.x + random_fixed (MAX_DST_WIDTH); t->right.p1.y = t->top - random_fixed (50); t->right.p2.x = t->left.p2.x + random_fixed (MAX_DST_WIDTH); t->right.p2.y = t->bottom - random_fixed (50); } } if (lcg_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; int n = lcg_rand_n (2) + 1; for (i = 0; i < n; i++) { clip_boxes[i].x1 = lcg_rand_n (dst_width); clip_boxes[i].y1 = lcg_rand_n (dst_height); clip_boxes[i].x2 = clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1); clip_boxes[i].y2 = clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1); if (verbose) { printf ("destination clip box: [%d,%d-%d,%d]\n", clip_boxes[i].x1, clip_boxes[i].y1, clip_boxes[i].x2, clip_boxes[i].y2); } } pixman_region_init_rects (&clip, clip_boxes, n); pixman_image_set_clip_region (dst_img, &clip); pixman_region_fini (&clip); } pixman_composite_trapezoids (op, src_img, dst_img, mask_format, src_x, src_y, dst_x, dst_y, n_traps, traps); if (dst_format == PIXMAN_x8r8g8b8) { /* ignore unused part */ for (i = 0; i < dst_stride * dst_height / 4; i++) dst_bits[i] &= 0xFFFFFF; } image_endian_swap (dst_img); if (verbose) { int j; for (i = 0; i < dst_height; i++) { for (j = 0; j < dst_stride; j++) printf ("%02X ", *((uint8_t *)dst_bits + i * dst_stride + j)); printf ("\n"); } } crc32 = compute_crc32 (0, dst_bits, dst_stride * dst_height); fence_free (dst_bits); pixman_image_unref (src_img); pixman_image_unref (dst_img); fence_free (traps); FLOAT_REGS_CORRUPTION_DETECTOR_FINISH (); return crc32; }
void PixmanBitmap::ToneBlit(int x, int y, Bitmap* _src, Rect src_rect, const Tone &tone) { if (tone == Tone()) { if (_src != this) Blit(x, y, _src, src_rect, 255); return; } PixmanBitmap* src = (PixmanBitmap*) _src; if (_src != this) pixman_image_composite32(PIXMAN_OP_SRC, src->bitmap, (pixman_image_t*) NULL, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); if (tone.gray == 0) { pixman_color_t tcolor = {tone.red << 8, tone.green << 8, tone.blue << 8, 0xFFFF}; pixman_image_t *timage = pixman_image_create_solid_fill(&tcolor); pixman_image_composite32(PIXMAN_OP_ADD, timage, src->bitmap, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_image_unref(timage); } else { pixman_rectangle16_t rect = {0, 0, src_rect.width, src_rect.height}; PixmanBitmap *gray = new PixmanBitmap(src, src_rect, GetTransparent()); pixman_color_t gcolor = {0, 0, 0, 0xFFFF}; pixman_image_fill_rectangles(PIXMAN_OP_HSL_SATURATION, gray->bitmap, &gcolor, 1, &rect); pixman_color_t acolor = {0, 0, 0, tone.gray << 8}; pixman_image_fill_rectangles(PIXMAN_OP_IN_REVERSE, gray->bitmap, &acolor, 1, &rect); pixman_image_composite32(PIXMAN_OP_ATOP, gray->bitmap, (pixman_image_t*) NULL, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_color_t tcolor = {tone.red << 8, tone.green << 8, tone.blue << 8, 0xFFFF}; pixman_image_t *timage = pixman_image_create_solid_fill(&tcolor); pixman_image_composite32(PIXMAN_OP_ADD, timage, src->bitmap, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_image_unref(timage); delete gray; } RefreshCallback(); }
/** Paint an intersected region * * \param ev The view to be painted. * \param output The output being painted. * \param repaint_output The region to be painted in output coordinates. * \param source_clip The region of the source image to use, in source image * coordinates. If NULL, use the whole source image. * \param pixman_op Compositing operator, either SRC or OVER. */ static void repaint_region(struct weston_view *ev, struct weston_output *output, pixman_region32_t *repaint_output, pixman_region32_t *source_clip, 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); struct weston_buffer_viewport *vp = &ev->surface->buffer_viewport; pixman_transform_t transform; pixman_filter_t filter; pixman_image_t *mask_image; pixman_color_t mask = { 0, }; /* Clip rendering to the damaged output region */ pixman_image_set_clip_region32(po->shadow_image, repaint_output); pixman_renderer_compute_transform(&transform, ev, output); if (ev->transform.enabled || output->current_scale != vp->buffer.scale) filter = PIXMAN_FILTER_BILINEAR; else filter = PIXMAN_FILTER_NEAREST; if (ps->buffer_ref.buffer) wl_shm_buffer_begin_access(ps->buffer_ref.buffer->shm_buffer); if (ev->alpha < 1.0) { mask.alpha = 0xffff * ev->alpha; mask_image = pixman_image_create_solid_fill(&mask); } else { mask_image = NULL; } if (source_clip) composite_clipped(ps->image, mask_image, po->shadow_image, &transform, filter, source_clip); else composite_whole(pixman_op, ps->image, mask_image, po->shadow_image, &transform, filter); if (mask_image) pixman_image_unref(mask_image); 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); }
static inline void combine_to_pixmap_from_pixmap(const RedDrawable_p* dest, const SpiceRect& area, const SpicePoint& offset, const PixelsSource_p* source, int src_x, int src_y, RedDrawable::CombineOP op) { pixman_image_t *dest_surface = dest->source.pixmap.pixman_image; pixman_image_t *src_surface = source->pixmap.pixman_image; SpiceROP rop; switch (op) { case RedDrawable::OP_COPY: rop = SPICE_ROP_COPY; break; case RedDrawable::OP_AND: rop = SPICE_ROP_AND; break; case RedDrawable::OP_XOR: rop = SPICE_ROP_XOR; break; default: THROW("invalid op %d", op); } if (pixman_image_get_depth (src_surface) == 1) { pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff }; pixman_image_t *solid; pixman_image_t *temp; /* Create a temporary rgb32 image that is black where mask is 0 and white where mask is 1 */ temp = pixman_image_create_bits(pixman_image_get_depth(dest_surface) == 24 ? PIXMAN_x8r8g8b8 : PIXMAN_a8r8g8b8, area.right - area.left, area.bottom - area.top, NULL, 0); solid = pixman_image_create_solid_fill(&white); pixman_image_composite32(PIXMAN_OP_SRC, solid, src_surface, temp, 0, 0, src_x + offset.x, src_y + offset.y, 0, 0, area.right - area.left, area.bottom - area.top); pixman_image_unref(solid); /* ROP the temp image on the destination */ spice_pixman_blit_rop(dest_surface, temp, 0, 0, area.left + offset.x, area.top + offset.y, area.right - area.left, area.bottom - area.top, rop); pixman_image_unref(temp); } else { spice_pixman_blit_rop(dest_surface, src_surface, src_x + offset.x, src_y + offset.y, area.left + offset.x, area.top + offset.y, area.right - area.left, area.bottom - area.top, rop); } }
int main () { pixman_region32_t r1; pixman_region32_t r2; pixman_region32_t r3; pixman_box32_t boxes[] = { { 10, 10, 20, 20 }, { 30, 30, 30, 40 }, { 50, 45, 60, 44 }, }; pixman_box32_t boxes2[] = { { 2, 6, 7, 6 }, { 4, 1, 6, 7 }, }; pixman_box32_t boxes3[] = { { 2, 6, 7, 6 }, { 4, 1, 6, 1 }, }; int i, j; pixman_box32_t *b; pixman_image_t *image, *fill; pixman_color_t white = { 0xffff, 0xffff, 0xffff, 0xffff }; /* This used to go into an infinite loop before pixman-region.c * was fixed to not use explict "short" variables */ pixman_region32_init_rect (&r1, 0, 0, 20, 64000); pixman_region32_init_rect (&r2, 0, 0, 20, 64000); pixman_region32_init_rect (&r3, 0, 0, 20, 64000); pixman_region32_subtract (&r1, &r2, &r3); /* This would produce a region containing an empty * rectangle in it. Such regions are considered malformed, * but using an empty rectangle for initialization should * work. */ pixman_region32_init_rects (&r1, boxes, 3); b = pixman_region32_rectangles (&r1, &i); assert (i == 1); while (i--) { assert (b[i].x1 < b[i].x2); assert (b[i].y1 < b[i].y2); } /* This would produce a rectangle containing the bounding box * of the two rectangles. The correct result is to eliminate * the broken rectangle. */ pixman_region32_init_rects (&r1, boxes2, 2); b = pixman_region32_rectangles (&r1, &i); assert (i == 1); assert (b[0].x1 == 4); assert (b[0].y1 == 1); assert (b[0].x2 == 6); assert (b[0].y2 == 7); /* This should produce an empty region */ pixman_region32_init_rects (&r1, boxes3, 2); b = pixman_region32_rectangles (&r1, &i); assert (i == 0); fill = pixman_image_create_solid_fill (&white); for (i = 0; i < 100; i++) { int image_size = 128; pixman_region32_init (&r1); /* Add some random rectangles */ for (j = 0; j < 64; j++) pixman_region32_union_rect (&r1, &r1, lcg_rand_n (image_size), lcg_rand_n (image_size), lcg_rand_n (25), lcg_rand_n (25)); /* Clip to image size */ pixman_region32_init_rect (&r2, 0, 0, image_size, image_size); pixman_region32_intersect (&r1, &r1, &r2); pixman_region32_fini (&r2); /* render region to a1 mask */ image = pixman_image_create_bits (PIXMAN_a1, image_size, image_size, NULL, 0); pixman_image_set_clip_region32 (image, &r1); pixman_image_composite32 (PIXMAN_OP_SRC, fill, NULL, image, 0, 0, 0, 0, 0, 0, image_size, image_size); pixman_region32_init_from_image (&r2, image); pixman_image_unref (image); assert (pixman_region32_equal (&r1, &r2)); pixman_region32_fini (&r1); pixman_region32_fini (&r2); } pixman_image_unref (fill); return 0; }
static pixman_image_t * create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags) { int width, height; pixman_image_t *image; pixman_format_code_t format; uint32_t *data; int bpp; int stride; int i; pixman_image_destroy_func_t destroy; if ((flags & ALLOW_SOLID) && lcg_rand_n (4) == 0) { pixman_color_t color; color.alpha = lcg_rand_u32(); color.red = lcg_rand_u32(); color.green = lcg_rand_u32(); color.blue = lcg_rand_u32(); return pixman_image_create_solid_fill (&color); } width = lcg_rand_n (max_size) + 1; height = lcg_rand_n (max_size) + 1; format = random_format (formats); bpp = PIXMAN_FORMAT_BPP (format); stride = (width * bpp + 7) / 8 + lcg_rand_n (17); stride = (stride + 3) & ~3; if (lcg_rand_n (64) == 0) { if (!(data = (uint32_t *)make_random_bytes (stride * height))) { fprintf (stderr, "Out of memory\n"); abort (); } destroy = destroy_fenced; } else { uint8_t *d8; data = malloc (stride * height); d8 = (uint8_t *)data; for (i = 0; i < height * stride; ++i) d8[i] = lcg_rand_n (256); destroy = destroy_malloced; } image = pixman_image_create_bits (format, width, height, data, stride); pixman_image_set_destroy_function (image, destroy, data); if ((flags & ALLOW_CLIPPED) && lcg_rand_n (8) == 0) { pixman_box16_t clip_boxes[8]; pixman_region16_t clip; int n = lcg_rand_n (8) + 1; for (i = 0; i < n; i++) { clip_boxes[i].x1 = lcg_rand_n (width); clip_boxes[i].y1 = lcg_rand_n (height); clip_boxes[i].x2 = clip_boxes[i].x1 + lcg_rand_n (width - clip_boxes[i].x1); clip_boxes[i].y2 = clip_boxes[i].y1 + lcg_rand_n (height - clip_boxes[i].y1); } pixman_region_init_rects (&clip, clip_boxes, n); pixman_image_set_clip_region (image, &clip); pixman_region_fini (&clip); } if ((flags & ALLOW_SOURCE_CLIPPING) && lcg_rand_n (4) == 0) { pixman_image_set_source_clipping (image, TRUE); pixman_image_set_has_client_clip (image, TRUE); } if ((flags & ALLOW_ALPHA_MAP) && lcg_rand_n (16) == 0) { pixman_image_t *alpha_map; int alpha_x, alpha_y; alpha_x = lcg_rand_n (width); alpha_y = lcg_rand_n (height); alpha_map = create_image (max_size, formats, (flags & ~(ALLOW_ALPHA_MAP | ALLOW_SOLID))); pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y); pixman_image_unref (alpha_map); } if ((flags & ALLOW_REPEAT) && lcg_rand_n (2) == 0) pixman_image_set_repeat (image, lcg_rand_n (4)); image_endian_swap (image); return image; }