# HG changeset patch # User YAMAMOTO Mitsuharu # Date 1125477328 0 # Node ID 8105f38368d5ab2c978a0289fbd2ccb30f91857a # Parent 1ac84342cdea96eae659d6f2e5964b9df0ae1f24 (PIX_MASK_DRAW, PIX_MASK_RETAIN): Remove argument. All uses changed. [MAC_OS] (XPutPixel, XGetPixel): Add efficient versions for common cases. (x_create_x_image_and_pixmap) [MAC_OS]: Don't call x_destroy_x_image. [MAC_OS] (find_image_fsspec) [!MAC_OSX]: Don't use FSRef. Use posix_pathname_to_fsspec. [MAC_OS] (xpm_load_image): Fill in background_transparent field while we have mask. diff -r 1ac84342cdea -r 8105f38368d5 src/image.c --- a/src/image.c Wed Aug 31 08:33:25 2005 +0000 +++ b/src/image.c Wed Aug 31 08:35:28 2005 +0000 @@ -54,8 +54,8 @@ #define RGB_PIXEL_COLOR unsigned long -#define PIX_MASK_RETAIN(f) 0 -#define PIX_MASK_DRAW(f) 1 +#define PIX_MASK_RETAIN 0 +#define PIX_MASK_DRAW 1 #endif /* HAVE_X_WINDOWS */ @@ -71,8 +71,8 @@ #define RGB_PIXEL_COLOR COLORREF -#define PIX_MASK_RETAIN(f) 0 -#define PIX_MASK_DRAW(f) 1 +#define PIX_MASK_RETAIN 0 +#define PIX_MASK_DRAW 1 #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual #define x_defined_color w32_defined_color @@ -112,6 +112,11 @@ #define RGB_PIXEL_COLOR unsigned long +/* A black pixel in a mask bitmap/pixmap means ``draw a source + pixel''. A white pixel means ``retain the current pixel''. */ +#define PIX_MASK_DRAW RGB_TO_ULONG(0,0,0) +#define PIX_MASK_RETAIN RGB_TO_ULONG(255,255,255) + #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual #define x_defined_color mac_defined_color #define DefaultDepthOfScreen(screen) (one_mac_display_info.n_planes) @@ -181,19 +186,43 @@ int x, y; unsigned long pixel; { - CGrafPtr old_port; - GDHandle old_gdh; - RGBColor color; - - GetGWorld (&old_port, &old_gdh); - SetGWorld (ximage, NULL); - - color.red = RED16_FROM_ULONG (pixel); - color.green = GREEN16_FROM_ULONG (pixel); - color.blue = BLUE16_FROM_ULONG (pixel); - SetCPixel (x, y, &color); - - SetGWorld (old_port, old_gdh); + PixMapHandle pixmap = GetGWorldPixMap (ximage); + short depth = GetPixDepth (pixmap); + + if (depth == 32) + { + char *base_addr = GetPixBaseAddr (pixmap); + short row_bytes = GetPixRowBytes (pixmap); + + ((unsigned long *) (base_addr + y * row_bytes))[x] = pixel; + } + else if (depth == 1) + { + char *base_addr = GetPixBaseAddr (pixmap); + short row_bytes = GetPixRowBytes (pixmap); + + if (pixel == PIX_MASK_DRAW) + base_addr[y * row_bytes + x / 8] |= (1 << 7) >> (x & 7); + else + base_addr[y * row_bytes + x / 8] &= ~((1 << 7) >> (x & 7)); + } + else + { + CGrafPtr old_port; + GDHandle old_gdh; + RGBColor color; + + GetGWorld (&old_port, &old_gdh); + SetGWorld (ximage, NULL); + + color.red = RED16_FROM_ULONG (pixel); + color.green = GREEN16_FROM_ULONG (pixel); + color.blue = BLUE16_FROM_ULONG (pixel); + + SetCPixel (x, y, &color); + + SetGWorld (old_port, old_gdh); + } } static unsigned long @@ -201,17 +230,40 @@ XImagePtr ximage; int x, y; { - CGrafPtr old_port; - GDHandle old_gdh; - RGBColor color; - - GetGWorld (&old_port, &old_gdh); - SetGWorld (ximage, NULL); - - GetCPixel (x, y, &color); - - SetGWorld (old_port, old_gdh); - return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8); + PixMapHandle pixmap = GetGWorldPixMap (ximage); + short depth = GetPixDepth (pixmap); + + if (depth == 32) + { + char *base_addr = GetPixBaseAddr (pixmap); + short row_bytes = GetPixRowBytes (pixmap); + + return ((unsigned long *) (base_addr + y * row_bytes))[x]; + } + else if (depth == 1) + { + char *base_addr = GetPixBaseAddr (pixmap); + short row_bytes = GetPixRowBytes (pixmap); + + if (base_addr[y * row_bytes + x / 8] & (1 << (~x & 7))) + return PIX_MASK_DRAW; + else + return PIX_MASK_RETAIN; + } + else + { + CGrafPtr old_port; + GDHandle old_gdh; + RGBColor color; + + GetGWorld (&old_port, &old_gdh); + SetGWorld (ximage, NULL); + + GetCPixel (x, y, &color); + + SetGWorld (old_port, old_gdh); + return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8); + } } static void @@ -1300,7 +1352,7 @@ } img->background_transparent - = (four_corners_best (mask, img->width, img->height) == PIX_MASK_RETAIN (f)); + = (four_corners_best (mask, img->width, img->height) == PIX_MASK_RETAIN); if (free_mask) Destroy_Image (mask, prev); @@ -2003,7 +2055,6 @@ *pixmap = XCreatePixmap (display, window, width, height, depth); if (*pixmap == NO_PIXMAP) { - x_destroy_x_image (*ximg); *ximg = NULL; image_error ("Unable to create X pixmap", Qnil, Qnil); return 0; @@ -2166,10 +2217,8 @@ Lisp_Object specified_file, *file; FSSpec *fss; { -#if TARGET_API_MAC_CARBON +#if MAC_OSX FSRef fsr; -#else - Str255 mac_pathname; #endif OSErr err; @@ -2178,15 +2227,12 @@ return fnfErr; /* file or directory not found; incomplete pathname */ /* Try to open the image file. */ -#if TARGET_API_MAC_CARBON +#if MAC_OSX err = FSPathMakeRef (SDATA (*file), &fsr, NULL); if (err == noErr) err = FSGetCatalogInfo (&fsr, kFSCatInfoNone, NULL, NULL, fss, NULL); #else - if (posix_to_mac_pathname (SDATA (*file), mac_pathname, MAXPATHLEN+1) == 0) - return fnfErr; - c2pstr (mac_pathname); - err = FSMakeFSSpec (0, 0, mac_pathname, fss); + err = posix_pathname_to_fsspec (SDATA (*file), fss); #endif return err; } @@ -3850,24 +3896,24 @@ Only XPM version 3 (without any extensions) is supported. */ static int xpm_scan P_ ((unsigned char **, unsigned char *, - unsigned char **, int *)); + unsigned char **, int *)); static Lisp_Object xpm_make_color_table_v P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), Lisp_Object (**) (Lisp_Object, unsigned char *, int))); static void xpm_put_color_table_v P_ ((Lisp_Object, unsigned char *, - int, Lisp_Object)); + int, Lisp_Object)); static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object, - unsigned char *, int)); + unsigned char *, int)); static Lisp_Object xpm_make_color_table_h P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), Lisp_Object (**) (Lisp_Object, unsigned char *, int))); static void xpm_put_color_table_h P_ ((Lisp_Object, unsigned char *, - int, Lisp_Object)); + int, Lisp_Object)); static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object, - unsigned char *, int)); + unsigned char *, int)); static int xpm_str_to_color_key P_ ((char *)); static int xpm_load_image P_ ((struct frame *, struct image *, - unsigned char *, unsigned char *)); + unsigned char *, unsigned char *)); /* Tokens returned from xpm_scan. */ @@ -3896,49 +3942,49 @@ { /* Skip white-space. */ while (*s < end && (c = *(*s)++, isspace (c))) - ; + ; /* gnus-pointer.xpm uses '-' in its identifier. - sb-dir-plus.xpm uses '+' in its identifier. */ + sb-dir-plus.xpm uses '+' in its identifier. */ if (isalpha (c) || c == '_' || c == '-' || c == '+') - { - *beg = *s - 1; - while (*s < end && - (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+')) - ++*s; - *len = *s - *beg; - return XPM_TK_IDENT; - } + { + *beg = *s - 1; + while (*s < end && + (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+')) + ++*s; + *len = *s - *beg; + return XPM_TK_IDENT; + } else if (c == '"') - { - *beg = *s; - while (*s < end && **s != '"') - ++*s; - *len = *s - *beg; - if (*s < end) - ++*s; - return XPM_TK_STRING; - } + { + *beg = *s; + while (*s < end && **s != '"') + ++*s; + *len = *s - *beg; + if (*s < end) + ++*s; + return XPM_TK_STRING; + } else if (c == '/') - { - if (*s < end && **s == '*') - { - /* C-style comment. */ - ++*s; - do - { - while (*s < end && *(*s)++ != '*') - ; - } - while (*s < end && **s != '/'); - if (*s < end) - ++*s; - } - else - return c; - } + { + if (*s < end && **s == '*') + { + /* C-style comment. */ + ++*s; + do + { + while (*s < end && *(*s)++ != '*') + ; + } + while (*s < end && **s != '/'); + if (*s < end) + ++*s; + } + else + return c; + } else - return c; + return c; } return XPM_TK_EOF; @@ -3988,9 +4034,9 @@ *put_func = xpm_put_color_table_h; *get_func = xpm_get_color_table_h; return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), - make_float (DEFAULT_REHASH_SIZE), - make_float (DEFAULT_REHASH_THRESHOLD), - Qnil, Qnil, Qnil); + make_float (DEFAULT_REHASH_SIZE), + make_float (DEFAULT_REHASH_THRESHOLD), + Qnil, Qnil, Qnil); } static void @@ -4016,7 +4062,7 @@ { struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len), - NULL); + NULL); return i >= 0 ? HASH_VALUE (table, i) : Qnil; } @@ -4065,17 +4111,17 @@ #define match() \ LA1 = xpm_scan (&s, end, &beg, &len) -#define expect(TOKEN) \ - if (LA1 != (TOKEN)) \ - goto failure; \ - else \ +#define expect(TOKEN) \ + if (LA1 != (TOKEN)) \ + goto failure; \ + else \ match () -#define expect_ident(IDENT) \ +#define expect_ident(IDENT) \ if (LA1 == XPM_TK_IDENT \ - && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \ - match (); \ - else \ + && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \ + match (); \ + else \ goto failure if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0)) @@ -4096,7 +4142,7 @@ memcpy (buffer, beg, len); buffer[len] = '\0'; if (sscanf (buffer, "%d %d %d %d", &width, &height, - &num_colors, &chars_per_pixel) != 4 + &num_colors, &chars_per_pixel) != 4 || width <= 0 || height <= 0 || num_colors <= 0 || chars_per_pixel <= 0) goto failure; @@ -4107,17 +4153,17 @@ best_key = XPM_COLOR_KEY_C; else if (!NILP (Fx_display_grayscale_p (frame))) best_key = (XFASTINT (Fx_display_planes (frame)) > 2 - ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4); + ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4); else best_key = XPM_COLOR_KEY_M; color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL); if (chars_per_pixel == 1) color_table = xpm_make_color_table_v (&put_color_table, - &get_color_table); + &get_color_table); else color_table = xpm_make_color_table_h (&put_color_table, - &get_color_table); + &get_color_table); while (num_colors-- > 0) { @@ -4128,71 +4174,71 @@ expect (XPM_TK_STRING); if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel) - goto failure; + goto failure; memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel); buffer[len - chars_per_pixel] = '\0'; str = strtok (buffer, " \t"); if (str == NULL) - goto failure; + goto failure; key = xpm_str_to_color_key (str); if (key < 0) - goto failure; + goto failure; do - { - color = strtok (NULL, " \t"); - if (color == NULL) - goto failure; - - while (str = strtok (NULL, " \t")) - { - next_key = xpm_str_to_color_key (str); - if (next_key >= 0) - break; - color[strlen (color)] = ' '; - } - - if (key == XPM_COLOR_KEY_S) - { - if (NILP (symbol_color)) - symbol_color = build_string (color); - } - else if (max_key < key && key <= best_key) - { - max_key = key; - max_color = color; - } - key = next_key; - } + { + color = strtok (NULL, " \t"); + if (color == NULL) + goto failure; + + while (str = strtok (NULL, " \t")) + { + next_key = xpm_str_to_color_key (str); + if (next_key >= 0) + break; + color[strlen (color)] = ' '; + } + + if (key == XPM_COLOR_KEY_S) + { + if (NILP (symbol_color)) + symbol_color = build_string (color); + } + else if (max_key < key && key <= best_key) + { + max_key = key; + max_color = color; + } + key = next_key; + } while (str); color_val = Qnil; if (!NILP (color_symbols) && !NILP (symbol_color)) - { - Lisp_Object specified_color = Fassoc (symbol_color, color_symbols); - - if (CONSP (specified_color) && STRINGP (XCDR (specified_color))) - if (xstricmp (SDATA (XCDR (specified_color)), "None") == 0) - color_val = Qt; - else if (x_defined_color (f, SDATA (XCDR (specified_color)), - &cdef, 0)) - color_val = make_number (cdef.pixel); - } + { + Lisp_Object specified_color = Fassoc (symbol_color, color_symbols); + + if (CONSP (specified_color) && STRINGP (XCDR (specified_color))) + if (xstricmp (SDATA (XCDR (specified_color)), "None") == 0) + color_val = Qt; + else if (x_defined_color (f, SDATA (XCDR (specified_color)), + &cdef, 0)) + color_val = make_number (cdef.pixel); + } if (NILP (color_val) && max_key > 0) - if (xstricmp (max_color, "None") == 0) - color_val = Qt; - else if (x_defined_color (f, max_color, &cdef, 0)) - color_val = make_number (cdef.pixel); + if (xstricmp (max_color, "None") == 0) + color_val = Qt; + else if (x_defined_color (f, max_color, &cdef, 0)) + color_val = make_number (cdef.pixel); if (!NILP (color_val)) - (*put_color_table) (color_table, beg, chars_per_pixel, color_val); + (*put_color_table) (color_table, beg, chars_per_pixel, color_val); expect (','); } if (!x_create_x_image_and_pixmap (f, width, height, 0, - &ximg, &img->pixmap) + &ximg, &img->pixmap) || !x_create_x_image_and_pixmap (f, width, height, 1, - &mask_img, &img->mask)) + &mask_img, &img->mask)) { image_error ("Out of memory (%s)", img->spec, Qnil); goto error; @@ -4203,21 +4249,21 @@ expect (XPM_TK_STRING); str = beg; if (len < width * chars_per_pixel) - goto failure; + goto failure; for (x = 0; x < width; x++, str += chars_per_pixel) - { - Lisp_Object color_val = - (*get_color_table) (color_table, str, chars_per_pixel); - - XPutPixel (ximg, x, y, - (INTEGERP (color_val) ? XINT (color_val) - : FRAME_FOREGROUND_PIXEL (f))); - XPutPixel (mask_img, x, y, - (!EQ (color_val, Qt) ? PIX_MASK_DRAW (f) - : (have_mask = 1, PIX_MASK_RETAIN (f)))); - } + { + Lisp_Object color_val = + (*get_color_table) (color_table, str, chars_per_pixel); + + XPutPixel (ximg, x, y, + (INTEGERP (color_val) ? XINT (color_val) + : FRAME_FOREGROUND_PIXEL (f))); + XPutPixel (mask_img, x, y, + (!EQ (color_val, Qt) ? PIX_MASK_DRAW + : (have_mask = 1, PIX_MASK_RETAIN))); + } if (y + 1 < height) - expect (','); + expect (','); } img->width = width; @@ -4227,6 +4273,10 @@ x_destroy_x_image (ximg); if (have_mask) { + /* Fill in the background_transparent field while we have the + mask handy. */ + image_background_transparent (img, f, mask_img); + x_put_x_image (f, mask_img, img->mask, width, height); x_destroy_x_image (mask_img); } @@ -4272,19 +4322,19 @@ file = x_find_image_file (file_name); GCPRO1 (file); if (!STRINGP (file)) - { - image_error ("Cannot find image file `%s'", file_name, Qnil); - UNGCPRO; - return 0; - } + { + image_error ("Cannot find image file `%s'", file_name, Qnil); + UNGCPRO; + return 0; + } contents = slurp_file (SDATA (file), &size); if (contents == NULL) - { - image_error ("Error loading XPM image `%s'", img->spec, Qnil); - UNGCPRO; - return 0; - } + { + image_error ("Error loading XPM image `%s'", img->spec, Qnil); + UNGCPRO; + return 0; + } success_p = xpm_load_image (f, img, contents, contents + size); xfree (contents); @@ -4296,7 +4346,7 @@ data = image_spec_value (img->spec, QCdata, NULL); success_p = xpm_load_image (f, img, SDATA (data), - SDATA (data) + SBYTES (data)); + SDATA (data) + SBYTES (data)); } return success_p; @@ -4973,7 +5023,7 @@ #ifdef MAC_OS #define XCreateGC_pixmap(dpy, pixmap) XCreateGC (dpy, NULL, 0, NULL) -#define MaskForeground(f) PIX_MASK_DRAW (f) +#define MaskForeground(f) PIX_MASK_DRAW #else #define XCreateGC_pixmap(dpy, pixmap) XCreateGC (dpy, pixmap, 0, NULL) #define MaskForeground(f) WHITE_PIX_DEFAULT (f) @@ -5121,7 +5171,7 @@ for (y = 0; y < img->height; ++y) for (x = 0; x < img->width; ++x) XPutPixel (mask_img, x, y, (XGetPixel (ximg, x, y) != bg - ? PIX_MASK_DRAW (f) : PIX_MASK_RETAIN (f))); + ? PIX_MASK_DRAW : PIX_MASK_RETAIN)); /* Fill in the background_transparent field while we have the mask handy. */ image_background_transparent (img, f, mask_img); @@ -6123,7 +6173,7 @@ if (channels == 4) { if (mask_img) - XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW (f) : PIX_MASK_RETAIN (f)); + XPutPixel (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN); ++p; } }