Delete old obsolete font builder tool and related files

This was SVN commit r7599.
This commit is contained in:
Ykkrosh 2010-05-31 19:04:39 +00:00
parent 7af705435f
commit 6de0cdc5f9
40 changed files with 6 additions and 3106 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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="&quot;E:\wx\wxWindows-2.4.2\include&quot;;&quot;E:\wx\wxWindows-2.4.2\lib\mswud&quot;;&quot;E:\freetype\freetype-2.1.8\include&quot;;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="&quot;E:\wx\wxWindows-2.4.2\lib&quot;;&quot;E:\freetype\freetype-2.1.8\objs&quot;"
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="&quot;E:\wx\wxWindows-2.4.2\include&quot;;&quot;E:\wx\wxWindows-2.4.2\lib\mswud&quot;;&quot;E:\freetype\freetype-2.1.8\include&quot;;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>

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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>

View File

@ -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]);
}

View File

@ -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

View File

@ -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 ));

View File

@ -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;
}

View File

@ -1,2 +0,0 @@
unsigned char* GenerateImage(int width, int height);
unsigned char* GreyscaleToRGB(int width, int height, unsigned char* grey);

View File

@ -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);
}
}

View File

@ -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;
};

View File

@ -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()
};

View File

@ -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("");
}

View File

@ -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");
}

View File

@ -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>

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -1 +0,0 @@
const wxString version = L"v1.11";

View File

@ -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;
}

View File

@ -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();
}

View File

@ -1,6 +0,0 @@
#include "wx/string.h"
void ConfigInit();
wxString ConfigGet(wxString key);
void ConfigSet(wxString key, wxString value);
void ConfigDestroy();

View File

@ -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);
}

View File

@ -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()
};

View File

@ -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;
}
};

View File

@ -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:
@ -18,7 +20,7 @@ The .fnt file is something like:
32 0 0 10 10 12
33 10 0 6 10 7
3300 16 0 6 10 7
First line = version number of file, for slightly better error
detection if people leave old ones hanging around.
@ -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.