Mercurial > emacs
changeset 94615:a0615a586d39
Merge from emacs--rel--22
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-1142
author | Miles Bader <miles@gnu.org> |
---|---|
date | Sun, 04 May 2008 19:46:16 +0000 |
parents | b333cf3be3cc (current diff) 0b1b6deb6e05 (diff) |
children | 7b6b7f6f8539 |
files | ChangeLog configure configure.in src/ChangeLog src/config.in src/image.c src/macgui.h src/macterm.c src/macterm.h src/s/darwin.h |
diffstat | 10 files changed, 698 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Sun May 04 19:46:02 2008 +0000 +++ b/ChangeLog Sun May 04 19:46:16 2008 +0000 @@ -1,3 +1,10 @@ +2008-05-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * configure.in: Check availability of AvailabilityMacros.h + if HAVE_CARBON. + + * configure: Regenerate. + 2008-05-03 Glenn Morris <rgm@gnu.org> * configure.in (x_libraries): Remove standard 64-bit directories -
--- a/configure Sun May 04 19:46:02 2008 +0000 +++ b/configure Sun May 04 19:46:16 2008 +0000 @@ -15020,6 +15020,146 @@ #define HAVE_CARBON 1 _ACEOF + +for ac_header in AvailabilityMacros.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + ## Specify the install directory carbon_appdir= if test "${carbon_appdir_x}" != ""; then
--- a/configure.in Sun May 04 19:46:02 2008 +0000 +++ b/configure.in Sun May 04 19:46:16 2008 +0000 @@ -2230,6 +2230,7 @@ ### Use Mac OS X Carbon API to implement GUI. if test "${HAVE_CARBON}" = "yes"; then AC_DEFINE(HAVE_CARBON, 1, [Define to 1 if you are using the Carbon API on Mac OS X.]) + AC_CHECK_HEADERS(AvailabilityMacros.h) ## Specify the install directory carbon_appdir= if test "${carbon_appdir_x}" != ""; then
--- a/src/ChangeLog Sun May 04 19:46:02 2008 +0000 +++ b/src/ChangeLog Sun May 04 19:46:16 2008 +0000 @@ -1,3 +1,52 @@ +2008-05-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * image.c [USE_MAC_IMAGE_IO] (image_load_image_io): + Create bitmap context in native byte order. + + * macterm.c (XDrawLine) + (XCreatePixmapFromBitmapData) [USE_MAC_IMAGE_IO]: Create bitmap + context in native byte order. + +2008-05-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> + + * config.in: Regenerate. + + * image.c (PIX_MASK_DRAW, PIX_MASK_RETAIN) [USE_MAC_IMAGE_IO]: + New definitions for Image I/O support. + (XGetImage, XPutPixel, XGetPixel, XDestroyImage) + (mac_create_cg_image_from_image, x_create_x_image_and_pixmap) + [USE_MAC_IMAGE_IO]: Add implementations for Image I/O support. + (mac_data_provider_release_data, image_load_image_io) + [USE_MAC_IMAGE_IO]: New functions. + (CGImageCreateWithPNGDataProviderProcType) [MAC_OSX]: Remove typedef. + (MyCGImageCreateWithPNGDataProvider) [MAC_OSX]: Remove variable. + (init_image_func_pointer) [MAC_OSX]: Remove function. + (image_load_quartz2d) [MAC_OSX]: Check availability of + CGImageCreateWithPNGDataProvider at compile time. + Use lowercase `false' for boolean constant. + (png_load, jpeg_load, tiff_load, gif_load) [USE_MAC_IMAGE_IO]: + Use image_load_image_io. + (png_load) [!USE_MAC_IMAGE_IO && MAC_OSX]: + Don't check MyCGImageCreateWithPNGDataProvider. + (init_image) [MAC_OSX && TARGET_API_MAC_CARBON]: + Don't call init_image_func_pointer. + + * macgui.h (Pixmap) [USE_MAC_IMAGE_IO]: New definition for Image I/O. + + * macterm.c (mac_cg_color_space_rgb) [USE_CG_DRAWING]: + Make variable non-static. + (XDrawLine, XCreatePixmap, XCreatePixmapFromBitmapData, XFreePixmap) + [USE_MAC_IMAGE_IO]: Add implementations for Image I/O support. + + * macterm.h (ARGB_TO_ULONG, ALPHA_FROM_ULONG): New macros. + (RED_FROM_ULONG): Mask off higher bits. + (mac_cg_color_space_rgb) [USE_MAC_IMAGE_IO]: New extern. + + * s/darwin.h [HAVE_CARBON && HAVE_AVAILABILITYMACROS_H]: + Include AvailabilityMacros.h. + (USE_MAC_IMAGE_IO, LIBS_IMAGE) [HAVE_CARBON]: New defines. + (LIBS_CARBON) [HAVE_CARBON]: Use LIBS_IMAGE. + 2008-05-03 Stefan Monnier <monnier@iro.umontreal.ca> * chartab.c (Fset_char_table_range): If range is t, really set all
--- a/src/config.in Sun May 04 19:46:02 2008 +0000 +++ b/src/config.in Sun May 04 19:46:16 2008 +0000 @@ -90,6 +90,9 @@ /* Define to 1 if ALSA is available. */ #undef HAVE_ALSA +/* Define to 1 if you have the <AvailabilityMacros.h> header file. */ +#undef HAVE_AVAILABILITYMACROS_H + /* Define to 1 if you have the `bcmp' function. */ #undef HAVE_BCMP
--- a/src/image.c Sun May 04 19:46:02 2008 +0000 +++ b/src/image.c Sun May 04 19:46:16 2008 +0000 @@ -115,10 +115,15 @@ #define RGB_PIXEL_COLOR unsigned long +#if USE_MAC_IMAGE_IO +#define PIX_MASK_DRAW 255 +#define PIX_MASK_RETAIN 0 +#else /* 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) +#endif #define FRAME_X_VISUAL(f) FRAME_X_DISPLAY_INFO (f)->visual #define x_defined_color mac_defined_color @@ -166,6 +171,7 @@ unsigned long plane_mask; /* not used */ int format; /* not used */ { +#if !USE_MAC_IMAGE_IO #if GLYPH_DEBUG xassert (x == 0 && y == 0); { @@ -177,6 +183,7 @@ #endif LockPixels (GetGWorldPixMap (pixmap)); +#endif return pixmap; } @@ -187,6 +194,12 @@ int x, y; unsigned long pixel; { +#if USE_MAC_IMAGE_IO + if (ximage->bits_per_pixel == 32) + ((unsigned int *)(ximage->data + y * ximage->bytes_per_line))[x] = pixel; + else + ((unsigned char *)(ximage->data + y * ximage->bytes_per_line))[x] = pixel; +#else PixMapHandle pixmap = GetGWorldPixMap (ximage); short depth = GetPixDepth (pixmap); @@ -227,6 +240,7 @@ SetGWorld (old_port, old_gdh); } +#endif } static unsigned long @@ -234,6 +248,12 @@ XImagePtr ximage; int x, y; { +#if USE_MAC_IMAGE_IO + if (ximage->bits_per_pixel == 32) + return ((unsigned int *)(ximage->data + y * ximage->bytes_per_line))[x]; + else + return ((unsigned char *)(ximage->data + y * ximage->bytes_per_line))[x]; +#else PixMapHandle pixmap = GetGWorldPixMap (ximage); short depth = GetPixDepth (pixmap); @@ -271,21 +291,80 @@ SetGWorld (old_port, old_gdh); return RGB_TO_ULONG (color.red >> 8, color.green >> 8, color.blue >> 8); } +#endif } static void XDestroyImage (ximg) XImagePtr ximg; { +#if !USE_MAC_IMAGE_IO UnlockPixels (GetGWorldPixMap (ximg)); +#endif } #if USE_CG_DRAWING +#if USE_MAC_IMAGE_IO +void +mac_data_provider_release_data (info, data, size) + void *info; + const void *data; + size_t size; +{ + xfree ((void *)data); +} +#endif + static CGImageRef mac_create_cg_image_from_image (f, img) struct frame *f; struct image *img; { +#if USE_MAC_IMAGE_IO + XImagePtr ximg = img->pixmap; + CGDataProviderRef provider; + CGImageRef result; + + if (img->mask) + { + int x, y; + unsigned long color, alpha; + + for (y = 0; y < ximg->height; y++) + for (x = 0; x < ximg->width; x++) + { + color = XGetPixel (ximg, x, y); + alpha = XGetPixel (img->mask, x, y); + XPutPixel (ximg, x, y, + ARGB_TO_ULONG (alpha, + RED_FROM_ULONG (color) + * alpha / PIX_MASK_DRAW, + GREEN_FROM_ULONG (color) + * alpha / PIX_MASK_DRAW, + BLUE_FROM_ULONG (color) + * alpha / PIX_MASK_DRAW)); + } + xfree (img->mask->data); + img->mask->data = NULL; + } + BLOCK_INPUT; + provider = CGDataProviderCreateWithData (NULL, ximg->data, + ximg->bytes_per_line * ximg->height, + mac_data_provider_release_data); + ximg->data = NULL; + result = CGImageCreate (ximg->width, ximg->height, 8, 32, + ximg->bytes_per_line, mac_cg_color_space_rgb, + (img->mask ? kCGImageAlphaPremultipliedFirst + : kCGImageAlphaNoneSkipFirst) +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 + | kCGBitmapByteOrder32Host +#endif + , provider, NULL, 0, kCGRenderingIntentDefault); + CGDataProviderRelease (provider); + UNBLOCK_INPUT; + + return result; +#else Pixmap mask; CGImageRef result = NULL; @@ -320,6 +399,7 @@ UNBLOCK_INPUT; return result; +#endif } #endif /* USE_CG_DRAWING */ #endif /* MAC_OS */ @@ -2301,7 +2381,9 @@ return 0; } +#if !USE_MAC_IMAGE_IO LockPixels (GetGWorldPixMap (*pixmap)); +#endif *ximg = *pixmap; return 1; @@ -2454,6 +2536,256 @@ MAC Image Load Functions ***********************************************************************/ +#if USE_MAC_IMAGE_IO +static int +image_load_image_io (f, img, type) + struct frame *f; + struct image *img; + CFStringRef type; +{ + CFDictionaryRef options, src_props = NULL, props = NULL; + CFStringRef keys[2]; + CFTypeRef values[2]; + Lisp_Object specified_file, specified_data; + CGImageSourceRef source = NULL; + size_t count; + CGImageRef image = NULL; + int loop_count = -1; + double delay_time = -1.0; + int width, height; + XImagePtr ximg = NULL; + CGContextRef context; + CGRect rectangle; + int has_alpha_p, gif_p; + + gif_p = UTTypeEqual (type, kUTTypeGIF); + + keys[0] = kCGImageSourceTypeIdentifierHint; + values[0] = (CFTypeRef) type; + keys[1] = kCGImageSourceShouldCache; + values[1] = (CFTypeRef) kCFBooleanFalse; + options = CFDictionaryCreate (NULL, (const void **) keys, + (const void **) values, + sizeof (keys) / sizeof (keys[0]), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (options == NULL) + { + image_error ("Error creating options for image `%s'", img->spec, Qnil); + return 0; + } + + /* Open the file. */ + specified_file = image_spec_value (img->spec, QCfile, NULL); + specified_data = image_spec_value (img->spec, QCdata, NULL); + + if (NILP (specified_data)) + { + Lisp_Object file; + CFStringRef path; + CFURLRef url; + + file = x_find_image_file (specified_file); + if (!STRINGP (file)) + { + image_error ("Cannot find image file `%s'", specified_file, Qnil); + return 0; + } + path = cfstring_create_with_utf8_cstring (SDATA (file)); + if (path) + { + url = CFURLCreateWithFileSystemPath (NULL, path, + kCFURLPOSIXPathStyle, 0); + CFRelease (path); + if (url) + { + source = CGImageSourceCreateWithURL (url, NULL); + CFRelease (url); + } + } + } + else + { + CFDataRef data = CFDataCreate (NULL, SDATA (specified_data), + SBYTES (specified_data)); + + if (data) + { + source = CGImageSourceCreateWithData (data, options); + CFRelease (data); + } + } + CFRelease (options); + + if (source) + { + CFStringRef real_type = CGImageSourceGetType (source); + + if (real_type && UTTypeEqual (type, real_type)) + src_props = CGImageSourceCopyProperties (source, NULL); + if (src_props) + { + EMACS_INT ino = 0; + + count = CGImageSourceGetCount (source); + if (gif_p) + { + Lisp_Object image = image_spec_value (img->spec, QCindex, NULL); + + if (INTEGERP (image)) + ino = XFASTINT (image); + } + if (ino >= 0 && ino < count) + { + props = CGImageSourceCopyPropertiesAtIndex (source, ino, NULL); + if (props) + image = CGImageSourceCreateImageAtIndex (source, ino, NULL); + } + } + CFRelease (source); + } + + if (image == NULL) + { + if (src_props) + CFRelease (src_props); + if (props) + CFRelease (props); + image_error ("Error reading image `%s'", img->spec, Qnil); + return 0; + } + else + { + CFBooleanRef boolean; + + if (CFDictionaryGetValueIfPresent (props, kCGImagePropertyHasAlpha, + (const void **) &boolean)) + has_alpha_p = CFBooleanGetValue (boolean); + if (gif_p) + { + CFDictionaryRef dict; + CFNumberRef number; + + dict = CFDictionaryGetValue (src_props, + kCGImagePropertyGIFDictionary); + if (dict + && CFDictionaryGetValueIfPresent (dict, + kCGImagePropertyGIFLoopCount, + (const void **) &number)) + CFNumberGetValue (number, kCFNumberIntType, &loop_count); + + dict = CFDictionaryGetValue (props, kCGImagePropertyGIFDictionary); + if (dict + && CFDictionaryGetValueIfPresent (dict, + kCGImagePropertyGIFDelayTime, + (const void **) &number)) + CFNumberGetValue (number, kCFNumberDoubleType, &delay_time); + } + CFRelease (src_props); + CFRelease (props); + } + + width = img->width = CGImageGetWidth (image); + height = img->height = CGImageGetHeight (image); + + if (!check_image_size (f, width, height)) + { + CGImageRelease (image); + image_error ("Invalid image size", Qnil, Qnil); + return 0; + } + + if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) + { + CGImageRelease (image); + image_error ("Out of memory (%s)", img->spec, Qnil); + return 0; + } + rectangle = CGRectMake (0, 0, width, height); + + context = CGBitmapContextCreate (ximg->data, ximg->width, ximg->height, 8, + ximg->bytes_per_line, + mac_cg_color_space_rgb, + kCGImageAlphaNoneSkipFirst +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 + | kCGBitmapByteOrder32Host +#endif + ); + if (has_alpha_p) + { + Lisp_Object specified_bg; + XColor color; + + specified_bg = image_spec_value (img->spec, QCbackground, NULL); + if (!STRINGP (specified_bg) + || !mac_defined_color (f, SDATA (specified_bg), &color, 0)) + { + color.pixel = FRAME_BACKGROUND_PIXEL (f); + color.red = RED16_FROM_ULONG (color.pixel); + color.green = GREEN16_FROM_ULONG (color.pixel); + color.blue = BLUE16_FROM_ULONG (color.pixel); + } + CGContextSetRGBFillColor (context, color.red / 65535.0, + color.green / 65535.0, + color.blue / 65535.0, 1.0); + CGContextFillRect (context, rectangle); + } + CGContextDrawImage (context, rectangle, image); + CGContextRelease (context); + CGImageRelease (image); + + /* Save GIF image extension data for `image-extension-data'. + Format is (count IMAGES + 0xff "NETSCAPE2.0" 0x00 DATA_SUB_BLOCK_FOR_LOOP_COUNT + 0xf9 GRAPHIC_CONTROL_EXTENSION_BLOCK). */ + if (gif_p) + { + img->data.lisp_val = Qnil; + if (delay_time >= 0) + { + Lisp_Object gce = make_uninit_string (4); + int centisec = delay_time * 100.0 + 0.5; + + /* Fill the delay time field. */ + SSET (gce, 1, centisec & 0xff); + SSET (gce, 2, (centisec >> 8) & 0xff); + /* We don't know about other fields. */ + SSET (gce, 0, 0); + SSET (gce, 3, 0); + img->data.lisp_val = Fcons (make_number (0xf9), + Fcons (gce, + img->data.lisp_val)); + } + if (loop_count >= 0) + { + Lisp_Object data_sub_block = make_uninit_string (3); + + SSET (data_sub_block, 0, 0x01); + SSET (data_sub_block, 1, loop_count & 0xff); + SSET (data_sub_block, 2, (loop_count >> 8) & 0xff); + img->data.lisp_val = Fcons (make_number (0), + Fcons (data_sub_block, + img->data.lisp_val)); + img->data.lisp_val = Fcons (make_number (0xff), + Fcons (build_string ("NETSCAPE2.0"), + img->data.lisp_val)); + } + if (count > 1) + img->data.lisp_val = Fcons (Qcount, + Fcons (make_number (count), + img->data.lisp_val)); + } + + /* Maybe fill in the background field while we have ximg handy. */ + if (NILP (image_spec_value (img->spec, QCbackground, NULL))) + IMAGE_BACKGROUND (img, f, ximg); + + /* Put the image into the pixmap. */ + x_put_x_image (f, ximg, img->pixmap, width, height); + x_destroy_x_image (ximg); + return 1; +} +#else /* !USE_MAC_IMAGE_IO */ static int image_load_quicktime P_ ((struct frame *, struct image *img, OSType)); #ifdef MAC_OSX @@ -2666,30 +2998,6 @@ #ifdef MAC_OSX -/* Load a PNG/JPEG image using Quartz 2D decoding routines. - CGImageCreateWithPNGDataProvider is provided after Mac OS X 10.2. - So don't use this function directly but determine at runtime - whether it exists. */ -typedef CGImageRef (*CGImageCreateWithPNGDataProviderProcType) - (CGDataProviderRef, const float [], bool, CGColorRenderingIntent); -static CGImageCreateWithPNGDataProviderProcType MyCGImageCreateWithPNGDataProvider; - - -static void -init_image_func_pointer () -{ - if (NSIsSymbolNameDefined ("_CGImageCreateWithPNGDataProvider")) - { - MyCGImageCreateWithPNGDataProvider - = (CGImageCreateWithPNGDataProviderProcType) - NSAddressOfSymbol (NSLookupAndBindSymbol - ("_CGImageCreateWithPNGDataProvider")); - } - else - MyCGImageCreateWithPNGDataProvider = NULL; -} - - static int image_load_quartz2d (f, img, png_p) struct frame *f; @@ -2737,11 +3045,13 @@ source = CGDataProviderCreateWithData (NULL, SDATA (specified_data), SBYTES (specified_data), NULL); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 if (png_p) - image = (*MyCGImageCreateWithPNGDataProvider) (source, NULL, FALSE, - kCGRenderingIntentDefault); + image = CGImageCreateWithPNGDataProvider (source, NULL, false, + kCGRenderingIntentDefault); else - image = CGImageCreateWithJPEGDataProvider (source, NULL, FALSE, +#endif + image = CGImageCreateWithJPEGDataProvider (source, NULL, false, kCGRenderingIntentDefault); CGDataProviderRelease (source); @@ -2805,6 +3115,7 @@ return 1; } #endif +#endif /* !USE_MAC_IMAGE_IO */ #endif /* MAC_OS */ @@ -4275,8 +4586,8 @@ if (isalpha (c) || c == '_' || c == '-' || c == '+') { *beg = *s - 1; - while (*s < end && - (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+')) + while (*s < end + && (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+')) ++*s; *len = *s - *beg; return XPM_TK_IDENT; @@ -6622,12 +6933,13 @@ struct frame *f; struct image *img; { -#ifdef MAC_OSX - if (MyCGImageCreateWithPNGDataProvider) - return image_load_quartz2d (f, img, 1); - else +#if USE_MAC_IMAGE_IO + return image_load_image_io (f, img, kUTTypePNG); +#elif MAC_OS_X_VERSION_MAX_ALLOWED >= 1020 + return image_load_quartz2d (f, img, 1); +#else + return image_load_quicktime (f, img, kQTFileTypePNG); #endif - return image_load_quicktime (f, img, kQTFileTypePNG); } #endif /* MAC_OS */ @@ -7200,7 +7512,9 @@ struct frame *f; struct image *img; { -#ifdef MAC_OSX +#if USE_MAC_IMAGE_IO + return image_load_image_io (f, img, kUTTypeJPEG); +#elif defined (MAC_OSX) return image_load_quartz2d (f, img, 0); #else return image_load_quicktime (f, img, kQTFileTypeJPEG); @@ -7625,7 +7939,11 @@ struct frame *f; struct image *img; { +#if USE_MAC_IMAGE_IO + return image_load_image_io (f, img, kUTTypeTIFF); +#else return image_load_quicktime (f, img, kQTFileTypeTIFF); +#endif } #endif /* MAC_OS */ @@ -8061,6 +8379,9 @@ struct frame *f; struct image *img; { +#if USE_MAC_IMAGE_IO + return image_load_image_io (f, img, kUTTypeGIF); +#else /* !USE_MAC_IMAGE_IO */ Lisp_Object specified_file, file; Lisp_Object specified_data; OSErr err; @@ -8189,8 +8510,8 @@ time_scale = GetMediaTimeScale (media); specified_bg = image_spec_value (img->spec, QCbackground, NULL); - if (!STRINGP (specified_bg) || - !mac_defined_color (f, SDATA (specified_bg), &color, 0)) + if (!STRINGP (specified_bg) + || !mac_defined_color (f, SDATA (specified_bg), &color, 0)) { color.pixel = FRAME_BACKGROUND_PIXEL (f); color.red = RED16_FROM_ULONG (color.pixel); @@ -8259,6 +8580,7 @@ if (dh) DisposeHandle (dh); return 0; +#endif /* !USE_MAC_IMAGE_IO */ } #endif /* MAC_OS */ @@ -9264,9 +9586,6 @@ void init_image () { -#if defined (MAC_OSX) && TARGET_API_MAC_CARBON - init_image_func_pointer (); -#endif } /* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
--- a/src/macgui.h Sun May 04 19:46:02 2008 +0000 +++ b/src/macgui.h Sun May 04 19:46:16 2008 +0000 @@ -154,7 +154,18 @@ #define mac_get_global_mouse GetGlobalMouse #define mac_is_window_toolbar_visible IsWindowToolbarVisible #define mac_rect_make(f, x, y, w, h) CGRectMake (x, y, w, h) + +#if USE_MAC_IMAGE_IO +typedef struct _XImage +{ + int width, height; /* size of image */ + char *data; /* pointer to image data */ + int bytes_per_line; /* accelarator to next line */ + int bits_per_pixel; /* bits per pixel (ZPixmap) */ +} *Pixmap; +#else typedef GWorldPtr Pixmap; +#endif #define Cursor ThemeCursor #define No_Cursor (-1)
--- a/src/macterm.c Sun May 04 19:46:02 2008 +0000 +++ b/src/macterm.c Sun May 04 19:46:16 2008 +0000 @@ -335,7 +335,7 @@ static int max_fringe_bmp = 0; static CGImageRef *fringe_bmp = 0; -static CGColorSpaceRef mac_cg_color_space_rgb; +CGColorSpaceRef mac_cg_color_space_rgb; #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 static CGColorRef mac_cg_color_black; #endif @@ -508,6 +508,48 @@ GC gc; int x1, y1, x2, y2; { +#if USE_MAC_IMAGE_IO + CGContextRef context; + XImagePtr ximg = p; + CGColorSpaceRef color_space; + CGImageAlphaInfo alpha_info; + CGFloat gx1 = x1, gy1 = y1, gx2 = x2, gy2 = y2; + + if (y1 != y2) + gx1 += 0.5f, gx2 += 0.5f; + if (x1 != x2) + gy1 += 0.5f, gy2 += 0.5f; + + if (ximg->bits_per_pixel == 32) + { + color_space = mac_cg_color_space_rgb; + alpha_info = (kCGImageAlphaNoneSkipFirst +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 + | kCGBitmapByteOrder32Host +#endif + ); + } + else + { + color_space = NULL; + alpha_info = kCGImageAlphaOnly; + } + if (color_space == NULL) + return; + context = CGBitmapContextCreate (ximg->data, ximg->width, + ximg->height, 8, + ximg->bytes_per_line, color_space, + alpha_info); + if (ximg->bits_per_pixel == 32) + CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND (context, gc); + else + CGContextSetGrayStrokeColor (context, gc->xgcv.foreground / 255.0f, 1.0); + CGContextMoveToPoint (context, gx1, gy1); + CGContextAddLineToPoint (context, gx2, gy2); + CGContextClosePath (context); + CGContextStrokePath (context); + CGContextRelease (context); +#else CGrafPtr old_port; GDHandle old_gdh; @@ -537,6 +579,7 @@ UnlockPixels (GetGWorldPixMap (p)); SetGWorld (old_port, old_gdh); +#endif } @@ -748,6 +791,17 @@ unsigned int width, height; unsigned int depth; { +#if USE_MAC_IMAGE_IO + XImagePtr ximg; + + ximg = xmalloc (sizeof (*ximg)); + ximg->width = width; + ximg->height = height; + ximg->bits_per_pixel = depth == 1 ? 8 : 32; + ximg->bytes_per_line = width * (ximg->bits_per_pixel / 8); + ximg->data = xmalloc (ximg->bytes_per_line * height); + return ximg; +#else Pixmap pixmap; Rect r; QDErr err; @@ -768,6 +822,7 @@ if (err != noErr) return NULL; return pixmap; +#endif } @@ -782,6 +837,38 @@ { Pixmap pixmap; BitMap bitmap; +#if USE_MAC_IMAGE_IO + CGDataProviderRef provider; + CGImageRef image_mask; + CGContextRef context; + + pixmap = XCreatePixmap (display, w, width, height, depth); + if (pixmap == NULL) + return NULL; + + mac_create_bitmap_from_bitmap_data (&bitmap, data, width, height); + provider = CGDataProviderCreateWithData (NULL, bitmap.baseAddr, + bitmap.rowBytes * height, NULL); + image_mask = CGImageMaskCreate (width, height, 1, 1, bitmap.rowBytes, + provider, NULL, 0); + CGDataProviderRelease (provider); + + context = CGBitmapContextCreate (pixmap->data, width, height, 8, + pixmap->bytes_per_line, + mac_cg_color_space_rgb, + kCGImageAlphaNoneSkipFirst +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 + | kCGBitmapByteOrder32Host +#endif + ); + + CG_SET_FILL_COLOR (context, fg); + CGContextFillRect (context, CGRectMake (0, 0, width, height)); + CG_SET_FILL_COLOR (context, bg); + CGContextDrawImage (context, CGRectMake (0, 0, width, height), image_mask); + CGContextRelease (context); + CGImageRelease (image_mask); +#else CGrafPtr old_port; GDHandle old_gdh; static GC gc = NULL; @@ -810,6 +897,7 @@ #endif /* not TARGET_API_MAC_CARBON */ UnlockPixels (GetGWorldPixMap (pixmap)); SetGWorld (old_port, old_gdh); +#endif mac_free_bitmap (&bitmap); return pixmap; @@ -821,7 +909,16 @@ Display *display; Pixmap pixmap; { +#if USE_MAC_IMAGE_IO + if (pixmap) + { + if (pixmap->data) + xfree (pixmap->data); + xfree (pixmap); + } +#else DisposeGWorld (pixmap); +#endif }
--- a/src/macterm.h Sun May 04 19:46:02 2008 +0000 +++ b/src/macterm.h Sun May 04 19:46:16 2008 +0000 @@ -25,8 +25,10 @@ #include "frame.h" #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b)) +#define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) -#define RED_FROM_ULONG(color) ((color) >> 16) +#define ALPHA_FROM_ULONG(color) ((color) >> 24) +#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff) #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff) #define BLUE_FROM_ULONG(color) ((color) & 0xff) @@ -649,6 +651,10 @@ #define FONT_TYPE_FOR_UNIBYTE(font, ch) 0 #define FONT_TYPE_FOR_MULTIBYTE(font, ch) 0 +#if USE_MAC_IMAGE_IO +extern CGColorSpaceRef mac_cg_color_space_rgb; +#endif + /* Defined in macselect.c */ extern void x_clear_frame_selections P_ ((struct frame *));
--- a/src/s/darwin.h Sun May 04 19:46:02 2008 +0000 +++ b/src/s/darwin.h Sun May 04 19:46:16 2008 +0000 @@ -265,9 +265,31 @@ /* Indicate that we are compiling for Mac OS X. */ #define C_SWITCH_SYSTEM -fpascal-strings -DMAC_OSX +#ifdef HAVE_CARBON + +#ifdef HAVE_AVAILABILITYMACROS_H +#include <AvailabilityMacros.h> +#endif + +/* Whether to use the Image I/O framework for reading images. */ +#ifndef USE_MAC_IMAGE_IO +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 && (MAC_OS_X_VERSION_MIN_REQUIRED >= 1040 || MAC_OS_X_VERSION_MIN_REQUIRED < 1020) +#define USE_MAC_IMAGE_IO 1 +#endif +#endif + +/* If the Image I/O framework is not used, fall back on QuickTime. */ +#if USE_MAC_IMAGE_IO +#define LIBS_IMAGE +#else +#define LIBS_IMAGE -framework QuickTime +#endif + +#endif /* HAVE_CARBON */ + /* Link in the Carbon lib. */ #ifdef HAVE_CARBON -#define LIBS_CARBON -framework Carbon -framework QuickTime +#define LIBS_CARBON -framework Carbon LIBS_IMAGE #else #define LIBS_CARBON #endif