- delayimp.h: Use FORCEINLINE instead of static __inline__
[reactos.git] / reactos / subsystems / win32 / win32k / eng / engbrush.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: GDI Driver Brush Functions
5 * FILE: subsystem/win32/win32k/eng/engbrush.c
6 * PROGRAMER: Jason Filby
7 * Timo Kreuzer
8 */
9
10 #include <w32k.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /** Internal functions ********************************************************/
16
17 VOID
18 NTAPI
19 EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
20 {
21 ULONG iSolidColor;
22 XLATEOBJ *pxlo;
23 PSURFACE psurfTrg;
24
25 ASSERT(pebo);
26 ASSERT(pbrush);
27 ASSERT(pdc);
28
29 psurfTrg = pdc->dclevel.pSurface;
30
31 pebo->psurfTrg = psurfTrg;
32 pebo->BrushObject.flColorType = 0;
33 pebo->pbrush = pbrush;
34 pebo->flattrs = pbrush->flAttrs;
35 pebo->crCurrentText = pdc->pdcattr->crForegroundClr;
36 pebo->crCurrentBack = pdc->pdcattr->crBackgroundClr;
37 pebo->BrushObject.pvRbrush = NULL;
38 pebo->pengbrush = NULL;
39
40 if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
41 {
42 pebo->BrushObject.iSolidColor = 0;
43 }
44 else if (pbrush->flAttrs & GDIBRUSH_IS_SOLID)
45 {
46 /* Set the RGB color */
47 pebo->crRealize = pbrush->BrushAttr.lbColor;
48 pebo->ulRGBColor = pbrush->BrushAttr.lbColor;
49
50 /* Translate the brush color to the target format */
51 pxlo = IntCreateBrushXlate(pbrush, psurfTrg, pebo->crCurrentBack);
52 iSolidColor = XLATEOBJ_iXlate(pxlo, pbrush->BrushAttr.lbColor);
53 pebo->BrushObject.iSolidColor = iSolidColor;
54 if (pxlo)
55 EngDeleteXlate(pxlo);
56 }
57 else
58 {
59 /* This is a pattern brush that needs realization */
60 pebo->BrushObject.iSolidColor = 0xFFFFFFFF;
61 }
62 }
63
64 VOID
65 FASTCALL
66 EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor, XLATEOBJ *pxlo)
67 {
68 ULONG iSolidColor;
69
70 /* Never use with non-solid brushes */
71 ASSERT(pebo->flattrs & GDIBRUSH_IS_SOLID);
72
73 /* Set the RGB color */
74 pebo->crRealize = crColor;
75 pebo->ulRGBColor = crColor;
76
77 /* Translate the brush color to the target format */
78 iSolidColor = XLATEOBJ_iXlate(pxlo, crColor);
79 pebo->BrushObject.iSolidColor = iSolidColor;
80
81 pebo->BrushObject.iSolidColor = iSolidColor;
82 }
83
84 VOID
85 NTAPI
86 EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
87 {
88 /* Check if there's a GDI realisation */
89 if (pebo->pengbrush)
90 {
91 EngDeleteSurface(pebo->pengbrush);
92 pebo->pengbrush = NULL;
93 }
94
95 /* Check if there's a driver's realisation */
96 if (pebo->BrushObject.pvRbrush)
97 {
98 /* Free allocated driver memory */
99 EngFreeMem(pebo->BrushObject.pvRbrush);
100 pebo->BrushObject.pvRbrush = NULL;
101 }
102 }
103
104 VOID
105 NTAPI
106 EBRUSHOBJ_vUpdate(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
107 {
108 /* Cleanup the brush */
109 EBRUSHOBJ_vCleanup(pebo);
110
111 /* Reinitialize */
112 EBRUSHOBJ_vInit(pebo, pbrush, pdc);
113 }
114
115 /**
116 * This function is not exported, because it makes no sense for
117 * The driver to punt back to this function */
118 BOOL
119 APIENTRY
120 EngRealizeBrush(
121 BRUSHOBJ *pbo,
122 SURFOBJ *psoDst,
123 SURFOBJ *psoPattern,
124 SURFOBJ *psoMask,
125 XLATEOBJ *pxlo,
126 ULONG iHatch)
127 {
128 EBRUSHOBJ *pebo;
129 HBITMAP hbmpRealize;
130 SURFOBJ *psoRealize;
131 POINTL ptlSrc = {0, 0};
132 RECTL rclDest;
133 ULONG lWidth;
134
135 /* Calculate width in bytes of the realized brush */
136 lWidth = DIB_GetDIBWidthBytes(psoPattern->sizlBitmap.cx,
137 BitsPerFormat(psoDst->iBitmapFormat));
138
139 /* Allocate a bitmap */
140 hbmpRealize = EngCreateBitmap(psoPattern->sizlBitmap,
141 lWidth,
142 psoDst->iBitmapFormat,
143 BMF_NOZEROINIT,
144 NULL);
145 if (!hbmpRealize)
146 {
147 return FALSE;
148 }
149
150 /* Lock the bitmap */
151 psoRealize = EngLockSurface(hbmpRealize);
152 if (!psoRealize)
153 {
154 EngDeleteSurface(hbmpRealize);
155 return FALSE;
156 }
157
158 /* Copy the bits to the new format bitmap */
159 rclDest.left = rclDest.top = 0;
160 rclDest.right = psoPattern->sizlBitmap.cx;
161 rclDest.bottom = psoPattern->sizlBitmap.cy;
162 EngCopyBits(psoRealize, psoPattern, NULL, pxlo, &rclDest, &ptlSrc);
163
164 /* Unlock the bitmap again */
165 EngUnlockSurface(psoRealize);
166
167 pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
168 pebo->pengbrush = (PVOID)hbmpRealize;
169
170 return TRUE;
171 }
172
173 BOOL
174 NTAPI
175 EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
176 {
177 BOOL bResult;
178 PFN_DrvRealizeBrush pfnRealzizeBrush = NULL;
179 PSURFACE psurfTrg, psurfPattern, psurfMask;
180 PPDEVOBJ ppdev = NULL;
181 XLATEOBJ *pxlo;
182
183 psurfTrg = pebo->psurfTrg; // FIXME: all EBRUSHOBJs need a surface
184 if (!psurfTrg)
185 {
186 DPRINT1("Pattern brush has no target surface!\n");
187 return FALSE;
188 }
189
190 ppdev = (PPDEVOBJ)psurfTrg->SurfObj.hdev; // FIXME: all SURFACEs need a PDEV
191 if (ppdev && bCallDriver)
192 pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush;
193 if (!pfnRealzizeBrush)
194 {
195 pfnRealzizeBrush = EngRealizeBrush;
196 }
197
198 psurfPattern = SURFACE_LockSurface(pebo->pbrush->hbmPattern);
199 if (!psurfPattern)
200 {
201 DPRINT1("No pattern, nothing to realize!\n");
202 return FALSE;
203 }
204
205 /* FIXME: implement mask */
206 psurfMask = NULL;
207
208 /* Create xlateobj for the brush */
209 pxlo = IntCreateBrushXlate(pebo->pbrush, psurfTrg, pebo->crCurrentBack);
210
211 /* Perform the realization */
212 bResult = pfnRealzizeBrush(&pebo->BrushObject,
213 &pebo->psurfTrg->SurfObj,
214 &psurfPattern->SurfObj,
215 psurfMask ? &psurfMask->SurfObj : NULL,
216 pxlo,
217 -1); // FIXME: what about hatch brushes?
218
219 EngDeleteXlate(pxlo);
220
221 if (psurfPattern)
222 SURFACE_UnlockSurface(psurfPattern);
223
224 if (psurfMask)
225 SURFACE_UnlockSurface(psurfMask);
226
227 return bResult;
228 }
229
230 PVOID
231 NTAPI
232 EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo)
233 {
234 BOOL bResult;
235
236 if (!pebo->pengbrush)
237 {
238 bResult = EBRUSHOBJ_bRealizeBrush(pebo, FALSE);
239 if (!bResult)
240 {
241 if (pebo->pengbrush)
242 EngDeleteSurface(pebo->pengbrush);
243 pebo->pengbrush = NULL;
244 }
245 }
246
247 return pebo->pengbrush;
248 }
249
250
251 /** Exported DDI functions ****************************************************/
252
253 /*
254 * @implemented
255 */
256 PVOID APIENTRY
257 BRUSHOBJ_pvAllocRbrush(
258 IN BRUSHOBJ *pbo,
259 IN ULONG cj)
260 {
261 pbo->pvRbrush = EngAllocMem(0, cj, 'rbdG');
262 return pbo->pvRbrush;
263 }
264
265 /*
266 * @implemented
267 */
268 PVOID APIENTRY
269 BRUSHOBJ_pvGetRbrush(
270 IN BRUSHOBJ *pbo)
271 {
272 EBRUSHOBJ *pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
273 BOOL bResult;
274
275 if (!pbo->pvRbrush)
276 {
277 bResult = EBRUSHOBJ_bRealizeBrush(pebo, TRUE);
278 if (!bResult)
279 {
280 if (pbo->pvRbrush)
281 {
282 EngFreeMem(pbo->pvRbrush);
283 pbo->pvRbrush = NULL;
284 }
285 }
286 }
287
288 return pbo->pvRbrush;
289 }
290
291 /*
292 * @implemented
293 */
294 ULONG APIENTRY
295 BRUSHOBJ_ulGetBrushColor(
296 IN BRUSHOBJ *pbo)
297 {
298 EBRUSHOBJ *pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
299 return pebo->ulRGBColor;
300 }
301
302 /* EOF */