From b1978229162b0d4c3b14d8ad8bff383eb3511969 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 18 Dec 2014 18:07:26 +0200 Subject: [PATCH] Allow querying font by name for its height and other info. (Bug#19395) src/font.c (Ffont_info): Add more font information to the vector returned by the function, inspired by query-font. Doc fix. doc/lispref/display.texi (Low-Level Font): Document font-info and query-font. lisp/international/mule-diag.el (describe-font-internal): Display additional info returned by font-info. lisp/linum.el (linum--face-width): Rename from linum--face-height, and use the new functionality of font-info. (linum-update-window): Use linum--face-width and frame-char-width, instead of approximating with height. etc/NEWS: Mention the enhancement in font-info. --- doc/lispref/ChangeLog | 4 ++ doc/lispref/display.texi | 124 +++++++++++++++++++++++++++++++- etc/NEWS | 26 ++++--- lisp/ChangeLog | 10 +++ lisp/international/mule-diag.el | 10 ++- lisp/linum.el | 15 ++-- src/ChangeLog | 6 ++ src/font.c | 47 ++++++++++-- 8 files changed, 217 insertions(+), 25 deletions(-) diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog index a48289c3b80..7424ab07cdf 100644 --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@ -1,3 +1,7 @@ +2014-12-18 Eli Zaretskii + + * display.texi (Low-Level Font): Document font-info and query-font. + 2014-12-16 Nicolas Petton * sequences.texi (Seq Library): Add documentation for seq.el. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 90aa9797a59..48860c8ebef 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -3349,9 +3349,9 @@ The script that the font must support (a symbol). @item :otf @cindex OpenType font The font must be an OpenType font that supports these OpenType -features, provided Emacs is compiled with support for @samp{libotf} (a -library for performing complex text layout in certain scripts). The -value must be a list of the form +features, provided Emacs is compiled with a library, such as +@samp{libotf} on GNU/Linux, that supports complex text layout for +scripts which need that. The value must be a list of the form @smallexample @code{(@var{script-tag} @var{langsys-tag} @var{gsub} @var{gpos})} @@ -3450,6 +3450,124 @@ If the optional argument @var{fold-wildcards} is non-@code{nil}, consecutive wildcards in the XLFD are folded into one. @end defun +The following two functions return important information about a font. + +@defun font-info name &optional frame +This function returns information about a font specified by its +@var{name}, a string, as it is used on @var{frame}. If @var{frame} is +omitted or @code{nil}, it defaults to the selected frame. + +The value returned by the function is a vector of the form +@code{[@var{opened-name} @var{full-name} @var{size} @var{height} +@var{baseline-offset} @var{relative-compose} @var{default-ascent} +@var{max-width} @var{ascent} @var{descent} @var{space-width} +@var{average-width} @var{filename} @var{capability}]}. Here's the +description of each components of this vector: + +@table @var +@item opened-name +The name used to open the font, a string. + +@item full-name +The full name of the font, a string. + +@item size +The pixel size of the font. + +@item height +The height of the font in pixels. + +@item baseline-offset +The offset in pixels from the @acronym{ASCII} baseline, positive +upward. + +@item relative-compose +@itemx default-ascent +Numbers controlling how to compose characters. + +@item ascent +@itemx descent +The ascent and descent of this font. The sum of these two numbers +should be equal to the value of @var{height} above. + +@item space-width +The width, in pixels, of the font's space character. + +@item average-width +The average width of the font characters. If this is zero, Emacs uses +the value of @var{space-width} instead, when it calculates text layout +on display. + +@item filename +The file name of the font as a string. This can be @code{nil} if the +font back-end does not provide a way to find out the font's file name. + +@item capability +A list whose first element is a symbol representing the font type, one +of @code{x}, @code{opentype}, @code{truetype}, @code{type1}, +@code{pcf}, or @code{bdf}. For OpenType fonts, the list includes 2 +additional elements describing the @sc{gsub} and @sc{gpos} features +supported by the font. Each of these elements is a list of the form +@code{((@var{script} (@var{langsys} @var{feature} @dots{}) @dots{}) +@dots{})}, where @var{script} is a symbol representing an OpenType +script tag, @var{langsys} is a symbol representing an OpenType langsys +tag (or @code{nil}, which stands for the default langsys), and each +@var{feature} is a symbol representing an OpenType feature tag. +@end table +@end defun + +@defun query-font font-object +This function returns information about a @var{font-object}. (This is +in contrast to @code{font-info}, which takes the font name, a string, +as its argument.) + +The value returned by the function is a vector of the form +@code{[@var{name} @var{filename} @var{pixel-size} @var{max-width} +@var{ascent} @var{descent} @var{space-width} @var{average-width} +@var{capability}]}. Here's the description of each components of this +vector: + +@table @var +@item name +The font name, a string. + +@item filename +The file name of the font as a string. This can be @code{nil} if the +font back-end does not provide a way to find out the font's file name. + +@item pixel-size +The pixel size of the font used to open the font. + +@item max-width +The maximum advance width of the font. + +@item ascent +@itemx descent +The ascent and descent of this font. The sum of these two numbers +gives the font height. + +@item space-width +The width, in pixels, of the font's space character. + +@item average-width +The average width of the font characters. If this is zero, Emacs uses +the value of @var{space-width} instead, when it calculates text layout +on display. + +@item capability +A list whose first element is a symbol representing the font type, one +of @code{x}, @code{opentype}, @code{truetype}, @code{type1}, +@code{pcf}, or @code{bdf}. For OpenType fonts, the list includes 2 +additional elements describing the @sc{gsub} and @sc{gpos} features +supported by the font. Each of these elements is a list of the form +@code{((@var{script} (@var{langsys} @var{feature} @dots{}) @dots{}) +@dots{})}, where @var{script} is a symbol representing an OpenType +script tag, @var{langsys} is a symbol representing an OpenType langsys +tag (or @code{nil}, which stands for the default langsys), and each +@var{feature} is a symbol representing an OpenType feature tag. +@end table +@end defun + @node Fringes @section Fringes @cindex fringes diff --git a/etc/NEWS b/etc/NEWS index a17cef62998..865ae074ae8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -108,6 +108,17 @@ environment. For the time being this is implemented for modern POSIX systems and for MS-Windows, for other systems they fall back to their counterparts `string-lessp' and `string-equal'. +*** The ls-lisp package uses `string-collate-lessp' to sort file names. +If you want the old, locale-independent sorting, customize the new +option `ls-lisp-use-string-collate' to a nil value. + +*** The MS-Windows specific variable `w32-collate-ignore-punctuation', +if set to a non-nil value, causes the above 2 functions to ignore +symbol and punctuation characters when collating strings. This +emulates the behavior of modern Posix platforms when the locale's +codeset is "UTF-8" (as in "en_US.UTF-8"). This is needed because +MS-Windows doesn't support UTF-8 as codeset in its locales. + +++ ** The new function `bidi-find-overridden-directionality' allows to find characters whose directionality was, perhaps maliciously, @@ -122,17 +133,6 @@ the visual appearance both of the copied text and the text at destination, even when the copied text includes mixed bidirectional text and directional control characters. -*** The ls-lisp package uses `string-collate-lessp' to sort file names. -If you want the old, locale-independent sorting, customize the new -option `ls-lisp-use-string-collate' to a nil value. - -*** The MS-Windows specific variable `w32-collate-ignore-punctuation', -if set to a non-nil value, causes the above 2 functions to ignore -symbol and punctuation characters when collating strings. This -emulates the behavior of modern Posix platforms when the locale's -codeset is "UTF-8" (as in "en_US.UTF-8"). This is needed because -MS-Windows doesn't support UTF-8 as codeset in its locales. - ** New variable `ns-use-fullscreen-animation' controls animation for non-native NS fullscreen. The default is nil. Set to t to enable animation when entering and leaving fullscreen. For native OSX fullscreen @@ -159,6 +159,10 @@ fontification during full screen scrolling operations, giving less hesitant operation during auto-repeat of C-v, M-v at the cost of possible inaccuracies in the end position. +** The function `font-info' now returns more details about a font. +In particular, it now returns the average width of the font's +characters, which can be used for geometry-related calculations. + * Editing Changes in Emacs 25.1 diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 89a92f6454f..cb8348e1d51 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,13 @@ +2014-12-18 Eli Zaretskii + + * international/mule-diag.el (describe-font-internal): Display + additional info returned by font-info. + + * linum.el (linum--face-width): Rename from linum--face-height, + and use the new functionality of font-info. + (linum-update-window): Use linum--face-width and frame-char-width, + instead of approximating with height. + 2014-12-18 Dmitry Gutov * vc/vc-svn.el (vc-svn-dir-status-files): Revert the 2014-12-02 diff --git a/lisp/international/mule-diag.el b/lisp/international/mule-diag.el index 13a178531bc..ead2decb771 100644 --- a/lisp/international/mule-diag.el +++ b/lisp/international/mule-diag.el @@ -825,10 +825,18 @@ but still contains full information about each coding system." The IGNORED argument is ignored." (print-list "name (opened by):" (aref font-info 0)) (print-list " full name:" (aref font-info 1)) + (and (aref font-info 12) + (print-list " file name:" (aref font-info 12))) (print-list " size:" (format "%2d" (aref font-info 2))) (print-list " height:" (format "%2d" (aref font-info 3))) (print-list " baseline-offset:" (format "%2d" (aref font-info 4))) - (print-list "relative-compose:" (format "%2d" (aref font-info 5)))) + (print-list "relative-compose:" (format "%2d" (aref font-info 5))) + (print-list " default-ascent:" (format "%2d" (aref font-info 6))) + (print-list " ascent:" (format "%2d" (aref font-info 8))) + (print-list " descent:" (format "%2d" (aref font-info 9))) + (print-list " average-width:" (format "%2d" (aref font-info 11))) + (print-list " space-width:" (format "%2d" (aref font-info 10))) + (print-list " max-width:" (format "%2d" (aref font-info 7)))) ;;;###autoload (defun describe-font (fontname) diff --git a/lisp/linum.el b/lisp/linum.el index b13bd8dbbb6..fb2cda6c506 100644 --- a/lisp/linum.el +++ b/lisp/linum.el @@ -138,8 +138,13 @@ Linum mode is a buffer-local minor mode." (mapc #'delete-overlay linum-available) (setq linum-available nil)))) -(defun linum--face-height (face) - (aref (font-info (face-font face)) 2)) +(defun linum--face-width (face) + (let ((info (font-info (face-font face))) + width) + (setq width (aref info 11)) + (if (<= width 0) + (setq width (aref info 10))) + width)) (defun linum-update-window (win) "Update line numbers for the portion visible in window WIN." @@ -183,10 +188,8 @@ Linum mode is a buffer-local minor mode." (setq line (1+ line))) (when (display-graphic-p) (setq width (ceiling - ;; We'd really want to check the widths rather than the - ;; heights, but it's a start. - (/ (* width 1.0 (linum--face-height 'linum)) - (frame-char-height))))) + (/ (* width 1.0 (linum--face-width 'linum)) + (frame-char-width))))) (set-window-margins win width (cdr (window-margins win))))) (defun linum-after-change (beg end _len) diff --git a/src/ChangeLog b/src/ChangeLog index 16e99aec99a..2b125d52723 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2014-12-18 Eli Zaretskii + + * font.c (Ffont_info): Add more font information to the vector + returned by the function, inspired by query-font. Doc fix. + (Bug#19395) + 2014-12-18 Stefan Monnier * keyboard.c (input_was_pending): New var. diff --git a/src/font.c b/src/font.c index 70e63164a34..d10d2280a5b 100644 --- a/src/font.c +++ b/src/font.c @@ -4921,8 +4921,11 @@ If FRAME is omitted or nil, use the selected frame. */) DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0, doc: /* Return information about a font named NAME on frame FRAME. If FRAME is omitted or nil, use the selected frame. -The returned value is a vector of OPENED-NAME, FULL-NAME, SIZE, - HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT, + +The returned value is a vector: + [ OPENED-NAME FULL-NAME SIZE HEIGHT BASELINE-OFFSET RELATIVE-COMPOSE + DEFAULT-ASCENT MAX-WIDTH ASCENT DESCENT SPACE-WIDTH AVERAGE-WIDTH + CAPABILITY ] where OPENED-NAME is the name used for opening the font, FULL-NAME is the full name of the font, @@ -4930,7 +4933,33 @@ where HEIGHT is the pixel-height of the font (i.e., ascent + descent), BASELINE-OFFSET is the upward offset pixels from ASCII baseline, RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling - how to compose characters. + how to compose characters, + MAX-WIDTH is the maximum advance width of the font, + ASCENT, DESCENT, SPACE-WIDTH, AVERAGE-WIDTH are metrics of the font + in pixels, + FILENAME is the font file name, a string (or nil if the font backend + doesn't provide a file name). + CAPABILITY is a list whose first element is a symbol representing the + font format, one of x, opentype, truetype, type1, pcf, or bdf. + The remaining elements describe the details of the font capabilities, + as follows: + + If the font is OpenType font, the form of the list is + \(opentype GSUB GPOS) + where GSUB shows which "GSUB" features the font supports, and GPOS + shows which "GPOS" features the font supports. Both GSUB and GPOS are + lists of the form: + \((SCRIPT (LANGSYS FEATURE ...) ...) ...) + + where + SCRIPT is a symbol representing OpenType script tag. + LANGSYS is a symbol representing OpenType langsys tag, or nil + representing the default langsys. + FEATURE is a symbol representing OpenType feature tag. + + If the font is not an OpenType font, there are no elements + in CAPABILITY except the font format symbol. + If the named font is not yet loaded, return nil. */) (Lisp_Object name, Lisp_Object frame) { @@ -4966,7 +4995,7 @@ If the named font is not yet loaded, return nil. */) return Qnil; font = XFONT_OBJECT (font_object); - info = make_uninit_vector (7); + info = make_uninit_vector (14); ASET (info, 0, AREF (font_object, FONT_NAME_INDEX)); ASET (info, 1, AREF (font_object, FONT_FULLNAME_INDEX)); ASET (info, 2, make_number (font->pixel_size)); @@ -4974,6 +5003,16 @@ If the named font is not yet loaded, return nil. */) ASET (info, 4, make_number (font->baseline_offset)); ASET (info, 5, make_number (font->relative_compose)); ASET (info, 6, make_number (font->default_ascent)); + ASET (info, 7, make_number (font->max_width)); + ASET (info, 8, make_number (font->ascent)); + ASET (info, 9, make_number (font->descent)); + ASET (info, 10, make_number (font->space_width)); + ASET (info, 11, make_number (font->average_width)); + ASET (info, 12, AREF (font_object, FONT_FILE_INDEX)); + if (font->driver->otf_capability) + ASET (info, 13, Fcons (Qopentype, font->driver->otf_capability (font))); + else + ASET (info, 13, Qnil); #if 0 /* As font_object is still in FONT_OBJLIST of the entity, we can't -- 2.39.2