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.

727 lines
23 KiB

  1. /*
  2. ** Copyright (c) 1991 Microsoft Corporation
  3. */
  4. //===========================================================================
  5. // FILE DORPL.C
  6. //
  7. // MODULE Host Resource Executor
  8. //
  9. // PURPOSE Convert A-form to B-form for jumbo driver
  10. //
  11. // DESCRIBED IN Resource Executor design spec.
  12. //
  13. // MNEMONICS n/a
  14. //
  15. // HISTORY 1/17/92 mslin extracted functions from cartrige JUMBO.C
  16. // and then modified.
  17. // 03/09/92 dstseng RP_FillScanRow -> RP_FILLSCANROW (.asm)
  18. // 03/10/92 dssteng add one parameter SrcxOrg to RP_BITMAP1TO1()
  19. // to handle the case xOffset <> 0
  20. // 03/11/92 dstseng <3> optimize fill rect. by calling RP_FILLSCANROW()
  21. // 05/21/92 mslin Add DUMBO compiled switch for Fixed memory
  22. // because real time interrupt routine will call
  23. // hre when printing in real-time rendering mode
  24. // 08/18/92 dstseng @1 fix bug that trashed the value of usPosOff
  25. // 08/21/92 dstseng @2 fix a inadvertent bug in BitMapHI
  26. // 10/12/92 dstseng @3 fix "Glyph range checking" bug
  27. // 11/12/92 dstseng @4 special treatment for hollow brush
  28. // 11/12/92 dstseng @5 fix bug in command ShowText & ShowField
  29. // 09/27/93 mslin add BuildPcrDirectory600() for Spicewood 6.
  30. //
  31. //
  32. //===========================================================================
  33. // Include files
  34. //
  35. #include <ifaxos.h>
  36. #include <resexec.h>
  37. #include "constant.h"
  38. #include "jtypes.h" // type definition used in cartridge
  39. #include "jres.h" // cartridge resource data type definition
  40. #include "hretype.h" // define data structure used by hre.c and rpgen.c
  41. #include "hreext.h" // declaration extern global var. and extern func.
  42. #include "multbyte.h" // define macros to take care of byte ordering
  43. #include "stllnent.h" // declare style line functions.
  44. #ifdef DEBUG
  45. DBGPARAM dpCurSettings = {"RESEXEC"};
  46. #endif
  47. #define Brush40Gray (ULONG)0x8140 /* all black */
  48. extern const WORD wRopTable[256];
  49. extern BYTE BrushPat[72][8];
  50. #define ASSERT(cond,mesg) if (cond) {DEBUGMSG (1, mesg); goto EndRPL;}
  51. // functions prototypes
  52. static void RP_NewRop (LPRESTATE lpRE, UBYTE ubRop);
  53. static int SelectResource(LPHRESTATE lpHREState, UINT uid);
  54. extern void GetTotalPixels (RP_SLICE_DESC FAR* psdSlice);
  55. extern BOOL OpenBlt (LPRESTATE, UINT);
  56. extern BOOL SetBrush (LPRESTATE);
  57. extern void CloseBlt (LPRESTATE);
  58. //---------------------------------------------------------------------------
  59. void
  60. DoRPL
  61. (
  62. LPHRESTATE lpHREState, // far pointer to current job context
  63. // corresponding to the job HANDLE
  64. LPRPLLIST lpRPLList // pointer to RPL list
  65. )
  66. // PURPOSE Execute a Render Primitive List (RPL)
  67. // which is a list of RPL block.
  68. //
  69. //
  70. // ASSUMPTIONS & ASSERTIONS None.
  71. //
  72. // INTERNAL STRUCTURES None visible outside of HRE.
  73. //
  74. // UNRESOLVED ISSUES programmer development notes
  75. //
  76. //---------------------------------------------------------------------------
  77. {
  78. LPBITMAP lpbmBand;
  79. LPRESTATE lpRE;
  80. UBYTE FAR* lpub;
  81. USHORT FAR* lpus;
  82. ULONG FAR* lpul;
  83. UBYTE FAR* lpubLimit;
  84. LPJG_RPL_HDR lpRPL;
  85. USHORT usTop;
  86. USHORT yBrush;
  87. USHORT iGlyph;
  88. LPFRAME lpFrame;
  89. LPRESDIR lpResDir;
  90. SHORT sLoopCount;
  91. RP_SLICE_DESC slice;
  92. lpRPL = (LPJG_RPL_HDR)lpRPLList->lpFrame->lpData;
  93. usTop = GETUSHORT(&lpRPL->usTopRow);
  94. yBrush = usTop & 0x001F;
  95. // 08/06/92 dstseng, Because band is not always 32x,
  96. // We have difficulty to paint our brush with correct offset
  97. // Unless We have a variable to keep the offset of usTop.
  98. lpRE = lpHREState->lpREState;
  99. lpbmBand = lpRE->lpBandBuffer;
  100. if (!OpenBlt (lpRE, yBrush))
  101. return;
  102. #ifdef MARSHAL
  103. lpFrame = lpRPLList->lpFrame;
  104. /* interpret the RPL, get parm list ptrs */
  105. lpul = (ULONG FAR*)((++lpFrame)->lpData);
  106. lpus = (USHORT FAR*)((++lpFrame)->lpData);
  107. lpub = (UBYTE FAR*)((++lpFrame)->lpData);
  108. /* get resource limit address */
  109. lpubLimit = (UBYTE FAR*)(lpub + lpFrame->wSize);
  110. #else
  111. /* interpret the RPL, get parm list ptrs */
  112. lpul = (ULONG FAR*)(lpRPL->ulParm);
  113. lpus = (USHORT FAR*) (GETUSHORT(&lpRPL->usLongs) * 4 +
  114. (UBYTE FAR*)(lpul));
  115. lpub = (UBYTE FAR*) (GETUSHORT(&lpRPL->usShorts) * 2 +
  116. (UBYTE FAR*)(lpus));
  117. /* get resource limit address */
  118. lpubLimit = (UBYTE FAR*)lpRPL + lpRPLList->lpFrame->wSize + 1;
  119. #endif
  120. // if first time call then initialize state variables ???
  121. /* state variables */
  122. /* Set to default value at beginning of each RPL. */
  123. /* The order of RPL execution is not specified and there must not be */
  124. /* any dependency on the previous RPL. */
  125. lpRE->sRow = 0 - usTop; //mslin 3/14/92 ccteng
  126. lpRE->sCol = lpRE->sCol2 = 0;
  127. lpRE->ubPenStyle = 0; /* set solid line */
  128. lpRE->usPenPhase = 0; /* restart the pattern */
  129. /* no current glyph set */
  130. lpRE->lpCurGS = NULL;
  131. SelectResource(lpHREState, Brush40Gray);
  132. lpRE->lpCurBitmap = NULL;
  133. /* set default ROP */
  134. RP_NewRop(lpRE, 0x88);
  135. while (1)
  136. {
  137. if (lpub > lpubLimit)
  138. {
  139. DEBUGMSG (1, ("HRE: Execution past end of RPL."));
  140. goto EndRPL;
  141. }
  142. switch ( *lpub++ )
  143. {
  144. /* 0x00 - 0x05 */
  145. case JG_RP_SetRowAbsS:
  146. /* long row setting */
  147. lpRE->sRow = GETUSHORTINC(lpus);
  148. lpRE->sRow -= usTop;
  149. break;
  150. case JG_RP_SetRowRelB:
  151. lpRE->sRow += (SBYTE)*lpub++;
  152. break;
  153. case JG_RP_SetColAbsS:
  154. /* short column setting */
  155. lpRE->sCol = GETUSHORTINC(lpus);
  156. break;
  157. case JG_RP_SetColRelB:
  158. lpRE->sCol += (SBYTE)*lpub++;
  159. break;
  160. case JG_RP_SetExtAbsS:
  161. lpRE->sCol2 = GETUSHORTINC(lpus);
  162. break;
  163. case JG_RP_SetExtRelB:
  164. lpRE->sCol2 += (SBYTE)*lpub++;
  165. break;
  166. /* 0x10 - 0x1A */
  167. case JG_RP_SelectS:
  168. /* make resource current */
  169. if (!SelectResource(lpHREState, GETUSHORT(lpus)))
  170. goto EndRPL; // select resource failure
  171. lpus++;
  172. break;
  173. case JG_RP_SelectB:
  174. /* make resource current */
  175. if (!SelectResource(lpHREState, *lpub))
  176. goto EndRPL; // select resource failure
  177. lpub += 1;
  178. break;
  179. case JG_RP_Null:
  180. case JG_RP_End:
  181. goto EndRPL;
  182. case JG_RP_SetRop:
  183. /* raster op setting */
  184. RP_NewRop(lpRE, *lpub++);
  185. break;
  186. case JG_RP_SetPenStyle:
  187. // if (lpREState->ubPenStyle != *lpub)
  188. // lpREState->usPenPhase = 0; /* restart the pattern */
  189. lpRE->ubPenStyle = *lpub++;
  190. break;
  191. #if 0
  192. case JG_RP_ShowText:
  193. {
  194. UBYTE ubCount;
  195. lpub++; // ubFontCode @5
  196. ubCount = *lpub++; // ubNChars
  197. lpub += ubCount; // ubCharCode ... @5
  198. break;
  199. }
  200. case JG_RP_ShowField:
  201. lpub++; // ubFontCode @5
  202. lpus++; // usFieldCode @5
  203. break;
  204. #endif
  205. case JG_RP_SetRopAndBrush :
  206. RP_NewRop (lpRE, *lpub++);
  207. /* make resource current */
  208. if (!SelectResource(lpHREState, GETUSHORT(lpus)))
  209. goto EndRPL; // select resource failure
  210. lpus++;
  211. break;
  212. case JG_RP_SetPatternPhase :
  213. lpRE->usPenPhase = GETUSHORTINC(lpus);
  214. break;
  215. /* 0x20 - 0x23 */
  216. case JG_RP_LineAbsS1:
  217. {
  218. USHORT usX, usY;
  219. /* draw line */
  220. usY = GETUSHORTINC(lpus); // absolute row
  221. usY -= usTop;
  222. usX = GETUSHORTINC(lpus); // absolute col
  223. ASSERT ((lpRE->sRow < 0) || (lpRE->sRow >= (SHORT)lpbmBand->bmHeight),
  224. ("HRE: LineAbsS1 y1 = %d\r\n", lpRE->sRow));
  225. ASSERT ((usY >= (WORD) lpbmBand->bmHeight),
  226. ("HRE: LineAbsS1 y2 = %d\r\n", usY));
  227. RP_SliceLine (lpRE->sCol, lpRE->sRow, usX , usY, &slice, lpRE->ubPenStyle);
  228. if (!StyleLineDraw(lpRE, &slice, lpRE->ubPenStyle,(SHORT)lpRE->ubRop, lpRE->wColor))
  229. RP_LineEE_Draw(&slice, lpbmBand);
  230. /* update current position */
  231. lpRE->sRow = usY;
  232. lpRE->sCol = usX;
  233. break;
  234. }
  235. case JG_RP_LineRelB1:
  236. {
  237. SHORT sX, sY;
  238. /* draw line */
  239. sY = lpRE->sRow + (SBYTE)*lpub++; // delta row
  240. sX = lpRE->sCol + (SBYTE)*lpub++; // delta col
  241. ASSERT ((lpRE->sRow < 0 || lpRE->sRow >= (SHORT)lpbmBand->bmHeight),
  242. ("HRE: LineRelB1 y1 = %d\r\n", lpRE->sRow));
  243. ASSERT ((sY < 0 || sY >= (SHORT)lpbmBand->bmHeight),
  244. ("HRE: LineRelB1 y2 = %d\r\n", sY));
  245. RP_SliceLine (lpRE->sCol, lpRE->sRow, sX , sY, &slice, lpRE->ubPenStyle);
  246. if (!StyleLineDraw(lpRE, &slice, lpRE->ubPenStyle,(SHORT)lpRE->ubRop, lpRE->wColor))
  247. RP_LineEE_Draw(&slice, lpbmBand);
  248. /* update current position */
  249. lpRE->sRow = sY;
  250. lpRE->sCol = sX;
  251. break;
  252. }
  253. case JG_RP_LineSlice:
  254. {
  255. USHORT us_trow, us_tcol;
  256. us_trow = *lpub++;
  257. slice.us_n_slices = *lpub++;
  258. us_tcol = us_trow; us_trow >>= 2; us_tcol &= 3; us_tcol -= 1;
  259. slice.s_dy_skip = us_tcol;
  260. us_tcol = us_trow; us_trow >>= 2; us_tcol &= 3; us_tcol -= 1;
  261. slice.s_dx_skip = us_tcol;
  262. us_tcol = us_trow; us_trow >>= 2; us_tcol &= 3; us_tcol -= 1;
  263. slice.s_dy_draw = us_tcol;
  264. us_tcol = us_trow; us_tcol &= 3; us_tcol -= 1;
  265. slice.s_dx_draw = us_tcol;
  266. slice.s_dis = GETUSHORTINC(lpus);
  267. slice.s_dis_lg = GETUSHORTINC(lpus);
  268. slice.s_dis_sm = GETUSHORTINC(lpus);
  269. slice.us_first = GETUSHORTINC(lpus);
  270. slice.us_last = GETUSHORTINC(lpus);
  271. slice.us_small = GETUSHORTINC(lpus);
  272. slice.us_x1 = lpRE->sCol;
  273. slice.us_y1 = lpRE->sRow;
  274. slice.us_x2 = lpRE->sCol;
  275. slice.us_y2 = lpRE->sRow;
  276. GetTotalPixels(&slice);
  277. if (!StyleLineDraw(lpRE, &slice, lpRE->ubPenStyle,(SHORT)lpRE->ubRop, lpRE->wColor))
  278. RP_LineEE_Draw(&slice, lpbmBand);
  279. break;
  280. }
  281. case JG_RP_FillRowD:
  282. lpRE->sCol += (SBYTE)*lpub++;
  283. lpRE->sCol2 += (SBYTE)*lpub++;
  284. // Yes, this should fall through!
  285. case JG_RP_FillRow1:
  286. ASSERT ((lpRE->sRow < 0 || lpRE->sRow >= (SHORT)lpbmBand->bmHeight),
  287. ("HRE: FillRow1 y1 = %d\r\n", lpRE->sRow));
  288. ASSERT ((lpRE->sCol2 - lpRE->sCol <= 0),
  289. ("HRE: FillRow1 Width <= 0"));
  290. RP_FILLSCANROW
  291. (
  292. lpRE, lpRE->sCol, lpRE->sRow, (USHORT)(lpRE->sCol2 - lpRE->sCol), 1,
  293. (LPBYTE) lpRE->lpCurBrush, lpRE->ulRop,
  294. lpbmBand->bmBits, lpbmBand->bmWidthBytes, yBrush
  295. );
  296. lpRE->sRow++;
  297. break;
  298. /* 0x40 - 0x41 */
  299. case JG_RP_RectB:
  300. {
  301. UBYTE ubHeight = *lpub++;
  302. UBYTE ubWidth = *lpub++;
  303. ASSERT ((lpRE->sRow < 0 || lpRE->sRow >= (SHORT)lpbmBand->bmHeight),
  304. ("HRE: RectB y1 = %d\r\n", lpRE->sRow));
  305. ASSERT ((lpRE->sRow + ubHeight > (SHORT)lpbmBand->bmHeight),
  306. ("HRE: RectB y2 = %d\r\n", lpRE->sRow + ubHeight));
  307. RP_FILLSCANROW
  308. (
  309. lpRE, lpRE->sCol, lpRE->sRow, ubWidth, ubHeight,
  310. (LPBYTE) lpRE->lpCurBrush, lpRE->ulRop,
  311. lpbmBand->bmBits, lpbmBand->bmWidthBytes, yBrush
  312. );
  313. break;
  314. }
  315. case JG_RP_RectS:
  316. {
  317. USHORT usHeight = *lpus++;
  318. USHORT usWidth = *lpus++;
  319. ASSERT ((lpRE->sCol < 0 || lpRE->sCol >= (SHORT) lpbmBand->bmWidth),
  320. ("HRE: RectS xLeft = %d\r\n", lpRE->sCol));
  321. ASSERT ((lpRE->sCol + (SHORT)usWidth> (SHORT) lpbmBand->bmWidth),
  322. ("HRE: RectS xRight = %d\r\n", lpRE->sCol + usWidth));
  323. ASSERT ((lpRE->sRow < 0 || lpRE->sRow >= (SHORT)lpbmBand->bmHeight),
  324. ("HRE: RectS yTop = %d\r\n", lpRE->sRow));
  325. ASSERT ((lpRE->sRow + (SHORT)usHeight > (SHORT)lpbmBand->bmHeight),
  326. ("HRE: RectS yBottom = %d\r\n", lpRE->sRow + usHeight));
  327. RP_FILLSCANROW
  328. (
  329. lpRE, lpRE->sCol, lpRE->sRow, usWidth, usHeight,
  330. (LPBYTE) lpRE->lpCurBrush, lpRE->ulRop,
  331. lpbmBand->bmBits, lpbmBand->bmWidthBytes, yBrush
  332. );
  333. break;
  334. }
  335. case JG_RP_BitMapHI:
  336. {
  337. UBYTE ubCompress;
  338. UBYTE ubLeft;
  339. USHORT usHeight;
  340. USHORT usWidth;
  341. ULONG FAR *ulBitMap;
  342. ubCompress = *lpub++;
  343. ubLeft = *lpub++;
  344. usHeight = GETUSHORTINC(lpus);
  345. usWidth = GETUSHORTINC(lpus);
  346. // ulBitMap = (ULONG FAR *)GETULONGINC(lpul);
  347. ulBitMap = lpul;
  348. RP_BITMAP1TO1
  349. (
  350. lpRE,
  351. (USHORT) ubLeft,
  352. (USHORT) lpRE->sRow,
  353. (USHORT) (lpRE->sCol + ubLeft),
  354. (USHORT) ((usWidth+ubLeft+0x1f) >>5),
  355. (USHORT) usHeight,
  356. (USHORT) usWidth,
  357. (ULONG FAR *) ulBitMap,
  358. (ULONG FAR *) lpRE->lpCurBrush,
  359. lpRE->ulRop
  360. );
  361. lpul += usHeight * ((usWidth + ubLeft + 0x1F) >> 5); // @2
  362. break;
  363. }
  364. case JG_RP_BitMapHR:
  365. {
  366. LPJG_BM_HDR lpBmp;
  367. UBYTE ubCompress;
  368. UBYTE ubLeft;
  369. USHORT usHeight;
  370. USHORT usWidth;
  371. ULONG FAR *ulBitMap;
  372. lpBmp = lpRE->lpCurBitmap;
  373. if (NULL == lpBmp)
  374. {
  375. // this is unexpected case.
  376. // the automatic tools warn us against this option
  377. // check windows bug# 333678 for details.
  378. // the simple cure: exit the function!
  379. goto EndRPL;
  380. }
  381. ubCompress = lpBmp->ubCompress;
  382. ubLeft = lpBmp->ubLeft;
  383. usHeight = GETUSHORT(&lpBmp->usHeight);
  384. usWidth = GETUSHORT(&lpBmp->usWidth);
  385. ulBitMap = lpRE->lpCurBitmapPtr;
  386. // Special case band bitmap.
  387. if (ulBitMap == (ULONG FAR*) lpbmBand->bmBits)
  388. break;
  389. // Call bitblt.
  390. RP_BITMAP1TO1
  391. (
  392. lpRE,
  393. (USHORT) ubLeft,
  394. (USHORT) lpRE->sRow,
  395. (USHORT) (lpRE->sCol + ubLeft),
  396. (USHORT) ((usWidth+ubLeft+0x1f) >>5),
  397. (USHORT) usHeight,
  398. (USHORT) usWidth,
  399. (ULONG FAR *) ulBitMap,
  400. (ULONG FAR *) lpRE->lpCurBrush,
  401. lpRE->ulRop
  402. );
  403. break;
  404. }
  405. case JG_RP_BitMapV:
  406. {
  407. UBYTE ubTopPad;
  408. USHORT usHeight;
  409. ubTopPad = *lpub++;
  410. usHeight = GETUSHORTINC(lpus);
  411. ASSERT ((lpRE->sRow - (SHORT)usHeight + 1 < 0 ||
  412. lpRE->sRow - (SHORT)usHeight + 1 >= (SHORT)lpbmBand->bmHeight),
  413. ("HRE: BitmapV y1 = %d\r\n", lpRE->sRow + usHeight));
  414. ASSERT ((lpRE->sRow < 0 || lpRE->sRow >= (SHORT)lpbmBand->bmHeight),
  415. ("HRE: BitmapV y2 = %d\r\n", lpRE->sRow));
  416. lpub += RP_BITMAPV (lpRE->sRow, lpRE->sCol, ubTopPad,
  417. usHeight, lpub, lpbmBand->bmBits, lpbmBand->bmWidthBytes);
  418. lpRE->sCol--;
  419. break;
  420. }
  421. /* 0x60 - 0x63 */
  422. case JG_RP_GlyphB1:
  423. iGlyph = (USHORT)*lpub++;
  424. sLoopCount = 1;
  425. goto PlaceGlyph;
  426. case JG_RP_GlyphBD:
  427. lpRE->sRow += (SBYTE)*lpub++;
  428. lpRE->sCol += (SBYTE)*lpub++;
  429. iGlyph = (USHORT)*lpub++;
  430. sLoopCount = 1;
  431. goto PlaceGlyph;
  432. case JG_RP_GlyphBDN:
  433. sLoopCount = *lpub++;
  434. lpRE->sRow += (SBYTE)*lpub++;
  435. lpRE->sCol += (SBYTE)*lpub++;
  436. iGlyph = (USHORT)*lpub++;
  437. goto PlaceGlyph;
  438. PlaceGlyph:
  439. {
  440. SHORT i;
  441. /* render the glyph */
  442. lpResDir = (LPRESDIR)(lpRE->lpCurGS);
  443. ASSERT ((!lpResDir), ("No selected glyph set!"));
  444. lpFrame = (LPFRAME)(lpResDir->lpFrameArray);
  445. for (i = 1; i <= sLoopCount; i++)
  446. {
  447. LPJG_GLYPH lpGlyph;
  448. ULONG FAR *lpSrc;
  449. #ifndef MARSHAL
  450. LPJG_GS_HDR lpGh = (LPJG_GS_HDR) (lpFrame->lpData);
  451. // Check that glyph index is within bounds.
  452. if (iGlyph >= lpGh->usGlyphs)
  453. {
  454. RETAILMSG(("WPSFAXRE DoRpl glyph index out of range!\n"));
  455. iGlyph = 0;
  456. }
  457. lpGlyph = (LPJG_GLYPH) (((UBYTE FAR*) &lpGh->ResHdr.ulUid)
  458. + GETUSHORT(&(lpGh->ausOffset[iGlyph])));
  459. lpSrc = (ULONG FAR *)&lpGlyph->aulPels[0];
  460. #else
  461. lpGlyph = (LPJG_GLYPH)(lpFrame[(iGlyph+1) << 1].lpData);
  462. lpSrc = (ULONG FAR*)(lpFrame[((iGlyph+1) << 1) + 1].lpData);
  463. #endif
  464. RP_BITMAP1TO1
  465. (
  466. lpRE,
  467. (USHORT)0,
  468. (USHORT)lpRE->sRow,
  469. (USHORT)lpRE->sCol,
  470. (USHORT) ((lpGlyph->usWidth + 31) / 32),
  471. (USHORT) lpGlyph->usHeight,
  472. (USHORT) lpGlyph->usWidth,
  473. (ULONG FAR *) lpSrc,
  474. (ULONG FAR *)lpRE->lpCurBrush,
  475. (ULONG)lpRE->ulRop
  476. );
  477. if (i != sLoopCount)
  478. {
  479. // only GlyphBDN comes here
  480. lpRE->sRow += (SBYTE)*lpub++;
  481. lpRE->sCol += (SBYTE)*lpub++;
  482. iGlyph = (USHORT)*lpub++;
  483. }
  484. }
  485. break;
  486. }
  487. default:
  488. ASSERT ((TRUE), ("Unsupported RPL command."));
  489. }
  490. }
  491. EndRPL:
  492. CloseBlt (lpRE);
  493. }
  494. // PRIVATE FUNCTIONS
  495. //---------------------------------------------------------------------------
  496. static
  497. void
  498. RP_NewRop
  499. (
  500. LPRESTATE lpRE,
  501. UBYTE ubRop // one byte ROP code from driver, this
  502. // ROP should be convert to printer ROP code
  503. // in this routine
  504. )
  505. // PURPOSE set new ROP value, also do conversion
  506. // since value 1 is black in printer
  507. // while value 0 is black in display
  508. //
  509. //---------------------------------------------------------------------------
  510. {
  511. lpRE->usBrushWidth = 0; // reset pattern width
  512. lpRE->ubRop = ubRop; // save old Rop code
  513. ubRop = (UBYTE) (
  514. (ubRop>>7&0x01) | (ubRop<<7&0x80) |
  515. (ubRop>>5&0x02) | (ubRop<<5&0x40) |
  516. (ubRop>>3&0x04) | (ubRop<<3&0x20) |
  517. (ubRop>>1&0x08) | (ubRop<<1&0x10)
  518. );
  519. ubRop = (UBYTE)~ubRop;
  520. lpRE->ulRop = ((ULONG) ubRop) << 16;
  521. #ifdef WIN32
  522. lpRE->dwRop = lpRE->ulRop | wRopTable[lpRE->ubRop];
  523. #endif
  524. }
  525. //==============================================================================
  526. void TileBrush (LPBYTE lpbPat8, LPDWORD lpdwPat32)
  527. {
  528. UINT iRow;
  529. for (iRow = 0; iRow < 8; iRow++)
  530. {
  531. DWORD dwRow = *lpbPat8++;
  532. dwRow |= dwRow << 8;
  533. dwRow |= dwRow << 16;
  534. lpdwPat32[iRow] = dwRow;
  535. lpdwPat32[iRow + 8] = dwRow;
  536. lpdwPat32[iRow + 16] = dwRow;
  537. lpdwPat32[iRow + 24] = dwRow;
  538. }
  539. }
  540. //---------------------------------------------------------------------------
  541. static
  542. int
  543. SelectResource
  544. (
  545. LPHRESTATE lpHREState, // far pointer to current job context
  546. // corresponding to the job HANDLE
  547. UINT uid // specified resource uid.
  548. )
  549. // PURPOSE given a resource block pointer
  550. // set this resource as current resource
  551. // only glyph, brush and bitmap can be
  552. // selected.
  553. //---------------------------------------------------------------------------
  554. {
  555. LPRESDIR lprh;
  556. LPRESDIR lpResDir;
  557. LPJG_RES_HDR lprh1;
  558. ULONG FAR *lpBrSrc;
  559. LPFRAME lpFrame;
  560. USHORT usClass;
  561. LPRESTATE lpRE = lpHREState->lpREState;
  562. lpRE->wColor = (uid == 0x8100)? 0x0000 : 0xFFFF;
  563. // Trap stock brushes.
  564. if ( uid & 0x8000 )
  565. {
  566. UINT iBrush = (uid < 0x8100)? uid - 0x8000 : uid - 0x8100 + 6;
  567. if (lpRE->lpBrushPat)
  568. lpRE->lpCurBrush = (LPDWORD) (lpRE->lpBrushPat + 128*iBrush);
  569. else
  570. {
  571. lpRE->lpCurBrush = (LPDWORD) lpRE->TiledPat;
  572. TileBrush (BrushPat[iBrush], lpRE->lpCurBrush);
  573. }
  574. SetBrush (lpRE);
  575. return SUCCESS;
  576. }
  577. /* must be downloaded resource */
  578. lprh = (&lpHREState->lpDlResDir[uid]);
  579. if ((lpResDir = (LPRESDIR)lprh) == NULL)
  580. return(FAILURE);
  581. lprh1 = (LPJG_RES_HDR)lpResDir->lpFrameArray->lpData;
  582. usClass = GETUSHORT(&lprh1->usClass);
  583. switch (usClass)
  584. {
  585. case JG_RS_GLYPH:
  586. lpRE->lpCurGS = (LPJG_GS_HDR)lprh;
  587. break;
  588. case JG_RS_BRUSH:
  589. lpFrame = (LPFRAME)(lpResDir->lpFrameArray);
  590. #ifdef MARSHAL
  591. lpBrSrc = (ULONG FAR *)((++lpFrame)->lpData);
  592. #else
  593. {
  594. LPJG_BRUSH lpBr = (LPJG_BRUSH)(lpFrame->lpData);
  595. lpBrSrc = (ULONG FAR *)(lpBr->aulPels);
  596. }
  597. #endif
  598. lpRE->lpCurBrush = (ULONG FAR *)lpBrSrc;
  599. SetBrush (lpRE);
  600. break;
  601. case JG_RS_BITMAP:
  602. lpFrame = (LPFRAME)(lpResDir->lpFrameArray);
  603. lpRE->lpCurBitmap = (LPJG_BM_HDR)(lpFrame->lpData);
  604. lpFrame++;
  605. #ifdef MARSHAL
  606. lpRE->lpCurBitmapPtr = (ULONG FAR *)(lpFrame->lpData);
  607. #else
  608. lpRE->lpCurBitmapPtr = (ULONG FAR *)lpRE->lpCurBitmap->aulPels;
  609. #endif
  610. default:
  611. break;
  612. }
  613. return(SUCCESS);
  614. }