From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Moritz Maxeiner Newsgroups: gmane.emacs.devel Subject: Re: DocView AutoFitting via "doc-view-autofit-mode" Date: Mon, 02 Apr 2012 19:58:45 +0200 Message-ID: <4F79E8D5.8080701@googlemail.com> References: <4F764EBB.5030102@googlemail.com> <87sjgnbxth.fsf@thinkpad.tsdh.de> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------010207080803090006070604" X-Trace: dough.gmane.org 1333389546 29821 80.91.229.3 (2 Apr 2012 17:59:06 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Mon, 2 Apr 2012 17:59:06 +0000 (UTC) Cc: emacs-devel@gnu.org To: Tassilo Horn Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Apr 02 19:59:05 2012 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 1SElWw-0003WF-26 for ged-emacs-devel@m.gmane.org; Mon, 02 Apr 2012 19:59:02 +0200 Original-Received: from localhost ([::1]:45384 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SElWv-0002XP-FQ for ged-emacs-devel@m.gmane.org; Mon, 02 Apr 2012 13:59:01 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:38181) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SElWp-0002Wz-43 for emacs-devel@gnu.org; Mon, 02 Apr 2012 13:58:58 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SElWl-0005i1-Hw for emacs-devel@gnu.org; Mon, 02 Apr 2012 13:58:54 -0400 Original-Received: from mail-bk0-f41.google.com ([209.85.214.41]:58579) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SElWk-0005hv-Um for emacs-devel@gnu.org; Mon, 02 Apr 2012 13:58:51 -0400 Original-Received: by bkwq16 with SMTP id q16so3035652bkw.0 for ; Mon, 02 Apr 2012 10:58:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type; bh=u4+bnqCqyQPADZ5d+hIHQZM0tPkvv+9bWzjpBTUCFmU=; b=TstcrOUewPJMvFNQ3HmkNoN1oFt4fMAnHtT8+di+/brBuLrRmNeJFvkXzlj2k4iAWw 83qtjbkjd+XYEXWZau0pG1Lw61eWsVL+mr/rf4wic/uBFy4ov7PFfnfK1UcO7Kjn+gGi TMf50S/Vhq9VQqTCE1cx7r9BMM/hI++y4j+O7e4/NPkj5VNVT4sQKGTs57T/BY5dxTkP eP32DvZU7LRhGoWiYdeJPHLmL4Cc7wDQr+QuNIlwHs49H0ESwJAmy5TIF58vYzhB0WdM 1mAWV2fmen7/tT54LSYlPo35kX8OYVLqRvv+/qj8FAUuZWCyGxfSiSWxiXy7awcqetzk 4FiA== Original-Received: by 10.204.156.2 with SMTP id u2mr4146599bkw.101.1333389527684; Mon, 02 Apr 2012 10:58:47 -0700 (PDT) Original-Received: from [192.168.2.117] (p5DDB3F9A.dip.t-dialin.net. [93.219.63.154]) by mx.google.com with ESMTPS id cy11sm14319372bkb.7.2012.04.02.10.58.45 (version=SSLv3 cipher=OTHER); Mon, 02 Apr 2012 10:58:46 -0700 (PDT) User-Agent: Mozilla/5.0 (X11; Linux i686; rv:11.0) Gecko/20120314 Thunderbird/11.0 In-Reply-To: <87sjgnbxth.fsf@thinkpad.tsdh.de> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.214.41 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:149296 Archived-At: This is a multi-part message in MIME format. --------------010207080803090006070604 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hi, so I updated a few things: > `C-1 W' enables width > autofitting. Done, see the added paragraph in the description, in short, either sets the type and if off turns on autofitting, or if on and type is already sets turn off autofitting, e.g. `C-1 W' `C-1 W' turns on autofitting and sets it to width and then turns it off again. > so you could just enable lexical binding for the complete > file and use just `let' It is already enabled (bzr trunk), I just didn't see it. Strangely enough, using `lexical-let' inside a lexical binding enabled file produces tons of "bad lexing" errors when used with named functions (It doesn't in lexica-binding disabled files). e.g. this will produce a [bad-lexical-ref] on `M-x eval-buffer RET' `M-x bar RET', but not when the file header (which enables lexical-binding) is removed. So far reading the information about lexical-binding in emacs has not let me to an understanding why, but meh. ;;; foo.el --- Foo -*- lexical-binding: t -*- (defun foo (window) (message "%s" window)) (defun bar () (interactive) (lexical-let ((foobar (selected-window))) (foo foobar))) Which is why I made the part you comment on here > make that lambda a named function a lambda instead of a named function in the first place (With a lambda is works both with lexical-binding enabled and not, but not with a named function). Well, it's let now instead of lexical-let since lexical-binding is enabled for doc-view anyway. > Compare symbols with `eq' Done, but any specific reason for that? `equal's doc-string states that symbols must match exactly, so in the specific event of symbols, don't equal and eq behave the same? > Why 2 whens instead of one if? 'cause one alternative of the if has to use progn anyway and at the time I had just copy-pasted the first and altered it to match. Changed to if now. If I missed anything you suggested or someone has more suggestions to better the minor mode please do say so. Bye, cal [Description] This is a minor mode allowing documents viewed with DocView to be automaticly refitted to the window they are shown in (no need to hit W/H/P every time the window size changes). Mode function is `doc-view-autofit-mode' and doc-view-fit-[width/height/page]-to-window have been modified for a prefix argument, which if is non-nil and numeric value 1 does (type refers to the part in brackets): 1. If autofit mode is off, turn it on with this type 2. If autofit is on and already set to this type: Turn autofit off 3. If autofit is on and not set to this type: Set it to this type It is implemented by adding a local hook to window-configuration-change-hook for the buffer the document is in, which in turn either starts or increases - if already started - a buffer local timer every time the hook is called. When the timer runs out, it calls doc-view-fit-[width/height/page]-to-window according to a buffer local variable. The timer is used, so that when the hook triggers a lot in a short period of time it doesn't cause too much overhead (Useful for slower computers). [ChangeLog] * doc-view.el (doc-view-fit-check-prefix doc-view-fit-width-to-window) (doc-view-fit-height-to-window doc-view-fit-page-to-window) (doc-view-autofit-timer-start doc-view-autofit-timer-inc) (doc-view-autofit-default-fit doc-view-autofit-timer-function) doc-view-fit-height-to-window (doc-view-autofit-fit doc-view-autofit-mode): New minor mode with customs and functions for automatic fitting in DocView buffers; also added prefix argument handling to doc-view-fit-*-to-window for setting the autofitting type easily. [Patch] *** doc-view.el 2012-04-02 18:49:03.380742235 +0200 --- doc-view.el 2012-04-02 19:09:03.163769708 +0200 *************** OpenDocument format)." *** 676,752 **** (interactive (list doc-view-shrink-factor)) (doc-view-enlarge (/ 1.0 factor))) ! (defun doc-view-fit-width-to-window () ! "Fit the image width to the window width." ! (interactive) ! (let ((win-width (- (nth 2 (window-inside-pixel-edges)) ! (nth 0 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-width (car (image-display-size ! (image-get-display-property) t)))) ! (doc-view-enlarge (/ (float win-width) (float img-width)))) ! ! ;; If slice is set ! (let* ((slice-width (nth 2 slice)) ! (scale-factor (/ (float win-width) (float slice-width))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page)))))) ! ! (defun doc-view-fit-height-to-window () ! "Fit the image height to the window height." ! (interactive) ! (let ((win-height (- (nth 3 (window-inside-pixel-edges)) ! (nth 1 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-height (cdr (image-display-size ! (image-get-display-property) t)))) ! ;; When users call 'doc-view-fit-height-to-window', ! ;; they might want to go to next page by typing SPC ! ;; ONLY once. So I used '(- win-height 1)' instead of ! ;; 'win-height' ! (doc-view-enlarge (/ (float (- win-height 1)) (float img-height)))) ! ! ;; If slice is set ! (let* ((slice-height (nth 3 slice)) ! (scale-factor (/ (float (- win-height 1)) (float slice-height))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page)))))) ! ! (defun doc-view-fit-page-to-window () ! "Fit the image to the window. More specifically, this function enlarges image by: min {(window-width / image-width), (window-height / image-height)} times." ! (interactive) ! (let ((win-width (- (nth 2 (window-inside-pixel-edges)) ! (nth 0 (window-inside-pixel-edges)))) ! (win-height (- (nth 3 (window-inside-pixel-edges)) ! (nth 1 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-width (car (image-display-size ! (image-get-display-property) t))) ! (img-height (cdr (image-display-size ! (image-get-display-property) t)))) ! (doc-view-enlarge (min (/ (float win-width) (float img-width)) ! (/ (float (- win-height 1)) (float img-height))))) ! ;; If slice is set ! (let* ((slice-width (nth 2 slice)) ! (slice-height (nth 3 slice)) ! (scale-factor (min (/ (float win-width) (float slice-width)) ! (/ (float (- win-height 1)) (float slice-height)))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page)))))) (defun doc-view-reconvert-doc () "Reconvert the current document. --- 676,773 ---- (interactive (list doc-view-shrink-factor)) (doc-view-enlarge (/ 1.0 factor))) ! (defun doc-view-fit-check-prefix (arg type) ! "Called by `doc-view-fit-width-to-window', `doc-view-fit-height-to-window' ! and `doc-view-fit-page-to-window' to determine if a prefix argument ! was used and call the appropriate function for each value. ! ! Numeric value 1: Handle automatic fitting" ! (if (and arg ! (= (prefix-numeric-value arg) 1)) ! (if doc-view-autofit-mode ! (if (eq type doc-view-autofit-type) ! (doc-view-autofit-mode 'toggle) ! (setq doc-view-autofit-type type) t) ! (set (make-local-variable 'doc-view-autofit-type) type) ! (doc-view-autofit-mode) nil) t)) ! ! (defun doc-view-fit-width-to-window (arg) ! "Fit the image width to the window width (Non-nil prefix argument ! with numeric value 1 enables doing this automaticly)." ! (interactive "P") ! (when (doc-view-fit-check-prefix arg 'width) ! (let ((win-width (- (nth 2 (window-inside-pixel-edges)) ! (nth 0 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-width (car (image-display-size ! (image-get-display-property) t)))) ! (doc-view-enlarge (/ (float win-width) (float img-width)))) ! ! ;; If slice is set ! (let* ((slice-width (nth 2 slice)) ! (scale-factor (/ (float win-width) (float slice-width))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page))))))) ! ! (defun doc-view-fit-height-to-window (arg) ! "Fit the image height to the window height (Non-nil prefix argument ! with numeric value 1 enables doing this automaticly)." ! (interactive "P") ! (when (doc-view-fit-check-prefix arg 'height) ! (let ((win-height (- (nth 3 (window-inside-pixel-edges)) ! (nth 1 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-height (cdr (image-display-size ! (image-get-display-property) t)))) ! ;; When users call 'doc-view-fit-height-to-window', ! ;; they might want to go to next page by typing SPC ! ;; ONLY once. So I used '(- win-height 1)' instead of ! ;; 'win-height' ! (doc-view-enlarge (/ (float (- win-height 1)) (float img-height)))) ! ! ;; If slice is set ! (let* ((slice-height (nth 3 slice)) ! (scale-factor (/ (float (- win-height 1)) (float slice-height))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page))))))) ! ! (defun doc-view-fit-page-to-window (arg) ! "Fit the image to the window (Non-nil prefix argument ! with numeric value 1 enables doing this automaticly). More specifically, this function enlarges image by: min {(window-width / image-width), (window-height / image-height)} times." ! (interactive "P") ! (when (doc-view-fit-check-prefix arg 'page) ! (let ((win-width (- (nth 2 (window-inside-pixel-edges)) ! (nth 0 (window-inside-pixel-edges)))) ! (win-height (- (nth 3 (window-inside-pixel-edges)) ! (nth 1 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-width (car (image-display-size ! (image-get-display-property) t))) ! (img-height (cdr (image-display-size ! (image-get-display-property) t)))) ! (doc-view-enlarge (min (/ (float win-width) (float img-width)) ! (/ (float (- win-height 1)) (float img-height))))) ! ;; If slice is set ! (let* ((slice-width (nth 2 slice)) ! (slice-height (nth 3 slice)) ! (scale-factor (min (/ (float win-width) (float slice-width)) ! (/ (float (- win-height 1)) (float slice-height)))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page))))))) (defun doc-view-reconvert-doc () "Reconvert the current document. *************** See the command `doc-view-mode' for more *** 1557,1562 **** --- 1578,1654 ---- (doc-view-goto-page page))))) + ;;;; Automatic fitting minor mode + + (defcustom doc-view-autofit-timer-start 1.0 + "Initial value (seconds) for the timer that delays the fitting when + `doc-view-autofit-fit' is called (Which is when a window + configuration change occurs and a document needs to be fitted)." + :type 'number + :group 'doc-view) + + (defcustom doc-view-autofit-timer-inc 0.02 + "Value to increase (seconds) the timer (see `doc-view-autofit-timer-start') + by, if there is another window configuration change occuring, before + it runs out." + :type 'number + :group 'doc-view) + + (defcustom doc-view-autofit-default-fit 'width + "The fitting type initially used when mode is enabled. + Valid values are: width, height, page." + :type 'symbol + :group 'doc-view) + + (defun doc-view-autofit-timer-function (window) + "The timer function used in `doc-view-autofit-fit' to be called delayed. + It expects `doc-view-autofit-timer' and `doc-view-autofit-type' to be + set to valid values." + (if (window-live-p window) + (save-selected-window + (select-window window) + (cancel-timer doc-view-autofit-timer) + (setq doc-view-autofit-timer nil) + (cond + ((eq 'width doc-view-autofit-type) + (doc-view-fit-width-to-window nil)) + ((eq 'height doc-view-autofit-type) + (doc-view-fit-height-to-window nil)) + ((eq 'page doc-view-autofit-type) + (doc-view-fit-page-to-window nil)))))) + + (defun doc-view-autofit-fit () + "Fits the document in the selected window's buffer + delayed withdoc-view-autofit a timer, so multiple calls in succession + don't cause as much overhead." + (let ((window (selected-window))) + (if doc-view-autofit-timer + (timer-inc-time doc-view-autofit-timer doc-view-autofit-timer-inc) + (setq doc-view-autofit-timer + (run-with-timer doc-view-autofit-timer-start nil + 'doc-view-autofit-timer-function window))))) + + (define-minor-mode doc-view-autofit-mode + "Minor mode for automatic (timer based) fitting in DocView." + :lighter " AFit" :group 'doc-view + (if doc-view-autofit-mode + (progn (if (or (not (boundp 'doc-view-autofit-type)) + (not doc-view-autofit-type)) + (set (make-local-variable 'doc-view-autofit-type) + doc-view-autofit-default-fit)) + (set (make-local-variable 'doc-view-autofit-timer) nil) + (add-hook 'window-configuration-change-hook + 'doc-view-autofit-fit nil t) + (doc-view-autofit-fit)) + (remove-hook 'window-configuration-change-hook + 'doc-view-autofit-fit t) + (when doc-view-autofit-timer + (cancel-timer doc-view-autofit-timer) + (setq doc-view-autofit-timer nil)) + (setq doc-view-autofit-type nil)) + doc-view-autofit-mode) + + (provide 'doc-view) ;; Local Variables: --------------010207080803090006070604 Content-Type: text/x-patch; name="doc-view-autofit.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="doc-view-autofit.patch" *** doc-view.el 2012-04-02 18:49:03.380742235 +0200 --- doc-view.el 2012-04-02 19:09:03.163769708 +0200 *************** OpenDocument format)." *** 676,752 **** (interactive (list doc-view-shrink-factor)) (doc-view-enlarge (/ 1.0 factor))) ! (defun doc-view-fit-width-to-window () ! "Fit the image width to the window width." ! (interactive) ! (let ((win-width (- (nth 2 (window-inside-pixel-edges)) ! (nth 0 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-width (car (image-display-size ! (image-get-display-property) t)))) ! (doc-view-enlarge (/ (float win-width) (float img-width)))) ! ! ;; If slice is set ! (let* ((slice-width (nth 2 slice)) ! (scale-factor (/ (float win-width) (float slice-width))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page)))))) ! ! (defun doc-view-fit-height-to-window () ! "Fit the image height to the window height." ! (interactive) ! (let ((win-height (- (nth 3 (window-inside-pixel-edges)) ! (nth 1 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-height (cdr (image-display-size ! (image-get-display-property) t)))) ! ;; When users call 'doc-view-fit-height-to-window', ! ;; they might want to go to next page by typing SPC ! ;; ONLY once. So I used '(- win-height 1)' instead of ! ;; 'win-height' ! (doc-view-enlarge (/ (float (- win-height 1)) (float img-height)))) ! ! ;; If slice is set ! (let* ((slice-height (nth 3 slice)) ! (scale-factor (/ (float (- win-height 1)) (float slice-height))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page)))))) ! ! (defun doc-view-fit-page-to-window () ! "Fit the image to the window. More specifically, this function enlarges image by: min {(window-width / image-width), (window-height / image-height)} times." ! (interactive) ! (let ((win-width (- (nth 2 (window-inside-pixel-edges)) ! (nth 0 (window-inside-pixel-edges)))) ! (win-height (- (nth 3 (window-inside-pixel-edges)) ! (nth 1 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-width (car (image-display-size ! (image-get-display-property) t))) ! (img-height (cdr (image-display-size ! (image-get-display-property) t)))) ! (doc-view-enlarge (min (/ (float win-width) (float img-width)) ! (/ (float (- win-height 1)) (float img-height))))) ! ;; If slice is set ! (let* ((slice-width (nth 2 slice)) ! (slice-height (nth 3 slice)) ! (scale-factor (min (/ (float win-width) (float slice-width)) ! (/ (float (- win-height 1)) (float slice-height)))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page)))))) (defun doc-view-reconvert-doc () "Reconvert the current document. --- 676,773 ---- (interactive (list doc-view-shrink-factor)) (doc-view-enlarge (/ 1.0 factor))) ! (defun doc-view-fit-check-prefix (arg type) ! "Called by `doc-view-fit-width-to-window', `doc-view-fit-height-to-window' ! and `doc-view-fit-page-to-window' to determine if a prefix argument ! was used and call the appropriate function for each value. ! ! Numeric value 1: Handle automatic fitting" ! (if (and arg ! (= (prefix-numeric-value arg) 1)) ! (if doc-view-autofit-mode ! (if (eq type doc-view-autofit-type) ! (doc-view-autofit-mode 'toggle) ! (setq doc-view-autofit-type type) t) ! (set (make-local-variable 'doc-view-autofit-type) type) ! (doc-view-autofit-mode) nil) t)) ! ! (defun doc-view-fit-width-to-window (arg) ! "Fit the image width to the window width (Non-nil prefix argument ! with numeric value 1 enables doing this automaticly)." ! (interactive "P") ! (when (doc-view-fit-check-prefix arg 'width) ! (let ((win-width (- (nth 2 (window-inside-pixel-edges)) ! (nth 0 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-width (car (image-display-size ! (image-get-display-property) t)))) ! (doc-view-enlarge (/ (float win-width) (float img-width)))) ! ! ;; If slice is set ! (let* ((slice-width (nth 2 slice)) ! (scale-factor (/ (float win-width) (float slice-width))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page))))))) ! ! (defun doc-view-fit-height-to-window (arg) ! "Fit the image height to the window height (Non-nil prefix argument ! with numeric value 1 enables doing this automaticly)." ! (interactive "P") ! (when (doc-view-fit-check-prefix arg 'height) ! (let ((win-height (- (nth 3 (window-inside-pixel-edges)) ! (nth 1 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-height (cdr (image-display-size ! (image-get-display-property) t)))) ! ;; When users call 'doc-view-fit-height-to-window', ! ;; they might want to go to next page by typing SPC ! ;; ONLY once. So I used '(- win-height 1)' instead of ! ;; 'win-height' ! (doc-view-enlarge (/ (float (- win-height 1)) (float img-height)))) ! ! ;; If slice is set ! (let* ((slice-height (nth 3 slice)) ! (scale-factor (/ (float (- win-height 1)) (float slice-height))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page))))))) ! ! (defun doc-view-fit-page-to-window (arg) ! "Fit the image to the window (Non-nil prefix argument ! with numeric value 1 enables doing this automaticly). More specifically, this function enlarges image by: min {(window-width / image-width), (window-height / image-height)} times." ! (interactive "P") ! (when (doc-view-fit-check-prefix arg 'page) ! (let ((win-width (- (nth 2 (window-inside-pixel-edges)) ! (nth 0 (window-inside-pixel-edges)))) ! (win-height (- (nth 3 (window-inside-pixel-edges)) ! (nth 1 (window-inside-pixel-edges)))) ! (slice (doc-view-current-slice))) ! (if (not slice) ! (let ((img-width (car (image-display-size ! (image-get-display-property) t))) ! (img-height (cdr (image-display-size ! (image-get-display-property) t)))) ! (doc-view-enlarge (min (/ (float win-width) (float img-width)) ! (/ (float (- win-height 1)) (float img-height))))) ! ;; If slice is set ! (let* ((slice-width (nth 2 slice)) ! (slice-height (nth 3 slice)) ! (scale-factor (min (/ (float win-width) (float slice-width)) ! (/ (float (- win-height 1)) (float slice-height)))) ! (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) ! (doc-view-enlarge scale-factor) ! (setf (doc-view-current-slice) new-slice) ! (doc-view-goto-page (doc-view-current-page))))))) (defun doc-view-reconvert-doc () "Reconvert the current document. *************** See the command `doc-view-mode' for more *** 1557,1562 **** --- 1578,1654 ---- (doc-view-goto-page page))))) + ;;;; Automatic fitting minor mode + + (defcustom doc-view-autofit-timer-start 1.0 + "Initial value (seconds) for the timer that delays the fitting when + `doc-view-autofit-fit' is called (Which is when a window + configuration change occurs and a document needs to be fitted)." + :type 'number + :group 'doc-view) + + (defcustom doc-view-autofit-timer-inc 0.02 + "Value to increase (seconds) the timer (see `doc-view-autofit-timer-start') + by, if there is another window configuration change occuring, before + it runs out." + :type 'number + :group 'doc-view) + + (defcustom doc-view-autofit-default-fit 'width + "The fitting type initially used when mode is enabled. + Valid values are: width, height, page." + :type 'symbol + :group 'doc-view) + + (defun doc-view-autofit-timer-function (window) + "The timer function used in `doc-view-autofit-fit' to be called delayed. + It expects `doc-view-autofit-timer' and `doc-view-autofit-type' to be + set to valid values." + (if (window-live-p window) + (save-selected-window + (select-window window) + (cancel-timer doc-view-autofit-timer) + (setq doc-view-autofit-timer nil) + (cond + ((eq 'width doc-view-autofit-type) + (doc-view-fit-width-to-window nil)) + ((eq 'height doc-view-autofit-type) + (doc-view-fit-height-to-window nil)) + ((eq 'page doc-view-autofit-type) + (doc-view-fit-page-to-window nil)))))) + + (defun doc-view-autofit-fit () + "Fits the document in the selected window's buffer + delayed withdoc-view-autofit a timer, so multiple calls in succession + don't cause as much overhead." + (let ((window (selected-window))) + (if doc-view-autofit-timer + (timer-inc-time doc-view-autofit-timer doc-view-autofit-timer-inc) + (setq doc-view-autofit-timer + (run-with-timer doc-view-autofit-timer-start nil + 'doc-view-autofit-timer-function window))))) + + (define-minor-mode doc-view-autofit-mode + "Minor mode for automatic (timer based) fitting in DocView." + :lighter " AFit" :group 'doc-view + (if doc-view-autofit-mode + (progn (if (or (not (boundp 'doc-view-autofit-type)) + (not doc-view-autofit-type)) + (set (make-local-variable 'doc-view-autofit-type) + doc-view-autofit-default-fit)) + (set (make-local-variable 'doc-view-autofit-timer) nil) + (add-hook 'window-configuration-change-hook + 'doc-view-autofit-fit nil t) + (doc-view-autofit-fit)) + (remove-hook 'window-configuration-change-hook + 'doc-view-autofit-fit t) + (when doc-view-autofit-timer + (cancel-timer doc-view-autofit-timer) + (setq doc-view-autofit-timer nil)) + (setq doc-view-autofit-type nil)) + doc-view-autofit-mode) + + (provide 'doc-view) ;; Local Variables: --------------010207080803090006070604--