Compare commits

...

2 Commits

Author SHA1 Message Date
sfan5
853939405b Add XMLFontConverter source file 2021-11-09 22:19:35 +01:00
sfan5
9b0bc2aaed Readd simple text format to replace bitmap font XML 2021-11-09 22:19:05 +01:00
4 changed files with 216 additions and 129 deletions

@ -1278,7 +1278,8 @@ IGUIFont* CGUIEnvironment::getFont(const io::path& filename)
} }
IGUIFont* ifont=0; IGUIFont* ifont=0;
#if 0 io::IReadFile *file = FileSystem->createAndOpenFile(filename);
if (file)
{ {
CGUIFont* font = new CGUIFont(this, filename); CGUIFont* font = new CGUIFont(this, filename);
ifont = (IGUIFont*)font; ifont = (IGUIFont*)font;
@ -1286,15 +1287,14 @@ IGUIFont* CGUIEnvironment::getFont(const io::path& filename)
// load the font // load the font
io::path directory; io::path directory;
core::splitFilename(filename, &directory); core::splitFilename(filename, &directory);
if (!font->load(xml, directory)) if (!font->load(file, directory))
{ {
font->drop(); font->drop();
font = 0; font = 0;
ifont = 0; ifont = 0;
} }
file->drop();
} }
#endif
if (!ifont) if (!ifont)
{ {

@ -6,6 +6,7 @@
#ifdef _IRR_COMPILE_WITH_GUI_ #ifdef _IRR_COMPILE_WITH_GUI_
#include "os.h" #include "os.h"
#include "fast_atof.h"
#include "coreutil.h" #include "coreutil.h"
#include "IGUIEnvironment.h" #include "IGUIEnvironment.h"
#include "IReadFile.h" #include "IReadFile.h"
@ -62,122 +63,106 @@ CGUIFont::~CGUIFont()
} }
#if 0 //! loads a font file from tsv
//! loads a font file from xml bool CGUIFont::load(io::IReadFile* file, const io::path& directory)
bool CGUIFont::load(io::IXMLReader* xml, const io::path& directory)
{ {
if (!SpriteBank) if (!SpriteBank)
return false; return false;
SpriteBank->clear(); SpriteBank->clear();
while (xml->read()) const long size = file->getSize();
core::stringc Buffer;
Buffer.reserve(size + 1);
if (file->read(&Buffer[0], size) != static_cast<size_t>(size))
{ {
if (io::EXN_ELEMENT == xml->getNodeType()) os::Printer::log("Could not read from file", ELL_ERROR);
return false;
}
Buffer[size] = 0;
const c8 *P = &Buffer[0], *End = P + size;
#define SkipSpace() \
while (P < End && (*P == ' ' || *P == '\t' || *P == '\v')) { P++; }
#define SkipLine(rest) \
while (rest && P < End && *P != '\r' && *P != '\n') P++; \
while (P < End && (*P == '\r' || *P == '\n')) { P++; }
while (P < End)
{ {
if (core::stringw(L"Texture") == xml->getNodeName()) if (!strncmp(P, "Texture:", 8))
{ {
// add a texture // add a texture
core::stringc fn = xml->getAttributeValue(L"filename"); P += 8;
u32 i = (u32)xml->getAttributeValueAsInt(L"index"); SkipSpace()
core::stringw alpha = xml->getAttributeValue(L"hasAlpha"); core::stringc fn;
for (; P < End && *P != '\r' && *P != '\n'; P++)
while (i+1 > SpriteBank->getTextureCount()) fn.append(*P);
SpriteBank->addTexture(0); SkipLine(0)
bool flags[3]; bool flags[3];
pushTextureCreationFlags(flags); pushTextureCreationFlags(flags);
// load texture // load texture
io::path textureFullName = core::mergeFilename(directory, fn); io::path textureFullName = core::mergeFilename(directory, fn);
SpriteBank->setTexture(i, Driver->getTexture(textureFullName)); SpriteBank->setTexture(0, Driver->getTexture(textureFullName));
popTextureCreationFlags(flags); popTextureCreationFlags(flags);
// couldn't load texture, abort. if (!SpriteBank->getTexture(0))
if (!SpriteBank->getTexture(i))
{ {
os::Printer::log("Unable to load all textures in the font, aborting", ELL_ERROR); os::Printer::log("Unable to load texture in the font, aborting", ELL_ERROR);
return false; return false;
} }
}
else else
{
// colorkey texture rather than alpha channel?
if (alpha == core::stringw("false"))
Driver->makeColorKeyTexture(SpriteBank->getTexture(i), core::position2di(0,0));
}
}
else if (core::stringw(L"c") == xml->getNodeName())
{ {
// adding a character to this font // adding a character to this font
SFontArea a; SFontArea a;
SGUISpriteFrame f; SGUISpriteFrame f;
SGUISprite s; SGUISprite s;
core::rect<s32> rectangle; core::rect<s32> rect;
wchar_t ch;
a.underhang = xml->getAttributeValueAsInt(L"u"); // Format of a line:
a.overhang = xml->getAttributeValueAsInt(L"o"); // <char (hex)> <X1> <Y1> <X2> <Y2> [u] [o]
a.spriteno = SpriteBank->getSprites().size();
s32 texno = xml->getAttributeValueAsInt(L"i");
// parse rectangle ch = static_cast<wchar_t>(core::strtoul16(P, &P));
core::stringc rectstr = xml->getAttributeValue(L"r"); SkipSpace()
wchar_t ch = xml->getAttributeValue(L"c")[0];
const c8 *c = rectstr.c_str(); rect.UpperLeftCorner.X = core::strtol10(P, &P);
s32 val; SkipSpace()
val = 0; rect.UpperLeftCorner.Y = core::strtol10(P, &P);
while (*c >= '0' && *c <= '9') SkipSpace()
rect.LowerRightCorner.X = core::strtol10(P, &P);
SkipSpace()
rect.LowerRightCorner.Y = core::strtol10(P, &P);
SkipSpace()
if (core::isdigit(*P))
{ {
val *= 10; a.underhang = core::strtol10(P, &P);
val += *c - '0'; SkipSpace()
c++; if (core::isdigit(*P))
a.overhang = core::strtol10(P, &P);
} }
rectangle.UpperLeftCorner.X = val;
while (*c == L' ' || *c == L',') c++;
val = 0; SkipLine(1)
while (*c >= '0' && *c <= '9')
{
val *= 10;
val += *c - '0';
c++;
}
rectangle.UpperLeftCorner.Y = val;
while (*c == L' ' || *c == L',') c++;
val = 0;
while (*c >= '0' && *c <= '9')
{
val *= 10;
val += *c - '0';
c++;
}
rectangle.LowerRightCorner.X = val;
while (*c == L' ' || *c == L',') c++;
val = 0;
while (*c >= '0' && *c <= '9')
{
val *= 10;
val += *c - '0';
c++;
}
rectangle.LowerRightCorner.Y = val;
CharacterMap.insert(ch, Areas.size()); CharacterMap.insert(ch, Areas.size());
// make frame // make frame
f.rectNumber = SpriteBank->getPositions().size(); f.rectNumber = SpriteBank->getPositions().size();
f.textureNumber = texno; f.textureNumber = 0;
// add frame to sprite // add frame to sprite
s.Frames.push_back(f); s.Frames.push_back(f);
s.frameTime = 0; s.frameTime = 0;
// add rectangle to sprite bank // add rectangle to sprite bank
SpriteBank->getPositions().push_back(rectangle); SpriteBank->getPositions().push_back(rect);
a.width = rectangle.getWidth(); a.width = rect.getWidth();
a.spriteno = SpriteBank->getSprites().size();
// add sprite to sprite bank // add sprite to sprite bank
SpriteBank->getSprites().push_back(s); SpriteBank->getSprites().push_back(s);
@ -186,7 +171,9 @@ bool CGUIFont::load(io::IXMLReader* xml, const io::path& directory)
Areas.push_back(a); Areas.push_back(a);
} }
} }
}
#undef SkipSpace
#undef SkipLine
// set bad character // set bad character
WrongCharacter = getAreaFromCharacter(L' '); WrongCharacter = getAreaFromCharacter(L' ');
@ -195,7 +182,6 @@ bool CGUIFont::load(io::IXMLReader* xml, const io::path& directory)
return true; return true;
} }
#endif
void CGUIFont::setMaxHeight() void CGUIFont::setMaxHeight()

@ -44,6 +44,10 @@ public:
//! loads a font from a texture file //! loads a font from a texture file
bool load(io::IReadFile* file); bool load(io::IReadFile* file);
//! loads a font from a TSV file
// \param directory Directory in which the bitmaps can be found
bool load(io::IReadFile* file, const io::path& directory);
//! draws an text and clips it to the specified rectangle if wanted //! draws an text and clips it to the specified rectangle if wanted
virtual void draw(const core::stringw& text, const core::rect<s32>& position, virtual void draw(const core::stringw& text, const core::rect<s32>& position,
video::SColor color, bool hcenter=false, video::SColor color, bool hcenter=false,

@ -0,0 +1,97 @@
#include <stdio.h>
#include <irrlicht.h>
using namespace irr;
// Builds with an Irrlicht version that still has XML (e.g. 1.9.0mt2)
// g++ -Wall -O2 XMLFontConverter.cpp -o XMLFontConverter -I/tmp/irrlicht/include -L/tmp/irrlicht/lib/Linux -lIrrlichtMt
int main(int argc, char* argv[])
{
if (argc < 3)
{
printf("Usage: XMLFontConverter <source.xml> <destination.tsv>\n");
return 1;
}
IrrlichtDevice *device = createDevice(video::EDT_NULL,
core::dimension2d<u32>(800, 600), 32, false, false, false, 0);
io::IXMLReader *xml = device->getFileSystem()->createXMLReader(argv[1]);
io::IWriteFile *wf = device->getFileSystem()->createAndWriteFile(argv[2]);
u32 nchars = 0;
while (xml->read())
{
if (io::EXN_ELEMENT != xml->getNodeType())
continue;
if (core::stringw(L"Texture") == xml->getNodeName())
{
core::stringc fn = xml->getAttributeValue(L"filename");
core::stringc line("Texture: ");
line.append(fn);
line.append('\n');
wf->write(line.c_str(), line.size());
}
else if (core::stringw(L"c") == xml->getNodeName())
{
core::rect<s32> rect;
s32 underhang = xml->getAttributeValueAsInt(L"u");
s32 overhang = xml->getAttributeValueAsInt(L"o");
core::stringc rectstr = xml->getAttributeValue(L"r");
wchar_t ch = xml->getAttributeValue(L"c")[0];
nchars++;
const c8 *c = rectstr.c_str();
s32 val = core::strtol10(c, &c);
rect.UpperLeftCorner.X = val;
while (*c == L' ' || *c == L',') c++;
val = core::strtol10(c, &c);
rect.UpperLeftCorner.Y = val;
while (*c == L' ' || *c == L',') c++;
val = core::strtol10(c, &c);
rect.LowerRightCorner.X = val;
while (*c == L' ' || *c == L',') c++;
val = core::strtol10(c, &c);
rect.LowerRightCorner.Y = val;
core::stringc line;
char tmp[6];
snprintf(tmp, 6, "%04X", static_cast<u32>(ch));
line.append(tmp);
line.append('\t');
line.append(core::stringc(rect.UpperLeftCorner.X));
line.append('\t');
line.append(core::stringc(rect.UpperLeftCorner.Y));
line.append('\t');
line.append(core::stringc(rect.LowerRightCorner.X));
line.append('\t');
line.append(core::stringc(rect.LowerRightCorner.Y));
if (underhang != 0 || overhang != 0)
{
line.append('\t');
line.append(core::stringc(underhang));
if (overhang != 0)
{
line.append('\t');
line.append(core::stringc(overhang));
}
}
line.append('\n');
wf->write(line.c_str(), line.size());
}
}
printf("Success: %d chars\n", nchars);
xml->drop();
wf->drop();
device->drop();
return 0;
}