summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>2019-05-29 17:58:04 +0900
committerYAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>2019-05-29 17:58:43 +0900
commitc89900ebd79d8c4bf5fd5550de053f379abd60ef (patch)
tree73e5d59325043b25306bad2670c0a55b8ef172c0
parent09dce0fd391571ab1b580d2818689d596a8b99de (diff)
downloademacs-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.h21
-rw-r--r--src/image.c957
-rw-r--r--src/xterm.c12
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
}