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.

550 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. brush.c
  5. Abstract:
  6. DrvRealizeBrush
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. 05/14/97 -amandan-
  11. Created
  12. --*/
  13. #include "unidrv.h"
  14. BRGBColorSpace(PDEV *);
  15. LONG
  16. FindCachedHTPattern(
  17. PDEV *pPDev,
  18. WORD wChecksum
  19. )
  20. /*++
  21. Routine Description:
  22. This function find the cached text brush pattern color, if not there then
  23. it will add it to the cached.
  24. Arguments:
  25. pPDev - Pointer to our PDEV
  26. wCheckSum - Checksum of pattern brush
  27. Return Value:
  28. LONG >0 - Found the cached, return value is the pattern ID
  29. =0 - Out of memory, not cached
  30. <0 - not in the cached, add to the cached, return value is
  31. the negated pattern ID
  32. Author:
  33. 08-Apr-1997 Tue 19:42:21 created -by- Daniel Chou (danielc)
  34. Revision History:
  35. --*/
  36. {
  37. LPWORD pDBCache;
  38. WORD cMaxDB;
  39. WORD cUsedDB;
  40. WORD Index;
  41. //
  42. // The first is the cMaxDB, the 2nd is the cUsedDB
  43. //
  44. if (pDBCache = pPDev->GState.pCachedPatterns)
  45. {
  46. cMaxDB = *(pDBCache + 0);
  47. cUsedDB = *(pDBCache + 1);
  48. pDBCache += 2;
  49. for (Index = 1; Index <= cUsedDB; Index++, pDBCache++)
  50. {
  51. if (*pDBCache == wChecksum)
  52. {
  53. VERBOSE(("\n\tRaddd:FindCachedHTPat(%04lx): FOUND=%ld ",
  54. wChecksum, Index));
  55. return((LONG)Index);
  56. }
  57. }
  58. //
  59. // If we can't find a cached one, add the new one to the list
  60. //
  61. if (cUsedDB < cMaxDB)
  62. {
  63. *pDBCache = wChecksum;
  64. *(pPDev->GState.pCachedPatterns + 1) += 1;
  65. VERBOSE(("\n\tRaddd:FindCachedHTPat(%04lx): NOT FOUND=%ld ",
  66. wChecksum, -(LONG)Index));
  67. return(-(LONG)Index);
  68. }
  69. }
  70. else
  71. {
  72. cUsedDB =
  73. cMaxDB = 0;
  74. }
  75. //
  76. // We need to expand the checksum cached buffer
  77. //
  78. VERBOSE(("\n\tUnidrv:FindCachedHTPat(%04lx): pDBCache=%08lx, cUsedDB=%ld, cMaxDB=%ld",
  79. wChecksum, pDBCache, cUsedDB, cMaxDB));
  80. if (((cMaxDB + DBCACHE_INC) < DBCACHE_MAX) &&
  81. (pDBCache = (LPWORD)MemAllocZ((cMaxDB + DBCACHE_INC + 2) *
  82. sizeof(WORD))))
  83. {
  84. if ((cMaxDB) && (pPDev->GState.pCachedPatterns))
  85. {
  86. CopyMemory(pDBCache + 2,
  87. pPDev->GState.pCachedPatterns + 2,
  88. cMaxDB * sizeof(WORD));
  89. MemFree(pPDev->GState.pCachedPatterns);
  90. }
  91. *(pDBCache + 0) = cMaxDB + DBCACHE_INC;
  92. *(pDBCache + 1) = cUsedDB + 1;
  93. *(pDBCache + 2 + cUsedDB) = wChecksum;
  94. pPDev->GState.pCachedPatterns = pDBCache;
  95. VERBOSE (("\n\tUnidrv:FindCachedHTPat(%04lx): pDBCache=%08lx, cUsedDB=%ld, cMaxDB=%ld, EMPTY=%ld ",
  96. wChecksum, pDBCache, *(pDBCache + 1), *(pDBCache + 0), -(LONG)(cUsedDB + 1)));
  97. return(-(LONG)(cUsedDB + 1));
  98. }
  99. //
  100. // Out of memory
  101. //
  102. WARNING(("\n\tUnidrv:FindCachedHTPat: OUT OF MEMORY"));
  103. return(0);
  104. }
  105. BOOL
  106. Download1BPPHTPattern(
  107. PDEV *pPDev,
  108. SURFOBJ *pso,
  109. DWORD dwPatID
  110. )
  111. /*++
  112. Routine Description:
  113. This function donload a user define pattern
  114. Arguments:
  115. pPDev - Pointer to the PDEV
  116. pDevBrush - Pointer to the cached device brush
  117. Return Value:
  118. INT to indicate a pattern number downloaed/defined
  119. Author:
  120. 08-Apr-1997 Tue 19:41:00 created -by- Daniel Chou (danielc)
  121. Revision History:
  122. --*/
  123. {
  124. SURFOBJ so;
  125. LPBYTE pb;
  126. LPBYTE pbEnd;
  127. LPBYTE pSrc;
  128. DWORD cbCX;
  129. DWORD cb;
  130. WORD cxcyRes;
  131. INT Len;
  132. BYTE Buf[64];
  133. BYTE XorMask;
  134. BYTE EndMask;
  135. so = *pso;
  136. pb = Buf;
  137. pbEnd = pb + sizeof(Buf) - 4;
  138. cbCX = (DWORD)(((DWORD)so.sizlBitmap.cx + 7) >> 3);
  139. //
  140. // Update standard variable and send command
  141. //
  142. pPDev->dwPatternBrushType = BRUSH_USERPATTERN;
  143. pPDev->dwPatternBrushSize = (DWORD)(cbCX * so.sizlBitmap.cy) + 12;
  144. pPDev->dwPatternBrushID = dwPatID;
  145. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_DOWNLOAD_PATTERN));
  146. //
  147. // Send header and pattern data
  148. //
  149. *pb++ = 20;
  150. *pb++ = 0;
  151. *pb++ = (so.iBitmapFormat == BMF_1BPP) ? 1 : 8;
  152. *pb++ = 0;
  153. *pb++ = HIBYTE((WORD)so.sizlBitmap.cx);
  154. *pb++ = LOBYTE((WORD)so.sizlBitmap.cx);
  155. *pb++ = HIBYTE((WORD)so.sizlBitmap.cy);
  156. *pb++ = LOBYTE((WORD)so.sizlBitmap.cy);
  157. *pb++ = HIBYTE((WORD)pPDev->ptGrxRes.x);
  158. *pb++ = LOBYTE((WORD)pPDev->ptGrxRes.x);
  159. *pb++ = HIBYTE((WORD)pPDev->ptGrxRes.y);
  160. *pb++ = LOBYTE((WORD)pPDev->ptGrxRes.y);
  161. //
  162. // The XorMask is used to flip the BLACK/WHITE bit depends on the output
  163. // and EndMask is to mask off any unwanted bit in the last byte to 0
  164. // this is to fix LJ5si, LJ4si firmware bugs, REMEMBER our palette always
  165. // in RGB additive mode so the passed in 1BPP format has 0=Black, 1=White
  166. //
  167. XorMask = (BRGBColorSpace(pPDev)) ? 0x00 : 0xff;
  168. if (!(EndMask = (BYTE)(0xff << (8 - (so.sizlBitmap.cx & 0x07)))))
  169. {
  170. EndMask = 0xff;
  171. }
  172. VERBOSE(("\n\tRaddd:DownLoaHTPattern: PatID=%ld, Format=%ld, %ld x %ld, XorMask=%02lx, EndMaks=%02lx\t\t",
  173. dwPatID, pso->iBitmapFormat, so.sizlBitmap.cx, so.sizlBitmap.cy,
  174. XorMask, EndMask));
  175. while (so.sizlBitmap.cy--)
  176. {
  177. cb = cbCX;
  178. pSrc = so.pvScan0;
  179. (LPBYTE)so.pvScan0 += so.lDelta;
  180. while (cb--)
  181. {
  182. *pb++ = (BYTE)(*pSrc++ ^ XorMask);
  183. if (!cb) {
  184. *(pb - 1) &= EndMask;
  185. }
  186. if (pb >= pbEnd) {
  187. WriteSpoolBuf(pPDev, Buf, (DWORD)(pb - Buf));
  188. pb = Buf;
  189. }
  190. }
  191. }
  192. //
  193. // Send remaining data
  194. //
  195. if (Len = (INT)(pb - Buf))
  196. {
  197. WriteSpoolBuf(pPDev, Buf, Len);
  198. }
  199. return(TRUE);
  200. }
  201. WORD
  202. GetBMPChecksum(
  203. SURFOBJ *pso,
  204. PRECTW prcw
  205. )
  206. /*++
  207. Routine Description:
  208. Arguments:
  209. Return Value:
  210. Author:
  211. 22-Apr-1997 Tue 11:32:37 created -by- Daniel Chou (danielc)
  212. Revision History:
  213. --*/
  214. {
  215. LPBYTE pb;
  216. RECTW rcw;
  217. LONG cy;
  218. LONG cPixels;
  219. LONG lDelta;
  220. WORD wChecksum;
  221. UINT c1stPixels;
  222. UINT Format;
  223. BYTE BegMask;
  224. BYTE EndMask;
  225. BYTE XorMask;
  226. rcw = *prcw;
  227. Format = (UINT)pso->iBitmapFormat;
  228. wChecksum = 0;
  229. VERBOSE(("\nComputeChecksum(%ld): (%4ld, %4ld)-(%4ld, %4ld)=%3ldx%3ld\t\t",
  230. Format, rcw.l, rcw.t, rcw.r, rcw.b,
  231. rcw.r - rcw.l, rcw.b - rcw.t));
  232. if (rcw.l > (WORD)pso->sizlBitmap.cx) {
  233. rcw.l = (WORD)pso->sizlBitmap.cx;
  234. }
  235. if (rcw.t > (WORD)pso->sizlBitmap.cy) {
  236. rcw.t = (WORD)pso->sizlBitmap.cy;
  237. }
  238. if (rcw.r > (WORD)pso->sizlBitmap.cx) {
  239. rcw.r = (WORD)pso->sizlBitmap.cx;
  240. }
  241. if (rcw.b > (WORD)pso->sizlBitmap.cy) {
  242. rcw.b = (WORD)pso->sizlBitmap.cy;
  243. }
  244. if ((rcw.r <= rcw.l) || (rcw.b <= rcw.t)) {
  245. return(wChecksum);
  246. }
  247. cPixels = (LONG)(rcw.r - rcw.l);
  248. cy = (LONG)(rcw.b - rcw.t);
  249. lDelta = pso->lDelta;
  250. pb = (LPBYTE)pso->pvScan0 + ((LONG)rcw.t * lDelta);
  251. XorMask = 0xFF;
  252. //
  253. // rcw.r and rcw.b are exclusive
  254. //
  255. --rcw.r;
  256. --rcw.b;
  257. switch (Format) {
  258. case BMF_1BPP:
  259. pb += (rcw.l >> 3);
  260. c1stPixels = (UINT)(8 - (rcw.l & 0x07));
  261. BegMask = (BYTE)(0xff >> (rcw.l & 0x07));
  262. EndMask = (BYTE)(0xff << (8 - (rcw.r & 0x07)));
  263. break;
  264. case BMF_4BPP:
  265. if (rcw.l & 0x01) {
  266. BegMask = 0x07;
  267. c1stPixels = 4;
  268. } else {
  269. BegMask = 0x77;
  270. c1stPixels = 0;
  271. }
  272. pb += (rcw.l >> 1);
  273. cPixels <<= 2;
  274. EndMask = (BYTE)((rcw.r & 0x01) ? 0x70 : 0x77);
  275. XorMask = 0x77;
  276. break;
  277. case BMF_8BPP:
  278. case BMF_16BPP:
  279. case BMF_24BPP:
  280. BegMask =
  281. EndMask = 0xFF;
  282. c1stPixels = (UINT)(Format - BMF_8BPP + 1);
  283. pb += (rcw.l * c1stPixels);
  284. cPixels *= (c1stPixels << 3);
  285. c1stPixels = 0;
  286. break;
  287. }
  288. while (cy--) {
  289. LPBYTE pbCur;
  290. LONG Count;
  291. WORD w;
  292. pbCur = pb;
  293. pb += lDelta;
  294. Count = cPixels;
  295. w = (WORD)((c1stPixels) ? ((*pbCur++ ^ XorMask) & BegMask) : 0);
  296. if ((Count -= c1stPixels) >= 8) {
  297. do {
  298. w <<= 8;
  299. w |= (*pbCur++ ^ XorMask);
  300. wChecksum += w;
  301. } while ((Count -= 8) >= 8);
  302. }
  303. if (Count > 0) {
  304. w <<= 8;
  305. w |= (WORD)((*pbCur ^ XorMask) & EndMask);
  306. } else {
  307. w &= EndMask;
  308. }
  309. wChecksum += w;
  310. }
  311. VERBOSE(("\nComputeChecksum(%ld:%04lx): (%4ld, %4ld)-(%4ld, %4ld)=%3ldx%3ld [%3ld], pb=%08lx [%02lx:%02lx], %1ld\t",
  312. Format, wChecksum,
  313. rcw.l, rcw.t, rcw.r + 1, rcw.b + 1,
  314. rcw.r - rcw.l + 1, rcw.b - rcw.t + 1, cPixels,
  315. pb, BegMask, EndMask, c1stPixels));
  316. return(wChecksum);
  317. }
  318. BOOL
  319. BRGBColorSpace(
  320. PDEV *pPDev
  321. )
  322. {
  323. LISTNODE *pListNode = NULL;
  324. if (pPDev->pDriverInfo && pPDev->pColorModeEx)
  325. pListNode = LISTNODEPTR(pPDev->pDriverInfo,pPDev->pColorModeEx->liColorPlaneOrder);
  326. while (pListNode)
  327. {
  328. switch (pListNode->dwData)
  329. {
  330. case COLOR_RED:
  331. case COLOR_GREEN:
  332. case COLOR_BLUE:
  333. return TRUE;
  334. default:
  335. break;
  336. }
  337. if (pListNode->dwNextItem == END_OF_LIST)
  338. break;
  339. else
  340. pListNode = LOCALLISTNODEPTR(pPDev->pDriverInfo, pListNode->dwNextItem);
  341. }
  342. return FALSE;
  343. }
  344. BOOL
  345. BFoundCachedBrush(
  346. PDEV *pPDev,
  347. PDEVBRUSH pDevBrush
  348. )
  349. {
  350. //
  351. // search the cache only if we want to use the last color. If
  352. // MODE_BRUSH_RESET_COLOR is set then we want to explicitly reset the brush
  353. // color by sending the command to the printer.
  354. //
  355. if ( (!(pPDev->ctl.dwMode & MODE_BRUSH_RESET_COLOR)) )
  356. {
  357. if ( (pDevBrush->dwBrushType == pPDev->GState.CurrentBrush.dwBrushType) &&
  358. (pDevBrush->iColor == pPDev->GState.CurrentBrush.iColor) )
  359. {
  360. return TRUE;
  361. }
  362. }
  363. else
  364. {
  365. //
  366. // Reset the MODE_BRUSH_RESET_COLOR flag as we want to search the cache
  367. // next time.
  368. //
  369. pPDev->ctl.dwMode &= ~MODE_BRUSH_RESET_COLOR;
  370. }
  371. return FALSE;
  372. }