From 3505b77ad7b54e5208685b6e229c76387120d5a1 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sun, 13 Aug 2017 01:47:05 +0100 Subject: [PATCH] Add multiframe image support to NS port (bug#21714) * src/nsimage.m (ns_load_image): Handle multiple frames. (EmacsImage::getMetadata, EmacsImage::setFrame): New functions. * src/nsterm.h (EmacsImage::getMetadata, EmacsImage::setFrame): New function prototypes. --- src/nsimage.m | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/nsterm.h | 2 ++ 2 files changed, 62 insertions(+) diff --git a/src/nsimage.m b/src/nsimage.m index fb2322afc30..94b24a3912c 100644 --- a/src/nsimage.m +++ b/src/nsimage.m @@ -76,9 +76,16 @@ ns_load_image (struct frame *f, struct image *img, { EmacsImage *eImg = nil; NSSize size; + Lisp_Object lisp_index; + unsigned int index; NSTRACE ("ns_load_image"); + eassert (valid_image_p (img->spec)); + + lisp_index = Fplist_get (XCDR (img->spec), QCindex); + index = INTEGERP (lisp_index) ? XFASTINT (lisp_index) : 0; + if (STRINGP (spec_file)) { eImg = [EmacsImage allocInitFromFile: spec_file]; @@ -99,12 +106,20 @@ ns_load_image (struct frame *f, struct image *img, return 0; } + if (index < 0 || ![eImg setFrame: index]) + { + add_to_log ("Unable to set index %d for image %s", index, img->spec); + return 0; + } + size = [eImg size]; img->width = size.width; img->height = size.height; /* 4) set img->pixmap = emacsimage */ img->pixmap = eImg; + + img->lisp_data = [eImg getMetadata]; return 1; } @@ -435,4 +450,49 @@ ns_set_alpha (void *img, int x, int y, unsigned char a) return stippleMask; } +/* If the image has multiple frames, get a count of them and the + animation delay, if available. */ +- (Lisp_Object)getMetadata +{ + Lisp_Object metadata = Qnil; + + for (NSImageRep * r in [self representations]) + { + if ([r isKindOfClass:[NSBitmapImageRep class]]) + { + NSBitmapImageRep * bm = (NSBitmapImageRep *)r; + int frames = [[bm valueForProperty: NSImageFrameCount] intValue]; + float delay = [[bm valueForProperty: NSImageCurrentFrameDuration] + floatValue]; + + if (frames > 1) + metadata = Fcons (Qcount, Fcons (make_number (frames), metadata)); + if (delay > 0) + metadata = Fcons (Qdelay, Fcons (make_float (delay), metadata)); + break; + } + } + return metadata; +} + +/* Attempt to set the animation frame to be displayed. */ +- (BOOL)setFrame: (unsigned int) index +{ + for (NSImageRep * r in [self representations]) + { + if ([r isKindOfClass:[NSBitmapImageRep class]]) + { + NSBitmapImageRep * bm = (NSBitmapImageRep *)r; + if ([[bm valueForProperty: NSImageFrameCount] intValue] <= index) + continue; + + [bm setProperty: NSImageCurrentFrame + withValue: [NSNumber numberWithUnsignedInt: index]]; + return YES; + } + } + + return NO; +} + @end diff --git a/src/nsterm.h b/src/nsterm.h index 0f1b36db7b2..67c0d42ac18 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -668,6 +668,8 @@ typedef id instancetype; alpha:(unsigned char)a; - (void)setAlphaAtX: (int)x Y: (int)y to: (unsigned char)a; - (NSColor *)stippleMask; +- (Lisp_Object)getMetadata; +- (BOOL)setFrame: (unsigned int) index; @end -- 2.39.5