Subject: bug#14233: 24.3; Don't constrain frame size to character multiples

From: "Drew Adams" <[email-masked]>
Date: Sat, 27 Apr 2013 06:53:11 -0700

>  > I have code that relies on this behavior to shrink not 
>  > only the default font size (of all windows in the frame)
>  > but the frame itself.  I do this not only to zoom
>  > (shrink or enlarge) a frame and its text slightly.  I do
>  > it also to shrink it a lot - down to a thumbnail/icon size
>  > - and later restore it.
>  >
>  > I would not like to see this behavior change, so that, 
>  > e.g., Emacs stopped resizing the frame when I change the
>  > font size for the frame.
> 
> It depends on the interface you use.

Already that does not sound very good.  Why should the behavior be different
depending on how you change a frame parameter?

> The function `set-frame-font' has the KEEP-SIZE argument
> and I don't intend to change its semantics (I'll probably
> remove the rounding when `frame-resize-pixelwise' is non-nil).

I use `modify-frame-parameters', providing a new value for parameter `font'.
The new value is calculated this way (in frame-cmds.el):

(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))
                       increment)))
      (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)))

This is the function that uses that new value:

(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 default.
    (when (< emacs-major-version 21) (frame-update-faces frame))))

I use this code a lot: in doremi-frm.el to enlarge/shrink incrementally; in
zoom-frm.el to do likewise, but differently; in thumb-frm.el to (de)thumbify.

I really hope this will not be broken by whatever changes you envision.  Thx.

The code is here:
http://www.emacswiki.org/emacs-en/download/frame-cmds.el
http://www.emacswiki.org/emacs-en/download/zoom-frm.el
http://www.emacswiki.org/emacs-en/download/thumb-frm.el