[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: face-remapping-alist client code

From: Drew Adams
Subject: RE: face-remapping-alist client code
Date: Mon, 2 Jun 2008 07:19:34 -0700

> Attached is a small example of code using face-remapping-alist.
> The file ("face-remap.el") contains a small set of utility 
> functions for making cooperative use of face-remapping-alist
> easier, and also contains two example uses:
>  (1) Face size increase/decrease commands (bound to C-= / C-+ 
>      and C--), similar to those in many GUI applications.
>  (2) The `variable-pitch-mode' minor mode, which causes the
>      `variable-pitch' face to be used for displaying the buffer
>      text while active.  [I bind this to `C-c v']
> Comments? [If nobody objects, I'll commit this file too.]
> Here's a newer version that makes the text-scaling stuff into a
> minor-mode.

I don't know if I object, because I won't be building Emacs to try out the face
remapping patch that this needs. I think the general idea of face remapping
sounds OK, however.

I'm not crazy about binding keys for this (just by loading), and those key
bindings in particular. It's OK to suggest bindings in the Commentary, however.

In May of 2004, I believe you proposed something similar. How does this differ?
I seem to recall vaguely that there were some limitations wrt the fonts that
could be resized this way (some available font sizes were skipped, perhaps?). Am
I misremembering?

FWIW, I use the following code to resize the default font by changing its point
size. If your resizing code works as well or better than this does, then yours
would be preferable, since it doesn't twiddle at the font-name level.

(defun enlarge-font (&optional increment frame)
  "Increase size of font in FRAME by INCREMENT.
Interactively, INCREMENT is given by the prefix argument.
Optional FRAME parameter defaults to current frame."
  (interactive "p")
  (setq frame (or frame (selected-frame)))
  (let ((fontname (cdr (assq 'font (frame-parameters frame))))
        (count enlarge-font-tries))
    (setq fontname (enlarged-font-name fontname frame increment))
    (while (and (not (x-list-fonts fontname))
                (wholenump (setq count (1- count))))
      (setq fontname (enlarged-font-name fontname frame increment)))
    (unless (x-list-fonts fontname) (error "Cannot change font size"))
    (modify-frame-parameters frame (list (cons 'font fontname)))
    ;; Update faces that want a bold or italic version of the
    ;; default font.
    (frame-update-faces frame)))

(defun enlarged-font-name (fontname frame increment)
  "FONTNAME, after enlarging font size of FRAME by INCREMENT.
FONTNAME is the font of FRAME."
  (when (query-fontset fontname)
    (let ((ascii (assq 'ascii (aref (fontset-info fontname frame) 2))))
      (when ascii (setq fontname (nth 2 ascii)))))
  (let ((xlfd-fields (x-decompose-font-name fontname)))
    (unless xlfd-fields (error "Cannot decompose font name"))
    (let ((new-size
            (+ (string-to-number
                (aref xlfd-fields xlfd-regexp-pixelsize-subnum))
      (unless (> new-size 0)
        (error "New font size is too small: %s" new-size))
      (aset xlfd-fields xlfd-regexp-pixelsize-subnum
            (number-to-string new-size)))
    ;; Set point size & width to "*", so frame width will adjust
    ;; to new font size
    (aset xlfd-fields xlfd-regexp-pointsize-subnum "*")
    (aset xlfd-fields xlfd-regexp-avgwidth-subnum "*")
    (x-compose-font-name xlfd-fields)))

(defcustom enlarge-font-tries 100
  "Number of times to try to change font size, when looking for a font.
The font-size portion of a font name is incremented or decremented at
most this many times, before giving up and raising an error."
  :type 'integer :group 'Frame-Commands)


Library zoom-frm.el uses the above code to provide convenient font (and frame)
zooming. It binds no keys, but suggests these key bindings:

(define-key global-map [S-mouse-1] 'zoom-frm-in)
(define-key global-map [C-S-mouse-1] 'zoom-frm-out)
;; Get rid of `mouse-set-font':
(define-key global-map [S-down-mouse-1] nil)

Zooming is incremental - just repeat to enlarge/shrink more.

(defun zoom-frm-in (&optional frame flip)
  "Zoom FRAME in by `frame-zoom-font-difference', making text larger.
If `frame-zoom-font-difference' is negative, make text smaller.
With prefix argument FLIP, reverse the direction:
if `frame-zoom-font-difference' is positive, then make text smaller.
This is equal but opposite to `zoom-frm-out'."
  (interactive (list (selected-frame) current-prefix-arg))
  (setq frame (or frame (selected-frame)))
  (let ((zoom-factor (frame-parameter frame 'zoomed))
        (increment (if flip
                       (- frame-zoom-font-difference)
    (unless zoom-factor (setq zoom-factor 0))
    (setq zoom-factor (+ zoom-factor increment))
    (enlarge-font increment frame)
      frame (list (cons 'zoomed zoom-factor)))))

(defun zoom-frm-out (&optional frame flip)
  "Zoom FRAME out by `frame-zoom-font-difference'.
If `frame-zoom-font-difference' is negative, make text larger.
With prefix argument FLIP, reverse the direction:
if `frame-zoom-font-difference' is positive, then make text larger.
This is equal but opposite to `zoom-frm-in'."
  (interactive (list (selected-frame) current-prefix-arg))
  (setq frame (or frame (selected-frame)))
  (let ((frame-zoom-font-difference (- frame-zoom-font-difference)))
    (zoom-frm-in frame flip)))

(defcustom frame-zoom-font-difference 1
  "*Number of points to change the frame font size when zooming.
The absolute value of this must be less than the current font size,
since the new font size cannot be less than 1 point."
  :type 'integer :group 'Frame-Commands)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]