This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Font Generation Tool Submitted by

We always need fonts, you can argue about what type of font you need, but in a game, or just for debug output you probably need bitmap fonts. So everyone has probably tried to find some tools online, or to program one. And if you find one online, it does not fit the needs, so you end up programming your own anyway, because the online version you found does not have source-code included... At least the ones that I found didn't have it, so indeed in the end I programmed my own, took me a whole day which I could have spend doing more useful stuff... This tool is quite similar to "all" (I only found 2) those other font generation tools, but it comes with full source-code, and you are free to use, modify, and redistribute it, also for commercial use.. no GPL or anything... just completely free. Although I wouldn't like it if you just put it on your website with a price tag in front of it... Anyway, I would like to get your comments, bug reports, fixes. And if you make a cewl feature, it would be nice if you e-mail it. For those that want to change the export output, I suggest to modify the ExportTGA and ExportInfo methods, at the bottom of "mudFontDlg.cpp". Currently I export a .tga image, with the font data in the alpha channel, while the color channel is completely white, and the information for each character is in an xml file. If you compile using the latest Platform SDK the tool gets an extra Quality setting "Cleartype", however this feature is only available on Windows XP and above, and since I don't have XP installed, it has never been tested, so any comments on that would be nice. (Line 147, mudFontDlg.cpp)
How to use?

> - build and start the program (or start prebuild .exe)
> - 'tools' / 'add characters', to add characters to the font.
> - adjust font, and/or all other settings.
> - export. (result == .tga & .xml file).

Tom van Dijck
mudGE Entertainment.

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/AddCharDlg.cpp] - (1,235 bytes)

    // --> Include files <---------------------------------------------------------

    #include "stdafx.h"
    #include "mudFont.h"
    #include "AddCharDlg.h"

    // --> Static members <--------------------------------------------------------

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

    BEGIN_MESSAGE_MAP(CAddCharDlg, CDialog)
    	//{{AFX_MSG_MAP(CAddCharDlg)
    	ON_WM_DESTROY()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    // --> Class implementation <--------------------------------------------------

    CAddCharDlg::CAddCharDlg(CWnd* pParent /*=NULL*/)
    	: CDialog(CAddCharDlg::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CAddCharDlg)
    	m_Chars = _T("");
    	//}}AFX_DATA_INIT
    }

    void CAddCharDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CAddCharDlg)
    	DDX_Control(pDX, IDC_EDIT2, m_String);
    	DDX_Text(pDX, IDC_EDIT2, m_Chars);
    	//}}AFX_DATA_MAP
    }

    void CAddCharDlg::OnDestroy()
    {
    	CDialog::OnDestroy();
    	UpdateData(TRUE);
    }

    BOOL CAddCharDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();

    	m_String.SetFocus();
    	return FALSE;
    }

    // --> End of file <-----------------------------------------------------------

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/AddCharDlg.h] - (1,298 bytes)

    #if !defined(AFX_ADDCHARDLG_H__4FD6C119_A4B4_4EA2_9596_07297335EDD2__INCLUDED_)
    #define AFX_ADDCHARDLG_H__4FD6C119_A4B4_4EA2_9596_07297335EDD2__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // AddCharDlg.h : header file
    //

    /////////////////////////////////////////////////////////////////////////////
    // CAddCharDlg dialog

    class CAddCharDlg : public CDialog
    {
    // Construction
    public:
    	CAddCharDlg(CWnd* pParent = NULL);   // standard constructor

    // Dialog Data
    	//{{AFX_DATA(CAddCharDlg)
    	enum { IDD = IDD_ADDCHAR };
    	CEdit	m_String;
    	CString	m_Chars;
    	//}}AFX_DATA

    	const CString& GetString() const { return m_Chars; }

    // Overrides
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CAddCharDlg)
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    	//}}AFX_VIRTUAL

    // Implementation
    protected:

    	// Generated message map functions
    	//{{AFX_MSG(CAddCharDlg)
    	afx_msg void OnDestroy();
    	virtual BOOL OnInitDialog();
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

    #endif // !defined(AFX_ADDCHARDLG_H__4FD6C119_A4B4_4EA2_9596_07297335EDD2__INCLUDED_)

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/mudDib.cpp] - (2,447 bytes)

    // --> Include files <---------------------------------------------------------

    #include "stdafx.h"
    #include "MudDib.h"
    #pragma hdrstop

    // --> Class implementation <--------------------------------------------------

    CMudDib::CMudDib ():
    	m_Bits(NULL),
    	m_Bitmap(NULL),
    	m_Width(0),
    	m_Height(0)
    {
    }

    CMudDib::~CMudDib()
    {
    	Destroy ();
    }

    bool CMudDib::Create(int a_Width, int a_Height, HDC a_DC)
    {
    	Destroy();

    	ZeroMemory(&m_Info, sizeof (BITMAPINFO));
    	m_Info.bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
    	m_Info.bmiHeader.biWidth		= a_Width;
    	m_Info.bmiHeader.biHeight		= -a_Height;
    	m_Info.bmiHeader.biPlanes		= 1;
    	m_Info.bmiHeader.biBitCount		= 32;
    	m_Info.bmiHeader.biCompression	= BI_RGB;
    	m_Info.bmiHeader.biSizeImage	= a_Width*a_Height*4;

    	m_Bitmap = CreateDIBSection(a_DC, &m_Info, DIB_RGB_COLORS, (void **)&m_Bits, NULL, NULL);

    	if (a_DC != NULL)
    	{
    		SelectObject(a_DC, m_Bitmap);
    	}

    	if (m_Bitmap)
    	{
    		m_Width = a_Width;
    		m_Height = a_Height;
    		return true;
    	}
    	else
    	{
    		m_Width = 0;
    		m_Height = 0;
    		return false;
    	}
    }

    bool CMudDib::Destroy ()
    {
    	if (m_Bitmap)
    	{
    		DeleteObject(m_Bitmap);
    	}

    	m_Bitmap	= NULL;
    	m_Width		= 0;
    	m_Height	= 0;

    	return true;
    }

    void CMudDib::Render(HDC a_DC, int a_X, int a_Y, int a_Width, int a_Height)
    {
    	StretchDIBits(a_DC,
    		a_X, a_Y, a_Width, a_Height,
    		0,0, m_Width, m_Height,
    		m_Bits, &m_Info, DIB_RGB_COLORS, SRCCOPY);
    }

    void CMudDib::Render(HDC a_DC, const CRect& a_Dest, const CRect& a_Source)
    {
    	StretchDIBits(a_DC,
    		a_Dest.left, a_Dest.top, a_Dest.Width(), a_Dest.Height(),
    		a_Source.left, a_Source.top, a_Source.Width(), a_Source.Height(),
    		m_Bits, &m_Info, DIB_RGB_COLORS, SRCCOPY);
    }

    static inline COLORREF gSwapRedBlue(COLORREF a_Color)
    {
    	return (a_Color & 0xff00ff00)   |
    		   ((a_Color >> 16) & 0xff) |
    		   ((a_Color & 0xff) << 16);
    }

    void CMudDib::SetPixel(int a_X, int a_Y, COLORREF a_Color)
    {
    	if (a_Y < 0 || a_X < 0)
    		return;
    	if (a_Y >= m_Height || a_X >= m_Width)
    		return;

    	m_Bits[a_Y * m_Width + a_X] = gSwapRedBlue(a_Color);
    }

    COLORREF CMudDib::GetPixel(int a_X, int a_Y)
    {
    	if (a_Y < 0 || a_X < 0)
    		return 0;
    	if (a_Y >= m_Height || a_X >= m_Width)
    		return 0;

    	return gSwapRedBlue(m_Bits[a_Y * m_Width + a_X]);
    }

    // --> End of file <-----------------------------------------------------------

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/mudDib.h] - (1,307 bytes)

    #ifndef HEADER_dib
    #define HEADER_dib

    // --> Class declarations <----------------------------------------------------

    class CMudDib
    {
    public:
    				CMudDib();
    	virtual		~CMudDib();

    	bool		Create(int a_Width, int a_Height, HDC a_DC=NULL);
    	bool		Destroy();

    	void		Render(HDC a_DC, int a_X, int a_Y, int a_Width, int a_Height);
    	void		Render(HDC a_DC, const CRect& a_Dest, const CRect& a_Source);

    	void		SetPixel(int a_X, int a_Y, COLORREF a_Color);
    	COLORREF	GetPixel(int a_X, int a_Y);

    	COLORREF*	GetBits();
    	COLORREF*	GetScanline(int a_Y);
    	int			GetWidth() const;
    	int			GetHeight() const;
    	int			GetPitch() const;

    private:
    	COLORREF*	m_Bits;
    	BITMAPINFO	m_Info;
    	HBITMAP		m_Bitmap;
    	int			m_Width;
    	int			m_Height;
    };

    // --> Inline functions <------------------------------------------------------

    inline COLORREF* CMudDib::GetBits()
    {
    	return m_Bits;
    }

    inline COLORREF* CMudDib::GetScanline(int a_Y)
    {
    	return m_Bits + (a_Y*m_Width);
    }

    inline int CMudDib::GetWidth() const
    {
    	return m_Width;
    }

    inline int CMudDib::GetHeight() const
    {
    	return m_Height;
    }

    inline int CMudDib::GetPitch() const
    {
    	return m_Width*4;
    }

    // --> End of file <-----------------------------------------------------------
    #endif // HEADER_dib

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/mudFont.cpp] - (1,036 bytes)

    // --> Include files <---------------------------------------------------------

    #include "stdafx.h"
    #include "mudFont.h"
    #include "mudFontDlg.h"

    // --> Static members <--------------------------------------------------------

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

    BEGIN_MESSAGE_MAP(CMudFontApp, CWinApp)
    	//{{AFX_MSG_MAP(CMudFontApp)
    	//}}AFX_MSG
    	ON_COMMAND(ID_HELP, CWinApp::OnHelp)
    END_MESSAGE_MAP()

    CMudFontApp theApp;

    // --> Class implementation <--------------------------------------------------

    CMudFontApp::CMudFontApp()
    {
    }

    BOOL CMudFontApp::InitInstance()
    {
    	AfxEnableControlContainer();

    #ifdef _AFXDLL
    	Enable3dControls();			// Call this when using MFC in a shared DLL
    #else
    	Enable3dControlsStatic();	// Call this when linking to MFC statically
    #endif

    	CMudFontDlg dlg;
    	m_pMainWnd = &dlg;
    	dlg.DoModal();

    	return FALSE;
    }

    // --> End of file <-----------------------------------------------------------

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/mudFont.h] - (1,193 bytes)

    // mudFont.h : main header file for the MUDFONT application
    //

    #if !defined(AFX_MUDFONT_H__86F0CCA8_0EF2_42AD_B90B_0CE380C02C16__INCLUDED_)
    #define AFX_MUDFONT_H__86F0CCA8_0EF2_42AD_B90B_0CE380C02C16__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    #ifndef __AFXWIN_H__
    	#error include 'stdafx.h' before including this file for PCH
    #endif

    #include "resource.h"		// main symbols

    /////////////////////////////////////////////////////////////////////////////
    // CMudFontApp:
    // See mudFont.cpp for the implementation of this class
    //

    class CMudFontApp : public CWinApp
    {
    public:
    	CMudFontApp();

    // Overrides
    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CMudFontApp)
    	public:
    	virtual BOOL InitInstance();
    	//}}AFX_VIRTUAL

    // Implementation

    	//{{AFX_MSG(CMudFontApp)
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };

    /////////////////////////////////////////////////////////////////////////////

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

    #endif // !defined(AFX_MUDFONT_H__86F0CCA8_0EF2_42AD_B90B_0CE380C02C16__INCLUDED_)

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/mudFontDlg.cpp] - (28,581 bytes)

    // --> Include files <---------------------------------------------------------

    #include "stdafx.h"
    #include "mudFont.h"
    #include "addchardlg.h"
    #include "mudFontDlg.h"

    // --> Static members <--------------------------------------------------------

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

    BEGIN_MESSAGE_MAP(CMudFontDlg, CDialog)
    	//{{AFX_MSG_MAP(CMudFontDlg)
    	ON_WM_PAINT()
    	ON_WM_VSCROLL()
    	ON_WM_HSCROLL()
    	ON_BN_CLICKED(IDC_H64, OnSizeChange)
    	ON_BN_CLICKED(IDC_ITALIC, OnFontChange)
    	ON_BN_CLICKED(IDC_RECT, OnRectChange)
    	ON_EN_CHANGE(IDC_CBL_EDIT, OnCharChange)
    	ON_CBN_SELCHANGE(IDC_CHAR, OnSelchangeChar)
    	ON_COMMAND(ID_TOOLS_ADDCHAR, OnToolsAddchar)
    	ON_COMMAND(ID_FILE_EXIT, OnFileExit)
    	ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
    	ON_COMMAND(ID_FILE_NEW, OnFileNew)
    	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
    	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
    	ON_BN_CLICKED(IDC_H512, OnSizeChange)
    	ON_BN_CLICKED(IDC_H256, OnSizeChange)
    	ON_BN_CLICKED(IDC_H128, OnSizeChange)
    	ON_BN_CLICKED(IDC_W64, OnSizeChange)
    	ON_BN_CLICKED(IDC_W512, OnSizeChange)
    	ON_BN_CLICKED(IDC_W256, OnSizeChange)
    	ON_BN_CLICKED(IDC_W128, OnSizeChange)
    	ON_CBN_SELCHANGE(IDC_QUALITY, OnFontChange)
    	ON_EN_CHANGE(IDC_SIZE_EDIT, OnFontChange)
    	ON_CBN_SELCHANGE(IDC_WEIGHT, OnFontChange)
    	ON_CBN_SELCHANGE(IDC_FONT, OnFontChange)
    	ON_EN_CHANGE(IDC_BB_EDIT, OnFontChange)
    	ON_EN_CHANGE(IDC_BL_EDIT, OnFontChange)
    	ON_EN_CHANGE(IDC_BR_EDIT, OnFontChange)
    	ON_EN_CHANGE(IDC_BT_EDIT, OnFontChange)
    	ON_EN_CHANGE(IDC_CBR_EDIT, OnCharChange)
    	ON_CBN_SELCHANGE(IDC_AA, OnFontChange)
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    // --> Class implementation <--------------------------------------------------

    CMudFontDlg::CMudFontDlg(CWnd* pParent /*=NULL*/):
    	CDialog(CMudFontDlg::IDD, pParent),
    	m_Running(false)
    {
    	//{{AFX_DATA_INIT(CMudFontDlg)
    	m_ZoomText = _T("");
    	m_Height = -1;
    	m_Width = -1;
    	m_Italic = FALSE;
    	m_ShowRect = FALSE;
    	//}}AFX_DATA_INIT
    }

    void CMudFontDlg::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CMudFontDlg)
    	DDX_Control(pDX, IDC_AA, m_AA);
    	DDX_Control(pDX, IDC_CBR_SPIN, m_cbrSpin);
    	DDX_Control(pDX, IDC_CBR_EDIT, m_cbrEdit);
    	DDX_Control(pDX, IDC_CBL_SPIN, m_cblSpin);
    	DDX_Control(pDX, IDC_CBL_EDIT, m_cblEdit);
    	DDX_Control(pDX, IDC_CHAR, m_CharSel);
    	DDX_Control(pDX, IDC_BT_SPIN, m_btSpin);
    	DDX_Control(pDX, IDC_BT_EDIT, m_btEdit);
    	DDX_Control(pDX, IDC_BR_SPIN, m_brSpin);
    	DDX_Control(pDX, IDC_BR_EDIT, m_brEdit);
    	DDX_Control(pDX, IDC_BL_SPIN, m_blSpin);
    	DDX_Control(pDX, IDC_BL_EDIT, m_blEdit);
    	DDX_Control(pDX, IDC_BB_SPIN, m_bbSpin);
    	DDX_Control(pDX, IDC_BB_EDIT, m_bbEdit);
    	DDX_Control(pDX, IDC_WEIGHT, m_Weight);
    	DDX_Control(pDX, IDC_SIZE_SPIN, m_SizeSpin);
    	DDX_Control(pDX, IDC_SIZE_EDIT, m_SizeEdit);
    	DDX_Control(pDX, IDC_QUALITY, m_Quality);
    	DDX_Control(pDX, IDC_FONT, m_FontName);
    	DDX_Control(pDX, IDC_ZOOM, m_Zoom);
    	DDX_Control(pDX, IDC_UP, m_Up);
    	DDX_Control(pDX, IDC_RIGHT, m_Right);
    	DDX_Control(pDX, IDC_VIEW, m_View);
    	DDX_Text(pDX, IDC_ZOOM_TEXT, m_ZoomText);
    	DDX_Radio(pDX, IDC_H64, m_Height);
    	DDX_Radio(pDX, IDC_W64, m_Width);
    	DDX_Check(pDX, IDC_ITALIC, m_Italic);
    	DDX_Check(pDX, IDC_RECT, m_ShowRect);
    	//}}AFX_DATA_MAP
    }

    BOOL CMudFontDlg::OnInitDialog()
    {
    	int index;
    	CDialog::OnInitDialog();

    	// set initial values.
    	m_Zoom.SetRange(100,1000, TRUE);
    	m_Zoom.SetPos(100);
    	m_Zoom.SetTicFreq(50);
    	m_View.ShowWindow(SW_HIDE);
    	m_ZoomText.Format("%d%%", m_Zoom.GetPos());
    	m_Width = 2;
    	m_Height = 2;
    	m_Border = CRect(0,0,0,0);
    	UpdateData(FALSE);

    	// enumerate fonts.
    	CDC* pDC = GetDC();
    	EnumFonts(pDC->GetSafeHdc(), NULL, (FONTENUMPROC)EnumFontsProc, (LPARAM)&m_FontName);
    	m_FontName.SetCurSel(0);

    	// add anti-aliasing.
    	index = m_AA.AddString("(none)");
    	m_AA.SetItemData(index, 1);
    	index = m_AA.AddString("2x2");
    	m_AA.SetItemData(index, 2);
    	index = m_AA.AddString("3x3");
    	m_AA.SetItemData(index, 3);
    	index = m_AA.AddString("4x4");
    	m_AA.SetItemData(index, 4);
    	m_AA.SetCurSel(0);

    	// add qualities.
    	index = m_Quality.AddString("Antialiased");
    	m_Quality.SetItemData(index, ANTIALIASED_QUALITY);
    	index = m_Quality.AddString("non-Antialiased");
    	m_Quality.SetItemData(index, NONANTIALIASED_QUALITY);
    	m_Quality.SetCurSel(0);

    #ifdef CLEARTYPE_QUALITY
    	index = m_Quality.AddString("Cleartype");
    	m_Quality.SetItemData(index, CLEARTYPE_QUALITY);
    #endif

    	// add weights.
    	index = m_Weight.AddString("Normal");
    	m_Weight.SetItemData(index, FW_NORMAL);
    	index = m_Weight.AddString("Medium");
    	m_Weight.SetItemData(index, FW_SEMIBOLD);
    	index = m_Weight.AddString("Bold");
    	m_Weight.SetItemData(index, FW_BOLD);
    	m_Weight.SetCurSel(0);

    	// setup size control.
    	m_SizeSpin.SetBuddy(&m_SizeEdit);
    	m_SizeSpin.SetRange(5, 100);
    	m_SizeSpin.SetPos(11);

    	// setup border controls.
    	m_blSpin.SetBuddy(&m_blEdit);
    	m_blSpin.SetRange(0, 16);
    	m_blSpin.SetPos(0);
    	m_brSpin.SetBuddy(&m_brEdit);
    	m_brSpin.SetRange(0, 16);
    	m_brSpin.SetPos(0);
    	m_bbSpin.SetBuddy(&m_bbEdit);
    	m_bbSpin.SetRange(0, 16);
    	m_bbSpin.SetPos(0);
    	m_btSpin.SetBuddy(&m_btEdit);
    	m_btSpin.SetRange(0, 16);
    	m_btSpin.SetPos(0);

    	m_cblSpin.SetBuddy(&m_cblEdit);
    	m_cblSpin.SetRange(0, 16);
    	m_cblSpin.SetPos(0);
    	m_cbrSpin.SetBuddy(&m_cbrEdit);
    	m_cbrSpin.SetRange(0, 16);
    	m_cbrSpin.SetPos(0);

    	// setup initial font.
    	SetupFont();

    	// create the dibs for the font.
    	CPaintDC dc(this);
    	m_MemDC.CreateCompatibleDC(&dc);
    	m_MemDib.Create(512, 512, m_MemDC.GetSafeHdc());
    	m_Dib.Create(512, 512);

    	// force one event.
    	OnSizeChange();
    	m_Running = true;
    	return TRUE;
    }

    void CMudFontDlg::OnPaint()
    {
    	CPaintDC dc(this);

    	CRect destRect;
    	CRect sourceRect;
    	m_View.GetWindowRect(&destRect);
    	::MapWindowPoints(HWND_DESKTOP, m_hWnd, reinterpret_cast<LPPOINT>(&destRect), 2);

    	CRgn rgn;
    	CPoint pnt1(destRect.left, destRect.top);
    	CPoint pnt2(destRect.right, destRect.bottom);
    	dc.LPtoDP(&pnt1, 1);
    	dc.LPtoDP(&pnt2, 1);
    	rgn.CreateRectRgn(pnt1.x, pnt1.y, pnt2.x, pnt2.y);
    	dc.SelectClipRgn(&rgn);

    	float zoom = (100.0f / m_Zoom.GetPos());
    	int width = destRect.Width() * zoom;
    	int height = destRect.Height() * zoom;

    	sourceRect.left = m_Right.GetScrollPos();
    	sourceRect.top = 512 - height - m_Up.GetScrollPos();
    	sourceRect.right = sourceRect.left + width;
    	sourceRect.bottom = sourceRect.top + height;
    	m_Dib.Render(dc.GetSafeHdc(), destRect, sourceRect);

    	m_Right.SetScrollRange(0, 512 - width);
    	m_Up.SetScrollRange(0, 512 - height);

    	CPen pen(PS_DOT, 1, RGB(192, 192, 192));
    	dc.SelectObject(pen);

    	if (m_ShowRect)
    	{
    		int len = m_Chars.GetSize();
    		for (int i=0; i<len; i++)
    		{
    			const cCharacter& ch = m_Chars[i];

    			CRect rect;
    			rect.left	= ch.m_Pos.x - m_Right.GetScrollPos();
    			rect.top	= ch.m_Pos.y - m_Up.GetScrollPos();
    			rect.right	= rect.left + ch.m_Size.cx;
    			rect.bottom = rect.top + ch.m_Size.cy;

    			rect.left	/= zoom;
    			rect.top	/= zoom;
    			rect.right	/= zoom;
    			rect.bottom /= zoom;

    			::MapWindowPoints(m_View.GetSafeHwnd(), m_hWnd, reinterpret_cast<LPPOINT>(&rect), 2);
    			rect.OffsetRect(-1, -1);

    			dc.MoveTo(rect.left, rect.top);
    			dc.LineTo(rect.right, rect.top);
    			dc.LineTo(rect.right, rect.bottom);
    			dc.LineTo(rect.left, rect.bottom);
    			dc.LineTo(rect.left, rect.top);
    		}
    	}
    }

    void CMudFontDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    	CDialog::OnVScroll(nSBCode, nPos, pScrollBar);

    	if (pScrollBar != NULL)
    	{
    		// Get the minimum and maximum scroll-bar positions.
    		int minpos;
    		int maxpos;
    		pScrollBar->GetScrollRange(&minpos, &maxpos);
    		maxpos = pScrollBar->GetScrollLimit();

    		// Get the current position of scroll box.
    		int curpos = pScrollBar->GetScrollPos();

    		// Determine the new position of scroll box.
    		switch (nSBCode)
    		{
    		case SB_TOP:
    			curpos = minpos;
    			break;

    		case SB_BOTTOM:
    			curpos = maxpos;
    			break;

    		case SB_ENDSCROLL:
    			break;

    		case SB_LINEUP:
    			if (curpos > minpos)
    				curpos--;
    			break;

    		case SB_LINEDOWN:
    			if (curpos < maxpos)
    				curpos++;
    			break;

    		case SB_PAGEUP:   // Scroll one page up.
    			if (curpos > minpos)
    			{
    				curpos = max(minpos, curpos - 10);
    			}
    			break;

    		case SB_PAGEDOWN:    // Scroll one page down.
    			if (curpos < maxpos)
    			{
    				curpos = min(maxpos, curpos + 10);
    			}
    			break;

    		case SB_THUMBPOSITION:
    			curpos = nPos;
    			break;

    		case SB_THUMBTRACK:
    			curpos = nPos;
    			break;
    		}

    		// Set the new position of the thumb (scroll box).
    		pScrollBar->SetScrollPos(curpos);
    		InvalidateView();
    	}
    }

    void CMudFontDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
    {
    	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
    	if (pScrollBar != NULL)
    	{
    		if (pScrollBar->GetSafeHwnd() == m_Zoom.GetSafeHwnd())
    		{
    			int pos = m_Zoom.GetPos();
    			m_ZoomText.Format("%d%%", pos);
    			UpdateData(FALSE);
    			InvalidateView();
    		} else
    		{
    			// Get the minimum and maximum scroll-bar positions.
    			int minpos;
    			int maxpos;
    			pScrollBar->GetScrollRange(&minpos, &maxpos);
    			maxpos = pScrollBar->GetScrollLimit();

    			// Get the current position of scroll box.
    			int curpos = pScrollBar->GetScrollPos();

    			// Determine the new position of scroll box.
    			switch (nSBCode)
    			{
    			case SB_LEFT:    // Scroll to far left.
    				curpos = minpos;
    				break;

    			case SB_RIGHT:    // Scroll to far right.
    				curpos = maxpos;
    				break;

    			case SB_ENDSCROLL:  // End scroll.
    				break;

    			case SB_LINELEFT:    // Scroll left.
    				if (curpos > minpos)
    					curpos--;
    				break;

    			case SB_LINERIGHT:  // Scroll right.
    				if (curpos < maxpos)
    					curpos++;
    				break;

    			case SB_PAGELEFT:   // Scroll one page left.
    				if (curpos > minpos)
    				{
    					curpos = max(minpos, curpos - 10);
    				}
    				break;

    			case SB_PAGERIGHT:    // Scroll one page right.
    				if (curpos < maxpos)
    				{
    					curpos = min(maxpos, curpos + 10);
    				}
    				break;

    			case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
    				curpos = nPos;      // of the scroll box at the end of the drag
    				// operation.
    				break;

    			case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is
    				// the
    				curpos = nPos;     // position that the scroll box has been dragged
    				// to.
    				break;
    			}

    			// Set the new position of the thumb (scroll box).
    			pScrollBar->SetScrollPos(curpos);
    			InvalidateView();
    		}
    	}
    }

    void CMudFontDlg::SetupFont()
    {
    	int		index;
    	int		nHeight;
    	int		nWeight;
    	int		nQuality;
    	CString Facename;

    	UpdateData(TRUE);
    	m_FontName.GetWindowText(Facename);

    	nHeight = m_SizeSpin.GetPos();
    	if (nHeight > 100)	nHeight = 100;
    	if (nHeight < 5)	nHeight = 5;
    	index = m_Weight.GetCurSel();
    	nWeight = m_Weight.GetItemData(index);

    	index = m_Quality.GetCurSel();
    	nQuality = m_Quality.GetItemData(index);

    	index = m_AA.GetCurSel();
    	nHeight *= m_AA.GetItemData(index);

    	// delete old font.
    	if (m_DrawFont.GetSafeHandle() != NULL)
    	{
    		m_DrawFont.DeleteObject();
    	}

    	// create new font.
    	CPaintDC dc(this);
    	int realHeight = -MulDiv(nHeight, GetDeviceCaps(dc.GetSafeHdc(), LOGPIXELSY), 72);
    	m_DrawFont.CreateFont(realHeight, 0, 0, 0, nWeight, m_Italic, FALSE,
    		0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
    		nQuality, DEFAULT_PITCH | FF_SWISS, Facename);
    }

    void CMudFontDlg::UpdateTextureSize()
    {
    	for (int y=0; y<512; y++)
    	{
    		for (int x=0; x<512; x++)
    		{
    			if (x < m_TextureWidth && y < m_TextureHeight)
    			{
    				m_Dib.SetPixel(x,y, RGB(255,0,255));
    			} else
    			{
    				if ((x % 10) == (y % 10) || ((512-x) % 10) == (y % 10))
    				{
    					m_Dib.SetPixel(x,y, RGB(0,0,0));
    				} else
    				{
    					m_Dib.SetPixel(x,y, RGB(128, 128, 128));
    				}
    			}
    		}
    	}
    }

    void CMudFontDlg::UpdateTexture()
    {
    	// clear the texture.
    	UpdateTextureSize();
    	UpdateSizes();
    	UpdatePositions();

    	DrawChars();
    	InvalidateView();
    }

    void CMudFontDlg::UpdateSizes()
    {
    	m_MemDC.SelectObject(m_DrawFont);

    	int sel = m_CharSel.GetCurSel();
    	m_CharSel.ResetContent();

    	int index = m_AA.GetCurSel();
    	int sampling = m_AA.GetItemData(index);

    	int len = m_Chars.GetSize();
    	for (int i=0; i<len; i++)
    	{
    		cCharacter& ch = m_Chars[i];
    		m_CharSel.AddString(CString(ch.m_Char));
    		ch.m_Size = m_MemDC.GetTextExtent(&ch.m_Char, 1);

    		ch.m_Size.cx /= sampling;
    		ch.m_Size.cy /= sampling;

    		ch.m_Size.cx += m_Border.left + m_Border.right + ch.m_bLeft + ch.m_bRight;
    		ch.m_Size.cy += m_Border.top + m_Border.bottom;
    	}

    	m_CharSel.SetCurSel(sel);
    }

    void CMudFontDlg::UpdatePositions()
    {
    	int cx = 0;
    	int cy = 0;
    	int height = 0;

    	int len = m_Chars.GetSize();
    	for (int i=0; i<len; i++)
    	{
    		cCharacter& ch = m_Chars[i];

    		if (ch.m_Size.cy > height)
    		{
    			height = ch.m_Size.cy;
    		}

    		if (cx + ch.m_Size.cx > m_TextureWidth)
    		{
    			cx = 0;
    			cy += height + 1;
    		}

    		ch.m_Pos.x = cx;
    		ch.m_Pos.y = cy;

    		cx += ch.m_Size.cx + 1;
    	}
    }

    void CMudFontDlg::InvalidateView()
    {
    	CRect rect;
    	m_View.GetWindowRect(&rect);
    	::MapWindowPoints(HWND_DESKTOP, m_hWnd, reinterpret_cast<LPPOINT>(&rect), 2);
    	InvalidateRect(&rect, FALSE);
    }

    void CMudFontDlg::OnSizeChange()
    {
    	UpdateData(TRUE);

    	switch (m_Width)
    	{
    	case 0:	m_TextureWidth = 64;	break;
    	case 1:	m_TextureWidth = 128;	break;
    	case 2:	m_TextureWidth = 256;	break;
    	case 3:	m_TextureWidth = 512;	break;
    	}

    	switch (m_Height)
    	{
    	case 0:	m_TextureHeight = 64;	break;
    	case 1:	m_TextureHeight = 128;	break;
    	case 2:	m_TextureHeight = 256;	break;
    	case 3:	m_TextureHeight = 512;	break;
    	}

    	UpdateTexture();
    }

    void CMudFontDlg::DrawChars()
    {
    	CBrush brush(RGB(0,0,0));
    	CPen   pen(PS_SOLID, 1, RGB(0,0,0));
    	m_MemDC.SelectObject(brush);
    	m_MemDC.SelectObject(pen);
    	m_MemDC.SetTextColor(RGB(255,255,255));
    	m_MemDC.SetBkMode(TRANSPARENT);
    	m_MemDC.SelectObject(m_DrawFont);

    	int index = m_AA.GetCurSel();
    	int sampling = m_AA.GetItemData(index);

    	int len = m_Chars.GetSize();
    	for (int i=0; i<len; i++)
    	{
    		const cCharacter& ch = m_Chars[i];
    		int width  = ch.m_Size.cx;
    		int height = ch.m_Size.cy;
    		int posx   = (m_Border.left + ch.m_bLeft) * sampling;
    		int posy   = (m_Border.top) * sampling;
    		int value, x, y;

    		// draw character.
    		CRect rect(0, 0, width * sampling, height * sampling);
    		m_MemDC.Rectangle(rect);
    		m_MemDC.TextOut(posx, posy, ch.m_Char);

    		// quite a quick hack this way...
    		// I guess we can think of a more generic way...
    		switch (sampling)
    		{
    		case 1:
    			for (y=0; y<height; y++)
    			{
    				for (x=0; x<width; x++)
    				{
    					COLORREF col = m_MemDib.GetPixel(x, y);
    					if (y + ch.m_Pos.y < m_TextureHeight && x + ch.m_Pos.x < m_TextureWidth)
    					{
    						m_Dib.SetPixel(x + ch.m_Pos.x, y + ch.m_Pos.y, col);
    					}
    				}
    			}
    			break;
    		case 2:
    			for (y=0; y<height; y++)
    			{
    				for (x=0; x<width; x++)
    				{
    					if (y + ch.m_Pos.y < m_TextureHeight && x + ch.m_Pos.x < m_TextureWidth)
    					{
    						int xb = x * 2;
    						int yb = y * 2;
    						value = m_MemDib.GetPixel(xb+0, yb+0) & 0xff;
    						value += m_MemDib.GetPixel(xb+1, yb+0) & 0xff;
    						value += m_MemDib.GetPixel(xb+1, yb+1) & 0xff;
    						value += m_MemDib.GetPixel(xb+0, yb+1) & 0xff;
    						value /= 4;

    						m_Dib.SetPixel(x + ch.m_Pos.x, y + ch.m_Pos.y, RGB(value, value, value));
    					}
    				}
    			}
    			break;

    		case 3:
    			for (y=0; y<height; y++)
    			{
    				for (x=0; x<width; x++)
    				{
    					if (y + ch.m_Pos.y < m_TextureHeight && x + ch.m_Pos.x < m_TextureWidth)
    					{
    						int xb = x * 3;
    						int yb = y * 3;
    						value  = (m_MemDib.GetPixel(xb+0, yb+0) & 0xff) * 1;
    						value += (m_MemDib.GetPixel(xb+1, yb+0) & 0xff) * 3;
    						value += (m_MemDib.GetPixel(xb+2, yb+0) & 0xff) * 1;
    						value += (m_MemDib.GetPixel(xb+0, yb+1) & 0xff) * 3;
    						value += (m_MemDib.GetPixel(xb+1, yb+1) & 0xff) * 5;
    						value += (m_MemDib.GetPixel(xb+2, yb+1) & 0xff) * 3;
    						value += (m_MemDib.GetPixel(xb+0, yb+2) & 0xff) * 1;
    						value += (m_MemDib.GetPixel(xb+1, yb+2) & 0xff) * 3;
    						value += (m_MemDib.GetPixel(xb+2, yb+2) & 0xff) * 1;
    						value /= 21;

    						m_Dib.SetPixel(x + ch.m_Pos.x, y + ch.m_Pos.y, RGB(value, value, value));
    					}
    				}
    			}
    			break;

    		case 4:
    			for (y=0; y<height; y++)
    			{
    				for (x=0; x<width; x++)
    				{
    					if (y + ch.m_Pos.y < m_TextureHeight && x + ch.m_Pos.x < m_TextureWidth)
    					{
    						int xb = x * 4;
    						int yb = y * 4;
    						value  = (m_MemDib.GetPixel(xb+0, yb+0) & 0xff) * 1;
    						value += (m_MemDib.GetPixel(xb+1, yb+0) & 0xff) * 2;
    						value += (m_MemDib.GetPixel(xb+2, yb+0) & 0xff) * 2;
    						value += (m_MemDib.GetPixel(xb+3, yb+0) & 0xff) * 1;
    						value += (m_MemDib.GetPixel(xb+0, yb+1) & 0xff) * 2;
    						value += (m_MemDib.GetPixel(xb+1, yb+1) & 0xff) * 4;
    						value += (m_MemDib.GetPixel(xb+2, yb+1) & 0xff) * 4;
    						value += (m_MemDib.GetPixel(xb+3, yb+1) & 0xff) * 2;
    						value += (m_MemDib.GetPixel(xb+0, yb+2) & 0xff) * 2;
    						value += (m_MemDib.GetPixel(xb+1, yb+2) & 0xff) * 4;
    						value += (m_MemDib.GetPixel(xb+2, yb+2) & 0xff) * 4;
    						value += (m_MemDib.GetPixel(xb+3, yb+2) & 0xff) * 2;
    						value += (m_MemDib.GetPixel(xb+0, yb+3) & 0xff) * 1;
    						value += (m_MemDib.GetPixel(xb+1, yb+3) & 0xff) * 2;
    						value += (m_MemDib.GetPixel(xb+2, yb+3) & 0xff) * 2;
    						value += (m_MemDib.GetPixel(xb+3, yb+3) & 0xff) * 1;
    						value /= 36;

    						m_Dib.SetPixel(x + ch.m_Pos.x, y + ch.m_Pos.y, RGB(value, value, value));
    					}
    				}
    			}
    			break;
    		}

    	}
    }

    void CMudFontDlg::AddCharacter(char a_Char)
    {
    	int len = m_Chars.GetSize();
    	for (int i=0; i<len; i++)
    	{
    		if (m_Chars[i].m_Char == a_Char)
    			return;
    	}

    	cCharacter ch;
    	ch.m_Char = a_Char;
    	ch.m_bLeft = 0;
    	ch.m_bRight = 0;

    	m_Chars.Add(ch);
    }

    int CALLBACK CMudFontDlg::EnumFontsProc(CONST LOGFONT* lplf, CONST TEXTMETRIC* lptm, DWORD dwType, LPARAM lpData)
    {
    	CComboBox* fonts = (CComboBox*)lpData;
    	fonts->AddString(lplf->lfFaceName);
        return 1;
    }

    void CMudFontDlg::OnFontChange()
    {
    	m_Border.left	= m_blSpin.GetPos();
    	m_Border.right	= m_brSpin.GetPos();
    	m_Border.top	= m_btSpin.GetPos();
    	m_Border.bottom = m_bbSpin.GetPos();

    	SetupFont();
    	if (m_Running)
    	{
    		UpdateTexture();
    	}
    }

    void CMudFontDlg::OnRectChange()
    {
    	UpdateData(TRUE);
    	InvalidateView();
    }

    void CMudFontDlg::OnCharChange()
    {
    	int index = m_CharSel.GetCurSel();
    	if (index >= 0)
    	{
    		m_Chars[index].m_bLeft  = m_cblSpin.GetPos();
    		m_Chars[index].m_bRight = m_cbrSpin.GetPos();

    		if (m_Running)
    		{
    			UpdateTexture();
    		}
    	}
    }

    void CMudFontDlg::OnSelchangeChar()
    {
    	int index = m_CharSel.GetCurSel();
    	if (index >= 0)
    	{
    		m_cblSpin.SetPos(m_Chars[index].m_bLeft);
    		m_cbrSpin.SetPos(m_Chars[index].m_bRight);
    	}
    }

    void CMudFontDlg::OnToolsAddchar()
    {
    	CAddCharDlg dlg;
    	if (dlg.DoModal())
    	{
    		CString chars = dlg.GetString();
    		int len = chars.GetLength();
    		for (int i=0; i<len; i++)
    		{
    			AddCharacter(chars[i]);
    		}
    		UpdateTexture();
    	}
    }

    void CMudFontDlg::OnFileExit()
    {
    	EndDialog(0);
    }

    void CMudFontDlg::OnFileExport()
    {
    	OPENFILENAME ofn;       // common dialog box structure
    	char szFile[260];       // buffer for file name
    	memset(szFile, 0, sizeof(szFile));

    	// Initialize OPENFILENAME
    	ZeroMemory(&ofn, sizeof(OPENFILENAME));
    	ofn.lStructSize = sizeof(OPENFILENAME);
    	ofn.hwndOwner = GetSafeHwnd();
    	ofn.lpstrFile = szFile;
    	ofn.nMaxFile = sizeof(szFile);
    	ofn.lpstrFilter = "Targa image (*.tga)\0*.tga\0";
    	ofn.nFilterIndex = 1;
    	ofn.lpstrFileTitle = NULL;
    	ofn.nMaxFileTitle = 0;
    	ofn.lpstrInitialDir = NULL;
    	ofn.lpstrDefExt = "tga";
    	ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;

    	// Display the Open dialog box.
    	if (GetSaveFileName(&ofn) == TRUE)
    	{
    		ExportTGA(szFile);
    		ExportInfo(szFile);
    	}
    }

    void CMudFontDlg::OnFileNew()
    {
    	m_Chars.RemoveAll();
    	UpdateTexture();
    }

    void CMudFontDlg::OnFileOpen()
    {
    	OPENFILENAME ofn;       // common dialog box structure
    	char szFile[260];       // buffer for file name
    	memset(szFile, 0, sizeof(szFile));

    	// Initialize OPENFILENAME
    	ZeroMemory(&ofn, sizeof(OPENFILENAME));
    	ofn.lStructSize = sizeof(OPENFILENAME);
    	ofn.hwndOwner = GetSafeHwnd();
    	ofn.lpstrFile = szFile;
    	ofn.nMaxFile = sizeof(szFile);
    	ofn.lpstrFilter = "Font (*.fnt)\0*.fnt\0All (*.*)\0*.*\0";
    	ofn.nFilterIndex = 1;
    	ofn.lpstrFileTitle = NULL;
    	ofn.nMaxFileTitle = 0;
    	ofn.lpstrDefExt = "fnt";
    	ofn.lpstrInitialDir = NULL;
    	ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

    	// Display the Open dialog box.
    	if (GetOpenFileName(&ofn) == TRUE)
    	{
    		m_Chars.RemoveAll();
    		FILE* file = fopen(szFile, "rb");
    		if (file != NULL)
    		{
    			int		nHeight;
    			int		nWeight;
    			int		nQuality;
    			int		nSampling;
    			CString Facename;

    			fread(&m_TextureWidth, sizeof(int), 1, file);
    			fread(&m_TextureHeight, sizeof(int), 1, file);

    			fread(&m_Border.left, sizeof(int), 1, file);
    			m_blSpin.SetPos(m_Border.left);
    			fread(&m_Border.top, sizeof(int), 1, file);
    			m_btSpin.SetPos(m_Border.top);
    			fread(&m_Border.right, sizeof(int), 1, file);
    			m_brSpin.SetPos(m_Border.right);
    			fread(&m_Border.bottom, sizeof(int), 1, file);
    			m_bbSpin.SetPos(m_Border.bottom);

    			fread(&nHeight, sizeof(int), 1, file);
    			fread(&nWeight, sizeof(int), 1, file);
    			fread(&nQuality, sizeof(int), 1, file);
    			fread(&nSampling, sizeof(int), 1, file);
    			fread(&m_Italic, sizeof(BOOL), 1, file);

    			int len;
    			char buf[256];
    			fread(&len, sizeof(int), 1, file);
    			fread(buf, len+1, 1, file);
    			Facename = buf;

    			UpdateUI(nHeight, nWeight, nQuality, nSampling, Facename);

    			int numChars;
    			fread(&numChars, sizeof(int), 1, file);
    			for (int i=0; i<numChars; i++)
    			{
    				char ch;
    				int bl, br;

    				fread(&ch, sizeof(char), 1, file);
    				fread(&bl, sizeof(int), 1, file);
    				fread(&br, sizeof(int), 1, file);

    				cCharacter kar;
    				kar.m_Char = ch;
    				kar.m_bLeft = bl;
    				kar.m_bRight = br;
    				m_Chars.Add(kar);
    			}

    			fclose(file);
    			OnFontChange();
    		}
    	}
    	DWORD error = CommDlgExtendedError();

    }

    void CMudFontDlg::OnFileSave()
    {
    	OPENFILENAME ofn;       // common dialog box structure
    	char szFile[260];       // buffer for file name
    	memset(szFile, 0, sizeof(szFile));

    	// Initialize OPENFILENAME
    	ZeroMemory(&ofn, sizeof(OPENFILENAME));
    	ofn.lStructSize = sizeof(OPENFILENAME);
    	ofn.hwndOwner = GetSafeHwnd();
    	ofn.lpstrFile = szFile;
    	ofn.nMaxFile = sizeof(szFile);
    	ofn.lpstrFilter = "Font (*.fnt)\0*.fnt\0All (*.*)\0*.*\0";
    	ofn.nFilterIndex = 1;
    	ofn.lpstrFileTitle = NULL;
    	ofn.nMaxFileTitle = 0;
    	ofn.lpstrInitialDir = NULL;
    	ofn.lpstrDefExt = "fnt";
    	ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;

    	// Display the Open dialog box.
    	if (GetSaveFileName(&ofn) == TRUE)
    	{
    		int		index;
    		int		nHeight;
    		int		nWeight;
    		int		nQuality;
    		int		nSampling;
    		CString Facename;

    		UpdateData(TRUE);
    		m_FontName.GetWindowText(Facename);

    		nHeight = m_SizeSpin.GetPos();
    		if (nHeight > 100)	nHeight = 100;
    		if (nHeight < 5)	nHeight = 5;
    		index = m_Weight.GetCurSel();
    		nWeight = m_Weight.GetItemData(index);

    		index = m_Quality.GetCurSel();
    		nQuality = m_Quality.GetItemData(index);

    		index = m_AA.GetCurSel();
    		nSampling = m_AA.GetItemData(index);

    		FILE* file = fopen(szFile, "w+b");
    		if (file != NULL)
    		{
    			fwrite(&m_TextureWidth, sizeof(int), 1, file);
    			fwrite(&m_TextureHeight, sizeof(int), 1, file);
    			fwrite(&m_Border.left, sizeof(int), 1, file);
    			fwrite(&m_Border.top, sizeof(int), 1, file);
    			fwrite(&m_Border.right, sizeof(int), 1, file);
    			fwrite(&m_Border.bottom, sizeof(int), 1, file);

    			fwrite(&nHeight, sizeof(int), 1, file);
    			fwrite(&nWeight, sizeof(int), 1, file);
    			fwrite(&nQuality, sizeof(int), 1, file);
    			fwrite(&nSampling, sizeof(int), 1, file);
    			fwrite(&m_Italic, sizeof(BOOL), 1, file);

    			int len = Facename.GetLength();
    			fwrite(&len, sizeof(int), 1, file);
    			fwrite((LPCTSTR)Facename, len+1, 1, file);

    			int numChars = m_Chars.GetSize();
    			fwrite(&numChars, sizeof(int), 1, file);
    			for (int i=0; i<numChars; i++)
    			{
    				fwrite(&m_Chars[i].m_Char, sizeof(char), 1, file);
    				fwrite(&m_Chars[i].m_bLeft, sizeof(int), 1, file);
    				fwrite(&m_Chars[i].m_bRight, sizeof(int), 1, file);
    			}

    			fclose(file);
    		}
    	}
    	DWORD error = CommDlgExtendedError();

    }

    void CMudFontDlg::UpdateUI(int nHeight, int nWeight, int nQuality, int nSampling, const CString& Facename)
    {
    	int i, len;

    	UpdateData(TRUE);
    	m_SizeSpin.SetPos(nHeight);

    	len = m_Weight.GetCount();
    	for (i=0; i<len; i++)
    	{
    		if (m_Weight.GetItemData(i) == nWeight)
    		{
    			m_Weight.SetCurSel(i);
    			break;
    		}
    	}

    	len = m_Quality.GetCount();
    	for (i=0; i<len; i++)
    	{
    		if (m_Quality.GetItemData(i) == nQuality)
    		{
    			m_Quality.SetCurSel(i);
    			break;
    		}
    	}

    	len = m_AA.GetCount();
    	for (i=0; i<len; i++)
    	{
    		if (m_AA.GetItemData(i) == nSampling)
    		{
    			m_AA.SetCurSel(i);
    			break;
    		}
    	}

    	len = m_FontName.GetCount();
    	for (i=0; i<len; i++)
    	{
    		CString str;
    		m_FontName.GetLBText(i, str);
    		if (str.CompareNoCase(Facename) == 0)
    		{
    			m_FontName.SetCurSel(i);
    			break;
    		}
    	}
    }

    void CMudFontDlg::ExportTGA(const char* a_Filename)
    {
    	char path[_MAX_PATH];
    	char drive[_MAX_DRIVE];
    	char dir[_MAX_DIR];
    	char fname[_MAX_FNAME];
    	_splitpath(a_Filename, drive, dir, fname, NULL);
    	_makepath(path, drive, dir, fname, ".tga");

    	FILE* file = fopen(path, "w+b");
    	if (file == NULL) return;

    	char	Id_Size			= 0;			// no user data at end of tga.
    	char	ColorMap_Type	= 0;			// no colormap.
    	char	Image_Type      = 2;			// uncompressed raw image data. (RGBA)
    	short	ColorMap_Low	= 0;			// no color map, so this must be set to zero.
    	short	ColorMap_Length	= 0;			// no color map, so this must be set to zero.
    	char	ColorMap_Bits	= 0;			// no color map, so this must be set to zero.
    	short	XOrigin			= 0;			// ??
    	short	YOrigin			= 0;			// ??
    	short	Width			= m_TextureWidth;
    	short	Height			= m_TextureHeight;
    	char	BPP				= 32;			// 32bits RGBA.
    	char	AttrBits		= 0x20 | 8;		// first pixel at top-left, and 8 bits for alpha.

    	fwrite(&Id_Size, sizeof(char), 1, file);
    	fwrite(&ColorMap_Type, sizeof(char), 1, file);
    	fwrite(&Image_Type, sizeof(char), 1, file);
    	fwrite(&ColorMap_Low, sizeof(short), 1, file);
    	fwrite(&ColorMap_Length, sizeof(short), 1, file);
    	fwrite(&ColorMap_Bits, sizeof(char), 1, file);
    	fwrite(&XOrigin, sizeof(short), 1, file);
    	fwrite(&YOrigin, sizeof(short), 1, file);
    	fwrite(&Width, sizeof(short), 1, file);
    	fwrite(&Height, sizeof(short), 1, file);
    	fwrite(&BPP, sizeof(char), 1, file);
    	fwrite(&AttrBits, sizeof(char), 1, file);

    	for (int y=0; y<m_TextureHeight; y++)
    	{
    		for (int x=0; x<m_TextureWidth; x++)
    		{
    			// get intensity.
    			int intensity = m_Dib.GetPixel(x,y) & 0xff;

    			// write rgba color;
    			unsigned int color = intensity << 24 | 0x00ffffff;
    			fwrite(&color, sizeof(unsigned int), 1, file);
    		}
    	}

    	fclose(file);
    }

    void CMudFontDlg::ExportInfo(const char* a_Filename)
    {
    	char path[_MAX_PATH];
    	char drive[_MAX_DRIVE];
    	char dir[_MAX_DIR];
    	char fname[_MAX_FNAME];
    	_splitpath(a_Filename, drive, dir, fname, NULL);
    	_makepath(path, drive, dir, fname, ".xml");

    	FILE* file = fopen(path, "w+t");
    	if (file == NULL) return;

    	fprintf(file, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
    	fprintf(file, "<font>\n");

    	int numChars = m_Chars.GetSize();
    	for (int i=0; i<numChars; i++)
    	{
    		const cCharacter& ch = m_Chars[i];
    		fprintf(file, "\t<char id=\"%d\" x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" />\n",
    			ch.m_Char, ch.m_Pos.x, ch.m_Pos.y, ch.m_Size.cx, ch.m_Size.cy);
    	}

    	fprintf(file, "</font>\n");
    	fclose(file);
    }

    // --> End of file <-----------------------------------------------------------

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/mudFontDlg.h] - (3,194 bytes)

    // mudFontDlg.h : header file
    //

    #if !defined(AFX_MUDFONTDLG_H__CFFC602D_8F6E_4340_B3EC_ADCD55315D0F__INCLUDED_)
    #define AFX_MUDFONTDLG_H__CFFC602D_8F6E_4340_B3EC_ADCD55315D0F__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    /////////////////////////////////////////////////////////////////////////////
    // CMudFontDlg dialog

    struct cCharacter
    {
    	char	m_Char;
    	int		m_bLeft;
    	int		m_bRight;

    	CPoint	m_Pos;	// generated.
    	CSize	m_Size;	// generated.
    };

    typedef CArray<cCharacter, const cCharacter&> CCharArray;

    class CMudFontDlg : public CDialog
    {
    // Construction
    public:
    	CMudFontDlg(CWnd* pParent = NULL);	// standard constructor

    // Dialog Data
    	//{{AFX_DATA(CMudFontDlg)
    	enum { IDD = IDD_MUDFONT };
    	CComboBox	m_AA;
    	CSpinButtonCtrl	m_cbrSpin;
    	CEdit			m_cbrEdit;
    	CSpinButtonCtrl	m_cblSpin;
    	CEdit			m_cblEdit;
    	CComboBox		m_CharSel;
    	CSpinButtonCtrl	m_btSpin;
    	CEdit			m_btEdit;
    	CSpinButtonCtrl	m_brSpin;
    	CEdit			m_brEdit;
    	CSpinButtonCtrl	m_blSpin;
    	CEdit			m_blEdit;
    	CSpinButtonCtrl	m_bbSpin;
    	CEdit			m_bbEdit;
    	CComboBox		m_Weight;
    	CSpinButtonCtrl	m_SizeSpin;
    	CEdit			m_SizeEdit;
    	CComboBox		m_Quality;
    	CComboBox		m_FontName;
    	CSliderCtrl		m_Zoom;
    	CScrollBar		m_Up;
    	CScrollBar		m_Right;
    	CStatic			m_View;
    	CString			m_ZoomText;
    	int				m_Height;
    	int				m_Width;
    	BOOL			m_Italic;
    	BOOL			m_ShowRect;
    	//}}AFX_DATA

    	// ClassWizard generated virtual function overrides
    	//{{AFX_VIRTUAL(CMudFontDlg)
    	protected:
    	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
    	//}}AFX_VIRTUAL

    // Implementation
    protected:
    	CMudDib				m_Dib;
    	int					m_TextureWidth;
    	int					m_TextureHeight;
    	CCharArray			m_Chars;
    	CDC					m_MemDC;
    	CMudDib				m_MemDib;
    	CFont				m_DrawFont;
    	bool				m_Running;
    	CRect				m_Border;

    	void		SetupFont();
    	void		UpdateTextureSize();
    	void		UpdateTexture();
    	void		UpdateSizes();
    	void		UpdatePositions();
    	void		DrawChars();
    	void		UpdateUI(int nHeight, int nWeight, int nQuality, int nSampling, const CString& Facename);

    	void		InvalidateView();
    	void		AddCharacter(char a_Char);
    	void		ExportTGA(const char* a_Filename);
    	void		ExportInfo(const char* a_Filename);

    	static int CALLBACK EnumFontsProc(CONST LOGFONT* lplf, CONST TEXTMETRIC* lptm, DWORD dwType, LPARAM lpData);

    	//{{AFX_MSG(CMudFontDlg)
    	virtual BOOL OnInitDialog();
    	afx_msg void OnPaint();
    	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    	afx_msg void OnSizeChange();
    	afx_msg void OnFontChange();
    	afx_msg void OnRectChange();
    	afx_msg void OnCharChange();
    	afx_msg void OnSelchangeChar();
    	afx_msg void OnToolsAddchar();
    	afx_msg void OnFileExit();
    	afx_msg void OnFileExport();
    	afx_msg void OnFileNew();
    	afx_msg void OnFileOpen();
    	afx_msg void OnFileSave();
    	//}}AFX_MSG
    	DECLARE_MESSAGE_MAP()
    };

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

    #endif // !defined(AFX_MUDFONTDLG_H__CFFC602D_8F6E_4340_B3EC_ADCD55315D0F__INCLUDED_)

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/resource.h] - (2,252 bytes)

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by mudFont.rc
    //
    #define IDD_MUDFONT                     102
    #define IDD_ADDCHAR                     132
    #define IDC_UP                          1001
    #define IDC_VIEW                        1002
    #define IDC_RIGHT                       1003
    #define IDC_ZOOM                        1006
    #define IDC_ZOOM_TEXT                   1007
    #define IDC_W64                         1008
    #define IDC_W128                        1009
    #define IDC_W256                        1010
    #define IDC_W512                        1011
    #define IDC_H64                         1012
    #define IDC_H128                        1013
    #define IDC_H256                        1014
    #define IDC_H512                        1015
    #define IDC_FONT                        1016
    #define IDC_QUALITY                     1017
    #define IDC_SIZE_EDIT                   1018
    #define IDC_SIZE_SPIN                   1019
    #define IDC_BL_EDIT                     1020
    #define IDC_BL_SPIN                     1021
    #define IDC_WEIGHT                      1022
    #define IDC_ITALIC                      1023
    #define IDC_BR_EDIT                     1024
    #define IDC_BR_SPIN                     1025
    #define IDC_BT_EDIT                     1026
    #define IDC_BT_SPIN                     1027
    #define IDC_BB_EDIT                     1028
    #define IDC_BB_SPIN                     1029
    #define IDC_CBL_EDIT                    1030
    #define IDC_CBL_SPIN                    1031
    #define IDC_CBR_EDIT                    1032
    #define IDC_CBR_SPIN                    1033
    #define IDC_CHAR                        1034
    #define IDC_RECT                        1035
    #define IDC_AA                          1036
    #define IDC_EDIT2                       1041
    #define ID_FILE_EXPORT                  32775
    #define ID_FILE_EXIT                    32776
    #define ID_TOOLS_ADDCHAR                32777

    // Next default values for new objects
    //
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        133
    #define _APS_NEXT_COMMAND_VALUE         32778
    #define _APS_NEXT_CONTROL_VALUE         1042
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/StdAfx.cpp] - (193 bytes)

    // --> Include files <---------------------------------------------------------

    #include "stdafx.h"

    // --> End of file <-----------------------------------------------------------

Currently browsing [mudFont.zip] (32,329 bytes) - [mudFont/StdAfx.h] - (1,125 bytes)

    // stdafx.h : include file for standard system include files,
    //  or project specific include files that are used frequently, but
    //      are changed infrequently
    //

    #if !defined(AFX_STDAFX_H__B36E3D1C_1BA5_405D_8E96_C7204D1BC20A__INCLUDED_)
    #define AFX_STDAFX_H__B36E3D1C_1BA5_405D_8E96_C7204D1BC20A__INCLUDED_

    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000

    #define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers

    #include <afxwin.h>         // MFC core and standard components
    #include <afxext.h>         // MFC extensions
    #include <afxdisp.h>        // MFC Automation classes
    #include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
    #include <afxtempl.h>

    #ifndef _AFX_NO_AFXCMN_SUPPORT
    #include <afxcmn.h>			// MFC support for Windows Common Controls
    #endif // _AFX_NO_AFXCMN_SUPPORT

    #include "resource.h"
    #include "mudDib.h"

    //{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.

    #endif // !defined(AFX_STDAFX_H__B36E3D1C_1BA5_405D_8E96_C7204D1BC20A__INCLUDED_)

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.