From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- dviware/ln03/rose/dvi2ln3nft.c | 1145 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1145 insertions(+) create mode 100644 dviware/ln03/rose/dvi2ln3nft.c (limited to 'dviware/ln03/rose/dvi2ln3nft.c') diff --git a/dviware/ln03/rose/dvi2ln3nft.c b/dviware/ln03/rose/dvi2ln3nft.c new file mode 100644 index 0000000000..dd6e0983b1 --- /dev/null +++ b/dviware/ln03/rose/dvi2ln3nft.c @@ -0,0 +1,1145 @@ +/* This file contains those portions of Dvi2ln3 that create font loads. It +is still being developed... + +Copyright (c) 1983, 1984, 1985, 1986 by Digital Equipment Corporation. +Author: Flavio Rose, ...!decwrl!dec-rhea!dec-dvinci!rose. + +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. + +*/ + +/* 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 +#else +#include +#endif + +/* 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 + +/* The following symbols are declared compatibly with those in the file +Dvi2ln3.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 float 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; + +/* The purpose of add_txf_to_lnf is to read the PXL 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) { + printf("\nDvi2ln3 internal error, bad txfno or lnfno"); + 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("\nLoading font %s",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); + +/* Now open the file from which we are getting rasters. We look first for a +PXL file, then for an LN03 format font file (NFT file). */ + + pxlf = -1; + nftf = -1; + open_nft_file(txfno); + if (nftf == -1) open_pxl_file(txfno); + +/* If neither a PXL 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 && nftf == -1) + printf("\n Couldn't find good font file: using blanks"); + +/* 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; + } + } + if (pxlf == -1 && 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 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(); + +/* 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",ras_len_added); + + 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; + +#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]; } + +/* 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) { + pxldir = getenv("TEX_PXLDIR"); + strcpy(fullspec,pxldir); + strcat(fullspec,"/"); + } +#endif + strcat(fullspec,font_name[txfno]); + k = (1500.0*conv*txfa[txfno] -> scaled_size)/ + (unmag_conv*txfa[txfno] -> design_size) + 0.5; + l = strlen(fullspec); + sprintf(&fullspec[l],".%dpxl\0",k); + + pxllen = 0; + pxlf = open(fullspec,0); + if (pxlf == -1) return(1); + + lseek(pxlf,-517*4,2); + i = read(pxlf,pxlbuf,517*4); + if (i != 517*4) { + printf("\n Error while reading PXL file"); + 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("\n Error while reading PXL file"); + 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)); + 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) { + printf("\nNo more room in LN03 font load buffer (%ld bytes long)", + 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 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) { + ln3dir = getenv("TEX_LN03DIR"); + 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; + if (k == 100) strcat(fullspec,".nft"); + else { + l = strlen(fullspec); + 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); + + 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(" -- Bad NFT file, lacks FONT."); + 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(" -- bad NFT file, not enough character parameters"); + 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(" -- bad NFT file, bad character range."); + 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("\n LN03 font file bad, using blanks"); + 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("\n LN03 font file bad, using blanks"); + 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("\n LN03 font file bad, using blanks"); + 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("\n LN03 font file bad, using blanks"); + return(1); + } + nftlen += l; + } + return(0); +} + +GLOBAL unsigned char preline[96]; + +/* write_lnf performs the last fixups to the LN03 font 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 quo*96) quo++; + + for (i=0; i>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. */ + +} -- cgit v1.2.3