diff options
| author | Jan D | 2015-04-03 18:10:27 +0200 |
|---|---|---|
| committer | Jan D | 2015-04-03 18:10:27 +0200 |
| commit | 74c4ce27b510b90c29d25c462d9b84b203d00252 (patch) | |
| tree | 465be24a6c2d3b8be458c0f7d81ad110d367a1d6 /src | |
| parent | 5558a14438172634e8802cbaa87abc265e5d7a4c (diff) | |
| download | emacs-74c4ce27b510b90c29d25c462d9b84b203d00252.tar.gz emacs-74c4ce27b510b90c29d25c462d9b84b203d00252.zip | |
Introduce limited Xpm support (32 bit ZPixmap) for Cairo.
* configure.ac (HAVE_RSVG): Move after cairo.
(USE_CAIRO): Disable rsvg, don't disable Xpm.
* src/image.c (prepare_image_for_display): Don't load if USE_CAIRO.
(x_clear_image): If USE_CAIRO, also free possible img->ximg->obdata and
don't return early.
(ALLOC_XPM_COLORS): Don't define when USE_CAIRO.
(xpm_load): Convert simple Xpms (32 bit ZPixmap) to CAIRO_FORMAT_ARGB32
and create a surface.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/image.c | 58 |
2 files changed, 63 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index f7941e04280..1a473e65386 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,12 @@ | |||
| 1 | 2015-04-03 Jan Djärv <jan.h.d@swipnet.se> | 1 | 2015-04-03 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 2 | ||
| 3 | * image.c (prepare_image_for_display): Don't load if USE_CAIRO. | ||
| 4 | (x_clear_image): If USE_CAIRO, also free possible img->ximg->obdata and | ||
| 5 | don't return early. | ||
| 6 | (ALLOC_XPM_COLORS): Don't define when USE_CAIRO. | ||
| 7 | (xpm_load): Convert simple Xpms (32 bit ZPixmap) to CAIRO_FORMAT_ARGB32 | ||
| 8 | and create a surface. | ||
| 9 | |||
| 3 | * xterm.c (handle_one_xevent): Always redraw tool tips on | 10 | * xterm.c (handle_one_xevent): Always redraw tool tips on |
| 4 | MapNotify. Update tool tip frame sizes on ConfigureNotify. | 11 | MapNotify. Update tool tip frame sizes on ConfigureNotify. |
| 5 | (x_update_begin): Don't create any surface for non-visible | 12 | (x_update_begin): Don't create any surface for non-visible |
diff --git a/src/image.c b/src/image.c index 09d068725d7..e24bc589ef0 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1019,6 +1019,7 @@ prepare_image_for_display (struct frame *f, struct image *img) | |||
| 1019 | /* We're about to display IMG, so set its timestamp to `now'. */ | 1019 | /* We're about to display IMG, so set its timestamp to `now'. */ |
| 1020 | img->timestamp = current_timespec (); | 1020 | img->timestamp = current_timespec (); |
| 1021 | 1021 | ||
| 1022 | #ifndef USE_CAIRO | ||
| 1022 | /* If IMG doesn't have a pixmap yet, load it now, using the image | 1023 | /* If IMG doesn't have a pixmap yet, load it now, using the image |
| 1023 | type dependent loader function. */ | 1024 | type dependent loader function. */ |
| 1024 | if (img->pixmap == NO_PIXMAP && !img->load_failed_p) | 1025 | if (img->pixmap == NO_PIXMAP && !img->load_failed_p) |
| @@ -1032,6 +1033,7 @@ prepare_image_for_display (struct frame *f, struct image *img) | |||
| 1032 | unblock_input (); | 1033 | unblock_input (); |
| 1033 | } | 1034 | } |
| 1034 | #endif | 1035 | #endif |
| 1036 | #endif | ||
| 1035 | } | 1037 | } |
| 1036 | 1038 | ||
| 1037 | 1039 | ||
| @@ -1303,8 +1305,7 @@ x_clear_image (struct frame *f, struct image *img) | |||
| 1303 | if (img->cr_data) | 1305 | if (img->cr_data) |
| 1304 | { | 1306 | { |
| 1305 | cairo_surface_destroy ((cairo_surface_t *)img->cr_data); | 1307 | cairo_surface_destroy ((cairo_surface_t *)img->cr_data); |
| 1306 | unblock_input (); | 1308 | if (img->ximg && img->ximg->obdata) xfree (img->ximg->obdata); |
| 1307 | return; | ||
| 1308 | } | 1309 | } |
| 1309 | #endif | 1310 | #endif |
| 1310 | x_clear_image_1 (f, img, | 1311 | x_clear_image_1 (f, img, |
| @@ -3162,9 +3163,11 @@ static struct image_type xpm_type = | |||
| 3162 | color allocation failures more gracefully than the ones on the XPM | 3163 | color allocation failures more gracefully than the ones on the XPM |
| 3163 | lib. */ | 3164 | lib. */ |
| 3164 | 3165 | ||
| 3166 | #ifndef USE_CAIRO | ||
| 3165 | #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure | 3167 | #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure |
| 3166 | #define ALLOC_XPM_COLORS | 3168 | #define ALLOC_XPM_COLORS |
| 3167 | #endif | 3169 | #endif |
| 3170 | #endif /* USE_CAIRO */ | ||
| 3168 | #endif /* HAVE_X_WINDOWS */ | 3171 | #endif /* HAVE_X_WINDOWS */ |
| 3169 | 3172 | ||
| 3170 | #ifdef ALLOC_XPM_COLORS | 3173 | #ifdef ALLOC_XPM_COLORS |
| @@ -3625,6 +3628,56 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3625 | #endif /* HAVE_NTGUI */ | 3628 | #endif /* HAVE_NTGUI */ |
| 3626 | } | 3629 | } |
| 3627 | 3630 | ||
| 3631 | #ifdef USE_CAIRO | ||
| 3632 | // Load very specific Xpm:s. | ||
| 3633 | if (rc == XpmSuccess | ||
| 3634 | && img->ximg->format == ZPixmap | ||
| 3635 | && img->ximg->bits_per_pixel == 32 | ||
| 3636 | && img->mask_img->bits_per_pixel == 1) | ||
| 3637 | { | ||
| 3638 | cairo_surface_t *surface; | ||
| 3639 | int width = img->ximg->width; | ||
| 3640 | int height = img->ximg->height; | ||
| 3641 | cairo_format_t format = CAIRO_FORMAT_ARGB32; | ||
| 3642 | int stride = cairo_format_stride_for_width (format, width); | ||
| 3643 | unsigned char *data = (unsigned char *) | ||
| 3644 | xmalloc (width*height*4); | ||
| 3645 | int i; | ||
| 3646 | uint32_t *od = (uint32_t *)data; | ||
| 3647 | uint32_t *id = (uint32_t *)img->ximg->data; | ||
| 3648 | unsigned char *mid = img->mask_img->data; | ||
| 3649 | |||
| 3650 | for (i = 0; i < height; ++i) | ||
| 3651 | { | ||
| 3652 | int k; | ||
| 3653 | for (k = 0; k < width; ++k) | ||
| 3654 | { | ||
| 3655 | int idx = i * img->ximg->bytes_per_line/4 + k; | ||
| 3656 | int maskidx = i * img->mask_img->bytes_per_line + k/8; | ||
| 3657 | int mask = mid[maskidx] & (1 << (k % 8)); | ||
| 3658 | |||
| 3659 | if (mask) od[idx] = id[idx] + 0xff000000; // ff => full alpha | ||
| 3660 | else od[idx] = 0; | ||
| 3661 | } | ||
| 3662 | } | ||
| 3663 | |||
| 3664 | surface = cairo_image_surface_create_for_data (data, | ||
| 3665 | format, | ||
| 3666 | width, | ||
| 3667 | height, | ||
| 3668 | stride); | ||
| 3669 | img->width = cairo_image_surface_get_width (surface); | ||
| 3670 | img->height = cairo_image_surface_get_height (surface); | ||
| 3671 | img->cr_data = surface; | ||
| 3672 | img->pixmap = 0; | ||
| 3673 | img->ximg->obdata = (char *)data; | ||
| 3674 | } | ||
| 3675 | else | ||
| 3676 | { | ||
| 3677 | rc = XpmFileInvalid; | ||
| 3678 | x_clear_image (f, img); | ||
| 3679 | } | ||
| 3680 | #else | ||
| 3628 | #ifdef HAVE_X_WINDOWS | 3681 | #ifdef HAVE_X_WINDOWS |
| 3629 | if (rc == XpmSuccess) | 3682 | if (rc == XpmSuccess) |
| 3630 | { | 3683 | { |
| @@ -3650,6 +3703,7 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3650 | } | 3703 | } |
| 3651 | } | 3704 | } |
| 3652 | #endif | 3705 | #endif |
| 3706 | #endif /* ! USE_CAIRO */ | ||
| 3653 | 3707 | ||
| 3654 | if (rc == XpmSuccess) | 3708 | if (rc == XpmSuccess) |
| 3655 | { | 3709 | { |