CACHECHARS(2)                                       CACHECHARS(2)

     NAME
          cachechars, agefont, loadchar, Subfont, Fontchar, Font  -
          font utilities

     SYNOPSIS
          #include <u.h>
          #include <libc.h>
          #include <libg.h>

          int  cachechars(Font *f, char **s, ushort *c, int n, int
          *widp)

          int  loadchar(Font *f, Rune r, Cacheinfo *c, int h, int
          noclr)

          void agefont(Font *f)

     DESCRIPTION
          A Font may contain too many characters to hold in memory
          simultaneously.  The graphics library and bitblt device (see
          bit(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: binit
          and its associated font variable, rdfontfile, charwidth,
          string, and ffree 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 bitmap with the characters placed
          side-by-side on a common baseline.  It is described by the
          following data structures.

               typedef
               struct Fontchar {
                     ushort   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 {
                     short    n;        /* number of chars in subfont */
                     uchar    height;   /* height of bitmap */
                     char     ascent;   /* top of bitmap to baseline */
                     Fontchar *info;    /* n+1 Fontchars */
                     int      id;       /* id as known in /dev/bitblt */
               } Subfont;

     CACHECHARS(2)                                       CACHECHARS(2)

          The bitmap 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 a bitmap, 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
          bitmap.  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 Bitmap 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 */
                     int       abs;      /* name has been made absolute */
                     char      *name;
               } Cachefont;

               typedef
               struct Cacheinfo {
                     Rune      value;    /* of char at this slot in cache */
                     ushort    age;
                     ulong     xright;   /* right edge of bits */
                     Fontchar;
               } 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;
                     uchar     height;   /* max ht of bitmap;interline space*/
                     char      ascent;   /* top of bitmap to baseline */
                     char      width;    /* widest so far; used in caching */
                     char      ldepth;   /* of images */
                     short     id;       /* of font */
                     short     nsub;     /* number of subfonts */

     CACHECHARS(2)                                       CACHECHARS(2)

                     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 */
               } Font;

          The `height' and `ascent' fields of Font are described in
          graphics(2). `Ldepth' is that of the cache, set by the argu-
          ment to rdfontfile. `Sub' contains `nsub' pointers to
          Cachefonts.  A Cachefont connects runes `min' through `max',
          inclusive, to the subfont with file name `name'; it corre-
          sponds 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 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 maxi-
          mum 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 character 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.
          It can return zero if it is unable to make progress because
          it is unable to resize the caches.

          Loadchar loads a character image into the character cache.
          First, if necessary, it loads the subfont containing the
          character.  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 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.  It returns 1

     CACHECHARS(2)                                       CACHECHARS(2)

          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.  Thus, characters or subfonts with
          small ages are the best candidates for replacement when the
          cache is full.

     SOURCE
          /sys/src/libg

     SEE ALSO
          graphics(2), balloc(2), bitblt(2), subfalloc(2), bitmap(6),
          font(6)

     DIAGNOSTICS
          All of the functions use the graphics error function (see
          graphics(2)).