aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChong Yidong2011-05-29 17:35:35 -0400
committerChong Yidong2011-05-29 17:35:35 -0400
commite8cbec34e8ef069f54c1189a7b6109f768047be8 (patch)
tree1890ec0a32380fed7a288e602405ed14e1c30a5b
parent34809aa6007e2c8ff75f9ec43500e6d34cc43aa3 (diff)
downloademacs-e8cbec34e8ef069f54c1189a7b6109f768047be8.tar.gz
emacs-e8cbec34e8ef069f54c1189a7b6109f768047be8.zip
Fix animated gifs (Bug#6981).
* lisp/image-mode.el (image-toggle-display-image): Ensure that the image spec passed to the animate timer is the same object as in the the buffer's display property. (image-transform-properties): Doc fix. * lisp/image.el (image-animate-max-time): Default to nil. * lisp/image.el (image-animate-max-time): Allow nil and t values. Default to nil. (create-animated-image): Doc fix. (image-animate-start): Remove second arg; just use image-animate-max-time. (image-animate-timeout): Doc fix. Args changed.
-rw-r--r--lisp/ChangeLog16
-rw-r--r--lisp/image-mode.el33
-rw-r--r--lisp/image.el75
3 files changed, 82 insertions, 42 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c54e48ef52a..6d4752efec0 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,19 @@
12011-05-29 Chong Yidong <cyd@stupidchicken.com>
2
3 * image.el (image-animate-max-time): Allow nil and t values.
4 Default to nil.
5 (create-animated-image): Doc fix.
6 (image-animate-start): Remove second arg; just use
7 image-animate-max-time.
8 (image-animate-timeout): Doc fix. Args changed.
9
10 * image-mode.el (image-toggle-display-image): Ensure that the
11 image spec passed to the animate timer is the same object as in
12 the the buffer's display property (Bug#6981).
13 (image-transform-properties): Doc fix.
14
15 * image.el (image-animate-max-time): Default to nil.
16
12011-05-29 Martin Rudalics <rudalics@gmx.at> 172011-05-29 Martin Rudalics <rudalics@gmx.at>
2 18
3 * menu-bar.el (kill-this-buffer-enabled-p): Avoid looping over 19 * menu-bar.el (kill-this-buffer-enabled-p): Avoid looping over
diff --git a/lisp/image-mode.el b/lisp/image-mode.el
index f4eb5eeaf45..145a15de246 100644
--- a/lisp/image-mode.el
+++ b/lisp/image-mode.el
@@ -484,18 +484,26 @@ was inserted."
484 (buffer-substring-no-properties (point-min) (point-max))) 484 (buffer-substring-no-properties (point-min) (point-max)))
485 filename)) 485 filename))
486 (type (image-type file-or-data nil data-p)) 486 (type (image-type file-or-data nil data-p))
487 (image0 (create-animated-image file-or-data type data-p)) 487 ;; Don't use create-animated-image here; that would start the
488 (image (append image0 488 ;; timer, which works by altering the spec destructively.
489 (image-transform-properties image0))) 489 ;; But we still need to append the transformation properties,
490 (props 490 ;; which would make a new list.
491 (image (create-image file-or-data type data-p))
492 (inhibit-read-only t)
493 (buffer-undo-list t)
494 (modified (buffer-modified-p))
495 props)
496
497 (setq image (append image (image-transform-properties image)))
498 (setq props
491 `(display ,image 499 `(display ,image
492 intangible ,image 500 intangible ,image
493 rear-nonsticky (display intangible) 501 rear-nonsticky (display intangible)
494 read-only t front-sticky (read-only))) 502 read-only t front-sticky (read-only)))
495 (inhibit-read-only t)
496 (buffer-undo-list t)
497 (modified (buffer-modified-p)))
498 (image-flush image) 503 (image-flush image)
504 ;; Begin the animation, if any.
505 (image-animate-start image)
506
499 (let ((buffer-file-truename nil)) ; avoid changing dir mtime by lock_file 507 (let ((buffer-file-truename nil)) ; avoid changing dir mtime by lock_file
500 (add-text-properties (point-min) (point-max) props) 508 (add-text-properties (point-min) (point-max) props)
501 (restore-buffer-modified-p modified)) 509 (restore-buffer-modified-p modified))
@@ -584,10 +592,13 @@ Its value should be one of the following:
584(defvar image-transform-rotation 0.0) 592(defvar image-transform-rotation 0.0)
585 593
586(defun image-transform-properties (display) 594(defun image-transform-properties (display)
587 "Rescale and/or rotate the current image. 595 "Return rescaling/rotation properties for the Image mode buffer.
588The scale factor and rotation angle are given by the variables 596These properties are suitable for appending to an image spec;
589`image-transform-resize' and `image-transform-rotation'. This 597they are determined by the variables `image-transform-resize' and
590takes effect only if Emacs is compiled with ImageMagick support." 598`image-transform-rotation'.
599
600Recaling and rotation properties only take effect if Emacs is
601compiled with ImageMagick support."
591 (let* ((size (image-size display t)) 602 (let* ((size (image-size display t))
592 (height 603 (height
593 (cond 604 (cond
diff --git a/lisp/image.el b/lisp/image.el
index 3f44be868ce..b9ed10eacf2 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -590,9 +590,13 @@ Example:
590 590
591;;; Animated image API 591;;; Animated image API
592 592
593(defcustom image-animate-max-time 30 593(defcustom image-animate-max-time nil
594 "Time in seconds to animate images." 594 "Time in seconds to animate images.
595 :type 'integer 595If the value is nil, play animations once.
596If the value is t, loop forever."
597 :type '(choice (const :tag "Play once" nil)
598 (const :tag "Loop forever" t)
599 integer)
596 :version "24.1" 600 :version "24.1"
597 :group 'image) 601 :group 'image)
598 602
@@ -601,7 +605,7 @@ Example:
601 605
602;;;###autoload 606;;;###autoload
603(defun create-animated-image (file-or-data &optional type data-p &rest props) 607(defun create-animated-image (file-or-data &optional type data-p &rest props)
604 "Create an animated image. 608 "Create an animated image, and begin animating it.
605FILE-OR-DATA is an image file name or image data. 609FILE-OR-DATA is an image file name or image data.
606Optional TYPE is a symbol describing the image type. If TYPE is omitted 610Optional TYPE is a symbol describing the image type. If TYPE is omitted
607or nil, try to determine the image type from its first few bytes 611or nil, try to determine the image type from its first few bytes
@@ -638,22 +642,20 @@ Images should not be larger than specified by `max-image-size'."
638 (setq timer nil))) 642 (setq timer nil)))
639 timer)) 643 timer))
640 644
641(defun image-animate-start (image &optional max-time) 645(defun image-animate-start (image)
642 "Start animation of image IMAGE. 646 "Start animating the image IMAGE.
643Optional second arg MAX-TIME is number of seconds to animate image, 647The variable `image-animate-max-time' determines how long to
644or t to animate infinitely." 648animate for."
645 (let ((anim (image-animated-p image)) 649 (let ((anim (image-animated-p image))
646 timer tmo) 650 delay ; in seconds
651 timer)
647 (when anim 652 (when anim
648 (if (setq timer (image-animate-timer image)) 653 (if (setq timer (image-animate-timer image))
649 (setcar (nthcdr 3 (aref timer 6)) max-time) 654 (cancel-timer timer))
650 (setq tmo (* (cdr anim) 0.01)) 655 (setq delay (max (* (cdr anim) 0.01) 0.025))
651 (setq max-time (or max-time image-animate-max-time)) 656 (run-with-timer 0.2 nil #'image-animate-timeout
652 (run-with-timer tmo nil #'image-animate-timeout 657 image 0 (car anim)
653 image 1 (car anim) 658 delay 0 image-animate-max-time))))
654 (if (numberp max-time)
655 (- max-time tmo)
656 max-time))))))
657 659
658(defun image-animate-stop (image) 660(defun image-animate-stop (image)
659 "Stop animation of image." 661 "Stop animation of image."
@@ -661,20 +663,31 @@ or t to animate infinitely."
661 (when timer 663 (when timer
662 (cancel-timer timer)))) 664 (cancel-timer timer))))
663 665
664(defun image-animate-timeout (image ino count time-left) 666(defun image-animate-timeout (image n count delay time-elapsed max)
665 (if (>= ino count) 667 "Display animation frame N of IMAGE.
666 (setq ino 0)) 668N=0 refers to the initial animation frame.
667 (plist-put (cdr image) :index ino) 669COUNT is the total number of frames in the animation.
668 (force-window-update) 670DELAY is the time between animation frames, in seconds.
669 (let ((anim (image-animated-p image)) tmo) 671TIME-ELAPSED is the total time that has elapsed since
670 (when anim 672`image-animate-start' was called.
671 (setq tmo (* (cdr anim) 0.01)) 673MAX determines when to stop. If t, loop forever. If nil, stop
672 (unless (and (= ino 0) (numberp time-left) (< time-left tmo)) 674 after displaying the last animation frame. Otherwise, stop
673 (run-with-timer tmo nil #'image-animate-timeout 675 after MAX seconds have elapsed."
674 image (1+ ino) count 676 (let (done)
675 (if (numberp time-left) 677 (plist-put (cdr image) :index n)
676 (- time-left tmo) 678 (force-window-update)
677 time-left)))))) 679 (setq n (1+ n))
680 (if (>= n count)
681 (if max
682 (setq n 0)
683 (setq done t)))
684 (setq time-elapsed (+ delay time-elapsed))
685 (if (numberp max)
686 (setq done (>= time-elapsed max)))
687 (unless done
688 (run-with-timer delay nil 'image-animate-timeout
689 image n count delay
690 time-elapsed max))))
678 691
679(defun image-animated-p (image) 692(defun image-animated-p (image)
680 "Return non-nil if image is animated. 693 "Return non-nil if image is animated.