Add image-auto-resize defcustoms to image-mode.el

* lisp/image-mode.el (image-auto-resize)
(image-auto-resize-on-window-resize): New defcustoms.
(image-mode-map): Bind "sb" to image-transform-fit-both.
(image-mode): Set image-transform-resize to image-auto-resize initially.
(image-mode--setup-mode): Add hook on image-auto-resize-on-window-resize.
(image-toggle-display-image): Check if image-transform-resize is t.
(image-transform-properties): Check image-transform-resize for nil and t.
(image-transform-fit-both): New command.
(image-transform-reset): Reset image-transform-resize to image-auto-resize.

* doc/emacs/files.texi (Image Mode): Mention image-auto-resize and
image-auto-resize-on-window-resize.

https://lists.gnu.org/archive/html/emacs-devel/2020-04/msg01160.html
This commit is contained in:
Juri Linkov 2020-04-21 02:42:16 +03:00
parent 692ad40539
commit a64da75961
3 changed files with 61 additions and 12 deletions

View file

@ -2122,12 +2122,18 @@ to toggle between displaying the file as an image in the Emacs buffer,
and displaying its underlying text (or raw byte) representation. and displaying its underlying text (or raw byte) representation.
Additionally you can type @kbd{C-c C-x} (@code{image-toggle-hex-display}) Additionally you can type @kbd{C-c C-x} (@code{image-toggle-hex-display})
to toggle between displaying the file as an image in the Emacs buffer, to toggle between displaying the file as an image in the Emacs buffer,
and displaying it in hex representation. and displaying it in hex representation. Displaying the file as an
Displaying the file as an image works only if Emacs is compiled with image works only if Emacs is compiled with support for displaying
support for displaying such images. If the displayed image is wider such images.
or taller than the frame, the usual point motion keys (@kbd{C-f},
@kbd{C-p}, and so forth) cause different parts of the image to be If the displayed image is wider or taller than the frame, the usual
displayed. You can press @kbd{n} (@code{image-next-file}) and @kbd{p} point motion keys (@kbd{C-f}, @kbd{C-p}, and so forth) cause different
parts of the image to be displayed. But by default the image is
resized automatically to fit to the window. You can configure this by
using two options @code{image-auto-resize} and
@code{image-auto-resize-on-window-resize}.
You can press @kbd{n} (@code{image-next-file}) and @kbd{p}
(@code{image-previous-file}) to visit the next image file and the (@code{image-previous-file}) to visit the next image file and the
previous image file in the same directory, respectively. previous image file in the same directory, respectively.

View file

@ -3523,9 +3523,12 @@ functions.
*** 'image-mode' now uses this library to automatically rotate images *** 'image-mode' now uses this library to automatically rotate images
according to the orientation in the Exif data, if any. according to the orientation in the Exif data, if any.
+++
*** In 'image-mode' the image is resized automatically to fit in window. *** In 'image-mode' the image is resized automatically to fit in window.
The image will resize upon first display and whenever the window's The image will resize upon first display and whenever the window's
dimensions change. dimensions change. Two user options 'image-auto-resize' and
'image-auto-resize-on-window-resize' can define resizing parameters or
disable auto-resizing.
--- ---
*** New library image-converter. *** New library image-converter.

View file

@ -53,11 +53,38 @@ See `image-mode-winprops'.")
"Special hook run when image data is requested in a new window. "Special hook run when image data is requested in a new window.
It is called with one argument, the initial WINPROPS.") It is called with one argument, the initial WINPROPS.")
(defcustom image-auto-resize t
"Non-nil to resize the image upon first display.
Its value should be one of the following:
- nil, meaning no resizing.
- t, meaning to fit the image to the window height and width.
- `fit-height', meaning to fit the image to the window height.
- `fit-width', meaning to fit the image to the window width.
- A number, which is a scale factor (the default size is 1)."
:type '(choice (const :tag "No resizing" nil)
(other :tag "Fit height and width" t)
(const :tag "Fit height" fit-height)
(const :tag "Fit width" fit-width)
(number :tag "Scale factor" 1))
:version "27.1"
:group 'image)
(defcustom image-auto-resize-on-window-resize 1
"Non-nil to resize the image whenever the window's dimensions change.
This will always keep the image fit to the window.
When non-nil, the value should be a number of seconds to wait before
resizing according to the value specified in `image-auto-resize'."
:type '(choice (const :tag "No auto-resize on window size change" nil)
(integer :tag "Wait for number of seconds before resize" 1))
:version "27.1"
:group 'image)
;; FIXME this doesn't seem mature yet. Document in manual when it is. ;; FIXME this doesn't seem mature yet. Document in manual when it is.
(defvar-local image-transform-resize nil (defvar-local image-transform-resize nil
"The image resize operation. "The image resize operation.
Its value should be one of the following: Its value should be one of the following:
- nil, meaning no resizing. - nil, meaning no resizing.
- t, meaning to fit the image to the window height and width.
- `fit-height', meaning to fit the image to the window height. - `fit-height', meaning to fit the image to the window height.
- `fit-width', meaning to fit the image to the window width. - `fit-width', meaning to fit the image to the window width.
- A number, which is a scale factor (the default size is 1).") - A number, which is a scale factor (the default size is 1).")
@ -425,6 +452,7 @@ call."
;; Transformation keys ;; Transformation keys
(define-key map "sf" 'image-mode-fit-frame) (define-key map "sf" 'image-mode-fit-frame)
(define-key map "sb" 'image-transform-fit-both)
(define-key map "sh" 'image-transform-fit-to-height) (define-key map "sh" 'image-transform-fit-to-height)
(define-key map "sw" 'image-transform-fit-to-width) (define-key map "sw" 'image-transform-fit-to-width)
(define-key map "sr" 'image-transform-set-rotation) (define-key map "sr" 'image-transform-set-rotation)
@ -482,6 +510,8 @@ call."
:help "Resize image to match the window height"] :help "Resize image to match the window height"]
["Fit to Window Width" image-transform-fit-to-width ["Fit to Window Width" image-transform-fit-to-width
:help "Resize image to match the window width"] :help "Resize image to match the window width"]
["Fit to Window Height and Width" image-transform-fit-both
:help "Resize image to match the window height and width"]
["Rotate Image..." image-transform-set-rotation ["Rotate Image..." image-transform-set-rotation
:help "Rotate the image"] :help "Rotate the image"]
["Reset Transformations" image-transform-reset ["Reset Transformations" image-transform-reset
@ -569,6 +599,7 @@ Key bindings:
(major-mode-suspend) (major-mode-suspend)
(setq major-mode 'image-mode) (setq major-mode 'image-mode)
(setq image-transform-resize image-auto-resize)
(if (not (image-get-display-property)) (if (not (image-get-display-property))
(progn (progn
@ -611,7 +642,8 @@ Key bindings:
(add-hook 'change-major-mode-hook #'image-toggle-display-text nil t) (add-hook 'change-major-mode-hook #'image-toggle-display-text nil t)
(add-hook 'after-revert-hook #'image-after-revert-hook nil t) (add-hook 'after-revert-hook #'image-after-revert-hook nil t)
(add-hook 'window-state-change-functions #'image--window-state-change nil t) (when image-auto-resize-on-window-resize
(add-hook 'window-state-change-functions #'image--window-state-change nil t))
(run-mode-hooks 'image-mode-hook) (run-mode-hooks 'image-mode-hook)
(let ((image (image-get-display-property)) (let ((image (image-get-display-property))
@ -768,7 +800,7 @@ was inserted."
filename)) filename))
;; If we have a `fit-width' or a `fit-height', don't limit ;; If we have a `fit-width' or a `fit-height', don't limit
;; the size of the image to the window size. ;; the size of the image to the window size.
(edges (and (null image-transform-resize) (edges (and (eq image-transform-resize t)
(window-inside-pixel-edges (get-buffer-window)))) (window-inside-pixel-edges (get-buffer-window))))
(type (if (image--imagemagick-wanted-p filename) (type (if (image--imagemagick-wanted-p filename)
'imagemagick 'imagemagick
@ -878,7 +910,9 @@ Otherwise, display the image by calling `image-mode'."
;; image resizing happens later during redisplay. So if those ;; image resizing happens later during redisplay. So if those
;; consecutive calls happen without any redisplay between them, ;; consecutive calls happen without any redisplay between them,
;; the costly operation of image resizing should happen only once. ;; the costly operation of image resizing should happen only once.
(run-with-idle-timer 1 nil #'image-fit-to-window window)) (when (numberp image-auto-resize-on-window-resize)
(run-with-idle-timer image-auto-resize-on-window-resize nil
#'image-fit-to-window window)))
(defun image-fit-to-window (window) (defun image-fit-to-window (window)
"Adjust size of image to display it exactly in WINDOW boundaries." "Adjust size of image to display it exactly in WINDOW boundaries."
@ -1282,7 +1316,7 @@ These properties are determined by the Image mode variables
`image-transform-resize' and `image-transform-rotation'. The `image-transform-resize' and `image-transform-rotation'. The
return value is suitable for appending to an image spec." return value is suitable for appending to an image spec."
(setq image-transform-scale 1.0) (setq image-transform-scale 1.0)
(when (or image-transform-resize (when (or (not (memq image-transform-resize '(nil t)))
(/= image-transform-rotation 0.0)) (/= image-transform-rotation 0.0))
;; Note: `image-size' looks up and thus caches the untransformed ;; Note: `image-size' looks up and thus caches the untransformed
;; image. There's no easy way to prevent that. ;; image. There's no easy way to prevent that.
@ -1328,6 +1362,12 @@ return value is suitable for appending to an image spec."
(setq image-transform-resize 'fit-width) (setq image-transform-resize 'fit-width)
(image-toggle-display-image)) (image-toggle-display-image))
(defun image-transform-fit-both ()
"Fit the current image both to the height and width of the current window."
(interactive)
(setq image-transform-resize t)
(image-toggle-display-image))
(defun image-transform-set-rotation (rotation) (defun image-transform-set-rotation (rotation)
"Prompt for an angle ROTATION, and rotate the image by that amount. "Prompt for an angle ROTATION, and rotate the image by that amount.
ROTATION should be in degrees." ROTATION should be in degrees."
@ -1338,7 +1378,7 @@ ROTATION should be in degrees."
(defun image-transform-reset () (defun image-transform-reset ()
"Display the current image with the default size and rotation." "Display the current image with the default size and rotation."
(interactive) (interactive)
(setq image-transform-resize nil (setq image-transform-resize image-auto-resize
image-transform-rotation 0.0 image-transform-rotation 0.0
image-transform-scale 1) image-transform-scale 1)
(image-toggle-display-image)) (image-toggle-display-image))