www.pudn.com > XRayImg.rar > PPDrawManager.cpp


#include "stdafx.h"
#include "PPDrawManager.h"

/*
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
*/

/*
DIBs use RGBQUAD format:
0xbb 0xgg 0xrr 0x00
*/
#ifndef CLR_TO_RGBQUAD
#define CLR_TO_RGBQUAD(clr) (RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)))
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CPPDrawManager::CPPDrawManager()
{

}

CPPDrawManager::~CPPDrawManager()
{

}

void CPPDrawManager::GetSizeOfIcon(HICON hIcon, LPSIZE pSize) const
{
pSize->cx = 0;
pSize->cy = 0;
if (hIcon != NULL)
{
ICONINFO ii;
// Gets icon dimension
::ZeroMemory(&amt;ii, sizeof(ICONINFO));
if (::GetIconInfo(hIcon, &amt;ii))
{
pSize->cx = (DWORD)(ii.xHotspot * 2);
pSize->cy = (DWORD)(ii.yHotspot * 2);
//release icon mask bitmaps
if(ii.hbmMask)
::DeleteObject(ii.hbmMask);
if(ii.hbmColor)
::DeleteObject(ii.hbmColor);
} //if
} //if
} //End GetSizeOfIcon

void CPPDrawManager::GetSizeOfBitmap(HBITMAP hBitmap, LPSIZE pSize) const
{
pSize->cx = 0;
pSize->cy = 0;
if (hBitmap != NULL)
{
BITMAP csBitmapSize;
// Get bitmap size
int nRetValue = ::GetObject(hBitmap, sizeof(csBitmapSize), &amt;csBitmapSize);
if (nRetValue)
{
pSize->cx = (DWORD)csBitmapSize.bmWidth;
pSize->cy = (DWORD)csBitmapSize.bmHeight;
} //if
} //if
} //End GetSizeOfBitmap

void CPPDrawManager::AlphaBitBlt(HDC hDestDC, int nDestX, int nDestY, DWORD dwWidth, DWORD dwHeight, HDC hSrcDC, int nSrcX, int nSrcY, int percent /* = 100 */)
{
_ASSERT ((NULL != hDestDC) || (NULL != hSrcDC));

if (percent >= 100)
{
::BitBlt(hDestDC, nDestX, nDestY, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, SRCCOPY);
return;
} //if

HDC hTempDC = ::CreateCompatibleDC(hDestDC);
if (NULL == hTempDC)
return;

//Creates Source DIB
LPBITMAPINFO lpbiSrc;
// Fill in the BITMAPINFOHEADER
lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiSrc->bmiHeader.biWidth = dwWidth;
lpbiSrc->bmiHeader.biHeight = dwHeight;
lpbiSrc->bmiHeader.biPlanes = 1;
lpbiSrc->bmiHeader.biBitCount = 32;
lpbiSrc->bmiHeader.biCompression = BI_RGB;
lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
lpbiSrc->bmiHeader.biClrUsed = 0;
lpbiSrc->bmiHeader.biClrImportant = 0;

COLORREF* pSrcBits = NULL;
HBITMAP hSrcDib = CreateDIBSection (
hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&amt;pSrcBits,
NULL, NULL);

if ((NULL != hSrcDib) &amt;&amt; (NULL != pSrcBits))
{
HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hSrcDib);
::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, SRCCOPY);
::SelectObject (hTempDC, hOldTempBmp);

//Creates Destination DIB
LPBITMAPINFO lpbiDest;
// Fill in the BITMAPINFOHEADER
lpbiDest = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiDest->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiDest->bmiHeader.biWidth = dwWidth;
lpbiDest->bmiHeader.biHeight = dwHeight;
lpbiDest->bmiHeader.biPlanes = 1;
lpbiDest->bmiHeader.biBitCount = 32;
lpbiDest->bmiHeader.biCompression = BI_RGB;
lpbiDest->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiDest->bmiHeader.biXPelsPerMeter = 0;
lpbiDest->bmiHeader.biYPelsPerMeter = 0;
lpbiDest->bmiHeader.biClrUsed = 0;
lpbiDest->bmiHeader.biClrImportant = 0;

COLORREF* pDestBits = NULL;
HBITMAP hDestDib = CreateDIBSection (
hDestDC, lpbiDest, DIB_RGB_COLORS, (void **)&amt;pDestBits,
NULL, NULL);

if ((NULL != hDestDib) &amt;&amt; (NULL != pDestBits))
{
::SelectObject (hTempDC, hDestDib);
::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hDestDC, nDestX, nDestY, SRCCOPY);
::SelectObject (hTempDC, hOldTempBmp);

double src_darken = (double)percent / 100.0;
double dest_darken = 1.0 - src_darken;

for (DWORD pixel = 0; pixel < dwWidth * dwHeight; pixel++, pSrcBits++, pDestBits++)
{
*pDestBits = PixelAlpha(*pSrcBits, src_darken, *pDestBits, dest_darken);
} //for

::SelectObject (hTempDC, hDestDib);
::BitBlt (hDestDC, nDestX, nDestY, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY);
::SelectObject (hTempDC, hOldTempBmp);

delete lpbiDest;
::DeleteObject(hDestDib);
} //if
delete lpbiSrc;
::DeleteObject(hSrcDib);
} //if

::DeleteDC(hTempDC);
} //End AlphaBitBlt

void CPPDrawManager::AlphaChannelBitBlt(HDC hDestDC, int nDestX, int nDestY, DWORD dwWidth, DWORD dwHeight, HDC hSrcDC, int nSrcX, int nSrcY)
{
_ASSERT ((NULL != hDestDC) || (NULL != hSrcDC));

HDC hTempDC = ::CreateCompatibleDC(hDestDC);
if (NULL == hTempDC)
return;

//Creates Source DIB
LPBITMAPINFO lpbiSrc;
// Fill in the BITMAPINFOHEADER
lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiSrc->bmiHeader.biWidth = dwWidth;
lpbiSrc->bmiHeader.biHeight = dwHeight;
lpbiSrc->bmiHeader.biPlanes = 1;
lpbiSrc->bmiHeader.biBitCount = 32;
lpbiSrc->bmiHeader.biCompression = BI_RGB;
lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
lpbiSrc->bmiHeader.biClrUsed = 0;
lpbiSrc->bmiHeader.biClrImportant = 0;

COLORREF* pSrcBits = NULL;
HBITMAP hSrcDib = CreateDIBSection (
hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&amt;pSrcBits,
NULL, NULL);

if ((NULL != hSrcDib) &amt;&amt; (NULL != pSrcBits))
{
HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hSrcDib);
::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hSrcDC, nSrcX, nSrcY, SRCCOPY);
::SelectObject (hTempDC, hOldTempBmp);

//Creates Destination DIB
LPBITMAPINFO lpbiDest;
// Fill in the BITMAPINFOHEADER
lpbiDest = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiDest->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiDest->bmiHeader.biWidth = dwWidth;
lpbiDest->bmiHeader.biHeight = dwHeight;
lpbiDest->bmiHeader.biPlanes = 1;
lpbiDest->bmiHeader.biBitCount = 32;
lpbiDest->bmiHeader.biCompression = BI_RGB;
lpbiDest->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiDest->bmiHeader.biXPelsPerMeter = 0;
lpbiDest->bmiHeader.biYPelsPerMeter = 0;
lpbiDest->bmiHeader.biClrUsed = 0;
lpbiDest->bmiHeader.biClrImportant = 0;

COLORREF* pDestBits = NULL;
HBITMAP hDestDib = CreateDIBSection (
hDestDC, lpbiDest, DIB_RGB_COLORS, (void **)&amt;pDestBits,
NULL, NULL);

if ((NULL != hDestDib) &amt;&amt; (NULL != pDestBits))
{
::SelectObject (hTempDC, hDestDib);
::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hDestDC, nDestX, nDestY, SRCCOPY);
::SelectObject (hTempDC, hOldTempBmp);

double src_darken;
BYTE nAlpha;

for (DWORD pixel = 0; pixel < dwWidth * dwHeight; pixel++, pSrcBits++, pDestBits++)
{
nAlpha = LOBYTE(*pSrcBits >> 24);
src_darken = (double)nAlpha / 255.0;
*pDestBits = PixelAlpha(*pSrcBits, src_darken, *pDestBits, 1.0 - src_darken);
} //for

::SelectObject (hTempDC, hDestDib);
::BitBlt (hDestDC, nDestX, nDestY, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY);
::SelectObject (hTempDC, hOldTempBmp);

delete lpbiDest;
::DeleteObject(hDestDib);
} //if
delete lpbiSrc;
::DeleteObject(hSrcDib);
} //if

::DeleteDC(hTempDC);
} //End of AlphaChannelBitBlt

HBITMAP CPPDrawManager::CreateImageEffect(HBITMAP hBitmap, DWORD dwWidth, DWORD dwHeight, DWORD dwEffect, BOOL bUseMask /* = TRUE */, COLORREF clrMask /* = RGB(255, 0, 255) */, COLORREF clrMono /* = RGB(255, 255, 255) */)
{
HBITMAP hOldSrcBmp = NULL;
HBITMAP hOldResBmp = NULL;
HDC hMainDC = NULL;
HDC hSrcDC = NULL;
HDC hResDC = NULL;

hMainDC = ::GetDC(NULL);
hSrcDC = ::CreateCompatibleDC(hMainDC);
hResDC = ::CreateCompatibleDC(hMainDC);

hOldSrcBmp = (HBITMAP)::SelectObject(hSrcDC, hBitmap);

LPBITMAPINFO lpbi;

// Fill in the BITMAPINFOHEADER
lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbi->bmiHeader.biWidth = dwWidth;
lpbi->bmiHeader.biHeight = dwHeight;
lpbi->bmiHeader.biPlanes = 1;
lpbi->bmiHeader.biBitCount = 32;
lpbi->bmiHeader.biCompression = BI_RGB;
lpbi->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbi->bmiHeader.biXPelsPerMeter = 0;
lpbi->bmiHeader.biYPelsPerMeter = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImportant = 0;

COLORREF* pBits = NULL;
HBITMAP hDibBmp = CreateDIBSection (
hSrcDC, lpbi, DIB_RGB_COLORS, (void **)&amt;pBits,
NULL, NULL);

if (hDibBmp == NULL || pBits == NULL)
{
delete lpbi;
_ASSERT (FALSE);
return NULL;
} //if

hOldResBmp = (HBITMAP)::SelectObject (hResDC, hDibBmp);
::BitBlt (hResDC, 0, 0, dwWidth, dwHeight, hSrcDC, 0, 0, SRCCOPY);

clrMask = CLR_TO_RGBQUAD(clrMask);
clrMono = CLR_TO_RGBQUAD(clrMono);

DWORD dwAlpha;
for (DWORD pixel = 0; pixel < dwWidth * dwHeight; pixel++, *pBits++)
{
COLORREF color = (COLORREF)*pBits;
//ENG: Extract an original alpha value
dwAlpha = color &amt; 0xFF000000;
if (dwAlpha != 0)
m_bIsAlpha = TRUE;
if (bUseMask &amt;&amt; (color == clrMask))
{
//This is transparent area
color = RGB(0, 0, 0);
}
else
{
//ENG: Color conversion
if (dwEffect &amt; IMAGE_EFFECT_GRAYEN) color = GrayMirrorColor(color);
if (dwEffect &amt; IMAGE_EFFECT_DARKEN) color = DarkenColor(color, 0.75);
if (dwEffect &amt; IMAGE_EFFECT_LIGHTEN) color = LightenColor(color, 0.25);
if (dwEffect &amt; IMAGE_EFFECT_MONOCHROME) color = clrMono;
} //if
if (dwEffect &amt; IMAGE_EFFECT_INVERT) color = InvertColor(color);
//ENG: Merges a color with an original alpha value
*pBits = (color | dwAlpha);
} //for

::SelectObject(hSrcDC, hOldSrcBmp);
::SelectObject(hResDC, hOldResBmp);
::DeleteDC(hSrcDC);
::DeleteDC(hResDC);
::ReleaseDC(NULL, hMainDC);

delete lpbi;

return hDibBmp;
} //End CreateImageEffect

//----------------------------------------------------------
// CPPDrawManager::GrayMirrorColor()
// Graying color in RGBQUAD format
//----------------------------------------------------------
// Parameter:
// clrColor - RGBQUAD value from DIB
// Return value:
// A grayed color in the RGBQUAD format
//----------------------------------------------------------
COLORREF CPPDrawManager::GrayMirrorColor(COLORREF clrColor)
{
BYTE nGrayColor = (BYTE)((GetBValue(clrColor) * 0.299) + (GetGValue(clrColor) * 0.587) + (GetRValue(clrColor) * 0.114));

return RGB(nGrayColor, nGrayColor, nGrayColor);
} //End of GrayMirrorColor

COLORREF CPPDrawManager::GrayColor(COLORREF clrColor)
{
BYTE nGrayColor = (BYTE)((GetRValue(clrColor) * 0.299) + (GetGValue(clrColor) * 0.587) + (GetBValue(clrColor) * 0.114));

return RGB(nGrayColor, nGrayColor, nGrayColor);
} //End GrayColor

COLORREF CPPDrawManager::InvertColor(COLORREF clrColor)
{
return RGB(255 - GetRValue(clrColor), 255 - GetGValue(clrColor), 255 - GetBValue(clrColor));
} //End InvertColor

COLORREF CPPDrawManager::DarkenColor(COLORREF clrColor, double darken)
{
if (darken >= 0.0 &amt;&amt; darken < 1.0)
{
BYTE color_r, color_g, color_b;
color_r = (BYTE)(GetRValue(clrColor) * darken);
color_g = (BYTE)(GetGValue(clrColor) * darken);
color_b = (BYTE)(GetBValue(clrColor) * darken);
clrColor = RGB(color_r, color_g, color_b);
} //if

return clrColor;
} //End DarkenColor

COLORREF CPPDrawManager::LightenColor(COLORREF clrColor, double lighten)
{
if (lighten > 0.0 &amt;&amt; lighten <= 1.0)
{
BYTE color_r, color_g, color_b;

lighten += 1.0;
color_r = (BYTE)min((DWORD)GetRValue(clrColor) * lighten, 255.0);
color_g = (BYTE)min((DWORD)GetGValue(clrColor) * lighten, 255.0);
color_b = (BYTE)min((DWORD)GetBValue(clrColor) * lighten, 255.0);
clrColor = RGB(color_r, color_g, color_b);
/*
lighten *= 255
color_r = (BYTE)max(0, min(255, (int)((color_r - 128) * 2.0 + 128 + lighten)));
color_g = (BYTE)max(0, min(255, (int)((color_g - 128) * 2.0 + 128 + lighten)));
color_b = (BYTE)max(0, min(255, (int)((color_b - 128) * 2.0 + 128 + lighten)));
clrColor = RGB(color_r, color_g, color_b);
*/
} //if

return clrColor;
} //End LightenColor

COLORREF CPPDrawManager::PixelAlpha(COLORREF clrSrc, double src_darken, COLORREF clrDest, double dest_darken)
{
return RGB (GetRValue (clrSrc) * src_darken + GetRValue (clrDest) * dest_darken,
GetGValue (clrSrc) * src_darken + GetGValue (clrDest) * dest_darken,
GetBValue (clrSrc) * src_darken + GetBValue (clrDest) * dest_darken);

} //End PixelAlpha

HICON CPPDrawManager::StretchIcon(HICON hIcon, DWORD dwWidth, DWORD dwHeight)
{
HICON hStretchedIcon = NULL;
HDC hMainDC = NULL;
HDC hSrcDC = NULL;
HDC hDestDC = NULL;
BITMAP bmp;
HBITMAP hOldSrcBitmap = NULL;
HBITMAP hOldDestBitmap = NULL;
ICONINFO csOriginal, csStretched;

if (!::GetIconInfo(hIcon, &amt;csOriginal))
return FALSE;

hMainDC = ::GetDC(NULL);
hSrcDC = ::CreateCompatibleDC(hMainDC);
hDestDC = ::CreateCompatibleDC(hMainDC);

if ((NULL == hMainDC) || (NULL == hSrcDC) || (NULL == hDestDC))
return NULL;

if (::GetObject(csOriginal.hbmColor, sizeof(BITMAP), &amt;bmp))
{
DWORD dwWidthOrg = csOriginal.xHotspot * 2;
DWORD dwHeightOrg = csOriginal.yHotspot * 2;

csStretched.hbmColor = ::CreateBitmap(dwWidth, dwHeight, bmp.bmPlanes, bmp.bmBitsPixel, NULL);
if (NULL != csStretched.hbmColor)
{
hOldSrcBitmap = (HBITMAP)::SelectObject(hSrcDC, csOriginal.hbmColor);
hOldDestBitmap = (HBITMAP)::SelectObject(hDestDC, csStretched.hbmColor);
::StretchBlt(hDestDC, 0, 0, dwWidth, dwHeight, hSrcDC, 0, 0, dwWidthOrg, dwHeightOrg, SRCCOPY);
if (::GetObject(csOriginal.hbmMask, sizeof(BITMAP), &amt;bmp))
{
csStretched.hbmMask = ::CreateBitmap(dwWidth, dwHeight, bmp.bmPlanes, bmp.bmBitsPixel, NULL);
if (NULL != csStretched.hbmMask)
{
::SelectObject(hSrcDC, csOriginal.hbmMask);
::SelectObject(hDestDC, csStretched.hbmMask);
::StretchBlt(hDestDC, 0, 0, dwWidth, dwHeight, hSrcDC, 0, 0, dwWidthOrg, dwHeightOrg, SRCCOPY);
} //if
} //if
::SelectObject(hSrcDC, hOldSrcBitmap);
::SelectObject(hDestDC, hOldDestBitmap);
csStretched.fIcon = TRUE;
hStretchedIcon = ::CreateIconIndirect(&amt;csStretched);
} //if
::DeleteObject(csStretched.hbmColor);
::DeleteObject(csStretched.hbmMask);
} //if

::DeleteObject(csOriginal.hbmColor);
::DeleteObject(csOriginal.hbmMask);
::DeleteDC(hSrcDC);
::DeleteDC(hDestDC);
::ReleaseDC(NULL, hMainDC);

return hStretchedIcon;
} //End StretchIcon

void CPPDrawManager::FillGradient (HDC hDC, LPCRECT lpRect,
COLORREF colorStart, COLORREF colorFinish,
BOOL bHorz/* = TRUE*/)
{
// this will make 2^6 = 64 fountain steps
int nShift = 6;
int nSteps = 1 << nShift;

RECT r2;
r2.top = lpRect->top;
r2.left = lpRect->left;
r2.right = lpRect->right;
r2.bottom = lpRect->bottom;

int nHeight = lpRect->bottom - lpRect->top;
int nWidth = lpRect->right - lpRect->left;

for (int i = 0; i < nSteps; i++)
{
// do a little alpha blending
BYTE bR = (BYTE) ((GetRValue(colorStart) * (nSteps - i) +
GetRValue(colorFinish) * i) >> nShift);
BYTE bG = (BYTE) ((GetGValue(colorStart) * (nSteps - i) +
GetGValue(colorFinish) * i) >> nShift);
BYTE bB = (BYTE) ((GetBValue(colorStart) * (nSteps - i) +
GetBValue(colorFinish) * i) >> nShift);

HBRUSH hBrush = ::CreateSolidBrush(RGB(bR, bG, bB));

// then paint with the resulting color

if (!bHorz)
{
r2.top = lpRect->top + ((i * nHeight) >> nShift);
r2.bottom = lpRect->top + (((i + 1) * nHeight) >> nShift);
if ((r2.bottom - r2.top) > 0)
::FillRect(hDC, &amt;r2, hBrush);
}
else
{
r2.left = lpRect->left + ((i * nWidth) >> nShift);
r2.right = lpRect->left + (((i + 1) * nWidth) >> nShift);
if ((r2.right - r2.left) > 0)
::FillRect(hDC, &amt;r2, hBrush);
} //if

if (NULL != hBrush)
{
::DeleteObject(hBrush);
hBrush = NULL;
} //if
} //for
} //End FillGradient

#ifdef USE_SHADE
void CPPDrawManager::SetShade(LPCRECT lpRect, UINT shadeID /* = 0 */, BYTE granularity /* = 8 */,
BYTE coloring /* = 0 */, COLORREF hicr /* = 0 */, COLORREF midcr /* = 0 */, COLORREF locr /* = 0 */)
{
long sXSize,sYSize,bytes,j,i,k,h;
BYTE *iDst ,*posDst;

sYSize = lpRect->bottom - lpRect->top;
sXSize = lpRect->right - lpRect->left;

m_dNormal.Create(sXSize,sYSize,8); //create the default bitmap

long r,g,b; //build the shaded palette
for(i = 0; i < 129; i++)
{
r=((128-i)*GetRValue(locr)+i*GetRValue(midcr))/128;
g=((128-i)*GetGValue(locr)+i*GetGValue(midcr))/128;
b=((128-i)*GetBValue(locr)+i*GetBValue(midcr))/128;
m_dNormal.SetPaletteIndex((BYTE)i,(BYTE)r,(BYTE)g,(BYTE)b);
} //for
for(i=1;i<129;i++){
r=((128-i)*GetRValue(midcr)+i*GetRValue(hicr))/128;
g=((128-i)*GetGValue(midcr)+i*GetGValue(hicr))/128;
b=((128-i)*GetBValue(midcr)+i*GetBValue(hicr))/128;
m_dNormal.SetPaletteIndex((BYTE)(i+127),(BYTE)r,(BYTE)g,(BYTE)b);
} //for

m_dNormal.BlendPalette(hicr,coloring); //color the palette

bytes = m_dNormal.GetLineWidth();
iDst = m_dNormal.GetBits();
posDst =iDst;
long a,x,y,d,xs,idxmax,idxmin;

int grainx2 = RAND_MAX/(max(1,2*granularity));
idxmax=255-granularity;
idxmin=granularity;

switch (shadeID)
{
//----------------------------------------------------
case EFFECT_METAL:
m_dNormal.Clear();
// create the strokes
k=40; //stroke granularity
for(a=0;a<200;a++){
x=rand()/(RAND_MAX/sXSize); //stroke postion
y=rand()/(RAND_MAX/sYSize); //stroke position
xs=rand()/(RAND_MAX/min(sXSize,sYSize))/2; //stroke lenght
d=rand()/(RAND_MAX/k); //stroke color
for(i=0;i<xs;i++){
if (((x-i)>0)&amt;&amt;((y+i)<sYSize))
m_dNormal.SetPixelIndex(x-i,y+i,(BYTE)d);
if (((x+i)<sXSize)&amt;&amt;((y-i)>0))
m_dNormal.SetPixelIndex(sXSize-x+i,y-i,(BYTE)d);
} //for
} //for
//blend strokes with SHS_DIAGONAL
posDst =iDst;
a=(idxmax-idxmin-k)/2;
for(i = 0; i < sYSize; i++) {
for(j = 0; j < sXSize; j++) {
d=posDst[j]+((a*i)/sYSize+(a*(sXSize-j))/sXSize);
posDst[j]=(BYTE)d;
posDst[j]+=rand()/grainx2;
} //for
posDst+=bytes;
} //for

break;
//----------------------------------------------------
case EFFECT_HARDBUMP: //
//set horizontal bump
for(i = 0; i < sYSize; i++) {
k=(255*i/sYSize)-127;
k=(k*(k*k)/128)/128;
k=(k*(128-granularity*2))/128+128;
for(j = 0; j < sXSize; j++) {
posDst[j]=(BYTE)k;
posDst[j]+=rand()/grainx2-granularity;
} //for
posDst+=bytes;
} //for
//set vertical bump
d=min(16,sXSize/6); //max edge=16
a=sYSize*sYSize/4;
posDst =iDst;
for(i = 0; i < sYSize; i++) {
y=i-sYSize/2;
for(j = 0; j < sXSize; j++) {
x=j-sXSize/2;
xs=sXSize/2-d+(y*y*d)/a;
if (x>xs) posDst[j]=(BYTE)idxmin+(BYTE)(((sXSize-j)*128)/d);
if ((x+xs)<0) posDst[j]=(BYTE)idxmax-(BYTE)((j*128)/d);
posDst[j]+=rand()/grainx2-granularity;
} //for
posDst+=bytes;
} //for
break;
//----------------------------------------------------
case EFFECT_SOFTBUMP: //
for(i = 0; i < sYSize; i++) {
h=(255*i/sYSize)-127;
for(j = 0; j < sXSize; j++) {
k=(255*(sXSize-j)/sXSize)-127;
k=(h*(h*h)/128)/128+(k*(k*k)/128)/128;
k=k*(128-granularity)/128+128;
if (k<idxmin) k=idxmin;
if (k>idxmax) k=idxmax;
posDst[j]=(BYTE)k;
posDst[j]+=rand()/grainx2-granularity;
} //for
posDst+=bytes;
} //for
break;
//----------------------------------------------------
case EFFECT_VBUMP: //
for(j = 0; j < sXSize; j++) {
k=(255*(sXSize-j)/sXSize)-127;
k=(k*(k*k)/128)/128;
k=(k*(128-granularity))/128+128;
for(i = 0; i < sYSize; i++) {
posDst[j+i*bytes]=(BYTE)k;
posDst[j+i*bytes]+=rand()/grainx2-granularity;
} //for
} //for
break;
//----------------------------------------------------
case EFFECT_HBUMP: //
for(i = 0; i < sYSize; i++) {
k=(255*i/sYSize)-127;
k=(k*(k*k)/128)/128;
k=(k*(128-granularity))/128+128;
for(j = 0; j < sXSize; j++) {
posDst[j]=(BYTE)k;
posDst[j]+=rand()/grainx2-granularity;
} //for
posDst+=bytes;
} //for
break;
//----------------------------------------------------
case EFFECT_DIAGSHADE: //
a=(idxmax-idxmin)/2;
for(i = 0; i < sYSize; i++) {
for(j = 0; j < sXSize; j++) {
posDst[j]=(BYTE)(idxmin+a*i/sYSize+a*(sXSize-j)/sXSize);
posDst[j]+=rand()/grainx2-granularity;
} //for
posDst+=bytes;
} //for
break;
//----------------------------------------------------
case EFFECT_HSHADE: //
a=idxmax-idxmin;
for(i = 0; i < sYSize; i++) {
k=a*i/sYSize+idxmin;
for(j = 0; j < sXSize; j++) {
posDst[j]=(BYTE)k;
posDst[j]+=rand()/grainx2-granularity;
} //for
posDst+=bytes;
} //for
break;
//----------------------------------------------------
case EFFECT_VSHADE: //:
a=idxmax-idxmin;
for(j = 0; j < sXSize; j++) {
k=a*(sXSize-j)/sXSize+idxmin;
for(i = 0; i < sYSize; i++) {
posDst[j+i*bytes]=(BYTE)k;
posDst[j+i*bytes]+=rand()/grainx2-granularity;
} //for
} //for
break;
//----------------------------------------------------
case EFFECT_NOISE:
for(i = 0; i < sYSize; i++) {
for(j = 0; j < sXSize; j++) {
posDst[j]=128+rand()/grainx2-granularity;
} //for
posDst+=bytes;
} //for
} //switch
//----------------------------------------------------
} //End SetShade
#endif

void CPPDrawManager::FillEffect(HDC hDC, DWORD dwEffect, LPCRECT lpRect, COLORREF clrBegin, COLORREF clrMid /* = 0 */, COLORREF clrEnd /* = 0 */, BYTE granularity /* = 0 */, BYTE coloring /* = 0 */)
{
HBRUSH hBrush = NULL;

RECT rect;
rect.left = lpRect->left;
rect.top = lpRect->top;
rect.right = lpRect->right;
rect.bottom = lpRect->bottom;

int nHeight = rect.bottom - rect.top;
int nWidth = rect.right - rect.left;

switch (dwEffect)
{
default:
hBrush = ::CreateSolidBrush(clrBegin);
::FillRect(hDC, lpRect, hBrush);
break;
case EFFECT_HGRADIENT:
FillGradient(hDC, lpRect, clrBegin, clrEnd, TRUE);
break;
case EFFECT_VGRADIENT:
FillGradient(hDC, lpRect, clrBegin, clrEnd, FALSE);
break;
case EFFECT_HCGRADIENT:
rect.right = rect.left + nWidth / 2;
FillGradient(hDC, &amt;rect, clrBegin, clrEnd, TRUE);
rect.left = rect.right;
rect.right = lpRect->right;
FillGradient(hDC, &amt;rect, clrEnd, clrBegin, TRUE);
break;
case EFFECT_3HGRADIENT:
rect.right = rect.left + nWidth / 2;
FillGradient(hDC, &amt;rect, clrBegin, clrMid, TRUE);
rect.left = rect.right;
rect.right = lpRect->right;
FillGradient(hDC, &amt;rect, clrMid, clrEnd, TRUE);
break;
case EFFECT_VCGRADIENT:
rect.bottom = rect.top + nHeight / 2;
FillGradient(hDC, &amt;rect, clrBegin, clrEnd, FALSE);
rect.top = rect.bottom;
rect.bottom = lpRect->bottom;
FillGradient(hDC, &amt;rect, clrEnd, clrBegin, FALSE);
break;
case EFFECT_3VGRADIENT:
rect.bottom = rect.top + nHeight / 2;
FillGradient(hDC, &amt;rect, clrBegin, clrMid, FALSE);
rect.top = rect.bottom;
rect.bottom = lpRect->bottom;
FillGradient(hDC, &amt;rect, clrMid, clrEnd, FALSE);
break;
#ifdef USE_SHADE
case EFFECT_NOISE:
case EFFECT_DIAGSHADE:
case EFFECT_HSHADE:
case EFFECT_VSHADE:
case EFFECT_HBUMP:
case EFFECT_VBUMP:
case EFFECT_SOFTBUMP:
case EFFECT_HARDBUMP:
case EFFECT_METAL:
rect.left = 0;
rect.top = 0;
rect.right = nWidth;
rect.bottom = nHeight;
SetShade(&amt;rect, dwEffect, granularity, coloring, clrBegin, clrMid, clrEnd);
m_dNormal.Draw(hDC, lpRect->left, lpRect->top);
break;
#endif
} //switch

if (NULL != hBrush)
{
::DeleteObject(hBrush);
hBrush = NULL;
} //if
} //End FillEffect

void CPPDrawManager::MultipleCopy(HDC hDestDC, int nDestX, int nDestY, DWORD dwDestWidth, DWORD dwDestHeight,
HDC hSrcDC, int nSrcX, int nSrcY, DWORD dwSrcWidth, DWORD dwSrcHeight)
{
// Horizontal copying
int right, bottom;
int nDestRight = (int)(nDestX + dwDestWidth);
int nDestBottom = (int)(nDestY + dwDestHeight);
for (int x = nDestX; x < nDestRight; x+= dwSrcWidth)
{
right = min (x + (int)dwSrcWidth, nDestRight);
// Vertical copying
for (int y = nDestY; y < nDestBottom; y+= dwSrcHeight)
{
bottom = min (y + (int)dwSrcHeight, nDestBottom);
::BitBlt(hDestDC, x, y, right - x, bottom - y, hSrcDC, nSrcX, nSrcY, SRCCOPY);
} //for
} //for
} //End MultipleCopy

void CPPDrawManager::DrawBitmap(HDC hDC, int x, int y, DWORD dwWidth, DWORD dwHeight, HBITMAP hSrcBitmap,
BOOL bUseMask, COLORREF crMask,
DWORD dwEffect /* = IMAGE_EFFECT_NONE */,
BOOL bShadow /* = FALSE */,
DWORD dwCxShadow /* = PPDRAWMANAGER_SHADOW_XOFFSET */,
DWORD dwCyShadow /* = PPDRAWMANAGER_SHADOW_YOFFSET */,
DWORD dwCxDepth /* = PPDRAWMANAGER_SHADOW_XDEPTH */,
DWORD dwCyDepth /* = PPDRAWMANAGER_SHADOW_YDEPTH */,
COLORREF clrShadow /* = PPDRAWMANAGER_SHADOW_COLOR */)
{
m_bIsAlpha = FALSE;
if (NULL == hSrcBitmap)
return;

SIZE sz;
GetSizeOfBitmap(hSrcBitmap, &amt;sz);

HDC hSrcDC = ::CreateCompatibleDC(hDC);
HDC hDestDC = ::CreateCompatibleDC(hDC);

HBITMAP hBitmapTemp = ::CreateCompatibleBitmap(hDC, dwWidth, dwHeight);

HBITMAP hOldSrcBitmap = (HBITMAP)::SelectObject(hSrcDC, hSrcBitmap);
HBITMAP hOldDestBitmap = (HBITMAP)::SelectObject(hDestDC, hBitmapTemp);

//Scales a bitmap if need
if (((DWORD)sz.cx != dwWidth) || ((DWORD)sz.cy != dwHeight))
::StretchBlt(hDestDC, 0, 0, dwWidth, dwHeight, hSrcDC, 0, 0, sz.cx, sz.cy, SRCCOPY);
else
::BitBlt(hDestDC, 0, 0, dwWidth, dwHeight, hSrcDC, 0, 0, SRCCOPY);

::SelectObject(hDestDC, hOldDestBitmap);

HBITMAP hMaskBmp = CreateImageEffect(hBitmapTemp, dwWidth, dwHeight, IMAGE_EFFECT_MASK, bUseMask, crMask);
HBITMAP hBitmap = CreateImageEffect(hBitmapTemp, dwWidth, dwHeight, dwEffect, bUseMask, crMask, clrShadow);

if (bShadow)
{
if (dwEffect &amt; IMAGE_EFFECT_SHADOW)
{
POINT ptShadow;
ptShadow.x = x + dwCxShadow;
ptShadow.y = y + dwCyShadow;
HBITMAP hShadowBmp = CreateImageEffect(hBitmapTemp, dwWidth, dwHeight, IMAGE_EFFECT_MASK, bUseMask, crMask, InvertColor(clrShadow));
DrawShadow(hDC, ptShadow.x, ptShadow.y, dwWidth, dwHeight, hShadowBmp, dwEffect &amt; IMAGE_EFFECT_GRADIENT_SHADOW, dwCxDepth, dwCyDepth);
::DeleteObject(hShadowBmp);
}
else
{
x += dwCxShadow;
y += dwCyShadow;
} //if
} //if

if (m_bIsAlpha)
{
::SelectObject(hSrcDC, hBitmap);
AlphaChannelBitBlt(hDC, x, y, dwWidth, dwHeight, hSrcDC, 0, 0);
}
else
{
//Merge the image mask with background
::SelectObject(hSrcDC, hMaskBmp);
::BitBlt(hDC, x, y, dwWidth, dwHeight, hSrcDC, 0, 0, SRCAND);

//Draw the image
::SelectObject(hSrcDC, hBitmap);
::BitBlt(hDC, x, y, dwWidth, dwHeight, hSrcDC, 0, 0, SRCPAINT);
}

::SelectObject(hSrcDC, hOldSrcBitmap);

::DeleteDC(hDestDC);
::DeleteDC(hSrcDC);

::DeleteObject(hBitmap);
::DeleteObject(hMaskBmp);
::DeleteObject(hBitmapTemp);
} //End DrawBitmap

void CPPDrawManager::DrawIcon(HDC hDC, int x, int y, DWORD dwWidth, DWORD dwHeight, HICON hSrcIcon,
DWORD dwEffect /* = IMAGE_EFFECT_NONE */,
BOOL bShadow /* = FALSE */,
DWORD dwCxShadow /* = PPDRAWMANAGER_SHADOW_XOFFSET */,
DWORD dwCyShadow /* = PPDRAWMANAGER_SHADOW_YOFFSET */,
DWORD dwCxDepth /* = PPDRAWMANAGER_SHADOW_XDEPTH */,
DWORD dwCyDepth /* = PPDRAWMANAGER_SHADOW_YDEPTH */,
COLORREF clrShadow /* = PPDRAWMANAGER_SHADOW_COLOR */)
{
m_bIsAlpha = FALSE;
if (NULL == hSrcIcon)
return;

SIZE sz;
GetSizeOfIcon(hSrcIcon, &amt;sz);

HICON hIcon = NULL;

if (((DWORD)sz.cx == dwWidth) &amt;&amt; ((DWORD)sz.cy == dwHeight))
hIcon = ::CopyIcon(hSrcIcon);
else hIcon = StretchIcon(hSrcIcon, dwWidth, dwHeight);

ICONINFO csOriginal;

if (!::GetIconInfo(hIcon, &amt;csOriginal))
return;

HDC hSrcDC = ::CreateCompatibleDC(hDC);

HBITMAP hBitmap;
if (dwEffect &amt; IMAGE_EFFECT_MONOCHROME)
hBitmap = CreateImageEffect(csOriginal.hbmMask, dwWidth, dwHeight, dwEffect, TRUE, RGB(255, 255, 255), clrShadow);
else
hBitmap = CreateImageEffect(csOriginal.hbmColor, dwWidth, dwHeight, dwEffect, TRUE, RGB(0, 0, 0), clrShadow);
HBITMAP hOldSrcBitmap = (HBITMAP)::SelectObject(hSrcDC, hBitmap);

if (bShadow)
{
if (dwEffect &amt; IMAGE_EFFECT_SHADOW)
{
POINT ptShadow;
ptShadow.x = x + dwCxShadow;
ptShadow.y = y + dwCyShadow;
HBITMAP hShadowBmp = CreateImageEffect(csOriginal.hbmMask, dwWidth, dwHeight, IMAGE_EFFECT_MASK, TRUE, RGB(255, 255, 255), InvertColor(clrShadow));
DrawShadow(hDC, ptShadow.x, ptShadow.y, dwWidth, dwHeight, hShadowBmp, dwEffect &amt; IMAGE_EFFECT_GRADIENT_SHADOW, dwCxDepth, dwCyDepth);
::DeleteObject(hShadowBmp);
}
else
{
x += dwCxShadow;
y += dwCyShadow;
} //if
} //if

if (m_bIsAlpha)
{
// ::SelectObject(hSrcDC, hBitmap);
AlphaChannelBitBlt(hDC, x, y, dwWidth, dwHeight, hSrcDC, 0, 0);
}
else
{
//-------------------------------------------------------------------
// !!! ATTENTION !!!
// I don't know why a icon uses text's color
// Therefore I change a text's color to BLACK and after draw I restore
// original color
//-------------------------------------------------------------------
COLORREF crOldColor = ::SetTextColor(hDC, RGB(0, 0, 0));
//Merge the image mask with background
::SelectObject(hSrcDC, csOriginal.hbmMask);
::BitBlt(hDC, x, y, dwWidth, dwHeight, hSrcDC, 0, 0, SRCAND);
//Draw the image
::SelectObject(hSrcDC, hBitmap);
::BitBlt(hDC, x, y, dwWidth, dwHeight, hSrcDC, 0, 0, SRCPAINT);
::SetTextColor(hDC, crOldColor);
} //if

::SelectObject(hSrcDC, hOldSrcBitmap);
::DeleteDC(hSrcDC);
::DeleteObject(hBitmap);
::DestroyIcon(hIcon);

::DeleteObject(csOriginal.hbmColor);
::DeleteObject(csOriginal.hbmMask);
} //End DrawIcon

void CPPDrawManager::DrawShadow(HDC hDestDC, int nDestX, int nDestY, DWORD dwWidth, DWORD dwHeight, HBITMAP hMask, BOOL bGradient /* = FALSE */, DWORD dwDepthX /* = PPDRAWMANAGER_SHADOW_YOFFSET */, DWORD dwDepthY /* = PPDRAWMANAGER_SHADOW_XOFFSET */)
{
HDC hSrcDC = ::CreateCompatibleDC(hDestDC);
if (NULL == hSrcDC)
return;

HDC hTempDC = ::CreateCompatibleDC(hDestDC);
if (NULL == hTempDC)
{
::DeleteDC(hSrcDC);
return;
} // if

//Creates Source DIB
LPBITMAPINFO lpbiSrc;
// Fill in the BITMAPINFOHEADER
lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiSrc->bmiHeader.biWidth = dwWidth;
lpbiSrc->bmiHeader.biHeight = dwHeight;
lpbiSrc->bmiHeader.biPlanes = 1;
lpbiSrc->bmiHeader.biBitCount = 32;
lpbiSrc->bmiHeader.biCompression = BI_RGB;
lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
lpbiSrc->bmiHeader.biClrUsed = 0;
lpbiSrc->bmiHeader.biClrImportant = 0;

COLORREF* pSrcBits = NULL;
HBITMAP hSrcDib = CreateDIBSection (
hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&amt;pSrcBits,
NULL, NULL);

if ((NULL != hSrcDib) &amt;&amt; (NULL != pSrcBits))
{
HBITMAP hOldSrcBmp = (HBITMAP)::SelectObject (hSrcDC, hSrcDib);
HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hMask);
if (bGradient)
{
if (!(dwDepthX &amt; 0x1)) dwDepthX++;
if (!(dwDepthY &amt; 0x1)) dwDepthY++;
::BitBlt(hSrcDC, 0, 0, dwWidth, dwHeight, hTempDC, 0, 0, WHITENESS);
::StretchBlt (hSrcDC, dwDepthX / 2, dwDepthY / 2, dwWidth - dwDepthX, dwHeight - dwDepthY, hTempDC, 0, 0, dwWidth, dwHeight, SRCCOPY);
}
else
{
::BitBlt(hSrcDC, 0, 0, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY);
} //if
::SelectObject (hTempDC, hOldTempBmp);
::SelectObject (hSrcDC, hOldSrcBmp);

//Creates Destination DIB
LPBITMAPINFO lpbiDest;
// Fill in the BITMAPINFOHEADER
lpbiDest = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiDest->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiDest->bmiHeader.biWidth = dwWidth;
lpbiDest->bmiHeader.biHeight = dwHeight;
lpbiDest->bmiHeader.biPlanes = 1;
lpbiDest->bmiHeader.biBitCount = 32;
lpbiDest->bmiHeader.biCompression = BI_RGB;
lpbiDest->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiDest->bmiHeader.biXPelsPerMeter = 0;
lpbiDest->bmiHeader.biYPelsPerMeter = 0;
lpbiDest->bmiHeader.biClrUsed = 0;
lpbiDest->bmiHeader.biClrImportant = 0;

COLORREF* pDestBits = NULL;
HBITMAP hDestDib = CreateDIBSection (
hDestDC, lpbiDest, DIB_RGB_COLORS, (void **)&amt;pDestBits,
NULL, NULL);

if ((NULL != hDestDib) &amt;&amt; (NULL != pDestBits))
{
::SelectObject (hTempDC, hDestDib);
::BitBlt (hTempDC, 0, 0, dwWidth, dwHeight, hDestDC, nDestX, nDestY, SRCCOPY);
::SelectObject (hTempDC, hOldTempBmp);

if (bGradient)
{
double * depth = new double [dwWidth * dwHeight];
SmoothMaskImage(dwWidth, dwHeight, pSrcBits, dwDepthX, dwDepthY, depth);
for(DWORD pixel = 0; pixel < dwWidth * dwHeight; pixel++, pDestBits++)
*pDestBits = DarkenColor(*pDestBits, *(depth + pixel));
delete [] depth;
}
else
{
for(DWORD pixel = 0; pixel < dwWidth * dwHeight; pixel++, pSrcBits++, pDestBits++)
*pDestBits = DarkenColor(*pDestBits, (double)GetRValue(*pSrcBits) / 255.0);
} //if


::SelectObject (hTempDC, hDestDib);
::BitBlt (hDestDC, nDestX, nDestY, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY);
::SelectObject (hTempDC, hOldTempBmp);

delete lpbiDest;
::DeleteObject(hDestDib);
} //if
delete lpbiSrc;
::DeleteObject(hSrcDib);
} //if
::DeleteDC(hTempDC);
::DeleteDC(hSrcDC);
} //End DrawIcon

void CPPDrawManager::DrawImageList(HDC hDC, int x, int y, DWORD dwWidth, DWORD dwHeight, HBITMAP hSrcBitmap,
int nIndex, int cx, int cy,
BOOL bUseMask, COLORREF crMask,
DWORD dwEffect /*= IMAGE_EFFECT_NONE*/,
BOOL bShadow /*= FALSE*/,
DWORD dwCxShadow /*= PPDRAWMANAGER_SHADOW_XOFFSET*/,
DWORD dwCyShadow /*= PPDRAWMANAGER_SHADOW_YOFFSET*/,
DWORD dwCxDepth /*= PPDRAWMANAGER_SHADOW_XDEPTH*/,
DWORD dwCyDepth /*= PPDRAWMANAGER_SHADOW_YDEPTH*/,
COLORREF clrShadow /*= PPDRAWMANAGER_SHADOW_COLOR*/)
{
if ((NULL == hSrcBitmap) || !cx || !cy)
return;

SIZE sz;
GetSizeOfBitmap(hSrcBitmap, &amt;sz);

//ENG: Gets a max columns and rows of the images on the bitmap
//RUS: Получаем максимальное число колонок и строк изображений на битмапке
int nMaxCol = sz.cx / cx;
int nMaxRow = sz.cy / cy;
int nMaxImages = nMaxCol * nMaxRow;

if ((nIndex < nMaxImages) &amt;&amt; nMaxCol &amt;&amt; nMaxRow)
{
//ENG: Gets an specified image from the bitmap
//RUS: Получаем указанное изображение из битмапа
HDC hSrcDC = ::CreateCompatibleDC(hDC);
HDC hDestDC = ::CreateCompatibleDC(hDC);
HBITMAP hIconBmp = ::CreateCompatibleBitmap(hDC, cx, cy);
HBITMAP hOldSrcBmp = (HBITMAP)::SelectObject(hSrcDC, hSrcBitmap);
HBITMAP hOldDestBmp = (HBITMAP)::SelectObject(hDestDC, hIconBmp);
::BitBlt(hDestDC, 0, 0, cx, cy, hSrcDC, (nIndex > nMaxCol) * cx, (nIndex / nMaxCol) * cy, SRCCOPY);
::SelectObject(hSrcDC, hOldSrcBmp);
::SelectObject(hDestDC, hOldDestBmp);
::DeleteDC(hSrcDC);
::DeleteDC(hDestDC);
DrawBitmap( hDC, x, y, dwWidth, dwHeight, hIconBmp,
bUseMask, crMask, dwEffect,
bShadow, dwCxShadow, dwCyShadow,
dwCxDepth, dwCyDepth, clrShadow);
::DeleteObject(hIconBmp);
} //if
} //End of DrawImageList

void CPPDrawManager::MaskToDepth(HDC hDC, DWORD dwWidth, DWORD dwHeight, HBITMAP hMask, double * pDepth, BOOL bGradient /* = FALSE */, DWORD dwDepthX /* = PPDRAWMANAGER_CXSHADOW */, DWORD dwDepthY /* = PPDRAWMANAGER_CYSHADOW */)
{
HDC hSrcDC = ::CreateCompatibleDC(hDC);
if (NULL == hSrcDC)
{
::DeleteDC(hSrcDC);
hSrcDC = NULL;
return;
} //if

HDC hTempDC = ::CreateCompatibleDC(hDC);
if (NULL == hTempDC)
{
::DeleteDC(hTempDC);
hTempDC = NULL;
return;
} //if

//Creates Source DIB
LPBITMAPINFO lpbiSrc;
// Fill in the BITMAPINFOHEADER
lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiSrc->bmiHeader.biWidth = dwWidth;
lpbiSrc->bmiHeader.biHeight = dwHeight;
lpbiSrc->bmiHeader.biPlanes = 1;
lpbiSrc->bmiHeader.biBitCount = 32;
lpbiSrc->bmiHeader.biCompression = BI_RGB;
lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
lpbiSrc->bmiHeader.biClrUsed = 0;
lpbiSrc->bmiHeader.biClrImportant = 0;

COLORREF* pSrcBits = NULL;
HBITMAP hSrcDib = CreateDIBSection (
hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&amt;pSrcBits,
NULL, NULL);

if ((NULL != hSrcDib) &amt;&amt; (NULL != pSrcBits))
{
HBITMAP hOldSrcBmp = (HBITMAP)::SelectObject (hSrcDC, hSrcDib);
HBITMAP hOldTempBmp = (HBITMAP)::SelectObject (hTempDC, hMask);
if (bGradient)
{
if (!(dwDepthX &amt; 0x1)) dwDepthX++;
if (!(dwDepthY &amt; 0x1)) dwDepthY++;
::BitBlt(hSrcDC, 0, 0, dwWidth, dwHeight, hTempDC, 0, 0, WHITENESS);
::StretchBlt (hSrcDC, dwDepthX / 2, dwDepthY / 2, dwWidth - dwDepthX, dwHeight - dwDepthY, hTempDC, 0, 0, dwWidth, dwHeight, SRCCOPY);
}
else
{
::BitBlt(hSrcDC, 0, 0, dwWidth, dwHeight, hTempDC, 0, 0, SRCCOPY);
} //if
::SelectObject (hTempDC, hOldTempBmp);
::SelectObject (hSrcDC, hOldSrcBmp);

if (bGradient)
{
SmoothMaskImage(dwWidth, dwHeight, pSrcBits, dwDepthX, dwDepthY, pDepth);
}
else
{
for (DWORD pixel = 0; pixel < (dwHeight * dwWidth); pixel++, pSrcBits++, pDepth++)
{
*pDepth = GetRValue(*pSrcBits) / 255;
} //for
} //if
delete lpbiSrc;
::DeleteObject(hSrcDib);
} //if
::DeleteDC(hTempDC);
::DeleteDC(hSrcDC);
} //End MaskToDepth

void CPPDrawManager::DarkenByDepth(HDC hDC, int x, int y, DWORD dwWidth, DWORD dwHeight, double * pDepth)
{
HDC hSrcDC = ::CreateCompatibleDC(hDC);
if (NULL == hSrcDC)
{
::DeleteDC(hSrcDC);
hSrcDC = NULL;
return;
} //if

//Creates Source DIB
LPBITMAPINFO lpbiSrc;
// Fill in the BITMAPINFOHEADER
lpbiSrc = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)];
lpbiSrc->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbiSrc->bmiHeader.biWidth = dwWidth;
lpbiSrc->bmiHeader.biHeight = dwHeight;
lpbiSrc->bmiHeader.biPlanes = 1;
lpbiSrc->bmiHeader.biBitCount = 32;
lpbiSrc->bmiHeader.biCompression = BI_RGB;
lpbiSrc->bmiHeader.biSizeImage = dwWidth * dwHeight;
lpbiSrc->bmiHeader.biXPelsPerMeter = 0;
lpbiSrc->bmiHeader.biYPelsPerMeter = 0;
lpbiSrc->bmiHeader.biClrUsed = 0;
lpbiSrc->bmiHeader.biClrImportant = 0;

COLORREF* pSrcBits = NULL;
HBITMAP hSrcDib = CreateDIBSection (
hSrcDC, lpbiSrc, DIB_RGB_COLORS, (void **)&amt;pSrcBits,
NULL, NULL);

if ((NULL != hSrcDib) &amt;&amt; (NULL != pSrcBits))
{
HBITMAP hOldSrcBmp = (HBITMAP)::SelectObject (hSrcDC, hSrcDib);
::BitBlt(hSrcDC, 0, 0, dwWidth, dwHeight, hDC, x, y, SRCCOPY);
::SelectObject (hSrcDC, hOldSrcBmp);

for (DWORD pixel = 0; pixel < (dwHeight * dwWidth); pixel++, pSrcBits++, pDepth++)
{
*pSrcBits = DarkenColor(*pSrcBits, *pDepth);
} //for

hOldSrcBmp = (HBITMAP)::SelectObject (hSrcDC, hSrcDib);
::BitBlt(hDC, x, y, dwWidth, dwHeight, hSrcDC, 0, 0, SRCCOPY);
::SelectObject (hSrcDC, hOldSrcBmp);

delete lpbiSrc;
::DeleteObject(hSrcDib);
} //if
::DeleteDC(hSrcDC);
} //DarkenByDepth

void CPPDrawManager::SmoothMaskImage(const int ImageWidth,
const int ImageHeight,
const COLORREF* const pInitImg,
const int KerWidth,
const int KerHeight,
double* const pResImg_R /*= NULL*/)
{
double* const pfBuff1 = new double[(ImageWidth + KerWidth - 1) *
(ImageHeight + KerHeight - 1)];
double* const pfBuff2 = new double[(ImageWidth + KerWidth - 1) *
(ImageHeight + KerHeight - 1)];

// expanding initial image with a padding procdure
double* p = pfBuff1;
const COLORREF * pInitImg_It = pInitImg;
if(NULL != pResImg_R)
{
for(int _i = - KerHeight/2; _i < ImageHeight + KerHeight/2; _i++)
{
for(int _j = -KerWidth/2; _j < ImageWidth + KerWidth/2; _j++, p++)
{
if ((_i >= 0) &amt;&amt; (_i < ImageHeight) &amt;&amt; (_j >= 0) &amt;&amt; (_j < ImageWidth))
{
*p = GetRValue(*pInitImg_It++);
// pInitImg_It++;
}
else
*p = 255;
} //for
} //for

//---
GetPartialSums(pfBuff1,
(ImageHeight + KerHeight - 1),
(ImageWidth + KerWidth - 1),
KerHeight,
KerWidth,
pfBuff2,
pResImg_R);

for(int i = 0; i < ImageHeight*ImageWidth; i++)
*(pResImg_R + i) /= KerHeight*KerWidth*255;
} //if


delete []pfBuff1;
delete []pfBuff2;
} //End SmoothMaskImage

void CPPDrawManager::GetPartialSums(const double* const pM,
unsigned int nMRows,
unsigned int nMCols,
unsigned int nPartRows,
unsigned int nPartCols,
double* const pBuff,
double* const pRes)
{
const double* it1;
const double* it2;
const double* it3;

double* pRowsPartSums;
const unsigned int nRowsPartSumsMRows = nMRows;
const unsigned int nRowsPartSumsMCols = nMCols - nPartCols + 1;

const unsigned int nResMRows = nMRows - nPartRows + 1;
const unsigned int nResMCols = nMCols - nPartCols + 1;


unsigned int i,j;
double s;

// частичные суммы строк
it1 = pM;
pRowsPartSums = pBuff;

for(i = 0; i < nMRows; i++)
{
//-------------
it2 = it1;
s = 0;
for(j = 0;j < nPartCols;j++)s+=*it2++;
//-------------
it3 = it1;
*pRowsPartSums++ = s;
for(/*j = nPartCols*/; j < nMCols; j++)
{
s+=*it2 - *it3;
*pRowsPartSums++ = s;
it2++;
it3++;
} //for
//--
it1 += nMCols;
} //for
// формирование резуьтата
const double* it4;
const double* it5;
const double* it6;

double* pResIt;

it4 = pBuff;
pResIt = pRes;

for(j = 0; j < nRowsPartSumsMCols; j++)
{
pResIt = pRes + j;
//-------------
it5 = it4;
s = 0;
for(i = 0; i < nPartRows; i++)
{
s += *it5;
it5 += nRowsPartSumsMCols;
} //for
//-------------
it6 = it4;
*pResIt = s;
pResIt += nRowsPartSumsMCols;

for(; i < nRowsPartSumsMRows; i++)
{
s += *it5 - *it6;//cout<<s<<endl;
*pResIt = s;
pResIt += nResMCols;
it5 += nRowsPartSumsMCols;
it6 += nRowsPartSumsMCols;
} //for
//--
it4 ++;
} //for
} //End GetPartialSums

void CPPDrawManager::DrawRectangle(HDC hDC, LPRECT lpRect, COLORREF crLight, COLORREF crDark, int nStyle /* = PEN_SOLID */, int nSize /* = 1 */)
{
DrawRectangle(hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom, crLight, crDark, nStyle, nSize);
}

void CPPDrawManager::DrawRectangle(HDC hDC, int left, int top, int right, int bottom,
COLORREF crLight, COLORREF crDark, int nStyle /* = PEN_SOLID */,
int nSize /* = 1 */)
{
if ((PEN_NULL == nStyle) || (nSize < 1))
return;

int nSysPenStyle = PS_SOLID;
int nDoubleLineOffset = nSize * 2;
switch (nStyle)
{
case PEN_DASH: nSysPenStyle = PS_DASH; break;
case PEN_DOT: nSysPenStyle = PS_DOT; break;
case PEN_DASHDOT: nSysPenStyle = PS_DASHDOT; break;
case PEN_DASHDOTDOT: nSysPenStyle = PS_DASHDOTDOT; break;
case PEN_DOUBLE:
case PEN_SOLID:
default:
nSysPenStyle = PS_SOLID;
break;
} //switch

//Insideframe
left += nSize / 2;
top += nSize / 2;
right -= nSize / 2;
bottom -= nSize / 2;

//Creates a light pen
HPEN hPen = ::CreatePen(nSysPenStyle, nSize, crLight);
HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);

//Draw light border
::MoveToEx(hDC, left, bottom, NULL);
::LineTo(hDC, left, top);
::LineTo(hDC, right, top);
if (PEN_DOUBLE == nStyle)
{
::MoveToEx(hDC, left + nDoubleLineOffset, bottom - nDoubleLineOffset, NULL);
::LineTo(hDC, left + nDoubleLineOffset, top + nDoubleLineOffset);
::LineTo(hDC, right - nDoubleLineOffset, top + nDoubleLineOffset);
} //if

//Creates a dark pen if needed
if (crLight != crDark)
{
SelectObject(hDC, hOldPen);
::DeleteObject(hPen);
hPen = ::CreatePen(nSysPenStyle, nSize, crDark);
hOldPen = (HPEN)::SelectObject(hDC, hPen);
} //if

//Draw dark border
::MoveToEx(hDC, right, top, NULL);
::LineTo(hDC, right, bottom);
::LineTo(hDC, left, bottom);
if (PEN_DOUBLE == nStyle)
{
::MoveToEx(hDC, right - nDoubleLineOffset, top + nDoubleLineOffset, NULL);
::LineTo(hDC, right - nDoubleLineOffset, bottom - nDoubleLineOffset);
::LineTo(hDC, left + nDoubleLineOffset, bottom - nDoubleLineOffset);
} //if

SelectObject(hDC, hOldPen);
::DeleteObject(hPen);
} //End DrawRectangle

void CPPDrawManager::DrawLine(HDC hDC,
int xStart, int yStart, int xEnd, int yEnd,
COLORREF color, int nStyle /* = PEN_SOLID */,
int nSize /* = 1 */) const
{
if ((PEN_NULL == nStyle) || (nSize < 1))
return;

int nSysPenStyle;
int nDoubleLineOffset = nSize * 2;
switch (nStyle)
{
case PEN_DASH: nSysPenStyle = PS_DASH; break;
case PEN_DOT: nSysPenStyle = PS_DOT; break;
case PEN_DASHDOT: nSysPenStyle = PS_DASHDOT; break;
case PEN_DASHDOTDOT: nSysPenStyle = PS_DASHDOTDOT; break;
case PEN_DOUBLE:
case PEN_SOLID:
default:
nSysPenStyle = PS_SOLID;
break;
} //switch

HPEN hPen = ::CreatePen(nSysPenStyle, nSize, color);
HPEN hOldPen = (HPEN)::SelectObject(hDC, hPen);

::MoveToEx(hDC, xStart, yStart, NULL);
::LineTo(hDC, xEnd, yEnd);

if (PEN_DOUBLE == nStyle)
{
if (xStart != xEnd)
{
yStart += nDoubleLineOffset;
yEnd += nDoubleLineOffset;
} //if

if (yStart != yEnd)
{
xStart += nDoubleLineOffset;
xEnd += nDoubleLineOffset;
} //if
::MoveToEx(hDC, xStart, yStart, NULL);
::LineTo(hDC, xEnd, yEnd);
} //if
SelectObject(hDC, hOldPen);
::DeleteObject(hPen);
} //End DrawLine