Remove the font tool, which is no longer necessary

This commit is contained in:
Marianne Gagnon 2015-10-18 20:10:31 -04:00
parent 6d365032f3
commit dd975de74f
9 changed files with 0 additions and 3005 deletions

View File

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

View File

@ -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, &currentchar, 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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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