Back to index

radiance  4R0+20100331
Defines | Functions | Variables
font.c File Reference
#include "copyright.h"
#include <stdlib.h>
#include "paths.h"
#include "rtio.h"
#include "rterror.h"
#include "font.h"

Go to the source code of this file.

Defines

#define galloc(nv)   (GLYPH *)malloc(sizeof(GLYPH)+2*sizeof(GORD)*(nv))

Functions

FONTgetfont (char *fname)
void freefont (FONT *fnt)
int uniftext (short *sp, char *tp, FONT *f)
int squeeztext (short *sp, char *tp, FONT *f, int cis)
int proptext (short *sp, char *tp, FONT *f, int cis, int nsi)

Variables

static const char RCSid [] = "$Id: font.c,v 2.19 2004/03/26 23:04:23 greg Exp $"
int retainfonts = 0
static FONTfontlist = NULL

Define Documentation

#define galloc (   nv)    (GLYPH *)malloc(sizeof(GLYPH)+2*sizeof(GORD)*(nv))

Definition at line 17 of file font.c.


Function Documentation

void freefont ( FONT fnt)

Definition at line 128 of file font.c.

{
       FONT  head;
       register FONT  *fl, *f;
       register int  i;
                                   /* check reference count */
       if (fnt != NULL && ((fnt->nref-- > 1) | retainfonts))
              return;
       head.next = fontlist;
       fl = &head;
       while ((f = fl->next) != NULL)
              if ((fnt == NULL) | (fnt == f)) {
                     fl->next = f->next;
                     for (i = 0; i < 256; i++)
                            if (f->fg[i] != NULL)
                                   free((void *)f->fg[i]);
                     freestr(f->name);
                     free((void *)f);
              } else
                     fl = f;
       fontlist = head.next;
}

Here is the call graph for this function:

Here is the caller graph for this function:

FONT* getfont ( char *  fname)

Definition at line 26 of file font.c.

{
       FILE  *fp;
       char  *pathname, *err = NULL;
       unsigned  wsum, hsum, ngly;
       int  gn, ngv, gv;
       register GLYPH       *g;
       GORD  *gp;
       register FONT  *f;

       for (f = fontlist; f != NULL; f = f->next)
              if (!strcmp(f->name, fname)) {
                     f->nref++;
                     return(f);
              }
                                          /* load the font file */
       if ((pathname = getpath(fname, getrlibpath(), R_OK)) == NULL) {
              sprintf(errmsg, "cannot find font file \"%s\"", fname);
              error(USER, errmsg);
       }
       f = (FONT *)calloc(1, sizeof(FONT));
       if (f == NULL)
              goto memerr;
       f->name = savestr(fname);
       f->nref = 1;
       if ((fp = fopen(pathname, "r")) == NULL) {
              sprintf(errmsg, "cannot open font file \"%s\"",
                            pathname);
              error(SYSTEM, errmsg);
       }
       wsum = hsum = ngly = 0;                   /* get each glyph */
       while ((ngv = fgetval(fp, 'i', (char *)&gn)) != EOF) {
              if (ngv == 0)
                     goto nonint;
              if (gn < 1 || gn > 255) {
                     err = "illegal";
                     goto fonterr;
              }
              if (f->fg[gn] != NULL) {
                     err = "duplicate";
                     goto fonterr;
              }
              if (fgetval(fp, 'i', (char *)&ngv) <= 0 ||
                            ngv < 0 || ngv > 32000) {
                     err = "bad # vertices for";
                     goto fonterr;
              }
              g = galloc(ngv);
              if (g == NULL)
                     goto memerr;
              g->nverts = ngv;
              g->left = g->right = g->top = g->bottom = 128;
              ngv *= 2;
              gp = gvlist(g);
              while (ngv--) {
                     if (fgetval(fp, 'i', (char *)&gv) <= 0 ||
                                   gv < 0 || gv > 255) {
                            err = "bad vertex for";
                            goto fonterr;
                     }
                     *gp++ = gv;
                     if (ngv & 1) {              /* follow x limits */
                            if (gv < g->left)
                                   g->left = gv;
                            else if (gv > g->right)
                                   g->right = gv;
                     } else {             /* follow y limits */
                            if (gv < g->bottom)
                                   g->bottom = gv;
                            else if (gv > g->top)
                                   g->top = gv;
                     }
              }
              if (g->right - g->left && g->top - g->bottom) {
                     ngly++;
                     wsum += g->right - g->left;
                     hsum += g->top - g->bottom;
              }
              f->fg[gn] = g;
       }
       fclose(fp);
       if (ngly) {
              f->mwidth = wsum / ngly;
              f->mheight = hsum / ngly;
       }
       f->next = fontlist;
       return(fontlist = f);
nonint:
       sprintf(errmsg, "non-integer in font file \"%s\"", pathname);
       error(USER, errmsg);
fonterr:
       sprintf(errmsg, "%s character (%d) in font file \"%s\"",
                     err, gn, pathname);
       error(USER, errmsg);
memerr:
       error(SYSTEM, "out of memory in fontglyph");
       return NULL; /* pro forma return */
}

Here is the call graph for this function:

Here is the caller graph for this function:

int proptext ( short *  sp,
char *  tp,
FONT f,
int  cis,
int  nsi 
)

Definition at line 207 of file font.c.

{
       register char  *end, *tab = NULL;
       GLYPH  *gp;
       short  *nsp;
       int  alen, len, width;
                                   /* start by squeezing it */
       squeeztext(sp, tp, f, cis);
                                   /* now, realign spacing */
       width = *sp++;
       while (*tp) {
              len = alen = 0;
              nsp = sp;
              for (end = tp; *end; end = tab) {
                     tab = end + 1;
                     alen += *nsp++;
                     if (f->fg[*end&0xff]) {
                            while ((gp = f->fg[*tab&0xff]) != NULL &&
                                          gp->nverts == 0) { /* tab in */
                                   alen += *nsp++;
                                   tab++;
                            }
                            len += tab - end;
                     }
                     if (nsi && tab - end > nsi)
                            break;
              }
              len *= f->mwidth + cis;            /* compute target length */
              width += len;
              len -= alen;                /* necessary adjustment */
              while (sp < nsp) {
                     alen = len/(nsp-sp);
                     *sp++ += alen;
                     len -= alen;
              }
              tp = tab;
       }
       return(width);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int squeeztext ( short *  sp,
char *  tp,
FONT f,
int  cis 
)

Definition at line 172 of file font.c.

{
       int  linelen;
       register GLYPH       *gp;

       linelen = 0;
       gp = NULL;
       while (*tp && (gp = f->fg[*tp++&0xff]) == NULL)
              *sp++ = 0;
       cis /= 2;
       *sp = cis;
       while (gp != NULL) {
              if (gp->nverts) {           /* regular character */
                     linelen += *sp++ += cis - gp->left;
                     *sp = gp->right + cis;
              } else {                    /* space */
                     linelen += *sp++;
                     *sp = f->mwidth;
              }
              gp = NULL;
              while (*tp && (gp = f->fg[*tp++&0xff]) == NULL) {
                     linelen += *sp++;
                     *sp = 0;
              }
       }
       linelen += *sp += cis;
       return(linelen);
}

Here is the caller graph for this function:

int uniftext ( short *  sp,
char *  tp,
FONT f 
)

Definition at line 154 of file font.c.

{
       int  linelen;

       linelen = *sp++ = 0;
       while (*tp)
              if (f->fg[*tp++&0xff] == NULL)
                     *sp++ = 0;
              else
                     linelen += *sp++ = 255;
       return(linelen);
}

Here is the caller graph for this function:


Variable Documentation

FONT* fontlist = NULL [static]

Definition at line 22 of file font.c.

const char RCSid[] = "$Id: font.c,v 2.19 2004/03/26 23:04:23 greg Exp $" [static]

Definition at line 2 of file font.c.

int retainfonts = 0

Definition at line 20 of file font.c.