home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel Volume 2 #1
/
carousel.iso
/
mactosh
/
unix
/
unix_dra.hqx
/
textimp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-02-14
|
8KB
|
357 lines
/* #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