home *** CD-ROM | disk | FTP | other *** search
- /*
- * railmag.c -- downloads vfonts to a Hewlett-Packard DeskJet.
- * Copyright (C) 1990 Vassilis Prevelakis
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation and included with this distribution in the
- * file named LICENSE.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Bug fixes, comments etc. to:
- * Vasilis Prevelakis
- * Centre Universitaire d'Informatique (CUI)
- * 12 Rue du Lac, Geneva, Switzerland CH-1207
- * email: vp@cui.unige.ch
- * uucp: ...!mcsun!cui!vp
- *
- */
-
- #include <assert.h>
- #include <stdio.h>
- #ifdef UNIX
- #include <string.h>
- #include <vfont.h>
- #include <sys/file.h>
- #else
- #include <string.h>
- #include <vp/vfont.h>
- #include <fcntl.h>
- #include <alloc.h>
- #endif
-
- typedef unsigned short u_short;
- typedef unsigned char u_char;
-
- #ifdef UNIX
- #define max(X, Y) ((X > Y) ? X : Y)
- #define min(X, Y) ((X < Y) ? X : Y)
- #endif
-
- #define FDB_LEN sizeof(struct fdb)
-
- struct fdb {
- u_short size; /* always 72 */
- u_char format; /* DeskJet only: header format (5 or 9) */
- u_char ftype; /* zero for 7-bit font */
- short xxx1; /* RESERVED, must be zero */
- u_short baseline; /* in dots */
- u_short cell_width; /* in dots */
- u_short cell_height; /* in dots */
- u_char orientation; /* 0 portrait, 1 landscape */
- u_char spacing; /* 0 fixed, 1 proportional */
- u_short symbol;
- u_short pitch; /* in quarter dots */
- u_short height; /* in quarter dots */
- u_short xHeight; /* in quarter dots -- IGNORED */
- u_char w_type; /* IGNORED, == 0 */
- u_char style;
- char str_weight;
- u_char typeface;
- u_char slant; /* DeskJet only */
- u_char s_style;
- u_char quality; /* DeskJet only */
- u_char placement; /* DeskJet only */
- char ud_dst;
- u_char ud_height; /* IGNORED, == 3 */
- u_short t_height; /* IGNORED, == 0 */
- u_short t_width; /* IGNORED, == 0 */
- u_short firstcode; /* DeskJet only */
- u_short lastcode; /* DeskJet only */
- u_char ext_pitch; /* IGNORED by DeskJet == 0 */
- u_char ext_height; /* IGNORED by DeskJet == 0 */
- short xxx5[3]; /* RESERVED, must be zero */
- #define MAXNAME 16
- char fname[MAXNAME];
- /* following fields DeskJet only */
- u_short hres; /* horizontal resolution == 600 */
- u_short vres; /* vertical resolution == 300 */
- char ud2_dst;
- u_char ud2_height;
- char bud_dst;
- u_char bud_height;
- u_short psbs; /* number of subsequent bytes == 20 */
- u_short font_size;
- char oneway;
- char compressed;
- u_char holdtime;
- char nohalfpitch;
- char nodoublepitch;
- char nohalfheight;
- char nobold;
- char nodraft;
- char boldmethod;
- char xxx7; /* RESERVED, must be zero */
- u_short baseoff2;
- /* following fields used by DeskJet PLUS **ONLY** */
- u_short baseoff3;
- u_short baseoff4;
- } myfdb;
-
- #define CDB_LEN sizeof(struct cdb)
- struct cdb {
- u_char format; /* 9 for large, 5 for small! */
- u_char continuation;
- u_char size; /* always == 6 */
- u_char type; /* single pass (=0) or pass number (=2,3,4,5) */
- u_char width;
- u_char compr_width;
- u_char left_pad;
- u_char right_pad;
- };
-
- #define NCHAR 127
- /* NPASS is the maximum number of passes that the printer can make
- * when printing a character, its 2 for the original DeskJet and 4 for
- * the DeskJet PLUS.
- */
- #define NPASS 4
- struct char_info {
- struct cdb mycdb;
- int cwidth; /* width in bytes */
- int cheight; /* character height */
- int top_pad; /* blank rows above character cell */
- int bottom_pad; /* blank rows bellow character cell */
- u_char *flagbytes[NPASS]; /* flag bytes for each pass */
- int flaglen; /* size of flagbytes, same on all passes */
- u_char *databytes[NPASS]; /* data bytes for each pass */
- int datalen[NPASS]; /* size of databytes for each pass */
-
- } cinfo[NCHAR];
-
- #define IMG_SIZE 50000
- #define DATA_SIZE 5000
- struct header vf_header;
- struct dispatch dsp[NUM_DISPATCH];
- #ifdef UNIX
- u_char imageTable[IMG_SIZE];
- u_char raster[IMG_SIZE];
- u_char dataptr[DATA_SIZE];
- #else
- u_char *imageTable;
- u_char *raster;
- u_char *dataptr;
- #endif
- char *fontname;
- FILE* printer; /* file descriptor for printer */
- u_short font_size;
-
- /* for the DeskJet the value used for dots is 300 despite the
- * fact that the fonts are defined in 600ths of an inch.
- */
- #define DPI 300
-
- /* number of pins on the DeskJet print head */
- #define DJ_CELLHEIGHT 50
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
-
- int wt = 0;
- char *sname = "2000V"; /* by default use ESC(2000V to select */
- char *fname = NULL;
- #ifdef MSDOS
- char* printername = NULL;
- #endif
- int isprop = 1; /* proportional spacing by default */
- int nofid = 0; /* do not generate fontid info */
- int isperm = 1; /* by default fornts are permanent */
- int fpitch = -1;
- int offset = 0; /* for BSD vfonts that have ascii mapping */
- /* i.e. 33rd character of vfont is "!" */
- int fid = 2; /* a bit arbitrary */
- int tpface = 30; /* use an undefined typeface */
- int i;
- char *vp;
- int npass, pass; /* number of passes per char */
-
- #ifndef UNIX
- /* allocate things that should have been global!!! */
- if ((imageTable = malloc(IMG_SIZE)) == NULL)
- {
- fprintf(stderr, "Couldn't allocate memory for imageTable\n");
- exit(1);
- }
- if ((raster = malloc(IMG_SIZE)) == NULL)
- {
- fprintf(stderr, "Couldn't allocate memory for raster\n");
- exit(1);
- }
- if ((dataptr = malloc(DATA_SIZE)) == NULL)
- {
- fprintf(stderr, "Couldn't allocate memory for dataptr\n");
- exit(1);
- }
- #endif
- argv++;
- argc--;
- if (argc > 0) /* process parameters */
- {
- while (argc > 0 && **argv == '-')
- {
- switch (*(*argv+1)) {
- case 'T':
- isperm = 0;
- argv++;
- argc--;
- break;
- case 'D':
- nofid = 1;
- argv++;
- argc--;
- break;
- case 'f':
- isprop = 0;
- argv++;
- argc--;
- break;
- case 'p':
- isprop = 0; /* force fixed width */
- fpitch = atoi(*(++argv));
- argv++;
- argc -= 2;
- break;
- case 'o':
- offset = atoi(*(++argv));
- argv++;
- argc -= 2;
- break;
- case 'n':
- fname = *++argv;
- argv++;
- argc -= 2;
- break;
- #ifndef UNIX
- case 'F':
- printername = *++argv;
- argv++;
- argc -= 2;
- break;
- #endif
- case 's':
- sname = *++argv;
- argv++;
- argc -= 2;
- break;
- case 'i':
- fid = atoi(*(++argv));
- argv++;
- argc -= 2;
- break;
- case 't':
- tpface = atoi(*(++argv));
- argv++;
- argc -= 2;
- break;
- default:
- usage(1);
- }
- }
-
- /*
- * filename
- */
- if (argc <= 0)
- usage(2);
- else {
- fontname = *argv++;
- argc--;
- }
- if (argc > 0)
- usage(3);
- }
-
- if (nofid)
- fid = -1;
- #ifdef UNIX
- /* under unix railmag is just a filter */
- printer = stdout;
- #else
- /* under MSDOS we have to go to the printer directly */
- if (printername == NULL)
- printername = "PRN:";
-
- if ((printer = fopen(printername, "wb")) == NULL)
- {
- fprintf(stderr, "Could not open printer %s.\n", printername);
- exit(1);
- }
- #endif
-
- loadfont(fontname);
- myfdb.size = 72;
- myfdb.ftype = 1;
- myfdb.cell_height = vf_header.maxy;
- /* raise cell_height to the next DJ_CELLHEIGHT multiple */
- myfdb.cell_height += (DJ_CELLHEIGHT-(myfdb.cell_height%DJ_CELLHEIGHT));
-
- /* baseline is calculated as the the distance from the top of
- * the BOTTOM pass for the font.
- */
- if ((myfdb.baseline = calcmaxdown(1, NCHAR)) > DJ_CELLHEIGHT)
- {
- fprintf(stderr, "Baseline (%d) greater than DJ_CELLHEIGHT\n",
- myfdb.baseline);
- exit(1);
- }
- myfdb.baseline = DJ_CELLHEIGHT - myfdb.baseline;
-
- myfdb.orientation = (fontname[strlen(fontname)-1] == 'r') ? 1 : 0;
- myfdb.spacing = isprop;
- myfdb.symbol = symbol_cvt(sname);
- /*
- * if fpitch is specified force cell width and pitch
- * otherwise calculate them from the header
- */
- if (fpitch > 0)
- {
- myfdb.cell_width = DPI/fpitch;
- /* multiply by four because these are quater dots */
- myfdb.pitch = myfdb.cell_width * 4;
- } else {
- myfdb.cell_width = vf_header.maxx;
- /* multiply by four because these are quater dots */
- myfdb.pitch = dsp['m'].width * 4;
- }
- myfdb.height = myfdb.cell_height * 4;
- myfdb.xHeight = dsp['x'].up * 4;
- myfdb.w_type = wt;
- /* following four should really be derived from fontname */
- myfdb.style = 0;
- myfdb.str_weight = 0;
- myfdb.typeface = tpface;
- myfdb.s_style = 0;
-
- myfdb.ud_dst = -(dsp['_'].down + 4);
- myfdb.ud_height = 3;
- myfdb.t_height = vf_header.maxy * 4;
- myfdb.t_width = average('a', 'z') * 4;
- myfdb.ext_pitch = myfdb.ext_height = 0;
- if (fname != NULL)
- strncpy(myfdb.fname, fname, MAXNAME);
- else {
- /* use basename(fontname) */
- #ifdef BSD
- vp = rindex(fontname, '/');
- #else
- vp = strrchr(fontname, '/');
- #endif
- strncpy(myfdb.fname, (vp != NULL) ? vp+1 : fontname, MAXNAME);
- }
-
- /* all the following values are for the DeskJet only */
- myfdb.slant = 0; /* ignored */
- myfdb.quality = 2; /* letter quality */
- myfdb.placement = 0; /* ignored */
- myfdb.firstcode = offset + 1;
- myfdb.lastcode = NCHAR;
- myfdb.hres = 600; /* horizontal resolution == 600 */
- myfdb.vres = 300; /* vertical resolution == 300 */
- myfdb.ud2_dst = -(dsp['_'].down);
- myfdb.ud2_height = 3;
- myfdb.bud_dst = -(dsp['_'].down + 4);
- myfdb.bud_height = 3;
- myfdb.psbs = 20; /* number of subsequent bytes == 20 */
- myfdb.font_size = 0; /* fill it up later */
- myfdb.oneway = 0; /* bidirectional */
- myfdb.compressed = 0; /* no compression info */
- myfdb.nohalfpitch = 0; /* allow half pitch */
- myfdb.nodoublepitch = 0; /* allow double pitch */
- myfdb.nohalfheight= 0; /* allow half height */
- myfdb.nobold = 0; /* allow algorithmic bold */
- myfdb.nodraft = 0; /* allow draft mode */
- myfdb.boldmethod = 1; /* dark bold, if too dark try = 0 */
- /* now for the tricky fields! */
- /* since cell_height is a multiple of DJ_CELLHEIGHT: */
- npass = myfdb.cell_height / DJ_CELLHEIGHT;
- if (npass <= 2)
- {
- myfdb.format = 5; /* DeskJet type font */
- myfdb.holdtime = 0; /* RESERVED == 0 */
- } else {
- myfdb.format = 9; /* DeskJet PLUS type font */
- myfdb.holdtime = 80; /* just a guess */
- }
- if (npass >= 2)
- myfdb.baseoff2 = myfdb.baseline + DJ_CELLHEIGHT;
- else
- myfdb.baseoff2 = 0;
- /* following fields used by DeskJet PLUS **ONLY** */
- if (npass >= 3)
- myfdb.baseoff3 = myfdb.baseline + 2*DJ_CELLHEIGHT;
- else
- myfdb.baseoff3 = 0;
- if (npass >= 4)
- myfdb.baseoff4 = myfdb.baseline + 3*DJ_CELLHEIGHT;
- else
- myfdb.baseoff4 = 0;
-
- fprintf(stderr, "main: npass=%d, cell_height=%d, baseline=%d\n",
- npass, myfdb.cell_height, myfdb.baseline);
- /* convert each character and calculate size of font */
- /* the numbers for the header come from the deskjet developers
- * guide:
- * +-----------------+--------------+--------------+
- * | Font type | <= 128 chars | <= 256 chars |
- * +-----------------+--------------+--------------+
- * | fixed, no compr | 320 | 832 |
- * +-----------------+--------------+--------------+
- * | fixed, compr | 448 | 1088 |
- * +-----------------+--------------+--------------+
- * | fixed, no compr | 576 | 1344 |
- * +-----------------+--------------+--------------+
- * Here we deal only with 127 char fonts without compression,
- * so we have to select between 448 and 576.
- */
- if (isprop)
- font_size = 576;
- else
- font_size = 448;
-
- for (i = 1; i < NCHAR-offset; i++)
- font_size += char_cvt(i, npass);
- myfdb.font_size = font_size;
-
- /* if DJ+ font divide size by 1024 cause the DJ+ wants Kbytes */
- if (myfdb.format == 9)
- myfdb.font_size /= 1024;
-
- /*
- * fid specifies font position, so that more than one font
- * can be loaded simultaneously.
- */
- pr_header(fid);
-
- /*
- * BSD vfonts are arranged in ASCII order, i.e. '!' is number 33
- * for these fonts offset should be zero!
- */
-
- if (npass == 1)
- for (i = 1; i < NCHAR-offset; i++)
- pr_glyph(i, i+offset, 0, 0);
- else
- for (pass = 0; pass < npass; pass++)
- for (i = 1; i < NCHAR-offset; i++)
- pr_glyph(i, i+offset, npass-pass-1, pass+2);
-
- pr_trailer(fid, isperm);
- }
-
- usage(i)
- int i;
- {
- #ifdef UNIX
- fprintf(stderr, "usage(%d): railmag [-n name] [-s sname] [-f] [-p nn] [-o nn] [-i fid] fontname\n", i);
- #else
- fprintf(stderr, "usage(%d): railmag [-n name] [-s sname] [-f] [-p nn] [-o nn] [-i fid]\n\t[-F filename] [-D] fontname\n", i);
- #endif
- exit(-1);
- }
-
-
-
- symbol_cvt(s)
- char *s;
- {
- return((s[strlen(s)-1] - '@') + (atoi(s) * 32));
- }
-
- calcmaxdown(st, fin)
- int st, fin;
- {
- int i, w;
- long res;
-
- res = 0;
- for (i = st; i <= fin; i++)
- {
- w = dsp[i].down;
- res = (res > w) ? res : w;
- }
- return(res);
- }
-
- average(st, fin)
- int st, fin;
- {
- int i;
- long sum;
-
- sum = 0;
- for (i = st; i <= fin; i++)
- sum += dsp[i].width;
- return(sum/(i-st));
- }
-
- pr_header(fid)
- int fid;
- {
- if (fid >= 0)
- fprintf(printer, "\033*c%dD", fid); /* select font */
- fprintf(printer, "\033)s%dW", FDB_LEN);
- #ifdef MSDOS
- /* swap bytes on all shorts */
- #define vp_swab(X) ((((u_short)X & 0xff) << 8) | (((u_short)X & 0xff00) >> 8))
- myfdb.size = vp_swab(myfdb.size);
- myfdb.baseline = vp_swab(myfdb.baseline);
- myfdb.cell_width = vp_swab(myfdb.cell_width);
- myfdb.cell_height = vp_swab(myfdb.cell_height);
- myfdb.symbol = vp_swab(myfdb.symbol);
- myfdb.pitch = vp_swab(myfdb.pitch);
- myfdb.height = vp_swab(myfdb.height);
- myfdb.xHeight = vp_swab(myfdb.xHeight);
- myfdb.t_height = vp_swab(myfdb.t_height);
- myfdb.t_width = vp_swab(myfdb.t_width);
- myfdb.firstcode = vp_swab(myfdb.firstcode);
- myfdb.lastcode = vp_swab(myfdb.lastcode);
- myfdb.hres = vp_swab(myfdb.hres);
- myfdb.vres = vp_swab(myfdb.vres);
- myfdb.psbs = vp_swab(myfdb.psbs);
- myfdb.font_size = vp_swab(myfdb.font_size);
- myfdb.baseoff2 = vp_swab(myfdb.baseoff2);
- myfdb.baseoff3 = vp_swab(myfdb.baseoff3);
- myfdb.baseoff4 = vp_swab(myfdb.baseoff4);
- #endif
- fwrite(&myfdb, FDB_LEN, 1, printer);
- }
-
- pr_trailer(fid, isperm)
- int fid, isperm;
- {
- if (fid < 0)
- return;
- if (isperm)
- fprintf(printer, "\033*c5F"); /* make font permanent, */
- fprintf(printer, "\033(%dX", fid); /* and select it */
- }
-
- int char_cvt(idx, npass)
- int idx;
- int npass;
- {
- int i, j;
- unsigned char *vp, *cp;
- int bottom_pad, top_pad, cheight, cwidth;
- int maxheight, maxbase;
- int size, band;
- static long int mem = 0L;
-
- if (dsp[idx].nbytes == 0)
- return(0);
-
- cheight = cinfo[idx].cheight = dsp[idx].up + dsp[idx].down;
- cinfo[idx].mycdb.format = myfdb.format; /* same as the font format */
- cinfo[idx].mycdb.continuation = 0; /* always == 0 */
- cinfo[idx].mycdb.size = 6; /* always == 6 */
- /* we leave the type undefined, as it will be filled by pr_glyph */
- cinfo[idx].mycdb.type = -1; /* illegal value */
-
- /* double as its in 600ths of an inch */
- cinfo[idx].mycdb.width = (dsp[idx].left + dsp[idx].right) * 2;
- /* flaglen is same as width */
- cinfo[idx].flaglen = cinfo[idx].mycdb.width;
- /* width in whole bytes */
- cwidth = cinfo[idx].cwidth = (dsp[idx].left + dsp[idx].right + 7) /8;
- cinfo[idx].mycdb.compr_width = 0;
- /* double as its in 600ths of an inch */
- cinfo[idx].mycdb.left_pad = 2 * max(-dsp[idx].left, 0);
- /* double as its in 600ths of an inch */
- cinfo[idx].mycdb.right_pad = 0;
-
- /* bottom_pad is the distance between the bottom of the character
- * cell to the bottom of the design cell
- */
- bottom_pad = cinfo[idx].bottom_pad =
- (DJ_CELLHEIGHT - myfdb.baseline) - dsp[idx].down;
- /* top_pad is the distance between the top of the character cell
- * and the top of the design cell.
- */
- top_pad = cinfo[idx].top_pad =
- myfdb.cell_height - (cheight + bottom_pad);
- vp = raster;
- for (i=0; i<top_pad; i++)
- for (j=0; j<cwidth; j++)
- *vp++ = 0;
- cp = &imageTable[dsp[idx].addr];
- for (i=0; i<cheight; i++)
- for (j=0; j<cwidth; j++)
- *vp++ = *cp++;
- for (i=0; i<bottom_pad; i++)
- for (j=0; j<cwidth; j++)
- *vp++ = 0;
- /*
- * at this stage raster contains the character bitmap
- * (row order) correctly centered within the design cell,
- */
- size = CDB_LEN + npass*cwidth;
- for (band=0; band < npass; band++)
- {
- u_char *dp, *fp;
- int len;
-
- if ((fp = cinfo[idx].flagbytes[band]= (u_char*)malloc(cinfo[idx].flaglen))==NULL)
- {
- fprintf(stderr, "Couldn't allocate flagbytes for char %d\n", idx);
- fprintf(stderr, "Pass %d, memory given so far = %ld\n", band, mem);
- exit(1);
- }
- mem += cinfo[idx].flaglen;
- /*
- * We will now convert the character bitmap
- * into something acceptable to the DeskJet.
- * We feed the bitmap to rast_cvt() which creates flag and data
- * bytes suitable for the DeskJet.
- */
- dp = dataptr;
- /*
- * Since we don't know how many databytes will be needed,
- * we use a temporary area, and after they have been generated
- * we allocate the memory and copy them.
- */
- rast_cvt(raster + band * (DJ_CELLHEIGHT * cwidth),
- cinfo[idx].mycdb.width/2, cwidth, &dp, &fp);
-
- len = cinfo[idx].datalen[band] = dp - dataptr;
- size += len;
- if (len > 0)
- {
- if ((cinfo[idx].databytes[band] = (u_char*)malloc(len))==NULL)
- {
- fprintf(stderr,
- "Couldn't allocate databytes for char %d\n", idx);
- fprintf(stderr,
- "Pass %d, memory given so far = %ld\n", band, mem);
- exit(1);
- }
- mem += len;
- memcpy(cinfo[idx].databytes[band], dataptr, len);
- }
- }
- /* we now return the memory taken up by this character */
- return(size);
- }
-
- /*
- * pr_glyph -- send the definition of a character glyph to the printer.
- *
- * idx is the position of the glyph in the vfont file and
- * dstidx will be the position that the glyph will occupy
- * in the downloaded font.
- * type designates the pass number, while band designates
- * the band of the design cell corresponding to the current
- * pass.
- */
- pr_glyph(idx, dstidx, band, type)
- int idx, dstidx, band, type;
- {
- struct char_info *cp;
-
- if (dsp[idx].nbytes == 0)
- return;
-
- cp = &cinfo[idx];
- cp->mycdb.type = type;
-
- fprintf(printer, "\033*c%dE", dstidx);
- fprintf(printer, "\033(s%dW", CDB_LEN+cp->flaglen+cp->datalen[band]);
- fwrite(&cinfo[idx].mycdb, CDB_LEN, 1, printer);
- fwrite(cp->flagbytes[band], cp->flaglen, 1, printer);
- if (cp->datalen[band] > 0)
- fwrite(cp->databytes[band], cp->datalen[band], 1, printer);
- }
-
- /*
- * rast_cvt -- convert raster to DeskJet format
- *
- * NOTE: the data in the source raster ARE MODIFIED by rast_cvt!!!
- * Also this routine assumes that character raster is padded so that
- * it its height is exactly equal to the DeskJet cell height (DJ_CELLHEIGHT).
- *
- * Now some comments:
- *
- * Think of the raster as a two dimentional array of boxes 1 byte wide
- * and 8 bytes high. Since our raster is DJ_CELLHEIGHT (==50) bytes high
- * there will be two rows at the bottom that will be left out. These
- * two rows form a little box.
- *
- * We now pick each box isolate the most significant bit in each byte.
- * We then use the following scheme to put all those bits in one byte:
- *
- * 1 A0000000 A0000000
- * 2 B0000000 0B000000
- * 3 C0000000 00C00000 |
- * 4 D0000000 ---> 000D0000 |
- * 5 E0000000 0000E000 \|/
- * 6 F0000000 00000F00
- * 7 G0000000 000000G0
- * 8 H0000000 0000000H
- * ----------
- * ABCDEFGH
- * We now have the grouped the first column of our box in one byte
- * we then shift all the bytes of that box one bit to the left and
- * repeat the whole process until all the columns of the box have been
- * stored in bytes. We then move to the next box and so on.
- *
- * The last two rows are treated similarly.
- */
-
- rast_cvt(raster, width, cwidth, dataptr, flagptr)
- u_char *raster;
- int width;
- int cwidth;
- u_char **dataptr;
- u_char **flagptr;
- {
- register u_char *vp;
- register u_char *dp = *dataptr;
- register u_char *fp = *flagptr;
- u_char w, flag;
- int boxes, cols, row;
- int remw;
- int i;
-
- for (remw = width; remw > 0; remw -= 8, raster++)
- for (cols = 1; cols <= min(8, remw); cols++)
- {
- flag = 0;
- for (row = 0; row < DJ_CELLHEIGHT-2; row += 8)
- {
- w = 0; /* initialize data byte */
- vp = raster+(row*cwidth);
- for (i = 0; i <8; i++)
- {
- w |= ((*vp & 0x80) >> i);
- (*vp) <<= 1; /* move next column to MSB position */
- vp += cwidth;
- }
- flag >>= 1;
- if (w != 0)
- {
- flag |= 0x80;
- *dp++ = w;
- }
- }
- /* and now the last (little) box */
- w = (*vp & 0x80); /* 49th bit */
- (*vp) <<= 1;
- vp += cwidth;
- w |= ((*vp & 0x80) >> 1); /* 50th bit */
- (*vp) <<= 1;
- vp += cwidth;
- /* here we both set the flag and leave MSBit clear */
- flag >>= 2;
- if (w != 0)
- {
- flag |= 0x40;
- *dp++ = w;
- }
- *fp++ = flag;
- *fp++ = 0; /* leave next column blank */
- }
- *flagptr = fp;
- *dataptr = dp;
- }
-
- loadfont(fontBuf)
- char *fontBuf;
- {
- int fd; /* file handle for vfont file */
- int i;
- int len;
- unsigned int size;
-
- #ifdef UNIX
- if ((fd = open(fontBuf, O_RDONLY)) < 0)
- #else
- if ((fd = open(fontBuf, O_RDONLY|O_BINARY)) < 0)
- #endif
- {
- fprintf(stderr, "railmag: Could not load font %s\n", fontBuf);
- exit(1);
- }
- fprintf(stderr, "Loaded font %s\n", fontBuf);
- len = sizeof(struct header);
- if (read(fd, &vf_header, len) != len)
- {
- fprintf(stderr, "railmag: Bad font file header\n");
- exit(1);
- }
- if (vf_header.magic != VFONT_MAGIC)
- {
- fprintf(stderr, "railmag: Bad font magic number\n");
- exit(1);
- }
- len = NUM_DISPATCH*sizeof(struct dispatch);
- if ((i=read(fd, dsp, len)) != len)
- {
- fprintf(stderr,
- "railmag: Could not load font dispatch table\n");
- fprintf(stderr, "\tlen = %d, read = %d\n", len, i);
- exit(1);
- }
- size = vf_header.size;
- if (size > IMG_SIZE)
- {
- fprintf(stderr, "railmag: image table size (= %u) TOO BIG\n",
- size);
- exit(1);
- }
- if (read(fd, imageTable, size) != size)
- {
- fprintf(stderr, "railmag: Error reading image table\n");
- exit(1);
- }
- return;
- }
-