Delete old obsolete font builder tool and related files
This was SVN commit r7599.
This commit is contained in:
parent
7af705435f
commit
6de0cdc5f9
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,20 +0,0 @@
|
||||
# Install cons (www.dsmit.com/cons), then run it in this directory
|
||||
# to attempt to compile. Update paths as appropriate. It still won't
|
||||
# work though - wxexpr.cpp dies if you use Unicode, so I had to
|
||||
# alter it a little. If anybody cares, let me know and I'll make
|
||||
# some more useful instructions.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
Default '.';
|
||||
|
||||
my $env = new cons (
|
||||
CFLAGS => '-O0 -g -Wall -I/usr/local/lib/wx/include/gtk2ud-2.4 -D__WXDEBUG__ -D__WXGTK__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -DUNICODE -D_UNICODE -DwxUSE_UNICODE=1',
|
||||
# CFLAGS => '-O0 -g -W3 -I/usr/local/lib/wx/include/gtk2ud-2.4 -D__WXDEBUG__ -D__WXGTK__ -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -DUNICODE -D_UNICODE -DwxUSE_UNICODE=1',
|
||||
# CC => '/opt/intel/compiler80/bin/icc',
|
||||
LIBPATH => ['/home/philip/wxGTK-2.4.2/lib'],
|
||||
LIBS => '-lwx_gtk2ud-2.4',
|
||||
CPPPATH => ['.', '/usr/include/freetype2', '/home/philip/wxGTK-2.4.2/include', '/home/philip/wxGTK-2.4.2/lib/wx/include/gtk2ud-2.4'],
|
||||
);
|
||||
Program $env 'FontBuilder', <*.cpp>, <platform/linux/*.cpp>;
|
Binary file not shown.
Before Width: | Height: | Size: 2.2 KiB |
@ -1,76 +0,0 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#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
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_ICON1 ICON "FontBuilder.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
@ -1,21 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FontBuilder", "FontBuilder.vcproj", "{D566B684-803B-4D6F-A617-829F050BE928}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{D566B684-803B-4D6F-A617-829F050BE928}.Debug.ActiveCfg = Debug|Win32
|
||||
{D566B684-803B-4D6F-A617-829F050BE928}.Debug.Build.0 = Debug|Win32
|
||||
{D566B684-803B-4D6F-A617-829F050BE928}.Release.ActiveCfg = Release|Win32
|
||||
{D566B684-803B-4D6F-A617-829F050BE928}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,299 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="FontBuilder"
|
||||
ProjectGUID="{D566B684-803B-4D6F-A617-829F050BE928}"
|
||||
RootNamespace="FontBuilder"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""E:\wx\wxWindows-2.4.2\include";"E:\wx\wxWindows-2.4.2\lib\mswud";"E:\freetype\freetype-2.1.8\include";E:\wx\pretends;."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;__WXDEBUG__;_UNICODE;UNICODE;wxUSE_UNICODE=1"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="TRUE"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wxmswud.lib comctl32.lib ws2_32.lib rpcrt4.lib"
|
||||
OutputFile="$(OutDir)/FontBuilder.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories=""E:\wx\wxWindows-2.4.2\lib";"E:\freetype\freetype-2.1.8\objs""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/FontBuilder.pdb"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="FALSE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="-Qinline_debug_info "
|
||||
Optimization="1"
|
||||
GlobalOptimizations="FALSE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="FALSE"
|
||||
FavorSizeOrSpeed="2"
|
||||
OmitFramePointers="FALSE"
|
||||
EnableFiberSafeOptimizations="FALSE"
|
||||
OptimizeForProcessor="2"
|
||||
OptimizeForWindowsApplication="FALSE"
|
||||
AdditionalIncludeDirectories=""E:\wx\wxWindows-2.4.2\include";"E:\wx\wxWindows-2.4.2\lib\mswud";"E:\freetype\freetype-2.1.8\include";E:\wx\pretends;."
|
||||
PreprocessorDefinitions="_STATIC_CPPLIB;WIN32;NDEBUG;_WINDOWS;_UNICODE;UNICODE;wxUSE_UNICODE=1"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="2"
|
||||
StructMemberAlignment="0"
|
||||
BufferSecurityCheck="FALSE"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
Detect64BitPortabilityProblems="FALSE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="wxmswu.lib freetype218MT.lib comctl32.lib ws2_32.lib rpcrt4.lib"
|
||||
OutputFile="$(OutDir)/FontBuilder.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="E:\wx\wxWindows-2.4.2\lib;E:\freetype\freetype-2.1.8\objs;e:\icc80\compiler80\ia32\lib"
|
||||
IgnoreDefaultLibraryNames="libmmd"
|
||||
GenerateDebugInformation="FALSE"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
OptimizeForWindows98="0"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="rem upx --best $(TargetPath)"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\filemanip.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\font.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\freetypedll.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\imagemanip.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\packer.cpp">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxapp.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxconfig.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxframe.cpp">
|
||||
</File>
|
||||
<Filter
|
||||
Name="platform"
|
||||
Filter="">
|
||||
<Filter
|
||||
Name="msw"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\platform\msw\fontselect.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="linux"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\platform\linux\fontselect.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\filemanip.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\font.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\freetypedll.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\freetypedll_funcs.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\imagemanip.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\packer.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\version.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxconfig.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxframe.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxspinner.h">
|
||||
</File>
|
||||
<Filter
|
||||
Name="platform"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\platform\fontselect.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
<File
|
||||
RelativePath=".\FontBuilder.ico">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FontBuilder.rc">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\fileformat.txt">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\readme.html">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\todo.txt">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,128 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "filemanip.h"
|
||||
|
||||
// Ensure there's no padding added into the struct,
|
||||
// in a very non-portable way
|
||||
#ifdef _WIN32
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char identsize; // size of ID field that follows 18 byte header (0 usually)
|
||||
char colourmaptype; // type of colour map 0=none, 1=has palette
|
||||
char imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
|
||||
|
||||
short colourmapstart; // first colour map entry in palette
|
||||
short colourmaplength; // number of colours in palette
|
||||
char colourmapbits; // number of bits per palette entry 15,16,24,32
|
||||
|
||||
short xstart; // image x origin
|
||||
short ystart; // image y origin
|
||||
short width; // image width in pixels
|
||||
short height; // image height in pixels
|
||||
char bits; // image bits per pixel 8,16,24,32
|
||||
char descriptor; // image descriptor bits (vh flip bits)
|
||||
#ifdef _WIN32
|
||||
} TGA_HEADER;
|
||||
# pragma pack(pop)
|
||||
#else
|
||||
} __attribute__ ((packed)) TGA_HEADER;
|
||||
#endif
|
||||
|
||||
// Convert the RGB image to 8-bit greyscale and output
|
||||
void RGB_OutputGreyscaleTGA(unsigned char* image_data, int width, int height, int pitch, wxFFile& file)
|
||||
{
|
||||
assert(sizeof(TGA_HEADER) == 18);
|
||||
|
||||
TGA_HEADER header;
|
||||
|
||||
header.identsize = 0;
|
||||
header.colourmaptype = 0;
|
||||
header.imagetype = 3;
|
||||
header.xstart = 0;
|
||||
header.ystart = 0;
|
||||
header.width = (short)width;
|
||||
header.height = (short)height;
|
||||
header.bits = 8;
|
||||
header.descriptor = 0;
|
||||
|
||||
file.Write(&header, sizeof(header));
|
||||
|
||||
// Start from the bottom, so things look the right way up
|
||||
image_data += height*pitch;
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
image_data -= pitch;
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
file.Write(&image_data[x*3], 1);
|
||||
}
|
||||
}
|
||||
|
||||
std::set<wchar_t> AnalyseChars(wxString filename)
|
||||
{
|
||||
wxFFile File (filename, "rb");
|
||||
if (! File.IsOpened())
|
||||
throw "Cannot open file";
|
||||
|
||||
enum {
|
||||
UNKNOWN,
|
||||
UTF8,
|
||||
UTF16SE, // same-endian as this machine
|
||||
UTF16DE // different-endian
|
||||
} Format = UNKNOWN;
|
||||
|
||||
unsigned short BOM;
|
||||
File.Read(&BOM, 2);
|
||||
if (BOM == 0xFEFF)
|
||||
Format = UTF16SE;
|
||||
else if (BOM == 0xFFFE)
|
||||
Format = UTF16DE;
|
||||
else {
|
||||
// Make an educated guess based on the first byte
|
||||
// If it's like "_\0" it's probably little-endian,
|
||||
// if it's like "\0_" it's probably big-endian
|
||||
if ((BOM & 0xFF00) == 0)
|
||||
Format = UTF16SE;
|
||||
else if ((BOM & 0x00FF) == 0)
|
||||
Format = UTF16DE;
|
||||
else
|
||||
throw "Can't determine endianness of source file - make sure it's UTF16 and starts with a simple letter";
|
||||
// (Maybe it's UTF8, but I don't want to bother with that)
|
||||
|
||||
File.Seek(0); // Make sure the first character is included in the list
|
||||
}
|
||||
|
||||
std::set<wchar_t> Chars;
|
||||
if (Format == UTF16SE)
|
||||
{
|
||||
wchar_t c;
|
||||
while (! File.Eof())
|
||||
{
|
||||
File.Read(&c, 2);
|
||||
if (c != '\r' && c != '\n')
|
||||
Chars.insert(c);
|
||||
}
|
||||
}
|
||||
else if (Format == UTF16DE)
|
||||
{
|
||||
unsigned short c;
|
||||
while (! File.Eof())
|
||||
{
|
||||
if (File.Read(&c, 2) != 2) break; // abort if failed (i.e. eof)
|
||||
c = (c>>8)|((c&0xff)<<8); // swap bytes
|
||||
if (c != '\r' && c != '\n')
|
||||
Chars.insert(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw "Internal error - invalid file format";
|
||||
}
|
||||
|
||||
return Chars;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#include "wx/ffile.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
void RGB_OutputGreyscaleTGA(unsigned char* image_data, int width, int height, int pitch, wxFFile& file);
|
||||
std::set<wchar_t> AnalyseChars(wxString filename);
|
@ -1,353 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "wx/wx.h"
|
||||
|
||||
#include "font.h"
|
||||
#include "freetype/ttunpat.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "freetypedll.h"
|
||||
|
||||
static char err[255]; // not exactly thread-safe
|
||||
|
||||
FontRenderer::FontRenderer(const char* filename0, const char* filename1, double ptsize, bool unpatented_hinting, bool hinting)
|
||||
{
|
||||
char* err_str = SelectDLL(hinting ? 0 : 1);
|
||||
if (err_str)
|
||||
{
|
||||
sprintf(err, "Error loading FreeType DLL (freetype(a|b).dll (%d)): %s", hinting, err_str);
|
||||
throw err;
|
||||
}
|
||||
|
||||
int error;
|
||||
|
||||
error = DLLFT_Init_FreeType(&FontLibrary0);
|
||||
if (error)
|
||||
{
|
||||
throw "Error initialising FreeType";
|
||||
}
|
||||
|
||||
error = DLLFT_Init_FreeType(&FontLibrary1);
|
||||
if (error)
|
||||
{
|
||||
DLLFT_Done_FreeType(FontLibrary0);
|
||||
throw "Error initialising FreeType";
|
||||
}
|
||||
|
||||
FT_Parameter openparam = { FT_PARAM_TAG_UNPATENTED_HINTING, NULL };
|
||||
|
||||
FT_Open_Args args0 = {
|
||||
FT_OPEN_PATHNAME | (unpatented_hinting ? FT_OPEN_PARAMS : 0),
|
||||
NULL, NULL,
|
||||
(FT_String*)filename0,
|
||||
NULL, NULL,
|
||||
1, &openparam
|
||||
};
|
||||
FT_Open_Args args1 = {
|
||||
FT_OPEN_PATHNAME | (unpatented_hinting ? FT_OPEN_PARAMS : 0),
|
||||
NULL, NULL,
|
||||
(FT_String*)filename1,
|
||||
NULL, NULL,
|
||||
1, &openparam
|
||||
};
|
||||
|
||||
error = DLLFT_Open_Face(
|
||||
FontLibrary0,
|
||||
&args0,
|
||||
0, // index of face inside font file
|
||||
&FontFace0
|
||||
);
|
||||
if (error)
|
||||
{
|
||||
DLLFT_Done_FreeType(FontLibrary0);
|
||||
DLLFT_Done_FreeType(FontLibrary1);
|
||||
throw "Error loading primary font";
|
||||
}
|
||||
|
||||
error = DLLFT_Open_Face(
|
||||
FontLibrary1,
|
||||
&args1,
|
||||
0, // index of face inside font file
|
||||
&FontFace1
|
||||
);
|
||||
if (error)
|
||||
{
|
||||
DLLFT_Done_Face(FontFace0);
|
||||
DLLFT_Done_FreeType(FontLibrary0);
|
||||
DLLFT_Done_FreeType(FontLibrary1);
|
||||
throw "Error loading secondary font face";
|
||||
}
|
||||
|
||||
error = DLLFT_Set_Char_Size(
|
||||
FontFace0,
|
||||
0, // char_width in 1/64th of points
|
||||
(int)(ptsize*64.0 + 0.5), // char_height in 1/64th of points
|
||||
96, // horizontal device resolution
|
||||
96 // vertical device resolution
|
||||
);
|
||||
if (error)
|
||||
{
|
||||
DLLFT_Done_Face(FontFace0);
|
||||
DLLFT_Done_Face(FontFace1);
|
||||
DLLFT_Done_FreeType(FontLibrary0);
|
||||
DLLFT_Done_FreeType(FontLibrary1);
|
||||
throw "Error loading scalable character from primary font - is this a TrueType font?";
|
||||
}
|
||||
|
||||
error = DLLFT_Set_Char_Size(
|
||||
FontFace1,
|
||||
0, // char_width in 1/64th of points
|
||||
(int)(ptsize*64.0 + 0.5), // char_height in 1/64th of points
|
||||
96, // horizontal device resolution
|
||||
96 // vertical device resolution
|
||||
);
|
||||
if (error)
|
||||
{
|
||||
DLLFT_Done_Face(FontFace0);
|
||||
DLLFT_Done_Face(FontFace1);
|
||||
DLLFT_Done_FreeType(FontLibrary0);
|
||||
DLLFT_Done_FreeType(FontLibrary1);
|
||||
throw "Error loading scalable character from secondary font - is this a TrueType font?";
|
||||
}
|
||||
|
||||
Boldness = 0;
|
||||
Italicness = 0;
|
||||
Tracking = 0;
|
||||
Leading = 0;
|
||||
}
|
||||
|
||||
FontRenderer::~FontRenderer()
|
||||
{
|
||||
DLLFT_Done_Face(FontFace0);
|
||||
DLLFT_Done_Face(FontFace1);
|
||||
DLLFT_Done_FreeType(FontLibrary0);
|
||||
DLLFT_Done_FreeType(FontLibrary1);
|
||||
}
|
||||
|
||||
#define deg2rad(a) ((double)a * 3.14159265358979323846 / 180.0)
|
||||
|
||||
int FontRenderer::LoadGlyph(const int charcode)
|
||||
{
|
||||
FT_Face FontFace = FontFace0;
|
||||
int glyph_index = DLLFT_Get_Char_Index(FontFace0, charcode);
|
||||
|
||||
Missing = false;
|
||||
if (glyph_index == 0)
|
||||
{
|
||||
// Can't find glyph in primary font - switch to secondary
|
||||
FontFace = FontFace1;
|
||||
glyph_index = DLLFT_Get_Char_Index(FontFace1, charcode);
|
||||
|
||||
// Still can't find it - use the missing glyph symbol
|
||||
if (glyph_index == 0)
|
||||
{
|
||||
glyph_index = DLLFT_Get_Char_Index(FontFace1, 0xFFFD);
|
||||
Missing = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int error;
|
||||
|
||||
if (Italicness)
|
||||
{
|
||||
// Start with identity matrix (rotations could be added in here easily)
|
||||
FT_Matrix mat;
|
||||
mat.xx = mat.yy = (FT_Fixed)(0x10000L);
|
||||
mat.xy = mat.yx = (FT_Fixed)(0x00000L);
|
||||
// Apply shear
|
||||
FT_Fixed f = (FT_Fixed)(tan(deg2rad(Italicness)) * 0x10000L);
|
||||
mat.xy += DLLFT_MulFix(f, mat.xx);
|
||||
mat.yy += DLLFT_MulFix(f, mat.yx);
|
||||
|
||||
DLLFT_Set_Transform(FontFace, &mat, 0);
|
||||
}
|
||||
|
||||
error = DLLFT_Load_Glyph(FontFace, glyph_index, FT_LOAD_DEFAULT);
|
||||
if (error)
|
||||
throw "Error loading glyph";
|
||||
|
||||
|
||||
if (Outline)
|
||||
{
|
||||
wxLogFatalError(wxT("Can't do this yet"));
|
||||
/*
|
||||
// Outline renderer which doesn't actually work:
|
||||
|
||||
assert(FontFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE);
|
||||
|
||||
//FT_Outline *FontOutline = new FT_Outline;
|
||||
//error = FT_Outline_New(FontLibrary, 1024, 1024, FontOutline);
|
||||
//assert(!error);
|
||||
FT_Outline *FontOutline = &FontFace->glyph->outline;
|
||||
|
||||
FT_BBox BBox;
|
||||
|
||||
error = FT_Outline_Get_BBox(FontOutline, &BBox);
|
||||
assert(!error);
|
||||
|
||||
// Translate back to (0,0)
|
||||
FT_Outline_Translate(FontOutline, -BBox.xMin, -BBox.yMin);
|
||||
|
||||
FT_Bitmap *Bmp = new FT_Bitmap;
|
||||
Bmp->pixel_mode = FT_PIXEL_MODE_GRAY;
|
||||
Bmp->num_grays = 256;
|
||||
FontFace->glyph->bitmap_left = (BBox.xMin) >> 6;
|
||||
FontFace->glyph->bitmap_top = (BBox.yMax + 31) >> 6;
|
||||
Bmp->width = (BBox.xMax - BBox.xMin) >> 6;
|
||||
Bmp->pitch = 3*Bmp->width;
|
||||
Bmp->rows = (BBox.yMax - BBox.yMin) >> 6;
|
||||
Bmp->buffer = new unsigned char[Bmp->pitch * Bmp->rows];
|
||||
memset(Bmp->buffer, 0, sizeof(unsigned char) * Bmp->pitch * Bmp->rows);
|
||||
|
||||
error = FT_Outline_Get_Bitmap(FontLibrary, FontOutline, Bmp);
|
||||
assert(!error);
|
||||
|
||||
FontFace->glyph->bitmap = *Bmp;
|
||||
|
||||
error = FT_Outline_Done(FontLibrary, FontOutline);
|
||||
assert(!error);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simple version:
|
||||
|
||||
error = DLLFT_Render_Glyph(FontFace->glyph, FT_RENDER_MODE_NORMAL);
|
||||
if (error)
|
||||
throw "Error rendering glyph";
|
||||
}
|
||||
|
||||
LastFontFace = FontFace;
|
||||
|
||||
return glyph_index;
|
||||
}
|
||||
|
||||
|
||||
void FontRenderer::GetBoundingBox(int& width, int& height)
|
||||
{
|
||||
FT_Bitmap* bmp = &LastFontFace->glyph->bitmap;
|
||||
width = bmp->width + Boldness;
|
||||
height = bmp->rows;
|
||||
}
|
||||
|
||||
|
||||
void FontRenderer::RenderGlyph(unsigned char* rgb_buffer, int& pos_left, int& pos_top, int width, int height, int pitch, bool single_glyph)
|
||||
{
|
||||
FT_Face FontFace = LastFontFace;
|
||||
|
||||
// This function only tries to work on 8-bit greyscale glyphs
|
||||
if (FontFace->glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
|
||||
throw "Error - invalid bitmap format";
|
||||
|
||||
// Add desired spacing, but not after zero-width combining glyphs
|
||||
if (!single_glyph && FontFace->glyph->advance.x)
|
||||
pos_left += Tracking;
|
||||
|
||||
FT_Bitmap* bmp = &FontFace->glyph->bitmap;
|
||||
|
||||
// Pointers to the appropriate row of pixel data
|
||||
unsigned char* ImageRow = rgb_buffer;
|
||||
unsigned char* GlyphRow = bmp->buffer;
|
||||
|
||||
int Left = pos_left;
|
||||
int Top = pos_top;
|
||||
if (!single_glyph)
|
||||
{
|
||||
Left += FontFace->glyph->bitmap_left;
|
||||
Top -= FontFace->glyph->bitmap_top;
|
||||
}
|
||||
|
||||
// Point to the first line that needs to be drawn
|
||||
if (Top >= 0)
|
||||
ImageRow += Top*pitch;
|
||||
|
||||
for (int GlyphY = 0; GlyphY < bmp->rows; ++GlyphY)
|
||||
{
|
||||
// Clip vertically
|
||||
if (Top+GlyphY < 0 || Top+GlyphY >= height)
|
||||
{
|
||||
GlyphRow += bmp->pitch;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
for (int GlyphX = 0; GlyphX < bmp->width+Boldness; ++GlyphX)
|
||||
{
|
||||
// Clip horizontally
|
||||
if (Left+GlyphX < 0 || Left+GlyphX >= width)
|
||||
continue;
|
||||
|
||||
int value = 0;
|
||||
|
||||
if (! Boldness)
|
||||
{
|
||||
value = GlyphRow[GlyphX];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Glyph: 001122221100
|
||||
//
|
||||
// Calc: 001122221100
|
||||
// + 001122221100
|
||||
// = 0012344432100
|
||||
// ||__ __||
|
||||
// row[0]+row[1] row[10]+row[11]
|
||||
// __| |__
|
||||
// row[0] row[11]
|
||||
//
|
||||
// output[x] = sum row[x-boldness .. x]
|
||||
|
||||
|
||||
int min = GlyphX - Boldness; // inclusive
|
||||
if (min < 0) min = 0;
|
||||
int max = GlyphX+1; // not inclusive
|
||||
if (max > bmp->width) max = bmp->width;
|
||||
|
||||
for (int x = min; x < max; ++x)
|
||||
value += GlyphRow[x];
|
||||
|
||||
}
|
||||
|
||||
// Additive composition of pixel onto image buffer
|
||||
value += ImageRow[(Left+GlyphX)*3];
|
||||
ImageRow[(Left+GlyphX)*3 ] =
|
||||
ImageRow[(Left+GlyphX)*3+1] =
|
||||
ImageRow[(Left+GlyphX)*3+2] = (unsigned char)(value > 255 ? 255 : value);
|
||||
|
||||
}
|
||||
|
||||
// Point everything at the next line
|
||||
ImageRow += pitch;
|
||||
GlyphRow += bmp->pitch;
|
||||
}
|
||||
|
||||
if (!single_glyph)
|
||||
{
|
||||
// Advance the drawing-cursor ( >>6 due to 26.6-bit number format)
|
||||
pos_left += FontFace->glyph->advance.x >> 6;
|
||||
pos_top += FontFace->glyph->advance.y >> 6;
|
||||
}
|
||||
}
|
||||
|
||||
int FontRenderer::GetLineSpacing()
|
||||
{
|
||||
return Leading + (FontFace0->size->metrics.height >> 6);
|
||||
}
|
||||
|
||||
void FontRenderer::GetMetrics(int& offset_x, int& offset_y, int& advance)
|
||||
{
|
||||
offset_x = LastFontFace->glyph->bitmap_left;
|
||||
offset_y = LastFontFace->glyph->bitmap_top;
|
||||
advance = LastFontFace->glyph->advance.x >> 6;
|
||||
if (advance)
|
||||
offset_x += Tracking;
|
||||
}
|
||||
|
||||
int FontRenderer::GetKerning(int left, int right)
|
||||
{
|
||||
FT_Vector vec;
|
||||
DLLFT_Get_Kerning(LastFontFace, left, right, FT_KERNING_DEFAULT, &vec);
|
||||
assert(vec.y == 0);
|
||||
return vec.x>>6;
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
#ifndef INCLUDED_FONT
|
||||
#define INCLUDED_FONT
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_BBOX_H
|
||||
|
||||
|
||||
// Make my IDE a little happier:
|
||||
#if 0
|
||||
#include "freetype/freetype.h"
|
||||
#include "freetype/freetype_defs.h"
|
||||
#include "freetype/ftimage.h"
|
||||
#include "freetype/fttypes.h"
|
||||
#include "freetype/ftbbox.h"
|
||||
#include "freetype/ftoutln.h"
|
||||
#endif
|
||||
|
||||
class FontRenderer
|
||||
{
|
||||
public:
|
||||
|
||||
// Two fonts are required - a primary (0) font which will be used first,
|
||||
// and a secondary (1) font for filling in missing glyphs.
|
||||
// (The secondary font should usually be Arial Unicode MS).
|
||||
FontRenderer(const char* filename0, const char* filename1, double ptsize, bool unpatented_hinting, bool hinting);
|
||||
|
||||
~FontRenderer();
|
||||
|
||||
// Generate the glyph for the given Unicode code point. Returns the glyph index.
|
||||
int LoadGlyph(const int charcode);
|
||||
|
||||
// Put the appropriate pixel sizes into width and height
|
||||
void GetBoundingBox(int& width, int& height);
|
||||
|
||||
// Copy the glyph onto a 24-bit RGB image buffer
|
||||
// pos_left / pos_top: Position to put the origin (usually bottom left corner) of the glyph.
|
||||
// Altered by the function to point towards the next character.
|
||||
// width / height: of bitmap, to do clipping
|
||||
// pitch: Bytes per row, including any padding
|
||||
// single_glyph: If true, doesn't update the cursor and draws with the bounding box at pos_left/top
|
||||
void RenderGlyph(unsigned char* rgb_buffer, int& pos_left, int& pos_top, int width, int height, int pitch, bool single_glyph);
|
||||
|
||||
// Returns baseline-to-baseline distance, including the desired leading
|
||||
int GetLineSpacing();
|
||||
|
||||
// Supplies some information for positioning glyphs
|
||||
void GetMetrics(int& offset_x, int& offset_y, int& advance);
|
||||
|
||||
int GetKerning(int left, int right);
|
||||
|
||||
// Set by LoadGlyph if it can't find the right glyph
|
||||
bool Missing;
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
// Font settings, set by users and used by this class:
|
||||
|
||||
// Shear angle (in degrees) for fake italics
|
||||
int Italicness;
|
||||
|
||||
// 0 for standard; otherwise draws n+1 overlapping copies of the text
|
||||
int Boldness;
|
||||
|
||||
// Additional spacing between each non-zero-width glyph and the next
|
||||
int Tracking;
|
||||
|
||||
// Additional spacing between lines
|
||||
int Leading;
|
||||
|
||||
// Whether to draw an outlined font
|
||||
bool Outline;
|
||||
|
||||
private:
|
||||
FT_Library FontLibrary0;
|
||||
FT_Library FontLibrary1;
|
||||
FT_Face FontFace0;
|
||||
FT_Face FontFace1;
|
||||
|
||||
FT_Face LastFontFace; // = FontFace(0|1), depending on the last LoadGlyph
|
||||
};
|
||||
|
||||
#endif // INCLUDED_FONT
|
@ -1,259 +0,0 @@
|
||||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Intel C++ Project"
|
||||
Version="7.1"
|
||||
Name="FontBuilder"
|
||||
VCNestedProjectGUID="{277A0C35-0B44-48FC-81FD-119AD97194EA}"
|
||||
VCNestedProjectFileName="FontBuilder.vcproj">
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32">
|
||||
<IntelOptions
|
||||
CompilerName="1"/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool">
|
||||
<IntelOptions
|
||||
Optimization="0"
|
||||
MinimalRebuild="1"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
BufferSecurityCheck="1"
|
||||
EnableFunctionLevelLinking="1"
|
||||
ForceConformanceInForLoopScope="1"/>
|
||||
</Tool>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool">
|
||||
<IntelOptions
|
||||
Optimization="1"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="2"
|
||||
OptimizeForProcessor="3"
|
||||
LoopUnrolling=""
|
||||
StringPooling="1"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="0"
|
||||
ForceConformanceInForLoopScope="1"
|
||||
OpenMPDirectives="0"/>
|
||||
</Tool>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\filemanip.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\font.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\freetypedll.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\imagemanip.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\packer.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool">
|
||||
<IntelOptions
|
||||
Optimization="1000"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="1"/>
|
||||
</Tool>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxapp.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxconfig.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxframe.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\platform\msw\fontselect.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\platform\linux\fontselect.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filemanip.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\font.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\freetypedll.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\freetypedll_funcs.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\imagemanip.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\packer.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\version.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxconfig.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxframe.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\wxspinner.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\platform\fontselect.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FontBuilder.ico">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FontBuilder.rc">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\fileformat.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\readme.html">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\todo.txt">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"/>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"/>
|
||||
</File>
|
||||
</Files>
|
||||
</VisualStudioProject>
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,52 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "freetypedll.h"
|
||||
|
||||
#define FUNC(ret, name, par) ret (* DLL##name) par
|
||||
#include "freetypedll_funcs.h"
|
||||
#undef FUNC
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
HINSTANCE dlls[2] = { 0, 0 };
|
||||
|
||||
static char err[255]; // not exactly thread-safe
|
||||
|
||||
char* SelectDLL(int DLL)
|
||||
{
|
||||
const char* name;
|
||||
switch (DLL)
|
||||
{
|
||||
case 0: name = "freetypea.dll"; break;
|
||||
case 1: name = "freetypeb.dll"; break;
|
||||
default: assert(! "Invalid DLL id!"); return "Invalid DLL ID";
|
||||
}
|
||||
|
||||
HINSTANCE hDLL;
|
||||
if (dlls[DLL])
|
||||
hDLL = dlls[DLL];
|
||||
else
|
||||
hDLL = dlls[DLL] = LoadLibraryA(name);
|
||||
|
||||
if (! hDLL)
|
||||
{
|
||||
sprintf(err, "LoadLibrary failed (%d)", GetLastError());
|
||||
return err;
|
||||
}
|
||||
|
||||
#define FUNC(ret, name, par) if (NULL == (DLL##name = (ret (*) par) GetProcAddress(hDLL, #name)) ) { sprintf(err, "GetProcAddress on %s failed (%d)", #name, GetLastError()); return err; }
|
||||
#include "freetypedll_funcs.h"
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FreeDLLs()
|
||||
{
|
||||
for (int i=0; i<2; ++i)
|
||||
if (dlls[i])
|
||||
FreeLibrary(dlls[i]);
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
// Returns NULL on success, else an error message
|
||||
char* SelectDLL(int DLL);
|
||||
|
||||
#define FUNC(ret, name, par) extern ret (* DLL##name) par
|
||||
#include "freetypedll_funcs.h"
|
||||
#undef FUNC
|
@ -1,11 +0,0 @@
|
||||
FUNC(FT_Error, FT_Init_FreeType, ( FT_Library *alibrary ));
|
||||
FUNC(FT_Error, FT_Done_FreeType, ( FT_Library Library ));
|
||||
FUNC(FT_Error, FT_Open_Face, ( FT_Library library, const FT_Open_Args* args, FT_Long face_index, FT_Face *aface ));
|
||||
FUNC(FT_Error, FT_Done_Face, ( FT_Face face ));
|
||||
FUNC(FT_Error, FT_Set_Char_Size, ( FT_Face face, FT_F26Dot6 char_width, FT_F26Dot6 char_height, FT_UInt horz_resolution, FT_UInt vert_resolution ));
|
||||
FUNC(FT_UInt, FT_Get_Char_Index, ( FT_Face face, FT_ULong charcode ));
|
||||
FUNC(FT_Long, FT_MulFix, ( FT_Long a, FT_Long b ));
|
||||
FUNC(void, FT_Set_Transform, ( FT_Face face, FT_Matrix* matrix, FT_Vector* delta ));
|
||||
FUNC(FT_Error, FT_Load_Glyph, ( FT_Face face, FT_UInt glyph_index, FT_Int32 load_flags ));
|
||||
FUNC(FT_Error, FT_Render_Glyph, ( FT_GlyphSlot slot, FT_Render_Mode render_mode ));
|
||||
FUNC(FT_Error, FT_Get_Kerning, ( FT_Face face, FT_UInt left_glyph, FT_UInt right_glyph, FT_UInt kern_mode, FT_Vector *akerning ));
|
@ -1,22 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "math.h"
|
||||
|
||||
unsigned char* GenerateImage(int width, int height)
|
||||
{
|
||||
unsigned char* ImageData = new unsigned char[width*height*3];
|
||||
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
// Slightly off black, so you can see the bounding boxes
|
||||
// by playing in some paint program
|
||||
ImageData[(x+y*width)*3+0] = 0;
|
||||
ImageData[(x+y*width)*3+1] = 0;
|
||||
ImageData[(x+y*width)*3+2] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ImageData;
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
unsigned char* GenerateImage(int width, int height);
|
||||
unsigned char* GreyscaleToRGB(int width, int height, unsigned char* grey);
|
@ -1,422 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "packer.h"
|
||||
|
||||
#include "wx/log.h"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
PackedFont::PackedFont(FontRenderer* font, std::set<wchar_t> chars)
|
||||
{
|
||||
TextureData = NULL;
|
||||
TextureWidth = TextureHeight = 0;
|
||||
Font = font;
|
||||
Chars = chars;
|
||||
}
|
||||
|
||||
|
||||
PackedFont::~PackedFont()
|
||||
{
|
||||
delete[] TextureData;
|
||||
}
|
||||
|
||||
|
||||
class GlyphInfo {
|
||||
public:
|
||||
GlyphInfo() { c = 0; w = h = size = -1; }
|
||||
GlyphInfo(wchar_t _c, int _w, int _h) { c=_c; w=_w; h=_h; size=(w*w)+(h*h); }
|
||||
wchar_t c;
|
||||
int w, h;
|
||||
int x, y; // of top-left corner
|
||||
|
||||
bool operator<(GlyphInfo& b) { return size > b.size; } // sort biggest first
|
||||
|
||||
private:
|
||||
int size; // used for sorting
|
||||
};
|
||||
|
||||
typedef std::vector<GlyphInfo> GlyphsInfo;
|
||||
|
||||
struct GlyphCharSort : public std::binary_function<GlyphInfo&, GlyphInfo&, bool> {
|
||||
bool operator()(GlyphInfo& x, GlyphInfo& y) { return x.c < y.c; }
|
||||
};
|
||||
|
||||
int next_power_of_two(int x)
|
||||
{
|
||||
// See something like http://bob.allegronetwork.com/prog/tricks.html for an explanation
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
return x+1;
|
||||
}
|
||||
|
||||
// To avoid a few ugly gotos. Returns true on collision.
|
||||
inline bool TryFittingInternal(const int &x, const int &y, GlyphsInfo& glyphs, const GlyphsInfo::iterator& ThisGlyph)
|
||||
{
|
||||
for (GlyphsInfo::iterator OtherGlyph = glyphs.begin(); OtherGlyph != ThisGlyph; ++OtherGlyph)
|
||||
{
|
||||
// Test for collisions - effectively trying to find a line that
|
||||
// can fit between the two rectangles
|
||||
if (x < OtherGlyph->x+OtherGlyph->w
|
||||
&& x+ThisGlyph->w > OtherGlyph->x
|
||||
&& y < OtherGlyph->y+OtherGlyph->h
|
||||
&& y+ThisGlyph->h > OtherGlyph->y) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool TryFitting(const int packing_precision, const int texture_width, const int texture_height, const bool randomness, GlyphsInfo& glyphs, bool ProgressCallback(float, wxString, void*), void* CallbackData)
|
||||
{
|
||||
// A roughly O(n^3) algorithm, but with lots of attempted
|
||||
// optimisations that do occasionally work.
|
||||
|
||||
int count = 0;
|
||||
|
||||
int ProgressCurrent = 0;
|
||||
int ProgressMax = (int)glyphs.size();
|
||||
|
||||
GlyphInfo* LastGlyph = NULL;
|
||||
for (GlyphsInfo::iterator ThisGlyph = glyphs.begin(); ThisGlyph != glyphs.end(); ++ThisGlyph, ++count)
|
||||
{
|
||||
if (ProgressCallback != NULL)
|
||||
{
|
||||
// Squaring makes the bar increase at a more constant rate
|
||||
float Progress = powf((float)ProgressCurrent++ / (float)ProgressMax, 2.0f);
|
||||
if (ProgressCallback(Progress, wxT("Fitting"), CallbackData))
|
||||
throw "Aborted";
|
||||
}
|
||||
|
||||
// After the first few easy ones, try sticking things in randomly
|
||||
// and see if it turns out adequately.
|
||||
|
||||
if (randomness && count > 32)
|
||||
{
|
||||
/*
|
||||
// except this is quite rubbish, so don't bother
|
||||
|
||||
bool fitted = false;
|
||||
for (int i = 0; i < 16; ++i) // try several times
|
||||
{
|
||||
int x = 1 + rand() % (texture_width-ThisGlyph->w-1);
|
||||
int y = 1 + rand() % (texture_height-ThisGlyph->h-1);
|
||||
for (GlyphsInfo::iterator OtherGlyph = glyphs.begin(); OtherGlyph != ThisGlyph; ++OtherGlyph)
|
||||
if (box_collide(x, y, x+ThisGlyphRef.w, y+ThisGlyphRef.h, OtherGlyph->x, OtherGlyph->y, OtherGlyph->x+OtherGlyph->w, OtherGlyph->y+OtherGlyph->h))
|
||||
goto randomly_collided;
|
||||
|
||||
ThisGlyph->x = x;
|
||||
ThisGlyph->y = y;
|
||||
goto fitted;
|
||||
|
||||
randomly_collided: ;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
bool fitted = false;
|
||||
|
||||
int starty, stepy;
|
||||
|
||||
// Check whether this glyph is no smaller than the previous one
|
||||
if (LastGlyph && LastGlyph->w <= ThisGlyph->w && LastGlyph->h <= ThisGlyph->h)
|
||||
{
|
||||
// If so, carry on the fitting from where the last glyph left off,
|
||||
// because we've already discovered that there's no more
|
||||
// space above.
|
||||
--count;
|
||||
if (count & 1)
|
||||
stepy = -packing_precision;
|
||||
else
|
||||
stepy = packing_precision;
|
||||
starty = LastGlyph->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Alternate between fitting glyphs at the top and bottom
|
||||
// to make things go a bit faster by minimising collisions
|
||||
if (count & 1)
|
||||
starty = texture_height-ThisGlyph->h, stepy = -packing_precision;
|
||||
else
|
||||
starty = 0, stepy = packing_precision;
|
||||
}
|
||||
|
||||
for (int y = starty; y >= 0 && y <= texture_height-ThisGlyph->h; y += stepy)
|
||||
{
|
||||
// and alternate between left and right
|
||||
int startx, stepx;
|
||||
if (count & 2)
|
||||
startx = 0, stepx = packing_precision;
|
||||
else
|
||||
startx = texture_width-ThisGlyph->w, stepx = -packing_precision;
|
||||
|
||||
int x;
|
||||
|
||||
/* If you have a multiple-processor machine and the Intel C++ compiler,
|
||||
// this parallel version might be a little faster. (It's only a few
|
||||
// tens of percents slower on a hyperthreaded computer)
|
||||
|
||||
// [Assuming it works at all, which it probably doesn't because I haven't
|
||||
// tried compiling it recently]
|
||||
|
||||
if (startx == 1)
|
||||
{
|
||||
int max = texture_width-ThisGlyph->w;
|
||||
#pragma omp parallel shared(startx, texture_width, ThisGlyph, stepx, glyphs)
|
||||
{
|
||||
#pragma omp for schedule(static) nowait
|
||||
for (x = startx; x < max; x += stepx)
|
||||
{
|
||||
if (! TryFittingInternal(x, y, glyphs, ThisGlyph))
|
||||
{
|
||||
ThisGlyph->x = x;
|
||||
stepx = 1e9; // Ugly hack so the threads finish at the same time
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#pragma omp parallel shared(startx, texture_width, ThisGlyph, stepx, glyphs)
|
||||
{
|
||||
#pragma omp for schedule(static) nowait
|
||||
for (x = startx; x > 0; x += stepx)
|
||||
{
|
||||
if (! TryFittingInternal(x, y, glyphs, ThisGlyph))
|
||||
{
|
||||
ThisGlyph->x = x;
|
||||
stepx = -1e9;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (stepx == 1e9 || stepx == -1e9)
|
||||
{
|
||||
ThisGlyph->y = y;
|
||||
goto fitted;
|
||||
}
|
||||
*/
|
||||
if (startx == 0)
|
||||
{
|
||||
for (x = startx; x <= texture_width-ThisGlyph->w; x += stepx)
|
||||
{
|
||||
if (! TryFittingInternal(x, y, glyphs, ThisGlyph))
|
||||
{
|
||||
ThisGlyph->x = x;
|
||||
fitted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = startx; x >= 0; x += stepx)
|
||||
{
|
||||
if (! TryFittingInternal(x, y, glyphs, ThisGlyph))
|
||||
{
|
||||
ThisGlyph->x = x;
|
||||
fitted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fitted)
|
||||
{
|
||||
ThisGlyph->y = y;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (!fitted)
|
||||
// Couldn't fit glyph anywhere - give up
|
||||
return false;
|
||||
|
||||
//fitted: ; // for lazy people who just want to goto
|
||||
|
||||
LastGlyph = &*ThisGlyph;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryFittingLots(int& texture_width, int& texture_height, GlyphsInfo& glyphs, bool ProgressCallback(float, wxString, void*), void* CallbackData)
|
||||
{
|
||||
// Try the fairly fast method
|
||||
if (TryFitting(16, texture_width, texture_height, false, glyphs, ProgressCallback, CallbackData))
|
||||
return true;
|
||||
|
||||
// Go a bit more carefully
|
||||
if (TryFitting(8, texture_width, texture_height, false, glyphs, ProgressCallback, CallbackData))
|
||||
return true;
|
||||
|
||||
// Maybe it just needs a little more precision?
|
||||
if (TryFitting(2, texture_width, texture_height, false, glyphs, ProgressCallback, CallbackData))
|
||||
return true;
|
||||
|
||||
// This takes a long time and doesn't usually achieve much, but try it anyway
|
||||
if (TryFitting(1, texture_width, texture_height, false, glyphs, ProgressCallback, CallbackData))
|
||||
return true;
|
||||
|
||||
// Try swapping the dimensions if it's currently rectangular
|
||||
if (texture_width != texture_height)
|
||||
{
|
||||
std::swap(texture_width, texture_height);
|
||||
if (TryFitting(1, texture_width, texture_height, false, glyphs, ProgressCallback, CallbackData))
|
||||
return true;
|
||||
// Didn't work, swap back again
|
||||
std::swap(texture_width, texture_height);
|
||||
}
|
||||
|
||||
// Double the size and try again
|
||||
if (texture_height == texture_width)
|
||||
texture_width *= 2;
|
||||
else
|
||||
texture_height *= 2;
|
||||
|
||||
if (TryFitting(32, texture_width, texture_height, true, glyphs, ProgressCallback, CallbackData))
|
||||
return true;
|
||||
|
||||
// How much space can it need?!
|
||||
if (TryFitting(4, texture_width, texture_height, false, glyphs, ProgressCallback, CallbackData))
|
||||
return true;
|
||||
|
||||
// Give up
|
||||
return false;
|
||||
}
|
||||
|
||||
void PackedFont::Generate(bool ProgressCallback(float, wxString, void*) = NULL, void* CallbackData = NULL)
|
||||
{
|
||||
GlyphsInfo glyphs;
|
||||
|
||||
int total_area = 0;
|
||||
|
||||
std::vector<wchar_t> MissingGlyphs;
|
||||
|
||||
int ProgressCurrent = 0;
|
||||
int ProgressMax = (int)Chars.size();
|
||||
|
||||
std::list<GlyphInfo> SortableGlyphs;
|
||||
|
||||
bool MissingMissingGlyph = false;
|
||||
|
||||
for (std::set<wchar_t>::iterator c = Chars.begin(); c != Chars.end(); ++c)
|
||||
{
|
||||
if (ProgressCallback != NULL)
|
||||
if (ProgressCallback((float)ProgressCurrent++ / (float)ProgressMax, wxT("Measuring"), CallbackData))
|
||||
throw "Aborted";
|
||||
|
||||
int w, h;
|
||||
Font->LoadGlyph(*c);
|
||||
if (Font->Missing)
|
||||
{
|
||||
// Was the missing glyph missing?
|
||||
if (*c == 0xFFFD)
|
||||
{
|
||||
// Just use a question mark. (Surely *every* font has a question mark...)
|
||||
Font->LoadGlyph('?');
|
||||
if (Font->Missing)
|
||||
throw "Can't find either a missing glyph symbol or a question mark!";
|
||||
Font->GetBoundingBox(w, h);
|
||||
SortableGlyphs.push_back( GlyphInfo(0xFFFD, w, h) );
|
||||
total_area += w*h;
|
||||
MissingMissingGlyph = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MissingGlyphs.push_back(*c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Font->GetBoundingBox(w, h);
|
||||
SortableGlyphs.push_back( GlyphInfo(*c, w, h) );
|
||||
total_area += w*h;
|
||||
}
|
||||
}
|
||||
SortableGlyphs.sort();
|
||||
// Convert into a vector for a little more speed
|
||||
for (std::list<GlyphInfo>::iterator i = SortableGlyphs.begin(); i != SortableGlyphs.end(); ++i)
|
||||
{
|
||||
glyphs.push_back(*i);
|
||||
}
|
||||
|
||||
// Calculate minimum size square to hold all glyphs
|
||||
int texture_width, texture_height;
|
||||
texture_width = texture_height = next_power_of_two(int( sqrt((double)total_area) ));
|
||||
|
||||
// See if a smaller rectangle ought to still fit
|
||||
if (texture_width*texture_height > total_area*2)
|
||||
texture_height /= 2;
|
||||
|
||||
if (! TryFittingLots(texture_width, texture_height, glyphs, ProgressCallback, CallbackData))
|
||||
throw "Failed to fit all the glyphs, too many times.";
|
||||
|
||||
TextureData = new unsigned char[texture_width*texture_height*3];
|
||||
memset(TextureData, 0, texture_width*texture_height*3);
|
||||
TextureWidth = texture_width;
|
||||
TextureHeight = texture_height;
|
||||
|
||||
FontDefinition = wxEmptyString;
|
||||
FontDefinition += wxT("100\n"); // version number
|
||||
FontDefinition << TextureWidth << wxT(" ") << TextureHeight << wxT("\n"); // size of texture
|
||||
FontDefinition << (int)glyphs.size() << wxT("\n"); // number of glyphs
|
||||
FontDefinition << Font->GetLineSpacing() << wxT("\n");
|
||||
|
||||
SortableGlyphs.clear();
|
||||
for (GlyphsInfo::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
|
||||
{
|
||||
SortableGlyphs.push_back(*i);
|
||||
}
|
||||
SortableGlyphs.sort(GlyphCharSort());
|
||||
|
||||
ProgressCurrent = 0;
|
||||
ProgressMax = (int)glyphs.size();
|
||||
for (std::list<GlyphInfo>::iterator ThisGlyph = SortableGlyphs.begin(); ThisGlyph != SortableGlyphs.end(); ++ThisGlyph)
|
||||
{
|
||||
if (ProgressCallback != NULL)
|
||||
if (ProgressCallback((float)ProgressCurrent++ / (float)ProgressMax, wxT("Rendering"), CallbackData))
|
||||
throw "Aborted";
|
||||
|
||||
if (MissingMissingGlyph && ThisGlyph->c == 0xFFFD)
|
||||
Font->LoadGlyph('?');
|
||||
else
|
||||
Font->LoadGlyph(ThisGlyph->c);
|
||||
|
||||
Font->RenderGlyph(TextureData, ThisGlyph->x, ThisGlyph->y, texture_width, texture_height, texture_width*3, true);
|
||||
int offset_x, offset_y, advance;
|
||||
Font->GetMetrics(offset_x, offset_y, advance);
|
||||
FontDefinition << (int)ThisGlyph->c
|
||||
<< wxT(" ") << ThisGlyph->x
|
||||
<< wxT(" ") << (TextureHeight - ThisGlyph->y) // because it's stored upside-down
|
||||
<< wxT(" ") << ThisGlyph->w
|
||||
<< wxT(" ") << ThisGlyph->h
|
||||
<< wxT(" ") << offset_x
|
||||
<< wxT(" ") << offset_y
|
||||
<< wxT(" ") << advance
|
||||
<< wxT("\n");
|
||||
}
|
||||
|
||||
if (MissingGlyphs.size())
|
||||
{
|
||||
wxString Error = wxString::Format(wxT("WARNING: %d glyphs were missing: "), MissingGlyphs.size());
|
||||
for (size_t i = 0; i < MissingGlyphs.size(); ++i)
|
||||
{
|
||||
if (i) Error += wxT(", ");
|
||||
if (i == 20)
|
||||
{
|
||||
Error += wxT("...");
|
||||
break;
|
||||
}
|
||||
Error += wxString::Format(wxT("%d"), MissingGlyphs[i]);
|
||||
}
|
||||
wxLogWarning(Error);
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
#include "font.h"
|
||||
|
||||
#include "wx/string.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
class PackedFont
|
||||
{
|
||||
public:
|
||||
PackedFont(FontRenderer* font, std::set<wchar_t> chars);
|
||||
~PackedFont();
|
||||
|
||||
void Generate(bool ProgressCallback(float, wxString, void*), void* CallbackData);
|
||||
|
||||
// Sizes are always a power of two
|
||||
int TextureWidth;
|
||||
int TextureHeight;
|
||||
|
||||
// 24-bit (RGB) but greyscale image
|
||||
unsigned char* TextureData;
|
||||
|
||||
// For the text file describing how to read all the glyphs
|
||||
wxString FontDefinition;
|
||||
|
||||
private:
|
||||
FontRenderer* Font;
|
||||
std::set<wchar_t> Chars;
|
||||
};
|
@ -1,35 +0,0 @@
|
||||
#include "wx/dialog.h"
|
||||
#include "wx/filedlg.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
class FontSelectorDialog : public wxDialog
|
||||
#else
|
||||
class FontSelectorDialog : public wxFileDialog
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
FontSelectorDialog(wxWindow* parent);
|
||||
~FontSelectorDialog();
|
||||
|
||||
wxString FontName;
|
||||
wxString FontFilename;
|
||||
|
||||
#ifdef _WIN32
|
||||
void OnFontSelect(wxCommandEvent& event);
|
||||
void OnOK(wxCommandEvent& event);
|
||||
//#else
|
||||
// void OnInit(wxInitDialogEvent& event);
|
||||
#endif
|
||||
|
||||
static void DefaultFonts(wxString& Name0, wxString& Filename0, wxString& Name1, wxString& Filename1);
|
||||
|
||||
private:
|
||||
|
||||
#ifdef _WIN32
|
||||
wxArrayString FontNames;
|
||||
wxCharBuffer** FontFilenames;
|
||||
#endif
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
@ -1,52 +0,0 @@
|
||||
/************
|
||||
|
||||
This attempt at completely separating the platform-dependent
|
||||
parts failed. Need to think about it more carefully in the
|
||||
future.
|
||||
|
||||
************/
|
||||
|
||||
#include "../../stdafx.h"
|
||||
|
||||
#include "../fontselect.h"
|
||||
|
||||
BEGIN_EVENT_TABLE(FontSelectorDialog, wxFileDialog)
|
||||
// EVT_INIT_DIALOG(FontSelectorDialog::OnInit)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
FontSelectorDialog::FontSelectorDialog(wxWindow* parent)
|
||||
//: wxFileDialog(parent, wxT("Font selector"), wxEmptyString, wxEmptyString, wxOPEN | wxHIDE_READONLY)
|
||||
: wxFileDialog(parent, wxT("Select a font file"), wxEmptyString, wxEmptyString, wxT("TTF files (*.ttf)|*.ttf|All files (*.*)|*.*"), wxOPEN | wxHIDE_READONLY)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
void FontSelectorDialog::OnDestroy(wxInitDialogEvent& WXUNUSED(event))
|
||||
{
|
||||
wxFileDialog Dlg (this, wxT("Select a font file"), wxEmptyString, wxEmptyString, wxT("TTF files (*.ttf)|*.ttf|All files (*.*)|*.*"), wxOPEN | wxHIDE_READONLY);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
FontName = Dlg.GetFilename();
|
||||
FontFilename = Dlg.GetPath();
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
EndModal(wxID_CANCEL);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
FontSelectorDialog::~FontSelectorDialog()
|
||||
{
|
||||
FontName = GetFilename();
|
||||
FontFilename = GetPath();
|
||||
}
|
||||
|
||||
void FontSelectorDialog::DefaultFonts(wxString& Name0, wxString& Filename0, wxString& Name1, wxString& Filename1)
|
||||
{
|
||||
Name0 = wxT("Please select");
|
||||
Filename0 = wxT("");
|
||||
Name1 = wxT("Please select");
|
||||
Filename1 = wxT("");
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "../fontselect.h"
|
||||
|
||||
#include "wx/sizer.h"
|
||||
#include "wx/listbox.h"
|
||||
#include "wx/stattext.h"
|
||||
#include "wx/button.h"
|
||||
#include "wx/regex.h"
|
||||
|
||||
#include "wx/msw/registry.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ID_FontList = wxID_HIGHEST+1,
|
||||
ID_FontPreview
|
||||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(FontSelectorDialog, wxDialog)
|
||||
EVT_LISTBOX(ID_FontList, FontSelectorDialog::OnFontSelect)
|
||||
EVT_BUTTON(wxID_OK, FontSelectorDialog::OnOK)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
FontSelectorDialog::FontSelectorDialog(wxWindow* parent)
|
||||
: wxDialog(parent, -1, wxString(wxT("Font selector")), wxDefaultPosition, wxSize(400, 200), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
|
||||
{
|
||||
wxBoxSizer* MainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxString PreviewString;
|
||||
PreviewString += wxT("Aa");
|
||||
PreviewString += (wchar_t)0x0105; // LATIN SMALL LETTER A WITH OGONEK
|
||||
PreviewString += wxT("\nBb");
|
||||
PreviewString += (wchar_t)0x00DF; // LATIN SMALL LETTER SHARP S
|
||||
PreviewString += wxT("\nCc");
|
||||
PreviewString += (wchar_t)0x00E7; // LATIN SMALL LETTER C WITH CEDILLA
|
||||
PreviewString += (wchar_t)0x033F; // COMBINING DOUBLE OVERLINE
|
||||
PreviewString += wxT("\n");
|
||||
PreviewString += (wchar_t)0xFB4E; // HEBREW LETTER PE WITH RAFE
|
||||
PreviewString += (wchar_t)0xFB6B; // ARABIC LETTER VEH FINAL FORM
|
||||
PreviewString += (wchar_t)0xF915; // CJK COMPATIBILITY IDEOGRAPH-F915
|
||||
PreviewString += (wchar_t)0x3342; // SQUARE HOON
|
||||
|
||||
wxBoxSizer* TopSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxListBox* FontListBox = new wxListBox(this, ID_FontList, wxDefaultPosition, wxSize(200, 100));
|
||||
TopSizer->Add(FontListBox, 0, wxGROW);
|
||||
TopSizer->Add(new wxStaticText(this, ID_FontPreview, PreviewString), 1, wxGROW);
|
||||
MainSizer->Add(TopSizer, 1);
|
||||
|
||||
wxBoxSizer* ButtonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
ButtonSizer->Add(new wxButton(this, wxID_OK, wxT("OK")), 0, wxALL, 10);
|
||||
ButtonSizer->Add(new wxButton(this, wxID_CANCEL, wxT("Cancel")), 0, wxALL, 10);
|
||||
MainSizer->Add(ButtonSizer, 0, wxALIGN_CENTER);
|
||||
|
||||
SetSizer(MainSizer);
|
||||
|
||||
// Get a list of all the fonts installed on the system
|
||||
|
||||
wxRegKey FontKey (wxT("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts"));
|
||||
|
||||
// Get the list of keys (= font names)
|
||||
wxString ValueName;
|
||||
long ValueIndex;
|
||||
FontKey.GetFirstValue(ValueName, ValueIndex);
|
||||
do {
|
||||
if (! ValueName.IsEmpty())
|
||||
FontNames.Add(ValueName);
|
||||
} while (FontKey.GetNextValue(ValueName, ValueIndex));
|
||||
|
||||
FontNames.Sort();
|
||||
|
||||
// Get all the filenames, and store in the listbox's client data
|
||||
|
||||
FontFilenames = new wxCharBuffer*[FontNames.Count()];
|
||||
|
||||
for (size_t i = 0; i < FontNames.Count(); ++i)
|
||||
{
|
||||
wxString t;
|
||||
FontKey.QueryValue(FontNames[i], t);
|
||||
wxCharBuffer* b = new wxCharBuffer(t.mb_str());
|
||||
FontFilenames[i] = b;
|
||||
}
|
||||
|
||||
FontListBox->Set(FontNames, (void**)FontFilenames);
|
||||
}
|
||||
|
||||
FontSelectorDialog::~FontSelectorDialog()
|
||||
{
|
||||
for (size_t i = 0; i < FontNames.Count(); ++i)
|
||||
delete FontFilenames[i];
|
||||
delete[] FontFilenames;
|
||||
}
|
||||
|
||||
|
||||
void FontSelectorDialog::OnOK(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
// Find where the fonts are on the disk
|
||||
wxRegKey FontPathKey (wxT("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"));
|
||||
wxString FontPath;
|
||||
FontPathKey.QueryValue(wxT("Fonts"), FontPath);
|
||||
|
||||
wxListBox* FontList = (wxListBox*)wxWindow::FindWindowById(ID_FontList);
|
||||
|
||||
int Selection = FontList->GetSelection();
|
||||
FontFilename = FontPath + wxT("\\");
|
||||
FontFilename += wxString::FromAscii( ((wxCharBuffer*) FontList->GetClientData(Selection))->data() );
|
||||
|
||||
FontName = FontList->GetStringSelection();
|
||||
|
||||
EndModal(wxID_OK);
|
||||
}
|
||||
|
||||
|
||||
void FontSelectorDialog::OnFontSelect(wxCommandEvent& event)
|
||||
{
|
||||
wxString FontName = event.GetString();
|
||||
|
||||
// Translate "Arial (TrueType)" into "Arial", etc
|
||||
wxRegEx ThingyRemove;
|
||||
ThingyRemove.Compile(wxT(" \\(.+\\)$"));
|
||||
ThingyRemove.Replace(&FontName, wxT(""));
|
||||
|
||||
// Set the preview box to use that font
|
||||
wxFont PreviewFont (18, wxDEFAULT, wxNORMAL, wxNORMAL, false, FontName, wxFONTENCODING_SYSTEM);
|
||||
wxStaticText* PreviewText = (wxStaticText*)wxWindow::FindWindowById(ID_FontPreview);
|
||||
PreviewText->SetFont(PreviewFont);
|
||||
}
|
||||
|
||||
void FontSelectorDialog::DefaultFonts(wxString& Name0, wxString& Filename0, wxString& Name1, wxString& Filename1)
|
||||
{
|
||||
// Find where the fonts are on the disk
|
||||
wxRegKey FontPathKey (wxT("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"));
|
||||
wxString FontPath;
|
||||
FontPathKey.QueryValue(wxT("Fonts"), FontPath);
|
||||
|
||||
Name0 = wxT("Verdana (TrueType)");
|
||||
Filename0 = FontPath + wxT("\\verdana.ttf");
|
||||
Name1 = wxT("Arial Unicode MS (TrueType)");
|
||||
Filename1 = FontPath + wxT("\\arialuni.ttf");
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Font Builder</title>
|
||||
</head>
|
||||
<body bgcolor="#fff4e6" text="black" style="font-family:sans-serif">
|
||||
|
||||
<h2>Font Builder</h2>
|
||||
|
||||
<h3>Usage</h3>
|
||||
|
||||
<ol>
|
||||
<li>Choose a <i>primary font</i>, which will be used for as much as
|
||||
it can be used for.
|
||||
<li>Optionally, choose a different <i>secondary font</i> which is used
|
||||
when the primary font is missing certain characters - for example,
|
||||
Trebuchet doesn't include any Greek/Cyrillic/Hebrew characters, so
|
||||
these will be taken from Arial Unicode MS (by default) instead.
|
||||
<li>Use the <i>Preview font</i> button to see what the font looks like
|
||||
by rendering the contents of the textbox. Adjust the font settings
|
||||
until perfection is attained.
|
||||
<li>Choose a desired <i>character list</i> - a text file containing
|
||||
all the characters that must be in the final font. The standard files
|
||||
are <tt>latin.txt</tt> (containing ASCII plus some accented characters,
|
||||
mainly useful for non-localised text) and <tt>standard.txt</tt>
|
||||
(containing Latin, Greek, Cyrillic and Hebrew characters, for text that
|
||||
could be in any language).
|
||||
<li>Click <i>Generate texture</i>, and select a name for the <tt>.fnt</tt>
|
||||
file. A <tt>.tga</tt> texture will also be generated, in the same directory
|
||||
with the same name. Depending on several random coincidences, the texture
|
||||
generation might be very fast or might take quite a while. When it finishes, the
|
||||
excitingly patterned texture will be displayed.
|
||||
<li>Save your settings through the <i>File</i> menu so that you can
|
||||
easily recreate the font later.
|
||||
</ol>
|
||||
|
||||
<h3>Unicode fonts</h3>
|
||||
|
||||
<p>
|
||||
|
||||
The font builder is intended to be used with Unicode characters.
|
||||
Unfortunately, most fonts aren't. The font builder tries
|
||||
to use <i>Arial Unicode MS</i> by default: this seems to
|
||||
be installed by some versions of Microsoft Office, or can
|
||||
be downloaded from locations such as
|
||||
<a href="http://wildfiregames.com/~code/libraries/fonts/arialuni.exe">this</a> (12MB
|
||||
self-extracting 7-Zip). It's probably worth getting, since it
|
||||
includes almost every Unicode glyph that you could wish for.
|
||||
|
||||
</p><p>
|
||||
|
||||
Another potentially useful Unicode font is Bitstream Cyberbit
|
||||
(available from <a href="ftp://ftp.netscape.com/pub/communicator/extras/fonts/windows/Cyberbit.ZIP">Netscape's FTP server</a>,
|
||||
6MB).
|
||||
|
||||
</p><p>
|
||||
|
||||
All fonts must be installed into Windows before you can use
|
||||
them in the font builder.
|
||||
|
||||
</p>
|
||||
|
||||
<h3>Font settings</h3>
|
||||
|
||||
<ul>
|
||||
<li><b>Size</b> - size of the font in arbitrary units.
|
||||
<li><b>Boldness</b> - if you don't have a proper bold variation of the
|
||||
font, the boldness setting fakes it by drawing
|
||||
the character several times.
|
||||
<li><b>Italicness</b> - if you don't have a proper italic variaton,
|
||||
the italicness setting slants it in 5-degree increments. Negative
|
||||
values slant the other way.
|
||||
<li><b>Tracking</b> - extra spacing in pixels added between every
|
||||
non-zero-width glyph.
|
||||
<li><b>Leading</b> - extra spacing in pixels between lines of text.
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,25 +0,0 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by FontBuilder.rc
|
||||
//
|
||||
#define IDC_MYICON 2
|
||||
#define IDD_FONTBUILDER_DIALOG 102
|
||||
#define IDS_APP_TITLE 103
|
||||
#define IDM_ABOUT 104
|
||||
#define IDM_EXIT 105
|
||||
#define IDI_FONTBUILDER 107
|
||||
#define IDC_FONTBUILDER 109
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDC_STATIC -1
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||
#define _APS_NEXT_SYMED_VALUE 110
|
||||
#endif
|
||||
#endif
|
@ -1,5 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// FontBuilder.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
@ -1,71 +0,0 @@
|
||||
// Precompiled headers
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef NDEBUG
|
||||
# define HAVE_PCH
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PCH
|
||||
|
||||
// Exclude rarely-used stuff from Windows headers
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
// Disable some complaints in wx headers
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4267 4311)
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
// Disable some of the excessively pedantic icl /W4 warnings (remarks)
|
||||
#pragma warning (disable: 193 373 444 981 383 1125 1418)
|
||||
#endif
|
||||
|
||||
// Include relevant wx headers
|
||||
#include "wx/wxprec.h"
|
||||
#include "wx/wx.h"
|
||||
#include "wx/menu.h"
|
||||
#include "wx/filedlg.h"
|
||||
#include "wx/button.h"
|
||||
#include "wx/image.h"
|
||||
#include "wx/spinctrl.h"
|
||||
#include "wx/regex.h"
|
||||
#include "wx/ffile.h"
|
||||
#include "wx/utils.h"
|
||||
#include "wx/progdlg.h"
|
||||
#include "wx/wxexpr.h"
|
||||
#include "wx/docview.h"
|
||||
#include "wx/config.h"
|
||||
#include "wx/filename.h"
|
||||
#include "wx/config.h"
|
||||
#include "wx/log.h"
|
||||
|
||||
#pragma warning (pop)
|
||||
|
||||
#include <set>
|
||||
#include <list>
|
||||
|
||||
|
||||
//// Things other than precompiled headers which
|
||||
// are just useful to include everywhere:
|
||||
|
||||
// For nicer memory-leak detection
|
||||
#ifdef _DEBUG
|
||||
#include <crtdbg.h>
|
||||
#define new new(_NORMAL_BLOCK ,__FILE__, __LINE__)
|
||||
#endif
|
||||
|
||||
// Don't care about copy constructors / assignment operators
|
||||
#pragma warning (disable: 4511 4512)
|
||||
|
||||
#endif // HAVE_PCH
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
// Disable some of the excessively pedantic warnings again
|
||||
#pragma warning (disable: 193 373 444 981 383 1418)
|
||||
#endif
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# define swprintf _snwprintf
|
||||
#endif
|
@ -1,43 +0,0 @@
|
||||
* Don't store full font path when it's unnecessary
|
||||
|
||||
* Command line batch conversion
|
||||
|
||||
* Fix bugs
|
||||
|
||||
* >2 fonts (standard+unavailable+Hebrew, maybe)
|
||||
|
||||
* Optimise storage of duplicated bitmaps (e.g. e and e-with-some-accent,
|
||||
comma and semicolon, anything and fullwidth versions, etc)
|
||||
|
||||
* Optional antialiasing
|
||||
|
||||
* Right-to-left text
|
||||
|
||||
* Optional outlining (text with e.g. yellow fill and black outline
|
||||
is made by drawing the black outline font and then the yellow
|
||||
normal font)
|
||||
|
||||
* Work out when I should say 'character', when 'code point', and when 'glyph'
|
||||
|
||||
* Kerning
|
||||
|
||||
|
||||
Unicodeness:
|
||||
|
||||
Many Latin-1 Supplement characters can be made from Basic Latin plus Combining Diacritical Marks. Storing the decomposed forms saves space in the texture, at the expense of longer and slightly more complex strings elsewhere.
|
||||
|
||||
Assume all displayed text comes out of the i18n system. (When displaying fixed strings, always use translate("$string")<<string)
|
||||
Standard phrases/words can be decomposed during the conversion process. Names / untranslated phrases need to be decomposed (and cached) by the [C++] i18n system.
|
||||
|
||||
Advantages:
|
||||
* Fonts can have smaller textures. 402 vs 695 glyphs, >25% less pixels required.
|
||||
* Works easily when fonts have only standard (accentless) Latin characters, though not necessarily well (Need to investigate that).
|
||||
Disadvantages:
|
||||
* Strings require a bit more memory
|
||||
* Processing necessary when displaying strings (=> [small] decomposition database in the C++ code)
|
||||
|
||||
But it looks really, really ugly.
|
||||
|
||||
|
||||
Boldness:
|
||||
Use SetTransform, 26.6, move fractional pixels
|
@ -1 +0,0 @@
|
||||
const wxString version = L"v1.11";
|
@ -1,40 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "wx/app.h"
|
||||
|
||||
#include "wxframe.h"
|
||||
#include "wxconfig.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
class FontBuilderApp : public wxApp
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
virtual int OnExit();
|
||||
};
|
||||
|
||||
|
||||
IMPLEMENT_APP(FontBuilderApp)
|
||||
|
||||
bool FontBuilderApp::OnInit()
|
||||
{
|
||||
ConfigInit();
|
||||
|
||||
MainFrame *frame = new MainFrame(wxString::Format(wxT("Font Builder %s"), (const wchar_t*)version), wxDefaultPosition, wxSize(640,480));
|
||||
frame->SetIcon(wxIcon(wxT("IDI_ICON1")));
|
||||
frame->Show(true);
|
||||
SetTopWindow(frame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
extern void FreeDLLs();
|
||||
|
||||
int FontBuilderApp::OnExit()
|
||||
{
|
||||
ConfigDestroy();
|
||||
FreeDLLs();
|
||||
return 0;
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "wx/config.h"
|
||||
#include "wx/filename.h"
|
||||
|
||||
#include "wxconfig.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
const wxString PathSep = wxT("\\");
|
||||
#else
|
||||
const wxString PathSep = wxT("/");
|
||||
#endif
|
||||
|
||||
void ConfigInit()
|
||||
{
|
||||
wxConfig* cfg = new wxConfig(wxT("WFG Font Builder"));
|
||||
wxConfig::Set(cfg);
|
||||
|
||||
// Default paths, for the first time program is run:
|
||||
|
||||
// Get "x:\wherever\etc\binaries\"
|
||||
wxFileName cwd = wxFileName::GetCwd()+PathSep;
|
||||
cwd.RemoveDir((int)cwd.GetDirCount()-1);
|
||||
|
||||
#define DIR(a) dir.AppendDir(wxT(a))
|
||||
|
||||
cwd.AppendDir(wxT("data"));
|
||||
if (!ConfigGet(wxT("FSF path")))
|
||||
{
|
||||
wxFileName dir = cwd;
|
||||
DIR("tools"); DIR("fontbuilder"); DIR("settings");
|
||||
ConfigSet(wxT("FSF path"), dir.GetPath(wxPATH_GET_VOLUME));
|
||||
}
|
||||
|
||||
if (!ConfigGet(wxT("FNT path")))
|
||||
{
|
||||
wxFileName dir = cwd;
|
||||
DIR("mods"); DIR("official"); DIR("fonts");
|
||||
ConfigSet(wxT("FNT path"), dir.GetPath(wxPATH_GET_VOLUME));
|
||||
}
|
||||
|
||||
if (!ConfigGet(wxT("Charset path")))
|
||||
{
|
||||
wxFileName dir = cwd;
|
||||
DIR("tools"); DIR("fontbuilder"); DIR("charsets");
|
||||
ConfigSet(wxT("Charset path"), dir.GetPath(wxPATH_GET_VOLUME));
|
||||
}
|
||||
}
|
||||
|
||||
wxString ConfigGet(wxString key)
|
||||
{
|
||||
wxConfig* cfg = (wxConfig*) wxConfig::Get();
|
||||
wxString ret;
|
||||
cfg->Read(key, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ConfigSet(wxString key, wxString value)
|
||||
{
|
||||
wxConfig* cfg = (wxConfig*) wxConfig::Get();
|
||||
cfg->Write(key, value);
|
||||
}
|
||||
|
||||
void ConfigDestroy()
|
||||
{
|
||||
delete wxConfig::Get();
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
#include "wx/string.h"
|
||||
|
||||
void ConfigInit();
|
||||
wxString ConfigGet(wxString key);
|
||||
void ConfigSet(wxString key, wxString value);
|
||||
void ConfigDestroy();
|
@ -1,644 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "wx/menu.h"
|
||||
#include "wx/config.h"
|
||||
#include "wx/sizer.h"
|
||||
#include "wx/stattext.h"
|
||||
#include "wx/button.h"
|
||||
#include "wx/textctrl.h"
|
||||
#include "wx/filedlg.h"
|
||||
#include "wx/msgdlg.h"
|
||||
#include "wx/image.h"
|
||||
#include "wx/wxexpr.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/filename.h"
|
||||
#include "wx/progdlg.h"
|
||||
#include "wx/dcbuffer.h"
|
||||
#include "wx/checkbox.h"
|
||||
|
||||
#include "wxframe.h"
|
||||
#include "wxconfig.h"
|
||||
#include "wxspinner.h"
|
||||
|
||||
#include "platform/fontselect.h"
|
||||
|
||||
#include "imagemanip.h"
|
||||
#include "font.h"
|
||||
#include "packer.h"
|
||||
#include "filemanip.h"
|
||||
|
||||
#include "version.h"
|
||||
|
||||
bool Changes = false;
|
||||
|
||||
enum
|
||||
{
|
||||
ID_Quit = wxID_HIGHEST+1,
|
||||
ID_About,
|
||||
ID_New,
|
||||
ID_Save,
|
||||
ID_Open,
|
||||
ID_Recent,
|
||||
|
||||
ID_GeneratePreview,
|
||||
ID_GenerateTexture,
|
||||
|
||||
ID_FontSelect0,
|
||||
ID_FontSelect1,
|
||||
ID_CharSelect,
|
||||
|
||||
// For accessing values:
|
||||
ID_PreviewText,
|
||||
ID_Style_Size,
|
||||
ID_Style_Boldness,
|
||||
ID_Style_Italicness,
|
||||
ID_Style_Tracking,
|
||||
ID_Style_Leading,
|
||||
ID_Style_Hinting
|
||||
};
|
||||
|
||||
BEGIN_EVENT_TABLE(MainFrame, wxFrame)
|
||||
EVT_MENU(ID_Quit, MainFrame::OnQuit)
|
||||
EVT_MENU(ID_About, MainFrame::OnAbout)
|
||||
EVT_MENU(ID_Save, MainFrame::OnSave)
|
||||
EVT_MENU(ID_Open, MainFrame::OnOpen)
|
||||
EVT_MENU_RANGE(wxID_FILE1, wxID_FILE9, MainFrame::OnMRUFile)
|
||||
|
||||
EVT_BUTTON(ID_FontSelect0, MainFrame::OnFontSelect0)
|
||||
EVT_BUTTON(ID_FontSelect1, MainFrame::OnFontSelect1)
|
||||
EVT_BUTTON(ID_CharSelect, MainFrame::OnCharSelect)
|
||||
|
||||
EVT_BUTTON(ID_GeneratePreview, MainFrame::OnGeneratePreview)
|
||||
EVT_BUTTON(ID_GenerateTexture, MainFrame::OnGenerateTexture)
|
||||
|
||||
EVT_CLOSE(MainFrame::OnClose)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE(BitmapPanel, wxPanel)
|
||||
EVT_PAINT(BitmapPanel::OnPaint)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
|
||||
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
|
||||
{
|
||||
RecentFiles = new wxFileHistory(5);
|
||||
|
||||
wxMenu* menuFile = new wxMenu;
|
||||
|
||||
//menuFile->Append(ID_New, wxT("&New"));
|
||||
menuFile->Append(ID_Open, wxT("&Open..."));
|
||||
menuFile->Append(ID_Save, wxT("&Save..."));
|
||||
menuFile->AppendSeparator();
|
||||
wxMenu* menuRecent = new wxMenu;
|
||||
menuFile->Append(ID_Recent, wxT("&Recent files"), menuRecent);
|
||||
menuFile->AppendSeparator();
|
||||
menuFile->Append(ID_About, wxT("&About"));
|
||||
menuFile->AppendSeparator();
|
||||
menuFile->Append(ID_Quit, wxT("E&xit"));
|
||||
|
||||
RecentFiles->UseMenu(menuRecent);
|
||||
|
||||
wxConfig* config = (wxConfig*)wxConfig::Get();
|
||||
RecentFiles->Load(*config);
|
||||
|
||||
wxMenuBar* menuBar = new wxMenuBar;
|
||||
menuBar->Append(menuFile, wxT("&File"));
|
||||
|
||||
SetMenuBar(menuBar);
|
||||
|
||||
CreateStatusBar();
|
||||
|
||||
// For textboxes that need to display Unicode text:
|
||||
wxFont ArialUnicodeFont (12, wxDEFAULT, wxNORMAL, wxNORMAL, false, wxT("Arial Unicode MS"), wxFONTENCODING_SYSTEM);
|
||||
|
||||
// Main panel that fills the whole window
|
||||
wxPanel* Panel = new wxPanel(this);
|
||||
|
||||
// Split the window into three main rows - controls, preview text, graphic
|
||||
wxBoxSizer* OutlineSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
// Split the controls part into three main columns: font, styles, actions
|
||||
wxBoxSizer* ControlSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
// Get some default values
|
||||
FontSelectorDialog::DefaultFonts(FontName0, FontFilename0, FontName1, FontFilename1);
|
||||
CharFilename = wxT("<ascii>");
|
||||
CharName = wxT("Basic ASCII");
|
||||
|
||||
wxFlexGridSizer* FontSizer = new wxFlexGridSizer(2);
|
||||
FontSizer->AddGrowableCol(0);
|
||||
|
||||
FontSizer->Add(new wxStaticText(Panel, -1, wxT("Primary font:")), 0, wxALIGN_RIGHT | wxALL, 2);
|
||||
FontSizer->Add(new wxButton(Panel, ID_FontSelect0, FontName0), 0, wxGROW | wxALL, 2);
|
||||
|
||||
FontSizer->Add(new wxStaticText(Panel, -1, wxT("Secondary font:")), 0, wxALIGN_RIGHT | wxALL, 2);
|
||||
FontSizer->Add(new wxButton(Panel, ID_FontSelect1, FontName1), 0, wxGROW | wxALL, 2);
|
||||
|
||||
FontSizer->Add(new wxStaticText(Panel, -1, wxT("Character list:")), 0, wxALIGN_RIGHT | wxALL, 2);
|
||||
FontSizer->Add(new wxButton(Panel, ID_CharSelect, CharName), 0, wxGROW | wxALL, 2);
|
||||
|
||||
ControlSizer->Add(FontSizer, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_HORIZONTAL | wxALIGN_TOP, 8);
|
||||
|
||||
wxFlexGridSizer* StyleSizer = new wxFlexGridSizer(2);
|
||||
StyleSizer->AddGrowableCol(0);
|
||||
|
||||
StyleSizer->Add(new wxStaticText(Panel, -1, wxT("Size:")), 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, 2);
|
||||
StyleSizer->Add(new StyleSpinCtrl(Panel, ID_Style_Size, 1, 1024, 18), 0, wxGROW | wxLEFT | wxRIGHT, 2);
|
||||
|
||||
StyleSizer->Add(new wxStaticText(Panel, -1, wxT("Boldness:")), 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, 2);
|
||||
StyleSizer->Add(new StyleSpinCtrl(Panel, ID_Style_Boldness, 0, 16, 0), 0, wxGROW | wxLEFT | wxRIGHT, 2);
|
||||
|
||||
StyleSizer->Add(new wxStaticText(Panel, -1, wxT("Italicness:")), 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, 2);
|
||||
StyleSizer->Add(new StyleSpinCtrl(Panel, ID_Style_Italicness, -16, 16, 0), 0, wxGROW | wxLEFT | wxRIGHT, 2);
|
||||
|
||||
StyleSizer->Add(new wxStaticText(Panel, -1, wxT("Tracking:")), 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, 2);
|
||||
StyleSizer->Add(new StyleSpinCtrl(Panel, ID_Style_Tracking, -256, 256, 0), 0, wxGROW | wxLEFT | wxRIGHT, 2);
|
||||
|
||||
StyleSizer->Add(new wxStaticText(Panel, -1, wxT("Leading:")), 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, 2);
|
||||
StyleSizer->Add(new StyleSpinCtrl(Panel, ID_Style_Leading, -256, 256, 0), 0, wxGROW | wxLEFT | wxRIGHT, 2);
|
||||
|
||||
StyleSizer->Add(new wxStaticText(Panel, -1, wxT("Disable hinting:")), 0, wxALIGN_RIGHT | wxLEFT | wxRIGHT, 2);
|
||||
StyleSizer->Add(new wxCheckBox(Panel, ID_Style_Hinting, wxT("")), 0, wxGROW | wxLEFT | wxRIGHT, 2);
|
||||
|
||||
ControlSizer->Add(StyleSizer, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER, 8);
|
||||
|
||||
wxBoxSizer* GenerateSizer = new wxBoxSizer(wxVERTICAL);
|
||||
GenerateSizer->Add(new wxButton(Panel, ID_GeneratePreview, wxT("Preview font")), 1, wxGROW | wxALL | wxALIGN_CENTER, 4);
|
||||
GenerateSizer->Add(new wxButton(Panel, ID_GenerateTexture, wxT("Generate texture")), 1, wxGROW | wxALL | wxALIGN_CENTER, 4);
|
||||
ControlSizer->Add(GenerateSizer, 0, wxLEFT | wxRIGHT | wxALIGN_CENTER_HORIZONTAL | wxALIGN_TOP, 8);
|
||||
|
||||
OutlineSizer->Add(ControlSizer);
|
||||
|
||||
OutlineSizer->Add(new wxStaticText(Panel, -1, wxT("Text to display in preview:")), 0, wxALL, 2);
|
||||
|
||||
// Create a textbox containing "abcABCfunnysymbols"
|
||||
wxString Font_string = wxT("abcABC"); Font_string += wchar_t(225); Font_string += wchar_t(223); Font_string += wchar_t(231); Font_string += wchar_t(779);Font_string += wchar_t(9812);
|
||||
wxTextCtrl* PreviewTextBox = new wxTextCtrl(Panel, ID_PreviewText, Font_string, wxDefaultPosition, wxSize(300, 80), wxTE_MULTILINE);
|
||||
PreviewTextBox->SetFont(ArialUnicodeFont);
|
||||
|
||||
OutlineSizer->Add(PreviewTextBox, 0, wxGROW | wxLEFT | wxRIGHT, 4);
|
||||
|
||||
PreviewPanel = new BitmapPanel(Panel);
|
||||
OutlineSizer->Add(PreviewPanel, 1, wxGROW);
|
||||
|
||||
Panel->SetSizer(OutlineSizer);
|
||||
|
||||
PreviewImageData = NULL;
|
||||
PreviewImage = NULL;
|
||||
PreviewWidth = 512;
|
||||
PreviewHeight = 256;
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
Close(false);
|
||||
}
|
||||
|
||||
void MainFrame::OnClose(wxCloseEvent& event)
|
||||
{
|
||||
if (Changes)
|
||||
{
|
||||
wxMessageDialog dlg (this, wxT("The font settings have been altered.\n\nDo you want to save the changes?"), wxT("Font Builder"), wxYES_NO|wxCANCEL | wxICON_QUESTION);
|
||||
int ret = dlg.ShowModal();
|
||||
if (ret == wxID_CANCEL)
|
||||
{
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
else if (ret == wxID_YES)
|
||||
{
|
||||
if (! SaveDialog())
|
||||
{
|
||||
event.Veto();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wxConfig* config = (wxConfig*)wxConfig::Get();
|
||||
RecentFiles->Save(*config);
|
||||
delete RecentFiles;
|
||||
|
||||
delete PreviewImage;
|
||||
delete[] PreviewImageData;
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::LoadSettings(wxString& filename)
|
||||
{
|
||||
wxExprDatabase db;
|
||||
|
||||
db.Read(filename);
|
||||
|
||||
wxTextCtrl* PreviewTextCtrl = (wxTextCtrl*)wxWindow::FindWindowById(ID_PreviewText);
|
||||
StyleSpinCtrl* BoldnessCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Boldness);
|
||||
StyleSpinCtrl* ItalicnessCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Italicness);
|
||||
StyleSpinCtrl* SizeCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Size);
|
||||
StyleSpinCtrl* TrackingCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Tracking);
|
||||
StyleSpinCtrl* LeadingCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Leading);
|
||||
wxCheckBox* HintingCtrl = (wxCheckBox*)wxWindow::FindWindowById(ID_Style_Hinting);
|
||||
wxButton* FontSelect0 = (wxButton*)wxWindow::FindWindowById(ID_FontSelect0);
|
||||
wxButton* FontSelect1 = (wxButton*)wxWindow::FindWindowById(ID_FontSelect1);
|
||||
wxButton* CharSelect = (wxButton*)wxWindow::FindWindowById(ID_CharSelect);
|
||||
|
||||
db.BeginFind();
|
||||
|
||||
wxExpr *Settings = db.FindClauseByFunctor(wxT("Settings"));
|
||||
Settings->GetAttributeValue(wxT("FontName0"), FontName0);
|
||||
Settings->GetAttributeValue(wxT("FontName1"), FontName1);
|
||||
Settings->GetAttributeValue(wxT("FontFilename0"), FontFilename0);
|
||||
Settings->GetAttributeValue(wxT("FontFilename1"), FontFilename1);
|
||||
FontSelect0->SetLabel(FontName0);
|
||||
FontSelect1->SetLabel(FontName1);
|
||||
|
||||
Settings->GetAttributeValue(wxT("CharName"), CharName);
|
||||
Settings->GetAttributeValue(wxT("CharFilename"), CharFilename);
|
||||
CharSelect->SetLabel(CharName);
|
||||
|
||||
int t;
|
||||
Settings->GetAttributeValue(wxT("Boldness"), t); BoldnessCtrl->SetValue(t);
|
||||
Settings->GetAttributeValue(wxT("Italicness"), t); ItalicnessCtrl->SetValue(t);
|
||||
Settings->GetAttributeValue(wxT("Size"), t); SizeCtrl->SetValue(t);
|
||||
Settings->GetAttributeValue(wxT("Tracking"), t); TrackingCtrl->SetValue(t);
|
||||
Settings->GetAttributeValue(wxT("Leading"), t); LeadingCtrl->SetValue(t);
|
||||
Settings->GetAttributeValue(wxT("Hinting"), t); HintingCtrl->SetValue(t ? true : false);
|
||||
|
||||
|
||||
// Convert back to UTF16 from hex, because wxExpr doesn't like non-ASCII
|
||||
|
||||
wxString PreviewTextHex;
|
||||
Settings->GetAttributeValue(wxT("PreviewText"), PreviewTextHex);
|
||||
|
||||
wxString PreviewText;
|
||||
for (size_t i=0; i<PreviewTextHex.Length(); i += 4)
|
||||
{
|
||||
wchar_t b[5];
|
||||
memcpy(b, &PreviewTextHex[i], sizeof(wchar_t)*4);
|
||||
b[4] = 0;
|
||||
PreviewText += (wxChar)wcstoul(b, NULL, 16);
|
||||
}
|
||||
PreviewTextCtrl->SetValue(PreviewText);
|
||||
|
||||
|
||||
Changes = false;
|
||||
}
|
||||
|
||||
void MainFrame::SaveSettings(wxString& filename)
|
||||
{
|
||||
wxExprDatabase db;
|
||||
|
||||
wxTextCtrl* PreviewTextCtrl = (wxTextCtrl*)wxWindow::FindWindowById(ID_PreviewText);
|
||||
StyleSpinCtrl* BoldnessCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Boldness);
|
||||
StyleSpinCtrl* ItalicnessCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Italicness);
|
||||
StyleSpinCtrl* SizeCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Size);
|
||||
StyleSpinCtrl* TrackingCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Tracking);
|
||||
StyleSpinCtrl* LeadingCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Leading);
|
||||
wxCheckBox* HintingCtrl = (wxCheckBox*)wxWindow::FindWindowById(ID_Style_Hinting);
|
||||
|
||||
wxExpr *Settings = new wxExpr(wxT("Settings"));
|
||||
Settings->AddAttributeValueString(wxT("FontName0"), FontName0);
|
||||
Settings->AddAttributeValueString(wxT("FontName1"), FontName1);
|
||||
Settings->AddAttributeValueString(wxT("FontFilename0"), FontFilename0);
|
||||
Settings->AddAttributeValueString(wxT("FontFilename1"), FontFilename1);
|
||||
Settings->AddAttributeValueString(wxT("CharName"), CharName);
|
||||
Settings->AddAttributeValueString(wxT("CharFilename"), CharFilename);
|
||||
Settings->AddAttributeValue(wxT("Boldness"), (long)BoldnessCtrl->GetValidValue());
|
||||
Settings->AddAttributeValue(wxT("Italicness"), (long)ItalicnessCtrl->GetValidValue());
|
||||
Settings->AddAttributeValue(wxT("Size"), (long)SizeCtrl->GetValidValue());
|
||||
Settings->AddAttributeValue(wxT("Tracking"), (long)TrackingCtrl->GetValidValue());
|
||||
Settings->AddAttributeValue(wxT("Leading"), (long)LeadingCtrl->GetValidValue());
|
||||
Settings->AddAttributeValue(wxT("Hinting"), (long)HintingCtrl->GetValue());
|
||||
|
||||
// Convert UTF16 to hex, because wxExpr doesn't like non-ASCII
|
||||
wxString PreviewText = PreviewTextCtrl->GetValue();
|
||||
wxString PreviewTextHex;
|
||||
for (size_t i=0; i<PreviewText.Length(); ++i)
|
||||
{
|
||||
wchar_t b[5];
|
||||
swprintf(b, 5, wxT("%04x"), PreviewText[i]);
|
||||
PreviewTextHex += wxString(b, 4);
|
||||
}
|
||||
Settings->AddAttributeValueString(wxT("PreviewText"), PreviewTextHex);
|
||||
|
||||
db.Append(Settings);
|
||||
|
||||
db.Write(filename);
|
||||
|
||||
Changes = false;
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxFileDialog Dlg (this, wxT("Open font settings"), ConfigGet(wxT("FSF path")), wxEmptyString, wxT("Font settings (*.fst)|*.fst|All files (*.*)|*.*"), wxOPEN | wxHIDE_READONLY);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
RecentFiles->AddFileToHistory(Dlg.GetPath());
|
||||
wxString path = Dlg.GetPath();
|
||||
LoadSettings(path);
|
||||
ConfigSet(wxT("FSF path"), Dlg.GetDirectory());
|
||||
}
|
||||
}
|
||||
|
||||
bool MainFrame::SaveDialog()
|
||||
{
|
||||
wxFileDialog Dlg (this, wxT("Save current settings"), ConfigGet(wxT("FSF path")), wxEmptyString, wxT("Font settings (*.fst)|*.fst|All files (*.*)|*.*"), wxSAVE | wxOVERWRITE_PROMPT);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
RecentFiles->AddFileToHistory(Dlg.GetPath());
|
||||
wxString path = Dlg.GetPath();
|
||||
SaveSettings(path);
|
||||
ConfigSet(wxT("FSF path"), Dlg.GetDirectory());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::OnSave(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
SaveDialog();
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::OnMRUFile(wxCommandEvent& event)
|
||||
{
|
||||
wxString filename = RecentFiles->GetHistoryFile(event.GetId() - wxID_FILE1);
|
||||
LoadSettings(filename);
|
||||
RecentFiles->AddFileToHistory(filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MainFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxMessageBox(wxString::Format(wxT("Unicode Font Builder %s - created by Philip Taylor for WildFire Games"), version.c_str()), wxT("About"), wxOK | wxICON_INFORMATION );
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::OnGeneratePreview(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
GeneratePreview();
|
||||
}
|
||||
|
||||
void MainFrame::GeneratePreview()
|
||||
{
|
||||
if (FontFilename0.IsEmpty() || FontFilename1.IsEmpty())
|
||||
return;
|
||||
|
||||
PreviewPanel->GetSize(&PreviewWidth, &PreviewHeight);
|
||||
|
||||
delete[] PreviewImageData;
|
||||
PreviewImageData = GenerateImage(PreviewWidth, PreviewHeight);
|
||||
|
||||
// Find all the relevant controls (slightly nicer than storing lots of pointers in the class)
|
||||
wxTextCtrl* PreviewTextCtrl = (wxTextCtrl*)wxWindow::FindWindowById(ID_PreviewText);
|
||||
StyleSpinCtrl* BoldnessCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Boldness);
|
||||
StyleSpinCtrl* ItalicnessCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Italicness);
|
||||
StyleSpinCtrl* SizeCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Size);
|
||||
StyleSpinCtrl* TrackingCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Tracking);
|
||||
StyleSpinCtrl* LeadingCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Leading);
|
||||
wxCheckBox* HintingCtrl = (wxCheckBox*)wxWindow::FindWindowById(ID_Style_Hinting);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
FontRenderer Font(
|
||||
FontFilename0.ToAscii(),
|
||||
FontFilename1.ToAscii(),
|
||||
SizeCtrl->GetValidValue(),
|
||||
false,
|
||||
!HintingCtrl->GetValue() );
|
||||
|
||||
Font.Boldness = BoldnessCtrl->GetValidValue();
|
||||
Font.Italicness = 5 * ItalicnessCtrl->GetValidValue();
|
||||
Font.Tracking = TrackingCtrl->GetValidValue();
|
||||
Font.Leading = LeadingCtrl->GetValidValue();
|
||||
Font.Outline = false;
|
||||
|
||||
int x = 16, y = Font.GetLineSpacing();
|
||||
|
||||
int prev_glyph_index = 0;
|
||||
|
||||
wxString PreviewText = PreviewTextCtrl->GetValue();
|
||||
for (size_t i = 0; i < PreviewText.Length(); ++i)
|
||||
{
|
||||
if (PreviewText[i] == wxT('\n'))
|
||||
{
|
||||
x = 16;
|
||||
y += Font.GetLineSpacing();
|
||||
}
|
||||
else
|
||||
{
|
||||
int glyph_index = Font.LoadGlyph(PreviewText[i]);
|
||||
|
||||
if (prev_glyph_index)
|
||||
x += Font.GetKerning(prev_glyph_index, glyph_index);
|
||||
|
||||
Font.RenderGlyph(PreviewImageData, x, y, PreviewWidth, PreviewHeight, PreviewWidth*3, false);
|
||||
|
||||
prev_glyph_index = glyph_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const char* m) {
|
||||
wxLogError(wxString::Format(wxT("Failed to generate preview: %s"), wxString::FromAscii(m).c_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
delete PreviewImage;
|
||||
PreviewImage = new wxImage(PreviewWidth, PreviewHeight, PreviewImageData, true);
|
||||
PreviewPanel->SetBitmap(new wxBitmap(PreviewImage));
|
||||
|
||||
PreviewPanel->Refresh();
|
||||
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::OnGenerateTexture(wxCommandEvent& WXUNUSED(event))
|
||||
{
|
||||
wxFileDialog Dlg (this, wxT("Save font definition and texture"), ConfigGet(wxT("FNT path")), wxEmptyString, wxT("Font definition files (*.fnt)|*.fnt|All files (*.*)|*.*"), wxSAVE | wxOVERWRITE_PROMPT);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
wxFileName FontDefnFilename (Dlg.GetPath());
|
||||
wxFileName TextureFilename = FontDefnFilename;
|
||||
TextureFilename.SetExt(wxT("tga"));
|
||||
GenerateTexture(TextureFilename.GetFullPath(), FontDefnFilename.GetFullPath());
|
||||
ConfigSet(wxT("FNT path"), TextureFilename.GetPath());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ProgressDialogCallback(float Progress, wxString Msg, void* data) {
|
||||
return ! ((wxProgressDialog *)data)->Update((int)(Progress*1024.0), Msg);
|
||||
}
|
||||
|
||||
void MainFrame::GenerateTexture(wxString TextureFilename, wxString FontDefnFilename)
|
||||
{
|
||||
if (FontFilename0.IsEmpty() || FontFilename1.IsEmpty())
|
||||
return;
|
||||
|
||||
// Find all the relevant controls (slightly nicer than storing lots of pointers in the class)
|
||||
StyleSpinCtrl* BoldnessCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Boldness);
|
||||
StyleSpinCtrl* ItalicnessCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Italicness);
|
||||
StyleSpinCtrl* SizeCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Size);
|
||||
StyleSpinCtrl* TrackingCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Tracking);
|
||||
StyleSpinCtrl* LeadingCtrl = (StyleSpinCtrl*)wxWindow::FindWindowById(ID_Style_Leading);
|
||||
wxCheckBox* HintingCtrl = (wxCheckBox*)wxWindow::FindWindowById(ID_Style_Hinting);
|
||||
|
||||
|
||||
// Work out what characters need to be included in the texture
|
||||
|
||||
std::set<wchar_t> Chars;
|
||||
if (CharFilename == wxT("<ascii>"))
|
||||
{
|
||||
for (wchar_t c = 0x20; c < 0x7f; ++c)
|
||||
Chars.insert(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Chars = AnalyseChars(CharFilename);
|
||||
}
|
||||
catch (const char* m) {
|
||||
wxLogError(wxString::Format(wxT("Failed to analyse character file: %s"), wxString::FromAscii(m).c_str()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Add the 'missing' symbol (if it's not missing, it'll use a ? instead)
|
||||
Chars.insert(0xFFFD);
|
||||
|
||||
// Generate the texture
|
||||
try
|
||||
{
|
||||
FontRenderer Font(
|
||||
FontFilename0.ToAscii(),
|
||||
FontFilename1.ToAscii(),
|
||||
SizeCtrl->GetValidValue(),
|
||||
false,
|
||||
!HintingCtrl->GetValue() );
|
||||
|
||||
Font.Boldness = BoldnessCtrl->GetValidValue();
|
||||
Font.Italicness = 5 * ItalicnessCtrl->GetValidValue();
|
||||
Font.Tracking = TrackingCtrl->GetValidValue();
|
||||
Font.Leading = LeadingCtrl->GetValidValue();
|
||||
Font.Outline = false;
|
||||
|
||||
PackedFont Packed (&Font, Chars);
|
||||
|
||||
wxProgressDialog ProgressDialog (wxT("Progress"), wxT("Thinking..."), 1024, this, wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME);
|
||||
|
||||
try
|
||||
{
|
||||
Packed.Generate(&ProgressDialogCallback, &ProgressDialog);
|
||||
}
|
||||
catch (const char* m) {
|
||||
wxLogError(wxString::Format(wxT("Failed to generate texture: %s"), wxString::FromAscii(m).c_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
ProgressDialog.Destroy();
|
||||
|
||||
PreviewWidth = Packed.TextureWidth;
|
||||
PreviewHeight = Packed.TextureHeight;
|
||||
delete[] PreviewImageData;
|
||||
PreviewImageData = new unsigned char[PreviewWidth*PreviewHeight*3];
|
||||
memcpy(PreviewImageData, Packed.TextureData, PreviewWidth*PreviewHeight*3);
|
||||
|
||||
delete PreviewImage;
|
||||
PreviewImage = new wxImage(PreviewWidth, PreviewHeight, PreviewImageData, true);
|
||||
PreviewPanel->SetBitmap(new wxBitmap(PreviewImage));
|
||||
|
||||
PreviewPanel->Refresh();
|
||||
|
||||
wxFFile TGAFile(TextureFilename, "wb");
|
||||
if (! TGAFile.IsOpened())
|
||||
throw "Error opening texture file for output";
|
||||
RGB_OutputGreyscaleTGA(PreviewImageData, PreviewWidth, PreviewHeight, PreviewWidth*3, TGAFile);
|
||||
TGAFile.Close();
|
||||
|
||||
wxFFile FntFile(FontDefnFilename, "w");
|
||||
if (! FntFile.IsOpened())
|
||||
throw "Error opening font definition file for output";
|
||||
FntFile.Write(Packed.FontDefinition);
|
||||
FntFile.Close();
|
||||
}
|
||||
catch (const char* m) {
|
||||
wxLogError(wxString::Format(wxT("Failed to generate texture: %s"), wxString::FromAscii(m).c_str()));
|
||||
return;
|
||||
}
|
||||
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::OnFontSelect0(wxCommandEvent& event)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FontSelectorDialog Dlg(this);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
FontFilename0 = Dlg.FontFilename;
|
||||
FontName0 = Dlg.FontName;
|
||||
((wxButton*)event.GetEventObject()) -> SetLabel(FontName0);
|
||||
}
|
||||
#else
|
||||
wxFileDialog Dlg (this, wxT("Select a font file"), wxEmptyString, wxEmptyString, wxT("TTF files (*.ttf)|*.ttf|All files (*.*)|*.*"), wxOPEN | wxHIDE_READONLY);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
FontFilename0 = Dlg.GetPath();
|
||||
FontName0 = Dlg.GetFilename();
|
||||
((wxButton*)event.GetEventObject()) -> SetLabel(FontName0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::OnFontSelect1(wxCommandEvent& event)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FontSelectorDialog Dlg(this);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
FontFilename1 = Dlg.FontFilename;
|
||||
FontName1 = Dlg.FontName;
|
||||
((wxButton*)event.GetEventObject()) -> SetLabel(FontName1);
|
||||
}
|
||||
#else
|
||||
wxFileDialog Dlg (this, wxT("Select a font file"), wxEmptyString, wxEmptyString, wxT("TTF files (*.ttf)|*.ttf|All files (*.*)|*.*"), wxOPEN | wxHIDE_READONLY);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
FontFilename1 = Dlg.GetPath();
|
||||
FontName1 = Dlg.GetFilename();
|
||||
((wxButton*)event.GetEventObject()) -> SetLabel(FontName1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainFrame::OnCharSelect(wxCommandEvent& event)
|
||||
{
|
||||
wxFileDialog Dlg(this, wxT("UTF16 text file containing desired characters"), ConfigGet(wxT("Charset path")), wxEmptyString, wxT("Text files (*.txt)|*.txt|All files (*.*)|*.*"), wxOPEN | wxHIDE_READONLY);
|
||||
if (Dlg.ShowModal() == wxID_OK)
|
||||
{
|
||||
CharFilename = Dlg.GetPath();
|
||||
CharName = Dlg.GetFilename();
|
||||
((wxButton*)event.GetEventObject()) -> SetLabel(CharName);
|
||||
ConfigSet(wxT("Charset path"), Dlg.GetDirectory());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BitmapPanel::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
if (Bitmap)
|
||||
dc.DrawBitmap(*Bitmap, 0, 0, false);
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
#include "wx/panel.h"
|
||||
#include "wx/bitmap.h"
|
||||
#include "wx/frame.h"
|
||||
#include "wx/docview.h"
|
||||
|
||||
class BitmapPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
BitmapPanel(wxWindow* parent)
|
||||
: wxPanel(parent)
|
||||
{
|
||||
Bitmap = NULL;
|
||||
}
|
||||
|
||||
~BitmapPanel()
|
||||
{
|
||||
delete Bitmap;
|
||||
}
|
||||
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void SetBitmap(wxBitmap* bmp)
|
||||
{
|
||||
delete Bitmap;
|
||||
Bitmap = bmp;
|
||||
}
|
||||
|
||||
private:
|
||||
wxBitmap* Bitmap;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
|
||||
|
||||
class MainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
|
||||
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnAbout(wxCommandEvent& event);
|
||||
|
||||
bool SaveDialog();
|
||||
void OnSave(wxCommandEvent& event);
|
||||
void OnOpen(wxCommandEvent& event);
|
||||
|
||||
void OnMRUFile(wxCommandEvent& event);
|
||||
|
||||
void OnFontSelect0(wxCommandEvent& event);
|
||||
void OnFontSelect1(wxCommandEvent& event);
|
||||
void OnCharSelect(wxCommandEvent& event);
|
||||
|
||||
void OnGeneratePreview(wxCommandEvent& event);
|
||||
void OnGenerateTexture(wxCommandEvent& event);
|
||||
|
||||
private:
|
||||
BitmapPanel* PreviewPanel;
|
||||
unsigned char* PreviewImageData;
|
||||
wxImage* PreviewImage;
|
||||
|
||||
void GeneratePreview();
|
||||
int PreviewWidth, PreviewHeight;
|
||||
|
||||
void GenerateTexture(wxString TextureFilename, wxString FontDefnFilename);
|
||||
|
||||
void SaveSettings(wxString& filename);
|
||||
void LoadSettings(wxString& filename);
|
||||
|
||||
wxString FontName0;
|
||||
wxString FontName1;
|
||||
wxString FontFilename0;
|
||||
wxString FontFilename1;
|
||||
|
||||
wxString CharName;
|
||||
wxString CharFilename;
|
||||
|
||||
wxFileHistory* RecentFiles;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
#include "wx/spinctrl.h"
|
||||
|
||||
class StyleSpinCtrl : public wxSpinCtrl
|
||||
{
|
||||
public:
|
||||
|
||||
StyleSpinCtrl(wxWindow* parent, wxWindowID win_id, int min_val, int max_val, int initial_val)
|
||||
: wxSpinCtrl(parent, win_id, wxEmptyString, wxDefaultPosition, wxSize(50, 20), wxSP_ARROW_KEYS, min_val, max_val, initial_val)
|
||||
{
|
||||
SetValue(initial_val);
|
||||
}
|
||||
|
||||
// Like GetValue, but guaranteed to be inside the range (Min..Max)
|
||||
// no matter what people type in
|
||||
int GetValidValue()
|
||||
{
|
||||
int Value = GetValue();
|
||||
int Min = GetMin();
|
||||
int Max = GetMax();
|
||||
return Value <= Min ? Min : Value >= Max ? Max : Value;
|
||||
}
|
||||
};
|
@ -1,11 +1,13 @@
|
||||
Fonts consist of
|
||||
fontname.fnt
|
||||
fontname.tga
|
||||
fontname.png
|
||||
and you load fonts by just specifying the "path/fontname" part.
|
||||
|
||||
The .tga is an 8-bit greyscale image, used for alpha-blending the text.
|
||||
The .png is an 8-bit greyscale image, used for alpha-blending the text.
|
||||
(DXTC allows 0.5 bytes/pixel at best, which isn't much better than
|
||||
TGA's 1 byte/pixel, and DXTC's lossiness is almost noticeable.)
|
||||
PNG's 1 byte/pixel, and DXTC's lossiness is almost noticeable,
|
||||
so we stick with lossless formats.)
|
||||
Or it's a 32-bit RGBA image, to allow more complex text styles.
|
||||
|
||||
The .fnt file is something like:
|
||||
|
||||
@ -41,5 +43,3 @@ Each subsequent line is
|
||||
x, y, width, height are in pixels on the texture.
|
||||
x/y offset are the position of the texture relative to the glyph's origin.
|
||||
advance is the number of pixels to move along for the next character.
|
||||
|
||||
Currently no support for kerning.
|
Loading…
Reference in New Issue
Block a user