diff options
| author | Jan D | 2015-05-23 12:34:45 +0200 |
|---|---|---|
| committer | Jan D | 2015-05-23 12:34:45 +0200 |
| commit | c03c730481bd2dc7bc857d9b4f1c41eea9bd495e (patch) | |
| tree | a34eb6ad435ab877848f7464374570549ca55ec5 /src/image.c | |
| parent | 7ac84a2570e1268cc040fcd529508307b2b22c01 (diff) | |
| parent | 6aaa489dc112f51f6045f79b37cb78dd513e398f (diff) | |
| download | emacs-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.c | 379 |
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 | ||
| 1087 | static uint32_t | ||
| 1088 | xcolor_to_argb32 (XColor xc) | ||
| 1089 | { | ||
| 1090 | return (0xff << 24) | ((xc.red / 256) << 16) | ||
| 1091 | | ((xc.green / 256) << 8) | (xc.blue / 256); | ||
| 1092 | } | ||
| 1093 | |||
| 1094 | static uint32_t | ||
| 1095 | get_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 | |||
| 1111 | static void | ||
| 1112 | create_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 | |||
| 1299 | x_clear_image (struct frame *f, struct image *img) | 1352 | x_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 |