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