⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 painting.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  ReactOS W32 Subsystem
 *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/* $Id: bitmaps.c 28300 2007-08-12 15:20:09Z tkreuzer $ */

#include <w32k.h>

#define NDEBUG
#include <debug.h>



BOOL STDCALL
NtGdiAlphaBlend(
	HDC  hDCDest,
	LONG  XOriginDest,
	LONG  YOriginDest,
	LONG  WidthDest,
	LONG  HeightDest,
	HDC  hDCSrc,
	LONG  XOriginSrc,
	LONG  YOriginSrc,
	LONG  WidthSrc,
	LONG  HeightSrc,
	BLENDFUNCTION  BlendFunc,
	HANDLE hcmXform)
{
	PDC DCDest = NULL;
	PDC DCSrc  = NULL;
	BITMAPOBJ *BitmapDest, *BitmapSrc;
	RECTL DestRect, SourceRect;
	BOOL Status;
	XLATEOBJ *XlateObj;
	BLENDOBJ BlendObj;
	HPALETTE SourcePalette = 0, DestPalette = 0;
	BlendObj.BlendFunction = BlendFunc;

	DCDest = DC_LockDc(hDCDest);
	if (NULL == DCDest)
	{
		DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\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 (hDCSrc != hDCDest)
	{
		DCSrc = DC_LockDc(hDCSrc);
		if (NULL == DCSrc)
		{
			DC_UnlockDc(DCDest);
			DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\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;
	}

	/* Offset the destination and source by the origin of their DCs. */
	XOriginDest += DCDest->w.DCOrgX;
	YOriginDest += DCDest->w.DCOrgY;
	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 (DCSrc->w.hBitmap == DCDest->w.hBitmap)
		BitmapSrc = BitmapDest;
	else
		BitmapSrc = BITMAPOBJ_LockBitmap(DCSrc->w.hBitmap);

	/* Create the XLATEOBJ. */
	if (DCDest->w.hPalette != 0)
		DestPalette = DCDest->w.hPalette;
	if (DCSrc->w.hPalette != 0)
		SourcePalette = DCSrc->w.hPalette;

	/* KB41464 details how to convert between mono and color */
	if (DCDest->w.bitsPerPixel == 1 && DCSrc->w.bitsPerPixel == 1)
	{
		XlateObj = NULL;
	}
	else
	{
		if (DCDest->w.bitsPerPixel == 1)
		{
			XlateObj = IntEngCreateMonoXlate(0, DestPalette, SourcePalette, DCSrc->Dc_Attr.crBackgroundClr);
		}
		else if (DCSrc->w.bitsPerPixel == 1)
		{
			XlateObj = IntEngCreateSrcMonoXlate(DestPalette, DCSrc->Dc_Attr.crBackgroundClr, DCSrc->Dc_Attr.crForegroundClr);
		}
		else
		{
			XlateObj = IntEngCreateXlate(0, 0, DestPalette, SourcePalette);
		}
		if (NULL == XlateObj)
		{
			BITMAPOBJ_UnlockBitmap(BitmapDest);
			if (BitmapSrc != BitmapDest)
				BITMAPOBJ_UnlockBitmap(BitmapSrc);
			DC_UnlockDc(DCDest);
			if (hDCSrc != hDCDest)
				DC_UnlockDc(DCSrc);
			SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
			return FALSE;
		}
	}

	/* Perform the alpha blend operation */
	Status = IntEngAlphaBlend(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
	                          DCDest->CombinedClip, XlateObj,
	                          &DestRect, &SourceRect, &BlendObj);

	if (XlateObj != NULL)
		EngDeleteXlate(XlateObj);

	BITMAPOBJ_UnlockBitmap(BitmapDest);
	if (BitmapSrc != BitmapDest)
		BITMAPOBJ_UnlockBitmap(BitmapSrc);
	DC_UnlockDc(DCDest);
	if (hDCSrc != hDCDest)
		DC_UnlockDc(DCSrc);

	return Status;
}

BOOL STDCALL
NtGdiBitBlt(
	HDC  hDCDest,
	INT  XDest,
	INT  YDest,
	INT  Width,
	INT  Height,
	HDC  hDCSrc,
	INT  XSrc,
	INT  YSrc,
	DWORD  ROP,
	IN DWORD crBackColor,
	IN FLONG fl)
{
	PDC DCDest = NULL;
	PDC DCSrc  = NULL;
	BITMAPOBJ *BitmapDest, *BitmapSrc;
	RECTL DestRect;
	POINTL SourcePoint, BrushOrigin;
	BOOL Status;
	XLATEOBJ *XlateObj = NULL;
	HPALETTE SourcePalette = 0, DestPalette = 0;
	PGDIBRUSHOBJ BrushObj;
	GDIBRUSHINST BrushInst;
	BOOL UsesSource = ROP3_USES_SOURCE(ROP);
	BOOL UsesPattern = ROP3_USES_PATTERN(ROP);

	DCDest = DC_LockDc(hDCDest);
	if (NULL == DCDest)
	{
		DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\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 NtGdiBitBlt\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. */
	XDest += DCDest->w.DCOrgX;
	YDest += DCDest->w.DCOrgY;
	if (UsesSource)
	{
		XSrc += DCSrc->w.DCOrgX;
		YSrc += DCSrc->w.DCOrgY;
	}

	DestRect.left   = XDest;
	DestRect.top    = YDest;
	DestRect.right  = XDest+Width;
	DestRect.bottom = YDest+Height;

	IntLPtoDP(DCDest, (LPPOINT)&DestRect, 2);

	SourcePoint.x = XSrc;
	SourcePoint.y = YSrc;

	BrushOrigin.x = 0;
	BrushOrigin.y = 0;

	/* 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 (UsesPattern)
	{
		BrushObj = BRUSHOBJ_LockBrush(DCDest->Dc_Attr.hbrush);
		if (NULL == BrushObj)
		{
			if (UsesSource && hDCSrc != hDCDest)
			{
				DC_UnlockDc(DCSrc);
			}
			if(BitmapDest != NULL)
			{
				BITMAPOBJ_UnlockBitmap(BitmapDest);
			}
			if(BitmapSrc != NULL && BitmapSrc != BitmapDest)
			{
				BITMAPOBJ_UnlockBitmap(BitmapSrc);
			}
			DC_UnlockDc(DCDest);
			SetLastWin32Error(ERROR_INVALID_HANDLE);
			return FALSE;
		}
		BrushOrigin = *((PPOINTL)&BrushObj->ptOrigin);
		IntGdiInitBrushInstance(&BrushInst, BrushObj, DCDest->XlateBrush);
	}
	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;

		/* KB41464 details how to convert between mono and color */
		if (DCDest->w.bitsPerPixel == 1 && DCSrc->w.bitsPerPixel == 1)
		{
			XlateObj = NULL;
		}
		else
		{
			if (DCDest->w.bitsPerPixel == 1)
			{
				XlateObj = IntEngCreateMonoXlate(0, DestPalette, SourcePalette, DCSrc->Dc_Attr.crBackgroundClr);
			}
			else if (DCSrc->w.bitsPerPixel == 1)
			{
				XlateObj = IntEngCreateSrcMonoXlate(DestPalette, DCSrc->Dc_Attr.crBackgroundClr, DCSrc->Dc_Attr.crForegroundClr);
			}
			else
			{
				XlateObj = IntEngCreateXlate(0, 0, DestPalette, SourcePalette);
			}
			if (NULL == XlateObj)
			{
				if (UsesSource && hDCSrc != hDCDest)
				{
					DC_UnlockDc(DCSrc);
				}
				DC_UnlockDc(DCDest);
				if(BitmapDest != NULL)
				{
					BITMAPOBJ_UnlockBitmap(BitmapDest);
				}
				if(BitmapSrc != NULL && BitmapSrc != BitmapDest)
				{
					BITMAPOBJ_UnlockBitmap(BitmapSrc);
				}
				if(BrushObj != NULL)
				{
					BRUSHOBJ_UnlockBrush(BrushObj);
				}
				SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
				return FALSE;
			}
		}
	}

	/* Perform the bitblt operation */
	Status = IntEngBitBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, NULL,
                          DCDest->CombinedClip, XlateObj, &DestRect,
                          &SourcePoint, NULL,
                          BrushObj ? &BrushInst.BrushObject : NULL,
                          &BrushOrigin, ROP3_TO_ROP4(ROP));

	if (UsesSource && XlateObj != NULL)
		EngDeleteXlate(XlateObj);

	if(BitmapDest != NULL)
	{
		BITMAPOBJ_UnlockBitmap(BitmapDest);
	}
	if (UsesSource && BitmapSrc != BitmapDest)
	{
		BITMAPOBJ_UnlockBitmap(BitmapSrc);
	}
	if (BrushObj != NULL)
	{
		BRUSHOBJ_UnlockBrush(BrushObj);
	}
	if (UsesSource && hDCSrc != hDCDest)
	{
		DC_UnlockDc(DCSrc);
	}
	DC_UnlockDc(DCDest);

	return Status;
}

BOOL STDCALL
NtGdiTransparentBlt(
	HDC			hdcDst,
	INT			xDst,
	INT			yDst,
	INT			cxDst,
	INT			cyDst,
	HDC			hdcSrc,
	INT			xSrc,
	INT			ySrc,
	INT			cxSrc,
	INT			cySrc,
	COLORREF	TransColor)
{
  PDC DCDest, DCSrc;
  RECTL rcDest, rcSrc;
  BITMAPOBJ *BitmapDest, *BitmapSrc;
  XLATEOBJ *XlateObj;
  HPALETTE SourcePalette = 0, DestPalette = 0;
  PPALGDI PalDestGDI, PalSourceGDI;
  USHORT PalDestMode, PalSrcMode;
  ULONG TransparentColor = 0;
  BOOL Ret = FALSE;

  if(!(DCDest = DC_LockDc(hdcDst)))
  {
    DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcDst);
    SetLastWin32Error(ERROR_INVALID_HANDLE);
    return FALSE;
  }
  if (DCDest->IsIC)
  {
    DC_UnlockDc(DCDest);
    /* Yes, Windows really returns TRUE in this case */
    return TRUE;
  }

  if((hdcDst != hdcSrc) && !(DCSrc = DC_LockDc(hdcSrc)))
  {
    DC_UnlockDc(DCDest);
    DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcSrc);
    SetLastWin32Error(ERROR_INVALID_HANDLE);
    return FALSE;
  }
  if(hdcDst == hdcSrc)
  {
    DCSrc = DCDest;
  }
  if (DCSrc->IsIC)
  {
    DC_UnlockDc(DCSrc);
    if(hdcDst != hdcSrc)
    {
      DC_UnlockDc(DCDest);
    }
    /* Yes, Windows really returns TRUE in this case */
    return TRUE;
  }

  /* Offset positions */
  xDst += DCDest->w.DCOrgX;
  yDst += DCDest->w.DCOrgY;
  xSrc += DCSrc->w.DCOrgX;
  ySrc += DCSrc->w.DCOrgY;

  if(DCDest->w.hPalette)
    DestPalette = DCDest->w.hPalette;

  if(DCSrc->w.hPalette)
    SourcePalette = DCSrc->w.hPalette;

  if(!(PalSourceGDI = PALETTE_LockPalette(SourcePalette)))
  {
    DC_UnlockDc(DCSrc);
    DC_UnlockDc(DCDest);
    SetLastWin32Error(ERROR_INVALID_HANDLE);
    return FALSE;
  }
  if((DestPalette != SourcePalette) && !(PalDestGDI = PALETTE_LockPalette(DestPalette)))
  {
    PALETTE_UnlockPalette(PalSourceGDI);
    DC_UnlockDc(DCSrc);
    DC_UnlockDc(DCDest);
    SetLastWin32Error(ERROR_INVALID_HANDLE);
    return FALSE;
  }
  if(DestPalette != SourcePalette)
  {
    PalDestMode = PalDestGDI->Mode;
    PalSrcMode = PalSourceGDI->Mode;
    PALETTE_UnlockPalette(PalDestGDI);
  }
  else
  {
    PalDestMode = PalSrcMode = PalSourceGDI->Mode;
  }
  PALETTE_UnlockPalette(PalSourceGDI);

  /* Translate Transparent (RGB) Color to the source palette */
  if((XlateObj = (XLATEOBJ*)IntEngCreateXlate(PalSrcMode, PAL_RGB, SourcePalette, NULL)))
  {
    TransparentColor = XLATEOBJ_iXlate(XlateObj, (ULONG)TransColor);
    EngDeleteXlate(XlateObj);
  }

  /* Create the XLATE object to convert colors between source and destination */
  XlateObj = (XLATEOBJ*)IntEngCreateXlate(PalDestMode, PalSrcMode, DestPalette, SourcePalette);

  BitmapDest = BITMAPOBJ_LockBitmap(DCDest->w.hBitmap);
  /* FIXME - BitmapDest can be NULL!!!! Don't assert here! */
  ASSERT(BitmapDest);
  BitmapSrc = BITMAPOBJ_LockBitmap(DCSrc->w.hBitmap);
  /* FIXME - BitmapSrc can be NULL!!!! Don't assert here! */
  ASSERT(BitmapSrc);

  rcDest.left = xDst;
  rcDest.top = yDst;
  rcDest.right = rcDest.left + cxDst;
  rcDest.bottom = rcDest.top + cyDst;
  rcSrc.left = xSrc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -