From: Titus von der Malsburg Date: Fri, 29 Apr 2022 13:14:09 +0000 (+0200) Subject: Add new functions for computing character metrics for windows X-Git-Tag: emacs-29.0.90~1931^2~217 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=91418d27e9c528fd9062c74a4ce58b657366a8c5;p=emacs.git Add new functions for computing character metrics for windows * doc/lispref/display.texi (Size of Displayed Text): Document the char functions. * doc/lispref/windows.texi (Window Sizes): Document window-max-characters-per-line. * lisp/window.el (window-char-pixel-width) (window-char-pixel-height) (window-max-characters-per-line): New functions (bug#19395). --- diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index becf7ecd157..390d1650253 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2252,6 +2252,20 @@ This is a convenience function that uses @code{window-text-pixel-size} to compute the width of @var{string} (in pixels). @end defun +@defun window-char-pixel-width &optional window face +Return the average character width for the font used by @var{face} in +@var{window}. If @var{face} is @code{nil} or omitted, the +@code{default} face is used. If @var{windows} is @code{nil} or +omitted, the currently selected window is used. +@end defun + +@defun window-char-pixel-height &optional window face +Return the average character height for the font used by @var{face} in +@var{window}. If @var{face} is @code{nil} or omitted, the +@code{default} face is used. If @var{windows} is @code{nil} or +omitted, the currently selected window is used. +@end defun + @defun line-pixel-height This function returns the height in pixels of the line at point in the selected window. The value includes the line spacing of the line diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi index 0b3fa0c8b5a..97908bea001 100644 --- a/doc/lispref/windows.texi +++ b/doc/lispref/windows.texi @@ -759,6 +759,15 @@ column and total width (@pxref{Coordinates and Windows}). The optional argument @var{round} behaves as it does for @code{window-total-height}. @end defun +@defun window-max-characters-per-line &optional window face +The maximum width of a line that can be displayed in a window (without +breaking the line) depends on many things, like the font used on the +line, and whether there are fringes around the window. This +convenience function can be used to calculate that number. If +@var{window} isn't given, this defaults to the currently selected +window. if @var{var} isn't given, the @code{default} face is used. +@end defun + @defun window-total-size &optional window horizontal round This function returns either the total height in lines or the total width in columns of the window @var{window}. If @var{horizontal} is diff --git a/etc/NEWS b/etc/NEWS index b0c0d0511a4..c796f605b12 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1521,6 +1521,15 @@ functions. * Lisp Changes in Emacs 29.1 ++++ +** New function 'window-max-characters-per-line'. + ++++ +** New function 'window-char-pixel-width'. + ++++ +** New function 'window-char-pixel-width'. + --- ** New function 'current-cpu-time'. It gives access to the CPU time used by the Emacs process, for diff --git a/lisp/window.el b/lisp/window.el index dc33eb8a12a..bb4d51da5f5 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -10480,6 +10480,58 @@ displaying that processes's buffer." (put 'shrink-window-horizontally 'repeat-map 'resize-window-repeat-map) (put 'shrink-window 'repeat-map 'resize-window-repeat-map) +(defun window-char-pixel-width (&optional window face) + "Return average character width for the font of FACE used in WINDOW. +WINDOW must be a live window and defaults to the selected one. + +If FACE is nil or omitted, the default face is used. If FACE is +remapped (see `face-remapping-alist'), the function returns the +information for the remapped face." + (with-selected-window (window-normalize-window window t) + (let* ((face (if face face 'default)) + (info (font-info (face-font face))) + (width (aref info 11))) + (if (> width 0) + width + (aref info 10))))) + +(defun window-char-pixel-height (&optional window face) + "Return character height for the font of FACE used in WINDOW. +WINDOW must be a live window and defaults to the selected one. + +If FACE is nil or omitted, the default face is used. If FACE is +remapped (see `face-remapping-alist'), the function returns the +information for the remapped face." + (with-selected-window (window-normalize-window window t) + (let* ((face (if face face 'default)) + (info (font-info (face-font face)))) + (aref info 3)))) + +(defun window-max-characters-per-line (&optional window face) + "Return the number of characters that can be displayed on one line in WINDOW. +WINDOW must be a live window and defaults to the selected one. + +The character width of FACE is used for the calculation. If FACE +is nil or omitted, the default face is used. If FACE is +remapped (see `face-remapping-alist'), the function uses the +remapped face. + +This function is different from `window-body-width' in two +ways. First, it accounts for the portions of the line reserved +for the continuation glyph. Second, it accounts for the size of +the font, which may have been adjusted, e.g., using +`text-scale-increase')." + (with-selected-window (window-normalize-window window t) + (let* ((window-width (window-body-width window t)) + (font-width (window-char-pixel-width window face)) + (ncols (/ window-width font-width))) + (if (and (display-graphic-p) + overflow-newline-into-fringe + (/= (frame-parameter nil 'left-fringe) 0) + (/= (frame-parameter nil 'right-fringe) 0)) + ncols + (1- ncols))))) + (provide 'window) ;;; window.el ends here diff --git a/src/window.c b/src/window.c index ad0f54000c0..cfe3977428b 100644 --- a/src/window.c +++ b/src/window.c @@ -1079,7 +1079,9 @@ means that if a column at the right of the text area is only partially visible, that column is not counted. Note that the returned value includes the column reserved for the -continuation glyph. */) +continuation glyph. + +Also see `window-max-characters-per-line'. */) (Lisp_Object window, Lisp_Object pixelwise) { return make_fixnum (window_body_width (decode_live_window (window),