synchronized to Pixmap. */
XImage *ximg, *mask_img;
-# ifdef HAVE_NATIVE_TRANSFORMS
+# if !defined USE_CAIRO && defined HAVE_XRENDER
/* Picture versions of pixmap and mask for compositing. */
Picture picture, mask_picture;
# endif
certain themes. */
#ifdef USE_CAIRO
- surface = img->cr_data;
+ if (cairo_pattern_get_type (img->cr_data) == CAIRO_PATTERN_TYPE_SURFACE)
+ cairo_pattern_get_surface (img->cr_data, &surface);
+ else
+ surface = NULL;
if (surface)
{
}
static cairo_surface_t *
-cr_create_cr_surface_from_image (struct frame *f, struct image *img)
+cr_create_surface_from_pix_containers (Emacs_Pix_Container pimg,
+ Emacs_Pix_Container mask)
{
- Emacs_Pix_Container pimg = img->pixmap;
cairo_surface_t *surface;
- if (img->mask)
+ if (mask)
{
int x, y;
int r, g, b;
color = GET_PIXEL (pimg, x, y);
- alpha = GET_PIXEL (img->mask, x, y);
+ alpha = GET_PIXEL (mask, x, y);
r = (RED_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
g = (GREEN_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
b = (BLUE_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
PUT_PIXEL (pimg, x, y, ARGB_TO_ULONG (alpha, r, g, b));
}
- xfree (img->mask->data);
- img->mask->data = NULL;
+ xfree (mask->data);
+ mask->data = NULL;
}
- block_input ();
surface = cairo_image_surface_create_for_data ((unsigned char *) pimg->data,
- (img->mask
- ? CAIRO_FORMAT_ARGB32
+ (mask ? CAIRO_FORMAT_ARGB32
: CAIRO_FORMAT_RGB24),
pimg->width, pimg->height,
pimg->bytes_per_line);
static const cairo_user_data_key_t key;
cairo_surface_set_user_data (surface, &key, pimg->data, xfree);
- unblock_input ();
pimg->data = NULL;
return surface;
}
+static void
+cr_put_image_to_cr_data (struct image *img)
+{
+ cairo_pattern_t *pattern = NULL;
+ cairo_surface_t *surface = cr_create_surface_from_pix_containers (img->pixmap,
+ img->mask);
+ if (surface)
+ {
+ pattern = cairo_pattern_create_for_surface (surface);
+ if (img->cr_data)
+ {
+ cairo_matrix_t matrix;
+ cairo_pattern_get_matrix (img->cr_data, &matrix);
+ cairo_pattern_set_matrix (pattern, &matrix);
+ cairo_pattern_destroy (img->cr_data);
+ }
+ cairo_surface_destroy (surface);
+ }
+
+ img->cr_data = pattern;
+}
+
#endif /* USE_CAIRO */
#ifdef HAVE_NS
c->images[img->id] = NULL;
-#ifdef HAVE_XRENDER
+#if !defined USE_CAIRO && defined HAVE_XRENDER
if (img->picture)
XRenderFreePicture (FRAME_X_DISPLAY (f), img->picture);
if (img->mask_picture)
img->load_failed_p = ! img->type->load (f, img);
#ifdef USE_CAIRO
- if (!img->load_failed_p && img->cr_data == NULL)
+ if (!img->load_failed_p)
{
- img->cr_data = cr_create_cr_surface_from_image (f, img);
- if (img->cr_data == NULL)
+ block_input ();
+ if (img->cr_data == NULL || (cairo_pattern_get_type (img->cr_data)
+ != CAIRO_PATTERN_TYPE_SURFACE))
{
- img->load_failed_p = 1;
- img->type->free (f, img);
+ cr_put_image_to_cr_data (img);
+ if (img->cr_data == NULL)
+ {
+ img->load_failed_p = 1;
+ img->type->free (f, img);
+ }
}
+ unblock_input ();
}
#elif defined HAVE_X_WINDOWS
if (!img->load_failed_p)
#ifdef USE_CAIRO
if (img->cr_data)
{
- cairo_surface_destroy ((cairo_surface_t *) img->cr_data);
+ cairo_pattern_destroy (img->cr_data);
img->cr_data = NULL;
}
#endif /* USE_CAIRO */
return;
# endif
-# ifdef HAVE_XRENDER
+# if !defined USE_CAIRO && defined HAVE_XRENDER
if (!img->picture)
return;
# endif
return;
# endif
-# ifdef HAVE_XRENDER
+# if !defined USE_CAIRO && defined HAVE_XRENDER
if (!img->picture)
return;
# endif
return;
# endif
-# ifdef HAVE_XRENDER
+# if !defined USE_CAIRO && defined HAVE_XRENDER
if (!img->picture)
return;
# endif
/* Under NS the transform is applied to the drawing surface at
drawing time, so store it for later. */
ns_image_set_transform (img->pixmap, matrix);
+# elif defined USE_CAIRO
+ cairo_matrix_t cr_matrix = {matrix[0][0], matrix[0][1], matrix[1][0],
+ matrix[1][1], matrix[2][0], matrix[2][1]};
+ cairo_pattern_t *pattern = cairo_pattern_create_rgb (0, 0, 0);
+ cairo_pattern_set_matrix (pattern, &cr_matrix);
+ /* Dummy solid color pattern just to record pattern matrix. */
+ img->cr_data = pattern;
# elif defined (HAVE_XRENDER)
if (img->picture)
{
eassert ((!mask_p ? img->pixmap : img->mask) == NO_PIXMAP);
Picture *picture = NULL;
-#ifdef HAVE_XRENDER
+#if !defined USE_CAIRO && defined HAVE_XRENDER
picture = !mask_p ? &img->picture : &img->mask_picture;
#endif
return image_create_x_image_and_pixmap_1 (f, width, height, depth, ximg,
/* Fringe bitmaps. */
static int max_fringe_bmp = 0;
-static cairo_surface_t **fringe_bmp = 0;
+static cairo_pattern_t **fringe_bmp = 0;
static void
x_cr_define_fringe_bitmap (int which, unsigned short *bits, int h, int wd)
{
int i, stride;
cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
unsigned char *data;
if (which >= max_fringe_bmp)
}
cairo_surface_mark_dirty (surface);
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (surface);
unblock_input ();
- fringe_bmp[which] = surface;
+ fringe_bmp[which] = pattern;
}
static void
if (fringe_bmp[which])
{
block_input ();
- cairo_surface_destroy (fringe_bmp[which]);
+ cairo_pattern_destroy (fringe_bmp[which]);
unblock_input ();
}
fringe_bmp[which] = 0;
}
static void
-x_cr_draw_image (struct frame *f, GC gc, cairo_surface_t *image,
- int image_width, int image_height,
+x_cr_draw_image (struct frame *f, GC gc, cairo_pattern_t *image,
int src_x, int src_y, int width, int height,
int dest_x, int dest_y, bool overlay_p)
{
cairo_fill_preserve (cr);
}
- int orig_image_width = cairo_image_surface_get_width (image);
- if (image_width == 0) image_width = orig_image_width;
- int orig_image_height = cairo_image_surface_get_height (image);
- if (image_height == 0) image_height = orig_image_height;
-
- cairo_pattern_t *pattern = cairo_pattern_create_for_surface (image);
- cairo_matrix_t matrix;
- cairo_matrix_init_scale (&matrix, orig_image_width / (double) image_width,
- orig_image_height / (double) image_height);
- cairo_matrix_translate (&matrix, src_x - dest_x, src_y - dest_y);
- cairo_pattern_set_matrix (pattern, &matrix);
+ cairo_translate (cr, dest_x - src_x, dest_y - src_y);
- cairo_format_t format = cairo_image_surface_get_format (image);
+ cairo_surface_t *surface;
+ cairo_pattern_get_surface (image, &surface);
+ cairo_format_t format = cairo_image_surface_get_format (surface);
if (format != CAIRO_FORMAT_A8 && format != CAIRO_FORMAT_A1)
{
- cairo_set_source (cr, pattern);
+ cairo_set_source (cr, image);
cairo_fill (cr);
}
else
{
x_set_cr_source_with_gc_foreground (f, gc);
cairo_clip (cr);
- cairo_mask (cr, pattern);
+ cairo_mask (cr, image);
}
- cairo_pattern_destroy (pattern);
x_end_cr_clip (f);
}
: f->output_data.x->cursor_pixel)
: face->foreground));
XSetBackground (display, gc, face->background);
- x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, 0, 0, p->dh,
+ x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
p->wd, p->h, p->x, p->y, p->overlay_p);
XSetForeground (display, gc, gcv.foreground);
XSetBackground (display, gc, gcv.background);
if (s->img->cr_data)
{
x_set_glyph_string_clipping (s);
- x_cr_draw_image (s->f, s->gc,
- s->img->cr_data, s->img->width, s->img->height,
+ x_cr_draw_image (s->f, s->gc, s->img->cr_data,
s->slice.x, s->slice.y, s->slice.width, s->slice.height,
x, y, true);
if (!s->img->mask)