/* PSPage.C * * Title: PSPAGE * Henry Burgess * Copyright Microsoft Corp, 1985 * July 4, 1985 * * Description: * This module contains the font table and the routine * that accesses it. It might also be OEM configurable. * *========================================================================== * Modification History: *-------------------------------------------------------------------------- * 9/11/85 Modified to adopt to the banner program. * * 4/20/86 MJH Adapt to lpr, page handling module. * * 3/3/89 Robert Hess Version 2.9 * Completely re-wrote PostScript support. * */ #include #include #include #include #include "lpr.h" char page[rowMax][colMax+1]; /* image of one printer page */ /* * the following defines the bits in the character font */ unsigned char Font_Bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* 01 */ 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* 02 */ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* 03 */ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* 04 */ 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, /* 05 */ 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, /* 06 */ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, /* 07 */ 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, /* 08 */ 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, /* 09 */ 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, /* 0a */ 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, /* 0b */ 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, /* 0c */ 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, /* 0d */ 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, /* 0e */ 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, /* 0f */ 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, /* 10 */ 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, /* 11 */ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, /* 12 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, /* 13 */ 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, /* 14 */ 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, /* 15 */ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, /* 16 */ 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, /* 17 */ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, /* 18 */ 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, /* 19 */ 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, /* 1a */ 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, /* 1b */ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, /* 1c */ 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, /* 1d */ 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, /* 1e */ 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, /* 1f */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20 */ 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, /* 21 ! */ 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 22 " */ 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, /* 23 # */ 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, /* 24 $ */ 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, /* 25 % */ 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, /* 26 & */ 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, /* 27 ' */ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, /* 28 ( */ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, /* 29 ) */ 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, /* 2a * */ 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, /* 2b + */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, /* 2c , */ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, /* 2d - */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, /* 2e . */ 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, /* 2f / */ 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, /* 30 0 */ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, /* 31 1 */ 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, /* 32 2 */ 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, /* 33 3 */ 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, /* 34 4 */ 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, /* 35 5 */ 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, /* 36 6 */ 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, /* 37 7 */ 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, /* 38 8 */ 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, /* 39 9 */ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, /* 3a : */ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, /* 3b ; */ 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, /* 3c < */ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, /* 3d = */ 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, /* 3e > */ 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, /* 3f ? */ 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, /* 40 @ */ 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, /* 41 A */ 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, /* 42 B */ 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, /* 43 C */ 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, /* 44 D */ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, /* 45 E */ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, /* 46 F */ 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, /* 47 G */ 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, /* 48 H */ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 49 I */ 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, /* 4a J */ 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, /* 4b K */ 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, /* 4c L */ 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, /* 4d M */ 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, /* 4e N */ 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, /* 4f O */ 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, /* 50 P */ 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, /* 51 Q */ 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, /* 52 R */ 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, /* 53 S */ 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 54 T */ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, /* 55 U */ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, /* 56 V */ 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, /* 57 W */ 0xc6, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0x00, /* 58 X */ 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, /* 59 Y */ 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, /* 5a Z */ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, /* 5b [ */ 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, /* 5c \ */ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, /* 5d ] */ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 5e ^ */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 5f _ */ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60 ` */ 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, /* 61 a */ 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, /* 62 b */ 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, /* 63 c */ 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, /* 64 d */ 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, /* 65 e */ 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, /* 66 f */ 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, /* 67 g */ 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, /* 68 h */ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 69 i */ 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, /* 6a j */ 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, /* 6b k */ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 6c l */ 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, /* 6d m */ 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, /* 6e n */ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, /* 6f o */ 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, /* 70 p */ 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, /* 71 q */ 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, /* 72 r */ 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, /* 73 s */ 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, /* 74 t */ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, /* 75 u */ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, /* 76 v */ 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, /* 77 w */ 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, /* 78 x */ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, /* 79 y */ 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, /* 7a z */ 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, /* 7b { */ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, /* 7c | */ 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, /* 7d } */ 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7e ~ */ 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00 /* 7f */ }; void block_flush(sz, rowTopLeft, colTopLeft) /*** do the actual block printing of sz to the page. */ char sz[]; int rowTopLeft, colTopLeft; { int row, col, ich; register unsigned char c; char chFill; if ((sz == NULL) || (sz[0] == '\0')) return; for (row =0; row < 8; row++) { /* 8 lines */ for (ich = 0; sz[ich] != '\0'; ich++) { /* characters in string */ /* * find this character in the font table * and byte for this row ( + i ) */ c = Font_Bits[((unsigned)sz[ich] << 3) + row]; if (chBanner<=' ') if (isprint(sz[ich])) chFill = sz[ich]; else chFill = 'X'; else chFill = chBanner; for (col = 0; col < 8; col++) { /* bits in a byte */ page[rowTopLeft + row][colTopLeft + (ich << 3) + col] = (char)(((int)c & 0x80) ? chFill : ' '); c = (unsigned char)((int)c << 1); } } } } void VertLine(char ch, int colAt, int rowMin, int rowMac) { register int row; for (row = rowMin; row < rowMac; page[row++][colAt] = ch) ; } void HorzLine(char ch, int rowAt, int colMin, int colMac) { register int col; for (col = colMin; col < colMac; page[rowAt][col++] = ch) ; } void FillRectangle(char ch, int rowTopLeft, int colTopLeft, int rowBotRight, int colBotRight) { register int col, row; for (row = rowTopLeft; row < rowBotRight; row++) { for (col = colTopLeft; col < colBotRight; col++) page[row][col] = ch; } } void WriteSzCoord(sz, row, col) register char *sz; int row, col; { register char *pch; for (pch = &page[row][col]; *sz != '\0'; *pch++ = *sz++) ; } void OutCmpLJ(szO,cchO) /* Accept a string, szO, of length cchO and remove runs of seven or more spaces by replacing them with a control sequence to move the printer head on the HP Laser Jet. ESC&a+#C moves the head # places to the right. NOTE: this is very similar to OutCmpPS(). */ char *szO; int cchO; { register int cchB; char chO; register char *pchB; char szMove[10]; chO = szO[cchO]; /* save for later restore */ szO[cchO] = '\0'; /* Make sure 0 terminated string. */ while (*szO != '\0') { pchB = szO; while ((pchB=strchr(pchB, ' ')) != 0 && (cchB=strspn(pchB, " ")) < 7) pchB += cchB; if (pchB != 0) { /* found a run of blanks of 7 or more */ if (szO != pchB) { /* output other stuff until pchB */ OutLPR(szO, pchB-szO); szO = pchB; } /* output run of blanks as ESC&a+#C */ sprintf(szMove, "\033&a+%dC", cchB); OutLPR(szMove, 0); szO += cchB; } else { /* no run of blanks; output all and terminate loop */ cchB = strlen(szO); /* not really blanks (!) */ OutLPR(szO, cchB); szO += cchB; } } *szO = chO; /* restore */ } void OutEncPS(pchF, cchF) /* output PostScript substring quoting *nothing* */ register char *pchF; int cchF; { register char *pchT; int cchT; char rgbT[1+colMax*2+5];/* enough for every character to be encoded */ pchT = rgbT; cchT = 0; while (cchF-- > 0) { switch(*pchF++) { default: *pchT++ = *(pchF-1); cchT++; break; } } *pchT = '\n'; cchT++; /* end of PostScript string */ OutLPR(rgbT, cchT); } void OutCmpPS(szO,cchO) /* Accept a string, szO, of length cchO. # sp moves the head # places to the right (local definition). NOTE: this is VERY similar to OutCmpPS(). */ char *szO; int cchO; { register int cchB; char chO; register char *pchB; chO = szO[cchO]; /* save for later restore */ szO[cchO] = '\0'; /* Make sure 0 terminated string. */ while (*szO != '\0') { pchB = szO; cchB = strlen(szO); /* not really blanks (!) */ OutEncPS (szO, cchB); szO += cchB; } *szO = chO; /* restore */ } int CchNoTrail(rgch,cch) /* returns the number of characters in a line of text without counting trailing blanks*/ char rgch[]; int cch; { register char *pch; for (pch = rgch + cch - 1; pch >= rgch && *pch==' ';pch--) ; return ((pch + 1) - rgch); } void OutRectangle(rowMin, colMin, rowLim, colLim) /* output rectangle of page triming blank lines and blanks from the ends of lines */ int rowMin, colMin, rowLim, colLim; { int row; int ccol = colLim - colMin; while (rowLim > rowMin && CchNoTrail(&page[rowLim-1][colMin], ccol) == 0) rowLim--; for (row = rowMin; row < rowLim; row++) { register char *pch = &page[row][colMin]; int cch = CchNoTrail(pch, ccol); if (cch != 0) { if (fLaser) OutCmpLJ(pch, cch); else if (fPostScript) { OutCmpPS(pch, cch); } else OutLPR(pch, cch); } else if (fPostScript) { OutCmpPS (" ", 1); } if (!fPostScript) OutLPR(row==rowLim - 1 ? "\r" : "\r\n", 0); } }