[CMAKE]
[reactos.git] / dll / win32 / 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 = NtGdiCreateSolidBrush(LogBrush->lbColor, 0);
238 break;
239
240 case BS_HATCHED:
241 hBrush = NtGdiCreateHatchBrushInternal(LogBrush->lbHatch,
242 LogBrush->lbColor,
243 FALSE);
244 break;
245
246 case BS_NULL:
247 hBrush = NtGdiGetStockObject(NULL_BRUSH);
248 break;
249
250 default:
251 SetLastError(ERROR_INVALID_PARAMETER);
252 hBrush = NULL;
253 break;
254 }
255
256 return hBrush;
257 }
258
259 BOOL
260 WINAPI
261 PatBlt(HDC hdc,
262 int nXLeft,
263 int nYLeft,
264 int nWidth,
265 int nHeight,
266 DWORD dwRop)
267 {
268 /* FIXME some part need be done in user mode */
269 return NtGdiPatBlt( hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop);
270 }
271
272 BOOL
273 WINAPI
274 PolyPatBlt(IN HDC hdc,
275 IN DWORD rop4,
276 IN PPOLYPATBLT pPoly,
277 IN DWORD Count,
278 IN DWORD Mode)
279 {
280 /* FIXME some part need be done in user mode */
281 return NtGdiPolyPatBlt(hdc, rop4, pPoly,Count,Mode);
282 }
283
284 /*
285 * @implemented
286 *
287 */
288 int
289 WINAPI
290 GetROP2(HDC hdc)
291 {
292 PDC_ATTR Dc_Attr;
293 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
294 return Dc_Attr->jROP2;
295 }
296
297 /*
298 * @implemented
299 */
300 int
301 WINAPI
302 SetROP2(HDC hdc,
303 int fnDrawMode)
304 {
305 PDC_ATTR Dc_Attr;
306 INT Old_ROP2;
307
308 #if 0
309 // Handle something other than a normal dc object.
310 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
311 {
312 if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
313 return MFDRV_SetROP2( hdc, fnDrawMode);
314 else
315 {
316 PLDC pLDC = GdiGetLDC(hdc);
317 if ( !pLDC )
318 {
319 SetLastError(ERROR_INVALID_HANDLE);
320 return FALSE;
321 }
322 if (pLDC->iType == LDC_EMFLDC)
323 {
324 return EMFDRV_SetROP2(( hdc, fnDrawMode);
325 }
326 return FALSE;
327 }
328 }
329 #endif
330 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
331
332 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
333 {
334 if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
335 {
336 NtGdiFlush();
337 Dc_Attr->ulDirty_ &= ~DC_MODE_DIRTY;
338 }
339 }
340
341 Old_ROP2 = Dc_Attr->jROP2;
342 Dc_Attr->jROP2 = fnDrawMode;
343
344 return Old_ROP2;
345 }
346
347 /*
348 * @implemented
349 *
350 */
351 BOOL
352 WINAPI
353 GetBrushOrgEx(HDC hdc,LPPOINT pt)
354 {
355 PDC_ATTR Dc_Attr;
356
357 if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
358 if (pt)
359 {
360 pt->x = Dc_Attr->ptlBrushOrigin.x;
361 pt->y = Dc_Attr->ptlBrushOrigin.y;
362 }
363 return TRUE;
364 }
365
366 /*
367 * @implemented
368 */
369 BOOL
370 WINAPI
371 SetBrushOrgEx(HDC hdc,
372 int nXOrg,
373 int nYOrg,
374 LPPOINT lppt)
375 {
376 PDC_ATTR Dc_Attr;
377 #if 0
378 // Handle something other than a normal dc object.
379 if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
380 {
381 PLDC pLDC = GdiGetLDC(hdc);
382 if ( (pLDC == NULL) || (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC))
383 {
384 SetLastError(ERROR_INVALID_HANDLE);
385 return FALSE;
386 }
387 if (pLDC->iType == LDC_EMFLDC)
388 {
389 return EMFDRV_SetBrushOrg(hdc, nXOrg, nYOrg); // ReactOS only.
390 }
391 return FALSE;
392 }
393 #endif
394 if (GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
395 {
396 PTEB pTeb = NtCurrentTeb();
397 if (lppt)
398 {
399 lppt->x = Dc_Attr->ptlBrushOrigin.x;
400 lppt->y = Dc_Attr->ptlBrushOrigin.y;
401 }
402 if ((nXOrg == Dc_Attr->ptlBrushOrigin.x) && (nYOrg == Dc_Attr->ptlBrushOrigin.y))
403 return TRUE;
404
405 if(((pTeb->GdiTebBatch.HDC == NULL) || (pTeb->GdiTebBatch.HDC == hdc)) &&
406 ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSSETBRHORG)) <= GDIBATCHBUFSIZE) &&
407 (!(Dc_Attr->ulDirty_ & DC_DIBSECTION)) )
408 {
409 PGDIBSSETBRHORG pgSBO = (PGDIBSSETBRHORG)(&pTeb->GdiTebBatch.Buffer[0] +
410 pTeb->GdiTebBatch.Offset);
411
412 Dc_Attr->ptlBrushOrigin.x = nXOrg;
413 Dc_Attr->ptlBrushOrigin.y = nYOrg;
414
415 pgSBO->gbHdr.Cmd = GdiBCSetBrushOrg;
416 pgSBO->gbHdr.Size = sizeof(GDIBSSETBRHORG);
417 pgSBO->ptlBrushOrigin = Dc_Attr->ptlBrushOrigin;
418
419 pTeb->GdiTebBatch.Offset += sizeof(GDIBSSETBRHORG);
420 pTeb->GdiTebBatch.HDC = hdc;
421 pTeb->GdiBatchCount++;
422 DPRINT("Loading the Flush!! COUNT-> %d\n", pTeb->GdiBatchCount);
423
424 if (pTeb->GdiBatchCount >= GDI_BatchLimit)
425 {
426 DPRINT("Call GdiFlush!!\n");
427 NtGdiFlush();
428 DPRINT("Exit GdiFlush!!\n");
429 }
430 return TRUE;
431 }
432 }
433 return NtGdiSetBrushOrg(hdc,nXOrg,nYOrg,lppt);
434 }