aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorMiles Bader2004-06-28 07:56:49 +0000
committerMiles Bader2004-06-28 07:56:49 +0000
commit327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801 (patch)
tree21de188e13b5e41a79bb50040933072ae0235217 /src/image.c
parent852f73b7fa7b71910282eacb6263b3ecfd4ee783 (diff)
parent376de73927383d6062483db10b8a82448505f52b (diff)
downloademacs-327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801.tar.gz
emacs-327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801.zip
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-15
Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-218 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-220 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-221 Restore deleted tagline in etc/TUTORIAL.ru * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-222 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-228 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-229 Remove TeX output files from the archive * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-230 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-247 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-248 src/lisp.h (CYCLE_CHECK): Macro moved from xfaces.c * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-249 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-256 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-258 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-263 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-264 Update from CVS: lispref/display.texi: emacs -> Emacs. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-265 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-274 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-275 Update from CVS: man/makefile.w32-in: Revert last change * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-276 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-295 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-296 Allow restarting an existing debugger session that's exited * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-297 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-299 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-300 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-327 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-328 Update from CVS: src/.gdbinit (xsymbol): Fix last change. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-329 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-344 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-345 Tweak source regexps so that building in place won't cause problems * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-346 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-351 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-352 Update from CVS: lisp/flymake.el: New file. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-353 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-361 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-362 Support " [...]" style defaults in minibuffer-electric-default-mode * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-363 (read-number): Use canonical format for default in prompt. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-364 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-367 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-368 Improve display-supports-face-attributes-p on non-ttys * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-369 Rewrite face-differs-from-default-p * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-370 Move `display-supports-face-attributes-p' entirely into C code * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-371 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-372 Simplify face-differs-from-default-p; don't consider :stipple. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-373 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-374 (tty_supports_face_attributes_p): Ensure attributes differ from default * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-375 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-376 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-377 (Fdisplay_supports_face_attributes_p): Work around bootstrapping problem * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-378 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-380 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-381 Face merging cleanups * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-382 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-384 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-385 src/xfaces.c (push_named_merge_point): Return 0 if a cycle is detected * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-386 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-395 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-396 Tweak arch tagging to make build/install-in-place less annoying * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-397 Work around vc-arch problems when building eshell * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-398 Tweak permissions * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-399 Tweak directory permissions * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-400 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-401 More build-in-place tweaking of arch tagging * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-402 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-403 Yet more build-in-place tweaking of arch tagging * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-404 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-409 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-410 Make sure image types are initialized for lookup too * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-411 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-416 Update from CVS
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c790
1 files changed, 694 insertions, 96 deletions
diff --git a/src/image.c b/src/image.c
index 34db5e53367..438e132807f 100644
--- a/src/image.c
+++ b/src/image.c
@@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
23#include <signal.h> 23#include <signal.h>
24#include <stdio.h> 24#include <stdio.h>
25#include <math.h> 25#include <math.h>
26#include <ctype.h>
26 27
27#ifdef HAVE_UNISTD_H 28#ifdef HAVE_UNISTD_H
28#include <unistd.h> 29#include <unistd.h>
@@ -51,7 +52,6 @@ Boston, MA 02111-1307, USA. */
51typedef struct x_bitmap_record Bitmap_Record; 52typedef struct x_bitmap_record Bitmap_Record;
52#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y) 53#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
53#define NO_PIXMAP None 54#define NO_PIXMAP None
54#define PNG_BG_COLOR_SHIFT 0
55 55
56#define RGB_PIXEL_COLOR unsigned long 56#define RGB_PIXEL_COLOR unsigned long
57 57
@@ -69,7 +69,6 @@ typedef struct x_bitmap_record Bitmap_Record;
69typedef struct w32_bitmap_record Bitmap_Record; 69typedef struct w32_bitmap_record Bitmap_Record;
70#define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y) 70#define GET_PIXEL(ximg, x, y) GetPixel(ximg, x, y)
71#define NO_PIXMAP 0 71#define NO_PIXMAP 0
72#define PNG_BG_COLOR_SHIFT 0
73 72
74#define RGB_PIXEL_COLOR COLORREF 73#define RGB_PIXEL_COLOR COLORREF
75 74
@@ -104,7 +103,6 @@ typedef struct mac_bitmap_record Bitmap_Record;
104 103
105#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y) 104#define GET_PIXEL(ximg, x, y) XGetPixel(ximg, x, y)
106#define NO_PIXMAP 0 105#define NO_PIXMAP 0
107#define PNG_BG_COLOR_SHIFT 8
108 106
109#define RGB_PIXEL_COLOR unsigned long 107#define RGB_PIXEL_COLOR unsigned long
110 108
@@ -177,14 +175,19 @@ XPutPixel (ximage, x, y, pixel)
177 int x, y; 175 int x, y;
178 unsigned long pixel; 176 unsigned long pixel;
179{ 177{
178 CGrafPtr old_port;
179 GDHandle old_gdh;
180 RGBColor color; 180 RGBColor color;
181 181
182 GetGWorld (&old_port, &old_gdh);
182 SetGWorld (ximage, NULL); 183 SetGWorld (ximage, NULL);
183 184
184 color.red = RED16_FROM_ULONG (pixel); 185 color.red = RED16_FROM_ULONG (pixel);
185 color.green = GREEN16_FROM_ULONG (pixel); 186 color.green = GREEN16_FROM_ULONG (pixel);
186 color.blue = BLUE16_FROM_ULONG (pixel); 187 color.blue = BLUE16_FROM_ULONG (pixel);
187 SetCPixel (x, y, &color); 188 SetCPixel (x, y, &color);
189
190 SetGWorld (old_port, old_gdh);
188} 191}
189 192
190static unsigned long 193static unsigned long
@@ -192,11 +195,16 @@ XGetPixel (ximage, x, y)
192 XImagePtr ximage; 195 XImagePtr ximage;
193 int x, y; 196 int x, y;
194{ 197{
198 CGrafPtr old_port;
199 GDHandle old_gdh;
195 RGBColor color; 200 RGBColor color;
196 201
202 GetGWorld (&old_port, &old_gdh);
197 SetGWorld (ximage, NULL); 203 SetGWorld (ximage, NULL);
198 204
199 GetCPixel (x, y, &color); 205 GetCPixel (x, y, &color);
206
207 SetGWorld (old_port, old_gdh);
200 return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8); 208 return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8);
201} 209}
202 210
@@ -206,7 +214,7 @@ XDestroyImage (ximg)
206{ 214{
207 UnlockPixels (GetGWorldPixMap (ximg)); 215 UnlockPixels (GetGWorldPixMap (ximg));
208} 216}
209#endif 217#endif /* MAC_OS */
210 218
211 219
212/* Functions to access the contents of a bitmap, given an id. */ 220/* Functions to access the contents of a bitmap, given an id. */
@@ -598,6 +606,14 @@ x_create_bitmap_mask (f, id)
598 606
599static struct image_type *image_types; 607static struct image_type *image_types;
600 608
609/* A list of symbols, one for each supported image type. */
610
611Lisp_Object Vimage_types;
612
613/* Cache for delayed-loading image types. */
614
615static Lisp_Object Vimage_type_cache;
616
601/* The symbol `xbm' which is used as the type symbol for XBM images. */ 617/* The symbol `xbm' which is used as the type symbol for XBM images. */
602 618
603Lisp_Object Qxbm; 619Lisp_Object Qxbm;
@@ -622,7 +638,7 @@ Lisp_Object Vimage_cache_eviction_delay;
622 638
623/* Function prototypes. */ 639/* Function prototypes. */
624 640
625static void define_image_type P_ ((struct image_type *type)); 641static Lisp_Object define_image_type P_ ((struct image_type *type, int loaded));
626static struct image_type *lookup_image_type P_ ((Lisp_Object symbol)); 642static struct image_type *lookup_image_type P_ ((Lisp_Object symbol));
627static void image_error P_ ((char *format, Lisp_Object, Lisp_Object)); 643static void image_error P_ ((char *format, Lisp_Object, Lisp_Object));
628static void x_laplace P_ ((struct frame *, struct image *)); 644static void x_laplace P_ ((struct frame *, struct image *));
@@ -630,21 +646,37 @@ static void x_emboss P_ ((struct frame *, struct image *));
630static int x_build_heuristic_mask P_ ((struct frame *, struct image *, 646static int x_build_heuristic_mask P_ ((struct frame *, struct image *,
631 Lisp_Object)); 647 Lisp_Object));
632 648
649#define CACHE_IMAGE_TYPE(type, status) \
650 do { Vimage_type_cache = Fcons (Fcons (type, status), Vimage_type_cache); } while (0)
651
652#define ADD_IMAGE_TYPE(type) \
653 do { Vimage_types = Fcons (type, Vimage_types); } while (0)
633 654
634/* Define a new image type from TYPE. This adds a copy of TYPE to 655/* Define a new image type from TYPE. This adds a copy of TYPE to
635 image_types and adds the symbol *TYPE->type to Vimage_types. */ 656 image_types and caches the loading status of TYPE. */
636 657
637static void 658static Lisp_Object
638define_image_type (type) 659define_image_type (type, loaded)
639 struct image_type *type; 660 struct image_type *type;
661 int loaded;
640{ 662{
641 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. 663 Lisp_Object success;
642 The initialized data segment is read-only. */ 664
643 struct image_type *p = (struct image_type *) xmalloc (sizeof *p); 665 if (!loaded)
644 bcopy (type, p, sizeof *p); 666 success = Qnil;
645 p->next = image_types; 667 else
646 image_types = p; 668 {
647 Vimage_types = Fcons (*p->type, Vimage_types); 669 /* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
670 The initialized data segment is read-only. */
671 struct image_type *p = (struct image_type *) xmalloc (sizeof *p);
672 bcopy (type, p, sizeof *p);
673 p->next = image_types;
674 image_types = p;
675 success = Qt;
676 }
677
678 CACHE_IMAGE_TYPE(*type->type, success);
679 return success;
648} 680}
649 681
650 682
@@ -657,6 +689,10 @@ lookup_image_type (symbol)
657{ 689{
658 struct image_type *type; 690 struct image_type *type;
659 691
692 /* We must initialize the image-type if it hasn't been already. */
693 if (NILP (Finit_image_library (symbol)))
694 return 0; /* unimplemented */
695
660 for (type = image_types; type; type = type->next) 696 for (type = image_types; type; type = type->next)
661 if (EQ (symbol, *type->type)) 697 if (EQ (symbol, *type->type))
662 break; 698 break;
@@ -1079,13 +1115,21 @@ prepare_image_for_display (f, img)
1079 drawn in face FACE. */ 1115 drawn in face FACE. */
1080 1116
1081int 1117int
1082image_ascent (img, face) 1118image_ascent (img, face, slice)
1083 struct image *img; 1119 struct image *img;
1084 struct face *face; 1120 struct face *face;
1121 struct glyph_slice *slice;
1085{ 1122{
1086 int height = img->height + img->vmargin; 1123 int height;
1087 int ascent; 1124 int ascent;
1088 1125
1126 if (slice->height == img->height)
1127 height = img->height + img->vmargin;
1128 else if (slice->y == 0)
1129 height = slice->height + img->vmargin;
1130 else
1131 height = slice->height;
1132
1089 if (img->ascent == CENTERED_IMAGE_ASCENT) 1133 if (img->ascent == CENTERED_IMAGE_ASCENT)
1090 { 1134 {
1091 if (face->font) 1135 if (face->font)
@@ -1172,7 +1216,7 @@ four_corners_best (ximg, width, height)
1172/* Return the `background' field of IMG. If IMG doesn't have one yet, 1216/* Return the `background' field of IMG. If IMG doesn't have one yet,
1173 it is guessed heuristically. If non-zero, XIMG is an existing 1217 it is guessed heuristically. If non-zero, XIMG is an existing
1174 XImage object (or device context with the image selected on W32) to 1218 XImage object (or device context with the image selected on W32) to
1175 use for the heuristic. */ 1219 use for the heuristic. */
1176 1220
1177RGB_PIXEL_COLOR 1221RGB_PIXEL_COLOR
1178image_background (img, f, ximg) 1222image_background (img, f, ximg)
@@ -1205,7 +1249,7 @@ image_background (img, f, ximg)
1205 1249
1206 if (free_ximg) 1250 if (free_ximg)
1207 Destroy_Image (ximg, prev); 1251 Destroy_Image (ximg, prev);
1208 1252
1209 img->background_valid = 1; 1253 img->background_valid = 1;
1210 } 1254 }
1211 1255
@@ -1581,6 +1625,11 @@ lookup_image (f, spec)
1581 Lisp_Object spec; 1625 Lisp_Object spec;
1582{ 1626{
1583 struct image_cache *c = FRAME_X_IMAGE_CACHE (f); 1627 struct image_cache *c = FRAME_X_IMAGE_CACHE (f);
1628#ifdef _MSC_VER
1629 /* Work around a problem with MinGW builds of graphics libraries
1630 not honoring calling conventions. */
1631 static
1632#endif
1584 struct image *img; 1633 struct image *img;
1585 int i; 1634 int i;
1586 unsigned hash; 1635 unsigned hash;
@@ -1768,6 +1817,33 @@ forall_images_in_image_cache (f, fn)
1768 if (!fn_##func) return 0; \ 1817 if (!fn_##func) return 0; \
1769 } 1818 }
1770 1819
1820/* Load a DLL implementing an image type.
1821 The `image-library-alist' variable associates a symbol,
1822 identifying an image type, to a list of possible filenames.
1823 The function returns NULL if no library could be loaded for
1824 the given image type, or if the library was previously loaded;
1825 else the handle of the DLL. */
1826static HMODULE
1827w32_delayed_load (Lisp_Object libraries, Lisp_Object type)
1828{
1829 HMODULE library = NULL;
1830
1831 if (CONSP (libraries) && NILP (Fassq (type, Vimage_type_cache)))
1832 {
1833 Lisp_Object dlls = Fassq (type, libraries);
1834
1835 if (CONSP (dlls))
1836 for (dlls = XCDR (dlls); CONSP (dlls); dlls = XCDR (dlls))
1837 {
1838 CHECK_STRING_CAR (dlls);
1839 if (library = LoadLibrary (SDATA (XCAR (dlls))))
1840 break;
1841 }
1842 }
1843
1844 return library;
1845}
1846
1771#endif /* HAVE_NTGUI */ 1847#endif /* HAVE_NTGUI */
1772 1848
1773static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, 1849static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
@@ -2191,6 +2267,10 @@ image_load_qt_1 (f, img, type, fss, dh)
2191 goto error; 2267 goto error;
2192 if (draw_all_pixels != graphicsImporterDrawsAllPixels) 2268 if (draw_all_pixels != graphicsImporterDrawsAllPixels)
2193 { 2269 {
2270 CGrafPtr old_port;
2271 GDHandle old_gdh;
2272
2273 GetGWorld (&old_port, &old_gdh);
2194 SetGWorld (ximg, NULL); 2274 SetGWorld (ximg, NULL);
2195 bg_color.red = color.red; 2275 bg_color.red = color.red;
2196 bg_color.green = color.green; 2276 bg_color.green = color.green;
@@ -2202,6 +2282,7 @@ image_load_qt_1 (f, img, type, fss, dh)
2202#else 2282#else
2203 EraseRect (&(ximg->portRect)); 2283 EraseRect (&(ximg->portRect));
2204#endif 2284#endif
2285 SetGWorld (old_port, old_gdh);
2205 } 2286 }
2206 GraphicsImportSetGWorld (gi, ximg, NULL); 2287 GraphicsImportSetGWorld (gi, ximg, NULL);
2207 GraphicsImportDraw (gi); 2288 GraphicsImportDraw (gi);
@@ -2990,7 +3071,7 @@ xbm_load_image (f, img, contents, end)
2990 non_default_colors = 1; 3071 non_default_colors = 1;
2991 } 3072 }
2992 3073
2993 Create_Pixmap_From_Bitmap_Data (f, img, data, 3074 Create_Pixmap_From_Bitmap_Data (f, img, data,
2994 foreground, background, 3075 foreground, background,
2995 non_default_colors); 3076 non_default_colors);
2996 xfree (data); 3077 xfree (data);
@@ -3164,28 +3245,36 @@ xbm_load (f, img)
3164 XPM images 3245 XPM images
3165 ***********************************************************************/ 3246 ***********************************************************************/
3166 3247
3167#ifdef HAVE_XPM 3248#if defined (HAVE_XPM) || defined (MAC_OS)
3168 3249
3169static int xpm_image_p P_ ((Lisp_Object object)); 3250static int xpm_image_p P_ ((Lisp_Object object));
3170static int xpm_load P_ ((struct frame *f, struct image *img)); 3251static int xpm_load P_ ((struct frame *f, struct image *img));
3171static int xpm_valid_color_symbols_p P_ ((Lisp_Object)); 3252static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
3172 3253
3254#endif /* HAVE_XPM || MAC_OS */
3255
3256#ifdef HAVE_XPM
3173#ifdef HAVE_NTGUI 3257#ifdef HAVE_NTGUI
3174/* Indicate to xpm.h that we don't have Xlib. */ 3258/* Indicate to xpm.h that we don't have Xlib. */
3175#define FOR_MSW 3259#define FOR_MSW
3176/* simx.h in xpm defines XColor and XImage differently than Emacs. */ 3260/* simx.h in xpm defines XColor and XImage differently than Emacs. */
3261/* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
3177#define XColor xpm_XColor 3262#define XColor xpm_XColor
3178#define XImage xpm_XImage 3263#define XImage xpm_XImage
3264#define Display xpm_Display
3179#define PIXEL_ALREADY_TYPEDEFED 3265#define PIXEL_ALREADY_TYPEDEFED
3180#include "X11/xpm.h" 3266#include "X11/xpm.h"
3181#undef FOR_MSW 3267#undef FOR_MSW
3182#undef XColor 3268#undef XColor
3183#undef XImage 3269#undef XImage
3270#undef Display
3184#undef PIXEL_ALREADY_TYPEDEFED 3271#undef PIXEL_ALREADY_TYPEDEFED
3185#else 3272#else
3186#include "X11/xpm.h" 3273#include "X11/xpm.h"
3187#endif /* HAVE_NTGUI */ 3274#endif /* HAVE_NTGUI */
3275#endif /* HAVE_XPM */
3188 3276
3277#if defined (HAVE_XPM) || defined (MAC_OS)
3189/* The symbol `xpm' identifying XPM-format images. */ 3278/* The symbol `xpm' identifying XPM-format images. */
3190 3279
3191Lisp_Object Qxpm; 3280Lisp_Object Qxpm;
@@ -3455,13 +3544,12 @@ DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
3455DEF_IMGLIB_FN (XpmReadFileToImage); 3544DEF_IMGLIB_FN (XpmReadFileToImage);
3456DEF_IMGLIB_FN (XImageFree); 3545DEF_IMGLIB_FN (XImageFree);
3457 3546
3458
3459static int 3547static int
3460init_xpm_functions (void) 3548init_xpm_functions (Lisp_Object libraries)
3461{ 3549{
3462 HMODULE library; 3550 HMODULE library;
3463 3551
3464 if (!(library = LoadLibrary ("libXpm.dll"))) 3552 if (!(library = w32_delayed_load (libraries, Qxpm)))
3465 return 0; 3553 return 0;
3466 3554
3467 LOAD_IMGLIB_FN (library, XpmFreeAttributes); 3555 LOAD_IMGLIB_FN (library, XpmFreeAttributes);
@@ -3513,10 +3601,13 @@ xpm_image_p (object)
3513 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))); 3601 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
3514} 3602}
3515 3603
3604#endif /* HAVE_XPM || MAC_OS */
3516 3605
3517/* Load image IMG which will be displayed on frame F. Value is 3606/* Load image IMG which will be displayed on frame F. Value is
3518 non-zero if successful. */ 3607 non-zero if successful. */
3519 3608
3609#ifdef HAVE_XPM
3610
3520static int 3611static int
3521xpm_load (f, img) 3612xpm_load (f, img)
3522 struct frame *f; 3613 struct frame *f;
@@ -3748,6 +3839,467 @@ xpm_load (f, img)
3748 3839
3749#endif /* HAVE_XPM */ 3840#endif /* HAVE_XPM */
3750 3841
3842#ifdef MAC_OS
3843
3844/* XPM support functions for Mac OS where libxpm is not available.
3845 Only XPM version 3 (without any extensions) is supported. */
3846
3847static int xpm_scan P_ ((unsigned char **, unsigned char *,
3848 unsigned char **, int *));
3849static Lisp_Object xpm_make_color_table_v
3850 P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object),
3851 Lisp_Object (**) (Lisp_Object, unsigned char *, int)));
3852static void xpm_put_color_table_v P_ ((Lisp_Object, unsigned char *,
3853 int, Lisp_Object));
3854static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object,
3855 unsigned char *, int));
3856static Lisp_Object xpm_make_color_table_h
3857 P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object),
3858 Lisp_Object (**) (Lisp_Object, unsigned char *, int)));
3859static void xpm_put_color_table_h P_ ((Lisp_Object, unsigned char *,
3860 int, Lisp_Object));
3861static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object,
3862 unsigned char *, int));
3863static int xpm_str_to_color_key P_ ((char *));
3864static int xpm_load_image P_ ((struct frame *, struct image *,
3865 unsigned char *, unsigned char *));
3866
3867/* Tokens returned from xpm_scan. */
3868
3869enum xpm_token
3870{
3871 XPM_TK_IDENT = 256,
3872 XPM_TK_STRING,
3873 XPM_TK_EOF
3874};
3875
3876/* Scan an XPM data and return a character (< 256) or a token defined
3877 by enum xpm_token above. *S and END are the start (inclusive) and
3878 the end (exclusive) addresses of the data, respectively. Advance
3879 *S while scanning. If token is either XPM_TK_IDENT or
3880 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
3881 length of the corresponding token, respectively. */
3882
3883static int
3884xpm_scan (s, end, beg, len)
3885 unsigned char **s, *end, **beg;
3886 int *len;
3887{
3888 int c;
3889
3890 while (*s < end)
3891 {
3892 /* Skip white-space. */
3893 while (*s < end && (c = *(*s)++, isspace (c)))
3894 ;
3895
3896 /* gnus-pointer.xpm uses '-' in its identifier.
3897 sb-dir-plus.xpm uses '+' in its identifier. */
3898 if (isalpha (c) || c == '_' || c == '-' || c == '+')
3899 {
3900 *beg = *s - 1;
3901 while (*s < end &&
3902 (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+'))
3903 ++*s;
3904 *len = *s - *beg;
3905 return XPM_TK_IDENT;
3906 }
3907 else if (c == '"')
3908 {
3909 *beg = *s;
3910 while (*s < end && **s != '"')
3911 ++*s;
3912 *len = *s - *beg;
3913 if (*s < end)
3914 ++*s;
3915 return XPM_TK_STRING;
3916 }
3917 else if (c == '/')
3918 {
3919 if (*s < end && **s == '*')
3920 {
3921 /* C-style comment. */
3922 ++*s;
3923 do
3924 {
3925 while (*s < end && *(*s)++ != '*')
3926 ;
3927 }
3928 while (*s < end && **s != '/');
3929 if (*s < end)
3930 ++*s;
3931 }
3932 else
3933 return c;
3934 }
3935 else
3936 return c;
3937 }
3938
3939 return XPM_TK_EOF;
3940}
3941
3942/* Functions for color table lookup in XPM data. A Key is a string
3943 specifying the color of each pixel in XPM data. A value is either
3944 an integer that specifies a pixel color, Qt that specifies
3945 transparency, or Qnil for the unspecified color. If the length of
3946 the key string is one, a vector is used as a table. Otherwise, a
3947 hash table is used. */
3948
3949static Lisp_Object
3950xpm_make_color_table_v (put_func, get_func)
3951 void (**put_func) (Lisp_Object, unsigned char *, int, Lisp_Object);
3952 Lisp_Object (**get_func) (Lisp_Object, unsigned char *, int);
3953{
3954 *put_func = xpm_put_color_table_v;
3955 *get_func = xpm_get_color_table_v;
3956 return Fmake_vector (make_number (256), Qnil);
3957}
3958
3959static void
3960xpm_put_color_table_v (color_table, chars_start, chars_len, color)
3961 Lisp_Object color_table;
3962 unsigned char *chars_start;
3963 int chars_len;
3964 Lisp_Object color;
3965{
3966 XVECTOR (color_table)->contents[*chars_start] = color;
3967}
3968
3969static Lisp_Object
3970xpm_get_color_table_v (color_table, chars_start, chars_len)
3971 Lisp_Object color_table;
3972 unsigned char *chars_start;
3973 int chars_len;
3974{
3975 return XVECTOR (color_table)->contents[*chars_start];
3976}
3977
3978static Lisp_Object
3979xpm_make_color_table_h (put_func, get_func)
3980 void (**put_func) (Lisp_Object, unsigned char *, int, Lisp_Object);
3981 Lisp_Object (**get_func) (Lisp_Object, unsigned char *, int);
3982{
3983 *put_func = xpm_put_color_table_h;
3984 *get_func = xpm_get_color_table_h;
3985 return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE),
3986 make_float (DEFAULT_REHASH_SIZE),
3987 make_float (DEFAULT_REHASH_THRESHOLD),
3988 Qnil, Qnil, Qnil);
3989}
3990
3991static void
3992xpm_put_color_table_h (color_table, chars_start, chars_len, color)
3993 Lisp_Object color_table;
3994 unsigned char *chars_start;
3995 int chars_len;
3996 Lisp_Object color;
3997{
3998 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
3999 unsigned hash_code;
4000 Lisp_Object chars = make_unibyte_string (chars_start, chars_len);
4001
4002 hash_lookup (table, chars, &hash_code);
4003 hash_put (table, chars, color, hash_code);
4004}
4005
4006static Lisp_Object
4007xpm_get_color_table_h (color_table, chars_start, chars_len)
4008 Lisp_Object color_table;
4009 unsigned char *chars_start;
4010 int chars_len;
4011{
4012 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
4013 int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len),
4014 NULL);
4015
4016 return i >= 0 ? HASH_VALUE (table, i) : Qnil;
4017}
4018
4019enum xpm_color_key {
4020 XPM_COLOR_KEY_S,
4021 XPM_COLOR_KEY_M,
4022 XPM_COLOR_KEY_G4,
4023 XPM_COLOR_KEY_G,
4024 XPM_COLOR_KEY_C
4025};
4026
4027static char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"};
4028
4029static int
4030xpm_str_to_color_key (s)
4031 char *s;
4032{
4033 int i;
4034
4035 for (i = 0;
4036 i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0];
4037 i++)
4038 if (strcmp (xpm_color_key_strings[i], s) == 0)
4039 return i;
4040 return -1;
4041}
4042
4043static int
4044xpm_load_image (f, img, contents, end)
4045 struct frame *f;
4046 struct image *img;
4047 unsigned char *contents, *end;
4048{
4049 unsigned char *s = contents, *beg, *str;
4050 unsigned char buffer[BUFSIZ];
4051 int width, height, x, y;
4052 int num_colors, chars_per_pixel;
4053 int len, LA1;
4054 void (*put_color_table) (Lisp_Object, unsigned char *, int, Lisp_Object);
4055 Lisp_Object (*get_color_table) (Lisp_Object, unsigned char *, int);
4056 Lisp_Object frame, color_symbols, color_table;
4057 int best_key, have_mask = 0;
4058 XImagePtr ximg = NULL, mask_img = NULL;
4059
4060#define match() \
4061 LA1 = xpm_scan (&s, end, &beg, &len)
4062
4063#define expect(TOKEN) \
4064 if (LA1 != (TOKEN)) \
4065 goto failure; \
4066 else \
4067 match ()
4068
4069#define expect_ident(IDENT) \
4070 if (LA1 == XPM_TK_IDENT \
4071 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
4072 match (); \
4073 else \
4074 goto failure
4075
4076 if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
4077 goto failure;
4078 s += 9;
4079 match();
4080 expect_ident ("static");
4081 expect_ident ("char");
4082 expect ('*');
4083 expect (XPM_TK_IDENT);
4084 expect ('[');
4085 expect (']');
4086 expect ('=');
4087 expect ('{');
4088 expect (XPM_TK_STRING);
4089 if (len >= BUFSIZ)
4090 goto failure;
4091 memcpy (buffer, beg, len);
4092 buffer[len] = '\0';
4093 if (sscanf (buffer, "%d %d %d %d", &width, &height,
4094 &num_colors, &chars_per_pixel) != 4
4095 || width <= 0 || height <= 0
4096 || num_colors <= 0 || chars_per_pixel <= 0)
4097 goto failure;
4098 expect (',');
4099
4100 XSETFRAME (frame, f);
4101 if (!NILP (Fxw_display_color_p (frame)))
4102 best_key = XPM_COLOR_KEY_C;
4103 else if (!NILP (Fx_display_grayscale_p (frame)))
4104 best_key = (XFASTINT (Fx_display_planes (frame)) > 2
4105 ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4);
4106 else
4107 best_key = XPM_COLOR_KEY_M;
4108
4109 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
4110 if (chars_per_pixel == 1)
4111 color_table = xpm_make_color_table_v (&put_color_table,
4112 &get_color_table);
4113 else
4114 color_table = xpm_make_color_table_h (&put_color_table,
4115 &get_color_table);
4116
4117 while (num_colors-- > 0)
4118 {
4119 unsigned char *color, *max_color;
4120 int key, next_key, max_key = 0;
4121 Lisp_Object symbol_color = Qnil, color_val;
4122 XColor cdef;
4123
4124 expect (XPM_TK_STRING);
4125 if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel)
4126 goto failure;
4127 memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel);
4128 buffer[len - chars_per_pixel] = '\0';
4129
4130 str = strtok (buffer, " \t");
4131 if (str == NULL)
4132 goto failure;
4133 key = xpm_str_to_color_key (str);
4134 if (key < 0)
4135 goto failure;
4136 do
4137 {
4138 color = strtok (NULL, " \t");
4139 if (color == NULL)
4140 goto failure;
4141
4142 while (str = strtok (NULL, " \t"))
4143 {
4144 next_key = xpm_str_to_color_key (str);
4145 if (next_key >= 0)
4146 break;
4147 color[strlen (color)] = ' ';
4148 }
4149
4150 if (key == XPM_COLOR_KEY_S)
4151 {
4152 if (NILP (symbol_color))
4153 symbol_color = build_string (color);
4154 }
4155 else if (max_key < key && key <= best_key)
4156 {
4157 max_key = key;
4158 max_color = color;
4159 }
4160 key = next_key;
4161 }
4162 while (str);
4163
4164 color_val = Qnil;
4165 if (!NILP (color_symbols) && !NILP (symbol_color))
4166 {
4167 Lisp_Object specified_color = Fassoc (symbol_color, color_symbols);
4168
4169 if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
4170 if (xstricmp (SDATA (XCDR (specified_color)), "None") == 0)
4171 color_val = Qt;
4172 else if (x_defined_color (f, SDATA (XCDR (specified_color)),
4173 &cdef, 0))
4174 color_val = make_number (cdef.pixel);
4175 }
4176 if (NILP (color_val) && max_key > 0)
4177 if (xstricmp (max_color, "None") == 0)
4178 color_val = Qt;
4179 else if (x_defined_color (f, max_color, &cdef, 0))
4180 color_val = make_number (cdef.pixel);
4181 if (!NILP (color_val))
4182 (*put_color_table) (color_table, beg, chars_per_pixel, color_val);
4183
4184 expect (',');
4185 }
4186
4187 if (!x_create_x_image_and_pixmap (f, width, height, 0,
4188 &ximg, &img->pixmap)
4189 || !x_create_x_image_and_pixmap (f, width, height, 1,
4190 &mask_img, &img->mask))
4191 {
4192 image_error ("Out of memory (%s)", img->spec, Qnil);
4193 goto error;
4194 }
4195
4196 for (y = 0; y < height; y++)
4197 {
4198 expect (XPM_TK_STRING);
4199 str = beg;
4200 if (len < width * chars_per_pixel)
4201 goto failure;
4202 for (x = 0; x < width; x++, str += chars_per_pixel)
4203 {
4204 Lisp_Object color_val =
4205 (*get_color_table) (color_table, str, chars_per_pixel);
4206
4207 XPutPixel (ximg, x, y,
4208 (INTEGERP (color_val) ? XINT (color_val)
4209 : FRAME_FOREGROUND_PIXEL (f)));
4210 XPutPixel (mask_img, x, y,
4211 (!EQ (color_val, Qt) ? PIX_MASK_DRAW (f)
4212 : (have_mask = 1, PIX_MASK_RETAIN (f))));
4213 }
4214 if (y + 1 < height)
4215 expect (',');
4216 }
4217
4218 img->width = width;
4219 img->height = height;
4220
4221 x_put_x_image (f, ximg, img->pixmap, width, height);
4222 x_destroy_x_image (ximg);
4223 if (have_mask)
4224 {
4225 x_put_x_image (f, mask_img, img->mask, width, height);
4226 x_destroy_x_image (mask_img);
4227 }
4228 else
4229 {
4230 x_destroy_x_image (mask_img);
4231 Free_Pixmap (FRAME_X_DISPLAY (f), img->mask);
4232 img->mask = NO_PIXMAP;
4233 }
4234
4235 return 1;
4236
4237 failure:
4238 image_error ("Invalid XPM file (%s)", img->spec, Qnil);
4239 error:
4240 x_destroy_x_image (ximg);
4241 x_destroy_x_image (mask_img);
4242 x_clear_image (f, img);
4243 return 0;
4244
4245#undef match
4246#undef expect
4247#undef expect_ident
4248}
4249
4250static int
4251xpm_load (f, img)
4252 struct frame *f;
4253 struct image *img;
4254{
4255 int success_p = 0;
4256 Lisp_Object file_name;
4257
4258 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4259 file_name = image_spec_value (img->spec, QCfile, NULL);
4260 if (STRINGP (file_name))
4261 {
4262 Lisp_Object file;
4263 unsigned char *contents;
4264 int size;
4265 struct gcpro gcpro1;
4266
4267 file = x_find_image_file (file_name);
4268 GCPRO1 (file);
4269 if (!STRINGP (file))
4270 {
4271 image_error ("Cannot find image file `%s'", file_name, Qnil);
4272 UNGCPRO;
4273 return 0;
4274 }
4275
4276 contents = slurp_file (SDATA (file), &size);
4277 if (contents == NULL)
4278 {
4279 image_error ("Error loading XPM image `%s'", img->spec, Qnil);
4280 UNGCPRO;
4281 return 0;
4282 }
4283
4284 success_p = xpm_load_image (f, img, contents, contents + size);
4285 xfree (contents);
4286 UNGCPRO;
4287 }
4288 else
4289 {
4290 Lisp_Object data;
4291
4292 data = image_spec_value (img->spec, QCdata, NULL);
4293 success_p = xpm_load_image (f, img, SDATA (data),
4294 SDATA (data) + SBYTES (data));
4295 }
4296
4297 return success_p;
4298}
4299
4300#endif /* MAC_OS */
4301
4302
3751 4303
3752/*********************************************************************** 4304/***********************************************************************
3753 Color table 4305 Color table
@@ -3857,7 +4409,7 @@ lookup_rgb_color (f, r, g, b)
3857 /* Assemble the pixel color. */ 4409 /* Assemble the pixel color. */
3858 return pr | pg | pb; 4410 return pr | pg | pb;
3859 } 4411 }
3860 4412
3861 for (p = ct_table[i]; p; p = p->next) 4413 for (p = ct_table[i]; p; p = p->next)
3862 if (p->r == r && p->g == g && p->b == b) 4414 if (p->r == r && p->g == g && p->b == b)
3863 break; 4415 break;
@@ -4968,7 +5520,7 @@ pbm_load (f, img)
4968 x_destroy_x_image (ximg); 5520 x_destroy_x_image (ximg);
4969 5521
4970 /* X and W32 versions did it here, MAC version above. ++kfs 5522 /* X and W32 versions did it here, MAC version above. ++kfs
4971 img->width = width; 5523 img->width = width;
4972 img->height = height; */ 5524 img->height = height; */
4973 5525
4974 UNGCPRO; 5526 UNGCPRO;
@@ -5091,21 +5643,12 @@ DEF_IMGLIB_FN (png_read_end);
5091DEF_IMGLIB_FN (png_error); 5643DEF_IMGLIB_FN (png_error);
5092 5644
5093static int 5645static int
5094init_png_functions (void) 5646init_png_functions (Lisp_Object libraries)
5095{ 5647{
5096 HMODULE library; 5648 HMODULE library;
5097 5649
5098 /* Ensure zlib is loaded. Try debug version first. */
5099 if (!LoadLibrary ("zlibd.dll")
5100 && !LoadLibrary ("zlib.dll"))
5101 return 0;
5102
5103 /* Try loading libpng under probable names. */ 5650 /* Try loading libpng under probable names. */
5104 if (!(library = LoadLibrary ("libpng13d.dll")) 5651 if (!(library = w32_delayed_load (libraries, Qpng)))
5105 && !(library = LoadLibrary ("libpng13.dll"))
5106 && !(library = LoadLibrary ("libpng12d.dll"))
5107 && !(library = LoadLibrary ("libpng12.dll"))
5108 && !(library = LoadLibrary ("libpng.dll")))
5109 return 0; 5652 return 0;
5110 5653
5111 LOAD_IMGLIB_FN (library, png_get_io_ptr); 5654 LOAD_IMGLIB_FN (library, png_get_io_ptr);
@@ -5196,6 +5739,12 @@ struct png_memory_storage
5196 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH 5739 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
5197 bytes from the input to DATA. */ 5740 bytes from the input to DATA. */
5198 5741
5742#ifdef _MSC_VER
5743 /* Work around a problem with MinGW builds of graphics libraries
5744 not honoring calling conventions. */
5745#pragma optimize("g", off)
5746#endif
5747
5199static void 5748static void
5200png_read_from_memory (png_ptr, data, length) 5749png_read_from_memory (png_ptr, data, length)
5201 png_structp png_ptr; 5750 png_structp png_ptr;
@@ -5212,6 +5761,11 @@ png_read_from_memory (png_ptr, data, length)
5212 tbr->index = tbr->index + length; 5761 tbr->index = tbr->index + length;
5213} 5762}
5214 5763
5764#ifdef _MSC_VER
5765/* Restore normal optimization, as specified on the command line. */
5766#pragma optimize("", on)
5767#endif
5768
5215/* Load PNG image IMG for use on frame F. Value is non-zero if 5769/* Load PNG image IMG for use on frame F. Value is non-zero if
5216 successful. */ 5770 successful. */
5217 5771
@@ -5412,9 +5966,9 @@ png_load (f, img)
5412 png_color_16 user_bg; 5966 png_color_16 user_bg;
5413 5967
5414 bzero (&user_bg, sizeof user_bg); 5968 bzero (&user_bg, sizeof user_bg);
5415 user_bg.red = color.red >> PNG_BG_COLOR_SHIFT; 5969 user_bg.red = color.red >> 8;
5416 user_bg.green = color.green >> PNG_BG_COLOR_SHIFT; 5970 user_bg.green = color.green >> 8;
5417 user_bg.blue = color.blue >> PNG_BG_COLOR_SHIFT; 5971 user_bg.blue = color.blue >> 8;
5418 5972
5419 fn_png_set_background (png_ptr, &user_bg, 5973 fn_png_set_background (png_ptr, &user_bg,
5420 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); 5974 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
@@ -5438,9 +5992,9 @@ png_load (f, img)
5438 x_query_color (f, &color); 5992 x_query_color (f, &color);
5439 5993
5440 bzero (&frame_background, sizeof frame_background); 5994 bzero (&frame_background, sizeof frame_background);
5441 frame_background.red = color.red; 5995 frame_background.red = color.red >> 8;
5442 frame_background.green = color.green; 5996 frame_background.green = color.green >> 8;
5443 frame_background.blue = color.blue; 5997 frame_background.blue = color.blue >> 8;
5444#endif /* HAVE_X_WINDOWS */ 5998#endif /* HAVE_X_WINDOWS */
5445 5999
5446#ifdef HAVE_NTGUI 6000#ifdef HAVE_NTGUI
@@ -5451,9 +6005,9 @@ png_load (f, img)
5451 x_query_color (f, &color); 6005 x_query_color (f, &color);
5452#endif 6006#endif
5453 bzero (&frame_background, sizeof frame_background); 6007 bzero (&frame_background, sizeof frame_background);
5454 frame_background.red = 256 * GetRValue (color); 6008 frame_background.red = GetRValue (color);
5455 frame_background.green = 256 * GetGValue (color); 6009 frame_background.green = GetGValue (color);
5456 frame_background.blue = 256 * GetBValue (color); 6010 frame_background.blue = GetBValue (color);
5457#endif /* HAVE_NTGUI */ 6011#endif /* HAVE_NTGUI */
5458 6012
5459#ifdef MAC_OS 6013#ifdef MAC_OS
@@ -5738,13 +6292,11 @@ DEF_IMGLIB_FN (jpeg_std_error);
5738DEF_IMGLIB_FN (jpeg_resync_to_restart); 6292DEF_IMGLIB_FN (jpeg_resync_to_restart);
5739 6293
5740static int 6294static int
5741init_jpeg_functions (void) 6295init_jpeg_functions (Lisp_Object libraries)
5742{ 6296{
5743 HMODULE library; 6297 HMODULE library;
5744 6298
5745 if (!(library = LoadLibrary ("libjpeg.dll")) 6299 if (!(library = w32_delayed_load (libraries, Qjpeg)))
5746 && !(library = LoadLibrary ("jpeg-62.dll"))
5747 && !(library = LoadLibrary ("jpeg.dll")))
5748 return 0; 6300 return 0;
5749 6301
5750 LOAD_IMGLIB_FN (library, jpeg_finish_decompress); 6302 LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
@@ -6175,11 +6727,11 @@ DEF_IMGLIB_FN (TIFFReadRGBAImage);
6175DEF_IMGLIB_FN (TIFFClose); 6727DEF_IMGLIB_FN (TIFFClose);
6176 6728
6177static int 6729static int
6178init_tiff_functions (void) 6730init_tiff_functions (Lisp_Object libraries)
6179{ 6731{
6180 HMODULE library; 6732 HMODULE library;
6181 6733
6182 if (!(library = LoadLibrary ("libtiff.dll"))) 6734 if (!(library = w32_delayed_load (libraries, Qtiff)))
6183 return 0; 6735 return 0;
6184 6736
6185 LOAD_IMGLIB_FN (library, TIFFSetErrorHandler); 6737 LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
@@ -6595,11 +7147,11 @@ DEF_IMGLIB_FN (DGifOpen);
6595DEF_IMGLIB_FN (DGifOpenFileName); 7147DEF_IMGLIB_FN (DGifOpenFileName);
6596 7148
6597static int 7149static int
6598init_gif_functions (void) 7150init_gif_functions (Lisp_Object libraries)
6599{ 7151{
6600 HMODULE library; 7152 HMODULE library;
6601 7153
6602 if (!(library = LoadLibrary ("libungif.dll"))) 7154 if (!(library = w32_delayed_load (libraries, Qgif)))
6603 return 0; 7155 return 0;
6604 7156
6605 LOAD_IMGLIB_FN (library, DGifCloseFile); 7157 LOAD_IMGLIB_FN (library, DGifCloseFile);
@@ -6875,6 +7427,8 @@ gif_load (f, img)
6875 TimeValue time; 7427 TimeValue time;
6876 struct gcpro gcpro1; 7428 struct gcpro gcpro1;
6877 int ino; 7429 int ino;
7430 CGrafPtr old_port;
7431 GDHandle old_gdh;
6878 7432
6879 specified_file = image_spec_value (img->spec, QCfile, NULL); 7433 specified_file = image_spec_value (img->spec, QCfile, NULL);
6880 specified_data = image_spec_value (img->spec, QCdata, NULL); 7434 specified_data = image_spec_value (img->spec, QCdata, NULL);
@@ -6992,11 +7546,13 @@ gif_load (f, img)
6992 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 7546 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6993 goto error; 7547 goto error;
6994 7548
7549 GetGWorld (&old_port, &old_gdh);
6995 SetGWorld (ximg, NULL); 7550 SetGWorld (ximg, NULL);
6996 bg_color.red = color.red; 7551 bg_color.red = color.red;
6997 bg_color.green = color.green; 7552 bg_color.green = color.green;
6998 bg_color.blue = color.blue; 7553 bg_color.blue = color.blue;
6999 RGBBackColor (&bg_color); 7554 RGBBackColor (&bg_color);
7555 SetGWorld (old_port, old_gdh);
7000 SetMovieActive (movie, TRUE); 7556 SetMovieActive (movie, TRUE);
7001 SetMovieGWorld (movie, ximg, NULL); 7557 SetMovieGWorld (movie, ximg, NULL);
7002 SampleNumToMediaTime (media, ino + 1, &time, NULL); 7558 SampleNumToMediaTime (media, ino + 1, &time, NULL);
@@ -7368,9 +7924,81 @@ DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
7368 Initialization 7924 Initialization
7369 ***********************************************************************/ 7925 ***********************************************************************/
7370 7926
7927#ifdef HAVE_NTGUI
7928/* Image types that rely on external libraries are loaded dynamically
7929 if the library is available. */
7930#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn) \
7931 define_image_type (image_type, init_lib_fn (libraries))
7932#else
7933#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn) \
7934 define_image_type (image_type, TRUE)
7935#endif /* HAVE_NTGUI */
7936
7937DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
7938 doc: /* Initialize image library implementing image type TYPE.
7939Return non-nil if TYPE is a supported image type.
7940
7941Image types pbm and xbm are prebuilt; other types are loaded here.
7942Libraries to load are specified in alist LIBRARIES (usually, the value
7943of `image-library-alist', which see. */)
7944 (type, libraries)
7945{
7946 Lisp_Object tested;
7947
7948 /* Don't try to reload the library. */
7949 tested = Fassq (type, Vimage_type_cache);
7950 if (CONSP (tested))
7951 return XCDR (tested);
7952
7953#if defined (HAVE_XPM) || defined (MAC_OS)
7954 if (EQ (type, Qxpm))
7955 return CHECK_LIB_AVAILABLE(&xpm_type, init_xpm_functions);
7956#endif
7957
7958#if defined (HAVE_JPEG) || defined (MAC_OS)
7959 if (EQ (type, Qjpeg))
7960 return CHECK_LIB_AVAILABLE(&jpeg_type, init_jpeg_functions);
7961#endif
7962
7963#if defined (HAVE_TIFF) || defined (MAC_OS)
7964 if (EQ (type, Qtiff))
7965 return CHECK_LIB_AVAILABLE(&tiff_type, init_tiff_functions);
7966#endif
7967
7968#if defined (HAVE_GIF) || defined (MAC_OS)
7969 if (EQ (type, Qgif))
7970 return CHECK_LIB_AVAILABLE(&gif_type, init_gif_functions);
7971#endif
7972
7973#if defined (HAVE_PNG) || defined (MAC_OS)
7974 if (EQ (type, Qpng))
7975 return CHECK_LIB_AVAILABLE(&png_type, init_png_functions);
7976#endif
7977
7978#ifdef HAVE_GHOSTSCRIPT
7979 if (EQ (type, Qpostscript))
7980 return CHECK_LIB_AVAILABLE(&gs_type, init_gs_functions);
7981#endif
7982
7983 /* If the type is not recognized, avoid testing it ever again. */
7984 CACHE_IMAGE_TYPE(type, Qnil);
7985 return Qnil;
7986}
7987
7371void 7988void
7372syms_of_image () 7989syms_of_image ()
7373{ 7990{
7991 /* Must be defined now becase we're going to update it below, while
7992 defining the supported image types. */
7993 DEFVAR_LISP ("image-types", &Vimage_types,
7994 doc: /* List of potentially supported image types.
7995Each element of the list is a symbol for a image type, like 'jpeg or 'png.
7996To check whether it is really supported, use `image-type-available-p'. */);
7997 Vimage_types = Qnil;
7998
7999 Vimage_type_cache = Qnil;
8000 staticpro (&Vimage_type_cache);
8001
7374 QCascent = intern (":ascent"); 8002 QCascent = intern (":ascent");
7375 staticpro (&QCascent); 8003 staticpro (&QCascent);
7376 QCmargin = intern (":margin"); 8004 QCmargin = intern (":margin");
@@ -7404,6 +8032,7 @@ syms_of_image ()
7404 Qpostscript = intern ("postscript"); 8032 Qpostscript = intern ("postscript");
7405 staticpro (&Qpostscript); 8033 staticpro (&Qpostscript);
7406#ifdef HAVE_GHOSTSCRIPT 8034#ifdef HAVE_GHOSTSCRIPT
8035 ADD_IMAGE_TYPE(Qpostscript);
7407 QCloader = intern (":loader"); 8036 QCloader = intern (":loader");
7408 staticpro (&QCloader); 8037 staticpro (&QCloader);
7409 QCbounding_box = intern (":bounding-box"); 8038 QCbounding_box = intern (":bounding-box");
@@ -7416,35 +8045,43 @@ syms_of_image ()
7416 8045
7417 Qpbm = intern ("pbm"); 8046 Qpbm = intern ("pbm");
7418 staticpro (&Qpbm); 8047 staticpro (&Qpbm);
8048 ADD_IMAGE_TYPE(Qpbm);
7419 8049
7420 Qxbm = intern ("xbm"); 8050 Qxbm = intern ("xbm");
7421 staticpro (&Qxbm); 8051 staticpro (&Qxbm);
8052 ADD_IMAGE_TYPE(Qxbm);
7422 8053
7423#ifdef HAVE_XPM 8054#if defined (HAVE_XPM) || defined (MAC_OS)
7424 Qxpm = intern ("xpm"); 8055 Qxpm = intern ("xpm");
7425 staticpro (&Qxpm); 8056 staticpro (&Qxpm);
8057 ADD_IMAGE_TYPE(Qxpm);
7426#endif 8058#endif
7427 8059
7428#if defined (HAVE_JPEG) || defined (MAC_OS) 8060#if defined (HAVE_JPEG) || defined (MAC_OS)
7429 Qjpeg = intern ("jpeg"); 8061 Qjpeg = intern ("jpeg");
7430 staticpro (&Qjpeg); 8062 staticpro (&Qjpeg);
8063 ADD_IMAGE_TYPE(Qjpeg);
7431#endif 8064#endif
7432 8065
7433#if defined (HAVE_TIFF) || defined (MAC_OS) 8066#if defined (HAVE_TIFF) || defined (MAC_OS)
7434 Qtiff = intern ("tiff"); 8067 Qtiff = intern ("tiff");
7435 staticpro (&Qtiff); 8068 staticpro (&Qtiff);
8069 ADD_IMAGE_TYPE(Qtiff);
7436#endif 8070#endif
7437 8071
7438#if defined (HAVE_GIF) || defined (MAC_OS) 8072#if defined (HAVE_GIF) || defined (MAC_OS)
7439 Qgif = intern ("gif"); 8073 Qgif = intern ("gif");
7440 staticpro (&Qgif); 8074 staticpro (&Qgif);
8075 ADD_IMAGE_TYPE(Qgif);
7441#endif 8076#endif
7442 8077
7443#if defined (HAVE_PNG) || defined (MAC_OS) 8078#if defined (HAVE_PNG) || defined (MAC_OS)
7444 Qpng = intern ("png"); 8079 Qpng = intern ("png");
7445 staticpro (&Qpng); 8080 staticpro (&Qpng);
8081 ADD_IMAGE_TYPE(Qpng);
7446#endif 8082#endif
7447 8083
8084 defsubr (&Sinit_image_library);
7448 defsubr (&Sclear_image_cache); 8085 defsubr (&Sclear_image_cache);
7449 defsubr (&Simage_size); 8086 defsubr (&Simage_size);
7450 defsubr (&Simage_mask_p); 8087 defsubr (&Simage_mask_p);
@@ -7472,52 +8109,13 @@ meaning don't clear the cache. */);
7472 Vimage_cache_eviction_delay = make_number (30 * 60); 8109 Vimage_cache_eviction_delay = make_number (30 * 60);
7473} 8110}
7474 8111
7475
7476#ifdef HAVE_NTGUI
7477/* Image types that rely on external libraries are loaded dynamically
7478 if the library is available. */
7479#define IF_LIB_AVAILABLE(init_lib_fn) if (init_lib_fn())
7480#else
7481#define IF_LIB_AVAILABLE(init_func) /* Load unconditionally */
7482#endif /* HAVE_NTGUI */
7483
7484void 8112void
7485init_image () 8113init_image ()
7486{ 8114{
7487 image_types = NULL; 8115 image_types = NULL;
7488 Vimage_types = Qnil;
7489
7490 define_image_type (&xbm_type);
7491 define_image_type (&pbm_type);
7492 8116
7493#ifdef HAVE_XPM 8117 define_image_type (&xbm_type, TRUE);
7494 IF_LIB_AVAILABLE(init_xpm_functions) 8118 define_image_type (&pbm_type, TRUE);
7495 define_image_type (&xpm_type);
7496#endif
7497
7498#if defined (HAVE_JPEG) || defined (MAC_OS)
7499 IF_LIB_AVAILABLE(init_jpeg_functions)
7500 define_image_type (&jpeg_type);
7501#endif
7502
7503#if defined (HAVE_TIFF) || defined (MAC_OS)
7504 IF_LIB_AVAILABLE(init_tiff_functions)
7505 define_image_type (&tiff_type);
7506#endif
7507
7508#if defined (HAVE_GIF) || defined (MAC_OS)
7509 IF_LIB_AVAILABLE(init_gif_functions)
7510 define_image_type (&gif_type);
7511#endif
7512
7513#if defined (HAVE_PNG) || defined (MAC_OS)
7514 IF_LIB_AVAILABLE(init_png_functions)
7515 define_image_type (&png_type);
7516#endif
7517
7518#ifdef HAVE_GHOSTSCRIPT
7519 define_image_type (&gs_type);
7520#endif
7521 8119
7522#ifdef MAC_OS 8120#ifdef MAC_OS
7523 /* Animated gifs use QuickTime Movie Toolbox. So initialize it here. */ 8121 /* Animated gifs use QuickTime Movie Toolbox. So initialize it here. */