diff --git a/stepmania/src/Texture Font Generator/Texture Font Generator-net2005.sln b/stepmania/src/Texture Font Generator/Texture Font Generator-net2005.sln
new file mode 100644
index 0000000000..04a476433a
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/Texture Font Generator-net2005.sln
@@ -0,0 +1,19 @@
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Texture Font Generator", "Texture Font Generator-net2005.vcproj", "{8B04E112-0CFE-4934-B085-AAD9E95DA5BB}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8B04E112-0CFE-4934-B085-AAD9E95DA5BB}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8B04E112-0CFE-4934-B085-AAD9E95DA5BB}.Debug|Win32.Build.0 = Debug|Win32
+ {8B04E112-0CFE-4934-B085-AAD9E95DA5BB}.Release|Win32.ActiveCfg = Release|Win32
+ {8B04E112-0CFE-4934-B085-AAD9E95DA5BB}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/stepmania/src/Texture Font Generator/Texture Font Generator-net2005.vcproj b/stepmania/src/Texture Font Generator/Texture Font Generator-net2005.vcproj
new file mode 100644
index 0000000000..339ba0b43d
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/Texture Font Generator-net2005.vcproj
@@ -0,0 +1,307 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/stepmania/src/Texture Font Generator/Texture Font Generator.cpp b/stepmania/src/Texture Font Generator/Texture Font Generator.cpp
new file mode 100644
index 0000000000..47849e8e4d
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/Texture Font Generator.cpp
@@ -0,0 +1,147 @@
+// Texture Font Generator.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "Texture Font Generator.h"
+#include "Texture Font GeneratorDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+/*
+ * TODO:
+ *
+ * allow importing fonts
+ * allow selectively creating font pages
+ * allow creating font page types
+ * tag font page names; "rage numbers=0"
+ * if only exporting one font page, don't include the name; "_times 16pt.png", not "_times 16pt [main].png"
+ * include font properties in the default filename "_times 16pt bold [main].png"
+ * allow selecting points or pixels; include this in the defualt filename: "16pt" "16px"
+ * separate m_BoundingRect for each page
+ * - optimize: if we have a few big characters, put them in a separate font page, so we can
+ * pack the smaller ones tighter
+ * "always expand to power of two" (enable or disable packing)?
+ * "white on black" vs. "opaque on transparent"?
+ */
+
+BEGIN_MESSAGE_MAP(CTextureFontGeneratorApp, CWinApp)
+ ON_COMMAND(ID_HELP, CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+CTextureFontGeneratorApp::CTextureFontGeneratorApp()
+{
+}
+
+
+// The one and only CTextureFontGeneratorApp object
+
+CTextureFontGeneratorApp theApp;
+
+const GUID CDECL BASED_CODE _tlid =
+ { 0x9BFC6AC5, 0x5A9, 0x4468, { 0xB0, 0x9, 0xA9, 0xE6, 0xC2, 0x59, 0xDF, 0xD8 } };
+const WORD _wVerMajor = 1;
+const WORD _wVerMinor = 0;
+
+
+BOOL CTextureFontGeneratorApp::InitInstance()
+{
+ CWinApp::InitInstance();
+
+ // Initialize OLE libraries
+ if( !AfxOleInit() )
+ {
+ AfxMessageBox(IDP_OLE_INIT_FAILED);
+ return FALSE;
+ }
+
+ AfxEnableControlContainer();
+
+ // Parse command line for automation or reg/unreg switches.
+ CCommandLineInfo cmdInfo;
+ ParseCommandLine(cmdInfo);
+
+ // App was launched with /Embedding or /Automation switch.
+ // Run app as automation server.
+ if( cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated )
+ {
+ // Register class factories via CoRegisterClassObject().
+ COleTemplateServer::RegisterAll();
+ }
+ // App was launched with /Unregserver or /Unregister switch. Remove
+ // entries from the registry.
+ else if (cmdInfo.m_nShellCommand == CCommandLineInfo::AppUnregister)
+ {
+ COleObjectFactory::UpdateRegistryAll(FALSE);
+ AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor);
+ return FALSE;
+ }
+ // App was launched standalone or with other switches (e.g. /Register
+ // or /Regserver). Update registry entries, including typelibrary.
+ else
+ {
+ COleObjectFactory::UpdateRegistryAll();
+ AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid);
+ if (cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister)
+ return FALSE;
+ }
+
+ m_hAccelerators = LoadAccelerators( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR) );
+
+ CTextureFontGeneratorDlg dlg;
+ m_pMainWnd = &dlg;
+ INT_PTR nResponse = dlg.DoModal();
+ if (nResponse == IDOK)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with OK
+ }
+ else if (nResponse == IDCANCEL)
+ {
+ // TODO: Place code here to handle when the dialog is
+ // dismissed with Cancel
+ }
+
+ // Since the dialog has been closed, return FALSE so that we exit the
+ // application, rather than start the application's message pump.
+ return FALSE;
+}
+
+BOOL CTextureFontGeneratorApp::ProcessMessageFilter( int code, LPMSG lpMsg )
+{
+ if( m_hAccelerators )
+ {
+ if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_hAccelerators, lpMsg))
+ return(TRUE);
+ }
+
+ return CWinApp::ProcessMessageFilter(code, lpMsg);
+}
+
+
+/*
+ * Copyright (c) 2003-2007 Glenn Maynard
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons to
+ * whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/stepmania/src/Texture Font Generator/Texture Font Generator.h b/stepmania/src/Texture Font Generator/Texture Font Generator.h
new file mode 100644
index 0000000000..219a3620cb
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/Texture Font Generator.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h" // main symbols
+
+
+class CTextureFontGeneratorApp : public CWinApp
+{
+public:
+ CTextureFontGeneratorApp();
+ BOOL ProcessMessageFilter( int code, LPMSG lpMsg );
+
+public:
+ virtual BOOL InitInstance();
+ HACCEL m_hAccelerators;
+
+ DECLARE_MESSAGE_MAP()
+};
+
+extern CTextureFontGeneratorApp theApp;
+
+/*
+ * Copyright (c) 2003-2007 Glenn Maynard
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons to
+ * whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/stepmania/src/Texture Font Generator/Texture Font Generator.rc b/stepmania/src/Texture Font Generator/Texture Font Generator.rc
new file mode 100644
index 0000000000..909ae8d2be
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/Texture Font Generator.rc
@@ -0,0 +1,220 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+ "LANGUAGE 9, 1\r\n"
+ "#pragma code_page(1252)\r\n"
+ "#include ""res\\Texture Font Generator.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""afxres.rc"" // Standard components\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON "res\\Texture Font Generator.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_TEXTUREFONTGENERATOR_DIALOG DIALOGEX 0, 0, 371, 293
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Texture Font Generator"
+MENU IDR_MENU
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ COMBOBOX IDC_FAMILY_LIST,7,7,97,155,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ EDITTEXT IDC_FONT_SIZE,108,7,19,13,ES_AUTOHSCROLL | ES_NUMBER
+ COMBOBOX IDC_SHOWN_PAGE,275,74,89,40,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ CONTROL "",IDC_SPIN_TOP,"msctls_updown32",UDS_ARROWKEYS,81,20,14,15
+ CONTROL "",IDC_PICTURE,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN,7,87,357,199
+ LTEXT "Static",IDC_ERROR_OR_WARNING,259,7,105,37
+ CONTROL "",IDC_CLOSEUP,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN,7,20,74,65
+ CONTROL "",IDC_SPIN_BASELINE,"msctls_updown32",UDS_ARROWKEYS,82,70,11,15
+ EDITTEXT IDC_PADDING,135,75,28,12,ES_AUTOHSCROLL | ES_NUMBER
+ LTEXT "Padding:",IDC_STATIC,105,76,27,10
+ LTEXT "Static",IDC_TEXT_OVERLAP,158,26,79,24
+ LTEXT "Page:",IDC_STATIC,254,76,19,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "FileVersion", "1.0.0.0"
+ VALUE "InternalName", "Texture Font Generator.exe"
+ VALUE "LegalCopyright", "(c) 2003-2007 Glenn F. Maynard. All rights reserved."
+ VALUE "OriginalFilename", "Texture Font Generator.exe"
+ VALUE "ProductName", "Texture Font Generator"
+ VALUE "ProductVersion", "1.0.0.0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_TEXTUREFONTGENERATOR_DIALOG, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 364
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 286
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_MENU MENU
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Save", 57603
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit", ID_FILE_EXIT
+ END
+ POPUP "&Style"
+ BEGIN
+ MENUITEM "&Bold\tCtrl+B", ID_STYLE_BOLD
+ MENUITEM "&Italic\tCtrl+I", ID_STYLE_ITALIC
+ MENUITEM "&AntiAliased", ID_STYLE_ANTIALIASED
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_ACCELERATOR ACCELERATORS
+BEGIN
+ "I", ID_ACCELERATOR_ITALIC, VIRTKEY, CONTROL, NOINVERT
+ "B", ID_ACCELERATOR_BOLD, VIRTKEY, CONTROL, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDP_OLE_INIT_FAILED "OLE initialization failed. Make sure that the OLE libraries are the correct version."
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#include "res\Texture Font Generator.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/stepmania/src/Texture Font Generator/Texture Font GeneratorDlg.cpp b/stepmania/src/Texture Font Generator/Texture Font GeneratorDlg.cpp
new file mode 100644
index 0000000000..402b250029
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/Texture Font GeneratorDlg.cpp
@@ -0,0 +1,601 @@
+#include "stdafx.h"
+#include "Texture Font Generator.h"
+#include "Texture Font GeneratorDlg.h"
+#include "TextureFont.h"
+#include "Utils.h"
+
+#include
+#include
+#include
+using namespace std;
+
+#include
+
+static TextureFont *g_pTextureFont = NULL;
+
+
+IMPLEMENT_DYNAMIC(CTextureFontGeneratorDlg, CDialog);
+CTextureFontGeneratorDlg::CTextureFontGeneratorDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CTextureFontGeneratorDlg::IDD, pParent)
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+
+ g_pTextureFont = new TextureFont;
+}
+CTextureFontGeneratorDlg::~CTextureFontGeneratorDlg()
+{
+ delete g_pTextureFont;
+}
+
+void CTextureFontGeneratorDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_PICTURE, m_FontView);
+ DDX_Control(pDX, IDC_SHOWN_PAGE, m_ShownPage);
+ DDX_Control(pDX, IDC_FAMILY_LIST, m_FamilyList);
+ DDX_Control(pDX, IDC_TEXT_OVERLAP, m_TextOverlap);
+ DDX_Control(pDX, IDC_FONT_SIZE, m_FontSize);
+ DDX_Control(pDX, IDC_ERROR_OR_WARNING, m_ErrorOrWarning);
+ DDX_Control(pDX, IDC_CLOSEUP, m_CloseUp);
+ DDX_Control(pDX, IDC_SPIN_TOP, m_SpinTop);
+ DDX_Control(pDX, IDC_SPIN_BASELINE, m_SpinBaseline);
+ DDX_Control(pDX, IDC_PADDING, m_Padding);
+}
+
+BEGIN_MESSAGE_MAP(CTextureFontGeneratorDlg, CDialog)
+ ON_WM_DESTROY()
+ ON_WM_CLOSE()
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ ON_WM_MOUSEWHEEL()
+ //}}AFX_MSG_MAP
+ ON_CBN_SELCHANGE(IDC_SHOWN_PAGE, OnCbnSelchangeShownPage)
+ ON_CBN_SELCHANGE(IDC_FAMILY_LIST, OnCbnSelchangeFamilyList)
+ ON_EN_CHANGE(IDC_FONT_SIZE, OnEnChangeFontSize)
+ ON_COMMAND(ID_STYLE_BOLD, OnStyleBold)
+ ON_COMMAND(ID_STYLE_ITALIC, OnStyleItalic)
+ ON_COMMAND(ID_STYLE_ANTIALIASED, OnStyleAntialiased)
+ ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_TOP, OnDeltaposSpinTop)
+ ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_BASELINE, OnDeltaposSpinBaseline)
+ ON_EN_CHANGE(IDC_PADDING, OnEnChangePadding)
+ ON_COMMAND(ID_FILE_SAVE, OnFileSave)
+ ON_COMMAND(ID_FILE_EXIT, OnFileExit)
+ ON_COMMAND(ID_ACCELERATOR_ITALIC, OnStyleItalic)
+ ON_COMMAND(ID_ACCELERATOR_BOLD, OnStyleBold)
+END_MESSAGE_MAP()
+
+
+static const wchar_t map_cp1252[] = {
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
+ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
+ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
+ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
+ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0xFFFF,
+ 0x20AC, 0xFFFF, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFF, 0x017D, 0xFFFF,
+ 0xFFFF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x017E, 0xFFFF, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF,
+ 0
+};
+
+static const wchar_t map_iso_8859_2[] = {
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
+ 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
+ 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
+ 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+ 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+ 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+ 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9,
+ 0
+};
+
+static const wchar_t map_numbers[] = {
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034,
+ 0x0035, 0x0036, 0x0037, 0x0038, 0x0039,
+ 0x0025, 0x002E, 0x0020, 0x003A, 0x0078,
+ 0
+};
+
+/* Regenerate the font, pulling in settings from widgets. */
+void CTextureFontGeneratorDlg::UpdateFont()
+{
+ m_bUpdateFontNeeded = false;
+
+ m_FontView.SetBitmap( NULL );
+ m_CloseUp.SetBitmap( NULL );
+
+ CString sOld;
+ {
+ int iOldSel = m_ShownPage.GetCurSel();
+ if( iOldSel != -1 && iOldSel < (int) g_pTextureFont->m_PagesToGenerate.size() )
+ sOld = g_pTextureFont->m_PagesToGenerate[iOldSel].name;
+ }
+
+ /* Get the selected font m_sFamily. */
+ CString sText;
+ m_FamilyList.GetWindowText( sText );
+ g_pTextureFont->m_sFamily = sText;
+
+ m_FontSize.GetWindowText(sText);
+ g_pTextureFont->m_fFontSizePixels = (float) atof(sText);
+
+ m_Padding.GetWindowText(sText);
+ g_pTextureFont->m_iPadding = atoi(sText);
+
+ CMenu *pMenu = GetMenu();
+ g_pTextureFont->m_bBold = !!( pMenu->GetMenuState(ID_STYLE_BOLD, 0) & MF_CHECKED );
+ g_pTextureFont->m_bItalic = !!( pMenu->GetMenuState(ID_STYLE_ITALIC, 0) & MF_CHECKED );
+ g_pTextureFont->m_bAntiAlias = !!( pMenu->GetMenuState(ID_STYLE_ANTIALIASED, 0) & MF_CHECKED );
+
+ g_pTextureFont->m_PagesToGenerate.clear();
+ FontPageDescription desc;
+ desc.name = "main";
+ for( int i = 0; map_cp1252[i]; ++i )
+ {
+ wchar_t wc = map_cp1252[i];
+ if( wc != 0xFFFF )
+ desc.chars.push_back(wc);
+ }
+ g_pTextureFont->m_PagesToGenerate.push_back( desc );
+
+ desc.name = "alt";
+ desc.chars.clear();
+ for( int i = 0; map_iso_8859_2[i]; ++i )
+ {
+ wchar_t wc = map_iso_8859_2[i];
+ if( wc != 0xFFFF )
+ desc.chars.push_back(wc);
+ }
+
+ g_pTextureFont->m_PagesToGenerate.push_back( desc );
+
+ desc.name = "numbers";
+ desc.chars.clear();
+ for( int i = 0; map_numbers[i]; ++i )
+ {
+ wchar_t wc = map_numbers[i];
+ if( wc != 0xFFFF )
+ desc.chars.push_back(wc);
+ }
+
+ g_pTextureFont->m_PagesToGenerate.push_back( desc );
+
+ /* Go: */
+ g_pTextureFont->FormatFontPages();
+
+ m_SpinTop.SetPos( g_pTextureFont->m_iCharTop );
+ m_SpinBaseline.SetPos( g_pTextureFont->m_iCharBaseline );
+
+ m_ShownPage.ResetContent();
+ for( unsigned p = 0; p < g_pTextureFont->m_PagesToGenerate.size(); ++p )
+ m_ShownPage.AddString( g_pTextureFont->m_PagesToGenerate[p].name.GetString() );
+ int iRet = m_ShownPage.FindStringExact( -1, sOld );
+ if( iRet == CB_ERR )
+ iRet = 0;
+ m_ShownPage.SetCurSel( iRet );
+}
+
+void CTextureFontGeneratorDlg::UpdateSample()
+{
+ HBITMAP hBitmap = m_CloseUp.GetBitmap();
+ m_CloseUp.SetBitmap( NULL );
+ if( hBitmap )
+ DeleteObject( hBitmap );
+
+ HBITMAP hSample = g_pTextureFont->m_Characters[L'A'];
+ if( hSample == NULL )
+ return;
+
+ HDC hCharacterDC = CreateCompatibleDC( NULL );
+ HGDIOBJ hOldCharacterBitmap = SelectObject( hCharacterDC, hSample );
+
+ BITMAPINFO CharacterInfo;
+ memset( &CharacterInfo, 0, sizeof(CharacterInfo) );
+ CharacterInfo.bmiHeader.biSize = sizeof(CharacterInfo.bmiHeader);
+ GetDIBits( hCharacterDC, hSample, 0, 0, NULL, &CharacterInfo, DIB_RGB_COLORS );
+
+ int iWidth = CharacterInfo.bmiHeader.biWidth;
+ int iHeight = CharacterInfo.bmiHeader.biHeight;
+
+ /* Set up a bitmap to zoom the image into. */
+ int iSourceHeight = g_pTextureFont->m_BoundingRect.bottom;
+ const int iZoomFactor = 4;
+
+ HBITMAP hZoom;
+ {
+ HDC hTempDC = ::GetDC(NULL);
+ hZoom = CreateCompatibleBitmap( hTempDC, iWidth * iZoomFactor, iSourceHeight * iZoomFactor );
+ ::ReleaseDC( NULL, hTempDC );
+ }
+ HDC hZoomDC = CreateCompatibleDC( NULL );
+ HGDIOBJ hOldZoomBitmap = SelectObject( hZoomDC, hZoom );
+
+ StretchBlt(
+ hZoomDC, 0, 0,
+ iWidth * iZoomFactor, iHeight * iZoomFactor,
+ hCharacterDC, 0, 0,
+ iWidth, iHeight,
+ SRCCOPY
+ );
+ SelectObject( hCharacterDC, hOldCharacterBitmap );
+ ::DeleteDC( hCharacterDC );
+
+ HPEN hPen = CreatePen( PS_SOLID, 1, RGB(0, 255, 255) );
+ HGDIOBJ hOldPen = SelectObject( hZoomDC, hPen );
+
+ /* Align the line with the top of the unit, so, when correct, the font
+ * "sits" on the line. */
+ int iY = iZoomFactor*g_pTextureFont->m_iCharBaseline - 1;
+ MoveToEx( hZoomDC, 0, iY, NULL );
+ LineTo( hZoomDC, iWidth * iZoomFactor, iY );
+
+ SelectObject( hZoomDC, hOldPen );
+ DeleteObject( hPen );
+
+ hPen = CreatePen( PS_SOLID, 1, RGB(255, 255, 50) );
+ hOldPen = SelectObject( hZoomDC, hPen );
+
+ /* Align the line with the bottom of the unit, so, when correct, the line
+ * "sits" on the font. */
+ iY = iZoomFactor*g_pTextureFont->m_iCharTop - 1;
+ MoveToEx( hZoomDC, 0, iY, NULL );
+ LineTo( hZoomDC, iWidth * iZoomFactor, iY );
+
+ SelectObject( hZoomDC, hOldPen );
+ DeleteObject( hPen );
+
+ SelectObject( hZoomDC, hOldZoomBitmap );
+ ::DeleteDC( hZoomDC );
+
+ m_CloseUp.SetBitmap( hZoom );
+}
+
+
+int CALLBACK CTextureFontGeneratorDlg::EnumFontFamiliesCallback( const LOGFONTA *pLogicalFontData, const TEXTMETRICA *pPhysicalFontData, DWORD FontType, LPARAM lParam )
+{
+ CTextureFontGeneratorDlg *pThis = (CTextureFontGeneratorDlg *) lParam;
+ set *pSet = (set *) lParam;
+ pSet->insert( pLogicalFontData->lfFaceName );
+ return 1;
+}
+
+BOOL CTextureFontGeneratorDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // Set the icon for this dialog. The framework does this automatically
+ // when the application's main window is not a dialog
+ SetIcon(m_hIcon, TRUE); // Set big icon
+ SetIcon(m_hIcon, FALSE); // Set small icon
+
+ // XXX: AddFontResourceEx
+ // AddFontMemResourceEx
+ // drag drop
+ {
+ LOGFONT font;
+ memset( &font, 0, sizeof(font) );
+ font.lfCharSet = DEFAULT_CHARSET;
+ CPaintDC dc(this);
+ set setFamilies;
+ EnumFontFamiliesEx( dc.GetSafeHdc(), &font, EnumFontFamiliesCallback, (LPARAM) &setFamilies, 0 );
+ for( set::const_iterator it = setFamilies.begin(); it != setFamilies.end(); ++it )
+ m_FamilyList.AddString( *it );
+ m_FamilyList.SetCurSel( 0 );
+ }
+
+ CMenu *pMenu = GetMenu();
+ pMenu->CheckMenuItem( ID_STYLE_ANTIALIASED, MF_CHECKED );
+
+ m_FontSize.SetWindowText( "20" );
+ m_Padding.SetWindowText( "2" );
+ m_SpinTop.SetRange( 64, 0 );
+ m_SpinBaseline.SetRange( 64, 0 );
+
+ m_bUpdateFontNeeded = true;
+ m_bUpdateDisplayNeeded = true;
+
+ return TRUE; // return TRUE unless you set the focus to a control
+}
+
+void CTextureFontGeneratorDlg::UpdateDisplay()
+{
+ m_bUpdateDisplayNeeded = false;
+ m_FontView.SetBitmap( NULL );
+ m_CloseUp.SetBitmap( NULL );
+
+ m_SpinTop.EnableWindow( true );
+ m_SpinBaseline.EnableWindow( true );
+ GetMenu()->EnableMenuItem( ID_FILE_SAVE, MF_ENABLED );
+
+ if( g_pTextureFont->m_sError != "" )
+ {
+ m_SpinTop.EnableWindow(false);
+ m_SpinBaseline.EnableWindow(false);
+ GetMenu()->EnableMenuItem( ID_FILE_SAVE, MF_GRAYED );
+
+ m_ErrorOrWarning.SetWindowText( "Error: " + g_pTextureFont->m_sError );
+ return;
+ }
+
+ m_ErrorOrWarning.SetWindowText( g_pTextureFont->m_sWarnings );
+
+ const int iSelectedPage = m_ShownPage.GetCurSel();
+ ASSERT( iSelectedPage < (int) g_pTextureFont->m_apPages.size() );
+
+ g_pTextureFont->m_iCharTop = LOWORD(m_SpinTop.GetPos());
+ g_pTextureFont->m_iCharBaseline = LOWORD(m_SpinBaseline.GetPos());
+
+ HBITMAP hBitmap = g_pTextureFont->m_apPages[iSelectedPage]->m_hPage;
+ m_FontView.SetBitmap( hBitmap );
+
+ UpdateSample();
+
+ CString sStr;
+ sStr.Format("Overlap: %i, %i\nMaximum size: %ix%i",
+ g_pTextureFont->m_iCharLeftOverlap, g_pTextureFont->m_iCharRightOverlap,
+ g_pTextureFont->m_BoundingRect.right - g_pTextureFont->m_BoundingRect.left,
+ g_pTextureFont->m_BoundingRect.bottom - g_pTextureFont->m_BoundingRect.top
+ );
+ m_TextOverlap.SetWindowText( sStr );
+}
+
+void CTextureFontGeneratorDlg::OnDestroy()
+{
+ WinHelp(0L, HELP_QUIT);
+ CDialog::OnDestroy();
+}
+
+void CTextureFontGeneratorDlg::OnPaint()
+{
+ if( IsIconic() )
+ {
+ CPaintDC dc(this); // device context for painting
+
+ SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);
+
+ // Center icon in client rectangle
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // Draw the icon
+ dc.DrawIcon(x, y, m_hIcon);
+ return;
+ }
+
+ if( m_bUpdateFontNeeded )
+ {
+ m_bUpdateDisplayNeeded = true;
+ UpdateFont();
+ }
+
+ if( m_bUpdateDisplayNeeded )
+ UpdateDisplay();
+
+ CDialog::OnPaint();
+}
+
+// The system calls this function to obtain the cursor to display while the user drags
+// the minimized window.
+HCURSOR CTextureFontGeneratorDlg::OnQueryDragIcon()
+{
+ return static_cast(m_hIcon);
+}
+
+
+void CTextureFontGeneratorDlg::OnClose()
+{
+ if( CanExit() )
+ CDialog::OnClose();
+}
+
+void CTextureFontGeneratorDlg::OnOK()
+{
+ if( CanExit() )
+ CDialog::OnOK();
+}
+
+void CTextureFontGeneratorDlg::OnCancel()
+{
+ if (CanExit())
+ CDialog::OnCancel();
+}
+
+BOOL CTextureFontGeneratorDlg::OnMouseWheel( UINT nFlags, short zDelta, CPoint pt )
+{
+ CWnd *pFocus = this->GetFocus();
+ if( nFlags & MK_CONTROL )
+ zDelta *= 5;
+ if( pFocus == &m_Padding || pFocus == &m_FontSize )
+ {
+ CEdit *pFocusedEdit = dynamic_cast(pFocus);
+ CString sText;
+ pFocusedEdit->GetWindowText( sText );
+ int i = atoi( sText );
+ i += zDelta / WHEEL_DELTA;
+ if( pFocus == &m_Padding )
+ i = max( i, 0 );
+ else if( pFocus == &m_FontSize )
+ i = max( i, 1 );
+
+ sText.Format( "%i", i );
+ pFocusedEdit->SetWindowText( sText );
+ return FALSE;
+ }
+
+ return CDialog::OnMouseWheel( nFlags, zDelta, pt );
+}
+
+BOOL CTextureFontGeneratorDlg::CanExit()
+{
+ return TRUE;
+}
+
+void CTextureFontGeneratorDlg::OnCbnSelchangeShownPage()
+{
+ m_bUpdateDisplayNeeded = true;
+ Invalidate( FALSE );
+ UpdateWindow();
+}
+
+void CTextureFontGeneratorDlg::OnCbnSelchangeFamilyList()
+{
+ m_bUpdateFontNeeded = true;
+ Invalidate( FALSE );
+ UpdateWindow();
+}
+
+void CTextureFontGeneratorDlg::OnEnChangeFontSize()
+{
+ m_bUpdateFontNeeded = true;
+ Invalidate( FALSE );
+ UpdateWindow();
+}
+
+void CTextureFontGeneratorDlg::OnEnChangePadding()
+{
+ m_bUpdateFontNeeded = true;
+ Invalidate( FALSE );
+}
+
+void CTextureFontGeneratorDlg::OnStyleAntialiased()
+{
+ CMenu *pMenu = GetMenu();
+ int Checked = pMenu->GetMenuState(ID_STYLE_ANTIALIASED, 0) & MF_CHECKED;
+ Checked ^= MF_CHECKED;
+ pMenu->CheckMenuItem( ID_STYLE_ANTIALIASED, Checked );
+ m_bUpdateFontNeeded = true;
+ Invalidate( FALSE );
+}
+
+void CTextureFontGeneratorDlg::OnStyleBold()
+{
+ CMenu *pMenu = GetMenu();
+ int Checked = pMenu->GetMenuState(ID_STYLE_BOLD, 0) & MF_CHECKED;
+ Checked ^= MF_CHECKED;
+ pMenu->CheckMenuItem( ID_STYLE_BOLD, Checked );
+ m_bUpdateFontNeeded = true;
+ Invalidate( FALSE );
+}
+
+void CTextureFontGeneratorDlg::OnStyleItalic()
+{
+ CMenu *pMenu = GetMenu();
+ int Checked = pMenu->GetMenuState(ID_STYLE_ITALIC, 0) & MF_CHECKED;
+ Checked ^= MF_CHECKED;
+ pMenu->CheckMenuItem( ID_STYLE_ITALIC, Checked );
+ m_bUpdateFontNeeded = true;
+ Invalidate( FALSE );
+}
+
+void CTextureFontGeneratorDlg::OnDeltaposSpinTop(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR);
+ *pResult = 0;
+
+ m_bUpdateDisplayNeeded = true;
+ Invalidate( FALSE );
+}
+
+void CTextureFontGeneratorDlg::OnDeltaposSpinBaseline(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR);
+ *pResult = 0;
+
+ m_bUpdateDisplayNeeded = true;
+ Invalidate( FALSE );
+}
+
+void CTextureFontGeneratorDlg::OnFileSave()
+{
+ // XXX
+ OPENFILENAME ofn;
+ memset( &ofn, 0, sizeof(ofn) );
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = m_hWnd;
+ ofn.lpstrFilter = "*.ini\000Font control files\000\000";
+
+ char szFile[1024] = "";
+ ofn.lpstrFile = szFile;
+ {
+ CString sName = g_pTextureFont->m_sFamily;
+ sName.MakeLower();
+ _snprintf( szFile, 1023, "_%s %gpx", (const char *) sName, g_pTextureFont->m_fFontSizePixels );
+ }
+ ofn.nMaxFile = sizeof(szFile);
+
+ // lpstrInitialDir
+ ofn.Flags = OFN_HIDEREADONLY|OFN_LONGNAMES;
+
+ if( !GetSaveFileName(&ofn) )
+ return;
+
+ /* If the filename provided has an extension, remove it. */
+ {
+ char *pExt = strrchr( szFile, '.' );
+ if( pExt )
+ *pExt = 0;
+ }
+
+
+/* {
+ vector asOldFiles;
+ WIN32_FIND_DATA fd;
+
+ CString sPath = szFile;
+ HANDLE hFind = FindFirstFile( sPath+"*", &fd );
+
+ if( hFind != INVALID_HANDLE_VALUE )
+ {
+ do {
+ if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ continue;
+ asOldFiles.push_back( fd.cFileName );
+ } while( FindNextFile(hFind, &fd) );
+ FindClose( hFind );
+ }
+ }
+*/
+ g_pTextureFont->Save( szFile );
+}
+
+void CTextureFontGeneratorDlg::OnFileExit()
+{
+ DestroyWindow();
+}
+
+/*
+ * Copyright (c) 2003-2007 Glenn Maynard
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons to
+ * whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/stepmania/src/Texture Font Generator/Texture Font GeneratorDlg.h b/stepmania/src/Texture Font Generator/Texture Font GeneratorDlg.h
new file mode 100644
index 0000000000..e6dd4c0fe5
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/Texture Font GeneratorDlg.h
@@ -0,0 +1,97 @@
+#pragma once
+#include
+#include
+
+#include "TextureFont.h"
+
+
+class CTextureFontGeneratorDlg : public CDialog
+{
+ DECLARE_DYNAMIC(CTextureFontGeneratorDlg);
+
+public:
+ CTextureFontGeneratorDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CTextureFontGeneratorDlg();
+
+ enum { IDD = IDD_TEXTUREFONTGENERATOR_DIALOG };
+
+protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+
+ HICON m_hIcon;
+ CFont m_Font;
+
+ BOOL CanExit();
+
+ bool m_bUpdateFontNeeded;
+ bool m_bUpdateDisplayNeeded;
+
+ // Generated message map functions
+ virtual BOOL OnInitDialog();
+ afx_msg void OnDestroy();
+ afx_msg void OnPaint();
+ afx_msg HCURSOR OnQueryDragIcon();
+ afx_msg void OnClose();
+ virtual void OnOK();
+ virtual void OnCancel();
+ virtual BOOL OnMouseWheel( UINT nFlags, short zDelta, CPoint pt );
+ DECLARE_MESSAGE_MAP()
+
+ void UpdateDisplay();
+ void UpdateFont();
+ void UpdateSample();
+
+public:
+ vector m_PagesToGenerate;
+
+ afx_msg void OnCbnSelchangeShownPage();
+ afx_msg void OnCbnSelchangeFamilyList();
+ afx_msg void OnEnChangeFontSize();
+ afx_msg void OnStyleAntialiased();
+ afx_msg void OnStyleBold();
+ afx_msg void OnStyleItalic();
+ afx_msg void OnDeltaposSpinTop(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnDeltaposSpinBaseline(NMHDR *pNMHDR, LRESULT *pResult);
+ afx_msg void OnEnChangePadding();
+ afx_msg void OnFileSave();
+ afx_msg void OnFileExit();
+
+ static int CALLBACK EnumFontFamiliesCallback( const LOGFONTA *pLogicalFontData, const TEXTMETRICA *pPhysicalFontData, DWORD FontType, LPARAM lParam );
+
+ CStatic m_FontView;
+ CComboBox m_ShownPage;
+ CComboBox m_FamilyList;
+ CStatic m_TextOverlap;
+ CEdit m_FontSize;
+ CEdit m_Padding;
+ CStatic m_ErrorOrWarning;
+ CStatic m_CloseUp;
+ CSpinButtonCtrl m_SpinTop;
+ CSpinButtonCtrl m_SpinBaseline;
+ CStatic m_FontType;
+};
+
+/*
+ * Copyright (c) 2003-2007 Glenn Maynard
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons to
+ * whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/stepmania/src/Texture Font Generator/TextureFont.cpp b/stepmania/src/Texture Font Generator/TextureFont.cpp
new file mode 100644
index 0000000000..b242cf72e2
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/TextureFont.cpp
@@ -0,0 +1,499 @@
+#include "stdafx.h"
+#include "TextureFont.h"
+#include "Utils.h"
+
+#include
+#include
+
+TextureFont::TextureFont()
+{
+ m_iCharDescent = 0;
+ m_iCharLeftOverlap = 0;
+ m_iCharRightOverlap = 0;
+ m_iCharBaseline = 0;
+ m_iCharTop = 0;
+ m_iCharVertSpacing = 0;
+}
+
+TextureFont::~TextureFont()
+{
+}
+
+void TextureFont::FormatFontPages()
+{
+ for( unsigned i = 0; i < m_apPages.size(); ++i )
+ delete m_apPages[i];
+ m_apPages.clear();
+ for( map::iterator i = m_Characters.begin(); i != m_Characters.end(); ++i )
+ {
+ if( i->second == NULL )
+ continue;
+ int b = DeleteObject( i->second );
+ ASSERT( b );
+ }
+ m_Characters.clear();
+
+ m_sError = m_sWarnings = "";
+
+ /*
+ * Create the system font.
+ */
+ LOGFONT font;
+ memset( &font, 0, sizeof(font) );
+ strncpy( &font.lfFaceName[0], (const char *) m_sFamily, 31 );
+ font.lfFaceName[31] = 0;
+ font.lfCharSet = DEFAULT_CHARSET;
+ if( m_bBold )
+ font.lfWeight = FW_BOLD;
+ if( m_bItalic )
+ font.lfItalic = TRUE;
+
+// (fPoints / 72.0f) * 90
+ font.lfHeight = (LONG) -m_fFontSizePixels;
+ font.lfQuality = m_bAntiAlias? ANTIALIASED_QUALITY: NONANTIALIASED_QUALITY;
+ font.lfPitchAndFamily = DEFAULT_PITCH;
+
+ HFONT hFont = CreateFontIndirect( &font );
+ if( hFont == NULL )
+ {
+ m_sError = "Font isn't available";
+ return;
+ }
+
+ HDC hDC = CreateCompatibleDC( NULL );
+ HGDIOBJ hOldFont = SelectObject( hDC, hFont );
+
+ /*
+ * Read high-level text metrics.
+ */
+ TEXTMETRIC TextMetrics;
+ GetTextMetrics( hDC, &TextMetrics );
+
+ m_iCharBaseline = TextMetrics.tmAscent;
+ m_iCharDescent = TextMetrics.tmDescent;
+ m_iCharVertSpacing = TextMetrics.tmHeight + TextMetrics.tmExternalLeading;
+ m_iCharTop = TextMetrics.tmInternalLeading;
+ m_iCharLeftOverlap = m_iCharRightOverlap = 0;
+ m_BoundingRect.top = m_BoundingRect.left = 0;
+ m_BoundingRect.bottom = m_BoundingRect.right = 0;
+
+
+ int n = GetKerningPairs( hDC, 0, NULL );
+ KERNINGPAIR *kp = new KERNINGPAIR[n];
+ GetKerningPairs( hDC, n, kp );
+
+ for( int i = 0; i < n; ++i )
+ {
+ if( kp[i].wFirst == 'A' && kp[i].wSecond == 'A' )
+ int q = 1;
+ if( kp[i].wFirst == 'A' && kp[i].wSecond == 'j' )
+ int q = 1;
+ if( kp[i].wFirst == 'j' && kp[i].wSecond == 'j' )
+ int q = 1;
+ }
+
+ m_RealBounds.clear();
+
+ for( unsigned i = 0; i < m_PagesToGenerate.size(); ++i )
+ {
+ m_apPages.push_back( new FontPage );
+ FormatFontPage( i, hDC );
+ }
+
+/* OUTLINETEXTMETRIC *tm = NULL;
+ int i = GetOutlineTextMetrics( hDC, 0, NULL );
+ if( i )
+ {
+ tm = (OUTLINETEXTMETRIC *) new char[i];
+ GetOutlineTextMetrics( hDC, i, tm );
+ }
+ delete [] tm;
+*/
+
+ SelectObject( hDC, hOldFont );
+ DeleteObject( hFont );
+ DeleteDC( hDC );
+}
+
+void TextureFont::FormatCharacter( wchar_t c, HDC hDC )
+{
+ if( m_Characters.find(c) != m_Characters.end() )
+ return;
+
+ WORD gi;
+ if( GetGlyphIndicesW(hDC, &c, 1, &gi, GGI_MARK_NONEXISTING_GLYPHS) && gi == 0xFFFF )
+ return;
+
+/* int ii = GetFontUnicodeRanges( hDC, NULL );
+ GLYPHSET *gs = (GLYPHSET *) alloca(ii);
+ GetFontUnicodeRanges( hDC, gs );
+
+ GLYPHMETRICS gm;
+ MAT2 mat;
+ memset( &mat, 0, sizeof(mat) );
+ mat.eM11.value = 1;
+ mat.eM22.value = 1;
+
+ ii = GetGlyphOutline( hDC, c, GGO_BEZIER, &gm, 0, NULL, &mat );
+ DWORD *data = (DWORD *) alloca(ii);
+ ii = GetGlyphOutline( hDC, c, GGO_BEZIER, &gm, ii, data, &mat );
+*/
+
+ if(c == L'j')
+ int q = 1;
+
+ ABC &abc = m_ABC[c];
+ {
+ /* Use GetCharABCWidthsFloatW, since it works on all types of fonts; GetCharABCWidths
+ * only works on TrueType fonts. */
+ ABCFLOAT abcf;
+ GetCharABCWidthsFloatW( hDC, c, c, &abcf );
+
+ abc.abcA = lrintf( abcf.abcfA );
+ abc.abcB = lrintf( abcf.abcfB );
+ abc.abcC = lrintf( abcf.abcfC );
+ }
+
+ /*
+ * If the A or C widths are positive, it's simply extra space to add to either side.
+ * Move this into the B width. The only time this actually matters is to be able to
+ * omit the A width from the first letter of a string which is left-aligned, or the
+ * last C width from a right-aligned string. The exported fonts don't support explicit
+ * ABC widths, instead representing overhang and underhang with global m_iCharLeftOverlap
+ * and m_iCharRightOverlap settings.
+ *
+ * After making this adjustment, the glyphs' B region is left-aligned in the bitmap.
+ */
+ if( abc.abcA > 0 )
+ {
+ abc.abcB += abc.abcA;
+ abc.abcA = 0;
+ }
+ if( abc.abcC > 0 )
+ {
+ abc.abcB += abc.abcC;
+ abc.abcC = 0;
+ }
+
+ /* Render the character into an empty bitmap. Since we don't know how
+ * large the character will be, this is somewhat oversized. */
+ HBITMAP hBitmap;
+ {
+ HDC hTempDC = GetDC(NULL);
+ hBitmap = CreateCompatibleBitmap( hTempDC, abc.abcB, 128 );
+ ReleaseDC( NULL, hTempDC );
+ }
+ HGDIOBJ hOldBitmap = SelectObject( hDC, hBitmap );
+
+ SetTextColor( hDC, RGB(0xFF,0xFF,0xFF) );
+ SetBkColor( hDC, RGB(0,0,0) );
+ SetBkMode( hDC, OPAQUE );
+
+ TextOutW( hDC, -abc.abcA, 0, &c, 1 );
+
+ /* Determine the real bounding box: */
+ RECT &realbounds = m_RealBounds[c];
+ realbounds.top = 0;
+ realbounds.bottom = 10;
+
+/* if(c == L'j')
+ {
+ Surface surf;
+ BitmapToSurface( hBitmap, &surf );
+ GrayScaleToAlpha( &surf );
+
+ FILE *f = fopen( "c:/foo5.png", "w+b" );
+ char szErrorbuf[1024];
+ SavePNG( f, szErrorbuf, &surf );
+ fclose( f );
+ }
+*/
+ {
+ Surface surf;
+ BitmapToSurface( hBitmap, &surf );
+ GetBounds( &surf, &realbounds );
+ }
+ realbounds.left = 0;
+ realbounds.right = abc.abcB;
+
+
+/* {
+// Graphics blit( pBitmap );
+// blit.DrawLine(&pen, abc.abcA, 5, abc.abcA+abc.abcB, 5);
+ const SolidBrush solidBrush1(Color(128, 255, 0, 255));
+ Pen pen( &solidBrush1, 1 );
+ graphics.DrawRectangle( &pen, 0, 0, (-abc.abcA) - 1, 10 );
+
+ pen.SetColor(Color(128, 0, 255, 255));
+ graphics.DrawRectangle( &pen, 0, 0, abc.abcB - 1, 10 );
+
+ pen.SetColor(Color(128, 255, 255, 0));
+ graphics.DrawRectangle( &pen, abc.abcA + abc.abcB, 10, abc.abcC - 1, 20 );
+ }
+*/
+
+ /*
+ * The bitmap is probably too big. Resize it: remove empty space on
+ * the left, right and bottom. Don't move it up; that'll confuse offsets.
+ */
+ BitBlt( hDC, 0, 0, realbounds.right, realbounds.bottom,
+ hDC, 0, 0, SRCCOPY );
+ SelectObject( hDC, hOldBitmap );
+
+
+ m_Characters[c] = hBitmap;
+
+ if( realbounds.left != realbounds.right && realbounds.top != realbounds.bottom )
+ {
+ m_BoundingRect.top = min( m_BoundingRect.top, (LONG) realbounds.top );
+ m_BoundingRect.left = min( m_BoundingRect.left, (LONG) realbounds.left );
+ m_BoundingRect.right = max( m_BoundingRect.right, (LONG) realbounds.right );
+ m_BoundingRect.bottom = max( m_BoundingRect.bottom, (LONG) realbounds.bottom );
+ if( m_BoundingRect.left == m_BoundingRect.right && m_BoundingRect.top == m_BoundingRect.bottom )
+ m_BoundingRect = realbounds;
+ }
+
+ m_iCharLeftOverlap = max( m_iCharLeftOverlap, -int(abc.abcA) );
+ m_iCharRightOverlap = max( m_iCharRightOverlap, int(abc.abcC) - int(abc.abcB) );
+
+// const SolidBrush solidBrush(Color(128, 255, 0, 255));
+// Pen pen(&solidBrush, 1);
+// graphics.DrawRectangle(&pen, bounds);
+
+// Graphics blit( pBitmap );
+// blit.DrawLine(&pen, abc.abcA, 5, abc.abcA+abc.abcB, 5);
+// blit.DrawRectangle( &pen, 1, 10, abc.abcA, 10 );
+
+// pen.SetColor(Color(255, 0, 255, 0));
+// graphics.DrawRectangle(&pen, realbounds);
+}
+
+/* Return the number of pixels the characters are shifted downwards in the final
+ * page for m_iPadding. */
+int TextureFont::GetTopPadding() const
+{
+ return m_iPadding/2;
+}
+
+void TextureFont::FormatFontPage( int iPage, HDC hDC )
+{
+ const FontPageDescription &Desc = m_PagesToGenerate[iPage];
+
+ /* First, generate bitmaps for all characters in this page. */
+ for( unsigned i = 0; i < Desc.chars.size(); ++i )
+ FormatCharacter( Desc.chars[i], hDC );
+
+ FontPage *pPage = m_apPages[iPage];
+ pPage->m_iFrameWidth = (m_BoundingRect.right - m_BoundingRect.left) + m_iPadding;
+ pPage->m_iFrameHeight = (m_BoundingRect.bottom - m_BoundingRect.top) + m_iPadding;
+ if( pPage->m_iFrameWidth % 2 )
+ ++pPage->m_iFrameWidth;
+ if( pPage->m_iFrameHeight % 2 )
+ ++pPage->m_iFrameHeight;
+
+ pPage->m_iNumFramesX = (int) ceil( powf( (float) Desc.chars.size(), 0.5f ) );
+ pPage->m_iNumFramesY = (int) ceil( (float) Desc.chars.size() / pPage->m_iNumFramesX );
+
+ pPage->Create( pPage->m_iNumFramesX*pPage->m_iFrameWidth, pPage->m_iNumFramesY*pPage->m_iFrameHeight );
+
+ HGDIOBJ hOldBitmap = SelectObject( hDC, pPage->m_hPage );
+
+ HDC hSrcDC = CreateCompatibleDC( NULL );
+
+ int iRow = 0, iCol = 0;
+ for( unsigned CurChar = 0; CurChar < Desc.chars.size(); ++CurChar )
+ {
+ const wchar_t c = Desc.chars[CurChar];
+ const ABC &abc = m_ABC[c];
+
+ /* The current frame is at fOffsetX/fOffsetY. Center the character
+ * horizontally in the frame. We can align it however we want
+ * vertically, as long as we align the baselines. */
+ float fOffsetX = (float) pPage->m_iFrameWidth*iCol; /* origin -> frame top-left */
+ fOffsetX += pPage->m_iFrameWidth/2.0f; /* frame top-left -> frame center */
+ fOffsetX -= (abc.abcA+abc.abcB+abc.abcC)/2.0f;
+ fOffsetX += abc.abcA;
+
+ /* Truncate, so we don't blit to half a pixel: */
+ fOffsetX = float(int(fOffsetX));
+
+ float fOffsetY = (float) pPage->m_iFrameHeight*iRow;
+ fOffsetY += GetTopPadding();
+
+ if( m_Characters[c] != NULL )
+ {
+ HBITMAP hCharacterBitmap = m_Characters[c];
+ HGDIOBJ hOldSrcBitmap = SelectObject( hSrcDC, hCharacterBitmap );
+
+ const RECT &realbounds = m_RealBounds[c];
+ BitBlt( hDC, int(fOffsetX), int(fOffsetY),
+ m_ABC[c].abcB, realbounds.bottom,
+ hSrcDC, 0, 0, SRCCOPY );
+
+ SelectObject( hSrcDC, hOldSrcBitmap );
+ }
+
+ ++iCol;
+ if( iCol == pPage->m_iNumFramesY )
+ {
+ iCol = 0;
+ ++iRow;
+ }
+ }
+
+ DeleteDC( hSrcDC );
+ SelectObject( hDC, hOldBitmap );
+}
+
+/* UTF-8 encode ch and append to out. */
+void wchar_to_utf8( wchar_t ch, string &out )
+{
+ if( ch < 0x80 ) { out.append( 1, (char) ch ); return; }
+
+ int cbytes = 0;
+ if( ch < 0x800 ) cbytes = 1;
+ else if( ch < 0x10000 ) cbytes = 2;
+ else if( ch < 0x200000 ) cbytes = 3;
+ else if( ch < 0x4000000 ) cbytes = 4;
+ else cbytes = 5;
+
+ {
+ int shift = cbytes*6;
+ const int init_masks[] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+ out.append( 1, (char) (init_masks[cbytes-1] | (ch>>shift)) );
+ }
+
+ for( int i = 0; i < cbytes; ++i )
+ {
+ int shift = (cbytes-i-1)*6;
+ out.append( 1, (char) (0x80 | ((ch>>shift)&0x3F)) );
+ }
+}
+
+#include
+
+void TextureFont::Save( CString sBasePath )
+{
+ if( m_sError != "" )
+ return;
+
+ const CString inipath = sBasePath + ".ini";
+
+ ofstream f(inipath.GetString());
+
+ /* Write global properties: */
+ f << "[common]\n";
+
+ f << "Baseline=" << m_iCharBaseline + GetTopPadding() << "\n";
+ f << "Top=" << m_iCharTop + GetTopPadding() << "\n";
+ f << "LineSpacing=" << m_iCharVertSpacing << "\n";
+ f << "DrawExtraPixelsLeft=" << m_iCharLeftOverlap << "\n";
+ f << "DrawExtraPixelsRight=" << m_iCharRightOverlap << "\n";
+ f << "AdvanceExtraPixels=0\n";
+
+ for( unsigned i = 0; i < m_apPages.size(); ++i )
+ {
+ const FontPageDescription &desc = m_PagesToGenerate[i];
+ ASSERT( m_apPages[i]->m_hPage );
+ FontPage &page = *m_apPages[i];
+
+ f << "\n" << "[" << desc.name.GetString() << "]\n";
+
+ {
+ int iWidth = 1;
+ if( desc.chars.size() / page.m_iNumFramesX > 10 )
+ iWidth = 2;
+
+ unsigned iChar = 0;
+ unsigned iLine = 0;
+ while( iChar < desc.chars.size() )
+ {
+ f << "Line " << setw(iWidth) << iLine << "=";
+ f << setw(1);
+ for( int iX = 0; iX < page.m_iNumFramesX && iChar < desc.chars.size(); ++iX, ++iChar )
+ {
+ const wchar_t c = desc.chars[iChar];
+ string sUTF8;
+ wchar_to_utf8( c, sUTF8 );
+ f << sUTF8.c_str();
+ }
+ f << "\n";
+ ++iLine;
+ }
+ }
+
+ f << "\n";
+ for( unsigned j = 0; j < desc.chars.size(); ++j )
+ {
+ /* This is the total width to advance for the whole character, which is the
+ * sum of the ABC widths. */
+ const wchar_t c = desc.chars[j];
+ ABC &abc = m_ABC[c];
+ int iCharWidth = abc.abcA + int(abc.abcB) + int(abc.abcC);
+ f << j << "=" << iCharWidth << "\n";
+ }
+
+ Surface surf;
+ BitmapToSurface( m_apPages[i]->m_hPage, &surf );
+
+ GrayScaleToAlpha( &surf );
+
+ CString sFile;
+ sFile.Format( "%s [%s] %ix%i.png",
+ sBasePath.GetString(),
+ m_PagesToGenerate[i].name.GetString(),
+ m_apPages[i]->m_iNumFramesX,
+ m_apPages[i]->m_iNumFramesY );
+
+ FILE *f = fopen( sFile, "w+b" );
+ char szErrorbuf[1024];
+ SavePNG( f, szErrorbuf, &surf );
+ fclose( f );
+ }
+}
+
+
+FontPage::FontPage()
+{
+ m_hPage = NULL;
+ m_iFrameWidth = 0;
+ m_iFrameHeight = 0;
+}
+
+FontPage::~FontPage()
+{
+ DeleteObject( m_hPage );
+}
+
+void FontPage::Create( unsigned width, unsigned height )
+{
+ DeleteObject( m_hPage );
+ HDC hDC = GetDC(NULL);
+ m_hPage = CreateCompatibleBitmap( hDC, width, height );
+ ReleaseDC( NULL, hDC );
+}
+
+/*
+ * Copyright (c) 2003-2007 Glenn Maynard
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, and/or sell copies of the Software, and to permit persons to
+ * whom the Software is furnished to do so, provided that the above
+ * copyright notice(s) and this permission notice appear in all copies of
+ * the Software and that both the above copyright notice(s) and this
+ * permission notice appear in supporting documentation.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+ * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
+ * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
+ * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
diff --git a/stepmania/src/Texture Font Generator/TextureFont.h b/stepmania/src/Texture Font Generator/TextureFont.h
new file mode 100644
index 0000000000..d737ac4bc1
--- /dev/null
+++ b/stepmania/src/Texture Font Generator/TextureFont.h
@@ -0,0 +1,97 @@
+#ifndef TEXTURE_FONT_H
+#define TEXTURE_FONT_H
+
+#include
+#include