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.

922 lines
25 KiB

  1. /*++
  2. Copyright (c) 1990-2003 Microsoft Corporation
  3. Module Name:
  4. brush.c
  5. Abstract:
  6. This module implements the code to realize brushes. BRUSHOBJS, are
  7. representations of logical objects. These objects are created in the
  8. win32 world and eventually need to be converted (or realized) to
  9. something that makes sense in the target device. This is done by realizing
  10. a brush. We look at the logical representation of the brush, then based
  11. on physical device characteristics, do the best job we can of simulating
  12. it on the target device. This conversion is done once, and the result
  13. is stored in the structure that represents the REALIZED brush. This
  14. is optimal since brushes tend to get re-used, and REALIZING them
  15. once, keeps us from having to execute the code every time a brush is used.
  16. Author:
  17. 19:15 on Mon 15 Apr 1991
  18. Created it
  19. 15-Nov-1993 Mon 19:29:07 updated
  20. clean up / fixed
  21. 27-Jan-1994 Thu 23:39:34 updated
  22. Add fill type cache. which we do not have to send FT if same one
  23. already on the plotter
  24. [Environment:]
  25. GDI Device Driver - Plotter.
  26. [Notes:]
  27. Revision History:
  28. --*/
  29. #include "precomp.h"
  30. #pragma hdrstop
  31. #define DBG_PLOTFILENAME DbgBrush
  32. #define DBG_RBRUSH 0x00000001
  33. #define DBG_HATCHTYPE 0x00000002
  34. #define DBG_SHOWSTDPAT 0x00000004
  35. #define DBG_COPYUSERPATBGR 0x00000008
  36. #define DBG_MINHTSIZE 0x00000010
  37. #define DBG_FINDDBCACHE 0x00000020
  38. DEFINE_DBGVAR(0);
  39. //
  40. // The pHSFillType's #d is the line spacing param
  41. //
  42. // for hatch brushes, we want the lines to be .01" thick and .0666666666667"
  43. // this is 15 LPI according to DC. That is, .254mm thick and 2.54mm apart.
  44. // for now, assume the pen is the correct thickness (.3 is right) to figure
  45. // out the separation, in device coordinates, we do 2.54 mm * (device units /
  46. // mm), or (254 * resolution / 100) where resolution is in device units /
  47. // milimeter.
  48. //
  49. #define PATLINESPACE(pPDev) FXTODEVL(pPDev,LTOFX(pPDev->lCurResolution+7)/15)
  50. static const BYTE CellSizePrims[10][4] = {
  51. { 2, 0, 0, 0 }, // 2x 2
  52. { 2, 2, 0, 0 }, // 4x 4
  53. { 2, 3, 0, 0 }, // 6x 6
  54. { 2, 2, 2, 0 }, // 8x 8
  55. { 2, 5, 0, 0 }, // 10x10
  56. { 2, 2, 3, 0 }, // 12x12
  57. { 2, 7, 0, 0 }, // 14x14
  58. { 2, 2, 2, 2 }, // 16x16
  59. { 91,0, 0, 0 }, // 91x91
  60. { 91,0, 0, 0 } // 91x91
  61. };
  62. VOID
  63. ResetDBCache(
  64. PPDEV pPDev
  65. )
  66. /*++
  67. Routine Description:
  68. This function clears the Device brush cach mechanism.
  69. Arguments:
  70. pPDev - Pointer to our PDEV
  71. Return Value:
  72. VOID
  73. Author:
  74. 27-Jan-1994 Thu 20:30:35 created
  75. Revision History:
  76. --*/
  77. {
  78. PDBCACHE pDBCache;
  79. UINT i;
  80. pDBCache = (PDBCACHE)&pPDev->DBCache[0];
  81. for (i = RF_MAX_IDX; i; i--, pDBCache++) {
  82. pDBCache->RFIndex = (WORD)i;
  83. pDBCache->DBUniq = 0;
  84. }
  85. }
  86. LONG
  87. FindDBCache(
  88. PPDEV pPDev,
  89. WORD DBUniq
  90. )
  91. /*++
  92. Routine Description:
  93. This function finds the RF Index number, if not there then it will add it
  94. to the cache.
  95. Arguments:
  96. pPDev - Pointer to our PDEV
  97. DBUniq - Uniq number to be search for
  98. Return Value:
  99. LONG value >0 found and RetVal is the RFIndex
  100. <0 NOT Found and -RetVal is the new RFIndex
  101. Author:
  102. 27-Jan-1994 Thu 20:32:12 created
  103. Revision History:
  104. --*/
  105. {
  106. PDBCACHE pDBCache;
  107. DBCACHE DBCache;
  108. LONG RetVal;
  109. UINT i;
  110. PLOTASSERT(1, "FindDevBrushCache: DBUniq is 0", DBUniq, 0);
  111. pDBCache = (PDBCACHE)&pPDev->DBCache[0];
  112. for (i = 0; i < RF_MAX_IDX; i++, pDBCache++) {
  113. if (pDBCache->DBUniq == DBUniq) {
  114. break;
  115. }
  116. }
  117. if (i < RF_MAX_IDX) {
  118. DBCache = *pDBCache;
  119. RetVal = (LONG)DBCache.RFIndex;
  120. PLOTDBG(DBG_FINDDBCACHE, ("FindDBCache: Found Uniq=%lu, RFIdx=%ld",
  121. (DWORD)DBCache.DBUniq, (DWORD)DBCache.RFIndex));
  122. } else {
  123. //
  124. // Since we did not find the pattern in the cache, we will add it
  125. // to the beggining and move the rest of the entries down the list.
  126. // We need to remember the last one.
  127. //
  128. pDBCache = (PDBCACHE)&pPDev->DBCache[i = (RF_MAX_IDX - 1)];
  129. DBCache = *pDBCache;
  130. DBCache.DBUniq = DBUniq;
  131. RetVal = -(LONG)DBCache.RFIndex;
  132. PLOTDBG(DBG_FINDDBCACHE, ("FindDBCache: NOT Found, NEW DBCache: Uniq=%lu, RFIdx=%ld",
  133. (DWORD)DBCache.DBUniq, (DWORD)DBCache.RFIndex));
  134. }
  135. PLOTASSERT(1, "FindDBCache: Invalid RFIndex=%ld in the cache",
  136. (DBCache.RFIndex > 0) && (DBCache.RFIndex <= RF_MAX_IDX),
  137. (DWORD)DBCache.RFIndex);
  138. //
  139. // Move everything down by one slot, so the first one is the most
  140. // recently used.
  141. //
  142. while (i--) {
  143. *pDBCache = *(pDBCache - 1);
  144. --pDBCache;
  145. }
  146. //
  147. // Save the current cach back and return the RF index.
  148. //
  149. *pDBCache = DBCache;
  150. return(RetVal);
  151. }
  152. BOOL
  153. CopyUserPatBGR(
  154. PPDEV pPDev,
  155. SURFOBJ *psoPat,
  156. XLATEOBJ *pxlo,
  157. LPBYTE pBGRBmp
  158. )
  159. /*++
  160. Routine Description:
  161. This function take a pattern surface and converts it to a form suitable,
  162. for downloading to the target device. The target device in this case,
  163. expects a pattern made up of different pens that define the color of each
  164. individual pixel. This conversion is done by first creating a
  165. BitmapSurface (24 bpp) of the passed in size, then EngBitBliting, the
  166. passed surface (that defines the pattern) into that 24 bpp surface, and
  167. finally copying the color data into the passed buffer.
  168. Arguments:
  169. pPDev - Pointer to our PDEV
  170. psoSrc - source surface object
  171. pxlo - translate object
  172. pBGRBmp - Pointer a 8x8 palette location for the bitmap
  173. Return Value:
  174. TRUE if sucessful, FALSE if failed
  175. Author:
  176. 18-Jan-1994 Tue 03:20:10 created
  177. Revision History:
  178. --*/
  179. {
  180. SURFOBJ *pso24;
  181. HBITMAP hBmp24;
  182. if (pso24 = CreateBitmapSURFOBJ(pPDev,
  183. &hBmp24,
  184. psoPat->sizlBitmap.cx,
  185. psoPat->sizlBitmap.cy,
  186. BMF_24BPP,
  187. NULL)) {
  188. LPBYTE pbSrc;
  189. RECTL rclDst;
  190. DWORD SizeBGRPerScan;
  191. BOOL Ok;
  192. rclDst.left =
  193. rclDst.top = 0;
  194. rclDst.right = pso24->sizlBitmap.cx;
  195. rclDst.bottom = pso24->sizlBitmap.cy;
  196. if (!(Ok = EngBitBlt(pso24, // psoDst
  197. psoPat, // psoSrc
  198. NULL, // psoMask
  199. NULL, // pco
  200. pxlo, // pxlo
  201. &rclDst, // prclDst
  202. (PPOINTL)&rclDst, // pptlSrc
  203. NULL, // pptlMask
  204. NULL, // pbo
  205. NULL, // pptlBrushOrg
  206. 0xCCCC))) {
  207. PLOTERR(("CopyUserPatBGR: EngBitBlt() FALIED"));
  208. return(FALSE);
  209. }
  210. SizeBGRPerScan = (DWORD)(pso24->sizlBitmap.cx * 3);
  211. pbSrc = (LPBYTE)pso24->pvScan0;
  212. PLOTDBG(DBG_COPYUSERPATBGR, ("CopyUserPatBGR: PerScan=%ld [%ld], cy=%ld",
  213. SizeBGRPerScan, pso24->lDelta, rclDst.bottom));
  214. while (rclDst.bottom--) {
  215. CopyMemory(pBGRBmp, pbSrc, SizeBGRPerScan);
  216. pBGRBmp += SizeBGRPerScan;
  217. pbSrc += pso24->lDelta;
  218. }
  219. if (pso24) {
  220. EngUnlockSurface(pso24);
  221. }
  222. if (hBmp24) {
  223. EngDeleteSurface((HSURF)hBmp24);
  224. }
  225. return(Ok);
  226. } else {
  227. PLOTERR(("CopyUserPatBGR: CANNOT Create 24BPP for UserPat"));
  228. return(FALSE);
  229. }
  230. }
  231. VOID
  232. GetMinHTSize(
  233. PPDEV pPDev,
  234. SIZEL *pszlPat
  235. )
  236. /*++
  237. Routine Description:
  238. This function computes and returns the minimum pattern size in pszlPat for
  239. a halftone tile-able pattern size. This is required in order to tile a
  240. repeating pattern correctly when filling an object. If the original
  241. brush wasn't useable, we create a composite of that original bitmap, by
  242. halftoning into a surface. In order for the result to be tile-able,
  243. we must take into account the different Cell/Patter sizes for our
  244. halftone data.
  245. Arguments:
  246. pPDev - Point to our PDEV
  247. pszlPat - Points to a SIZEL structure for the original pattern size
  248. Return Value:
  249. VOID
  250. Author:
  251. 26-Jan-1994 Wed 10:10:15 created
  252. Revision History:
  253. --*/
  254. {
  255. LPBYTE pCellPrims;
  256. LPBYTE pPrims;
  257. LONG Prim;
  258. SIZEL szlPat;
  259. LONG CellSize;
  260. UINT i;
  261. if (0 == pszlPat->cx || 0 == pszlPat->cy)
  262. {
  263. return;
  264. }
  265. szlPat = *pszlPat;
  266. CellSize = (LONG)HTPATSIZE(pPDev);
  267. pCellPrims = (LPBYTE)&CellSizePrims[(CellSize >> 1) - 1][0];
  268. if (!(CellSize % szlPat.cx)) {
  269. szlPat.cx = CellSize;
  270. } else if (szlPat.cx % CellSize) {
  271. //
  272. // Since it's not an exact fit, calculate the correct number now.
  273. //
  274. i = 4;
  275. pPrims = pCellPrims;
  276. while ((i--) && (Prim = (LONG)*pPrims++)) {
  277. if (!(szlPat.cx % Prim)) {
  278. szlPat.cx /= Prim;
  279. }
  280. }
  281. szlPat.cx *= CellSize;
  282. }
  283. if (!(CellSize % szlPat.cy)) {
  284. szlPat.cy = CellSize;
  285. } else if (szlPat.cy % CellSize) {
  286. //
  287. // Since it's not an exact fit, calculate the correct number now.
  288. //
  289. i = 4;
  290. pPrims = pCellPrims;
  291. while ((i--) && (Prim = (LONG)*pPrims++)) {
  292. if (!(szlPat.cy % Prim)) {
  293. szlPat.cy /= Prim;
  294. }
  295. }
  296. szlPat.cy *= CellSize;
  297. }
  298. PLOTDBG(DBG_MINHTSIZE, ("GetMinHTSize: PatSize=%ld x %ld, HTSize=%ld x %ld, MinSize=%ld x %ld",
  299. pszlPat->cx, pszlPat->cy, CellSize, CellSize,
  300. szlPat.cx, szlPat.cy));
  301. *pszlPat = szlPat;
  302. }
  303. BOOL
  304. DrvRealizeBrush(
  305. BRUSHOBJ *pbo,
  306. SURFOBJ *psoDst,
  307. SURFOBJ *psoPattern,
  308. SURFOBJ *psoMask,
  309. XLATEOBJ *pxlo,
  310. ULONG iHatch
  311. )
  312. /*++
  313. Routine Description:
  314. DrvRealizeBrush requests the driver to realize a specified brush for a
  315. specified surface. NT's GDI will usually realize a brush before using it.
  316. Realing a brush allows our driver to take a logical representation of
  317. a brush, and convert it to something that makes sense in the target device.
  318. By having the NT GDI realize the brush, in essence allows us to cache the
  319. physical representation of the brush, for future use.
  320. Arguments:
  321. pbo - Points to the BRUSHOBJ which is to be realized. All the other
  322. parameters, except for psoDst, can be queried from this
  323. object. Parameter specifications are provided as an
  324. optimization. This parameter is best used only as a parameter
  325. for BRUSHOBJ_pvAllocRBrush, which allocates the memory for
  326. the realized brush.
  327. psoDst - Points to the surface for which the brush is to be realized.
  328. This surface could be the physical surface for the device,
  329. a device format bitmap, or a standard format bitmap.
  330. psoPattern - Points to the surface that describes the pattern for the
  331. brush. For a raster device, this always represents a bitmap.
  332. For a vector device, this is always one of the pattern
  333. surfaces returned by DrvEnablePDEV.
  334. psoMask - Points to a transparency mask for the brush. This is a one
  335. bit per pixel bitmap that has the same extent as the pattern.
  336. A mask of zero means the pixel is considered a background
  337. pixel for the brush. (In transparent background mode, the
  338. background pixels are unaffected in a fill.) Pen Plotters can
  339. ignore this parameter because they never draw background
  340. information.
  341. pxlo - Points to an XLATEOBJ that tells how to interpret the colors
  342. in the pattern. An XLATEOBJXxx service routine can be called
  343. to translate the colors to device color indexes. Vector
  344. devices should translate color zero through the XLATEOBJ to
  345. get the foreground color for the brush.
  346. iHatch - If this is less than HS_API_MAX, then it indicates that
  347. psoPattern is one of the hatch brushes returned by
  348. DrvEnablePDEV, such as HS_HORIZONTAL.
  349. Return Value:
  350. DrvRealizeBrush returns TRUE if the brush was successfully realized.
  351. Otherwise, FALSE is returned and an error code is logged.
  352. Author:
  353. 09-Feb-1994 Wed 10:04:17 updated
  354. Put the CloneSURFOBJToHT() back for all psoPatterns, (this was to
  355. prevent GDI go into GP), now we will raised a bug against it.
  356. 13-Jan-1994 Thu 23:12:40 updated
  357. Totally re-write so that we will cached the psoPattern always
  358. 01-Dec-1993 Wed 17:27:19 updated
  359. clean up, and re-write to generate the standard brush string.
  360. Revision History:
  361. --*/
  362. {
  363. PPDEV pPDev;
  364. if (!(pPDev = SURFOBJ_GETPDEV(psoDst))) {
  365. PLOTERR(("DrvRealizeBrush has invalid pPDev"));
  366. return(FALSE);
  367. }
  368. //
  369. // We don't check if iHatch is valid or not at this poin.
  370. // We should always get a psoPattern that either points to the user
  371. // defined pattern or to the standard monochrome pattern.
  372. //
  373. if ((psoPattern) &&
  374. (psoPattern->iType == STYPE_BITMAP)) {
  375. PDEVBRUSH pBrush;
  376. SURFOBJ *psoHT;
  377. HBITMAP hBmp;
  378. SIZEL szlPat;
  379. SIZEL szlHT;
  380. RECTL rclHT;
  381. LONG Size;
  382. DWORD OffBGR;
  383. BOOL RetOk;
  384. //
  385. // leave room for the color table. then allocate the new device brush
  386. //
  387. PLOTDBG(DBG_RBRUSH, ("DrvRealizeBrush: psoPat=%08lx [%ld], psoMask=%08lx, iHatch=%ld",
  388. psoPattern, psoPattern->iBitmapFormat, psoMask, iHatch));
  389. PLOTDBG(DBG_RBRUSH, ("psoPattern size = %ld x %ld",
  390. (LONG)psoPattern->sizlBitmap.cx,
  391. (LONG)psoPattern->sizlBitmap.cy));
  392. #if DBG
  393. if ((DBG_PLOTFILENAME & DBG_SHOWSTDPAT) &&
  394. ((psoPattern->iBitmapFormat == BMF_1BPP) ||
  395. (iHatch < HS_DDI_MAX))) {
  396. LPBYTE pbSrc;
  397. LPBYTE pbCur;
  398. LONG x;
  399. LONG y;
  400. BYTE bData;
  401. BYTE Mask;
  402. BYTE Buf[128];
  403. //
  404. // Debug code that allows the pattern to be displayed with
  405. // ASCII codes on the debug terminal. This was very helpful
  406. // during development.
  407. //
  408. pbSrc = psoPattern->pvScan0;
  409. for (y = 0; y < psoPattern->sizlBitmap.cy; y++) {
  410. pbCur = pbSrc;
  411. pbSrc += psoPattern->lDelta;
  412. Mask = 0x0;
  413. Size = 0;
  414. for (x = 0;
  415. x < psoPattern->sizlBitmap.cx && Size < sizeof(Buf);
  416. x++)
  417. {
  418. if (!(Mask >>= 1)) {
  419. Mask = 0x80;
  420. bData = *pbCur++;
  421. }
  422. Buf[Size++] = (BYTE)((bData & Mask) ? 0xdb : 0xb0);
  423. }
  424. if (Size < sizeof(Buf))
  425. {
  426. Buf[Size] = '\0';
  427. }
  428. else
  429. {
  430. //
  431. // Error case. Null-terminate anyway.
  432. //
  433. Buf[sizeof(Buf) - 1] = '\0';
  434. }
  435. DBGP((Buf));
  436. }
  437. }
  438. #endif
  439. //
  440. // For pen plotter, we need to remember this one as well.
  441. //
  442. szlHT =
  443. szlPat = psoPattern->sizlBitmap;
  444. PLOTDBG(DBG_RBRUSH,
  445. ("DrvRealizeBrush: BG=%08lx, FG=%08lx",
  446. (DWORD)XLATEOBJ_iXlate(pxlo, 1),
  447. (DWORD)XLATEOBJ_iXlate(pxlo, 0)));
  448. if (IS_RASTER(pPDev)) {
  449. //
  450. // For raster plotters, we will clone the surface and halftone
  451. // the orignal pattern into a halftone bitmap which itself is
  452. // tile-able. This allows us to use our color reduction code,
  453. // to make the pattern look good.
  454. //
  455. if ((iHatch >= HS_DDI_MAX) &&
  456. (!IsHTCompatibleSurfObj(pPDev,
  457. psoPattern,
  458. pxlo,
  459. ISHTF_ALTFMT | ISHTF_DSTPRIM_OK))) {
  460. GetMinHTSize(pPDev, &szlHT);
  461. }
  462. rclHT.left =
  463. rclHT.top = 0;
  464. rclHT.right = szlHT.cx;
  465. rclHT.bottom = szlHT.cy;
  466. PLOTDBG(DBG_RBRUSH,
  467. ("DrvRealizeBrush: PatSize=%ld x %ld, HT=%ld x %ld",
  468. szlPat.cx, szlPat.cy, szlHT.cx, szlHT.cy));
  469. //
  470. // Go generate the bits for the pattern.
  471. //
  472. if (psoHT = CloneSURFOBJToHT(pPDev, // pPDev,
  473. psoDst, // psoDst,
  474. psoPattern, // psoSrc,
  475. pxlo, // pxlo,
  476. &hBmp, // hBmp,
  477. &rclHT, // prclDst,
  478. NULL)) { // prclSrc,
  479. RetOk = TRUE;
  480. } else {
  481. PLOTDBG(DBG_RBRUSH, ("DrvRealizeBrush: Clone PATTERN FAILED"));
  482. return(FALSE);
  483. }
  484. } else {
  485. //
  486. // For Pen type plotter we will never do a standard pattern in the
  487. // memory (compatible DC). For user defined patterns we will
  488. // only hatch '\' with background color and a '/' with foreground
  489. // color with double standard line spacing. This is the best we
  490. // can hope for on a pen plotter.
  491. //
  492. RetOk = TRUE;
  493. psoHT = psoPattern;
  494. hBmp = NULL;
  495. }
  496. if (RetOk) {
  497. //
  498. // Now Allocate device brush, remember we will only allocate the
  499. // minimum size.
  500. //
  501. Size = (LONG)psoHT->cjBits - (LONG)sizeof(pBrush->BmpBits);
  502. if (Size < 0) {
  503. Size = sizeof(DEVBRUSH);
  504. } else {
  505. Size += sizeof(DEVBRUSH);
  506. }
  507. //
  508. // Following are the user defined pattern sizes which can be handled
  509. // internally by HPGL2. This is only for raster plotters. Pen
  510. // plotters will have a cross hatch to show an emulation of the
  511. // pattern.
  512. //
  513. if ((iHatch >= HS_DDI_MAX) &&
  514. (IS_RASTER(pPDev)) &&
  515. ((szlPat.cx == 8) ||
  516. (szlPat.cx == 16) ||
  517. (szlPat.cx == 32) ||
  518. (szlPat.cx == 64)) &&
  519. ((szlPat.cy == 8) ||
  520. (szlPat.cy == 16) ||
  521. (szlPat.cy == 32) ||
  522. (szlPat.cy == 64))) {
  523. //
  524. // Adding the size which stored the BGR format of the pattern
  525. //
  526. OffBGR = Size;
  527. Size += (psoPattern->sizlBitmap.cx * 3) *
  528. psoPattern->sizlBitmap.cy;
  529. } else {
  530. OffBGR = 0;
  531. }
  532. PLOTDBG(DBG_RBRUSH, ("DrvRealizeBrush: AllocDEVBRUSH(Bmp=%ld,BGR=%ld), TOT=%ld",
  533. psoHT->cjBits, Size - OffBGR, Size));
  534. //
  535. // Now ask the NT graphics engine to allocate the device
  536. // brush memory for us. This is done, so NT knows how to discard
  537. // the memory when it is no longer needed (The brush getting
  538. // destroyed).
  539. //
  540. if (pBrush = (PDEVBRUSH)BRUSHOBJ_pvAllocRbrush(pbo, Size)) {
  541. //
  542. // Set up either standard pattern or user defined pattern
  543. // HPGL/2 FT command string pointer and parameters.
  544. //
  545. pBrush->psoMask = psoMask;
  546. pBrush->PatIndex = (WORD)iHatch;
  547. pBrush->Uniq = (WORD)(pPDev->DevBrushUniq += 1);
  548. pBrush->LineSpacing = (LONG)PATLINESPACE(pPDev);
  549. pBrush->ColorFG = (DWORD)XLATEOBJ_iXlate(pxlo, 1);
  550. pBrush->ColorBG = (DWORD)XLATEOBJ_iXlate(pxlo, 0);
  551. pBrush->sizlBitmap = psoHT->sizlBitmap;
  552. pBrush->ScanLineDelta = psoHT->lDelta;
  553. pBrush->BmpFormat = (WORD)psoHT->iBitmapFormat;
  554. pBrush->BmpFlags = (WORD)psoHT->fjBitmap;
  555. pBrush->pbgr24 = NULL;
  556. pBrush->cxbgr24 =
  557. pBrush->cybgr24 = 0;
  558. PLOTDBG(DBG_RBRUSH, ("DrvRealizeBrush: DevBrush's Uniq = %ld",
  559. pBrush->Uniq));
  560. //
  561. // Check to see if the cache is wrapping and handle it.
  562. //
  563. if (pBrush->Uniq == 0) {
  564. ResetDBCache(pPDev);
  565. pBrush->Uniq =
  566. pPDev->DevBrushUniq = 1;
  567. PLOTDBG(DBG_RBRUSH, ("DrvRealizeBrush: Reset DB Cache, (Uniq WRAP)"));
  568. }
  569. //
  570. // Is it a user defined pattern.
  571. //
  572. if (iHatch >= HS_DDI_MAX) {
  573. //
  574. // Check to see if the brush could be downloaded to the
  575. // target device as an HPGL2 brush. If this is the case
  576. // save that information.
  577. //
  578. if (OffBGR) {
  579. pBrush->pbgr24 = (LPBYTE)pBrush + OffBGR;
  580. pBrush->cxbgr24 = (WORD)psoPattern->sizlBitmap.cx;
  581. pBrush->cybgr24 = (WORD)psoPattern->sizlBitmap.cy;
  582. ZeroMemory(pBrush->pbgr24, Size - OffBGR);
  583. CopyUserPatBGR(pPDev, psoPattern, pxlo, pBrush->pbgr24);
  584. } else if (!IS_RASTER(pPDev)) {
  585. //
  586. // If we are not talking to a RASTER plotter, not much
  587. // we can do here. Trigger the simulation.
  588. //
  589. pBrush->pbgr24 = (LPBYTE)-1;
  590. }
  591. }
  592. //
  593. // Copy down the halftoned bits if any.
  594. //
  595. if (psoHT->cjBits) {
  596. CopyMemory((LPBYTE)pBrush->BmpBits,
  597. (LPBYTE)psoHT->pvBits,
  598. psoHT->cjBits);
  599. }
  600. //
  601. // Now record the realized brush pointer in the BRUSHOBJ.
  602. //
  603. pbo->pvRbrush = (LPVOID)pBrush;
  604. } else {
  605. PLOTERR(("DrvRealizeBrush: brush allocation failed"));
  606. RetOk = FALSE;
  607. }
  608. } else {
  609. PLOTERR(("DrvRealizeBrush: Cloning the psoPattern failed!"));
  610. RetOk = FALSE;
  611. }
  612. if (psoHT != psoPattern) {
  613. EngUnlockSurface(psoHT);
  614. }
  615. if (hBmp) {
  616. EngDeleteSurface((HSURF)hBmp);
  617. }
  618. return(RetOk);
  619. } else {
  620. PLOTASSERT(0, "The psoPattern is not a bitmap (psoPattern= %08lx)",
  621. (psoPattern) &&
  622. (psoPattern->iType == STYPE_BITMAP), psoPattern);
  623. return(FALSE);
  624. }
  625. }