pja::CBitmap Compare(const pja::CBitmap &Bitmap1, const pja::CBitmap &Bitmap2, int x = 0, int y = 0, COLORREF ClrSame = 0x00FFFFFF, COLORREF ClrDiff = 0x00000000);
pja::CBitmap Compare(const pja::CBitmap &Bitmap1, // The first bitmap
const pja::CBitmap &Bitmap2, // The second bitmap
int x, int y, // The offset of the second bitmap from the first bitmap
COLORREF ClrSame, // Colour used for pixels that are the same
COLORREF ClrDiff) // Colour used for pixels that are different
{
// Sanity check
ASSERT (x > -Bitmap2.Width() && x < Bitmap1.Width());
ASSERT (y > -Bitmap2.Height() && y < Bitmap1.Height());
if (x <= -Bitmap2.Width() || x >= Bitmap1.Width() || y <= -Bitmap2.Height() || y >= Bitmap1.Height())
{
return pja::CBitmap();
}
// Setup the rectangles for where stuff gets drawn
CRect Bitmap1Rect(0, 0, Bitmap1.Width(), Bitmap1.Height());
CRect Bitmap2Rect(0, 0, Bitmap2.Width(), Bitmap2.Height());
if (x < 0)
Bitmap1Rect.OffsetRect(-x, 0);
else
Bitmap2Rect.OffsetRect(x, 0);
if (y < 0)
Bitmap1Rect.OffsetRect(0, -y);
else
Bitmap2Rect.OffsetRect(0, y);
CRect FinalRect = Bitmap1Rect | Bitmap2Rect;
CRect CombinedRect = Bitmap1Rect & Bitmap2Rect;
// Create the bitmaps needed
pja::CBitmap FinalBitmap(NULL, FinalRect.Width(), FinalRect.Height());
pja::CBitmap CombinedBitmap(NULL, CombinedRect.Width(), CombinedRect.Height());
pja::CBitmap MonoBitmap(CreateBitmap(CombinedRect.Width(), CombinedRect.Height(), 1, 1, NULL));
// DCs for all the bitmaps
pja::CCompatibleDC Bitmap1DC;
pja::CCompatibleDC Bitmap2DC;
pja::CCompatibleDC FinalBitmapDC;
pja::CCompatibleDC CombinedBitmapDC;
pja::CCompatibleDC MonoBitmapDC;
// Select the bitmaps into the DCs
SelectObject(Bitmap1DC, Bitmap1);
SelectObject(Bitmap2DC, Bitmap2);
SelectObject(FinalBitmapDC, FinalBitmap);
SelectObject(CombinedBitmapDC, CombinedBitmap);
SelectObject(MonoBitmapDC, MonoBitmap);
// Combine the two supplied bitmaps,
// same pixels will be white - all others will be whatever
BitBlt(CombinedBitmapDC,
0, 0, CombinedRect.Width(), CombinedRect.Height(),
Bitmap1DC,
CombinedRect.left > Bitmap1Rect.left ? CombinedRect.left : 0,
CombinedRect.top > Bitmap1Rect.top ? CombinedRect.top : 0,
SRCCOPY);
BitBlt(CombinedBitmapDC, 0, 0, CombinedRect.Width(), CombinedRect.Height(),
Bitmap2DC,
CombinedRect.left > Bitmap2Rect.left ? CombinedRect.left : 0,
CombinedRect.top > Bitmap2Rect.top ? CombinedRect.top : 0,
0x00990066); //DSxn ROP
// On 32 bit bitmaps we have to reset the alpha channel to zero
if (CombinedBitmap.BitsPixel() >= 32)
{
SelectObject(CombinedBitmapDC, GetStockObject(WHITE_BRUSH));
PatBlt(CombinedBitmapDC, 0, 0, CombinedBitmap.Width(), CombinedBitmap.Height(), 0x00A000C9); // DPa ROP
}
// transfer the combined bitmap to a black and white monochrome bitmap
// white stays white, the rest turns black
SetBkColor(CombinedBitmapDC, 0x00FFFFFF);
BitBlt(MonoBitmapDC, 0, 0, CombinedRect.Width(), CombinedRect.Height(), CombinedBitmapDC, 0, 0, SRCCOPY);
// Fill the background of the final bitmap with our background colour
// TODO: Change this line when this function is imported into the Image Viewer
//FillRect(FinalBitmapDC, FinalRect, CBrush(reinterpret_cast<COLORREF>(AfxGetMainWnd()->SendMessage(WMU_GETBGCOLOUR, 0, 0);
FillRect(FinalBitmapDC, FinalRect, CBrush(RGB(236, 233, 216)));
// Draw our two bitmaps
if (FinalRect != CombinedRect)
{
BitBlt(FinalBitmapDC, Bitmap1Rect.left, Bitmap1Rect.top, Bitmap1Rect.Width(), Bitmap1Rect.Height(), Bitmap1DC, 0, 0, SRCCOPY);
BitBlt(FinalBitmapDC, Bitmap2Rect.left, Bitmap2Rect.top, Bitmap2Rect.Width(), Bitmap2Rect.Height(), Bitmap2DC, 0, 0, SRCCOPY);
}
// Draw the differences using the supplied colours
SetBkColor(FinalBitmapDC, ClrSame);
SetTextColor(FinalBitmapDC, ClrDiff);
BitBlt(FinalBitmapDC, CombinedRect.left, CombinedRect.top, CombinedRect.Width(), CombinedRect.Height(), MonoBitmapDC, 0, 0, SRCCOPY);
return FinalBitmap;
}