add Texture Font Generator. This has been sitting around in slow development on my machine since like 2003. It's incomplete and needs a lot of cleanup, but it's a lot better than Bitmap Font Builder: open source, supports our full font format, multiple font pages, Unicode pages, numbers pages, etc.

This commit is contained in:
Glenn Maynard
2008-04-28 20:20:13 +00:00
parent dddcf5b22d
commit 6003843f0c
16 changed files with 2492 additions and 0 deletions
@@ -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
@@ -0,0 +1,307 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="Texture Font Generator"
ProjectGUID="{8B04E112-0CFE-4934-B085-AAD9E95DA5BB}"
RootNamespace="Texture Font Generator"
Keyword="MFCProj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="2"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="false"
TypeLibraryName="$(IntDir)/$(ProjectName).tlb"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_WINDOWS;_DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
AdditionalIncludeDirectories="$(IntDir)"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="2"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="false"
TypeLibraryName="$(IntDir)/$(ProjectName).tlb"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OmitFramePointers="true"
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG"
StringPooling="true"
MinimalRebuild="false"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
TreatWChar_tAsBuiltInType="true"
UsePrecompiledHeader="2"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
AdditionalIncludeDirectories="$(IntDir)"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateManifest="true"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
AllowIsolation="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="true"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
>
<File
RelativePath="Resource.h"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCustomBuildTool"
Description=""
CommandLine=""
Outputs=""
/>
</FileConfiguration>
</File>
<File
RelativePath="stdafx.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
</File>
<File
RelativePath="stdafx.h"
>
</File>
<File
RelativePath="Texture Font Generator.cpp"
>
</File>
<File
RelativePath="Texture Font Generator.h"
>
</File>
<File
RelativePath="Texture Font GeneratorDlg.cpp"
>
</File>
<File
RelativePath="Texture Font GeneratorDlg.h"
>
</File>
<File
RelativePath="TextureFont.cpp"
>
</File>
<File
RelativePath="TextureFont.h"
>
</File>
<File
RelativePath="Utils.cpp"
>
</File>
<File
RelativePath="Utils.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"
>
<File
RelativePath="res\Texture Font Generator.ico"
>
</File>
<File
RelativePath="Texture Font Generator.rc"
>
</File>
<File
RelativePath="res\Texture Font Generator.rc2"
>
</File>
</Filter>
</Files>
<Globals>
<Global
Name="RESOURCE_FILE"
Value="Texture Font Generator.rc"
/>
</Globals>
</VisualStudioProject>
@@ -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.
*/
@@ -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.
*/
@@ -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
@@ -0,0 +1,601 @@
#include "stdafx.h"
#include "Texture Font Generator.h"
#include "Texture Font GeneratorDlg.h"
#include "TextureFont.h"
#include "Utils.h"
#include <vector>
#include <fstream>
#include <set>
using namespace std;
#include <math.h>
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<CString> *pSet = (set<CString> *) 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<CString> setFamilies;
EnumFontFamiliesEx( dc.GetSafeHdc(), &font, EnumFontFamiliesCallback, (LPARAM) &setFamilies, 0 );
for( set<CString>::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<WPARAM>(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<HCURSOR>(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<CEdit *>(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<LPNMUPDOWN>(pNMHDR);
*pResult = 0;
m_bUpdateDisplayNeeded = true;
Invalidate( FALSE );
}
void CTextureFontGeneratorDlg::OnDeltaposSpinBaseline(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(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<CString> 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.
*/
@@ -0,0 +1,97 @@
#pragma once
#include <afxwin.h>
#include <afxcmn.h>
#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<FontPageDescription> 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.
*/
@@ -0,0 +1,499 @@
#include "stdafx.h"
#include "TextureFont.h"
#include "Utils.h"
#include <fstream>
#include <math.h>
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<wchar_t, HBITMAP>::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 <iomanip>
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.
*/
@@ -0,0 +1,97 @@
#ifndef TEXTURE_FONT_H
#define TEXTURE_FONT_H
#include <vector>
#include <map>
using namespace std;
struct FontPageDescription
{
CString name;
vector<wchar_t> chars;
};
struct FontPage
{
FontPage();
~FontPage();
void Create( unsigned width, unsigned height );
HBITMAP m_hPage;
/* Width and height of this page: */
// int Width, Height;
int m_iFrameWidth, m_iFrameHeight;
int m_iNumFramesX, m_iNumFramesY;
};
/* Create a bitmap font with the given parameters. */
class TextureFont
{
public:
TextureFont();
~TextureFont();
vector<FontPageDescription> m_PagesToGenerate;
void FormatFontPage( int iPage, HDC hDC );
void FormatFontPages();
void Save( CString sPath );
map<wchar_t, HBITMAP> m_Characters;
/* Font generation properties: */
bool m_bBold; /* whether font is bold */
bool m_bItalic; /* whether font is italic */
bool m_bAntiAlias; /* antialiasing type */
float m_fFontSizePixels; /* font size in pixels */
CString m_sFamily; /* font family */
int m_iPadding; /* empty padding between characters */
/* Derived properties: */
int m_iCharDescent, m_iCharLeftOverlap, m_iCharRightOverlap, m_iCharBaseline,
m_iCharTop, m_iCharVertSpacing;
RECT m_BoundingRect;
vector<FontPage *> m_apPages;
CString m_sError, m_sWarnings;
private:
int GetTopPadding() const;
/* Bounds of each character, according to MeasureCharacterRanges. */
map<wchar_t, RECT> m_RealBounds;
map<wchar_t, ABC> m_ABC;
void FormatCharacter( wchar_t c, HDC hDC );
};
#endif
/*
* 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.
*/
@@ -0,0 +1,231 @@
#include "stdafx.h"
#include "Utils.h"
Surface::Surface( const Surface &cpy )
{
iWidth = cpy.iWidth;
iHeight = cpy.iHeight;
iPitch = cpy.iPitch;
if( cpy.pRGBA )
{
pRGBA = new unsigned char[iHeight * iPitch];
}
else
{
pRGBA = NULL;
}
}
void BitmapToSurface( HBITMAP hBitmap, Surface *pSurf )
{
HDC hDC = CreateCompatibleDC( NULL );
HGDIOBJ hOldBitmap = SelectObject( hDC, hBitmap );
BITMAPINFO bi;
memset( &bi, 0, sizeof(bi) );
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
GetDIBits( hDC, hBitmap, 0, 0, NULL, &bi, DIB_RGB_COLORS );
pSurf->iWidth = bi.bmiHeader.biWidth;
pSurf->iHeight = bi.bmiHeader.biHeight;
pSurf->iPitch = bi.bmiHeader.biWidth * 4;
pSurf->pRGBA = (unsigned char *) new unsigned char[pSurf->iWidth * pSurf->iHeight * 4];
bi.bmiHeader.biHeight = -bi.bmiHeader.biHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = pSurf->iHeight * pSurf->iWidth * 4;
//LONG biXPelsPerMeter;
//LONG biYPelsPerMeter;
// DWORD biClrUsed;
// DWORD biClrImportant;
if( !GetDIBits(hDC, hBitmap, 0, pSurf->iHeight, pSurf->pRGBA, &bi, DIB_RGB_COLORS) )
{
int q = 1;
}
SelectObject( hDC, hOldBitmap );
DeleteDC( hDC );
}
void GrayScaleToAlpha( Surface *pSurf )//void *pImg, int iWidth, int iHeight, int iPitch )
{
char *p = (char *) pSurf->pRGBA;
for( int iY = 0; iY < pSurf->iHeight; ++iY )
{
unsigned *pos = (unsigned *) p;
for( int iX = 0; iX < pSurf->iWidth; ++iX )
{
unsigned pixel = pos[iX];
pixel <<= 24;
pixel |= 0x00FFFFFF;
pos[iX] = pixel;
}
p += pSurf->iPitch;
}
}
void GetBounds( const Surface *pSurf, RECT *out )
{
out->left = out->right = out->top = out->bottom = 0;
int FirstCol = 9999, LastCol = 0, FirstRow = 9999, LastRow = 0;
const char *p = (const char *) pSurf->pRGBA;
for( int row = 0; row < pSurf->iHeight; ++row )
{
const unsigned *pos = (const unsigned *) p;
for( int col = 0; col < pSurf->iWidth; ++col )
{
unsigned pixel = pos[col];
if( (pixel & 0xFFFFFF) == 0 )
continue; /* black */
FirstCol = min(FirstCol, col);
LastCol = max(LastCol, col);
FirstRow = min(FirstRow, row);
LastRow = max(LastRow, row);
}
p += pSurf->iPitch;
}
if( FirstCol != 9999 && FirstRow != 9999 )
{
out->left = FirstCol;
out->top = FirstRow;
out->right = LastCol+1;
out->bottom = LastRow+1;
}
}
#pragma include_alias( "zlib/zlib.h", "../zlib/zlib.h" )
#include "../libpng/include/png.h"
#if defined(_MSC_VER)
# if defined(_XBOX)
# pragma comment(lib, "../libpng/lib/xboxlibpng.lib")
# else
# pragma comment(lib, "../libpng/lib/libpng.lib")
# endif
#pragma warning(disable: 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
#endif
static void File_png_write( png_struct *pPng, png_byte *pData, png_size_t iSize )
{
FILE *f = (FILE *) pPng->io_ptr;
size_t iGot = fwrite( pData, (int) iSize, 1, f );
if( iGot == 0 )
png_error( pPng, strerror(errno) );
}
static void File_png_flush( png_struct *pPng )
{
FILE *f = (FILE *) pPng->io_ptr;
int iGot = fflush(f);
if( iGot == -1 )
png_error( pPng, strerror(errno) );
}
struct error_info
{
char *szErr;
};
static void PNG_Error( png_struct *pPng, const char *szError )
{
error_info *pInfo = (error_info *) pPng->error_ptr;
strncpy( pInfo->szErr, szError, 1024 );
pInfo->szErr[1023] = 0;
longjmp( pPng->jmpbuf, 1 );
}
static void PNG_Warning( png_struct *png, const char *warning )
{
}
/* Since libpng forces us to use longjmp, this function shouldn't create any C++
* objects, and needs to watch out for memleaks. */
bool SavePNG( FILE *f, char szErrorbuf[1024], const Surface *pSurf )
{
/* RageSurfaceUtils::ConvertSurface( pImgIn, pImg, pImgIn->w, pImgIn->h, 32,
Swap32BE( 0xFF000000 ),
Swap32BE( 0x00FF0000 ),
Swap32BE( 0x0000FF00 ),
Swap32BE( 0x000000FF ) );
*/
error_info error;
error.szErr = szErrorbuf;
png_struct *pPng = png_create_write_struct( PNG_LIBPNG_VER_STRING, &error, PNG_Error, PNG_Warning );
if( pPng == NULL )
{
sprintf( szErrorbuf, "creating png_create_write_struct failed");
return false;
}
png_info *pInfo = png_create_info_struct(pPng);
if( pInfo == NULL )
{
png_destroy_read_struct( &pPng, NULL, NULL );
sprintf( szErrorbuf, "creating png_create_info_struct failed");
return false;
}
if( setjmp(pPng->jmpbuf) )
{
png_destroy_read_struct( &pPng, &pInfo, png_infopp_NULL );
return false;
}
png_set_write_fn( pPng, f, File_png_write, File_png_flush );
png_set_compression_level( pPng, 1 );
png_set_IHDR( pPng, pInfo, pSurf->iWidth, pSurf->iHeight, 8, PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE );
png_write_info( pPng, pInfo );
png_set_filler( pPng, 0, PNG_FILLER_AFTER );
png_byte *pixels = (png_byte *) pSurf->pRGBA;
for( int y = 0; y < pSurf->iHeight; y++ )
png_write_row( pPng, pixels + pSurf->iPitch*y );
png_write_end( pPng, pInfo );
png_destroy_write_struct( &pPng, &pInfo );
return true;
}
/*
* 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.
*/
@@ -0,0 +1,59 @@
#ifndef UTILS_H
#define UTILS_H
inline float truncf( float f ) { return float(int(f)); };
inline float roundf( float f ) { if(f < 0) return truncf(f-0.5f); return truncf(f+0.5f); };
inline long int lrintf( float f )
{
int retval;
_asm fld f;
_asm fistp retval;
return retval;
}
struct Surface
{
Surface() { pRGBA = NULL; }
~Surface() { delete [] pRGBA; }
Surface( const Surface &cpy );
int iWidth;
int iHeight;
int iPitch;
unsigned char *pRGBA;
};
void BitmapToSurface( HBITMAP hBitmap, Surface *pSurf );
void GrayScaleToAlpha( Surface *pSurf );
void GetBounds( const Surface *pSurf, RECT *out );
bool SavePNG( FILE *f, char szErrorbuf[1024], const Surface *pSurf );
#endif
/*
* 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.
*/
Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@@ -0,0 +1,13 @@
//
// TextureFontGenerator.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,41 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Texture Font Generator.rc
//
#define IDP_OLE_INIT_FAILED 100
#define ID_STYLE_ITALIC 101
#define IDD_TEXTUREFONTGENERATOR_DIALOG 102
#define IDR_MAINFRAME 103
#define IDR_MENU 104
#define ID_STYLE_BOLD 110
#define ID_FILE_SAVE141 141
#define ID_FILE_EXIT 142
#define ID_Menu 143
#define IDR_ACCELERATOR 144
#define ID_STYLE_ANTIALIASED 302
#define IDC_PICTURE 1000
#define IDC_SHOWN_PAGE 1011
#define IDC_FAMILY_LIST 1013
#define IDC_BOLD 1015
#define IDC_ITALIC 1016
#define IDC_TEXT_OVERLAP 1017
#define IDC_FONT_SIZE 1018
#define IDC_ERROR_OR_WARNING 1020
#define IDC_CLOSEUP 1021
#define IDC_SPIN_TOP 1022
#define IDC_SPIN_BASELINE 1023
#define IDC_PADDING 1025
#define IDC_CHECK1 1026
#define ID_ACCELERATOR_ITALIC 32773
#define ID_ACCELERATOR_BOLD 32774
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 145
#define _APS_NEXT_COMMAND_VALUE 32779
#define _APS_NEXT_CONTROL_VALUE 1028
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
@@ -0,0 +1,26 @@
#include "stdafx.h"
/*
* 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.
*/
@@ -0,0 +1,87 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#pragma once
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#endif
#define NOMINMAX
#include <algorithm>
using namespace std;
// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later.
#define WINVER 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif
#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later.
#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later.
#endif
#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
#endif
#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later.
#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later.
#endif
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit
// turns off MFC's hiding of some common and often safely ignored warning messages
#define _AFX_ALL_WARNINGS
#pragma warning (disable : 4996) // deprecated functions vs "ISO C++ conformant names". (stricmp vs _stricmp)
#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
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//#include <gdiplus.h>
//#include <GdiPlusGraphics.h>
// This macro is the same as IMPLEMENT_OLECREATE, except it passes TRUE
// for the bMultiInstance parameter to the COleObjectFactory constructor.
// We want a separate instance of this application to be launched for
// each automation proxy object requested by automation controllers.
#ifndef IMPLEMENT_OLECREATE2
#define IMPLEMENT_OLECREATE2(class_name, external_name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
AFX_DATADEF COleObjectFactory class_name::factory(class_name::guid, \
RUNTIME_CLASS(class_name), TRUE, _T(external_name)); \
const AFX_DATADEF GUID class_name::guid = \
{ l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } };
#endif // IMPLEMENT_OLECREATE2
/*
* 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.
*/