windows-nt/Source/XPSP1/NT/sdktools/ppr/pspage.c
2020-09-26 16:20:57 +08:00

420 lines
14 KiB
C

/* 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 <windef.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#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, (int)(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 ((int)((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);
}
}