home *** CD-ROM | disk | FTP | other *** search
- /* #define DEBUG */
- /* #define DEBUG2 */
-
- #include "types.h"
- #include "pxl.h"
- #include <stdio.h>
- #include "drawimp.h"
-
- #define NFONTS 128 /* max number of fonts */
-
- extern int errno;
-
- /* Globals */
-
- struct fontinfo {
- struct pxltail *px; /* pxl file info */
- int family; /* Imagen family number (we pick one) */
- int cwidth[128]; /* width (in DEVs) of each char */
- char cload[128]; /* flag for ``char loaded into Imagen'' */
- };
-
- struct fontinfo FontInfo[NFONTS];/* the fonts themselves */
- struct fontinfo *CurrentFont; /* the current font (if any) */
- int NextFamilyNumber = FONT_FAMILY_TOP;
- /* next available Imagen glyph-family index */
- int numfonts; /* number of fonts read in so far */
-
- char *TeXfonts; /* getenv("TEXFONTS") */
-
- int hh; /* current horizontal position, in DEVs */
- int vv; /* current vertical position, in DEVs */
-
- int ImHH; /* Imagen horizontal position */
- int ImVV; /* Imagen vertical position */
- int ImFamily; /* Imagen current-font number */
-
- double UserMag; /* user specified magnification */
- double GlobalMag; /* overall magnification (UserMag*DVIMag) */
- int IntGlobalMag; /* ROUND (GlobalMag * 1000.0) */
- double conv; /* conversion factor for magnified DVI units */
-
- double OneHalf = 0.5; /* .5, so compiler can generate constant only
- once */
-
- char *getenv (), *malloc ();
-
- /* Round a floating point number to integer */
- #define ROUND(f) ((int) ((f) + OneHalf))
-
- /* Convert a value in sp's to dev's, and vice versa */
- #define SPtoDEV(sp) (ROUND ((sp) * conv))
- #define DEVtoSP(dev) (ROUND ((dev) / conv))
-
- static int text_init, sp_size_set, il_size_set;
- extern int resolution;
- extern int sp_size, tab_size, il_size;
- extern FILE *fontfp, *impout();
-
- /***********************************************************************/
-
- textimp(s,startv,starth,setpos)
- char *s;
- int startv,starth,setpos;
- {
- char ch;
- if (text_init == 0)
- initialize();
- if (setpos) { /* setpos != 0 to set h,v position and mark BOL */
- hh = starth;
- vv = startv;
- imP_set_bol(hh);
- }
- while ((ch = *s++) != '\0') {
- if (ch & 0x80) { /* something special */
- ch &= 0x7f;
- if (ch == '\r') {
- if (il_size != il_size_set)
- imP_set_il(il_size_set = il_size);
- imP_crlf();
- ImVV += il_size;
- vv += il_size;
- }
- else if (ch == ' ') {
- if (sp_size != sp_size_set)
- imP_set_sp(sp_size_set = sp_size);
- imP_sp();
- ImHH += sp_size;
- hh += sp_size;
- }
- else if (ch == '\t') {
- if (tab_size != sp_size_set)
- imP_set_sp(sp_size_set = tab_size);
- imP_sp();
- ImHH += sp_size;
- hh += sp_size;
- }
- }
- else {
- DoChar(ch, 1);
- }
- }
- }
-
- static initialize()
- {
- reset_text();
- TeXfonts = getenv ("TEXFONTS");
- if (TeXfonts == 0)
- TeXfonts = "";
- UserMag = ((double) resolution) / 200;
- GlobalMag = UserMag;
- IntGlobalMag = ROUND (GlobalMag * 1000.0);
- conv = (100.0) * (200.0 / 473628672) * GlobalMag;
- #ifdef DEBUG
- fprintf(stderr,"TeXfonts=%s\n",TeXfonts);
- fprintf(stderr,"UserMag=%g, GlobalMag=%g, IntGlobalMag=%d\n",
- UserMag, GlobalMag, IntGlobalMag);
- fprintf(stderr,"conv=%g\n",conv);
- #endif
- text_init = 1;
- }
-
- /* This should be called after each output file is complete to make sure
- things get set right for the next file.
- */
- reset_text()
- {
- sp_size_set = 0;
- il_size_set = 0;
- ImHH = ImVV = ImFamily = -1;
- }
-
- /* Resets all fonts to show as not downloaded yet. */
- reset_fonts()
- {
- int i, j;
- char *cl;
- for (i = 0; i < numfonts; i++) {
- cl = FontInfo[i].cload;
- for (j = 128; j > 0; j--)
- *cl++ = 0;
- }
- }
-
- /* Given a font file name, find the font table entry for it. If 'define'
- is nonzero, make an entry for it. */
- selectfont(name,at_size,design_size)
- char *name;
- int at_size, design_size;
- {
- char *font;
- struct finder {
- char *name; /* the font file name */
- struct fontinfo *f; /* the font info defined for it */
- };
- register struct finder *f, *f1, *f2;
- static struct finder finder[NFONTS];
-
- if (text_init == 0)
- initialize();
- font = GenPXLFileName(name, at_size, design_size, IntGlobalMag,
- TeXfonts);
- #ifdef DEBUG
- fprintf(stderr,"\nLooking for font \"%s\", numfonts=%d\n",
- font,numfonts);
- #endif
- /* If there are fonts defined, look around for the given font */
- if (numfonts) {
- register int h, l, m, x;
- h = numfonts - 1;
- l = 0;
- #ifdef DEBUG
- for (x = 0; x < numfonts; x++) {
- fprintf(stderr,"%d: id=%d, \"%s\"\n",x,
- (finder[x].f)->family, finder[x].name);
- }
- #endif
- while (l <= h) {
- f = &finder[m = (l + h) >> 1];
- if ((x = strcmp(f->name, font)) > 0)
- h = m - 1;
- else if (x < 0)
- l = m + 1;
- else {
- CurrentFont = f->f;
- #ifdef DEBUG
- fprintf(stderr,"Found it, id=%d\n",
- CurrentFont->family);
- #endif
- return(CurrentFont->family);
- }
- }
- if (l == numfonts)
- f = &finder[numfonts];
- }
- else
- f = finder;
-
- /* f is now where the font should have been found, if anywhere */
-
- f1 = &finder[numfonts];
- if (numfonts > NFONTS)
- error (1, 0, "too many fonts used (%d)", numfonts);
- while (f1 > f) {
- *f1 = *(f2 = f1 - 1);
- f1 = f2;
- }
- f->name = malloc(strlen(font) + 1);
- strcpy(f->name, font);
- CurrentFont = f->f = &FontInfo[numfonts];
- if ((CurrentFont->px = ReadPXLFile(font, 1)) == 0)
- error(1, errno, "can't find font \"%s\"",font);
- ScaleTFMWidths(CurrentFont->px, at_size);
- ComputeCWidths(CurrentFont);
- CurrentFont->family = NextFamilyNumber--;
- numfonts++;
- #ifdef DEBUG
- fprintf(stderr,"Font file now loaded, id=%d\n",CurrentFont->family);
- #endif
- #ifdef DEBUG2
- printwidths(CurrentFont,stderr);
- #endif
- return(CurrentFont->family);
- }
-
- /* Compute the DEV widths of the characters in the given font */
- static ComputeCWidths (fi)
- struct fontinfo *fi;
- {
- register int i;
- register struct chinfo *ch;
- register int *cw;
-
- ch = fi -> px -> px_info;
- cw = fi -> cwidth;
- i = 128;
- while (--i >= 0) {
- *cw++ = SPtoDEV (ch -> ch_TFMwidth);
- ch++;
- }
- }
-
- static DoChar(c, advance)
- char c;
- int advance;
- {
- register struct chinfo *ch;
- register struct fontinfo *cf;
-
- cf = CurrentFont;
- ch = &cf -> px -> px_info[c];
- if (ch -> ch_width != 0) {
- if (!cf -> cload[c])
- DownLoadGlyph (c, ch, cf);
- ImSetPosition(hh, vv);
- if (ImFamily != cf->family) {
- ImFamily = cf->family;
- imP_set_family(ImFamily);
- }
- imP_member(c);
- ImHH += cf -> cwidth[c]; /* where the Imagen thinks we are */
- }
-
- if (advance) {
- hh += cf -> cwidth[c]; /* where we want to be */
- }
- }
-
- #define RoundUp(n,r) (((n) + ((r) - 1)) & ~((r) - 1))
-
- /* Download the character c/ch/cf (also, do rotation if needed) */
- static DownLoadGlyph (c, ch, cf)
- int c; /* ordinal value */
- register struct chinfo *ch; /* chinfo for c */
- register struct fontinfo *cf; /* advance amount */
- {
- register char *p;
- register int i,
- j,
- o,
- w;
- FILE *fp;
- /*
- if (!LFlag)
- w = 0;
- else {
- PerformRotation (ch, -90);
- w = 1;
- } */
- w = 0;
-
- fp = impout(fontfp); /* switch to font file */
- /* Define the character */
- imP_bgly(w, cf->family, c, cf->cwidth[c],
- ch->ch_width, ch->ch_xoffset,
- ch->ch_height, ch->ch_yoffset, NULL);
-
- /* Now put out the bitmap. We have to drop any extra ``all blank'' bytes
- that are implied by the definition of the PXL fonts, since the Imagen
- doesn't need (nor want) them. */
- w = (RoundUp (ch -> ch_width, 8) >> 3);
- o = (RoundUp (ch -> ch_width, 32) >> 3) - w;
- p = ch -> ch_raster;
- for (i = ch -> ch_height; --i >= 0;) {
- for (j = w; --j >= 0;)
- imP_member(*p++);
- p += o;
- }
- cf -> cload[c] = 1; /* it's now loaded */
- impout(fp);
- }
-
- /* Set the Imagen's h & v positions. (It's currently at ImHH, ImVV.) */
- static ImSetPosition (h, v)
- register int h, v;
- {
- if (ImHH != h) {
- if (ImHH == h - 1)
- imP_mplus();
- else if (ImHH == h + 1)
- imP_mminus();
- else
- imP_set_abs_h(h);
- ImHH = h;
- }
- if (ImVV != v) {
- imP_set_abs_v(v);
- ImVV = v;
- }
- }
-
- #ifdef DEBUG2
- /* Print out the DEV widths of the characters in the given font */
- static printwidths (fi, fp)
- struct fontinfo *fi;
- FILE *fp;
- {
- register int i, j, k;
- register struct chinfo *ch;
- register int *cw;
-
- ch = fi -> px -> px_info;
- cw = fi -> cwidth;
- i = 0;
- k = 32;
- while (--k >= 0) {
- j = 4;
- while (--j >= 0) {
- fprintf(fp,"%d: %d %d ",i++,ch->ch_TFMwidth,*cw);
- cw++;
- ch++;
- }
- fprintf(fp,"\n");
- }
- }
- #endif
-