Replaced tabs with spaces.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5697 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
9549138017
commit
03c6500265
@ -22,7 +22,7 @@ namespace gui
|
||||
//! constructor
|
||||
ScalableFont::ScalableFont(IGUIEnvironment *env, const io::path& filename)
|
||||
: Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0),
|
||||
MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0)
|
||||
MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0)
|
||||
{
|
||||
m_fallback_font = NULL;
|
||||
m_fallback_font_scale = 1.0f;
|
||||
@ -32,27 +32,27 @@ ScalableFont::ScalableFont(IGUIEnvironment *env, const io::path& filename)
|
||||
|
||||
m_black_border = false;
|
||||
|
||||
#ifdef _DEBUG
|
||||
setDebugName("ScalableFont");
|
||||
#endif
|
||||
#ifdef _DEBUG
|
||||
setDebugName("ScalableFont");
|
||||
#endif
|
||||
|
||||
m_scale = 1.0f;
|
||||
m_shadow = false;
|
||||
|
||||
if (Environment)
|
||||
{
|
||||
// don't grab environment, to avoid circular references
|
||||
Driver = Environment->getVideoDriver();
|
||||
if (Environment)
|
||||
{
|
||||
// don't grab environment, to avoid circular references
|
||||
Driver = Environment->getVideoDriver();
|
||||
|
||||
SpriteBank = Environment->addEmptySpriteBank(filename);
|
||||
if (SpriteBank)
|
||||
SpriteBank->grab();
|
||||
}
|
||||
SpriteBank = Environment->addEmptySpriteBank(filename);
|
||||
if (SpriteBank)
|
||||
SpriteBank->grab();
|
||||
}
|
||||
|
||||
if (Driver)
|
||||
Driver->grab();
|
||||
if (Driver)
|
||||
Driver->grab();
|
||||
|
||||
setInvisibleCharacters ( L" " );
|
||||
setInvisibleCharacters ( L" " );
|
||||
|
||||
load( file_manager->createXMLReader(filename.c_str()) );
|
||||
assert(Areas.size() > 0);
|
||||
@ -78,33 +78,33 @@ void ScalableFont::setShadow(irr::video::SColor col)
|
||||
//! loads a font file from xml
|
||||
bool ScalableFont::load(io::IXMLReader* xml)
|
||||
{
|
||||
if (!SpriteBank)
|
||||
return false;
|
||||
if (!SpriteBank)
|
||||
return false;
|
||||
|
||||
while (xml->read())
|
||||
{
|
||||
if (io::EXN_ELEMENT == xml->getNodeType())
|
||||
{
|
||||
if (core::stringw(L"Texture") == xml->getNodeName())
|
||||
{
|
||||
// add a texture
|
||||
while (xml->read())
|
||||
{
|
||||
if (io::EXN_ELEMENT == xml->getNodeType())
|
||||
{
|
||||
if (core::stringw(L"Texture") == xml->getNodeName())
|
||||
{
|
||||
// add a texture
|
||||
core::stringc filename = xml->getAttributeValue(L"filename");
|
||||
core::stringc fn = file_manager->getFontFile(filename.c_str()).c_str();
|
||||
u32 i = (u32)xml->getAttributeValueAsInt(L"index");
|
||||
core::stringc fn = file_manager->getFontFile(filename.c_str()).c_str();
|
||||
u32 i = (u32)xml->getAttributeValueAsInt(L"index");
|
||||
|
||||
float scale = xml->getAttributeValueAsFloat(L"scale");
|
||||
if (scale < 0.01f) scale = 1.0f; // FIXME: how do you check if some property exists in a cleaner way?
|
||||
//std::cout << "scale = " << scale << std::endl;
|
||||
|
||||
core::stringw alpha = xml->getAttributeValue(L"hasAlpha");
|
||||
core::stringw alpha = xml->getAttributeValue(L"hasAlpha");
|
||||
|
||||
//std::cout << "---- Adding font texture " << fn.c_str() << "; alpha=" << alpha.c_str() << std::endl;
|
||||
|
||||
|
||||
// make sure the sprite bank has enough textures in it
|
||||
while (i+1 > SpriteBank->getTextureCount())
|
||||
while (i+1 > SpriteBank->getTextureCount())
|
||||
{
|
||||
SpriteBank->addTexture(NULL);
|
||||
SpriteBank->addTexture(NULL);
|
||||
}
|
||||
|
||||
TextureInfo info;
|
||||
@ -112,123 +112,123 @@ bool ScalableFont::load(io::IXMLReader* xml)
|
||||
info.m_has_alpha = (alpha == core::stringw("true"));
|
||||
info.m_scale = scale;
|
||||
|
||||
// disable mipmaps+filtering
|
||||
//bool mipmap = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
//Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
|
||||
// disable mipmaps+filtering
|
||||
//bool mipmap = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
|
||||
//Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
|
||||
|
||||
m_texture_files[i] = info;
|
||||
|
||||
/*
|
||||
// load texture
|
||||
SpriteBank->setTexture(i, Driver->getTexture(fn));
|
||||
// load texture
|
||||
SpriteBank->setTexture(i, Driver->getTexture(fn));
|
||||
|
||||
// set previous mip-map+filter state
|
||||
//Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap);
|
||||
// set previous mip-map+filter state
|
||||
//Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap);
|
||||
|
||||
// couldn't load texture, abort.
|
||||
if (!SpriteBank->getTexture(i))
|
||||
{
|
||||
// couldn't load texture, abort.
|
||||
if (!SpriteBank->getTexture(i))
|
||||
{
|
||||
std::cerr << "!!!!! Unable to load all textures in the font, aborting" << std::endl;
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// colorkey texture rather than alpha channel?
|
||||
if (alpha == core::stringw("false"))
|
||||
Driver->makeColorKeyTexture(SpriteBank->getTexture(i), core::position2di(0,0));
|
||||
}
|
||||
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
|
||||
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;
|
||||
}
|
||||
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");
|
||||
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];
|
||||
// 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++;
|
||||
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.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.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;
|
||||
val = 0;
|
||||
while (*c >= '0' && *c <= '9')
|
||||
{
|
||||
val *= 10;
|
||||
val += *c - '0';
|
||||
c++;
|
||||
}
|
||||
rectangle.LowerRightCorner.Y = val;
|
||||
|
||||
CharacterMap[ch] = Areas.size();
|
||||
CharacterMap[ch] = Areas.size();
|
||||
|
||||
//std::cout << "Inserting character '" << (int)ch << "' with area " << Areas.size() << std::endl;
|
||||
|
||||
// make frame
|
||||
f.rectNumber = SpriteBank->getPositions().size();
|
||||
f.textureNumber = texno;
|
||||
// make frame
|
||||
f.rectNumber = SpriteBank->getPositions().size();
|
||||
f.textureNumber = texno;
|
||||
|
||||
// add frame to sprite
|
||||
s.Frames.push_back(f);
|
||||
s.frameTime = 0;
|
||||
// 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 rectangle to sprite bank
|
||||
SpriteBank->getPositions().push_back(rectangle);
|
||||
a.width = rectangle.getWidth();
|
||||
|
||||
// add sprite to sprite bank
|
||||
SpriteBank->getSprites().push_back(s);
|
||||
// add sprite to sprite bank
|
||||
SpriteBank->getSprites().push_back(s);
|
||||
|
||||
// add character to font
|
||||
Areas.push_back(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
// add character to font
|
||||
Areas.push_back(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set bad character
|
||||
WrongCharacter = getAreaFromCharacter(L' ', NULL);
|
||||
// set bad character
|
||||
WrongCharacter = getAreaFromCharacter(L' ', NULL);
|
||||
|
||||
setMaxHeight();
|
||||
setMaxHeight();
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
void ScalableFont::setScale(const float scale)
|
||||
{
|
||||
@ -238,17 +238,17 @@ void ScalableFont::setScale(const float scale)
|
||||
void ScalableFont::setMaxHeight()
|
||||
{
|
||||
// FIXME: should consider per-texture scaling
|
||||
MaxHeight = 0;
|
||||
s32 t;
|
||||
MaxHeight = 0;
|
||||
s32 t;
|
||||
|
||||
core::array< core::rect<s32> >& p = SpriteBank->getPositions();
|
||||
core::array< core::rect<s32> >& p = SpriteBank->getPositions();
|
||||
|
||||
for (u32 i=0; i<p.size(); ++i)
|
||||
{
|
||||
t = p[i].getHeight();
|
||||
if (t>MaxHeight)
|
||||
MaxHeight = t;
|
||||
}
|
||||
for (u32 i=0; i<p.size(); ++i)
|
||||
{
|
||||
t = p[i].getHeight();
|
||||
if (t>MaxHeight)
|
||||
MaxHeight = t;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -258,9 +258,9 @@ void ScalableFont::setMaxHeight()
|
||||
/*
|
||||
bool ScalableFont::load(io::IReadFile* file)
|
||||
{
|
||||
if (!Driver) return false;
|
||||
if (!Driver) return false;
|
||||
|
||||
return loadTexture(Driver->createImageFromFile(file), file->getFileName());
|
||||
return loadTexture(Driver->createImageFromFile(file), file->getFileName());
|
||||
}
|
||||
*/
|
||||
|
||||
@ -268,9 +268,9 @@ bool ScalableFont::load(io::IReadFile* file)
|
||||
/*
|
||||
bool ScalableFont::load(const io::path& filename)
|
||||
{
|
||||
if (!Driver) return false;
|
||||
if (!Driver) return false;
|
||||
|
||||
return loadTexture(Driver->createImageFromFile( filename ), filename);
|
||||
return loadTexture(Driver->createImageFromFile( filename ), filename);
|
||||
}
|
||||
*/
|
||||
|
||||
@ -278,186 +278,186 @@ bool ScalableFont::load(const io::path& filename)
|
||||
#if 0
|
||||
bool ScalableFont::loadTexture(video::IImage* image, const io::path& name)
|
||||
{
|
||||
if (!image) return false;
|
||||
if (!image) return false;
|
||||
|
||||
s32 lowerRightPositions = 0;
|
||||
s32 lowerRightPositions = 0;
|
||||
|
||||
video::IImage* tmpImage=image;
|
||||
video::IImage* tmpImage=image;
|
||||
/*
|
||||
bool deleteTmpImage=false;
|
||||
switch(image->getColorFormat())
|
||||
{
|
||||
case video::ECF_R5G6B5:
|
||||
tmpImage = new video::CImage(video::ECF_A1R5G5B5,image);
|
||||
deleteTmpImage=true;
|
||||
break;
|
||||
case video::ECF_A1R5G5B5:
|
||||
case video::ECF_A8R8G8B8:
|
||||
break;
|
||||
case video::ECF_R8G8B8:
|
||||
tmpImage = new video::CImage(video::ECF_A8R8G8B8,image);
|
||||
deleteTmpImage=true;
|
||||
break;
|
||||
}*/
|
||||
readPositions(tmpImage, lowerRightPositions);
|
||||
bool deleteTmpImage=false;
|
||||
switch(image->getColorFormat())
|
||||
{
|
||||
case video::ECF_R5G6B5:
|
||||
tmpImage = new video::CImage(video::ECF_A1R5G5B5,image);
|
||||
deleteTmpImage=true;
|
||||
break;
|
||||
case video::ECF_A1R5G5B5:
|
||||
case video::ECF_A8R8G8B8:
|
||||
break;
|
||||
case video::ECF_R8G8B8:
|
||||
tmpImage = new video::CImage(video::ECF_A8R8G8B8,image);
|
||||
deleteTmpImage=true;
|
||||
break;
|
||||
}*/
|
||||
readPositions(tmpImage, lowerRightPositions);
|
||||
|
||||
WrongCharacter = getAreaFromCharacter(L' ', NULL);
|
||||
WrongCharacter = getAreaFromCharacter(L' ', NULL);
|
||||
|
||||
// output warnings
|
||||
if (!lowerRightPositions || !SpriteBank->getSprites().size())
|
||||
std::cerr << "Either no upper or lower corner pixels in the font file. If this font was made using the new font tool, please load the XML file instead. If not, the font may be corrupted.\n";
|
||||
else
|
||||
if (lowerRightPositions != (s32)SpriteBank->getPositions().size())
|
||||
std::cerr << "The amount of upper corner pixels and the lower corner pixels is not equal, font file may be corrupted.\n";
|
||||
// output warnings
|
||||
if (!lowerRightPositions || !SpriteBank->getSprites().size())
|
||||
std::cerr << "Either no upper or lower corner pixels in the font file. If this font was made using the new font tool, please load the XML file instead. If not, the font may be corrupted.\n";
|
||||
else
|
||||
if (lowerRightPositions != (s32)SpriteBank->getPositions().size())
|
||||
std::cerr << "The amount of upper corner pixels and the lower corner pixels is not equal, font file may be corrupted.\n";
|
||||
|
||||
bool ret = ( !SpriteBank->getSprites().empty() && lowerRightPositions );
|
||||
bool ret = ( !SpriteBank->getSprites().empty() && lowerRightPositions );
|
||||
|
||||
if ( ret )
|
||||
{
|
||||
bool flag[2];
|
||||
flag[0] = Driver->getTextureCreationFlag ( video::ETCF_ALLOW_NON_POWER_2 );
|
||||
flag[1] = Driver->getTextureCreationFlag ( video::ETCF_CREATE_MIP_MAPS );
|
||||
if ( ret )
|
||||
{
|
||||
bool flag[2];
|
||||
flag[0] = Driver->getTextureCreationFlag ( video::ETCF_ALLOW_NON_POWER_2 );
|
||||
flag[1] = Driver->getTextureCreationFlag ( video::ETCF_CREATE_MIP_MAPS );
|
||||
|
||||
Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, true);
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true );
|
||||
Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, true);
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true );
|
||||
|
||||
SpriteBank->addTexture(Driver->addTexture(name, tmpImage));
|
||||
SpriteBank->addTexture(Driver->addTexture(name, tmpImage));
|
||||
|
||||
Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, flag[0] );
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, flag[1] );
|
||||
}
|
||||
//if (deleteTmpImage)
|
||||
// tmpImage->drop();
|
||||
image->drop();
|
||||
Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, flag[0] );
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, flag[1] );
|
||||
}
|
||||
//if (deleteTmpImage)
|
||||
// tmpImage->drop();
|
||||
image->drop();
|
||||
|
||||
setMaxHeight();
|
||||
setMaxHeight();
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
void ScalableFont::readPositions(video::IImage* image, s32& spriteID)
|
||||
{
|
||||
const core::dimension2d<u32> size = image->getDimension();
|
||||
const core::dimension2d<u32> size = image->getDimension();
|
||||
|
||||
video::SColor colorTopLeft = image->getPixel(0,0);
|
||||
colorTopLeft.setAlpha(255);
|
||||
image->setPixel(0,0,colorTopLeft);
|
||||
video::SColor colorLowerRight = image->getPixel(1,0);
|
||||
video::SColor colorBackGround = image->getPixel(2,0);
|
||||
video::SColor colorBackGroundTransparent = 0;
|
||||
video::SColor colorTopLeft = image->getPixel(0,0);
|
||||
colorTopLeft.setAlpha(255);
|
||||
image->setPixel(0,0,colorTopLeft);
|
||||
video::SColor colorLowerRight = image->getPixel(1,0);
|
||||
video::SColor colorBackGround = image->getPixel(2,0);
|
||||
video::SColor colorBackGroundTransparent = 0;
|
||||
|
||||
image->setPixel(1,0,colorBackGround);
|
||||
image->setPixel(1,0,colorBackGround);
|
||||
|
||||
// start parsing
|
||||
// start parsing
|
||||
|
||||
core::position2d<s32> pos(0,0);
|
||||
for (pos.Y=0; pos.Y<(s32)size.Height; ++pos.Y)
|
||||
{
|
||||
for (pos.X=0; pos.X<(s32)size.Width; ++pos.X)
|
||||
{
|
||||
const video::SColor c = image->getPixel(pos.X, pos.Y);
|
||||
if (c == colorTopLeft)
|
||||
{
|
||||
image->setPixel(pos.X, pos.Y, colorBackGroundTransparent);
|
||||
SpriteBank->getPositions().push_back(core::rect<s32>(pos, pos));
|
||||
}
|
||||
else
|
||||
if (c == colorLowerRight)
|
||||
{
|
||||
// too many lower right points
|
||||
if (SpriteBank->getPositions().size()<=(u32)spriteID)
|
||||
{
|
||||
spriteID = 0;
|
||||
return;
|
||||
}
|
||||
core::position2d<s32> pos(0,0);
|
||||
for (pos.Y=0; pos.Y<(s32)size.Height; ++pos.Y)
|
||||
{
|
||||
for (pos.X=0; pos.X<(s32)size.Width; ++pos.X)
|
||||
{
|
||||
const video::SColor c = image->getPixel(pos.X, pos.Y);
|
||||
if (c == colorTopLeft)
|
||||
{
|
||||
image->setPixel(pos.X, pos.Y, colorBackGroundTransparent);
|
||||
SpriteBank->getPositions().push_back(core::rect<s32>(pos, pos));
|
||||
}
|
||||
else
|
||||
if (c == colorLowerRight)
|
||||
{
|
||||
// too many lower right points
|
||||
if (SpriteBank->getPositions().size()<=(u32)spriteID)
|
||||
{
|
||||
spriteID = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
image->setPixel(pos.X, pos.Y, colorBackGroundTransparent);
|
||||
SpriteBank->getPositions()[spriteID].LowerRightCorner = pos;
|
||||
// add frame to sprite bank
|
||||
SGUISpriteFrame f;
|
||||
f.rectNumber = spriteID;
|
||||
f.textureNumber = 0;
|
||||
SGUISprite s;
|
||||
s.Frames.push_back(f);
|
||||
s.frameTime = 0;
|
||||
SpriteBank->getSprites().push_back(s);
|
||||
// add character to font
|
||||
SFontArea a;
|
||||
a.overhang = 0;
|
||||
a.underhang = 0;
|
||||
a.spriteno = spriteID;
|
||||
a.width = SpriteBank->getPositions()[spriteID].getWidth();
|
||||
Areas.push_back(a);
|
||||
// map letter to character
|
||||
wchar_t ch = (wchar_t)(spriteID + 32);
|
||||
CharacterMap[ch] = spriteID;
|
||||
image->setPixel(pos.X, pos.Y, colorBackGroundTransparent);
|
||||
SpriteBank->getPositions()[spriteID].LowerRightCorner = pos;
|
||||
// add frame to sprite bank
|
||||
SGUISpriteFrame f;
|
||||
f.rectNumber = spriteID;
|
||||
f.textureNumber = 0;
|
||||
SGUISprite s;
|
||||
s.Frames.push_back(f);
|
||||
s.frameTime = 0;
|
||||
SpriteBank->getSprites().push_back(s);
|
||||
// add character to font
|
||||
SFontArea a;
|
||||
a.overhang = 0;
|
||||
a.underhang = 0;
|
||||
a.spriteno = spriteID;
|
||||
a.width = SpriteBank->getPositions()[spriteID].getWidth();
|
||||
Areas.push_back(a);
|
||||
// map letter to character
|
||||
wchar_t ch = (wchar_t)(spriteID + 32);
|
||||
CharacterMap[ch] = spriteID;
|
||||
|
||||
++spriteID;
|
||||
}
|
||||
else
|
||||
if (c == colorBackGround)
|
||||
image->setPixel(pos.X, pos.Y, colorBackGroundTransparent);
|
||||
}
|
||||
}
|
||||
++spriteID;
|
||||
}
|
||||
else
|
||||
if (c == colorBackGround)
|
||||
image->setPixel(pos.X, pos.Y, colorBackGroundTransparent);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//! set an Pixel Offset on Drawing ( scale position on width )
|
||||
void ScalableFont::setKerningWidth(s32 kerning)
|
||||
{
|
||||
GlobalKerningWidth = kerning;
|
||||
GlobalKerningWidth = kerning;
|
||||
}
|
||||
|
||||
|
||||
//! set an Pixel Offset on Drawing ( scale position on width )
|
||||
s32 ScalableFont::getKerningWidth(const wchar_t* thisLetter, const wchar_t* previousLetter) const
|
||||
{
|
||||
s32 ret = GlobalKerningWidth;
|
||||
s32 ret = GlobalKerningWidth;
|
||||
|
||||
if (thisLetter)
|
||||
{
|
||||
ret += Areas[getAreaFromCharacter(*thisLetter, NULL)].overhang;
|
||||
if (thisLetter)
|
||||
{
|
||||
ret += Areas[getAreaFromCharacter(*thisLetter, NULL)].overhang;
|
||||
|
||||
if (previousLetter)
|
||||
{
|
||||
ret += Areas[getAreaFromCharacter(*previousLetter, NULL)].underhang;
|
||||
}
|
||||
}
|
||||
if (previousLetter)
|
||||
{
|
||||
ret += Areas[getAreaFromCharacter(*previousLetter, NULL)].underhang;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! set an Pixel Offset on Drawing ( scale position on height )
|
||||
void ScalableFont::setKerningHeight(s32 kerning)
|
||||
{
|
||||
GlobalKerningHeight = kerning;
|
||||
GlobalKerningHeight = kerning;
|
||||
}
|
||||
|
||||
|
||||
//! set an Pixel Offset on Drawing ( scale position on height )
|
||||
s32 ScalableFont::getKerningHeight () const
|
||||
{
|
||||
return GlobalKerningHeight;
|
||||
return GlobalKerningHeight;
|
||||
}
|
||||
|
||||
|
||||
//! returns the sprite number from a given character
|
||||
u32 ScalableFont::getSpriteNoFromChar(const wchar_t *c) const
|
||||
{
|
||||
return Areas[getAreaFromCharacter(*c, NULL)].spriteno;
|
||||
return Areas[getAreaFromCharacter(*c, NULL)].spriteno;
|
||||
}
|
||||
|
||||
|
||||
s32 ScalableFont::getAreaFromCharacter(const wchar_t c, bool* fallback_font) const
|
||||
{
|
||||
std::map<wchar_t, s32>::const_iterator n = CharacterMap.find(c);
|
||||
if (n != CharacterMap.end())
|
||||
std::map<wchar_t, s32>::const_iterator n = CharacterMap.find(c);
|
||||
if (n != CharacterMap.end())
|
||||
{
|
||||
if (fallback_font != NULL) *fallback_font = false;
|
||||
return (*n).second;
|
||||
return (*n).second;
|
||||
}
|
||||
else if (m_fallback_font != NULL && fallback_font != NULL)
|
||||
{
|
||||
@ -465,17 +465,17 @@ s32 ScalableFont::getAreaFromCharacter(const wchar_t c, bool* fallback_font) con
|
||||
*fallback_font = true;
|
||||
return m_fallback_font->getAreaFromCharacter(c, NULL);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
//std::cout << "The font does not have this character : <" << (int)c << ">" << std::endl;
|
||||
if (fallback_font != NULL) *fallback_font = false;
|
||||
return WrongCharacter;
|
||||
return WrongCharacter;
|
||||
}
|
||||
}
|
||||
|
||||
void ScalableFont::setInvisibleCharacters( const wchar_t *s )
|
||||
{
|
||||
Invisible = s;
|
||||
Invisible = s;
|
||||
}
|
||||
|
||||
|
||||
@ -484,50 +484,50 @@ core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
|
||||
{
|
||||
assert(Areas.size() > 0);
|
||||
|
||||
core::dimension2d<u32> dim(0, 0);
|
||||
core::dimension2d<u32> thisLine(0, (int)(MaxHeight*m_scale));
|
||||
core::dimension2d<u32> dim(0, 0);
|
||||
core::dimension2d<u32> thisLine(0, (int)(MaxHeight*m_scale));
|
||||
|
||||
for (const wchar_t* p = text; *p; ++p)
|
||||
{
|
||||
bool lineBreak=false;
|
||||
if (*p == L'\r') // Windows breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
if (p[1] == L'\n') // Windows breaks
|
||||
++p;
|
||||
}
|
||||
else if (*p == L'\n') // Unix breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
}
|
||||
if (lineBreak)
|
||||
{
|
||||
dim.Height += thisLine.Height;
|
||||
if (dim.Width < thisLine.Width)
|
||||
dim.Width = thisLine.Width;
|
||||
thisLine.Width = 0;
|
||||
continue;
|
||||
}
|
||||
for (const wchar_t* p = text; *p; ++p)
|
||||
{
|
||||
bool lineBreak=false;
|
||||
if (*p == L'\r') // Windows breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
if (p[1] == L'\n') // Windows breaks
|
||||
++p;
|
||||
}
|
||||
else if (*p == L'\n') // Unix breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
}
|
||||
if (lineBreak)
|
||||
{
|
||||
dim.Height += thisLine.Height;
|
||||
if (dim.Width < thisLine.Width)
|
||||
dim.Width = thisLine.Width;
|
||||
thisLine.Width = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool fallback = false;
|
||||
const int areaID = getAreaFromCharacter(*p, &fallback);
|
||||
assert(areaID < (int)Areas.size());
|
||||
const SFontArea &area = (fallback ? m_fallback_font->Areas[areaID] : Areas[areaID]);
|
||||
const SFontArea &area = (fallback ? m_fallback_font->Areas[areaID] : Areas[areaID]);
|
||||
|
||||
|
||||
//const TextureInfo& info = (*(m_texture_files.find(area.spriteno))).second;
|
||||
//const float char_scale = info.m_scale;
|
||||
|
||||
thisLine.Width += area.underhang;
|
||||
thisLine.Width += area.underhang;
|
||||
|
||||
thisLine.Width += getCharWidth(area, fallback);
|
||||
|
||||
//if (fallback) thisLine.Width += (area.width + area.overhang)*m_fallback_font_scale*char_scale*m_scale + m_fallback_kerning_width;
|
||||
//else thisLine.Width += (area.width + area.overhang)*m_scale*char_scale + GlobalKerningWidth;
|
||||
}
|
||||
//else thisLine.Width += (area.width + area.overhang)*m_scale*char_scale + GlobalKerningWidth;
|
||||
}
|
||||
|
||||
dim.Height += thisLine.Height;
|
||||
if (dim.Width < thisLine.Width) dim.Width = thisLine.Width;
|
||||
dim.Height += thisLine.Height;
|
||||
if (dim.Width < thisLine.Width) dim.Width = thisLine.Width;
|
||||
|
||||
// std::cout << "ScalableFont::getDimension returns : " << dim.Width << ", " << dim.Height << " --> ";
|
||||
|
||||
@ -536,14 +536,14 @@ core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
|
||||
|
||||
//std::cout << dim.Width << ", " << dim.Height << std::endl;
|
||||
|
||||
return dim;
|
||||
return dim;
|
||||
}
|
||||
|
||||
//! draws some text and clips it to the specified rectangle if wanted
|
||||
void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& position,
|
||||
video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip)
|
||||
video::SColor color, bool hcenter, bool vcenter, const core::rect<s32>* clip)
|
||||
{
|
||||
if (!Driver) return;
|
||||
if (!Driver) return;
|
||||
|
||||
if (m_shadow)
|
||||
{
|
||||
@ -560,41 +560,41 @@ void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& positi
|
||||
|
||||
//color = video::SColor(255,255,255,255);
|
||||
|
||||
core::dimension2d<s32> textDimension;
|
||||
core::position2d<s32> offset = position.UpperLeftCorner;
|
||||
core::dimension2d<s32> textDimension;
|
||||
core::position2d<s32> offset = position.UpperLeftCorner;
|
||||
|
||||
if (m_rtl || hcenter || vcenter || clip) textDimension = getDimension(text.c_str());
|
||||
if (m_rtl || hcenter || vcenter || clip) textDimension = getDimension(text.c_str());
|
||||
|
||||
if (hcenter)
|
||||
if (hcenter)
|
||||
{
|
||||
offset.X += (position.getWidth() - textDimension.Width) / 2;
|
||||
offset.X += (position.getWidth() - textDimension.Width) / 2;
|
||||
}
|
||||
else if (m_rtl)
|
||||
{
|
||||
offset.X += (position.getWidth() - textDimension.Width);
|
||||
}
|
||||
|
||||
if (vcenter)
|
||||
if (vcenter)
|
||||
{
|
||||
offset.Y += (position.getHeight() - textDimension.Height) / 2;
|
||||
offset.Y += (position.getHeight() - textDimension.Height) / 2;
|
||||
}
|
||||
|
||||
if (clip)
|
||||
{
|
||||
core::rect<s32> clippedRect(offset, textDimension);
|
||||
clippedRect.clipAgainst(*clip);
|
||||
if (!clippedRect.isValid()) return;
|
||||
}
|
||||
if (clip)
|
||||
{
|
||||
core::rect<s32> clippedRect(offset, textDimension);
|
||||
clippedRect.clipAgainst(*clip);
|
||||
if (!clippedRect.isValid()) return;
|
||||
}
|
||||
|
||||
// ---- collect character locations
|
||||
const unsigned int text_size = text.size();
|
||||
core::array<s32> indices(text_size);
|
||||
core::array<core::position2di> offsets(text_size);
|
||||
core::array<s32> indices(text_size);
|
||||
core::array<core::position2di> offsets(text_size);
|
||||
std::vector<bool> fallback(text_size);
|
||||
|
||||
for (u32 i = 0; i<text_size; i++)
|
||||
{
|
||||
wchar_t c = text[i];
|
||||
for (u32 i = 0; i<text_size; i++)
|
||||
{
|
||||
wchar_t c = text[i];
|
||||
|
||||
//hack: one tab character is supported, it moves the cursor to the middle of the area
|
||||
if (c == L'\t')
|
||||
@ -603,45 +603,45 @@ void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& positi
|
||||
continue;
|
||||
}
|
||||
|
||||
bool lineBreak=false;
|
||||
if (c == L'\r') // Windows breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
if (text[i + 1] == L'\n') c = text[++i];
|
||||
}
|
||||
else if ( c == L'\n') // Unix breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
}
|
||||
bool lineBreak=false;
|
||||
if (c == L'\r') // Windows breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
if (text[i + 1] == L'\n') c = text[++i];
|
||||
}
|
||||
else if ( c == L'\n') // Unix breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
}
|
||||
|
||||
if (lineBreak)
|
||||
{
|
||||
offset.Y += MaxHeight;
|
||||
offset.X = position.UpperLeftCorner.X;
|
||||
if (lineBreak)
|
||||
{
|
||||
offset.Y += MaxHeight;
|
||||
offset.X = position.UpperLeftCorner.X;
|
||||
|
||||
if ( hcenter )
|
||||
{
|
||||
core::dimension2d<u32> lineDim = getDimension(text.c_str());
|
||||
offset.X += (position.getWidth() - lineDim.Width) >> 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( hcenter )
|
||||
{
|
||||
core::dimension2d<u32> lineDim = getDimension(text.c_str());
|
||||
offset.X += (position.getWidth() - lineDim.Width) >> 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
bool fallback_font = false;
|
||||
const int areaID = getAreaFromCharacter(c, &fallback_font);
|
||||
//std::cout << "Char " << c << " has area " << areaID << std::endl;
|
||||
SFontArea& area = (fallback_font ? m_fallback_font->Areas[areaID] : Areas[areaID]);
|
||||
SFontArea& area = (fallback_font ? m_fallback_font->Areas[areaID] : Areas[areaID]);
|
||||
|
||||
//float char_scale = m_texture_files[area.spriteno].m_scale;
|
||||
|
||||
offset.X += area.underhang;
|
||||
if ( Invisible.findFirst ( c ) < 0 )
|
||||
{
|
||||
indices.push_back(area.spriteno);
|
||||
offsets.push_back(offset);
|
||||
offset.X += area.underhang;
|
||||
if ( Invisible.findFirst ( c ) < 0 )
|
||||
{
|
||||
indices.push_back(area.spriteno);
|
||||
offsets.push_back(offset);
|
||||
fallback[i] = fallback_font;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// invisible character. add something to the array anyway so that indices from
|
||||
@ -667,7 +667,7 @@ void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& positi
|
||||
offset.X += getCharWidth(area, fallback[i]);
|
||||
}
|
||||
|
||||
//SpriteBank->draw2DSpriteBatch(indices, offsets, clip, color);
|
||||
//SpriteBank->draw2DSpriteBatch(indices, offsets, clip, color);
|
||||
|
||||
// ---- do the actual rendering
|
||||
const int indiceAmount = indices.size();
|
||||
@ -871,28 +871,28 @@ int ScalableFont::getCharWidth(const SFontArea& area, const bool fallback) const
|
||||
//! Calculates the index of the character in the text which is on a specific position.
|
||||
s32 ScalableFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const
|
||||
{
|
||||
s32 x = 0;
|
||||
s32 idx = 0;
|
||||
s32 x = 0;
|
||||
s32 idx = 0;
|
||||
|
||||
while (text[idx])
|
||||
{
|
||||
const SFontArea& a = Areas[getAreaFromCharacter(text[idx], NULL)];
|
||||
while (text[idx])
|
||||
{
|
||||
const SFontArea& a = Areas[getAreaFromCharacter(text[idx], NULL)];
|
||||
|
||||
x += a.width + a.overhang + a.underhang + GlobalKerningWidth;
|
||||
x += a.width + a.overhang + a.underhang + GlobalKerningWidth;
|
||||
|
||||
if (x >= pixel_x)
|
||||
return idx;
|
||||
if (x >= pixel_x)
|
||||
return idx;
|
||||
|
||||
++idx;
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
IGUISpriteBank* ScalableFont::getSpriteBank() const
|
||||
{
|
||||
return SpriteBank;
|
||||
return SpriteBank;
|
||||
}
|
||||
|
||||
} // end namespace gui
|
||||
|
@ -21,14 +21,14 @@ namespace irr
|
||||
|
||||
namespace video
|
||||
{
|
||||
class IVideoDriver;
|
||||
class IImage;
|
||||
class IVideoDriver;
|
||||
class IImage;
|
||||
}
|
||||
|
||||
namespace gui
|
||||
{
|
||||
|
||||
class IGUIEnvironment;
|
||||
class IGUIEnvironment;
|
||||
|
||||
class ScalableFont : public IGUIFontBitmap
|
||||
{
|
||||
@ -63,8 +63,8 @@ public:
|
||||
float m_fallback_font_scale;
|
||||
int m_fallback_kerning_width;
|
||||
|
||||
//! constructor
|
||||
ScalableFont(IGUIEnvironment* env, const io::path& filename);
|
||||
//! constructor
|
||||
ScalableFont(IGUIEnvironment* env, const io::path& filename);
|
||||
|
||||
/** Creates a hollow copy of this font; i.e. the underlying font data is the *same* for
|
||||
* both fonts. The advantage of doing this is that you can change "view" parameters
|
||||
@ -81,84 +81,84 @@ public:
|
||||
return out;
|
||||
}
|
||||
|
||||
//! destructor
|
||||
virtual ~ScalableFont();
|
||||
//! destructor
|
||||
virtual ~ScalableFont();
|
||||
|
||||
//! loads a font from a texture file
|
||||
//bool load(const io::path& filename);
|
||||
//! loads a font from a texture file
|
||||
//bool load(const io::path& filename);
|
||||
|
||||
//! loads a font from a texture file
|
||||
//bool load(io::IReadFile* file);
|
||||
//! loads a font from a texture file
|
||||
//bool load(io::IReadFile* file);
|
||||
|
||||
//! loads a font from an XML file
|
||||
bool load(io::IXMLReader* xml);
|
||||
//! loads a font from an XML file
|
||||
bool load(io::IXMLReader* xml);
|
||||
|
||||
//! draws an text and clips it to the specified rectangle if wanted
|
||||
virtual void draw(const core::stringw& text, const core::rect<s32>& position,
|
||||
video::SColor color, bool hcenter=false,
|
||||
bool vcenter=false, const core::rect<s32>* clip=0);
|
||||
//! draws an text and clips it to the specified rectangle if wanted
|
||||
virtual void draw(const core::stringw& text, const core::rect<s32>& position,
|
||||
video::SColor color, bool hcenter=false,
|
||||
bool vcenter=false, const core::rect<s32>* clip=0);
|
||||
|
||||
//! returns the dimension of a text
|
||||
virtual core::dimension2d<u32> getDimension(const wchar_t* text) const;
|
||||
//! returns the dimension of a text
|
||||
virtual core::dimension2d<u32> getDimension(const wchar_t* text) const;
|
||||
|
||||
//! Calculates the index of the character in the text which is on a specific position.
|
||||
virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const;
|
||||
//! Calculates the index of the character in the text which is on a specific position.
|
||||
virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const;
|
||||
|
||||
//! Returns the type of this font
|
||||
virtual EGUI_FONT_TYPE getType() const { return EGFT_BITMAP; }
|
||||
//! Returns the type of this font
|
||||
virtual EGUI_FONT_TYPE getType() const { return EGFT_BITMAP; }
|
||||
|
||||
//! set an Pixel Offset on Drawing ( scale position on width )
|
||||
virtual void setKerningWidth (s32 kerning);
|
||||
virtual void setKerningHeight (s32 kerning);
|
||||
//! set an Pixel Offset on Drawing ( scale position on width )
|
||||
virtual void setKerningWidth (s32 kerning);
|
||||
virtual void setKerningHeight (s32 kerning);
|
||||
|
||||
//! set an Pixel Offset on Drawing ( scale position on width )
|
||||
virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const;
|
||||
virtual s32 getKerningHeight() const;
|
||||
//! set an Pixel Offset on Drawing ( scale position on width )
|
||||
virtual s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const;
|
||||
virtual s32 getKerningHeight() const;
|
||||
|
||||
void setShadow(irr::video::SColor col);
|
||||
|
||||
//! gets the sprite bank
|
||||
virtual IGUISpriteBank* getSpriteBank() const;
|
||||
//! gets the sprite bank
|
||||
virtual IGUISpriteBank* getSpriteBank() const;
|
||||
|
||||
//! returns the sprite number from a given character
|
||||
virtual u32 getSpriteNoFromChar(const wchar_t *c) const;
|
||||
//! returns the sprite number from a given character
|
||||
virtual u32 getSpriteNoFromChar(const wchar_t *c) const;
|
||||
|
||||
virtual void setInvisibleCharacters( const wchar_t *s );
|
||||
virtual void setInvisibleCharacters( const wchar_t *s );
|
||||
|
||||
void setScale(const float scale);
|
||||
float getScale() const { return m_scale; }
|
||||
|
||||
private:
|
||||
|
||||
struct SFontArea
|
||||
{
|
||||
SFontArea() : underhang(0), overhang(0), width(0), spriteno(0) {}
|
||||
s32 underhang;
|
||||
s32 overhang;
|
||||
s32 width;
|
||||
u32 spriteno;
|
||||
};
|
||||
struct SFontArea
|
||||
{
|
||||
SFontArea() : underhang(0), overhang(0), width(0), spriteno(0) {}
|
||||
s32 underhang;
|
||||
s32 overhang;
|
||||
s32 width;
|
||||
u32 spriteno;
|
||||
};
|
||||
|
||||
int getCharWidth(const SFontArea& area, const bool fallback) const;
|
||||
|
||||
//! load & prepare font from ITexture
|
||||
//bool loadTexture(video::IImage * image, const io::path& name);
|
||||
//! load & prepare font from ITexture
|
||||
//bool loadTexture(video::IImage * image, const io::path& name);
|
||||
|
||||
//void readPositions(video::IImage* texture, s32& lowerRightPositions);
|
||||
//void readPositions(video::IImage* texture, s32& lowerRightPositions);
|
||||
|
||||
s32 getAreaFromCharacter (const wchar_t c, bool* fallback_font) const;
|
||||
void setMaxHeight();
|
||||
s32 getAreaFromCharacter (const wchar_t c, bool* fallback_font) const;
|
||||
void setMaxHeight();
|
||||
|
||||
core::array<SFontArea> Areas;
|
||||
std::map<wchar_t, s32> CharacterMap;
|
||||
video::IVideoDriver* Driver;
|
||||
IGUISpriteBank* SpriteBank;
|
||||
IGUIEnvironment* Environment;
|
||||
u32 WrongCharacter;
|
||||
s32 MaxHeight;
|
||||
s32 GlobalKerningWidth, GlobalKerningHeight;
|
||||
core::array<SFontArea> Areas;
|
||||
std::map<wchar_t, s32> CharacterMap;
|
||||
video::IVideoDriver* Driver;
|
||||
IGUISpriteBank* SpriteBank;
|
||||
IGUIEnvironment* Environment;
|
||||
u32 WrongCharacter;
|
||||
s32 MaxHeight;
|
||||
s32 GlobalKerningWidth, GlobalKerningHeight;
|
||||
|
||||
core::stringw Invisible;
|
||||
core::stringw Invisible;
|
||||
};
|
||||
|
||||
} // end namespace gui
|
||||
|
@ -16,35 +16,35 @@ namespace gui
|
||||
{
|
||||
|
||||
STKModifiedSpriteBank::STKModifiedSpriteBank(IGUIEnvironment* env) :
|
||||
Environment(env), Driver(0)
|
||||
Environment(env), Driver(0)
|
||||
{
|
||||
m_magic_number = 0xCAFEC001;
|
||||
|
||||
#ifdef _DEBUG
|
||||
setDebugName("STKModifiedSpriteBank");
|
||||
#endif
|
||||
#ifdef _DEBUG
|
||||
setDebugName("STKModifiedSpriteBank");
|
||||
#endif
|
||||
|
||||
m_scale = 1.0f;
|
||||
|
||||
if (Environment)
|
||||
{
|
||||
Driver = Environment->getVideoDriver();
|
||||
if (Driver)
|
||||
Driver->grab();
|
||||
}
|
||||
if (Environment)
|
||||
{
|
||||
Driver = Environment->getVideoDriver();
|
||||
if (Driver)
|
||||
Driver->grab();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STKModifiedSpriteBank::~STKModifiedSpriteBank()
|
||||
{
|
||||
// drop textures
|
||||
for (u32 i=0; i<Textures.size(); ++i)
|
||||
if (Textures[i])
|
||||
Textures[i]->drop();
|
||||
// drop textures
|
||||
for (u32 i=0; i<Textures.size(); ++i)
|
||||
if (Textures[i])
|
||||
Textures[i]->drop();
|
||||
|
||||
// drop video driver
|
||||
if (Driver)
|
||||
Driver->drop();
|
||||
// drop video driver
|
||||
if (Driver)
|
||||
Driver->drop();
|
||||
|
||||
m_magic_number = 0xDEADBEEF;
|
||||
}
|
||||
@ -67,57 +67,57 @@ core::array< core::rect<s32> >& STKModifiedSpriteBank::getPositions()
|
||||
);
|
||||
}
|
||||
|
||||
return copy;
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
core::array< SGUISprite >& STKModifiedSpriteBank::getSprites()
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
return Sprites;
|
||||
return Sprites;
|
||||
}
|
||||
|
||||
|
||||
u32 STKModifiedSpriteBank::getTextureCount() const
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
return Textures.size();
|
||||
return Textures.size();
|
||||
}
|
||||
|
||||
|
||||
video::ITexture* STKModifiedSpriteBank::getTexture(u32 index) const
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
if (index < Textures.size())
|
||||
return Textures[index];
|
||||
else
|
||||
return 0;
|
||||
if (index < Textures.size())
|
||||
return Textures[index];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void STKModifiedSpriteBank::addTexture(video::ITexture* texture)
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
if (texture)
|
||||
texture->grab();
|
||||
if (texture)
|
||||
texture->grab();
|
||||
|
||||
Textures.push_back(texture);
|
||||
Textures.push_back(texture);
|
||||
}
|
||||
|
||||
|
||||
void STKModifiedSpriteBank::setTexture(u32 index, video::ITexture* texture)
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
while (index >= Textures.size())
|
||||
Textures.push_back(0);
|
||||
while (index >= Textures.size())
|
||||
Textures.push_back(0);
|
||||
|
||||
if (texture)
|
||||
texture->grab();
|
||||
if (texture)
|
||||
texture->grab();
|
||||
|
||||
if (Textures[index])
|
||||
Textures[index]->drop();
|
||||
if (Textures[index])
|
||||
Textures[index]->drop();
|
||||
|
||||
Textures[index] = texture;
|
||||
Textures[index] = texture;
|
||||
}
|
||||
|
||||
|
||||
@ -125,78 +125,78 @@ void STKModifiedSpriteBank::setTexture(u32 index, video::ITexture* texture)
|
||||
void STKModifiedSpriteBank::clear()
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
// drop textures
|
||||
for (u32 i=0; i<Textures.size(); ++i)
|
||||
if (Textures[i])
|
||||
Textures[i]->drop();
|
||||
Textures.clear();
|
||||
Sprites.clear();
|
||||
Rectangles.clear();
|
||||
// drop textures
|
||||
for (u32 i=0; i<Textures.size(); ++i)
|
||||
if (Textures[i])
|
||||
Textures[i]->drop();
|
||||
Textures.clear();
|
||||
Sprites.clear();
|
||||
Rectangles.clear();
|
||||
}
|
||||
|
||||
//! Add the texture and use it for a single non-animated sprite.
|
||||
s32 STKModifiedSpriteBank::addTextureAsSprite(video::ITexture* texture)
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
if ( !texture )
|
||||
return -1;
|
||||
if ( !texture )
|
||||
return -1;
|
||||
|
||||
addTexture(texture);
|
||||
u32 textureIndex = getTextureCount() - 1;
|
||||
addTexture(texture);
|
||||
u32 textureIndex = getTextureCount() - 1;
|
||||
|
||||
u32 rectangleIndex = Rectangles.size();
|
||||
Rectangles.push_back( core::rect<s32>(0,0, texture->getOriginalSize().Width, texture->getOriginalSize().Height) );
|
||||
u32 rectangleIndex = Rectangles.size();
|
||||
Rectangles.push_back( core::rect<s32>(0,0, texture->getOriginalSize().Width, texture->getOriginalSize().Height) );
|
||||
|
||||
SGUISprite sprite;
|
||||
sprite.frameTime = 0;
|
||||
SGUISprite sprite;
|
||||
sprite.frameTime = 0;
|
||||
|
||||
SGUISpriteFrame frame;
|
||||
frame.textureNumber = textureIndex;
|
||||
frame.rectNumber = rectangleIndex;
|
||||
sprite.Frames.push_back( frame );
|
||||
SGUISpriteFrame frame;
|
||||
frame.textureNumber = textureIndex;
|
||||
frame.rectNumber = rectangleIndex;
|
||||
sprite.Frames.push_back( frame );
|
||||
|
||||
Sprites.push_back( sprite );
|
||||
Sprites.push_back( sprite );
|
||||
|
||||
return Sprites.size() - 1;
|
||||
return Sprites.size() - 1;
|
||||
}
|
||||
|
||||
//! draws a sprite in 2d with scale and color
|
||||
void STKModifiedSpriteBank::draw2DSprite(u32 index, const core::position2di& pos,
|
||||
const core::rect<s32>* clip, const video::SColor& color,
|
||||
u32 starttime, u32 currenttime, bool loop, bool center)
|
||||
const core::rect<s32>* clip, const video::SColor& color,
|
||||
u32 starttime, u32 currenttime, bool loop, bool center)
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
if (index >= Sprites.size() || Sprites[index].Frames.empty() )
|
||||
return;
|
||||
if (index >= Sprites.size() || Sprites[index].Frames.empty() )
|
||||
return;
|
||||
|
||||
// work out frame number
|
||||
u32 frame = 0;
|
||||
if (Sprites[index].frameTime)
|
||||
{
|
||||
u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
|
||||
if (loop)
|
||||
frame = f % Sprites[index].Frames.size();
|
||||
else
|
||||
frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
|
||||
}
|
||||
// work out frame number
|
||||
u32 frame = 0;
|
||||
if (Sprites[index].frameTime)
|
||||
{
|
||||
u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
|
||||
if (loop)
|
||||
frame = f % Sprites[index].Frames.size();
|
||||
else
|
||||
frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
|
||||
}
|
||||
|
||||
const video::ITexture* tex = Textures[Sprites[index].Frames[frame].textureNumber];
|
||||
if (!tex)
|
||||
return;
|
||||
const video::ITexture* tex = Textures[Sprites[index].Frames[frame].textureNumber];
|
||||
if (!tex)
|
||||
return;
|
||||
|
||||
const u32 rn = Sprites[index].Frames[frame].rectNumber;
|
||||
if (rn >= Rectangles.size())
|
||||
return;
|
||||
const u32 rn = Sprites[index].Frames[frame].rectNumber;
|
||||
if (rn >= Rectangles.size())
|
||||
return;
|
||||
|
||||
const core::rect<s32>& r = Rectangles[rn];
|
||||
const core::rect<s32>& r = Rectangles[rn];
|
||||
|
||||
const core::dimension2d<s32>& dim = r.getSize();
|
||||
|
||||
core::rect<s32> dest( pos, core::dimension2d<s32>((int)(dim.Width*m_scale),
|
||||
(int)(dim.Height*m_scale)) );
|
||||
if (center)
|
||||
{
|
||||
dest -= dest.getSize() / 2;
|
||||
if (center)
|
||||
{
|
||||
dest -= dest.getSize() / 2;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -209,73 +209,73 @@ void STKModifiedSpriteBank::draw2DSprite(u32 index, const core::position2di& pos
|
||||
}
|
||||
|
||||
|
||||
void STKModifiedSpriteBank::draw2DSpriteBatch( const core::array<u32>& indices,
|
||||
const core::array<core::position2di>& pos,
|
||||
const core::rect<s32>* clip,
|
||||
const video::SColor& color,
|
||||
u32 starttime, u32 currenttime,
|
||||
bool loop, bool center)
|
||||
void STKModifiedSpriteBank::draw2DSpriteBatch( const core::array<u32>& indices,
|
||||
const core::array<core::position2di>& pos,
|
||||
const core::rect<s32>* clip,
|
||||
const video::SColor& color,
|
||||
u32 starttime, u32 currenttime,
|
||||
bool loop, bool center)
|
||||
{
|
||||
assert( m_magic_number == 0xCAFEC001 );
|
||||
const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());
|
||||
const irr::u32 drawCount = core::min_<u32>(indices.size(), pos.size());
|
||||
|
||||
core::array<SDrawBatch> drawBatches(Textures.size());
|
||||
for(u32 i = 0;i < Textures.size();i++)
|
||||
{
|
||||
drawBatches.push_back(SDrawBatch());
|
||||
drawBatches[i].positions.reallocate(drawCount);
|
||||
drawBatches[i].sourceRects.reallocate(drawCount);
|
||||
}
|
||||
core::array<SDrawBatch> drawBatches(Textures.size());
|
||||
for(u32 i = 0;i < Textures.size();i++)
|
||||
{
|
||||
drawBatches.push_back(SDrawBatch());
|
||||
drawBatches[i].positions.reallocate(drawCount);
|
||||
drawBatches[i].sourceRects.reallocate(drawCount);
|
||||
}
|
||||
|
||||
for(u32 i = 0;i < drawCount;i++)
|
||||
{
|
||||
const u32 index = indices[i];
|
||||
for(u32 i = 0;i < drawCount;i++)
|
||||
{
|
||||
const u32 index = indices[i];
|
||||
|
||||
if (index >= Sprites.size() || Sprites[index].Frames.empty() )
|
||||
continue;
|
||||
if (index >= Sprites.size() || Sprites[index].Frames.empty() )
|
||||
continue;
|
||||
|
||||
// work out frame number
|
||||
u32 frame = 0;
|
||||
if (Sprites[index].frameTime)
|
||||
{
|
||||
u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
|
||||
if (loop)
|
||||
frame = f % Sprites[index].Frames.size();
|
||||
else
|
||||
frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
|
||||
}
|
||||
// work out frame number
|
||||
u32 frame = 0;
|
||||
if (Sprites[index].frameTime)
|
||||
{
|
||||
u32 f = ((currenttime - starttime) / Sprites[index].frameTime);
|
||||
if (loop)
|
||||
frame = f % Sprites[index].Frames.size();
|
||||
else
|
||||
frame = (f >= Sprites[index].Frames.size()) ? Sprites[index].Frames.size()-1 : f;
|
||||
}
|
||||
|
||||
const u32 texNum = Sprites[index].Frames[frame].textureNumber;
|
||||
const u32 texNum = Sprites[index].Frames[frame].textureNumber;
|
||||
|
||||
SDrawBatch& currentBatch = drawBatches[texNum];
|
||||
SDrawBatch& currentBatch = drawBatches[texNum];
|
||||
|
||||
const u32 rn = Sprites[index].Frames[frame].rectNumber;
|
||||
if (rn >= Rectangles.size())
|
||||
return;
|
||||
const u32 rn = Sprites[index].Frames[frame].rectNumber;
|
||||
if (rn >= Rectangles.size())
|
||||
return;
|
||||
|
||||
const core::rect<s32>& r = Rectangles[rn];
|
||||
const core::rect<s32>& r = Rectangles[rn];
|
||||
|
||||
if (center)
|
||||
{
|
||||
core::position2di p = pos[i];
|
||||
p -= r.getSize() / 2;
|
||||
if (center)
|
||||
{
|
||||
core::position2di p = pos[i];
|
||||
p -= r.getSize() / 2;
|
||||
|
||||
currentBatch.positions.push_back(p);
|
||||
currentBatch.sourceRects.push_back(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentBatch.positions.push_back(pos[i]);
|
||||
currentBatch.sourceRects.push_back(r);
|
||||
}
|
||||
}
|
||||
currentBatch.positions.push_back(p);
|
||||
currentBatch.sourceRects.push_back(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentBatch.positions.push_back(pos[i]);
|
||||
currentBatch.sourceRects.push_back(r);
|
||||
}
|
||||
}
|
||||
|
||||
for(u32 i = 0;i < drawBatches.size();i++)
|
||||
{
|
||||
if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty())
|
||||
Driver->draw2DImageBatch(Textures[i], drawBatches[i].positions,
|
||||
drawBatches[i].sourceRects, clip, color, true);
|
||||
}
|
||||
for(u32 i = 0;i < drawBatches.size();i++)
|
||||
{
|
||||
if(!drawBatches[i].positions.empty() && !drawBatches[i].sourceRects.empty())
|
||||
Driver->draw2DImageBatch(Textures[i], drawBatches[i].positions,
|
||||
drawBatches[i].sourceRects, clip, color, true);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gui
|
||||
|
@ -15,48 +15,48 @@ namespace irr
|
||||
|
||||
namespace video
|
||||
{
|
||||
class IVideoDriver;
|
||||
class ITexture;
|
||||
class IVideoDriver;
|
||||
class ITexture;
|
||||
}
|
||||
|
||||
namespace gui
|
||||
{
|
||||
|
||||
class IGUIEnvironment;
|
||||
class IGUIEnvironment;
|
||||
|
||||
//! Sprite bank interface.
|
||||
class STKModifiedSpriteBank : public IGUISpriteBank
|
||||
{
|
||||
public:
|
||||
|
||||
STKModifiedSpriteBank(IGUIEnvironment* env);
|
||||
virtual ~STKModifiedSpriteBank();
|
||||
STKModifiedSpriteBank(IGUIEnvironment* env);
|
||||
virtual ~STKModifiedSpriteBank();
|
||||
|
||||
virtual core::array< core::rect<s32> >& getPositions();
|
||||
virtual core::array< SGUISprite >& getSprites();
|
||||
virtual core::array< core::rect<s32> >& getPositions();
|
||||
virtual core::array< SGUISprite >& getSprites();
|
||||
|
||||
virtual u32 getTextureCount() const;
|
||||
virtual video::ITexture* getTexture(u32 index) const;
|
||||
virtual void addTexture(video::ITexture* texture);
|
||||
virtual void setTexture(u32 index, video::ITexture* texture);
|
||||
virtual u32 getTextureCount() const;
|
||||
virtual video::ITexture* getTexture(u32 index) const;
|
||||
virtual void addTexture(video::ITexture* texture);
|
||||
virtual void setTexture(u32 index, video::ITexture* texture);
|
||||
|
||||
//! Add the texture and use it for a single non-animated sprite.
|
||||
virtual s32 addTextureAsSprite(video::ITexture* texture);
|
||||
//! Add the texture and use it for a single non-animated sprite.
|
||||
virtual s32 addTextureAsSprite(video::ITexture* texture);
|
||||
|
||||
//! clears sprites, rectangles and textures
|
||||
virtual void clear();
|
||||
//! clears sprites, rectangles and textures
|
||||
virtual void clear();
|
||||
|
||||
//! Draws a sprite in 2d with position and color
|
||||
virtual void draw2DSprite(u32 index, const core::position2di& pos, const core::rect<s32>* clip=0,
|
||||
const video::SColor& color= video::SColor(255,255,255,255),
|
||||
u32 starttime=0, u32 currenttime=0, bool loop=true, bool center=false);
|
||||
//! Draws a sprite in 2d with position and color
|
||||
virtual void draw2DSprite(u32 index, const core::position2di& pos, const core::rect<s32>* clip=0,
|
||||
const video::SColor& color= video::SColor(255,255,255,255),
|
||||
u32 starttime=0, u32 currenttime=0, bool loop=true, bool center=false);
|
||||
|
||||
//! Draws a sprite batch in 2d using an array of positions and a color
|
||||
virtual void draw2DSpriteBatch(const core::array<u32>& indices, const core::array<core::position2di>& pos,
|
||||
const core::rect<s32>* clip=0,
|
||||
const video::SColor& color= video::SColor(255,255,255,255),
|
||||
u32 starttime=0, u32 currenttime=0,
|
||||
bool loop=true, bool center=false);
|
||||
//! Draws a sprite batch in 2d using an array of positions and a color
|
||||
virtual void draw2DSpriteBatch(const core::array<u32>& indices, const core::array<core::position2di>& pos,
|
||||
const core::rect<s32>* clip=0,
|
||||
const video::SColor& color= video::SColor(255,255,255,255),
|
||||
u32 starttime=0, u32 currenttime=0,
|
||||
bool loop=true, bool center=false);
|
||||
|
||||
void setScale(float scale)
|
||||
{
|
||||
@ -71,22 +71,22 @@ protected:
|
||||
|
||||
float m_scale;
|
||||
|
||||
struct SDrawBatch
|
||||
{
|
||||
core::array<core::position2di> positions;
|
||||
core::array<core::recti> sourceRects;
|
||||
u32 textureNumber;
|
||||
};
|
||||
struct SDrawBatch
|
||||
{
|
||||
core::array<core::position2di> positions;
|
||||
core::array<core::recti> sourceRects;
|
||||
u32 textureNumber;
|
||||
};
|
||||
|
||||
//FIXME: ugly hack to work around irrLicht limitations, see STKModifiedSpriteBank::getPositions()
|
||||
// for all the gory details.
|
||||
core::array< core::rect<s32> > copy;
|
||||
|
||||
core::array<SGUISprite> Sprites;
|
||||
core::array< core::rect<s32> > Rectangles;
|
||||
core::array<video::ITexture*> Textures;
|
||||
IGUIEnvironment* Environment;
|
||||
video::IVideoDriver* Driver;
|
||||
core::array<SGUISprite> Sprites;
|
||||
core::array< core::rect<s32> > Rectangles;
|
||||
core::array<video::ITexture*> Textures;
|
||||
IGUIEnvironment* Environment;
|
||||
video::IVideoDriver* Driver;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user