NT4/private/wangview/norway/iedit95/transbmp.cpp
2020-09-30 17:12:29 +02:00

246 lines
7.7 KiB
C++

//=============================================================================
// (c) Copyright Wang Laboratories, Inc. 1995 All rights reserved.
//-----------------------------------------------------------------------------
// Project: Norway - Image Editor
//
// Component: CTransparentBmp
//
// File Name: transbmp.cpp
//
// Class: CTransparentBmp
//
// Functions:
//-----------------------------------------------------------------------------
// Maintenance Log:
/*
$Header:$
$Log: S:\norway\iedit95\transbmp.cpv $
Rev 1.1 29 Nov 1995 10:34:18 MMB
delete the bitmap when the destructor is called
Rev 1.0 21 Sep 1995 09:21:52 MMB
Initial entry
*/
//=============================================================================
// ----------------------------> Includes <-------------------------------
#include "stdafx.h"
#include "ieditetc.h"
#include "transbmp.h"
// ----------------------------> Globals <-------------------------------
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
// Colors
#define rgbWhite RGB(255,255,255)
// Raster op codes
#define DSa 0x008800C6L
#define DSx 0x00660046L
// ---------------------------> Message Maps <----------------------------
//=============================================================================
// Function: CTransparentBmp()
//-----------------------------------------------------------------------------
CTransparentBmp::CTransparentBmp()
{
m_iWidth = 0;
m_iHeight = 0;
m_hbmMask = NULL;
}
//=============================================================================
// Function: ~CTransparentBmp()
//-----------------------------------------------------------------------------
CTransparentBmp::~CTransparentBmp()
{
if (m_hbmMask)
{
::DeleteObject(m_hbmMask);
}
}
//=============================================================================
// Function: GetMetrics()
//-----------------------------------------------------------------------------
void CTransparentBmp::GetMetrics()
{
// Get the width and height
BITMAP bm;
GetObject(sizeof(bm), &bm);
m_iWidth = bm.bmWidth;
m_iHeight = bm.bmHeight;
}
//=============================================================================
// Function: GetWidth()
//-----------------------------------------------------------------------------
int CTransparentBmp::GetWidth()
{
if ((m_iWidth == 0) || (m_iHeight == 0))
{
GetMetrics();
}
return m_iWidth;
}
//=============================================================================
// Function: GetHeight()
//-----------------------------------------------------------------------------
int CTransparentBmp::GetHeight()
{
if ((m_iWidth == 0) || (m_iHeight == 0))
{
GetMetrics();
}
return m_iHeight;
}
//=============================================================================
// Function: Draw(HDC hDC, int x, int y)
//
//-----------------------------------------------------------------------------
void CTransparentBmp::Draw(HDC hDC, int x, int y)
{
ASSERT(hDC);
// Create a memory DC
HDC hdcMem = ::CreateCompatibleDC(hDC);
// Select the bitmap into the mem DC
HBITMAP hbmold =
(HBITMAP)::SelectObject(hdcMem,
(HBITMAP)(m_hObject));
// Blt the bits
::BitBlt(hDC,
x, y,
GetWidth(), GetHeight(),
hdcMem,
0, 0,
SRCCOPY);
::SelectObject(hdcMem, hbmold);
::DeleteDC(hdcMem);
}
//=============================================================================
// Function: Draw(CDC* pDC, int x, int y)
//
//-----------------------------------------------------------------------------
void CTransparentBmp::Draw(CDC* pDC, int x, int y)
{
ASSERT(pDC);
HDC hDC = pDC->GetSafeHdc();
Draw(hDC, x, y);
}
//=============================================================================
// Function: CreateMask(HDC hDC)
//
//-----------------------------------------------------------------------------
void CTransparentBmp::CreateMask(HDC hDC)
{
// Nuke any existing mask
if (m_hbmMask)
{
::DeleteObject(m_hbmMask);
}
// Create memory DCs to work with
HDC hdcMask = ::CreateCompatibleDC(hDC);
HDC hdcImage = ::CreateCompatibleDC(hDC);
// Create a monochrome bitmap for the mask
m_hbmMask = ::CreateBitmap(GetWidth(),
GetHeight(),
1,
1,
NULL);
// Select the mono bitmap into its DC
HBITMAP hbmOldMask = (HBITMAP)::SelectObject(hdcMask, m_hbmMask);
// Select the image bitmap into its DC
HBITMAP hbmOldImage = (HBITMAP)::SelectObject(hdcImage, m_hObject);
// Set the transparency color to be the top-left pixel
::SetBkColor(hdcImage, ::GetPixel(hdcImage, 0, 0));
// Make the mask
::BitBlt(hdcMask,
0, 0,
GetWidth(), GetHeight(),
hdcImage,
0, 0,
SRCCOPY);
// Tidy up
::SelectObject(hdcMask, hbmOldMask);
::SelectObject(hdcImage, hbmOldImage);
::DeleteDC(hdcMask);
::DeleteDC(hdcImage);
}
//=============================================================================
// Function: DrawTrans(HDC hDC, int x, int y)
//
//-----------------------------------------------------------------------------
void CTransparentBmp::DrawTrans(HDC hDC, int x, int y)
{
ASSERT(hDC);
if (!m_hbmMask) CreateMask(hDC);
ASSERT(m_hbmMask);
int dx = GetWidth();
int dy = GetHeight();
// Create a memory DC to do the drawing to
HDC hdcOffScr = ::CreateCompatibleDC(hDC);
// Create a bitmap for the off-screen DC that is really
// color compatible with the destination DC.
HBITMAP hbmOffScr = ::CreateBitmap(dx, dy,
(BYTE)GetDeviceCaps(hDC, PLANES),
(BYTE)GetDeviceCaps(hDC, BITSPIXEL),
NULL);
// Select the buffer bitmap into the off-screen DC
HBITMAP hbmOldOffScr = (HBITMAP)::SelectObject(hdcOffScr, hbmOffScr);
// Copy the image of the destination rectangle to the
// off-screen buffer DC so we can play with it
::BitBlt(hdcOffScr, 0, 0, dx, dy, hDC, x, y, SRCCOPY);
// Create a memory DC for the source image
HDC hdcImage = ::CreateCompatibleDC(hDC);
HBITMAP hbmOldImage = (HBITMAP)::SelectObject(hdcImage, m_hObject);
// Create a memory DC for the mask
HDC hdcMask = ::CreateCompatibleDC(hDC);
HBITMAP hbmOldMask = (HBITMAP)::SelectObject(hdcMask, m_hbmMask);
// XOR the image with the destination
::SetBkColor(hdcOffScr,rgbWhite);
::BitBlt(hdcOffScr, 0, 0, dx, dy ,hdcImage, 0, 0, DSx);
// AND the destination with the mask
::BitBlt(hdcOffScr, 0, 0, dx, dy, hdcMask, 0,0, DSa);
// XOR the destination with the image again
::BitBlt(hdcOffScr, 0, 0, dx, dy, hdcImage, 0, 0, DSx);
// Copy the resultant image back to the screen DC
::BitBlt(hDC, x, y, dx, dy, hdcOffScr, 0, 0, SRCCOPY);
// Tidy up
::SelectObject(hdcOffScr, hbmOldOffScr);
::SelectObject(hdcImage, hbmOldImage);
::SelectObject(hdcMask, hbmOldMask);
::DeleteObject(hbmOffScr);
::DeleteDC(hdcOffScr);
::DeleteDC(hdcImage);
::DeleteDC(hdcMask);
}
//=============================================================================
// Function: DrawTrans(CDC* pDC, int x, int y)
//
//-----------------------------------------------------------------------------
void CTransparentBmp::DrawTrans(CDC* pDC, int x, int y)
{
ASSERT(pDC);
HDC hDC = pDC->GetSafeHdc();
DrawTrans(hDC, x, y);
}