From 74c4ce27b510b90c29d25c462d9b84b203d00252 Mon Sep 17 00:00:00 2001 From: Jan D Date: Fri, 3 Apr 2015 18:10:27 +0200 Subject: [PATCH] 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. --- ChangeLog | 5 +++++ configure.ac | 46 ++++++++++++++++++++-------------------- src/ChangeLog | 7 +++++++ src/image.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 91 insertions(+), 25 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ffd4a184a8..6e8cadebb15 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2015-04-03 Jan Djärv + + * configure.ac (HAVE_RSVG): Move after cairo. + (USE_CAIRO): Disable rsvg, don't disable Xpm. + 2015-04-03 Ulrich Müller * configure.ac (LD_SWITCH_SYSTEM_TEMACS): Add -nopie option if it diff --git a/configure.ac b/configure.ac index f2cb28dba98..9d4e3758fda 100644 --- a/configure.ac +++ b/configure.ac @@ -2361,28 +2361,6 @@ fail; fi -### Use -lrsvg-2 if available, unless `--with-rsvg=no' is specified. -HAVE_RSVG=no -if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" = "mingw32"; then - if test "${with_rsvg}" != "no"; then - RSVG_REQUIRED=2.11.0 - RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED" - - EMACS_CHECK_MODULES([RSVG], [$RSVG_MODULE]) - AC_SUBST(RSVG_CFLAGS) - AC_SUBST(RSVG_LIBS) - - if test $HAVE_RSVG = yes; then - AC_DEFINE(HAVE_RSVG, 1, [Define to 1 if using librsvg.]) - CFLAGS="$CFLAGS $RSVG_CFLAGS" - # Windows loads librsvg dynamically - if test "${opsys}" = "mingw32"; then - RSVG_LIBS= - fi - fi - fi -fi - HAVE_IMAGEMAGICK=no if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes"; then if test "${with_imagemagick}" != "no"; then @@ -3111,10 +3089,10 @@ if test "${HAVE_X11}" = "yes"; then else AC_MSG_ERROR([cairo requested but not found.]) fi - with_xpm=no with_jpeg=no with_gif=no with_tiff=no + with_rsvg=no CFLAGS="$CFLAGS $CAIRO_CFLAGS" LIBS="$LIBS $CAIRO_LIBS" @@ -3123,6 +3101,28 @@ if test "${HAVE_X11}" = "yes"; then fi fi +### Use -lrsvg-2 if available, unless `--with-rsvg=no' is specified. +HAVE_RSVG=no +if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" = "mingw32"; then + if test "${with_rsvg}" != "no"; then + RSVG_REQUIRED=2.11.0 + RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED" + + EMACS_CHECK_MODULES([RSVG], [$RSVG_MODULE]) + AC_SUBST(RSVG_CFLAGS) + AC_SUBST(RSVG_LIBS) + + if test $HAVE_RSVG = yes; then + AC_DEFINE(HAVE_RSVG, 1, [Define to 1 if using librsvg.]) + CFLAGS="$CFLAGS $RSVG_CFLAGS" + # Windows loads librsvg dynamically + if test "${opsys}" = "mingw32"; then + RSVG_LIBS= + fi + fi + fi +fi + ### Use -lXpm if available, unless `--with-xpm=no'. ### mingw32 doesn't use -lXpm, since it loads the library dynamically. diff --git a/src/ChangeLog b/src/ChangeLog index f7941e04280..1a473e65386 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,12 @@ 2015-04-03 Jan Djärv + * 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. + * xterm.c (handle_one_xevent): Always redraw tool tips on MapNotify. Update tool tip frame sizes on ConfigureNotify. (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) /* We're about to display IMG, so set its timestamp to `now'. */ img->timestamp = current_timespec (); +#ifndef USE_CAIRO /* If IMG doesn't have a pixmap yet, load it now, using the image type dependent loader function. */ if (img->pixmap == NO_PIXMAP && !img->load_failed_p) @@ -1032,6 +1033,7 @@ prepare_image_for_display (struct frame *f, struct image *img) unblock_input (); } #endif +#endif } @@ -1303,8 +1305,7 @@ x_clear_image (struct frame *f, struct image *img) if (img->cr_data) { cairo_surface_destroy ((cairo_surface_t *)img->cr_data); - unblock_input (); - return; + if (img->ximg && img->ximg->obdata) xfree (img->ximg->obdata); } #endif x_clear_image_1 (f, img, @@ -3162,9 +3163,11 @@ static struct image_type xpm_type = color allocation failures more gracefully than the ones on the XPM lib. */ +#ifndef USE_CAIRO #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure #define ALLOC_XPM_COLORS #endif +#endif /* USE_CAIRO */ #endif /* HAVE_X_WINDOWS */ #ifdef ALLOC_XPM_COLORS @@ -3625,6 +3628,56 @@ xpm_load (struct frame *f, struct image *img) #endif /* HAVE_NTGUI */ } +#ifdef USE_CAIRO + // Load very specific Xpm:s. + if (rc == XpmSuccess + && img->ximg->format == ZPixmap + && img->ximg->bits_per_pixel == 32 + && img->mask_img->bits_per_pixel == 1) + { + cairo_surface_t *surface; + int width = img->ximg->width; + int height = img->ximg->height; + cairo_format_t format = CAIRO_FORMAT_ARGB32; + int stride = cairo_format_stride_for_width (format, width); + unsigned char *data = (unsigned char *) + xmalloc (width*height*4); + int i; + uint32_t *od = (uint32_t *)data; + uint32_t *id = (uint32_t *)img->ximg->data; + unsigned char *mid = img->mask_img->data; + + for (i = 0; i < height; ++i) + { + int k; + for (k = 0; k < width; ++k) + { + int idx = i * img->ximg->bytes_per_line/4 + k; + int maskidx = i * img->mask_img->bytes_per_line + k/8; + int mask = mid[maskidx] & (1 << (k % 8)); + + if (mask) od[idx] = id[idx] + 0xff000000; // ff => full alpha + else od[idx] = 0; + } + } + + surface = cairo_image_surface_create_for_data (data, + format, + width, + height, + stride); + img->width = cairo_image_surface_get_width (surface); + img->height = cairo_image_surface_get_height (surface); + img->cr_data = surface; + img->pixmap = 0; + img->ximg->obdata = (char *)data; + } + else + { + rc = XpmFileInvalid; + x_clear_image (f, img); + } +#else #ifdef HAVE_X_WINDOWS if (rc == XpmSuccess) { @@ -3650,6 +3703,7 @@ xpm_load (struct frame *f, struct image *img) } } #endif +#endif /* ! USE_CAIRO */ if (rc == XpmSuccess) { -- 2.39.5