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.

476 lines
13 KiB

  1. //
  2. // fuband.c
  3. //
  4. // August.26,1997 H.Ishida(FPL)
  5. // fuxlres.dll (NT5.0 MiniDriver)
  6. //
  7. // July.31,1996 H.Ishida (FPL)
  8. // FUXL.DLL (NT4.0 MiniDriver)
  9. //
  10. #include "fuxl.h"
  11. #include "fumh.h"
  12. #include "fumh2.h"
  13. #include "fuband.h"
  14. #include "fuimg2.h"
  15. #include "fuimg4.h"
  16. #include "fudebug.h"
  17. //
  18. // FjBAND:
  19. // In Win-F image command(RTGIMG2 and RTGIMG4), image coordinate must
  20. // be a multiple of 32. But I can't create such a GPC file for RasDD.
  21. // Some image data, not on 32x32 grid, must be buffered in FjBAND,
  22. // width:papser width, height:32, x-coordinate:0, y-coordinate:a multiple
  23. // of 32.
  24. //
  25. // Image to be output
  26. // (0, y)
  27. // A----------------------------------+
  28. // | partA |
  29. // B----------------------------------+
  30. // | partB |
  31. // | |
  32. // | |
  33. // C----------------------------------+
  34. // | partC |
  35. // D----------------------------------+
  36. //
  37. // I split source image to 3 part.
  38. // A: top of image, is not a multiple of 32.
  39. // B: top of image, is a multiple of 32.
  40. // C: bottom of image, is a multilpe of 32.
  41. // D: bottom of image, is not a multile of 32.
  42. //
  43. // partA: A to B. this part is buffered in FjBAND, ORed on
  44. // previousely written image.
  45. // partB: B to C. this part is not bufferd, output immediately.
  46. // partC: C to D. this part is buffered in FjBAND, may be ORed
  47. // partA of next image.
  48. //
  49. #define FUXL_BANDHEIGHT 32
  50. //
  51. // void fuxlInitBand(PFUXLPDEV pFuxlPDEV) // fuxlres private PDEV
  52. //
  53. // This function initializes FjBAND, but not allocate memory for band.
  54. //
  55. void fuxlInitBand(PFUXLPDEV pFuxlPDEV)
  56. {
  57. int i;
  58. pFuxlPDEV->cBandByteWidth = (pFuxlPDEV->cxPage + 7) / 8;
  59. i = 0x10000L / pFuxlPDEV->cBandByteWidth;
  60. pFuxlPDEV->cyBandSegment = i - (i % FUXL_BANDHEIGHT);
  61. pFuxlPDEV->pbBand = NULL;
  62. pFuxlPDEV->cbBand = FUXL_BANDHEIGHT * pFuxlPDEV->cBandByteWidth;
  63. pFuxlPDEV->yBandTop = 0;
  64. pFuxlPDEV->bBandDirty = FALSE;
  65. pFuxlPDEV->bBandError = FALSE;
  66. }
  67. //
  68. // BOOL fuxlEnableBand(
  69. // PFUXLPDEV pFuxlPDEV // fuxlres private PDEV
  70. // );
  71. //
  72. // This function allocates memory for FjBAND.
  73. //
  74. // Return Values
  75. // TRUE: band memory is allocated.
  76. // FALSE: band memory is not allocated.
  77. //
  78. BOOL fuxlEnableBand(PFUXLPDEV pFuxlPDEV)
  79. {
  80. DWORD cbBand;
  81. pFuxlPDEV->pbBand = (LPBYTE)MemAllocZ(pFuxlPDEV->cbBand);
  82. if(pFuxlPDEV->pbBand == NULL){
  83. pFuxlPDEV->bBandError = TRUE;
  84. return FALSE;
  85. }
  86. memset(pFuxlPDEV->pbBand, 0, pFuxlPDEV->cbBand);
  87. pFuxlPDEV->bBandDirty = FALSE;
  88. return TRUE;
  89. }
  90. //
  91. // void fuxlDisableBand(
  92. // PFUXLPDEV pFuxlPDEV // fuxlres private PDEV
  93. // );
  94. //
  95. // This function frees memory for FjBAND.
  96. //
  97. void fuxlDisableBand(PFUXLPDEV pFuxlPDEV)
  98. {
  99. if(pFuxlPDEV->pbBand != NULL){
  100. MemFree(pFuxlPDEV->pbBand);
  101. pFuxlPDEV->pbBand = NULL;
  102. }
  103. pFuxlPDEV->bBandError = FALSE;
  104. }
  105. //
  106. // void fuxlCopyBand(
  107. // PDEVOBJ pdevobj, // MINI5 data
  108. // LPBYTE pBuff, // address of source image data.
  109. // LONG lDelta, // width of source image data(in bytes)
  110. // int y, // y-coordinate of source image.
  111. // int cy // height of source image data(scanline)
  112. // );
  113. //
  114. // This function copies source image data to FjBAND.
  115. //
  116. //
  117. void fuxlCopyBand(PDEVOBJ pdevobj, LPCBYTE pbSrc, int cSrcBandWidth, int y, int cy)
  118. {
  119. PFUXLPDEV pFuxlPDEV;
  120. LPCBYTE pbSrcTmp;
  121. LPBYTE pbDst;
  122. LPBYTE pbDstTmp;
  123. int i;
  124. int j;
  125. UINT uTmp;
  126. pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM;
  127. if(pFuxlPDEV->yBandTop <= y && y + cy <= pFuxlPDEV->yBandTop + FUXL_BANDHEIGHT){
  128. pbDst = pFuxlPDEV->pbBand + (y - pFuxlPDEV->yBandTop) * pFuxlPDEV->cBandByteWidth;
  129. uTmp = 0;
  130. for(i = cy; i > 0; --i){
  131. pbDstTmp = pbDst;
  132. for(j = cSrcBandWidth; j > 0; --j){
  133. uTmp |= *pbSrc;
  134. *pbDstTmp++ |= *pbSrc++;
  135. }
  136. pbDst += pFuxlPDEV->cBandByteWidth;
  137. }
  138. if(uTmp != 0)
  139. pFuxlPDEV->bBandDirty = TRUE;
  140. }
  141. }
  142. //
  143. // BOOL fuxlOutputMH(
  144. // PDEVOBJ pdevobj // MINI5 data
  145. // LPCBYTE pbSrc, // address of source image data.
  146. // LONG lDelta, // width of source image data(in byte).
  147. // int y, // y-coordinate of source image data.
  148. // int cy // height of source image data(scanline).
  149. // );
  150. //
  151. // This function outputs image, uses FM-MH(old type).
  152. //
  153. // Return Values
  154. // TRUE: output succeeded.
  155. // FALSE: output failed.
  156. // memory allocate error, or
  157. // MH compression is not effecive for this image data.
  158. //
  159. BOOL fuxlOutputMH(PDEVOBJ pdevobj, LPCBYTE pbSrc, int cSrcBandWidth, int y, int cy)
  160. {
  161. BOOL bResult;
  162. LPBYTE pDest;
  163. LONG cb;
  164. LONG cDestN;
  165. DWORD cbMHData;
  166. BYTE abTmp[10];
  167. bResult = FALSE;
  168. cb = cSrcBandWidth * cy;
  169. cDestN = (cb + 1) / 2;
  170. pDest = (LPBYTE)MemAllocZ(cDestN);
  171. if(pDest != NULL){
  172. cbMHData = (WORD)MhCompress(pDest, cDestN, (LPBYTE)pbSrc, cSrcBandWidth * cy, cSrcBandWidth, cy);
  173. if(cbMHData > 0){
  174. memcpy(abTmp, "\x1d\x30\x20\x62\x00\x00", 6);
  175. abTmp[6] = HIBYTE((WORD)y);
  176. abTmp[7] = LOBYTE((WORD)y);
  177. abTmp[8] = HIBYTE(cbMHData);
  178. abTmp[9] = LOBYTE(cbMHData);
  179. WRITESPOOLBUF(pdevobj, abTmp, 10);
  180. WRITESPOOLBUF(pdevobj, pDest, cbMHData);
  181. WRITESPOOLBUF(pdevobj, "\x00\x00", 2 );
  182. bResult = TRUE;
  183. }
  184. MemFree(pDest);
  185. }
  186. return bResult;
  187. }
  188. //
  189. // BOOL fuxlOutputMH2(
  190. // PDEVOBJ pdevobj, // MINI5 data
  191. // LPCBYTE pbSrc, // address of source image data.
  192. // LONG lDelta, // width of source image data(in byte).
  193. // int y, // y-coordinate of source image data.
  194. // int cy // height of source image data(scanline).
  195. // );
  196. //
  197. // This function outputs image, uses FM-MH2(for XL-65K and after).
  198. //
  199. // Return Value
  200. // TRUE: output succeeded.
  201. // FALSE: output failed.
  202. // memory allocate error, or
  203. // MH compression is not effective for this iamge data.
  204. //
  205. BOOL fuxlOutputMH2(PDEVOBJ pdevobj, LPCBYTE pbSrc, int cSrcByteWidth, int y, int cy)
  206. {
  207. BOOL bResult;
  208. LPBYTE pDest;
  209. LONG cb;
  210. LONG cDestN;
  211. DWORD cbMHData;
  212. BYTE abTmp[10];
  213. bResult = FALSE;
  214. cb = cSrcByteWidth * cy;
  215. cDestN = (cb + 1) / 2;
  216. pDest = (LPBYTE)MemAllocZ(cDestN);
  217. if(pDest != NULL){
  218. cbMHData = Mh2Compress(pDest, cDestN, (LPBYTE)pbSrc, cSrcByteWidth * cy, cSrcByteWidth, cy);
  219. if(cbMHData > 0){
  220. memcpy(abTmp, "\x1d\x30\x20\x62\x00\x00", 6);
  221. abTmp[6] = HIBYTE((WORD)y);
  222. abTmp[7] = LOBYTE((WORD)y);
  223. abTmp[8] = HIBYTE(cbMHData);
  224. abTmp[9] = LOBYTE(cbMHData);
  225. WRITESPOOLBUF(pdevobj, abTmp, 10);
  226. WRITESPOOLBUF(pdevobj, pDest, cbMHData);
  227. WRITESPOOLBUF(pdevobj, "\x00\x00", 2 );
  228. bResult = TRUE;
  229. }
  230. MemFree(pDest);
  231. }
  232. return bResult;
  233. }
  234. //
  235. // void fuxlOutputGraphics(
  236. // PDEVOBJ pdevobj, // MINI5
  237. // LPCBYTE pbSrc, // address of source image data.
  238. // UINT bx, // width of source iamge data(in byte).
  239. // UINT y, // y-coordinate of source iamge data.
  240. // UINT cy // height of source iamge data(scanline).
  241. // );
  242. //
  243. // This function outputs source iamge data.
  244. //
  245. void fuxlOutputGraphics(PDEVOBJ pdevobj, LPCBYTE pbSrc, int cSrcByteWidth, UINT y, UINT cy)
  246. {
  247. PFUXLPDEV pFuxlPDEV;
  248. DWORD dwOutputCmd;
  249. TRACEOUT(("[fuxlOutputGraphics]y %d cy %d\r\n", y, cy))
  250. pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM;
  251. dwOutputCmd = pFuxlPDEV->dwOutputCmd;
  252. if((dwOutputCmd & OUTPUT_MH2) != 0){
  253. TRACEOUT(("[fuxlOutputGraphics]Try MH2\r\n"))
  254. if(fuxlOutputMH2(pdevobj, pbSrc, cSrcByteWidth, y, cy) != FALSE)
  255. return;
  256. }
  257. if((dwOutputCmd & OUTPUT_RTGIMG4) != 0){
  258. TRACEOUT(("[fuxlOutputGraphics]Send RTGIMG4\r\n"))
  259. fuxlOutputRTGIMG4(pdevobj, pbSrc, cSrcByteWidth, y, cy);
  260. return;
  261. }
  262. if((dwOutputCmd & OUTPUT_MH) != 0){
  263. TRACEOUT(("[fuxlOutputGraphics]Try MH\r\n"))
  264. if(fuxlOutputMH(pdevobj, pbSrc, cSrcByteWidth, y, cy) != FALSE)
  265. return;
  266. }
  267. TRACEOUT(("[fuxlOutputGraphics]Send RTGIMG2\r\n"))
  268. fuxlOutputRTGIMG2(pdevobj, pbSrc, cSrcByteWidth, y, cy);
  269. }
  270. //
  271. // BOOL fuxlSetBandPos(
  272. // PDEVOBJ pdevobj, // MINI5 data
  273. // int yPos // y-coordinate
  274. // );
  275. //
  276. // This function sets y-coordinate of FjBAND.
  277. //
  278. // Return Value.
  279. // TRUE: secceeded
  280. // FALSE: failed(FjBAND can't move upward)
  281. //
  282. // Remarks
  283. // Internally, y-coordinate is adjust to a multiple of 32.
  284. // Then check new y-coordinate, if it is equal to previous y-coordinate,
  285. // the contents of FjBAND remain. Otherwise, flushes FjBAND.
  286. //
  287. BOOL fuxlSetBandPos(PDEVOBJ pdevobj, int yPos)
  288. {
  289. PFUXLPDEV pFuxlPDEV;
  290. pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM;
  291. if(yPos < pFuxlPDEV->yBandTop)
  292. return FALSE;
  293. yPos -= yPos % FUXL_BANDHEIGHT;
  294. if(yPos != pFuxlPDEV->yBandTop){
  295. if(pFuxlPDEV->bBandDirty != FALSE){
  296. fuxlOutputGraphics(pdevobj, pFuxlPDEV->pbBand, pFuxlPDEV->cBandByteWidth, pFuxlPDEV->yBandTop, FUXL_BANDHEIGHT);
  297. memset(pFuxlPDEV->pbBand, 0, pFuxlPDEV->cbBand);
  298. pFuxlPDEV->bBandDirty = FALSE;
  299. }
  300. pFuxlPDEV->yBandTop = yPos;
  301. }
  302. return TRUE;
  303. }
  304. //
  305. // void fuxlRefreshBand(
  306. // PDEVOBJ pdevobj // MINI5 data
  307. // );
  308. //
  309. // This function flushes FjBAND, send FormFeed command, and sets
  310. // y-coordinate to top(0).
  311. //
  312. void fuxlRefreshBand(PDEVOBJ pdevobj)
  313. {
  314. PFUXLPDEV pFuxlPDEV;
  315. pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM;
  316. if(pFuxlPDEV->bBandDirty != FALSE){
  317. fuxlOutputGraphics(pdevobj, pFuxlPDEV->pbBand, pFuxlPDEV->cBandByteWidth, pFuxlPDEV->yBandTop, FUXL_BANDHEIGHT);
  318. memset(pFuxlPDEV->pbBand, 0, pFuxlPDEV->cbBand);
  319. pFuxlPDEV->bBandDirty = FALSE;
  320. }
  321. WRITESPOOLBUF(pdevobj, "\x0c", 1); // FF command
  322. pFuxlPDEV->yBandTop = 0;
  323. }
  324. //
  325. // WORD OEMFilterGraphics(
  326. // LPDV lpdv, // address of private data, used by RasDD.
  327. // LPBYTE lpBuf, // address of source iamge data.
  328. // WORD wLen // size of source image data.
  329. // );
  330. //
  331. // This function convert image format to Printer command sequence,
  332. // and spool it.
  333. //
  334. // Return Value
  335. // the number of bytes of processed raster data.
  336. // the number of bytes may be the same as wLen, but not necessarily.
  337. //
  338. // Remarks
  339. //
  340. // | <--------------- pFuxlPDEV->cBlockWidth-----------> |
  341. // lpBuf *--------+--------+--------+--------+--------+--------+---
  342. // | | | | | | | ^
  343. // +--------+--------+--------+--------+--------+--------+ |
  344. // | | | | | | | pFuxlPDEV->
  345. // +--------+--------+--------+--------+--------+--------+ cBlockHeight
  346. // | | | | | | | |
  347. // +--------+--------+--------+--------+--------+--------+ |
  348. // | | | | | | | v
  349. // +--------+--------+--------+--------+--------+--------+---
  350. //
  351. // white dot:0
  352. // black dot:1
  353. //
  354. // coordinate of '*' (left-top of image):
  355. // pFuxlPDEV->x
  356. // pFuxlPDEV->y
  357. //
  358. //
  359. // MINI5 export
  360. BOOL APIENTRY OEMFilterGraphics(PDEVOBJ pdevobj, LPBYTE pbBuf, DWORD dwLen)
  361. {
  362. PFUXLPDEV pFuxlPDEV;
  363. LPCBYTE pbSrc;
  364. int y;
  365. int yAlignTop;
  366. int yBottom;
  367. int yAlignBottom;
  368. int cSrcByteWidth;
  369. int cLine;
  370. TRACEOUT(("[OEMFilterGraphics]\r\n"))
  371. pFuxlPDEV = (PFUXLPDEV)pdevobj->pdevOEM;
  372. if(pFuxlPDEV->pbBand == NULL){
  373. if(pFuxlPDEV->bBandError != FALSE)
  374. return FALSE;
  375. if(fuxlEnableBand(pFuxlPDEV) == FALSE)
  376. return FALSE;
  377. }
  378. pbSrc = pbBuf;
  379. y = pFuxlPDEV->y;
  380. yAlignTop = y - (y % FUXL_BANDHEIGHT);
  381. yBottom = y + pFuxlPDEV->cBlockHeight;
  382. yAlignBottom = yBottom - (yBottom % FUXL_BANDHEIGHT);
  383. cSrcByteWidth = pFuxlPDEV->cBlockByteWidth;
  384. if(yAlignTop < y){
  385. // partA
  386. if(fuxlSetBandPos(pdevobj, y) == FALSE) // FUXL band pos can't move up
  387. return TRUE;
  388. cLine = FUXL_BANDHEIGHT - (y - yAlignTop);
  389. if(y + cLine >= yBottom){
  390. fuxlCopyBand(pdevobj, pbSrc, cSrcByteWidth, y, yBottom - y);
  391. return TRUE;
  392. }
  393. fuxlCopyBand(pdevobj, pbSrc, cSrcByteWidth, y, cLine);
  394. pbSrc += cSrcByteWidth * cLine;
  395. y += cLine;
  396. }
  397. if(y < yAlignBottom){
  398. // partB
  399. if(fuxlSetBandPos(pdevobj, yAlignBottom) == FALSE) // FUXL band pos can't move up
  400. return TRUE;
  401. for(cLine = yAlignBottom - y; cLine >= pFuxlPDEV->cyBandSegment; cLine -= pFuxlPDEV->cyBandSegment){
  402. fuxlOutputGraphics(pdevobj, pbSrc, cSrcByteWidth, y, pFuxlPDEV->cyBandSegment);
  403. pbSrc += cSrcByteWidth * pFuxlPDEV->cyBandSegment;
  404. y += pFuxlPDEV->cyBandSegment;
  405. }
  406. if(cLine > 0){
  407. fuxlOutputGraphics(pdevobj, pbSrc, cSrcByteWidth, y, cLine);
  408. pbSrc += cSrcByteWidth * cLine;
  409. y += cLine;
  410. }
  411. }
  412. if(y < yBottom){
  413. // partC
  414. if(fuxlSetBandPos(pdevobj, y) == FALSE) // FUXL band pos can't move up
  415. return TRUE;
  416. fuxlCopyBand(pdevobj, pbSrc, cSrcByteWidth, y, yBottom - y);
  417. }
  418. return TRUE;
  419. }
  420. // end of fuband.c