Function: font-get-glyphs
font-get-glyphs is a function defined in font.c.
Signature
(font-get-glyphs FONT-OBJECT FROM TO &optional OBJECT)
Documentation
Return a vector of FONT-OBJECT's glyphs for the specified characters.
FROM and TO are positions (integers or markers) specifying a region
of the current buffer, and can be in either order. If the optional
fourth arg OBJECT is not nil, it is a string or a vector containing
the target characters between indices FROM and TO, which are treated
as in substring.
Each element is a vector containing information of a glyph in this format:
[FROM-IDX TO-IDX C CODE WIDTH LBEARING RBEARING ASCENT DESCENT ADJUSTMENT]
where
FROM is an index numbers of a character the glyph corresponds to.
TO is the same as FROM.
C is the character of the glyph.
CODE is the glyph-code of C in FONT-OBJECT.
WIDTH thru DESCENT are the metrics (in pixels) of the glyph.
ADJUSTMENT is always nil.
If FONT-OBJECT doesn't have a glyph for a character, the corresponding element is nil.
Also see font-has-char-p, which is more efficient than this function
if you just want to check whether FONT-OBJECT has a glyph for a
character.
Source Code
// Defined in /usr/src/emacs/src/font.c
{
struct font *font = CHECK_FONT_GET_OBJECT (font_object);
ptrdiff_t len;
Lisp_Object *chars;
USE_SAFE_ALLOCA;
if (NILP (object))
{
ptrdiff_t charpos, bytepos;
validate_region (&from, &to);
if (EQ (from, to))
return Qnil;
len = XFIXNAT (to) - XFIXNAT (from);
SAFE_ALLOCA_LISP (chars, len);
charpos = XFIXNAT (from);
bytepos = CHAR_TO_BYTE (charpos);
for (ptrdiff_t i = 0; charpos < XFIXNAT (to); i++)
{
int c = fetch_char_advance (&charpos, &bytepos);
chars[i] = make_fixnum (c);
}
}
else if (STRINGP (object))
{
const unsigned char *p;
ptrdiff_t ifrom, ito;
validate_subarray (object, from, to, SCHARS (object), &ifrom, &ito);
if (ifrom == ito)
return Qnil;
len = ito - ifrom;
SAFE_ALLOCA_LISP (chars, len);
p = SDATA (object);
if (STRING_MULTIBYTE (object))
{
int c;
/* Skip IFROM characters from the beginning. */
for (ptrdiff_t i = 0; i < ifrom; i++)
p += BYTES_BY_CHAR_HEAD (*p);
/* Now fetch an interesting characters. */
for (ptrdiff_t i = 0; i < len; i++)
{
c = string_char_advance (&p);
chars[i] = make_fixnum (c);
}
}
else
for (ptrdiff_t i = 0; i < len; i++)
chars[i] = make_fixnum (p[ifrom + i]);
}
else if (VECTORP (object))
{
ptrdiff_t ifrom, ito;
validate_subarray (object, from, to, ASIZE (object), &ifrom, &ito);
if (ifrom == ito)
return Qnil;
len = ito - ifrom;
for (ptrdiff_t i = 0; i < len; i++)
{
Lisp_Object elt = AREF (object, ifrom + i);
CHECK_CHARACTER (elt);
}
chars = aref_addr (object, ifrom);
}
else
wrong_type_argument (Qarrayp, object);
Lisp_Object vec = make_nil_vector (len);
for (ptrdiff_t i = 0; i < len; i++)
{
Lisp_Object g;
int c = XFIXNAT (chars[i]);
unsigned code;
struct font_metrics metrics;
code = font->driver->encode_char (font, c);
if (code == FONT_INVALID_CODE)
{
ASET (vec, i, Qnil);
continue;
}
g = LGLYPH_NEW ();
LGLYPH_SET_FROM (g, i);
LGLYPH_SET_TO (g, i);
LGLYPH_SET_CHAR (g, c);
LGLYPH_SET_CODE (g, code);
font->driver->text_extents (font, &code, 1, &metrics);
LGLYPH_SET_WIDTH (g, metrics.width);
LGLYPH_SET_LBEARING (g, metrics.lbearing);
LGLYPH_SET_RBEARING (g, metrics.rbearing);
LGLYPH_SET_ASCENT (g, metrics.ascent);
LGLYPH_SET_DESCENT (g, metrics.descent);
ASET (vec, i, g);
}
if (! VECTORP (object))
SAFE_FREE ();
return vec;
}