Click here to Skip to main content
15,896,501 members
Articles / Desktop Programming / MFC

QuickFill: An Efficient Flood Fill Algorithm

Rate me:
Please Sign up or sign in to vote.
4.84/5 (71 votes)
12 Mar 200413 min read 529.4K   12K   103  
Design and implementation of efficient flood fill algorithms.
// DlgMasks.cpp : implementation file
//

#include "stdafx.h"
#include "QuickFillDemo.h"
#include "DlgMasks.h"

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

/////////////////////////////////////////////////////////////////////////////
// CDlgMasks dialog

int CDlgMasks::m_nMask = 0;

// Just add new mask IDs here
const UINT lg_MaskID[] = { IDB_MASK0, // default mask
	IDB_MASK1 ,IDB_MASK2 ,IDB_MASK3 ,IDB_MASK4 ,IDB_MASK5 ,
	IDB_MASK6 ,IDB_MASK7 ,IDB_MASK8 ,IDB_MASK9 ,IDB_MASK10,
	IDB_MASK11,IDB_MASK12,IDB_MASK13,IDB_MASK14,IDB_MASK15 };

CDlgMasks::CDlgMasks(CWnd* pParent /*=NULL*/)
	: CDialog(CDlgMasks::IDD, pParent), m_bOK(FALSE)
{
	//{{AFX_DATA_INIT(CDlgMasks)
	//}}AFX_DATA_INIT
	memset(m_Mask,0,sizeof(m_Mask));
}


void CDlgMasks::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDlgMasks)
	DDX_Control(pDX, IDC_RECT, m_CtrlRect);
	DDX_Control(pDX, IDC_COMBO_MASKS, m_CmbMasks);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDlgMasks, CDialog)
	//{{AFX_MSG_MAP(CDlgMasks)
	ON_WM_PAINT()
	ON_CBN_SELCHANGE(IDC_COMBO_MASKS, OnSelchangeComboMasks)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
//
UINT CDlgMasks::GetMask(LPBYTE pMask,UINT cbMask)
{
	UINT nSize = 0U;
	if( m_bOK )
	{
		nSize = min(cbMask,sizeof(m_Mask));
		memcpy(pMask,m_Mask,nSize);
	}
	return nSize;
}

/////////////////////////////////////////////////////////////////////////////
// CDlgMasks message handlers

BOOL CDlgMasks::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	int nSize = sizeof(lg_MaskID)/sizeof(lg_MaskID[0]);
	CString csTemp;
	for( int i = 0; i < nSize; ++i )
	{
		csTemp.Format(_T("Mask %d"),i+1);
		m_CmbMasks.SetItemData(m_CmbMasks.AddString(csTemp),lg_MaskID[i]);
	}
	m_CmbMasks.SetCurSel(m_nMask);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CDlgMasks::OnOK() 
{
	m_bOK = TRUE;
	CDialog::OnOK();
}

void CDlgMasks::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	CBitmap bitmap;
	m_nMask = m_CmbMasks.GetCurSel();
	if( bitmap.LoadBitmap(m_CmbMasks.GetItemData(m_nMask)) )
	{
		BITMAP bm;
		bitmap.GetBitmap(&bm);

		CRect rc;
		m_CtrlRect.GetWindowRect(&rc);
		ScreenToClient(&rc);

		CDC dcMem;
		dcMem.CreateCompatibleDC(&dc);

		CBitmap* pOldBitmap = dcMem.SelectObject(&bitmap);

		// draw preview
		dc.StretchBlt(rc.left,rc.top,rc.Width(),rc.Height(),
			&dcMem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);

		// update mask
		const BYTE bitMask[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
		bm.bmHeight = min(bm.bmHeight,sizeof(m_Mask));
		memset(m_Mask,0,sizeof(m_Mask));
		for( int y = 0; y < bm.bmHeight; ++y )
		{
			for( int x = 0; x < 8; ++x )
			{
				if( !dcMem.GetPixel(x,y) )
					m_Mask[y] |= bitMask[x&7];
			}
		}

		dcMem.SelectObject(pOldBitmap);
		dcMem.DeleteDC();
	}	
	// Do not call CDialog::OnPaint() for painting messages
}

void CDlgMasks::OnSelchangeComboMasks() 
{
	CRect rc;
	m_CtrlRect.GetWindowRect(&rc);
	ScreenToClient(&rc);
	InvalidateRect(&rc,FALSE);
	UpdateWindow();
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
Software Developer (Senior)
United States United States
I am a senior software engineer who has been designing and developing software for many years, mostly in C/C++. You might say that I think in code; which is why I am passionate about my first rule of coding: “First do no harm”. So if I get carried away in my explanations, please realize that it is just part of my personality. I enjoy learning new things and, when I have the time, passing that knowledge onto others.

Comments and Discussions