#endif /* HAVE_NTGUI */
+#ifdef USE_CAIRO
+#undef COLOR_TABLE_SUPPORT
+#endif
+
#ifdef HAVE_NS
#undef COLOR_TABLE_SUPPORT
#endif /* HAVE_NTGUI */
#ifdef HAVE_NS
- void *bitmap = ns_image_from_XBM (bits, width, height);
+ void *bitmap = ns_image_from_XBM (bits, width, height, 0, 0);
if (!bitmap)
return -1;
#endif
#endif /* HAVE_X_WINDOWS */
-
/***********************************************************************
Image types
***********************************************************************/
/* 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)
unblock_input ();
}
#endif
+#endif
}
return ascent;
}
+#ifdef USE_CAIRO
+static uint32_t
+xcolor_to_argb32 (XColor xc)
+{
+ return (0xff << 24) | ((xc.red / 256) << 16)
+ | ((xc.green / 256) << 8) | (xc.blue / 256);
+}
+
+static uint32_t
+get_spec_bg_or_alpha_as_argb (struct image *img,
+ struct frame *f)
+{
+ uint32_t bgcolor = 0;
+ XColor xbgcolor;
+ Lisp_Object bg = image_spec_value (img->spec, QCbackground, NULL);
+
+ if (STRINGP (bg) && XParseColor (FRAME_X_DISPLAY (f),
+ FRAME_X_COLORMAP (f),
+ SSDATA (bg),
+ &xbgcolor))
+ bgcolor = xcolor_to_argb32 (xbgcolor);
+
+ return bgcolor;
+}
+
+static void
+create_cairo_image_surface (struct image *img,
+ unsigned char *data,
+ int width,
+ int height)
+{
+ cairo_surface_t *surface;
+ cairo_format_t format = CAIRO_FORMAT_ARGB32;
+ int stride = cairo_format_stride_for_width (format, width);
+ surface = cairo_image_surface_create_for_data (data,
+ format,
+ width,
+ height,
+ stride);
+ img->width = width;
+ img->height = height;
+ img->cr_data = surface;
+ img->cr_data2 = data;
+ img->pixmap = 0;
+}
+#endif
+
+
\f
/* Image background colors. */
x_clear_image (struct frame *f, struct image *img)
{
block_input ();
+#ifdef USE_CAIRO
+ if (img->cr_data)
+ cairo_surface_destroy ((cairo_surface_t *)img->cr_data);
+ if (img->cr_data2) xfree (img->cr_data2);
+#endif
x_clear_image_1 (f, img,
CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS);
unblock_input ();
convert_mono_to_color_image (f, img, fg, bg);
#elif defined (HAVE_NS)
- img->pixmap = ns_image_from_XBM (data, img->width, img->height);
+ img->pixmap = ns_image_from_XBM (data, img->width, img->height, fg, bg);
#else
img->pixmap =
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
#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 || img->mask_img->bits_per_pixel == 1))
+ {
+ int width = img->ximg->width;
+ int height = img->ximg->height;
+ 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;
+ char *mid = img->mask_img ? img->mask_img->data : 0;
+ uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
+
+ 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 = mid ? i * img->mask_img->bytes_per_line + k/8 : 0;
+ int mask = mid ? mid[maskidx] & (1 << (k % 8)) : 1;
+
+ if (mask) od[idx] = id[idx] + 0xff000000; // ff => full alpha
+ else od[idx] = bgcolor;
+ }
+ }
+
+ create_cairo_image_surface (img, data, width, height);
+ }
+ else
+ {
+ rc = XpmFileInvalid;
+ x_clear_image (f, img);
+ }
+#else
#ifdef HAVE_X_WINDOWS
if (rc == XpmSuccess)
{
}
}
#endif
+#endif /* ! USE_CAIRO */
if (rc == XpmSuccess)
{
Colormap cmap;
bool rc;
- if (ct_colors_allocated_max <= ct_colors_allocated)
+ if (ct_colors_allocated >= ct_colors_allocated_max)
return FRAME_FOREGROUND_PIXEL (f);
#ifdef HAVE_X_WINDOWS
HGDIOBJ prev;
#endif /* HAVE_NTGUI */
- if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height)
+ if (img->height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width)
memory_full (SIZE_MAX);
colors = xmalloc (sizeof *colors * img->width * img->height);
#define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
- if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height)
+ if (img->height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width)
memory_full (SIZE_MAX);
new = xmalloc (sizeof *new * img->width * img->height);
if (i == 3 && NILP (how))
{
char color_name[30];
- sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
+ sprintf (color_name, "#%04x%04x%04x",
+ rgb[0] + 0u, rgb[1] + 0u, rgb[2] + 0u);
bg = (
#ifdef HAVE_NTGUI
0x00ffffff & /* Filter out palette info. */
bool raw_p;
int x, y;
int width, height, max_color_idx = 0;
- XImagePtr ximg;
Lisp_Object file, specified_file;
enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
unsigned char *contents = NULL;
unsigned char *end, *p;
ptrdiff_t size;
+#ifdef USE_CAIRO
+ unsigned char *data = 0;
+ uint32_t *dataptr;
+#else
+ XImagePtr ximg;
+#endif
specified_file = image_spec_value (img->spec, QCfile, NULL);
width = pbm_scan_number (&p, end);
height = pbm_scan_number (&p, end);
+#ifdef USE_CAIRO
+ data = (unsigned char *) xmalloc (width * height * 4);
+ dataptr = (uint32_t *) data;
+#endif
+
if (type != PBM_MONO)
{
max_color_idx = pbm_scan_number (&p, end);
goto error;
}
+#ifndef USE_CAIRO
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
goto error;
+#endif
/* Initialize the color hash table. */
init_color_table ();
struct image_keyword fmt[PBM_LAST];
unsigned long fg = FRAME_FOREGROUND_PIXEL (f);
unsigned long bg = FRAME_BACKGROUND_PIXEL (f);
-
+#ifdef USE_CAIRO
+ XColor xfg, xbg;
+ int fga32, bga32;
+#endif
/* Parse the image specification. */
memcpy (fmt, pbm_format, sizeof fmt);
parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
/* Get foreground and background colors, maybe allocate colors. */
+#ifdef USE_CAIRO
+ if (! fmt[PBM_FOREGROUND].count
+ || ! STRINGP (fmt[PBM_FOREGROUND].value)
+ || ! x_defined_color (f, SSDATA (fmt[PBM_FOREGROUND].value), &xfg, 0))
+ {
+ xfg.pixel = fg;
+ x_query_color (f, &xfg);
+ }
+ fga32 = xcolor_to_argb32 (xfg);
+
+ if (! fmt[PBM_BACKGROUND].count
+ || ! STRINGP (fmt[PBM_BACKGROUND].value)
+ || ! x_defined_color (f, SSDATA (fmt[PBM_BACKGROUND].value), &xbg, 0))
+ {
+ xbg.pixel = bg;
+ x_query_color (f, &xbg);
+ }
+ bga32 = xcolor_to_argb32 (xbg);
+#else
if (fmt[PBM_FOREGROUND].count
&& STRINGP (fmt[PBM_FOREGROUND].value))
fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
img->background = bg;
img->background_valid = 1;
}
+#endif
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
{
if (p >= end)
{
+#ifdef USE_CAIRO
+ xfree (data);
+#else
x_destroy_x_image (ximg);
+#endif
x_clear_image (f, img);
image_error ("Invalid image size in image `%s'",
img->spec, Qnil);
else
g = pbm_scan_number (&p, end);
+#ifdef USE_CAIRO
+ *dataptr++ = g ? fga32 : bga32;
+#else
XPutPixel (ximg, x, y, g ? fg : bg);
+#endif
}
}
else
if (raw_p && p + expected_size > end)
{
+#ifdef USE_CAIRO
+ xfree (data);
+#else
x_destroy_x_image (ximg);
+#endif
x_clear_image (f, img);
image_error ("Invalid image size in image `%s'",
img->spec, Qnil);
if (r < 0 || g < 0 || b < 0)
{
+#ifdef USE_CAIRO
+ xfree (data);
+#else
x_destroy_x_image (ximg);
+#endif
image_error ("Invalid pixel value in image `%s'",
img->spec, Qnil);
goto error;
}
+#ifdef USE_CAIRO
+ r = (double) r * 255 / max_color_idx;
+ g = (double) g * 255 / max_color_idx;
+ b = (double) b * 255 / max_color_idx;
+ *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
+#else
/* RGB values are now in the range 0..max_color_idx.
Scale this to the range 0..0xffff supported by X. */
r = (double) r * 65535 / max_color_idx;
g = (double) g * 65535 / max_color_idx;
b = (double) b * 65535 / max_color_idx;
XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
+#endif
}
}
/* Maybe fill in the background field while we have ximg handy. */
+#ifdef USE_CAIRO
+ create_cairo_image_surface (img, data, width, height);
+#else
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
/* Casting avoids a GCC warning. */
IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
+#endif
/* X and W32 versions did it here, MAC version above. ++kfs
img->width = width;
PNG
***********************************************************************/
-#if defined (HAVE_PNG) || defined (HAVE_NS)
+#if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
/* Function prototypes. */
return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
}
-#endif /* HAVE_PNG || HAVE_NS */
+#endif /* HAVE_PNG || HAVE_NS || USE_CAIRO */
-#if defined HAVE_PNG && !defined HAVE_NS
+#if (defined HAVE_PNG && !defined HAVE_NS) || defined USE_CAIRO
# ifdef WINDOWSNT
/* PNG library details. */
Lisp_Object specified_data;
int x, y;
ptrdiff_t i;
- XImagePtr ximg, mask_img = NULL;
png_struct *png_ptr;
png_info *info_ptr = NULL, *end_info = NULL;
FILE *fp = NULL;
bool transparent_p;
struct png_memory_storage tbr; /* Data to be read */
+#ifdef USE_CAIRO
+ unsigned char *data = 0;
+ uint32_t *dataptr;
+#else
+ XImagePtr ximg, mask_img = NULL;
+#endif
+
/* Find out what file to load. */
specified_file = image_spec_value (img->spec, QCfile, NULL);
specified_data = image_spec_value (img->spec, QCdata, NULL);
+ IF_LINT (Lisp_Object volatile specified_data_volatile = specified_data);
if (NILP (specified_data))
{
/* Silence a bogus diagnostic; see GCC bug 54561. */
IF_LINT (fp = c->fp);
+ IF_LINT (specified_data = specified_data_volatile);
/* Read image info. */
if (!NILP (specified_data))
goto error;
}
+#ifndef USE_CAIRO
/* Create the X image and pixmap now, so that the work below can be
omitted if the image is too large for X. */
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
goto error;
+#endif
/* If image contains simply transparency data, we prefer to
construct a clipping mask. */
row_bytes = png_get_rowbytes (png_ptr, info_ptr);
/* Allocate memory for the image. */
- if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
- || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
+ if (height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows
+ || row_bytes > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height)
memory_full (SIZE_MAX);
c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
c->rows = rows = xmalloc (height * sizeof *rows);
c->fp = NULL;
}
+#ifdef USE_CAIRO
+ data = (unsigned char *) xmalloc (width * height * 4);
+ dataptr = (uint32_t *) data;
+#else
/* Create an image and pixmap serving as mask if the PNG image
contains an alpha channel. */
if (channels == 4
x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
goto error;
}
+#endif
/* Fill the X image and mask from PNG data. */
init_color_table ();
{
int r, g, b;
+#ifdef USE_CAIRO
+ int a = 0xff;
+ r = *p++;
+ g = *p++;
+ b = *p++;
+ if (channels == 4) a = *p++;
+ *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
+#else
r = *p++ << 8;
g = *p++ << 8;
b = *p++ << 8;
XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
++p;
}
+#endif
}
}
img->width = width;
img->height = height;
+#ifdef USE_CAIRO
+ create_cairo_image_surface (img, data, width, height);
+#else
/* Maybe fill in the background field while we have ximg handy.
Casting avoids a GCC warning. */
IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg);
image_put_x_image (f, img, mask_img, 1);
}
+#endif
return 1;
}
image_spec_value (img->spec, QCdata, NULL));
}
+
#endif /* HAVE_NS */
FILE * IF_LINT (volatile) fp = NULL;
JSAMPARRAY buffer;
int row_stride, x, y;
- XImagePtr ximg = NULL;
unsigned long *colors;
int width, height;
+ int i, ir, ig, ib;
+#ifndef USE_CAIRO
+ XImagePtr ximg = NULL;
+#endif
/* Open the JPEG file. */
specified_file = image_spec_value (img->spec, QCfile, NULL);
specified_data = image_spec_value (img->spec, QCdata, NULL);
+ IF_LINT (Lisp_Object volatile specified_data_volatile = specified_data);
if (NILP (specified_data))
{
jpeg_destroy_decompress (&mgr->cinfo);
/* If we already have an XImage, free that. */
+#ifndef USE_CAIRO
x_destroy_x_image (ximg);
-
+#endif
/* Free pixmap and colors. */
x_clear_image (f, img);
return 0;
}
+ /* Silence a bogus diagnostic; see GCC bug 54561. */
+ IF_LINT (specified_data = specified_data_volatile);
+
/* Create the JPEG decompression object. Let it read from fp.
Read the JPEG image header. */
jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
sys_longjmp (mgr->setjmp_buffer, 1);
}
+#ifndef USE_CAIRO
/* Create X image and pixmap. */
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
{
mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
sys_longjmp (mgr->setjmp_buffer, 1);
}
+#endif
/* Allocate colors. When color quantization is used,
mgr->cinfo.actual_number_of_colors has been set with the number of
No more than 255 colors will be generated. */
USE_SAFE_ALLOCA;
{
- int i, ir, ig, ib;
-
if (mgr->cinfo.out_color_components > 2)
ir = 0, ig = 1, ib = 2;
else if (mgr->cinfo.out_color_components > 1)
else
ir = 0, ig = 0, ib = 0;
+#ifndef CAIRO
/* Use the color table mechanism because it handles colors that
cannot be allocated nicely. Such colors will be replaced with
a default color, and we don't have to care about which colors
int b = mgr->cinfo.colormap[ib][i] << 8;
colors[i] = lookup_rgb_color (f, r, g, b);
}
+#endif
#ifdef COLOR_TABLE_SUPPORT
/* Remember those colors actually allocated. */
row_stride = width * mgr->cinfo.output_components;
buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
JPOOL_IMAGE, row_stride, 1);
+#ifdef USE_CAIRO
+ {
+ unsigned char *data = (unsigned char *) xmalloc (width*height*4);
+ uint32_t *dataptr = (uint32_t *) data;
+ int r, g, b;
+
+ for (y = 0; y < height; ++y)
+ {
+ jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
+
+ for (x = 0; x < width; ++x)
+ {
+ i = buffer[0][x];
+ r = mgr->cinfo.colormap[ir][i];
+ g = mgr->cinfo.colormap[ig][i];
+ b = mgr->cinfo.colormap[ib][i];
+ *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
+ }
+ }
+
+ create_cairo_image_surface (img, data, width, height);
+ }
+#else
for (y = 0; y < height; ++y)
{
jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
for (x = 0; x < mgr->cinfo.output_width; ++x)
XPutPixel (ximg, x, y, colors[buffer[0][x]]);
}
+#endif
/* Clean up. */
jpeg_finish_decompress (&mgr->cinfo);
if (fp)
fclose (fp);
+#ifndef USE_CAIRO
/* Maybe fill in the background field while we have ximg handy. */
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
/* Casting avoids a GCC warning. */
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
+#endif
SAFE_FREE ();
return 1;
}
return 0;
}
+#ifdef USE_CAIRO
+ {
+ unsigned char *data = (unsigned char *) xmalloc (width*height*4);
+ uint32_t *dataptr = (uint32_t *) data;
+ int r, g, b, a;
+
+ for (y = 0; y < height; ++y)
+ {
+ uint32 *row = buf + (height - 1 - y) * width;
+ for (x = 0; x < width; ++x)
+ {
+ uint32 abgr = row[x];
+ int r = TIFFGetR (abgr);
+ int g = TIFFGetG (abgr);
+ int b = TIFFGetB (abgr);
+ int a = TIFFGetA (abgr);
+ *dataptr++ = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+ }
+
+ create_cairo_image_surface (img, data, width, height);
+ }
+#else
/* Initialize the color table. */
init_color_table ();
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
- xfree (buf);
+#endif /* ! USE_CAIRO */
+
+ xfree (buf);
return 1;
}
# ifdef WINDOWSNT
/* GIF library details. */
-# if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
+# if GIFLIB_MAJOR + (GIFLIB_MINOR >= 1) > 5
DEF_DLL_FN (int, DGifCloseFile, (GifFileType *, int *));
# else
DEF_DLL_FN (int, DGifCloseFile, (GifFileType *));
{
int retval;
-#if 5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR)
+#if GIFLIB_MAJOR + (GIFLIB_MINOR >= 1) > 5
retval = DGifCloseFile (gif, err);
#else
retval = DGifCloseFile (gif);
{
Lisp_Object file;
int rc, width, height, x, y, i, j;
- XImagePtr ximg;
ColorMapObject *gif_color_map;
unsigned long pixel_colors[256];
GifFileType *gif;
EMACS_INT idx;
int gif_err;
+#ifdef USE_CAIRO
+ unsigned char *data = 0;
+#else
+ XImagePtr ximg;
+#endif
+
if (NILP (specified_data))
{
file = x_find_image_file (specified_file);
int subimg_height = subimage->ImageDesc.Height;
int subimg_top = subimage->ImageDesc.Top;
int subimg_left = subimage->ImageDesc.Left;
- if (! (0 <= subimg_width && 0 <= subimg_height
+ if (! (subimg_width >= 0 && subimg_height >= 0
&& 0 <= subimg_top && subimg_top <= height - subimg_height
&& 0 <= subimg_left && subimg_left <= width - subimg_width))
{
}
}
+#ifdef USE_CAIRO
+ /* xzalloc so data is zero => transparent */
+ data = (unsigned char *) xzalloc (width * height * 4);
+ if (STRINGP (specified_bg))
+ {
+ XColor color;
+ if (x_defined_color (f, SSDATA (specified_bg), &color, 0))
+ {
+ uint32_t *dataptr = (uint32_t *)data;
+ int r = color.red/256;
+ int g = color.green/256;
+ int b = color.blue/256;
+
+ for (y = 0; y < height; ++y)
+ for (x = 0; x < width; ++x)
+ *dataptr++ = (0xff << 24) | (r << 16) | (g << 8) | b;
+ }
+ }
+#else
/* Create the X image and pixmap. */
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
{
for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
XPutPixel (ximg, x, y, FRAME_BACKGROUND_PIXEL (f));
}
+#endif
/* Read the GIF image into the X image. */
if (disposal == 0)
disposal = 1;
- /* Allocate subimage colors. */
- memset (pixel_colors, 0, sizeof pixel_colors);
gif_color_map = subimage->ImageDesc.ColorMap;
if (!gif_color_map)
gif_color_map = gif->SColorMap;
+#ifndef USE_CAIRO
+ /* Allocate subimage colors. */
+ memset (pixel_colors, 0, sizeof pixel_colors);
+
if (gif_color_map)
for (i = 0; i < gif_color_map->ColorCount; ++i)
{
pixel_colors[i] = lookup_rgb_color (f, r, g, b);
}
}
+#endif
/* Apply the pixel values. */
if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace)
{
int c = raster[y * subimg_width + x];
if (transparency_color_index != c || disposal != 1)
- XPutPixel (ximg, x + subimg_left, row + subimg_top,
- pixel_colors[c]);
+ {
+#ifdef USE_CAIRO
+ uint32_t *dataptr =
+ ((uint32_t*)data + ((row + subimg_top) * subimg_width
+ + x + subimg_left));
+ int r = gif_color_map->Colors[c].Red;
+ int g = gif_color_map->Colors[c].Green;
+ int b = gif_color_map->Colors[c].Blue;
+
+ if (transparency_color_index != c)
+ *dataptr = (0xff << 24) | (r << 16) | (g << 8) | b;
+#else
+ XPutPixel (ximg, x + subimg_left, row + subimg_top,
+ pixel_colors[c]);
+#endif
+ }
}
}
}
else
{
- for (y = 0; y < subimg_height; ++y)
+ for (y = 0; y < subimg_height; ++y)
for (x = 0; x < subimg_width; ++x)
{
int c = raster[y * subimg_width + x];
if (transparency_color_index != c || disposal != 1)
- XPutPixel (ximg, x + subimg_left, y + subimg_top,
- pixel_colors[c]);
+ {
+#ifdef USE_CAIRO
+ uint32_t *dataptr =
+ ((uint32_t*)data + ((y + subimg_top) * subimg_width
+ + x + subimg_left));
+ int r = gif_color_map->Colors[c].Red;
+ int g = gif_color_map->Colors[c].Green;
+ int b = gif_color_map->Colors[c].Blue;
+ if (transparency_color_index != c)
+ *dataptr = (0xff << 24) | (r << 16) | (g << 8) | b;
+#else
+ XPutPixel (ximg, x + subimg_left, y + subimg_top,
+ pixel_colors[c]);
+#endif
+ }
}
}
}
#endif
}
+#ifdef USE_CAIRO
+ create_cairo_image_surface (img, data, width, height);
+#else
/* Maybe fill in the background field while we have ximg handy. */
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
/* Casting avoids a GCC warning. */
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
+#endif
return 1;
}
eassert (gdk_pixbuf_get_has_alpha (pixbuf));
eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
+#ifdef USE_CAIRO
+ {
+ unsigned char *data = (unsigned char *) xmalloc (width*height*4);
+ int y;
+ uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
+
+ for (y = 0; y < height; ++y)
+ {
+ const guchar *iconptr = pixels + y * rowstride;
+ uint32_t *dataptr = (uint32_t *) (data + y * rowstride);
+ int x;
+
+ for (x = 0; x < width; ++x)
+ {
+ if (iconptr[3] == 0)
+ *dataptr = bgcolor;
+ else
+ *dataptr = (iconptr[0] << 16)
+ | (iconptr[1] << 8)
+ | iconptr[2]
+ | (iconptr[3] << 24);
+
+ iconptr += 4;
+ ++dataptr;
+ }
+ }
+
+ create_cairo_image_surface (img, data, width, height);
+ g_object_unref (pixbuf);
+ }
+#else
/* Try to create a x pixmap to hold the svg pixmap. */
if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
{
/* Put ximg into the image. */
image_put_x_image (f, img, ximg, 0);
+#endif /* ! USE_CAIRO */
return 1;
/* For each pixel of the image, look its color up in the
color table. After having done so, the color table will
contain an entry for each color used by the image. */
+#ifdef COLOR_TABLE_SUPPORT
for (y = 0; y < img->height; ++y)
for (x = 0; x < img->width; ++x)
{
unsigned long pixel = XGetPixel (ximg, x, y);
+
lookup_pixel_color (f, pixel);
}
/* Record colors in the image. Free color table and XImage. */
-#ifdef COLOR_TABLE_SUPPORT
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
#endif
}
-DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
+DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0,
+ doc: /* */)
(Lisp_Object spec)
{
ptrdiff_t id = -1;
return define_image_type (&gif_type);
#endif
-#if defined (HAVE_PNG) || defined (HAVE_NS)
+#if defined (HAVE_PNG) || defined (HAVE_NS) || defined (USE_CAIRO)
if (EQ (type, Qpng))
return define_image_type (&png_type);
#endif
DEFSYM (QCcolor_symbols, ":color-symbols");
DEFSYM (QCheuristic_mask, ":heuristic-mask");
DEFSYM (QCindex, ":index");
- DEFSYM (QCgeometry, ":geometry");
DEFSYM (QCcrop, ":crop");
DEFSYM (QCrotation, ":rotation");
DEFSYM (QCmatrix, ":matrix");
#ifdef HAVE_GHOSTSCRIPT
ADD_IMAGE_TYPE (Qpostscript);
DEFSYM (QCloader, ":loader");
- DEFSYM (QCbounding_box, ":bounding-box");
DEFSYM (QCpt_width, ":pt-width");
DEFSYM (QCpt_height, ":pt-height");
#endif /* HAVE_GHOSTSCRIPT */