diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/kane/dvijep_p |
Initial commit
Diffstat (limited to 'dviware/kane/dvijep_p')
-rw-r--r-- | dviware/kane/dvijep_p | 1189 |
1 files changed, 1189 insertions, 0 deletions
diff --git a/dviware/kane/dvijep_p b/dviware/kane/dvijep_p new file mode 100644 index 0000000000..da0d36a1fc --- /dev/null +++ b/dviware/kane/dvijep_p @@ -0,0 +1,1189 @@ + +Date: 20-MAR-1989 17:19:34 GMT +From: PHYOKANE@CS8700.UCG.IE +To: abbottp@ASTON.AC.UK +Subject: file dvijep_p +sender: hea"phyokane@cs8700.ucg.ie" <phyokane@cs8700.ucg.ie> + +/*-->dvipp8*/ +/**********************************************************************/ +/******************************* dvipp8 *******************************/ +/**********************************************************************/ + +#include "dvihead.h" + +/*********************************************************************** +***********************************************************************/ + +/**********************************************************************/ +/************************ Device Definitions ************************/ +/**********************************************************************/ + +/* All output-device-specific definitions go here. This section must +be changed when modifying a dvi driver for use on a new device */ + +#undef HPJETPLUS +#define HPJETPLUS 1 /* conditional compilation flag */ + +#define VERSION_NO "2.10" /* DVI driver version number */ + +#define DEVICE_ID "Hewlett Packard Laserjet+ laser printer" + /* this string is printed at runtime */ + +#define OUTFILE_EXT "jep" + +#define BYTE_SIZE 8 /* output file byte size */ + +#undef STDRES +#define STDRES 1 /* to get standard font resolution */ + +#define MAXLINE 4096 /* maximum input file line size */ + /* it is needed only in special() */ + +#define MAXPAGEFONTS 16 /* silly limit on fonts/page */ + +#define FIRSTPRINTERFONT 16 /* Lowest font number used */ +#define LASTPRINTERFONT 31 /* Highest font number used */ + +#define XDPI 300 /* horizontal dots/inch */ +#define XPSIZE 9 /* horizontal paper size in inches */ +#define XSIZE (((XDPI*XPSIZE+2*HOST_WORD_SIZE-1)/\ + (2*HOST_WORD_SIZE))*(2*HOST_WORD_SIZE)) + /* number of horizontal dots; */ + /* MUST BE multiple of */ + /* 2*HOST_WORD_SIZE */ + +#define YDPI 300 /* vertical dots/inch */ +#define YPSIZE 11 /* vertical paper size in inches */ +#define YSIZE 4096 /* number of vertical dots */ + +#define XORIGIN 60 /* measured pixel coordinates of */ +#define YORIGIN 15 /* page origin (should be at (0,0) */ + +/*********************************************************************** +Define some useful shorthand macros for all required LaserJet Plus +commands. With the exception of the CREATEFONT and DOWNLOADCHAR macros, +which require extra data, NO escape sequences appear anywhere else in +the text. + +The LaserJet Plus allows coordinates in dots as well as the decipoints +supported by the regular LaserJet. Dot coordinates are more convenient, +so we use them exclusively. The Plus puts the page origin in the upper- +left corner, while we have it in the lower-left corner, so MOVEY adjusts +the coordinate accordingly. + +With 7-bit fonts, only characters 33..127 are printable, and with 8-bit fonts, +33..127 and 160..255 are printable. Since TeX assumes characters 0..255 are +available, but 0..127 are used most often, we remap character numbers in 0..32 +to 191..223, and 128..159 to 224..255, and use 8-bit fonts. The macros +conceal the remapping. This means that 191..255 are not available for +downloading to: these characters are handles by raster graphics. + +Whenever possible, escape sequences are combined and 0 parameters +omitted, in order to compress the output. +***********************************************************************/ + +/* Begin raster graphics .. {transfer raster graphics} .. end raster graphics */ +#define BEGIN_RASTER_GRAPHICS OUTS("\033*t300R\033*r1A") + +/* CREATE_FONT must be followed by a 26-byte font header (see readfont) */ +#define CREATE_FONT OUTS("\033\051s26W") + +#define DELETE_ALL_FONTS OUTS("\033*c1F") + +#define SELECT_ROMAN8 + +/* DOWNLOAD_CHARACTER is not a complete specification---it must be followed by +two-byte values of xoff, yoff, width, height, deltax */ +#define DOWNLOAD_CHARACTER(nbytes) OUTF("\033\050s%dW",(nbytes)+16) + +/* End raster graphics */ +#define END_RASTER_GRAPHICS OUTS("\033*rB") + +/* Map characters */ +#define MAP_CHAR(c)\ + (((c) < 33) ? ((c) + 191) :\ + (((c) < 128) ? (c) :\ + (((c) < 160) ? ((c) + 96) : (c)))) + +#define BAD_CHAR(c) ((c) > 255) + +/* Move absolute to (x,y), page origin in lower left corner */ +#define MOVETO(x,y) OUTF2("\033*p%dx%dY",(x),YSIZE-(y)) + +/* Move absolute to (x,current y), page origin in lower left corner */ +#define MOVEX(x) OUTF("\033*p%dX",(x)) + +/* Move absolute to (current x,y), page origin in lower left corner */ +#define MOVEY(y) OUTF("\033*p%dY",YSIZE-(y)) + +/* Output TeX character number with mapping to HP LaserJet Plus number */ +#define OUT_CHAR(c) OUTC(MAP_CHAR(c)) + +/* Output a 16-bit binary number in two bytes */ +#define OUT16(n) {OUTC((n)>>8); OUTC((n));} + +/* Eject a page from the printer--this is the last command on each page */ +#define PAGEEJECT OUTC('\f') + +/* Reset printer at job start. <ESC>E is global reset which clears +everything but permanent fonts, which we do not use. <ESC>&l0E resets +left margin to 0. <ESC>&a0L resets top margin to 0. Without these, +default margins are supplied which lie inside page. Unfortunately, +these do not permit negative values, so we have to further correct the +origin with (XORIGIN, YORIGIN) defined above; these bias (lmargin, +tmargin) set in dviinit(). */ +#define RESET_PRINTER OUTS("\033E\033&lE\033&aL") +#define RESET_PRINTER_END /* OUTS("\033E") */ + +/* Move relative by (delx,dely) from current point */ +#define RMOVETO(delx,dely) {\ +if ((delx) == 0)\ + RMOVEY(dely)\ +else if ((dely) == 0)\ + RMOVEX(delx)\ +else\ + OUTF2("\033*p%c%dx%c%dY",\ + ((delx) > 0 ? '+' : '-'),ABS(delx),\ + ((dely) < 0 ? '+' : '-'),ABS(dely));\ +} + +/* Move relative to (delx+currentx,currenty), page origin in lower left +corner */ +#define RMOVEX(delx) {\ +if ((delx) > 0)\ + OUTF("\033*p+%dX",(delx));\ +else if ((delx) < 0)\ + OUTF("\033*p%dX",(delx));\ +} + +/* Move relative to (currentx,dely+currenty), page origin in lower left +corner */ +#define RMOVEY(dely) {\ +if ((dely) > 0)\ + OUTF("\033*p%dY",-(dely));\ +else if ((dely) < 0)\ + OUTF("\033*p+%dY",-(dely));\ +} + +/* Round a POSITIVE floating-point value to the nearest integer */ +#define ROUND(x) ((int)(x + 0.5)) + +/* Output a new rule at TeX position (x,y). The device coordinates will +be changed on completion. The rule origin is the TeX convention of the +lower-left corner, while the LaserJet Plus uses the upper-left corner. +*/ +#define RULE(x,y,width,height) {\ + MOVETO(x,(y)+height-1);\ + OUTF2("\033*c%da%dbP",width,height);\ +} + +/* Set rule of same size as previous one at TeX position (x,y). The +device coordinates will be changed on completion. */ +#define RULE2(x,y) {\ + MOVETO(x,(y)+rule_height-1);\ + OUTS("\033*cP");\ +} + +/* Set the character in preparation for a DOWNLOAD_CHARACTER */ +#define SET_CHAR_CODE(ch)\ + OUTF("\033*c%dE",MAP_CHAR(ch)); + + +/* Set the number of copies of the current page (issue just before +PAGEEJECT) */ +#define SETCOPIES(n) OUTF("\033&l%dX",MAX(1,MIN(n,99))) + +/* Set the font number in preparation for a CREATE_FONT */ +#define SET_FONT_ID(fontnumber) OUTF("\033*c%dd4F",(fontnumber)); + +#define SET_CURRENT_FONT(fontnumber) OUTF("\033\050%dX",fontnumber); + + +#define TRANSFER_RASTER_GRAPHICS(nbytes) OUTF("\033*b%dW",(nbytes)); + +#define UNDEFINED_FONT 65535 /* fonts are numbered 0,1,2,... */ + +/* In order to handle the MAXPAGEFONTS restriction, we keep a set of the +fonts in use, accessing them with these two functions. If a later +printer model increases MAXFONTS beyond 32, we can transparently change +to another representation, but for now, we use an efficient bit +set implementation. */ + +UNSIGN32 page_members; /* the bit set for current page */ +#define ADD_MEMBER(set,member) {set |= (1 << (member));} +#define IS_MEMBER(set,member) (set & (1 << (member))) +#define EMPTY_SET(set) {set = 0L;} + + /* BIGCHAR() is used in setchar() and setstr(). BIGCHAR() + is TRUE if the character is too big to send as a downloaded font, or + if more than MAXPAGEFONTS have been used on this page, and the + required font's font_number is not in the page_members set, or if + more the font is not in the first MAXFONTS fonts. */ + +#define BIGCHAR(t) (((t->wp > (COORDINATE)size_limit) ||\ +(t->hp > (COORDINATE)size_limit)) || (fontptr->font_number >= MAXFONTS) ||\ +(t->istoobig)) + +#include "main.h" +void checkchldd(); +#include "abortrun.h" +#include "actfact.h" +#include "alldone.h" + +/*-->bopact*/ +/**********************************************************************/ +/******************************* bopact *******************************/ +/**********************************************************************/ + +void +bopact() /* beginning of page action */ +{ + page_fonts = 0; /* no fonts used on this page yet */ + EMPTY_SET(page_members); + + rule_height = -1; /* reset last rule parameters */ + rule_width = -1; + + str_ycp = -1; /* reset string y coordinate */ +} + +#include "chargf.h" +#include "charpk.h" +#include "charpxl.h" +void makefont1(); +/*-->checkchldd*/ +/**********************************************************************/ +/**************************** checkchldd ******************************/ +/**********************************************************************/ +void +checkchldd(c) +register BYTE c; +{ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + if (fontptr->font_number == UNDEFINED_FONT) + (void)makefont1(); + tcharptr = &(fontptr->ch[c]); + + if ((BIGCHAR(tcharptr)) || (BAD_CHAR(c))) + { /* we shall need to send a graphics bitmap */ + tcharptr->isloaded = FALSE; + } + else { + if (tcharptr->isloaded == FALSE) + { + fontptr->used_chars++; + tcharptr->isloaded = TRUE; + } + } +} + + + +#include "checkpage.h" +#include "clrrow.h" +#include "dbgopen.h" + +/*-->devinit*/ +/**********************************************************************/ +/****************************** devinit *******************************/ +/**********************************************************************/ + +void +devinit(argc,argv) /* initialize device */ +int argc; +char *argv[]; +{ + RESET_PRINTER; /* printer reset */ + DELETE_ALL_FONTS; /* delete all downloaded fonts */ + font_count = 0; /* no font numbers are assigned yet */ + pf = -1; +} + +/*-->devterm*/ +/**********************************************************************/ +/****************************** devterm *******************************/ +/**********************************************************************/ + +void +devterm() /* terminate device */ +{ + RESET_PRINTER_END; /* printer reset */ +} + +#include "dvifile_p.h" +#include "dviinit.h" +#include "dviterm.h" + +/*-->eopact*/ +/**********************************************************************/ +/******************************* eopact *******************************/ +/**********************************************************************/ + +void +eopact() /* end of page action */ +{ + if (copies > 1) + SETCOPIES(copies); + PAGEEJECT; +} + +#include "f20open.h" +#include "fatal.h" + +/*-->fillrect*/ +/**********************************************************************/ +/****************************** fillrect ******************************/ +/**********************************************************************/ + +void +fillrect(x,y,width,height) +COORDINATE x,y,width,height; /* lower left corner, size */ + +/*********************************************************************** +With the page origin (0,0) at the lower-left corner, draw a filled +rectangle at (x,y). + +For most TeX uses, rules are uncommon, and little optimization is +possible. However, for the LaTeX Bezier option, curves are simulated by +many small rules (typically 2 x 2) separated by positioning commands. +By remembering the size of the last rule set, we can test for the +occurrence of repeated rules of the same size, and reduce the output by +omitting the rule sizes. The last rule parameters are reset by the +begin-page action in prtpage(), so they do not carry across pages. + +It is not possible to use relative, instead of absolute, moves in these +sequences, without stacking rules for the whole page, because each rule +is separated in the DVI file by push, pop, and positioning commands, +making for an uncertain correspondence between internal (xcp,ycp) +pixel page coordinates and external device coordinates. + +The last string y coordinate, str_ycp, must be reset here to force any +later setstring() to reissue new absolute positioning commands. +***********************************************************************/ + +{ + str_ycp = -1; /* invalidate string y coordinate */ + + if ((height != rule_height) || (width != rule_width)) + { + RULE(x,y,width,height); + rule_width = width; /* save current rule parameters */ + rule_height = height; + } + else /* same size rule again */ + RULE2(x,y); +} + +#include "findpost.h" +#include "fixpos.h" +#include "fontfile.h" +#include "fontsub.h" +#include "getbytes.h" +#include "getfntdf.h" +#include "getpgtab.h" +#include "inch.h" +#include "initglob.h" + +/*-->loadbmap*/ +/**********************************************************************/ +/****************************** loadbmap ******************************/ +/**********************************************************************/ + +void +loadbmap(c) /* load big character as raster bitmap */ +register BYTE c; +{ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + void (*charyy)(); /* subterfuge to get around PCC-20 bug */ + + if (fontptr != pfontptr) + (void)openfont(fontptr->n); + if (fontfp == (FILE *)NULL) /* do nothing if no font file */ + return; + + tcharptr = &(fontptr->ch[c]); + + moveto(hh - tcharptr->xoffp,YSIZE-vv+tcharptr->yoffp); + + MOVETO(xcp,ycp); + BEGIN_RASTER_GRAPHICS; + + /* Bug fix: PCC-20 otherwise jumps to charxx instead of *charxx */ + charyy = fontptr->charxx; + (void)(*charyy)(c,outraster); /* load rasters into device */ + + END_RASTER_GRAPHICS; + str_ycp = -1; /* invalidate string y coordinate */ +} + +/*-->loadchar*/ +/**********************************************************************/ +/****************************** loadchar ******************************/ +/**********************************************************************/ + +void +loadchar(c,pc) +register BYTE c; +BYTE pc; +{ + void (*charyy)(); /* subterfuge to get around PCC-20 bug */ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + COORDINATE nbytes; /* number of bytes per row */ + float temp; + INT16 ntemp; + + if ((c < FIRSTPXLCHAR) || (LASTPXLCHAR < c)) /* check character range */ + return; + + tcharptr = &(fontptr->ch[c]); + + if (!VISIBLE(tcharptr)) + return; /* do nothing for invisible fonts */ + + if (fontptr != pfontptr) + openfont(fontptr->n); + + if (fontfp == (FILE *)NULL) /* do nothing if no font file */ + return; + + (void)clearerr(plotfp); + + tcharptr->isloaded = TRUE; + + SET_CHAR_CODE(pc); + + /* Number of bytes in bitmap, possibly reduced because of LaserJet Plus */ + /* limits. Large characters really need to be handled as bitmaps */ + /* instead of as downloaded characters. */ + + nbytes = ((tcharptr->wp) + 7) >> 3; /* wp div 8 */ + DOWNLOAD_CHARACTER(MIN(16,nbytes)*MIN(255,(tcharptr->hp))); + + OUTC(4); /* 4 0 14 1 is fixed sequence */ + OUTC(0); + + OUTC(14); + OUTC(1); + + OUTC(0); /* orientation = 0 ==> portrait */ + OUTC(0); + + /* Apologies for the temporary variables; the Sun OS 3.2 cc could + not compile the original expressions. */ + ntemp = MIN(-(tcharptr->xoffp),127); + ntemp = MAX(-128,ntemp); + OUT16(ntemp); + ntemp = MIN(tcharptr->yoffp,127); + ntemp = MAX(-128,ntemp); + OUT16(ntemp); + ntemp = MIN(128,tcharptr->wp); + OUT16(ntemp); + ntemp = MIN(255,tcharptr->hp); + OUT16(ntemp); + temp = (float)(tcharptr->tfmw); + temp = temp*conv; + ntemp = ROUND(temp); + OUT16(4*ntemp); /* delta x to nearest dot */ + + /* Bug fix: PCC-20 otherwise jumps to charxx instead of *charxx */ + charyy = fontptr->charxx; + (void)(*charyy)(c,outrow); /* output rasters */ + + if (DISKFULL(plotfp)) + (void)fatal("loadchar(): Output error -- disk storage probably full"); +} + +/*-->makefont1*/ +/**********************************************************************/ +/***************************** makefont1 *******************************/ +/**********************************************************************/ + +void +makefont1() +{ + register UNSIGN16 the_char; /* loop index */ + INT16 j; /* loop index */ + /* parameters of largest cell */ + COORDINATE cell_above; /* dots above baseline */ + COORDINATE cell_below; /* dots below baseline */ + COORDINATE char_below; /* dots below baseline */ + COORDINATE cell_height; /* total height */ + COORDINATE cell_left; /* dots left of character cell */ + COORDINATE cell_width; /* total width */ + COORDINATE cell_baseline; /* in 0..(cell_height-1) */ + + /******************************************************************* + Each LaserJet Plus font must be assigned a unique number in + 0..32767, and only 32 fonts can be active at one time. We keep a + table of font pointers for this purpose and store the corresponding + table index in font_number. Each time a new font is encountered, we + increment font_count and store it in that font's font_number. TeX + produces a unique font number as well, and TeX82 only uses values in + the range 0..255. The DVI file supports 32-bit font numbers, so it + is better to generate our own, because someday other programs may + produce DVI files too. + + If fonts are freed dynamically, the table entry must be invalidated + and a command sent to the printer to delete that font. At present, + font freeing happens only in dviterm() at the close of processing of + a single DVI file. A subsequent DVI file processed will result in + the invocation of devinit() which resets font_count to 0. It is not + possible to avoid downloading some fonts for subsequent files, + because we have no control over what order they are printed in, and + each output file must therefore be regarded as independent. + + In order to deal with the limit of MAXFONTS active fonts in the + LaserJet Plus, we have two choices. The first and best and most + difficult, is to entirely discard the matching of TeX fonts with + LaserJet Plus fonts---new characters would simply be assigned to the + next available entry in the current open font. The second choice is + less satisfactory---when MAXFONTS fonts have been downloaded, we + delete the last of them and reset the isloaded flags for all the + characters in that font. The Plus also allows deletion of + individual characters, so in the first case, we could delete + little-used characters to make room in the font tables on the + device; we do not use that approach here. One problem is that font + metrics must be assigned which match the largest character in the + font, so individual character deletion and later re-use of the + vacated slot is not in general possible. A second problem is the + bizarre behavior of the LaserJet Plus in response to a font + deletion--the current page is printed, and the all text following + the delete font command will appear on the next page. + + There is a silly restriction that only MAXPAGEFONTS fonts can be + used on a single page, where MAXPAGEFONTS < MAXFONTS. We handle + this by keeping a count, page_fonts, of the number of fonts in use + on the current page, and whenever a font is requested whose + font_number (0,1,...) reaches or exceeds MAXPAGEFONTS, then + setchar() and setstr() will not download the character as a font + character, but instead will set it as a raster bitmap, in the same + fashion that large characters are handled. + + We handle the font deletion misfeature by just not using it. If a + document requires more than MAXFONTS fonts, then the characters for + those additional fonts are sent as raster bitmaps, instead of + downloaded characters. + + These two actions completely remove any limitation on the size or + number of fonts in the LaserJet Plus. + + As an optimization to reduce the effort of font table searching, + each time a font is requested which has already been loaded, we move + that font to the front of font_table[]; the least popular fonts will + therefore be the ones that get deleted. The least recently used + priority mechanism is widely used in operating systems for buffer + management; the overhead of list rearrangement here is acceptable, + because font changing occurs relatively infrequently, compared to + character setting. + + <------wp------> + ^ ................ + | ................ + | ................ + | ................ + | ................ + | ................ + | ................ + hp ................ + | ................ + | ................ + | ................ + | .....o.......... <-- character reference point (xcp,ycp) at "o" + | ................ ^ + | ................ | + | ................ |--- (hp - yoffp - 1) + | ................ | + v +............... v <-- (xcorner,ycorner) at "+" + <---> + | + | + xoffp (negative if (xcp,ycp) left of bitmap) + + + The LaserJet Plus font mechanism requires the declaration of cell + height, width, and baseline in the CreateFont command. Experiments + show that these must be large enough to incorporate the maximum + extent above and below the baseline of any characters in the font. + The metric correspondences are as follows: + + ----- ------------- + TeX LaserJet Plus + ----- ------------- + xoffp -(left offset) + yoffp top offset + max(yoffp) + 1 cell baseline + max(wp) cell width + max(yoffp) + + max(hp-yoff,yoff-hp) + 1 cell height + + + *******************************************************************/ + + for (j = 0; j < (INT16)font_count; ++j) + if (font_table[j] == fontptr) /* then font already known */ + { + for (; j > 0; --j) /* LRU: move find to front */ + font_table[j] = font_table[j-1]; + font_table[0] = fontptr; + return; /* nothing more to do */ + } + + if (font_count >= MAXFONTS) /* then no more fonts can be downloaded */ + { + /* set up so BIGCHAR() recognizes the font as not downloadable + and sends bitmaps instead */ + fontptr->font_number = font_count; + for (the_char = FIRSTPXLCHAR; the_char <= LASTPXLCHAR; ++the_char) + { + fontptr->ch[the_char].isloaded = FALSE; + fontptr->ch[the_char].istoobig = TRUE; + } + return; + } + +/* new font */ + fontptr->font_number = font_count; + font_table[font_count] = fontptr; + font_count++; /* count the next font */ + fontptr->used_chars = 0; + fontptr->assigned_chars = 0; + + cell_above = 0; + cell_below = 0; + cell_left = 0; + cell_width = 0; + + for (the_char = FIRSTPXLCHAR; the_char <= LASTPXLCHAR; ++the_char) + { + char_below = fontptr->ch[the_char].yoffp - + fontptr->ch[the_char].hp; + char_below = ABS(char_below); + cell_height = 1 + fontptr->ch[the_char].yoffp + char_below; + fontptr->ch[the_char].isloaded = FALSE; + fontptr->ch[the_char].lj_char = -1; + fontptr->ch[the_char].lj_font = -1; + fontptr->ch[the_char].istoobig = (BOOLEAN)( + !IN(-128,-fontptr->ch[the_char].xoffp,127) || + !IN(-128, fontptr->ch[the_char].yoffp,127) || + !IN(1,fontptr->ch[the_char].wp,255) || + !IN(1,cell_height,255)); + } + +} +/*-->makefont*/ +/**********************************************************************/ +/***************************** makefont *******************************/ +/**********************************************************************/ + +void +makefont(pptr,n_slots) +struct printer_font *pptr; +int n_slots; +{ + register UNSIGN16 the_char; /* loop index */ + register the_slot; + INT16 j; /* loop index */ + /* parameters of largest cell */ + COORDINATE cell_above; /* dots above baseline */ + COORDINATE cell_below; /* dots below baseline */ + COORDINATE char_below; /* dots below baseline */ + COORDINATE cell_height; /* total height */ + COORDINATE cell_left; /* dots left of character cell */ + COORDINATE cell_width; /* total width */ + COORDINATE cell_baseline; /* in 0..(cell_height-1) */ + + + + cell_above = 0; + cell_below = 0; + cell_left = 0; + cell_width = 0; + + for (the_slot = 0; the_slot < n_slots; ++the_slot) + { + fontptr = pptr->char_slots[the_slot].tex_font; + the_char = pptr->char_slots[the_slot].tex_char; + char_below = fontptr->ch[the_char].yoffp - + fontptr->ch[the_char].hp; + char_below = ABS(char_below); + cell_height = 1 + fontptr->ch[the_char].yoffp + char_below; + fontptr->ch[the_char].istoobig = (BOOLEAN)( + !IN(-128,-fontptr->ch[the_char].xoffp,127) || + !IN(-128, fontptr->ch[the_char].yoffp,127) || + !IN(1,fontptr->ch[the_char].wp,255) || + !IN(1,cell_height,255)); + cell_above = MAX(cell_above,fontptr->ch[the_char].yoffp); + cell_below = MAX(cell_below,char_below); + cell_left = MAX(cell_left,-fontptr->ch[the_char].xoffp); + cell_width = MAX(cell_width,fontptr->ch[the_char].wp); + } + cell_baseline = cell_above + 1; + cell_height = (cell_above + cell_below) + 1; + + if ((cell_width > 255) || (cell_height > 255)) + { /* don't worry, big characters are handled specially later */ + cell_height = MIN(cell_height,255); + cell_width = MIN(cell_width,255); + } + cell_width = MAX(1,cell_width); + + SET_FONT_ID(pf); + + CREATE_FONT; + + OUTC(0); + OUTC(26); /* descriptor length */ + + OUTC(0); /* always 0 */ + OUTC(1); /* 8-bit font (for more than 95 characters) */ + + OUT16(0); /* always 0 */ + + OUT16(cell_baseline); /* baseline position (in 0..cell_height-1)*/ + + OUT16(cell_width); /* cell width */ + + OUT16(cell_height); /* cell height */ + + OUTC(0); /* orientation = 0 ==> portrait */ + OUTC(1); /* spacing = 1 ==> proportional */ + + OUT16(0); /* symbol set (arbitrary) */ + + OUT16(2); /* pitch (arbitrary in 2..1260) */ + + OUT16(cell_height); /* font height (arbitrary in 0..10922) */ + + OUT16(0); /* always 0 */ + + OUTC(0); /* always 0 */ + OUTC(0); /* style = 0 ==> upright */ + + OUTC(0); /* stroke weight = 0 ==> normal */ + OUTC(0); /* typeface = 0 (arbitrary) */ +} + +#include "movedown.h" +#include "moveover.h" +#include "moveto.h" + +/*-->newfont*/ +/**********************************************************************/ +/****************************** newfont *******************************/ +/**********************************************************************/ + +void +newfont() +{ + /******************************************************************* + Creating fonts immediately (usually at postamble read time, before + any pages have been printed), would exhaust the LaserJet Plus font + supply in a document with more than 32 fonts, requiring many fonts + to be sent as bitmaps, instead of as downloaded characters. If only + a few pages were selected for printing, it is unlikely that more + than 32 would actually be needed. With character bitmaps, the + output file is much larger than when downloaded characters are used, + and there is a likelihood of raising printer error code 21 (page too + complex to process), at least on the LaserJet Plus, which has rather + limited internal memory (about 512Kb). The HPLJ Series II can have + up to 4.5Mb of memory, and possibly would eliminate this error + condition. + + Instead, we simply mark the font as currently undefined. When it is + first referenced, setfont() will call makefont() to actually create + it in the printer. + *******************************************************************/ + + fontptr->font_number = UNDEFINED_FONT; +} + +#include "nosignex.h" +#include "openfont.h" +#include "option.h" + +/*-->outraster*/ +/**********************************************************************/ +/***************************** outraster ******************************/ +/**********************************************************************/ + +void +outraster(c,yoff)/* print single raster line in bitmap graphics mode */ +BYTE c; /* current character value */ +UNSIGN16 yoff; /* offset from top row (0,1,...,hp-1) */ +{ + UNSIGN16 bytes_per_row; /* number of raster bytes to copy */ + register UNSIGN16 k; /* loop index */ + register UNSIGN32 *p; /* pointer into img_row[] */ + struct char_entry *tcharptr;/* temporary char_entry pointer */ + register BYTE the_byte; /* unpacked raster byte */ + + tcharptr = &(fontptr->ch[c]);/* assume check for valid c has been done */ + bytes_per_row = (UNSIGN16)((tcharptr->wp) + 7) >> 3; /* wp div 8 */ + p = img_row; /* we step pointer p along img_row[] */ + + TRANSFER_RASTER_GRAPHICS(bytes_per_row); + + for (k = bytes_per_row; k > 0; ++p) + { + the_byte = (BYTE)((*p) >> 24); + OUTC(the_byte); + if ((--k) <= 0) + break; + + the_byte = (BYTE)((*p) >> 16); + OUTC(the_byte); + if ((--k) <= 0) + break; + + the_byte = (BYTE)((*p) >> 8); + OUTC(the_byte); + if ((--k) <= 0) + break; + + the_byte = (BYTE)(*p); + OUTC(the_byte); + if ((--k) <= 0) + break; + } +} + +/*-->outrow*/ +/**********************************************************************/ +/******************************* outrow *******************************/ +/**********************************************************************/ + +void +outrow(c,yoff) /* copy img_row[] into rasters[] if allocated, else no-op */ +BYTE c; /* current character value */ +UNSIGN16 yoff; /* offset from top row (0,1,...,hp-1) */ +{ + UNSIGN16 bytes_per_row; /* number of raster bytes to copy */ + register UNSIGN16 k; /* loop index */ + register UNSIGN32 *p; /* pointer into img_row[] */ + struct char_entry *tcharptr;/* temporary char_entry pointer */ + register BYTE the_byte; /* unpacked raster byte */ + + if (yoff > 255) /* LaserJet Plus cannot handle big characters */ + return; + + tcharptr = &(fontptr->ch[c]);/* assume check for valid c has been done */ + bytes_per_row = (UNSIGN16)((tcharptr->wp) + 7) >> 3; /* wp div 8 */ + bytes_per_row = MIN(16,bytes_per_row); /* limited to 128 bits/row */ + p = img_row; /* we step pointer p along img_row[] */ + + for (k = bytes_per_row; k > 0; ++p) + { + the_byte = (BYTE)((*p) >> 24); + OUTC(the_byte); + if ((--k) <= 0) + break; + + the_byte = (BYTE)((*p) >> 16); + OUTC(the_byte); + if ((--k) <= 0) + break; + + the_byte = (BYTE)((*p) >> 8); + OUTC(the_byte); + if ((--k) <= 0) + break; + + the_byte = (BYTE)(*p); + OUTC(the_byte); + if ((--k) <= 0) + break; + } +} + +#include "prtpage_p.h" +#include "readfont.h" +#include "readgf.h" +#include "readpk.h" +#include "readpost.h" +#include "readpxl.h" +#include "reldfont.h" +#include "rulepxl.h" + +/*-->setchar*/ +/**********************************************************************/ +/****************************** setchar *******************************/ +/**********************************************************************/ + +void +setchar(c, update_h) +register BYTE c; +register BOOLEAN update_h; +{ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + + /* ONPAGE() is used here and in setstr(). */ + +#define ONPAGE(t) (((hh - t->xoffp + t->pxlw) <= XSIZE) \ + && (hh >= 0)\ + && (vv <= YSIZE)\ + && (vv >= 0)) + + if (DBGOPT(DBG_SET_TEXT)) + { + (void)fprintf(stderr,"setchar('"); + if (isprint(c)) + (void)putc(c,stderr); + else + (void)fprintf(stderr,"\\%03o",(int)c); + (void)fprintf(stderr,"'<%d>) (hh,vv) = (%ld,%ld) font name <%s>", + (int)c, (long)hh, (long)vv, fontptr->n); + NEWLINE(stderr); + } + + tcharptr = &(fontptr->ch[c]); + + moveto(hh,(COORDINATE)(YSIZE-vv)); + if (ONPAGE(tcharptr)) + { /* character fits entirely on page */ + if (tcharptr->lj_font != pf) + { + (void)setfont(tcharptr->lj_font); + } + + if (VISIBLE(tcharptr)) + { + if ((BIGCHAR(tcharptr)) || (BAD_CHAR(c))) + loadbmap(c); + else + { + if (ycp != str_ycp) + { + MOVETO(xcp,ycp); + str_ycp = ycp; + } + else + MOVEX(xcp); + + c = tcharptr->lj_char; + OUT_CHAR(c); + } + } + } + else if (DBGOPT(DBG_OFF_PAGE) && !quiet) + { /* character is off page -- discard it */ + (void)fprintf(stderr, + "setchar(): Char %c [10#%3d 8#%03o 16#%02x] off page.", + isprint(c) ? c : '?',c,c,c); + NEWLINE(stderr); + } + + if (update_h) + { + h += (INT32)tcharptr->tfmw; + hh += (COORDINATE)tcharptr->pxlw; + hh = fixpos(hh-lmargin,h,conv) + lmargin; + } +} + +#include "setfntnm.h" + +/*-->setfont*/ +/**********************************************************************/ +/****************************** setfont *******************************/ +/**********************************************************************/ + +void +setfont(font) +{ + pf = font; + SET_CURRENT_FONT(pf); +} + +#include "setrule.h" + +/*-->setstr*/ +/**********************************************************************/ +/******************************* setstr *******************************/ +/**********************************************************************/ + +void +setstr(c) +register BYTE c; +{ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + register BOOLEAN inside; + COORDINATE hh_last; /* hh before call to fixpos() */ + register UNSIGN16 k; /* loop index */ + UNSIGN16 nstr; /* number of characters in str[] */ + BYTE str[MAXSTR+1]; /* string accumulator */ + BOOLEAN truncated; /* off-page string truncation flag */ + + /******************************************************************* + Set a sequence of characters in SETC_000 .. SETC_127 with a minimal + number of LaserJet Plus commands. These sequences tend to occur in + long clumps in a DVI file, and setting them together whenever + possible substantially decreases the overhead and the size of the + output file. A sequence can be set as a single string if + + * TeX and LaserJet Plus coordinates of each character agree (may + not be true, since device coordinates are in multiples of 1/4 + pixel; violation of this requirement can be detected if + fixpos() changes hh, or if ycp != str_ycp), AND + + * each character is in the same font (this will always be true + in a sequence from a DVI file), AND +[this needs looking at in PP8 version] + + * each character fits within the page boundaries, AND + + * each character definition is already loaded, AND + + * each character is from a visible font, AND + + * each character bitmap extent is smaller than the size_limit + (which is used to enable discarding large characters after + each use in order to conserve virtual memory storage on the + output device). + + Whenever any of these conditions does not hold, any string already + output is terminated, and a new one begun. + + Two output optimizations are implemented here. First, up to MAXSTR + (in practice more than enough) characters are collected in str[], + and any that require downloading are handled. Then the entire + string is set at once, subject to the above limitations. Second, by + recording the vertical page coordinate, ycp, in the global variable + str_ycp (reset in prtpage() at begin-page processing), it is + possible to avoid outputting y coordinates unnecessarily, since a + single line of text will generally result in many calls to this + function. + *******************************************************************/ + +#define BEGINSTRING {inside = TRUE;\ + if (ycp != str_ycp)\ + {\ + MOVETO(xcp,ycp);\ + str_ycp = ycp;\ + }\ + else\ + MOVEX(xcp);} + +#define ENDSTRING {inside = FALSE;} + +#define OFF_PAGE (-1) /* off-page coordinate value */ + + tcharptr = &(fontptr->ch[c]); + + if (tcharptr->lj_font != pf) /* output new font selection */ + { + (void)setfont(tcharptr->lj_font); + } + + inside = FALSE; + truncated = FALSE; + + nstr = 0; + while ((SETC_000 <= c) && (c <= SETC_127) && (nstr < MAXSTR)) + { /* loop over character sequence */ + str[nstr++] = c; /* save string character */ + + c = (BYTE)nosignex(dvifp,(BYTE)1); + } + + /* put back character which terminated the loop */ + (void)UNGETC((int)(c),dvifp); + + if (DBGOPT(DBG_SET_TEXT)) + { + (void)fprintf(stderr,"setstr(\""); + for (k = 0; k < nstr; ++k) + { + c = str[k]; + if (isprint(c)) + (void)putc(c,stderr); + else + (void)fprintf(stderr,"\\%03o",(int)c); + } + (void)fprintf(stderr,"\") (hh,vv) = (%ld,%ld) font name <%s>", + (long)hh, (long)vv, fontptr->n); + NEWLINE(stderr); + } + + for (k = 0; k < nstr; ++k) + { /* loop over character sequence */ + c = str[k]; + tcharptr = &(fontptr->ch[c]); + moveto(hh,YSIZE-vv); + + if (ONPAGE(tcharptr) && VISIBLE(tcharptr)) + { /* character fits entirely on page and is visible */ + /* We must check first for a big character. The character */ + /* may have been downloaded on a previous page, but if it is */ + /* not in the page_members font set, we must send it again */ + /* as a bitmap instead. */ + if (BIGCHAR(tcharptr)) /* BAD_CHAR(c)) cannot be true here */ + { + if (inside) + ENDSTRING; /* finish any open string */ + loadbmap(c); + } + else if (tcharptr->lj_font != pf) + { + if (inside) + ENDSTRING; + } + else + { + if (!inside) + BEGINSTRING; + c = tcharptr->lj_char; + OUT_CHAR(c); + } + } + else /* character does not fit on page -- output */ + { /* current string and discard the character */ + truncated = TRUE; + if (inside) + ENDSTRING; + } + /* update horizontal positions in TFM and pixel units */ + h += (INT32)tcharptr->tfmw; + hh += (COORDINATE)tcharptr->pxlw; + hh_last = hh; + hh = fixpos(hh-lmargin,h,conv) + lmargin; + if (DBGOPT(DBG_POS_CHAR)) + { + (void)fprintf(stderr, + "[%03o] xcp = %d\tycp = %d\thh = %d\thh_last = %d\n", + c,xcp,ycp,hh,hh_last); + } + + /* If fixpos() changed position, we need new string next time */ + /* around. Actually, since the LaserJet Plus stores character */ + /* widths in units of 1/4 dot, we could compute coordinates at */ + /* four times the precision, but for now, we start a new string */ + /* each time we have one or more dots of error. */ + + if ((hh != hh_last) && inside) + ENDSTRING; + } + if (truncated && DBGOPT(DBG_OFF_PAGE) && !quiet) + { + (void)fprintf(stderr,"setstr(): Text ["); + for (k = 0; k < nstr; ++k) + (void)fprintf(stderr,isprint(str[k]) ? "%c" : "\\%03o",str[k]); + (void)fprintf(stderr,"] truncated at page boundaries."); + NEWLINE(stderr); + } + if (inside) /* finish last string */ + ENDSTRING; +} + +#include "signex.h" +#include "skgfspec.h" +#include "skipfont.h" +#include "skpkspec.h" +#include "special.h" +#include "strchr.h" +#include "strcm2.h" +#include "strid2.h" +#include "strrchr.h" +#include "tctos.h" +#include "usage.h" +#include "warning.h" |