summaryrefslogtreecommitdiff
path: root/dviware/kane/dvijep_p
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/kane/dvijep_p
Initial commit
Diffstat (limited to 'dviware/kane/dvijep_p')
-rw-r--r--dviware/kane/dvijep_p1189
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"