summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rwxr-xr-xconfigure140
-rw-r--r--configure.in1
-rw-r--r--src/ChangeLog49
-rw-r--r--src/config.in3
-rw-r--r--src/image.c399
-rw-r--r--src/macgui.h11
-rw-r--r--src/macterm.c99
-rw-r--r--src/macterm.h8
-rw-r--r--src/s/darwin.h24
10 files changed, 698 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index d5ab34f6252..f42a3a36bca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 -
diff --git a/configure b/configure
index 529e3af5a57..170eb393dea 100755
--- a/configure
+++ b/configure
@@ -15020,6 +15020,146 @@ cat >>confdefs.h <<\_ACEOF
#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
diff --git a/configure.in b/configure.in
index bbaca559148..2e3aa63edc5 100644
--- a/configure.in
+++ b/configure.in
@@ -2230,6 +2230,7 @@ AC_CHECK_HEADER(malloc/malloc.h, [AC_DEFINE(HAVE_MALLOC_MALLOC_H, 1, [Define to
### 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
diff --git a/src/ChangeLog b/src/ChangeLog
index 1bf4586c26a..48ee2eeca69 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -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
diff --git a/src/config.in b/src/config.in
index 2ed107fc288..6c51c6e91ed 100644
--- a/src/config.in
+++ b/src/config.in
@@ -90,6 +90,9 @@ Boston, MA 02110-1301, USA. */
/* 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
diff --git a/src/image.c b/src/image.c
index fbf6a15cef6..48b223c6c76 100644
--- a/src/image.c
+++ b/src/image.c
@@ -115,10 +115,15 @@ typedef struct mac_bitmap_record Bitmap_Record;
#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 @@ XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
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 @@ XGetImage (display, pixmap, x, y, width, height, plane_mask, format)
#endif
LockPixels (GetGWorldPixMap (pixmap));
+#endif
return pixmap;
}
@@ -187,6 +194,12 @@ XPutPixel (ximage, x, y, pixel)
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 @@ XPutPixel (ximage, x, y, pixel)
SetGWorld (old_port, old_gdh);
}
+#endif
}
static unsigned long
@@ -234,6 +248,12 @@ XGetPixel (ximage, x, y)
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 @@ XGetPixel (ximage, x, y)
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 @@ mac_create_cg_image_from_image (f, img)
UNBLOCK_INPUT;
return result;
+#endif
}
#endif /* USE_CG_DRAWING */
#endif /* MAC_OS */
@@ -2301,7 +2381,9 @@ x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
return 0;
}
+#if !USE_MAC_IMAGE_IO
LockPixels (GetGWorldPixMap (*pixmap));
+#endif
*ximg = *pixmap;
return 1;
@@ -2454,6 +2536,256 @@ slurp_file (file, size)
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 @@ image_load_quicktime (f, img, type)
#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 @@ image_load_quartz2d (f, img, png_p)
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 @@ image_load_quartz2d (f, img, png_p)
return 1;
}
#endif
+#endif /* !USE_MAC_IMAGE_IO */
#endif /* MAC_OS */
@@ -4275,8 +4586,8 @@ xpm_scan (s, end, beg, len)
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 @@ png_load (f, img)
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 @@ jpeg_load (f, img)
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 @@ tiff_load (f, img)
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 @@ gif_load (f, img)
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 @@ gif_load (f, img)
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 @@ gif_load (f, img)
if (dh)
DisposeHandle (dh);
return 0;
+#endif /* !USE_MAC_IMAGE_IO */
}
#endif /* MAC_OS */
@@ -9264,9 +9586,6 @@ meaning don't clear the cache. */);
void
init_image ()
{
-#if defined (MAC_OSX) && TARGET_API_MAC_CARBON
- init_image_func_pointer ();
-#endif
}
/* arch-tag: 123c2a5e-14a8-4c53-ab95-af47d7db49b9
diff --git a/src/macgui.h b/src/macgui.h
index 41ac28f49ec..9d4eb0ed9f4 100644
--- a/src/macgui.h
+++ b/src/macgui.h
@@ -154,7 +154,18 @@ typedef int Selection;
#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)
diff --git a/src/macterm.c b/src/macterm.c
index b458444f977..671ac1010d2 100644
--- a/src/macterm.c
+++ b/src/macterm.c
@@ -335,7 +335,7 @@ static struct terminal *mac_create_terminal P_ ((struct mac_display_info *dpyinf
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 @@ XDrawLine (display, p, gc, x1, y1, x2, y2)
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 @@ XDrawLine (display, p, gc, x1, y1, x2, y2)
UnlockPixels (GetGWorldPixMap (p));
SetGWorld (old_port, old_gdh);
+#endif
}
@@ -748,6 +791,17 @@ XCreatePixmap (display, w, width, height, depth)
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 @@ XCreatePixmap (display, w, width, height, depth)
if (err != noErr)
return NULL;
return pixmap;
+#endif
}
@@ -782,6 +837,38 @@ XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
{
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 @@ XCreatePixmapFromBitmapData (display, w, data, width, height, fg, bg, depth)
#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 @@ XFreePixmap (display, pixmap)
Display *display;
Pixmap pixmap;
{
+#if USE_MAC_IMAGE_IO
+ if (pixmap)
+ {
+ if (pixmap->data)
+ xfree (pixmap->data);
+ xfree (pixmap);
+ }
+#else
DisposeGWorld (pixmap);
+#endif
}
diff --git a/src/macterm.h b/src/macterm.h
index 6a000451785..00b01e452da 100644
--- a/src/macterm.h
+++ b/src/macterm.h
@@ -25,8 +25,10 @@ Boston, MA 02110-1301, USA. */
#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 @@ extern int mac_quit_char_key_p P_ ((UInt32, UInt32));
#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 *));
diff --git a/src/s/darwin.h b/src/s/darwin.h
index dee3480c783..2e7e4e40be4 100644
--- a/src/s/darwin.h
+++ b/src/s/darwin.h
@@ -265,9 +265,31 @@ Boston, MA 02110-1301, USA. */
/* 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