diff options
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 405 |
1 files changed, 229 insertions, 176 deletions
diff --git a/src/image.c b/src/image.c index 928ec0437aa..6ec0734e785 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* Functions for image support on window system. | 1 | /* Functions for image support on window system. |
| 2 | Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 99, 2000,01,02,03,04 | 2 | Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, |
| 3 | Free Software Foundation. | 3 | 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | This file is part of GNU Emacs. | 5 | This file is part of GNU Emacs. |
| 6 | 6 | ||
| @@ -54,8 +54,8 @@ typedef struct x_bitmap_record Bitmap_Record; | |||
| 54 | 54 | ||
| 55 | #define RGB_PIXEL_COLOR unsigned long | 55 | #define RGB_PIXEL_COLOR unsigned long |
| 56 | 56 | ||
| 57 | #define PIX_MASK_RETAIN(f) 0 | 57 | #define PIX_MASK_RETAIN 0 |
| 58 | #define PIX_MASK_DRAW(f) 1 | 58 | #define PIX_MASK_DRAW 1 |
| 59 | #endif /* HAVE_X_WINDOWS */ | 59 | #endif /* HAVE_X_WINDOWS */ |
| 60 | 60 | ||
| 61 | 61 | ||
| @@ -71,8 +71,8 @@ typedef struct w32_bitmap_record Bitmap_Record; | |||
| 71 | 71 | ||
| 72 | #define RGB_PIXEL_COLOR COLORREF | 72 | #define RGB_PIXEL_COLOR COLORREF |
| 73 | 73 | ||
| 74 | #define PIX_MASK_RETAIN(f) 0 | 74 | #define PIX_MASK_RETAIN 0 |
| 75 | #define PIX_MASK_DRAW(f) 1 | 75 | #define PIX_MASK_DRAW 1 |
| 76 | 76 | ||
| 77 | #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual | 77 | #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual |
| 78 | #define x_defined_color w32_defined_color | 78 | #define x_defined_color w32_defined_color |
| @@ -112,6 +112,11 @@ typedef struct mac_bitmap_record Bitmap_Record; | |||
| 112 | 112 | ||
| 113 | #define RGB_PIXEL_COLOR unsigned long | 113 | #define RGB_PIXEL_COLOR unsigned long |
| 114 | 114 | ||
| 115 | /* A black pixel in a mask bitmap/pixmap means ``draw a source | ||
| 116 | pixel''. A white pixel means ``retain the current pixel''. */ | ||
| 117 | #define PIX_MASK_DRAW RGB_TO_ULONG(0,0,0) | ||
| 118 | #define PIX_MASK_RETAIN RGB_TO_ULONG(255,255,255) | ||
| 119 | |||
| 115 | #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual | 120 | #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual |
| 116 | #define x_defined_color mac_defined_color | 121 | #define x_defined_color mac_defined_color |
| 117 | #define DefaultDepthOfScreen(screen) (one_mac_display_info.n_planes) | 122 | #define DefaultDepthOfScreen(screen) (one_mac_display_info.n_planes) |
| @@ -181,19 +186,43 @@ XPutPixel (ximage, x, y, pixel) | |||
| 181 | int x, y; | 186 | int x, y; |
| 182 | unsigned long pixel; | 187 | unsigned long pixel; |
| 183 | { | 188 | { |
| 184 | CGrafPtr old_port; | 189 | PixMapHandle pixmap = GetGWorldPixMap (ximage); |
| 185 | GDHandle old_gdh; | 190 | short depth = GetPixDepth (pixmap); |
| 186 | RGBColor color; | ||
| 187 | 191 | ||
| 188 | GetGWorld (&old_port, &old_gdh); | 192 | if (depth == 32) |
| 189 | SetGWorld (ximage, NULL); | 193 | { |
| 194 | char *base_addr = GetPixBaseAddr (pixmap); | ||
| 195 | short row_bytes = GetPixRowBytes (pixmap); | ||
| 190 | 196 | ||
| 191 | color.red = RED16_FROM_ULONG (pixel); | 197 | ((unsigned long *) (base_addr + y * row_bytes))[x] = pixel; |
| 192 | color.green = GREEN16_FROM_ULONG (pixel); | 198 | } |
| 193 | color.blue = BLUE16_FROM_ULONG (pixel); | 199 | else if (depth == 1) |
| 194 | SetCPixel (x, y, &color); | 200 | { |
| 201 | char *base_addr = GetPixBaseAddr (pixmap); | ||
| 202 | short row_bytes = GetPixRowBytes (pixmap); | ||
| 195 | 203 | ||
| 196 | SetGWorld (old_port, old_gdh); | 204 | if (pixel == PIX_MASK_DRAW) |
| 205 | base_addr[y * row_bytes + x / 8] |= (1 << 7) >> (x & 7); | ||
| 206 | else | ||
| 207 | base_addr[y * row_bytes + x / 8] &= ~((1 << 7) >> (x & 7)); | ||
| 208 | } | ||
| 209 | else | ||
| 210 | { | ||
| 211 | CGrafPtr old_port; | ||
| 212 | GDHandle old_gdh; | ||
| 213 | RGBColor color; | ||
| 214 | |||
| 215 | GetGWorld (&old_port, &old_gdh); | ||
| 216 | SetGWorld (ximage, NULL); | ||
| 217 | |||
| 218 | color.red = RED16_FROM_ULONG (pixel); | ||
| 219 | color.green = GREEN16_FROM_ULONG (pixel); | ||
| 220 | color.blue = BLUE16_FROM_ULONG (pixel); | ||
| 221 | |||
| 222 | SetCPixel (x, y, &color); | ||
| 223 | |||
| 224 | SetGWorld (old_port, old_gdh); | ||
| 225 | } | ||
| 197 | } | 226 | } |
| 198 | 227 | ||
| 199 | static unsigned long | 228 | static unsigned long |
| @@ -201,17 +230,40 @@ XGetPixel (ximage, x, y) | |||
| 201 | XImagePtr ximage; | 230 | XImagePtr ximage; |
| 202 | int x, y; | 231 | int x, y; |
| 203 | { | 232 | { |
| 204 | CGrafPtr old_port; | 233 | PixMapHandle pixmap = GetGWorldPixMap (ximage); |
| 205 | GDHandle old_gdh; | 234 | short depth = GetPixDepth (pixmap); |
| 206 | RGBColor color; | ||
| 207 | 235 | ||
| 208 | GetGWorld (&old_port, &old_gdh); | 236 | if (depth == 32) |
| 209 | SetGWorld (ximage, NULL); | 237 | { |
| 238 | char *base_addr = GetPixBaseAddr (pixmap); | ||
| 239 | short row_bytes = GetPixRowBytes (pixmap); | ||
| 210 | 240 | ||
| 211 | GetCPixel (x, y, &color); | 241 | return ((unsigned long *) (base_addr + y * row_bytes))[x]; |
| 242 | } | ||
| 243 | else if (depth == 1) | ||
| 244 | { | ||
| 245 | char *base_addr = GetPixBaseAddr (pixmap); | ||
| 246 | short row_bytes = GetPixRowBytes (pixmap); | ||
| 212 | 247 | ||
| 213 | SetGWorld (old_port, old_gdh); | 248 | if (base_addr[y * row_bytes + x / 8] & (1 << (~x & 7))) |
| 214 | return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8); | 249 | return PIX_MASK_DRAW; |
| 250 | else | ||
| 251 | return PIX_MASK_RETAIN; | ||
| 252 | } | ||
| 253 | else | ||
| 254 | { | ||
| 255 | CGrafPtr old_port; | ||
| 256 | GDHandle old_gdh; | ||
| 257 | RGBColor color; | ||
| 258 | |||
| 259 | GetGWorld (&old_port, &old_gdh); | ||
| 260 | SetGWorld (ximage, NULL); | ||
| 261 | |||
| 262 | GetCPixel (x, y, &color); | ||
| 263 | |||
| 264 | SetGWorld (old_port, old_gdh); | ||
| 265 | return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8); | ||
| 266 | } | ||
| 215 | } | 267 | } |
| 216 | 268 | ||
| 217 | static void | 269 | static void |
| @@ -1300,7 +1352,7 @@ image_background_transparent (img, f, mask) | |||
| 1300 | } | 1352 | } |
| 1301 | 1353 | ||
| 1302 | img->background_transparent | 1354 | img->background_transparent |
| 1303 | = (four_corners_best (mask, img->width, img->height) == PIX_MASK_RETAIN (f)); | 1355 | = (four_corners_best (mask, img->width, img->height) == PIX_MASK_RETAIN); |
| 1304 | 1356 | ||
| 1305 | if (free_mask) | 1357 | if (free_mask) |
| 1306 | Destroy_Image (mask, prev); | 1358 | Destroy_Image (mask, prev); |
| @@ -2003,7 +2055,6 @@ x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap) | |||
| 2003 | *pixmap = XCreatePixmap (display, window, width, height, depth); | 2055 | *pixmap = XCreatePixmap (display, window, width, height, depth); |
| 2004 | if (*pixmap == NO_PIXMAP) | 2056 | if (*pixmap == NO_PIXMAP) |
| 2005 | { | 2057 | { |
| 2006 | x_destroy_x_image (*ximg); | ||
| 2007 | *ximg = NULL; | 2058 | *ximg = NULL; |
| 2008 | image_error ("Unable to create X pixmap", Qnil, Qnil); | 2059 | image_error ("Unable to create X pixmap", Qnil, Qnil); |
| 2009 | return 0; | 2060 | return 0; |
| @@ -2166,10 +2217,8 @@ find_image_fsspec (specified_file, file, fss) | |||
| 2166 | Lisp_Object specified_file, *file; | 2217 | Lisp_Object specified_file, *file; |
| 2167 | FSSpec *fss; | 2218 | FSSpec *fss; |
| 2168 | { | 2219 | { |
| 2169 | #if TARGET_API_MAC_CARBON | 2220 | #if MAC_OSX |
| 2170 | FSRef fsr; | 2221 | FSRef fsr; |
| 2171 | #else | ||
| 2172 | Str255 mac_pathname; | ||
| 2173 | #endif | 2222 | #endif |
| 2174 | OSErr err; | 2223 | OSErr err; |
| 2175 | 2224 | ||
| @@ -2178,15 +2227,12 @@ find_image_fsspec (specified_file, file, fss) | |||
| 2178 | return fnfErr; /* file or directory not found; | 2227 | return fnfErr; /* file or directory not found; |
| 2179 | incomplete pathname */ | 2228 | incomplete pathname */ |
| 2180 | /* Try to open the image file. */ | 2229 | /* Try to open the image file. */ |
| 2181 | #if TARGET_API_MAC_CARBON | 2230 | #if MAC_OSX |
| 2182 | err = FSPathMakeRef (SDATA (*file), &fsr, NULL); | 2231 | err = FSPathMakeRef (SDATA (*file), &fsr, NULL); |
| 2183 | if (err == noErr) | 2232 | if (err == noErr) |
| 2184 | err = FSGetCatalogInfo (&fsr, kFSCatInfoNone, NULL, NULL, fss, NULL); | 2233 | err = FSGetCatalogInfo (&fsr, kFSCatInfoNone, NULL, NULL, fss, NULL); |
| 2185 | #else | 2234 | #else |
| 2186 | if (posix_to_mac_pathname (SDATA (*file), mac_pathname, MAXPATHLEN+1) == 0) | 2235 | err = posix_pathname_to_fsspec (SDATA (*file), fss); |
| 2187 | return fnfErr; | ||
| 2188 | c2pstr (mac_pathname); | ||
| 2189 | err = FSMakeFSSpec (0, 0, mac_pathname, fss); | ||
| 2190 | #endif | 2236 | #endif |
| 2191 | return err; | 2237 | return err; |
| 2192 | } | 2238 | } |
| @@ -3850,24 +3896,24 @@ xpm_load (f, img) | |||
| 3850 | Only XPM version 3 (without any extensions) is supported. */ | 3896 | Only XPM version 3 (without any extensions) is supported. */ |
| 3851 | 3897 | ||
| 3852 | static int xpm_scan P_ ((unsigned char **, unsigned char *, | 3898 | static int xpm_scan P_ ((unsigned char **, unsigned char *, |
| 3853 | unsigned char **, int *)); | 3899 | unsigned char **, int *)); |
| 3854 | static Lisp_Object xpm_make_color_table_v | 3900 | static Lisp_Object xpm_make_color_table_v |
| 3855 | P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), | 3901 | P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), |
| 3856 | Lisp_Object (**) (Lisp_Object, unsigned char *, int))); | 3902 | Lisp_Object (**) (Lisp_Object, unsigned char *, int))); |
| 3857 | static void xpm_put_color_table_v P_ ((Lisp_Object, unsigned char *, | 3903 | static void xpm_put_color_table_v P_ ((Lisp_Object, unsigned char *, |
| 3858 | int, Lisp_Object)); | 3904 | int, Lisp_Object)); |
| 3859 | static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object, | 3905 | static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object, |
| 3860 | unsigned char *, int)); | 3906 | unsigned char *, int)); |
| 3861 | static Lisp_Object xpm_make_color_table_h | 3907 | static Lisp_Object xpm_make_color_table_h |
| 3862 | P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), | 3908 | P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), |
| 3863 | Lisp_Object (**) (Lisp_Object, unsigned char *, int))); | 3909 | Lisp_Object (**) (Lisp_Object, unsigned char *, int))); |
| 3864 | static void xpm_put_color_table_h P_ ((Lisp_Object, unsigned char *, | 3910 | static void xpm_put_color_table_h P_ ((Lisp_Object, unsigned char *, |
| 3865 | int, Lisp_Object)); | 3911 | int, Lisp_Object)); |
| 3866 | static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object, | 3912 | static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object, |
| 3867 | unsigned char *, int)); | 3913 | unsigned char *, int)); |
| 3868 | static int xpm_str_to_color_key P_ ((char *)); | 3914 | static int xpm_str_to_color_key P_ ((char *)); |
| 3869 | static int xpm_load_image P_ ((struct frame *, struct image *, | 3915 | static int xpm_load_image P_ ((struct frame *, struct image *, |
| 3870 | unsigned char *, unsigned char *)); | 3916 | unsigned char *, unsigned char *)); |
| 3871 | 3917 | ||
| 3872 | /* Tokens returned from xpm_scan. */ | 3918 | /* Tokens returned from xpm_scan. */ |
| 3873 | 3919 | ||
| @@ -3896,49 +3942,49 @@ xpm_scan (s, end, beg, len) | |||
| 3896 | { | 3942 | { |
| 3897 | /* Skip white-space. */ | 3943 | /* Skip white-space. */ |
| 3898 | while (*s < end && (c = *(*s)++, isspace (c))) | 3944 | while (*s < end && (c = *(*s)++, isspace (c))) |
| 3899 | ; | 3945 | ; |
| 3900 | 3946 | ||
| 3901 | /* gnus-pointer.xpm uses '-' in its identifier. | 3947 | /* gnus-pointer.xpm uses '-' in its identifier. |
| 3902 | sb-dir-plus.xpm uses '+' in its identifier. */ | 3948 | sb-dir-plus.xpm uses '+' in its identifier. */ |
| 3903 | if (isalpha (c) || c == '_' || c == '-' || c == '+') | 3949 | if (isalpha (c) || c == '_' || c == '-' || c == '+') |
| 3904 | { | 3950 | { |
| 3905 | *beg = *s - 1; | 3951 | *beg = *s - 1; |
| 3906 | while (*s < end && | 3952 | while (*s < end && |
| 3907 | (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+')) | 3953 | (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+')) |
| 3908 | ++*s; | 3954 | ++*s; |
| 3909 | *len = *s - *beg; | 3955 | *len = *s - *beg; |
| 3910 | return XPM_TK_IDENT; | 3956 | return XPM_TK_IDENT; |
| 3911 | } | 3957 | } |
| 3912 | else if (c == '"') | 3958 | else if (c == '"') |
| 3913 | { | 3959 | { |
| 3914 | *beg = *s; | 3960 | *beg = *s; |
| 3915 | while (*s < end && **s != '"') | 3961 | while (*s < end && **s != '"') |
| 3916 | ++*s; | 3962 | ++*s; |
| 3917 | *len = *s - *beg; | 3963 | *len = *s - *beg; |
| 3918 | if (*s < end) | 3964 | if (*s < end) |
| 3919 | ++*s; | 3965 | ++*s; |
| 3920 | return XPM_TK_STRING; | 3966 | return XPM_TK_STRING; |
| 3921 | } | 3967 | } |
| 3922 | else if (c == '/') | 3968 | else if (c == '/') |
| 3923 | { | 3969 | { |
| 3924 | if (*s < end && **s == '*') | 3970 | if (*s < end && **s == '*') |
| 3925 | { | 3971 | { |
| 3926 | /* C-style comment. */ | 3972 | /* C-style comment. */ |
| 3927 | ++*s; | 3973 | ++*s; |
| 3928 | do | 3974 | do |
| 3929 | { | 3975 | { |
| 3930 | while (*s < end && *(*s)++ != '*') | 3976 | while (*s < end && *(*s)++ != '*') |
| 3931 | ; | 3977 | ; |
| 3932 | } | 3978 | } |
| 3933 | while (*s < end && **s != '/'); | 3979 | while (*s < end && **s != '/'); |
| 3934 | if (*s < end) | 3980 | if (*s < end) |
| 3935 | ++*s; | 3981 | ++*s; |
| 3936 | } | 3982 | } |
| 3937 | else | 3983 | else |
| 3938 | return c; | 3984 | return c; |
| 3939 | } | 3985 | } |
| 3940 | else | 3986 | else |
| 3941 | return c; | 3987 | return c; |
| 3942 | } | 3988 | } |
| 3943 | 3989 | ||
| 3944 | return XPM_TK_EOF; | 3990 | return XPM_TK_EOF; |
| @@ -3988,9 +4034,9 @@ xpm_make_color_table_h (put_func, get_func) | |||
| 3988 | *put_func = xpm_put_color_table_h; | 4034 | *put_func = xpm_put_color_table_h; |
| 3989 | *get_func = xpm_get_color_table_h; | 4035 | *get_func = xpm_get_color_table_h; |
| 3990 | return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), | 4036 | return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), |
| 3991 | make_float (DEFAULT_REHASH_SIZE), | 4037 | make_float (DEFAULT_REHASH_SIZE), |
| 3992 | make_float (DEFAULT_REHASH_THRESHOLD), | 4038 | make_float (DEFAULT_REHASH_THRESHOLD), |
| 3993 | Qnil, Qnil, Qnil); | 4039 | Qnil, Qnil, Qnil); |
| 3994 | } | 4040 | } |
| 3995 | 4041 | ||
| 3996 | static void | 4042 | static void |
| @@ -4016,7 +4062,7 @@ xpm_get_color_table_h (color_table, chars_start, chars_len) | |||
| 4016 | { | 4062 | { |
| 4017 | struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); | 4063 | struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); |
| 4018 | int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len), | 4064 | int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len), |
| 4019 | NULL); | 4065 | NULL); |
| 4020 | 4066 | ||
| 4021 | return i >= 0 ? HASH_VALUE (table, i) : Qnil; | 4067 | return i >= 0 ? HASH_VALUE (table, i) : Qnil; |
| 4022 | } | 4068 | } |
| @@ -4065,17 +4111,17 @@ xpm_load_image (f, img, contents, end) | |||
| 4065 | #define match() \ | 4111 | #define match() \ |
| 4066 | LA1 = xpm_scan (&s, end, &beg, &len) | 4112 | LA1 = xpm_scan (&s, end, &beg, &len) |
| 4067 | 4113 | ||
| 4068 | #define expect(TOKEN) \ | 4114 | #define expect(TOKEN) \ |
| 4069 | if (LA1 != (TOKEN)) \ | 4115 | if (LA1 != (TOKEN)) \ |
| 4070 | goto failure; \ | 4116 | goto failure; \ |
| 4071 | else \ | 4117 | else \ |
| 4072 | match () | 4118 | match () |
| 4073 | 4119 | ||
| 4074 | #define expect_ident(IDENT) \ | 4120 | #define expect_ident(IDENT) \ |
| 4075 | if (LA1 == XPM_TK_IDENT \ | 4121 | if (LA1 == XPM_TK_IDENT \ |
| 4076 | && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \ | 4122 | && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \ |
| 4077 | match (); \ | 4123 | match (); \ |
| 4078 | else \ | 4124 | else \ |
| 4079 | goto failure | 4125 | goto failure |
| 4080 | 4126 | ||
| 4081 | if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0)) | 4127 | if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0)) |
| @@ -4096,7 +4142,7 @@ xpm_load_image (f, img, contents, end) | |||
| 4096 | memcpy (buffer, beg, len); | 4142 | memcpy (buffer, beg, len); |
| 4097 | buffer[len] = '\0'; | 4143 | buffer[len] = '\0'; |
| 4098 | if (sscanf (buffer, "%d %d %d %d", &width, &height, | 4144 | if (sscanf (buffer, "%d %d %d %d", &width, &height, |
| 4099 | &num_colors, &chars_per_pixel) != 4 | 4145 | &num_colors, &chars_per_pixel) != 4 |
| 4100 | || width <= 0 || height <= 0 | 4146 | || width <= 0 || height <= 0 |
| 4101 | || num_colors <= 0 || chars_per_pixel <= 0) | 4147 | || num_colors <= 0 || chars_per_pixel <= 0) |
| 4102 | goto failure; | 4148 | goto failure; |
| @@ -4107,17 +4153,17 @@ xpm_load_image (f, img, contents, end) | |||
| 4107 | best_key = XPM_COLOR_KEY_C; | 4153 | best_key = XPM_COLOR_KEY_C; |
| 4108 | else if (!NILP (Fx_display_grayscale_p (frame))) | 4154 | else if (!NILP (Fx_display_grayscale_p (frame))) |
| 4109 | best_key = (XFASTINT (Fx_display_planes (frame)) > 2 | 4155 | best_key = (XFASTINT (Fx_display_planes (frame)) > 2 |
| 4110 | ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4); | 4156 | ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4); |
| 4111 | else | 4157 | else |
| 4112 | best_key = XPM_COLOR_KEY_M; | 4158 | best_key = XPM_COLOR_KEY_M; |
| 4113 | 4159 | ||
| 4114 | color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL); | 4160 | color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL); |
| 4115 | if (chars_per_pixel == 1) | 4161 | if (chars_per_pixel == 1) |
| 4116 | color_table = xpm_make_color_table_v (&put_color_table, | 4162 | color_table = xpm_make_color_table_v (&put_color_table, |
| 4117 | &get_color_table); | 4163 | &get_color_table); |
| 4118 | else | 4164 | else |
| 4119 | color_table = xpm_make_color_table_h (&put_color_table, | 4165 | color_table = xpm_make_color_table_h (&put_color_table, |
| 4120 | &get_color_table); | 4166 | &get_color_table); |
| 4121 | 4167 | ||
| 4122 | while (num_colors-- > 0) | 4168 | while (num_colors-- > 0) |
| 4123 | { | 4169 | { |
| @@ -4128,71 +4174,71 @@ xpm_load_image (f, img, contents, end) | |||
| 4128 | 4174 | ||
| 4129 | expect (XPM_TK_STRING); | 4175 | expect (XPM_TK_STRING); |
| 4130 | if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel) | 4176 | if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel) |
| 4131 | goto failure; | 4177 | goto failure; |
| 4132 | memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel); | 4178 | memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel); |
| 4133 | buffer[len - chars_per_pixel] = '\0'; | 4179 | buffer[len - chars_per_pixel] = '\0'; |
| 4134 | 4180 | ||
| 4135 | str = strtok (buffer, " \t"); | 4181 | str = strtok (buffer, " \t"); |
| 4136 | if (str == NULL) | 4182 | if (str == NULL) |
| 4137 | goto failure; | 4183 | goto failure; |
| 4138 | key = xpm_str_to_color_key (str); | 4184 | key = xpm_str_to_color_key (str); |
| 4139 | if (key < 0) | 4185 | if (key < 0) |
| 4140 | goto failure; | 4186 | goto failure; |
| 4141 | do | 4187 | do |
| 4142 | { | 4188 | { |
| 4143 | color = strtok (NULL, " \t"); | 4189 | color = strtok (NULL, " \t"); |
| 4144 | if (color == NULL) | 4190 | if (color == NULL) |
| 4145 | goto failure; | 4191 | goto failure; |
| 4146 | 4192 | ||
| 4147 | while (str = strtok (NULL, " \t")) | 4193 | while (str = strtok (NULL, " \t")) |
| 4148 | { | 4194 | { |
| 4149 | next_key = xpm_str_to_color_key (str); | 4195 | next_key = xpm_str_to_color_key (str); |
| 4150 | if (next_key >= 0) | 4196 | if (next_key >= 0) |
| 4151 | break; | 4197 | break; |
| 4152 | color[strlen (color)] = ' '; | 4198 | color[strlen (color)] = ' '; |
| 4153 | } | 4199 | } |
| 4154 | 4200 | ||
| 4155 | if (key == XPM_COLOR_KEY_S) | 4201 | if (key == XPM_COLOR_KEY_S) |
| 4156 | { | 4202 | { |
| 4157 | if (NILP (symbol_color)) | 4203 | if (NILP (symbol_color)) |
| 4158 | symbol_color = build_string (color); | 4204 | symbol_color = build_string (color); |
| 4159 | } | 4205 | } |
| 4160 | else if (max_key < key && key <= best_key) | 4206 | else if (max_key < key && key <= best_key) |
| 4161 | { | 4207 | { |
| 4162 | max_key = key; | 4208 | max_key = key; |
| 4163 | max_color = color; | 4209 | max_color = color; |
| 4164 | } | 4210 | } |
| 4165 | key = next_key; | 4211 | key = next_key; |
| 4166 | } | 4212 | } |
| 4167 | while (str); | 4213 | while (str); |
| 4168 | 4214 | ||
| 4169 | color_val = Qnil; | 4215 | color_val = Qnil; |
| 4170 | if (!NILP (color_symbols) && !NILP (symbol_color)) | 4216 | if (!NILP (color_symbols) && !NILP (symbol_color)) |
| 4171 | { | 4217 | { |
| 4172 | Lisp_Object specified_color = Fassoc (symbol_color, color_symbols); | 4218 | Lisp_Object specified_color = Fassoc (symbol_color, color_symbols); |
| 4173 | 4219 | ||
| 4174 | if (CONSP (specified_color) && STRINGP (XCDR (specified_color))) | 4220 | if (CONSP (specified_color) && STRINGP (XCDR (specified_color))) |
| 4175 | if (xstricmp (SDATA (XCDR (specified_color)), "None") == 0) | 4221 | if (xstricmp (SDATA (XCDR (specified_color)), "None") == 0) |
| 4176 | color_val = Qt; | 4222 | color_val = Qt; |
| 4177 | else if (x_defined_color (f, SDATA (XCDR (specified_color)), | 4223 | else if (x_defined_color (f, SDATA (XCDR (specified_color)), |
| 4178 | &cdef, 0)) | 4224 | &cdef, 0)) |
| 4179 | color_val = make_number (cdef.pixel); | 4225 | color_val = make_number (cdef.pixel); |
| 4180 | } | 4226 | } |
| 4181 | if (NILP (color_val) && max_key > 0) | 4227 | if (NILP (color_val) && max_key > 0) |
| 4182 | if (xstricmp (max_color, "None") == 0) | 4228 | if (xstricmp (max_color, "None") == 0) |
| 4183 | color_val = Qt; | 4229 | color_val = Qt; |
| 4184 | else if (x_defined_color (f, max_color, &cdef, 0)) | 4230 | else if (x_defined_color (f, max_color, &cdef, 0)) |
| 4185 | color_val = make_number (cdef.pixel); | 4231 | color_val = make_number (cdef.pixel); |
| 4186 | if (!NILP (color_val)) | 4232 | if (!NILP (color_val)) |
| 4187 | (*put_color_table) (color_table, beg, chars_per_pixel, color_val); | 4233 | (*put_color_table) (color_table, beg, chars_per_pixel, color_val); |
| 4188 | 4234 | ||
| 4189 | expect (','); | 4235 | expect (','); |
| 4190 | } | 4236 | } |
| 4191 | 4237 | ||
| 4192 | if (!x_create_x_image_and_pixmap (f, width, height, 0, | 4238 | if (!x_create_x_image_and_pixmap (f, width, height, 0, |
| 4193 | &ximg, &img->pixmap) | 4239 | &ximg, &img->pixmap) |
| 4194 | || !x_create_x_image_and_pixmap (f, width, height, 1, | 4240 | || !x_create_x_image_and_pixmap (f, width, height, 1, |
| 4195 | &mask_img, &img->mask)) | 4241 | &mask_img, &img->mask)) |
| 4196 | { | 4242 | { |
| 4197 | image_error ("Out of memory (%s)", img->spec, Qnil); | 4243 | image_error ("Out of memory (%s)", img->spec, Qnil); |
| 4198 | goto error; | 4244 | goto error; |
| @@ -4203,21 +4249,21 @@ xpm_load_image (f, img, contents, end) | |||
| 4203 | expect (XPM_TK_STRING); | 4249 | expect (XPM_TK_STRING); |
| 4204 | str = beg; | 4250 | str = beg; |
| 4205 | if (len < width * chars_per_pixel) | 4251 | if (len < width * chars_per_pixel) |
| 4206 | goto failure; | 4252 | goto failure; |
| 4207 | for (x = 0; x < width; x++, str += chars_per_pixel) | 4253 | for (x = 0; x < width; x++, str += chars_per_pixel) |
| 4208 | { | 4254 | { |
| 4209 | Lisp_Object color_val = | 4255 | Lisp_Object color_val = |
| 4210 | (*get_color_table) (color_table, str, chars_per_pixel); | 4256 | (*get_color_table) (color_table, str, chars_per_pixel); |
| 4211 | 4257 | ||
| 4212 | XPutPixel (ximg, x, y, | 4258 | XPutPixel (ximg, x, y, |
| 4213 | (INTEGERP (color_val) ? XINT (color_val) | 4259 | (INTEGERP (color_val) ? XINT (color_val) |
| 4214 | : FRAME_FOREGROUND_PIXEL (f))); | 4260 | : FRAME_FOREGROUND_PIXEL (f))); |
| 4215 | XPutPixel (mask_img, x, y, | 4261 | XPutPixel (mask_img, x, y, |
| 4216 | (!EQ (color_val, Qt) ? PIX_MASK_DRAW (f) | 4262 | (!EQ (color_val, Qt) ? PIX_MASK_DRAW |
| 4217 | : (have_mask = 1, PIX_MASK_RETAIN (f)))); | 4263 | : (have_mask = 1, PIX_MASK_RETAIN))); |
| 4218 | } | 4264 | } |
| 4219 | if (y + 1 < height) | 4265 | if (y + 1 < height) |
| 4220 | expect (','); | 4266 | expect (','); |
| 4221 | } | 4267 | } |
| 4222 | 4268 | ||
| 4223 | img->width = width; | 4269 | img->width = width; |
| @@ -4227,6 +4273,10 @@ xpm_load_image (f, img, contents, end) | |||
| 4227 | x_destroy_x_image (ximg); | 4273 | x_destroy_x_image (ximg); |
| 4228 | if (have_mask) | 4274 | if (have_mask) |
| 4229 | { | 4275 | { |
| 4276 | /* Fill in the background_transparent field while we have the | ||
| 4277 | mask handy. */ | ||
| 4278 | image_background_transparent (img, f, mask_img); | ||
| 4279 | |||
| 4230 | x_put_x_image (f, mask_img, img->mask, width, height); | 4280 | x_put_x_image (f, mask_img, img->mask, width, height); |
| 4231 | x_destroy_x_image (mask_img); | 4281 | x_destroy_x_image (mask_img); |
| 4232 | } | 4282 | } |
| @@ -4272,19 +4322,19 @@ xpm_load (f, img) | |||
| 4272 | file = x_find_image_file (file_name); | 4322 | file = x_find_image_file (file_name); |
| 4273 | GCPRO1 (file); | 4323 | GCPRO1 (file); |
| 4274 | if (!STRINGP (file)) | 4324 | if (!STRINGP (file)) |
| 4275 | { | 4325 | { |
| 4276 | image_error ("Cannot find image file `%s'", file_name, Qnil); | 4326 | image_error ("Cannot find image file `%s'", file_name, Qnil); |
| 4277 | UNGCPRO; | 4327 | UNGCPRO; |
| 4278 | return 0; | 4328 | return 0; |
| 4279 | } | 4329 | } |
| 4280 | 4330 | ||
| 4281 | contents = slurp_file (SDATA (file), &size); | 4331 | contents = slurp_file (SDATA (file), &size); |
| 4282 | if (contents == NULL) | 4332 | if (contents == NULL) |
| 4283 | { | 4333 | { |
| 4284 | image_error ("Error loading XPM image `%s'", img->spec, Qnil); | 4334 | image_error ("Error loading XPM image `%s'", img->spec, Qnil); |
| 4285 | UNGCPRO; | 4335 | UNGCPRO; |
| 4286 | return 0; | 4336 | return 0; |
| 4287 | } | 4337 | } |
| 4288 | 4338 | ||
| 4289 | success_p = xpm_load_image (f, img, contents, contents + size); | 4339 | success_p = xpm_load_image (f, img, contents, contents + size); |
| 4290 | xfree (contents); | 4340 | xfree (contents); |
| @@ -4296,7 +4346,7 @@ xpm_load (f, img) | |||
| 4296 | 4346 | ||
| 4297 | data = image_spec_value (img->spec, QCdata, NULL); | 4347 | data = image_spec_value (img->spec, QCdata, NULL); |
| 4298 | success_p = xpm_load_image (f, img, SDATA (data), | 4348 | success_p = xpm_load_image (f, img, SDATA (data), |
| 4299 | SDATA (data) + SBYTES (data)); | 4349 | SDATA (data) + SBYTES (data)); |
| 4300 | } | 4350 | } |
| 4301 | 4351 | ||
| 4302 | return success_p; | 4352 | return success_p; |
| @@ -4973,7 +5023,7 @@ x_disable_image (f, img) | |||
| 4973 | 5023 | ||
| 4974 | #ifdef MAC_OS | 5024 | #ifdef MAC_OS |
| 4975 | #define XCreateGC_pixmap(dpy, pixmap) XCreateGC (dpy, NULL, 0, NULL) | 5025 | #define XCreateGC_pixmap(dpy, pixmap) XCreateGC (dpy, NULL, 0, NULL) |
| 4976 | #define MaskForeground(f) PIX_MASK_DRAW (f) | 5026 | #define MaskForeground(f) PIX_MASK_DRAW |
| 4977 | #else | 5027 | #else |
| 4978 | #define XCreateGC_pixmap(dpy, pixmap) XCreateGC (dpy, pixmap, 0, NULL) | 5028 | #define XCreateGC_pixmap(dpy, pixmap) XCreateGC (dpy, pixmap, 0, NULL) |
| 4979 | #define MaskForeground(f) WHITE_PIX_DEFAULT (f) | 5029 | #define MaskForeground(f) WHITE_PIX_DEFAULT (f) |
| @@ -5121,7 +5171,7 @@ x_build_heuristic_mask (f, img, how) | |||
| 5121 | for (y = 0; y < img->height; ++y) | 5171 | for (y = 0; y < img->height; ++y) |
| 5122 | for (x = 0; x < img->width; ++x) | 5172 | for (x = 0; x < img->width; ++x) |
| 5123 | XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg | 5173 | XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg |
| 5124 | ? PIX_MASK_DRAW (f) : PIX_MASK_RETAIN (f))); | 5174 | ? PIX_MASK_DRAW : PIX_MASK_RETAIN)); |
| 5125 | 5175 | ||
| 5126 | /* Fill in the background_transparent field while we have the mask handy. */ | 5176 | /* Fill in the background_transparent field while we have the mask handy. */ |
| 5127 | image_background_transparent (img, f, mask_img); | 5177 | image_background_transparent (img, f, mask_img); |
| @@ -6123,7 +6173,7 @@ png_load (f, img) | |||
| 6123 | if (channels == 4) | 6173 | if (channels == 4) |
| 6124 | { | 6174 | { |
| 6125 | if (mask_img) | 6175 | if (mask_img) |
| 6126 | XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW (f) : PIX_MASK_RETAIN (f)); | 6176 | XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN); |
| 6127 | ++p; | 6177 | ++p; |
| 6128 | } | 6178 | } |
| 6129 | } | 6179 | } |
| @@ -8025,6 +8075,11 @@ syms_of_image () | |||
| 8025 | { | 8075 | { |
| 8026 | extern Lisp_Object Qrisky_local_variable; /* Syms_of_xdisp has already run. */ | 8076 | extern Lisp_Object Qrisky_local_variable; /* Syms_of_xdisp has already run. */ |
| 8027 | 8077 | ||
| 8078 | /* Initialize this only once, since that's what we do with Vimage_types | ||
| 8079 | and they are supposed to be in sync. Initializing here gives correct | ||
| 8080 | operation on GNU/Linux of calling dump-emacs after loading some images. */ | ||
| 8081 | image_types = NULL; | ||
| 8082 | |||
| 8028 | /* Must be defined now becase we're going to update it below, while | 8083 | /* Must be defined now becase we're going to update it below, while |
| 8029 | defining the supported image types. */ | 8084 | defining the supported image types. */ |
| 8030 | DEFVAR_LISP ("image-types", &Vimage_types, | 8085 | DEFVAR_LISP ("image-types", &Vimage_types, |
| @@ -8050,6 +8105,17 @@ listed; they're always supported. */); | |||
| 8050 | Vimage_type_cache = Qnil; | 8105 | Vimage_type_cache = Qnil; |
| 8051 | staticpro (&Vimage_type_cache); | 8106 | staticpro (&Vimage_type_cache); |
| 8052 | 8107 | ||
| 8108 | Qpbm = intern ("pbm"); | ||
| 8109 | staticpro (&Qpbm); | ||
| 8110 | ADD_IMAGE_TYPE(Qpbm); | ||
| 8111 | |||
| 8112 | Qxbm = intern ("xbm"); | ||
| 8113 | staticpro (&Qxbm); | ||
| 8114 | ADD_IMAGE_TYPE(Qxbm); | ||
| 8115 | |||
| 8116 | define_image_type (&xbm_type, 1); | ||
| 8117 | define_image_type (&pbm_type, 1); | ||
| 8118 | |||
| 8053 | QCascent = intern (":ascent"); | 8119 | QCascent = intern (":ascent"); |
| 8054 | staticpro (&QCascent); | 8120 | staticpro (&QCascent); |
| 8055 | QCmargin = intern (":margin"); | 8121 | QCmargin = intern (":margin"); |
| @@ -8094,14 +8160,6 @@ listed; they're always supported. */); | |||
| 8094 | staticpro (&QCpt_height); | 8160 | staticpro (&QCpt_height); |
| 8095 | #endif /* HAVE_GHOSTSCRIPT */ | 8161 | #endif /* HAVE_GHOSTSCRIPT */ |
| 8096 | 8162 | ||
| 8097 | Qpbm = intern ("pbm"); | ||
| 8098 | staticpro (&Qpbm); | ||
| 8099 | ADD_IMAGE_TYPE(Qpbm); | ||
| 8100 | |||
| 8101 | Qxbm = intern ("xbm"); | ||
| 8102 | staticpro (&Qxbm); | ||
| 8103 | ADD_IMAGE_TYPE(Qxbm); | ||
| 8104 | |||
| 8105 | #if defined (HAVE_XPM) || defined (MAC_OS) | 8163 | #if defined (HAVE_XPM) || defined (MAC_OS) |
| 8106 | Qxpm = intern ("xpm"); | 8164 | Qxpm = intern ("xpm"); |
| 8107 | staticpro (&Qxpm); | 8165 | staticpro (&Qxpm); |
| @@ -8163,11 +8221,6 @@ meaning don't clear the cache. */); | |||
| 8163 | void | 8221 | void |
| 8164 | init_image () | 8222 | init_image () |
| 8165 | { | 8223 | { |
| 8166 | image_types = NULL; | ||
| 8167 | |||
| 8168 | define_image_type (&xbm_type, 1); | ||
| 8169 | define_image_type (&pbm_type, 1); | ||
| 8170 | |||
| 8171 | #ifdef MAC_OS | 8224 | #ifdef MAC_OS |
| 8172 | /* Animated gifs use QuickTime Movie Toolbox. So initialize it here. */ | 8225 | /* Animated gifs use QuickTime Movie Toolbox. So initialize it here. */ |
| 8173 | EnterMovies (); | 8226 | EnterMovies (); |