diff options
Diffstat (limited to 'lisp/image.el')
-rw-r--r-- | lisp/image.el | 80 |
1 files changed, 66 insertions, 14 deletions
diff --git a/lisp/image.el b/lisp/image.el index 6955a90de77..494c26a8a33 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -141,6 +141,18 @@ based on the font pixel size." (const :tag "Automatically compute" auto)) :version "26.1") +(defcustom image-transform-smoothing #'image--default-smoothing + "Whether to do smoothing when applying transforms to images. +Common transforms are rescaling and rotation. + +Valid values are nil (no smoothing), t (smoothing) or a predicate +function that is called with the image specification and should return +either nil or non-nil." + :type '(choice (const :tag "Do smoothing" t) + (const :tag "No smoothing" nil) + function) + :version "28.1") + (defcustom image-use-external-converter nil "If non-nil, `create-image' will use external converters for exotic formats. Emacs handles most of the common image formats (SVG, JPEG, PNG, GIF @@ -485,11 +497,40 @@ Image file names that are not absolute are searched for in the type 'png data-p t))) (when (image-type-available-p type) - (append (list 'image :type type (if data-p :data :file) file-or-data) - (and (not (plist-get props :scale)) - (list :scale - (image-compute-scaling-factor image-scaling-factor))) - props))) + (let ((image + (append (list 'image :type type (if data-p :data :file) + file-or-data) + (and (not (plist-get props :scale)) + ;; Add default scaling. + (list :scale + (image-compute-scaling-factor + image-scaling-factor))) + props))) + ;; Add default smoothing. + (unless (plist-member props :transform-smoothing) + (setq image (nconc image + (list :transform-smoothing + (pcase image-transform-smoothing + ('t t) + ('nil nil) + (func (funcall func image))))))) + image))) + +(defun image--default-smoothing (image) + "Say whether IMAGE should be smoothed when transformed." + (let* ((props (nthcdr 5 image)) + (scaling (plist-get props :scale)) + (rotation (plist-get props :rotation))) + (cond + ;; We always smooth when scaling down and small upwards scaling. + ((and scaling (< scaling 2)) + t) + ;; Smooth when doing non-90-degree rotation + ((and rotation + (or (not (zerop (mod rotation 1))) + (not (zerop (% (truncate rotation) 90))))) + t) + (t nil)))) (defun image--set-property (image property value) "Set PROPERTY in IMAGE to VALUE. @@ -562,12 +603,16 @@ means display it in the right marginal area." (defun insert-image (image &optional string area slice) "Insert IMAGE into current buffer at point. IMAGE is displayed by inserting STRING into the current buffer -with a `display' property whose value is the image. STRING -defaults to a single space if you omit it. +with a `display' property whose value is the image. + +STRING defaults to a single space if you omit it, which means +that the inserted image will behave as whitespace syntactically. + AREA is where to display the image. AREA nil or omitted means display it in the text area, a value of `left-margin' means display it in the left marginal area, a value of `right-margin' means display it in the right marginal area. + SLICE specifies slice of IMAGE to insert. SLICE nil or omitted means insert whole image. SLICE is a list (X Y WIDTH HEIGHT) specifying the X and Y positions and WIDTH and HEIGHT of image area @@ -794,6 +839,9 @@ number, play until that number of seconds has elapsed." (cancel-timer timer)) (plist-put (cdr image) :animate-buffer (current-buffer)) (plist-put (cdr image) :animate-tardiness 0) + ;; Stash the data about the animation here so that we don't + ;; trigger image recomputation unnecessarily later. + (plist-put (cdr image) :animate-multi-frame-data animation) (run-with-timer 0.2 nil #'image-animate-timeout image (or index 0) (car animation) 0 limit (+ (float-time) 0.2))))) @@ -824,9 +872,10 @@ 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 (image-multi-frame-p image))))))) + (setq n (min n (1- (car (plist-get (cdr image) + :animate-multi-frame-data))))))) (plist-put (cdr image) :index n) - (force-window-update)) + (force-window-update (plist-get (cdr image) :animate-buffer))) (defun image-animate-get-speed (image) "Return the speed factor for animating IMAGE." @@ -872,11 +921,11 @@ for the animation speed. A negative value means to animate in reverse." (image-show-frame image n t) (let* ((speed (image-animate-get-speed image)) (time (current-time)) - (animation (image-multi-frame-p image)) (time-to-load-image (time-since time)) - (stated-delay-time (/ (or (cdr animation) - image-default-frame-delay) - (float (abs speed)))) + (stated-delay-time + (/ (or (cdr (plist-get (cdr image) :animate-multi-frame-data)) + image-default-frame-delay) + (float (abs speed)))) ;; Subtract off the time we took to load the image from the ;; stated delay time. (delay (max (float-time (time-subtract stated-delay-time @@ -1089,6 +1138,7 @@ default is 20%." image)) (defun image--get-imagemagick-and-warn (&optional position) + (declare-function image-transforms-p "image.c" (&optional frame)) (unless (or (fboundp 'imagemagick-types) (image-transforms-p)) (error "Cannot rescale images on this terminal")) (let ((image (image--get-image position))) @@ -1141,7 +1191,9 @@ rotations by only multiples of 90 degrees." 360))))) (defun image-save () - "Save the image under point." + "Save the image under point. +This writes the original image data to a file. Rotating or +changing the displayed image size does not affect the saved image." (interactive) (let ((image (image--get-image))) (with-temp-buffer |