You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
778 lines
20 KiB
C++
778 lines
20 KiB
C++
2 years ago
|
// XTPSkinImage.cpp: implementation of the CXTPSkinImage class.
|
||
|
//
|
||
|
// This file is a part of the XTREME SKINFRAMEWORK MFC class library.
|
||
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
||
|
//
|
||
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
||
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
||
|
// CONSENT OF CODEJOCK SOFTWARE.
|
||
|
//
|
||
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
||
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
||
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
||
|
// SINGLE COMPUTER.
|
||
|
//
|
||
|
// CONTACT INFORMATION:
|
||
|
// support@codejock.com
|
||
|
// http://www.codejock.com
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
|
||
|
#include "Common/Tmschema.h"
|
||
|
#include "Common/XTPImageManager.h"
|
||
|
#include "Common/XTPColorManager.h"
|
||
|
#include "Common/XTPDrawHelpers.h"
|
||
|
#include "Common/XTPVC80Helpers.h"
|
||
|
|
||
|
#include "XTPSkinImage.h"
|
||
|
#include "XTPSkinManagerResource.h"
|
||
|
#include "XTPSkinManager.h"
|
||
|
#include "XTPSkinManagerSchema.h"
|
||
|
#include "XTPSkinDrawTools.h"
|
||
|
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#undef THIS_FILE
|
||
|
static char THIS_FILE[]=__FILE__;
|
||
|
#define new DEBUG_NEW
|
||
|
#endif
|
||
|
|
||
|
#define TILE_VERTICAL 1
|
||
|
#define TILE_HORIZONTAL 2
|
||
|
#define TILE_ALL 3
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////
|
||
|
// CXTPSkinImage
|
||
|
|
||
|
CXTPSkinImage::CXTPSkinImage()
|
||
|
{
|
||
|
m_hBitmap = NULL;
|
||
|
m_bAlpha = FALSE;
|
||
|
m_bFiltered = FALSE;
|
||
|
m_bInvert = FALSE;
|
||
|
m_bMirrorImage = TRUE;
|
||
|
m_bOptimized = FALSE;
|
||
|
m_clrTransparent = COLORREF_NULL;
|
||
|
}
|
||
|
|
||
|
CXTPSkinImage::~CXTPSkinImage()
|
||
|
{
|
||
|
if (m_hBitmap != NULL)
|
||
|
{
|
||
|
DeleteObject(m_hBitmap);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CXTPSkinImage::SetBitmap(HBITMAP hBitmap, BOOL bAlpha /*= FALSE*/)
|
||
|
{
|
||
|
ASSERT(m_hBitmap == NULL);
|
||
|
|
||
|
m_hBitmap = hBitmap;
|
||
|
m_bAlpha = bAlpha;
|
||
|
|
||
|
m_bOptimized = FALSE;
|
||
|
m_arrSolidRects.RemoveAll();
|
||
|
|
||
|
m_szBitmap = _GetExtent();
|
||
|
}
|
||
|
|
||
|
#define FREE(hHandle) if (hHandle) { free(hHandle); hHandle = 0; }
|
||
|
|
||
|
|
||
|
BOOL CXTPSkinImage::CheckBitmapRect(LPBYTE pBits, CRect rcCheck, CSize sz)
|
||
|
{
|
||
|
if (rcCheck.left >= rcCheck.right || rcCheck.top >= rcCheck.bottom ||
|
||
|
rcCheck.left < 0 || rcCheck.top < 0 || rcCheck.right >= sz.cx || rcCheck.bottom >= sz.cy)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL bFirst = TRUE;
|
||
|
COLORREF clrTransparent = COLORREF_NULL;
|
||
|
|
||
|
for (int x = rcCheck.left; x < rcCheck.right; x++)
|
||
|
for (int y = rcCheck.top; y < rcCheck.bottom; y++)
|
||
|
{
|
||
|
COLORREF clr = ((LPDWORD)pBits)[x + (sz.cy - y - 1) * sz.cx];
|
||
|
|
||
|
if (bFirst)
|
||
|
clrTransparent = clr;
|
||
|
else if (clrTransparent != clr)
|
||
|
return FALSE;
|
||
|
|
||
|
bFirst = FALSE;
|
||
|
}
|
||
|
|
||
|
SOLIDRECT sr;
|
||
|
sr.rc = rcCheck;
|
||
|
sr.clr = RGB(GetBValue(clrTransparent), GetGValue(clrTransparent), GetRValue(clrTransparent));
|
||
|
|
||
|
if (m_bAlpha)
|
||
|
sr.clr |= (clrTransparent & 0xFF000000);
|
||
|
|
||
|
m_arrSolidRects.Add(sr);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPSkinImage::CreateSolidRectArray(int nBitmaps, BOOL bHorizontalImage, const CRect& rcSizingMargins)
|
||
|
{
|
||
|
ASSERT(nBitmaps >= 1);
|
||
|
if (!m_hBitmap || nBitmaps < 1)
|
||
|
return;
|
||
|
|
||
|
if (m_bOptimized || m_bFiltered)
|
||
|
return;
|
||
|
|
||
|
if (nBitmaps == 1)
|
||
|
bHorizontalImage = FALSE;
|
||
|
|
||
|
CSize sz(GetExtent());
|
||
|
|
||
|
m_bOptimized = TRUE;
|
||
|
m_arrSolidRects.RemoveAll();
|
||
|
|
||
|
HBITMAP hbm = NULL;
|
||
|
LPBYTE pBits = NULL;
|
||
|
|
||
|
CDC dcSrc;
|
||
|
dcSrc.CreateCompatibleDC(NULL);
|
||
|
|
||
|
TRY
|
||
|
{
|
||
|
if (!m_bAlpha)
|
||
|
{
|
||
|
hbm = CXTPImageManager::Create32BPPDIBSection(dcSrc, sz.cx, sz.cy, &pBits);
|
||
|
|
||
|
{
|
||
|
CXTPCompatibleDC dc(NULL, hbm);
|
||
|
dc.DrawState(CPoint(0, 0), sz, m_hBitmap, 0, NULL);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
PBITMAPINFO pBitmapInfo = 0;
|
||
|
|
||
|
UINT nSize;
|
||
|
if (!CXTPImageManagerIcon::GetBitmapBits(dcSrc, m_hBitmap, pBitmapInfo, (LPVOID&)pBits, nSize))
|
||
|
return;
|
||
|
|
||
|
FREE(pBitmapInfo);
|
||
|
}
|
||
|
|
||
|
if (!pBits)
|
||
|
return;
|
||
|
|
||
|
|
||
|
if (!bHorizontalImage)
|
||
|
{
|
||
|
int nSpriteHeight = sz.cy / nBitmaps;
|
||
|
|
||
|
for (int i = 0; i < nBitmaps; i++)
|
||
|
{
|
||
|
CRect rcSprite(0, i * nSpriteHeight, sz.cx, (i + 1) * nSpriteHeight);
|
||
|
if (CheckBitmapRect(pBits, rcSprite, sz))
|
||
|
continue;
|
||
|
|
||
|
if (rcSizingMargins.IsRectNull())
|
||
|
continue;
|
||
|
|
||
|
CheckBitmapRect(pBits, CRect(rcSprite.left, rcSprite.top + rcSizingMargins.top,
|
||
|
rcSprite.left + rcSizingMargins.left, rcSprite.bottom - rcSizingMargins.bottom), sz);
|
||
|
|
||
|
CheckBitmapRect(pBits, CRect(rcSprite.left + rcSizingMargins.left, rcSprite.top,
|
||
|
rcSprite.right - rcSizingMargins.right, rcSprite.top + rcSizingMargins.top), sz);
|
||
|
|
||
|
CheckBitmapRect(pBits, CRect(rcSprite.right - rcSizingMargins.right , rcSprite.top + rcSizingMargins.top,
|
||
|
rcSprite.right, rcSprite.bottom - rcSizingMargins.bottom), sz);
|
||
|
|
||
|
CheckBitmapRect(pBits, CRect(rcSprite.left + rcSizingMargins.left, rcSprite.bottom - rcSizingMargins.bottom,
|
||
|
rcSprite.right - rcSizingMargins.right, rcSprite.bottom), sz);
|
||
|
|
||
|
CheckBitmapRect(pBits, CRect(rcSprite.left + rcSizingMargins.left, rcSprite.top + rcSizingMargins.top,
|
||
|
rcSprite.right - rcSizingMargins.right, rcSprite.bottom - rcSizingMargins.bottom), sz);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
CATCH (CMemoryException, e)
|
||
|
{
|
||
|
TRACE(_T("Failed -- Memory exception thrown."));
|
||
|
}
|
||
|
END_CATCH
|
||
|
|
||
|
if (hbm && !m_bAlpha)
|
||
|
{
|
||
|
DeleteObject(hbm);
|
||
|
}
|
||
|
if (m_bAlpha)
|
||
|
{
|
||
|
FREE(pBits);
|
||
|
}
|
||
|
|
||
|
|
||
|
m_bOptimized = TRUE;
|
||
|
}
|
||
|
|
||
|
void CXTPSkinImage::FilterImage(COLORREF clrTransparent)
|
||
|
{
|
||
|
if (!m_hBitmap || m_bFiltered)
|
||
|
return;
|
||
|
|
||
|
m_bFiltered = TRUE;
|
||
|
|
||
|
CXTPSkinManager* pManager = XTPSkinManager();
|
||
|
|
||
|
if (!pManager->IsColorFilterExists())
|
||
|
return;
|
||
|
|
||
|
CDC dcSrc;
|
||
|
dcSrc.CreateCompatibleDC(NULL);
|
||
|
|
||
|
if (!m_bAlpha)
|
||
|
{
|
||
|
BITMAPINFO bmi;
|
||
|
HBITMAP hbm;
|
||
|
LPBYTE pBits;
|
||
|
BITMAP hbmInfo;
|
||
|
GetObject(m_hBitmap, sizeof(BITMAP), &hbmInfo);
|
||
|
|
||
|
// Initialize header to 0s.
|
||
|
ZeroMemory(&bmi, sizeof(bmi));
|
||
|
|
||
|
// Fill out the fields you care about.
|
||
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||
|
bmi.bmiHeader.biWidth = hbmInfo.bmWidth;
|
||
|
bmi.bmiHeader.biHeight = hbmInfo.bmHeight;
|
||
|
bmi.bmiHeader.biPlanes = 1;
|
||
|
bmi.bmiHeader.biBitCount = 32;
|
||
|
bmi.bmiHeader.biCompression = BI_RGB;
|
||
|
|
||
|
// Create the surface.
|
||
|
hbm = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (LPVOID*)&pBits, NULL, 0);
|
||
|
|
||
|
{
|
||
|
CXTPCompatibleDC dc(NULL, hbm);
|
||
|
dc.DrawState(CPoint(0, 0), CSize(hbmInfo.bmWidth, hbmInfo.bmHeight), m_hBitmap, 0, NULL);
|
||
|
}
|
||
|
|
||
|
DeleteObject(m_hBitmap);
|
||
|
m_hBitmap = hbm;
|
||
|
}
|
||
|
|
||
|
PBYTE pBits = 0;
|
||
|
PBITMAPINFO pBitmapInfo = 0;
|
||
|
HBITMAP hBitmapAlpha = 0;
|
||
|
|
||
|
TRY
|
||
|
{
|
||
|
UINT nSize;
|
||
|
if (!CXTPImageManagerIcon::GetBitmapBits(dcSrc, m_hBitmap, pBitmapInfo, (LPVOID&)pBits, nSize))
|
||
|
return;
|
||
|
|
||
|
BYTE* pDest = NULL;
|
||
|
|
||
|
hBitmapAlpha = CreateDIBSection(dcSrc, pBitmapInfo, DIB_RGB_COLORS, (void**)&pDest, NULL, 0);
|
||
|
if (pDest == NULL || hBitmapAlpha == NULL)
|
||
|
AfxThrowMemoryException();
|
||
|
|
||
|
MEMCPY_S(pDest, pBits, nSize);
|
||
|
|
||
|
for (UINT i = 0; i < nSize; i += 4)
|
||
|
{
|
||
|
COLORREF clr = RGB(pDest[i + 2], pDest[i + 1], pDest[i + 0]);
|
||
|
|
||
|
if (clr != clrTransparent)
|
||
|
{
|
||
|
pManager->ApplyColorFilter(clr);
|
||
|
|
||
|
pDest[i + 0] = GetBValue(clr);
|
||
|
pDest[i + 1] = GetGValue(clr);
|
||
|
pDest[i + 2] = GetRValue(clr);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
CATCH (CMemoryException, e)
|
||
|
{
|
||
|
TRACE(_T("Failed -- Memory exception thrown."));
|
||
|
}
|
||
|
END_CATCH
|
||
|
|
||
|
FREE(pBits);
|
||
|
FREE(pBitmapInfo);
|
||
|
|
||
|
DeleteObject(m_hBitmap);
|
||
|
m_hBitmap = hBitmapAlpha;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPSkinImage::LoadFile(LPCTSTR lpszFileName)
|
||
|
{
|
||
|
m_bAlpha = FALSE;
|
||
|
|
||
|
BOOL bAlpha = FALSE;
|
||
|
HBITMAP hBmp = CXTPImageManagerIcon::LoadBitmapFromFile(lpszFileName, &bAlpha);
|
||
|
|
||
|
if (!hBmp)
|
||
|
return FALSE;
|
||
|
|
||
|
if (bAlpha)
|
||
|
{
|
||
|
if (XTPSkinManager()->GetSchema()->m_bPreMultiplyImages)
|
||
|
{
|
||
|
m_hBitmap = CXTPImageManagerIcon::PreMultiplyAlphaBitmap(hBmp, &m_bAlpha);
|
||
|
DeleteObject(hBmp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_hBitmap = hBmp;
|
||
|
m_bAlpha = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_hBitmap = hBmp;
|
||
|
}
|
||
|
|
||
|
m_szBitmap = _GetExtent();
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPSkinImage::LoadFile(HMODULE hModule, LPCTSTR lpszBitmapFileName)
|
||
|
{
|
||
|
if (!hModule)
|
||
|
return FALSE;
|
||
|
|
||
|
m_bAlpha = FALSE;
|
||
|
|
||
|
ASSERT(m_hBitmap == NULL);
|
||
|
|
||
|
BOOL bAlpha = FALSE;
|
||
|
HBITMAP hBmp = XTPSkinFrameworkLoadBitmap(hModule, lpszBitmapFileName, bAlpha);
|
||
|
|
||
|
if (!hBmp)
|
||
|
return FALSE;
|
||
|
|
||
|
if (bAlpha)
|
||
|
{
|
||
|
if (XTPSkinManager()->GetSchema()->m_bPreMultiplyImages)
|
||
|
{
|
||
|
m_hBitmap = CXTPImageManagerIcon::PreMultiplyAlphaBitmap(hBmp, &m_bAlpha);
|
||
|
DeleteObject(hBmp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_hBitmap = hBmp;
|
||
|
m_bAlpha = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_hBitmap = hBmp;
|
||
|
}
|
||
|
|
||
|
m_szBitmap = _GetExtent();
|
||
|
|
||
|
return m_hBitmap != NULL;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPSkinImage::DrawImagePart(CDC* pDCDest, const CRect& rcDest, CDC* pDCSrc, const CRect& rcSrc) const
|
||
|
{
|
||
|
if (rcDest.Width() <= 0 || rcDest.Height() <= 0 || rcSrc.Width() <= 0 || rcSrc.Height() <= 0)
|
||
|
return TRUE;
|
||
|
|
||
|
BOOL bResult = TRUE;
|
||
|
|
||
|
if (m_bAlpha)
|
||
|
{
|
||
|
bResult = XTPImageManager()->AlphaBlend(pDCDest->GetSafeHdc(), rcDest, pDCSrc->GetSafeHdc(), rcSrc);
|
||
|
}
|
||
|
else if ((rcSrc.Width() == rcDest.Width()) && (rcSrc.Height() == rcDest.Height()))
|
||
|
{
|
||
|
bResult = pDCDest->BitBlt(rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
|
||
|
pDCSrc, rcSrc.left, rcSrc.top, SRCCOPY);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bResult = pDCDest->StretchBlt(rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(),
|
||
|
pDCSrc, rcSrc.left, rcSrc.top, rcSrc.Width(), rcSrc.Height(), SRCCOPY);
|
||
|
}
|
||
|
|
||
|
return bResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CXTPSkinImage::DrawImageTile(CDC* pDCDest, const CRect& rcDest, CDC* pDCSrc, const CRect& rcSrc, BOOL bTile) const
|
||
|
{
|
||
|
if (rcDest.Width() <= 0 || rcDest.Height() <= 0 || rcSrc.Width() <= 0 || rcSrc.Height() <= 0)
|
||
|
return TRUE;
|
||
|
|
||
|
SOLIDRECT sr;
|
||
|
if (FindSolidRect(rcSrc, sr))
|
||
|
{
|
||
|
COLORREF clrFilter = sr.clr & 0xFFFFFF;
|
||
|
if (clrFilter != m_clrTransparent) XTPSkinManager()->ApplyColorFilter(clrFilter);
|
||
|
|
||
|
if (!m_bAlpha)
|
||
|
{
|
||
|
pDCDest->FillSolidRect(rcDest, clrFilter);
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (sr.clr == 0)
|
||
|
return TRUE;
|
||
|
|
||
|
if ((sr.clr >> 24) == 0xFF)
|
||
|
{
|
||
|
pDCDest->FillSolidRect(rcDest, clrFilter);
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!bTile)
|
||
|
{
|
||
|
return DrawImagePart(pDCDest, rcDest, pDCSrc, rcSrc);
|
||
|
}
|
||
|
|
||
|
if (rcSrc.Width() == 1 && (rcSrc.Height() == 1 || rcSrc.Height() == rcDest.Height()))
|
||
|
{
|
||
|
return DrawImagePart(pDCDest, rcDest, pDCSrc, rcSrc);
|
||
|
}
|
||
|
|
||
|
if (rcSrc.Height() == 1 && (rcSrc.Width() == 1 || rcSrc.Width() == rcDest.Width()))
|
||
|
{
|
||
|
return DrawImagePart(pDCDest, rcDest, pDCSrc, rcSrc);
|
||
|
}
|
||
|
|
||
|
if (rcSrc.right <= rcSrc.left || rcDest.right <= rcDest.left)
|
||
|
return TRUE;
|
||
|
|
||
|
if (rcSrc.bottom <= rcSrc.top || rcDest.bottom <= rcDest.top)
|
||
|
return TRUE;
|
||
|
|
||
|
int nHeight = bTile & TILE_VERTICAL? min(rcSrc.Height(), rcDest.Height()): rcDest.Height();
|
||
|
int nWidth = bTile & TILE_HORIZONTAL? min(rcSrc.Width(), rcDest.Width()): rcDest.Width();
|
||
|
|
||
|
for (int x = rcDest.left; x < rcDest.right; x += nWidth)
|
||
|
{
|
||
|
for (int y = rcDest.top; y < rcDest.bottom; y += nHeight)
|
||
|
{
|
||
|
CRect rcDestTile(x, y, x + nWidth, y + nHeight);
|
||
|
CRect rcSrcTile(rcSrc);
|
||
|
|
||
|
if (bTile & TILE_VERTICAL)
|
||
|
{
|
||
|
if (rcSrcTile.Height() > rcDestTile.Height())
|
||
|
rcSrcTile.bottom = rcSrcTile.top + rcDestTile.Height();
|
||
|
|
||
|
if (rcDestTile.bottom > rcDest.bottom)
|
||
|
{
|
||
|
rcDestTile.bottom = rcDest.bottom;
|
||
|
rcSrcTile.bottom = rcSrcTile.top + rcDestTile.Height();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (bTile & TILE_HORIZONTAL)
|
||
|
{
|
||
|
if (rcSrcTile.Width() > rcDestTile.Width())
|
||
|
rcSrcTile.right = rcSrcTile.left + rcDestTile.Width();
|
||
|
|
||
|
if (rcDestTile.right > rcDest.right)
|
||
|
{
|
||
|
rcDestTile.right = rcDest.right;
|
||
|
rcSrcTile.right = rcSrcTile.left + rcDestTile.Width();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DrawImagePart(pDCDest, rcDestTile, pDCSrc, rcSrcTile);
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPSkinImage::FindSolidRect(const CRect& rcSrc, SOLIDRECT& sr) const
|
||
|
{
|
||
|
for (int i = 0; i < m_arrSolidRects.GetSize(); i++)
|
||
|
{
|
||
|
sr = m_arrSolidRects[i];
|
||
|
|
||
|
RECT rc;
|
||
|
if (IntersectRect(&rc, &rcSrc, &sr.rc) && rcSrc == rc)
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CXTPSkinImage::DrawImage(CDC* pDC, const CRect& rcDest, const CRect& rcSrc, const CRect& rcSizingMargins, COLORREF clrTransparent, int nSizingType, BOOL bBorderOnly)
|
||
|
{
|
||
|
if (rcSizingMargins.top + rcSizingMargins.bottom > rcSrc.Height())
|
||
|
return;
|
||
|
|
||
|
SOLIDRECT sr;
|
||
|
if (FindSolidRect(rcSrc, sr))
|
||
|
{
|
||
|
COLORREF clrFilter = sr.clr & 0xFFFFFF;
|
||
|
if (clrFilter != clrTransparent) XTPSkinManager()->ApplyColorFilter(clrFilter);
|
||
|
|
||
|
if (!m_bAlpha)
|
||
|
{
|
||
|
if (clrFilter != clrTransparent)
|
||
|
pDC->FillSolidRect(rcDest, clrFilter);
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (sr.clr == 0)
|
||
|
return;
|
||
|
|
||
|
if ((sr.clr >> 24) == 0xFF)
|
||
|
{
|
||
|
pDC->FillSolidRect(rcDest, clrFilter);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_clrTransparent = clrTransparent;
|
||
|
|
||
|
if (clrTransparent == COLORREF_NULL || m_bAlpha)
|
||
|
{
|
||
|
DrawImage(pDC, rcDest, rcSrc, rcSizingMargins, nSizingType, bBorderOnly);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
FilterImage(clrTransparent);
|
||
|
|
||
|
CBitmap bmp;
|
||
|
bmp.CreateCompatibleBitmap(pDC, rcDest.Width(), rcDest.Height());
|
||
|
|
||
|
CXTPCompatibleDC dc(pDC, &bmp);
|
||
|
|
||
|
CRect rcDestOrig(0, 0, rcDest.Width(), rcDest.Height());
|
||
|
|
||
|
dc.FillSolidRect(rcDestOrig, clrTransparent);
|
||
|
DrawImage(&dc, rcDestOrig, rcSrc, rcSizingMargins, nSizingType, bBorderOnly);
|
||
|
|
||
|
XTPImageManager()->TransparentBlt(*pDC, rcDest, dc, rcDestOrig, clrTransparent);
|
||
|
|
||
|
}
|
||
|
|
||
|
void CXTPSkinImage::InvertBitmap()
|
||
|
{
|
||
|
if (!m_bAlpha)
|
||
|
return;
|
||
|
|
||
|
HBITMAP hBitmap = m_hBitmap;
|
||
|
m_hBitmap = CXTPImageManagerIcon::InvertAlphaBitmap(m_hBitmap);
|
||
|
DeleteObject(hBitmap);
|
||
|
|
||
|
m_bInvert = !m_bInvert;
|
||
|
}
|
||
|
|
||
|
void CXTPSkinImage::DrawImage(CDC* pDC, const CRect& rcDest, const CRect& rcSrc, const CRect& rcSizingMargins, int nSizingType, BOOL bBorderOnly)
|
||
|
{
|
||
|
if (m_hBitmap == NULL)
|
||
|
return;
|
||
|
|
||
|
if (rcSizingMargins.top + rcSizingMargins.bottom > rcSrc.Height())
|
||
|
return;
|
||
|
|
||
|
FilterImage(COLORREF_NULL);
|
||
|
|
||
|
|
||
|
pDC->SetStretchBltMode(COLORONCOLOR);
|
||
|
|
||
|
CRect rcDestSizingMargins = rcSizingMargins;
|
||
|
BOOL bTile = nSizingType == ST_TILE? TILE_ALL: 0;
|
||
|
|
||
|
if (rcDest.left >= rcDest.right || rcDest.top >= rcDest.bottom)
|
||
|
return;
|
||
|
|
||
|
BOOL bRtl = CXTPDrawHelpers::IsContextRTL(pDC);
|
||
|
|
||
|
if (m_bAlpha && m_bMirrorImage)
|
||
|
{
|
||
|
if ((bRtl && !m_bInvert) || (!bRtl && m_bInvert))
|
||
|
{
|
||
|
InvertBitmap();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CXTPCompatibleDC dcSrc(pDC, m_hBitmap);
|
||
|
|
||
|
if (bRtl && !m_bAlpha && m_bMirrorImage)
|
||
|
{
|
||
|
CXTPDrawHelpers::SetContextRTL(&dcSrc, FALSE);
|
||
|
}
|
||
|
|
||
|
if (rcSizingMargins.IsRectNull())
|
||
|
{
|
||
|
DrawImageTile(pDC, rcDest, &dcSrc, rcSrc, bTile);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ((rcDest.Height() <= rcSizingMargins.top + rcSizingMargins.bottom) || (rcSrc.Height() == rcSizingMargins.top + rcSizingMargins.bottom))
|
||
|
{
|
||
|
rcDestSizingMargins.top = MulDiv(rcDest.Height(), rcSizingMargins.top, (rcSizingMargins.top + rcSizingMargins.bottom));
|
||
|
rcDestSizingMargins.bottom = rcDest.Height() - rcDestSizingMargins.top;
|
||
|
|
||
|
if (rcDestSizingMargins.bottom > 0 && (rcDestSizingMargins.bottom % 2 != rcSizingMargins.bottom % 2))
|
||
|
rcDestSizingMargins.bottom++;
|
||
|
|
||
|
|
||
|
if (bTile) bTile -= TILE_VERTICAL;
|
||
|
}
|
||
|
|
||
|
if ((rcDest.Width() <= rcSizingMargins.left + rcSizingMargins.right) || (rcSrc.Width() == rcSizingMargins.left + rcSizingMargins.right))
|
||
|
{
|
||
|
rcDestSizingMargins.left = MulDiv(rcDest.Width(), rcSizingMargins.left, (rcSizingMargins.left + rcSizingMargins.right));
|
||
|
rcDestSizingMargins.right = rcDest.Width() - rcDestSizingMargins.left;
|
||
|
|
||
|
if (bTile) bTile -= TILE_HORIZONTAL;
|
||
|
}
|
||
|
|
||
|
/*if ((rcDestSizingMargins.top + rcDestSizingMargins.bottom <
|
||
|
rcSizingMargins.top + rcSizingMargins.bottom)
|
||
|
&& rcDest.Width() < rcSrc.Width() + 3)
|
||
|
{
|
||
|
DrawImagePart(pDC, CRect(rcDest.left, rcDest.top, rcDest.right, rcDest.top + rcDestSizingMargins.top),
|
||
|
&dcSrc, CRect(rcSrc.left, rcSrc.top , rcSrc.right, rcSrc.top + rcSizingMargins.top));
|
||
|
|
||
|
DrawImagePart(pDC, CRect(rcDest.left, rcDest.bottom - rcDestSizingMargins.bottom, rcDest.right, rcDest.bottom),
|
||
|
&dcSrc, CRect(rcSrc.left, rcSrc.bottom - rcSizingMargins.bottom , rcSrc.right, rcSrc.bottom ));
|
||
|
|
||
|
return;
|
||
|
}*/
|
||
|
|
||
|
DrawImagePart(pDC, CRect(rcDest.left, rcDest.top, rcDest.left + rcDestSizingMargins.left, rcDest.top + rcDestSizingMargins.top),
|
||
|
&dcSrc, CRect(rcSrc.left, rcSrc.top, rcSrc.left + rcSizingMargins.left, rcSrc.top + rcSizingMargins.top ));
|
||
|
DrawImageTile(pDC, CRect(rcDest.left + rcDestSizingMargins.left, rcDest.top, rcDest.right - rcDestSizingMargins.right, rcDest.top + rcDestSizingMargins.top),
|
||
|
&dcSrc, CRect(rcSrc.left + rcSizingMargins.left, rcSrc.top, rcSrc.right - rcSizingMargins.right, rcSrc.top + rcSizingMargins.top ), bTile);
|
||
|
DrawImagePart(pDC, CRect(rcDest.right - rcDestSizingMargins.right, rcDest.top, rcDest.right, rcDest.top + rcDestSizingMargins.top),
|
||
|
&dcSrc, CRect(rcSrc.right - rcSizingMargins.right, rcSrc.top , rcSrc.right, rcSrc.top + rcSizingMargins.top ));
|
||
|
|
||
|
DrawImageTile(pDC, CRect(rcDest.left, rcDest.top + rcDestSizingMargins.top, rcDest.left + rcDestSizingMargins.left, rcDest.bottom - rcDestSizingMargins.bottom),
|
||
|
&dcSrc, CRect(rcSrc.left, rcSrc.top + rcSizingMargins.top , rcSrc.left + rcSizingMargins.left, rcSrc.bottom - rcSizingMargins.bottom ), bTile);
|
||
|
|
||
|
if (!bBorderOnly)
|
||
|
{
|
||
|
DrawImageTile(pDC, CRect(rcDest.left + rcDestSizingMargins.left, rcDest.top + rcDestSizingMargins.top, rcDest.right - rcDestSizingMargins.right, rcDest.bottom - rcDestSizingMargins.bottom),
|
||
|
&dcSrc, CRect(rcSrc.left + rcSizingMargins.left, rcSrc.top + rcSizingMargins.top , rcSrc.right - rcSizingMargins.right, rcSrc.bottom - rcSizingMargins.bottom ), bTile);
|
||
|
}
|
||
|
|
||
|
DrawImageTile(pDC, CRect(rcDest.right - rcDestSizingMargins.right , rcDest.top + rcDestSizingMargins.top, rcDest.right, rcDest.bottom - rcDestSizingMargins.bottom),
|
||
|
&dcSrc, CRect(rcSrc.right - rcSizingMargins.right, rcSrc.top + rcSizingMargins.top , rcSrc.right, rcSrc.bottom - rcSizingMargins.bottom), bTile);
|
||
|
|
||
|
DrawImagePart(pDC, CRect(rcDest.left, rcDest.bottom - rcDestSizingMargins.bottom, rcDest.left + rcDestSizingMargins.left, rcDest.bottom),
|
||
|
&dcSrc, CRect(rcSrc.left, rcSrc.bottom - rcSizingMargins.bottom , rcSrc.left + rcSizingMargins.left, rcSrc.bottom ));
|
||
|
DrawImageTile(pDC, CRect(rcDest.left + rcDestSizingMargins.left, rcDest.bottom - rcDestSizingMargins.bottom, rcDest.right - rcDestSizingMargins.right, rcDest.bottom),
|
||
|
&dcSrc, CRect(rcSrc.left + rcSizingMargins.left, rcSrc.bottom - rcSizingMargins.bottom , rcSrc.right - rcSizingMargins.right, rcSrc.bottom ), bTile);
|
||
|
DrawImagePart(pDC, CRect(rcDest.right - rcDestSizingMargins.right, rcDest.bottom - rcDestSizingMargins.bottom, rcDest.right, rcDest.bottom),
|
||
|
&dcSrc, CRect(rcSrc.right - rcSizingMargins.right, rcSrc.bottom - rcSizingMargins.bottom , rcSrc.right, rcSrc.bottom));
|
||
|
|
||
|
}
|
||
|
|
||
|
CSize CXTPSkinImage::GetExtent() const
|
||
|
{
|
||
|
return m_szBitmap;
|
||
|
}
|
||
|
|
||
|
CSize CXTPSkinImage::_GetExtent() const
|
||
|
{
|
||
|
if (!m_hBitmap)
|
||
|
return CSize(0, 0);
|
||
|
|
||
|
BITMAP bmpInfo;
|
||
|
GetObject(m_hBitmap, sizeof(BITMAP), &bmpInfo);
|
||
|
|
||
|
return CSize(bmpInfo.bmWidth, bmpInfo.bmHeight);
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD CXTPSkinImage::GetHeight() const
|
||
|
{
|
||
|
return m_szBitmap.cy;
|
||
|
}
|
||
|
|
||
|
DWORD CXTPSkinImage::GetWidth() const
|
||
|
{
|
||
|
return m_szBitmap.cx;
|
||
|
}
|
||
|
|
||
|
BOOL CXTPSkinImage::IsAlphaImage() const
|
||
|
{
|
||
|
return m_bAlpha;
|
||
|
}
|
||
|
|
||
|
CRect CXTPSkinImage::GetSource(int nState, int nCount) const
|
||
|
{
|
||
|
CSize szExtent = m_szBitmap;
|
||
|
CRect rcImage(0, 0, szExtent.cx, szExtent.cy / nCount);
|
||
|
rcImage.OffsetRect(0, nState * rcImage.Height());
|
||
|
|
||
|
return rcImage;
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
|
||
|
CXTPSkinImages::CXTPSkinImages()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
CXTPSkinImages::~CXTPSkinImages()
|
||
|
{
|
||
|
RemoveAll();
|
||
|
}
|
||
|
|
||
|
void CXTPSkinImages::RemoveAll()
|
||
|
{
|
||
|
POSITION pos = m_mapImages.GetStartPosition();
|
||
|
CString strImageFile;
|
||
|
CXTPSkinImage* pImage;
|
||
|
while (pos != NULL)
|
||
|
{
|
||
|
m_mapImages.GetNextAssoc( pos, strImageFile, (void*&)pImage);
|
||
|
delete pImage;
|
||
|
}
|
||
|
m_mapImages.RemoveAll();
|
||
|
}
|
||
|
|
||
|
CXTPSkinImage* CXTPSkinImages::LoadFile(CXTPSkinManagerResourceFile* pResourceFile, LPCTSTR lpszImageFile)
|
||
|
{
|
||
|
if (!pResourceFile)
|
||
|
return NULL;
|
||
|
|
||
|
if (lpszImageFile == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
CXTPSkinImage* pImage = 0;
|
||
|
if (m_mapImages.Lookup(lpszImageFile, (void*&)pImage))
|
||
|
return pImage;
|
||
|
|
||
|
pImage = pResourceFile->LoadImage(lpszImageFile);
|
||
|
if (!pImage)
|
||
|
return NULL;
|
||
|
|
||
|
m_mapImages.SetAt(lpszImageFile, pImage);
|
||
|
return pImage;
|
||
|
}
|
||
|
|
||
|
CSize CXTPSkinImages::GetExtent(CXTPSkinManagerResourceFile* pResourceFile, LPCTSTR lpszImageFile)
|
||
|
{
|
||
|
CXTPSkinImage* pImage = LoadFile(pResourceFile, lpszImageFile);
|
||
|
|
||
|
if (!pImage)
|
||
|
return CSize(0, 0);
|
||
|
|
||
|
return pImage->GetExtent();
|
||
|
}
|