summaryrefslogtreecommitdiff
path: root/lisp/image.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/image.el')
-rw-r--r--lisp/image.el134
1 files changed, 91 insertions, 43 deletions
diff --git a/lisp/image.el b/lisp/image.el
index c9165f77814..bdaaec608ef 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -171,18 +171,18 @@ or \"ffmpeg\") is installed."
(define-error 'unknown-image-type "Unknown image type")
-;; Map put into text properties on images.
-(defvar image-map
- (let ((map (make-sparse-keymap)))
- (define-key map "-" 'image-decrease-size)
- (define-key map "+" 'image-increase-size)
- (define-key map [C-wheel-down] 'image-mouse-decrease-size)
- (define-key map [C-mouse-5] 'image-mouse-decrease-size)
- (define-key map [C-wheel-up] 'image-mouse-increase-size)
- (define-key map [C-mouse-4] 'image-mouse-increase-size)
- (define-key map "r" 'image-rotate)
- (define-key map "o" 'image-save)
- map))
+(defvar-keymap image-map
+ :doc "Map put into text properties on images."
+ "-" #'image-decrease-size
+ "+" #'image-increase-size
+ "r" #'image-rotate
+ "o" #'image-save
+ "h" #'image-flip-horizontally
+ "v" #'image-flip-vertically
+ "C-<wheel-down>" #'image-mouse-decrease-size
+ "C-<mouse-5>" #'image-mouse-decrease-size
+ "C-<wheel-up>" #'image-mouse-increase-size
+ "C-<mouse-4>" #'image-mouse-increase-size)
(defun image-load-path-for-library (library image &optional path no-error)
"Return a suitable search path for images used by LIBRARY.
@@ -382,6 +382,7 @@ be determined."
"Determine the type of image file FILE from its name.
Value is a symbol specifying the image type, or nil if type cannot
be determined."
+ (declare (obsolete image-supported-file-p "29.1"))
(let (type first (case-fold-search t))
(catch 'found
(dolist (elem image-type-file-name-regexps first)
@@ -391,6 +392,20 @@ be determined."
;; If nothing seems to be supported, return first type that matched.
(or first (setq first type))))))))
+ ;;;###autoload
+(defun image-supported-file-p (file)
+ "Say whether Emacs has native support for displaying TYPE.
+The value is a symbol specifying the image type, or nil if type
+cannot be determined (or if Emacs doesn't have built-in support
+for the image type)."
+ (let ((case-fold-search t)
+ type)
+ (catch 'found
+ (dolist (elem image-type-file-name-regexps)
+ (when (and (string-match-p (car elem) file)
+ (image-type-available-p (setq type (cdr elem))))
+ (throw 'found type))))))
+
(declare-function image-convert-p "image-converter.el"
(source &optional image-format))
(declare-function image-convert "image-converter.el"
@@ -419,7 +434,7 @@ type if we can't otherwise guess it."
(require 'image-converter)
(image-convert-p source data-p))))
(or (image-type-from-file-header source)
- (image-type-from-file-name source)
+ (image-supported-file-p source)
(and image-use-external-converter
(progn
(require 'image-converter)
@@ -431,15 +446,6 @@ type if we can't otherwise guess it."
(error "Invalid image type `%s'" type))
type)
-
-(if (fboundp 'image-metadata) ; eg not --without-x
- (define-obsolete-function-alias 'image-extension-data
- 'image-metadata "24.1"))
-
-(define-obsolete-variable-alias
- 'image-library-alist
- 'dynamic-library-alist "24.1")
-
;;;###autoload
(defun image-type-available-p (type)
"Return t if image type TYPE is available.
@@ -463,6 +469,7 @@ must be available."
(and auto
(or (eq auto t) (image-type-available-p type)))))
+(defvar image-convert-to-format)
;;;###autoload
(defun create-image (file-or-data &optional type data-p &rest props)
@@ -500,7 +507,7 @@ Image file names that are not absolute are searched for in the
(when (eq type 'image-convert)
(require 'image-converter)
(setq file-or-data (image-convert file-or-data data-format)
- type 'png
+ type (intern image-convert-to-format)
data-p t)))
(when (image-type-available-p type)
(let ((image
@@ -750,13 +757,15 @@ SPECS is a list of image specifications.
Each image specification in SPECS is a property list. The contents of
a specification are image type dependent. All specifications must at
-least contain the properties `:type TYPE' and either `:file FILE' or
-`:data DATA', where TYPE is a symbol specifying the image type,
-e.g. `xbm', FILE is the file to load the image from, and DATA is a
-string containing the actual image data. The specification whose TYPE
-is supported, and FILE exists, is used to construct the image
-specification to be returned. Return nil if no specification is
-satisfied.
+least contain either the property `:file FILE' or `:data DATA',
+where FILE is the file to load the image from, and DATA is a string
+containing the actual image data. If the property `:type TYPE' is
+omitted or nil, try to determine the image type from its first few
+bytes of image data. If that doesn't work, and the property `:file
+FILE' provide a file name, use its file extension as image type.
+If `:type TYPE' is provided, it must match the actual type
+determined for FILE or DATA by `create-image'. Return nil if no
+specification is satisfied.
If CACHE is non-nil, results are cached and returned on subsequent calls.
@@ -771,22 +780,44 @@ Image files should not be larger than specified by `max-image-size'."
(let* ((spec (car specs))
(type (plist-get spec :type))
(data (plist-get spec :data))
- (file (plist-get spec :file))
- found)
- (when (image-type-available-p type)
- (cond ((stringp file)
- (if (setq found (image-search-load-path file))
- (setq image
- (cons 'image (plist-put (copy-sequence spec)
- :file found)))))
- ((not (null data))
- (setq image (cons 'image spec)))))
+ (file (plist-get spec :file)))
+ (cond
+ ((stringp file)
+ (when (setq file (image-search-load-path file))
+ ;; At this point, remove the :type and :file properties.
+ ;; `create-image' will set them depending on image file.
+ (setq image (cons 'image (copy-sequence spec)))
+ (setf (image-property image :type) nil)
+ (setf (image-property image :file) nil)
+ (and (setq image (ignore-errors
+ (apply #'create-image file nil nil
+ (cdr image))))
+ ;; Ensure, if a type has been provided, it is
+ ;; consistent with the type returned by
+ ;; `create-image'. If not, return nil.
+ (not (null type))
+ (not (eq type (image-property image :type)))
+ (setq image nil))))
+ ((not (null data))
+ ;; At this point, remove the :type and :data properties.
+ ;; `create-image' will set them depending on image data.
+ (setq image (cons 'image (copy-sequence spec)))
+ (setf (image-property image :type) nil)
+ (setf (image-property image :data) nil)
+ (and (setq image (ignore-errors
+ (apply #'create-image data nil t
+ (cdr image))))
+ ;; Ensure, if a type has been provided, it is
+ ;; consistent with the type returned by
+ ;; `create-image'. If not, return nil.
+ (not (null type))
+ (not (eq type (image-property image :type)))
+ (setq image nil))))
(setq specs (cdr specs))))
(when cache
(setf (gethash orig-specs find-image--cache) image))
image)))
-
;;;###autoload
(defmacro defimage (symbol specs &optional doc)
"Define SYMBOL as an image, and return SYMBOL.
@@ -894,8 +925,9 @@ Frames are indexed from 0. Optional argument NOCHECK non-nil means
do not check N is within the range of frames present in the image."
(unless nocheck
(if (< n 0) (setq n 0)
- (setq n (min n (1- (car (plist-get (cdr image)
- :animate-multi-frame-data)))))))
+ (setq n (min n (1- (car (or (plist-get (cdr image)
+ :animate-multi-frame-data)
+ (image-multi-frame-p image))))))))
(plist-put (cdr image) :index n)
(force-window-update (plist-get (cdr image) :animate-buffer)))
@@ -1249,6 +1281,22 @@ changing the displayed image size does not affect the saved image."
(write-region (point-min) (point-max)
(read-file-name "Write image to file: ")))))
+(defun image-flip-horizontally ()
+ "Horizontally flip the image under point."
+ (interactive)
+ (let ((image (image--get-image)))
+ (image-flush image)
+ (setf (image-property image :flip)
+ (not (image-property image :flip)))))
+
+(defun image-flip-vertically ()
+ "Vertically flip the image under point."
+ (interactive)
+ (let ((image (image--get-image)))
+ (image-rotate 180)
+ (setf (image-property image :flip)
+ (not (image-property image :flip)))))
+
(provide 'image)
;;; image.el ends here