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; }
void PixmanBitmap::FlipBlit(int x, int y, Bitmap* _src, Rect src_rect, bool horizontal, bool vertical) { if (!horizontal && !vertical) { Blit(x, y, _src, src_rect, 255); return; } PixmanBitmap* src = (PixmanBitmap*) _src; pixman_transform_t xform; pixman_transform_init_scale(&xform, pixman_int_to_fixed(horizontal ? -1 : 1), pixman_int_to_fixed(vertical ? -1 : 1)); pixman_transform_translate((pixman_transform_t*) NULL, &xform, pixman_int_to_fixed(horizontal ? src_rect.width : 0), pixman_int_to_fixed(vertical ? src_rect.height : 0)); pixman_image_set_transform(bitmap, &xform); 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_transform_init_identity(&xform); pixman_image_set_transform(bitmap, &xform); RefreshCallback(); }
static void bench (const bench_info_t *bi, uint32_t max_n, uint32_t max_time, uint32_t *ret_n, uint32_t *ret_time, void (*func) (const pixman_composite_info_t *info)) { uint32_t n = 0; uint32_t t0; uint32_t t1; uint32_t x = 0; pixman_transform_t t; pixman_composite_info_t info; t = bi->transform; info.op = bi->op; info.src_image = bi->src_image; info.mask_image = bi->mask_image; info.dest_image = bi->dest_image; info.src_x = 0; info.src_y = 0; info.mask_x = 0; info.mask_y = 0; /* info.dest_x set below */ info.dest_y = 0; info.width = WIDTH; info.height = HEIGHT; t0 = gettimei (); do { if (++x >= 64) x = 0; info.dest_x = 63 - x; t.matrix[0][2] = pixman_int_to_fixed (bi->src_x + x); t.matrix[1][2] = pixman_int_to_fixed (bi->src_y); pixman_image_set_transform (bi->src_image, &t); if (bi->mask_image) pixman_image_set_transform (bi->mask_image, &t); func (&info); t1 = gettimei (); } while (++n < max_n && (t1 - t0) < max_time); if (ret_n) *ret_n = n; *ret_time = t1 - t0; }
static int pixman_renderer_surface_copy_content(struct weston_surface *surface, void *target, size_t size, int src_x, int src_y, int width, int height) { const pixman_format_code_t format = PIXMAN_a8b8g8r8; const size_t bytespp = 4; /* PIXMAN_a8b8g8r8 */ struct pixman_surface_state *ps = get_surface_state(surface); pixman_image_t *out_buf; if (!ps->image) return -1; out_buf = pixman_image_create_bits(format, width, height, target, width * bytespp); pixman_image_set_transform(ps->image, NULL); pixman_image_composite32(PIXMAN_OP_SRC, ps->image, /* src */ NULL, /* mask */ out_buf, /* dest */ src_x, src_y, /* src_x, src_y */ 0, 0, /* mask_x, mask_y */ 0, 0, /* dest_x, dest_y */ width, height); pixman_image_unref(out_buf); return 0; }
static int pixman_renderer_read_pixels(struct weston_output *output, pixman_format_code_t format, void *pixels, uint32_t x, uint32_t y, uint32_t width, uint32_t height) { struct pixman_output_state *po = get_output_state(output); pixman_transform_t transform; pixman_image_t *out_buf; if (!po->hw_buffer) { errno = ENODEV; return -1; } out_buf = pixman_image_create_bits(format, width, height, pixels, (PIXMAN_FORMAT_BPP(format) / 8) * width); /* Caller expects vflipped source image */ pixman_transform_init_translate(&transform, pixman_int_to_fixed (x), pixman_int_to_fixed (y - pixman_image_get_height (po->hw_buffer))); pixman_transform_scale(&transform, NULL, pixman_fixed_1, pixman_fixed_minus_1); pixman_image_set_transform(po->hw_buffer, &transform); pixman_image_composite32(PIXMAN_OP_SRC, po->hw_buffer, /* src */ NULL /* mask */, out_buf, /* dest */ 0, 0, /* src_x, src_y */ 0, 0, /* mask_x, mask_y */ 0, 0, /* dest_x, dest_y */ pixman_image_get_width (po->hw_buffer), /* width */ pixman_image_get_height (po->hw_buffer) /* height */); pixman_image_set_transform(po->hw_buffer, NULL); pixman_image_unref(out_buf); return 0; }
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 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); }
static cairo_status_t _cairo_image_surface_set_matrix (cairo_image_surface_t *surface, const cairo_matrix_t *matrix) { pixman_transform_t pixman_transform; _cairo_matrix_to_pixman_matrix (matrix, &pixman_transform); pixman_image_set_transform (surface->pixman_image, &pixman_transform); return CAIRO_STATUS_SUCCESS; }
static void pixman_image_composite_empty (pixman_implementation_t *impl, pixman_composite_info_t *info) { if (use_scaling) { pixman_image_set_filter (info->src_image, filter, NULL, 0); pixman_image_set_transform(info->src_image, &m); } pixman_image_composite (info->op, info->src_image, info->mask_image, info->dest_image, 0, 0, 0, 0, 0, 0, 1, 1); }
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(); }
static void Transform(DataSourceSurface* aDest, DataSourceSurface* aSource, const gfx3DMatrix& aTransform, const Point& aDestOffset) { IntSize destSize = aDest->GetSize(); pixman_image_t* dest = pixman_image_create_bits(PIXMAN_a8r8g8b8, destSize.width, destSize.height, (uint32_t*)aDest->GetData(), aDest->Stride()); IntSize srcSize = aSource->GetSize(); pixman_image_t* src = pixman_image_create_bits(PIXMAN_a8r8g8b8, srcSize.width, srcSize.height, (uint32_t*)aSource->GetData(), aSource->Stride()); MOZ_ASSERT(src !=0 && dest != 0, "Failed to create pixman images?"); pixman_transform pixTransform = Matrix3DToPixman(aTransform); pixman_transform pixTransformInverted; // If the transform is singular then nothing would be drawn anyway, return here if (!pixman_transform_invert(&pixTransformInverted, &pixTransform)) { pixman_image_unref(dest); pixman_image_unref(src); return; } pixman_image_set_transform(src, &pixTransformInverted); pixman_image_composite32(PIXMAN_OP_SRC, src, nullptr, dest, aDestOffset.x, aDestOffset.y, 0, 0, 0, 0, destSize.width, destSize.height); pixman_image_unref(dest); pixman_image_unref(src); }
static cairo_status_t _cairo_image_surface_set_matrix (cairo_image_surface_t *surface, const cairo_matrix_t *matrix) { pixman_transform_t pixman_transform; //+EAWebKitChange - Added a ref point (width/2, height/2) for shadow box bug fix. //6/26/2013 _cairo_matrix_to_pixman_matrix (matrix, &pixman_transform, surface->width/2., surface->height/2.); //-EAWebKitChange if (! pixman_image_set_transform (surface->pixman_image, &pixman_transform)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; }
static void pixman_image_composite_wrapper (pixman_implementation_t *impl, pixman_composite_info_t *info) { if (use_scaling) { pixman_image_set_filter (info->src_image, filter, NULL, 0); pixman_image_set_transform(info->src_image, &m); } pixman_image_composite (info->op, info->src_image, info->mask_image, info->dest_image, info->src_x, info->src_y, info->mask_x, info->mask_y, info->dest_x, info->dest_y, info->width, info->height); }
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; }
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 * make_image (void) { pixman_format_code_t format = RANDOM_FORMAT(); uint32_t *bytes = malloc (WIDTH * HEIGHT * 4); pixman_image_t *image; prng_randmemset (bytes, WIDTH * HEIGHT * 4, 0); image = pixman_image_create_bits ( format, WIDTH, HEIGHT, bytes, WIDTH * 4); pixman_image_set_transform (image, RANDOM_TRANSFORM()); pixman_image_set_destroy_function (image, on_destroy, bytes); pixman_image_set_repeat (image, PIXMAN_REPEAT_NORMAL); image_endian_swap (image); return image; }
/* 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; }
static void composite_whole(pixman_op_t op, pixman_image_t *src, pixman_image_t *mask, pixman_image_t *dest, const pixman_transform_t *transform, pixman_filter_t filter) { int32_t dest_width; int32_t dest_height; dest_width = pixman_image_get_width(dest); dest_height = pixman_image_get_height(dest); pixman_image_set_transform(src, transform); pixman_image_set_filter(src, filter, NULL, 0); pixman_image_composite32(op, src, mask, dest, 0, 0, /* src_x, src_y */ 0, 0, /* mask_x, mask_y */ 0, 0, /* dest_x, dest_y */ dest_width, dest_height); }
struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor) { int new_width = img->width * w_factor; int new_height = img->height * h_factor; pixman_image_t *orig, *resized; pixman_transform_t transform; struct fp_img *newimg; orig = pixman_image_create_bits(PIXMAN_a8, img->width, img->height, (uint32_t *)img->data, img->width); resized = pixman_image_create_bits(PIXMAN_a8, new_width, new_height, NULL, new_width); pixman_transform_init_identity(&transform); pixman_transform_scale(NULL, &transform, pixman_int_to_fixed(w_factor), pixman_int_to_fixed(h_factor)); pixman_image_set_transform(orig, &transform); pixman_image_set_filter(orig, PIXMAN_FILTER_BILINEAR, NULL, 0); pixman_image_composite32(PIXMAN_OP_SRC, orig, /* src */ NULL, /* mask */ resized, /* dst */ 0, 0, /* src x y */ 0, 0, /* mask x y */ 0, 0, /* dst x y */ new_width, new_height /* width height */ ); newimg = fpi_img_new(new_width * new_height); newimg->width = new_width; newimg->height = new_height; newimg->flags = img->flags; memcpy(newimg->data, pixman_image_get_data(resized), new_width * new_height); pixman_image_unref(orig); pixman_image_unref(resized); return newimg; }
bool mSDLSWInit(struct mSDLRenderer* renderer) { #if !SDL_VERSION_ATLEAST(2, 0, 0) #ifdef COLOR_16_BIT SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE); #else SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE); #endif #endif unsigned width, height; renderer->core->desiredVideoDimensions(renderer->core, &width, &height); #if SDL_VERSION_ATLEAST(2, 0, 0) renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen)); SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); renderer->player.window = renderer->window; renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); #else renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, width, height); #endif #else renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, width, height); #endif int stride; SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride); renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL); #else SDL_Surface* surface = SDL_GetVideoSurface(); SDL_LockSurface(surface); if (renderer->ratio == 1) { renderer->core->setVideoBuffer(renderer->core, surface->pixels, surface->pitch / BYTES_PER_PIXEL); } else { #ifdef USE_PIXMAN renderer->outputBuffer = malloc(width * height * BYTES_PER_PIXEL); renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, width); #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 pixman_format_code_t format = PIXMAN_r5g6b5; #else pixman_format_code_t format = PIXMAN_x1b5g5r5; #endif #else pixman_format_code_t format = PIXMAN_x8b8g8r8; #endif renderer->pix = pixman_image_create_bits(format, width, height, renderer->outputBuffer, width * BYTES_PER_PIXEL); renderer->screenpix = pixman_image_create_bits(format, renderer->viewportWidth, renderer->viewportHeight, surface->pixels, surface->pitch); pixman_transform_t transform; pixman_transform_init_identity(&transform); pixman_transform_scale(0, &transform, pixman_int_to_fixed(renderer->ratio), pixman_int_to_fixed(renderer->ratio)); pixman_image_set_transform(renderer->pix, &transform); pixman_image_set_filter(renderer->pix, PIXMAN_FILTER_NEAREST, 0, 0); #else return false; #endif } #endif return true; }
static void rescale (GtkWidget *may_be_null, app_t *app) { pixman_f_transform_t ftransform; pixman_transform_t transform; double new_width, new_height; double fscale_x, fscale_y; double rotation; pixman_fixed_t *params; int n_params; double sx, sy; pixman_f_transform_init_identity (&ftransform); if (may_be_null && gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON (get_widget (app, "lock_checkbutton")))) { copy_to_counterpart (app, G_OBJECT (may_be_null)); } fscale_x = gtk_adjustment_get_value (app->scale_x_adjustment); fscale_y = gtk_adjustment_get_value (app->scale_y_adjustment); rotation = gtk_adjustment_get_value (app->rotate_adjustment); fscale_x = to_scale (fscale_x); fscale_y = to_scale (fscale_y); new_width = pixman_image_get_width (app->original) * fscale_x; new_height = pixman_image_get_height (app->original) * fscale_y; pixman_f_transform_scale (&ftransform, NULL, fscale_x, fscale_y); pixman_f_transform_translate (&ftransform, NULL, - new_width / 2.0, - new_height / 2.0); rotation = (rotation / 360.0) * 2 * M_PI; pixman_f_transform_rotate (&ftransform, NULL, cos (rotation), sin (rotation)); pixman_f_transform_translate (&ftransform, NULL, new_width / 2.0, new_height / 2.0); pixman_f_transform_invert (&ftransform, &ftransform); compute_extents (&ftransform, &sx, &sy); pixman_transform_from_pixman_f_transform (&transform, &ftransform); pixman_image_set_transform (app->original, &transform); params = pixman_filter_create_separable_convolution ( &n_params, sx * 65536.0 + 0.5, sy * 65536.0 + 0.5, get_value (app, filters, "reconstruct_x_combo_box"), get_value (app, filters, "reconstruct_y_combo_box"), get_value (app, filters, "sample_x_combo_box"), get_value (app, filters, "sample_y_combo_box"), gtk_adjustment_get_value (app->subsample_adjustment), gtk_adjustment_get_value (app->subsample_adjustment)); pixman_image_set_filter (app->original, PIXMAN_FILTER_SEPARABLE_CONVOLUTION, params, n_params); pixman_image_set_repeat ( app->original, get_value (app, repeats, "repeat_combo_box")); free (params); app->scaled_width = ceil (new_width); app->scaled_height = ceil (new_height); gtk_widget_set_size_request ( get_widget (app, "drawing_area"), new_width + 0.5, new_height + 0.5); gtk_widget_queue_draw ( get_widget (app, "drawing_area")); }
/* * 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_transform_t transform; pixman_region16_t clip; 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 src_bpp; int dst_bpp; int w, h; pixman_fixed_t scale_x = 65536, scale_y = 65536; pixman_fixed_t translate_x = 0, translate_y = 0; int op; int repeat = 0; int src_fmt, dst_fmt; uint32_t * srcbuf; uint32_t * dstbuf; uint32_t crc32; lcg_srand (testnum); src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4; dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4; op = (lcg_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER; src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1; src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1; dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1; dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1; src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp; dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp; if (src_stride & 3) src_stride += 2; if (dst_stride & 3) dst_stride += 2; src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2); src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2); dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2); dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2); w = lcg_rand_n (dst_width * 3 / 2 - dst_x); h = lcg_rand_n (dst_height * 3 / 2 - dst_y); srcbuf = (uint32_t *)malloc (src_stride * src_height); dstbuf = (uint32_t *)malloc (dst_stride * dst_height); for (i = 0; i < src_stride * src_height; i++) *((uint8_t *)srcbuf + i) = lcg_rand_n (256); for (i = 0; i < dst_stride * dst_height; i++) *((uint8_t *)dstbuf + i) = lcg_rand_n (256); src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; src_img = pixman_image_create_bits ( src_fmt, src_width, src_height, srcbuf, src_stride); dst_img = pixman_image_create_bits ( dst_fmt, dst_width, dst_height, dstbuf, dst_stride); image_endian_swap (src_img, src_bpp * 8); image_endian_swap (dst_img, dst_bpp * 8); if (lcg_rand_n (8) > 0) { scale_x = -32768 * 3 + lcg_rand_N (65536 * 5); scale_y = -32768 * 3 + lcg_rand_N (65536 * 5); translate_x = lcg_rand_N (65536); translate_y = lcg_rand_N (65536); pixman_transform_init_scale (&transform, scale_x, scale_y); pixman_transform_translate (&transform, NULL, translate_x, translate_y); pixman_image_set_transform (src_img, &transform); } switch (lcg_rand_n (4)) { case 0: repeat = PIXMAN_REPEAT_NONE; break; case 1: repeat = PIXMAN_REPEAT_NORMAL; break; case 2: repeat = PIXMAN_REPEAT_PAD; break; case 3: repeat = PIXMAN_REPEAT_REFLECT; break; default: break; } pixman_image_set_repeat (src_img, repeat); if (lcg_rand_n (2)) pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0); else pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0); if (verbose) { printf ("src_fmt=%08X, dst_fmt=%08X\n", src_fmt, dst_fmt); printf ("op=%d, scale_x=%d, scale_y=%d, repeat=%d\n", op, scale_x, scale_y, repeat); printf ("translate_x=%d, translate_y=%d\n", translate_x, translate_y); 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 ("w=%d, h=%d\n", w, h); } 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); } 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_image_composite (op, src_img, NULL, dst_img, src_x, src_y, 0, 0, dst_x, dst_y, w, h); if (dst_fmt == PIXMAN_x8r8g8b8) { /* ignore unused part */ for (i = 0; i < dst_stride * dst_height / 4; i++) dstbuf[i] &= 0xFFFFFF; } image_endian_swap (dst_img, dst_bpp * 8); if (verbose) { int j; for (i = 0; i < dst_height; i++) { for (j = 0; j < dst_stride; j++) printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j)); printf ("\n"); } } pixman_image_unref (src_img); pixman_image_unref (dst_img); crc32 = compute_crc32 (0, dstbuf, dst_stride * dst_height); free (srcbuf); free (dstbuf); return crc32; }
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; }
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 set_image_properties(pixman_image_t * image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map) { pixman_repeat_t repeat; pixman_filter_t filter; if (pict->transform) { /* For source images, adjust the transform to account * for the drawable offset within the pixman image, * then set the offset to 0 as it will be used * to compute positions within the transformed image. */ if (!has_clip) { struct pixman_transform adjusted; adjusted = *pict->transform; pixman_transform_translate(&adjusted, NULL, pixman_int_to_fixed(*xoff), pixman_int_to_fixed(*yoff)); pixman_image_set_transform(image, &adjusted); *xoff = 0; *yoff = 0; } else pixman_image_set_transform(image, pict->transform); } switch (pict->repeatType) { default: case RepeatNone: repeat = PIXMAN_REPEAT_NONE; break; case RepeatPad: repeat = PIXMAN_REPEAT_PAD; break; case RepeatNormal: repeat = PIXMAN_REPEAT_NORMAL; break; case RepeatReflect: repeat = PIXMAN_REPEAT_REFLECT; break; } pixman_image_set_repeat(image, repeat); /* Fetch alpha map unless 'pict' is being used * as the alpha map for this operation */ if (pict->alphaMap && !is_alpha_map) { int alpha_xoff, alpha_yoff; pixman_image_t *alpha_map = image_from_pict_internal(pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff, TRUE); pixman_image_set_alpha_map(image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y); free_pixman_pict(pict->alphaMap, alpha_map); } pixman_image_set_component_alpha(image, pict->componentAlpha); switch (pict->filter) { default: case PictFilterNearest: case PictFilterFast: filter = PIXMAN_FILTER_NEAREST; break; case PictFilterBilinear: case PictFilterGood: filter = PIXMAN_FILTER_BILINEAR; break; case PictFilterConvolution: filter = PIXMAN_FILTER_CONVOLUTION; break; } if (pict->pDrawable) pixman_image_set_destroy_function(image, &image_destroy, pict->pDrawable); pixman_image_set_filter(image, filter, (pixman_fixed_t *) pict->filter_params, pict->filter_nparams); pixman_image_set_source_clipping(image, TRUE); }
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; } }
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); }
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; }
/* * We have a source image filled with solid color, set NORMAL or PAD repeat, * and some transform which results in nearest neighbour scaling. * * The expected result is either that the destination image filled with this solid * color or, if the transformation is such that we can't composite anything at * all, that nothing has changed in the destination. * * The surrounding memory of the source image is a different solid color so that * we are sure to get failures if we access it. */ static int run_test (int32_t dst_width, int32_t dst_height, int32_t src_width, int32_t src_height, int32_t src_x, int32_t src_y, int32_t scale_x, int32_t scale_y, pixman_filter_t filter, pixman_repeat_t repeat) { pixman_image_t * src_img; pixman_image_t * dst_img; pixman_transform_t transform; uint32_t * srcbuf; uint32_t * dstbuf; pixman_box32_t box = { 0, 0, src_width, src_height }; pixman_color_t color_cc = { 0xcccc, 0xcccc, 0xcccc, 0xcccc }; int result; int i; static const pixman_fixed_t kernel[] = { #define D(f) (pixman_double_to_fixed (f) + 0x0001) pixman_int_to_fixed (5), pixman_int_to_fixed (5), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0), D(1/25.0) }; result = 0; srcbuf = (uint32_t *)malloc ((src_width + 10) * (src_height + 10) * 4); dstbuf = (uint32_t *)malloc (dst_width * dst_height * 4); memset (srcbuf, 0x88, src_width * src_height * 4); memset (dstbuf, 0x33, dst_width * dst_height * 4); src_img = pixman_image_create_bits ( PIXMAN_a8r8g8b8, src_width, src_height, srcbuf + (src_width + 10) * 5 + 5, (src_width + 10) * 4); pixman_image_fill_boxes (PIXMAN_OP_SRC, src_img, &color_cc, 1, &box); dst_img = pixman_image_create_bits ( PIXMAN_a8r8g8b8, dst_width, dst_height, dstbuf, dst_width * 4); pixman_transform_init_scale (&transform, scale_x, scale_y); pixman_image_set_transform (src_img, &transform); pixman_image_set_repeat (src_img, repeat); if (filter == PIXMAN_FILTER_CONVOLUTION) pixman_image_set_filter (src_img, filter, kernel, 27); else pixman_image_set_filter (src_img, filter, NULL, 0); pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img, src_x, src_y, 0, 0, 0, 0, dst_width, dst_height); pixman_image_unref (src_img); pixman_image_unref (dst_img); for (i = 0; i < dst_width * dst_height; i++) { if (dstbuf[i] != 0xCCCCCCCC && dstbuf[i] != 0x33333333) { result = 1; break; } } free (srcbuf); free (dstbuf); return result; }