📄 painting.c
字号:
rcSrc.top = ySrc;
rcSrc.right = rcSrc.left + cxSrc;
rcSrc.bottom = rcSrc.top + cySrc;
if((cxDst != cxSrc) || (cyDst != cySrc))
{
DPRINT1("TransparentBlt() does not support stretching at the moment!\n");
goto done;
}
Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
DCDest->CombinedClip, XlateObj, &rcDest, &rcSrc,
TransparentColor, 0);
done:
BITMAPOBJ_UnlockBitmap(BitmapDest);
BITMAPOBJ_UnlockBitmap(BitmapSrc);
DC_UnlockDc(DCSrc);
if(hdcDst != hdcSrc)
{
DC_UnlockDc(DCDest);
}
if(XlateObj)
{
EngDeleteXlate(XlateObj);
}
return Ret;
}
BOOL STDCALL
NtGdiExtFloodFill(
HDC hDC,
INT XStart,
INT YStart,
COLORREF Color,
UINT FillType)
{
DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
/* lie and say we succeded */
return TRUE;
}
/***********************************************************************
* MaskBlt
* Ported from WINE by sedwards 11-4-03
*
* Someone thought it would be faster to do it here and then switch back
* to GDI32. I dunno. Write a test and let me know.
*/
static __inline BYTE
SwapROP3_SrcDst(BYTE bRop3)
{
return (bRop3 & 0x99) | ((bRop3 & 0x22) << 1) | ((bRop3 & 0x44) >> 1);
}
#define FRGND_ROP3(ROP4) ((ROP4) & 0x00FFFFFF)
#define BKGND_ROP3(ROP4) (ROP3Table[(SwapROP3_SrcDst((ROP4)>>24)) & 0xFF])
#define DSTCOPY 0x00AA0029
#define DSTERASE 0x00220326 /* dest = dest & (~src) : DSna */
BOOL STDCALL
NtGdiMaskBlt (
HDC hdcDest, INT nXDest, INT nYDest,
INT nWidth, INT nHeight, HDC hdcSrc,
INT nXSrc, INT nYSrc, HBITMAP hbmMask,
INT xMask, INT yMask, DWORD dwRop,
IN DWORD crBackColor)
{
HBITMAP hOldMaskBitmap, hBitmap2, hOldBitmap2, hBitmap3, hOldBitmap3;
HDC hDCMask, hDC1, hDC2;
static const DWORD ROP3Table[256] =
{
0x00000042, 0x00010289,
0x00020C89, 0x000300AA,
0x00040C88, 0x000500A9,
0x00060865, 0x000702C5,
0x00080F08, 0x00090245,
0x000A0329, 0x000B0B2A,
0x000C0324, 0x000D0B25,
0x000E08A5, 0x000F0001,
0x00100C85, 0x001100A6,
0x00120868, 0x001302C8,
0x00140869, 0x001502C9,
0x00165CCA, 0x00171D54,
0x00180D59, 0x00191CC8,
0x001A06C5, 0x001B0768,
0x001C06CA, 0x001D0766,
0x001E01A5, 0x001F0385,
0x00200F09, 0x00210248,
0x00220326, 0x00230B24,
0x00240D55, 0x00251CC5,
0x002606C8, 0x00271868,
0x00280369, 0x002916CA,
0x002A0CC9, 0x002B1D58,
0x002C0784, 0x002D060A,
0x002E064A, 0x002F0E2A,
0x0030032A, 0x00310B28,
0x00320688, 0x00330008,
0x003406C4, 0x00351864,
0x003601A8, 0x00370388,
0x0038078A, 0x00390604,
0x003A0644, 0x003B0E24,
0x003C004A, 0x003D18A4,
0x003E1B24, 0x003F00EA,
0x00400F0A, 0x00410249,
0x00420D5D, 0x00431CC4,
0x00440328, 0x00450B29,
0x004606C6, 0x0047076A,
0x00480368, 0x004916C5,
0x004A0789, 0x004B0605,
0x004C0CC8, 0x004D1954,
0x004E0645, 0x004F0E25,
0x00500325, 0x00510B26,
0x005206C9, 0x00530764,
0x005408A9, 0x00550009,
0x005601A9, 0x00570389,
0x00580785, 0x00590609,
0x005A0049, 0x005B18A9,
0x005C0649, 0x005D0E29,
0x005E1B29, 0x005F00E9,
0x00600365, 0x006116C6,
0x00620786, 0x00630608,
0x00640788, 0x00650606,
0x00660046, 0x006718A8,
0x006858A6, 0x00690145,
0x006A01E9, 0x006B178A,
0x006C01E8, 0x006D1785,
0x006E1E28, 0x006F0C65,
0x00700CC5, 0x00711D5C,
0x00720648, 0x00730E28,
0x00740646, 0x00750E26,
0x00761B28, 0x007700E6,
0x007801E5, 0x00791786,
0x007A1E29, 0x007B0C68,
0x007C1E24, 0x007D0C69,
0x007E0955, 0x007F03C9,
0x008003E9, 0x00810975,
0x00820C49, 0x00831E04,
0x00840C48, 0x00851E05,
0x008617A6, 0x008701C5,
0x008800C6, 0x00891B08,
0x008A0E06, 0x008B0666,
0x008C0E08, 0x008D0668,
0x008E1D7C, 0x008F0CE5,
0x00900C45, 0x00911E08,
0x009217A9, 0x009301C4,
0x009417AA, 0x009501C9,
0x00960169, 0x0097588A,
0x00981888, 0x00990066,
0x009A0709, 0x009B07A8,
0x009C0704, 0x009D07A6,
0x009E16E6, 0x009F0345,
0x00A000C9, 0x00A11B05,
0x00A20E09, 0x00A30669,
0x00A41885, 0x00A50065,
0x00A60706, 0x00A707A5,
0x00A803A9, 0x00A90189,
0x00AA0029, 0x00AB0889,
0x00AC0744, 0x00AD06E9,
0x00AE0B06, 0x00AF0229,
0x00B00E05, 0x00B10665,
0x00B21974, 0x00B30CE8,
0x00B4070A, 0x00B507A9,
0x00B616E9, 0x00B70348,
0x00B8074A, 0x00B906E6,
0x00BA0B09, 0x00BB0226,
0x00BC1CE4, 0x00BD0D7D,
0x00BE0269, 0x00BF08C9,
0x00C000CA, 0x00C11B04,
0x00C21884, 0x00C3006A,
0x00C40E04, 0x00C50664,
0x00C60708, 0x00C707AA,
0x00C803A8, 0x00C90184,
0x00CA0749, 0x00CB06E4,
0x00CC0020, 0x00CD0888,
0x00CE0B08, 0x00CF0224,
0x00D00E0A, 0x00D1066A,
0x00D20705, 0x00D307A4,
0x00D41D78, 0x00D50CE9,
0x00D616EA, 0x00D70349,
0x00D80745, 0x00D906E8,
0x00DA1CE9, 0x00DB0D75,
0x00DC0B04, 0x00DD0228,
0x00DE0268, 0x00DF08C8,
0x00E003A5, 0x00E10185,
0x00E20746, 0x00E306EA,
0x00E40748, 0x00E506E5,
0x00E61CE8, 0x00E70D79,
0x00E81D74, 0x00E95CE6,
0x00EA02E9, 0x00EB0849,
0x00EC02E8, 0x00ED0848,
0x00EE0086, 0x00EF0A08,
0x00F00021, 0x00F10885,
0x00F20B05, 0x00F3022A,
0x00F40B0A, 0x00F50225,
0x00F60265, 0x00F708C5,
0x00F802E5, 0x00F90845,
0x00FA0089, 0x00FB0A09,
0x00FC008A, 0x00FD0A0A,
0x00FE02A9, 0x00FF0062,
};
if (!hbmMask)
return NtGdiBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop), 0, 0);
/* 1. make mask bitmap's dc */
hDCMask = NtGdiCreateCompatibleDC(hdcDest);
hOldMaskBitmap = (HBITMAP)NtGdiSelectObject(hDCMask, hbmMask);
/* 2. make masked Background bitmap */
/* 2.1 make bitmap */
hDC1 = NtGdiCreateCompatibleDC(hdcDest);
hBitmap2 = NtGdiCreateCompatibleBitmap(hdcDest, nWidth, nHeight);
hOldBitmap2 = (HBITMAP)NtGdiSelectObject(hDC1, hBitmap2);
/* 2.2 draw dest bitmap and mask */
NtGdiBitBlt(hDC1, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY, 0, 0);
NtGdiBitBlt(hDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, BKGND_ROP3(dwRop), 0, 0);
NtGdiBitBlt(hDC1, 0, 0, nWidth, nHeight, hDCMask, xMask, yMask, DSTERASE, 0, 0);
/* 3. make masked Foreground bitmap */
/* 3.1 make bitmap */
hDC2 = NtGdiCreateCompatibleDC(hdcDest);
hBitmap3 = NtGdiCreateCompatibleBitmap(hdcDest, nWidth, nHeight);
hOldBitmap3 = (HBITMAP)NtGdiSelectObject(hDC2, hBitmap3);
/* 3.2 draw src bitmap and mask */
NtGdiBitBlt(hDC2, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY, 0, 0);
NtGdiBitBlt(hDC2, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, FRGND_ROP3(dwRop), 0,0);
NtGdiBitBlt(hDC2, 0, 0, nWidth, nHeight, hDCMask, xMask, yMask, SRCAND, 0, 0);
/* 4. combine two bitmap and copy it to hdcDest */
NtGdiBitBlt(hDC1, 0, 0, nWidth, nHeight, hDC2, 0, 0, SRCPAINT, 0, 0);
NtGdiBitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hDC1, 0, 0, SRCCOPY, 0, 0);
/* 5. restore all object */
NtGdiSelectObject(hDCMask, hOldMaskBitmap);
NtGdiSelectObject(hDC1, hOldBitmap2);
NtGdiSelectObject(hDC2, hOldBitmap3);
/* 6. delete all temp object */
NtGdiDeleteObject(hBitmap2);
NtGdiDeleteObject(hBitmap3);
NtGdiDeleteObjectApp(hDC1);
NtGdiDeleteObjectApp(hDC2);
NtGdiDeleteObjectApp(hDCMask);
return TRUE;
}
BOOL
APIENTRY
NtGdiPlgBlt(
IN HDC hdcTrg,
IN LPPOINT pptlTrg,
IN HDC hdcSrc,
IN INT xSrc,
IN INT ySrc,
IN INT cxSrc,
IN INT cySrc,
IN HBITMAP hbmMask,
IN INT xMask,
IN INT yMask,
IN DWORD crBackColor)
{
UNIMPLEMENTED;
return FALSE;
}
BOOL STDCALL
NtGdiStretchBlt(
HDC hDCDest,
INT XOriginDest,
INT YOriginDest,
INT WidthDest,
INT HeightDest,
HDC hDCSrc,
INT XOriginSrc,
INT YOriginSrc,
INT WidthSrc,
INT HeightSrc,
DWORD ROP,
IN DWORD dwBackColor)
{
PDC DCDest = NULL;
PDC DCSrc = NULL;
BITMAPOBJ *BitmapDest, *BitmapSrc;
RECTL DestRect;
RECTL SourceRect;
BOOL Status;
XLATEOBJ *XlateObj = NULL;
HPALETTE SourcePalette = 0, DestPalette = 0;
PGDIBRUSHOBJ BrushObj;
BOOL UsesSource = ((ROP & 0xCC0000) >> 2) != (ROP & 0x330000);
BOOL UsesPattern = ((ROP & 0xF00000) >> 4) != (ROP & 0x0F0000);
if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
DCDest = DC_LockDc(hDCDest);
if (NULL == DCDest)
{
DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (DCDest->IsIC)
{
DC_UnlockDc(DCDest);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
if (UsesSource)
{
if (hDCSrc != hDCDest)
{
DCSrc = DC_LockDc(hDCSrc);
if (NULL == DCSrc)
{
DC_UnlockDc(DCDest);
DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (DCSrc->IsIC)
{
DC_UnlockDc(DCSrc);
DC_UnlockDc(DCDest);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
}
else
{
DCSrc = DCDest;
}
}
else
{
DCSrc = NULL;
}
/* Offset the destination and source by the origin of their DCs. */
XOriginDest += DCDest->w.DCOrgX;
YOriginDest += DCDest->w.DCOrgY;
if (UsesSource)
{
XOriginSrc += DCSrc->w.DCOrgX;
YOriginSrc += DCSrc->w.DCOrgY;
}
DestRect.left = XOriginDest;
DestRect.top = YOriginDest;
DestRect.right = XOriginDest+WidthDest;
DestRect.bottom = YOriginDest+HeightDest;
SourceRect.left = XOriginSrc;
SourceRect.top = YOriginSrc;
SourceRect.right = XOriginSrc+WidthSrc;
SourceRect.bottom = YOriginSrc+HeightSrc;
/* Determine surfaces to be used in the bitblt */
BitmapDest = BITMAPOBJ_LockBitmap(DCDest->w.hBitmap);
if (UsesSource)
{
if (DCSrc->w.hBitmap == DCDest->w.hBitmap)
BitmapSrc = BitmapDest;
else
BitmapSrc = BITMAPOBJ_LockBitmap(DCSrc->w.hBitmap);
}
else
{
BitmapSrc = NULL;
}
if ( UsesSource )
{
int sw = BitmapSrc->SurfObj.sizlBitmap.cx;
int sh = BitmapSrc->SurfObj.sizlBitmap.cy;
if ( SourceRect.left < 0 )
{
DestRect.left = DestRect.right - (DestRect.right-DestRect.left) * (SourceRect.right)/abs(SourceRect.right-SourceRect.left);
SourceRect.left = 0;
}
if ( SourceRect.top < 0 )
{
DestRect.top = DestRect.bottom - (DestRect.bottom-DestRect.top) * (SourceRect.bottom)/abs(SourceRect.bottom-SourceRect.top);
SourceRect.top = 0;
}
if ( SourceRect.right < -1 )
{
DestRect.right = DestRect.left + (DestRect.right-DestRect.left) * (-1-SourceRect.left)/abs(SourceRect.right-SourceRect.left);
SourceRect.right = -1;
}
if ( SourceRect.bottom < -1 )
{
DestRect.bottom = DestRect.top + (DestRect.bottom-DestRect.top) * (-1-SourceRect.top)/abs(SourceRect.bottom-SourceRect.top);
SourceRect.bottom = -1;
}
if ( SourceRect.right > sw )
{
DestRect.right = DestRect.left + (DestRect.right-DestRect.left) * abs(sw-SourceRect.left) / abs(SourceRect.right-SourceRect.left);
SourceRect.right = sw;
}
if ( SourceRect.bottom > sh )
{
DestRect.bottom = DestRect.top + (DestRect.bottom-DestRect.top) * abs(sh-SourceRect.top) / abs(SourceRect.bottom-SourceRect.top);
SourceRect.bottom = sh;
}
sw--;
sh--;
if ( SourceRect.left > sw )
{
DestRect.left = DestRect.right - (DestRect.right-DestRect.left) * (SourceRect.right-sw) / abs(SourceRect.right-SourceRect.left);
SourceRect.left = 0;
}
if ( SourceRect.top > sh )
{
DestRect.top = DestRect.bottom - (DestRect.bottom-DestRect.top) * (SourceRect.bottom-sh) / abs(SourceRect.bottom-SourceRect.top);
SourceRect.top = 0;
}
if (0 == (DestRect.right-DestRect.left) || 0 == (DestRect.bottom-DestRect.top) || 0 == (SourceRect.right-SourceRect.left) || 0 == (SourceRect.bottom-SourceRect.top))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
Status = FALSE;
goto failed;
}
}
if (UsesPattern)
{
BrushObj = BRUSHOBJ_LockBrush(DCDest->Dc_Attr.hbrush);
if (NULL == BrushObj)
{
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(DCSrc);
}
DC_UnlockDc(DCDest);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
}
else
{
BrushObj = NULL;
}
/* Create the XLATEOBJ. */
if (UsesSource)
{
if (DCDest->w.hPalette != 0)
DestPalette = DCDest->w.hPalette;
if (DCSrc->w.hPalette != 0)
SourcePalette = DCSrc->w.hPalette;
/* FIXME: Use the same logic for create XLATEOBJ as in NtGdiBitBlt. */
XlateObj = (XLATEOBJ*)IntEngCreateXlate(0, 0, DestPalette, SourcePalette);
if (NULL == XlateObj)
{
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(DCSrc);
}
DC_UnlockDc(DCDest);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return FALSE;
}
}
/* Perform the bitblt operation */
Status = IntEngStretchBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
NULL, DCDest->CombinedClip, XlateObj,
&DestRect, &SourceRect, NULL, NULL, NULL,
COLORONCOLOR);
if (UsesSource)
EngDeleteXlate(XlateObj);
if (UsesPattern)
{
BRUSHOBJ_UnlockBrush(BrushObj);
}
failed:
if (UsesSource && DCSrc->w.hBitmap != DCDest->w.hBitmap)
{
BITMAPOBJ_UnlockBitmap(BitmapSrc);
}
BITMAPOBJ_UnlockBitmap(BitmapDest);
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(DCSrc);
}
DC_UnlockDc(DCDest);
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -