summaryrefslogtreecommitdiff
path: root/dviware/ln03/thomas/ln03fonts.c
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/ln03/thomas/ln03fonts.c')
-rw-r--r--dviware/ln03/thomas/ln03fonts.c1388
1 files changed, 1388 insertions, 0 deletions
diff --git a/dviware/ln03/thomas/ln03fonts.c b/dviware/ln03/thomas/ln03fonts.c
new file mode 100644
index 0000000000..830b4f35d6
--- /dev/null
+++ b/dviware/ln03/thomas/ln03fonts.c
@@ -0,0 +1,1388 @@
+/* This file contains those portions of Ln03DVI that create
+font loads. It is still being developed...
+
+Copyright (c) 1983, 1984, 1985, 1986, 1987 by Digital Equipment
+Corporation. Author: Flavio Rose,
+...!decwrl!dec-rhea!dec-dvinci!rose.
+
+This version of Ln03DVI is maintained by Matt Thomas.
+Please send all bug reports to either:
+ ...!decwrl!thebay.dec.com!mthomas (UUCP)
+ mthomas@thebay.dec.com (Internet)
+
+Development chronology:
+
+11/28/84: Initial version in PL/I. Finished 11/30/84.
+ 3/4/85: C translation, a prelude to writing DVI2LN3.
+ 5/7/85: Finally got around to debugging the C translation!
+ 6/5/85: Convert to work with Dvi2ln3 -- minor changes.
+ 6/18/85: Try not to use big input array.
+ 6/22/85: Cleanup, try to identify longs.
+11/12/85: Changed to read PXLs rather than LN03 format files. Old file
+ called dvi2ln3nft, now renamed to dvi2ln3pxl.
+11/15/85: More optimized PXL reading -- use lnf instead of the pxlbuf
+ when reading rasters. Return just status value from add_txf_...,
+ use ras_len_added to communicate size. Facilitate error
+ recovery with copy_ersatz_char. LN03 file reading functionality
+ woven back in.
+ 1/16/86: Embarrassing bug, forgot to close the nftf after done with it.
+ 3/28/86: Conditionalization for Ultrix.
+ 4/7/86: After moving this to 4.3bsd at MIT, a couple more
+ fixes to the portability.
+ 8/6/86: Try to make changes for Apollo. No way to test
+ them. #ifdef Apollo ... #endif
+ 11/5/86: Add error message giving PXL extension if no PXL
+ file can be found.
+ 2/20/87: Add support for reading of PK files. Reorganize output to be
+ simpler. Change name to Ln03DVI.
+ 5/5/87: Misc fixups relating to the CM fonts. COnditionalize some code, etc.
+ 5/15/87: Fix NFT filename problem (accvio under VMS). cleaup some error
+ messages.
+*/
+
+/* INTRODUCTION: When writing an LN03 driver for TeX, it
+must be kept in mind that the LN03 has limited font storage
+capability. The standard LN03 has just 27k bytes, and two
+128k byte RAM cartridges may be added.
+
+For this reason, when we convert a DVI file to LN03 form, we
+build a special font load that has just the glyphs that the
+DVI file needs. This allows very complex files, e.g. the
+first nine chapters of the Metafontbook, to be printed on
+LN03s that have just one extra RAM cartridge. This approach
+does, however, consume considerable resources in the VAX to
+build those font loads. */
+
+/* The following is customary boilerplate. */
+
+#ifdef vms
+#include stdio
+#include errno
+#else
+#include <stdio.h>
+#include <errno.h>
+#endif
+#include "pk.h"
+
+/* In VMS we declare external variables to be globalref.
+This is not really necessary, just an old habit. */
+
+#ifdef vms
+#define GLOBAL globaldef
+#define EXTERN globalref
+#else
+#define GLOBAL
+#define EXTERN extern
+#endif
+
+/* errno is declared in errno.h under VMS and System V but
+not under BSD 4.2. Also we use strchr instead of index so
+we conditionalize that too. */
+
+#ifdef bsd4_2
+
+# define index strchr
+extern int errno;
+
+#endif
+
+
+/* The following symbols are declared compatibly with those
+in the file Ln03DVI.c. */
+
+#define maxnfonts 31
+#define MAXTEXFONTS 100
+#define FILESPECLEN 252
+#define leftfirst 33
+#define leftlast 126
+#define rightfirst 161
+#define rightlast 254
+
+EXTERN FILE *outfile;
+EXTERN int lastch[maxnfonts];
+EXTERN unsigned char chw[maxnfonts][256];
+
+struct txf { unsigned char chu[256]; int bc, ec; long space, design_size,
+ scaled_size; int nchs; };
+EXTERN struct txf *txfa[MAXTEXFONTS+1];
+EXTERN long int *font_width[MAXTEXFONTS+1];
+
+EXTERN char *font_name[MAXTEXFONTS+1];
+EXTERN double conv, unmag_conv;
+
+#ifndef vms
+char *getenv();
+#endif
+
+/* The LN03 font load we build is buffered in a fixed-size
+area, slightly smaller than the maximum amount of font
+memory available on an LN03. [[The code should be changed to
+chain fixed-size buffers, so font loads of unlimited size
+can be handled, subject only to memory availability. On
+systems with limited memory, it may be desirable to use a
+disk file instead of this buffer.]] */
+
+#define OBUFLEN 2*256*256
+GLOBAL unsigned char lnf[OBUFLEN];
+
+/* While constructing the font load, we keep track of the
+length of the "character definitions area" in ras_len. We
+also have to keep track of the raster size measured in three
+different ways, as psize (portrait), lsize (landscape), and
+msize (mixed). This is required to fill certain fields in
+the font load. */
+
+GLOBAL long int ras_len,psize,lsize,msize;
+
+/* The font load that we construct consists of a number of
+LN03 fonts. Each of these contains up to 94 glyphs. They may
+be "left fonts", so their glyphs are invoked with codes 33
+through 126; or they may be "right fonts" that respond to
+codes 161 through 254.
+
+The font load that we construct is made up of alternating
+left and right fonts (sometimes called "font pairs"). A TeX
+font (represented by a txf record) is added to a font pair.
+It may be split between the left and right halves of the
+pair.
+
+The variable using_r keeps track of whether we are using a
+right font. */
+
+GLOBAL char using_r;
+
+GLOBAL unsigned int nft_first_ch,nft_last_ch,chardir_offset;
+GLOBAL int lnf_chardir,ras_beg;
+GLOBAL long ras_len_added;
+
+GLOBAL int pxlf,nftf;
+GLOBAL PKFont *pkfont;
+
+/* The purpose of add_txf_to_lnf is to read the PXL, PK, or LN03
+font file corresponding to TeX font txfno and add its
+rasters to the font pair referred to by lnfno. The function
+returns 0 if all went well, and various negative numbers to
+indicate problems. The number of bytes added to the font
+load is returned in the global ras_len_added. */
+
+int add_txf_to_lnf(lnfno,txfno)
+int lnfno,txfno;
+{
+ int i,j,k,l,width;
+ int first_txfc,last_txfc;
+ char first_txf,last_txf;
+
+ ras_len_added = 0;
+
+ if (txfno < 0 || txfno > MAXTEXFONTS || txfa[txfno] == 0 ||
+ lnfno < 0 || lnfno > maxnfonts) {
+ fprintf(stderr,"\nLn03DVI internal error, bad txfno or lnfno\n");
+ goto error_return;
+ }
+
+/* Now, compute first_txfc and last_txfc, the first and last
+characters codes to be copied from the TeX font. */
+
+ first_txfc = -1; last_txfc = -1;
+ for (i=0; i<256; i++) {
+ if (txfa[txfno] -> chu[i] != 0) {
+ if (first_txfc == -1) first_txfc = i;
+ last_txfc = i;
+ }
+ }
+ if (first_txfc == -1 || last_txfc == -1) return(0);
+
+/* Tell user what font is being loaded */
+
+ printf("Font %s:\t",font_name[txfno]);
+ k = (1500.0*conv*txfa[txfno] -> scaled_size)/
+ (unmag_conv*txfa[txfno] -> design_size) + 0.5;
+ l = ((float)k)/15.0 + 0.5;
+ if (l != 100) printf("magnified %d%%, ",l);
+ fflush(stdout);
+
+/* Now open the file from which we are getting rasters. We
+look first for a PK file, the for a PXL file, and finally for a
+LN03 format font file (NFT file). */
+
+ pkfont = NULL;
+ pxlf = -1;
+ nftf = -1;
+ open_pk_file(txfno);
+ if (pkfont == NULL) open_pxl_file(txfno);
+ if (pkfont == NULL && pxlf == -1) open_nft_file(txfno);
+
+/* If neither a PXL file nor a PK file nor an LN03 format
+file could be opened, warn the user. The font load will be
+filled in with blanks nonetheless. */
+
+ if (pxlf == -1 && pkfont == NULL && nftf == -1) {
+ printf("not available, loading blanks, ");
+ fflush(stdout);
+ }
+
+/* Now replace first_txfc and last_txfc by the character
+codes into which they are going to be copied. */
+
+ first_txfc = txfa[txfno] -> chu[first_txfc];
+ last_txfc = txfa[txfno] -> chu[last_txfc];
+
+/* Determine if this is the first or last TeX font that is
+being copied into the current LN03 font pair. */
+
+ first_txf = (first_txfc == leftfirst);
+ last_txf = (last_txfc == lastch[lnfno]);
+
+/* If this is the first TeX font for the current LN03 font
+pair, then we have to initialize the LN03 font load buffer.
+The initialization routine computes where the rasters begin
+in the output buffer, puts in the blanks, etc. */
+
+ if (first_txf) {
+ using_r = 0;
+ initialize_lnf(lnfno);
+ }
+
+/* Now go through all the characters in the TeX font and
+copy their rasters into the appropriate positions in the
+LN03 font pair. When we copy the the last rasters into the
+left font, we write the font out and then a comma to
+separate it from the next font. [[Fencepost error?]] */
+
+ for (i=0; i<256; i++) {
+ if (txfa[txfno] -> chu[i] != 0) {
+ j = txfa[txfno] -> chu[i];
+ if (!using_r && j >= rightfirst) {
+ write_lnf();
+ fprintf(outfile,"\n,");
+ using_r = 1;
+ initialize_lnf(lnfno);
+ }
+ if (pxlf != -1) {
+ k = copy_pxl_char(i,j,lnfno);
+ if (k != 0) {
+ close(pxlf);
+ pxlf = -1;
+ }
+ } else if (nftf != -1) {
+ k = copy_nft_char(i,j,lnfno);
+ if (k != 0) {
+ close(nftf);
+ nftf = -1;
+ }
+ } else if (pkfont != NULL) {
+ k = copy_pk_char(pkfont,i,txfno,j,lnfno);
+ if (k != 0) {
+ PKUnloadFont(pkfont);
+ pkfont = NULL;
+ }
+ }
+ if (pxlf == -1 && pkfont == NULL && nftf == -1) {
+ width = font_width[txfno][i]*conv+0.5;
+ k = copy_ersatz_char(j,lnfno,width);
+ }
+ }
+ }
+
+ if (nftf != -1) close(nftf);
+ if (pxlf != -1) close(pxlf);
+ if (pkfont != NULL) PKUnloadFont(pkfont);
+
+/* Type and return the incremental amount of space that the
+TeX font being added takes up in the output font load. */
+
+ ras_len_added += 4*(txfa[txfno] -> nchs);
+ printf("%d bytes\n",ras_len_added);
+
+/* If this is the last TeX font being added to this LN03
+font pair, write out the current font (right or left) from
+the pair. */
+
+ if (last_txf) write_lnf();
+
+ return(0);
+
+error_return:
+ return(-1);
+
+}
+
+/* A buffer is used to hold the directory part of the PXL file. */
+
+#define PXLBUFSIZE 4*517
+
+GLOBAL unsigned char pxlbuf[PXLBUFSIZE];
+GLOBAL long pxllen;
+
+/* The value pxlconv is computed to be the correct
+conversion factor from the widths in the PXL file, which are
+expressed in units of 2^-20 times the design size, to
+pixels. */
+
+GLOBAL float pxlconv;
+
+/* As usual when dealing with TeX files, we have to
+rearrange bytes in an overlay to combine them into
+longwords. The reason for this is that bytes in TeX files
+are combined into longwords the opposite way from how the
+VAX combines them.
+
+Hence, the following overlay and macro: */
+
+GLOBAL union lc { unsigned long int ul;
+ long int l;
+ unsigned char c[4]; } lcy;
+
+#ifdef BIG_ENDIAN
+#define copy_from_lnf(i) lcy.c[3] = lnf[i]; lcy.c[2] = lnf[i+1]; \
+ lcy.c[1] = lnf[i+2]; lcy.c[0] = lnf[i+3]
+#define copy_to_lnf(i) lnf[i] = lcy.c[3]; lnf[i+1] = lcy.c[2]; \
+ lnf[i+2] = lcy.c[1] ; lnf[i+3] = lcy.c[0]
+#define copy_from_pxl(_x) { lcy.c[0] = pxlbuf[_x]; \
+ lcy.c[1] = pxlbuf[(_x)+1]; lcy.c[2] = pxlbuf[(_x)+2]; \
+ lcy.c[3] = pxlbuf[(_x)+3]; }
+#else /* not big endian */
+#define copy_from_lnf(i) lcy.c[0] = lnf[i]; lcy.c[1] = lnf[i+1]; \
+ lcy.c[2] = lnf[i+2]; lcy.c[3] = lnf[i+3]
+#define copy_to_lnf(i) lnf[i] = lcy.c[0]; lnf[i+1] = lcy.c[1]; \
+ lnf[i+2] = lcy.c[2] ; lnf[i+3] = lcy.c[3]
+#define copy_from_pxl(_x) { lcy.c[3] = pxlbuf[_x]; \
+ lcy.c[2] = pxlbuf[(_x)+1]; lcy.c[1] = pxlbuf[(_x)+2]; \
+ lcy.c[0] = pxlbuf[(_x)+3]; }
+#endif
+
+
+/* open_pxl_file reads the last 517 longwords of the PXL
+file into the pxlbuf. */
+
+int open_pxl_file(txfno)
+int txfno;
+{
+
+ long i,j;
+ float two_to_the_20th = 0x100000;
+ int k,l,jnam,jext,target;
+ char fullspec[FILESPECLEN];
+#ifndef vms
+ char *pxldir;
+#endif
+
+ find_filename(font_name[txfno],&jnam,&jext);
+
+ fullspec[0] = '\0';
+#ifdef vms
+ if (jnam == 0) strcpy(fullspec,"TEX$PXLDIR:");
+#else
+ if (jnam == 0) {
+#ifndef Apollo
+ pxldir = getenv("TEXPXLDIR");
+ if (pxldir == NULL)
+ pxldir = "/usr/lib/tex/pxldir";
+#else
+ pxldir = "/usr/lib/tex/pxl";
+#endif
+ strcpy(fullspec,pxldir);
+ if (fullspec[strlen(fullspec)-1] != '/')
+ strcat(fullspec,"/");
+ }
+#endif
+ strcat(fullspec,font_name[txfno]);
+
+ l = 1000.0 * ( (float) txfa[txfno]->scaled_size /
+ (float) txfa[txfno]->design_size ) + 0.5;
+ k = 0.5 + 1.5 * (conv / unmag_conv ) * (float) l ;
+
+ l = strlen(fullspec);
+ sprintf(&fullspec[l],".%dpxl\0",k);
+
+ pxllen = 0;
+ pxlf = open(fullspec,0);
+ if (pxlf == -1) return(1);
+ printf("loading PXL file %s%s, ",font_name[txfno],&fullspec[l]);
+ fflush(stdout);
+
+ lseek(pxlf,-517*4,2);
+ i = read(pxlf,pxlbuf,517*4);
+ if (i != 517*4) {
+ if (i < 0) {
+ fflush(stdout);
+ perror("error");
+ printf("\t\t");
+ } else
+ printf("error: premature EOF (%d)\n\t\t",i);
+ close(pxlf);
+ pxlf = -1;
+ return(1);
+ }
+ pxllen = 4*517;
+
+/* Now that we have read the PXL file, check that it is in
+correct format by looking for a trailing ID byte of 1001. */
+
+ copy_from_pxl(pxllen-4);
+ if (lcy.ul != 1001) {
+ printf("error: invalid .PXL id %d\n\t\t",lcy.ul);
+ close(pxlf);
+ pxlf = -1;
+ return(1);
+ }
+
+/* If the format is correct, derive a scale factor for the
+widths. */
+
+ copy_from_pxl(pxllen-12);
+ pxlconv = lcy.ul;
+ copy_from_pxl(pxllen-16);
+ pxlconv = (pxlconv/two_to_the_20th)*(lcy.ul/5.0)
+ *(1.0/(72.27*two_to_the_20th));
+/* printf( "pxlconv=%g, ",pxlconv ); fflush(stdout); /**/
+
+ return(0);
+
+}
+
+GLOBAL unsigned char rev_byte[256] = {
+ 0,128,64,192,32,160,96,224,
+ 16,144,80,208,48,176,112,240,
+ 8,136,72,200,40,168,104,232,
+ 24,152,88,216,56,184,120,248,
+ 4,132,68,196,36,164,100,228,
+ 20,148,84,212,52,180,116,244,
+ 12,140,76,204,44,172,108,236,
+ 28,156,92,220,60,188,124,252,
+ 2,130,66,194,34,162,98,226,
+ 18,146,82,210,50,178,114,242,
+ 10,138,74,202,42,170,106,234,
+ 26,154,90,218,58,186,122,250,
+ 6,134,70,198,38,166,102,230,
+ 22,150,86,214,54,182,118,246,
+ 14,142,78,206,46,174,110,238,
+ 30,158,94,222,62,190,126,254,
+ 1,129,65,193,33,161,97,225,
+ 17,145,81,209,49,177,113,241,
+ 9,137,73,201,41,169,105,233,
+ 25,153,89,217,57,185,121,249,
+ 5,133,69,197,37,165,101,229,
+ 21,149,85,213,53,181,117,245,
+ 13,141,77,205,45,173,109,237,
+ 29,157,93,221,61,189,125,253,
+ 3,131,67,195,35,163,99,227,
+ 19,147,83,211,51,179,115,243,
+ 11,139,75,203,43,171,107,235,
+ 27,155,91,219,59,187,123,251,
+ 7,135,71,199,39,167,103,231,
+ 23,151,87,215,55,183,119,247,
+ 15,143,79,207,47,175,111,239,
+ 31,159,95,223,63,191,127,255
+ };
+
+#define pxl_word(_x) (pxlbuf[_x]*256+pxlbuf[(_x)+1])
+#define signed_pxl_word(_x) ((pxl_word(_x)>0x8000) ? \
+ (pxl_word(_x)-0x10000) : pxl_word(_x))
+
+/* Copy_pxl_char copies the rasters and character directory
+information corresponding to code from in the PXL file, into
+the to position of the LN03 font load buffer. */
+
+int copy_pxl_char(from,to,lnfno)
+unsigned char from,to;
+int lnfno;
+{
+
+ unsigned long ds,rs,i,j,def_start;
+ unsigned int rows,cols,k,l,m,n;
+ int xoffset, yoffset;
+ int width;
+ char all_blank;
+
+/* Check if the character code from is in the right range
+for the PXL file. */
+
+ if (from > 127) return(1);
+
+/* Locate the definition and the rasters for from in the PXL
+file. */
+
+ ds = 16*from;
+ copy_from_pxl(ds+8);
+ rs = 4*lcy.ul;
+ cols = pxl_word(ds); rows = pxl_word(ds+2);
+
+/* If a glyph has no rasters, an "undocumented feature" of
+the LN03 seems to cause the glyph to be printed incorrectly.
+Because of this, we set the number of rows and columns to 1,
+and put in a blank byte (below). */
+
+ all_blank = ((rows == 0) & (cols == 0)) | rs == 0;
+ if (all_blank) {
+ cols = 1;
+ rows = 1;
+ }
+
+/* Compute the width of the glyph in pixels, the xoffset,
+and the yoffset. */
+
+ copy_from_pxl(ds+12);
+ width = pxlconv*lcy.ul+0.5;
+ xoffset = signed_pxl_word(ds+4);
+ yoffset = signed_pxl_word(ds+6);
+ chw[lnfno][to] = width;
+
+/* Check that we have enough room left in the LN03 font load
+buffer. Fudge factor of 3 added because the read below may
+read too much. */
+
+ def_start = ras_beg+ras_len;
+ if (def_start+rows*((cols+7)/32)+24+3 > OBUFLEN) {
+ fprintf(stderr,"no more room in LN03 font load buffer (%ld bytes long)\n",
+ OBUFLEN);
+ return(1);
+ }
+
+/* Clear the character definition area in the LN03 font load
+buffer. */
+
+ for(i=0; i<24+rows*((cols+7)/8); i++)
+ lnf[def_start+i] = 0;
+
+/* Set the fields in the first six longwords of the LN03
+font load character definition. The first assignment sets
+the so-called "flag flag", which must be always be set
+according to the Common Font File Format. A conversion
+factor of 24 is used in converting pixel values, because the
+values are supposed to be in centipoints in the LN03 font
+load, and if we assume there are 300 pixels in an inch, then
+there are 7200 centipoints in an inch. */
+
+ lnf[def_start+3] = 0x80;
+ lcy.ul = 24*width;
+ copy_to_lnf(def_start+4);
+ lcy.l = -24*xoffset;
+ copy_to_lnf(def_start+8);
+ lcy.l = -24*yoffset;
+ copy_to_lnf(def_start+12);
+
+/* The rasters are always placed in portrait into the LN03
+font load, with no use of run-length encoding. Thus, the
+orient field in the raster format will be 0, and the Type 1
+field is set to 0x81. */
+
+ lnf[def_start+17] = 0x81;
+ lnf[def_start+20] = rows%256;
+ lnf[def_start+21] = rows/256;
+ lnf[def_start+22] = cols%256;
+ lnf[def_start+23] = cols/256;
+
+/* Now we copy the rasters themselves. As we do so, we have
+to reverse the bits within each byte. */
+
+ k = (cols+31)/32;
+ n = (cols+7)/8;
+ lseek(pxlf,rs,0);
+ if (!all_blank) {
+ for (l=0; l<rows; l++) {
+ read(pxlf,&lnf[def_start+24+n*l],4*k);
+ }
+ for (m=0; m<n*rows; m++)
+ lnf[def_start+24+m] = rev_byte[lnf[def_start+24+m]];
+ }
+
+/* Set the character locator, increment the LN03 font load
+buffer length, and recompute the three sizes. */
+
+ lcy.l = def_start;
+ if (to <= leftlast) i = to-leftfirst; else i = to-rightfirst;
+ copy_to_lnf(lnf_chardir+4*i);
+ ras_len += 24+rows*n;
+ ras_len_added += 24+rows*n;
+ if (ras_len%2 == 1) {
+ lnf[ras_beg+ras_len] = 0;
+ ras_len++;
+ ras_len_added++;
+ }
+
+ i = rows*((cols+7)/8);
+ psize += i;
+ j = ((rows+7)/8)*cols;
+ lsize += j;
+ msize += (i > j) ? i : j;
+
+ return(0);
+}
+
+/* Write a blank character of specified width (in pixels)
+into LN03 font load buffer. Also, set the chw array. [[This
+function is a bit excessive. If we couldn't find a
+character's rasters, it would suffice just to leave the
+character locator blank.]] */
+
+int copy_ersatz_char(to,lnfno,width)
+unsigned char to;
+int lnfno,width;
+{
+
+ unsigned long ds,rs,i,j,def_start;
+ unsigned int rows,cols,k,l,m,n;
+
+ cols = 1;
+ rows = 1;
+ chw[lnfno][to] = width;
+
+/* Check that we have enough room left in the LN03 font load
+buffer. Return silently if not. */
+
+ def_start = ras_beg+ras_len;
+ if (def_start+rows*((cols+7)/32)+24 > OBUFLEN) return(1);
+
+/* Clear the character definition area in the LN03 font load
+buffer. */
+
+ for(i=0; i<24+rows*((cols+7)/8); i++)
+ lnf[def_start+i] = 0;
+ lnf[def_start+3] = 0x80;
+ lcy.ul = 24*width;
+ copy_to_lnf(def_start+4);
+
+/* The rasters are always placed in portrait into the LN03
+font load, with [no use of run-length encoding. Thus, the
+orient field in the raster format will be 0, and the Type 1
+field is set to 0x81. */
+
+ lnf[def_start+17] = 0x81;
+ lnf[def_start+20] = rows%256;
+ lnf[def_start+21] = rows/256;
+ lnf[def_start+22] = cols%256;
+ lnf[def_start+23] = cols/256;
+
+/* Set the character locator, increment the LN03 font load
+buffer length, and recompute the three sizes. */
+
+ n = (cols+7)/8;
+ lcy.l = def_start;
+ if (to <= leftlast) i = to-leftfirst; else i = to-rightfirst;
+ copy_to_lnf(lnf_chardir+4*i);
+ ras_len += 24+rows*n;
+ ras_len_added += 24+rows*n;
+ if (ras_len%2 == 1) {
+ lnf[ras_beg+ras_len] = 0;
+ ras_len++;
+ ras_len_added++;
+ }
+
+ i = rows*((cols+7)/8);
+ psize += i;
+ j = ((rows+7)/8)*cols;
+ lsize += j;
+ msize += (i > j) ? i : j;
+
+ return(0);
+}
+
+/* The opening part of each NFT file is copied into the
+array nfta. Nftlen keeps track of how much of the NFT file
+we have read. Nftf is the file descriptor used to do the
+reading. */
+
+GLOBAL unsigned char nfta[480+1024];
+GLOBAL long nftlen;
+
+#define copy_from_nft(i) lcy.c[0] = nfta[i]; lcy.c[1] = nfta[i+1]; \
+ lcy.c[2] = nfta[i+2]; lcy.c[3] = nfta[i+3]
+
+/* Open_nft_file opens the NFT file and reads the opening
+part into the NFT array. */
+
+int open_nft_file(txfno)
+int txfno;
+{
+ int k,l,jnam,jext,target;
+ char fullspec[FILESPECLEN];
+#ifndef vms
+ char *ln3dir;
+#endif
+
+ find_filename(font_name[txfno],&jnam,&jext);
+
+ fullspec[0] = '\0';
+#ifdef vms
+ if (jnam == 0) strcpy(fullspec,"TEX$LN03DIR:");
+#else
+ if (jnam == 0) {
+#ifndef Apollo
+ ln3dir = getenv("TEXLN03DIR");
+#else
+ ln3dir = "/usr/lib/tex/ln03";
+#endif
+ strcpy(fullspec,ln3dir);
+ strcat(fullspec,"/");
+ }
+#endif
+ strcat(fullspec,font_name[txfno]);
+ k = (100.0*conv*txfa[txfno] -> scaled_size)/
+ (unmag_conv*txfa[txfno] -> design_size) + 0.5;
+ l = strlen(fullspec);
+ if (k == 100) strcat(fullspec,".nft");
+ else {
+ if (k < 1000) sprintf(&fullspec[l],".%03d\0",k);
+ else sprintf(&fullspec[l],".%d\0",k);
+ }
+
+ nftlen = 0;
+ nftf = open(fullspec,0);
+ if (nftf == -1) return(1);
+ printf("loading NFT file %s%s, ", font_name[txfno],&fullspec[l]);
+ fflush(stdout);
+
+ if (read_nft_with_retry(nfta,480) != 0) {
+ close(nftf);
+ nftf = -1;
+ return(1);
+ }
+
+/* The NFT file might be random, or it might be a Common
+Font File Format file that isn't loadable into an LN03. So,
+we make a few checks.
+
+The second longword must be 'FONT'. */
+
+ if (nfta[4] != 'F' || nfta[5] != 'O' || nfta[6] != 'N'
+ || nfta[7] != 'T') {
+ printf("error: Bad NFT file, lacks FONT.\n\t\t");
+ close(nftf);
+ nftf = -1;
+ return(1);
+ }
+
+/* We also check that there are a full 16 bytes of character
+parameters. If there are fewer, we give up: LN03s need all
+sixteen, and it's too hard to figure out how to give the
+missing ones reasonable values.
+
+Throughout this program, we define some constants beginning
+with fnt__ which define byte offsets into the nft file.
+[[The long prefixes of these may cause some trouble if one's
+C compiler does not recognize too many significant
+characters in identifiers.]] */
+
+#define fnt__l_parameters_size 200
+
+ copy_from_nft(fnt__l_parameters_size);
+ if (lcy.l != 16) {
+ printf(" error: bad NFT file, not enough character parameters\n\t\t");
+ close(nftf);
+ nftf = -1;
+ return(1);
+ }
+
+/* Set the variable that tells us the starting location of
+the character directory. */
+
+ chardir_offset = 480;
+
+/* Figure out what the first and last character codes in the
+NFT file are. */
+
+#define fnt__l_first_character 164
+
+ copy_from_nft(fnt__l_first_character);
+ nft_first_ch = lcy.l;
+ copy_from_nft(fnt__l_first_character+4);
+ nft_last_ch = lcy.l;
+
+/* We must have 0 <= nft_first_ch <= nft_last_ch <= 255,
+otherwise we give up on the NFT file. */
+
+ if (!((0 <= nft_first_ch) && (nft_first_ch <= nft_last_ch) &&
+ (nft_last_ch <= 255))) {
+ printf(" error: bad NFT file, bad character range.\n\t\t");
+ close(nftf);
+ nftf = -1;
+ return(1);
+ }
+
+/* Now read the character directory into the nfta. */
+
+ target = chardir_offset+4*(nft_last_ch+1-nft_first_ch);
+ if (read_nft_with_retry(&nfta[480],target) != 0) {
+ close(nftf);
+ nftf = -1;
+ return(1);
+ }
+ return(0);
+}
+
+/* Copy_nft_char copies the character parameters and rasters
+corresponding to the from argument out of the NFT file and
+into the LN03 font buffer. It also updates the chw
+(character width) array. */
+
+int copy_nft_char(from,to,lnfno)
+unsigned char from,to;
+int lnfno;
+{
+
+ int rows,columns,quo;
+ long i,j,len,def_start,target;
+
+/* Replace from by the first character code if the NFT file
+has no rasters for code from. If this is done, the output
+will of course be mangled. The user has already been warned
+above, so no further message is needed. */
+
+ if (from < nft_first_ch) from = nft_first_ch;
+ if (from > nft_last_ch) from = nft_last_ch;
+
+/* First we need to determine def_start, the byte offset of
+the character definition for code from in the NFT file */
+
+ copy_from_nft(chardir_offset+(from-nft_first_ch)*4);
+ def_start = lcy.l;
+
+/* If the locator is earlier in the file, just give up. Otherwise, assume
+it's good, continue and give a vague error message is something goes wrong.
+*/
+
+ if (def_start < nftlen || read_nft_until(def_start) != 0) {
+ printf(" -- LN03 font file bad, using blanks\n");
+ return(1);
+ }
+
+/* Read the first 24 bytes of character data. */
+
+ def_start = ras_beg+ras_len;
+ if (read_nft_with_retry(&lnf[def_start],nftlen+24) != 0) return(1);
+
+/* Now we need to check that the rasters are uncompressed.
+LN03s can't accept compressed rasters, and this program
+isn't clever enough to decompress them. */
+
+ if (lnf[def_start+17] != 129) {
+ printf(" -- LN03 font file bad, using blanks\n");
+ return(1);
+ }
+
+/* Fill in the chw array (which holds character widths).
+Centipoint to pixel conversion is necessary (there are 24
+centipoints in a pixel), with rounding (hence the 12). */
+
+ copy_from_lnf(def_start+4);
+ chw[lnfno][to] = (lcy.l+12)/24;
+
+/* NFT files may contain character widths which are not
+integral numbers of pixels. It is necessary to round such
+values to pixels when copying into the final font load -- if
+sent unrounded to the LN03, the widths will be truncated and
+positions will be off in the printed output. */
+
+ lcy.l = 24*chw[lnfno][to];
+ copy_to_lnf(def_start+4);
+
+/* Now we need to compute the size of the rasters, and copy
+that number of bytes into the LN03 font buffer. */
+
+ rows = lnf[def_start+20]+256*lnf[def_start+21];
+ columns = lnf[def_start+22]+256*lnf[def_start+23];
+
+/* We have to update psize, lsize and msize to fill slots in
+the format. */
+
+ quo = rows/8;
+ if (rows != quo*8) quo++;
+ i = quo*columns;
+ lsize += quo*columns;
+ quo = columns/8;
+ if (columns != quo*8) quo++;
+ psize += quo*rows;
+ if (i > quo*rows) msize += i; else msize += quo*rows;
+
+/* Now do the actual copy. We have to ensure that the rasters are
+word-aligned in the font load (where one word = 2 bytes, of course). */
+
+ if (lnf[def_start+16] % 2 == 0) len = quo*rows; else len = i;
+ if (read_nft_with_retry(&lnf[def_start+24],nftlen+len) != 0)
+ return(1);
+ lcy.l = def_start;
+ if (to <= leftlast) i = to-leftfirst; else i = to-rightfirst;
+ copy_to_lnf(lnf_chardir+4*i);
+ ras_len += len+24;
+ ras_len_added += len+24;
+ if (ras_len % 2 != 0) {
+ lnf[ras_beg+ras_len] = 0;
+ ras_len++;
+ ras_len_added++;
+ }
+ return(0);
+
+}
+
+int read_nft_with_retry(where,upto)
+long upto;
+char *where;
+{
+ long i,target;
+ int l;
+
+ i = 0;
+ while (nftlen < upto) {
+ target = upto-nftlen;
+ l = read(nftf,&where[i],target);
+ if (l <= 0) {
+ printf(" -- LN03 font file bad, using blanks\n");
+ return(1);
+ }
+ nftlen += l;
+ i += l;
+ }
+ return(0);
+}
+
+int read_nft_until(pos)
+long pos;
+{
+ char bit_bucket[512];
+ int l;
+ long target;
+
+ while (nftlen < pos) {
+ target = pos-nftlen;
+ if (target > 512) target = 512;
+ l = read(nftf,bit_bucket,target);
+ if (l <= 0) {
+ printf(" -- LN03 font file bad, using blanks\n");
+ return(1);
+ }
+ nftlen += l;
+ }
+ return(0);
+}
+
+GLOBAL unsigned char preline[96];
+
+/* write_lnf performs the last fixups to the LN03 fnnt buffer and dumps it,
+sixelized, into the output file. */
+
+int write_lnf (){
+
+ long i,j,k,rem,quo,ma;
+
+/* We now have to fix a number of slots: size of file, length of rasters,
+final 'FONT', psize, lsize, msize. */
+
+ lcy.l = ras_beg+ras_len+8;
+ copy_to_lnf(0);
+ copy_to_lnf(lcy.l-8);
+ lnf[lcy.l-4] = 'F';
+ lnf[lcy.l-3] = 'O';
+ lnf[lcy.l-2] = 'N';
+ lnf[lcy.l-1] = 'T';
+
+/* Clear out remaining bytes up to 96 more. */
+
+ j = 96*((lcy.l+95)/96);
+ for (i=lcy.l; i<j; i++) lnf[i] = 0;
+
+/* Length of rasters */
+
+#define fnt__l_char_definitions_length 156
+
+ lcy.l = ras_len;
+ copy_to_lnf(fnt__l_char_definitions_length);
+
+#define fnt__l_portrait_byte_count 228
+#define fnt__l_landscape_byte_count 232
+#define fnt__l_mixed_byte_count 236
+
+ lcy.l = psize;
+ copy_to_lnf(fnt__l_portrait_byte_count);
+
+ lcy.l = lsize;
+ copy_to_lnf(fnt__l_landscape_byte_count);
+
+ lcy.l = msize;
+ copy_to_lnf(fnt__l_mixed_byte_count);
+
+/* Now sixelize and write the contents of LNF. */
+
+ sixelize_and_write(ras_beg+ras_len+8);
+ return(0);
+}
+
+int sixelize_and_write(howmuch)
+int howmuch;
+{
+ int quo,i,j;
+
+ quo = howmuch/96;
+ if (howmuch > quo*96) quo++;
+
+ for (i=0; i<quo; i++) {
+ for (j=0; j<96; j++)
+ preline[j] = lnf[96*i+j];
+ write_preline();
+ }
+
+}
+
+int write_preline() {
+
+ char sixel_line[129];
+ int i,j,ix,pllen;
+ unsigned v,w;
+
+ pllen = 96;
+ ix = 0;
+ sixel_line[128] = '\0';
+ for (i=0; i<128; i++) sixel_line[i] = '?';
+ for (i=0; i<pllen; i += 3) {
+ v = preline[i];
+ w = v>>2;
+ sixel_line[ix] = 63+w;
+ ix++;
+ w = (v&3)<<4;
+ v = preline[i+1];
+ w |= v>>4;
+ sixel_line[ix] = 63+w;
+ ix++;
+ w = (v&15)<<2;
+ v = preline[i+2];
+ w |= v>>6;
+ sixel_line[ix] = 63+w;
+ ix++;
+ w = v&63;
+ sixel_line[ix] = 63+w;
+ ix++;
+ }
+ fprintf(outfile,"\n%s",sixel_line);
+}
+
+/* Initializes the LN03 font buffer. */
+
+int initialize_lnf(lnfno)
+int lnfno;
+{
+ int i,j;
+
+/* The following array holds reasonable values for bytes 0-479 of an LN03
+format font. These bytes were copied from a font load which the LN03 was
+known to accept. The font loads generated by this program are initialized
+using these values. Some of them are overwritten later, however. */
+
+ static char good_opening[512] = {
+ 104,38,0,0,70,79,78,84,
+ 1,0,0,0,31,0,0,0,
+ 20,0,0,0,85,48,48,48,
+ 48,48,48,48,48,50,83,75,
+ 48,48,71,71,48,48,48,49,
+ 85,90,90,90,90,48,50,70,
+ 48,48,48,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 181,7,9,0,11,0,14,0,
+ 0,0,0,0,104,0,0,0,
+ 252,0,0,0,124,0,0,0,
+ 100,1,0,0,120,1,0,0,
+ 224,1,0,0,4,0,0,0,
+ 88,3,0,0,0,0,0,0,
+ 92,3,0,0,48,0,0,0,
+ 92,3,0,0,0,0,0,0,
+ 140,3,0,0,212,34,0,0,
+ 140,3,0,0,33,0,0,0,
+ 126,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 32,0,0,0,168,0,0,0,
+ 16,0,0,0,94,0,0,0,
+ 0,0,0,0,94,0,0,0,
+ 0,0,0,0,94,0,0,0,
+ 0,0,0,0,236,25,0,0,
+ 54,25,0,0,14,27,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,2,0,0,0,
+ 7,0,0,0,92,3,0,0,
+ 7,0,0,0,99,3,0,0,
+ 16,0,0,0,106,3,0,0,
+ 16,0,0,0,122,3,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 10,0,0,0,244,1,0,0,
+ 0,0,24,0,16,0,0,0,
+ 16,0,0,0,1,0,1,0,
+ 1,0,1,0,0,0,1,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 30,0,0,0,20,0,0,0,
+ 196,255,255,255,20,0,0,0,
+ 106,255,255,255,20,0,0,0,
+ 0,0,1,0,0,0,30,0,
+ 166,255,255,255,0,0,0,0,
+ 40,0,0,0,0,0,0,0,
+ 60,0,0,0,240,0,0,0,
+ 60,0,0,0,100,0,0,0,
+ 240,0,0,0,120,0,0,0,
+ 40,0,0,0,120,0,0,0,
+ 96,255,255,255,136,255,255,255,
+ 186,255,255,255,240,0,0,0,
+ 76,255,255,255,60,0,0,0,
+ 160,0,0,0,120,0,0,0,
+ 20,0,0,0,20,0,0,0,
+ 140,3,0,0,194,3,0,0,
+ 244,3,0,0,160,4,0,0,
+ 254,4,0,0,162,5,0,0,
+ 46,6,0,0,84,6,0,0};
+ int pool_beg;
+
+/* The character directory always begins at position 480 in the Common
+Font File Format. */
+
+ lnf_chardir = 480;
+ ras_len = 0;
+ psize = 0;
+ lsize = 0;
+ msize = 0;
+
+/* Copy the good values into the lnf array */
+
+ for (i=0; i<480; i++)
+ lnf[i] = good_opening[i];
+
+/* Set the last character if necessary */
+
+#define fnt__l_first_character 164
+
+ if (lastch[lnfno] < leftlast && !using_r)
+ lnf[fnt__l_first_character+4] = lastch[lnfno];
+ if (using_r)
+ lnf[fnt__l_first_character+4] = lastch[lnfno]-rightfirst+
+ leftfirst;
+
+/* Set the character counts */
+
+#define fnt__l_infile_locators 204
+#define fnt__l_character_definitions 212
+#define fnt__l_raster_count 220
+
+ i = lnf[fnt__l_first_character+4]-
+ lnf[fnt__l_first_character]+1;
+ ras_beg = lnf_chardir + 4*i + 4 + 48;
+ lnf[fnt__l_infile_locators] = i;
+ lnf[fnt__l_character_definitions] = i;
+ lnf[fnt__l_raster_count] = i;
+ lnf[ras_beg-52] = lnf[ras_beg-51] = lnf[ras_beg-50] =
+ lnf[ras_beg-49] = 0;
+
+/* Set the font file id. This id is a 31-byte string. We make it depend on
+the lnfno number, and on whether this is a left or right font.
+Specifically, the first seven bytes are U0000nn where nn is lnfno possibly
+with a leading zero. The character set part of the ID is 1O if using_r,
+otherwise the default from good_opening. */
+
+#define fnt__t_font_file_id 20
+
+ lnf[fnt__t_font_file_id+5] = lnfno/10+'0';
+ lnf[fnt__t_font_file_id+6] = lnfno % 10 + '0';
+ if (using_r) lnf[fnt__t_font_file_id+20] = 'O';
+
+/* We now have to set some fields in the font format that are pointers to
+where other fields begin. These pointers depend on the number of glyphs we
+are placing in the font file. */
+
+#define fnt__a_subset_tables 128
+
+ lcy.l = lnf_chardir+4*i;
+ copy_to_lnf(fnt__a_subset_tables);
+
+ lcy.l = lcy.l+4;
+ copy_to_lnf(fnt__a_subset_tables+8);
+ copy_to_lnf(fnt__a_subset_tables+16);
+
+ lcy.l = lcy.l+48;
+ copy_to_lnf(fnt__a_subset_tables+24);
+
+#define fnt__a_char_definitions 160
+
+ copy_to_lnf(fnt__a_char_definitions);
+
+/* Set up the string pool region of the font load (48 bytes). The only
+tricky part here is the character set designator at the very beginning of
+the pool. Left fonts use one designator, right fonts another. [[More
+explanation is needed.]] */
+
+ pool_beg = ras_beg-48;
+
+ lnf[pool_beg] = '0';
+ lnf[pool_beg+1] = using_r ? '<':'B';
+ lnf[pool_beg+2] = '\011'; /* ascii tab */
+ lnf[pool_beg+3] = 'Z';
+ lnf[pool_beg+4] = 'Z';
+ lnf[pool_beg+5] = 'Z';
+ lnf[pool_beg+6] = 'Z';
+
+/* For reasons that are beyond my comprehension, the Common Font File
+Format requires us to copy the first seven characters of the font file id
+into one piece of the string pool, and the first sixteen into another
+place. */
+
+ for (i=1; i<8; i++)
+ lnf[pool_beg+7+i-1] = lnf[fnt__t_font_file_id+i-1];
+ for (i=1; i<17; i++)
+ lnf[pool_beg+7+7+i-1] = ' ';
+ for (i=1; i<17; i++)
+ lnf[pool_beg+7+7+16+i-1] = lnf[fnt__t_font_file_id+i-1];
+ lnf[pool_beg+46] = lnf[pool_beg+47] = 0;
+
+/* Now make string descriptors point into the string pool. */
+
+#define fnt__a_char_set 260
+#define fnt__a_family_id 268
+#define fnt__a_family_name 276
+#define fnt__a_font_id 284
+
+ lcy.l = pool_beg;
+ copy_to_lnf(fnt__a_char_set);
+ lcy.l = pool_beg+7;
+ copy_to_lnf(fnt__a_family_id);
+ lcy.l = pool_beg+7+7;
+ copy_to_lnf(fnt__a_family_name);
+ lcy.l = pool_beg+7+7+16;
+ copy_to_lnf(fnt__a_font_id);
+
+/* Mercifully, all remaining font file slots that we can fill now are
+already good as received from good_opening. */
+
+}
+
+
+/* There are only two global entry points to this code. here they are: */
+
+extern int open_pk_file();
+extern int copy_pk_char();
+
+/* We use the following global variables (that were previously defined). */
+
+EXTERN PKFont *pkfont; /* in open_pk_file */
+static float pkconv; /* conversion factor */
+
+/* This routine opens the PK file. It really is just a jacket for the
+routine PKLoadFont We also calculate the conversion factor (pkconv).
+
+Much of this routine is taken or adapted from open_pxl_file. */
+
+
+int open_pk_file(txfno)
+int txfno;
+{
+ float two_to_the_20th = 0x100000;
+ int magnification;
+
+ magnification = 1000.0 * ( (float) txfa[txfno]->scaled_size /
+ (float) txfa[txfno]->design_size ) + 0.5;
+
+ pkfont = PKLoadFont( font_name[txfno], magnification, 300 );
+ if (pkfont == NULL) {
+ if (errno != ENOENT && errno != ENXIO)
+ fprintf( stderr, "%s\n\t\t", PKerror );
+ return(-1);
+ }
+ printf("loading PK file %s, ", PKerror); fflush(stdout);
+
+ pkconv = ( (float) pkfont->design_size * (float) pkfont->magnification ) /
+ ( 5.0 * 72.27 * two_to_the_20th * two_to_the_20th );
+#ifdef PKDEBUG
+ printf( "pkconv=%g, ", pkconv ); fflush(stdout);
+#endif
+ return(0);
+}
+
+
+/* This routine obtains a glyph from a PK font then copies it to the LN03
+buffer. If the glyph isn't in the font, then we call copy_ersatz_char
+to insert a blank character. This routine has greatly adapted and/or
+stolen code from copy_pxl_char. */
+
+copy_pk_char(fontptr,from,txfno,to,lnfno)
+PKFont *fontptr;
+unsigned char from,to;
+int txfno,lnfno;
+{
+ PKGlyph *glyphptr;
+ int i,j, bytes_per_row, def_start = ras_beg + ras_len;
+ int tfm_width, width;
+
+ glyphptr = PKGetGlyph( fontptr, (int) from ); /* get the glyph */
+
+ if (glyphptr == NULL) { /* not there? */
+ width = font_width[txfno][from]*conv + 0.5; /* insert a */
+ return copy_ersatz_char(to,lnfno,width); /* blank */
+ } else if (strlen(PKerror) != 0) { /* error? */
+ printf("%s\n\t\t",PKerror); /* print it out */
+ }
+
+ if (glyphptr->height == 0 || glyphptr->width == 0) { /* kludge for LN03 */
+ width = font_width[txfno][from]*conv + 0.5; /* insert a blank */
+ return copy_ersatz_char(to,lnfno,width);
+ }
+
+/* Copy the rasters to the LN03 buffer. First zero the LN03 glyph header
+and the copy the rasters. */
+
+ bytes_per_row = (glyphptr->width + 7) / 8;
+
+ for (i = 0; i < 24; i++ )
+ lnf[def_start+i] = 0;
+
+ for (i = 0; i < glyphptr->height*bytes_per_row; i++ )
+ lnf[def_start+i+24] = glyphptr->rasters[i];
+
+/* Fill in the header for the LN03 glyph */
+
+ tfm_width = glyphptr->tfm_width*pkconv + 0.5;
+ chw[lnfno][to] = glyphptr->h_escapement / 65536;
+#ifdef PKDEBUG
+ if (tfm_width != chw[lnfno][to]) {
+#ifdef vms
+ globalvalue SS$_DEBUG;
+ LIB$SIGNAL(SS$_DEBUG);
+#else
+ abort();
+#endif
+ }
+#endif
+
+
+ lnf[def_start+3] = 0x80;
+ lcy.ul = 24*chw[lnfno][to]; copy_to_lnf(def_start+4);
+ lcy.l = -24*glyphptr->h_offset; copy_to_lnf(def_start+8);
+ lcy.l = -24*glyphptr->v_offset; copy_to_lnf(def_start+12);
+
+ lnf[def_start+17] = 0x81;
+ lnf[def_start+20] = glyphptr->height%256;
+ lnf[def_start+21] = glyphptr->height*256;
+ lnf[def_start+22] = glyphptr->width%256;
+ lnf[def_start+23] = glyphptr->width*256;
+
+/* The following is copy directly from copy_pxl_char. I have no idea what
+it is really for... */
+
+ { int i, j;
+ lcy.l = def_start;
+ if (to <= leftlast) i = to-leftfirst; else i = to-rightfirst;
+ copy_to_lnf(lnf_chardir+4*i);
+ ras_len += 24 + glyphptr->height*bytes_per_row;
+ ras_len_added += 24 + glyphptr->height*bytes_per_row;
+ if (ras_len%2 == 1) {
+ lnf[ras_beg+ras_len] = 0;
+ ras_len++;
+ ras_len_added++;
+ }
+
+ i = glyphptr->height*((glyphptr->width+7)/8);
+ psize += i;
+ j = ((glyphptr->height+7)/8)*glyphptr->width;
+ lsize += j;
+ msize += (i > j) ? i : j;
+ }
+ return(0);
+}