[GDI32]
[reactos.git] / reactos / win32ss / gdi / gdi32 / objects / brush.c
1 #include <precomp.h>
2
3 #define NDEBUG
4 #include <debug.h>
5
6
7
8 /*
9 * @implemented
10 */
11 HPEN
12 APIENTRY
13 ExtCreatePen(DWORD dwPenStyle,
14 DWORD dwWidth,
15 CONST LOGBRUSH *lplb,
16 DWORD dwStyleCount,
17 CONST DWORD *lpStyle)
18 {
19 PVOID lpPackedDIB = NULL;
20 HPEN hPen = NULL;
21 PBITMAPINFO pConvertedInfo = NULL;
22 UINT ConvertedInfoSize = 0, lbStyle;
23 BOOL Hit = FALSE;
24
25 if ((dwPenStyle & PS_STYLE_MASK) == PS_USERSTYLE)
26 {
27 if(!lpStyle)
28 {
29 SetLastError(ERROR_INVALID_PARAMETER);
30 return 0;
31 }
32 } // This is an enhancement and prevents a call to kernel space.
33 else if ((dwPenStyle & PS_STYLE_MASK) == PS_INSIDEFRAME &&
34 (dwPenStyle & PS_TYPE_MASK) != PS_GEOMETRIC)
35 {
36 SetLastError(ERROR_INVALID_PARAMETER);
37 return 0;
38 }
39 else if ((dwPenStyle & PS_STYLE_MASK) == PS_ALTERNATE &&
40 (dwPenStyle & PS_TYPE_MASK) != PS_COSMETIC)
41 {
42 SetLastError(ERROR_INVALID_PARAMETER);
43 return 0;
44 }
45 else
46 {
47 if (dwStyleCount || lpStyle)
48 {
49 SetLastError(ERROR_INVALID_PARAMETER);
50 return 0;
51 }
52 }
53
54 lbStyle = lplb->lbStyle;
55
56 if (lplb->lbStyle > BS_HATCHED)
57 {
58 if (lplb->lbStyle == BS_PATTERN)
59 {
60 pConvertedInfo = (PBITMAPINFO)lplb->lbHatch;
61 if (!pConvertedInfo) return 0;
62 }
63 else
64 {
65 if ((lplb->lbStyle == BS_DIBPATTERN) || (lplb->lbStyle == BS_DIBPATTERNPT))
66 {
67 if (lplb->lbStyle == BS_DIBPATTERN)
68 {
69 lbStyle = BS_DIBPATTERNPT;
70 lpPackedDIB = GlobalLock((HGLOBAL)lplb->lbHatch);
71 if (lpPackedDIB == NULL) return 0;
72 }
73 pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB,
74 lplb->lbColor,
75 &ConvertedInfoSize,
76 TRUE);
77 Hit = TRUE; // We converted DIB.
78 }
79 else
80 pConvertedInfo = (PBITMAPINFO)lpStyle;
81 }
82 }
83 else
84 pConvertedInfo = (PBITMAPINFO)lplb->lbHatch;
85
86
87 hPen = NtGdiExtCreatePen(dwPenStyle,
88 dwWidth,
89 lbStyle,
90 lplb->lbColor,
91 lplb->lbHatch,
92 (ULONG_PTR)pConvertedInfo,
93 dwStyleCount,
94 (PULONG)lpStyle,
95 ConvertedInfoSize,
96 FALSE,
97 NULL);
98
99
100 if (lplb->lbStyle == BS_DIBPATTERN) GlobalUnlock((HGLOBAL)lplb->lbHatch);
101
102 if (Hit)
103 {
104 if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)
105 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
106 }
107 return hPen;
108 }
109
110 /*
111 * @implemented
112 */
113 HBRUSH WINAPI
114 CreateDIBPatternBrush(
115 HGLOBAL hglbDIBPacked,
116 UINT fuColorSpec)
117 {
118 PVOID lpPackedDIB;
119 HBRUSH hBrush = NULL;
120 PBITMAPINFO pConvertedInfo;
121 UINT ConvertedInfoSize;
122
123 lpPackedDIB = GlobalLock(hglbDIBPacked);
124 if (lpPackedDIB == NULL)
125 return 0;
126
127 pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, fuColorSpec,
128 &ConvertedInfoSize, TRUE);
129 if (pConvertedInfo)
130 {
131 hBrush = NtGdiCreateDIBBrush(pConvertedInfo, fuColorSpec,
132 ConvertedInfoSize, FALSE, FALSE, lpPackedDIB);
133 if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)
134 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
135 }
136
137 GlobalUnlock(hglbDIBPacked);
138
139 return hBrush;
140 }
141
142 /*
143 * @implemented
144 */
145 HBRUSH WINAPI
146 CreateDIBPatternBrushPt(
147 CONST VOID *lpPackedDIB,
148 UINT fuColorSpec)
149 {
150 HBRUSH hBrush = NULL;
151 PBITMAPINFO pConvertedInfo;
152 UINT ConvertedInfoSize;
153
154 if (lpPackedDIB == NULL)
155 return 0;
156
157 pConvertedInfo = ConvertBitmapInfo((PBITMAPINFO)lpPackedDIB, fuColorSpec,
158 &ConvertedInfoSize, TRUE);
159 if (pConvertedInfo)
160 {
161 hBrush = NtGdiCreateDIBBrush(pConvertedInfo, fuColorSpec,
162 ConvertedInfoSize, FALSE, FALSE, (PVOID)lpPackedDIB);
163 if ((PBITMAPINFO)lpPackedDIB != pConvertedInfo)
164 RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
165 }
166
167 return hBrush;
168 }
169
170 /*
171 * @implemented
172 */
173 HBRUSH
174 WINAPI
175 CreateHatchBrush(INT fnStyle,
176 COLORREF clrref)
177 {
178 return NtGdiCreateHatchBrushInternal(fnStyle, clrref, FALSE);
179 }
180
181 /*
182 * @implemented
183 */
184 HBRUSH
185 WINAPI
186 CreatePatternBrush(HBITMAP hbmp)
187 {
188 return NtGdiCreatePatternBrushInternal(hbmp, FALSE, FALSE);
189 }
190
191 /*
192 * @implemented
193 */
194 HBRUSH
195 WINAPI
196 CreateSolidBrush(IN COLORREF crColor)
197 {
198 /* Call Server-Side API */
199 return NtGdiCreateSolidBrush(crColor, NULL);
200 }
201
202 /*
203 * @implemented
204 */
205 HBRUSH WINAPI
206 CreateBrushIndirect(
207 CONST LOGBRUSH *LogBrush)
208 {
209 HBRUSH hBrush;
210
211 switch (LogBrush->lbStyle)
212 {
213 case BS_DIBPATTERN8X8:
214 case BS_DIBPATTERN:
215 hBrush = CreateDIBPatternBrush((HGLOBAL)LogBrush->lbHatch,
216 LogBrush->lbColor);
217 break;
218
219 case BS_DIBPATTERNPT:
220 hBrush = CreateDIBPatternBrushPt((PVOID)LogBrush->lbHatch,
221 LogBrush->lbColor);
222 break;
223
224 case BS_PATTERN:
225 hBrush = NtGdiCreatePatternBrushInternal((HBITMAP)LogBrush->lbHatch,
226 FALSE,
227 FALSE);
228 break;
229
230 case BS_PATTERN8X8:
231 hBrush = NtGdiCreatePatternBrushInternal((HBITMAP)LogBrush->lbHatch,
232 FALSE,
233 TRUE);
234 break;
235
236 case BS_SOLID:
237 /* hBrush = hGetPEBHandle(hctBrushHandle, LogBrush->lbColor);
238 if (!hBrush)*/
239 hBrush = NtGdiCreateSolidBrush(LogBrush->lbColor, 0);
240 break;
241
242 case BS_HATCHED:
243 hBrush = NtGdiCreateHatchBrushInternal(LogBrush->lbHatch,
244 LogBrush->lbColor,
245 FALSE);
246 break;
247
248 case BS_NULL:
249 hBrush = NtGdiGetStockObject(NULL_BRUSH);
250 break;
251
252 default:
253 SetLastError(ERROR_INVALID_PARAMETER);
254 hBrush = NULL;
255 break;
256 }
257
258 return hBrush;
259 }
260
261 BOOL
262 WINAPI
263 PatBlt(HDC hdc,
264 int nXLeft,
265 int nYLeft,
266 int nWidth,
267 int nHeight,
268 DWORD dwRop)
269 {
270 /* FIXME some part need be done in user mode */
271 return NtGdiPatBlt( hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop);
272 }
273
274 BOOL
275 WINAPI
276 PolyPatBlt(IN HDC hdc,
277 IN DWORD rop4,
278 IN PPOLYPATBLT pPoly,
279 IN DWORD Count,
280 IN DWORD Mode)
281 {
282 /* FIXME some part need be done in user mode */
283 return NtGdiPolyPatBlt(hdc, rop4, pPoly,Count,Mode);
284 }
285
286 /*
287 * @implemented
288 *
289 */
290 int
291 WINAPI
292 GetROP2(HDC hdc)
293 {
294 PDC_ATTR Dc_Attr;
295 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
296 return Dc_Attr->jROP2;
297 }
298
299 /*
300 * @implemented
301 */
302 int
303 WINAPI
304 SetROP2(HDC hdc,
305 int fnDrawMode)
306 {
307 PDC_ATTR Dc_Attr;
308 INT Old_ROP2;
309
310 #if 0
311 // Handle something other than a normal dc object.
312 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
313 {
314 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
315 return MFDRV_SetROP2( hdc, fnDrawMode);
316 else
317 {
318 PLDC pLDC = GdiGetLDC(hdc);
319 if ( !pLDC )
320 {
321 SetLastError(ERROR_INVALID_HANDLE);
322 return FALSE;
323 }
324 if (pLDC->iType == LDC_EMFLDC)
325 {
326 return EMFDRV_SetROP2(( hdc, fnDrawMode);
327 }
328 return FALSE;
329 }
330 }
331 #endif
332 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
333
334 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
335 {
336 if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
337 {
338 NtGdiFlush();
339 Dc_Attr->ulDirty_ &= ~DC_MODE_DIRTY;
340 }
341 }
342
343 Old_ROP2 = Dc_Attr->jROP2;
344 Dc_Attr->jROP2 = fnDrawMode;
345
346 return Old_ROP2;
347 }
348
349 /*
350 * @implemented
351 *
352 */
353 BOOL
354 WINAPI
355 GetBrushOrgEx(HDC hdc,LPPOINT pt)
356 {
357 PDC_ATTR Dc_Attr;
358
359 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
360 if (pt)
361 {
362 pt->x = Dc_Attr->ptlBrushOrigin.x;
363 pt->y = Dc_Attr->ptlBrushOrigin.y;
364 }
365 return TRUE;
366 }
367
368 /*
369 * @implemented
370 */
371 BOOL
372 WINAPI
373 SetBrushOrgEx(HDC hdc,
374 int nXOrg,
375 int nYOrg,
376 LPPOINT lppt)
377 {
378 PDC_ATTR Dc_Attr;
379 #if 0
380 // Handle something other than a normal dc object.
381 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
382 {
383 PLDC pLDC = GdiGetLDC(hdc);
384 if ( (pLDC == NULL) || (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC))
385 {
386 SetLastError(ERROR_INVALID_HANDLE);
387 return FALSE;
388 }
389 if (pLDC->iType == LDC_EMFLDC)
390 {
391 return EMFDRV_SetBrushOrg(hdc, nXOrg, nYOrg); // ReactOS only.
392 }
393 return FALSE;
394 }
395 #endif
396 if (GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID)&Dc_Attr))
397 {
398 PGDIBSSETBRHORG pgSBO;
399
400 /* Does the caller want the current brush origin to be returned? */
401 if (lppt)
402 {
403 lppt->x = Dc_Attr->ptlBrushOrigin.x;
404 lppt->y = Dc_Attr->ptlBrushOrigin.y;
405 }
406
407 /* Check if we have nothing to do */
408 if ((nXOrg == Dc_Attr->ptlBrushOrigin.x) &&
409 (nYOrg == Dc_Attr->ptlBrushOrigin.y))
410 return TRUE;
411
412 /* Allocate a batch command buffer */
413 pgSBO = GdiAllocBatchCommand(hdc, GdiBCSetBrushOrg);
414 if (pgSBO != NULL)
415 {
416 /* Set current brush origin in the DC attribute */
417 Dc_Attr->ptlBrushOrigin.x = nXOrg;
418 Dc_Attr->ptlBrushOrigin.y = nYOrg;
419
420 /* Setup the GDI batch command */
421 pgSBO->ptlBrushOrigin = Dc_Attr->ptlBrushOrigin;
422
423 return TRUE;
424 }
425 }
426
427 /* Fall back to the slower kernel path */
428 return NtGdiSetBrushOrg(hdc, nXOrg, nYOrg, lppt);
429 }