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.
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,
and displaying it in hex representation.
Displaying the file as an image works only if Emacs is compiled with
support for displaying such images. If the displayed image is wider
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
displayed. You can press @kbd{n} (@code{image-next-file}) and @kbd{p}
and displaying it in hex representation. Displaying the file as an
image works only if Emacs is compiled with support for displaying
such images.
If the displayed image is wider 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 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
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
according to the orientation in the Exif data, if any.
+++
*** In 'image-mode' the image is resized automatically to fit in window.
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.

View file

@ -53,11 +53,38 @@ See `image-mode-winprops'.")
"Special hook run when image data is requested in a new window.
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.
(defvar-local image-transform-resize nil
"The image resize operation.
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).")
@ -425,6 +452,7 @@ call."
;; Transformation keys
(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 "sw" 'image-transform-fit-to-width)
(define-key map "sr" 'image-transform-set-rotation)
@ -482,6 +510,8 @@ call."
:help "Resize image to match the window height"]
["Fit to Window Width" image-transform-fit-to-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
:help "Rotate the image"]
["Reset Transformations" image-transform-reset
@ -569,6 +599,7 @@ Key bindings:
(major-mode-suspend)
(setq major-mode 'image-mode)
(setq image-transform-resize image-auto-resize)
(if (not (image-get-display-property))
(progn
@ -611,7 +642,8 @@ Key bindings:
(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 '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)
(let ((image (image-get-display-property))
@ -768,7 +800,7 @@ was inserted."
filename))
;; If we have a `fit-width' or a `fit-height', don't limit
;; 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))))
(type (if (image--imagemagick-wanted-p filename)
'imagemagick
@ -878,7 +910,9 @@ Otherwise, display the image by calling `image-mode'."
;; image resizing happens later during redisplay. So if those
;; consecutive calls happen without any redisplay between them,
;; 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)
"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
return value is suitable for appending to an image spec."
(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))
;; Note: `image-size' looks up and thus caches the untransformed
;; 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)
(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)
"Prompt for an angle ROTATION, and rotate the image by that amount.
ROTATION should be in degrees."
@ -1338,7 +1378,7 @@ ROTATION should be in degrees."
(defun image-transform-reset ()
"Display the current image with the default size and rotation."
(interactive)
(setq image-transform-resize nil
(setq image-transform-resize image-auto-resize
image-transform-rotation 0.0
image-transform-scale 1)
(image-toggle-display-image))