aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2019-05-29 17:58:04 +0900
committerYAMAMOTO Mitsuharu2019-05-29 17:58:43 +0900
commitc89900ebd79d8c4bf5fd5550de053f379abd60ef (patch)
tree73e5d59325043b25306bad2670c0a55b8ef172c0 /src/image.c
parent09dce0fd391571ab1b580d2818689d596a8b99de (diff)
downloademacs-c89900ebd79d8c4bf5fd5550de053f379abd60ef.tar.gz
emacs-c89900ebd79d8c4bf5fd5550de053f379abd60ef.zip
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.
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c957
1 files changed, 454 insertions, 503 deletions
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/>. */
30 30
31#include <setjmp.h> 31#include <setjmp.h>
32 32
33#include <stdint.h>
33#include <c-ctype.h> 34#include <c-ctype.h>
34#include <flexmember.h> 35#include <flexmember.h>
35 36
@@ -67,13 +68,37 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
67 68
68#ifdef HAVE_X_WINDOWS 69#ifdef HAVE_X_WINDOWS
69typedef struct x_bitmap_record Bitmap_Record; 70typedef struct x_bitmap_record Bitmap_Record;
71#ifndef USE_CAIRO
70#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) 72#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
73#define PUT_PIXEL XPutPixel
71#define NO_PIXMAP None 74#define NO_PIXMAP None
72 75
73#define PIX_MASK_RETAIN 0 76#define PIX_MASK_RETAIN 0
74#define PIX_MASK_DRAW 1 77#define PIX_MASK_DRAW 1
78#endif /* !USE_CAIRO */
75#endif /* HAVE_X_WINDOWS */ 79#endif /* HAVE_X_WINDOWS */
76 80
81#ifdef USE_CAIRO
82#define GET_PIXEL image_pix_context_get_pixel
83#define PUT_PIXEL image_pix_container_put_pixel
84#define NO_PIXMAP 0
85
86#define PIX_MASK_RETAIN 0
87#define PIX_MASK_DRAW 255
88
89#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
90#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
91#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
92#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
93#define BLUE_FROM_ULONG(color) ((color) & 0xff)
94#define RED16_FROM_ULONG(color) (RED_FROM_ULONG (color) * 0x101)
95#define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG (color) * 0x101)
96#define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG (color) * 0x101)
97
98static unsigned long image_alloc_image_color (struct frame *, struct image *,
99 Lisp_Object, unsigned long);
100#endif /* USE_CAIRO */
101
77#ifdef HAVE_NTGUI 102#ifdef HAVE_NTGUI
78 103
79/* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */ 104/* 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;
84 109
85typedef struct w32_bitmap_record Bitmap_Record; 110typedef struct w32_bitmap_record Bitmap_Record;
86#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y) 111#define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
112#define PUT_PIXEL XPutPixel
87#define NO_PIXMAP 0 113#define NO_PIXMAP 0
88 114
89#define PIX_MASK_RETAIN 0 115#define PIX_MASK_RETAIN 0
@@ -95,6 +121,7 @@ typedef struct w32_bitmap_record Bitmap_Record;
95typedef struct ns_bitmap_record Bitmap_Record; 121typedef struct ns_bitmap_record Bitmap_Record;
96 122
97#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) 123#define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
124#define PUT_PIXEL XPutPixel
98#define NO_PIXMAP 0 125#define NO_PIXMAP 0
99 126
100#define PIX_MASK_RETAIN 0 127#define PIX_MASK_RETAIN 0
@@ -118,16 +145,109 @@ static void free_color_table (void);
118static unsigned long *colors_in_color_table (int *n); 145static unsigned long *colors_in_color_table (int *n);
119#endif 146#endif
120 147
121/* Code to deal with bitmaps. Bitmaps are referenced by their bitmap 148#ifdef USE_CAIRO
122 id, which is just an int that this section returns. Bitmaps are
123 reference counted so they can be shared among frames.
124 149
125 Bitmap indices are guaranteed to be > 0, so a negative number can 150static Emacs_Pix_Container
126 be used to indicate no bitmap. 151image_create_pix_container (struct frame *f, unsigned int width,
152 unsigned int height, unsigned int depth)
153{
154 Emacs_Pix_Container pimg;
127 155
128 If you use image_create_bitmap_from_data, then you must keep track 156 pimg = xmalloc (sizeof (*pimg));
129 of the bitmaps yourself. That is, creating a bitmap from the same 157 pimg->width = width;
130 data more than once will not be caught. */ 158 pimg->height = height;
159 pimg->bits_per_pixel = depth == 1 ? 8 : 32;
160 pimg->bytes_per_line = cairo_format_stride_for_width ((depth == 1
161 ? CAIRO_FORMAT_A8
162 : CAIRO_FORMAT_RGB24),
163 width);
164 pimg->data = xmalloc (pimg->bytes_per_line * height);
165
166 return pimg;
167}
168
169static void
170image_pix_container_put_pixel (Emacs_Pix_Container image,
171 int x, int y, unsigned long pixel)
172{
173 if (image->bits_per_pixel == 32)
174 ((uint32_t *)(image->data + y * image->bytes_per_line))[x] = pixel;
175 else
176 ((uint8_t *)(image->data + y * image->bytes_per_line))[x] = pixel;
177}
178
179static unsigned long
180image_pix_context_get_pixel (Emacs_Pix_Context image, int x, int y)
181{
182 if (image->bits_per_pixel == 32)
183 return ((uint32_t *)(image->data + y * image->bytes_per_line))[x];
184 else
185 return ((uint8_t *)(image->data + y * image->bytes_per_line))[x];
186}
187
188static Emacs_Pix_Container
189image_pix_container_create_from_bitmap_data (struct frame *f,
190 char *data, unsigned int width,
191 unsigned int height,
192 unsigned long fg,
193 unsigned long bg)
194{
195 Emacs_Pix_Container pimg = image_create_pix_container (f, width, height, 0);
196 int bytes_per_line = (width + (CHAR_BIT - 1)) / CHAR_BIT;
197
198 for (int y = 0; y < height; y++)
199 {
200 for (int x = 0; x < width; x++)
201 PUT_PIXEL (pimg, x, y,
202 (data[x / CHAR_BIT] >> (x % CHAR_BIT)) & 1 ? fg : bg);
203 data += bytes_per_line;
204 }
205
206 return pimg;
207}
208
209static cairo_surface_t *
210cr_create_cr_surface_from_image (struct frame *f, struct image *img)
211{
212 Emacs_Pix_Container pimg = img->pixmap;
213 cairo_surface_t *surface;
214
215 if (img->mask)
216 {
217 int x, y;
218
219 for (y = 0; y < pimg->height; y++)
220 for (x = 0; x < pimg->width; x++)
221 {
222 unsigned long color, alpha;
223 int r, g, b;
224
225 color = GET_PIXEL (pimg, x, y);
226 alpha = GET_PIXEL (img->mask, x, y);
227 r = (RED_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
228 g = (GREEN_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
229 b = (BLUE_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
230 PUT_PIXEL (pimg, x, y, ARGB_TO_ULONG (alpha, r, g, b));
231 }
232 xfree (img->mask->data);
233 img->mask->data = NULL;
234 }
235 block_input ();
236 surface = cairo_image_surface_create_for_data ((unsigned char *) pimg->data,
237 (img->mask
238 ? CAIRO_FORMAT_ARGB32
239 : CAIRO_FORMAT_RGB24),
240 pimg->width, pimg->height,
241 pimg->bytes_per_line);
242 static cairo_user_data_key_t key;
243 cairo_surface_set_user_data (surface, &key, pimg->data, xfree);
244 unblock_input ();
245 pimg->data = NULL;
246
247 return surface;
248}
249
250#endif /* USE_CAIRO */
131 251
132#ifdef HAVE_NS 252#ifdef HAVE_NS
133/* Use with images created by ns_image_for_XPM. */ 253/* 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)
146} 266}
147#endif /* HAVE_NS */ 267#endif /* HAVE_NS */
148 268
269/* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
270 id, which is just an int that this section returns. Bitmaps are
271 reference counted so they can be shared among frames.
272
273 Bitmap indices are guaranteed to be > 0, so a negative number can
274 be used to indicate no bitmap.
275
276 If you use image_create_bitmap_from_data, then you must keep track
277 of the bitmaps yourself. That is, creating a bitmap from the same
278 data more than once will not be caught. */
149 279
150/* Functions to access the contents of a bitmap, given an id. */ 280/* Functions to access the contents of a bitmap, given an id. */
151 281
@@ -433,16 +563,17 @@ static void image_unget_x_image (struct image *, bool, Emacs_Pix_Container);
433 563
434#ifdef HAVE_X_WINDOWS 564#ifdef HAVE_X_WINDOWS
435 565
566#ifndef USE_CAIRO
436static void image_sync_to_pixmaps (struct frame *, struct image *); 567static void image_sync_to_pixmaps (struct frame *, struct image *);
568#endif /* !USE_CAIRO */
437 569
438/* Useful functions defined in the section 570/* We are working on X-specific data structures here even with cairo.
439 `Image type independent image structures' below. */ 571 So we use X-specific versions of image construction/destruction
440 572 functions and inline the specific case of four_corners_best. */
441static unsigned long four_corners_best (XImage *ximg,
442 int *corners,
443 unsigned long width,
444 unsigned long height);
445 573
574static bool x_create_x_image_and_pixmap (struct frame *, int, int, int,
575 XImage **, Pixmap *);
576static void x_destroy_x_image (XImage *);
446 577
447/* Create a mask of a bitmap. Note is this not a perfect mask. 578/* Create a mask of a bitmap. Note is this not a perfect mask.
448 It's nicer with some borders in this context */ 579 It's nicer with some borders in this context */
@@ -454,7 +585,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
454 XImage *ximg, *mask_img; 585 XImage *ximg, *mask_img;
455 unsigned long width, height; 586 unsigned long width, height;
456 bool result; 587 bool result;
457 unsigned long bg; 588 unsigned long bg UNINIT;
458 unsigned long x, y, xp, xm, yp, ym; 589 unsigned long x, y, xp, xm, yp, ym;
459 GC gc; 590 GC gc;
460 591
@@ -477,8 +608,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
477 return; 608 return;
478 } 609 }
479 610
480 result = image_create_x_image_and_pixmap_1 (f, width, height, 1, 611 result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
481 &mask_img, &mask, NULL);
482 612
483 unblock_input (); 613 unblock_input ();
484 if (!result) 614 if (!result)
@@ -487,7 +617,23 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
487 return; 617 return;
488 } 618 }
489 619
490 bg = four_corners_best (ximg, NULL, width, height); 620 unsigned long corner_pixels[4];
621 corner_pixels[0] = XGetPixel (ximg, 0, 0);
622 corner_pixels[1] = XGetPixel (ximg, width - 1, 0);
623 corner_pixels[2] = XGetPixel (ximg, width - 1, height - 1);
624 corner_pixels[3] = XGetPixel (ximg, 0, height - 1);
625 int i, best_count;
626 for (i = best_count = 0; i < 4; ++i)
627 {
628 int j, n;
629
630 for (j = n = 0; j < 4; ++j)
631 if (corner_pixels[i] == corner_pixels[j])
632 ++n;
633
634 if (n > best_count)
635 bg = corner_pixels[i], best_count = n;
636 }
491 637
492 for (y = 0; y < ximg->height; ++y) 638 for (y = 0; y < ximg->height; ++y)
493 { 639 {
@@ -522,7 +668,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
522 dpyinfo->bitmaps[id - 1].mask = mask; 668 dpyinfo->bitmaps[id - 1].mask = mask;
523 669
524 XDestroyImage (ximg); 670 XDestroyImage (ximg);
525 image_destroy_x_image (mask_img); 671 x_destroy_x_image (mask_img);
526} 672}
527 673
528#endif /* HAVE_X_WINDOWS */ 674#endif /* HAVE_X_WINDOWS */
@@ -1015,13 +1161,22 @@ prepare_image_for_display (struct frame *f, struct image *img)
1015 /* We're about to display IMG, so set its timestamp to `now'. */ 1161 /* We're about to display IMG, so set its timestamp to `now'. */
1016 img->timestamp = current_timespec (); 1162 img->timestamp = current_timespec ();
1017 1163
1018#ifndef USE_CAIRO
1019 /* If IMG doesn't have a pixmap yet, load it now, using the image 1164 /* If IMG doesn't have a pixmap yet, load it now, using the image
1020 type dependent loader function. */ 1165 type dependent loader function. */
1021 if (img->pixmap == NO_PIXMAP && !img->load_failed_p) 1166 if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
1022 img->load_failed_p = ! img->type->load (f, img); 1167 img->load_failed_p = ! img->type->load (f, img);
1023 1168
1024#ifdef HAVE_X_WINDOWS 1169#ifdef USE_CAIRO
1170 if (!img->load_failed_p && img->cr_data == NULL)
1171 {
1172 img->cr_data = cr_create_cr_surface_from_image (f, img);
1173 if (img->cr_data == NULL)
1174 {
1175 img->load_failed_p = 1;
1176 img->type->free (f, img);
1177 }
1178 }
1179#elif defined HAVE_X_WINDOWS
1025 if (!img->load_failed_p) 1180 if (!img->load_failed_p)
1026 { 1181 {
1027 block_input (); 1182 block_input ();
@@ -1029,7 +1184,6 @@ prepare_image_for_display (struct frame *f, struct image *img)
1029 unblock_input (); 1184 unblock_input ();
1030 } 1185 }
1031#endif 1186#endif
1032#endif
1033} 1187}
1034 1188
1035 1189
@@ -1076,48 +1230,6 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
1076 return ascent; 1230 return ascent;
1077} 1231}
1078 1232
1079#ifdef USE_CAIRO
1080static uint32_t
1081emacs_color_to_argb32 (Emacs_Color *ec)
1082{
1083 return ((0xffu << 24) | ((ec->red / 256) << 16)
1084 | ((ec->green / 256) << 8) | (ec->blue / 256));
1085}
1086
1087static uint32_t
1088get_spec_bg_or_alpha_as_argb (struct image *img,
1089 struct frame *f)
1090{
1091 uint32_t bgcolor = 0;
1092 Emacs_Color xbgcolor;
1093 Lisp_Object bg = image_spec_value (img->spec, QCbackground, NULL);
1094
1095 if (STRINGP (bg) && x_parse_color (f, SSDATA (bg), &xbgcolor))
1096 bgcolor = emacs_color_to_argb32 (&xbgcolor);
1097
1098 return bgcolor;
1099}
1100
1101static cairo_surface_t *
1102create_cairo_image_surface (int width, int height)
1103{
1104 cairo_format_t format = CAIRO_FORMAT_ARGB32;
1105 eassert (cairo_format_stride_for_width (format, width) == width * 4);
1106
1107 return cairo_image_surface_create (format, width, height);
1108}
1109
1110static void
1111set_cairo_image_surface (struct image *img, cairo_surface_t *surface)
1112{
1113 cairo_surface_mark_dirty (surface);
1114 img->width = cairo_image_surface_get_width (surface);
1115 img->height = cairo_image_surface_get_height (surface);
1116 img->cr_data = surface;
1117 img->pixmap = 0;
1118}
1119#endif
1120
1121 1233
1122 1234
1123/* Image background colors. */ 1235/* Image background colors. */
@@ -1184,7 +1296,19 @@ image_background (struct image *img, struct frame *f, Emacs_Pix_Context pimg)
1184 if (free_pimg) 1296 if (free_pimg)
1185 pimg = image_get_x_image_or_dc (f, img, 0, &prev); 1297 pimg = image_get_x_image_or_dc (f, img, 0, &prev);
1186 1298
1187 img->background = four_corners_best (pimg, img->corners, img->width, img->height); 1299 RGB_PIXEL_COLOR bg
1300 = four_corners_best (pimg, img->corners, img->width, img->height);
1301#ifdef USE_CAIRO
1302 {
1303 char color_name[30];
1304 sprintf (color_name, "#%04x%04x%04x",
1305 (unsigned int) RED16_FROM_ULONG (bg),
1306 (unsigned int) GREEN16_FROM_ULONG (bg),
1307 (unsigned int) BLUE16_FROM_ULONG (bg));
1308 bg = image_alloc_image_color (f, img, build_string (color_name), 0);
1309 }
1310#endif
1311 img->background = bg;
1188 1312
1189 if (free_pimg) 1313 if (free_pimg)
1190 image_unget_x_image_or_dc (img, 0, pimg, prev); 1314 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)
1259 /* NOTE (HAVE_NS): background color is NOT an indexed color! */ 1383 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1260 img->background_valid = 0; 1384 img->background_valid = 0;
1261 } 1385 }
1262#ifdef HAVE_X_WINDOWS 1386#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
1263 if (img->ximg) 1387 if (img->ximg)
1264 { 1388 {
1265 image_destroy_x_image (img->ximg); 1389 image_destroy_x_image (img->ximg);
@@ -1277,7 +1401,7 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags)
1277 img->mask = NO_PIXMAP; 1401 img->mask = NO_PIXMAP;
1278 img->background_transparent_valid = 0; 1402 img->background_transparent_valid = 0;
1279 } 1403 }
1280#ifdef HAVE_X_WINDOWS 1404#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
1281 if (img->mask_img) 1405 if (img->mask_img)
1282 { 1406 {
1283 image_destroy_x_image (img->mask_img); 1407 image_destroy_x_image (img->mask_img);
@@ -1290,14 +1414,21 @@ image_clear_image_1 (struct frame *f, struct image *img, int flags)
1290 if ((flags & CLEAR_IMAGE_COLORS) && img->ncolors) 1414 if ((flags & CLEAR_IMAGE_COLORS) && img->ncolors)
1291 { 1415 {
1292 /* W32_TODO: color table support. */ 1416 /* W32_TODO: color table support. */
1293#ifdef HAVE_X_WINDOWS 1417#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
1294 x_free_colors (f, img->colors, img->ncolors); 1418 x_free_colors (f, img->colors, img->ncolors);
1295#endif /* HAVE_X_WINDOWS */ 1419#endif /* HAVE_X_WINDOWS && !USE_CAIRO */
1296 xfree (img->colors); 1420 xfree (img->colors);
1297 img->colors = NULL; 1421 img->colors = NULL;
1298 img->ncolors = 0; 1422 img->ncolors = 0;
1299 } 1423 }
1300 1424
1425#ifdef USE_CAIRO
1426 if (img->cr_data)
1427 {
1428 cairo_surface_destroy ((cairo_surface_t *) img->cr_data);
1429 img->cr_data = NULL;
1430 }
1431#endif /* USE_CAIRO */
1301} 1432}
1302 1433
1303/* Free X resources of image IMG which is used on frame F. */ 1434/* Free X resources of image IMG which is used on frame F. */
@@ -1306,10 +1437,6 @@ static void
1306image_clear_image (struct frame *f, struct image *img) 1437image_clear_image (struct frame *f, struct image *img)
1307{ 1438{
1308 block_input (); 1439 block_input ();
1309#ifdef USE_CAIRO
1310 if (img->cr_data)
1311 cairo_surface_destroy ((cairo_surface_t *)img->cr_data);
1312#endif
1313 image_clear_image_1 (f, img, 1440 image_clear_image_1 (f, img,
1314 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS); 1441 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS);
1315 unblock_input (); 1442 unblock_input ();
@@ -2000,14 +2127,10 @@ mark_image_cache (struct image_cache *c)
2000 X / NS / W32 support code 2127 X / NS / W32 support code
2001 ***********************************************************************/ 2128 ***********************************************************************/
2002 2129
2003/* Return true if XIMG's size WIDTH x HEIGHT doesn't break the 2130#ifdef HAVE_X_WINDOWS
2004 windowing system.
2005 WIDTH and HEIGHT must both be positive.
2006 If XIMG is null, assume it is a bitmap. */
2007static bool 2131static bool
2008image_check_image_size (Emacs_Pix_Container ximg, int width, int height) 2132x_check_image_size (XImage *ximg, int width, int height)
2009{ 2133{
2010#ifdef HAVE_X_WINDOWS
2011 /* Respect Xlib's limits: it cannot deal with images that have more 2134 /* Respect Xlib's limits: it cannot deal with images that have more
2012 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits 2135 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
2013 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */ 2136 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)
2032 } 2155 }
2033 return (width <= (INT_MAX - (bitmap_pad - 1)) / depth 2156 return (width <= (INT_MAX - (bitmap_pad - 1)) / depth
2034 && height <= X_IMAGE_BYTES_MAX / bytes_per_line); 2157 && height <= X_IMAGE_BYTES_MAX / bytes_per_line);
2035#else
2036 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
2037 For now, assume that every image size is allowed on these systems. */
2038 return 1;
2039#endif
2040} 2158}
2041 2159
2042/* Create an Emacs_Pix_Container and a pixmap of size WIDTH x
2043 HEIGHT for use on frame F. Set *PIMG and *PIXMAP to the
2044 Emacs_Pix_Container and Emacs_Pixmap created. Set (*PIMG)->data
2045 to a raster of WIDTH x HEIGHT pixels allocated via xmalloc. Print
2046 error messages via image_error if an error occurs. Value is true
2047 if successful.
2048
2049 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
2050 should indicate the bit depth of the image. */
2051
2052static bool 2160static bool
2053image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int depth, 2161x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
2054 Emacs_Pix_Container *pimg, 2162 XImage **ximg, Pixmap *pixmap)
2055 Emacs_Pixmap *pixmap, Picture *picture)
2056{ 2163{
2057#ifdef HAVE_X_WINDOWS
2058 Display *display = FRAME_X_DISPLAY (f); 2164 Display *display = FRAME_X_DISPLAY (f);
2059 Drawable drawable = FRAME_X_DRAWABLE (f); 2165 Drawable drawable = FRAME_X_DRAWABLE (f);
2060 Screen *screen = FRAME_X_SCREEN (f); 2166 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
2063 2169
2064 if (depth <= 0) 2170 if (depth <= 0)
2065 depth = DefaultDepthOfScreen (screen); 2171 depth = DefaultDepthOfScreen (screen);
2066 *pimg = XCreateImage (display, DefaultVisualOfScreen (screen), 2172 *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
2067 depth, ZPixmap, 0, NULL, width, height, 2173 depth, ZPixmap, 0, NULL, width, height,
2068 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0); 2174 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
2069 if (*pimg == NULL) 2175 if (*ximg == NULL)
2070 { 2176 {
2071 image_error ("Unable to allocate X image"); 2177 image_error ("Unable to allocate X image");
2072 return 0; 2178 return 0;
2073 } 2179 }
2074 2180
2075 if (! image_check_image_size (*pimg, width, height)) 2181 if (! x_check_image_size (*ximg, width, height))
2076 { 2182 {
2077 image_destroy_x_image (*pimg); 2183 x_destroy_x_image (*ximg);
2078 *pimg = NULL; 2184 *ximg = NULL;
2079 image_error ("Image too large (%dx%d)", 2185 image_error ("Image too large (%dx%d)",
2080 make_fixnum (width), make_fixnum (height)); 2186 make_fixnum (width), make_fixnum (height));
2081 return 0; 2187 return 0;
2082 } 2188 }
2083 2189
2084 /* Allocate image raster. */ 2190 /* Allocate image raster. */
2085 (*pimg)->data = xmalloc ((*pimg)->bytes_per_line * height); 2191 (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
2086 2192
2087 /* Allocate a pixmap of the same size. */ 2193 /* Allocate a pixmap of the same size. */
2088 *pixmap = XCreatePixmap (display, drawable, width, height, depth); 2194 *pixmap = XCreatePixmap (display, drawable, width, height, depth);
2089 if (*pixmap == NO_PIXMAP) 2195 if (*pixmap == NO_PIXMAP)
2090 { 2196 {
2091 image_destroy_x_image (*pimg); 2197 x_destroy_x_image (*ximg);
2092 *pimg = NULL; 2198 *ximg = NULL;
2093 image_error ("Unable to create X pixmap"); 2199 image_error ("Unable to create X pixmap");
2094 return 0; 2200 return 0;
2095 } 2201 }
2096 2202
2203 return 1;
2204}
2205
2206static void
2207x_destroy_x_image (XImage *ximg)
2208{
2209 eassert (input_blocked_p ());
2210 if (ximg)
2211 {
2212 xfree (ximg->data);
2213 ximg->data = NULL;
2214 }
2215}
2216
2217#endif /* HAVE_X_WINDOWS */
2218
2219/* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
2220 windowing system.
2221 WIDTH and HEIGHT must both be positive.
2222 If XIMG is null, assume it is a bitmap. */
2223
2224static bool
2225image_check_image_size (Emacs_Pix_Container ximg, int width, int height)
2226{
2227#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
2228 return x_check_image_size (ximg, width, height);
2229#else
2230 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
2231 For now, assume that every image size is allowed on these systems. */
2232 return 1;
2233#endif
2234}
2235
2236/* Create an Emacs_Pix_Container and a pixmap of size WIDTH x
2237 HEIGHT for use on frame F. Set *PIMG and *PIXMAP to the
2238 Emacs_Pix_Container and Emacs_Pixmap created. Set (*PIMG)->data
2239 to a raster of WIDTH x HEIGHT pixels allocated via xmalloc. Print
2240 error messages via image_error if an error occurs. Value is true
2241 if successful.
2242
2243 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
2244 should indicate the bit depth of the image. */
2245
2246static bool
2247image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int depth,
2248 Emacs_Pix_Container *pimg,
2249 Emacs_Pixmap *pixmap, Picture *picture)
2250{
2251#ifdef USE_CAIRO
2252 eassert (input_blocked_p ());
2253
2254 /* Allocate a pixmap of the same size. */
2255 *pixmap = image_create_pix_container (f, width, height, depth);
2256 if (*pixmap == NO_PIXMAP)
2257 {
2258 *pimg = NULL;
2259 image_error ("Unable to create X pixmap", Qnil, Qnil);
2260 return 0;
2261 }
2262
2263 *pimg = *pixmap;
2264 return 1;
2265#elif defined HAVE_X_WINDOWS
2266 if (!x_create_x_image_and_pixmap (f, width, height, depth, pimg, pixmap))
2267 return 0;
2097# ifdef HAVE_XRENDER 2268# ifdef HAVE_XRENDER
2269 Display *display = FRAME_X_DISPLAY (f);
2098 int event_basep, error_basep; 2270 int event_basep, error_basep;
2099 if (picture && XRenderQueryExtension (display, &event_basep, &error_basep)) 2271 if (picture && XRenderQueryExtension (display, &event_basep, &error_basep))
2100 { 2272 {
@@ -2238,14 +2410,14 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
2238static void 2410static void
2239image_destroy_x_image (Emacs_Pix_Container pimg) 2411image_destroy_x_image (Emacs_Pix_Container pimg)
2240{ 2412{
2413#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
2414 x_destroy_x_image (pimg);
2415#else
2241 eassert (input_blocked_p ()); 2416 eassert (input_blocked_p ());
2242 if (pimg) 2417 if (pimg)
2243 { 2418 {
2244#ifdef HAVE_X_WINDOWS 2419#ifdef USE_CAIRO
2245 xfree (pimg->data); 2420#endif /* USE_CAIRO */
2246 pimg->data = NULL;
2247 XDestroyImage (pimg);
2248#endif /* HAVE_X_WINDOWS */
2249#ifdef HAVE_NTGUI 2421#ifdef HAVE_NTGUI
2250 /* Data will be freed by DestroyObject. */ 2422 /* Data will be freed by DestroyObject. */
2251 pimg->data = NULL; 2423 pimg->data = NULL;
@@ -2255,6 +2427,7 @@ image_destroy_x_image (Emacs_Pix_Container pimg)
2255 ns_release_object (pimg); 2427 ns_release_object (pimg);
2256#endif /* HAVE_NS */ 2428#endif /* HAVE_NS */
2257 } 2429 }
2430#endif
2258} 2431}
2259 2432
2260 2433
@@ -2266,7 +2439,9 @@ static void
2266gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg, 2439gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg,
2267 Emacs_Pixmap pixmap, int width, int height) 2440 Emacs_Pixmap pixmap, int width, int height)
2268{ 2441{
2269#ifdef HAVE_X_WINDOWS 2442#ifdef USE_CAIRO
2443 eassert (pimg == pixmap);
2444#elif defined HAVE_X_WINDOWS
2270 GC gc; 2445 GC gc;
2271 2446
2272 eassert (input_blocked_p ()); 2447 eassert (input_blocked_p ());
@@ -2319,7 +2494,7 @@ static void
2319image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg, 2494image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg,
2320 bool mask_p) 2495 bool mask_p)
2321{ 2496{
2322#ifdef HAVE_X_WINDOWS 2497#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
2323 if (!mask_p) 2498 if (!mask_p)
2324 { 2499 {
2325 eassert (img->ximg == NULL); 2500 eassert (img->ximg == NULL);
@@ -2337,7 +2512,7 @@ image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg,
2337#endif 2512#endif
2338} 2513}
2339 2514
2340#ifdef HAVE_X_WINDOWS 2515#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
2341/* Put the X images recorded in IMG on frame F into pixmaps, then free 2516/* Put the X images recorded in IMG on frame F into pixmaps, then free
2342 the X images and their buffers. */ 2517 the X images and their buffers. */
2343 2518
@@ -2391,7 +2566,9 @@ image_unget_x_image_or_dc (struct image *img, bool mask_p,
2391static Emacs_Pix_Container 2566static Emacs_Pix_Container
2392image_get_x_image (struct frame *f, struct image *img, bool mask_p) 2567image_get_x_image (struct frame *f, struct image *img, bool mask_p)
2393{ 2568{
2394#ifdef HAVE_X_WINDOWS 2569#ifdef USE_CAIRO
2570 return !mask_p ? img->pixmap : img->mask;
2571#elif defined HAVE_X_WINDOWS
2395 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img; 2572 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
2396 2573
2397 if (ximg_in_img) 2574 if (ximg_in_img)
@@ -2410,7 +2587,8 @@ image_get_x_image (struct frame *f, struct image *img, bool mask_p)
2410static void 2587static void
2411image_unget_x_image (struct image *img, bool mask_p, Emacs_Pix_Container ximg) 2588image_unget_x_image (struct image *img, bool mask_p, Emacs_Pix_Container ximg)
2412{ 2589{
2413#ifdef HAVE_X_WINDOWS 2590#ifdef USE_CAIRO
2591#elif defined HAVE_X_WINDOWS
2414 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img; 2592 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
2415 2593
2416 if (ximg_in_img) 2594 if (ximg_in_img)
@@ -2869,28 +3047,32 @@ Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
2869 RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg, 3047 RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg,
2870 bool non_default_colors) 3048 bool non_default_colors)
2871{ 3049{
2872#ifdef HAVE_NTGUI 3050#ifdef USE_CAIRO
3051 Emacs_Color fgbg[] = {{.pixel = fg}, {.pixel = bg}};
3052 FRAME_TERMINAL (f)->query_colors (f, fgbg, ARRAYELTS (fgbg));
3053 fg = lookup_rgb_color (f, fgbg[0].red, fgbg[0].green, fgbg[0].blue);
3054 bg = lookup_rgb_color (f, fgbg[1].red, fgbg[1].green, fgbg[1].blue);
3055 img->pixmap
3056 = image_pix_container_create_from_bitmap_data (f, data, img->width,
3057 img->height, fg, bg);
3058#elif defined HAVE_X_WINDOWS
3059 img->pixmap
3060 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
3061 FRAME_X_DRAWABLE (f),
3062 data,
3063 img->width, img->height,
3064 fg, bg,
3065 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
3066#elif defined HAVE_NTGUI
2873 img->pixmap 3067 img->pixmap
2874 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data); 3068 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
2875 3069
2876 /* If colors were specified, transfer the bitmap to a color one. */ 3070 /* If colors were specified, transfer the bitmap to a color one. */
2877 if (non_default_colors) 3071 if (non_default_colors)
2878 convert_mono_to_color_image (f, img, fg, bg); 3072 convert_mono_to_color_image (f, img, fg, bg);
2879 3073#elif defined HAVE_NS
2880#elif defined (HAVE_NS)
2881 img->pixmap = ns_image_from_XBM (data, img->width, img->height, fg, bg); 3074 img->pixmap = ns_image_from_XBM (data, img->width, img->height, fg, bg);
2882 3075#endif
2883#else
2884 img->pixmap =
2885 (image_check_image_size (0, img->width, img->height)
2886 ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
2887 FRAME_X_DRAWABLE (f),
2888 data,
2889 img->width, img->height,
2890 fg, bg,
2891 DefaultDepthOfScreen (FRAME_X_SCREEN (f)))
2892 : NO_PIXMAP);
2893#endif /* !HAVE_NTGUI && !HAVE_NS */
2894} 3076}
2895 3077
2896 3078
@@ -3099,9 +3281,12 @@ xbm_load_image (struct frame *f, struct image *img, char *contents, char *end)
3099 non_default_colors = 1; 3281 non_default_colors = 1;
3100 } 3282 }
3101 3283
3102 Create_Pixmap_From_Bitmap_Data (f, img, data, 3284 if (image_check_image_size (0, img->width, img->height))
3103 foreground, background, 3285 Create_Pixmap_From_Bitmap_Data (f, img, data,
3104 non_default_colors); 3286 foreground, background,
3287 non_default_colors);
3288 else
3289 img->pixmap = NO_PIXMAP;
3105 xfree (data); 3290 xfree (data);
3106 3291
3107 if (img->pixmap == NO_PIXMAP) 3292 if (img->pixmap == NO_PIXMAP)
@@ -3315,7 +3500,7 @@ xbm_load (struct frame *f, struct image *img)
3315#endif /* not HAVE_NTGUI */ 3500#endif /* not HAVE_NTGUI */
3316#endif /* HAVE_XPM */ 3501#endif /* HAVE_XPM */
3317 3502
3318#if defined (HAVE_XPM) || defined (HAVE_NS) 3503#if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS
3319 3504
3320/* Indices of image specification fields in xpm_format, below. */ 3505/* Indices of image specification fields in xpm_format, below. */
3321 3506
@@ -3353,19 +3538,17 @@ static const struct image_keyword xpm_format[XPM_LAST] =
3353 {":background", IMAGE_STRING_OR_NIL_VALUE, 0} 3538 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
3354}; 3539};
3355 3540
3356#ifdef HAVE_X_WINDOWS 3541#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
3357 3542
3358/* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation 3543/* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
3359 functions for allocating image colors. Our own functions handle 3544 functions for allocating image colors. Our own functions handle
3360 color allocation failures more gracefully than the ones on the XPM 3545 color allocation failures more gracefully than the ones on the XPM
3361 lib. */ 3546 lib. */
3362 3547
3363#ifndef USE_CAIRO
3364#if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure 3548#if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3365#define ALLOC_XPM_COLORS 3549#define ALLOC_XPM_COLORS
3366#endif 3550#endif
3367#endif /* USE_CAIRO */ 3551#endif /* HAVE_X_WINDOWS && !USE_CAIRO */
3368#endif /* HAVE_X_WINDOWS */
3369 3552
3370#ifdef ALLOC_XPM_COLORS 3553#ifdef ALLOC_XPM_COLORS
3371 3554
@@ -3614,7 +3797,7 @@ xpm_image_p (Lisp_Object object)
3614 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))); 3797 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
3615} 3798}
3616 3799
3617#endif /* HAVE_XPM || HAVE_NS */ 3800#endif /* HAVE_XPM || USE_CAIRO || HAVE_NS */
3618 3801
3619#if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK 3802#if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
3620ptrdiff_t 3803ptrdiff_t
@@ -3670,7 +3853,7 @@ x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
3670/* Load image IMG which will be displayed on frame F. Value is 3853/* Load image IMG which will be displayed on frame F. Value is
3671 true if successful. */ 3854 true if successful. */
3672 3855
3673#ifdef HAVE_XPM 3856#if defined HAVE_XPM && !defined USE_CAIRO
3674 3857
3675static bool 3858static bool
3676xpm_load (struct frame *f, struct image *img) 3859xpm_load (struct frame *f, struct image *img)
@@ -3838,44 +4021,6 @@ xpm_load (struct frame *f, struct image *img)
3838#endif /* HAVE_NTGUI */ 4021#endif /* HAVE_NTGUI */
3839 } 4022 }
3840 4023
3841#ifdef USE_CAIRO
3842 /* Load very specific Xpm:s. */
3843 if (rc == XpmSuccess
3844 && img->ximg->format == ZPixmap
3845 && img->ximg->bits_per_pixel == 32
3846 && (! img->mask_img || img->mask_img->bits_per_pixel == 1))
3847 {
3848 int width = img->ximg->width;
3849 int height = img->ximg->height;
3850 cairo_surface_t *surface = create_cairo_image_surface (width, height);
3851 int i;
3852 uint32_t *od = (uint32_t *) cairo_image_surface_get_data (surface);
3853 uint32_t *id = (uint32_t *) img->ximg->data;
3854 char *mid = img->mask_img ? img->mask_img->data : 0;
3855 uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
3856
3857 for (i = 0; i < height; ++i)
3858 {
3859 int k;
3860 for (k = 0; k < width; ++k)
3861 {
3862 int idx = i * img->ximg->bytes_per_line/4 + k;
3863 int maskidx = mid ? i * img->mask_img->bytes_per_line + k/8 : 0;
3864 int mask = mid ? mid[maskidx] & (1 << (k % 8)) : 1;
3865
3866 if (mask) od[idx] = id[idx] + 0xff000000; /* ff => full alpha */
3867 else od[idx] = bgcolor;
3868 }
3869 }
3870
3871 set_cairo_image_surface (img, surface);
3872 }
3873 else
3874 {
3875 rc = XpmFileInvalid;
3876 image_clear_image (f, img);
3877 }
3878#else
3879#ifdef HAVE_X_WINDOWS 4024#ifdef HAVE_X_WINDOWS
3880 if (rc == XpmSuccess) 4025 if (rc == XpmSuccess)
3881 { 4026 {
@@ -3901,7 +4046,6 @@ xpm_load (struct frame *f, struct image *img)
3901 } 4046 }
3902 } 4047 }
3903#endif 4048#endif
3904#endif /* ! USE_CAIRO */
3905 4049
3906 if (rc == XpmSuccess) 4050 if (rc == XpmSuccess)
3907 { 4051 {
@@ -4004,9 +4148,9 @@ xpm_load (struct frame *f, struct image *img)
4004 return rc == XpmSuccess; 4148 return rc == XpmSuccess;
4005} 4149}
4006 4150
4007#endif /* HAVE_XPM */ 4151#endif /* HAVE_XPM && !USE_CAIRO */
4008 4152
4009#if defined (HAVE_NS) && !defined (HAVE_XPM) 4153#if defined USE_CAIRO || (defined HAVE_NS && !defined HAVE_XPM)
4010 4154
4011/* XPM support functions for NS where libxpm is not available. 4155/* XPM support functions for NS where libxpm is not available.
4012 Only XPM version 3 (without any extensions) is supported. */ 4156 Only XPM version 3 (without any extensions) is supported. */
@@ -4346,7 +4490,9 @@ xpm_load_image (struct frame *f,
4346 color_val = Qt; 4490 color_val = Qt;
4347 else if (FRAME_TERMINAL (f)->defined_color_hook 4491 else if (FRAME_TERMINAL (f)->defined_color_hook
4348 (f, SSDATA (XCDR (specified_color)), &cdef, false, false)) 4492 (f, SSDATA (XCDR (specified_color)), &cdef, false, false))
4349 color_val = make_fixnum (cdef.pixel); 4493 color_val
4494 = make_fixnum (lookup_rgb_color (f, cdef.red, cdef.green,
4495 cdef.blue));
4350 } 4496 }
4351 } 4497 }
4352 if (NILP (color_val) && max_key > 0) 4498 if (NILP (color_val) && max_key > 0)
@@ -4355,7 +4501,8 @@ xpm_load_image (struct frame *f,
4355 color_val = Qt; 4501 color_val = Qt;
4356 else if (FRAME_TERMINAL (f)->defined_color_hook 4502 else if (FRAME_TERMINAL (f)->defined_color_hook
4357 (f, max_color, &cdef, false, false)) 4503 (f, max_color, &cdef, false, false))
4358 color_val = make_fixnum (cdef.pixel); 4504 color_val = make_fixnum (lookup_rgb_color (f, cdef.red, cdef.green,
4505 cdef.blue));
4359 } 4506 }
4360 if (!NILP (color_val)) 4507 if (!NILP (color_val))
4361 (*put_color_table) (color_table, beg, chars_per_pixel, color_val); 4508 (*put_color_table) (color_table, beg, chars_per_pixel, color_val);
@@ -4363,6 +4510,14 @@ xpm_load_image (struct frame *f,
4363 expect (','); 4510 expect (',');
4364 } 4511 }
4365 4512
4513 unsigned long frame_fg = FRAME_FOREGROUND_PIXEL (f);
4514#ifdef USE_CAIRO
4515 {
4516 Emacs_Color color = {.pixel = frame_fg};
4517 FRAME_TERMINAL (f)->query_colors (f, &color, 1);
4518 frame_fg = lookup_rgb_color (f, color.red, color.green, color.blue);
4519 }
4520#endif
4366 for (y = 0; y < height; y++) 4521 for (y = 0; y < height; y++)
4367 { 4522 {
4368 expect (XPM_TK_STRING); 4523 expect (XPM_TK_STRING);
@@ -4374,11 +4529,10 @@ xpm_load_image (struct frame *f,
4374 Lisp_Object color_val = 4529 Lisp_Object color_val =
4375 (*get_color_table) (color_table, str, chars_per_pixel); 4530 (*get_color_table) (color_table, str, chars_per_pixel);
4376 4531
4377 XPutPixel (ximg, x, y, 4532 PUT_PIXEL (ximg, x, y,
4378 (FIXNUMP (color_val) ? XFIXNUM (color_val) 4533 FIXNUMP (color_val) ? XFIXNUM (color_val) : frame_fg);
4379 : FRAME_FOREGROUND_PIXEL (f)));
4380#ifndef HAVE_NS 4534#ifndef HAVE_NS
4381 XPutPixel (mask_img, x, y, 4535 PUT_PIXEL (mask_img, x, y,
4382 (!EQ (color_val, Qt) ? PIX_MASK_DRAW 4536 (!EQ (color_val, Qt) ? PIX_MASK_DRAW
4383 : (have_mask = true, PIX_MASK_RETAIN))); 4537 : (have_mask = true, PIX_MASK_RETAIN)));
4384#else 4538#else
@@ -4735,10 +4889,8 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
4735{ 4889{
4736#ifdef HAVE_NTGUI 4890#ifdef HAVE_NTGUI
4737 return PALETTERGB (r >> 8, g >> 8, b >> 8); 4891 return PALETTERGB (r >> 8, g >> 8, b >> 8);
4738#elif defined HAVE_NS 4892#elif defined USE_CAIRO || defined HAVE_NS
4739 return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8); 4893 return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
4740#elif defined USE_CAIRO
4741 return (0xffu << 24) | (r << 16) | (g << 8) | b;
4742#else 4894#else
4743 xsignal1 (Qfile_error, 4895 xsignal1 (Qfile_error,
4744 build_string ("This Emacs mishandles this image file type")); 4896 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)
4810 p = colors; 4962 p = colors;
4811 for (y = 0; y < img->height; ++y) 4963 for (y = 0; y < img->height; ++y)
4812 { 4964 {
4813#if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI) 4965#if !defined USE_CAIRO && !defined HAVE_NS
4814 Emacs_Color *row = p; 4966 Emacs_Color *row = p;
4815 for (x = 0; x < img->width; ++x, ++p) 4967 for (x = 0; x < img->width; ++x, ++p)
4816 p->pixel = GET_PIXEL (ximg, x, y); 4968 p->pixel = GET_PIXEL (ximg, x, y);
@@ -4818,11 +4970,9 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
4818 { 4970 {
4819 FRAME_TERMINAL (f)->query_colors (f, row, img->width); 4971 FRAME_TERMINAL (f)->query_colors (f, row, img->width);
4820 } 4972 }
4821#else 4973#else /* USE_CAIRO || HAVE_NS */
4822
4823 for (x = 0; x < img->width; ++x, ++p) 4974 for (x = 0; x < img->width; ++x, ++p)
4824 { 4975 {
4825 /* W32_TODO: palette support needed here? */
4826 p->pixel = GET_PIXEL (ximg, x, y); 4976 p->pixel = GET_PIXEL (ximg, x, y);
4827 if (rgb_p) 4977 if (rgb_p)
4828 { 4978 {
@@ -4831,7 +4981,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
4831 p->blue = BLUE16_FROM_ULONG (p->pixel); 4981 p->blue = BLUE16_FROM_ULONG (p->pixel);
4832 } 4982 }
4833 } 4983 }
4834#endif /* HAVE_X_WINDOWS */ 4984#endif /* USE_CAIRO || HAVE_NS */
4835 } 4985 }
4836 4986
4837 image_unget_x_image_or_dc (img, 0, ximg, prev); 4987 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
4907 { 5057 {
4908 unsigned long pixel; 5058 unsigned long pixel;
4909 pixel = lookup_rgb_color (f, p->red, p->green, p->blue); 5059 pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
4910 XPutPixel (oimg, x, y, pixel); 5060 PUT_PIXEL (oimg, x, y, pixel);
4911 } 5061 }
4912 5062
4913 xfree (colors); 5063 xfree (colors);
@@ -5056,6 +5206,44 @@ image_edge_detection (struct frame *f, struct image *img,
5056} 5206}
5057 5207
5058 5208
5209#if defined HAVE_X_WINDOWS || defined USE_CAIRO
5210static void
5211image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap,
5212 int x, int y, unsigned int width, unsigned int height,
5213 unsigned long color)
5214{
5215#ifdef USE_CAIRO
5216 cairo_surface_t *surface
5217 = cairo_image_surface_create_for_data ((unsigned char *) pixmap->data,
5218 (pixmap->bits_per_pixel == 32
5219 ? CAIRO_FORMAT_RGB24
5220 : CAIRO_FORMAT_A8),
5221 pixmap->width, pixmap->height,
5222 pixmap->bytes_per_line);
5223 cairo_t *cr = cairo_create (surface);
5224 cairo_surface_destroy (surface);
5225 cairo_set_source_rgb (cr, RED_FROM_ULONG (color) / 255.0,
5226 GREEN_FROM_ULONG (color) / 255.0,
5227 BLUE_FROM_ULONG (color) / 255.0);
5228 cairo_move_to (cr, x + 0.5, y + 0.5);
5229 cairo_rel_line_to (cr, width - 1, height - 1);
5230 cairo_rel_move_to (cr, 0, - (height - 1));
5231 cairo_rel_line_to (cr, - (width - 1), height - 1);
5232 cairo_set_line_width (cr, 1);
5233 cairo_stroke (cr);
5234 cairo_destroy (cr);
5235#elif HAVE_X_WINDOWS
5236 Display *dpy = FRAME_X_DISPLAY (f);
5237 GC gc = XCreateGC (dpy, pixmap, 0, NULL);
5238
5239 XSetForeground (dpy, gc, color);
5240 XDrawLine (dpy, pixmap, gc, x, y, x + width - 1, y + height - 1);
5241 XDrawLine (dpy, pixmap, gc, x, y + height - 1, x + width - 1, y);
5242 XFreeGC (dpy, gc);
5243#endif /* HAVE_X_WINDOWS */
5244}
5245#endif /* HAVE_X_WINDOWS || USE_CAIRO */
5246
5059/* Transform image IMG on frame F so that it looks disabled. */ 5247/* Transform image IMG on frame F so that it looks disabled. */
5060 5248
5061static void 5249static void
@@ -5097,30 +5285,22 @@ image_disable_image (struct frame *f, struct image *img)
5097#ifndef HAVE_NTGUI 5285#ifndef HAVE_NTGUI
5098#ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */ 5286#ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
5099 5287
5288#ifndef USE_CAIRO
5289#define CrossForeground(f) BLACK_PIX_DEFAULT (f)
5100#define MaskForeground(f) WHITE_PIX_DEFAULT (f) 5290#define MaskForeground(f) WHITE_PIX_DEFAULT (f)
5291#else /* USE_CAIRO */
5292#define CrossForeground(f) 0
5293#define MaskForeground(f) PIX_MASK_DRAW
5294#endif /* USE_CAIRO */
5101 5295
5102 Display *dpy = FRAME_X_DISPLAY (f); 5296#ifndef USE_CAIRO
5103 GC gc;
5104
5105 image_sync_to_pixmaps (f, img); 5297 image_sync_to_pixmaps (f, img);
5106 gc = XCreateGC (dpy, img->pixmap, 0, NULL); 5298#endif /* !USE_CAIRO */
5107 XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f)); 5299 image_pixmap_draw_cross (f, img->pixmap, 0, 0, img->width, img->height,
5108 XDrawLine (dpy, img->pixmap, gc, 0, 0, 5300 CrossForeground (f));
5109 img->width - 1, img->height - 1);
5110 XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1,
5111 img->width - 1, 0);
5112 XFreeGC (dpy, gc);
5113
5114 if (img->mask) 5301 if (img->mask)
5115 { 5302 image_pixmap_draw_cross (f, img->mask, 0, 0, img->width, img->height,
5116 gc = XCreateGC (dpy, img->mask, 0, NULL); 5303 MaskForeground (f));
5117 XSetForeground (dpy, gc, MaskForeground (f));
5118 XDrawLine (dpy, img->mask, gc, 0, 0,
5119 img->width - 1, img->height - 1);
5120 XDrawLine (dpy, img->mask, gc, 0, img->height - 1,
5121 img->width - 1, 0);
5122 XFreeGC (dpy, gc);
5123 }
5124#endif /* !HAVE_NS */ 5304#endif /* !HAVE_NS */
5125#else 5305#else
5126 HDC hdc, bmpdc; 5306 HDC hdc, bmpdc;
@@ -5212,6 +5392,7 @@ image_build_heuristic_mask (struct frame *f, struct image *img,
5212 5392
5213 if (i == 3 && NILP (how)) 5393 if (i == 3 && NILP (how))
5214 { 5394 {
5395#ifndef USE_CAIRO
5215 char color_name[30]; 5396 char color_name[30];
5216 sprintf (color_name, "#%04x%04x%04x", 5397 sprintf (color_name, "#%04x%04x%04x",
5217 rgb[0] + 0u, rgb[1] + 0u, rgb[2] + 0u); 5398 rgb[0] + 0u, rgb[1] + 0u, rgb[2] + 0u);
@@ -5220,6 +5401,9 @@ image_build_heuristic_mask (struct frame *f, struct image *img,
5220 0x00ffffff & /* Filter out palette info. */ 5401 0x00ffffff & /* Filter out palette info. */
5221#endif /* HAVE_NTGUI */ 5402#endif /* HAVE_NTGUI */
5222 image_alloc_image_color (f, img, build_string (color_name), 0)); 5403 image_alloc_image_color (f, img, build_string (color_name), 0));
5404#else /* USE_CAIRO */
5405 bg = lookup_rgb_color (f, rgb[0], rgb[1], rgb[2]);
5406#endif /* USE_CAIRO */
5223 use_img_background = 0; 5407 use_img_background = 0;
5224 } 5408 }
5225 } 5409 }
@@ -5233,7 +5417,7 @@ image_build_heuristic_mask (struct frame *f, struct image *img,
5233 for (y = 0; y < img->height; ++y) 5417 for (y = 0; y < img->height; ++y)
5234 for (x = 0; x < img->width; ++x) 5418 for (x = 0; x < img->width; ++x)
5235#ifndef HAVE_NS 5419#ifndef HAVE_NS
5236 XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg 5420 PUT_PIXEL (mask_img, x, y, (GET_PIXEL (ximg, x, y) != bg
5237 ? PIX_MASK_DRAW : PIX_MASK_RETAIN)); 5421 ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
5238#else 5422#else
5239 if (XGetPixel (ximg, x, y) == bg) 5423 if (XGetPixel (ximg, x, y) == bg)
@@ -5406,9 +5590,7 @@ pbm_load (struct frame *f, struct image *img)
5406 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; 5590 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5407 char *contents = NULL; 5591 char *contents = NULL;
5408 char *end, *p; 5592 char *end, *p;
5409#ifndef USE_CAIRO
5410 Emacs_Pix_Container ximg; 5593 Emacs_Pix_Container ximg;
5411#endif
5412 5594
5413 specified_file = image_spec_value (img->spec, QCfile, NULL); 5595 specified_file = image_spec_value (img->spec, QCfile, NULL);
5414 5596
@@ -5492,11 +5674,6 @@ pbm_load (struct frame *f, struct image *img)
5492 width = pbm_scan_number (&p, end); 5674 width = pbm_scan_number (&p, end);
5493 height = pbm_scan_number (&p, end); 5675 height = pbm_scan_number (&p, end);
5494 5676
5495#ifdef USE_CAIRO
5496 cairo_surface_t *surface = create_cairo_image_surface (width, height);
5497 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
5498#endif
5499
5500 if (type != PBM_MONO) 5677 if (type != PBM_MONO)
5501 { 5678 {
5502 max_color_idx = pbm_scan_number (&p, end); 5679 max_color_idx = pbm_scan_number (&p, end);
@@ -5513,10 +5690,8 @@ pbm_load (struct frame *f, struct image *img)
5513 goto error; 5690 goto error;
5514 } 5691 }
5515 5692
5516#ifndef USE_CAIRO
5517 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 5693 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
5518 goto error; 5694 goto error;
5519#endif
5520 5695
5521 /* Initialize the color hash table. */ 5696 /* Initialize the color hash table. */
5522 init_color_table (); 5697 init_color_table ();
@@ -5528,42 +5703,11 @@ pbm_load (struct frame *f, struct image *img)
5528 struct image_keyword fmt[PBM_LAST]; 5703 struct image_keyword fmt[PBM_LAST];
5529 unsigned long fg = FRAME_FOREGROUND_PIXEL (f); 5704 unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
5530 unsigned long bg = FRAME_BACKGROUND_PIXEL (f); 5705 unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
5531#ifdef USE_CAIRO
5532 Emacs_Color xfg, xbg;
5533 int fga32, bga32;
5534#endif
5535 /* Parse the image specification. */ 5706 /* Parse the image specification. */
5536 memcpy (fmt, pbm_format, sizeof fmt); 5707 memcpy (fmt, pbm_format, sizeof fmt);
5537 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); 5708 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
5538 5709
5539 /* Get foreground and background colors, maybe allocate colors. */ 5710 /* Get foreground and background colors, maybe allocate colors. */
5540#ifdef USE_CAIRO
5541 if (! fmt[PBM_FOREGROUND].count
5542 || ! STRINGP (fmt[PBM_FOREGROUND].value)
5543 || ! FRAME_TERMINAL (f)->defined_color_hook (f,
5544 SSDATA (fmt[PBM_FOREGROUND].value),
5545 &xfg,
5546 false,
5547 false))
5548 {
5549 xfg.pixel = fg;
5550 x_query_colors (f, &xfg, 1);
5551 }
5552 fga32 = emacs_color_to_argb32 (&xfg);
5553
5554 if (! fmt[PBM_BACKGROUND].count
5555 || ! STRINGP (fmt[PBM_BACKGROUND].value)
5556 || ! FRAME_TERMINAL (f)->defined_color_hook (f,
5557 SSDATA (fmt[PBM_BACKGROUND].value),
5558 &xbg,
5559 false,
5560 false))
5561 {
5562 xbg.pixel = bg;
5563 x_query_colors (f, &xbg, 1);
5564 }
5565 bga32 = emacs_color_to_argb32 (&xbg);
5566#else
5567 if (fmt[PBM_FOREGROUND].count 5711 if (fmt[PBM_FOREGROUND].count
5568 && STRINGP (fmt[PBM_FOREGROUND].value)) 5712 && STRINGP (fmt[PBM_FOREGROUND].value))
5569 fg = image_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg); 5713 fg = image_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
@@ -5574,8 +5718,15 @@ pbm_load (struct frame *f, struct image *img)
5574 img->background = bg; 5718 img->background = bg;
5575 img->background_valid = 1; 5719 img->background_valid = 1;
5576 } 5720 }
5577#endif
5578 5721
5722#ifdef USE_CAIRO
5723 {
5724 Emacs_Color fgbg[] = {{.pixel = fg}, {.pixel = bg}};
5725 FRAME_TERMINAL (f)->query_colors (f, fgbg, ARRAYELTS (fgbg));
5726 fg = lookup_rgb_color (f, fgbg[0].red, fgbg[0].green, fgbg[0].blue);
5727 bg = lookup_rgb_color (f, fgbg[1].red, fgbg[1].green, fgbg[1].blue);
5728 }
5729#endif
5579 for (y = 0; y < height; ++y) 5730 for (y = 0; y < height; ++y)
5580 for (x = 0; x < width; ++x) 5731 for (x = 0; x < width; ++x)
5581 { 5732 {
@@ -5585,11 +5736,7 @@ pbm_load (struct frame *f, struct image *img)
5585 { 5736 {
5586 if (p >= end) 5737 if (p >= end)
5587 { 5738 {
5588#ifdef USE_CAIRO
5589 cairo_surface_destroy (surface);
5590#else
5591 image_destroy_x_image (ximg); 5739 image_destroy_x_image (ximg);
5592#endif
5593 image_clear_image (f, img); 5740 image_clear_image (f, img);
5594 image_error ("Invalid image size in image `%s'", 5741 image_error ("Invalid image size in image `%s'",
5595 img->spec); 5742 img->spec);
@@ -5613,11 +5760,7 @@ pbm_load (struct frame *f, struct image *img)
5613 g = 0; 5760 g = 0;
5614 } 5761 }
5615 5762
5616#ifdef USE_CAIRO 5763 PUT_PIXEL (ximg, x, y, g ? fg : bg);
5617 *dataptr++ = g ? fga32 : bga32;
5618#else
5619 XPutPixel (ximg, x, y, g ? fg : bg);
5620#endif
5621 } 5764 }
5622 } 5765 }
5623 else 5766 else
@@ -5631,11 +5774,7 @@ pbm_load (struct frame *f, struct image *img)
5631 5774
5632 if (raw_p && p + expected_size > end) 5775 if (raw_p && p + expected_size > end)
5633 { 5776 {
5634#ifdef USE_CAIRO
5635 cairo_surface_destroy (surface);
5636#else
5637 image_destroy_x_image (ximg); 5777 image_destroy_x_image (ximg);
5638#endif
5639 image_clear_image (f, img); 5778 image_clear_image (f, img);
5640 image_error ("Invalid image size in image `%s'", img->spec); 5779 image_error ("Invalid image size in image `%s'", img->spec);
5641 goto error; 5780 goto error;
@@ -5665,28 +5804,17 @@ pbm_load (struct frame *f, struct image *img)
5665 5804
5666 if (r < 0 || g < 0 || b < 0) 5805 if (r < 0 || g < 0 || b < 0)
5667 { 5806 {
5668#ifdef USE_CAIRO
5669 cairo_surface_destroy (surface);
5670#else
5671 image_destroy_x_image (ximg); 5807 image_destroy_x_image (ximg);
5672#endif
5673 image_error ("Invalid pixel value in image `%s'", img->spec); 5808 image_error ("Invalid pixel value in image `%s'", img->spec);
5674 goto error; 5809 goto error;
5675 } 5810 }
5676 5811
5677#ifdef USE_CAIRO
5678 r = (double) r * 255 / max_color_idx;
5679 g = (double) g * 255 / max_color_idx;
5680 b = (double) b * 255 / max_color_idx;
5681 *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b;
5682#else
5683 /* RGB values are now in the range 0..max_color_idx. 5812 /* RGB values are now in the range 0..max_color_idx.
5684 Scale this to the range 0..0xffff supported by X. */ 5813 Scale this to the range 0..0xffff supported by X. */
5685 r = (double) r * 65535 / max_color_idx; 5814 r = (double) r * 65535 / max_color_idx;
5686 g = (double) g * 65535 / max_color_idx; 5815 g = (double) g * 65535 / max_color_idx;
5687 b = (double) b * 65535 / max_color_idx; 5816 b = (double) b * 65535 / max_color_idx;
5688 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); 5817 PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b));
5689#endif
5690 } 5818 }
5691 } 5819 }
5692 5820
@@ -5702,16 +5830,12 @@ pbm_load (struct frame *f, struct image *img)
5702 5830
5703 /* Maybe fill in the background field while we have ximg handy. */ 5831 /* Maybe fill in the background field while we have ximg handy. */
5704 5832
5705#ifdef USE_CAIRO
5706 set_cairo_image_surface (img, surface);
5707#else
5708 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 5833 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5709 /* Casting avoids a GCC warning. */ 5834 /* Casting avoids a GCC warning. */
5710 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg); 5835 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
5711 5836
5712 /* Put ximg into the image. */ 5837 /* Put ximg into the image. */
5713 image_put_x_image (f, img, ximg, 0); 5838 image_put_x_image (f, img, ximg, 0);
5714#endif
5715 5839
5716 /* X and W32 versions did it here, MAC version above. ++kfs 5840 /* X and W32 versions did it here, MAC version above. ++kfs
5717 img->width = width; 5841 img->width = width;
@@ -6028,13 +6152,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6028 bool transparent_p; 6152 bool transparent_p;
6029 struct png_memory_storage tbr; /* Data to be read */ 6153 struct png_memory_storage tbr; /* Data to be read */
6030 ptrdiff_t nbytes; 6154 ptrdiff_t nbytes;
6031
6032#ifdef USE_CAIRO
6033 cairo_surface_t *surface;
6034 uint32_t *dataptr;
6035#else
6036 Emacs_Pix_Container ximg, mask_img = NULL; 6155 Emacs_Pix_Container ximg, mask_img = NULL;
6037#endif
6038 6156
6039 /* Find out what file to load. */ 6157 /* Find out what file to load. */
6040 specified_file = image_spec_value (img->spec, QCfile, NULL); 6158 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)
6152 goto error; 6270 goto error;
6153 } 6271 }
6154 6272
6155#ifndef USE_CAIRO
6156 /* Create the X image and pixmap now, so that the work below can be 6273 /* Create the X image and pixmap now, so that the work below can be
6157 omitted if the image is too large for X. */ 6274 omitted if the image is too large for X. */
6158 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 6275 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
6159 goto error; 6276 goto error;
6160#endif
6161 6277
6162 /* If image contains simply transparency data, we prefer to 6278 /* If image contains simply transparency data, we prefer to
6163 construct a clipping mask. */ 6279 construct a clipping mask. */
@@ -6249,10 +6365,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6249 c->fp = NULL; 6365 c->fp = NULL;
6250 } 6366 }
6251 6367
6252#ifdef USE_CAIRO
6253 surface = create_cairo_image_surface (width, height);
6254 dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
6255#else
6256 /* Create an image and pixmap serving as mask if the PNG image 6368 /* Create an image and pixmap serving as mask if the PNG image
6257 contains an alpha channel. */ 6369 contains an alpha channel. */
6258 if (channels == 4 6370 if (channels == 4
@@ -6264,7 +6376,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6264 image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP); 6376 image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
6265 goto error; 6377 goto error;
6266 } 6378 }
6267#endif
6268 6379
6269 /* Fill the X image and mask from PNG data. */ 6380 /* Fill the X image and mask from PNG data. */
6270 init_color_table (); 6381 init_color_table ();
@@ -6277,18 +6388,10 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6277 { 6388 {
6278 int r, g, b; 6389 int r, g, b;
6279 6390
6280#ifdef USE_CAIRO
6281 int a = 0xff;
6282 r = *p++;
6283 g = *p++;
6284 b = *p++;
6285 if (channels == 4) a = *p++;
6286 *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
6287#else
6288 r = *p++ << 8; 6391 r = *p++ << 8;
6289 g = *p++ << 8; 6392 g = *p++ << 8;
6290 b = *p++ << 8; 6393 b = *p++ << 8;
6291 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); 6394 PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b));
6292 /* An alpha channel, aka mask channel, associates variable 6395 /* An alpha channel, aka mask channel, associates variable
6293 transparency with an image. Where other image formats 6396 transparency with an image. Where other image formats
6294 support binary transparency---fully transparent or fully 6397 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)
6308 if (channels == 4) 6411 if (channels == 4)
6309 { 6412 {
6310 if (mask_img) 6413 if (mask_img)
6311 XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN); 6414 PUT_PIXEL (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
6312 ++p; 6415 ++p;
6313 } 6416 }
6314#endif
6315 } 6417 }
6316 } 6418 }
6317 6419
@@ -6322,7 +6424,14 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6322 png_color_16 *bg; 6424 png_color_16 *bg;
6323 if (png_get_bKGD (png_ptr, info_ptr, &bg)) 6425 if (png_get_bKGD (png_ptr, info_ptr, &bg))
6324 { 6426 {
6427#ifndef USE_CAIRO
6325 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); 6428 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
6429#else /* USE_CAIRO */
6430 char color_name[30];
6431 sprintf (color_name, "#%04x%04x%04x", bg->red, bg->green, bg->blue);
6432 img->background
6433 = image_alloc_image_color (f, img, build_string (color_name), 0);
6434#endif /* USE_CAIRO */
6326 img->background_valid = 1; 6435 img->background_valid = 1;
6327 } 6436 }
6328 } 6437 }
@@ -6341,9 +6450,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6341 img->width = width; 6450 img->width = width;
6342 img->height = height; 6451 img->height = height;
6343 6452
6344#ifdef USE_CAIRO
6345 set_cairo_image_surface (img, surface);
6346#else
6347 /* Maybe fill in the background field while we have ximg handy. 6453 /* Maybe fill in the background field while we have ximg handy.
6348 Casting avoids a GCC warning. */ 6454 Casting avoids a GCC warning. */
6349 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg); 6455 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)
6360 6466
6361 image_put_x_image (f, img, mask_img, 1); 6467 image_put_x_image (f, img, mask_img, 1);
6362 } 6468 }
6363#endif
6364 6469
6365 return 1; 6470 return 1;
6366} 6471}
@@ -6774,10 +6879,8 @@ jpeg_load_body (struct frame *f, struct image *img,
6774 int row_stride, x, y; 6879 int row_stride, x, y;
6775 int width, height; 6880 int width, height;
6776 int i, ir, ig, ib; 6881 int i, ir, ig, ib;
6777#ifndef USE_CAIRO
6778 unsigned long *colors; 6882 unsigned long *colors;
6779 Emacs_Pix_Container ximg = NULL; 6883 Emacs_Pix_Container ximg = NULL;
6780#endif
6781 6884
6782 /* Open the JPEG file. */ 6885 /* Open the JPEG file. */
6783 specified_file = image_spec_value (img->spec, QCfile, NULL); 6886 specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -6837,9 +6940,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6837 jpeg_destroy_decompress (&mgr->cinfo); 6940 jpeg_destroy_decompress (&mgr->cinfo);
6838 6941
6839 /* If we already have an XImage, free that. */ 6942 /* If we already have an XImage, free that. */
6840#ifndef USE_CAIRO
6841 image_destroy_x_image (ximg); 6943 image_destroy_x_image (ximg);
6842#endif
6843 /* Free pixmap and colors. */ 6944 /* Free pixmap and colors. */
6844 image_clear_image (f, img); 6945 image_clear_image (f, img);
6845 return 0; 6946 return 0;
@@ -6870,23 +6971,19 @@ jpeg_load_body (struct frame *f, struct image *img,
6870 sys_longjmp (mgr->setjmp_buffer, 1); 6971 sys_longjmp (mgr->setjmp_buffer, 1);
6871 } 6972 }
6872 6973
6873#ifndef USE_CAIRO
6874 /* Create X image and pixmap. */ 6974 /* Create X image and pixmap. */
6875 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 6975 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
6876 { 6976 {
6877 mgr->failure_code = MY_JPEG_CANNOT_CREATE_X; 6977 mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
6878 sys_longjmp (mgr->setjmp_buffer, 1); 6978 sys_longjmp (mgr->setjmp_buffer, 1);
6879 } 6979 }
6880#endif
6881 6980
6882 /* Allocate colors. When color quantization is used, 6981 /* Allocate colors. When color quantization is used,
6883 mgr->cinfo.actual_number_of_colors has been set with the number of 6982 mgr->cinfo.actual_number_of_colors has been set with the number of
6884 colors generated, and mgr->cinfo.colormap is a two-dimensional array 6983 colors generated, and mgr->cinfo.colormap is a two-dimensional array
6885 of color indices in the range 0..mgr->cinfo.actual_number_of_colors. 6984 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
6886 No more than 255 colors will be generated. */ 6985 No more than 255 colors will be generated. */
6887#ifndef USE_CAIRO
6888 USE_SAFE_ALLOCA; 6986 USE_SAFE_ALLOCA;
6889#endif
6890 { 6987 {
6891 if (mgr->cinfo.out_color_components > 2) 6988 if (mgr->cinfo.out_color_components > 2)
6892 ir = 0, ig = 1, ib = 2; 6989 ir = 0, ig = 1, ib = 2;
@@ -6895,7 +6992,6 @@ jpeg_load_body (struct frame *f, struct image *img,
6895 else 6992 else
6896 ir = 0, ig = 0, ib = 0; 6993 ir = 0, ig = 0, ib = 0;
6897 6994
6898#ifndef USE_CAIRO
6899 /* Use the color table mechanism because it handles colors that 6995 /* Use the color table mechanism because it handles colors that
6900 cannot be allocated nicely. Such colors will be replaced with 6996 cannot be allocated nicely. Such colors will be replaced with
6901 a default color, and we don't have to care about which colors 6997 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,
6912 int b = mgr->cinfo.colormap[ib][i] << 8; 7008 int b = mgr->cinfo.colormap[ib][i] << 8;
6913 colors[i] = lookup_rgb_color (f, r, g, b); 7009 colors[i] = lookup_rgb_color (f, r, g, b);
6914 } 7010 }
6915#endif
6916 7011
6917#ifdef COLOR_TABLE_SUPPORT 7012#ifdef COLOR_TABLE_SUPPORT
6918 /* Remember those colors actually allocated. */ 7013 /* Remember those colors actually allocated. */
@@ -6925,36 +7020,12 @@ jpeg_load_body (struct frame *f, struct image *img,
6925 row_stride = width * mgr->cinfo.output_components; 7020 row_stride = width * mgr->cinfo.output_components;
6926 buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo, 7021 buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
6927 JPOOL_IMAGE, row_stride, 1); 7022 JPOOL_IMAGE, row_stride, 1);
6928#ifdef USE_CAIRO
6929 {
6930 cairo_surface_t *surface = create_cairo_image_surface (width, height);
6931 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
6932 int r, g, b;
6933
6934 for (y = 0; y < height; ++y)
6935 {
6936 jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
6937
6938 for (x = 0; x < width; ++x)
6939 {
6940 i = buffer[0][x];
6941 r = mgr->cinfo.colormap[ir][i];
6942 g = mgr->cinfo.colormap[ig][i];
6943 b = mgr->cinfo.colormap[ib][i];
6944 *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b;
6945 }
6946 }
6947
6948 set_cairo_image_surface (img, surface);
6949 }
6950#else
6951 for (y = 0; y < height; ++y) 7023 for (y = 0; y < height; ++y)
6952 { 7024 {
6953 jpeg_read_scanlines (&mgr->cinfo, buffer, 1); 7025 jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
6954 for (x = 0; x < mgr->cinfo.output_width; ++x) 7026 for (x = 0; x < mgr->cinfo.output_width; ++x)
6955 XPutPixel (ximg, x, y, colors[buffer[0][x]]); 7027 PUT_PIXEL (ximg, x, y, colors[buffer[0][x]]);
6956 } 7028 }
6957#endif
6958 7029
6959 /* Clean up. */ 7030 /* Clean up. */
6960 jpeg_finish_decompress (&mgr->cinfo); 7031 jpeg_finish_decompress (&mgr->cinfo);
@@ -6962,7 +7033,6 @@ jpeg_load_body (struct frame *f, struct image *img,
6962 if (fp) 7033 if (fp)
6963 fclose (fp); 7034 fclose (fp);
6964 7035
6965#ifndef USE_CAIRO
6966 /* Maybe fill in the background field while we have ximg handy. */ 7036 /* Maybe fill in the background field while we have ximg handy. */
6967 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 7037 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6968 /* Casting avoids a GCC warning. */ 7038 /* Casting avoids a GCC warning. */
@@ -6971,7 +7041,6 @@ jpeg_load_body (struct frame *f, struct image *img,
6971 /* Put ximg into the image. */ 7041 /* Put ximg into the image. */
6972 image_put_x_image (f, img, ximg, 0); 7042 image_put_x_image (f, img, ximg, 0);
6973 SAFE_FREE (); 7043 SAFE_FREE ();
6974#endif
6975 return 1; 7044 return 1;
6976} 7045}
6977 7046
@@ -7384,28 +7453,6 @@ tiff_load (struct frame *f, struct image *img)
7384 return 0; 7453 return 0;
7385 } 7454 }
7386 7455
7387#ifdef USE_CAIRO
7388 {
7389 cairo_surface_t *surface = create_cairo_image_surface (width, height);
7390 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
7391
7392 for (y = 0; y < height; ++y)
7393 {
7394 uint32 *row = buf + (height - 1 - y) * width;
7395 for (x = 0; x < width; ++x)
7396 {
7397 uint32 abgr = row[x];
7398 int r = TIFFGetR (abgr);
7399 int g = TIFFGetG (abgr);
7400 int b = TIFFGetB (abgr);
7401 int a = TIFFGetA (abgr);
7402 *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
7403 }
7404 }
7405
7406 set_cairo_image_surface (img, surface);
7407 }
7408#else
7409 /* Initialize the color table. */ 7456 /* Initialize the color table. */
7410 init_color_table (); 7457 init_color_table ();
7411 7458
@@ -7420,7 +7467,7 @@ tiff_load (struct frame *f, struct image *img)
7420 int r = TIFFGetR (abgr) << 8; 7467 int r = TIFFGetR (abgr) << 8;
7421 int g = TIFFGetG (abgr) << 8; 7468 int g = TIFFGetG (abgr) << 8;
7422 int b = TIFFGetB (abgr) << 8; 7469 int b = TIFFGetB (abgr) << 8;
7423 XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b)); 7470 PUT_PIXEL (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
7424 } 7471 }
7425 } 7472 }
7426 7473
@@ -7441,8 +7488,6 @@ tiff_load (struct frame *f, struct image *img)
7441 /* Put ximg into the image. */ 7488 /* Put ximg into the image. */
7442 image_put_x_image (f, img, ximg, 0); 7489 image_put_x_image (f, img, ximg, 0);
7443 7490
7444#endif /* ! USE_CAIRO */
7445
7446 xfree (buf); 7491 xfree (buf);
7447 return 1; 7492 return 1;
7448} 7493}
@@ -7819,26 +7864,6 @@ gif_load (struct frame *f, struct image *img)
7819 } 7864 }
7820 } 7865 }
7821 7866
7822#ifdef USE_CAIRO
7823 cairo_surface_t *surface = create_cairo_image_surface (width, height);
7824 uint32_t *data32 = (uint32_t *) cairo_image_surface_get_data (surface);
7825 if (STRINGP (specified_bg))
7826 {
7827 Emacs_Color color;
7828 if (FRAME_TERMINAL (f)->defined_color_hook
7829 (f, SSDATA (specified_bg), &color, false, false))
7830 {
7831 uint32_t *dataptr = data32;
7832 int r = color.red/256;
7833 int g = color.green/256;
7834 int b = color.blue/256;
7835
7836 for (y = 0; y < height; ++y)
7837 for (x = 0; x < width; ++x)
7838 *dataptr++ = (0xffu << 24) | (r << 16) | (g << 8) | b;
7839 }
7840 }
7841#else
7842 /* Create the X image and pixmap. */ 7867 /* Create the X image and pixmap. */
7843 Emacs_Pix_Container ximg; 7868 Emacs_Pix_Container ximg;
7844 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 7869 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)
7851 Full animated GIF support requires more here (see the gif89 spec, 7876 Full animated GIF support requires more here (see the gif89 spec,
7852 disposal methods). Let's simply assume that the part not covered 7877 disposal methods). Let's simply assume that the part not covered
7853 by a sub-image is in the frame's background color. */ 7878 by a sub-image is in the frame's background color. */
7879 unsigned long frame_bg;
7880#ifndef USE_CAIRO
7881 frame_bg = FRAME_BACKGROUND_PIXEL (f);
7882#else /* USE_CAIRO */
7883 {
7884 Emacs_Color color;
7885 FRAME_TERMINAL (f)->query_frame_background_color (f, &color);
7886 frame_bg = lookup_rgb_color (f, color.red, color.green, color.blue);
7887 }
7888#endif /* USE_CAIRO */
7854 for (y = 0; y < img->corners[TOP_CORNER]; ++y) 7889 for (y = 0; y < img->corners[TOP_CORNER]; ++y)
7855 for (x = 0; x < width; ++x) 7890 for (x = 0; x < width; ++x)
7856 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7891 PUT_PIXEL (ximg, x, y, frame_bg);
7857 7892
7858 for (y = img->corners[BOT_CORNER]; y < height; ++y) 7893 for (y = img->corners[BOT_CORNER]; y < height; ++y)
7859 for (x = 0; x < width; ++x) 7894 for (x = 0; x < width; ++x)
7860 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7895 PUT_PIXEL (ximg, x, y, frame_bg);
7861 7896
7862 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y) 7897 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
7863 { 7898 {
7864 for (x = 0; x < img->corners[LEFT_CORNER]; ++x) 7899 for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
7865 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7900 PUT_PIXEL (ximg, x, y, frame_bg);
7866 for (x = img->corners[RIGHT_CORNER]; x < width; ++x) 7901 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
7867 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7902 PUT_PIXEL (ximg, x, y, frame_bg);
7868 } 7903 }
7869#endif
7870 7904
7871 /* Read the GIF image into the X image. */ 7905 /* Read the GIF image into the X image. */
7872 7906
@@ -7877,12 +7911,17 @@ gif_load (struct frame *f, struct image *img)
7877 7911
7878 init_color_table (); 7912 init_color_table ();
7879 7913
7880#ifndef USE_CAIRO
7881 unsigned long bgcolor UNINIT; 7914 unsigned long bgcolor UNINIT;
7882 if (STRINGP (specified_bg)) 7915 if (STRINGP (specified_bg))
7883 bgcolor = image_alloc_image_color (f, img, specified_bg, 7916 {
7884 FRAME_BACKGROUND_PIXEL (f)); 7917 bgcolor = image_alloc_image_color (f, img, specified_bg,
7918 FRAME_BACKGROUND_PIXEL (f));
7919#ifdef USE_CAIRO
7920 Emacs_Color color = {.pixel = bgcolor};
7921 FRAME_TERMINAL (f)->query_colors (f, &color, 1);
7922 bgcolor = lookup_rgb_color (f, color.red, color.green, color.blue);
7885#endif 7923#endif
7924 }
7886 7925
7887 for (j = 0; j <= idx; ++j) 7926 for (j = 0; j <= idx; ++j)
7888 { 7927 {
@@ -7930,7 +7969,6 @@ gif_load (struct frame *f, struct image *img)
7930 if (!gif_color_map) 7969 if (!gif_color_map)
7931 gif_color_map = gif->SColorMap; 7970 gif_color_map = gif->SColorMap;
7932 7971
7933#ifndef USE_CAIRO
7934 /* Allocate subimage colors. */ 7972 /* Allocate subimage colors. */
7935 unsigned long pixel_colors[256] = { 0, }; 7973 unsigned long pixel_colors[256] = { 0, };
7936 7974
@@ -7939,7 +7977,7 @@ gif_load (struct frame *f, struct image *img)
7939 { 7977 {
7940 if (transparency_color_index == i) 7978 if (transparency_color_index == i)
7941 pixel_colors[i] = STRINGP (specified_bg) 7979 pixel_colors[i] = STRINGP (specified_bg)
7942 ? bgcolor : FRAME_BACKGROUND_PIXEL (f); 7980 ? bgcolor : frame_bg;
7943 else 7981 else
7944 { 7982 {
7945 int r = gif_color_map->Colors[i].Red << 8; 7983 int r = gif_color_map->Colors[i].Red << 8;
@@ -7948,7 +7986,6 @@ gif_load (struct frame *f, struct image *img)
7948 pixel_colors[i] = lookup_rgb_color (f, r, g, b); 7986 pixel_colors[i] = lookup_rgb_color (f, r, g, b);
7949 } 7987 }
7950 } 7988 }
7951#endif
7952 7989
7953 /* Apply the pixel values. */ 7990 /* Apply the pixel values. */
7954 if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace) 7991 if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace)
@@ -7967,21 +8004,9 @@ gif_load (struct frame *f, struct image *img)
7967 int c = raster[y * subimg_width + x]; 8004 int c = raster[y * subimg_width + x];
7968 if (transparency_color_index != c || disposal != 1) 8005 if (transparency_color_index != c || disposal != 1)
7969 { 8006 {
7970#ifdef USE_CAIRO 8007 PUT_PIXEL (ximg, x + subimg_left, row + subimg_top,
7971 uint32_t *dataptr =
7972 (data32 + ((row + subimg_top) * width
7973 + x + subimg_left));
7974 int r = gif_color_map->Colors[c].Red;
7975 int g = gif_color_map->Colors[c].Green;
7976 int b = gif_color_map->Colors[c].Blue;
7977
7978 if (transparency_color_index != c)
7979 *dataptr = (0xffu << 24) | (r << 16) | (g << 8) | b;
7980#else
7981 XPutPixel (ximg, x + subimg_left, row + subimg_top,
7982 pixel_colors[c]); 8008 pixel_colors[c]);
7983#endif 8009 }
7984 }
7985 } 8010 }
7986 } 8011 }
7987 } 8012 }
@@ -7993,19 +8018,8 @@ gif_load (struct frame *f, struct image *img)
7993 int c = raster[y * subimg_width + x]; 8018 int c = raster[y * subimg_width + x];
7994 if (transparency_color_index != c || disposal != 1) 8019 if (transparency_color_index != c || disposal != 1)
7995 { 8020 {
7996#ifdef USE_CAIRO 8021 PUT_PIXEL (ximg, x + subimg_left, y + subimg_top,
7997 uint32_t *dataptr =
7998 (data32 + ((y + subimg_top) * width
7999 + x + subimg_left));
8000 int r = gif_color_map->Colors[c].Red;
8001 int g = gif_color_map->Colors[c].Green;
8002 int b = gif_color_map->Colors[c].Blue;
8003 if (transparency_color_index != c)
8004 *dataptr = (0xffu << 24) | (r << 16) | (g << 8) | b;
8005#else
8006 XPutPixel (ximg, x + subimg_left, y + subimg_top,
8007 pixel_colors[c]); 8022 pixel_colors[c]);
8008#endif
8009 } 8023 }
8010 } 8024 }
8011 } 8025 }
@@ -8064,9 +8078,6 @@ gif_load (struct frame *f, struct image *img)
8064#endif 8078#endif
8065 } 8079 }
8066 8080
8067#ifdef USE_CAIRO
8068 set_cairo_image_surface (img, surface);
8069#else
8070 /* Maybe fill in the background field while we have ximg handy. */ 8081 /* Maybe fill in the background field while we have ximg handy. */
8071 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 8082 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
8072 /* Casting avoids a GCC warning. */ 8083 /* Casting avoids a GCC warning. */
@@ -8074,7 +8085,6 @@ gif_load (struct frame *f, struct image *img)
8074 8085
8075 /* Put ximg into the image. */ 8086 /* Put ximg into the image. */
8076 image_put_x_image (f, img, ximg, 0); 8087 image_put_x_image (f, img, ximg, 0);
8077#endif
8078 8088
8079 return 1; 8089 return 1;
8080} 8090}
@@ -8453,9 +8463,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8453 int width, height; 8463 int width, height;
8454 size_t image_width, image_height; 8464 size_t image_width, image_height;
8455 MagickBooleanType status; 8465 MagickBooleanType status;
8456#ifndef USE_CAIRO
8457 Emacs_Pix_Container ximg; 8466 Emacs_Pix_Container ximg;
8458#endif
8459 int x, y; 8467 int x, y;
8460 MagickWand *image_wand; 8468 MagickWand *image_wand;
8461 PixelIterator *iterator; 8469 PixelIterator *iterator;
@@ -8469,9 +8477,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
8469 double rotation; 8477 double rotation;
8470 char hint_buffer[MaxTextExtent]; 8478 char hint_buffer[MaxTextExtent];
8471 char *filename_hint = NULL; 8479 char *filename_hint = NULL;
8472#ifdef USE_CAIRO
8473 cairo_surface_t *surface;
8474#endif
8475 8480
8476 /* Initialize the ImageMagick environment. */ 8481 /* Initialize the ImageMagick environment. */
8477 static bool imagemagick_initialized; 8482 static bool imagemagick_initialized;
@@ -8685,11 +8690,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
8685 method is also well tested. Some aspects of this method are 8690 method is also well tested. Some aspects of this method are
8686 ad-hoc and needs to be more researched. */ 8691 ad-hoc and needs to be more researched. */
8687 void *dataptr; 8692 void *dataptr;
8688#ifdef USE_CAIRO
8689 surface = create_cairo_image_surface (width, height);
8690 const char *exportdepth = "BGRA";
8691 dataptr = cairo_image_surface_get_data (surface);
8692#else
8693 int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/ 8693 int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/
8694 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/ 8694 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/
8695 /* Try to create a x pixmap to hold the imagemagick pixmap. */ 8695 /* Try to create a x pixmap to hold the imagemagick pixmap. */
@@ -8703,7 +8703,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
8703 goto imagemagick_error; 8703 goto imagemagick_error;
8704 } 8704 }
8705 dataptr = ximg->data; 8705 dataptr = ximg->data;
8706#endif /* not USE_CAIRO */
8707 8706
8708 /* Oddly, the below code doesn't seem to work:*/ 8707 /* Oddly, the below code doesn't seem to work:*/
8709 /* switch(ximg->bitmap_unit){ */ 8708 /* switch(ximg->bitmap_unit){ */
@@ -8734,11 +8733,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
8734 size_t image_height; 8733 size_t image_height;
8735 double quantum_range = QuantumRange; 8734 double quantum_range = QuantumRange;
8736 MagickRealType color_scale = 65535.0 / quantum_range; 8735 MagickRealType color_scale = 65535.0 / quantum_range;
8737#ifdef USE_CAIRO
8738 surface = create_cairo_image_surface (width, height);
8739 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
8740 color_scale /= 256;
8741#else
8742 /* Try to create a x pixmap to hold the imagemagick pixmap. */ 8736 /* Try to create a x pixmap to hold the imagemagick pixmap. */
8743 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, 8737 if (!image_create_x_image_and_pixmap (f, img, width, height, 0,
8744 &ximg, 0)) 8738 &ximg, 0))
@@ -8749,7 +8743,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
8749 image_error ("Imagemagick X bitmap allocation failure"); 8743 image_error ("Imagemagick X bitmap allocation failure");
8750 goto imagemagick_error; 8744 goto imagemagick_error;
8751 } 8745 }
8752#endif
8753 8746
8754 /* Copy imagemagick image to x with primitive yet robust pixel 8747 /* Copy imagemagick image to x with primitive yet robust pixel
8755 pusher loop. This has been tested a lot with many different 8748 pusher loop. This has been tested a lot with many different
@@ -8762,9 +8755,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
8762#ifdef COLOR_TABLE_SUPPORT 8755#ifdef COLOR_TABLE_SUPPORT
8763 free_color_table (); 8756 free_color_table ();
8764#endif 8757#endif
8765#ifndef USE_CAIRO
8766 image_destroy_x_image (ximg); 8758 image_destroy_x_image (ximg);
8767#endif
8768 image_error ("Imagemagick pixel iterator creation failed"); 8759 image_error ("Imagemagick pixel iterator creation failed");
8769 goto imagemagick_error; 8760 goto imagemagick_error;
8770 } 8761 }
@@ -8780,27 +8771,16 @@ imagemagick_load_image (struct frame *f, struct image *img,
8780 for (x = 0; x < xlim; x++) 8771 for (x = 0; x < xlim; x++)
8781 { 8772 {
8782 PixelGetMagickColor (pixels[x], &pixel); 8773 PixelGetMagickColor (pixels[x], &pixel);
8783#ifdef USE_CAIRO 8774 PUT_PIXEL (ximg, x, y,
8784 dataptr[width * y + x] =
8785 lookup_rgb_color (f,
8786 color_scale * pixel.red,
8787 color_scale * pixel.green,
8788 color_scale * pixel.blue);
8789#else
8790 XPutPixel (ximg, x, y,
8791 lookup_rgb_color (f, 8775 lookup_rgb_color (f,
8792 color_scale * pixel.red, 8776 color_scale * pixel.red,
8793 color_scale * pixel.green, 8777 color_scale * pixel.green,
8794 color_scale * pixel.blue)); 8778 color_scale * pixel.blue));
8795#endif
8796 } 8779 }
8797 } 8780 }
8798 DestroyPixelIterator (iterator); 8781 DestroyPixelIterator (iterator);
8799 } 8782 }
8800 8783
8801#ifdef USE_CAIRO
8802 set_cairo_image_surface (img, surface);
8803#else
8804#ifdef COLOR_TABLE_SUPPORT 8784#ifdef COLOR_TABLE_SUPPORT
8805 /* Remember colors allocated for this image. */ 8785 /* Remember colors allocated for this image. */
8806 img->colors = colors_in_color_table (&img->ncolors); 8786 img->colors = colors_in_color_table (&img->ncolors);
@@ -8812,7 +8792,6 @@ imagemagick_load_image (struct frame *f, struct image *img,
8812 8792
8813 /* Put ximg into the image. */ 8793 /* Put ximg into the image. */
8814 image_put_x_image (f, img, ximg, 0); 8794 image_put_x_image (f, img, ximg, 0);
8815#endif
8816 8795
8817 /* Final cleanup. image_wand should be the only resource left. */ 8796 /* Final cleanup. image_wand should be the only resource left. */
8818 DestroyMagickWand (image_wand); 8797 DestroyMagickWand (image_wand);
@@ -9257,33 +9236,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9257 eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); 9236 eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
9258 9237
9259 { 9238 {
9260#ifdef USE_CAIRO
9261 cairo_surface_t *surface = create_cairo_image_surface (width, height);
9262 uint32_t *dataptr = (uint32_t *) cairo_image_surface_get_data (surface);
9263 uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
9264
9265 for (int y = 0; y < height; ++y)
9266 {
9267 const guchar *iconptr = pixels + y * rowstride;
9268
9269 for (int x = 0; x < width; ++x)
9270 {
9271 if (iconptr[3] == 0)
9272 *dataptr = bgcolor;
9273 else
9274 *dataptr = (iconptr[0] << 16)
9275 | (iconptr[1] << 8)
9276 | iconptr[2]
9277 | (iconptr[3] << 24);
9278
9279 iconptr += 4;
9280 ++dataptr;
9281 }
9282 }
9283
9284 set_cairo_image_surface (img, surface);
9285 g_object_unref (pixbuf);
9286#else
9287 /* Try to create a x pixmap to hold the svg pixmap. */ 9239 /* Try to create a x pixmap to hold the svg pixmap. */
9288 Emacs_Pix_Container ximg; 9240 Emacs_Pix_Container ximg;
9289 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 9241 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,
9333 blue = ((blue * opacity) 9285 blue = ((blue * opacity)
9334 + (background.blue * ((1 << 8) - opacity))); 9286 + (background.blue * ((1 << 8) - opacity)));
9335 9287
9336 XPutPixel (ximg, x, y, lookup_rgb_color (f, red, green, blue)); 9288 PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red, green, blue));
9337 } 9289 }
9338 9290
9339 pixels += rowstride - 4 * width; 9291 pixels += rowstride - 4 * width;
@@ -9356,7 +9308,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9356 9308
9357 /* Put ximg into the image. */ 9309 /* Put ximg into the image. */
9358 image_put_x_image (f, img, ximg, 0); 9310 image_put_x_image (f, img, ximg, 0);
9359#endif /* ! USE_CAIRO */
9360 } 9311 }
9361 9312
9362 return 1; 9313 return 1;
@@ -9379,9 +9330,9 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
9379 Ghostscript 9330 Ghostscript
9380 ***********************************************************************/ 9331 ***********************************************************************/
9381 9332
9382#ifdef HAVE_X_WINDOWS 9333#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
9383#define HAVE_GHOSTSCRIPT 1 9334#define HAVE_GHOSTSCRIPT 1
9384#endif /* HAVE_X_WINDOWS */ 9335#endif /* HAVE_X_WINDOWS && !USE_CAIRO */
9385 9336
9386#ifdef HAVE_GHOSTSCRIPT 9337#ifdef HAVE_GHOSTSCRIPT
9387 9338