]> git.eshelyaron.com Git - emacs.git/commitdiff
Add multiframe image support to NS port (bug#21714)
authorAlan Third <alan@idiocy.org>
Sun, 13 Aug 2017 00:47:05 +0000 (01:47 +0100)
committerAlan Third <alan@idiocy.org>
Wed, 16 Aug 2017 19:56:55 +0000 (20:56 +0100)
* 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
src/nsterm.h

index fb2322afc3085d6bbb19d2c56f1af737ed5015b9..94b24a3912c3bef521d869cbdaa9229bdc9d8ab3 100644 (file)
@@ -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
index 0f1b36db7b263491600fb7db05e1f2106e86c5ba..67c0d42ac18b44a79b22c9533322191142ebf770 100644 (file)
@@ -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