Leaked source code of windows server 2003
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.

514 lines
16 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. dloadpcl.c
  5. Abstract:
  6. Functions associated with downloading fonts to printers. This
  7. specifically applies to LaserJet style printers. There are really
  8. two sets of functions here: those for downloading fonts supplied
  9. by the user (and installed with the font installer), and those
  10. we generate internally to cache TT style fonts in the printer.
  11. Environment:
  12. Windows NT Unidrv driver
  13. Revision History:
  14. 03/06/97 -ganeshp-
  15. Created
  16. --*/
  17. #include "font.h"
  18. #define PCL_MAX_FONT_HEADER_SIZE 32767
  19. #define PCL_MAX_CHAR_HEADER_SIZE 32767
  20. #if PRINT_INFO
  21. void vPrintPCLCharHeader(CH_HEADER);
  22. void vPrintPCLFontHeader(SF_HEADER20);
  23. void vPrintPCLChar(char *, WORD, WORD);
  24. #endif
  25. DWORD
  26. DwDLPCLHeader(
  27. PDEV *pPDev,
  28. IFIMETRICS *pifi,
  29. INT id
  30. )
  31. /*++
  32. Routine Description:
  33. Given the IFIMETRICS of the font, and it's download ID, create
  34. and send off the download font header.
  35. Arguments:
  36. pPDev Pointer to PDEV
  37. pifi; IFIMETRICS of this font
  38. id; Font Selection ID
  39. Return Value:
  40. The memory used fo this font.
  41. Note:
  42. 3/6/1997 -ganeshp-
  43. Created it.
  44. --*/
  45. {
  46. INT cjSend; /* Number of bytes to send down */
  47. SF_HEADER20 sfh; /* Structure to send down */
  48. BYTE aPCLFontHdrCmd[20];
  49. INT iFontHdrCmdLen = 0;
  50. WORD wSymSet;
  51. BYTE bFontType;
  52. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  53. /*
  54. * No major brainwork here. Basically need to map from IFIMETRICS
  55. * to HP's font header structure, swap the bytes, then send it off.
  56. * We should be consistent with the (inverse) mapping applied by
  57. * the font installer.
  58. * NOTE that we use the larger of the 2 headers. Should this
  59. * printer not use the additional resolution fields, we ignore
  60. * that part of the structure.
  61. */
  62. #if PRINT_INFO
  63. WCHAR * pwch;
  64. pwch = (WCHAR *)((BYTE *)pifi + pifi->dpwszFaceName);
  65. DbgPrint("\nRasdd!iDLHeader:Dumping font,Name is %ws\n",pwch);
  66. #endif
  67. ZeroMemory( &sfh, sizeof( sfh ) ); /* Safe default values */
  68. /*
  69. * Fill in the structure: easy to do, and many of the fields
  70. * are irrelevant anyway, since the font is selected by ID, and
  71. * NOT on its attributes.
  72. */
  73. if( (pPDev->pGlobals->fontformat == FF_HPPCL))
  74. {
  75. sfh.wSize = cjSend = sizeof( SF_HEADER );
  76. sfh.bFormat = PCL_FM_ORIGINAL;
  77. }
  78. else
  79. {
  80. /* Extended format: allows for resolution */
  81. sfh.wSize = cjSend = sizeof( SF_HEADER20 );
  82. sfh.bFormat = PCL_FM_RESOLUTION;
  83. sfh.wXResn = (WORD)pPDev->ptGrxRes.x;
  84. sfh.wYResn = (WORD)pPDev->ptGrxRes.y;
  85. }
  86. if( pPDev->pGlobals->dlsymbolset == UNUSED_ITEM )
  87. {
  88. /*
  89. * GPD file doesn't define a symbols set for downloaded fonts.
  90. * Now we have a bit of a hack. Early LaserJets are limited to
  91. * the Roman 8 symbol set, which basically allows 0x20 - 0x7f,
  92. * and 0xa0 to 0xfe. We do not have any information which tells
  93. * us the capability of this printer. So we have a compromise:
  94. * use the "Can rotate device fonts" flag as an indicator. If
  95. * this bit is set, we assume the PC-8 symbol set is OK, otherwise
  96. * use Roman 8. This is a slightly pessimistic assumption, since
  97. * we use the LaserJet Series II in Roman 8 mode, when PC-8
  98. * is just fine.
  99. */
  100. if( pFontPDev->flFlags & FDV_ROTATE_FONT_ABLE )
  101. {
  102. //
  103. // PC-8, the large symbol set
  104. // PC-8: 10U -> 341 [ = 10 * 32 + 'U' - 64 ]
  105. // 8 bit font
  106. //
  107. bFontType = PCL_FT_PC8;
  108. wSymSet = 341;
  109. }
  110. else
  111. {
  112. //
  113. // The Roman 8 limited character set
  114. // Roman 8, 8U -> 277 [ = 8 * 32 + 'U' - 64]
  115. // Limited 8 bit font
  116. //
  117. bFontType = PCL_FT_8LIM;
  118. wSymSet = 277;
  119. }
  120. }
  121. else
  122. {
  123. //
  124. // Explicit Symbol Set defined in GPD, So use it.
  125. //
  126. if( pPDev->pGlobals->dlsymbolset == DLSS_ROMAN8 )
  127. {
  128. /*
  129. * The Roman 8 limited character set. Limited 8 bit font.
  130. * Roman 8, 8U -> 277 [ = 8 * 32 + 'U' - 64]
  131. */
  132. bFontType = PCL_FT_8LIM;
  133. wSymSet = 277; /* */
  134. }
  135. else
  136. {
  137. /*
  138. * PC-8, the large symbol set. 8 bit font
  139. * PC-8: 10U -> 341 [ = 10 * 32 + 'U' - 64 ]
  140. */
  141. bFontType = PCL_FT_PC8;
  142. wSymSet = 341;
  143. }
  144. }
  145. sfh.bFontType = bFontType;
  146. sfh.wSymSet = wSymSet;
  147. #if PRINT_INFO
  148. DbgPrint("\nRasdd!iDLHeader:pifi->rclFontBox.top = %d,pifi->fwdWinAscender = %d\n",
  149. pifi->rclFontBox.top, pifi->fwdWinAscender);
  150. DbgPrint("UniFont!iDLHeader:pifi->fwdWinDescender = %d, pifi->rclFontBox.bottom = %d\n",
  151. pifi->fwdWinDescender, pifi->rclFontBox.bottom);
  152. #endif
  153. sfh.wBaseline = (WORD)max( pifi->rclFontBox.top, pifi->fwdWinAscender );
  154. sfh.wCellWide = (WORD)max( pifi->rclFontBox.right - pifi->rclFontBox.left + 1,
  155. pifi->fwdAveCharWidth );
  156. sfh.wCellHeight = (WORD)(1+ max(pifi->rclFontBox.top,pifi->fwdWinAscender) -
  157. min( -pifi->fwdWinDescender, pifi->rclFontBox.bottom ));
  158. sfh.bOrientation = 0; //Set the Orientation to 0 always, else it won't work.
  159. sfh.bSpacing = (pifi->flInfo & FM_INFO_CONSTANT_WIDTH) ? 0 : 1;
  160. sfh.wPitch = 4 * pifi->fwdAveCharWidth; // PCL quarter dots
  161. sfh.wHeight = 4 * sfh.wCellHeight;
  162. sfh.wXHeight = 4 * (pifi->fwdWinAscender / 2);
  163. sfh.sbWidthType = 0; // Normal weight
  164. sfh.bStyle = pifi->ptlCaret.x ? 0 : 1; // Italic unless upright
  165. sfh.sbStrokeW = 0;
  166. sfh.bTypeface = 0;
  167. sfh.bSerifStyle = 0;
  168. sfh.sbUDist = -1; // Next 2 are not used by us
  169. sfh.bUHeight = 3;
  170. sfh.wTextHeight = 4 * (pifi->fwdWinAscender + pifi->fwdWinDescender);
  171. sfh.wTextWidth = 4 * pifi->fwdAveCharWidth;
  172. sfh.bPitchExt = 0;
  173. sfh.bHeightExt = 0;
  174. if ( 0 > iDrvPrintfSafeA( sfh.chName, CCHOF(sfh.chName), "Cache %d", id ) )
  175. {
  176. // if iDrvPrintfSafeA returns negative, then return.
  177. return 0;
  178. }
  179. #if PRINT_INFO
  180. vPrintPCLFontHeader(sfh);
  181. #endif
  182. /*
  183. * Do the switch: little endian to 68k big endian.
  184. */
  185. SWAB( sfh.wSize );
  186. SWAB( sfh.wBaseline );
  187. SWAB( sfh.wCellWide );
  188. SWAB( sfh.wCellHeight );
  189. SWAB( sfh.wSymSet );
  190. SWAB( sfh.wPitch );
  191. SWAB( sfh.wHeight );
  192. SWAB( sfh.wXHeight );
  193. SWAB( sfh.wTextHeight );
  194. SWAB( sfh.wTextWidth );
  195. SWAB( sfh.wXResn );
  196. SWAB( sfh.wYResn );
  197. if (cjSend > PCL_MAX_FONT_HEADER_SIZE)
  198. return 0;
  199. else
  200. {
  201. ZeroMemory( aPCLFontHdrCmd, sizeof( aPCLFontHdrCmd ) );
  202. iFontHdrCmdLen = iDrvPrintfSafeA( aPCLFontHdrCmd, CCHOF(aPCLFontHdrCmd), "\x1B)s%dW", cjSend );
  203. if ( iFontHdrCmdLen < 0 )
  204. {
  205. return 0;
  206. }
  207. if( WriteSpoolBuf( pPDev, aPCLFontHdrCmd, iFontHdrCmdLen ) != iFontHdrCmdLen )
  208. return 0;
  209. }
  210. if( WriteSpoolBuf( pPDev, (BYTE *)&sfh, cjSend ) != cjSend )
  211. return 0;
  212. return PCL_FONT_OH;
  213. }
  214. INT
  215. IDLGlyph(
  216. PDEV *pPDev,
  217. int iIndex,
  218. GLYPHDATA *pgd,
  219. DWORD *pdwMem
  220. )
  221. /*++
  222. Routine Description:
  223. Download the Char bitmap etc. for the glyph passed to us.
  224. Arguments:
  225. pPDev Pointer to PDEV
  226. iIndex Which glyph this is
  227. pgd Details of the glyph
  228. pdwMem Add the amount of memory used to this.
  229. Return Value:
  230. Character width; < 1 is an error.
  231. Note:
  232. 3/6/1997 -ganeshp-
  233. Created it.
  234. --*/
  235. {
  236. /*
  237. * Two basic steps: first is to generate the header structure
  238. * and send that off, then send the actual bitmap data. The only
  239. * complication happens if the download data exceeds 32,767 bytes
  240. * of glyph image. This is unlikely to happen, but we should
  241. * be prepared for it.
  242. */
  243. int cbLines; /* Bytes per scan line (sent to printer) */
  244. int cbTotal; /* Total number of bytes to send */
  245. int cbSend; /* If size > 32767; send in chunks */
  246. GLYPHBITS *pgb; /* Speedier access */
  247. CH_HEADER chh; /* The initial, main header */
  248. BYTE aPCLCharHdrCmd[20];
  249. INT iCharHdrCmdLen = 0;
  250. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  251. ASSERTMSG(pgd, ("UniFont!IDLGlyph:pgd is NULL.\n"));
  252. ZeroMemory( &chh, sizeof( chh ) ); /* Safe initial values */
  253. chh.bFormat = CH_FM_RASTER;
  254. chh.bContinuation = 0;
  255. chh.bDescSize = sizeof( chh ) - sizeof( CH_CONT_HDR );
  256. chh.bClass = CH_CL_BITMAP;
  257. chh.bOrientation = 0; //Set the Orientation to 0 always, else it won't work.
  258. pgb = pgd->gdf.pgb;
  259. chh.sLOff = (short)pgb->ptlOrigin.x;
  260. chh.sTOff = (short)-pgb->ptlOrigin.y;
  261. chh.wChWidth = (WORD)pgb->sizlBitmap.cx; /* Active pels */
  262. chh.wChHeight = (WORD)pgb->sizlBitmap.cy; /* Scanlines in bitmap */
  263. chh.wDeltaX = (WORD)((pgd->ptqD.x.HighPart + 3) >> 2); /* 28.4 ->14.2 */
  264. #if PRINT_INFO
  265. DbgPrint("UniFont!IDLGlyph:Value of (pgd->ptqD.x.HighPart ) is %d\n",
  266. (pgd->ptqD.x.HighPart ) );
  267. DbgPrint("UniFont!IDLGlyph:Value of pgb->sizlBitmap.cx is %d\n",
  268. pgb->sizlBitmap.cx );
  269. DbgPrint("UniFont!IDLGlyph:Value of pgb->sizlBitmap.cy is %d\n",
  270. pgb->sizlBitmap.cy );
  271. vPrintPCLCharHeader(chh);
  272. vPrintPCLChar((char*)pgb->aj,(WORD)pgb->sizlBitmap.cy,(WORD)pgb->sizlBitmap.cx);
  273. #endif
  274. /*
  275. * Calculate some sizes of bitmaps: coming from GDI, going to printer.
  276. */
  277. cbLines = (chh.wChWidth + BBITS - 1) / BBITS;
  278. cbTotal = sizeof( chh ) + cbLines * pgb->sizlBitmap.cy;
  279. /* Do the big endian shuffle */
  280. SWAB( chh.sLOff );
  281. SWAB( chh.sTOff );
  282. SWAB( chh.wChWidth );
  283. SWAB( chh.wChHeight );
  284. SWAB( chh.wDeltaX );
  285. // If the char is a pseudo one don't download it.
  286. if ( !(pgd->ptqD.x.HighPart) )
  287. {
  288. #if PRINT_INFO
  289. DbgPrint("\nRasdd!IDLGlyph:Returning 0 for fake char\n");
  290. #endif
  291. return 0;
  292. }
  293. /*
  294. * Presume that data is less than the maximum, and so can be
  295. * sent in one hit. Then loop on any remaining data.
  296. */
  297. cbSend = min( cbTotal, PCL_MAX_CHAR_HEADER_SIZE );
  298. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETCHARCODE));
  299. ASSERT(cbSend <= PCL_MAX_CHAR_HEADER_SIZE);
  300. ZeroMemory( aPCLCharHdrCmd, sizeof( aPCLCharHdrCmd ) );
  301. iCharHdrCmdLen = iDrvPrintfSafeA( aPCLCharHdrCmd, CCHOF(aPCLCharHdrCmd), "\x1B(s%dW", cbSend );
  302. PRINTVAL(iCharHdrCmdLen,%d);
  303. if ( iCharHdrCmdLen < 0 )
  304. {
  305. return 0;
  306. }
  307. if( WriteSpoolBuf( pPDev, aPCLCharHdrCmd, iCharHdrCmdLen ) != iCharHdrCmdLen )
  308. return 0;
  309. if( WriteSpoolBuf( pPDev, (BYTE *)&chh, sizeof( chh ) ) != sizeof( chh ))
  310. return 0;
  311. /* Sent some, so reduce byte count to compensate */
  312. cbSend -= sizeof( chh );
  313. cbTotal -= sizeof( chh );
  314. cbTotal -= cbSend; /* Adjust for about to send data */
  315. if( WriteSpoolBuf( pPDev, pgb->aj, cbSend ) != cbSend )
  316. return 0;
  317. if( cbTotal > 0 )
  318. {
  319. #if DBG
  320. DbgPrint( "UniFont!IDLGlyph: cbTotal != 0: NEEDS SENDING LOOP\n" );
  321. #endif
  322. return 0;
  323. }
  324. *pdwMem += cbLines * pgb->sizlBitmap.cy; /* Bytes used, roughly */
  325. return (SWAB( chh.wDeltaX ) + 3) >> 2; /* PCL is in quarter dots! */
  326. }
  327. #if PRINT_INFO
  328. void vPrintPCLCharHeader(chh)
  329. CH_HEADER chh;
  330. {
  331. DbgPrint("\nDUMPING FONT PCL GLYPH DESCRIPTOR\n");
  332. if(chh.bFormat == CH_FM_RASTER)
  333. DbgPrint("Value of chh.bFormat is CH_FM_RASTER\n");
  334. DbgPrint("Value of chh.bContinuation is %d \n",chh.bContinuation);
  335. DbgPrint("Value of chh.bDescSize is %d \n",chh.bDescSize);
  336. if(chh.bClass == CH_CL_BITMAP)
  337. DbgPrint("Value of chh.bClass is CH_CL_BITMAP \n");
  338. DbgPrint("Value of chh.bOrientation is %d \n",chh.bOrientation);
  339. DbgPrint("Value of chh.sLOff is %u \n",chh.sLOff);
  340. DbgPrint("Value of chh.sTOff is %u \n",chh.sTOff);
  341. DbgPrint("Value of chh.wChWidth is %u \n",chh.wChWidth);
  342. DbgPrint("Value of chh.wChHeight is %u \n",chh.wChHeight);
  343. DbgPrint("Value of chh.wDeltaX is %u \n",chh.wDeltaX);
  344. }
  345. void vPrintPCLFontHeader(sfh)
  346. SF_HEADER20 sfh;
  347. {
  348. DbgPrint("\nDUMPING FONT PCL FONT DESCRIPTOR\n");
  349. DbgPrint("Value of sfh.wSize is %d \n",sfh.wSize);
  350. if(sfh.bFormat == PCL_FM_RESOLUTION)
  351. DbgPrint("Value of sfh.bFormat is PCL_FM_RESOLUTION\n");
  352. else if (sfh.bFormat == PCL_FM_ORIGINAL)
  353. DbgPrint("Value of sfh.bFormat is PCL_FM_ORIGINAL\n");
  354. DbgPrint("Value of sfh.wXResn is %d \n",sfh.wXResn);
  355. DbgPrint("Value of sfh.wYResn is %d \n",sfh.wYResn);
  356. if(sfh.bFontType == PCL_FT_PC8)
  357. DbgPrint("Value of sfh.bFontType is PCL_FT_PC8\n");
  358. else if (sfh.bFontType == PCL_FT_8LIM)
  359. DbgPrint("Value of sfh.bFontType is PCL_FT_8LIM\n");
  360. DbgPrint("Value of sfh.wSymSet is %d \n",sfh.wSymSet);
  361. DbgPrint("Value of sfh.wBaseline is %d \n",sfh.wBaseline);
  362. DbgPrint("Value of sfh.wCellWide is %d \n",sfh.wCellWide);
  363. DbgPrint("Value of sfh.wCellHeight is %d \n",sfh.wCellHeight);
  364. DbgPrint("Value of sfh.bOrientation is %d \n",sfh.bOrientation);
  365. DbgPrint("Value of sfh.bSpacing is %d \n",sfh.bSpacing);
  366. DbgPrint("Value of sfh.wPitch is %d \n",sfh.wPitch);
  367. DbgPrint("Value of sfh.wHeight is %d \n",sfh.wHeight);
  368. DbgPrint("Value of sfh.wXHeight is %d \n",sfh.wXHeight);
  369. DbgPrint("Value of sfh.sbWidthType is %d \n",sfh.sbWidthType);
  370. DbgPrint("Value of sfh.bStyle is %d \n",sfh.bStyle);
  371. DbgPrint("Value of sfh.sbStrokeW is %d \n",sfh.sbStrokeW);
  372. DbgPrint("Value of sfh.bTypeface is %d \n",sfh.bTypeface);
  373. DbgPrint("Value of sfh.bSerifStyle is %d \n",sfh.bSerifStyle);
  374. DbgPrint("Value of sfh.sbUDist is %d \n",sfh.sbUDist);
  375. DbgPrint("Value of sfh.bUHeight is %d \n",sfh.bUHeight);
  376. DbgPrint("Value of sfh.wTextHeight is %d \n",sfh.wTextHeight);
  377. DbgPrint("Value of sfh.wTextWidth is %d \n",sfh.wTextWidth);
  378. DbgPrint("Value of sfh.bPitchExt is %d \n",sfh.bPitchExt);
  379. DbgPrint("Value of sfh.bHeightExt is %d \n",sfh.bHeightExt);
  380. }
  381. void vPrintPCLChar(pGlyphBits,wHeight,wWidth)
  382. char * pGlyphBits;
  383. WORD wHeight;
  384. WORD wWidth;
  385. {
  386. int iIndex1, iIndex2;
  387. char cMaskBits[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  388. unsigned char bBitON;
  389. DbgPrint("\nDUMPING THE GLYPH BITS\n");
  390. for(iIndex1 = 0;iIndex1 < wHeight; iIndex1++)
  391. {
  392. for(iIndex2 = 0;iIndex2 < wWidth; iIndex2++)
  393. {
  394. bBitON = (pGlyphBits[iIndex2 / 8] & cMaskBits[iIndex2 % 8]);
  395. if (bBitON)
  396. DbgPrint("*");
  397. else
  398. DbgPrint("0");
  399. //if(!(iIndex2%8))
  400. //DbgPrint("%x ",(unsigned char)(*(pGlyphBits+(iIndex2/8))) );
  401. //DbgPrint("%x ",(unsigned char)(bBitON >> (7-(iIndex2%8))) );
  402. }
  403. pGlyphBits+= (wWidth+7) / 8;
  404. DbgPrint("\n");
  405. }
  406. }
  407. #endif