rsc | cfa37a7 | 2004-04-10 18:53:55 +0000 | [diff] [blame] | 1 | .TH CACHECHARS 3 |
| 2 | .SH NAME |
| 3 | cachechars, agefont, loadchar, Subfont, Fontchar, Font \- font utilities |
| 4 | .SH SYNOPSIS |
| 5 | .B #include <u.h> |
| 6 | .br |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 7 | .B #include <libc.h> |
rsc | cfa37a7 | 2004-04-10 18:53:55 +0000 | [diff] [blame] | 8 | .br |
| 9 | .B #include <draw.h> |
| 10 | .PP |
| 11 | .ta \w'\fLCacheinfo 'u |
| 12 | .PP |
| 13 | .B |
| 14 | int cachechars(Font *f, char **s, Rune **r, ushort *c, int max, |
| 15 | .PP |
| 16 | .B |
| 17 | int *widp, char **sfname) |
| 18 | .PP |
| 19 | .B |
| 20 | int loadchar(Font *f, Rune r, Cacheinfo *c, int h, |
| 21 | .PP |
| 22 | .B |
| 23 | int noclr, char **sfname) |
| 24 | .PP |
| 25 | .B |
| 26 | void agefont(Font *f) |
| 27 | .SH DESCRIPTION |
| 28 | A |
| 29 | .I Font |
| 30 | may contain too many characters to hold in memory |
| 31 | simultaneously. |
| 32 | The graphics library and draw device (see |
| 33 | .IR draw (3)) |
| 34 | cooperate to solve this problem by maintaining a cache of recently used |
| 35 | character images. |
| 36 | The details of this cooperation need not be known by most programs: |
| 37 | .I initdraw |
| 38 | and its associated |
| 39 | .I font |
| 40 | variable, |
| 41 | .IR openfont , |
| 42 | .IR stringwidth , |
| 43 | .IR string , |
| 44 | and |
| 45 | .I freefont |
| 46 | are sufficient for most purposes. |
| 47 | The routines described below are used internally by the graphics library |
| 48 | to maintain the font cache. |
| 49 | .PP |
| 50 | A |
| 51 | .B Subfont |
| 52 | is a set of images for a contiguous range of characters, stored as a single |
| 53 | image |
| 54 | with the characters |
| 55 | placed side-by-side on a common baseline. |
| 56 | It is described by the following data structures. |
| 57 | .IP |
| 58 | .EX |
| 59 | .ta 6n +\w'Fontchar 'u +\w'bottom; 'u |
| 60 | typedef |
| 61 | struct Fontchar { |
| 62 | int x; /* left edge of bits */ |
| 63 | uchar top; /* first non-zero scan-line */ |
| 64 | uchar bottom; /* last non-zero scan-line */ |
| 65 | char left; /* offset of baseline */ |
| 66 | uchar width; /* width of baseline */ |
| 67 | } Fontchar; |
| 68 | |
| 69 | typedef |
| 70 | struct Subfont { |
| 71 | char *name; |
| 72 | short n; /* number of chars in subfont */ |
| 73 | uchar height; /* height of image */ |
| 74 | char ascent; /* top of image to baseline */ |
| 75 | Fontchar *info; /* n+1 Fontchars */ |
| 76 | Image *bits; /* of font */ |
| 77 | } Subfont; |
| 78 | .EE |
| 79 | .PP |
| 80 | The image fills the rectangle |
| 81 | \fL(0, 0, \fIw\fP, height)\fR, |
| 82 | where |
| 83 | .I w |
| 84 | is the sum of the horizontal extents (of non-zero pixels) |
| 85 | for all characters. |
| 86 | The pixels to be displayed for character |
| 87 | .I c |
| 88 | are in the rectangle |
| 89 | \fL(\fIi\fP->x, \fIi\fP->top, (\fIi\fP+1)->x, \%\fIi\fP->bottom)\fR |
| 90 | where |
| 91 | .I i |
| 92 | is |
| 93 | .B |
| 94 | &subfont->info[\fIc\fP]\fR. |
| 95 | When a character is displayed at |
| 96 | .B Point |
| 97 | .B p |
| 98 | in an image, |
| 99 | the character rectangle is placed at |
| 100 | .BI (p.x+ i ->left, |
| 101 | .B p.y) |
| 102 | and the next character of the string is displayed at |
| 103 | .BI (p.x+ i ->width, |
| 104 | .BR p.y) . |
| 105 | The baseline of the characters is |
| 106 | .L ascent |
| 107 | rows down from the top of the subfont image. |
| 108 | The |
| 109 | .L info |
| 110 | array has |
| 111 | .B n+1 |
| 112 | elements, one each for characters 0 to |
| 113 | .BR n-1 |
| 114 | plus an additional entry so the size of the last character |
| 115 | can be calculated. |
| 116 | Thus the width, |
| 117 | .IR w , |
| 118 | of the |
| 119 | .B Image |
| 120 | associated with a |
| 121 | .B Subfont |
| 122 | .B s |
| 123 | is |
| 124 | .BR s->info[s->n].x . |
| 125 | .PP |
| 126 | A |
| 127 | .B Font |
| 128 | consists of an overall height and ascent |
| 129 | and a collection of subfonts together with the ranges of runes (see |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 130 | .IR utf (7)) |
rsc | cfa37a7 | 2004-04-10 18:53:55 +0000 | [diff] [blame] | 131 | they represent. |
| 132 | Fonts are described by the following structures. |
| 133 | .IP |
| 134 | .EX |
| 135 | .ta 6n +\w'Cacheinfo 'u +\w'height; 'u |
| 136 | typedef |
| 137 | struct Cachefont { |
| 138 | Rune min; /* value of 0th char in subfont */ |
| 139 | Rune max; /* value+1 of last char in subfont */ |
| 140 | int offset; /* posn in subfont of char at min */ |
| 141 | char *name; /* stored in font */ |
| 142 | char *subfontname; /* to access subfont */ |
| 143 | } Cachefont; |
| 144 | |
| 145 | typedef |
| 146 | struct Cacheinfo { |
| 147 | ushort x; /* left edge of bits */ |
| 148 | uchar width; /* width of baseline */ |
| 149 | schar left; /* offset of baseline */ |
| 150 | Rune value; /* of char at this slot in cache */ |
| 151 | ushort age; |
| 152 | } Cacheinfo; |
| 153 | |
| 154 | typedef |
| 155 | struct Cachesubf { |
| 156 | ulong age; /* for replacement */ |
| 157 | Cachefont *cf; /* font info that owns us */ |
| 158 | Subfont *f; /* attached subfont */ |
| 159 | } Cachesubf; |
| 160 | |
| 161 | typedef |
| 162 | struct Font { |
| 163 | char *name; |
| 164 | Display *display; |
| 165 | short height; /* max ht of image;interline space*/ |
| 166 | short ascent; /* top of image to baseline */ |
| 167 | short width; /* widest so far; used in caching */ |
| 168 | short nsub; /* number of subfonts */ |
| 169 | ulong age; /* increasing counter; for LRU */ |
| 170 | int ncache; /* size of cache */ |
| 171 | int nsubf; /* size of subfont list */ |
| 172 | Cacheinfo *cache; |
| 173 | Cachesubf *subf; |
| 174 | Cachefont **sub; /* as read from file */ |
| 175 | Image *cacheimage; |
| 176 | } Font; |
| 177 | .EE |
| 178 | .PP |
| 179 | The |
| 180 | .LR height |
| 181 | and |
| 182 | .LR ascent |
| 183 | fields of Font are described in |
rsc | bf8a59f | 2004-04-11 03:42:27 +0000 | [diff] [blame] | 184 | .IR graphics (3). |
rsc | cfa37a7 | 2004-04-10 18:53:55 +0000 | [diff] [blame] | 185 | .L Sub |
| 186 | contains |
| 187 | .L nsub |
| 188 | pointers to |
| 189 | .BR Cachefonts . |
| 190 | A |
| 191 | .B Cachefont |
| 192 | connects runes |
| 193 | .L min |
| 194 | through |
| 195 | .LR max , |
| 196 | inclusive, to the subfont |
| 197 | with file name |
| 198 | .LR name ; |
| 199 | it corresponds to a line of the file describing the font. |
| 200 | .PP |
| 201 | The characters |
| 202 | are taken from the subfont starting at character number |
| 203 | .L offset |
| 204 | (usually zero) in the subfont, permitting selection of parts of subfonts. |
| 205 | Thus |
| 206 | the image for rune |
| 207 | .I r |
| 208 | is found in position |
| 209 | .IB r -min+offset |
| 210 | of the subfont. |
| 211 | .PP |
| 212 | For each font, the library, with support from the |
| 213 | graphics server, |
| 214 | maintains a cache of |
| 215 | subfonts and a cache of recently used |
| 216 | character images. |
| 217 | The |
| 218 | .B subf |
| 219 | and |
| 220 | .B cache |
| 221 | fields are used by the library to maintain these caches. |
| 222 | The |
| 223 | .L width |
| 224 | of a font is the maximum of the horizontal extents of the characters |
| 225 | in the cache. |
| 226 | .I String |
| 227 | draws a string by loading the cache and emitting a sequence of |
| 228 | cache indices to draw. |
| 229 | .I Cachechars |
| 230 | guarantees the images for the characters pointed to by |
| 231 | .I *s |
| 232 | or |
| 233 | .I *r |
| 234 | (one of these must be nil in each call) |
| 235 | are in the cache of |
| 236 | .IR f . |
| 237 | It calls |
| 238 | .I loadchar |
| 239 | to put missing characters into the cache. |
| 240 | .I Cachechars |
| 241 | translates the character string into a set of cache indices |
| 242 | which it loads into the array |
| 243 | .IR c , |
| 244 | up to a maximum of |
| 245 | .I n |
| 246 | indices or the length of the string. |
| 247 | .I Cachechars |
| 248 | returns in |
| 249 | .I c |
| 250 | the number of cache indices emitted, |
| 251 | updates |
| 252 | .I *s |
| 253 | to point to the next character to be processed, and sets |
| 254 | .I *widp |
| 255 | to the total width of the characters processed. |
| 256 | .I Cachechars |
| 257 | may return before the end of the string if it cannot |
| 258 | proceed without destroying active data in the caches. |
| 259 | If it needs to load a new subfont, it will fill |
| 260 | .B *sfname |
| 261 | with the name of the subfont it needs and return \-1. |
| 262 | It can return zero if it is unable to make progress because |
| 263 | it cannot resize the caches. |
| 264 | .PP |
| 265 | .I Loadchar |
| 266 | loads a character image into the character cache. |
| 267 | Then it tells the graphics server to copy the character |
| 268 | into position |
| 269 | .I h |
| 270 | in the character cache. |
| 271 | If the current font |
| 272 | .L width |
| 273 | is smaller than the horizontal extent of the character being loaded, |
| 274 | .I loadfont |
| 275 | clears the cache and resets it to |
| 276 | accept characters with the bigger width, unless |
| 277 | .I noclr |
| 278 | is set, in which case it just returns \-1. |
| 279 | If the character does not exist in the font at all, |
| 280 | .I loadfont |
| 281 | returns 0; if it is unable to load the character |
| 282 | without destroying cached information, it returns \-1, |
| 283 | updating |
| 284 | .B *sfname |
| 285 | as described above. |
| 286 | It returns 1 to indicate success. |
| 287 | .PP |
| 288 | The |
| 289 | .L age |
| 290 | fields record when |
| 291 | subfonts and characters have been used. |
| 292 | The font |
| 293 | .L age |
| 294 | is increased every time the font is used |
| 295 | .RI ( agefont |
| 296 | does this). |
| 297 | A character or subfont |
| 298 | .L age |
| 299 | is set to the font age at each use. |
| 300 | Thus, characters or subfonts with small ages are the best candidates |
| 301 | for replacement when the cache is full. |
| 302 | .SH SOURCE |
rsc | c3674de | 2005-01-11 17:37:33 +0000 | [diff] [blame] | 303 | .B \*9/src/libdraw |
rsc | cfa37a7 | 2004-04-10 18:53:55 +0000 | [diff] [blame] | 304 | .SH SEE ALSO |
rsc | bf8a59f | 2004-04-11 03:42:27 +0000 | [diff] [blame] | 305 | .IR graphics (3), |
| 306 | .IR allocimage (3), |
| 307 | .IR draw (3), |
| 308 | .IR subfont (3), |
rsc | 058b011 | 2005-01-03 06:40:20 +0000 | [diff] [blame] | 309 | .IR image (7), |
| 310 | .IR font (7) |
rsc | cfa37a7 | 2004-04-10 18:53:55 +0000 | [diff] [blame] | 311 | .SH DIAGNOSTICS |
| 312 | All of the functions use the graphics error function (see |
rsc | bf8a59f | 2004-04-11 03:42:27 +0000 | [diff] [blame] | 313 | .IR graphics (3)). |