Remove the font tool, which is no longer necessary
This commit is contained in:
parent
6d365032f3
commit
dd975de74f
@ -434,9 +434,6 @@ if(MINGW)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Optional tools
|
||||
add_subdirectory(tools/font_tool)
|
||||
|
||||
|
||||
# ==== Checking if data folder exists ====
|
||||
if(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/data)
|
||||
|
@ -1,861 +0,0 @@
|
||||
#include "CFontTool.h"
|
||||
#include "IXMLWriter.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace irr;
|
||||
|
||||
const int fontsizes[] = {4,6,8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,56,68,72,0};
|
||||
|
||||
char bUsed[0x10000]={0};
|
||||
|
||||
/** True if pot files where given, which indicates that Asian fonts
|
||||
* are to be created, and an offset needs to be used for the index. */
|
||||
bool has_pot_files = false;
|
||||
|
||||
inline u32 getTextureSizeFromSurfaceSize(u32 size)
|
||||
{
|
||||
u32 ts = 0x01;
|
||||
while(ts < size)
|
||||
ts <<= 1;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
bool LoadPoFiles(const char* sListFileName){
|
||||
has_pot_files = true;
|
||||
char s[1024];
|
||||
std::ifstream fin(sListFileName);
|
||||
if(!fin){
|
||||
std::cout<<"Error: Can't open "<<sListFileName<<std::endl;
|
||||
return false;
|
||||
}
|
||||
std::cout<<"Opened list file "<<sListFileName<<std::endl;
|
||||
for(;;){
|
||||
fin.getline(s,1024);
|
||||
if(fin.eof()) break;
|
||||
std::ifstream fin2(s);
|
||||
if(!fin2){
|
||||
std::cout<<"Error: Can't open "<<s<<std::endl;
|
||||
}else{
|
||||
std::cout<<"Opened "<<s<<std::endl;
|
||||
//buggy code that convert UTF-8 to UCS-2
|
||||
for(;;){
|
||||
unsigned char c1=(unsigned char)fin2.get();
|
||||
unsigned short out=0;
|
||||
if(fin2.eof()) break;
|
||||
if(c1>=0xF0) continue;
|
||||
else if(c1>=0xE0){
|
||||
out=((c1&0xF)<<12)
|
||||
|((((unsigned char)fin2.get())&0x3F)<<6)
|
||||
|(((unsigned char)fin2.get())&0x3F);
|
||||
}else if(c1>=0xC0){
|
||||
out=((c1&0x1F)<<6)
|
||||
|(((unsigned char)fin2.get())&0x3F);
|
||||
}else{
|
||||
out=c1;
|
||||
}
|
||||
bUsed[out]=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Set all characters in the given character string to be used. */
|
||||
bool setUsedCharacters(const char* characters)
|
||||
{
|
||||
int n = strlen(characters);
|
||||
for(int i=0; i<n; i++)
|
||||
bUsed[short(characters[i])] = true;
|
||||
return true;
|
||||
} // setUsedCharacters
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// windows specific
|
||||
#ifdef _IRR_WINDOWS_
|
||||
|
||||
const DWORD charsets[] = { ANSI_CHARSET, DEFAULT_CHARSET, OEM_CHARSET, BALTIC_CHARSET, GB2312_CHARSET, CHINESEBIG5_CHARSET,
|
||||
EASTEUROPE_CHARSET, GREEK_CHARSET, HANGUL_CHARSET, MAC_CHARSET, RUSSIAN_CHARSET,
|
||||
SHIFTJIS_CHARSET, SYMBOL_CHARSET, TURKISH_CHARSET, VIETNAMESE_CHARSET, JOHAB_CHARSET,
|
||||
ARABIC_CHARSET, HEBREW_CHARSET, THAI_CHARSET, 0};
|
||||
|
||||
const wchar_t *setnames[] = {L"ANSI", L"All Available", L"OEM", L"Baltic", L"Chinese Simplified", L"Chinese Traditional",
|
||||
L"Eastern European", L"Greek", L"Hangul", L"Macintosh", L"Russian",
|
||||
L"Japanese", L"Symbol", L"Turkish", L"Vietnamese", L"Johab",
|
||||
L"Arabic", L"Hebrew", L"Thai", 0};
|
||||
|
||||
// callback for adding font names
|
||||
int CALLBACK EnumFontFamExProc( ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme,
|
||||
DWORD FontType, LPARAM lParam)
|
||||
{
|
||||
CFontTool* t = (CFontTool*) lParam;
|
||||
t->FontNames.push_back( core::stringw(lpelfe->elfFullName));
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
|
||||
CFontTool::CFontTool(IrrlichtDevice* device) : FontSizes(fontsizes),
|
||||
Device(device), UseAlphaChannel(false),
|
||||
// win specific
|
||||
dc(0)
|
||||
{
|
||||
// init display context
|
||||
dc = CreateDC(L"DISPLAY", L"DISPLAY", 0 ,0 );
|
||||
|
||||
// populate list of available character set names
|
||||
for (int i=0; setnames[i] != 0; ++i)
|
||||
CharSets.push_back( core::stringw(setnames[i]));
|
||||
|
||||
selectCharSet(0);
|
||||
}
|
||||
|
||||
void CFontTool::selectCharSet(u32 currentCharSet)
|
||||
{
|
||||
if ( currentCharSet >= CharSets.size() )
|
||||
return;
|
||||
|
||||
LOGFONTW lf;
|
||||
lf.lfFaceName[0] = L'\0';
|
||||
lf.lfCharSet = (BYTE) charsets[currentCharSet];
|
||||
// HRESULT hr; // no error checking(!)
|
||||
|
||||
// clear font list
|
||||
FontNames.clear();
|
||||
|
||||
// create list of available fonts
|
||||
EnumFontFamiliesExW( dc, (LPLOGFONTW) &lf, (FONTENUMPROCW) EnumFontFamExProc, (LPARAM) this, 0);
|
||||
}
|
||||
|
||||
bool CFontTool::makeBitmapFont(u32 fontIndex, u32 charsetIndex, s32 fontSize, u32 textureWidth, u32 textureHeight, bool bold, bool italic, bool aa, bool alpha,bool usedOnly,bool excludeLatin)
|
||||
{
|
||||
if (fontIndex >= FontNames.size() || charsetIndex >= CharSets.size() )
|
||||
return false;
|
||||
|
||||
UseAlphaChannel = alpha;
|
||||
u32 currentImage = 0;
|
||||
|
||||
// create the font
|
||||
HFONT font = CreateFontW(
|
||||
-MulDiv(fontSize, GetDeviceCaps(dc, LOGPIXELSY), 72), 0,
|
||||
0,0,
|
||||
bold ? FW_BOLD : 0,
|
||||
italic, 0,0, charsets[charsetIndex], 0,0,
|
||||
aa ? ANTIALIASED_QUALITY : 0,
|
||||
0, FontNames[fontIndex].c_str() );
|
||||
|
||||
if (!font)
|
||||
return false;
|
||||
|
||||
SelectObject(dc, font);
|
||||
SetTextAlign (dc,TA_LEFT | TA_TOP | TA_NOUPDATECP);
|
||||
|
||||
// get rid of the current textures/images
|
||||
for (u32 i=0; i<currentTextures.size(); ++i)
|
||||
currentTextures[i]->drop();
|
||||
currentTextures.clear();
|
||||
|
||||
for (u32 i=0; i<currentImages.size(); ++i)
|
||||
currentImages[i]->drop();
|
||||
currentImages.clear();
|
||||
|
||||
// clear current image mappings
|
||||
CharMap.clear();
|
||||
// clear array
|
||||
Areas.clear();
|
||||
|
||||
// get information about this font's unicode ranges.
|
||||
s32 size = GetFontUnicodeRanges( dc, 0);
|
||||
c8 *buf = new c8[size];
|
||||
LPGLYPHSET glyphs = (LPGLYPHSET)buf;
|
||||
|
||||
GetFontUnicodeRanges( dc, glyphs);
|
||||
|
||||
// s32 TotalCharCount = glyphs->cGlyphsSupported;
|
||||
|
||||
s32 currentx=0, currenty=0, maxy=0;
|
||||
|
||||
for (u32 range=0; range < glyphs->cRanges; range++)
|
||||
{
|
||||
WCRANGE* current = &glyphs->ranges[range];
|
||||
|
||||
//maxy=0;
|
||||
|
||||
// loop through each glyph and write its size and position
|
||||
for (s32 ch=current->wcLow; ch< current->wcLow + current->cGlyphs; ch++)
|
||||
{
|
||||
wchar_t currentchar = ch;
|
||||
|
||||
/* if ( IsDBCSLeadByte((BYTE) ch))
|
||||
continue; // surragate pairs unsupported */
|
||||
if(excludeLatin && ch>=0 && ch<0x100) continue;
|
||||
if(usedOnly && !bUsed[(unsigned short)ch]) continue;
|
||||
|
||||
// get the dimensions
|
||||
SIZE size;
|
||||
ABC abc;
|
||||
GetTextExtentPoint32W(dc, ¤tchar, 1, &size);
|
||||
SFontArea fa;
|
||||
fa.underhang = 0;
|
||||
fa.overhang = 0;
|
||||
|
||||
if (GetCharABCWidthsW(dc, currentchar, currentchar, &abc)) // for unicode fonts, get overhang, underhang, width
|
||||
{
|
||||
size.cx = abc.abcB;
|
||||
fa.underhang = abc.abcA;
|
||||
fa.overhang = abc.abcC;
|
||||
}
|
||||
if (size.cy < 1)
|
||||
continue;
|
||||
|
||||
//GetGlyphOutline(dc, currentchar, GGO_METRICS, &gm, 0, 0, 0);
|
||||
|
||||
//size.cx++; size.cy++;
|
||||
|
||||
// wrap around?
|
||||
if (currentx + size.cx > (s32) textureWidth)
|
||||
{
|
||||
currenty += maxy;
|
||||
currentx = 0;
|
||||
if ((u32)(currenty + maxy) > textureHeight)
|
||||
{
|
||||
currentImage++; // increase Image count
|
||||
currenty=0;
|
||||
}
|
||||
maxy = 0;
|
||||
}
|
||||
// add this char dimension to the current map
|
||||
|
||||
fa.rectangle = core::rect<s32>(currentx, currenty, currentx + size.cx, currenty + size.cy);
|
||||
fa.sourceimage = currentImage;
|
||||
|
||||
CharMap.insert(currentchar, Areas.size());
|
||||
Areas.push_back( fa );
|
||||
|
||||
currentx += size.cx +1;
|
||||
|
||||
if (size.cy+1 > maxy)
|
||||
maxy = size.cy+1;
|
||||
}
|
||||
}
|
||||
currenty += maxy;
|
||||
|
||||
u32 lastTextureHeight = getTextureSizeFromSurfaceSize(currenty);
|
||||
|
||||
// delete the glyph set
|
||||
delete [] buf;
|
||||
|
||||
currentImages.set_used(currentImage+1);
|
||||
currentTextures.set_used(currentImage+1);
|
||||
|
||||
for (currentImage=0; currentImage < currentImages.size(); ++currentImage)
|
||||
{
|
||||
core::stringc logmsg = "Creating image ";
|
||||
logmsg += (s32) (currentImage+1);
|
||||
logmsg += " of ";
|
||||
logmsg += (s32) currentImages.size();
|
||||
Device->getLogger()->log(logmsg.c_str());
|
||||
// no need for a huge final texture
|
||||
u32 texHeight = textureHeight;
|
||||
if (currentImage == currentImages.size()-1 )
|
||||
texHeight = lastTextureHeight;
|
||||
|
||||
// make a new bitmap
|
||||
HBITMAP bmp = CreateCompatibleBitmap(dc, textureWidth, texHeight);
|
||||
HDC bmpdc = CreateCompatibleDC(dc);
|
||||
|
||||
LOGBRUSH lbrush;
|
||||
lbrush.lbColor = RGB(0,0,0);
|
||||
lbrush.lbHatch = 0;
|
||||
lbrush.lbStyle = BS_SOLID;
|
||||
|
||||
HBRUSH brush = CreateBrushIndirect(&lbrush);
|
||||
HPEN pen = CreatePen(PS_NULL, 0, 0);
|
||||
|
||||
HGDIOBJ oldbmp = SelectObject(bmpdc, bmp);
|
||||
HGDIOBJ oldbmppen = SelectObject(bmpdc, pen);
|
||||
HGDIOBJ oldbmpbrush = SelectObject(bmpdc, brush);
|
||||
HGDIOBJ oldbmpfont = SelectObject(bmpdc, font);
|
||||
|
||||
SetTextColor(bmpdc, RGB(255,255,255));
|
||||
|
||||
Rectangle(bmpdc, 0,0,textureWidth,texHeight);
|
||||
SetBkMode(bmpdc, TRANSPARENT);
|
||||
|
||||
// draw the letters...
|
||||
|
||||
// iterate through the tree
|
||||
core::map<wchar_t, u32>::Iterator it = CharMap.getIterator();
|
||||
while (!it.atEnd())
|
||||
{
|
||||
s32 currentArea = (*it).getValue();
|
||||
wchar_t wch = (*it).getKey();
|
||||
// sloppy but I couldnt be bothered rewriting it
|
||||
if (Areas[currentArea].sourceimage == currentImage)
|
||||
{
|
||||
// draw letter
|
||||
s32 sx = Areas[currentArea].rectangle.UpperLeftCorner.X - Areas[currentArea].underhang;
|
||||
TextOutW(bmpdc, sx, Areas[currentArea].rectangle.UpperLeftCorner.Y, &wch, 1);
|
||||
|
||||
// if ascii font...
|
||||
//SetPixel(bmpdc, Areas[currentArea].rectangle.UpperLeftCorner.X, Areas[currentArea].rectangle.UpperLeftCorner.Y, RGB(255,255,0));// left upper corner mark
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
// copy the font bitmap into a new irrlicht image
|
||||
BITMAP b;
|
||||
PBITMAPINFO pbmi;
|
||||
WORD cClrBits;
|
||||
u32 cformat;
|
||||
|
||||
// Retrieve the bitmap color format, width, and height.
|
||||
GetObject(bmp, sizeof(BITMAP), (LPSTR)&b);
|
||||
|
||||
// Convert the color format to a count of bits.
|
||||
cClrBits = (WORD)(b.bmPlanes * b.bmBitsPixel);
|
||||
|
||||
if (cClrBits <= 8) // we're not supporting these
|
||||
cformat = -1;
|
||||
else if (cClrBits <= 16)
|
||||
cformat = video::ECF_A1R5G5B5;
|
||||
else if (cClrBits <= 24)
|
||||
cformat = video::ECF_R8G8B8;
|
||||
else
|
||||
cformat = video::ECF_A8R8G8B8;
|
||||
|
||||
pbmi = (PBITMAPINFO) LocalAlloc(LPTR,
|
||||
sizeof(BITMAPINFOHEADER));
|
||||
|
||||
// Initialize the fields in the BITMAPINFO structure.
|
||||
|
||||
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
pbmi->bmiHeader.biWidth = b.bmWidth;
|
||||
pbmi->bmiHeader.biHeight = b.bmHeight;
|
||||
pbmi->bmiHeader.biPlanes = b.bmPlanes;
|
||||
pbmi->bmiHeader.biBitCount = b.bmBitsPixel;
|
||||
|
||||
// If the bitmap is not compressed, set the BI_RGB flag.
|
||||
pbmi->bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
// Compute the number of bytes in the array of color
|
||||
// indices and store the result in biSizeImage.
|
||||
// For Windows NT, the width must be DWORD aligned unless
|
||||
// the bitmap is RLE compressed. This example shows this.
|
||||
// For Windows 95/98/Me, the width must be WORD aligned unless the
|
||||
// bitmap is RLE compressed.
|
||||
pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8
|
||||
* pbmi->bmiHeader.biHeight;
|
||||
// Set biClrImportant to 0, indicating that all of the
|
||||
// device colors are important.
|
||||
pbmi->bmiHeader.biClrImportant = 0;
|
||||
|
||||
LPBYTE lpBits; // memory pointer
|
||||
|
||||
PBITMAPINFOHEADER pbih = (PBITMAPINFOHEADER) pbmi;
|
||||
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
|
||||
|
||||
GetDIBits(dc, bmp, 0, (WORD) pbih->biHeight, lpBits, pbmi, DIB_RGB_COLORS);
|
||||
|
||||
// DEBUG- copy to clipboard
|
||||
//OpenClipboard(hWnd);
|
||||
//EmptyClipboard();
|
||||
//SetClipboardData(CF_BITMAP, bmp);
|
||||
//CloseClipboard();
|
||||
|
||||
// flip bitmap
|
||||
s32 rowsize = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8;
|
||||
c8 *row = new c8[rowsize];
|
||||
for (s32 i=0; i < (pbih->biHeight/2); ++i)
|
||||
{
|
||||
// grab a row
|
||||
memcpy(row, lpBits + (rowsize * i), rowsize);
|
||||
// swap row
|
||||
memcpy(lpBits + (rowsize * i), lpBits + ((pbih->biHeight-1 -i) * rowsize ) , rowsize);
|
||||
memcpy(lpBits + ((pbih->biHeight-1 -i) * rowsize ), row , rowsize);
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
|
||||
if (cformat == video::ECF_A8R8G8B8)
|
||||
{
|
||||
// in this case the font should have an alpha channel, but since windows doesn't draw one
|
||||
// we have to set one manually by going through all the pixels.. *sigh*
|
||||
|
||||
u8* m;
|
||||
for (m = lpBits; m < lpBits + pbih->biSizeImage; m+=4)
|
||||
{
|
||||
if (UseAlphaChannel)
|
||||
{
|
||||
if (m[0] > 0) // pixel has colour
|
||||
{
|
||||
m[3]=m[0]; // set alpha
|
||||
m[0]=m[1]=m[2] = 255; // everything else is full
|
||||
}
|
||||
}
|
||||
else
|
||||
m[3]=255; // all pixels are full alpha
|
||||
}
|
||||
|
||||
}
|
||||
else if (cformat == video::ECF_A1R5G5B5)
|
||||
{
|
||||
u8* m;
|
||||
for (m = lpBits; m < lpBits + pbih->biSizeImage; m+=2)
|
||||
{
|
||||
WORD *p = (WORD*)m;
|
||||
if (m[0] > 0 || !UseAlphaChannel) // alpha should be set
|
||||
*p |= 0x8000; // set alpha bit
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cformat = -1;
|
||||
}
|
||||
|
||||
// make a texture from the image
|
||||
if (cformat != -1)
|
||||
{
|
||||
// turn mip-mapping off
|
||||
bool b = Device->getVideoDriver()->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
currentImages[currentImage] = Device->getVideoDriver()->createImageFromData((video::ECOLOR_FORMAT)cformat, core::dimension2d<u32>(textureWidth,texHeight), (void*)lpBits);
|
||||
Device->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS,b);
|
||||
}
|
||||
else
|
||||
{
|
||||
Device->getLogger()->log("Couldn't create font, your pixel format is unsupported.");
|
||||
}
|
||||
|
||||
// free memory and windows resources
|
||||
// sloppy I know, but I only intended to create one image at first.
|
||||
delete [] row;
|
||||
LocalFree(pbmi);
|
||||
GlobalFree(lpBits);
|
||||
DeleteDC(bmpdc);
|
||||
DeleteObject(brush);
|
||||
DeleteObject(pen);
|
||||
DeleteObject(bmp);
|
||||
|
||||
if (currentImages[currentImage])
|
||||
{
|
||||
// add texture
|
||||
currentTextures[currentImage] = Device->getVideoDriver()->addTexture("GUIFontImage",currentImages[currentImage]);
|
||||
currentTextures[currentImage]->grab();
|
||||
}
|
||||
else
|
||||
{
|
||||
Device->getLogger()->log("Something went wrong, aborting.");
|
||||
// drop all images
|
||||
DeleteObject(font);
|
||||
return false;
|
||||
}
|
||||
} // looping through each texture
|
||||
DeleteObject(font);
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CFontTool::CFontTool(IrrlichtDevice *device) : FontSizes(fontsizes), Device(device), UseAlphaChannel(false)
|
||||
{
|
||||
if (!XftInitFtLibrary())
|
||||
{
|
||||
core::stringc logmsg = "XFT not found\n";
|
||||
Device->getLogger()->log(logmsg.c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Get a list of the font foundries, storing them in a set to sort */
|
||||
std::set<core::stringw> foundries;
|
||||
Display* display = (Display*)Device->getVideoDriver()->getExposedVideoData().OpenGLLinux.X11Display;
|
||||
XftFontSet* fonts = XftListFonts(display, DefaultScreen(display), 0, XFT_FOUNDRY, NULL);
|
||||
for (int i = 0; i < fonts->nfont; i++)
|
||||
{
|
||||
char *foundry;
|
||||
XftPatternGetString(fonts->fonts[i], XFT_FOUNDRY, 0, &foundry);
|
||||
core::stringw tmp(foundry);
|
||||
foundries.insert(tmp);
|
||||
}
|
||||
XftFontSetDestroy(fonts);
|
||||
|
||||
/* Copy the sorted list into the array */
|
||||
CharSets.clear();
|
||||
for (std::set<core::stringw>::iterator i = foundries.begin(); i != foundries.end(); i++)
|
||||
CharSets.push_back((*i).c_str());
|
||||
selectCharSet(0);
|
||||
}
|
||||
|
||||
/* Note: There must be some trick for using strings as pattern parameters to XftListFonts because
|
||||
no matter how I specify a string, I end up with an intermittent segfault. Since XftFontList is
|
||||
just calling FcFontList, that's what I'll do too since that works OK */
|
||||
void CFontTool::selectCharSet(u32 currentCharSet)
|
||||
{
|
||||
/* Get a list of the font families, storing them in a set to sort */
|
||||
char foundry[256];
|
||||
sprintf(&foundry[0],"%ls",CharSets[currentCharSet].c_str());
|
||||
std::set<core::stringw> families;
|
||||
XftPattern *pattern = FcPatternCreate();
|
||||
XftPatternAddString(pattern, FC_FOUNDRY, &foundry[0]);
|
||||
XftObjectSet *objectset = FcObjectSetCreate();
|
||||
XftObjectSetAdd(objectset, XFT_FOUNDRY);
|
||||
XftObjectSetAdd(objectset, XFT_FAMILY);
|
||||
FcFontSet *fonts = FcFontList(NULL, pattern, objectset);
|
||||
|
||||
for (int i = 0; i < fonts->nfont; i++)
|
||||
{
|
||||
char* ptr;
|
||||
XftPatternGetString(fonts->fonts[i], XFT_FAMILY, 0, &ptr);
|
||||
core::stringw family(ptr);
|
||||
families.insert(family);
|
||||
}
|
||||
XftPatternDestroy(pattern);
|
||||
FcObjectSetDestroy(objectset);
|
||||
|
||||
/* Copy the sorted list into the array */
|
||||
FontNames.clear();
|
||||
for (std::set<core::stringw>::iterator i = families.begin(); i != families.end(); i++)
|
||||
FontNames.push_back((*i).c_str());
|
||||
}
|
||||
|
||||
bool CFontTool::makeBitmapFont(u32 fontIndex, u32 charsetIndex, s32 fontSize, u32 textureWidth, u32 textureHeight, bool bold, bool italic, bool aa, bool alpha,bool usedOnly,bool excludeLatin)
|
||||
{
|
||||
if (fontIndex >= FontNames.size() || charsetIndex >= CharSets.size() )
|
||||
return false;
|
||||
|
||||
Display *display = (Display*) Device->getVideoDriver()->getExposedVideoData().OpenGLLinux.X11Display;
|
||||
u32 screen = DefaultScreen(display);
|
||||
Window win = RootWindow(display, screen);
|
||||
Visual *visual = DefaultVisual(display, screen);
|
||||
UseAlphaChannel = alpha;
|
||||
u32 currentImage = 0;
|
||||
|
||||
XftResult result;
|
||||
XftPattern *request = XftPatternCreate();
|
||||
char foundry[256], family[256];
|
||||
sprintf(&foundry[0],"%ls",CharSets[charsetIndex].c_str());
|
||||
sprintf(&family[0],"%ls",FontNames[fontIndex].c_str());
|
||||
XftPatternAddString(request, XFT_FOUNDRY, &foundry[0]);
|
||||
XftPatternAddString(request, XFT_FAMILY, &family[0]);
|
||||
XftPatternAddInteger(request, XFT_PIXEL_SIZE, fontSize);
|
||||
XftPatternAddInteger(request, XFT_WEIGHT, bold ? XFT_WEIGHT_BLACK : XFT_WEIGHT_LIGHT);
|
||||
XftPatternAddInteger(request, XFT_SLANT, italic ? XFT_SLANT_ITALIC : XFT_SLANT_ROMAN);
|
||||
XftPatternAddBool(request, XFT_ANTIALIAS, aa);
|
||||
|
||||
/* Find the closest font that matches the user choices and open it and check if the returned
|
||||
font has anti aliasing enabled by default, even if it wasn't requested */
|
||||
FcBool aaEnabled;
|
||||
XftPattern *found = XftFontMatch(display, DefaultScreen(display), request, &result);
|
||||
XftPatternGetBool(found, XFT_ANTIALIAS, 0, &aaEnabled);
|
||||
aa = aaEnabled;
|
||||
XftFont *font = XftFontOpenPattern(display, found);
|
||||
|
||||
// get rid of the current textures/images
|
||||
for (u32 i=0; i<currentTextures.size(); ++i)
|
||||
currentTextures[i]->drop();
|
||||
currentTextures.clear();
|
||||
for (u32 i=0; i<currentImages.size(); ++i)
|
||||
currentImages[i]->drop();
|
||||
currentImages.clear();
|
||||
CharMap.clear();
|
||||
Areas.clear();
|
||||
|
||||
/* Calculate the max height of the font. Annoyingly, it seems that the height property of the font
|
||||
is the maximum height of any single character, but a string of characters, aligned along their
|
||||
baselines, can exceed this figure. Because I don't know any better way of doing it, I'm going to
|
||||
have to use the brute force method.
|
||||
|
||||
Note: There will be a certain number of charters in a font, however they may not be grouped
|
||||
consecutively, and could in fact be spread out with many gaps */
|
||||
u32 maxY = 0;
|
||||
u32 charsFound = 0;
|
||||
for (FT_UInt charCode = 0; charsFound < FcCharSetCount(font->charset); charCode++)
|
||||
{
|
||||
if (!XftCharExists(display, font, charCode))
|
||||
continue;
|
||||
|
||||
charsFound++;
|
||||
|
||||
XGlyphInfo extents;
|
||||
XftTextExtents32(display, font, &charCode, 1, &extents);
|
||||
if ((extents.xOff <= 0) && (extents.height <= 0))
|
||||
continue;
|
||||
|
||||
/* Calculate the width and height, adding 1 extra pixel if anti aliasing is enabled */
|
||||
u32 chWidth = extents.xOff + (aa ? 1 : 0);
|
||||
u32 chHeight = (font->ascent - extents.y + extents.height) + (aa ? 1 : 0);
|
||||
if (chHeight > maxY)
|
||||
maxY = chHeight;
|
||||
|
||||
/* Store the character details here */
|
||||
SFontArea fontArea;
|
||||
fontArea.rectangle = core::rect<s32>(0, 0, chWidth, chHeight);
|
||||
CharMap.insert(charCode, Areas.size());
|
||||
Areas.push_back(fontArea);
|
||||
}
|
||||
core::stringc logmsg = "Found ";
|
||||
logmsg += (s32) (CharMap.size() + 1);
|
||||
logmsg += " characters";
|
||||
Device->getLogger()->log(logmsg.c_str());
|
||||
|
||||
/* Get the size of the chars and allocate them a position on a texture. If the next character that
|
||||
is added would be outside the width or height of the texture, then a new texture is added */
|
||||
u32 currentX = 0, currentY = 0, rowY = 0;
|
||||
for (core::map<wchar_t, u32>::Iterator it = CharMap.getIterator(); !it.atEnd(); it++)
|
||||
{
|
||||
s32 currentArea = (*it).getValue();
|
||||
SFontArea *fontArea = &Areas[currentArea];
|
||||
u32 chWidth = fontArea->rectangle.LowerRightCorner.X;
|
||||
u32 chHeight = fontArea->rectangle.LowerRightCorner.Y;
|
||||
|
||||
/* If the width of this char will exceed the textureWidth then start a new row */
|
||||
if ((currentX + chWidth) > textureWidth)
|
||||
{
|
||||
currentY += rowY;
|
||||
currentX = 0;
|
||||
|
||||
/* If the new row added to the texture exceeds the textureHeight then start a new texture */
|
||||
if ((currentY + rowY) > textureHeight)
|
||||
{
|
||||
currentImage++;
|
||||
currentY = 0;
|
||||
}
|
||||
rowY = 0;
|
||||
}
|
||||
|
||||
/* Update the area with the current x and y and texture */
|
||||
fontArea->rectangle = core::rect<s32>(currentX, currentY, currentX + chWidth, currentY + chHeight);
|
||||
fontArea->sourceimage = currentImage;
|
||||
currentX += chWidth + 1;
|
||||
if (chHeight + 1 > rowY)
|
||||
rowY = chHeight + 1;
|
||||
}
|
||||
|
||||
/* The last row of chars and the last texture weren't accounted for in the loop, so add them here */
|
||||
currentY += rowY;
|
||||
u32 lastTextureHeight = getTextureSizeFromSurfaceSize(currentY);
|
||||
currentImages.set_used(currentImage + 1);
|
||||
currentTextures.set_used(currentImage + 1);
|
||||
|
||||
/* Initialise colours */
|
||||
XftColor colFore, colBack;
|
||||
XRenderColor xFore = {0xffff, 0xffff, 0xffff, 0xffff};
|
||||
XRenderColor xBack = {0x0000, 0x0000, 0x0000, 0xffff};
|
||||
XftColorAllocValue(display, DefaultVisual(display, screen), DefaultColormap(display, screen), &xFore, &colFore);
|
||||
XftColorAllocValue(display, DefaultVisual(display, screen), DefaultColormap(display, screen), &xBack, &colBack);
|
||||
|
||||
/* Create a pixmap that is large enough to hold any character in the font */
|
||||
Pixmap pixmap = XCreatePixmap(display, win, textureWidth, maxY, DefaultDepth(display, screen));
|
||||
XftDraw *draw = XftDrawCreate(display, pixmap, visual, DefaultColormap(display, screen));
|
||||
|
||||
/* Render the chars */
|
||||
for (currentImage = 0; currentImage < currentImages.size(); ++currentImage)
|
||||
{
|
||||
core::stringc logmsg = "Creating image ";
|
||||
logmsg += (s32) (currentImage+1);
|
||||
logmsg += " of ";
|
||||
logmsg += (s32) currentImages.size();
|
||||
Device->getLogger()->log(logmsg.c_str());
|
||||
|
||||
/* The last texture that is saved is vertically shrunk to fit the characters drawn on it */
|
||||
u32 texHeight = textureHeight;
|
||||
if (currentImage == currentImages.size() - 1)
|
||||
texHeight = lastTextureHeight;
|
||||
|
||||
/* The texture that holds this "page" of characters */
|
||||
currentImages[currentImage] = Device->getVideoDriver()->createImage(video::ECF_A8R8G8B8, core::dimension2du(textureWidth, texHeight));
|
||||
currentImages[currentImage]->fill(video::SColor(alpha ? 0 : 255,0,0,0));
|
||||
|
||||
for (core::map<wchar_t, u32>::Iterator it = CharMap.getIterator(); !it.atEnd(); it++)
|
||||
{
|
||||
FcChar32 wch = (*it).getKey();
|
||||
s32 currentArea = (*it).getValue();
|
||||
if (Areas[currentArea].sourceimage == currentImage)
|
||||
{
|
||||
SFontArea *fontArea = &Areas[currentArea];
|
||||
u32 chWidth = fontArea->rectangle.LowerRightCorner.X - fontArea->rectangle.UpperLeftCorner.X;
|
||||
u32 chHeight = fontArea->rectangle.LowerRightCorner.Y - fontArea->rectangle.UpperLeftCorner.Y;
|
||||
|
||||
/* Draw the glyph onto the pixmap */
|
||||
XGlyphInfo extents;
|
||||
XftDrawRect(draw, &colBack, 0, 0, chWidth, chHeight);
|
||||
XftTextExtents32(display, font, &wch, 1, &extents);
|
||||
XftDrawString32(draw, &colFore, font, extents.x, extents.y, &wch, 1);
|
||||
|
||||
/* Convert the pixmap into an image, then copy it onto the Irrlicht texture, pixel by pixel.
|
||||
There's bound to be a faster way, but this is adequate */
|
||||
u32 xDest = fontArea->rectangle.UpperLeftCorner.X;
|
||||
u32 yDest = fontArea->rectangle.UpperLeftCorner.Y + font->ascent - extents.y;
|
||||
XImage *image = XGetImage(display, pixmap, 0, 0, chWidth, chHeight, 0xffffff, XYPixmap);
|
||||
if (image)
|
||||
{
|
||||
for (u32 ySrc = 0; ySrc < chHeight; ySrc++)
|
||||
for (u32 xSrc = 0; xSrc < chWidth; xSrc++)
|
||||
{
|
||||
/* Get the pixel colour and break it down into rgb components */
|
||||
u32 col = XGetPixel(image, xSrc, ySrc);
|
||||
u32 a = 255;
|
||||
u32 r = col & visual->red_mask;
|
||||
u32 g = col & visual->green_mask;
|
||||
u32 b = col & visual->blue_mask;
|
||||
while (r > 0xff) r >>= 8;
|
||||
while (g > 0xff) g >>= 8;
|
||||
while (b > 0xff) b >>= 8;
|
||||
|
||||
/* To make the background transparent, set the colour to 100% white and the alpha to
|
||||
the average of the three rgb colour components to maintain the anti-aliasing */
|
||||
if (alpha)
|
||||
{
|
||||
a = (r + g + b) / 3;
|
||||
r = 255;
|
||||
g = 255;
|
||||
b = 255;
|
||||
}
|
||||
currentImages[currentImage]->setPixel(xDest + xSrc,yDest + ySrc,video::SColor(a,r,g,b));
|
||||
}
|
||||
image->f.destroy_image(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the texture to the list */
|
||||
currentTextures[currentImage] = Device->getVideoDriver()->addTexture("GUIFontImage",currentImages[currentImage]);
|
||||
currentTextures[currentImage]->grab();
|
||||
}
|
||||
|
||||
XftColorFree (display, visual, DefaultColormap(display, screen), &colFore);
|
||||
XftColorFree (display, visual, DefaultColormap(display, screen), &colBack);
|
||||
XftFontClose(display,font);
|
||||
XftPatternDestroy(request);
|
||||
XftDrawDestroy(draw);
|
||||
XFreePixmap(display, pixmap);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
CFontTool::~CFontTool()
|
||||
{
|
||||
#ifdef _IRR_WINDOWS_
|
||||
// destroy display context
|
||||
if (dc)
|
||||
DeleteDC(dc);
|
||||
#endif
|
||||
|
||||
// drop textures+images
|
||||
for (u32 i=0; i<currentTextures.size(); ++i)
|
||||
currentTextures[i]->drop();
|
||||
currentTextures.clear();
|
||||
|
||||
for (u32 i=0; i<currentImages.size(); ++i)
|
||||
currentImages[i]->drop();
|
||||
currentImages.clear();
|
||||
}
|
||||
|
||||
bool CFontTool::saveBitmapFont(const c8 *filename, const c8* format)
|
||||
{
|
||||
if (currentImages.size() == 0)
|
||||
{
|
||||
Device->getLogger()->log("No image data to write, aborting.");
|
||||
return false;
|
||||
}
|
||||
|
||||
core::stringc fn = filename;
|
||||
core::stringc imagename = filename;
|
||||
fn += ".xml";
|
||||
|
||||
io::IXMLWriter *writer = Device->getFileSystem()->createXMLWriter(fn.c_str());
|
||||
|
||||
// header and line breaks
|
||||
writer->writeXMLHeader();
|
||||
writer->writeLineBreak();
|
||||
|
||||
// write information
|
||||
writer->writeElement(L"font", false, L"type", L"bitmap");
|
||||
writer->writeLineBreak();
|
||||
writer->writeLineBreak();
|
||||
|
||||
// write images and link to them
|
||||
// Only use the offset if Asian fonts are created.
|
||||
u32 offset_for_asian_fonts=has_pot_files ? 100 : 0;
|
||||
for (u32 i=0; i<currentImages.size(); ++i)
|
||||
{
|
||||
imagename = filename;
|
||||
imagename += (s32)i;
|
||||
imagename += ".";
|
||||
imagename += format;
|
||||
Device->getVideoDriver()->writeImageToFile(currentImages[i],imagename.c_str());
|
||||
|
||||
writer->writeElement(L"Texture", true,
|
||||
L"index", core::stringw(i+offset_for_asian_fonts).c_str(),
|
||||
L"filename", core::stringw(imagename.c_str()).c_str(),
|
||||
L"hasAlpha", UseAlphaChannel ? L"true" : L"false");
|
||||
writer->writeLineBreak();
|
||||
}
|
||||
|
||||
writer->writeLineBreak();
|
||||
|
||||
// write each character
|
||||
core::map<wchar_t, u32>::Iterator it = CharMap.getIterator();
|
||||
while (!it.atEnd())
|
||||
{
|
||||
SFontArea &fa = Areas[(*it).getValue()];
|
||||
|
||||
wchar_t c[2];
|
||||
c[0] = (*it).getKey();
|
||||
c[1] = L'\0';
|
||||
core::stringw area, under, over, image;
|
||||
area = core::stringw(fa.rectangle.UpperLeftCorner.X);
|
||||
area += L", ";
|
||||
area += fa.rectangle.UpperLeftCorner.Y;
|
||||
area += L", ";
|
||||
area += fa.rectangle.LowerRightCorner.X;
|
||||
area += L", ";
|
||||
area += fa.rectangle.LowerRightCorner.Y;
|
||||
|
||||
core::array<core::stringw> names;
|
||||
core::array<core::stringw> values;
|
||||
names.clear();
|
||||
values.clear();
|
||||
// char
|
||||
names.push_back(core::stringw(L"c"));
|
||||
values.push_back(core::stringw(c));
|
||||
// image number
|
||||
if (fa.sourceimage+offset_for_asian_fonts != 0)
|
||||
{
|
||||
image = core::stringw(fa.sourceimage+offset_for_asian_fonts);
|
||||
names.push_back(core::stringw(L"i"));
|
||||
values.push_back(image);
|
||||
}
|
||||
// rectangle
|
||||
names.push_back(core::stringw(L"r"));
|
||||
values.push_back(area);
|
||||
|
||||
if (fa.underhang != 0)
|
||||
{
|
||||
under = core::stringw(fa.underhang);
|
||||
names.push_back(core::stringw(L"u"));
|
||||
values.push_back(under);
|
||||
}
|
||||
if (fa.overhang != 0)
|
||||
{
|
||||
over = core::stringw(fa.overhang);
|
||||
names.push_back(core::stringw(L"o"));
|
||||
values.push_back(over);
|
||||
}
|
||||
writer->writeElement(L"c", true, names, values);
|
||||
|
||||
writer->writeLineBreak();
|
||||
it++;
|
||||
}
|
||||
|
||||
writer->writeClosingTag(L"font");
|
||||
|
||||
writer->drop();
|
||||
|
||||
Device->getLogger()->log("Bitmap font saved.");
|
||||
|
||||
return true;
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
#ifndef __IRR_FONT_TOOL_INCLUDED__
|
||||
#define __IRR_FONT_TOOL_INCLUDED__
|
||||
|
||||
|
||||
#include "irrlicht.h"
|
||||
|
||||
#if defined(_IRR_WINDOWS_)
|
||||
#ifdef _MBCS
|
||||
#undef _MBCS
|
||||
#endif
|
||||
|
||||
#define UNICODE
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#include "windows.h"
|
||||
#else
|
||||
#ifdef _IRR_COMPILE_WITH_X11_
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
#include <X11/Xft/Xft.h>
|
||||
#include <set>
|
||||
#endif
|
||||
|
||||
bool LoadPoFiles(const char* sListFileName);
|
||||
bool setUsedCharacters(const char* characters);
|
||||
|
||||
namespace irr {
|
||||
class CFontTool : public irr::IReferenceCounted
|
||||
{
|
||||
public:
|
||||
CFontTool(irr::IrrlichtDevice* device);
|
||||
~CFontTool();
|
||||
|
||||
virtual bool makeBitmapFont(u32 fontIndex, u32 charsetIndex,
|
||||
s32 fontSize, u32 texturewidth, u32 textureHeight,
|
||||
bool bold, bool italic, bool aa, bool alpha,
|
||||
bool usedOnly=false,bool exclideLatin=false);
|
||||
|
||||
virtual bool saveBitmapFont(const c8* filename, const c8* format);
|
||||
|
||||
virtual void selectCharSet(u32 currentCharSet);
|
||||
|
||||
struct SFontArea
|
||||
{
|
||||
SFontArea() : rectangle(), underhang(0), overhang(0), sourceimage(0) {}
|
||||
core::rect<s32> rectangle;
|
||||
s32 underhang;
|
||||
s32 overhang;
|
||||
u32 sourceimage;
|
||||
};
|
||||
|
||||
/* struct SFontMap
|
||||
{
|
||||
SFontMap() : areas(), start(0), count(0) {}
|
||||
core::array< SFontArea > areas;
|
||||
s32 start;
|
||||
s32 count;
|
||||
};*/
|
||||
|
||||
core::array<core::stringw> FontNames;
|
||||
core::array<core::stringw> CharSets;
|
||||
//core::array<SFontMap> Mappings;
|
||||
core::array<SFontArea> Areas;
|
||||
core::map<wchar_t, u32> CharMap;
|
||||
|
||||
core::array<video::ITexture*> currentTextures;
|
||||
core::array<video::IImage*> currentImages;
|
||||
const int *FontSizes;
|
||||
IrrlichtDevice *Device;
|
||||
|
||||
bool UseAlphaChannel;
|
||||
|
||||
// windows
|
||||
#ifdef _IRR_WINDOWS_
|
||||
HDC dc;
|
||||
#endif
|
||||
|
||||
};
|
||||
}
|
||||
#endif // __IRR_FONT_TOOL_INCLUDED__
|
@ -1,39 +0,0 @@
|
||||
option(FONT_TOOL "Compile font tool (only useful for developers)" OFF)
|
||||
mark_as_advanced(FONT_TOOL)
|
||||
|
||||
if(FONT_TOOL)
|
||||
if(MSVC)
|
||||
add_executable(font_tool CFontTool.cpp main.cpp)
|
||||
target_link_libraries(font_tool stkirrlicht)
|
||||
else()
|
||||
find_package(Freetype)
|
||||
find_library(FONTCONFIG_LIBRARY fontconfig)
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Xrandr REQUIRED)
|
||||
find_package(X11 REQUIRED)
|
||||
include_directories(${X11_INCLUDE_DIR})
|
||||
if(NOT XRANDR_FOUND)
|
||||
message(STATUS "XRANDR not found.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(FREETYPE_FOUND)
|
||||
include_directories(${FREETYPE_INCLUDE_DIRS})
|
||||
add_executable(font_tool CFontTool.cpp main.cpp)
|
||||
|
||||
target_link_libraries(font_tool stkirrlicht)
|
||||
target_link_libraries(font_tool ${FREETYPE_LIBRARIES})
|
||||
target_link_libraries(font_tool ${OPENGL_LIBRARIES})
|
||||
target_link_libraries(font_tool ${FONTCONFIG_LIBRARY})
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(font_tool ${XRANDR_LIBRARIES})
|
||||
target_link_libraries(font_tool ${X11_Xft_LIB} Xxf86vm)
|
||||
target_link_libraries(font_tool ${X11_LIBRARIES})
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Freetype was not found, the font tool won't be built (only useful for developers)")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Font tool deactivated, the font tool won't be built (only useful for developers)")
|
||||
endif()
|
File diff suppressed because it is too large
Load Diff
@ -1,20 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Font Tool", "irrFontTool_v9.vcproj", "{4D53E40F-37E3-42B1-8848-F4C6F8313A17}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4D53E40F-37E3-42B1-8848-F4C6F8313A17}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4D53E40F-37E3-42B1-8848-F4C6F8313A17}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4D53E40F-37E3-42B1-8848-F4C6F8313A17}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4D53E40F-37E3-42B1-8848-F4C6F8313A17}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,204 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="Font Tool"
|
||||
ProjectGUID="{4D53E40F-37E3-42B1-8848-F4C6F8313A17}"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../lib/irrlicht/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_IRR_STATIC_LIB_"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions=" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib glu32.lib opengl32.lib gdi32.lib"
|
||||
AdditionalDependencies="Irrlicht.lib"
|
||||
OutputFile="../../font_tool.exe"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../lib/irrlicht/lib/Win32-visualstudio"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/TestProject.pdb"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
WholeProgramOptimization="false"
|
||||
AdditionalIncludeDirectories="../../lib/irrlicht/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_IRR_STATIC_LIB_"
|
||||
MinimalRebuild="true"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions=" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib glu32.lib opengl32.lib gdi32.lib"
|
||||
AdditionalDependencies="Irrlicht.lib"
|
||||
OutputFile="../../FontTool.exe"
|
||||
LinkIncremental="0"
|
||||
AdditionalLibraryDirectories="../../lib/irrlicht/lib/Win32-visualstudio"
|
||||
GenerateDebugInformation="false"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
LinkTimeCodeGeneration="0"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\CFontTool.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CFontTool.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\CVectorFontTool.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\main.cpp"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,592 +0,0 @@
|
||||
/*
|
||||
Tool for creating Irrlicht bitmap+vector fonts,
|
||||
started by Gaz Davidson in December 2006
|
||||
|
||||
Due to my laziness and Microsoft's unituitive API, surragate pairs and
|
||||
nonspacing diacritical marks are not supported!
|
||||
|
||||
Linux bitmap font support added by Neil Burlock Oct 2008
|
||||
Note: Xft/Freetype2 is used to render the fonts under X11. Anti-aliasing
|
||||
is controlled by the system and cannot be overriden by an application,
|
||||
so fonts that are rendered will be aliased or anti-aliased depending
|
||||
on the system that they are created on.
|
||||
|
||||
acme_pjz modified the original irrlicht font tool to only write the
|
||||
characters needed in a list of .po files - which saves huge amount
|
||||
of space for Asian fonts.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <irrlicht.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "CFontTool.h"
|
||||
#include "CVectorFontTool.h"
|
||||
#include "ITexture.h"
|
||||
|
||||
using namespace irr;
|
||||
using namespace gui;
|
||||
|
||||
#if DEBUG
|
||||
bool GLContextDebugBit = true;
|
||||
#else
|
||||
bool GLContextDebugBit = false;
|
||||
#endif
|
||||
|
||||
const int WIDTH = 1024;
|
||||
const int HEIGHT = 768;
|
||||
|
||||
const s32 texturesizes[] = {128, 256, 512, 1024, 2048, 4096, 0};
|
||||
|
||||
const wchar_t *fileformats[] = { L"bmp", L"ppm", 0 }; // bitmap font formats
|
||||
const wchar_t *alphafileformats[] = { L"png", L"tga", 0 }; // bitmap font formats which support alpha channels
|
||||
const wchar_t *vectorfileformats[] = { L"xml", L"bin", 0 }; // file formats for vector fonts
|
||||
|
||||
const wchar_t *warntext = L"Legal Notice\n"
|
||||
L"------------\n\n"
|
||||
L"When making bitmap and vector fonts, you should consider the potential legal "
|
||||
L"issues with redistributing the fonts with your software; this tool basically "
|
||||
L"copies font data and some authors might not like this!\n"
|
||||
L"If you purchased fonts or they came with an application or your OS, you'll have"
|
||||
L"to check the license to see what restrictions are placed on making derivative works.\n\n"
|
||||
L"PD and the OFL\n"
|
||||
L"--------------\n\n"
|
||||
L"You'll find lots of fonts on the web listed as Public Domain, you can do what you like "
|
||||
L"with these.\n"
|
||||
L"Many fonts are released under the Open Font License, which is a 'viral' open source "
|
||||
L"license like the GPL. It's worth reading the license here: http://scripts.sil.org/OFL\n"
|
||||
L"The most important restrictions are- you must include the original font's license, you "
|
||||
L"can't stop your users from using or distributing the font, the font must have a "
|
||||
L"different name the original.\n\n"
|
||||
L"Some free fonts can be found here- www.openfontlibrary.org\n"
|
||||
L"http://savannah.nongnu.org/projects/freefont/";
|
||||
|
||||
const wchar_t *helptext = L"This tool creates bitmap fonts for the Irrlicht Engine\n\n"
|
||||
|
||||
L"First select a character encoding from the list, then choose the font, "
|
||||
L"size, and whether you'd like bold, italic, antialiasing and an alpha channel. "
|
||||
L"In Windows, antialiasing will be ignored for small fonts\n\n"
|
||||
|
||||
L"Then select a texture width and height. If the output exceeds this then more than "
|
||||
L"one image will be created. You can use the scrollbar at the top of the screen to "
|
||||
L"preview them. Most modern graphics cards will support up to 2048x2048, "
|
||||
L"keep in mind that more images means worse performance when drawing text!\n\n"
|
||||
|
||||
L"If you want a vector font rather than a bitmap font, check the vector box. "
|
||||
L"Vector fonts are stored in system memory while bitmap fonts are in video ram\n\n"
|
||||
|
||||
L"Click create to preview your font, this may take lots of time and memory "
|
||||
L"when making a font with a lot of characters, please be patient!\n\n"
|
||||
|
||||
L"Now you're ready to give your font a name, select a format and click save.\n\n"
|
||||
L"To load your font in Irrlicht, simply use env->getFont(\"Myfont.xml\");\n\n"
|
||||
|
||||
L"That's all, have fun :-)";
|
||||
|
||||
#ifdef _IRR_WINDOWS
|
||||
const wchar_t *completeText = L"Font created"
|
||||
#else
|
||||
const wchar_t *completeText = L"Font created\n\n"
|
||||
L"Please note that anti-aliasing under X11 is controlled by the system "
|
||||
L"configuration, so if your system is set to use anti-aliasing, then so "
|
||||
L"will any fonts you create with FontTool";
|
||||
#endif
|
||||
|
||||
enum MYGUI
|
||||
{
|
||||
MYGUI_CHARSET = 100,
|
||||
MYGUI_FONTNAME,
|
||||
MYGUI_SIZE,
|
||||
MYGUI_TEXWIDTH,
|
||||
MYGUI_TEXHEIGHT,
|
||||
MYGUI_BOLD,
|
||||
MYGUI_ITALIC,
|
||||
MYGUI_ANTIALIAS,
|
||||
MYGUI_ALPHA,
|
||||
MYGUI_VECTOR,
|
||||
MYGUI_FILENAME,
|
||||
MYGUI_FORMAT,
|
||||
MYGUI_CREATE,
|
||||
MYGUI_SAVE,
|
||||
MYGUI_IMAGE,
|
||||
MYGUI_CURRENTIMAGE,
|
||||
MYGUI_HELPBUTTON
|
||||
};
|
||||
|
||||
|
||||
// event reciever
|
||||
class MyEventReceiver : public IEventReceiver
|
||||
{
|
||||
public:
|
||||
|
||||
MyEventReceiver(IrrlichtDevice* device, CFontTool*& fonttool, CVectorFontTool* &vectool) :
|
||||
Device(device), FontTool(fonttool), VecTool(vectool)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool OnEvent(const SEvent &event)
|
||||
{
|
||||
if (event.EventType == EET_GUI_EVENT)
|
||||
{
|
||||
s32 id = event.GUIEvent.Caller->getID();
|
||||
IGUIEnvironment* env = Device->getGUIEnvironment();
|
||||
|
||||
switch(event.GUIEvent.EventType)
|
||||
{
|
||||
case EGET_SCROLL_BAR_CHANGED:
|
||||
if (id == MYGUI_CURRENTIMAGE)
|
||||
{
|
||||
IGUIImage* img = (IGUIImage*)env->getRootGUIElement()->getElementFromId(MYGUI_IMAGE,true);
|
||||
s32 i = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
|
||||
img->setImage(FontTool->currentTextures[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case EGET_COMBO_BOX_CHANGED:
|
||||
if (id == MYGUI_CHARSET)
|
||||
{
|
||||
IGUIComboBox* cbo = (IGUIComboBox*)event.GUIEvent.Caller;
|
||||
IGUIComboBox* cbo_1 = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_FONTNAME,true);
|
||||
core::stringw str=FontTool->FontNames[cbo_1->getSelected()];
|
||||
u32 j=0;
|
||||
FontTool->selectCharSet(cbo->getSelected());
|
||||
// rebuild font list
|
||||
cbo = cbo_1;
|
||||
cbo->clear();
|
||||
for (u32 i=0; i < FontTool->FontNames.size(); ++i){
|
||||
cbo->addItem(FontTool->FontNames[i].c_str());
|
||||
if(FontTool->FontNames[i]==str) j=i;
|
||||
}
|
||||
cbo->setSelected(j);
|
||||
return true;
|
||||
}
|
||||
else if(id==MYGUI_FONTNAME){
|
||||
IGUIComboBox* cbo = (IGUIComboBox*)event.GUIEvent.Caller;
|
||||
std::cout << FontTool->FontNames[cbo->getSelected()].c_str() << std::endl;
|
||||
}
|
||||
break;
|
||||
case EGET_CHECKBOX_CHANGED:
|
||||
if (id == MYGUI_VECTOR)
|
||||
{
|
||||
IGUICheckBox* chk = (IGUICheckBox*)event.GUIEvent.Caller;
|
||||
|
||||
IGUIComboBox *cbo = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_FORMAT,true);
|
||||
cbo->clear();
|
||||
|
||||
if (chk->isChecked() && VecTool)
|
||||
{
|
||||
// vector formats
|
||||
for (s32 i=0; fileformats[i] != 0; ++i)
|
||||
cbo->addItem( core::stringw(vectorfileformats[i]).c_str());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// bitmap formats
|
||||
if (!FontTool->UseAlphaChannel)
|
||||
{
|
||||
// add non-alpha formats
|
||||
for (s32 i=0; fileformats[i] != 0; ++i)
|
||||
cbo->addItem( core::stringw(fileformats[i]).c_str());
|
||||
}
|
||||
// add formats which support alpha
|
||||
for (s32 i=0; alphafileformats[i] != 0; ++i)
|
||||
cbo->addItem( core::stringw(alphafileformats[i]).c_str());
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case EGET_BUTTON_CLICKED:
|
||||
|
||||
if (id == MYGUI_CREATE)
|
||||
{
|
||||
// create the font with the params
|
||||
IGUIComboBox* cbo = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_CHARSET, true);
|
||||
int charset = cbo->getSelected();
|
||||
|
||||
cbo = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_FONTNAME,true);
|
||||
int fontname = cbo->getSelected();
|
||||
|
||||
/*
|
||||
cbo = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_SIZE,true);
|
||||
int fontsize = cbo->getSelected();
|
||||
*/
|
||||
|
||||
int fontsize=wcstol(((IGUIEditBox*)env->getRootGUIElement()->getElementFromId(MYGUI_SIZE,true))->getText(),NULL,10);
|
||||
|
||||
cbo = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_TEXWIDTH,true);
|
||||
int texwidth = cbo->getSelected();
|
||||
|
||||
cbo = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_TEXHEIGHT,true);
|
||||
int texheight = cbo->getSelected();
|
||||
|
||||
IGUICheckBox* chk = (IGUICheckBox*)env->getRootGUIElement()->getElementFromId(MYGUI_BOLD,true);
|
||||
bool bold = chk->isChecked();
|
||||
chk = (IGUICheckBox*)env->getRootGUIElement()->getElementFromId(MYGUI_ITALIC,true);
|
||||
bool italic = chk->isChecked();
|
||||
|
||||
chk = (IGUICheckBox*)env->getRootGUIElement()->getElementFromId(MYGUI_ALPHA,true);
|
||||
bool alpha = chk->isChecked();
|
||||
|
||||
chk = (IGUICheckBox*)env->getRootGUIElement()->getElementFromId(MYGUI_ANTIALIAS,true);
|
||||
bool aa = chk->isChecked();
|
||||
|
||||
chk = (IGUICheckBox*)env->getRootGUIElement()->getElementFromId(201,true);
|
||||
bool usedOnly = chk->isChecked();
|
||||
|
||||
chk = (IGUICheckBox*)env->getRootGUIElement()->getElementFromId(202,true);
|
||||
bool excludeLatin = chk->isChecked();
|
||||
|
||||
// vector fonts disabled
|
||||
//chk = (IGUICheckBox*)env->getRootGUIElement()->getElementFromId(MYGUI_VECTOR,true);
|
||||
bool vec = false;//chk->isChecked();
|
||||
|
||||
FontTool->makeBitmapFont(fontname, charset, /*FontTool->FontSizes[fontsize]*/ fontsize, texturesizes[texwidth], texturesizes[texheight], bold, italic, aa, alpha, usedOnly, excludeLatin);
|
||||
|
||||
IGUIScrollBar* scrl = (IGUIScrollBar*)env->getRootGUIElement()->getElementFromId(MYGUI_CURRENTIMAGE,true);
|
||||
scrl->setMax(FontTool->currentTextures.size() == 0 ? 0 : FontTool->currentTextures.size()-1);
|
||||
|
||||
if (FontTool->currentTextures.size() > 0)
|
||||
{
|
||||
IGUIImage* img = (IGUIImage*)env->getRootGUIElement()->getElementFromId(MYGUI_IMAGE,true);
|
||||
img->setImage(FontTool->currentTextures[0]);
|
||||
scrl->setPos(0);
|
||||
}
|
||||
|
||||
// make sure users pick a file format that supports alpha channel
|
||||
cbo = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_FORMAT,true);
|
||||
cbo->clear();
|
||||
|
||||
if (vec)
|
||||
{
|
||||
// add vector formats
|
||||
for (s32 i=0; fileformats[i] != 0; ++i)
|
||||
cbo->addItem( core::stringw(vectorfileformats[i]).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!alpha)
|
||||
{
|
||||
// add non-alpha formats
|
||||
for (s32 i=0; fileformats[i] != 0; ++i)
|
||||
cbo->addItem( core::stringw(fileformats[i]).c_str());
|
||||
}
|
||||
// add formats which support alpha
|
||||
for (s32 i=0; alphafileformats[i] != 0; ++i)
|
||||
cbo->addItem( core::stringw(alphafileformats[i]).c_str());
|
||||
}
|
||||
if (VecTool)
|
||||
{
|
||||
delete VecTool;
|
||||
VecTool = 0;
|
||||
}
|
||||
if (vec)
|
||||
{
|
||||
VecTool = new CVectorFontTool(FontTool);
|
||||
}
|
||||
|
||||
/* Message box letting the user know the process is complete */
|
||||
env->addMessageBox(L"Create", completeText);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id == MYGUI_SAVE)
|
||||
{
|
||||
IGUIEditBox *edt = (IGUIEditBox*)env->getRootGUIElement()->getElementFromId(MYGUI_FILENAME,true);
|
||||
core::stringc name = edt->getText();
|
||||
|
||||
IGUIComboBox *fmt = (IGUIComboBox*)env->getRootGUIElement()->getElementFromId(MYGUI_FORMAT,true);
|
||||
core::stringc format = fmt->getItem(fmt->getSelected());
|
||||
|
||||
// vector fonts disabled
|
||||
// IGUICheckBox *chk = (IGUICheckBox*)env->getRootGUIElement()->getElementFromId(MYGUI_VECTOR,true);
|
||||
// bool vec = chk->isChecked();
|
||||
bool vec = false;
|
||||
|
||||
if (vec && VecTool)
|
||||
VecTool->saveVectorFont(name.c_str(), format.c_str());
|
||||
else
|
||||
FontTool->saveBitmapFont(name.c_str(), format.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id == MYGUI_HELPBUTTON)
|
||||
{
|
||||
env->addMessageBox(L"Irrlicht Unicode Font Tool", helptext);
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
IrrlichtDevice* Device;
|
||||
CFontTool* FontTool;
|
||||
CVectorFontTool* VecTool;
|
||||
|
||||
};
|
||||
|
||||
void createGUI(IrrlichtDevice* device, CFontTool* fc)
|
||||
{
|
||||
// Scaling factor to allow a larger font to be used
|
||||
float scale = 2.0f;
|
||||
io::path previous_cwd = device->getFileSystem()->getWorkingDirectory();
|
||||
|
||||
gui::IGUIEnvironment *env = device->getGUIEnvironment();
|
||||
gui::IGUIFont *font = env->getFont(io::path("../../../data/fonts/StkFont.xml"));
|
||||
device->getGUIEnvironment()->getSkin()->setFont(font);
|
||||
|
||||
//env->getSkin()->setSize((gui::EGUI_DEFAULT_SIZE, 24);
|
||||
// change transparency of skin
|
||||
for (s32 i=0; i<gui::EGDC_COUNT ; ++i)
|
||||
{
|
||||
video::SColor col = env->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);
|
||||
col.setAlpha(255);
|
||||
env->getSkin()->setColor((gui::EGUI_DEFAULT_COLOR)i, col);
|
||||
}
|
||||
|
||||
IGUIWindow *win = env->addWindow( core::rect<s32>(10,HEIGHT/30,int(scale*WIDTH)/4,HEIGHT-100), false, L"Font Creator");
|
||||
win->getCloseButton()->setVisible(false);
|
||||
|
||||
s32 xs=10,xp=xs, yp=HEIGHT/20, h=HEIGHT/20;
|
||||
|
||||
env->addStaticText(L"Charset", core::rect<s32>(int(scale*xp),yp,int(scale*90),yp+h),false,false, win);
|
||||
|
||||
xp+=60;
|
||||
|
||||
// charset combo
|
||||
gui::IGUIComboBox* cbo = env->addComboBox( core::rect<s32>(int(scale*xp),yp,int(scale*180),yp+h),win, MYGUI_CHARSET);
|
||||
for (u32 i=0; i < fc->CharSets.size(); ++i)
|
||||
cbo->addItem(fc->CharSets[i].c_str());
|
||||
|
||||
yp += (s32)(h*1.5f);
|
||||
xp = xs;
|
||||
|
||||
env->addStaticText(L"Font", core::rect<s32>(int(scale*xp),yp,int(scale*50),yp+h),false,false, win);
|
||||
|
||||
xp+=60;
|
||||
|
||||
// font name combo
|
||||
cbo = env->addComboBox( core::rect<s32>(int(scale*xp),yp,int(scale*180),yp+h),win, MYGUI_FONTNAME);
|
||||
for (u32 i=0; i < fc->FontNames.size(); ++i){
|
||||
cbo->addItem(fc->FontNames[i].c_str());
|
||||
if(fc->FontNames[i] == L"\u6587\u6CC9\u9A7F\u5FAE\u7C73\u9ED1") cbo->setSelected(i); //auto select wqy-microhei
|
||||
}
|
||||
|
||||
yp += (s32)(h*1.5f);
|
||||
xp = xs;
|
||||
|
||||
env->addStaticText(L"Size", core::rect<s32>(int(scale*xp),yp,int(scale*(50+xp)),yp+h),false,false, win);
|
||||
|
||||
xp += 60;
|
||||
|
||||
/*
|
||||
// font size combo
|
||||
cbo = env->addComboBox( core::rect<s32>(xp,yp,xp+50,yp+h),win, MYGUI_SIZE);
|
||||
for (s32 i=0; fc->FontSizes[i] != 0; ++i)
|
||||
cbo->addItem( ((core::stringw(fc->FontSizes[i])) + L"pt").c_str()); */
|
||||
|
||||
env->addEditBox(L"24",core::rect<s32>(int(scale*xp),yp,int(scale*(xp+70)),yp+h), true, win, MYGUI_SIZE);
|
||||
xp += int(scale*80);
|
||||
env->addStaticText(L"pt", core::rect<s32>(xp,yp,xp+50,yp+h),false,false,win);
|
||||
|
||||
xp = xs;
|
||||
yp += (s32)(h*1.5f);
|
||||
|
||||
// bold checkbox
|
||||
env->addCheckBox(false, core::rect<s32>(xp,yp,int(scale*(xp+50)),yp+h),win, MYGUI_BOLD, L"Bold");
|
||||
|
||||
xp += int(45*scale);
|
||||
|
||||
// italic checkbox
|
||||
env->addCheckBox(false, core::rect<s32>(xp,yp,int(scale*(xp+50)),yp+h),win, MYGUI_ITALIC, L"Italic");
|
||||
|
||||
xp += int(55*scale);
|
||||
|
||||
// AA checkbox
|
||||
env->addCheckBox(false, core::rect<s32>(xp,yp,int(scale*(xp+50)),yp+h),win, MYGUI_ANTIALIAS, L"AA");
|
||||
|
||||
xp += int(scale * 40);
|
||||
|
||||
// Alpha checkbox
|
||||
env->addCheckBox(false, core::rect<s32>(xp,yp,int(scale*(xp+50)),yp+h),win, MYGUI_ALPHA, L"Alpha");
|
||||
|
||||
xp = xs;
|
||||
yp += (s32)(h*1.5f);
|
||||
|
||||
//new
|
||||
|
||||
env->addCheckBox(false, core::rect<s32>(xp,yp,int(scale*(xp+200)),yp+h),win, 201, L"Only used characters")->setChecked(false);
|
||||
yp += (s32)(h*1.5f);
|
||||
|
||||
env->addCheckBox(false, core::rect<s32>(xp,yp,int(scale*(xp+200)),yp+h),win, 202, L"Exclude basic latin");
|
||||
yp += (s32)(h*1.5f);
|
||||
|
||||
/*
|
||||
// vector fonts can't be loaded yet
|
||||
env->addCheckBox(false, core::rect<s32>(xp,yp,xp+200,yp+h),win, MYGUI_VECTOR, L"Vector Font");
|
||||
|
||||
yp += (s32)(h*1.5f);
|
||||
*/
|
||||
|
||||
env->addStaticText(L"Max Width:", core::rect<s32>(xp,yp,int(scale*100),yp+h),false,false, win);
|
||||
|
||||
xp += int(scale*90);
|
||||
|
||||
// texture widths
|
||||
cbo = env->addComboBox( core::rect<s32>(xp,yp,xp+int(scale*80),yp+h),win, MYGUI_TEXWIDTH);
|
||||
for (s32 i=0; texturesizes[i] != 0; ++i)
|
||||
cbo->addItem( ((core::stringw(texturesizes[i])) + L" wide").c_str());
|
||||
cbo->setSelected(2); // 128, 256, 512 --> make 512 the default
|
||||
xp=xs;
|
||||
yp += (s32)(h*1.5f);
|
||||
|
||||
env->addStaticText(L"Max Height:", core::rect<s32>(xp,yp,int(scale*100),yp+h),false,false, win);
|
||||
|
||||
xp += int(scale*90);
|
||||
|
||||
// texture height
|
||||
cbo = env->addComboBox( core::rect<s32>(xp,yp,xp+int(scale*80),yp+h),win, MYGUI_TEXHEIGHT);
|
||||
for (s32 i=0; texturesizes[i] != 0; ++i)
|
||||
cbo->addItem( ((core::stringw(texturesizes[i])) + L" tall").c_str());
|
||||
cbo->setSelected(2); // 512 as default
|
||||
// file name
|
||||
xp = xs;
|
||||
yp += (s32)(h*1.5f);
|
||||
env->addStaticText(L"Filename", core::rect<s32>(xp,yp,int(scale*100),yp+h),false,false, win);
|
||||
xp += int(scale*90);
|
||||
env->addEditBox(L"wqyMicroHei",core::rect<s32>(xp,yp,xp+int(scale*80),yp+h), true, win, MYGUI_FILENAME);
|
||||
|
||||
// file format
|
||||
xp = xs;
|
||||
yp += (s32)(h*1.5f);
|
||||
env->addStaticText(L"File Format", core::rect<s32>(xp,yp,int(scale*100),yp+h),false,false, win);
|
||||
xp += int(scale*90);
|
||||
|
||||
cbo = env->addComboBox( core::rect<s32>(xp,yp,xp+int(scale*80),yp+h),win, MYGUI_FORMAT);
|
||||
for (s32 i=0; fileformats[i] != 0; ++i)
|
||||
cbo->addItem( core::stringw(fileformats[i]).c_str());
|
||||
for (s32 i=0; alphafileformats[i] != 0; ++i)
|
||||
cbo->addItem( core::stringw(alphafileformats[i]).c_str());
|
||||
cbo->setSelected(2); // bmp, ppm, png, ... --> select pn
|
||||
xp = xs;
|
||||
yp += h*2;
|
||||
|
||||
// create button
|
||||
env->addButton( core::rect<s32>(xp,yp,int(scale*(xp+50)),yp+h),win, MYGUI_CREATE, L"Create");
|
||||
|
||||
xp += int(scale*60);
|
||||
|
||||
// save button
|
||||
env->addButton( core::rect<s32>(xp,yp,xp+int(scale*50),yp+h),win, MYGUI_SAVE, L"Save");
|
||||
|
||||
xp += int(scale*60);
|
||||
|
||||
// help button
|
||||
env->addButton( core::rect<s32>(xp,yp,xp+int(scale*50),yp+h),win, MYGUI_HELPBUTTON, L"Help");
|
||||
|
||||
// font image
|
||||
gui::IGUIImage *img = env->addImage(0, core::position2d<s32>(0,0), true,0, MYGUI_IMAGE);
|
||||
img->setRelativePosition(core::rect<s32>(0,HEIGHT/30,WIDTH,HEIGHT));
|
||||
|
||||
// font scrollbar
|
||||
IGUIScrollBar *scrl= env->addScrollBar(true,core::rect<s32>(0,0,WIDTH,HEIGHT/30),0, MYGUI_CURRENTIMAGE);
|
||||
scrl->setMax(0);
|
||||
scrl->setSmallStep(1);
|
||||
|
||||
yp += h*3;
|
||||
|
||||
env->getRootGUIElement()->bringToFront(win);
|
||||
win->setRelativePosition( core::rect<s32>(0,HEIGHT/30,int(scale*200),yp));
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
SIrrlichtCreationParameters p;
|
||||
p.DriverType = video::EDT_OPENGL;
|
||||
p.WindowSize = core::dimension2du(WIDTH, HEIGHT);
|
||||
p.Bits = 16;
|
||||
p.Fullscreen = false;
|
||||
p.Stencilbuffer = false;
|
||||
p.Vsync = false;
|
||||
p.EventReceiver = NULL;
|
||||
p.FileSystem = NULL;
|
||||
p.ForceLegacyDevice = true;
|
||||
|
||||
IrrlichtDevice *device = createDeviceEx(p);
|
||||
|
||||
video::IVideoDriver* driver = device->getVideoDriver();
|
||||
scene::ISceneManager* smgr = device->getSceneManager();
|
||||
gui::IGUIEnvironment *env = device->getGUIEnvironment();
|
||||
|
||||
// create font tool
|
||||
CFontTool *fc = new CFontTool(device);
|
||||
CVectorFontTool *vc = 0;
|
||||
|
||||
MyEventReceiver events(device,fc,vc);
|
||||
device->setEventReceiver(&events);
|
||||
|
||||
createGUI(device, fc);
|
||||
|
||||
for(int i=1; i<argc; i++)
|
||||
{
|
||||
if(!strcmp(argv[i],"-c") && i<argc-1)
|
||||
{
|
||||
i++;
|
||||
if(setUsedCharacters(argv[i]))
|
||||
{
|
||||
IGUICheckBox *box =
|
||||
dynamic_cast<IGUICheckBox*>(device->getGUIEnvironment()
|
||||
->getRootGUIElement()
|
||||
->getElementFromId(201, true));
|
||||
box->setChecked(true);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Old style: just a single parameter, assume it's a file name with pot files in it
|
||||
if(LoadPoFiles(argv[i]))
|
||||
{
|
||||
IGUICheckBox *box =
|
||||
dynamic_cast<IGUICheckBox*>(device->getGUIEnvironment()
|
||||
->getRootGUIElement()
|
||||
->getElementFromId(201, true));
|
||||
box->setChecked(true);
|
||||
}
|
||||
}
|
||||
} // for i <argc
|
||||
|
||||
while(device->run())
|
||||
{
|
||||
device->sleep(50);
|
||||
if (device->isWindowActive())
|
||||
{
|
||||
|
||||
driver->beginScene(true, true, video::SColor(0,200,200,200));
|
||||
smgr->drawAll();
|
||||
env->drawAll();
|
||||
driver->endScene();
|
||||
}
|
||||
}
|
||||
|
||||
// drop the font tool and resources
|
||||
fc->drop();
|
||||
|
||||
device->drop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
data/po/ko.po
|
||||
data/po/vi.po
|
||||
data/po/zh_CN.po
|
||||
data/po/zh_TW.po
|
||||
data/po/uk.po
|
||||
data/po/ky.po
|
Loading…
Reference in New Issue
Block a user