Sync to trunk head (r42241)
[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 = (RECTL){0, 0, psoPattern->sizlBitmap.cx, psoPattern->sizlBitmap.cy};
160 EngCopyBits(psoRealize, psoPattern, NULL, pxlo, &rclDest, &ptlSrc);
161
162 /* Unlock the bitmap again */
163 EngUnlockSurface(psoRealize);
164
165 pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
166 pebo->pengbrush = (PVOID)hbmpRealize;
167
168 return TRUE;
169 }
170
171 BOOL
172 NTAPI
173 EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
174 {
175 BOOL bResult;
176 PFN_DrvRealizeBrush pfnRealzizeBrush = NULL;
177 PSURFACE psurfTrg, psurfPattern, psurfMask;
178 PPDEVOBJ ppdev = NULL;
179 XLATEOBJ *pxlo;
180
181 psurfTrg = pebo->psurfTrg; // FIXME: all EBRUSHOBJs need a surface
182 if (!psurfTrg)
183 {
184 DPRINT1("Pattern brush has no target surface!\n");
185 return FALSE;
186 }
187
188 ppdev = (PPDEVOBJ)psurfTrg->SurfObj.hdev; // FIXME: all SURFACEs need a PDEV
189 if (ppdev && bCallDriver)
190 pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush;
191 if (!pfnRealzizeBrush)
192 {
193 pfnRealzizeBrush = EngRealizeBrush;
194 }
195
196 psurfPattern = SURFACE_LockSurface(pebo->pbrush->hbmPattern);
197 if (!psurfPattern)
198 {
199 DPRINT1("No pattern, nothing to realize!\n");
200 return FALSE;
201 }
202
203 /* FIXME: implement mask */
204 psurfMask = NULL;
205
206 /* Create xlateobj for the brush */
207 pxlo = IntCreateBrushXlate(pebo->pbrush, psurfTrg, pebo->crCurrentBack);
208
209 /* Perform the realization */
210 bResult = pfnRealzizeBrush(&pebo->BrushObject,
211 &pebo->psurfTrg->SurfObj,
212 &psurfPattern->SurfObj,
213 psurfMask ? &psurfMask->SurfObj : NULL,
214 pxlo,
215 -1); // FIXME: what about hatch brushes?
216
217 EngDeleteXlate(pxlo);
218
219 if (psurfPattern)
220 SURFACE_UnlockSurface(psurfPattern);
221
222 if (psurfMask)
223 SURFACE_UnlockSurface(psurfMask);
224
225 return bResult;
226 }
227
228 PVOID
229 NTAPI
230 EBRUSHOBJ_pvGetEngBrush(EBRUSHOBJ *pebo)
231 {
232 BOOL bResult;
233
234 if (!pebo->pengbrush)
235 {
236 bResult = EBRUSHOBJ_bRealizeBrush(pebo, FALSE);
237 if (!bResult)
238 {
239 if (pebo->pengbrush)
240 EngDeleteSurface(pebo->pengbrush);
241 pebo->pengbrush = NULL;
242 }
243 }
244
245 return pebo->pengbrush;
246 }
247
248
249 /** Exported DDI functions ****************************************************/
250
251 /*
252 * @implemented
253 */
254 PVOID APIENTRY
255 BRUSHOBJ_pvAllocRbrush(
256 IN BRUSHOBJ *pbo,
257 IN ULONG cj)
258 {
259 pbo->pvRbrush = EngAllocMem(0, cj, 'rbdG');
260 return pbo->pvRbrush;
261 }
262
263 /*
264 * @implemented
265 */
266 PVOID APIENTRY
267 BRUSHOBJ_pvGetRbrush(
268 IN BRUSHOBJ *pbo)
269 {
270 EBRUSHOBJ *pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
271 BOOL bResult;
272
273 if (!pbo->pvRbrush)
274 {
275 bResult = EBRUSHOBJ_bRealizeBrush(pebo, TRUE);
276 if (!bResult)
277 {
278 if (pbo->pvRbrush)
279 {
280 EngFreeMem(pbo->pvRbrush);
281 pbo->pvRbrush = NULL;
282 }
283 }
284 }
285
286 return pbo->pvRbrush;
287 }
288
289 /*
290 * @implemented
291 */
292 ULONG APIENTRY
293 BRUSHOBJ_ulGetBrushColor(
294 IN BRUSHOBJ *pbo)
295 {
296 EBRUSHOBJ *pebo = CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject);
297 return pebo->ulRGBColor;
298 }
299
300 /* EOF */