*** 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: