Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

419 lines
14 KiB

  1. /* PSPage.C
  2. *
  3. * Title: PSPAGE
  4. * Henry Burgess
  5. * Copyright Microsoft Corp, 1985
  6. * July 4, 1985
  7. *
  8. * Description:
  9. * This module contains the font table and the routine
  10. * that accesses it. It might also be OEM configurable.
  11. *
  12. *==========================================================================
  13. * Modification History:
  14. *--------------------------------------------------------------------------
  15. * 9/11/85 Modified to adopt to the banner program.
  16. *
  17. * 4/20/86 MJH Adapt to lpr, page handling module.
  18. *
  19. * 3/3/89 Robert Hess Version 2.9
  20. * Completely re-wrote PostScript support.
  21. *
  22. */
  23. #include <windef.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #include "lpr.h"
  28. char page[rowMax][colMax+1]; /* image of one printer page */
  29. /*
  30. * the following defines the bits in the character font
  31. */
  32. unsigned char Font_Bits[] = {
  33. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00 */
  34. 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* 01 */
  35. 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* 02 */
  36. 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* 03 */
  37. 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* 04 */
  38. 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c, /* 05 */
  39. 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, /* 06 */
  40. 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, /* 07 */
  41. 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, /* 08 */
  42. 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, /* 09 */
  43. 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, /* 0a */
  44. 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78, /* 0b */
  45. 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, /* 0c */
  46. 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0, /* 0d */
  47. 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, /* 0e */
  48. 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99, /* 0f */
  49. 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, /* 10 */
  50. 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, /* 11 */
  51. 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, /* 12 */
  52. 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, /* 13 */
  53. 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, /* 14 */
  54. 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78, /* 15 */
  55. 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, /* 16 */
  56. 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff, /* 17 */
  57. 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, /* 18 */
  58. 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, /* 19 */
  59. 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, /* 1a */
  60. 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, /* 1b */
  61. 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, /* 1c */
  62. 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, /* 1d */
  63. 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, /* 1e */
  64. 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00, /* 1f */
  65. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20 */
  66. 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, /* 21 ! */
  67. 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 22 " */
  68. 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, /* 23 # */
  69. 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, /* 24 $ */
  70. 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00, /* 25 % */
  71. 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, /* 26 & */
  72. 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, /* 27 ' */
  73. 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, /* 28 ( */
  74. 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, /* 29 ) */
  75. 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, /* 2a * */
  76. 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, /* 2b + */
  77. 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, /* 2c , */
  78. 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, /* 2d - */
  79. 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, /* 2e . */
  80. 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, /* 2f / */
  81. 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, /* 30 0 */
  82. 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00, /* 31 1 */
  83. 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, /* 32 2 */
  84. 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00, /* 33 3 */
  85. 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, /* 34 4 */
  86. 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00, /* 35 5 */
  87. 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, /* 36 6 */
  88. 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00, /* 37 7 */
  89. 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, /* 38 8 */
  90. 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00, /* 39 9 */
  91. 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, /* 3a : */
  92. 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, /* 3b ; */
  93. 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, /* 3c < */
  94. 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00, /* 3d = */
  95. 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, /* 3e > */
  96. 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00, /* 3f ? */
  97. 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, /* 40 @ */
  98. 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00, /* 41 A */
  99. 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, /* 42 B */
  100. 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00, /* 43 C */
  101. 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, /* 44 D */
  102. 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, /* 45 E */
  103. 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, /* 46 F */
  104. 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00, /* 47 G */
  105. 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, /* 48 H */
  106. 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 49 I */
  107. 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, /* 4a J */
  108. 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00, /* 4b K */
  109. 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, /* 4c L */
  110. 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, /* 4d M */
  111. 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, /* 4e N */
  112. 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, /* 4f O */
  113. 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, /* 50 P */
  114. 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00, /* 51 Q */
  115. 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, /* 52 R */
  116. 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00, /* 53 S */
  117. 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 54 T */
  118. 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, /* 55 U */
  119. 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, /* 56 V */
  120. 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00, /* 57 W */
  121. 0xc6, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0x00, /* 58 X */
  122. 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00, /* 59 Y */
  123. 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, /* 5a Z */
  124. 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, /* 5b [ */
  125. 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, /* 5c \ */
  126. 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, /* 5d ] */
  127. 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, /* 5e ^ */
  128. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, /* 5f _ */
  129. 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60 ` */
  130. 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00, /* 61 a */
  131. 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, /* 62 b */
  132. 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00, /* 63 c */
  133. 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, /* 64 d */
  134. 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, /* 65 e */
  135. 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, /* 66 f */
  136. 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, /* 67 g */
  137. 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, /* 68 h */
  138. 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, /* 69 i */
  139. 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, /* 6a j */
  140. 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00, /* 6b k */
  141. 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, /* 6c l */
  142. 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00, /* 6d m */
  143. 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, /* 6e n */
  144. 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, /* 6f o */
  145. 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, /* 70 p */
  146. 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e, /* 71 q */
  147. 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, /* 72 r */
  148. 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00, /* 73 s */
  149. 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, /* 74 t */
  150. 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, /* 75 u */
  151. 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, /* 76 v */
  152. 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00, /* 77 w */
  153. 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, /* 78 x */
  154. 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, /* 79 y */
  155. 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, /* 7a z */
  156. 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00, /* 7b { */
  157. 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, /* 7c | */
  158. 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00, /* 7d } */
  159. 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7e ~ */
  160. 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00 /* 7f */
  161. };
  162. void block_flush(sz, rowTopLeft, colTopLeft)
  163. /*** do the actual block printing of sz to the page. */
  164. char sz[];
  165. int rowTopLeft, colTopLeft;
  166. {
  167. int row, col, ich;
  168. register unsigned char c;
  169. char chFill;
  170. if ((sz == NULL) || (sz[0] == '\0'))
  171. return;
  172. for (row =0; row < 8; row++)
  173. { /* 8 lines */
  174. for (ich = 0; sz[ich] != '\0'; ich++)
  175. { /* characters in string */
  176. /*
  177. * find this character in the font table
  178. * and byte for this row ( + i )
  179. */
  180. c = Font_Bits[((unsigned)sz[ich] << 3) + row];
  181. if (chBanner<=' ')
  182. if (isprint(sz[ich]))
  183. chFill = sz[ich];
  184. else chFill = 'X';
  185. else
  186. chFill = chBanner;
  187. for (col = 0; col < 8; col++)
  188. { /* bits in a byte */
  189. page[rowTopLeft + row][colTopLeft + (ich << 3) + col] =
  190. (char)(((int)c & 0x80) ? chFill : ' ');
  191. c = (unsigned char)((int)c << 1);
  192. }
  193. }
  194. }
  195. }
  196. void VertLine(char ch, int colAt, int rowMin, int rowMac)
  197. {
  198. register int row;
  199. for (row = rowMin; row < rowMac; page[row++][colAt] = ch)
  200. ;
  201. }
  202. void HorzLine(char ch, int rowAt, int colMin, int colMac)
  203. {
  204. register int col;
  205. for (col = colMin; col < colMac; page[rowAt][col++] = ch)
  206. ;
  207. }
  208. void FillRectangle(char ch, int rowTopLeft, int colTopLeft, int rowBotRight, int colBotRight)
  209. {
  210. register int col, row;
  211. for (row = rowTopLeft; row < rowBotRight; row++)
  212. {
  213. for (col = colTopLeft; col < colBotRight; col++)
  214. page[row][col] = ch;
  215. }
  216. }
  217. void WriteSzCoord(sz, row, col)
  218. register char *sz;
  219. int row, col;
  220. {
  221. register char *pch;
  222. for (pch = &page[row][col]; *sz != '\0'; *pch++ = *sz++)
  223. ;
  224. }
  225. void OutCmpLJ(szO,cchO)
  226. /* Accept a string, szO, of length cchO and remove runs of seven or
  227. more spaces by replacing them with a control sequence to move the
  228. printer head on the HP Laser Jet.
  229. ESC&a+#C moves the head # places to the right.
  230. NOTE: this is very similar to OutCmpPS().
  231. */
  232. char *szO;
  233. int cchO;
  234. {
  235. register int cchB;
  236. char chO;
  237. register char *pchB;
  238. char szMove[10];
  239. chO = szO[cchO]; /* save for later restore */
  240. szO[cchO] = '\0'; /* Make sure 0 terminated string. */
  241. while (*szO != '\0')
  242. {
  243. pchB = szO;
  244. while ((pchB=strchr(pchB, ' ')) != 0 && (cchB=strspn(pchB, " ")) < 7)
  245. pchB += cchB;
  246. if (pchB != 0)
  247. {
  248. /* found a run of blanks of 7 or more */
  249. if (szO != pchB)
  250. {
  251. /* output other stuff until pchB */
  252. OutLPR(szO, (int)(pchB-szO));
  253. szO = pchB;
  254. }
  255. /* output run of blanks as ESC&a+#C */
  256. sprintf(szMove, "\033&a+%dC", cchB);
  257. OutLPR(szMove, 0);
  258. szO += cchB;
  259. }
  260. else
  261. {
  262. /* no run of blanks; output all and terminate loop */
  263. cchB = strlen(szO); /* not really blanks (!) */
  264. OutLPR(szO, cchB);
  265. szO += cchB;
  266. }
  267. }
  268. *szO = chO; /* restore */
  269. }
  270. void OutEncPS(pchF, cchF)
  271. /* output PostScript substring quoting *nothing* */
  272. register char *pchF;
  273. int cchF;
  274. {
  275. register char *pchT;
  276. int cchT;
  277. char rgbT[1+colMax*2+5];/* enough for every character to be encoded */
  278. pchT = rgbT;
  279. cchT = 0;
  280. while (cchF-- > 0) {
  281. switch(*pchF++) {
  282. default:
  283. *pchT++ = *(pchF-1);
  284. cchT++;
  285. break;
  286. }
  287. }
  288. *pchT = '\n'; cchT++; /* end of PostScript string */
  289. OutLPR(rgbT, cchT);
  290. }
  291. void OutCmpPS(szO,cchO)
  292. /* Accept a string, szO, of length cchO.
  293. # sp moves the head # places to the right (local definition).
  294. NOTE: this is VERY similar to OutCmpPS().
  295. */
  296. char *szO;
  297. int cchO;
  298. {
  299. register int cchB;
  300. char chO;
  301. register char *pchB;
  302. chO = szO[cchO]; /* save for later restore */
  303. szO[cchO] = '\0'; /* Make sure 0 terminated string. */
  304. while (*szO != '\0') {
  305. pchB = szO;
  306. cchB = strlen(szO); /* not really blanks (!) */
  307. OutEncPS (szO, cchB);
  308. szO += cchB;
  309. }
  310. *szO = chO; /* restore */
  311. }
  312. int CchNoTrail(rgch,cch)
  313. /* returns the number of characters in a line of text without counting
  314. trailing blanks*/
  315. char rgch[];
  316. int cch;
  317. {
  318. register char *pch;
  319. for (pch = rgch + cch - 1; pch >= rgch && *pch==' ';pch--)
  320. ;
  321. return ((int)((pch + 1) - rgch));
  322. }
  323. void OutRectangle(rowMin, colMin, rowLim, colLim)
  324. /* output rectangle of page triming blank lines and blanks from the ends of
  325. lines
  326. */
  327. int rowMin, colMin, rowLim, colLim;
  328. {
  329. int row;
  330. int ccol = colLim - colMin;
  331. while (rowLim > rowMin && CchNoTrail(&page[rowLim-1][colMin], ccol) == 0)
  332. rowLim--;
  333. for (row = rowMin; row < rowLim; row++)
  334. {
  335. register char *pch = &page[row][colMin];
  336. int cch = CchNoTrail(pch, ccol);
  337. if (cch != 0)
  338. {
  339. if (fLaser)
  340. OutCmpLJ(pch, cch);
  341. else if (fPostScript) {
  342. OutCmpPS(pch, cch);
  343. } else
  344. OutLPR(pch, cch);
  345. }
  346. else if (fPostScript) {
  347. OutCmpPS (" ", 1);
  348. }
  349. if (!fPostScript)
  350. OutLPR(row==rowLim - 1 ? "\r" : "\r\n", 0);
  351. }
  352. }