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.

964 lines
35 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: trivblt.cxx
  3. *
  4. * EngCopyBits does the bitmap simulations source copy blts.
  5. * The Rop is 0xCCCC, no brush or mask required. Dib src
  6. * and Dib dest are required.
  7. *
  8. * Created: 05-Feb-1991 21:06:12
  9. * Author: Patrick Haluptzok patrickh
  10. *
  11. * Copyright (c) 1990-1999 Microsoft Corporation
  12. \**************************************************************************/
  13. #include "precomp.hxx"
  14. //
  15. // The following table is used to lookup the function to be used for a
  16. // particular type of copy operation. The table is indexed by a loosely
  17. // encoded index composed of the source format, the destination format,
  18. // the direction of the move, and whether the function is an identify
  19. // function.
  20. //
  21. // This table is used in lieu of a doubly nested switch structure that
  22. // not only takes more room, but requires more execution time.
  23. //
  24. // The index is formed as:
  25. //
  26. // Index = (iFormatDst << 5) | (iFormatSrc << 2);
  27. // if (xDir < 0) {
  28. // Index += 2;
  29. // }
  30. //
  31. // if (pxlo->bIsIdentity()) {
  32. // Index += 1;
  33. // }
  34. //
  35. // N.B. The entire table is filled. Entries that are illegal are tested
  36. // for using assertions. In free systems, dummy entries are used.
  37. //
  38. VOID
  39. vSrcCopyDummy (
  40. PBLTINFO BltInfo
  41. );
  42. PFN_SRCCPY SrcCopyFunctionTable[] = {
  43. vSrcCopyDummy, // 000-000-0-0 Dst = ?, Src = ?
  44. vSrcCopyDummy, // 000-000-0-1
  45. vSrcCopyDummy, // 000-000-1-0
  46. vSrcCopyDummy, // 000-000-1-1
  47. vSrcCopyDummy, // 000-001-0-0 Dst = ?, Src = BMF_1BPP
  48. vSrcCopyDummy, // 000-001-0-1
  49. vSrcCopyDummy, // 000-001-1-0
  50. vSrcCopyDummy, // 000-001-1-1
  51. vSrcCopyDummy, // 000-010-0-0 Dst = ?, Src = BMF_4BPP
  52. vSrcCopyDummy, // 000-010-0-1
  53. vSrcCopyDummy, // 000-010-1-0
  54. vSrcCopyDummy, // 000-010-1-1
  55. vSrcCopyDummy, // 000-011-0-0 Dst = ?, Src = BMF_8BPP
  56. vSrcCopyDummy, // 000-011-0-1
  57. vSrcCopyDummy, // 000-011-1-0
  58. vSrcCopyDummy, // 000-011-1-1
  59. vSrcCopyDummy, // 000-100-0-0 Dst = ?, Src = BMF_16BPP
  60. vSrcCopyDummy, // 000-100-0-1
  61. vSrcCopyDummy, // 000-100-1-0
  62. vSrcCopyDummy, // 000-100-1-1
  63. vSrcCopyDummy, // 000-101-0-0 Dst = ?, Src = BMF_24BPP
  64. vSrcCopyDummy, // 000-101-0-1
  65. vSrcCopyDummy, // 000-101-1-0
  66. vSrcCopyDummy, // 000-101-1-1
  67. vSrcCopyDummy, // 000-110-0-0 Dst = ?, Src = BMF_32BPP
  68. vSrcCopyDummy, // 000-110-0-1
  69. vSrcCopyDummy, // 000-110-1-0
  70. vSrcCopyDummy, // 000-110-1-1
  71. vSrcCopyDummy, // 000-111-0-0 Dst = ?, Src = ?
  72. vSrcCopyDummy, // 000-111-0-1
  73. vSrcCopyDummy, // 000-111-1-0
  74. vSrcCopyDummy, // 000-111-1-1
  75. vSrcCopyDummy, // 001-000-0-0 Dst = BMF_1BPP, Src = ?
  76. vSrcCopyDummy, // 001-000-0-1
  77. vSrcCopyDummy, // 001-000-1-0
  78. vSrcCopyDummy, // 001-000-1-1
  79. vSrcCopyS1D1LtoR, // 001-001-0-0 Dst = BMF_1BPP, Src = BMF_1BPP
  80. vSrcCopyS1D1LtoR, // 001-001-0-1
  81. vSrcCopyS1D1RtoL, // 001-001-1-0
  82. vSrcCopyS1D1RtoL, // 001-001-1-1
  83. vSrcCopyS4D1, // 001-010-0-0 Dst = BMF_1BPP, Src = BMF_4BPP
  84. vSrcCopyS4D1, // 001-010-0-1
  85. vSrcCopyS4D1, // 001-010-1-0
  86. vSrcCopyS4D1, // 001-010-1-1
  87. vSrcCopyS8D1, // 001-011-0-0 Dst = BMF_1BPP, Src = BMF_8BPP
  88. vSrcCopyS8D1, // 001-011-0-1
  89. vSrcCopyS8D1, // 001-011-1-0
  90. vSrcCopyS8D1, // 001-011-1-1
  91. vSrcCopyS16D1, // 001-100-0-0 Dst = BMF_1BPP, Src = BMF_16BPP
  92. vSrcCopyS16D1, // 001-100-0-1
  93. vSrcCopyS16D1, // 001-100-1-0
  94. vSrcCopyS16D1, // 001-100-1-1
  95. vSrcCopyS24D1, // 001-101-0-0 Dst = BMF_1BPP, Src = BMF_24BPP
  96. vSrcCopyS24D1, // 001-101-0-1
  97. vSrcCopyS24D1, // 001-101-1-0
  98. vSrcCopyS24D1, // 001-101-1-1
  99. vSrcCopyS32D1, // 001-110-0-0 Dst = BMF_1BPP, Src = BMF_32BPP
  100. vSrcCopyS32D1, // 001-110-0-1
  101. vSrcCopyS32D1, // 001-110-1-0
  102. vSrcCopyS32D1, // 001-110-1-1
  103. vSrcCopyDummy, // 001-111-0-0 Dst = BMF_1BPP, Src = ?
  104. vSrcCopyDummy, // 001-111-0-1
  105. vSrcCopyDummy, // 001-111-1-0
  106. vSrcCopyDummy, // 001-111-1-1
  107. vSrcCopyDummy, // 010-000-0-0 Dst = BMF_4BPP, Src = ?
  108. vSrcCopyDummy, // 010-000-0-1
  109. vSrcCopyDummy, // 010-000-1-0
  110. vSrcCopyDummy, // 010-000-1-1
  111. vSrcCopyS1D4, // 010-001-0-0 Dst = BMF_4BPP, Src = BMF_1BPP
  112. vSrcCopyS1D4, // 010-001-0-1
  113. vSrcCopyS1D4, // 010-001-1-0
  114. vSrcCopyS1D4, // 010-001-1-1
  115. vSrcCopyS4D4, // 010-010-0-0 Dst = BMF_4BPP, Src =BMF_4BPP
  116. vSrcCopyS4D4Identity, // 010-010-0-1
  117. vSrcCopyS4D4, // 010-010-1-0
  118. vSrcCopyS4D4Identity, // 010-010-1-1
  119. vSrcCopyS8D4, // 010-011-0-0 Dst = BMF_4BPP, Src = BMF_8BPP
  120. vSrcCopyS8D4, // 010-011-0-1
  121. vSrcCopyS8D4, // 010-011-1-0
  122. vSrcCopyS8D4, // 010-011-1-1
  123. vSrcCopyS16D4, // 010-100-0-0 Dst = BMF_4BPP, Src = BMF_16BPP
  124. vSrcCopyS16D4, // 010-100-0-1
  125. vSrcCopyS16D4, // 010-100-1-0
  126. vSrcCopyS16D4, // 010-100-1-1
  127. vSrcCopyS24D4, // 010-101-0-0 Dst = BMF_4BPP, Src = BMF_24BPP
  128. vSrcCopyS24D4, // 010-101-0-1
  129. vSrcCopyS24D4, // 010-101-1-0
  130. vSrcCopyS24D4, // 010-101-1-1
  131. vSrcCopyS32D4, // 010-110-0-0 Dst = BMF_4BPP, Src = BMF_32BPP
  132. vSrcCopyS32D4, // 010-110-0-1
  133. vSrcCopyS32D4, // 010-110-1-0
  134. vSrcCopyS32D4, // 010-110-1-1
  135. vSrcCopyDummy, // 010-111-0-0 Dst = BMF_4BPP, Src = ?
  136. vSrcCopyDummy, // 010-111-0-1
  137. vSrcCopyDummy, // 010-111-1-0
  138. vSrcCopyDummy, // 010-111-1-1
  139. vSrcCopyDummy, // 011-000-0-0 Dst = BMF_8BPP, Src = ?
  140. vSrcCopyDummy, // 011-000-0-1
  141. vSrcCopyDummy, // 011-000-1-0
  142. vSrcCopyDummy, // 011-000-1-1
  143. vSrcCopyS1D8, // 011-001-0-0 Dst = BMF_8BPP, Src = BMF_1BPP
  144. vSrcCopyS1D8, // 011-001-0-1
  145. vSrcCopyS1D8, // 011-001-1-0
  146. vSrcCopyS1D8, // 011-001-1-1
  147. vSrcCopyS4D8, // 011-010-0-0 Dst = BMF_8BPP, Src = BMF_4BPP
  148. vSrcCopyS4D8, // 011-010-0-1
  149. vSrcCopyS4D8, // 011-010-1-0
  150. vSrcCopyS4D8, // 011-010-1-1
  151. vSrcCopyS8D8, // 011-011-0-0 Dst = BMF_8BPP, Src = BMF_8BPP
  152. vSrcCopyS8D8IdentityLtoR, // 011-011-0-1
  153. vSrcCopyS8D8, // 011-011-1-0
  154. vSrcCopyS8D8IdentityRtoL, // 011-011-1-1
  155. vSrcCopyS16D8, // 011-100-0-0 Dst = BMF_8BPP, Src = BMF_16BPP
  156. vSrcCopyS16D8, // 011-100-0-1
  157. vSrcCopyS16D8, // 011-100-1-0
  158. vSrcCopyS16D8, // 011-100-1-1
  159. vSrcCopyS24D8, // 011-101-0-0 Dst = BMF_8BPP, Src = BMF_24BPP
  160. vSrcCopyS24D8, // 011-101-0-1
  161. vSrcCopyS24D8, // 011-101-1-0
  162. vSrcCopyS24D8, // 011-101-1-1
  163. vSrcCopyS32D8, // 011-110-0-0 Dst = BMF_8BPP, Src = BMF_32BPP
  164. vSrcCopyS32D8, // 011-110-0-1
  165. vSrcCopyS32D8, // 011-110-1-0
  166. vSrcCopyS32D8, // 011-110-1-1
  167. vSrcCopyDummy, // 011-111-0-0 Dst = BMF_8BPP, Src = ?
  168. vSrcCopyDummy, // 011-111-0-1
  169. vSrcCopyDummy, // 011-111-1-0
  170. vSrcCopyDummy, // 011-111-1-1
  171. vSrcCopyDummy, // 100-000-0-0 Dst = BMF_16BPP, Src = ?
  172. vSrcCopyDummy, // 100-000-0-1
  173. vSrcCopyDummy, // 100-000-1-0
  174. vSrcCopyDummy, // 100-000-1-1
  175. vSrcCopyS1D16, // 100-001-0-0 Dst = BMF_16BPP, Src = BMF_1BPP
  176. vSrcCopyS1D16, // 100-001-0-1
  177. vSrcCopyS1D16, // 100-001-1-0
  178. vSrcCopyS1D16, // 100-001-1-1
  179. vSrcCopyS4D16, // 100-010-0-0 Dst = BMF_16BPP, Src = BMF_4BPP
  180. vSrcCopyS4D16, // 100-010-0-1
  181. vSrcCopyS4D16, // 100-010-1-0
  182. vSrcCopyS4D16, // 100-010-1-1
  183. vSrcCopyS8D16, // 100-011-0-0 Dst = BMF_16BPP, Src = BMF_8BPP
  184. vSrcCopyS8D16, // 100-011-0-1
  185. vSrcCopyS8D16, // 100-011-1-0
  186. vSrcCopyS8D16, // 100-011-1-1
  187. vSrcCopyS16D16, // 100-100-0-0 Dst = BMF_16BPP, Src = BMF_16BPP
  188. vSrcCopyS16D16Identity, // 100-100-0-1
  189. vSrcCopyS16D16, // 100-100-1-0
  190. vSrcCopyS16D16Identity, // 100-100-1-1
  191. vSrcCopyS24D16, // 100-101-0-0 Dst = BMF_16BPP, Src = BMF_24BPP
  192. vSrcCopyS24D16, // 100-101-0-1
  193. vSrcCopyS24D16, // 100-101-1-0
  194. vSrcCopyS24D16, // 100-101-1-1
  195. vSrcCopyS32D16, // 100-110-0-0 Dst = BMF_16BPP, Src = BMF_32BPP
  196. vSrcCopyS32D16, // 100-110-0-1
  197. vSrcCopyS32D16, // 100-110-1-0
  198. vSrcCopyS32D16, // 100-110-1-1
  199. vSrcCopyDummy, // 100-111-0-0 Dst = BMF_16BPP, Src = ?
  200. vSrcCopyDummy, // 100-111-0-1
  201. vSrcCopyDummy, // 100-111-1-0
  202. vSrcCopyDummy, // 100-111-1-1
  203. vSrcCopyDummy, // 101-000-0-0 Dst = BMF_24BPP, Src = ?
  204. vSrcCopyDummy, // 101-000-0-1
  205. vSrcCopyDummy, // 101-000-1-0
  206. vSrcCopyDummy, // 101-000-1-1
  207. vSrcCopyS1D24, // 101-001-0-0 Dst = BMF_24BPP, Src = BMF_1BPP
  208. vSrcCopyS1D24, // 101-001-0-1
  209. vSrcCopyS1D24, // 101-001-1-0
  210. vSrcCopyS1D24, // 101-001-1-1
  211. vSrcCopyS4D24, // 101-010-0-0 Dst = BMF_24BPP, Src = BMF_4BPP
  212. vSrcCopyS4D24, // 101-010-0-1
  213. vSrcCopyS4D24, // 101-010-1-0
  214. vSrcCopyS4D24, // 101-010-1-1
  215. vSrcCopyS8D24, // 101-011-0-0 Dst = BMF_24BPP, Src = BMF_8BPP
  216. vSrcCopyS8D24, // 101-011-0-1
  217. vSrcCopyS8D24, // 101-011-1-0
  218. vSrcCopyS8D24, // 101-011-1-1
  219. vSrcCopyS16D24, // 101-100-0-0 Dst = BMF_24BPP, Src = BMF_16BPP
  220. vSrcCopyS16D24, // 101-100-0-1
  221. vSrcCopyS16D24, // 101-100-1-0
  222. vSrcCopyS16D24, // 101-100-1-1
  223. vSrcCopyS24D24, // 101-101-0-0 Dst = BMF_24BPP, Src = BMF_24BPP
  224. vSrcCopyS24D24Identity, // 101-101-0-1
  225. vSrcCopyS24D24, // 101-101-1-0
  226. vSrcCopyS24D24Identity, // 101-101-1-1
  227. vSrcCopyS32D24, // 101-110-0-0 Dst = BMF_24BPP, Src = BMF_32BPP
  228. vSrcCopyS32D24, // 101-110-0-1
  229. vSrcCopyS32D24, // 101-110-1-0
  230. vSrcCopyS32D24, // 101-110-1-1
  231. vSrcCopyDummy, // 101-111-0-0 Dst = BMF_24BPP, Src = ?
  232. vSrcCopyDummy, // 101-111-0-1
  233. vSrcCopyDummy, // 101-111-1-0
  234. vSrcCopyDummy, // 101-111-1-1
  235. vSrcCopyDummy, // 110-000-0-0 Dst = BMF_32BPP, Src = ?
  236. vSrcCopyDummy, // 110-000-0-1
  237. vSrcCopyDummy, // 110-000-1-0
  238. vSrcCopyDummy, // 110-000-1-1
  239. vSrcCopyS1D32, // 110-001-0-0 Dst = BMF_32BPP, Src = BMF_1BPP
  240. vSrcCopyS1D32, // 110-001-0-1
  241. vSrcCopyS1D32, // 110-001-1-0
  242. vSrcCopyS1D32, // 110-001-1-1
  243. vSrcCopyS4D32, // 110-010-0-0 Dst = BMF_32BPP, Src = BMF_4BPP
  244. vSrcCopyS4D32, // 110-010-0-1
  245. vSrcCopyS4D32, // 110-010-1-0
  246. vSrcCopyS4D32, // 110-010-1-1
  247. vSrcCopyS8D32, // 110-011-0-0 Dst = BMF_32BPP, Src = BMF_8BPP
  248. vSrcCopyS8D32, // 110-011-0-1
  249. vSrcCopyS8D32, // 110-011-1-0
  250. vSrcCopyS8D32, // 110-011-1-1
  251. vSrcCopyS16D32, // 110-100-0-0 Dst = BMF_32BPP, Src = BMF_16BPP
  252. vSrcCopyS16D32, // 110-100-0-1
  253. vSrcCopyS16D32, // 110-100-1-0
  254. vSrcCopyS16D32, // 110-100-1-1
  255. vSrcCopyS24D32, // 110-101-0-0 Dst = BMF_32BPP, Src = BMF_24BPP
  256. vSrcCopyS24D32, // 110-101-0-1
  257. vSrcCopyS24D32, // 110-101-1-0
  258. vSrcCopyS24D32, // 110-101-1-1
  259. vSrcCopyS32D32, // 110-110-0-0 Dst = BMF_32BPP, Src = BMF_32BPP
  260. vSrcCopyS32D32Identity, // 110-110-0-1
  261. vSrcCopyS32D32, // 110-110-1-0
  262. vSrcCopyS32D32Identity, // 110-110-1-1
  263. vSrcCopyDummy, // 110-111-0-0 Dst = BMF_32BPP, Src = ?
  264. vSrcCopyDummy, // 110-111-0-1
  265. vSrcCopyDummy, // 110-111-1-0
  266. vSrcCopyDummy // 110-111-1-1
  267. };
  268. /******************************Public*Routine******************************\
  269. * EngCopyBits
  270. *
  271. * Purpose: Does all 0xCCCC blts. This includes RLE blts.
  272. *
  273. * Description:
  274. *
  275. * Sets up for a blt from <psoSrc> to <psoDst>. The actual copying of
  276. * the bits is performed by a function call. The function to be used
  277. * is determined by the formats of the source & destination - and is
  278. * is selected by making a call to <pfnSrcCpy>.
  279. *
  280. * The blt setup consists of filling a BLTINFO structure with
  281. * - offsets into the source and destination bitmaps
  282. * - intial values of the source and destination pointers
  283. * - ending points in source and destination.
  284. *
  285. * This function also controls clipping: In the complex clipping case,
  286. * the BLTINFO structure is set up and the blt function is called for
  287. * EACH rectangle in the clipping object <pco>.
  288. *
  289. * NB: RLE Sources are treated as a special case, since we can't cheat
  290. * and start copying from inside the source bitmap. We must play
  291. * the RLE from the beginning for each clipping region.
  292. * An optimization to get around this is coming.
  293. *
  294. * History:
  295. * 22-Jan-1992 - Andrew Milton (w-andym):
  296. * Isolated the RLE source cases and provided some RLE play
  297. * optimizations.
  298. *
  299. * 02-May-1991 -by- Patrick Haluptzok patrickh
  300. * Wrote it.
  301. \**************************************************************************/
  302. BOOL
  303. EngCopyBits(
  304. SURFOBJ *psoDst,
  305. SURFOBJ *psoSrc,
  306. CLIPOBJ *pco,
  307. XLATEOBJ *pxlo,
  308. PRECTL prclDst,
  309. PPOINTL pptlSrc
  310. )
  311. {
  312. ASSERTGDI(psoDst != NULL, "ERROR EngCopyBits: No Dst. Object\n");
  313. ASSERTGDI(psoSrc != NULL, "ERROR EngCopyBits: No Src. Object\n");
  314. ASSERTGDI(prclDst != (PRECTL) NULL, "ERROR EngCopyBits: No Target Rect.\n");
  315. ASSERTGDI(pptlSrc != (PPOINTL) NULL, "ERROR EngCopyBits: No Start Point.\n");
  316. ASSERTGDI(prclDst->left < prclDst->right, "ERROR EngCopyBits0\n");
  317. ASSERTGDI(prclDst->top < prclDst->bottom, "ERROR EngCopyBits1\n");
  318. ASSERTGDI(psoDst->iType == STYPE_BITMAP,
  319. "ERROR EngCopyBits: Dst. Object is not a bitmap.\n");
  320. PSURFACE pSurfDst = SURFOBJ_TO_SURFACE(psoDst);
  321. PSURFACE pSurfSrc = SURFOBJ_TO_SURFACE(psoSrc);
  322. ASSERTGDI(pSurfDst->iFormat() != BMF_JPEG,
  323. "ERROR EngCopyBits: dst BMF_JPEG\n");
  324. ASSERTGDI(pSurfDst->iFormat() != BMF_PNG,
  325. "ERROR EngCopyBits: dst BMF_PNG\n");
  326. ASSERTGDI(pSurfSrc->iFormat() != BMF_JPEG,
  327. "ERROR EngCopyBits: src BMF_JPEG\n");
  328. ASSERTGDI(pSurfSrc->iFormat() != BMF_PNG,
  329. "ERROR EngCopyBits: src BMF_PNG\n");
  330. // If this is a device surface pass it off to the driver.
  331. if (psoSrc->iType != STYPE_BITMAP)
  332. {
  333. PDEVOBJ pdoSrc(pSurfSrc->hdev());
  334. PFN_DrvCopyBits pfnCopyBits = PPFNDRV(pdoSrc,CopyBits);
  335. // If the source is a mirrored surface, pass the read request back
  336. // through the DDML. This allows a driver like NetMeeting to read
  337. // from the screen:
  338. EXLATEOBJ xloParent;
  339. if (pSurfSrc->bMirrorSurface() &&
  340. (pdoSrc.hdev() != pdoSrc.hdevParent()))
  341. {
  342. PDEVOBJ pdoSrc(pSurfSrc->hdev());
  343. PDEVOBJ pdoParent(pdoSrc.hdevParent());
  344. SURFREF srParent((HSURF)pSurfSrc->hMirrorParent);
  345. if (!srParent.bValid()) return (FALSE);
  346. if (xloParent.bInitXlateObj(
  347. NULL,DC_ICM_OFF,
  348. pdoParent.ppalSurf(), pdoSrc.ppalSurf(),
  349. ppalDefault, ppalDefault,
  350. 0L,0L,0L, XLATE_USE_SURFACE_PAL))
  351. pxlo = xloParent.pxlo();
  352. else
  353. return (FALSE);
  354. psoSrc = srParent.ps->pSurfobj();
  355. pfnCopyBits = PPFNDRV(pdoParent, CopyBits);
  356. }
  357. return(pfnCopyBits(psoDst,
  358. psoSrc,
  359. pco,
  360. pxlo,
  361. prclDst,
  362. pptlSrc));
  363. }
  364. // Synchronize with the device driver before touching the device surface.
  365. {
  366. PDEVOBJ po(psoDst->hdev);
  367. po.vSync(psoDst,NULL,0);
  368. }
  369. {
  370. PDEVOBJ po(psoSrc->hdev);
  371. po.vSync(psoSrc,NULL,0);
  372. }
  373. // Local Variables required for the blt
  374. BOOL bMore; // True while more clip regions exist
  375. BOOL bRLE = FALSE; // True if the source is an RLE bitmap
  376. ULONG ircl; // Clip region index
  377. BLTINFO bltinfo; // Data passed to our vSrcCopySnDn fxn
  378. /* Compute the directions for the copy and clipping enumeration. There
  379. * are two cases: RLE & not.
  380. *
  381. * RLE's are always copied Left-Right, Bottom-Top; which is also their
  382. * clipping enumeration.
  383. *
  384. * For non-RLE's, the copy direction is dependant on overlap. The
  385. * X and Y directions must be chosen so ensure no portion of the source
  386. * is clobbered by the copy operation. If there is no overlap, the
  387. * copy and clipping enumeration is Left-Right, Top-Bottom.
  388. */
  389. LONG xDir = 1L, yDir = 1L; /* X, Y Directions. Positive = Left, Down */
  390. LONG iDir; // Order to fetch clip region rectangles
  391. /*
  392. * Are we going to do reads from BMF_NOTSYSMEM ie Video memory ?
  393. * If so set up bltinfo so the blitting routine wil do source aligned reads.
  394. */
  395. if ((psoSrc->iBitmapFormat == BMF_8RLE) || (psoSrc->iBitmapFormat == BMF_4RLE))
  396. {
  397. /* RLE Case. */
  398. iDir = CD_RIGHTUP;
  399. xDir = 1L;
  400. yDir = -1L;
  401. bltinfo.lDeltaDst = -psoDst->lDelta;
  402. bltinfo.lDeltaSrc = 0;
  403. bRLE = TRUE;
  404. }
  405. else
  406. {
  407. /* Non-RLE Case.
  408. *
  409. * Check whether source and destination are the same by comparing
  410. * the pvScan0 pointers. We can't simply compare surface pointers or
  411. * handles because some drivers punt this call to GDI, but pass us
  412. * different SURFOBJs for the source and destination even when
  413. * they're really the same surface.
  414. */
  415. if (psoSrc->pvScan0 == psoDst->pvScan0)
  416. {
  417. if (pptlSrc->x < prclDst->left)
  418. {
  419. xDir = -1L; /* Copy Right to Left */
  420. if (pptlSrc->y < prclDst->top)
  421. {
  422. yDir = -1L; /* Copy Bottom to Top */
  423. iDir = CD_LEFTUP; /* Clip Left-Right, Bottom-Top */
  424. }
  425. else
  426. {
  427. iDir = CD_LEFTDOWN; /* Clip Left-Right, Top-Bottom */
  428. }
  429. }
  430. else
  431. {
  432. if (pptlSrc->y < prclDst->top)
  433. {
  434. yDir = -1L; /* Copy Bottom to Top */
  435. iDir = CD_RIGHTUP; /* Clip Right-Left, Bottom-Top */
  436. }
  437. else
  438. iDir = CD_RIGHTDOWN;
  439. }
  440. }
  441. else
  442. iDir = CD_ANY;
  443. bltinfo.lDeltaSrc = (yDir > 0) ? psoSrc->lDelta :
  444. -psoSrc->lDelta;
  445. bltinfo.lDeltaDst = (yDir > 0) ? psoDst->lDelta :
  446. -psoDst->lDelta;
  447. }
  448. /* Determine the clipping region complexity. */
  449. CLIPENUMRECT clenr; /* buffer for storing clip rectangles */
  450. if (pco != (CLIPOBJ *) NULL)
  451. {
  452. switch(pco->iDComplexity)
  453. {
  454. case DC_TRIVIAL:
  455. bMore = FALSE;
  456. clenr.c = 1;
  457. clenr.arcl[0] = *prclDst; // Use the target for clipping
  458. break;
  459. case DC_RECT:
  460. bMore = FALSE;
  461. clenr.c = 1;
  462. clenr.arcl[0] = pco->rclBounds;
  463. break;
  464. case DC_COMPLEX:
  465. bMore = TRUE;
  466. ((ECLIPOBJ *) pco)->cEnumStart(FALSE, CT_RECTANGLES, iDir,
  467. CLIPOBJ_ENUM_LIMIT);
  468. break;
  469. default:
  470. RIP("ERROR EngCopyBits bad clipping type");
  471. } /* switch */
  472. }
  473. else
  474. {
  475. bMore = FALSE; /* Default to TRIVIAL for no clip */
  476. clenr.c = 1;
  477. clenr.arcl[0] = *prclDst; // Use the target for clipping
  478. } /* if */
  479. /* Set up the static blt information into the BLTINFO structure -
  480. * The colour translation, & the copy directions.
  481. */
  482. /* pxlo is NULL implies identity colour translation. */
  483. if (pxlo == NULL)
  484. bltinfo.pxlo = &xloIdent;
  485. else
  486. bltinfo.pxlo = (XLATE *) pxlo;
  487. bltinfo.xDir = xDir;
  488. bltinfo.yDir = yDir;
  489. /* Use a seperate loop for RLE bitmaps. This way, we won't slow down
  490. * an iteration with an IF on each pass. The trade-off is to duplicate
  491. * a portion of the code.
  492. */
  493. if (bRLE)
  494. {
  495. /* Fetch our blt function. Die if NULL */
  496. PFN_RLECPY pfnRLECopy = pfnGetRLESrcCopy(psoSrc->iBitmapFormat,
  497. psoDst->iBitmapFormat);
  498. if (pfnRLECopy == (PFN_RLECPY) NULL)
  499. return (FALSE);
  500. BOOL bBytesRemain = TRUE;
  501. /* Since an RLE bitmap must be played from its beginning,
  502. * we do not need to calculate offsets into the source bitmap.
  503. * This way, most of the information required for the BLTINFO
  504. * can be read off the Source & Destination objects.
  505. */
  506. bltinfo.ptlSrc = *pptlSrc;
  507. bltinfo.pdioSrc = pSurfSrc;
  508. bltinfo.yDstStart = (LONG)(prclDst->top + psoSrc->sizlBitmap.cy -
  509. pptlSrc->y - 1);
  510. bltinfo.xDstStart = (LONG)(prclDst->left - pptlSrc->x);
  511. bltinfo.ulOutCol = bltinfo.xDstStart;
  512. bltinfo.pjSrc = (PBYTE) psoSrc->pvScan0;
  513. bltinfo.pjDst = (PBYTE) (((PBYTE) psoDst->pvScan0) +
  514. bltinfo.yDstStart*psoDst->lDelta);
  515. bltinfo.ulConsumed = 0;
  516. bltinfo.rclDst.top = 0;
  517. do
  518. {
  519. PRECTL prcl;
  520. if (bMore)
  521. bMore = ((ECLIPOBJ *) pco)->bEnum(sizeof(clenr),
  522. (PVOID) &clenr);
  523. for (ircl = 0; ircl < clenr.c; ircl++)
  524. {
  525. prcl = &clenr.arcl[ircl];
  526. /* Insersect the clip rectangle with the target rectangle to
  527. * determine our visible rectangle
  528. */
  529. if (prcl->left < prclDst->left)
  530. prcl->left = prclDst->left;
  531. if (prcl->right > prclDst->right)
  532. prcl->right = prclDst->right;
  533. if (prcl->top < prclDst->top)
  534. prcl->top = prclDst->top;
  535. if (prcl->bottom > prclDst->bottom)
  536. prcl->bottom = prclDst->bottom;
  537. /* Process the result if it's a valid rectangle. */
  538. if ((prcl->top < prcl->bottom) && (prcl->left < prcl->right))
  539. {
  540. /* Adjust our starting position based on previous clips */
  541. if (prcl->bottom <= bltinfo.rclDst.top)
  542. {
  543. if ((ULONG)prcl->top > bltinfo.ulEndRow)
  544. continue;
  545. if (!bBytesRemain)
  546. {
  547. bMore = FALSE; // Force us out of the outer loop
  548. break; // Force us out of the inner loop
  549. }
  550. bltinfo.pjSrc = bltinfo.pjSrcEnd;
  551. bltinfo.pjDst = bltinfo.pjDstEnd;
  552. bltinfo.yDstStart = bltinfo.ulEndRow;
  553. bltinfo.ulOutCol = bltinfo.ulEndCol;
  554. bltinfo.ulConsumed = bltinfo.ulEndConsumed;
  555. }
  556. bltinfo.rclDst = *prcl;
  557. bBytesRemain = (*pfnRLECopy)(&bltinfo);
  558. }
  559. } /* for */
  560. } while(bMore);
  561. }
  562. else
  563. {
  564. /* Non-RLE Case */
  565. ULONG Index;
  566. PFN_SRCCPY pfnSrcCopy;
  567. ASSERTGDI(BMF_1BPP == 1, "ERROR EngCopyBits: BMF_1BPP not eq 1");
  568. ASSERTGDI(BMF_4BPP == 2, "ERROR EngCopyBits: BMF_1BPP not eq 2");
  569. ASSERTGDI(BMF_8BPP == 3, "ERROR EngCopyBits: BMF_1BPP not eq 3");
  570. ASSERTGDI(BMF_16BPP == 4, "ERROR EngCopyBits: BMF_1BPP not eq 4");
  571. ASSERTGDI(BMF_24BPP == 5, "ERROR EngCopyBits: BMF_1BPP not eq 5");
  572. ASSERTGDI(BMF_32BPP == 6, "ERROR EngCopyBits: BMF_1BPP not eq 6");
  573. ASSERTGDI(psoDst->iBitmapFormat <= BMF_32BPP, "ERROR EngCopyBits: bad destination format");
  574. ASSERTGDI(psoSrc->iBitmapFormat <= BMF_32BPP, "ERROR EngCopyBits: bad source format");
  575. ASSERTGDI(psoDst->iBitmapFormat != 0, "ERROR EngCopyBits: bad destination format");
  576. ASSERTGDI(psoSrc->iBitmapFormat != 0, "ERROR EngCopyBits: bad source format");
  577. //
  578. // Compute the function table index and select the source copy
  579. // function.
  580. //
  581. Index = (psoDst->iBitmapFormat << 5) | (psoSrc->iBitmapFormat << 2);
  582. if (xDir < 0) {
  583. Index += 2;
  584. }
  585. KFLOATING_SAVE fpState;
  586. BOOL bRestoreFP = FALSE;
  587. if (((XLATE *)(bltinfo.pxlo))->bIsIdentity())
  588. {
  589. Index += 1;
  590. if(psoSrc->fjBitmap & BMF_NOTSYSMEM)
  591. {
  592. bltinfo.fSrcAlignedRd = TRUE;
  593. #if i386
  594. if(HasMMX)
  595. {
  596. bRestoreFP = TRUE;
  597. if(!NT_SUCCESS(KeSaveFloatingPointState(&fpState)))
  598. {
  599. bltinfo.fSrcAlignedRd = FALSE;
  600. bRestoreFP = FALSE;
  601. }
  602. }
  603. #endif
  604. }
  605. }
  606. pfnSrcCopy = SrcCopyFunctionTable[Index];
  607. do {
  608. if (bMore)
  609. bMore = ((ECLIPOBJ *) pco)->bEnum(sizeof(clenr),
  610. (PVOID) &clenr);
  611. for (ircl = 0; ircl < clenr.c; ircl++)
  612. {
  613. PRECTL prcl = &clenr.arcl[ircl];
  614. /* Insersect the clip rectangle with the target rectangle to
  615. * determine our visible recangle
  616. */
  617. if (prcl->left < prclDst->left)
  618. prcl->left = prclDst->left;
  619. if (prcl->right > prclDst->right)
  620. prcl->right = prclDst->right;
  621. if (prcl->top < prclDst->top)
  622. prcl->top = prclDst->top;
  623. if (prcl->bottom > prclDst->bottom)
  624. prcl->bottom = prclDst->bottom;
  625. /* Process the result if it's a valid rectangle. */
  626. if ((prcl->top < prcl->bottom) && (prcl->left < prcl->right))
  627. {
  628. /* These variables are used for computing where the
  629. * scanlines start.
  630. */
  631. LONG xSrc;
  632. LONG ySrc;
  633. LONG xDst;
  634. LONG yDst;
  635. // Figure out the upper-left coordinates of rects to blt
  636. xDst = prcl->left;
  637. yDst = prcl->top;
  638. xSrc = pptlSrc->x + xDst - prclDst->left;
  639. ySrc = pptlSrc->y + yDst - prclDst->top;
  640. // Figure out the width and height of this rectangle
  641. bltinfo.cx = prcl->right - xDst;
  642. bltinfo.cy = prcl->bottom - yDst;
  643. /* # of pixels offset to first pixel for src and dst
  644. * from start of scan
  645. */
  646. bltinfo.xSrcStart = (xDir > 0) ? xSrc :
  647. (xSrc + bltinfo.cx - 1);
  648. bltinfo.xSrcEnd = bltinfo.xSrcStart +
  649. (bltinfo.cx * xDir);
  650. bltinfo.xDstStart = (xDir > 0) ? xDst :
  651. (xDst + bltinfo.cx - 1);
  652. bltinfo.yDstStart = prcl->top;
  653. // Src scanline begining
  654. // Destination scanline begining
  655. if (yDir > 0)
  656. {
  657. bltinfo.pjSrc = ((PBYTE) psoSrc->pvScan0) +
  658. ySrc*(psoSrc->lDelta);
  659. bltinfo.pjDst = ((PBYTE) psoDst->pvScan0) +
  660. yDst * (psoDst->lDelta);
  661. }
  662. else
  663. {
  664. bltinfo.pjSrc = ((PBYTE) psoSrc->pvScan0) +
  665. (ySrc + bltinfo.cy - 1) * (psoSrc->lDelta);
  666. bltinfo.pjDst = ((PBYTE) psoDst->pvScan0) +
  667. (yDst + bltinfo.cy - 1) * (psoDst->lDelta);
  668. } /* if */
  669. /* Do the blt */
  670. (*pfnSrcCopy)(&bltinfo);
  671. } /* if */
  672. } /* for */
  673. } while (bMore);
  674. #if i386
  675. if(HasMMX)
  676. {
  677. if(bRestoreFP)
  678. {
  679. KeRestoreFloatingPointState(&fpState);
  680. }
  681. }
  682. #endif
  683. } /* if */
  684. return(TRUE);
  685. } /* EngCopyBits */
  686. /******************************Private*Routine*****************************\
  687. * vSrcCopyDummy
  688. *
  689. * This gets the correct function to dispatch to for Src Copy Bitblt.
  690. *
  691. * History:
  692. * 02-Sep-1992 -by- David N. Cutler davec
  693. * Wrote it.
  694. \**************************************************************************/
  695. VOID
  696. vSrcCopyDummy (
  697. PBLTINFO BltInfo
  698. )
  699. {
  700. ASSERTGDI(FALSE, "ERROR EngCopyBits: dummy function called");
  701. return;
  702. }
  703. /******************************Public*Routine******************************\
  704. * pfnGetRLESrcCopy
  705. *
  706. * This gets the correct function to dispatch to for Src Copy Bitblt,
  707. * assuming that the source is an RLE bitmap.
  708. *
  709. * History:
  710. *
  711. * 05 Mar 1992 - Andrew Milton (w-andym):
  712. * Creation.
  713. *
  714. \**************************************************************************/
  715. PFN_RLECPY
  716. pfnGetRLESrcCopy(
  717. ULONG iFormatSrc,
  718. ULONG iFormatDst)
  719. {
  720. switch(iFormatDst) {
  721. case BMF_1BPP:
  722. switch(iFormatSrc)
  723. {
  724. case BMF_8RLE:
  725. return(bSrcCopySRLE8D1);
  726. case BMF_4RLE:
  727. return(bSrcCopySRLE4D1);
  728. default:
  729. RIP("ERROR: Invalid iFormatSrc in XlateList");
  730. }
  731. case BMF_4BPP:
  732. switch(iFormatSrc)
  733. {
  734. case BMF_8RLE:
  735. return(bSrcCopySRLE8D4);
  736. case BMF_4RLE:
  737. return(bSrcCopySRLE4D4);
  738. default:
  739. RIP("ERROR: Invalid iFormatSrc in XlateList");
  740. }
  741. case BMF_8BPP:
  742. switch(iFormatSrc)
  743. {
  744. case BMF_8RLE:
  745. return(bSrcCopySRLE8D8);
  746. case BMF_4RLE:
  747. return(bSrcCopySRLE4D8);
  748. default:
  749. RIP("ERROR: Invalid iFormatSrc in XlateList");
  750. }
  751. case BMF_16BPP:
  752. switch(iFormatSrc)
  753. {
  754. case BMF_8RLE:
  755. return(bSrcCopySRLE8D16);
  756. case BMF_4RLE:
  757. return(bSrcCopySRLE4D16);
  758. default:
  759. RIP("ERROR: Invalid iFormatSrc in XlateList");
  760. }
  761. case BMF_24BPP:
  762. switch(iFormatSrc)
  763. {
  764. case BMF_8RLE:
  765. return(bSrcCopySRLE8D24);
  766. case BMF_4RLE:
  767. return(bSrcCopySRLE4D24);
  768. default:
  769. RIP("ERROR: Invalid iFormatSrc in XlateList");
  770. }
  771. case BMF_32BPP:
  772. switch(iFormatSrc)
  773. {
  774. case BMF_8RLE:
  775. return(bSrcCopySRLE8D32);
  776. case BMF_4RLE:
  777. return(bSrcCopySRLE4D32);
  778. default:
  779. RIP("ERROR: Invalid iFormatSrc in XlateList");
  780. }
  781. default:
  782. RIP("ERROR: Invalid iFormatDst in XlateList");
  783. } /* switch */
  784. return(NULL);
  785. } /* pfnGetRLESrcCopy */