Source code of Windows XP (NT5)
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.

339 lines
12 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: misc.c
  3. *
  4. * Miscellaneous common routines.
  5. *
  6. * Copyright (c) 1992-1995 Microsoft Corporation
  7. *
  8. \**************************************************************************/
  9. #include "precomp.h"
  10. /******************************Public*Table********************************\
  11. * BYTE gaulHwMixFromRop2[]
  12. *
  13. * Table to convert from a Source and Destination Rop2 to the hardware's
  14. * mix.
  15. \**************************************************************************/
  16. BYTE gajHwMixFromRop2[] = {
  17. HW_0, // 00 -- 0 BLACKNESS
  18. HW_DPon, // 11 -- DSon NOTSRCERASE
  19. HW_DPna, // 22 -- DSna
  20. HW_Pn, // 33 -- Sn NOSRCCOPY
  21. HW_PDna, // 44 -- SDna SRCERASE
  22. HW_Dn, // 55 -- Dn DSTINVERT
  23. HW_DPx, // 66 -- DSx SRCINVERT
  24. HW_DPan, // 77 -- DSan
  25. HW_DPa, // 88 -- DSa SRCAND
  26. HW_DPxn, // 99 -- DSxn
  27. HW_D, // AA -- D
  28. HW_DPno, // BB -- DSno MERGEPAINT
  29. HW_P, // CC -- S SRCCOPY
  30. HW_PDno, // DD -- SDno
  31. HW_DPo, // EE -- DSo SRCPAINT
  32. HW_1 // FF -- 1 WHITENESS
  33. };
  34. /******************************Public*Table********************************\
  35. * BYTE gajHwMixFromMix[]
  36. *
  37. * Table to convert from a GDI mix value to the hardware's mix.
  38. *
  39. * Ordered so that the mix may be calculated from gajHwMixFromMix[mix & 0xf]
  40. * or gajHwMixFromMix[mix & 0xff].
  41. \**************************************************************************/
  42. BYTE gajHwMixFromMix[] = {
  43. HW_1, // 0 -- 1
  44. HW_0, // 1 -- 0
  45. HW_DPon, // 2 -- DPon
  46. HW_DPna, // 3 -- DPna
  47. HW_Pn, // 4 -- Pn
  48. HW_PDna, // 5 -- PDna
  49. HW_Dn, // 6 -- Dn
  50. HW_DPx, // 7 -- DPx
  51. HW_DPan, // 8 -- DPan
  52. HW_DPa, // 9 -- DPa
  53. HW_DPxn, // 10 -- DPxn
  54. HW_D, // 11 -- D
  55. HW_DPno, // 12 -- DPno
  56. HW_P, // 13 -- P
  57. HW_PDno, // 14 -- PDno
  58. HW_DPo, // 15 -- DPo
  59. HW_1 // 16 -- 1
  60. };
  61. #if 1 // D5480
  62. /******************************Public*Table********************************\
  63. * DWORD gaulHwPackedMixFromRop2_Packed[]
  64. *
  65. * Table to convert from a Source and Destination Rop2 to the hardware's
  66. * mix in DWORD packed mode.
  67. \**************************************************************************/
  68. DWORD gajHwPackedMixFromRop2[] = {
  69. HW_PACKED_0, // 00 -- 0 BLACKNESS
  70. HW_PACKED_DPon, // 11 -- DSon NOTSRCERASE
  71. HW_PACKED_DPna, // 22 -- DSna
  72. HW_PACKED_Pn, // 33 -- Sn NOSRCCOPY
  73. HW_PACKED_PDna, // 44 -- SDna SRCERASE
  74. HW_PACKED_Dn, // 55 -- Dn DSTINVERT
  75. HW_PACKED_DPx, // 66 -- DSx SRCINVERT
  76. HW_PACKED_DPan, // 77 -- DSan
  77. HW_PACKED_DPa, // 88 -- DSa SRCAND
  78. HW_PACKED_DPxn, // 99 -- DSxn
  79. HW_PACKED_D, // AA -- D
  80. HW_PACKED_DPno, // BB -- DSno MERGEPAINT
  81. HW_PACKED_P, // CC -- S SRCCOPY
  82. HW_PACKED_PDno, // DD -- SDno
  83. HW_PACKED_DPo, // EE -- DSo SRCPAINT
  84. HW_PACKED_1 // FF -- 1 WHITENESS
  85. };
  86. /******************************Public*Table********************************\
  87. * DWORD gajHwPackedMixFromMix[]
  88. *
  89. * Table to convert from a GDI mix value to the hardware's mix.
  90. *
  91. * Ordered so that the mix may be calculated from
  92. * gajHwPackedMixFromMix[mix & 0xf] or gajHwPackedMixFromMix[mix & 0xff].
  93. \**************************************************************************/
  94. DWORD gajHwPackedMixFromMix[] = {
  95. HW_PACKED_1, // 0 -- 1
  96. HW_PACKED_0, // 1 -- 0
  97. HW_PACKED_DPon, // 2 -- DPon
  98. HW_PACKED_DPna, // 3 -- DPna
  99. HW_PACKED_Pn, // 4 -- Pn
  100. HW_PACKED_PDna, // 5 -- PDna
  101. HW_PACKED_Dn, // 6 -- Dn
  102. HW_PACKED_DPx, // 7 -- DPx
  103. HW_PACKED_DPan, // 8 -- DPan
  104. HW_PACKED_DPa, // 9 -- DPa
  105. HW_PACKED_DPxn, // 10 -- DPxn
  106. HW_PACKED_D, // 11 -- D
  107. HW_PACKED_DPno, // 12 -- DPno
  108. HW_PACKED_P, // 13 -- P
  109. HW_PACKED_PDno, // 14 -- PDno
  110. HW_PACKED_DPo, // 15 -- DPo
  111. HW_PACKED_1 // 16 -- 1
  112. };
  113. #endif // endif D5480
  114. /******************************Public*Data*********************************\
  115. * MIX translation table
  116. *
  117. * Translates a mix 1-16, into an old style Rop 0-255.
  118. *
  119. \**************************************************************************/
  120. BYTE gaRop3FromMix[] =
  121. {
  122. R3_WHITENESS, // R2_WHITE - Allow rop = gaRop3FromMix[mix & 0x0f]
  123. R3_BLACKNESS, // R2_BLACK
  124. 0x05, // R2_NOTMERGEPEN
  125. 0x0A, // R2_MASKNOTPEN
  126. 0x0F, // R2_NOTCOPYPEN
  127. 0x50, // R2_MASKPENNOT
  128. R3_DSTINVERT, // R2_NOT
  129. R3_PATINVERT, // R2_XORPEN
  130. 0x5F, // R2_NOTMASKPEN
  131. 0xA0, // R2_MASKPEN
  132. 0xA5, // R2_NOTXORPEN
  133. R3_NOP, // R2_NOP
  134. 0xAF, // R2_MERGENOTPEN
  135. R3_PATCOPY, // R2_COPYPEN
  136. 0xF5, // R2_MERGEPENNOT
  137. 0xFA, // R2_MERGEPEN
  138. R3_WHITENESS // R2_WHITE - Allow rop = gaRop3FromMix[mix & 0xff]
  139. };
  140. /******************************Public*Data*********************************\
  141. * Edge masks for clipping DWORDS
  142. *
  143. * Masks off unwanted bits.
  144. *
  145. \**************************************************************************/
  146. ULONG gaulLeftClipMask[] =
  147. {
  148. 0xFFFFFFFF, 0xFFFFFF7F, 0xFFFFFF3F, 0xFFFFFF1F,
  149. 0xFFFFFF0F, 0xFFFFFF07, 0xFFFFFF03, 0xFFFFFF01,
  150. 0xFFFFFF00, 0xFFFF7F00, 0xFFFF3F00, 0xFFFF1F00,
  151. 0xFFFF0F00, 0xFFFF0700, 0xFFFF0300, 0xFFFF0100,
  152. 0xFFFF0000, 0xFF7F0000, 0xFF3F0000, 0xFF1F0000,
  153. 0xFF0F0000, 0xFF070000, 0xFF030000, 0xFF010000,
  154. 0xFF000000, 0x7F000000, 0x3F000000, 0x1F000000,
  155. 0x0F000000, 0x07000000, 0x03000000, 0x01000000
  156. };
  157. ULONG gaulRightClipMask[] =
  158. {
  159. 0xFFFFFFFF, 0xFEFFFFFF, 0xFCFFFFFF, 0xF8FFFFFF,
  160. 0xF0FFFFFF, 0xE0FFFFFF, 0xC0FFFFFF, 0x80FFFFFF,
  161. 0x00FFFFFF, 0x00FEFFFF, 0x00FCFFFF, 0x00F8FFFF,
  162. 0x00F0FFFF, 0x00E0FFFF, 0x00C0FFFF, 0x0080FFFF,
  163. 0x0000FFFF, 0x0000FEFF, 0x0000FCFF, 0x0000F8FF,
  164. 0x0000F0FF, 0x0000E0FF, 0x0000C0FF, 0x000080FF,
  165. 0x000000FF, 0x000000FE, 0x000000FC, 0x000000F8,
  166. 0x000000F0, 0x000000E0, 0x000000C0, 0x00000080
  167. };
  168. /******************************Public*Routine******************************\
  169. * BOOL bIntersect
  170. *
  171. * If 'prcl1' and 'prcl2' intersect, has a return value of TRUE and returns
  172. * the intersection in 'prclResult'. If they don't intersect, has a return
  173. * value of FALSE, and 'prclResult' is undefined.
  174. *
  175. \**************************************************************************/
  176. BOOL bIntersect(
  177. RECTL* prcl1,
  178. RECTL* prcl2,
  179. RECTL* prclResult)
  180. {
  181. prclResult->left = max(prcl1->left, prcl2->left);
  182. prclResult->right = min(prcl1->right, prcl2->right);
  183. if (prclResult->left < prclResult->right)
  184. {
  185. prclResult->top = max(prcl1->top, prcl2->top);
  186. prclResult->bottom = min(prcl1->bottom, prcl2->bottom);
  187. if (prclResult->top < prclResult->bottom)
  188. {
  189. return(TRUE);
  190. }
  191. }
  192. return(FALSE);
  193. }
  194. /******************************Public*Routine******************************\
  195. * LONG cIntersect
  196. *
  197. * This routine takes a list of rectangles from 'prclIn' and clips them
  198. * in-place to the rectangle 'prclClip'. The input rectangles don't
  199. * have to intersect 'prclClip'; the return value will reflect the
  200. * number of input rectangles that did intersect, and the intersecting
  201. * rectangles will be densely packed.
  202. *
  203. \**************************************************************************/
  204. LONG cIntersect(
  205. RECTL* prclClip,
  206. RECTL* prclIn, // List of rectangles
  207. LONG c) // Can be zero
  208. {
  209. LONG cIntersections;
  210. RECTL* prclOut;
  211. cIntersections = 0;
  212. prclOut = prclIn;
  213. for (; c != 0; prclIn++, c--)
  214. {
  215. prclOut->left = max(prclIn->left, prclClip->left);
  216. prclOut->right = min(prclIn->right, prclClip->right);
  217. if (prclOut->left < prclOut->right)
  218. {
  219. prclOut->top = max(prclIn->top, prclClip->top);
  220. prclOut->bottom = min(prclIn->bottom, prclClip->bottom);
  221. if (prclOut->top < prclOut->bottom)
  222. {
  223. prclOut++;
  224. cIntersections++;
  225. }
  226. }
  227. }
  228. return(cIntersections);
  229. }
  230. /******************************Public*Routine******************************\
  231. * VOID vImageTransfer
  232. *
  233. * This routine transfers a bitmap image via the data transfer
  234. * area in video memory.
  235. *
  236. \**************************************************************************/
  237. VOID vImageTransfer( // Type FNIMAGETRANSFER
  238. PDEV* ppdev,
  239. BYTE* pjSrc, // Source pointer
  240. LONG lDelta, // Delta from start of scan to start of next
  241. LONG cjSrc, // Number of bytes to be output on every scan
  242. LONG cScans) // Number of scans
  243. {
  244. ULONG* pulXfer = ppdev->pulXfer;
  245. LONG cdSrc;
  246. LONG cjEnd;
  247. ULONG d;
  248. ASSERTDD(cScans > 0, "Can't handle non-positive count of scans");
  249. cdSrc = cjSrc >> 2;
  250. cjEnd = cdSrc << 2;
  251. switch (cjSrc & 3)
  252. {
  253. case 3:
  254. do {
  255. if (cdSrc > 0)
  256. {
  257. TRANSFER_DWORD(ppdev, pulXfer, pjSrc, cdSrc);
  258. }
  259. d = (ULONG) (*(pjSrc + cjEnd)) |
  260. (*(pjSrc + cjEnd + 1) << 8) |
  261. (*(pjSrc + cjEnd + 2) << 16);
  262. TRANSFER_DWORD(ppdev, pulXfer, &d, 1);
  263. pjSrc += lDelta;
  264. } while (--cScans != 0);
  265. break;
  266. case 2:
  267. do {
  268. if (cdSrc > 0)
  269. {
  270. TRANSFER_DWORD(ppdev, pulXfer, pjSrc, cdSrc);
  271. }
  272. d = (ULONG) (*(pjSrc + cjEnd)) |
  273. (*(pjSrc + cjEnd + 1) << 8);
  274. TRANSFER_DWORD(ppdev, pulXfer, &d, 1);
  275. pjSrc += lDelta;
  276. } while (--cScans != 0);
  277. break;
  278. case 1:
  279. do {
  280. if (cdSrc > 0)
  281. {
  282. TRANSFER_DWORD(ppdev, pulXfer, pjSrc, cdSrc);
  283. }
  284. d = (ULONG) (*(pjSrc + cjEnd));
  285. TRANSFER_DWORD(ppdev, pulXfer, &d, 1);
  286. pjSrc += lDelta;
  287. } while (--cScans != 0);
  288. break;
  289. case 0:
  290. do {
  291. TRANSFER_DWORD(ppdev, pulXfer, pjSrc, cdSrc);
  292. pjSrc += lDelta;
  293. } while (--cScans != 0);
  294. break;
  295. }
  296. }