aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorJan D2015-05-23 12:34:45 +0200
committerJan D2015-05-23 12:34:45 +0200
commitc03c730481bd2dc7bc857d9b4f1c41eea9bd495e (patch)
treea34eb6ad435ab877848f7464374570549ca55ec5 /src/image.c
parent7ac84a2570e1268cc040fcd529508307b2b22c01 (diff)
parent6aaa489dc112f51f6045f79b37cb78dd513e398f (diff)
downloademacs-c03c730481bd2dc7bc857d9b4f1c41eea9bd495e.tar.gz
emacs-c03c730481bd2dc7bc857d9b4f1c41eea9bd495e.zip
Merge branch 'cairo'.
Main work done by YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>. Small fixes and image work by Jan D. <jan.h.d@swipnet.se>.
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c379
1 files changed, 358 insertions, 21 deletions
diff --git a/src/image.c b/src/image.c
index d7f48bd81dd..87029bfa1b0 100644
--- a/src/image.c
+++ b/src/image.c
@@ -88,6 +88,10 @@ typedef struct w32_bitmap_record Bitmap_Record;
88 88
89#endif /* HAVE_NTGUI */ 89#endif /* HAVE_NTGUI */
90 90
91#ifdef USE_CAIRO
92#undef COLOR_TABLE_SUPPORT
93#endif
94
91#ifdef HAVE_NS 95#ifdef HAVE_NS
92#undef COLOR_TABLE_SUPPORT 96#undef COLOR_TABLE_SUPPORT
93 97
@@ -514,7 +518,6 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
514 518
515#endif /* HAVE_X_WINDOWS */ 519#endif /* HAVE_X_WINDOWS */
516 520
517
518/*********************************************************************** 521/***********************************************************************
519 Image types 522 Image types
520 ***********************************************************************/ 523 ***********************************************************************/
@@ -1019,6 +1022,7 @@ prepare_image_for_display (struct frame *f, struct image *img)
1019 /* We're about to display IMG, so set its timestamp to `now'. */ 1022 /* We're about to display IMG, so set its timestamp to `now'. */
1020 img->timestamp = current_timespec (); 1023 img->timestamp = current_timespec ();
1021 1024
1025#ifndef USE_CAIRO
1022 /* If IMG doesn't have a pixmap yet, load it now, using the image 1026 /* If IMG doesn't have a pixmap yet, load it now, using the image
1023 type dependent loader function. */ 1027 type dependent loader function. */
1024 if (img->pixmap == NO_PIXMAP && !img->load_failed_p) 1028 if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
@@ -1032,6 +1036,7 @@ prepare_image_for_display (struct frame *f, struct image *img)
1032 unblock_input (); 1036 unblock_input ();
1033 } 1037 }
1034#endif 1038#endif
1039#endif
1035} 1040}
1036 1041
1037 1042
@@ -1078,6 +1083,54 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
1078 return ascent; 1083 return ascent;
1079} 1084}
1080 1085
1086#ifdef USE_CAIRO
1087static uint32_t
1088xcolor_to_argb32 (XColor xc)
1089{
1090 return (0xff << 24) | ((xc.red / 256) << 16)
1091 | ((xc.green / 256) << 8) | (xc.blue / 256);
1092}
1093
1094static uint32_t
1095get_spec_bg_or_alpha_as_argb (struct image *img,
1096 struct frame *f)
1097{
1098 uint32_t bgcolor = 0;
1099 XColor xbgcolor;
1100 Lisp_Object bg = image_spec_value (img->spec, QCbackground, NULL);
1101
1102 if (STRINGP (bg) && XParseColor (FRAME_X_DISPLAY (f),
1103 FRAME_X_COLORMAP (f),
1104 SSDATA (bg),
1105 &xbgcolor))
1106 bgcolor = xcolor_to_argb32 (xbgcolor);
1107
1108 return bgcolor;
1109}
1110
1111static void
1112create_cairo_image_surface (struct image *img,
1113 unsigned char *data,
1114 int width,
1115 int height)
1116{
1117 cairo_surface_t *surface;
1118 cairo_format_t format = CAIRO_FORMAT_ARGB32;
1119 int stride = cairo_format_stride_for_width (format, width);
1120 surface = cairo_image_surface_create_for_data (data,
1121 format,
1122 width,
1123 height,
1124 stride);
1125 img->width = width;
1126 img->height = height;
1127 img->cr_data = surface;
1128 img->cr_data2 = data;
1129 img->pixmap = 0;
1130}
1131#endif
1132
1133
1081 1134
1082/* Image background colors. */ 1135/* Image background colors. */
1083 1136
@@ -1299,6 +1352,11 @@ static void
1299x_clear_image (struct frame *f, struct image *img) 1352x_clear_image (struct frame *f, struct image *img)
1300{ 1353{
1301 block_input (); 1354 block_input ();
1355#ifdef USE_CAIRO
1356 if (img->cr_data)
1357 cairo_surface_destroy ((cairo_surface_t *)img->cr_data);
1358 if (img->cr_data2) xfree (img->cr_data2);
1359#endif
1302 x_clear_image_1 (f, img, 1360 x_clear_image_1 (f, img,
1303 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS); 1361 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS);
1304 unblock_input (); 1362 unblock_input ();
@@ -3154,9 +3212,11 @@ static struct image_type xpm_type =
3154 color allocation failures more gracefully than the ones on the XPM 3212 color allocation failures more gracefully than the ones on the XPM
3155 lib. */ 3213 lib. */
3156 3214
3215#ifndef USE_CAIRO
3157#if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure 3216#if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
3158#define ALLOC_XPM_COLORS 3217#define ALLOC_XPM_COLORS
3159#endif 3218#endif
3219#endif /* USE_CAIRO */
3160#endif /* HAVE_X_WINDOWS */ 3220#endif /* HAVE_X_WINDOWS */
3161 3221
3162#ifdef ALLOC_XPM_COLORS 3222#ifdef ALLOC_XPM_COLORS
@@ -3617,6 +3677,44 @@ xpm_load (struct frame *f, struct image *img)
3617#endif /* HAVE_NTGUI */ 3677#endif /* HAVE_NTGUI */
3618 } 3678 }
3619 3679
3680#ifdef USE_CAIRO
3681 // Load very specific Xpm:s.
3682 if (rc == XpmSuccess
3683 && img->ximg->format == ZPixmap
3684 && img->ximg->bits_per_pixel == 32
3685 && (! img->mask_img || img->mask_img->bits_per_pixel == 1))
3686 {
3687 int width = img->ximg->width;
3688 int height = img->ximg->height;
3689 unsigned char *data = (unsigned char *) xmalloc (width*height*4);
3690 int i;
3691 uint32_t *od = (uint32_t *)data;
3692 uint32_t *id = (uint32_t *)img->ximg->data;
3693 unsigned char *mid = img->mask_img ? img->mask_img->data : 0;
3694 uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
3695
3696 for (i = 0; i < height; ++i)
3697 {
3698 int k;
3699 for (k = 0; k < width; ++k)
3700 {
3701 int idx = i * img->ximg->bytes_per_line/4 + k;
3702 int maskidx = mid ? i * img->mask_img->bytes_per_line + k/8 : 0;
3703 int mask = mid ? mid[maskidx] & (1 << (k % 8)) : 1;
3704
3705 if (mask) od[idx] = id[idx] + 0xff000000; // ff => full alpha
3706 else od[idx] = bgcolor;
3707 }
3708 }
3709
3710 create_cairo_image_surface (img, data, width, height);
3711 }
3712 else
3713 {
3714 rc = XpmFileInvalid;
3715 x_clear_image (f, img);
3716 }
3717#else
3620#ifdef HAVE_X_WINDOWS 3718#ifdef HAVE_X_WINDOWS
3621 if (rc == XpmSuccess) 3719 if (rc == XpmSuccess)
3622 { 3720 {
@@ -3642,6 +3740,7 @@ xpm_load (struct frame *f, struct image *img)
3642 } 3740 }
3643 } 3741 }
3644#endif 3742#endif
3743#endif /* ! USE_CAIRO */
3645 3744
3646 if (rc == XpmSuccess) 3745 if (rc == XpmSuccess)
3647 { 3746 {
@@ -5148,12 +5247,17 @@ pbm_load (struct frame *f, struct image *img)
5148 bool raw_p; 5247 bool raw_p;
5149 int x, y; 5248 int x, y;
5150 int width, height, max_color_idx = 0; 5249 int width, height, max_color_idx = 0;
5151 XImagePtr ximg;
5152 Lisp_Object file, specified_file; 5250 Lisp_Object file, specified_file;
5153 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type; 5251 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
5154 unsigned char *contents = NULL; 5252 unsigned char *contents = NULL;
5155 unsigned char *end, *p; 5253 unsigned char *end, *p;
5156 ptrdiff_t size; 5254 ptrdiff_t size;
5255#ifdef USE_CAIRO
5256 unsigned char *data = 0;
5257 uint32_t *dataptr;
5258#else
5259 XImagePtr ximg;
5260#endif
5157 5261
5158 specified_file = image_spec_value (img->spec, QCfile, NULL); 5262 specified_file = image_spec_value (img->spec, QCfile, NULL);
5159 5263
@@ -5235,6 +5339,11 @@ pbm_load (struct frame *f, struct image *img)
5235 width = pbm_scan_number (&p, end); 5339 width = pbm_scan_number (&p, end);
5236 height = pbm_scan_number (&p, end); 5340 height = pbm_scan_number (&p, end);
5237 5341
5342#ifdef USE_CAIRO
5343 data = (unsigned char *) xmalloc (width * height * 4);
5344 dataptr = (uint32_t *) data;
5345#endif
5346
5238 if (type != PBM_MONO) 5347 if (type != PBM_MONO)
5239 { 5348 {
5240 max_color_idx = pbm_scan_number (&p, end); 5349 max_color_idx = pbm_scan_number (&p, end);
@@ -5251,8 +5360,10 @@ pbm_load (struct frame *f, struct image *img)
5251 goto error; 5360 goto error;
5252 } 5361 }
5253 5362
5363#ifndef USE_CAIRO
5254 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 5364 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
5255 goto error; 5365 goto error;
5366#endif
5256 5367
5257 /* Initialize the color hash table. */ 5368 /* Initialize the color hash table. */
5258 init_color_table (); 5369 init_color_table ();
@@ -5263,12 +5374,34 @@ pbm_load (struct frame *f, struct image *img)
5263 struct image_keyword fmt[PBM_LAST]; 5374 struct image_keyword fmt[PBM_LAST];
5264 unsigned long fg = FRAME_FOREGROUND_PIXEL (f); 5375 unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
5265 unsigned long bg = FRAME_BACKGROUND_PIXEL (f); 5376 unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
5266 5377#ifdef USE_CAIRO
5378 XColor xfg, xbg;
5379 int fga32, bga32;
5380#endif
5267 /* Parse the image specification. */ 5381 /* Parse the image specification. */
5268 memcpy (fmt, pbm_format, sizeof fmt); 5382 memcpy (fmt, pbm_format, sizeof fmt);
5269 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); 5383 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
5270 5384
5271 /* Get foreground and background colors, maybe allocate colors. */ 5385 /* Get foreground and background colors, maybe allocate colors. */
5386#ifdef USE_CAIRO
5387 if (! fmt[PBM_FOREGROUND].count
5388 || ! STRINGP (fmt[PBM_FOREGROUND].value)
5389 || ! x_defined_color (f, SSDATA (fmt[PBM_FOREGROUND].value), &xfg, 0))
5390 {
5391 xfg.pixel = fg;
5392 x_query_color (f, &xfg);
5393 }
5394 fga32 = xcolor_to_argb32 (xfg);
5395
5396 if (! fmt[PBM_BACKGROUND].count
5397 || ! STRINGP (fmt[PBM_BACKGROUND].value)
5398 || ! x_defined_color (f, SSDATA (fmt[PBM_BACKGROUND].value), &xbg, 0))
5399 {
5400 xbg.pixel = bg;
5401 x_query_color (f, &xbg);
5402 }
5403 bga32 = xcolor_to_argb32 (xbg);
5404#else
5272 if (fmt[PBM_FOREGROUND].count 5405 if (fmt[PBM_FOREGROUND].count
5273 && STRINGP (fmt[PBM_FOREGROUND].value)) 5406 && STRINGP (fmt[PBM_FOREGROUND].value))
5274 fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg); 5407 fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
@@ -5279,6 +5412,7 @@ pbm_load (struct frame *f, struct image *img)
5279 img->background = bg; 5412 img->background = bg;
5280 img->background_valid = 1; 5413 img->background_valid = 1;
5281 } 5414 }
5415#endif
5282 5416
5283 for (y = 0; y < height; ++y) 5417 for (y = 0; y < height; ++y)
5284 for (x = 0; x < width; ++x) 5418 for (x = 0; x < width; ++x)
@@ -5289,7 +5423,11 @@ pbm_load (struct frame *f, struct image *img)
5289 { 5423 {
5290 if (p >= end) 5424 if (p >= end)
5291 { 5425 {
5426#ifdef USE_CAIRO
5427 xfree (data);
5428#else
5292 x_destroy_x_image (ximg); 5429 x_destroy_x_image (ximg);
5430#endif
5293 x_clear_image (f, img); 5431 x_clear_image (f, img);
5294 image_error ("Invalid image size in image `%s'", 5432 image_error ("Invalid image size in image `%s'",
5295 img->spec, Qnil); 5433 img->spec, Qnil);
@@ -5303,7 +5441,11 @@ pbm_load (struct frame *f, struct image *img)
5303 else 5441 else
5304 g = pbm_scan_number (&p, end); 5442 g = pbm_scan_number (&p, end);
5305 5443
5444#ifdef USE_CAIRO
5445 *dataptr++ = g ? fga32 : bga32;
5446#else
5306 XPutPixel (ximg, x, y, g ? fg : bg); 5447 XPutPixel (ximg, x, y, g ? fg : bg);
5448#endif
5307 } 5449 }
5308 } 5450 }
5309 else 5451 else
@@ -5316,7 +5458,11 @@ pbm_load (struct frame *f, struct image *img)
5316 5458
5317 if (raw_p && p + expected_size > end) 5459 if (raw_p && p + expected_size > end)
5318 { 5460 {
5461#ifdef USE_CAIRO
5462 xfree (data);
5463#else
5319 x_destroy_x_image (ximg); 5464 x_destroy_x_image (ximg);
5465#endif
5320 x_clear_image (f, img); 5466 x_clear_image (f, img);
5321 image_error ("Invalid image size in image `%s'", 5467 image_error ("Invalid image size in image `%s'",
5322 img->spec, Qnil); 5468 img->spec, Qnil);
@@ -5357,18 +5503,29 @@ pbm_load (struct frame *f, struct image *img)
5357 5503
5358 if (r < 0 || g < 0 || b < 0) 5504 if (r < 0 || g < 0 || b < 0)
5359 { 5505 {
5506#ifdef USE_CAIRO
5507 xfree (data);
5508#else
5360 x_destroy_x_image (ximg); 5509 x_destroy_x_image (ximg);
5510#endif
5361 image_error ("Invalid pixel value in image `%s'", 5511 image_error ("Invalid pixel value in image `%s'",
5362 img->spec, Qnil); 5512 img->spec, Qnil);
5363 goto error; 5513 goto error;
5364 } 5514 }
5365 5515
5516#ifdef USE_CAIRO
5517 r = (double) r * 255 / max_color_idx;
5518 g = (double) g * 255 / max_color_idx;
5519 b = (double) b * 255 / max_color_idx;
5520 *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
5521#else
5366 /* RGB values are now in the range 0..max_color_idx. 5522 /* RGB values are now in the range 0..max_color_idx.
5367 Scale this to the range 0..0xffff supported by X. */ 5523 Scale this to the range 0..0xffff supported by X. */
5368 r = (double) r * 65535 / max_color_idx; 5524 r = (double) r * 65535 / max_color_idx;
5369 g = (double) g * 65535 / max_color_idx; 5525 g = (double) g * 65535 / max_color_idx;
5370 b = (double) b * 65535 / max_color_idx; 5526 b = (double) b * 65535 / max_color_idx;
5371 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); 5527 XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
5528#endif
5372 } 5529 }
5373 } 5530 }
5374 5531
@@ -5384,12 +5541,16 @@ pbm_load (struct frame *f, struct image *img)
5384 5541
5385 /* Maybe fill in the background field while we have ximg handy. */ 5542 /* Maybe fill in the background field while we have ximg handy. */
5386 5543
5544#ifdef USE_CAIRO
5545 create_cairo_image_surface (img, data, width, height);
5546#else
5387 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 5547 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5388 /* Casting avoids a GCC warning. */ 5548 /* Casting avoids a GCC warning. */
5389 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); 5549 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
5390 5550
5391 /* Put ximg into the image. */ 5551 /* Put ximg into the image. */
5392 image_put_x_image (f, img, ximg, 0); 5552 image_put_x_image (f, img, ximg, 0);
5553#endif
5393 5554
5394 /* X and W32 versions did it here, MAC version above. ++kfs 5555 /* X and W32 versions did it here, MAC version above. ++kfs
5395 img->width = width; 5556 img->width = width;
@@ -5404,7 +5565,7 @@ pbm_load (struct frame *f, struct image *img)
5404 PNG 5565 PNG
5405 ***********************************************************************/ 5566 ***********************************************************************/
5406 5567
5407#if defined (HAVE_PNG) || defined (HAVE_NS) 5568#if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
5408 5569
5409/* Function prototypes. */ 5570/* Function prototypes. */
5410 5571
@@ -5478,7 +5639,7 @@ png_image_p (Lisp_Object object)
5478 return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1; 5639 return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
5479} 5640}
5480 5641
5481#endif /* HAVE_PNG || HAVE_NS */ 5642#endif /* HAVE_PNG || HAVE_NS || USE_CAIRO */
5482 5643
5483 5644
5484#if defined HAVE_PNG && !defined HAVE_NS 5645#if defined HAVE_PNG && !defined HAVE_NS
@@ -5713,7 +5874,6 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5713 Lisp_Object specified_data; 5874 Lisp_Object specified_data;
5714 int x, y; 5875 int x, y;
5715 ptrdiff_t i; 5876 ptrdiff_t i;
5716 XImagePtr ximg, mask_img = NULL;
5717 png_struct *png_ptr; 5877 png_struct *png_ptr;
5718 png_info *info_ptr = NULL, *end_info = NULL; 5878 png_info *info_ptr = NULL, *end_info = NULL;
5719 FILE *fp = NULL; 5879 FILE *fp = NULL;
@@ -5727,6 +5887,13 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5727 bool transparent_p; 5887 bool transparent_p;
5728 struct png_memory_storage tbr; /* Data to be read */ 5888 struct png_memory_storage tbr; /* Data to be read */
5729 5889
5890#ifdef USE_CAIRO
5891 unsigned char *data = 0;
5892 uint32_t *dataptr;
5893#else
5894 XImagePtr ximg, mask_img = NULL;
5895#endif
5896
5730 /* Find out what file to load. */ 5897 /* Find out what file to load. */
5731 specified_file = image_spec_value (img->spec, QCfile, NULL); 5898 specified_file = image_spec_value (img->spec, QCfile, NULL);
5732 specified_data = image_spec_value (img->spec, QCdata, NULL); 5899 specified_data = image_spec_value (img->spec, QCdata, NULL);
@@ -5847,10 +6014,12 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5847 goto error; 6014 goto error;
5848 } 6015 }
5849 6016
6017#ifndef USE_CAIRO
5850 /* Create the X image and pixmap now, so that the work below can be 6018 /* Create the X image and pixmap now, so that the work below can be
5851 omitted if the image is too large for X. */ 6019 omitted if the image is too large for X. */
5852 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 6020 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
5853 goto error; 6021 goto error;
6022#endif
5854 6023
5855 /* If image contains simply transparency data, we prefer to 6024 /* If image contains simply transparency data, we prefer to
5856 construct a clipping mask. */ 6025 construct a clipping mask. */
@@ -5937,6 +6106,10 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5937 c->fp = NULL; 6106 c->fp = NULL;
5938 } 6107 }
5939 6108
6109#ifdef USE_CAIRO
6110 data = (unsigned char *) xmalloc (width * height * 4);
6111 dataptr = (uint32_t *) data;
6112#else
5940 /* Create an image and pixmap serving as mask if the PNG image 6113 /* Create an image and pixmap serving as mask if the PNG image
5941 contains an alpha channel. */ 6114 contains an alpha channel. */
5942 if (channels == 4 6115 if (channels == 4
@@ -5948,6 +6121,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5948 x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP); 6121 x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
5949 goto error; 6122 goto error;
5950 } 6123 }
6124#endif
5951 6125
5952 /* Fill the X image and mask from PNG data. */ 6126 /* Fill the X image and mask from PNG data. */
5953 init_color_table (); 6127 init_color_table ();
@@ -5960,6 +6134,14 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5960 { 6134 {
5961 int r, g, b; 6135 int r, g, b;
5962 6136
6137#ifdef USE_CAIRO
6138 int a = 0xff;
6139 r = *p++;
6140 g = *p++;
6141 b = *p++;
6142 if (channels == 4) a = *p++;
6143 *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
6144#else
5963 r = *p++ << 8; 6145 r = *p++ << 8;
5964 g = *p++ << 8; 6146 g = *p++ << 8;
5965 b = *p++ << 8; 6147 b = *p++ << 8;
@@ -5986,6 +6168,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5986 XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN); 6168 XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
5987 ++p; 6169 ++p;
5988 } 6170 }
6171#endif
5989 } 6172 }
5990 } 6173 }
5991 6174
@@ -6015,6 +6198,9 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6015 img->width = width; 6198 img->width = width;
6016 img->height = height; 6199 img->height = height;
6017 6200
6201#ifdef USE_CAIRO
6202 create_cairo_image_surface (img, data, width, height);
6203#else
6018 /* Maybe fill in the background field while we have ximg handy. 6204 /* Maybe fill in the background field while we have ximg handy.
6019 Casting avoids a GCC warning. */ 6205 Casting avoids a GCC warning. */
6020 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); 6206 IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
@@ -6031,6 +6217,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
6031 6217
6032 image_put_x_image (f, img, mask_img, 1); 6218 image_put_x_image (f, img, mask_img, 1);
6033 } 6219 }
6220#endif
6034 6221
6035 return 1; 6222 return 1;
6036} 6223}
@@ -6052,6 +6239,7 @@ png_load (struct frame *f, struct image *img)
6052 image_spec_value (img->spec, QCdata, NULL)); 6239 image_spec_value (img->spec, QCdata, NULL));
6053} 6240}
6054 6241
6242
6055#endif /* HAVE_NS */ 6243#endif /* HAVE_NS */
6056 6244
6057 6245
@@ -6463,9 +6651,12 @@ jpeg_load_body (struct frame *f, struct image *img,
6463 FILE * IF_LINT (volatile) fp = NULL; 6651 FILE * IF_LINT (volatile) fp = NULL;
6464 JSAMPARRAY buffer; 6652 JSAMPARRAY buffer;
6465 int row_stride, x, y; 6653 int row_stride, x, y;
6466 XImagePtr ximg = NULL;
6467 unsigned long *colors; 6654 unsigned long *colors;
6468 int width, height; 6655 int width, height;
6656 int i, ir, ig, ib;
6657#ifndef USE_CAIRO
6658 XImagePtr ximg = NULL;
6659#endif
6469 6660
6470 /* Open the JPEG file. */ 6661 /* Open the JPEG file. */
6471 specified_file = image_spec_value (img->spec, QCfile, NULL); 6662 specified_file = image_spec_value (img->spec, QCfile, NULL);
@@ -6525,8 +6716,9 @@ jpeg_load_body (struct frame *f, struct image *img,
6525 jpeg_destroy_decompress (&mgr->cinfo); 6716 jpeg_destroy_decompress (&mgr->cinfo);
6526 6717
6527 /* If we already have an XImage, free that. */ 6718 /* If we already have an XImage, free that. */
6719#ifndef USE_CAIRO
6528 x_destroy_x_image (ximg); 6720 x_destroy_x_image (ximg);
6529 6721#endif
6530 /* Free pixmap and colors. */ 6722 /* Free pixmap and colors. */
6531 x_clear_image (f, img); 6723 x_clear_image (f, img);
6532 return 0; 6724 return 0;
@@ -6560,12 +6752,14 @@ jpeg_load_body (struct frame *f, struct image *img,
6560 sys_longjmp (mgr->setjmp_buffer, 1); 6752 sys_longjmp (mgr->setjmp_buffer, 1);
6561 } 6753 }
6562 6754
6755#ifndef USE_CAIRO
6563 /* Create X image and pixmap. */ 6756 /* Create X image and pixmap. */
6564 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 6757 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
6565 { 6758 {
6566 mgr->failure_code = MY_JPEG_CANNOT_CREATE_X; 6759 mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
6567 sys_longjmp (mgr->setjmp_buffer, 1); 6760 sys_longjmp (mgr->setjmp_buffer, 1);
6568 } 6761 }
6762#endif
6569 6763
6570 /* Allocate colors. When color quantization is used, 6764 /* Allocate colors. When color quantization is used,
6571 mgr->cinfo.actual_number_of_colors has been set with the number of 6765 mgr->cinfo.actual_number_of_colors has been set with the number of
@@ -6574,8 +6768,6 @@ jpeg_load_body (struct frame *f, struct image *img,
6574 No more than 255 colors will be generated. */ 6768 No more than 255 colors will be generated. */
6575 USE_SAFE_ALLOCA; 6769 USE_SAFE_ALLOCA;
6576 { 6770 {
6577 int i, ir, ig, ib;
6578
6579 if (mgr->cinfo.out_color_components > 2) 6771 if (mgr->cinfo.out_color_components > 2)
6580 ir = 0, ig = 1, ib = 2; 6772 ir = 0, ig = 1, ib = 2;
6581 else if (mgr->cinfo.out_color_components > 1) 6773 else if (mgr->cinfo.out_color_components > 1)
@@ -6583,6 +6775,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6583 else 6775 else
6584 ir = 0, ig = 0, ib = 0; 6776 ir = 0, ig = 0, ib = 0;
6585 6777
6778#ifndef CAIRO
6586 /* Use the color table mechanism because it handles colors that 6779 /* Use the color table mechanism because it handles colors that
6587 cannot be allocated nicely. Such colors will be replaced with 6780 cannot be allocated nicely. Such colors will be replaced with
6588 a default color, and we don't have to care about which colors 6781 a default color, and we don't have to care about which colors
@@ -6599,6 +6792,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6599 int b = mgr->cinfo.colormap[ib][i] << 8; 6792 int b = mgr->cinfo.colormap[ib][i] << 8;
6600 colors[i] = lookup_rgb_color (f, r, g, b); 6793 colors[i] = lookup_rgb_color (f, r, g, b);
6601 } 6794 }
6795#endif
6602 6796
6603#ifdef COLOR_TABLE_SUPPORT 6797#ifdef COLOR_TABLE_SUPPORT
6604 /* Remember those colors actually allocated. */ 6798 /* Remember those colors actually allocated. */
@@ -6611,12 +6805,36 @@ jpeg_load_body (struct frame *f, struct image *img,
6611 row_stride = width * mgr->cinfo.output_components; 6805 row_stride = width * mgr->cinfo.output_components;
6612 buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo, 6806 buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
6613 JPOOL_IMAGE, row_stride, 1); 6807 JPOOL_IMAGE, row_stride, 1);
6808#ifdef USE_CAIRO
6809 {
6810 unsigned char *data = (unsigned char *) xmalloc (width*height*4);
6811 uint32_t *dataptr = (uint32_t *) data;
6812 int r, g, b;
6813
6814 for (y = 0; y < height; ++y)
6815 {
6816 jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
6817
6818 for (x = 0; x < width; ++x)
6819 {
6820 i = buffer[0][x];
6821 r = mgr->cinfo.colormap[ir][i];
6822 g = mgr->cinfo.colormap[ig][i];
6823 b = mgr->cinfo.colormap[ib][i];
6824 *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
6825 }
6826 }
6827
6828 create_cairo_image_surface (img, data, width, height);
6829 }
6830#else
6614 for (y = 0; y < height; ++y) 6831 for (y = 0; y < height; ++y)
6615 { 6832 {
6616 jpeg_read_scanlines (&mgr->cinfo, buffer, 1); 6833 jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
6617 for (x = 0; x < mgr->cinfo.output_width; ++x) 6834 for (x = 0; x < mgr->cinfo.output_width; ++x)
6618 XPutPixel (ximg, x, y, colors[buffer[0][x]]); 6835 XPutPixel (ximg, x, y, colors[buffer[0][x]]);
6619 } 6836 }
6837#endif
6620 6838
6621 /* Clean up. */ 6839 /* Clean up. */
6622 jpeg_finish_decompress (&mgr->cinfo); 6840 jpeg_finish_decompress (&mgr->cinfo);
@@ -6624,6 +6842,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6624 if (fp) 6842 if (fp)
6625 fclose (fp); 6843 fclose (fp);
6626 6844
6845#ifndef USE_CAIRO
6627 /* Maybe fill in the background field while we have ximg handy. */ 6846 /* Maybe fill in the background field while we have ximg handy. */
6628 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 6847 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6629 /* Casting avoids a GCC warning. */ 6848 /* Casting avoids a GCC warning. */
@@ -6631,6 +6850,7 @@ jpeg_load_body (struct frame *f, struct image *img,
6631 6850
6632 /* Put ximg into the image. */ 6851 /* Put ximg into the image. */
6633 image_put_x_image (f, img, ximg, 0); 6852 image_put_x_image (f, img, ximg, 0);
6853#endif
6634 SAFE_FREE (); 6854 SAFE_FREE ();
6635 return 1; 6855 return 1;
6636} 6856}
@@ -7063,6 +7283,29 @@ tiff_load (struct frame *f, struct image *img)
7063 return 0; 7283 return 0;
7064 } 7284 }
7065 7285
7286#ifdef USE_CAIRO
7287 {
7288 unsigned char *data = (unsigned char *) xmalloc (width*height*4);
7289 uint32_t *dataptr = (uint32_t *) data;
7290 int r, g, b, a;
7291
7292 for (y = 0; y < height; ++y)
7293 {
7294 uint32 *row = buf + (height - 1 - y) * width;
7295 for (x = 0; x < width; ++x)
7296 {
7297 uint32 abgr = row[x];
7298 int r = TIFFGetR (abgr);
7299 int g = TIFFGetG (abgr);
7300 int b = TIFFGetB (abgr);
7301 int a = TIFFGetA (abgr);
7302 *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
7303 }
7304 }
7305
7306 create_cairo_image_surface (img, data, width, height);
7307 }
7308#else
7066 /* Initialize the color table. */ 7309 /* Initialize the color table. */
7067 init_color_table (); 7310 init_color_table ();
7068 7311
@@ -7097,8 +7340,10 @@ tiff_load (struct frame *f, struct image *img)
7097 7340
7098 /* Put ximg into the image. */ 7341 /* Put ximg into the image. */
7099 image_put_x_image (f, img, ximg, 0); 7342 image_put_x_image (f, img, ximg, 0);
7100 xfree (buf);
7101 7343
7344#endif /* ! USE_CAIRO */
7345
7346 xfree (buf);
7102 return 1; 7347 return 1;
7103} 7348}
7104 7349
@@ -7348,7 +7593,6 @@ gif_load (struct frame *f, struct image *img)
7348{ 7593{
7349 Lisp_Object file; 7594 Lisp_Object file;
7350 int rc, width, height, x, y, i, j; 7595 int rc, width, height, x, y, i, j;
7351 XImagePtr ximg;
7352 ColorMapObject *gif_color_map; 7596 ColorMapObject *gif_color_map;
7353 unsigned long pixel_colors[256]; 7597 unsigned long pixel_colors[256];
7354 GifFileType *gif; 7598 GifFileType *gif;
@@ -7360,6 +7604,12 @@ gif_load (struct frame *f, struct image *img)
7360 EMACS_INT idx; 7604 EMACS_INT idx;
7361 int gif_err; 7605 int gif_err;
7362 7606
7607#ifdef USE_CAIRO
7608 unsigned char *data = 0;
7609#else
7610 XImagePtr ximg;
7611#endif
7612
7363 if (NILP (specified_data)) 7613 if (NILP (specified_data))
7364 { 7614 {
7365 file = x_find_image_file (specified_file); 7615 file = x_find_image_file (specified_file);
@@ -7488,6 +7738,25 @@ gif_load (struct frame *f, struct image *img)
7488 } 7738 }
7489 } 7739 }
7490 7740
7741#ifdef USE_CAIRO
7742 /* xzalloc so data is zero => transparent */
7743 data = (unsigned char *) xzalloc (width * height * 4);
7744 if (STRINGP (specified_bg))
7745 {
7746 XColor color;
7747 if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
7748 {
7749 uint32_t *dataptr = (uint32_t *)data;
7750 int r = color.red/256;
7751 int g = color.green/256;
7752 int b = color.blue/256;
7753
7754 for (y = 0; y < height; ++y)
7755 for (x = 0; x < width; ++x)
7756 *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
7757 }
7758 }
7759#else
7491 /* Create the X image and pixmap. */ 7760 /* Create the X image and pixmap. */
7492 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 7761 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
7493 { 7762 {
@@ -7514,6 +7783,7 @@ gif_load (struct frame *f, struct image *img)
7514 for (x = img->corners[RIGHT_CORNER]; x < width; ++x) 7783 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
7515 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f)); 7784 XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
7516 } 7785 }
7786#endif
7517 7787
7518 /* Read the GIF image into the X image. */ 7788 /* Read the GIF image into the X image. */
7519 7789
@@ -7568,12 +7838,14 @@ gif_load (struct frame *f, struct image *img)
7568 if (disposal == 0) 7838 if (disposal == 0)
7569 disposal = 1; 7839 disposal = 1;
7570 7840
7571 /* Allocate subimage colors. */
7572 memset (pixel_colors, 0, sizeof pixel_colors);
7573 gif_color_map = subimage->ImageDesc.ColorMap; 7841 gif_color_map = subimage->ImageDesc.ColorMap;
7574 if (!gif_color_map) 7842 if (!gif_color_map)
7575 gif_color_map = gif->SColorMap; 7843 gif_color_map = gif->SColorMap;
7576 7844
7845#ifndef USE_CAIRO
7846 /* Allocate subimage colors. */
7847 memset (pixel_colors, 0, sizeof pixel_colors);
7848
7577 if (gif_color_map) 7849 if (gif_color_map)
7578 for (i = 0; i < gif_color_map->ColorCount; ++i) 7850 for (i = 0; i < gif_color_map->ColorCount; ++i)
7579 { 7851 {
@@ -7588,6 +7860,7 @@ gif_load (struct frame *f, struct image *img)
7588 pixel_colors[i] = lookup_rgb_color (f, r, g, b); 7860 pixel_colors[i] = lookup_rgb_color (f, r, g, b);
7589 } 7861 }
7590 } 7862 }
7863#endif
7591 7864
7592 /* Apply the pixel values. */ 7865 /* Apply the pixel values. */
7593 if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace) 7866 if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace)
@@ -7605,20 +7878,47 @@ gif_load (struct frame *f, struct image *img)
7605 { 7878 {
7606 int c = raster[y * subimg_width + x]; 7879 int c = raster[y * subimg_width + x];
7607 if (transparency_color_index != c || disposal != 1) 7880 if (transparency_color_index != c || disposal != 1)
7608 XPutPixel (ximg, x + subimg_left, row + subimg_top, 7881 {
7609 pixel_colors[c]); 7882#ifdef USE_CAIRO
7883 uint32_t *dataptr =
7884 ((uint32_t*)data + ((row + subimg_top) * subimg_width
7885 + x + subimg_left));
7886 int r = gif_color_map->Colors[c].Red;
7887 int g = gif_color_map->Colors[c].Green;
7888 int b = gif_color_map->Colors[c].Blue;
7889
7890 if (transparency_color_index != c)
7891 *dataptr = (0xff << 24) | (r << 16) | (g << 8) | b;
7892#else
7893 XPutPixel (ximg, x + subimg_left, row + subimg_top,
7894 pixel_colors[c]);
7895#endif
7896 }
7610 } 7897 }
7611 } 7898 }
7612 } 7899 }
7613 else 7900 else
7614 { 7901 {
7615 for (y = 0; y < subimg_height; ++y) 7902 for (y = 0; y < subimg_height; ++y)
7616 for (x = 0; x < subimg_width; ++x) 7903 for (x = 0; x < subimg_width; ++x)
7617 { 7904 {
7618 int c = raster[y * subimg_width + x]; 7905 int c = raster[y * subimg_width + x];
7619 if (transparency_color_index != c || disposal != 1) 7906 if (transparency_color_index != c || disposal != 1)
7620 XPutPixel (ximg, x + subimg_left, y + subimg_top, 7907 {
7621 pixel_colors[c]); 7908#ifdef USE_CAIRO
7909 uint32_t *dataptr =
7910 ((uint32_t*)data + ((y + subimg_top) * subimg_width
7911 + x + subimg_left));
7912 int r = gif_color_map->Colors[c].Red;
7913 int g = gif_color_map->Colors[c].Green;
7914 int b = gif_color_map->Colors[c].Blue;
7915 if (transparency_color_index != c)
7916 *dataptr = (0xff << 24) | (r << 16) | (g << 8) | b;
7917#else
7918 XPutPixel (ximg, x + subimg_left, y + subimg_top,
7919 pixel_colors[c]);
7920#endif
7921 }
7622 } 7922 }
7623 } 7923 }
7624 } 7924 }
@@ -7675,6 +7975,9 @@ gif_load (struct frame *f, struct image *img)
7675#endif 7975#endif
7676 } 7976 }
7677 7977
7978#ifdef USE_CAIRO
7979 create_cairo_image_surface (img, data, width, height);
7980#else
7678 /* Maybe fill in the background field while we have ximg handy. */ 7981 /* Maybe fill in the background field while we have ximg handy. */
7679 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 7982 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7680 /* Casting avoids a GCC warning. */ 7983 /* Casting avoids a GCC warning. */
@@ -7682,6 +7985,7 @@ gif_load (struct frame *f, struct image *img)
7682 7985
7683 /* Put ximg into the image. */ 7986 /* Put ximg into the image. */
7684 image_put_x_image (f, img, ximg, 0); 7987 image_put_x_image (f, img, ximg, 0);
7988#endif
7685 7989
7686 return 1; 7990 return 1;
7687} 7991}
@@ -8901,6 +9205,37 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
8901 eassert (gdk_pixbuf_get_has_alpha (pixbuf)); 9205 eassert (gdk_pixbuf_get_has_alpha (pixbuf));
8902 eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); 9206 eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
8903 9207
9208#ifdef USE_CAIRO
9209 {
9210 unsigned char *data = (unsigned char *) xmalloc (width*height*4);
9211 int y;
9212 uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
9213
9214 for (y = 0; y < height; ++y)
9215 {
9216 const guchar *iconptr = pixels + y * rowstride;
9217 uint32_t *dataptr = (uint32_t *) (data + y * rowstride);
9218 int x;
9219
9220 for (x = 0; x < width; ++x)
9221 {
9222 if (iconptr[3] == 0)
9223 *dataptr = bgcolor;
9224 else
9225 *dataptr = (iconptr[0] << 16)
9226 | (iconptr[1] << 8)
9227 | iconptr[2]
9228 | (iconptr[3] << 24);
9229
9230 iconptr += 4;
9231 ++dataptr;
9232 }
9233 }
9234
9235 create_cairo_image_surface (img, data, width, height);
9236 g_object_unref (pixbuf);
9237 }
9238#else
8904 /* Try to create a x pixmap to hold the svg pixmap. */ 9239 /* Try to create a x pixmap to hold the svg pixmap. */
8905 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) 9240 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
8906 { 9241 {
@@ -8972,6 +9307,7 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
8972 9307
8973 /* Put ximg into the image. */ 9308 /* Put ximg into the image. */
8974 image_put_x_image (f, img, ximg, 0); 9309 image_put_x_image (f, img, ximg, 0);
9310#endif /* ! USE_CAIRO */
8975 9311
8976 return 1; 9312 return 1;
8977 9313
@@ -9239,15 +9575,16 @@ x_kill_gs_process (Pixmap pixmap, struct frame *f)
9239 /* For each pixel of the image, look its color up in the 9575 /* For each pixel of the image, look its color up in the
9240 color table. After having done so, the color table will 9576 color table. After having done so, the color table will
9241 contain an entry for each color used by the image. */ 9577 contain an entry for each color used by the image. */
9578#ifdef COLOR_TABLE_SUPPORT
9242 for (y = 0; y < img->height; ++y) 9579 for (y = 0; y < img->height; ++y)
9243 for (x = 0; x < img->width; ++x) 9580 for (x = 0; x < img->width; ++x)
9244 { 9581 {
9245 unsigned long pixel = XGetPixel (ximg, x, y); 9582 unsigned long pixel = XGetPixel (ximg, x, y);
9583
9246 lookup_pixel_color (f, pixel); 9584 lookup_pixel_color (f, pixel);
9247 } 9585 }
9248 9586
9249 /* Record colors in the image. Free color table and XImage. */ 9587 /* Record colors in the image. Free color table and XImage. */
9250#ifdef COLOR_TABLE_SUPPORT
9251 img->colors = colors_in_color_table (&img->ncolors); 9588 img->colors = colors_in_color_table (&img->ncolors);
9252 free_color_table (); 9589 free_color_table ();
9253#endif 9590#endif
@@ -9360,7 +9697,7 @@ lookup_image_type (Lisp_Object type)
9360 return define_image_type (&gif_type); 9697 return define_image_type (&gif_type);
9361#endif 9698#endif
9362 9699
9363#if defined (HAVE_PNG) || defined (HAVE_NS) 9700#if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
9364 if (EQ (type, Qpng)) 9701 if (EQ (type, Qpng))
9365 return define_image_type (&png_type); 9702 return define_image_type (&png_type);
9366#endif 9703#endif