From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Greg Minshall Newsgroups: gmane.emacs.devel Subject: Re: unsolicited patch to image-mode.el -- "fit to window" Date: Thu, 23 Jul 2015 20:52:33 +0300 Message-ID: <37018.1437673953@greg-minshalls-mbp.local> References: NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1437675302 14927 80.91.229.3 (23 Jul 2015 18:15:02 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 23 Jul 2015 18:15:02 +0000 (UTC) To: emacs-devel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Jul 23 20:14:53 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1ZIL1A-00018k-SS for ged-emacs-devel@m.gmane.org; Thu, 23 Jul 2015 20:14:53 +0200 Original-Received: from localhost ([::1]:42398 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZIL19-00007f-Sz for ged-emacs-devel@m.gmane.org; Thu, 23 Jul 2015 14:14:51 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:50596) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZIL0x-00007C-A7 for emacs-devel@gnu.org; Thu, 23 Jul 2015 14:14:40 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZIL0s-00043n-Ac for emacs-devel@gnu.org; Thu, 23 Jul 2015 14:14:39 -0400 Original-Received: from relay00.pair.com ([209.68.5.9]:4113) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1ZIL0s-00042a-39 for emacs-devel@gnu.org; Thu, 23 Jul 2015 14:14:34 -0400 Original-Received: (qmail 79930 invoked by uid 0); 23 Jul 2015 18:14:27 -0000 Original-Received: from 178.240.234.166 (HELO gregair.cliq.com) (178.240.234.166) by relay00.pair.com with SMTP; 23 Jul 2015 18:14:27 -0000 X-pair-Authenticated: 178.240.234.166 Original-Received: from greg-minshalls-mbp.local (localhost [127.0.0.1]) by gregair.cliq.com (Postfix) with ESMTP id 3E0CE9069D5B for ; Thu, 23 Jul 2015 20:52:34 +0300 (EEST) In-reply-to: Your message of "Tue, 14 Jul 2015 19:23:15 -0400." X-Mailer: MH-E 8.5; nmh 1.5; GNU Emacs 24.5.50 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.68.5.9 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:188037 Archived-At: sorry again for the defective patch. below is a reformed patch that, after more testing, appears to work. again, this patch adds a 'fit-window option to the Image menu when viewing images, which resizes the image (maintaining its aspect ratio) to fit within both the height and width of the containing window. i've filled out and submitted GNU paperwork. please let me know if the paperwork has, or if the patch retains, deficiencies. cheers, Greg Minshall ---- diff --git a/lisp/image-mode.el b/lisp/image-mode.el index 2ed7fbe..6377699 100644 --- a/lisp/image-mode.el +++ b/lisp/image-mode.el @@ -385,6 +385,9 @@ call." ["Fit to Window Width" image-transform-fit-to-width :visible (eq image-type 'imagemagick) :help "Resize image to match the window width"] + ["Fit to Window" image-transform-fit-to-window + :visible (eq image-type 'imagemagick) + :help "Resize image to fit in the window"] ["Rotate Image..." image-transform-set-rotation :visible (eq image-type 'imagemagick) :help "Rotate the image"] @@ -895,6 +898,7 @@ Its value should be one of the following: - nil, meaning no resizing. - `fit-height', meaning to fit the image to the window height. - `fit-width', meaning to fit the image to the window width. + - `fit-window', meaning to fit the image to the window. - A number, which is a scale factor (the default size is 1).") (defvar image-transform-scale 1.0 @@ -952,6 +956,9 @@ a slightly different angle. Currently this is done for values close to a multiple of 90, see `image-transform-right-angle-fudge'." (cond ((< (abs (- (mod (+ image-transform-rotation 90) 180) 90)) image-transform-right-angle-fudge) + ;; in this case, there is either no rotation (close to zero) + ;; or a 180 degree rotation. in either case, the width of + ;; the image's post-rotation bounding box doesn't change. (cl-assert (not (zerop width)) t) (setq image-transform-rotation (float (round image-transform-rotation)) @@ -959,6 +966,9 @@ close to a multiple of 90, see `image-transform-right-angle-fudge'." (cons length nil)) ((< (abs (- (mod (+ image-transform-rotation 45) 90) 45)) image-transform-right-angle-fudge) + ;; in this case, the rotation is 90 or 270 degrees, i.e., the + ;; width and height of the image are flipped. so, we use the + ;; image height as the new image width. (cl-assert (not (zerop height)) t) (setq image-transform-rotation (float (round image-transform-rotation)) @@ -1007,17 +1017,18 @@ of a rotated image." (when (and (not (numberp image-transform-resize)) (boundp 'image-type) (eq image-type 'imagemagick)) - (let ((size (image-display-size (image-get-display-property) t))) - (cond ((eq image-transform-resize 'fit-width) - (cl-assert (= (car size) - (- (nth 2 (window-inside-pixel-edges)) + (let ((size (image-display-size (image-get-display-property) t)) + (width (- (nth 2 (window-inside-pixel-edges)) (nth 0 (window-inside-pixel-edges)))) - t)) + (height (- (nth 3 (window-inside-pixel-edges)) + (nth 1 (window-inside-pixel-edges))))) + (cond ((eq image-transform-resize 'fit-width) + (cl-assert (= (car size) width) t)) ((eq image-transform-resize 'fit-height) - (cl-assert (= (cdr size) - (- (nth 3 (window-inside-pixel-edges)) - (nth 1 (window-inside-pixel-edges)))) - t)))))) + (cl-assert (= (cdr size) height) t) ) + ((eq image-transform-resize 'fit-window) + (cl-assert (or (= (car size) width) + (= (cdr size) height)) t)))))) (defun image-transform-properties (spec) "Return rescaling/rotation properties for image SPEC. @@ -1032,24 +1043,38 @@ compiled with ImageMagick support." (/= image-transform-rotation 0.0)) ;; Note: `image-size' looks up and thus caches the untransformed ;; image. There's no easy way to prevent that. - (let* ((size (image-size spec t)) + (let* ((isize (image-size spec t)) ; (car isize) == width; + ; (cdr isize) == height + (wpixels (window-inside-pixel-edges)) + (wsize (cons (- (nth 2 wpixels) (nth 0 wpixels)) + (- (nth 3 wpixels) (nth 1 wpixels)))) ; ditto + (ifwidth (lambda () + (image-transform-fit-width + (car isize) (cdr isize) (car wsize)))) + (ifheight (lambda () + (let ((res (image-transform-fit-width + (cdr isize) (car isize) (cdr wsize)))) + (cons (cdr res) (car res))))) + (ifwindow (lambda () + ;; is the constraint the *width* or the *height* of the + ;; image? we can tell this by comparing the *aspect* + ;; ratio of the image with that of the window + (if (>= (/ (float (car isize)) (cdr isize)) + (/ (float (car wsize)) (cdr wsize))) + (funcall ifwidth) + (funcall ifheight)))) (resized (cond ((numberp image-transform-resize) (unless (= image-transform-resize 1) (setq image-transform-scale image-transform-resize) - (cons nil (floor (* image-transform-resize (cdr size)))))) + (cons nil (floor (* image-transform-resize (cdr isize)))))) ((eq image-transform-resize 'fit-width) - (image-transform-fit-width - (car size) (cdr size) - (- (nth 2 (window-inside-pixel-edges)) - (nth 0 (window-inside-pixel-edges))))) + (funcall ifwidth)) ((eq image-transform-resize 'fit-height) - (let ((res (image-transform-fit-width - (cdr size) (car size) - (- (nth 3 (window-inside-pixel-edges)) - (nth 1 (window-inside-pixel-edges)))))) - (cons (cdr res) (car res))))))) + (funcall ifheight)) + ((eq image-transform-resize 'fit-window) + (funcall ifwindow))))) `(,@(when (car resized) (list :width (car resized))) ,@(when (cdr resized) @@ -1081,6 +1106,14 @@ ImageMagick support." (setq image-transform-resize 'fit-width) (image-toggle-display-image)) +(defun image-transform-fit-to-window () + "Fit the current image to the width of the current window. +This command has no effect unless Emacs is compiled with +ImageMagick support." + (interactive) + (setq image-transform-resize 'fit-window) + (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. This command has no effect unless