2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 IN OPTIONAL LPBYTE pBits
)
39 /* NOTE: Windows also doesn't store nr. of planes separately! */
40 BitsPixel
= BITMAP_GetRealBitsPixel(BitsPixel
* Planes
);
42 /* Check parameters */
43 if (BitsPixel
== 0 || Width
<= 0 || Width
>= 0x8000000 || Height
== 0)
45 DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
46 Width
, Height
, BitsPixel
);
47 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
51 WidthBytes
= BITMAP_GetWidthBytes(Width
, BitsPixel
);
54 Size
.cy
= abs(Height
);
56 /* Make sure that cjBits will not overflow */
57 if ((ULONGLONG
)WidthBytes
* Size
.cy
>= 0x100000000ULL
)
59 DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
60 Width
, Height
, BitsPixel
);
61 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
65 /* Create the bitmap object. */
66 hBitmap
= IntCreateBitmap(Size
, WidthBytes
,
67 BitmapFormat(BitsPixel
, BI_RGB
),
68 (Height
< 0 ? BMF_TOPDOWN
: 0) |
69 (NULL
== pBits
? 0 : BMF_NOZEROINIT
), NULL
);
72 DPRINT("IntGdiCreateBitmap: returned 0\n");
76 psurfBmp
= SURFACE_LockSurface(hBitmap
);
79 NtGdiDeleteObject(hBitmap
);
83 psurfBmp
->flFlags
= BITMAPOBJ_IS_APIBITMAP
;
84 psurfBmp
->hDC
= NULL
; // Fixme
88 IntSetBitmapBits(psurfBmp
, psurfBmp
->SurfObj
.cjBits
, pBits
);
91 SURFACE_UnlockSurface(psurfBmp
);
93 DPRINT("IntGdiCreateBitmap : %dx%d, %d BPP colors, topdown %d, returning %08x\n",
94 Size
.cx
, Size
.cy
, BitsPixel
, (Height
< 0 ? 1 : 0), hBitmap
);
106 IN OPTIONAL LPBYTE pUnsafeBits
)
111 UINT cjBits
= BITMAP_GetWidthBytes(Width
, BitsPixel
) * abs(Height
);
113 // FIXME: Use MmSecureVirtualMemory
116 ProbeForRead(pUnsafeBits
, cjBits
, 1);
118 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
127 return IntGdiCreateBitmap(Width
, Height
, Planes
, BitsPixel
, pUnsafeBits
);
131 IntCreateCompatibleBitmap(
138 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
139 if (0 == Width
|| 0 == Height
)
141 Bmp
= NtGdiGetStockObject(DEFAULT_BITMAP
);
145 if (Dc
->dctype
!= DC_TYPE_MEMORY
)
147 Bmp
= IntGdiCreateBitmap(abs(Width
),
149 IntGdiGetDeviceCaps(Dc
,PLANES
),
150 IntGdiGetDeviceCaps(Dc
,BITSPIXEL
),
157 PSURFACE psurf
= SURFACE_LockSurface(Dc
->rosdc
.hBitmap
);
158 Count
= BITMAP_GetObject(psurf
, sizeof(dibs
), &dibs
);
162 if (Count
== sizeof(BITMAP
))
164 /* We have a bitmap bug!!! W/O the HACK, we have white icons.
166 MSDN Note: When a memory device context is created, it initially
167 has a 1-by-1 monochrome bitmap selected into it. If this memory
168 device context is used in CreateCompatibleBitmap, the bitmap that
169 is created is a monochrome bitmap. To create a color bitmap, use
170 the hDC that was used to create the memory device context, as
171 shown in the following code:
173 HDC memDC = CreateCompatibleDC(hDC);
174 HBITMAP memBM = CreateCompatibleBitmap(hDC, nWidth, nHeight);
175 SelectObject(memDC, memBM);
177 Bmp
= IntGdiCreateBitmap(abs(Width
),
180 IntGdiGetDeviceCaps(Dc
,BITSPIXEL
),//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
185 /* A DIB section is selected in the DC */
189 /* Allocate memory for a BITMAPINFOHEADER structure and a
190 color table. The maximum number of colors in a color table
191 is 256 which corresponds to a bitmap with depth 8.
192 Bitmaps with higher depths don't have color tables. */
193 bi
= ExAllocatePoolWithTag(PagedPool
,
194 sizeof(BITMAPINFOHEADER
) +
195 256 * sizeof(RGBQUAD
),
200 bi
->bmiHeader
.biSize
= sizeof(bi
->bmiHeader
);
201 bi
->bmiHeader
.biWidth
= Width
;
202 bi
->bmiHeader
.biHeight
= Height
;
203 bi
->bmiHeader
.biPlanes
= dibs
.dsBmih
.biPlanes
;
204 bi
->bmiHeader
.biBitCount
= dibs
.dsBmih
.biBitCount
;
205 bi
->bmiHeader
.biCompression
= dibs
.dsBmih
.biCompression
;
206 bi
->bmiHeader
.biSizeImage
= 0;
207 bi
->bmiHeader
.biXPelsPerMeter
= dibs
.dsBmih
.biXPelsPerMeter
;
208 bi
->bmiHeader
.biYPelsPerMeter
= dibs
.dsBmih
.biYPelsPerMeter
;
209 bi
->bmiHeader
.biClrUsed
= dibs
.dsBmih
.biClrUsed
;
210 bi
->bmiHeader
.biClrImportant
= dibs
.dsBmih
.biClrImportant
;
212 if (bi
->bmiHeader
.biCompression
== BI_BITFIELDS
)
214 /* Copy the color masks */
215 RtlCopyMemory(bi
->bmiColors
, dibs
.dsBitfields
, 3 * sizeof(DWORD
));
217 else if (bi
->bmiHeader
.biBitCount
<= 8)
219 /* Copy the color table */
221 PPALGDI PalGDI
= PALETTE_LockPalette(psurf
->hDIBPalette
);
225 ExFreePoolWithTag(bi
, TAG_TEMP
);
226 SURFACE_UnlockSurface(psurf
);
227 SetLastWin32Error(ERROR_INVALID_HANDLE
);
232 Index
< 256 && Index
< PalGDI
->NumColors
;
235 bi
->bmiColors
[Index
].rgbRed
= PalGDI
->IndexedColors
[Index
].peRed
;
236 bi
->bmiColors
[Index
].rgbGreen
= PalGDI
->IndexedColors
[Index
].peGreen
;
237 bi
->bmiColors
[Index
].rgbBlue
= PalGDI
->IndexedColors
[Index
].peBlue
;
238 bi
->bmiColors
[Index
].rgbReserved
= 0;
240 PALETTE_UnlockPalette(PalGDI
);
242 SURFACE_UnlockSurface(psurf
);
244 Bmp
= DIB_CreateDIBSection(Dc
,
252 ExFreePoolWithTag(bi
, TAG_TEMP
);
257 SURFACE_UnlockSurface(psurf
);
264 NtGdiCreateCompatibleBitmap(
272 if (Width
<= 0 || Height
<= 0 || (Width
* Height
) > 0x3FFFFFFF)
274 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
279 return IntGdiCreateBitmap(Width
, Height
, 1, 1, 0);
283 DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n",
284 hDC
, Width
, Height
, Dc
->ppdev
->GDIInfo
.cBitsPixel
);
288 SetLastWin32Error(ERROR_INVALID_HANDLE
);
292 Bmp
= IntCreateCompatibleBitmap(Dc
, Width
, Height
);
294 DPRINT("\t\t%04x\n", Bmp
);
300 NtGdiGetBitmapDimension(
310 psurfBmp
= SURFACE_LockSurface(hBitmap
);
311 if (psurfBmp
== NULL
)
313 SetLastWin32Error(ERROR_INVALID_HANDLE
);
319 ProbeForWrite(Dimension
, sizeof(SIZE
), 1);
320 *Dimension
= psurfBmp
->dimension
;
322 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
328 SURFACE_UnlockSurface(psurfBmp
);
334 NtGdiGetPixel(HDC hDC
, INT XPos
, INT YPos
)
337 COLORREF Result
= (COLORREF
)CLR_INVALID
; // default to failure
338 BOOL bInRect
= FALSE
;
349 SetLastWin32Error(ERROR_INVALID_HANDLE
);
353 if (dc
->dctype
== DC_TYPE_INFO
)
359 XPos
+= dc
->ptlDCOrig
.x
;
360 YPos
+= dc
->ptlDCOrig
.y
;
361 if (RECTL_bPointInRect(&dc
->rosdc
.CombinedClip
->rclBounds
, XPos
, YPos
))
364 psurf
= SURFACE_LockSurface(dc
->rosdc
.hBitmap
);
365 pso
= &psurf
->SurfObj
;
368 Pal
= psurf
->hDIBPalette
;
369 if (!Pal
) Pal
= pPrimarySurface
->DevInfo
.hpalDefault
;
371 /* FIXME: Verify if it shouldn't be PAL_BGR! */
372 XlateObj
= (XLATEOBJ
*)IntEngCreateXlate(PAL_RGB
, 0, NULL
, Pal
);
375 // check if this DC has a DIB behind it...
376 if (pso
->pvScan0
) // STYPE_BITMAP == pso->iType
379 Result
= XLATEOBJ_iXlate(XlateObj
,
380 DibFunctionsForBitmapFormat
[pso
->iBitmapFormat
].DIB_GetPixel(pso
, XPos
, YPos
));
382 EngDeleteXlate(XlateObj
);
384 SURFACE_UnlockSurface(psurf
);
389 // if Result is still CLR_INVALID, then the "quick" method above didn't work
390 if (bInRect
&& Result
== CLR_INVALID
)
392 // FIXME: create a 1x1 32BPP DIB, and blit to it
393 HDC hDCTmp
= NtGdiCreateCompatibleDC(hDC
);
396 static const BITMAPINFOHEADER bih
= { sizeof(BITMAPINFOHEADER
), 1, 1, 1, 32, BI_RGB
, 0, 0, 0, 0, 0 };
398 RtlMoveMemory(&(bi
.bmiHeader
), &bih
, sizeof(bih
));
399 hBmpTmp
= NtGdiCreateDIBitmapInternal(hDC
,
400 bi
.bmiHeader
.biWidth
,
401 bi
.bmiHeader
.biHeight
,
406 bi
.bmiHeader
.biBitCount
,
407 bi
.bmiHeader
.biSizeImage
,
411 //HBITMAP hBmpTmp = IntGdiCreateBitmap(1, 1, 1, 32, NULL);
414 HBITMAP hBmpOld
= (HBITMAP
)NtGdiSelectBitmap(hDCTmp
, hBmpTmp
);
419 NtGdiBitBlt(hDCTmp
, 0, 0, 1, 1, hDC
, XPos
, YPos
, SRCCOPY
, 0, 0);
420 NtGdiSelectBitmap(hDCTmp
, hBmpOld
);
422 // our bitmap is no longer selected, so we can access it's stuff...
423 psurf
= SURFACE_LockSurface(hBmpTmp
);
426 // Dont you need to convert something here?
427 Result
= *(COLORREF
*)psurf
->SurfObj
.pvScan0
;
428 SURFACE_UnlockSurface(psurf
);
431 NtGdiDeleteObject(hBmpTmp
);
433 NtGdiDeleteObjectApp(hDCTmp
);
451 /* Don't copy more bytes than the buffer has */
452 Bytes
= min(Bytes
, psurf
->SurfObj
.cjBits
);
455 /* FIXME: Call DDI CopyBits here if available */
458 DPRINT("Calling device specific BitmapBits\n");
459 if (psurf
->DDBitmap
->funcs
->pBitmapBits
)
461 ret
= psurf
->DDBitmap
->funcs
->pBitmapBits(hbitmap
,
468 ERR_(bitmap
)("BitmapBits == NULL??\n");
475 RtlCopyMemory(Bits
, psurf
->SurfObj
.pvBits
, Bytes
);
485 OUT OPTIONAL PBYTE pUnsafeBits
)
490 if (pUnsafeBits
!= NULL
&& Bytes
== 0)
495 psurf
= SURFACE_LockSurface(hBitmap
);
498 SetLastWin32Error(ERROR_INVALID_HANDLE
);
502 bmSize
= BITMAP_GetWidthBytes(psurf
->SurfObj
.sizlBitmap
.cx
,
503 BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
)) *
504 abs(psurf
->SurfObj
.sizlBitmap
.cy
);
506 /* If the bits vector is null, the function should return the read size */
507 if (pUnsafeBits
== NULL
)
509 SURFACE_UnlockSurface(psurf
);
513 /* Don't copy more bytes than the buffer has */
514 Bytes
= min(Bytes
, bmSize
);
516 // FIXME: use MmSecureVirtualMemory
519 ProbeForWrite(pUnsafeBits
, Bytes
, 1);
520 ret
= IntGetBitmapBits(psurf
, Bytes
, pUnsafeBits
);
522 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
528 SURFACE_UnlockSurface(psurf
);
542 /* Don't copy more bytes than the buffer has */
543 Bytes
= min(Bytes
, psurf
->SurfObj
.cjBits
);
546 /* FIXME: call DDI specific function here if available */
549 DPRINT("Calling device specific BitmapBits\n");
550 if (psurf
->DDBitmap
->funcs
->pBitmapBits
)
552 ret
= psurf
->DDBitmap
->funcs
->pBitmapBits(hBitmap
,
559 DPRINT("BitmapBits == NULL??\n");
566 RtlCopyMemory(psurf
->SurfObj
.pvBits
, Bits
, Bytes
);
578 IN PBYTE pUnsafeBits
)
583 if (pUnsafeBits
== NULL
|| Bytes
== 0)
588 psurf
= SURFACE_LockSurface(hBitmap
);
591 SetLastWin32Error(ERROR_INVALID_HANDLE
);
597 ProbeForRead(pUnsafeBits
, Bytes
, 1);
598 ret
= IntSetBitmapBits(psurf
, Bytes
, pUnsafeBits
);
600 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
606 SURFACE_UnlockSurface(psurf
);
612 NtGdiSetBitmapDimension(
624 psurf
= SURFACE_LockSurface(hBitmap
);
627 SetLastWin32Error(ERROR_INVALID_HANDLE
);
635 ProbeForWrite(Size
, sizeof(SIZE
), 1);
636 *Size
= psurf
->dimension
;
638 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
645 /* The dimension is changed even if writing the old value failed */
646 psurf
->dimension
.cx
= Width
;
647 psurf
->dimension
.cy
= Height
;
649 SURFACE_UnlockSurface(psurf
);
661 HBRUSH hbrush
= NtGdiCreateSolidBrush(Color
, NULL
);
667 OldBrush
= NtGdiSelectBrush(hDC
, hbrush
);
668 if (OldBrush
== NULL
)
670 NtGdiDeleteObject(hbrush
);
674 NtGdiPatBlt(hDC
, X
, Y
, 1, 1, PATCOPY
);
675 NtGdiSelectBrush(hDC
, OldBrush
);
676 NtGdiDeleteObject(hbrush
);
688 DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
690 if (GdiSetPixelV(hDC
,X
,Y
,Color
))
692 Color
= NtGdiGetPixel(hDC
,X
,Y
);
693 DPRINT("1 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
697 Color
= (COLORREF
)CLR_INVALID
;
698 DPRINT("2 NtGdiSetPixel X %ld Y %ld C %ld\n", X
, Y
, Color
);
703 /* Internal Functions */
706 BITMAP_GetRealBitsPixel(UINT nBitsPixel
)
714 if (nBitsPixel
<= 16)
716 if (nBitsPixel
<= 24)
718 if (nBitsPixel
<= 32)
725 BITMAP_GetWidthBytes(INT bmWidth
, INT bpp
)
731 return 2 * ((bmWidth
+15) >> 4);
734 bmWidth
*= 3; /* fall through */
736 return bmWidth
+ (bmWidth
& 1);
746 return 2 * ((bmWidth
+3) >> 2);
755 return ((bmWidth
* bpp
+ 15) & ~15) >> 3;
759 BITMAP_CopyBitmap(HBITMAP hBitmap
)
763 SURFACE
*Bitmap
, *resBitmap
;
771 Bitmap
= GDIOBJ_LockObj(hBitmap
, GDI_OBJECT_TYPE_BITMAP
);
777 BITMAP_GetObject(Bitmap
, sizeof(BITMAP
), (PVOID
)&bm
);
779 if (Bitmap
->SurfObj
.lDelta
>= 0)
780 bm
.bmHeight
= -bm
.bmHeight
;
782 Size
.cx
= abs(bm
.bmWidth
);
783 Size
.cy
= abs(bm
.bmHeight
);
784 res
= IntCreateBitmap(Size
,
786 BitmapFormat(bm
.bmBitsPixel
* bm
.bmPlanes
, BI_RGB
),
787 (bm
.bmHeight
< 0 ? BMF_TOPDOWN
: 0) | BMF_NOZEROINIT
,
794 resBitmap
= GDIOBJ_LockObj(res
, GDI_OBJECT_TYPE_BITMAP
);
797 buf
= ExAllocatePoolWithTag(PagedPool
,
798 bm
.bmWidthBytes
* abs(bm
.bmHeight
),
802 GDIOBJ_UnlockObjByPtr((POBJ
)resBitmap
);
803 GDIOBJ_UnlockObjByPtr((POBJ
)Bitmap
);
804 NtGdiDeleteObject(res
);
807 IntGetBitmapBits(Bitmap
, bm
.bmWidthBytes
* abs(bm
.bmHeight
), buf
);
808 IntSetBitmapBits(resBitmap
, bm
.bmWidthBytes
* abs(bm
.bmHeight
), buf
);
809 ExFreePoolWithTag(buf
,TAG_BITMAP
);
810 resBitmap
->flFlags
= Bitmap
->flFlags
;
811 GDIOBJ_UnlockObjByPtr((POBJ
)resBitmap
);
815 NtGdiDeleteObject(res
);
820 GDIOBJ_UnlockObjByPtr((POBJ
)Bitmap
);
826 BITMAP_GetObject(SURFACE
*psurf
, INT Count
, LPVOID buffer
)
830 if (!buffer
) return sizeof(BITMAP
);
831 if ((UINT
)Count
< sizeof(BITMAP
)) return 0;
833 /* always fill a basic BITMAP structure */
836 pBitmap
->bmWidth
= psurf
->SurfObj
.sizlBitmap
.cx
;
837 pBitmap
->bmHeight
= psurf
->SurfObj
.sizlBitmap
.cy
;
838 pBitmap
->bmWidthBytes
= abs(psurf
->SurfObj
.lDelta
);
839 pBitmap
->bmPlanes
= 1;
840 pBitmap
->bmBitsPixel
= BitsPerFormat(psurf
->SurfObj
.iBitmapFormat
);
842 /* Check for DIB section */
845 /* Set bmBits in this case */
846 pBitmap
->bmBits
= psurf
->SurfObj
.pvBits
;
848 if (Count
>= sizeof(DIBSECTION
))
850 /* Fill rest of DIBSECTION */
851 PDIBSECTION pds
= buffer
;
853 pds
->dsBmih
.biSize
= sizeof(BITMAPINFOHEADER
);
854 pds
->dsBmih
.biWidth
= pds
->dsBm
.bmWidth
;
855 pds
->dsBmih
.biHeight
= pds
->dsBm
.bmHeight
;
856 pds
->dsBmih
.biPlanes
= pds
->dsBm
.bmPlanes
;
857 pds
->dsBmih
.biBitCount
= pds
->dsBm
.bmBitsPixel
;
858 switch (psurf
->SurfObj
.iBitmapFormat
)
860 /* FIXME: What about BI_BITFIELDS? */
867 pds
->dsBmih
.biCompression
= BI_RGB
;
870 pds
->dsBmih
.biCompression
= BI_RLE4
;
873 pds
->dsBmih
.biCompression
= BI_RLE8
;
876 pds
->dsBmih
.biCompression
= BI_JPEG
;
879 pds
->dsBmih
.biCompression
= BI_PNG
;
882 pds
->dsBmih
.biSizeImage
= psurf
->SurfObj
.cjBits
;
883 pds
->dsBmih
.biXPelsPerMeter
= 0;
884 pds
->dsBmih
.biYPelsPerMeter
= 0;
885 pds
->dsBmih
.biClrUsed
= psurf
->biClrUsed
;
886 pds
->dsBmih
.biClrImportant
= psurf
->biClrImportant
;
887 pds
->dsBitfields
[0] = psurf
->dsBitfields
[0];
888 pds
->dsBitfields
[1] = psurf
->dsBitfields
[1];
889 pds
->dsBitfields
[2] = psurf
->dsBitfields
[2];
890 pds
->dshSection
= psurf
->hDIBSection
;
891 pds
->dsOffset
= psurf
->dwOffset
;
893 return sizeof(DIBSECTION
);
898 /* not set according to wine test, confirmed in win2k */
899 pBitmap
->bmBits
= NULL
;
902 return sizeof(BITMAP
);
914 PSURFACE psurf
= SURFACE_LockSurface(hsurf
);
918 SURFACE_UnlockSurface(psurf
);
940 if (hDC
== NULL
|| hBmp
== NULL
) return NULL
;
942 pDC
= DC_LockDc(hDC
);
948 pdcattr
= pDC
->pdcattr
;
950 /* must be memory dc to select bitmap */
951 if (pDC
->dctype
!= DC_TYPE_MEMORY
)
957 psurfBmp
= SURFACE_LockSurface(hBmp
);
963 hOrgBmp
= pDC
->rosdc
.hBitmap
;
965 /* Release the old bitmap, lock the new one and convert it to a SURF */
966 pDC
->rosdc
.hBitmap
= hBmp
;
968 // If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
969 pDC
->dclevel
.pSurface
= psurfBmp
;
972 // if we're working with a DIB, get the palette
973 // [fixme: only create if the selected palette is null]
974 if (psurfBmp
->hSecure
)
976 // pDC->rosdcbitsPerPixel = psurfBmp->dib->dsBmih.biBitCount; ???
977 pDC
->rosdc
.bitsPerPixel
= BitsPerFormat(psurfBmp
->SurfObj
.iBitmapFormat
);
981 pDC
->rosdc
.bitsPerPixel
= BitsPerFormat(psurfBmp
->SurfObj
.iBitmapFormat
);
984 hVisRgn
= NtGdiCreateRectRgn(0,
986 psurfBmp
->SurfObj
.sizlBitmap
.cx
,
987 psurfBmp
->SurfObj
.sizlBitmap
.cy
);
988 SURFACE_UnlockSurface(psurfBmp
);
990 /* Regenerate the XLATEOBJs. */
991 pbrush
= BRUSH_LockBrush(pdcattr
->hbrush
);
994 if (pDC
->rosdc
.XlateBrush
)
996 EngDeleteXlate(pDC
->rosdc
.XlateBrush
);
998 pDC
->rosdc
.XlateBrush
= IntGdiCreateBrushXlate(pDC
, pbrush
, &bFailed
);
999 BRUSH_UnlockBrush(pbrush
);
1002 pbrush
= PENOBJ_LockPen(pdcattr
->hpen
);
1005 if (pDC
->rosdc
.XlatePen
)
1007 EngDeleteXlate(pDC
->rosdc
.XlatePen
);
1009 pDC
->rosdc
.XlatePen
= IntGdiCreateBrushXlate(pDC
, pbrush
, &bFailed
);
1010 PENOBJ_UnlockPen(pbrush
);
1017 GdiSelectVisRgn(hDC
, hVisRgn
);
1018 NtGdiDeleteObject(hVisRgn
);