diff options
| author | Chong Yidong | 2011-05-29 17:35:35 -0400 |
|---|---|---|
| committer | Chong Yidong | 2011-05-29 17:35:35 -0400 |
| commit | e8cbec34e8ef069f54c1189a7b6109f768047be8 (patch) | |
| tree | 1890ec0a32380fed7a288e602405ed14e1c30a5b | |
| parent | 34809aa6007e2c8ff75f9ec43500e6d34cc43aa3 (diff) | |
| download | emacs-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/ChangeLog | 16 | ||||
| -rw-r--r-- | lisp/image-mode.el | 33 | ||||
| -rw-r--r-- | lisp/image.el | 75 |
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 @@ | |||
| 1 | 2011-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 | |||
| 1 | 2011-05-29 Martin Rudalics <rudalics@gmx.at> | 17 | 2011-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. |
| 588 | The scale factor and rotation angle are given by the variables | 596 | These properties are suitable for appending to an image spec; |
| 589 | `image-transform-resize' and `image-transform-rotation'. This | 597 | they are determined by the variables `image-transform-resize' and |
| 590 | takes effect only if Emacs is compiled with ImageMagick support." | 598 | `image-transform-rotation'. |
| 599 | |||
| 600 | Recaling and rotation properties only take effect if Emacs is | ||
| 601 | compiled 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 | 595 | If the value is nil, play animations once. |
| 596 | If 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. |
| 605 | FILE-OR-DATA is an image file name or image data. | 609 | FILE-OR-DATA is an image file name or image data. |
| 606 | Optional TYPE is a symbol describing the image type. If TYPE is omitted | 610 | Optional TYPE is a symbol describing the image type. If TYPE is omitted |
| 607 | or nil, try to determine the image type from its first few bytes | 611 | or 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. |
| 643 | Optional second arg MAX-TIME is number of seconds to animate image, | 647 | The variable `image-animate-max-time' determines how long to |
| 644 | or t to animate infinitely." | 648 | animate 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)) | 668 | N=0 refers to the initial animation frame. |
| 667 | (plist-put (cdr image) :index ino) | 669 | COUNT is the total number of frames in the animation. |
| 668 | (force-window-update) | 670 | DELAY is the time between animation frames, in seconds. |
| 669 | (let ((anim (image-animated-p image)) tmo) | 671 | TIME-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)) | 673 | MAX 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. |