#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
***********************************************************************/
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. */
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 =
if (rc == XpmSuccess
&& img->ximg->format == ZPixmap
&& img->ximg->bits_per_pixel == 32
- && img->mask_img->bits_per_pixel == 1)
+ && (! img->mask_img || 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);
+ 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;
+ 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)
{
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));
+ 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] = 0;
+ else od[idx] = bgcolor;
}
}
- 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->cr_data2 = data;
+ create_cairo_image_surface (img, data, width, height);
}
else
{
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;
#endif /* HAVE_PNG || HAVE_NS || USE_CAIRO */
-#if defined HAVE_PNG && !defined HAVE_NS && !defined USE_CAIRO
+#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. */
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));
}
-#elif defined USE_CAIRO
-
-static bool
-png_load (struct frame *f, struct image *img)
-{
- Lisp_Object file;
- Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
- cairo_surface_t *surface;
-
- if (! STRINGP (specified_file))
- {
- image_error ("Invalid image spec, file missing `%s'", img->spec, Qnil);
- return false;
- }
-
- file = x_find_image_file (specified_file);
- if (! STRINGP (file))
- {
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- return false;
- }
-
- surface = cairo_image_surface_create_from_png (SSDATA (file));
- if (! surface)
- {
- image_error ("Error creating surface from file `%s'",
- specified_file, Qnil);
- return false;
- }
- img->width = cairo_image_surface_get_width (surface);
- img->height = cairo_image_surface_get_height (surface);
- img->cr_data = surface;
- img->pixmap = 0;
-
- return true;
-}
-#endif /* USE_CAIRO */
+#endif /* HAVE_NS */
\f
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
JPOOL_IMAGE, row_stride, 1);
#ifdef USE_CAIRO
{
- cairo_surface_t *surface;
- 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);
uint32_t *dataptr = (uint32_t *) data;
int r, g, b;
}
}
- 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;
+ create_cairo_image_surface (img, data, width, height);
}
#else
for (y = 0; y < height; ++y)
if (fp)
fclose (fp);
-#ifndef CAIRO
+#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. */
#ifdef USE_CAIRO
{
- cairo_surface_t *surface;
- 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);
uint32_t *dataptr = (uint32_t *) data;
int r, g, b, a;
}
}
- 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 = buf;
- img->pixmap = 0;
+ create_cairo_image_surface (img, data, width, height);
}
#else
/* Initialize the color table. */
{
Lisp_Object file;
int rc, width, height, x, y, i, j;
- XImagePtr ximg;
ColorMapObject *gif_color_map;
unsigned long pixel_colors[256];
GifFileType *gif;
#ifdef USE_CAIRO
unsigned char *data = 0;
+#else
+ XImagePtr ximg;
#endif
if (NILP (specified_data))
#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))
}
#ifdef USE_CAIRO
- {
- 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;
- }
+ 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)))
#ifdef USE_CAIRO
{
- cairo_surface_t *surface;
- 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 y;
+ uint32_t bgcolor = get_spec_bg_or_alpha_as_argb (img, f);
for (y = 0; y < height; ++y)
{
for (x = 0; x < width; ++x)
{
- *dataptr = (iconptr[0] << 16)
- | (iconptr[1] << 8)
- | iconptr[2]
- | (iconptr[3] << 24);
+ if (iconptr[3] == 0)
+ *dataptr = bgcolor;
+ else
+ *dataptr = (iconptr[0] << 16)
+ | (iconptr[1] << 8)
+ | iconptr[2]
+ | (iconptr[3] << 24);
+
iconptr += 4;
++dataptr;
}
}
- surface = cairo_image_surface_create_for_data (data,
- format,
- width,
- height,
- stride);
-
+ create_cairo_image_surface (img, data, width, height);
g_object_unref (pixbuf);
- img->width = width;
- img->height = height;
- img->cr_data = surface;
- img->cr_data2 = data;
- img->pixmap = 0;
}
#else
/* Try to create a x pixmap to hold the svg pixmap. */
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 */