xref: /reactos/win32ss/gdi/gdi32/objects/painting.c (revision a6726659)
1 #include <precomp.h>
2 
3 
4 /*
5  * @implemented
6  */
7 BOOL
8 WINAPI
9 LineTo(
10     _In_ HDC hdc,
11     _In_ INT x,
12     _In_ INT y )
13 {
14     HANDLE_METADC(BOOL, LineTo, FALSE, hdc, x, y);
15 
16     return NtGdiLineTo(hdc, x, y);
17 }
18 
19 
20 BOOL
21 WINAPI
22 MoveToEx(
23     _In_ HDC hdc,
24     _In_ INT x,
25     _In_ INT y,
26     _Out_opt_ LPPOINT ppt)
27 {
28     PDC_ATTR pdcattr;
29 
30     HANDLE_METADC(BOOL, MoveTo, FALSE, hdc, x, y, ppt);
31 
32     /* Get the DC attribute */
33     pdcattr = GdiGetDcAttr(hdc);
34     if (pdcattr == NULL)
35     {
36         SetLastError(ERROR_INVALID_PARAMETER);
37         return FALSE;
38     }
39 
40     if (ppt)
41     {
42         if ( pdcattr->ulDirty_ & DIRTY_PTLCURRENT ) // Double hit!
43         {
44             ppt->x = pdcattr->ptfxCurrent.x; // ret prev before change.
45             ppt->y = pdcattr->ptfxCurrent.y;
46             DPtoLP (hdc, ppt, 1);          // reconvert back.
47         }
48         else
49         {
50             ppt->x = pdcattr->ptlCurrent.x;
51             ppt->y = pdcattr->ptlCurrent.y;
52         }
53     }
54 
55     pdcattr->ptlCurrent.x = x;
56     pdcattr->ptlCurrent.y = y;
57 
58     pdcattr->ulDirty_ &= ~DIRTY_PTLCURRENT;
59     pdcattr->ulDirty_ |= ( DIRTY_PTFXCURRENT|DIRTY_STYLESTATE); // Set dirty
60     return TRUE;
61 }
62 
63 
64 /*
65  * @implemented
66  */
67 BOOL
68 WINAPI
69 Ellipse(
70     _In_ HDC hdc,
71     _In_ INT left,
72     _In_ INT top,
73     _In_ INT right,
74     _In_ INT bottom)
75 {
76     HANDLE_METADC(BOOL, Ellipse, FALSE, hdc, left, top, right, bottom);
77 
78     return NtGdiEllipse(hdc, left, top, right, bottom);
79 }
80 
81 
82 /*
83  * @implemented
84  */
85 BOOL
86 WINAPI
87 Rectangle(
88     _In_ HDC hdc,
89     _In_ INT left,
90     _In_ INT top,
91     _In_ INT right,
92     _In_ INT bottom)
93 {
94     HANDLE_METADC(BOOL, Rectangle, FALSE, hdc, left, top, right, bottom);
95 
96     return NtGdiRectangle(hdc, left, top, right, bottom);
97 }
98 
99 
100 /*
101  * @implemented
102  */
103 BOOL
104 WINAPI
105 RoundRect(
106     _In_ HDC hdc,
107     _In_ INT left,
108     _In_ INT top,
109     _In_ INT right,
110     _In_ INT bottom,
111     _In_ INT width,
112     _In_ INT height)
113 {
114     HANDLE_METADC(BOOL, RoundRect, FALSE, hdc, left, top, right, bottom, width, height);
115 
116     return NtGdiRoundRect(hdc, left, top, right, bottom, width, height);
117 }
118 
119 
120 /*
121  * @implemented
122  */
123 COLORREF
124 WINAPI
125 GetPixel(
126     _In_ HDC hdc,
127     _In_ INT x,
128     _In_ INT y)
129 {
130     if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC) return CLR_INVALID;
131     if (!GdiValidateHandle((HGDIOBJ) hdc)) return CLR_INVALID;
132     return NtGdiGetPixel(hdc, x, y);
133 }
134 
135 
136 /*
137  * @implemented
138  */
139 COLORREF
140 WINAPI
141 SetPixel(
142     _In_ HDC hdc,
143     _In_ INT x,
144     _In_ INT y,
145     _In_ COLORREF crColor)
146 {
147     HANDLE_METADC(COLORREF, SetPixel, CLR_INVALID, hdc, x, y, crColor);
148 
149     return NtGdiSetPixel(hdc, x, y, crColor);
150 }
151 
152 
153 /*
154  * @implemented
155  */
156 BOOL
157 WINAPI
158 SetPixelV(
159     _In_ HDC hdc,
160     _In_ INT x,
161     _In_ INT y,
162     _In_ COLORREF crColor)
163 {
164     return SetPixel(hdc, x, y, crColor) != CLR_INVALID;
165 }
166 
167 
168 /*
169  * @implemented
170  */
171 BOOL
172 WINAPI
173 FillRgn(
174     _In_ HDC hdc,
175     _In_ HRGN hrgn,
176     _In_ HBRUSH hbr)
177 {
178 
179     if ((hrgn == NULL) || (hbr == NULL))
180         return FALSE;
181 
182     HANDLE_METADC(BOOL, FillRgn, FALSE, hdc, hrgn, hbr);
183 
184     return NtGdiFillRgn(hdc, hrgn, hbr);
185 }
186 
187 
188 /*
189  * @implemented
190  */
191 BOOL
192 WINAPI
193 FrameRgn(
194     _In_ HDC hdc,
195     _In_ HRGN hrgn,
196     _In_ HBRUSH hbr,
197     _In_ INT nWidth,
198     _In_ INT nHeight)
199 {
200 
201     if ((hrgn == NULL) || (hbr == NULL))
202         return FALSE;
203 
204     HANDLE_METADC(BOOL, FrameRgn, FALSE, hdc, hrgn, hbr, nWidth, nHeight);
205 
206     return NtGdiFrameRgn(hdc, hrgn, hbr, nWidth, nHeight);
207 }
208 
209 
210 /*
211  * @implemented
212  */
213 BOOL
214 WINAPI
215 InvertRgn(
216     _In_ HDC hdc,
217     _In_ HRGN hrgn)
218 {
219 
220     if (hrgn == NULL)
221         return FALSE;
222 
223     HANDLE_METADC(BOOL, InvertRgn, FALSE, hdc, hrgn);
224 
225     return NtGdiInvertRgn(hdc, hrgn);
226 }
227 
228 
229 /*
230  * @implemented
231  */
232 BOOL
233 WINAPI
234 PaintRgn(
235     _In_ HDC hdc,
236     _In_ HRGN hrgn)
237 {
238     return FillRgn(hdc, hrgn, GetCurrentObject(hdc, OBJ_BRUSH));
239 }
240 
241 
242 /*
243  * @implemented
244  */
245 BOOL
246 WINAPI
247 PolyBezier(
248     _In_ HDC hdc,
249     _In_reads_(cpt) const POINT *apt,
250     _In_ DWORD cpt)
251 {
252     HANDLE_METADC(BOOL, PolyBezier, FALSE, hdc, apt, cpt);
253 
254     return NtGdiPolyPolyDraw(hdc ,(PPOINT)apt, &cpt, 1, GdiPolyBezier);
255 }
256 
257 
258 /*
259  * @implemented
260  */
261 BOOL
262 WINAPI
263 PolyBezierTo(
264     _In_ HDC hdc,
265     _In_reads_(cpt) const POINT *apt,
266     _In_ DWORD cpt)
267 {
268     HANDLE_METADC(BOOL, PolyBezierTo, FALSE, hdc, apt, cpt);
269 
270     return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, &cpt, 1, GdiPolyBezierTo);
271 }
272 
273 
274 /*
275  * @implemented
276  */
277 BOOL
278 WINAPI
279 PolyDraw(
280     _In_ HDC hdc,
281     _In_reads_(cpt) const POINT *apt,
282     _In_reads_(cpt) const BYTE *aj,
283     _In_ INT cpt)
284 {
285     HANDLE_METADC(BOOL, PolyDraw, FALSE, hdc, apt, aj, cpt);
286 
287     return NtGdiPolyDraw(hdc, (PPOINT)apt, (PBYTE)aj, cpt);
288 }
289 
290 
291 /*
292  * @implemented
293  */
294 BOOL
295 WINAPI
296 Polygon(
297     _In_ HDC hdc,
298     _In_reads_(cpt) const POINT *apt,
299     _In_ INT cpt)
300 {
301     HANDLE_METADC(BOOL, Polygon, FALSE, hdc, apt, cpt);
302 
303     return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, (PULONG)&cpt, 1, GdiPolyPolygon);
304 }
305 
306 
307 /*
308  * @implemented
309  */
310 BOOL
311 WINAPI
312 Polyline(
313     _In_ HDC hdc,
314     _In_reads_(cpt) const POINT *apt,
315     _In_ INT cpt)
316 {
317     HANDLE_METADC(BOOL, Polyline, FALSE, hdc, apt, cpt);
318 
319     return NtGdiPolyPolyDraw(hdc, (PPOINT)apt, (PULONG)&cpt, 1, GdiPolyPolyLine);
320 }
321 
322 
323 /*
324  * @implemented
325  */
326 BOOL
327 WINAPI
328 PolylineTo(
329     _In_ HDC hdc,
330     _In_reads_(cpt) const POINT *apt,
331     _In_ DWORD cpt)
332 {
333     HANDLE_METADC(BOOL, PolylineTo, FALSE, hdc, apt, cpt);
334 
335     return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, &cpt, 1, GdiPolyLineTo);
336 }
337 
338 
339 /*
340  * @implemented
341  */
342 BOOL
343 WINAPI
344 PolyPolygon(
345     _In_ HDC hdc,
346     _In_ const POINT *apt,
347     _In_reads_(csz) const INT *asz,
348     _In_ INT csz)
349 {
350     HANDLE_METADC(BOOL, PolyPolygon, FALSE, hdc, apt, asz, csz);
351 
352     return NtGdiPolyPolyDraw(hdc, (PPOINT)apt, (PULONG)asz, csz, GdiPolyPolygon);
353 }
354 
355 
356 /*
357  * @implemented
358  */
359 BOOL
360 WINAPI
361 PolyPolyline(
362     _In_ HDC hdc,
363     _In_ CONST POINT *apt,
364     _In_reads_(csz) CONST DWORD *asz,
365     _In_ DWORD csz)
366 {
367     if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE)
368         return FALSE;
369 
370     HANDLE_METADC(BOOL, PolyPolyline, FALSE, hdc, apt, asz, csz);
371 
372     return NtGdiPolyPolyDraw(hdc , (PPOINT)apt, (PULONG)asz, csz, GdiPolyPolyLine);
373 }
374 
375 
376 /*
377  * @implemented
378  */
379 BOOL
380 WINAPI
381 ExtFloodFill(
382     _In_ HDC hdc,
383     _In_ INT xStart,
384     _In_ INT yStart,
385     _In_ COLORREF crFill,
386     _In_ UINT fuFillType)
387 {
388     HANDLE_METADC(BOOL, ExtFloodFill, FALSE, hdc, xStart, yStart, crFill, fuFillType);
389 
390     return NtGdiExtFloodFill(hdc, xStart, yStart, crFill, fuFillType);
391 }
392 
393 
394 /*
395  * @implemented
396  */
397 BOOL
398 WINAPI
399 FloodFill(
400     _In_ HDC hdc,
401     _In_ INT xStart,
402     _In_ INT yStart,
403     _In_ COLORREF crFill)
404 {
405     return ExtFloodFill(hdc, xStart, yStart, crFill, FLOODFILLBORDER);
406 }
407 
408 /*
409  * @implemented
410  */
411 BOOL
412 WINAPI
413 BitBlt(
414     _In_ HDC hdcDest,
415     _In_ INT xDest,
416     _In_ INT yDest,
417     _In_ INT cx,
418     _In_ INT cy,
419     _In_opt_ HDC hdcSrc,
420     _In_ INT xSrc,
421     _In_ INT ySrc,
422     _In_ DWORD dwRop)
423 {
424     /* Use PatBlt for no source blt, like windows does */
425     if (!ROP_USES_SOURCE(dwRop))
426     {
427         return PatBlt(hdcDest, xDest, yDest, cx, cy, dwRop);
428     }
429 
430     /* For meta DCs we use StretchBlt */
431     HANDLE_METADC(BOOL,
432                   StretchBlt,
433                   FALSE,
434                   hdcDest,
435                   xDest,
436                   yDest,
437                   cx,
438                   cx,
439                   hdcSrc,
440                   xSrc,
441                   ySrc,
442                   cx,
443                   cx,
444                   dwRop);
445 
446     return NtGdiBitBlt(hdcDest, xDest, yDest, cx, cy, hdcSrc, xSrc, ySrc, dwRop, 0, 0);
447 }
448 
449 BOOL
450 WINAPI
451 PatBlt(
452     _In_ HDC hdc,
453     _In_ INT nXLeft,
454     _In_ INT nYLeft,
455     _In_ INT nWidth,
456     _In_ INT nHeight,
457     _In_ DWORD dwRop)
458 {
459     PDC_ATTR pdcattr;
460 
461     HANDLE_METADC(BOOL, PatBlt, FALSE, hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop);
462 
463     /* Get the DC attribute */
464     pdcattr = GdiGetDcAttr(hdc);
465     if (pdcattr && !(pdcattr->ulDirty_ & DC_DIBSECTION))
466     {
467         PGDIBSPATBLT pgO;
468 
469         pgO = GdiAllocBatchCommand(hdc, GdiBCPatBlt);
470         if (pgO)
471         {
472             pgO->nXLeft  = nXLeft;
473             pgO->nYLeft  = nYLeft;
474             pgO->nWidth  = nWidth;
475             pgO->nHeight = nHeight;
476             pgO->dwRop   = dwRop;
477             /* Snapshot attributes */
478             pgO->hbrush          = pdcattr->hbrush;
479             pgO->crForegroundClr = pdcattr->crForegroundClr;
480             pgO->crBackgroundClr = pdcattr->crBackgroundClr;
481             pgO->crBrushClr      = pdcattr->crBrushClr;
482             pgO->ulForegroundClr = pdcattr->ulForegroundClr;
483             pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
484             pgO->ulBrushClr      = pdcattr->ulBrushClr;
485             return TRUE;
486         }
487     }
488     return NtGdiPatBlt( hdc,  nXLeft,  nYLeft,  nWidth,  nHeight,  dwRop);
489 }
490 
491 BOOL
492 WINAPI
493 PolyPatBlt(
494     _In_ HDC hdc,
495     _In_ DWORD dwRop,
496     _In_ PPOLYPATBLT pPoly,
497     _In_ DWORD nCount,
498     _In_ DWORD dwMode)
499 {
500     UINT i;
501     BOOL bResult;
502     HBRUSH hbrOld;
503     PDC_ATTR pdcattr;
504 
505     /* Handle meta DCs */
506     if ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) ||
507         (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_ALTDC_TYPE))
508     {
509         if (!GdiValidateHandle(hdc))
510         {
511             return FALSE;
512         }
513 
514         /* Save the current DC brush */
515         hbrOld = SelectObject(hdc, GetStockObject(DC_BRUSH));
516 
517         /* Assume success */
518         bResult = TRUE;
519 
520         /* Loop all rect */
521         for (i = 0; i < nCount; i++)
522         {
523             /* Select the brush for this rect */
524             SelectObject(hdc, pPoly[i].hBrush);
525 
526             /* Do the PatBlt operation for this rect */
527             bResult &= PatBlt(hdc,
528                                pPoly[i].nXLeft,
529                                pPoly[i].nYLeft,
530                                pPoly[i].nWidth,
531                                pPoly[i].nHeight,
532                                dwRop);
533         }
534 
535         /* Restore the old brush */
536         SelectObject(hdc, hbrOld);
537 
538         return bResult;
539     }
540 
541     /* Get the DC attribute */
542     pdcattr = GdiGetDcAttr(hdc);
543     if (nCount && pdcattr && !(pdcattr->ulDirty_ & DC_DIBSECTION))
544     {
545         PGDIBSPPATBLT pgO;
546         PTEB pTeb = NtCurrentTeb();
547 
548         pgO = GdiAllocBatchCommand(hdc, GdiBCPolyPatBlt);
549         if (pgO)
550         {
551             USHORT cjSize = sizeof(GDIBSPPATBLT) + (nCount-1) * sizeof(PATRECT);
552 
553             if ((pTeb->GdiTebBatch.Offset + cjSize) <= GDIBATCHBUFSIZE)
554             {
555                 pgO->Count = nCount;
556                 pgO->Mode  = dwMode;
557                 pgO->rop4  = dwRop;
558                 /* Snapshot attributes */
559                 pgO->crForegroundClr = pdcattr->crForegroundClr;
560                 pgO->crBackgroundClr = pdcattr->crBackgroundClr;
561                 pgO->crBrushClr      = pdcattr->crBrushClr;
562                 pgO->ulForegroundClr = pdcattr->ulForegroundClr;
563                 pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
564                 pgO->ulBrushClr      = pdcattr->ulBrushClr;
565                 RtlCopyMemory(pgO->pRect, pPoly, nCount * sizeof(PATRECT));
566                 // Recompute offset, remember one is already accounted for in the structure.
567                 pTeb->GdiTebBatch.Offset += (nCount-1) * sizeof(PATRECT);
568                 return TRUE;
569             }
570         }
571     }
572     return NtGdiPolyPatBlt(hdc, dwRop, pPoly, nCount, dwMode);
573 }
574 
575 /*
576  * @implemented
577  */
578 BOOL
579 WINAPI
580 StretchBlt(
581     _In_ HDC hdcDest,
582     _In_ INT xDest,
583     _In_ INT yDest,
584     _In_ INT cxDest,
585     _In_ INT cyDest,
586     _In_opt_ HDC hdcSrc,
587     _In_ INT xSrc,
588     _In_ INT ySrc,
589     _In_ INT cxSrc,
590     _In_ INT cySrc,
591     _In_ DWORD dwRop)
592 {
593     HANDLE_METADC(BOOL,
594                   StretchBlt,
595                   FALSE,
596                   hdcDest,
597                   xDest,
598                   yDest,
599                   cxDest,
600                   cyDest,
601                   hdcSrc,
602                   xSrc,
603                   ySrc,
604                   cxSrc,
605                   cySrc,
606                   dwRop);
607 
608     return NtGdiStretchBlt(hdcDest,
609                            xDest,
610                            yDest,
611                            cxDest,
612                            cyDest,
613                            hdcSrc,
614                            xSrc,
615                            ySrc,
616                            cxSrc,
617                            cySrc,
618                            dwRop,
619                            0);
620 }
621 
622 
623 /*
624  * @implemented
625  */
626 BOOL
627 WINAPI
628 MaskBlt(
629     _In_ HDC hdcDest,
630     _In_ INT xDest,
631     _In_ INT yDest,
632     _In_ INT cx,
633     _In_ INT cy,
634     _In_ HDC hdcSrc,
635     _In_ INT xSrc,
636     _In_ INT ySrc,
637     _In_ HBITMAP hbmMask,
638     _In_ INT xMask,
639     _In_ INT yMask,
640     _In_ DWORD dwRop)
641 {
642     HANDLE_METADC(BOOL,
643                   MaskBlt,
644                   FALSE,
645                   hdcDest,
646                   xDest,
647                   yDest,
648                   cx,
649                   cy,
650                   hdcSrc,
651                   xSrc,
652                   ySrc,
653                   hbmMask,
654                   xMask,
655                   yMask,
656                   dwRop);
657 
658     return NtGdiMaskBlt(hdcDest,
659                         xDest,
660                         yDest,
661                         cx,
662                         cy,
663                         hdcSrc,
664                         xSrc,
665                         ySrc,
666                         hbmMask,
667                         xMask,
668                         yMask,
669                         dwRop,
670                         GetBkColor(hdcSrc));
671 }
672 
673 
674 /*
675  * @implemented
676  */
677 BOOL
678 WINAPI
679 PlgBlt(
680     _In_ HDC hdcDest,
681     _In_reads_(3) const POINT * ppt,
682     _In_ HDC hdcSrc,
683     _In_ INT xSrc,
684     _In_ INT ySrc,
685     _In_ INT cx,
686     _In_ INT cy,
687     _In_opt_ HBITMAP hbmMask,
688     _In_ INT xMask,
689     _In_ INT yMask)
690 {
691     HANDLE_METADC(BOOL,
692                   PlgBlt,
693                   FALSE,
694                   hdcDest,
695                   ppt,
696                   hdcSrc,
697                   xSrc,
698                   ySrc,
699                   cx,
700                   cy,
701                   hbmMask,
702                   xMask,
703                   yMask);
704 
705     return NtGdiPlgBlt(hdcDest,
706                        (LPPOINT)ppt,
707                        hdcSrc,
708                        xSrc,
709                        ySrc,
710                        cx,
711                        cy,
712                        hbmMask,
713                        xMask,
714                        yMask,
715                        GetBkColor(hdcSrc));
716 }
717 
718 BOOL
719 WINAPI
720 GdiAlphaBlend(
721     _In_ HDC hdcDst,
722     _In_ INT xDst,
723     _In_ INT yDst,
724     _In_ INT cxDst,
725     _In_ INT cyDst,
726     _In_ HDC hdcSrc,
727     _In_ INT xSrc,
728     _In_ INT ySrc,
729     _In_ INT cxSrc,
730     _In_ INT cySrc,
731     _In_ BLENDFUNCTION blendfn)
732 {
733     if (hdcSrc == NULL ) return FALSE;
734 
735     if (GDI_HANDLE_GET_TYPE(hdcSrc) == GDI_OBJECT_TYPE_METADC) return FALSE;
736 
737     HANDLE_METADC(BOOL,
738                   AlphaBlend,
739                   FALSE,
740                   hdcDst,
741                   xDst,
742                   yDst,
743                   cxDst,
744                   cyDst,
745                   hdcSrc,
746                   xSrc,
747                   ySrc,
748                   cxSrc,
749                   cySrc,
750                   blendfn);
751 
752     return NtGdiAlphaBlend(hdcDst,
753                            xDst,
754                            yDst,
755                            cxDst,
756                            cyDst,
757                            hdcSrc,
758                            xSrc,
759                            ySrc,
760                            cxSrc,
761                            cySrc,
762                            blendfn,
763                            0);
764 }
765 
766 
767 /*
768  * @implemented
769  */
770 BOOL
771 WINAPI
772 GdiTransparentBlt(
773     _In_ HDC hdcDst,
774     _In_ INT xDst,
775     _In_ INT yDst,
776     _In_ INT cxDst,
777     _In_ INT cyDst,
778     _In_ HDC hdcSrc,
779     _In_ INT xSrc,
780     _In_ INT ySrc,
781     _In_ INT cxSrc,
782     _In_ INT cySrc,
783     _In_ UINT crTransparent)
784 {
785     HANDLE_METADC(BOOL,
786                   TransparentBlt,
787                   FALSE,
788                   hdcDst,
789                   xDst,
790                   yDst,
791                   cxDst,
792                   cyDst,
793                   hdcSrc,
794                   xSrc,
795                   ySrc,
796                   cxSrc,
797                   cySrc,
798                   crTransparent);
799 
800     /* FIXME some part need be done in user mode */
801     return NtGdiTransparentBlt(hdcDst, xDst, yDst, cxDst, cyDst, hdcSrc, xSrc, ySrc, cxSrc, cySrc, crTransparent);
802 }
803 
804 /*
805  * @implemented
806  */
807 BOOL
808 WINAPI
809 GdiGradientFill(
810     _In_ HDC hdc,
811     _In_reads_(nVertex) PTRIVERTEX pVertex,
812     _In_ ULONG nVertex,
813     _In_ PVOID pMesh,
814     _In_ ULONG nCount,
815     _In_ ULONG ulMode)
816 {
817     HANDLE_METADC(BOOL, GradientFill, FALSE, hdc, pVertex, nVertex, pMesh, nCount, ulMode);
818 
819     /* FIXME some part need be done in user mode */
820     return NtGdiGradientFill(hdc, pVertex, nVertex, pMesh, nCount, ulMode);
821 }
822