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.

626 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. state.c
  5. Abstract:
  6. Printer graphics state tracking.
  7. Implemenation of
  8. GSRealizeBrush
  9. GSUnRealizeBrush
  10. GSSelectBrush
  11. GSResetBrush
  12. Environment:
  13. Windows NT Unidrv driver
  14. Revision History:
  15. 04/29/97 -amandan-
  16. Created
  17. --*/
  18. #include "unidrv.h"
  19. #ifdef WINNT_40 // NT 4.0
  20. extern HSEMAPHORE hSemBrushColor;
  21. LPDWORD pBrushSolidColor = NULL;
  22. DWORD
  23. GetBRUSHOBJRealColor(
  24. PDEV *pPDev,
  25. BRUSHOBJ *pbo
  26. )
  27. /*++
  28. Routine Description:
  29. Given a BRUSHOBJ Gets the original color ofthe brush using DrvDitherColor.
  30. Arguments:
  31. pPDev - Pointer to PDEV
  32. pbo - Pointer to BRUSHOBJ
  33. Return Value:
  34. Original RGB color
  35. Note:
  36. --*/
  37. {
  38. DWORD SolidColor;
  39. if ((SolidColor = pbo->iSolidColor) == 0xFFFFFFFF)
  40. {
  41. SolidColor = 0;
  42. EngAcquireSemaphore(hSemBrushColor);
  43. pBrushSolidColor = &SolidColor;
  44. BRUSHOBJ_pvGetRbrush(pbo);
  45. EngReleaseSemaphore(hSemBrushColor);
  46. }
  47. else
  48. {
  49. ERR(( "GetBRUSHOBJRealColor: Should not be Called for mapped color\n" ));
  50. SolidColor = 0;
  51. }
  52. return(SolidColor);
  53. }
  54. #endif //WINNT_40
  55. ULONG GetRGBColor(PDEV *, ULONG);
  56. PDEVBRUSH
  57. GSRealizeBrush(
  58. IN OUT PDEV *pPDev,
  59. IN SURFOBJ *pso,
  60. IN BRUSHOBJ *pbo
  61. )
  62. /*++
  63. Routine Description:
  64. Given a BRUSHOBJ perform one of the following:
  65. Color Printer:
  66. 1. Programmable Palette
  67. 2. Non-Programmable Palette
  68. Monochrome Printer:
  69. 1. User defined pattern, only if brush is pattern brush
  70. 2. Shading Patterns , only if brush is pattern brush
  71. 3. Maps to black/white brush
  72. 4. Maps to black
  73. Arguments:
  74. pPDev - Pointer to PDEV
  75. pso - Pointer to SURFOBJ
  76. pbo - Pointer to BRUSHOBJ
  77. Return Value:
  78. PDEVBRUSH if successful, otherwise NULL
  79. Note:
  80. It's up to the caller to call GSUnRealizeBrush to free brushes
  81. --*/
  82. {
  83. ULONG ulColor = pbo->iSolidColor;
  84. PDEVBRUSH pDevBrush;
  85. BOOL bPatternBrush = FALSE;
  86. //
  87. // Allocate memory for Brush, deallocation is done in GSUnRealizeBrush
  88. //
  89. if ((pDevBrush = MemAllocZ(sizeof(DEVBRUSH))) == NULL)
  90. return NULL;
  91. if (pso->iBitmapFormat != BMF_24BPP &&
  92. pbo->iSolidColor != DITHERED_COLOR)
  93. {
  94. //
  95. // Index case
  96. // pbo->iSolidColor holds the Index, Map index to RGB color
  97. //
  98. ulColor = GetRGBColor(pPDev, pbo->iSolidColor);
  99. }
  100. //
  101. // TBD: BUG_BUG NT4 - needs to be fixed
  102. // no NT4 bugs will be fixed unless necessary.
  103. //
  104. if (pbo->iSolidColor == DITHERED_COLOR)
  105. {
  106. //
  107. // Pattern Brush, get the color
  108. //
  109. #ifndef WINNT_40 //NT 5.0
  110. ulColor = BRUSHOBJ_ulGetBrushColor(pbo);
  111. // BUG_BUG: Unidrv currently doesn't handle the case where the brush is
  112. // a non-solid brush (return -1). The HPGL / PCL-XL implementations will require
  113. // this so we will merge that implementation when it is complete.
  114. if (ulColor != -1)
  115. ulColor &= 0x00FFFFFF;
  116. #else // NT 4.0
  117. ulColor = GetBRUSHOBJRealColor(pPDev, pbo);
  118. #endif //!WINNT_40
  119. bPatternBrush = TRUE;
  120. }
  121. //
  122. // ulColor should always be RGB color by the time we get here
  123. //
  124. if ((pso->iBitmapFormat == BMF_1BPP) )
  125. {
  126. //
  127. // Monochrome case
  128. // Download user define pattern or select intensity for
  129. // non-solid brush ONLY. Otherwise, map it to black or white.
  130. //
  131. //
  132. if ((pPDev->fMode & PF_DOWNLOAD_PATTERN) && bPatternBrush)
  133. {
  134. PDEVBRUSH pDB;
  135. // Support user defined pattern, iColor will hold the pattern ID
  136. if ((pDB = (PDEVBRUSH)BRUSHOBJ_pvGetRbrush(pbo)) == NULL)
  137. {
  138. WARNING(("BRUSHOBJ_pvGetRBrush failed"));
  139. MemFree(pDevBrush);
  140. return NULL;
  141. }
  142. pDevBrush->dwBrushType = BRUSH_USERPATTERN;
  143. pDevBrush->iColor = pDB->iColor;
  144. }
  145. else if ((pPDev->fMode & PF_SHADING_PATTERN) && bPatternBrush)
  146. {
  147. // Support shading pattern, iColor holds %of gray
  148. pDevBrush->dwBrushType = BRUSH_SHADING;
  149. pDevBrush->iColor = GET_SHADING_PERCENT(ulColor);
  150. }
  151. else if (pPDev->fMode & PF_WHITEBLACK_BRUSH)
  152. {
  153. // Support black/white brush commands, iColor will hold RBG color
  154. // We are here means solid color brush, and for monochrome
  155. // it can be either black or white. If it's indexed, we
  156. // have taken care of mapping index to RGB color already
  157. //
  158. pDevBrush->dwBrushType = BRUSH_BLKWHITE;
  159. pDevBrush->iColor = ulColor;
  160. }
  161. else
  162. {
  163. //
  164. // Map to black
  165. //
  166. pDevBrush->dwBrushType = BRUSH_BLKWHITE;
  167. pDevBrush->iColor = RGB_BLACK_COLOR;
  168. }
  169. }
  170. else if (pPDev->fMode & PF_ANYCOLOR_BRUSH )
  171. {
  172. //
  173. // Programmable
  174. //
  175. pDevBrush->dwBrushType = BRUSH_PROGCOLOR;
  176. pDevBrush->iColor = ulColor;
  177. }
  178. else
  179. {
  180. //
  181. // Non-Programmable
  182. //
  183. pDevBrush->dwBrushType = BRUSH_NONPROGCOLOR;
  184. //
  185. // Since ulColor is RGB color, need to map it to the nearest
  186. // color in the fixed palette.
  187. // iColor will hold the index of the color
  188. //
  189. if (pbo->iSolidColor == DITHERED_COLOR)
  190. pDevBrush->iColor = BestMatchDeviceColor(pPDev,(DWORD)ulColor);
  191. else
  192. pDevBrush->iColor = pbo->iSolidColor;
  193. }
  194. //
  195. // Save the brush to the Realized Brush linked list
  196. //
  197. if (pPDev->GState.pRealizedBrush == NULL)
  198. {
  199. pDevBrush->pNext = NULL;
  200. pPDev->GState.pRealizedBrush = pDevBrush;
  201. }
  202. else
  203. {
  204. pDevBrush->pNext = pPDev->GState.pRealizedBrush;
  205. pPDev->GState.pRealizedBrush = pDevBrush;
  206. }
  207. return pDevBrush;
  208. }
  209. VOID
  210. GSUnRealizeBrush(
  211. IN PDEV *pPDev
  212. )
  213. /*++
  214. Routine Description:
  215. Deallocate memory for the realized brush
  216. Arguments:
  217. pPDev Pointer to PDEV
  218. Return Value:
  219. None
  220. --*/
  221. {
  222. PDEVBRUSH pDevBrush = pPDev->GState.pRealizedBrush;
  223. VERBOSE(("GSUnRealizeBrush \n"));
  224. while(pPDev->GState.pRealizedBrush !=NULL)
  225. {
  226. pDevBrush = pPDev->GState.pRealizedBrush;
  227. pPDev->GState.pRealizedBrush = pDevBrush->pNext;
  228. MemFree(pDevBrush);
  229. }
  230. pPDev->GState.pRealizedBrush = NULL;
  231. }
  232. BOOL
  233. GSSelectBrush(
  234. IN PDEV *pPDev,
  235. IN PDEVBRUSH pDevBrush
  236. )
  237. /*++
  238. Routine Description:
  239. Given a pDevBrush, select the brush.
  240. Arguments:
  241. pPDev - Pointer to PDEV
  242. pDevBrush - Pointer to DEVBRUSH
  243. Return Value:
  244. TRUE if sucessful, otherwise FALSE
  245. --*/
  246. {
  247. BOOL bIndexedColor = FALSE;
  248. //
  249. // Find Cached Brush, if the current selected brush matches
  250. // the caller request, do nothing.
  251. //
  252. if (BFoundCachedBrush(pPDev, pDevBrush))
  253. return TRUE;
  254. switch(pDevBrush->dwBrushType){
  255. case BRUSH_PROGCOLOR:
  256. {
  257. VERBOSE(("Using Programmable RGB Color \n"));
  258. if (((PAL_DATA *)pPDev->pPalData)->fFlags & PDF_PALETTE_FOR_8BPP_MONO)
  259. pDevBrush->iColor = ConvertRGBToGrey(pDevBrush->iColor);
  260. if ( !BSelectProgrammableBrushColor(pPDev, pDevBrush->iColor) )
  261. {
  262. WARNING(("\nCan't Select the brush color for RGB = 0x%x\n",pDevBrush->iColor));
  263. pDevBrush->iColor = BestMatchDeviceColor(pPDev, pDevBrush->iColor);
  264. bIndexedColor = TRUE;
  265. }
  266. }
  267. //
  268. // Let it fall thru to catch the indexed case
  269. //
  270. case BRUSH_NONPROGCOLOR:
  271. {
  272. if (bIndexedColor || pDevBrush->dwBrushType == BRUSH_NONPROGCOLOR)
  273. {
  274. INT iCmd;
  275. VERBOSE(("Using Non Programmable Indexed Color"));
  276. //
  277. // If this color is not supported, use the default color: black.
  278. //
  279. pDevBrush->iColor &= (MAX_COLOR_SELECTION - 1); /* 16 entry palette wrap around */
  280. //
  281. // If there is no command to set the color, map to black.
  282. //
  283. if(COMMANDPTR(pPDev->pDriverInfo, CMD_COLORSELECTION_FIRST + pDevBrush->iColor) == NULL)
  284. pDevBrush->iColor = BLACK_COLOR_CMD_INDEX;
  285. iCmd = CMD_COLORSELECTION_FIRST + pDevBrush->iColor;
  286. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, iCmd));
  287. }
  288. }
  289. break;
  290. case BRUSH_USERPATTERN:
  291. {
  292. VERBOSE(("Selecting user defined pattern brush"));
  293. //
  294. // The pattern ID, is stored in pDevBrush->iColor
  295. //
  296. pPDev->dwPatternBrushType = BRUSH_USERPATTERN;
  297. pPDev->dwPatternBrushID = pDevBrush->iColor;
  298. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SELECT_PATTERN));
  299. }
  300. break;
  301. case BRUSH_SHADING:
  302. {
  303. VERBOSE(("Selecting shading pattern brush"));
  304. //
  305. // The gray level (expressed as intensity) is stored in
  306. // pDevBrush->iColor
  307. //
  308. //
  309. // Update standard variable for brush selection command
  310. //
  311. pPDev->dwPatternBrushType = BRUSH_SHADING;
  312. pPDev->dwPatternBrushID = pDevBrush->iColor;
  313. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SELECT_PATTERN));
  314. }
  315. break;
  316. case BRUSH_BLKWHITE:
  317. {
  318. INT iCmd;
  319. if (pDevBrush->iColor == RGB_WHITE_COLOR)
  320. {
  321. VERBOSE(("Selecting white brush"));
  322. //
  323. // BUG_BUG, need to remove the CMD_WHITETEXTON and CMD_WHITETEXTOFF
  324. // once all GPD changes have been made for BLACKBRUSH, WHITEBRUSH
  325. // doesn't hurt to leave it in.
  326. if (pPDev->arCmdTable[CMD_SELECT_WHITEBRUSH])
  327. iCmd = CMD_SELECT_WHITEBRUSH;
  328. else
  329. iCmd = CMD_WHITETEXTON;
  330. }
  331. else
  332. {
  333. //
  334. // Black - standard text color
  335. //
  336. VERBOSE(("Selecting black brush"));
  337. //
  338. // BUG_BUG, need to remove the CMD_WHITETEXT_ON and CMD_WHITETEXT_OFF
  339. // once all GPD changes have been made for BLACKBRUSH, WHITEBRUSH
  340. // doesn't hurt to leave it in.
  341. //
  342. if (pPDev->arCmdTable[CMD_SELECT_BLACKBRUSH])
  343. iCmd = CMD_SELECT_BLACKBRUSH;
  344. else
  345. iCmd = CMD_WHITETEXTOFF;
  346. }
  347. //
  348. // Set the desired colour !
  349. //
  350. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, iCmd));
  351. }
  352. break;
  353. }
  354. //
  355. // Cached the brush
  356. //
  357. CACHE_CURRENT_BRUSH(pPDev, pDevBrush)
  358. return TRUE;
  359. }
  360. VOID
  361. GSResetBrush(
  362. IN OUT PDEV *pPDev
  363. )
  364. /*++
  365. Routine Description:
  366. Select the default brush
  367. Arguments:
  368. pPDev - Pointer to PDEV
  369. Return Value:
  370. None
  371. --*/
  372. {
  373. DEVBRUSH DeviceBrush;
  374. PDEVBRUSH pDevBrush = &DeviceBrush;
  375. PAL_DATA *pPD;
  376. pPD = pPDev->pPalData;
  377. if (pPD->fFlags & PDF_PALETTE_FOR_1BPP)
  378. {
  379. //
  380. // Monochrome case. Select black brush
  381. //
  382. pDevBrush->dwBrushType = BRUSH_BLKWHITE;
  383. pDevBrush->iColor = RGB_BLACK_COLOR;
  384. if (BFoundCachedBrush(pPDev, pDevBrush))
  385. return;
  386. //
  387. // BUG_BUG, need to remove the CMD_WHITETEXT_ON and CMD_WHITETEXT_OFF
  388. // once all GPD changes have been made
  389. // doesn't hurt to leave it in.
  390. //
  391. if (pPDev->arCmdTable[CMD_SELECT_BLACKBRUSH])
  392. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SELECT_BLACKBRUSH));
  393. else
  394. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_WHITETEXTOFF));
  395. }
  396. else if (pPDev->fMode & PF_ANYCOLOR_BRUSH )
  397. {
  398. //
  399. // Programmable
  400. //
  401. pDevBrush->dwBrushType = BRUSH_PROGCOLOR;
  402. pDevBrush->iColor = RGB_BLACK_COLOR;
  403. VResetProgrammableBrushColor(pPDev);
  404. }
  405. else
  406. {
  407. //
  408. // Non-Programmable
  409. //
  410. pDevBrush->dwBrushType = BRUSH_NONPROGCOLOR;
  411. pDevBrush->iColor = ((PAL_DATA*)(pPDev->pPalData))->iBlackIndex;
  412. if (BFoundCachedBrush(pPDev, pDevBrush))
  413. return;
  414. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo,CMD_SELECTBLACKCOLOR));
  415. }
  416. CACHE_CURRENT_BRUSH(pPDev, pDevBrush)
  417. }
  418. ULONG
  419. GetRGBColor(
  420. IN PDEV *pPDev,
  421. IN ULONG ulIndex
  422. )
  423. /*++
  424. Routine Description:
  425. Given an Indexed color, map to an RGB color
  426. Arguments:
  427. pPDev - Pointer to PDEV
  428. pDevBrush - Pointer to DEVBRUSH
  429. Return Value:
  430. TRUE if sucessful, otherwise FALSE
  431. --*/
  432. {
  433. // If the index is invalid, map to Black.
  434. if (ulIndex > PALETTE_MAX)
  435. {
  436. ERR(( "GSSelectBrush: Bad input Color Index\n" ));
  437. ulIndex = ((PAL_DATA*)(pPDev->pPalData))->iBlackIndex;
  438. }
  439. return( ((PAL_DATA *)(pPDev->pPalData))->ulPalCol[ulIndex]);
  440. }