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

📄 scdcrendimages_i.cpp

📁 Source code for EMFexplorer 1.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
*	This file is part of the EMFexplorer projet.
*	Copyright (C) 2004 Smith Charles.
*
*	This library is free software; you can redistribute it and/or
*	modify it under the terms of the GNU Lesser General Public
*	License as published by the Free Software Foundation; either
*	version 2.1 of the License, or (at your option) any later version.
*
*   This library 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
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
*
*	Extension: for commercial use, apply the Equity Public License, which
*	adds to the normal terms of the GLPL a condition of donation to the author.
*   If you are interested in support for this source code,
*   contact Smith Charles <smith.charles@free.fr> for more information.
*/


#include "stdafx.h"
#include "SCEMFdcRenderer.h"

using namespace Gdiplus;

///////////////////////////////////////////////////////////////////////////////////////
// Images/Pixels management
//

///
///	Draw a DIB bitmap.
///
void CSCEMFdcRenderer::SCDrawImage(LPCRECT pDest, LPCRECT pSrc, LPCBYTE pBits,
								 LPCBITMAPINFO pBmi, DWORD dwUsage, DWORD dwRop3,
								 XFORM* pXForm/*=NULL*/)
{
	ASSERT(m_pGraphics);
	ASSERT(pBmi && pBits && pDest && pSrc);

	// dwUsage can be: DIB_PAL_COLORS, DIB_PAL_INDICES, or DIB_RGB_COLORS
	ASSERT(dwUsage==DIB_RGB_COLORS || dwUsage==DIB_PAL_COLORS); // the other ones are not managed for now

	Bitmap* pBmp = NULL;
	HBITMAP hNewBmp = NULL;
	if (dwUsage==DIB_PAL_COLORS)
	{// Convert bitmap. Otherwise, GDI+ would mess with the color table.
		// Use a device-dependent bitmap + current palette combination
		HPALETTE hPal = (HPALETTE)::GetCurrentObject(m_hDC, OBJ_PAL);
		ASSERT(hPal);

#pragma message( __FILE__  "(43): TODO: create bitmap with destination DC instead of m_hDC ")
		hNewBmp = CreateDIBitmap(m_hDC, (BITMAPINFOHEADER*)pBmi, CBM_INIT, pBits, pBmi, dwUsage);
		pBmp = new Bitmap(hNewBmp, hPal);
	} else
	if (4==pBmi->bmiHeader.biBitCount)
	{// I don't see why Bitmap(pBmi, (VOID*)pBits) fails. Yet another color table problem?
		// tracking occurrences (4-bpp failure on w2k-xls/Tdb_fev00/page0013)
		hNewBmp = CreateDIBitmap(m_hDC, (BITMAPINFOHEADER*)pBmi, CBM_INIT, pBits, pBmi, dwUsage);
		pBmp = new Bitmap(hNewBmp, (HPALETTE)NULL);
	} else
	{
		// tracking occurrences (8-bpp passed with w98, w95-bmp/swtchbrd,
		// 1-bpp passed with "w98, w95-gif/santa workshop")
		//ASSERT(pBmi->bmiHeader.biBitCount>8);
		pBmp = new Bitmap(pBmi, (VOID*)pBits);
	}
	ASSERT(pBmp->GetLastStatus()==Ok);

	// Note: very special stuff here.
	// Convert sizes when a source transformation is present
	Matrix SvdMatrix;
	RECT rcSrc;
	if (pXForm)
	{
		// save current transform
		m_pGraphics->GetTransform(&SvdMatrix);

		// Convert the source with the source transform only
		// (because pXForm is the "world-space to page-space transformation of
		// the source device context" -- not the destination device -- when the record was registered)

		CopyRect(&rcSrc, pSrc);
		pSrc = &rcSrc;

		Matrix matrix(pXForm->eM11, pXForm->eM12, pXForm->eM21, pXForm->eM22,
			pXForm->eDx, pXForm->eDy);
		matrix.TransformPoints((Point*)pSrc, 2);
	}
	//

	Rect destRect(pDest->left, pDest->top, PRECT_WIDTH(pDest), PRECT_HEIGHT(pDest));

	// GDI+ 1.0: the ROP is simply let aside => unexpected results in perspective
	// Good place to say: GDI+ does not work!
	if (SRCCOPY==dwRop3)
	{
		// Copies the source rectangle directly to the destination rectangle. 
		m_pGraphics->DrawImage(pBmp, destRect,
		pSrc->left, pSrc->top, PRECT_WIDTH(pSrc), PRECT_HEIGHT(pSrc), UnitPixel, m_pImgAttribs);
	}
	else
	{// At the expense of some CPU time, GDI The Great will be called to do the job.

		// Check popular rops
		switch (dwRop3)
		{
		case BLACKNESS:
			// Fills the destination rectangle using the color associated with index 0
			// in the physical palette.
			// (This color is black for the default physical palette.)
			SCSysPaletteFillRect(this, destRect, 0);
			goto enddraw;

		case DSTINVERT:
			// Inverts the destination rectangle.
			break;

		case MERGECOPY:
			// Merges the colors of the source rectangle with the specified pattern
			// by using the Boolean AND operator.
			break;

		case MERGEPAINT:
			// Merges the colors of the inverted source rectangle with the colors
			// of the destination rectangle by using the Boolean OR operator. 
			break;

		case NOTSRCCOPY:
			// Copies the inverted source rectangle to the destination.
			break;

		case NOTSRCERASE:
			// Combines the colors of the source and destination rectangles by using
			// the Boolean OR operator and then inverts the resultant color.
			break;

		case PATCOPY:
			// Copies the specified pattern into the destination bitmap.
			ASSERT(m_pBrush);
			if (m_pBrush)
				m_pGraphics->FillRectangle(m_pBrush, destRect);
			goto enddraw;

		case PATINVERT:
			// Combines the colors of the specified pattern with the colors of the
			// destination rectangle by using the Boolean XOR operator.
			break;

		case PATPAINT:
			// Combines the colors of the pattern with the colors of the inverted
			// source rectangle by using the Boolean OR operator. The result of this
			// operation is combined with the colors of the destination rectangle by
			// using the Boolean OR operator. 
			break;

		case SRCAND:
			// Combines the colors of the source and destination rectangles by using
			// the Boolean AND operator. 
			break;

		case SRCERASE:
			// Combines the inverted colors of the destination rectangle with the
			// colors of the source rectangle by using the Boolean AND operator. 
			break;

		case SRCINVERT:
			// Combines the colors of the source and destination rectangles by using
			// the Boolean XOR operator.
			break;

		case SRCPAINT:
			// Combines the colors of the source and destination rectangles by using
			// the Boolean OR operator. 
			break;

		case WHITENESS:
			//Fills the destination rectangle using the color associated with index 1
			// in the physical palette.
			// (This color is white for the default physical palette.)
			SCSysPaletteFillRect(this, destRect, 1);
			goto enddraw;

		//case SRCCOPY: // done
		//	// Copies the source rectangle directly to the destination rectangle. 
		//	break;
		}

		// Wild, general rop management:
		// 1. if the rop implies the destination we must copy it
		// 2. if the rop implies the brush, we must use it
		SCStretchDIBits(this,
			destRect.X, destRect.Y, destRect.Width, destRect.Height,
			pSrc->left, pSrc->top, PRECT_WIDTH(pSrc), PRECT_HEIGHT(pSrc),
			pBits, pBmi, dwUsage, dwRop3);
	}
enddraw:
	if (pXForm)
		m_pGraphics->SetTransform(&SvdMatrix);
	if (hNewBmp)
		DeleteObject(hNewBmp);
	delete pBmp;
}

///
///	Draw GDI+ bitmap.
///
void CSCEMFdcRenderer::SCDrawBitmap(Bitmap* pBmp, Rect& rRcDest)
{
	ASSERT(m_pGraphics);
	ASSERT(pBmp);

	m_pGraphics->DrawImage(pBmp, rRcDest,
		0, 0, pBmp->GetWidth(), pBmp->GetHeight(), UnitPixel, m_pImgAttribs);
}

///
///	Draw a masked DIB bitmap into a parallelogram.
///
void CSCEMFdcRenderer::SCDrawImagePlg(LPCPOINTL p3PtDest,
					LPCRECT pSrc, LPCBYTE pBits, LPCBITMAPINFO pBmi,
					DWORD dwUsage, XFORM* pXForm, COLORREF crBkColorSrc,
					LONG lxMask, LONG lyMask,
					LPCBYTE pBitsMask, LPCBITMAPINFO pBmiMask, DWORD dwUsageMask)
{
	ASSERT(m_pGraphics);
	ASSERT(pBmi && pBits && p3PtDest && pSrc);

	// dwUsage can be: DIB_PAL_COLORS, DIB_PAL_INDICES, or DIB_RGB_COLORS
	ASSERT(dwUsage==DIB_RGB_COLORS); // the other ones are not managed for now

	// The p3PtDest array contains three points in logical space that identify three
	// corners of the destination parallelogram.
	// In GDI the mapping is as follows: the upper-left corner of the source rectangle is mapped to
	// the first point in this array, the upper-right corner to the second point in this array,
	// and the lower-left corner to the third point. The lower-right corner of the source
	// rectangle is mapped to the implicit fourth point in the parallelogram.
	// In GDI+: destPoints[0] <=> top-left, destPoints[1] <=> top-right, destPoints[2] <=> bottom-left
	Point destPoints[3];
	for (INT i=0; (i<3); i++)
	{
		destPoints[i].X = p3PtDest[i].x;
		destPoints[i].Y = p3PtDest[i].y;
	}

	if (!pBitsMask || !pBmiMask)
	{// No mask: just blt.
		Bitmap bmp(pBmi, (VOID*)pBits);
		m_pGraphics->DrawImage(&bmp, destPoints, 3,
			pSrc->left, pSrc->top, PRECT_WIDTH(pSrc), PRECT_HEIGHT(pSrc), UnitPixel, m_pImgAttribs);
	} else
	{// see the SCDrawImageMsk function for documentation.

		INT iHeight = abs(pBmi->bmiHeader.biHeight);
		INT iWidth = pBmi->bmiHeader.biWidth;
		BOOL bFlip = (pBmi->bmiHeader.biHeight>0);
		// lay out the mask on an array of bytes containg 0 or 1
		BYTE* pExpandedMask = SCExpandMask(iWidth, iHeight,
			lxMask, lyMask, pBitsMask, pBmiMask, dwUsageMask, !bFlip);
		if (!pExpandedMask)
			return;

		// create alpha bitmap
		HBITMAP hbm = SCBuildAlphaBitmap(pBits, pBmi, dwUsage, pExpandedMask, bFlip);
		if (hbm)
		{
			DIBSECTION ds;
			GetObject(hbm, sizeof(DIBSECTION), &ds);
			Bitmap bmp(iWidth, iHeight, 4*iWidth,
				PixelFormat32bppARGB, (BYTE*)ds.dsBm.bmBits); 

			// Draw the alpha bitmap
			m_pGraphics->DrawImage(&bmp, destPoints, 3,
				pSrc->left, pSrc->top, PRECT_WIDTH(pSrc), PRECT_HEIGHT(pSrc), UnitPixel, m_pImgAttribs);

			DeleteObject(hbm);
		}

		delete [] pExpandedMask;
	}
}

///
///	Mask Blt: uses a ROP4 to mask the source bitmap.
///
void CSCEMFdcRenderer::SCDrawImageMsk(LPCRECT pDest,
					LPCRECT pSrc, LPCBYTE pBits, LPCBITMAPINFO pBmi,
					DWORD dwUsage, DWORD dwRop4, XFORM* pXForm, COLORREF crBkColorSrc,
					LONG lxMask, LONG lyMask,
					LPCBYTE pBitsMask, LPCBITMAPINFO pBmiMask, DWORD dwUsageMask)
{
	ASSERT(m_pGraphics);
	ASSERT(pBmi && pBits && pDest && pSrc);

	// dwUsage can be: DIB_PAL_COLORS, DIB_PAL_INDICES, or DIB_RGB_COLORS
	ASSERT(dwUsage==DIB_RGB_COLORS); // the other ones are not managed for now
	Bitmap bmp(pBmi, (VOID*)pBits);

	if (!pBitsMask || !pBmiMask)
	{// No mask: just blt, using the foreground ROP index as ROP3.
		SCDrawImage(pDest, pSrc, pBits, pBmi, dwUsage,
			SCRop4GetForegroundROP3(dwRop4), pXForm);
	} else
	{
		INT iHeight = abs(pBmi->bmiHeader.biHeight);
		INT iWidth = pBmi->bmiHeader.biWidth;
		BOOL bFlip = (pBmi->bmiHeader.biHeight>0);
		// Lay out the mask on an array of bytes containg 0 or 1
		// Note: this layout must follow the same orientation as the bitmap (ie not flipped).
		BYTE* pExpandedMask = SCExpandMask(iWidth, iHeight,
			lxMask, lyMask, pBitsMask, pBmiMask, dwUsageMask, !bFlip);
		if (!pExpandedMask)
			return;

⌨️ 快捷键说明

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