| .TH CACHECHARS 3 |
| .SH NAME |
| cachechars, agefont, loadchar, Subfont, Fontchar, Font \- font utilities |
| .SH SYNOPSIS |
| .B #include <u.h> |
| .br |
| .B #include <libc.h> |
| .br |
| .B #include <draw.h> |
| .PP |
| .ta \w'\fLCacheinfo 'u |
| .PP |
| .B |
| int cachechars(Font *f, char **s, Rune **r, ushort *c, int max, |
| .PP |
| .B |
| int *widp, char **sfname) |
| .PP |
| .B |
| int loadchar(Font *f, Rune r, Cacheinfo *c, int h, |
| .PP |
| .B |
| int noclr, char **sfname) |
| .PP |
| .B |
| void agefont(Font *f) |
| .SH DESCRIPTION |
| A |
| .I Font |
| may contain too many characters to hold in memory |
| simultaneously. |
| The graphics library and draw device (see |
| .IR 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: |
| .I initdraw |
| and its associated |
| .I font |
| variable, |
| .IR openfont , |
| .IR stringwidth , |
| .IR string , |
| and |
| .I freefont |
| are sufficient for most purposes. |
| The routines described below are used internally by the graphics library |
| to maintain the font cache. |
| .PP |
| A |
| .B Subfont |
| is a set of images for a contiguous range of characters, stored as a single |
| image |
| with the characters |
| placed side-by-side on a common baseline. |
| It is described by the following data structures. |
| .IP |
| .EX |
| .ta 6n +\w'Fontchar 'u +\w'bottom; 'u |
| 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 */ |
| char ascent; /* top of image to baseline */ |
| Fontchar *info; /* n+1 Fontchars */ |
| Image *bits; /* of font */ |
| } Subfont; |
| .EE |
| .PP |
| The image fills the rectangle |
| \fL(0, 0, \fIw\fP, height)\fR, |
| where |
| .I w |
| is the sum of the horizontal extents (of non-zero pixels) |
| for all characters. |
| The pixels to be displayed for character |
| .I c |
| are in the rectangle |
| \fL(\fIi\fP->x, \fIi\fP->top, (\fIi\fP+1)->x, \%\fIi\fP->bottom)\fR |
| where |
| .I i |
| is |
| .B |
| &subfont->info[\fIc\fP]\fR. |
| When a character is displayed at |
| .B Point |
| .B p |
| in an image, |
| the character rectangle is placed at |
| .BI (p.x+ i ->left, |
| .B p.y) |
| and the next character of the string is displayed at |
| .BI (p.x+ i ->width, |
| .BR p.y) . |
| The baseline of the characters is |
| .L ascent |
| rows down from the top of the subfont image. |
| The |
| .L info |
| array has |
| .B n+1 |
| elements, one each for characters 0 to |
| .BR n-1 |
| plus an additional entry so the size of the last character |
| can be calculated. |
| Thus the width, |
| .IR w , |
| of the |
| .B Image |
| associated with a |
| .B Subfont |
| .B s |
| is |
| .BR s->info[s->n].x . |
| .PP |
| A |
| .B Font |
| consists of an overall height and ascent |
| and a collection of subfonts together with the ranges of runes (see |
| .IR utf (7)) |
| they represent. |
| Fonts are described by the following structures. |
| .IP |
| .EX |
| .ta 6n +\w'Cacheinfo 'u +\w'height; 'u |
| 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; |
| 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; |
| .EE |
| .PP |
| The |
| .LR height |
| and |
| .LR ascent |
| fields of Font are described in |
| .IR graphics (3). |
| .L Sub |
| contains |
| .L nsub |
| pointers to |
| .BR Cachefonts . |
| A |
| .B Cachefont |
| connects runes |
| .L min |
| through |
| .LR max , |
| inclusive, to the subfont |
| with file name |
| .LR name ; |
| it corresponds to a line of the file describing the font. |
| .PP |
| The characters |
| are taken from the subfont starting at character number |
| .L offset |
| (usually zero) in the subfont, permitting selection of parts of subfonts. |
| Thus |
| the image for rune |
| .I r |
| is found in position |
| .IB r -min+offset |
| of the subfont. |
| .PP |
| 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 |
| .B subf |
| and |
| .B cache |
| fields are used by the library to maintain these caches. |
| The |
| .L width |
| of a font is the maximum of the horizontal extents of the characters |
| in the cache. |
| .I String |
| draws a string by loading the cache and emitting a sequence of |
| cache indices to draw. |
| .I Cachechars |
| guarantees the images for the characters pointed to by |
| .I *s |
| or |
| .I *r |
| (one of these must be nil in each call) |
| are in the cache of |
| .IR f . |
| It calls |
| .I loadchar |
| to put missing characters into the cache. |
| .I Cachechars |
| translates the character string into a set of cache indices |
| which it loads into the array |
| .IR c , |
| up to a maximum of |
| .I n |
| indices or the length of the string. |
| .I Cachechars |
| returns in |
| .I c |
| the number of cache indices emitted, |
| updates |
| .I *s |
| to point to the next character to be processed, and sets |
| .I *widp |
| to the total width of the characters processed. |
| .I 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 subfont, it will fill |
| .B *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. |
| .PP |
| .I Loadchar |
| loads a character image into the character cache. |
| Then it tells the graphics server to copy the character |
| into position |
| .I h |
| in the character cache. |
| If the current font |
| .L width |
| is smaller than the horizontal extent of the character being loaded, |
| .I loadfont |
| clears the cache and resets it to |
| accept characters with the bigger width, unless |
| .I noclr |
| is set, in which case it just returns \-1. |
| If the character does not exist in the font at all, |
| .I loadfont |
| returns 0; if it is unable to load the character |
| without destroying cached information, it returns \-1, |
| updating |
| .B *sfname |
| as described above. |
| It returns 1 to indicate success. |
| .PP |
| The |
| .L age |
| fields record when |
| subfonts and characters have been used. |
| The font |
| .L age |
| is increased every time the font is used |
| .RI ( agefont |
| does this). |
| A character or subfont |
| .L 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. |
| .SH SOURCE |
| .B \*9/src/libdraw |
| .SH SEE ALSO |
| .IR graphics (3), |
| .IR allocimage (3), |
| .IR draw (3), |
| .IR subfont (3), |
| .IR image (7), |
| .IR font (7) |
| .SH DIAGNOSTICS |
| All of the functions use the graphics error function (see |
| .IR graphics (3)). |