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.

263 lines
8.4 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: Brush.c
  8. *
  9. * Content: Handles all brush/pattern initialization and realization.
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "precomp.h"
  15. #include "glint.h"
  16. /////////////////////////////////////////////////////////////////////////////
  17. //
  18. // bDeviceBrush[SurfaceBpp][PatternBpp]
  19. //
  20. // 0 1 2 3 4 5 6 7 8
  21. // 0 1BPP 4BPP 8BPP 16BPP 24BPP 32BPP 4RLE 8RLE (brush)
  22. //
  23. BOOL bDeviceBrush[BMF_8RLE + 1][BMF_8RLE + 1] =
  24. {
  25. {0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0
  26. {0, 1, 0, 0, 0, 0, 0, 0, 0 }, // 1bpp
  27. {0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4bpp
  28. {0, 1, 0, 1, 1, 0, 0, 0, 0 }, // 8bpp
  29. {0, 1, 0, 1, 1, 0, 0, 0, 0 }, // 16bpp
  30. {0, 1, 0, 0, 0, 0, 0, 0, 0 }, // 24bpp (screen)
  31. {0, 1, 0, 0, 0, 0, 0, 0, 0 }, // 32bpp
  32. {0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4RLE
  33. {0, 0, 0, 0, 0, 0, 0, 0, 0 } // 8RLE
  34. };
  35. /******************************Public*Routine******************************\
  36. * BOOL DrvRealizeBrush
  37. *
  38. * This function allows us to convert GDI brushes into an internal form
  39. * we can use. It is called by GDI when we've called BRUSHOBJ_pvGetRbrush
  40. * in some other function like DrvBitBlt, and GDI doesn't happen have a cached
  41. * realization lying around.
  42. *
  43. * Input:
  44. *
  45. * ppdev->bRealizeTransparent -- Hint for whether or not the brush should be
  46. * realized for transparency. If this hint is
  47. * wrong, there will be no error, but the brush
  48. * will have to be unnecessarily re-realized.
  49. *
  50. * Note: You should always set 'ppdev->bRealizeTransparent' before calling
  51. * BRUSHOBJ_pvGetRbrush!
  52. *
  53. \**************************************************************************/
  54. BOOL
  55. DrvRealizeBrush(
  56. BRUSHOBJ* pbo,
  57. SURFOBJ* psoDst,
  58. SURFOBJ* psoPattern,
  59. SURFOBJ* psoMask,
  60. XLATEOBJ* pxlo,
  61. ULONG iHatch)
  62. {
  63. static ULONG iBrushUniq = 0;
  64. PDEV* ppdev = (PDEV*) psoDst->dhpdev;
  65. ULONG iPatternFormat;
  66. BYTE* pjSrc;
  67. BYTE* pjDst;
  68. USHORT* pusDst;
  69. LONG lSrcDelta;
  70. LONG cj;
  71. LONG i;
  72. LONG j;
  73. RBRUSH* prb;
  74. ULONG* pulXlate;
  75. GLINT_DECL;
  76. DISPDBG((DBGLVL, "DrvRealizeBrush called for pbo 0x%08X", pbo));
  77. if( iHatch & RB_DITHERCOLOR )
  78. {
  79. // Let GDI to handle this brush.
  80. goto ReturnFalse;
  81. }
  82. iPatternFormat = psoPattern->iBitmapFormat;
  83. // We only accelerate 8x8 patterns. Since Win3.1 and Chicago don't
  84. // support patterns of any other size, it's a safe bet that 99.9%
  85. // of the patterns we'll ever get will be 8x8:
  86. if ((psoPattern->sizlBitmap.cx != 8) ||
  87. (psoPattern->sizlBitmap.cy != 8))
  88. {
  89. goto ReturnFalse;
  90. }
  91. if (bDeviceBrush[ppdev->iBitmapFormat][iPatternFormat])
  92. {
  93. prb = BRUSHOBJ_pvAllocRbrush(pbo,
  94. sizeof(RBRUSH) +
  95. (TOTAL_BRUSH_SIZE << ppdev->cPelSize));
  96. if( prb == NULL )
  97. {
  98. goto ReturnFalse;
  99. }
  100. // Initialize the fields we need:
  101. prb->ptlBrushOrg.x = LONG_MIN;
  102. prb->iUniq = ++iBrushUniq;
  103. prb->fl = 0;
  104. prb->apbe = NULL;
  105. lSrcDelta = psoPattern->lDelta;
  106. pjSrc = (BYTE*) psoPattern->pvScan0;
  107. pjDst = (BYTE*) &prb->aulPattern[0];
  108. if (ppdev->iBitmapFormat == iPatternFormat)
  109. {
  110. if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL))
  111. {
  112. DISPDBG((DBGLVL, "Realizing un-translated brush"));
  113. // The pattern is the same colour depth as the screen, and
  114. // there's no translation to be done:
  115. cj = (8 << ppdev->cPelSize); // Every pattern is 8 pels wide
  116. for (i = 8; i != 0; i--)
  117. {
  118. RtlCopyMemory(pjDst, pjSrc, cj);
  119. pjSrc += lSrcDelta;
  120. pjDst += cj;
  121. }
  122. }
  123. else if (ppdev->iBitmapFormat == BMF_8BPP)
  124. {
  125. DISPDBG((DBGLVL, "Realizing 8bpp translated brush"));
  126. // The screen is 8bpp, and there's translation to be done:
  127. pulXlate = pxlo->pulXlate;
  128. for (i = 8; i != 0; i--)
  129. {
  130. for (j = 8; j != 0; j--)
  131. {
  132. *pjDst++ = (BYTE) pulXlate[*pjSrc++];
  133. }
  134. pjSrc += lSrcDelta - 8;
  135. }
  136. }
  137. else
  138. {
  139. goto ReturnFalse;
  140. }
  141. }
  142. else if (iPatternFormat == BMF_1BPP)
  143. {
  144. DWORD Data;
  145. DISPDBG((DBGLVL, "Realizing 1bpp brush"));
  146. // We dword align the monochrome bitmap so that every row starts
  147. // on a new long (so that we can do long writes later to transfer
  148. // the bitmap to the area stipple unit).
  149. for (i = 8; i != 0; i--)
  150. {
  151. // Replicate the brush to 32 bits wide, as the TX cannot
  152. // span fill 8 bit wide brushes
  153. Data = (*pjSrc) & 0xff;
  154. Data |= Data << 8;
  155. Data |= Data << 16;
  156. *(DWORD *)pjDst = Data;
  157. // area stipple is loaded with DWORDS
  158. pjDst += sizeof(DWORD);
  159. pjSrc += lSrcDelta;
  160. }
  161. pulXlate = pxlo->pulXlate;
  162. prb->fl |= RBRUSH_2COLOR;
  163. prb->ulForeColor = pulXlate[1];
  164. prb->ulBackColor = pulXlate[0];
  165. }
  166. else if ((iPatternFormat == BMF_4BPP) &&
  167. (ppdev->iBitmapFormat == BMF_8BPP))
  168. {
  169. DISPDBG((DBGLVL, "Realizing 4bpp brush"));
  170. // The screen is 8bpp and the pattern is 4bpp:
  171. pulXlate = pxlo->pulXlate;
  172. for (i = 8; i != 0; i--)
  173. {
  174. // Inner loop is repeated only 4 times because each iteration
  175. // handles 2 pixels:
  176. for (j = 4; j != 0; j--)
  177. {
  178. *pjDst++ = (BYTE) pulXlate[*pjSrc >> 4];
  179. *pjDst++ = (BYTE) pulXlate[*pjSrc & 15];
  180. pjSrc++;
  181. }
  182. pjSrc += lSrcDelta - 4;
  183. }
  184. }
  185. else if ((iPatternFormat == BMF_8BPP) &&
  186. (ppdev->iBitmapFormat == BMF_16BPP))
  187. {
  188. DISPDBG((DBGLVL, "Realizing 8bpp translated brush"));
  189. // The screen is 16bpp, and there's translation to be done:
  190. pulXlate = pxlo->pulXlate;
  191. for (i = 8; i != 0; i--)
  192. {
  193. for (j = 8; j != 0; j--)
  194. {
  195. *((USHORT *) pjDst) = (USHORT)pulXlate[*pjSrc++];
  196. pjDst += 2;
  197. }
  198. pjSrc += lSrcDelta - 8;
  199. }
  200. }
  201. else
  202. {
  203. goto ReturnFalse;
  204. }
  205. DISPDBG((DBGLVL, "DrvRealizeBrush returning true"));
  206. return TRUE;
  207. }
  208. ReturnFalse:
  209. if (psoPattern != NULL)
  210. {
  211. DISPDBG((WRNLVL, "Failed realization -- "
  212. "Type: %li Format: %li cx: %li cy: %li",
  213. psoPattern->iType,
  214. psoPattern->iBitmapFormat,
  215. psoPattern->sizlBitmap.cx,
  216. psoPattern->sizlBitmap.cy));
  217. }
  218. DISPDBG((DBGLVL, "DrvRealizeBrush returning false"));
  219. return FALSE;
  220. }