forked from Mirrorlandia_minetest/irrlicht
Compare commits
2 Commits
master
...
bitmapfont
Author | SHA1 | Date | |
---|---|---|---|
|
853939405b | ||
|
9b0bc2aaed |
@ -1278,23 +1278,23 @@ 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);
|
||||||
|
ifont = (IGUIFont*)font;
|
||||||
|
|
||||||
|
// load the font
|
||||||
|
io::path directory;
|
||||||
|
core::splitFilename(filename, &directory);
|
||||||
|
if (!font->load(file, directory))
|
||||||
{
|
{
|
||||||
CGUIFont* font = new CGUIFont(this, filename);
|
font->drop();
|
||||||
ifont = (IGUIFont*)font;
|
font = 0;
|
||||||
|
ifont = 0;
|
||||||
// load the font
|
|
||||||
io::path directory;
|
|
||||||
core::splitFilename(filename, &directory);
|
|
||||||
if (!font->load(xml, directory))
|
|
||||||
{
|
|
||||||
font->drop();
|
|
||||||
font = 0;
|
|
||||||
ifont = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
file->drop();
|
||||||
|
}
|
||||||
|
|
||||||
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,132 +63,118 @@ 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 (!strncmp(P, "Texture:", 8))
|
||||||
{
|
{
|
||||||
if (core::stringw(L"Texture") == xml->getNodeName())
|
// add a texture
|
||||||
|
P += 8;
|
||||||
|
SkipSpace()
|
||||||
|
core::stringc fn;
|
||||||
|
for (; P < End && *P != '\r' && *P != '\n'; P++)
|
||||||
|
fn.append(*P);
|
||||||
|
SkipLine(0)
|
||||||
|
|
||||||
|
bool flags[3];
|
||||||
|
pushTextureCreationFlags(flags);
|
||||||
|
|
||||||
|
// load texture
|
||||||
|
io::path textureFullName = core::mergeFilename(directory, fn);
|
||||||
|
SpriteBank->setTexture(0, Driver->getTexture(textureFullName));
|
||||||
|
|
||||||
|
popTextureCreationFlags(flags);
|
||||||
|
|
||||||
|
if (!SpriteBank->getTexture(0))
|
||||||
{
|
{
|
||||||
// add a texture
|
os::Printer::log("Unable to load texture in the font, aborting", ELL_ERROR);
|
||||||
core::stringc fn = xml->getAttributeValue(L"filename");
|
return false;
|
||||||
u32 i = (u32)xml->getAttributeValueAsInt(L"index");
|
|
||||||
core::stringw alpha = xml->getAttributeValue(L"hasAlpha");
|
|
||||||
|
|
||||||
while (i+1 > SpriteBank->getTextureCount())
|
|
||||||
SpriteBank->addTexture(0);
|
|
||||||
|
|
||||||
bool flags[3];
|
|
||||||
pushTextureCreationFlags(flags);
|
|
||||||
|
|
||||||
// load texture
|
|
||||||
io::path textureFullName = core::mergeFilename(directory, fn);
|
|
||||||
SpriteBank->setTexture(i, Driver->getTexture(textureFullName));
|
|
||||||
|
|
||||||
popTextureCreationFlags(flags);
|
|
||||||
|
|
||||||
// couldn't load texture, abort.
|
|
||||||
if (!SpriteBank->getTexture(i))
|
|
||||||
{
|
|
||||||
os::Printer::log("Unable to load all textures in the font, aborting", ELL_ERROR);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
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
|
|
||||||
SFontArea a;
|
|
||||||
SGUISpriteFrame f;
|
|
||||||
SGUISprite s;
|
|
||||||
core::rect<s32> rectangle;
|
|
||||||
|
|
||||||
a.underhang = xml->getAttributeValueAsInt(L"u");
|
|
||||||
a.overhang = xml->getAttributeValueAsInt(L"o");
|
|
||||||
a.spriteno = SpriteBank->getSprites().size();
|
|
||||||
s32 texno = xml->getAttributeValueAsInt(L"i");
|
|
||||||
|
|
||||||
// parse rectangle
|
|
||||||
core::stringc rectstr = xml->getAttributeValue(L"r");
|
|
||||||
wchar_t ch = xml->getAttributeValue(L"c")[0];
|
|
||||||
|
|
||||||
const c8 *c = rectstr.c_str();
|
|
||||||
s32 val;
|
|
||||||
val = 0;
|
|
||||||
while (*c >= '0' && *c <= '9')
|
|
||||||
{
|
|
||||||
val *= 10;
|
|
||||||
val += *c - '0';
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
rectangle.UpperLeftCorner.X = val;
|
|
||||||
while (*c == L' ' || *c == L',') c++;
|
|
||||||
|
|
||||||
val = 0;
|
|
||||||
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());
|
|
||||||
|
|
||||||
// make frame
|
|
||||||
f.rectNumber = SpriteBank->getPositions().size();
|
|
||||||
f.textureNumber = texno;
|
|
||||||
|
|
||||||
// add frame to sprite
|
|
||||||
s.Frames.push_back(f);
|
|
||||||
s.frameTime = 0;
|
|
||||||
|
|
||||||
// add rectangle to sprite bank
|
|
||||||
SpriteBank->getPositions().push_back(rectangle);
|
|
||||||
a.width = rectangle.getWidth();
|
|
||||||
|
|
||||||
// add sprite to sprite bank
|
|
||||||
SpriteBank->getSprites().push_back(s);
|
|
||||||
|
|
||||||
// add character to font
|
|
||||||
Areas.push_back(a);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// adding a character to this font
|
||||||
|
SFontArea a;
|
||||||
|
SGUISpriteFrame f;
|
||||||
|
SGUISprite s;
|
||||||
|
core::rect<s32> rect;
|
||||||
|
wchar_t ch;
|
||||||
|
|
||||||
|
// Format of a line:
|
||||||
|
// <char (hex)> <X1> <Y1> <X2> <Y2> [u] [o]
|
||||||
|
|
||||||
|
ch = static_cast<wchar_t>(core::strtoul16(P, &P));
|
||||||
|
SkipSpace()
|
||||||
|
|
||||||
|
rect.UpperLeftCorner.X = core::strtol10(P, &P);
|
||||||
|
SkipSpace()
|
||||||
|
rect.UpperLeftCorner.Y = core::strtol10(P, &P);
|
||||||
|
SkipSpace()
|
||||||
|
rect.LowerRightCorner.X = core::strtol10(P, &P);
|
||||||
|
SkipSpace()
|
||||||
|
rect.LowerRightCorner.Y = core::strtol10(P, &P);
|
||||||
|
SkipSpace()
|
||||||
|
|
||||||
|
if (core::isdigit(*P))
|
||||||
|
{
|
||||||
|
a.underhang = core::strtol10(P, &P);
|
||||||
|
SkipSpace()
|
||||||
|
if (core::isdigit(*P))
|
||||||
|
a.overhang = core::strtol10(P, &P);
|
||||||
|
}
|
||||||
|
|
||||||
|
SkipLine(1)
|
||||||
|
|
||||||
|
CharacterMap.insert(ch, Areas.size());
|
||||||
|
|
||||||
|
// make frame
|
||||||
|
f.rectNumber = SpriteBank->getPositions().size();
|
||||||
|
f.textureNumber = 0;
|
||||||
|
|
||||||
|
// add frame to sprite
|
||||||
|
s.Frames.push_back(f);
|
||||||
|
s.frameTime = 0;
|
||||||
|
|
||||||
|
// add rectangle to sprite bank
|
||||||
|
SpriteBank->getPositions().push_back(rect);
|
||||||
|
a.width = rect.getWidth();
|
||||||
|
a.spriteno = SpriteBank->getSprites().size();
|
||||||
|
|
||||||
|
// add sprite to sprite bank
|
||||||
|
SpriteBank->getSprites().push_back(s);
|
||||||
|
|
||||||
|
// add character to font
|
||||||
|
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,
|
||||||
|
97
tools/XMLFontConverter.cpp
Normal file
97
tools/XMLFontConverter.cpp
Normal file
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user