CACHECHARS(2) CACHECHARS(2)
NAME
cachechars, agefont, loadchar, Subfont, Fontchar, Font -
font utilities
SYNOPSIS
#include <u.h>
#include <libc.h>
#include <draw.h>
int cachechars(Font *f, char **s, Rune **r, ushort *c, int
max,
int *widp, char **sfname)
int loadchar(Font *f, Rune r, Cacheinfo *c, int h,
int noclr, char **sfname)
void agefont(Font *f)
DESCRIPTION
A Font may contain too many characters to hold in memory
simultaneously. The graphics library and draw device (see
draw(3)) cooperate to solve this problem by maintaining a
cache of recently used character images. The details of
this cooperation need not be known by most programs:
initdraw and its associated font variable, openfont,
stringwidth, string, and freefont are sufficient for most
purposes. The routines described below are used internally
by the graphics library to maintain the font cache.
A Subfont is a set of images for a contiguous range of char-
acters, stored as a single image with the characters placed
side-by-side on a common baseline. It is described by the
following data structures.
typedef
struct Fontchar {
int x; /* left edge of bits */
uchar top; /* first non-zero scan-line */
uchar bottom; /* last non-zero scan-line */
char left; /* offset of baseline */
uchar width; /* width of baseline */
} Fontchar;
typedef
struct Subfont {
char *name;
short n; /* number of chars in subfont */
uchar height; /* height of image */
Page 1 Plan 9 (printed 10/26/25)
CACHECHARS(2) CACHECHARS(2)
char ascent; /* top of image to baseline */
Fontchar *info; /* n+1 Fontchars */
Image *bits; /* of font */
} Subfont;
The image fills the rectangle (0, 0, w, height), where w is
the sum of the horizontal extents (of non-zero pixels) for
all characters. The pixels to be displayed for character c
are in the rectangle (i->x, i->top, (i+1)->x, i->bottom)
where i is &subfont->info[c]. When a character is displayed
at Point p in an image, the character rectangle is placed at
(p.x+i->left, p.y) and the next character of the string is
displayed at (p.x+i->width, p.y). The baseline of the char-
acters is `ascent' rows down from the top of the subfont
image. The `info' array has n+1 elements, one each for
characters 0 to n-1 plus an additional entry so the size of
the last character can be calculated. Thus the width, w, of
the Image associated with a Subfont s is s->info[s->n].x.
A Font consists of an overall height and ascent and a col-
lection of subfonts together with the ranges of runes (see
utf(6)) they represent. Fonts are described by the follow-
ing structures.
typedef
struct Cachefont {
Rune min; /* value of 0th char in subfont */
Rune max; /* value+1 of last char in subfont */
int offset; /* posn in subfont of char at min */
char *name; /* stored in font */
char *subfontname;/* to access subfont */
} Cachefont;
typedef
struct Cacheinfo {
ushort x; /* left edge of bits */
uchar width; /* width of baseline */
schar left; /* offset of baseline */
Rune value; /* of char at this slot in cache */
ushort age;
} Cacheinfo;
typedef
struct Cachesubf {
ulong age; /* for replacement */
Cachefont *cf; /* font info that owns us */
Subfont *f; /* attached subfont */
} Cachesubf;
typedef
struct Font {
char *name;
Page 2 Plan 9 (printed 10/26/25)
CACHECHARS(2) CACHECHARS(2)
Display *display;
short height; /* max ht of image;interline space*/
short ascent; /* top of image to baseline */
short width; /* widest so far; used in caching */
short nsub; /* number of subfonts */
ulong age; /* increasing counter; for LRU */
int ncache; /* size of cache */
int nsubf; /* size of subfont list */
Cacheinfo *cache;
Cachesubf *subf;
Cachefont **sub; /* as read from file */
Image *cacheimage;
} Font;
The `height' and `ascent' fields of Font are described in
graphics(2). `Sub' contains `nsub' pointers to Cachefonts.
A Cachefont connects runes `min' through `max', inclusive,
to the subfont with file name `name'; it corresponds to a
line of the file describing the font.
The characters are taken from the subfont starting at char-
acter number `offset' (usually zero) in the subfont, permit-
ting selection of parts of subfonts. Thus the image for
rune r is found in position r-min+offset of the subfont.
For each font, the library, with support from the graphics
server, maintains a cache of subfonts and a cache of
recently used character images. The subf and cache fields
are used by the library to maintain these caches. The
`width' of a font is the maximum of the horizontal extents
of the characters in the cache. String draws a string by
loading the cache and emitting a sequence of cache indices
to draw. Cachechars guarantees the images for the charac-
ters pointed to by *s or *r (one of these must be nil in
each call) are in the cache of f. It calls loadchar to put
missing characters into the cache. Cachechars translates
the character string into a set of cache indices which it
loads into the array c, up to a maximum of n indices or the
length of the string. Cachechars returns in c the number of
cache indices emitted, updates *s to point to the next char-
acter to be processed, and sets *widp to the total width of
the characters processed. Cachechars may return before the
end of the string if it cannot proceed without destroying
active data in the caches. If it needs to load a new sub-
font, it will fill *sfname with the name of the subfont it
needs and return -1. It can return zero if it is unable to
make progress because it cannot resize the caches.
Loadchar loads a character image into the character cache.
Then it tells the graphics server to copy the character into
position h in the character cache. If the current font
`width' is smaller than the horizontal extent of the
Page 3 Plan 9 (printed 10/26/25)
CACHECHARS(2) CACHECHARS(2)
character being loaded, loadfont clears the cache and resets
it to accept characters with the bigger width, unless noclr
is set, in which case it just returns -1. If the character
does not exist in the font at all, loadfont returns 0; if it
is unable to load the character without destroying cached
information, it returns -1, updating *sfname as described
above. It returns 1 to indicate success.
The `age' fields record when subfonts and characters have
been used. The font `age' is increased every time the font
is used (agefont does this). A character or subfont `age'
is set to the font age at each use. Thus, characters or
subfonts with small ages are the best candidates for
replacement when the cache is full.
SOURCE
/sys/src/libdraw
SEE ALSO
graphics(2), allocimage(2), draw(2), subfont(2), image(6),
font(6)
DIAGNOSTICS
All of the functions use the graphics error function (see
graphics(2)).
Page 4 Plan 9 (printed 10/26/25)