diff options
author | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 2019-05-29 17:58:04 +0900 |
---|---|---|
committer | YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 2019-05-29 17:58:43 +0900 |
commit | c89900ebd79d8c4bf5fd5550de053f379abd60ef (patch) | |
tree | 73e5d59325043b25306bad2670c0a55b8ef172c0 | |
parent | 09dce0fd391571ab1b580d2818689d596a8b99de (diff) | |
download | emacs-c89900ebd79d8c4bf5fd5550de053f379abd60ef.tar.gz |
Rework cairo image support to improve consistency (Bug#35871)
* src/dispextern.h (Emacs_Pix_Container) [USE_CAIRO]: New struct. Also used
as aliases of Emacs_Pixmap and Emacs_Pix_Context.
(x_kill_gs_process) [USE_CAIRO]: #ifdef out extern.
(RGB_PIXEL_COLOR) [USE_CAIRO]: Define as unsigned long.
* src/image.c: Include stdint.h. On cairo, remove existing image support
code, use non-X11-specific code for XBM/XPM, and remove POSTSCRIPT support.
(PUT_PIXEL): New macro. Use it instead of XPutPixel when not specific to X11.
(GET_PIXEL, NO_PIXMAP, PIX_MASK_RETAIN, PIX_MASK_DRAW)
(RGB_TO_ULONG, ARGB_TO_ULONG, RED_FROM_ULONG)
(GREEN_FROM_ULONG, BLUE_FROM_ULONG, RED16_FROM_ULONG)
(GREEN16_FROM_ULONG, BLUE16_FROM_ULONG) [USE_CAIRO]: New macros.
(image_create_pix_container, image_pix_container_put_pixel)
(image_pix_context_get_pixel, image_pix_container_create_from_bitmap_data)
(cr_create_cr_surface_from_image) [USE_CAIRO]: New functions.
(image_create_x_image_and_pixmap_1, image_destroy_x_image)
(image_check_image_size): Extract X11-specific code from here ...
(x_create_x_image_and_pixmap, x_destroy_x_image)
(x_check_image_size) [HAVE_X_WINDOWS]: ... to here.
(x_create_bitmap_mask) [HAVE_X_WINDOWS]: Use them. Inline specialized version
of four_corners_best.
(prepare_image_for_display, image_clear_image_1, image_destroy_x_image)
(gui_put_x_image, image_put_x_image, image_get_x_image, image_unget_x_image)
(Create_Pixmap_From_Bitmap_Data, lookup_rgb_color)
(image_to_emacs_colors) [USE_CAIRO]: Add cairo support.
(image_background, png_load_body) [USE_CAIRO]: Use image_alloc_image_color for
img->background.
(image_sync_to_pixmaps) [USE_CAIRO]: #ifdef out function.
(Create_Pixmap_From_Bitmap_Data) [HAVE_X_WINDOWS]: Move image_check_image_size
call from here ...
(xbm_load_image): ... to here.
(xpm_load_image):
(image_build_heuristic_mask, pbm_load, gif_load) [USE_CAIRO]: Use
lookup_rgb_color for argument of PUT_PIXEL.
(image_pixmap_draw_cross) [HAVE_X_WINDOWS || USE_CAIRO]: New function.
(image_disable_image) [HAVE_X_WINDOWS || USE_CAIRO]: Use it.
(CrossForeground) [!HAVE_NTGUI && !HAVE_NS]: New macro.
(image_disable_image) [!HAVE_NTGUI && !HAVE_NS]: Use it.
* src/xterm.c (handle_one_xevent) <ClientMessage> [USE_CAIRO]: #ifdef out
x_kill_gs_process call.
(x_free_pixmap) [USE_CAIRO]: Free Emacs_Pix_Container and data it contains.
-rw-r--r-- | src/dispextern.h | 21 | ||||
-rw-r--r-- | src/image.c | 957 | ||||
-rw-r--r-- | src/xterm.c | 12 |
3 files changed, 485 insertions, 505 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index aa80fa653db..70ae96b8243 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -38,7 +38,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ typedef XColor Emacs_Color; typedef Cursor Emacs_Cursor; #define No_Cursor (None) +#ifndef USE_CAIRO typedef Pixmap Emacs_Pixmap; +#endif typedef XRectangle Emacs_Rectangle; typedef XGCValues Emacs_GC; #else /* !HAVE_X_WINDOWS */ @@ -92,11 +94,26 @@ xstrcasecmp (char const *a, char const *b) #ifdef HAVE_X_WINDOWS #include <X11/Xresource.h> /* for XrmDatabase */ typedef struct x_display_info Display_Info; +#ifndef USE_CAIRO typedef XImage *Emacs_Pix_Container; typedef XImage *Emacs_Pix_Context; +#endif /* !USE_CAIRO */ #define NativeRectangle XRectangle #endif +#ifdef USE_CAIRO +/* Mininal version of XImage. */ +typedef struct +{ + int width, height; /* size of image */ + char *data; /* pointer to image data */ + int bytes_per_line; /* accelarator to next line */ + int bits_per_pixel; /* bits per pixel (ZPixmap) */ +} *Emacs_Pix_Container; +typedef Emacs_Pix_Container Emacs_Pixmap; +typedef Emacs_Pix_Container Emacs_Pix_Context; +#endif + #ifdef HAVE_NTGUI #include "w32gui.h" typedef struct w32_display_info Display_Info; @@ -3396,7 +3413,9 @@ extern void image_destroy_bitmap (struct frame *, ptrdiff_t); extern void image_destroy_all_bitmaps (Display_Info *); #ifdef HAVE_X_WINDOWS extern void x_create_bitmap_mask (struct frame *, ptrdiff_t); +#ifndef USE_CAIRO extern void x_kill_gs_process (Pixmap, struct frame *); +#endif /* !USE_CAIRO */ #endif extern Lisp_Object image_find_image_file (Lisp_Object); @@ -3408,7 +3427,7 @@ bool valid_image_p (Lisp_Object); void prepare_image_for_display (struct frame *, struct image *); ptrdiff_t lookup_image (struct frame *, Lisp_Object); -#if defined (HAVE_X_WINDOWS) || defined (HAVE_NS) +#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS #define RGB_PIXEL_COLOR unsigned long #endif diff --git a/src/image.c b/src/image.c index 699bdfd4fa1..70ca1079f3f 100644 --- a/src/image.c +++ b/src/image.c @@ -30,6 +30,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #include <setjmp.h> +#include <stdint.h> #include <c-ctype.h> #include <flexmember.h> @@ -67,13 +68,37 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ #ifdef HAVE_X_WINDOWS typedef struct x_bitmap_record Bitmap_Record; +#ifndef USE_CAIRO #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) +#define PUT_PIXEL XPutPixel #define NO_PIXMAP None #define PIX_MASK_RETAIN 0 #define PIX_MASK_DRAW 1 +#endif /* !USE_CAIRO */ #endif /* HAVE_X_WINDOWS */ +#ifdef USE_CAIRO +#define GET_PIXEL image_pix_context_get_pixel +#define PUT_PIXEL image_pix_container_put_pixel +#define NO_PIXMAP 0 + +#define PIX_MASK_RETAIN 0 +#define PIX_MASK_DRAW 255 + +#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) +#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff) +#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff) +#define BLUE_FROM_ULONG(color) ((color) & 0xff) +#define RED16_FROM_ULONG(color) (RED_FROM_ULONG (color) * 0x101) +#define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG (color) * 0x101) +#define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG (color) * 0x101) + +static unsigned long image_alloc_image_color (struct frame *, struct image *, + Lisp_Object, unsigned long); +#endif /* USE_CAIRO */ + #ifdef HAVE_NTGUI /* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */ @@ -84,6 +109,7 @@ typedef struct x_bitmap_record Bitmap_Record; typedef struct w32_bitmap_record Bitmap_Record; #define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y) +#define PUT_PIXEL XPutPixel #define NO_PIXMAP 0 #define PIX_MASK_RETAIN 0 @@ -95,6 +121,7 @@ typedef struct w32_bitmap_record Bitmap_Record; typedef struct ns_bitmap_record Bitmap_Record; #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) +#define PUT_PIXEL XPutPixel #define NO_PIXMAP 0 #define PIX_MASK_RETAIN 0 @@ -118,16 +145,109 @@ static void free_color_table (void); static unsigned long *colors_in_color_table (int *n); #endif -/* Code to deal with bitmaps. Bitmaps are referenced by their bitmap - id, which is just an int that this section returns. Bitmaps are - reference counted so they can be shared among frames. +#ifdef USE_CAIRO - Bitmap indices are guaranteed to be > 0, so a negative number can - be used to indicate no bitmap. +static Emacs_Pix_Container +image_create_pix_container (struct frame *f, unsigned int width, + unsigned int height, unsigned int depth) +{ + Emacs_Pix_Container pimg; - If you use image_create_bitmap_from_data, then you must keep track - of the bitmaps yourself. That is, creating a bitmap from the same - data more than once will not be caught. */ + pimg = xmalloc (sizeof (*pimg)); + pimg->width = width; + pimg->height = height; + pimg->bits_per_pixel = depth == 1 ? 8 : 32; + pimg->bytes_per_line = cairo_format_stride_for_width ((depth == 1 + ? CAIRO_FORMAT_A8 + : CAIRO_FORMAT_RGB24), + width); + pimg->data = xmalloc (pimg->bytes_per_line * height); + + return pimg; +} + +static void +image_pix_container_put_pixel (Emacs_Pix_Container image, + int x, int y, unsigned long pixel) +{ + if (image->bits_per_pixel == 32) + ((uint32_t *)(image->data + y * image->bytes_per_line))[x] = pixel; + else + ((uint8_t *)(image->data + y * image->bytes_per_line))[x] = pixel; +} + +static unsigned long +image_pix_context_get_pixel (Emacs_Pix_Context image, int x, int y) +{ + if (image->bits_per_pixel == 32) + return ((uint32_t *)(image->data + y * image->bytes_per_line))[x]; + else + return ((uint8_t *)(image->data + y * image->bytes_per_line))[x]; +} + +static Emacs_Pix_Container +image_pix_container_create_from_bitmap_data (struct frame *f, + char *data, unsigned int width, + unsigned int height, + unsigned long fg, + unsigned long bg) +{ + Emacs_Pix_Container pimg = image_create_pix_container (f, width, height, 0); + int bytes_per_line = (width + (CHAR_BIT - 1)) / CHAR_BIT; + + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + PUT_PIXEL (pimg, x, y, + (data[x / CHAR_BIT] >> (x % CHAR_BIT)) & 1 ? fg : bg); + data += bytes_per_line; + } + + return pimg; +} + +static cairo_surface_t * +cr_create_cr_surface_from_image (struct frame *f, struct image *img) +{ + Emacs_Pix_Container pimg = img->pixmap; + cairo_surface_t *surface; + + if (img->mask) + { + int x, y; + + for (y = 0; y < pimg->height; y++) + for (x = 0; x < pimg->width; x++) + { + unsigned long color, alpha; + int r, g, b; + + color = GET_PIXEL (pimg, x, y); + alpha = GET_PIXEL (img->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; + } + block_input (); + surface = cairo_image_surface_create_for_data ((unsigned char *) pimg->data, + (img->mask + ? CAIRO_FORMAT_ARGB32 + : CAIRO_FORMAT_RGB24), + pimg->width, pimg->height, + pimg->bytes_per_line); + static cairo_user_data_key_t key; + cairo_surface_set_user_data (surface, &key, pimg->data, xfree); + unblock_input (); + pimg->data = NULL; + + return surface; +} + +#endif /* USE_CAIRO */ #ifdef HAVE_NS /* Use with images created by ns_image_for_XPM. */ @@ -146,6 +266,16 @@ XPutPixel (Emacs_Pix_Container image, int x, int y, unsigned long pixel) } #endif /* HAVE_NS */ +/* Code to deal with bitmaps. Bitmaps are referenced by their bitmap + id, which is just an int that this section returns. Bitmaps are + reference counted so they can be shared among frames. + + Bitmap indices are guaranteed to be > 0, so a negative number can + be used to indicate no bitmap. + + If you use image_create_bitmap_from_data, then you must keep track + of the bitmaps yourself. That is, creating a bitmap from the same + data more than once will not be caught. */ /* Functions to access the contents of a bitmap, given an id. */ @@ -433,16 +563,17 @@ static void image_unget_x_image (struct image *, bool, Emacs_Pix_Container); #ifdef HAVE_X_WINDOWS +#ifndef USE_CAIRO static void image_sync_to_pixmaps (struct frame *, struct image *); +#endif /* !USE_CAIRO */ -/* Useful functions defined in the section - `Image type independent image structures' below. */ - -static unsigned long four_corners_best (XImage *ximg, - int *corners, - unsigned long width, - unsigned long height); +/* We are working on X-specific data structures here even with cairo. + So we use X-specific versions of image construction/destruction + functions and inline the specific case of four_corners_best. */ +static bool x_create_x_image_and_pixmap (struct frame *, int, int, int, + XImage **, Pixmap *); +static void x_destroy_x_image (XImage *); /* Create a mask of a bitmap. Note is this not a perfect mask. It's nicer with some borders in this context */ @@ -454,7 +585,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) XImage *ximg, *mask_img; unsigned long width, height; bool result; - unsigned long bg; + unsigned long bg UNINIT; unsigned long x, y, xp, xm, yp, ym; GC gc; @@ -477,8 +608,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) return; } - result = image_create_x_image_and_pixmap_1 (f, width, height, 1, - &mask_img, &mask, NULL); + result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask); unblock_input (); if (!result) @@ -487,7 +617,23 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) return; } - bg = four_corners_best (ximg, NULL, width, height); + unsigned long corner_pixels[4]; + corner_pixels[0] = XGetPixel (ximg, 0, 0); + corner_pixels[1] = XGetPixel (ximg, width - 1, 0); + corner_pixels[2] = XGetPixel (ximg, width - 1, height - 1); + corner_pixels[3] = XGetPixel (ximg, 0, height - 1); + int i, best_count; + for (i = best_count = 0; i < 4; ++i) + { + int j, n; + + for (j = n = 0; j < 4; ++j) + if (corner_pixels[i] == corner_pixels[j]) + ++n; + + if (n > best_count) + bg = corner_pixels[i], best_count = n; + } for (y = 0; y < ximg->height; ++y) { @@ -522,7 +668,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id) dpyinfo->bitmaps[id - 1].mask = mask; XDestroyImage (ximg); - image_destroy_x_image (mask_img); + x_destroy_x_image (mask_img); } #endif /* HAVE_X_WINDOWS */ @@ -1015,13 +1161,22 @@ prepare_image_for_display (struct frame *f, struct image *img) /* We're about to display IMG, so set its timestamp to `now'. */ img->timestamp = current_timespec (); -#ifndef USE_CAIRO /* If IMG doesn't have a pixmap yet, load it now, using the image type dependent loader function. */ if (img->pixmap == NO_PIXMAP && !img->load_failed_p) img->load_failed_p = ! img->type->load (f, img); -#ifdef HAVE_X_WINDOWS +#ifdef USE_CAIRO + if (!img->load_failed_p && img->cr_data == NULL) + { + img->cr_data = cr_create_cr_surface_from_image (f, img); + if (img->cr_data == NULL) + { + img->load_failed_p = 1; + img->type->free (f, img); + } + } +#elif defined HAVE_X_WINDOWS if (!img->load_failed_p) { block_input (); @@ -1029,7 +1184,6 @@ prepare_image_for_display (struct frame *f, struct image *img) unblock_input (); } #endif -#endif } @@ -1076,48 +1230,6 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice) return ascent; } -#ifdef USE_CAIRO -static uint32_t -emacs_color_to_argb32 (Emacs_Color *ec) -{ - return ((0xffu << 24) | ((ec->red / 256) << 16) - | ((ec->green / 256) << 8) | (ec->blue / 256)); -} - -static uint32_t -get_spec_bg_or_alpha_as_argb (struct image *img, - struct frame *f) -{ - uint32_t bgcolor = 0; - Emacs_Color xbgcolor; - Lisp_Object bg = image_spec_value (img->spec, QCbackground, NULL); - - if (STRINGP (bg) && x_parse_color (f, SSDATA (bg), &xbgcolor)) - bgcolor = emacs_color_to_argb32 (&xbgcolor); - - return bgcolor; -} - -static cairo_surface_t * -create_cairo_image_surface (int width, int height) -{ - cairo_format_t format = CAIRO_FORMAT_ARGB32; - eassert (cairo_format_stride_for_width (format, width) == width * 4); - - return cairo_image_surface_create (format, width, height); -} - -static void -set_cairo_image_surface (struct image *img, cairo_surface_t *surface) -{ - cairo_surface_mark_dirty (surface); - img->width = cairo_image_surface_get_width (surface); - img->height = cairo_image_surface_get_height (surface); - img->cr_data = surface; - img->pixmap = 0; -} -#endif - /* Image background colors. */ @@ -1184,7 +1296,19 @@ image_background (struct image *img, struct frame *f, Emacs_Pix_Context pimg) if (free_pimg) pimg = image_get_x_image_or_dc (f, img, 0, &prev); - img->background = four_corners_best (pimg, img->corners, img->width, img->height); + RGB_PIXEL_COLOR bg + = four_corners_best (pimg, img->corners, img->width, img->height); +#ifdef USE_CAIRO + { + char color_name[30]; + sprintf (color_name, "#%04x%04x%04x", + (unsigned int) RED16_FROM_ULONG (bg), + (unsigned int) GREEN16_FROM_ULONG (bg), + (unsigned int) BLUE16_FROM_ULONG (bg)); + bg = image_alloc_image_color (f, img, build_string (color_name), 0); + } +#endif + img->background = bg; if (free_pimg) image_unget_x_image_or_dc (img, 0, pimg, prev); @@ -1259,7 +1383,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags) /* NOTE (HAVE_NS): background color is NOT an indexed color! */ img->background_valid = 0; } -#ifdef HAVE_X_WINDOWS +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO if (img->ximg) { image_destroy_x_image (img->ximg); @@ -1277,7 +1401,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags) img->mask = NO_PIXMAP; img->background_transparent_valid = 0; } -#ifdef HAVE_X_WINDOWS +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO if (img->mask_img) { image_destroy_x_image (img->mask_img); @@ -1290,14 +1414,21 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags) if ((flags & CLEAR_IMAGE_COLORS) && img->ncolors) { /* W32_TODO: color table support. */ -#ifdef HAVE_X_WINDOWS +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO x_free_colors (f, img->colors, img->ncolors); -#endif /* HAVE_X_WINDOWS */ +#endif /* HAVE_X_WINDOWS && !USE_CAIRO */ xfree (img->colors); img->colors = NULL; img->ncolors = 0; } +#ifdef USE_CAIRO + if (img->cr_data) + { + cairo_surface_destroy ((cairo_surface_t *) img->cr_data); + img->cr_data = NULL; + } +#endif /* USE_CAIRO */ } /* Free X resources of image IMG which is used on frame F. */ @@ -1306,10 +1437,6 @@ static void image_clear_image (struct frame *f, struct image *img) { block_input (); -#ifdef USE_CAIRO - if (img->cr_data) - cairo_surface_destroy ((cairo_surface_t *)img->cr_data); -#endif image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS); unblock_input (); @@ -2000,14 +2127,10 @@ mark_image_cache (struct image_cache *c) X / NS / W32 support code ***********************************************************************/ -/* Return true if XIMG's size WIDTH x HEIGHT doesn't break the - windowing system. - WIDTH and HEIGHT must both be positive. - If XIMG is null, assume it is a bitmap. */ +#ifdef HAVE_X_WINDOWS static bool -image_check_image_size (Emacs_Pix_Container ximg, int width, int height) +x_check_image_size (XImage *ximg, int width, int height) { -#ifdef HAVE_X_WINDOWS /* Respect Xlib's limits: it cannot deal with images that have more than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */ @@ -2032,29 +2155,12 @@ image_check_image_size (Emacs_Pix_Container ximg, int width, int height) } return (width <= (INT_MAX - (bitmap_pad - 1)) / depth && height <= X_IMAGE_BYTES_MAX / bytes_per_line); -#else - /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases. - For now, assume that every image size is allowed on these systems. */ - return 1; -#endif } -/* Create an Emacs_Pix_Container and a pixmap of size WIDTH x - HEIGHT for use on frame F. Set *PIMG and *PIXMAP to the - Emacs_Pix_Container and Emacs_Pixmap created. Set (*PIMG)->data - to a raster of WIDTH x HEIGHT pixels allocated via xmalloc. Print - error messages via image_error if an error occurs. Value is true - if successful. - - On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH - should indicate the bit depth of the image. */ - static bool -image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int depth, - Emacs_Pix_Container *pimg, - Emacs_Pixmap *pixmap, Picture *picture) +x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth, + XImage **ximg, Pixmap *pixmap) { -#ifdef HAVE_X_WINDOWS Display *display = FRAME_X_DISPLAY (f); Drawable drawable = FRAME_X_DRAWABLE (f); Screen *screen = FRAME_X_SCREEN (f); @@ -2063,38 +2169,104 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d if (depth <= 0) depth = DefaultDepthOfScreen (screen); - *pimg = XCreateImage (display, DefaultVisualOfScreen (screen), + *ximg = XCreateImage (display, DefaultVisualOfScreen (screen), depth, ZPixmap, 0, NULL, width, height, depth > 16 ? 32 : depth > 8 ? 16 : 8, 0); - if (*pimg == NULL) + if (*ximg == NULL) { image_error ("Unable to allocate X image"); return 0; } - if (! image_check_image_size (*pimg, width, height)) + if (! x_check_image_size (*ximg, width, height)) { - image_destroy_x_image (*pimg); - *pimg = NULL; + x_destroy_x_image (*ximg); + *ximg = NULL; image_error ("Image too large (%dx%d)", make_fixnum (width), make_fixnum (height)); return 0; } /* Allocate image raster. */ - (*pimg)->data = xmalloc ((*pimg)->bytes_per_line * height); + (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height); /* Allocate a pixmap of the same size. */ *pixmap = XCreatePixmap (display, drawable, width, height, depth); if (*pixmap == NO_PIXMAP) { - image_destroy_x_image (*pimg); - *pimg = NULL; + x_destroy_x_image (*ximg); + *ximg = NULL; image_error ("Unable to create X pixmap"); return 0; } + return 1; +} + +static void +x_destroy_x_image (XImage *ximg) +{ + eassert (input_blocked_p ()); + if (ximg) + { + xfree (ximg->data); + ximg->data = NULL; + } +} + +#endif /* HAVE_X_WINDOWS */ + +/* Return true if XIMG's size WIDTH x HEIGHT doesn't break the + windowing system. + WIDTH and HEIGHT must both be positive. + If XIMG is null, assume it is a bitmap. */ + +static bool +image_check_image_size (Emacs_Pix_Container ximg, int width, int height) +{ +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO + return x_check_image_size (ximg, width, height); +#else + /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases. + For now, assume that every image size is allowed on these systems. */ + return 1; +#endif +} + +/* Create an Emacs_Pix_Container and a pixmap of size WIDTH x + HEIGHT for use on frame F. Set *PIMG and *PIXMAP to the + Emacs_Pix_Container and Emacs_Pixmap created. Set (*PIMG)->data + to a raster of WIDTH x HEIGHT pixels allocated via xmalloc. Print + error messages via image_error if an error occurs. Value is true + if successful. + + On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH + should indicate the bit depth of the image. */ + +static bool +image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int depth, + Emacs_Pix_Container *pimg, + Emacs_Pixmap *pixmap, Picture *picture) +{ +#ifdef USE_CAIRO + eassert (input_blocked_p ()); + + /* Allocate a pixmap of the same size. */ + *pixmap = image_create_pix_container (f, width, height, depth); + if (*pixmap == NO_PIXMAP) + { + *pimg = NULL; + image_error ("Unable to create X pixmap", Qnil, Qnil); + return 0; + } + + *pimg = *pixmap; + return 1; +#elif defined HAVE_X_WINDOWS + if (!x_create_x_image_and_pixmap (f, width, height, depth, pimg, pixmap)) + return 0; # ifdef HAVE_XRENDER + Display *display = FRAME_X_DISPLAY (f); int event_basep, error_basep; if (picture && XRenderQueryExtension (display, &event_basep, &error_basep)) { @@ -2238,14 +2410,14 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d static void image_destroy_x_image (Emacs_Pix_Container pimg) { +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO + x_destroy_x_image (pimg); +#else eassert (input_blocked_p ()); if (pimg) { -#ifdef HAVE_X_WINDOWS - xfree (pimg->data); - pimg->data = NULL; - XDestroyImage (pimg); -#endif /* HAVE_X_WINDOWS */ +#ifdef USE_CAIRO +#endif /* USE_CAIRO */ #ifdef HAVE_NTGUI /* Data will be freed by DestroyObject. */ pimg->data = NULL; @@ -2255,6 +2427,7 @@ image_destroy_x_image (Emacs_Pix_Container pimg) ns_release_object (pimg); #endif /* HAVE_NS */ } +#endif } @@ -2266,7 +2439,9 @@ static void gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg, Emacs_Pixmap pixmap, int width, int height) { -#ifdef HAVE_X_WINDOWS +#ifdef USE_CAIRO + eassert (pimg == pixmap); +#elif defined HAVE_X_WINDOWS GC gc; eassert (input_blocked_p ()); @@ -2319,7 +2494,7 @@ static void image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg, bool mask_p) { -#ifdef HAVE_X_WINDOWS +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO if (!mask_p) { eassert (img->ximg == NULL); @@ -2337,7 +2512,7 @@ image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg, #endif } -#ifdef HAVE_X_WINDOWS +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO /* Put the X images recorded in IMG on frame F into pixmaps, then free the X images and their buffers. */ @@ -2391,7 +2566,9 @@ image_unget_x_image_or_dc (struct image *img, bool mask_p, static Emacs_Pix_Container image_get_x_image (struct frame *f, struct image *img, bool mask_p) { -#ifdef HAVE_X_WINDOWS +#ifdef USE_CAIRO + return !mask_p ? img->pixmap : img->mask; +#elif defined HAVE_X_WINDOWS XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img; if (ximg_in_img) @@ -2410,7 +2587,8 @@ image_get_x_image (struct frame *f, struct image *img, bool mask_p) static void image_unget_x_image (struct image *img, bool mask_p, Emacs_Pix_Container ximg) { -#ifdef HAVE_X_WINDOWS +#ifdef USE_CAIRO +#elif defined HAVE_X_WINDOWS XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img; if (ximg_in_img) @@ -2869,28 +3047,32 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data, RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg, bool non_default_colors) { -#ifdef HAVE_NTGUI +#ifdef USE_CAIRO + Emacs_Color fgbg[] = {{.pixel = fg}, {.pixel = bg}}; + FRAME_TERMINAL (f)->query_colors (f, fgbg, ARRAYELTS (fgbg)); + fg = lookup_rgb_color (f, fgbg[0].red, fgbg[0].green, fgbg[0].blue); + bg = lookup_rgb_color (f, fgbg[1].red, fgbg[1].green, fgbg[1].blue); + img->pixmap + = image_pix_container_create_from_bitmap_data (f, data, img->width, + img->height, fg, bg); +#elif defined HAVE_X_WINDOWS + img->pixmap + = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f), + FRAME_X_DRAWABLE (f), + data, + img->width, img->height, + fg, bg, + DefaultDepthOfScreen (FRAME_X_SCREEN (f))); +#elif defined HAVE_NTGUI img->pixmap = w32_create_pixmap_from_bitmap_data (img->width, img->height, data); /* If colors were specified, transfer the bitmap to a color one. */ if (non_default_colors) convert_mono_to_color_image (f, img, fg, bg); - -#elif defined (HAVE_NS) +#elif defined HAVE_NS img->pixmap = ns_image_from_XBM (data, img->width, img->height, fg, bg); - -#else - img->pixmap = - (image_check_image_size (0, img->width, img->height) - ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f), - FRAME_X_DRAWABLE (f), - data, - img->width, img->height, - fg, bg, - DefaultDepthOfScreen (FRAME_X_SCREEN (f))) - : NO_PIXMAP); -#endif /* !HAVE_NTGUI && !HAVE_NS */ +#endif } @@ -3099,9 +3281,12 @@ xbm_load_image (struct frame *f, struct image *img, char *contents, char *end) non_default_colors = 1; } - Create_Pixmap_From_Bitmap_Data (f, img, data, - foreground, background, - non_default_colors); + if (image_check_image_size (0, img->width, img->height)) + Create_Pixmap_From_Bitmap_Data (f, img, data, + foreground, background, + non_default_colors); + else + img->pixmap = NO_PIXMAP; xfree (data); if (img->pixmap == NO_PIXMAP) @@ -3315,7 +3500,7 @@ xbm_load (struct frame *f, struct image *img) #endif /* not HAVE_NTGUI */ #endif /* HAVE_XPM */ -#if defined (HAVE_XPM) || defined (HAVE_NS) +#if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS /* Indices of image specification fields in xpm_format, below. */ @@ -3353,19 +3538,17 @@ static const struct image_keyword xpm_format[XPM_LAST] = {":background", IMAGE_STRING_OR_NIL_VALUE, 0} }; -#ifdef HAVE_X_WINDOWS +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation functions for allocating image colors. Our own functions handle color allocation failures more gracefully than the ones on the XPM lib. */ -#ifndef USE_CAIRO #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure #define ALLOC_XPM_COLORS #endif -#endif /* USE_CAIRO */ -#endif /* HAVE_X_WINDOWS */ +#endif /* HAVE_X_WINDOWS && !USE_CAIRO */ #ifdef ALLOC_XPM_COLORS @@ -3614,7 +3797,7 @@ xpm_image_p (Lisp_Object object) || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))); } -#endif /* HAVE_XPM || HAVE_NS */ +#endif /* HAVE_XPM || USE_CAIRO || HAVE_NS */ #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK ptrdiff_t @@ -3670,7 +3853,7 @@ x_create_bitmap_from_xpm_data (struct frame *f, const char **bits) /* Load image IMG which will be displayed on frame F. Value is true if successful. */ -#ifdef HAVE_XPM +#if defined HAVE_XPM && !defined USE_CAIRO static bool xpm_load (struct frame *f, struct image *img) @@ -3838,44 +4021,6 @@ xpm_load (struct frame *f, struct image *img) #endif /* HAVE_NTGUI */ } -#ifdef USE_CAIRO - /* Load very specific Xpm:s. */ - if (rc == XpmSuccess - && img->ximg->format == ZPixmap - && img->ximg->bits_per_pixel == 32 - && (! img->mask_img || img->mask_img->bits_per_pixel == 1)) - { - int width = img->ximg->width; - int height = img->ximg->height; - cairo_surface_t *surface = create_cairo_image_surface (width, height); - int i; - uint32_t *od = (uint32_t *) cairo_image_surface_get_data (surface); - uint32_t *id = (uint32_t *) img->ximg->data; - char *mid = img->mask_img ? img->mask_img->data : 0; - uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f); - - for (i = 0; i < height; ++i) - { - int k; - for (k = 0; k < width; ++k) - { - int idx = i * img->ximg->bytes_per_line/4 + k; - int maskidx = mid ? i * img->mask_img->bytes_per_line + k/8 : 0; - int mask = mid ? mid[maskidx] & (1 << (k % 8)) : 1; - - if (mask) od[idx] = id[idx] + 0xff000000; /* ff => full alpha */ - else od[idx] = bgcolor; - } - } - - set_cairo_image_surface (img, surface); - } - else - { - rc = XpmFileInvalid; - image_clear_image (f, img); - } -#else #ifdef HAVE_X_WINDOWS if (rc == XpmSuccess) { @@ -3901,7 +4046,6 @@ xpm_load (struct frame *f, struct image *img) } } #endif -#endif /* ! USE_CAIRO */ if (rc == XpmSuccess) { @@ -4004,9 +4148,9 @@ xpm_load (struct frame *f, struct image *img) return rc == XpmSuccess; } -#endif /* HAVE_XPM */ +#endif /* HAVE_XPM && !USE_CAIRO */ -#if defined (HAVE_NS) && !defined (HAVE_XPM) +#if defined USE_CAIRO || (defined HAVE_NS && !defined HAVE_XPM) /* XPM support functions for NS where libxpm is not available. Only XPM version 3 (without any extensions) is supported. */ @@ -4346,7 +4490,9 @@ xpm_load_image (struct frame *f, color_val = Qt; else if (FRAME_TERMINAL (f)->defined_color_hook (f, SSDATA (XCDR (specified_color)), &cdef, false, false)) - color_val = make_fixnum (cdef.pixel); + color_val + = make_fixnum (lookup_rgb_color (f, cdef.red, cdef.green, + cdef.blue)); } } if (NILP (color_val) && max_key > 0) @@ -4355,7 +4501,8 @@ xpm_load_image (struct frame *f, color_val = Qt; else if (FRAME_TERMINAL (f)->defined_color_hook (f, max_color, &cdef, false, false)) - color_val = make_fixnum (cdef.pixel); + color_val = make_fixnum (lookup_rgb_color (f, cdef.red, cdef.green, + cdef.blue)); } if (!NILP (color_val)) (*put_color_table) (color_table, beg, chars_per_pixel, color_val); @@ -4363,6 +4510,14 @@ xpm_load_image (struct frame *f, expect (','); } + unsigned long frame_fg = FRAME_FOREGROUND_PIXEL (f); +#ifdef USE_CAIRO + { + Emacs_Color color = {.pixel = frame_fg}; + FRAME_TERMINAL (f)->query_colors (f, &color, 1); + frame_fg = lookup_rgb_color (f, color.red, color.green, color.blue); + } +#endif for (y = 0; y < height; y++) { expect (XPM_TK_STRING); @@ -4374,11 +4529,10 @@ xpm_load_image (struct frame *f, Lisp_Object color_val = (*get_color_table) (color_table, str, chars_per_pixel); - XPutPixel (ximg, x, y, - (FIXNUMP (color_val) ? XFIXNUM (color_val) - : FRAME_FOREGROUND_PIXEL (f))); + PUT_PIXEL (ximg, x, y, + FIXNUMP (color_val) ? XFIXNUM (color_val) : frame_fg); #ifndef HAVE_NS - XPutPixel (mask_img, x, y, + PUT_PIXEL (mask_img, x, y, (!EQ (color_val, Qt) ? PIX_MASK_DRAW : (have_mask = true, PIX_MASK_RETAIN))); #else @@ -4735,10 +4889,8 @@ lookup_rgb_color (struct frame *f, int r, int g, int b) { #ifdef HAVE_NTGUI return PALETTERGB (r >> 8, g >> 8, b >> 8); -#elif defined HAVE_NS +#elif defined USE_CAIRO || defined HAVE_NS return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8); -#elif defined USE_CAIRO - return (0xffu << 24) | (r << 16) | (g << 8) | b; #else xsignal1 (Qfile_error, build_string ("This Emacs mishandles this image file type")); @@ -4810,7 +4962,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p) p = colors; for (y = 0; y < img->height; ++y) { -#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) +#if !defined USE_CAIRO && !defined HAVE_NS Emacs_Color *row = p; for (x = 0; x < img->width; ++x, ++p) p->pixel = GET_PIXEL (ximg, x, y); @@ -4818,11 +4970,9 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p) { FRAME_TERMINAL (f)->query_colors (f, row, img->width); } -#else - +#else /* USE_CAIRO || HAVE_NS */ for (x = 0; x < img->width; ++x, ++p) { - /* W32_TODO: palette support needed here? */ p->pixel = GET_PIXEL (ximg, x, y); if (rgb_p) { @@ -4831,7 +4981,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p) p->blue = BLUE16_FROM_ULONG (p->pixel); } } -#endif /* HAVE_X_WINDOWS */ +#endif /* USE_CAIRO || HAVE_NS */ } image_unget_x_image_or_dc (img, 0, ximg, prev); @@ -4907,7 +5057,7 @@ image_from_emacs_colors (struct frame *f, struct image *img, Emacs_Color *colors { unsigned long pixel; pixel = lookup_rgb_color (f, p->red, p->green, p->blue); - XPutPixel (oimg, x, y, pixel); + PUT_PIXEL (oimg, x, y, pixel); } xfree (colors); @@ -5056,6 +5206,44 @@ image_edge_detection (struct frame *f, struct image *img, } +#if defined HAVE_X_WINDOWS || defined USE_CAIRO +static void +image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap, + int x, int y, unsigned int width, unsigned int height, + unsigned long color) +{ +#ifdef USE_CAIRO + cairo_surface_t *surface + = cairo_image_surface_create_for_data ((unsigned char *) pixmap->data, + (pixmap->bits_per_pixel == 32 + ? CAIRO_FORMAT_RGB24 + : CAIRO_FORMAT_A8), + pixmap->width, pixmap->height, + pixmap->bytes_per_line); + cairo_t *cr = cairo_create (surface); + cairo_surface_destroy (surface); + cairo_set_source_rgb (cr, RED_FROM_ULONG (color) / 255.0, + GREEN_FROM_ULONG (color) / 255.0, + BLUE_FROM_ULONG (color) / 255.0); + cairo_move_to (cr, x + 0.5, y + 0.5); + cairo_rel_line_to (cr, width - 1, height - 1); + cairo_rel_move_to (cr, 0, - (height - 1)); + cairo_rel_line_to (cr, - (width - 1), height - 1); + cairo_set_line_width (cr, 1); + cairo_stroke (cr); + cairo_destroy (cr); +#elif HAVE_X_WINDOWS + Display *dpy = FRAME_X_DISPLAY (f); + GC gc = XCreateGC (dpy, pixmap, 0, NULL); + + XSetForeground (dpy, gc, color); + XDrawLine (dpy, pixmap, gc, x, y, x + width - 1, y + height - 1); + XDrawLine (dpy, pixmap, gc, x, y + height - 1, x + width - 1, y); + XFreeGC (dpy, gc); +#endif /* HAVE_X_WINDOWS */ +} +#endif /* HAVE_X_WINDOWS || USE_CAIRO */ + /* Transform image IMG on frame F so that it looks disabled. */ static void @@ -5097,30 +5285,22 @@ image_disable_image (struct frame *f, struct image *img) #ifndef HAVE_NTGUI #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */ +#ifndef USE_CAIRO +#define CrossForeground(f) BLACK_PIX_DEFAULT (f) #define MaskForeground(f) WHITE_PIX_DEFAULT (f) +#else /* USE_CAIRO */ +#define CrossForeground(f) 0 +#define MaskForeground(f) PIX_MASK_DRAW +#endif /* USE_CAIRO */ - Display *dpy = FRAME_X_DISPLAY (f); - GC gc; - +#ifndef USE_CAIRO image_sync_to_pixmaps (f, img); - gc = XCreateGC (dpy, img->pixmap, 0, NULL); - XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f)); - XDrawLine (dpy, img->pixmap, gc, 0, 0, - img->width - 1, img->height - 1); - XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1, - img->width - 1, 0); - XFreeGC (dpy, gc); - +#endif /* !USE_CAIRO */ + image_pixmap_draw_cross (f, img->pixmap, 0, 0, img->width, img->height, + CrossForeground (f)); if (img->mask) - { - gc = XCreateGC (dpy, img->mask, 0, NULL); - XSetForeground (dpy, gc, MaskForeground (f)); - XDrawLine (dpy, img->mask, gc, 0, 0, - img->width - 1, img->height - 1); - XDrawLine (dpy, img->mask, gc, 0, img->height - 1, - img->width - 1, 0); - XFreeGC (dpy, gc); - } + image_pixmap_draw_cross (f, img->mask, 0, 0, img->width, img->height, + MaskForeground (f)); #endif /* !HAVE_NS */ #else HDC hdc, bmpdc; @@ -5212,6 +5392,7 @@ image_build_heuristic_mask (struct frame *f, struct image *img, if (i == 3 && NILP (how)) { +#ifndef USE_CAIRO char color_name[30]; sprintf (color_name, "#%04x%04x%04x", rgb[0] + 0u, rgb[1] + 0u, rgb[2] + 0u); @@ -5220,6 +5401,9 @@ image_build_heuristic_mask (struct frame *f, struct image *img, 0x00ffffff & /* Filter out palette info. */ #endif /* HAVE_NTGUI */ image_alloc_image_color (f, img, build_string (color_name), 0)); +#else /* USE_CAIRO */ + bg = lookup_rgb_color (f, rgb[0], rgb[1], rgb[2]); +#endif /* USE_CAIRO */ use_img_background = 0; } } @@ -5233,7 +5417,7 @@ image_build_heuristic_mask (struct frame *f, struct image *img, for (y = 0; y < img->height; ++y) for (x = 0; x < img->width; ++x) #ifndef HAVE_NS - XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg + PUT_PIXEL (mask_img, x, y, (GET_PIXEL (ximg, x, y) != bg ? PIX_MASK_DRAW : PIX_MASK_RETAIN)); #else if (XGetPixel (ximg, x, y) == bg) @@ -5406,9 +5590,7 @@ pbm_load (struct frame *f, struct image *img) enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; char *contents = NULL; char *end, *p; -#ifndef USE_CAIRO Emacs_Pix_Container ximg; -#endif specified_file = image_spec_value (img->spec, QCfile, NULL); @@ -5492,11 +5674,6 @@ pbm_load (struct frame *f, struct image *img) width = pbm_scan_number (&p, end); height = pbm_scan_number (&p, end); -#ifdef USE_CAIRO - cairo_surface_t *surface = create_cairo_image_surface (width, height); - uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface); -#endif - if (type != PBM_MONO) { max_color_idx = pbm_scan_number (&p, end); @@ -5513,10 +5690,8 @@ pbm_load (struct frame *f, struct image *img) goto error; } -#ifndef USE_CAIRO if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) goto error; -#endif /* Initialize the color hash table. */ init_color_table (); @@ -5528,42 +5703,11 @@ pbm_load (struct frame *f, struct image *img) struct image_keyword fmt[PBM_LAST]; unsigned long fg = FRAME_FOREGROUND_PIXEL (f); unsigned long bg = FRAME_BACKGROUND_PIXEL (f); -#ifdef USE_CAIRO - Emacs_Color xfg, xbg; - int fga32, bga32; -#endif /* Parse the image specification. */ memcpy (fmt, pbm_format, sizeof fmt); parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); /* Get foreground and background colors, maybe allocate colors. */ -#ifdef USE_CAIRO - if (! fmt[PBM_FOREGROUND].count - || ! STRINGP (fmt[PBM_FOREGROUND].value) - || ! FRAME_TERMINAL (f)->defined_color_hook (f, - SSDATA (fmt[PBM_FOREGROUND].value), - &xfg, - false, - false)) - { - xfg.pixel = fg; - x_query_colors (f, &xfg, 1); - } - fga32 = emacs_color_to_argb32 (&xfg); - - if (! fmt[PBM_BACKGROUND].count - || ! STRINGP (fmt[PBM_BACKGROUND].value) - || ! FRAME_TERMINAL (f)->defined_color_hook (f, - SSDATA (fmt[PBM_BACKGROUND].value), - &xbg, - false, - false)) - { - xbg.pixel = bg; - x_query_colors (f, &xbg, 1); - } - bga32 = emacs_color_to_argb32 (&xbg); -#else if (fmt[PBM_FOREGROUND].count && STRINGP (fmt[PBM_FOREGROUND].value)) fg = image_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg); @@ -5574,8 +5718,15 @@ pbm_load (struct frame *f, struct image *img) img->background = bg; img->background_valid = 1; } -#endif +#ifdef USE_CAIRO + { + Emacs_Color fgbg[] = {{.pixel = fg}, {.pixel = bg}}; + FRAME_TERMINAL (f)->query_colors (f, fgbg, ARRAYELTS (fgbg)); + fg = lookup_rgb_color (f, fgbg[0].red, fgbg[0].green, fgbg[0].blue); + bg = lookup_rgb_color (f, fgbg[1].red, fgbg[1].green, fgbg[1].blue); + } +#endif for (y = 0; y < height; ++y) for (x = 0; x < width; ++x) { @@ -5585,11 +5736,7 @@ pbm_load (struct frame *f, struct image *img) { if (p >= end) { -#ifdef USE_CAIRO - cairo_surface_destroy (surface); -#else image_destroy_x_image (ximg); -#endif image_clear_image (f, img); image_error ("Invalid image size in image `%s'", img->spec); @@ -5613,11 +5760,7 @@ pbm_load (struct frame *f, struct image *img) g = 0; } -#ifdef USE_CAIRO - *dataptr++ = g ? fga32 : bga32; -#else - XPutPixel (ximg, x, y, g ? fg : bg); -#endif + PUT_PIXEL (ximg, x, y, g ? fg : bg); } } else @@ -5631,11 +5774,7 @@ pbm_load (struct frame *f, struct image *img) if (raw_p && p + expected_size > end) { -#ifdef USE_CAIRO - cairo_surface_destroy (surface); -#else image_destroy_x_image (ximg); -#endif image_clear_image (f, img); image_error ("Invalid image size in image `%s'", img->spec); goto error; @@ -5665,28 +5804,17 @@ pbm_load (struct frame *f, struct image *img) if (r < 0 || g < 0 || b < 0) { -#ifdef USE_CAIRO - cairo_surface_destroy (surface); -#else image_destroy_x_image (ximg); -#endif image_error ("Invalid pixel value in image `%s'", img->spec); goto error; } -#ifdef USE_CAIRO - r = (double) r * 255 / max_color_idx; - g = (double) g * 255 / max_color_idx; - b = (double) b * 255 / max_color_idx; - *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b; -#else /* RGB values are now in the range 0..max_color_idx. Scale this to the range 0..0xffff supported by X. */ r = (double) r * 65535 / max_color_idx; g = (double) g * 65535 / max_color_idx; b = (double) b * 65535 / max_color_idx; - XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); -#endif + PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b)); } } @@ -5702,16 +5830,12 @@ pbm_load (struct frame *f, struct image *img) /* Maybe fill in the background field while we have ximg handy. */ -#ifdef USE_CAIRO - set_cairo_image_surface (img, surface); -#else if (NILP (image_spec_value (img->spec, QCbackground, NULL))) /* Casting avoids a GCC warning. */ IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg); /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); -#endif /* X and W32 versions did it here, MAC version above. ++kfs img->width = width; @@ -6028,13 +6152,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) bool transparent_p; struct png_memory_storage tbr; /* Data to be read */ ptrdiff_t nbytes; - -#ifdef USE_CAIRO - cairo_surface_t *surface; - uint32_t *dataptr; -#else Emacs_Pix_Container ximg, mask_img = NULL; -#endif /* Find out what file to load. */ specified_file = image_spec_value (img->spec, QCfile, NULL); @@ -6152,12 +6270,10 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) goto error; } -#ifndef USE_CAIRO /* Create the X image and pixmap now, so that the work below can be omitted if the image is too large for X. */ if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) goto error; -#endif /* If image contains simply transparency data, we prefer to construct a clipping mask. */ @@ -6249,10 +6365,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) c->fp = NULL; } -#ifdef USE_CAIRO - surface = create_cairo_image_surface (width, height); - dataptr = (uint32_t *) cairo_image_surface_get_data (surface); -#else /* Create an image and pixmap serving as mask if the PNG image contains an alpha channel. */ if (channels == 4 @@ -6264,7 +6376,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP); goto error; } -#endif /* Fill the X image and mask from PNG data. */ init_color_table (); @@ -6277,18 +6388,10 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) { int r, g, b; -#ifdef USE_CAIRO - int a = 0xff; - r = *p++; - g = *p++; - b = *p++; - if (channels == 4) a = *p++; - *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b; -#else r = *p++ << 8; g = *p++ << 8; b = *p++ << 8; - XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); + PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b)); /* An alpha channel, aka mask channel, associates variable transparency with an image. Where other image formats support binary transparency---fully transparent or fully @@ -6308,10 +6411,9 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) if (channels == 4) { if (mask_img) - XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN); + PUT_PIXEL (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN); ++p; } -#endif } } @@ -6322,7 +6424,14 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) png_color_16 *bg; if (png_get_bKGD (png_ptr, info_ptr, &bg)) { +#ifndef USE_CAIRO img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); +#else /* USE_CAIRO */ + char color_name[30]; + sprintf (color_name, "#%04x%04x%04x", bg->red, bg->green, bg->blue); + img->background + = image_alloc_image_color (f, img, build_string (color_name), 0); +#endif /* USE_CAIRO */ img->background_valid = 1; } } @@ -6341,9 +6450,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) img->width = width; img->height = height; -#ifdef USE_CAIRO - set_cairo_image_surface (img, surface); -#else /* Maybe fill in the background field while we have ximg handy. Casting avoids a GCC warning. */ IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg); @@ -6360,7 +6466,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) image_put_x_image (f, img, mask_img, 1); } -#endif return 1; } @@ -6774,10 +6879,8 @@ jpeg_load_body (struct frame *f, struct image *img, int row_stride, x, y; int width, height; int i, ir, ig, ib; -#ifndef USE_CAIRO unsigned long *colors; Emacs_Pix_Container ximg = NULL; -#endif /* Open the JPEG file. */ specified_file = image_spec_value (img->spec, QCfile, NULL); @@ -6837,9 +6940,7 @@ jpeg_load_body (struct frame *f, struct image *img, jpeg_destroy_decompress (&mgr->cinfo); /* If we already have an XImage, free that. */ -#ifndef USE_CAIRO image_destroy_x_image (ximg); -#endif /* Free pixmap and colors. */ image_clear_image (f, img); return 0; @@ -6870,23 +6971,19 @@ jpeg_load_body (struct frame *f, struct image *img, sys_longjmp (mgr->setjmp_buffer, 1); } -#ifndef USE_CAIRO /* Create X image and pixmap. */ if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) { mgr->failure_code = MY_JPEG_CANNOT_CREATE_X; sys_longjmp (mgr->setjmp_buffer, 1); } -#endif /* Allocate colors. When color quantization is used, mgr->cinfo.actual_number_of_colors has been set with the number of colors generated, and mgr->cinfo.colormap is a two-dimensional array of color indices in the range 0..mgr->cinfo.actual_number_of_colors. No more than 255 colors will be generated. */ -#ifndef USE_CAIRO USE_SAFE_ALLOCA; -#endif { if (mgr->cinfo.out_color_components > 2) ir = 0, ig = 1, ib = 2; @@ -6895,7 +6992,6 @@ jpeg_load_body (struct frame *f, struct image *img, else ir = 0, ig = 0, ib = 0; -#ifndef USE_CAIRO /* Use the color table mechanism because it handles colors that cannot be allocated nicely. Such colors will be replaced with a default color, and we don't have to care about which colors @@ -6912,7 +7008,6 @@ jpeg_load_body (struct frame *f, struct image *img, int b = mgr->cinfo.colormap[ib][i] << 8; colors[i] = lookup_rgb_color (f, r, g, b); } -#endif #ifdef COLOR_TABLE_SUPPORT /* Remember those colors actually allocated. */ @@ -6925,36 +7020,12 @@ jpeg_load_body (struct frame *f, struct image *img, row_stride = width * mgr->cinfo.output_components; buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo, JPOOL_IMAGE, row_stride, 1); -#ifdef USE_CAIRO - { - cairo_surface_t *surface = create_cairo_image_surface (width, height); - uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface); - int r, g, b; - - for (y = 0; y < height; ++y) - { - jpeg_read_scanlines (&mgr->cinfo, buffer, 1); - - for (x = 0; x < width; ++x) - { - i = buffer[0][x]; - r = mgr->cinfo.colormap[ir][i]; - g = mgr->cinfo.colormap[ig][i]; - b = mgr->cinfo.colormap[ib][i]; - *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b; - } - } - - set_cairo_image_surface (img, surface); - } -#else for (y = 0; y < height; ++y) { jpeg_read_scanlines (&mgr->cinfo, buffer, 1); for (x = 0; x < mgr->cinfo.output_width; ++x) - XPutPixel (ximg, x, y, colors[buffer[0][x]]); + PUT_PIXEL (ximg, x, y, colors[buffer[0][x]]); } -#endif /* Clean up. */ jpeg_finish_decompress (&mgr->cinfo); @@ -6962,7 +7033,6 @@ jpeg_load_body (struct frame *f, struct image *img, if (fp) fclose (fp); -#ifndef USE_CAIRO /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) /* Casting avoids a GCC warning. */ @@ -6971,7 +7041,6 @@ jpeg_load_body (struct frame *f, struct image *img, /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); SAFE_FREE (); -#endif return 1; } @@ -7384,28 +7453,6 @@ tiff_load (struct frame *f, struct image *img) return 0; } -#ifdef USE_CAIRO - { - cairo_surface_t *surface = create_cairo_image_surface (width, height); - uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface); - - for (y = 0; y < height; ++y) - { - uint32 *row = buf + (height - 1 - y) * width; - for (x = 0; x < width; ++x) - { - uint32 abgr = row[x]; - int r = TIFFGetR (abgr); - int g = TIFFGetG (abgr); - int b = TIFFGetB (abgr); - int a = TIFFGetA (abgr); - *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b; - } - } - - set_cairo_image_surface (img, surface); - } -#else /* Initialize the color table. */ init_color_table (); @@ -7420,7 +7467,7 @@ tiff_load (struct frame *f, struct image *img) int r = TIFFGetR (abgr) << 8; int g = TIFFGetG (abgr) << 8; int b = TIFFGetB (abgr) << 8; - XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b)); + PUT_PIXEL (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b)); } } @@ -7441,8 +7488,6 @@ tiff_load (struct frame *f, struct image *img) /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); -#endif /* ! USE_CAIRO */ - xfree (buf); return 1; } @@ -7819,26 +7864,6 @@ gif_load (struct frame *f, struct image *img) } } -#ifdef USE_CAIRO - cairo_surface_t *surface = create_cairo_image_surface (width, height); - uint32_t *data32 = (uint32_t *) cairo_image_surface_get_data (surface); - if (STRINGP (specified_bg)) - { - Emacs_Color color; - if (FRAME_TERMINAL (f)->defined_color_hook - (f, SSDATA (specified_bg), &color, false, false)) - { - uint32_t *dataptr = data32; - int r = color.red/256; - int g = color.green/256; - int b = color.blue/256; - - for (y = 0; y < height; ++y) - for (x = 0; x < width; ++x) - *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b; - } - } -#else /* Create the X image and pixmap. */ Emacs_Pix_Container ximg; if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) @@ -7851,22 +7876,31 @@ gif_load (struct frame *f, struct image *img) Full animated GIF support requires more here (see the gif89 spec, disposal methods). Let's simply assume that the part not covered by a sub-image is in the frame's background color. */ + unsigned long frame_bg; +#ifndef USE_CAIRO + frame_bg = FRAME_BACKGROUND_PIXEL (f); +#else /* USE_CAIRO */ + { + Emacs_Color color; + FRAME_TERMINAL (f)->query_frame_background_color (f, &color); + frame_bg = lookup_rgb_color (f, color.red, color.green, color.blue); + } +#endif /* USE_CAIRO */ for (y = 0; y < img->corners[TOP_CORNER]; ++y) for (x = 0; x < width; ++x) - XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); + PUT_PIXEL (ximg, x, y, frame_bg); for (y = img->corners[BOT_CORNER]; y < height; ++y) for (x = 0; x < width; ++x) - XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); + PUT_PIXEL (ximg, x, y, frame_bg); for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y) { for (x = 0; x < img->corners[LEFT_CORNER]; ++x) - XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); + PUT_PIXEL (ximg, x, y, frame_bg); for (x = img->corners[RIGHT_CORNER]; x < width; ++x) - XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); + PUT_PIXEL (ximg, x, y, frame_bg); } -#endif /* Read the GIF image into the X image. */ @@ -7877,12 +7911,17 @@ gif_load (struct frame *f, struct image *img) init_color_table (); -#ifndef USE_CAIRO unsigned long bgcolor UNINIT; if (STRINGP (specified_bg)) - bgcolor = image_alloc_image_color (f, img, specified_bg, - FRAME_BACKGROUND_PIXEL (f)); + { + bgcolor = image_alloc_image_color (f, img, specified_bg, + FRAME_BACKGROUND_PIXEL (f)); +#ifdef USE_CAIRO + Emacs_Color color = {.pixel = bgcolor}; + FRAME_TERMINAL (f)->query_colors (f, &color, 1); + bgcolor = lookup_rgb_color (f, color.red, color.green, color.blue); #endif + } for (j = 0; j <= idx; ++j) { @@ -7930,7 +7969,6 @@ gif_load (struct frame *f, struct image *img) if (!gif_color_map) gif_color_map = gif->SColorMap; -#ifndef USE_CAIRO /* Allocate subimage colors. */ unsigned long pixel_colors[256] = { 0, }; @@ -7939,7 +7977,7 @@ gif_load (struct frame *f, struct image *img) { if (transparency_color_index == i) pixel_colors[i] = STRINGP (specified_bg) - ? bgcolor : FRAME_BACKGROUND_PIXEL (f); + ? bgcolor : frame_bg; else { int r = gif_color_map->Colors[i].Red << 8; @@ -7948,7 +7986,6 @@ gif_load (struct frame *f, struct image *img) pixel_colors[i] = lookup_rgb_color (f, r, g, b); } } -#endif /* Apply the pixel values. */ if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace) @@ -7967,21 +8004,9 @@ gif_load (struct frame *f, struct image *img) int c = raster[y * subimg_width + x]; if (transparency_color_index != c || disposal != 1) { -#ifdef USE_CAIRO - uint32_t *dataptr = - (data32 + ((row + subimg_top) * width - + x + subimg_left)); - int r = gif_color_map->Colors[c].Red; - int g = gif_color_map->Colors[c].Green; - int b = gif_color_map->Colors[c].Blue; - - if (transparency_color_index != c) - *dataptr = (0xffu << 24) | (r << 16) | (g << 8) | b; -#else - XPutPixel (ximg, x + subimg_left, row + subimg_top, + PUT_PIXEL (ximg, x + subimg_left, row + subimg_top, pixel_colors[c]); -#endif - } + } } } } @@ -7993,19 +8018,8 @@ gif_load (struct frame *f, struct image *img) int c = raster[y * subimg_width + x]; if (transparency_color_index != c || disposal != 1) { -#ifdef USE_CAIRO - uint32_t *dataptr = - (data32 + ((y + subimg_top) * width - + x + subimg_left)); - int r = gif_color_map->Colors[c].Red; - int g = gif_color_map->Colors[c].Green; - int b = gif_color_map->Colors[c].Blue; - if (transparency_color_index != c) - *dataptr = (0xffu << 24) | (r << 16) | (g << 8) | b; -#else - XPutPixel (ximg, x + subimg_left, y + subimg_top, + PUT_PIXEL (ximg, x + subimg_left, y + subimg_top, pixel_colors[c]); -#endif } } } @@ -8064,9 +8078,6 @@ gif_load (struct frame *f, struct image *img) #endif } -#ifdef USE_CAIRO - set_cairo_image_surface (img, surface); -#else /* Maybe fill in the background field while we have ximg handy. */ if (NILP (image_spec_value (img->spec, QCbackground, NULL))) /* Casting avoids a GCC warning. */ @@ -8074,7 +8085,6 @@ gif_load (struct frame *f, struct image *img) /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); -#endif return 1; } @@ -8453,9 +8463,7 @@ imagemagick_load_image (struct frame *f, struct image *img, int width, height; size_t image_width, image_height; MagickBooleanType status; -#ifndef USE_CAIRO Emacs_Pix_Container ximg; -#endif int x, y; MagickWand *image_wand; PixelIterator *iterator; @@ -8469,9 +8477,6 @@ imagemagick_load_image (struct frame *f, struct image *img, double rotation; char hint_buffer[MaxTextExtent]; char *filename_hint = NULL; -#ifdef USE_CAIRO - cairo_surface_t *surface; -#endif /* Initialize the ImageMagick environment. */ static bool imagemagick_initialized; @@ -8685,11 +8690,6 @@ imagemagick_load_image (struct frame *f, struct image *img, method is also well tested. Some aspects of this method are ad-hoc and needs to be more researched. */ void *dataptr; -#ifdef USE_CAIRO - surface = create_cairo_image_surface (width, height); - const char *exportdepth = "BGRA"; - dataptr = cairo_image_surface_get_data (surface); -#else int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/ const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/ /* Try to create a x pixmap to hold the imagemagick pixmap. */ @@ -8703,7 +8703,6 @@ imagemagick_load_image (struct frame *f, struct image *img, goto imagemagick_error; } dataptr = ximg->data; -#endif /* not USE_CAIRO */ /* Oddly, the below code doesn't seem to work:*/ /* switch(ximg->bitmap_unit){ */ @@ -8734,11 +8733,6 @@ imagemagick_load_image (struct frame *f, struct image *img, size_t image_height; double quantum_range = QuantumRange; MagickRealType color_scale = 65535.0 / quantum_range; -#ifdef USE_CAIRO - surface = create_cairo_image_surface (width, height); - uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface); - color_scale /= 256; -#else /* Try to create a x pixmap to hold the imagemagick pixmap. */ if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) @@ -8749,7 +8743,6 @@ imagemagick_load_image (struct frame *f, struct image *img, image_error ("Imagemagick X bitmap allocation failure"); goto imagemagick_error; } -#endif /* Copy imagemagick image to x with primitive yet robust pixel pusher loop. This has been tested a lot with many different @@ -8762,9 +8755,7 @@ imagemagick_load_image (struct frame *f, struct image *img, #ifdef COLOR_TABLE_SUPPORT free_color_table (); #endif -#ifndef USE_CAIRO image_destroy_x_image (ximg); -#endif image_error ("Imagemagick pixel iterator creation failed"); goto imagemagick_error; } @@ -8780,27 +8771,16 @@ imagemagick_load_image (struct frame *f, struct image *img, for (x = 0; x < xlim; x++) { PixelGetMagickColor (pixels[x], &pixel); -#ifdef USE_CAIRO - dataptr[width * y + x] = - lookup_rgb_color (f, - color_scale * pixel.red, - color_scale * pixel.green, - color_scale * pixel.blue); -#else - XPutPixel (ximg, x, y, + PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, color_scale * pixel.red, color_scale * pixel.green, color_scale * pixel.blue)); -#endif } } DestroyPixelIterator (iterator); } -#ifdef USE_CAIRO - set_cairo_image_surface (img, surface); -#else #ifdef COLOR_TABLE_SUPPORT /* Remember colors allocated for this image. */ img->colors = colors_in_color_table (&img->ncolors); @@ -8812,7 +8792,6 @@ imagemagick_load_image (struct frame *f, struct image *img, /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); -#endif /* Final cleanup. image_wand should be the only resource left. */ DestroyMagickWand (image_wand); @@ -9257,33 +9236,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents, eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); { -#ifdef USE_CAIRO - cairo_surface_t *surface = create_cairo_image_surface (width, height); - uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface); - uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f); - - for (int y = 0; y < height; ++y) - { - const guchar *iconptr = pixels + y * rowstride; - - for (int x = 0; x < width; ++x) - { - if (iconptr[3] == 0) - *dataptr = bgcolor; - else - *dataptr = (iconptr[0] << 16) - | (iconptr[1] << 8) - | iconptr[2] - | (iconptr[3] << 24); - - iconptr += 4; - ++dataptr; - } - } - - set_cairo_image_surface (img, surface); - g_object_unref (pixbuf); -#else /* Try to create a x pixmap to hold the svg pixmap. */ Emacs_Pix_Container ximg; if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) @@ -9333,7 +9285,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, blue = ((blue * opacity) + (background.blue * ((1 << 8) - opacity))); - XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue)); + PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red, green, blue)); } pixels += rowstride - 4 * width; @@ -9356,7 +9308,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents, /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); -#endif /* ! USE_CAIRO */ } return 1; @@ -9379,9 +9330,9 @@ svg_load_image (struct frame *f, struct image *img, char *contents, Ghostscript ***********************************************************************/ -#ifdef HAVE_X_WINDOWS +#if defined HAVE_X_WINDOWS && !defined USE_CAIRO #define HAVE_GHOSTSCRIPT 1 -#endif /* HAVE_X_WINDOWS */ +#endif /* HAVE_X_WINDOWS && !USE_CAIRO */ #ifdef HAVE_GHOSTSCRIPT diff --git a/src/xterm.c b/src/xterm.c index 559d1b48924..03458cb03f6 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -7794,12 +7794,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, reply with "Next" if we received "Page", but we currently never do because we are interested in images, only, which should have 1 page. */ - Pixmap pixmap = (Pixmap) event->xclient.data.l[1]; f = x_window_to_frame (dpyinfo, event->xclient.window); if (!f) goto OTHER; +#ifndef USE_CAIRO + Pixmap pixmap = (Pixmap) event->xclient.data.l[1]; x_kill_gs_process (pixmap, f); expose_frame (f, 0, 0, 0, 0); +#endif /* !USE_CAIRO */ goto done; } @@ -12154,7 +12156,15 @@ x_check_font (struct frame *f, struct font *font) static void x_free_pixmap (struct frame *f, Emacs_Pixmap pixmap) { +#ifdef USE_CAIRO + if (pixmap) + { + xfree (pixmap->data); + xfree (pixmap); + } +#else XFreePixmap (FRAME_X_DISPLAY (f), pixmap); +#endif } |