Commit 8cb3aebf authored by hybrid's avatar hybrid

Fix warnings, layout, and return value.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3871 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 009a6bfc
...@@ -9,23 +9,23 @@ namespace ...@@ -9,23 +9,23 @@ namespace
// based on code and media from SuperTuxKart // based on code and media from SuperTuxKart
class ScalableFont : public gui::IGUIFontBitmap class ScalableFont : public gui::IGUIFontBitmap
{ {
float m_scale; float m_scale;
struct TextureInfo struct TextureInfo
{ {
irr::core::stringc m_file_name; irr::core::stringc m_file_name;
bool m_has_alpha; bool m_has_alpha;
float m_scale; float m_scale;
TextureInfo() TextureInfo()
{ {
m_has_alpha = false; m_has_alpha = false;
m_scale = 1.0f; m_scale = 1.0f;
} }
}; };
std::map<int /* texture file ID */, TextureInfo> m_texture_files; std::map<int /* texture file ID */, TextureInfo> m_texture_files;
void lazyLoadTexture(int texID) void lazyLoadTexture(int texID)
{ {
const bool mipmap = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); const bool mipmap = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true); Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
...@@ -33,7 +33,7 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -33,7 +33,7 @@ class ScalableFont : public gui::IGUIFontBitmap
SpriteBank->setTexture(texID, Driver->getTexture( m_texture_files[texID].m_file_name )); SpriteBank->setTexture(texID, Driver->getTexture( m_texture_files[texID].m_file_name ));
// set previous mip-map+filter state // set previous mip-map+filter state
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap); Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap);
// couldn't load texture, abort. // couldn't load texture, abort.
if (!SpriteBank->getTexture(texID)) if (!SpriteBank->getTexture(texID))
{ {
...@@ -48,7 +48,7 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -48,7 +48,7 @@ class ScalableFont : public gui::IGUIFontBitmap
} }
} }
} }
void doReadXmlFile(io::IXMLReader* xml) void doReadXmlFile(io::IXMLReader* xml)
{ {
while (xml->read()) while (xml->read())
{ {
...@@ -70,29 +70,29 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -70,29 +70,29 @@ class ScalableFont : public gui::IGUIFontBitmap
core::stringc filename = xml->getAttributeValue(L"filename"); core::stringc filename = xml->getAttributeValue(L"filename");
core::stringc fn = filename; core::stringc fn = filename;
u32 i = (u32)xml->getAttributeValueAsInt(L"index"); u32 i = (u32)xml->getAttributeValueAsInt(L"index");
float scale=1.0f; float scale=1.0f;
if(xml->getAttributeValue(L"scale")) if (xml->getAttributeValue(L"scale"))
scale = xml->getAttributeValueAsFloat(L"scale"); scale = xml->getAttributeValueAsFloat(L"scale");
//std::cout << "scale = " << scale << std::endl; //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; //std::cout << "---- Adding font texture " << fn.c_str() << "; alpha=" << alpha.c_str() << std::endl;
// make sure the sprite bank has enough textures in it // 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; TextureInfo info;
info.m_file_name = fn; info.m_file_name = fn;
info.m_has_alpha = (alpha == core::stringw("true")); info.m_has_alpha = (alpha == core::stringw("true"));
info.m_scale = scale; info.m_scale = scale;
m_texture_files[i] = info; m_texture_files[i] = info;
} }
else if (core::stringw(L"c") == xml->getNodeName()) else if (core::stringw(L"c") == xml->getNodeName())
{ {
...@@ -101,16 +101,16 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -101,16 +101,16 @@ class ScalableFont : public gui::IGUIFontBitmap
gui::SGUISpriteFrame f; gui::SGUISpriteFrame f;
gui::SGUISprite s; gui::SGUISprite s;
core::rect<s32> rectangle; core::rect<s32> rectangle;
a.underhang = xml->getAttributeValueAsInt(L"u"); a.underhang = xml->getAttributeValueAsInt(L"u");
a.overhang = xml->getAttributeValueAsInt(L"o"); a.overhang = xml->getAttributeValueAsInt(L"o");
a.spriteno = SpriteBank->getSprites().size(); a.spriteno = SpriteBank->getSprites().size();
s32 texno = xml->getAttributeValueAsInt(L"i"); s32 texno = xml->getAttributeValueAsInt(L"i");
// parse rectangle // parse rectangle
core::stringc rectstr = xml->getAttributeValue(L"r"); core::stringc rectstr = xml->getAttributeValue(L"r");
wchar_t ch = xml->getAttributeValue(L"c")[0]; wchar_t ch = xml->getAttributeValue(L"c")[0];
const c8 *c = rectstr.c_str(); const c8 *c = rectstr.c_str();
s32 val; s32 val;
val = 0; val = 0;
...@@ -122,7 +122,7 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -122,7 +122,7 @@ class ScalableFont : public gui::IGUIFontBitmap
} }
rectangle.UpperLeftCorner.X = val; rectangle.UpperLeftCorner.X = val;
while (*c == L' ' || *c == L',') c++; while (*c == L' ' || *c == L',') c++;
val = 0; val = 0;
while (*c >= '0' && *c <= '9') while (*c >= '0' && *c <= '9')
{ {
...@@ -132,7 +132,7 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -132,7 +132,7 @@ class ScalableFont : public gui::IGUIFontBitmap
} }
rectangle.UpperLeftCorner.Y = val; rectangle.UpperLeftCorner.Y = val;
while (*c == L' ' || *c == L',') c++; while (*c == L' ' || *c == L',') c++;
val = 0; val = 0;
while (*c >= '0' && *c <= '9') while (*c >= '0' && *c <= '9')
{ {
...@@ -142,7 +142,7 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -142,7 +142,7 @@ class ScalableFont : public gui::IGUIFontBitmap
} }
rectangle.LowerRightCorner.X = val; rectangle.LowerRightCorner.X = val;
while (*c == L' ' || *c == L',') c++; while (*c == L' ' || *c == L',') c++;
val = 0; val = 0;
while (*c >= '0' && *c <= '9') while (*c >= '0' && *c <= '9')
{ {
...@@ -151,24 +151,24 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -151,24 +151,24 @@ class ScalableFont : public gui::IGUIFontBitmap
c++; c++;
} }
rectangle.LowerRightCorner.Y = val; rectangle.LowerRightCorner.Y = val;
CharacterMap[ch] = Areas.size(); CharacterMap[ch] = Areas.size();
// make frame // make frame
f.rectNumber = SpriteBank->getPositions().size(); f.rectNumber = SpriteBank->getPositions().size();
f.textureNumber = texno; f.textureNumber = texno;
// 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(rectangle);
a.width = rectangle.getWidth(); a.width = rectangle.getWidth();
// add sprite to sprite bank // add sprite to sprite bank
SpriteBank->getSprites().push_back(s); SpriteBank->getSprites().push_back(s);
// add character to font // add character to font
Areas.push_back(a); Areas.push_back(a);
} }
...@@ -178,13 +178,13 @@ class ScalableFont : public gui::IGUIFontBitmap ...@@ -178,13 +178,13 @@ class ScalableFont : public gui::IGUIFontBitmap
public: public:
bool m_black_border; bool m_black_border;
ScalableFont* m_fallback_font; ScalableFont* m_fallback_font;
float m_fallback_font_scale; float m_fallback_font_scale;
int m_fallback_kerning_width; int m_fallback_kerning_width;
//! constructor //! constructor
ScalableFont(gui::IGUIEnvironment *env, const io::path& filename) ScalableFont(gui::IGUIEnvironment *env, const io::path& filename)
: Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0), : Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0),
MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0) MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0)
...@@ -192,12 +192,12 @@ public: ...@@ -192,12 +192,12 @@ public:
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("ScalableFont"); setDebugName("ScalableFont");
#endif #endif
m_fallback_font = NULL; m_fallback_font = NULL;
m_fallback_kerning_width = 0; m_fallback_kerning_width = 0;
m_fallback_font_scale = 1.0f; m_fallback_font_scale = 1.0f;
m_scale = 0.37f; m_scale = 0.37f;
m_black_border = false; m_black_border = false;
if (Environment) if (Environment)
{ {
...@@ -213,7 +213,7 @@ public: ...@@ -213,7 +213,7 @@ public:
Driver->grab(); Driver->grab();
setInvisibleCharacters ( L" " ); setInvisibleCharacters ( L" " );
io::IXMLReader* reader = env->getFileSystem()->createXMLReader(filename.c_str()); io::IXMLReader* reader = env->getFileSystem()->createXMLReader(filename.c_str());
if (reader) if (reader)
{ {
...@@ -223,21 +223,23 @@ public: ...@@ -223,21 +223,23 @@ public:
assert(Areas.size() > 0); assert(Areas.size() > 0);
} }
//! destructor //! destructor
virtual ~ScalableFont() virtual ~ScalableFont()
{ {
if (Driver) Driver->drop(); if (Driver)
if (SpriteBank) SpriteBank->drop(); Driver->drop();
if (SpriteBank)
SpriteBank->drop();
} }
//! loads a font from an XML file //! loads a font from an XML file
bool load(io::IXMLReader* xml) bool load(io::IXMLReader* xml)
{ {
if (!SpriteBank) if (!SpriteBank)
return false; return false;
doReadXmlFile(xml); doReadXmlFile(xml);
// set bad character // set bad character
WrongCharacter = getAreaIDFromCharacter(L' ', NULL); WrongCharacter = getAreaIDFromCharacter(L' ', NULL);
...@@ -246,20 +248,21 @@ public: ...@@ -246,20 +248,21 @@ public:
for(wchar_t c='0'; c<='9'; c++) for(wchar_t c='0'; c<='9'; c++)
{ {
SFontArea a = getAreaFromCharacter(c, NULL); SFontArea a = getAreaFromCharacter(c, NULL);
if(a.overhang > m_max_digit_area.overhang ) m_max_digit_area.overhang = a.overhang; if (a.overhang > m_max_digit_area.overhang ) m_max_digit_area.overhang = a.overhang;
if(a.underhang > m_max_digit_area.underhang) m_max_digit_area.underhang = a.underhang; if (a.underhang > m_max_digit_area.underhang) m_max_digit_area.underhang = a.underhang;
if(a.width > m_max_digit_area.width ) m_max_digit_area.width = a.width; if (a.width > m_max_digit_area.width) m_max_digit_area.width = a.width;
} }
m_max_digit_area.overhang = 0;m_max_digit_area.underhang=0; m_max_digit_area.overhang = 0;
m_max_digit_area.underhang=0;
return true; return true;
} }
//! 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,
bool vcenter=false, const core::rect<s32>* clip=0) bool vcenter=false, const core::rect<s32>* clip=0)
{ {
if (!Driver) return; if (!Driver) return;
core::position2d<s32> offset = position.UpperLeftCorner; core::position2d<s32> offset = position.UpperLeftCorner;
core::dimension2d<s32> text_dimension; core::dimension2d<s32> text_dimension;
...@@ -267,11 +270,11 @@ public: ...@@ -267,11 +270,11 @@ public:
// bool has_tab = (text.findFirst(L'\t') != -1); // bool has_tab = (text.findFirst(L'\t') != -1);
// ---- collect character locations // ---- collect character locations
const unsigned int text_size = text.size(); const unsigned int text_size = text.size();
core::array<s32> indices(text_size); core::array<s32> indices(text_size);
core::array<core::position2di> offsets(text_size); core::array<core::position2di> offsets(text_size);
core::array<bool> fallback; core::array<bool> fallback;
fallback.set_used(text_size); fallback.set_used(text_size);
for (u32 i = 0; i<text_size; i++) for (u32 i = 0; i<text_size; i++)
{ {
wchar_t c = text[i]; wchar_t c = text[i];
...@@ -282,11 +285,12 @@ public: ...@@ -282,11 +285,12 @@ public:
offset.X = position.UpperLeftCorner.X + position.getWidth()/2; offset.X = position.UpperLeftCorner.X + position.getWidth()/2;
continue; continue;
} }
if (c == L'\r' || // Windows breaks if (c == L'\r' || // Windows breaks
c == L'\n' ) // Unix breaks c == L'\n') // Unix breaks
{ {
if(c==L'\r' && text[i+1]==L'\n') c = text[++i]; if (c==L'\r' && text[i+1]==L'\n')
c = text[++i];
offset.Y += (int)(MaxHeight*m_scale); offset.Y += (int)(MaxHeight*m_scale);
offset.X = position.UpperLeftCorner.X; offset.X = position.UpperLeftCorner.X;
if (hcenter) if (hcenter)
...@@ -296,23 +300,23 @@ public: ...@@ -296,23 +300,23 @@ public:
bool use_fallback_font = false; bool use_fallback_font = false;
const SFontArea &area = getAreaFromCharacter(c, &use_fallback_font); const SFontArea &area = getAreaFromCharacter(c, &use_fallback_font);
fallback[i] = use_fallback_font; fallback[i] = use_fallback_font;
offset.X += area.underhang; offset.X += area.underhang;
offsets.push_back(offset); offsets.push_back(offset);
// Invisible character. add something to the array anyway so that // Invisible character. add something to the array anyway so that
// indices from the various arrays remain in sync // indices from the various arrays remain in sync
indices.push_back( Invisible.findFirst(c) < 0 ? area.spriteno indices.push_back((Invisible.findFirst(c) < 0) ? (int)area.spriteno
: -1 ); : -1);
offset.X += getCharWidth(area, fallback[i]); offset.X += getCharWidth(area, fallback[i]);
} // for i<text_size } // for i<text_size
// ---- do the actual rendering // ---- do the actual rendering
const int indiceAmount = indices.size(); const int indiceAmount = indices.size();
core::array< gui::SGUISprite >& sprites = SpriteBank->getSprites(); core::array< gui::SGUISprite >& sprites = SpriteBank->getSprites();
core::array< core::rect<s32> >& positions = SpriteBank->getPositions(); core::array< core::rect<s32> >& positions = SpriteBank->getPositions();
core::array< gui::SGUISprite >* fallback_sprites; core::array< gui::SGUISprite >* fallback_sprites;
core::array< core::rect<s32> >* fallback_positions; core::array< core::rect<s32> >* fallback_positions;
if(m_fallback_font!=NULL) if (m_fallback_font!=NULL)
{ {
fallback_sprites = &m_fallback_font->SpriteBank->getSprites(); fallback_sprites = &m_fallback_font->SpriteBank->getSprites();
fallback_positions = &m_fallback_font->SpriteBank->getPositions(); fallback_positions = &m_fallback_font->SpriteBank->getPositions();
...@@ -324,50 +328,51 @@ public: ...@@ -324,50 +328,51 @@ public:
} }
video::IVideoDriver* driver = Environment->getVideoDriver(); video::IVideoDriver* driver = Environment->getVideoDriver();
const int spriteAmount = sprites.size(); const int spriteAmount = sprites.size();
for (int n=0; n<indiceAmount; n++) for (int n=0; n<indiceAmount; n++)
{ {
const int spriteID = indices[n]; const int spriteID = indices[n];
if (!fallback[n] && (spriteID < 0 || spriteID >= spriteAmount)) continue; if (!fallback[n] && (spriteID < 0 || spriteID >= spriteAmount))
if (indices[n] == -1) continue; continue;
if (indices[n] == -1)
continue;
//assert(sprites[spriteID].Frames.size() > 0); //assert(sprites[spriteID].Frames.size() > 0);
const int texID = (fallback[n] ? const int texID = (fallback[n] ?
(*fallback_sprites)[spriteID].Frames[0].textureNumber : (*fallback_sprites)[spriteID].Frames[0].textureNumber :
sprites[spriteID].Frames[0].textureNumber); sprites[spriteID].Frames[0].textureNumber);
core::rect<s32> source = (fallback[n] ? core::rect<s32> source = (fallback[n] ?
(*fallback_positions)[(*fallback_sprites)[spriteID].Frames[0].rectNumber] : (*fallback_positions)[(*fallback_sprites)[spriteID].Frames[0].rectNumber] :
positions[sprites[spriteID].Frames[0].rectNumber]); positions[sprites[spriteID].Frames[0].rectNumber]);
const TextureInfo& info = (fallback[n] ? const TextureInfo& info = (fallback[n] ?
(*(m_fallback_font->m_texture_files.find(texID))).second : (*(m_fallback_font->m_texture_files.find(texID))).second :
(*(m_texture_files.find(texID))).second (*(m_texture_files.find(texID))).second);
);
float char_scale = info.m_scale; float char_scale = info.m_scale;
core::dimension2d<s32> size = source.getSize(); core::dimension2d<s32> size = source.getSize();
float scale = (fallback[n] ? m_scale*m_fallback_font_scale : m_scale); float scale = (fallback[n] ? m_scale*m_fallback_font_scale : m_scale);
size.Width = (int)(size.Width * scale * char_scale); size.Width = (int)(size.Width * scale * char_scale);
size.Height = (int)(size.Height * scale * char_scale); size.Height = (int)(size.Height * scale * char_scale);
// align vertically if character is smaller // align vertically if character is smaller
int y_shift = (size.Height < MaxHeight*m_scale ? (int)((MaxHeight*m_scale - size.Height)/2.0f) : 0); int y_shift = (size.Height < MaxHeight*m_scale ? (int)((MaxHeight*m_scale - size.Height)/2.0f) : 0);
core::rect<s32> dest(offsets[n] + core::position2di(0, y_shift), size); core::rect<s32> dest(offsets[n] + core::position2di(0, y_shift), size);
video::SColor colors[] = {color, color, color, color}; video::SColor colors[] = {color, color, color, color};
video::ITexture* texture = (fallback[n] ? video::ITexture* texture = (fallback[n] ?
m_fallback_font->SpriteBank->getTexture(texID) : m_fallback_font->SpriteBank->getTexture(texID) :
SpriteBank->getTexture(texID) ); SpriteBank->getTexture(texID) );
if (texture == NULL) if (texture == NULL)
{ {
// perform lazy loading // perform lazy loading
if (fallback[n]) if (fallback[n])
{ {
m_fallback_font->lazyLoadTexture(texID); m_fallback_font->lazyLoadTexture(texID);
...@@ -378,19 +383,19 @@ public: ...@@ -378,19 +383,19 @@ public:
lazyLoadTexture(texID); lazyLoadTexture(texID);
texture = SpriteBank->getTexture(texID); texture = SpriteBank->getTexture(texID);
} }
if (texture == NULL) if (texture == NULL)
{ {
continue; // no such character continue; // no such character
} }
} }
if (m_black_border) if (m_black_border)
{ {
// draw black border // draw black border
video::SColor black(color.getAlpha(),0,0,0); video::SColor black(color.getAlpha(),0,0,0);
video::SColor black_colors[] = {black, black, black, black}; video::SColor black_colors[] = {black, black, black, black};
for (int x_delta=-2; x_delta<=2; x_delta++) for (int x_delta=-2; x_delta<=2; x_delta++)
{ {
for (int y_delta=-2; y_delta<=2; y_delta++) for (int y_delta=-2; y_delta<=2; y_delta++)
...@@ -401,10 +406,10 @@ public: ...@@ -401,10 +406,10 @@ public:
source, source,
clip, clip,
black_colors, true); black_colors, true);
} }
} }
} }
if (fallback[n]) if (fallback[n])
{ {
// draw text over // draw text over
...@@ -424,23 +429,23 @@ public: ...@@ -424,23 +429,23 @@ public:
source, source,
clip, clip,
colors, true); colors, true);
} }
} }
} }
//! returns the dimension of a text //! returns the dimension of a text
virtual core::dimension2d<u32> getDimension(const wchar_t* text) const virtual core::dimension2d<u32> getDimension(const wchar_t* text) const
{ {
assert(Areas.size() > 0); assert(Areas.size() > 0);
core::dimension2d<u32> dim(0, 0); core::dimension2d<u32> dim(0, 0);
core::dimension2d<u32> thisLine(0, (int)(MaxHeight*m_scale)); core::dimension2d<u32> thisLine(0, (int)(MaxHeight*m_scale));
for (const wchar_t* p = text; *p; ++p) for (const wchar_t* p = text; *p; ++p)
{ {
if (*p == L'\r' || // Windows breaks if (*p == L'\r' || // Windows breaks
*p == L'\n' ) // Unix breaks *p == L'\n') // Unix breaks
{ {
if (*p==L'\r' && p[1] == L'\n') // Windows breaks if (*p==L'\r' && p[1] == L'\n') // Windows breaks
++p; ++p;
...@@ -453,26 +458,26 @@ public: ...@@ -453,26 +458,26 @@ public:
bool fallback = false; bool fallback = false;
const SFontArea &area = getAreaFromCharacter(*p, &fallback); const SFontArea &area = getAreaFromCharacter(*p, &fallback);
thisLine.Width += area.underhang; thisLine.Width += area.underhang;
thisLine.Width += getCharWidth(area, fallback); thisLine.Width += getCharWidth(area, fallback);
} }
dim.Height += thisLine.Height; dim.Height += thisLine.Height;
if (dim.Width < thisLine.Width) dim.Width = thisLine.Width; if (dim.Width < thisLine.Width) dim.Width = thisLine.Width;
// std::cout << "ScalableFont::getDimension returns : " << dim.Width << ", " << dim.Height << " --> "; // std::cout << "ScalableFont::getDimension returns : " << dim.Width << ", " << dim.Height << " --> ";
dim.Width = (int)(dim.Width + 0.9f); // round up dim.Width = (int)(dim.Width + 0.9f); // round up
dim.Height = (int)(dim.Height + 0.9f); dim.Height = (int)(dim.Height + 0.9f);
//std::cout << dim.Width << ", " << dim.Height << std::endl; //std::cout << dim.Width << ", " << dim.Height << std::endl;
return dim; return dim;
} }
//! Calculates the index of the character in the text which is on a specific position. //! 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 virtual s32 getCharacterFromPos(const wchar_t* text, s32 pixel_x) const
{ {
s32 x = 0; s32 x = 0;
s32 idx = 0; s32 idx = 0;
...@@ -491,20 +496,20 @@ public: ...@@ -491,20 +496,20 @@ public:
return -1; return -1;
} }
//! Returns the type of this font //! Returns the type of this font
virtual gui::EGUI_FONT_TYPE getType() const { return gui::EGFT_BITMAP; } virtual gui::EGUI_FONT_TYPE getType() const { return gui::EGFT_BITMAP; }
//! set an Pixel Offset on Drawing ( scale position on width ) //! set an Pixel Offset on Drawing ( scale position on width )
virtual void setKerningWidth (s32 kerning) virtual void setKerningWidth (s32 kerning)
{ {
GlobalKerningWidth = kerning; GlobalKerningWidth = kerning;
} }
virtual void setKerningHeight (s32 kerning) virtual void setKerningHeight (s32 kerning)
{ {
GlobalKerningHeight = kerning; GlobalKerningHeight = kerning;
} }
//! set an Pixel Offset on Drawing ( scale position on width ) //! 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 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const
{ {
s32 ret = GlobalKerningWidth; s32 ret = GlobalKerningWidth;
...@@ -520,67 +525,69 @@ public: ...@@ -520,67 +525,69 @@ public:
return ret; return ret;
} }
virtual s32 getKerningHeight() const virtual s32 getKerningHeight() const
{ {
return GlobalKerningHeight; return GlobalKerningHeight;
} }
//! gets the sprite bank //! gets the sprite bank
virtual gui::IGUISpriteBank* getSpriteBank() const virtual gui::IGUISpriteBank* getSpriteBank() const
{ {
return SpriteBank; return SpriteBank;
} }
//! returns the sprite number from a given character //! returns the sprite number from a given character
virtual u32 getSpriteNoFromChar(const wchar_t *c) const virtual u32 getSpriteNoFromChar(const wchar_t *c) const
{ {
return Areas[getAreaIDFromCharacter(*c, NULL)].spriteno; return Areas[getAreaIDFromCharacter(*c, NULL)].spriteno;
} }
virtual void setInvisibleCharacters( const wchar_t *s ) virtual void setInvisibleCharacters( const wchar_t *s )
{ {
Invisible = s; Invisible = s;
} }
private: private:
struct SFontArea 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
{ {
core::array< gui::SGUISprite >& sprites = SpriteBank->getSprites(); 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
{
core::array< gui::SGUISprite >& sprites = SpriteBank->getSprites();
core::array< gui::SGUISprite >* fallback_sprites = (m_fallback_font != NULL ? core::array< gui::SGUISprite >* fallback_sprites = (m_fallback_font != NULL ?
&m_fallback_font->SpriteBank->getSprites() : &m_fallback_font->SpriteBank->getSprites() :
NULL); NULL);
const int texID = (fallback ? const int texID = (fallback ?
(*fallback_sprites)[area.spriteno].Frames[0].textureNumber : (*fallback_sprites)[area.spriteno].Frames[0].textureNumber :
sprites[area.spriteno].Frames[0].textureNumber); sprites[area.spriteno].Frames[0].textureNumber);
const TextureInfo& info = (fallback ? const TextureInfo& info = (fallback ?
(*(m_fallback_font->m_texture_files.find(texID))).second : (*(m_fallback_font->m_texture_files.find(texID))).second :
(*(m_texture_files.find(texID))).second (*(m_texture_files.find(texID))).second);
);
const float char_scale = info.m_scale; const float char_scale = info.m_scale;
//std::cout << "area.spriteno=" << area.spriteno << ", char_scale=" << char_scale << std::endl; //std::cout << "area.spriteno=" << area.spriteno << ", char_scale=" << char_scale << std::endl;
if (fallback) return (int)(((area.width + area.overhang)*m_fallback_font_scale + m_fallback_kerning_width) * m_scale * char_scale); if (fallback)
else return (int)((area.width + area.overhang + GlobalKerningWidth) * m_scale * char_scale); return (int)(((area.width + area.overhang)*m_fallback_font_scale + m_fallback_kerning_width) * m_scale * char_scale);
else
return (int)((area.width + area.overhang + GlobalKerningWidth) * m_scale * char_scale);
} }
s32 getAreaIDFromCharacter(const wchar_t c, bool* fallback_font) const s32 getAreaIDFromCharacter(const wchar_t c, bool* fallback_font) const
{ {
std::map<wchar_t, s32>::const_iterator n = CharacterMap.find(c); std::map<wchar_t, s32>::const_iterator n = CharacterMap.find(c);
if (n != CharacterMap.end()) if (n != CharacterMap.end())
{ {
if (fallback_font != NULL) *fallback_font = false; if (fallback_font != NULL)
*fallback_font = false;
return (*n).second; return (*n).second;
} }
else if (m_fallback_font != NULL && fallback_font != NULL) else if (m_fallback_font != NULL && fallback_font != NULL)
...@@ -591,19 +598,20 @@ private: ...@@ -591,19 +598,20 @@ private:
else else
{ {
// std::cout << "The font does not have this character : <" << (int)c << ">" << std::endl; // std::cout << "The font does not have this character : <" << (int)c << ">" << std::endl;
if (fallback_font != NULL) *fallback_font = false; if (fallback_font != NULL)
*fallback_font = false;
return WrongCharacter; return WrongCharacter;
} }
} }
const SFontArea &getAreaFromCharacter(const wchar_t c, bool* fallback_font) const const SFontArea &getAreaFromCharacter(const wchar_t c, bool* fallback_font) const
{ {
const int area_id = getAreaIDFromCharacter(c, fallback_font); const int area_id = getAreaIDFromCharacter(c, fallback_font);
const bool use_fallback_font = (fallback_font && *fallback_font); const bool use_fallback_font = (fallback_font && *fallback_font);
// Note: fallback_font can be NULL // Note: fallback_font can be NULL
return ( use_fallback_font ? m_fallback_font->Areas[area_id] : Areas[area_id]); return ( use_fallback_font ? m_fallback_font->Areas[area_id] : Areas[area_id]);
} // getAreaFromCharacter } // getAreaFromCharacter
void setMaxHeight() void setMaxHeight()
{ {
// FIXME: should consider per-texture scaling // FIXME: should consider per-texture scaling
MaxHeight = 0; MaxHeight = 0;
...@@ -618,18 +626,18 @@ private: ...@@ -618,18 +626,18 @@ private:
MaxHeight = t; MaxHeight = t;
} }
} }
core::array<SFontArea> Areas; core::array<SFontArea> Areas;
/** The maximum values of all digits, used in monospace_digits. */ /** The maximum values of all digits, used in monospace_digits. */
mutable SFontArea m_max_digit_area; mutable SFontArea m_max_digit_area;
std::map<wchar_t, s32> CharacterMap; std::map<wchar_t, s32> CharacterMap;
video::IVideoDriver* Driver; video::IVideoDriver* Driver;
gui::IGUISpriteBank* SpriteBank; gui::IGUISpriteBank* SpriteBank;
gui::IGUIEnvironment* Environment; gui::IGUIEnvironment* Environment;
u32 WrongCharacter; u32 WrongCharacter;
s32 MaxHeight; s32 MaxHeight;
s32 GlobalKerningWidth, GlobalKerningHeight; s32 GlobalKerningWidth, GlobalKerningHeight;
core::stringw Invisible; core::stringw Invisible;
}; };
} }
...@@ -655,12 +663,12 @@ static bool draw2DImage4c(video::E_DRIVER_TYPE type) ...@@ -655,12 +663,12 @@ static bool draw2DImage4c(video::E_DRIVER_TYPE type)
logTestString("Testing driver %ls\n", driver->getName()); logTestString("Testing driver %ls\n", driver->getName());
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS,true); driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS,true);
driver->setTextureCreationFlag(video::ETCF_OPTIMIZED_FOR_QUALITY,true); driver->setTextureCreationFlag(video::ETCF_OPTIMIZED_FOR_QUALITY,true);
video::ITexture* images = driver->getTexture("../media/2ddemo.png"); video::ITexture* images = driver->getTexture("../media/2ddemo.png");
driver->makeColorKeyTexture(images, core::position2d<s32>(0,0)); driver->makeColorKeyTexture(images, core::position2d<s32>(0,0));
core::rect<s32> imp1(349,15,385,78); core::rect<s32> imp1(349,15,385,78);
core::rect<s32> imp2(387,15,423,78); core::rect<s32> imp2(387,15,423,78);
...@@ -668,54 +676,54 @@ static bool draw2DImage4c(video::E_DRIVER_TYPE type) ...@@ -668,54 +676,54 @@ static bool draw2DImage4c(video::E_DRIVER_TYPE type)
io::path cwd = device->getFileSystem()->getWorkingDirectory(); io::path cwd = device->getFileSystem()->getWorkingDirectory();
device->getFileSystem()->changeWorkingDirectoryTo("media"); device->getFileSystem()->changeWorkingDirectoryTo("media");
ScalableFont* font = new ScalableFont(device->getGUIEnvironment(), "title_font.xml"); ScalableFont* font = new ScalableFont(device->getGUIEnvironment(), "title_font.xml");
font->m_fallback_font_scale = 4.0f; font->m_fallback_font_scale = 4.0f;
font->m_fallback_kerning_width = 15; font->m_fallback_kerning_width = 15;
font->setKerningWidth(-18); font->setKerningWidth(-18);
font->m_black_border = true; font->m_black_border = true;
/* /*
Prepare a nicely filtering 2d render mode for special cases. Prepare a nicely filtering 2d render mode for special cases.
*/ */
driver->getMaterial2D().UseMipMaps = true; driver->getMaterial2D().UseMipMaps = true;
driver->getMaterial2D().TextureLayer[0].BilinearFilter = true; driver->getMaterial2D().TextureLayer[0].BilinearFilter = true;
{ {
driver->beginScene(true, true, video::SColor(255,120,102,136)); driver->beginScene(true, true, video::SColor(255,120,102,136));
driver->enableMaterial2D(); driver->enableMaterial2D();
// draw fire & dragons background world // draw fire & dragons background world
driver->draw2DImage(images, core::position2di(), driver->draw2DImage(images, core::position2di(),
core::rect<s32>(0,0,342,224), 0, core::rect<s32>(0,0,342,224), 0,
video::SColor(255,255,255,255), true); video::SColor(255,255,255,255), true);
// draw flying imp // draw flying imp
driver->draw2DImage(images, core::position2d<s32>(114,75), driver->draw2DImage(images, core::position2d<s32>(114,75),
imp1, 0, video::SColor(255,255,255,255), true); imp1, 0, video::SColor(255,255,255,255), true);
// draw second flying imp // draw second flying imp
driver->draw2DImage(images, core::position2d<s32>(220,55), driver->draw2DImage(images, core::position2d<s32>(220,55),
imp2, 0, video::SColor(255,255,255,255), true); imp2, 0, video::SColor(255,255,255,255), true);
driver->draw2DImage(images, core::rect<s32>(10,10,108,48), driver->draw2DImage(images, core::rect<s32>(10,10,108,48),
core::rect<s32>(354,87,442,118)); core::rect<s32>(354,87,442,118));
video::SColor colors[] = {0xff00ffff, 0xff00ffff, 0xffffff00, 0xffffff00}; video::SColor colors[] = {0xff00ffff, 0xff00ffff, 0xffffff00, 0xffffff00};
driver->draw2DImage(images, core::recti(10,50,108,88), driver->draw2DImage(images, core::recti(10,50,108,88),
core::recti(354,87,442,118), 0, colors, true); core::recti(354,87,442,118), 0, colors, true);
font->draw( L"WXYZsSdDrRjJbB", core::rect<s32>(30,20,300,300), font->draw( L"WXYZsSdDrRjJbB", core::rect<s32>(30,20,300,300),
video::SColor(255,255,255,255) ); video::SColor(255,255,255,255) );
driver->enableMaterial2D(false); driver->enableMaterial2D(false);
driver->draw2DImage(images, core::recti(10,90,108,128), driver->draw2DImage(images, core::recti(10,90,108,128),
core::recti(354,87,442,118), 0, colors, true); core::recti(354,87,442,118), 0, colors, true);
font->draw( L"WXYZsSdDrRjJbB", core::rect<s32>(30,60,300,400), font->draw( L"WXYZsSdDrRjJbB", core::rect<s32>(30,60,300,400),
video::SColor(255,255,255,255) ); video::SColor(255,255,255,255) );
driver->endScene(); driver->endScene();
} }
font->drop(); font->drop();
...@@ -727,7 +735,7 @@ static bool draw2DImage4c(video::E_DRIVER_TYPE type) ...@@ -727,7 +735,7 @@ static bool draw2DImage4c(video::E_DRIVER_TYPE type)
device->closeDevice(); device->closeDevice();
device->run(); device->run();
device->drop(); device->drop();
return result; return result;
} }
// This test renders a 3d scene and a gui on top of it. The GUI is // This test renders a 3d scene and a gui on top of it. The GUI is
...@@ -821,7 +829,7 @@ static bool addBlend2d(video::E_DRIVER_TYPE type) ...@@ -821,7 +829,7 @@ static bool addBlend2d(video::E_DRIVER_TYPE type)
device->closeDevice(); device->closeDevice();
device->run(); device->run();
device->drop(); device->drop();
return result; return result;
} }
// This test renders 4 times the same image. Two via IGUIImage, two via draw2DImage // This test renders 4 times the same image. Two via IGUIImage, two via draw2DImage
...@@ -833,8 +841,8 @@ static bool moreFilterTests(video::E_DRIVER_TYPE type) ...@@ -833,8 +841,8 @@ static bool moreFilterTests(video::E_DRIVER_TYPE type)
if (!device) if (!device)
return true; return true;
video::IVideoDriver* driver = device->getVideoDriver(); video::IVideoDriver* driver = device->getVideoDriver();
gui::IGUIEnvironment* gui = device->getGUIEnvironment(); gui::IGUIEnvironment* gui = device->getGUIEnvironment();
if (!driver->queryFeature(video::EVDF_BILINEAR_FILTER)) if (!driver->queryFeature(video::EVDF_BILINEAR_FILTER))
{ {
...@@ -848,41 +856,41 @@ static bool moreFilterTests(video::E_DRIVER_TYPE type) ...@@ -848,41 +856,41 @@ static bool moreFilterTests(video::E_DRIVER_TYPE type)
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
video::ITexture* tex = driver->getTexture("../media/irrlichtlogo.jpg"); video::ITexture* tex = driver->getTexture("../media/irrlichtlogo.jpg");
gui::IGUIImage* image = gui->addImage(core::recti(0,0,64,64)); gui::IGUIImage* image = gui->addImage(core::recti(0,0,64,64));
image->setScaleImage(true); image->setScaleImage(true);
image->setImage(tex); image->setImage(tex);
image->setUseAlphaChannel(true); image->setUseAlphaChannel(true);
driver->getMaterial2D().TextureLayer[0].BilinearFilter=true; driver->getMaterial2D().TextureLayer[0].BilinearFilter=true;
driver->getMaterial2D().TextureLayer[0].TrilinearFilter=true; driver->getMaterial2D().TextureLayer[0].TrilinearFilter=true;
{ {
driver->beginScene(true, true, irr::video::SColor(255,255,255,255)); driver->beginScene(true, true, irr::video::SColor(255,255,255,255));
// all three logos should be with filtering // all three logos should be with filtering
driver->enableMaterial2D(); driver->enableMaterial2D();
driver->getMaterial2D().setTexture(0, 0); driver->getMaterial2D().setTexture(0, 0);
driver->draw2DImage(tex, irr::core::rect<irr::s32>(64, 64, 128, 128), irr::core::rect<irr::s32>(0, 0, 88, 31)); driver->draw2DImage(tex, irr::core::rect<irr::s32>(64, 64, 128, 128), irr::core::rect<irr::s32>(0, 0, 88, 31));
driver->getMaterial2D().setTexture(0, tex); driver->getMaterial2D().setTexture(0, tex);
driver->draw2DImage(tex, irr::core::rect<irr::s32>(64, 0, 128, 64), irr::core::rect<irr::s32>(0, 0, 88, 31)); driver->draw2DImage(tex, irr::core::rect<irr::s32>(64, 0, 128, 64), irr::core::rect<irr::s32>(0, 0, 88, 31));
gui->drawAll(); gui->drawAll();
// the next gui image should be without filter // the next gui image should be without filter
driver->enableMaterial2D(false); driver->enableMaterial2D(false);
image->setRelativePosition(core::recti(0,64,64,128)); image->setRelativePosition(core::recti(0,64,64,128));
gui->drawAll(); gui->drawAll();
driver->endScene(); driver->endScene();
} }
bool result = takeScreenshotAndCompareAgainstReference(driver, "-2dmatFilter.png"); bool result = takeScreenshotAndCompareAgainstReference(driver, "-2dmatFilter.png");
device->closeDevice(); device->closeDevice();
device->run(); device->run();
device->drop(); device->drop();
return result; return result;
} }
bool twodmaterial() bool twodmaterial()
......
...@@ -41,7 +41,7 @@ bool testShots(video::E_DRIVER_TYPE type) ...@@ -41,7 +41,7 @@ bool testShots(video::E_DRIVER_TYPE type)
smgr->drawAll(); smgr->drawAll();
driver->endScene(); driver->endScene();
for (u32 i=0; i<video::ECF_UNKNOWN; ++i) for (s32 i=0; i<video::ECF_UNKNOWN; ++i)
{ {
video::IImage* img = driver->createScreenShot((video::ECOLOR_FORMAT)i); video::IImage* img = driver->createScreenShot((video::ECOLOR_FORMAT)i);
logTestString("Color Format %d %ssupported\n", i, (img && img->getColorFormat() == i)?"":"un"); logTestString("Color Format %d %ssupported\n", i, (img && img->getColorFormat() == i)?"":"un");
......
...@@ -10,41 +10,41 @@ namespace ...@@ -10,41 +10,41 @@ namespace
// test camera changes with terrain scene node recalculation // test camera changes with terrain scene node recalculation
bool terrainRecalc(void) bool terrainRecalc(void)
{ {
IrrlichtDevice *device = IrrlichtDevice *device =
createDevice(video::EDT_BURNINGSVIDEO, dimension2du(160, 120), 32); createDevice(video::EDT_BURNINGSVIDEO, dimension2du(160, 120), 32);
if (!device) if (!device)
return true; return true;
video::IVideoDriver* driver = device->getVideoDriver(); video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager(); scene::ISceneManager* smgr = device->getSceneManager();
scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode( scene::ITerrainSceneNode* terrain = smgr->addTerrainSceneNode(
"../media/terrain-heightmap.bmp"); "../media/terrain-heightmap.bmp");
terrain->setScale(core::vector3df(40.f, .1f, 40.f)); terrain->setScale(core::vector3df(40.f, .1f, 40.f));
terrain->setMaterialFlag(video::EMF_LIGHTING, false); terrain->setMaterialFlag(video::EMF_LIGHTING, false);
terrain->setMaterialTexture(0, driver->getTexture("../media/terrain-texture.jpg")); terrain->setMaterialTexture(0, driver->getTexture("../media/terrain-texture.jpg"));
terrain->setDebugDataVisible(scene::EDS_FULL); terrain->setDebugDataVisible(scene::EDS_FULL);
scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(); scene::ICameraSceneNode* camera = smgr->addCameraSceneNode();
const core::vector3df center(terrain->getBoundingBox().getCenter()); const core::vector3df center(terrain->getBoundingBox().getCenter());
camera->setTarget(center); camera->setTarget(center);
// yes, Y is intentionally being set to X here // yes, Y is intentionally being set to X here
const core::vector3df above (center.X, center.X, center.Z); const core::vector3df above (center.X, center.X, center.Z);
camera->setPosition (above); camera->setPosition (above);
camera->setUpVector(vector3df(1.f, 0.f, 0.f)); camera->setUpVector(vector3df(1.f, 0.f, 0.f));
camera->setFarValue(above.Y); camera->setFarValue(above.Y);
device->run(); device->run();
smgr->drawAll(); smgr->drawAll();
// This shouldn't cause a recalc // This shouldn't cause a recalc
camera->setUpVector(vector3df(1.f, 0.f, .01f).normalize()); camera->setUpVector(vector3df(1.f, 0.f, .01f).normalize());
device->run(); device->run();
driver->beginScene(true, true, video::SColor(255,100,101,140)); driver->beginScene(true, true, video::SColor(255,100,101,140));
smgr->drawAll(); smgr->drawAll();
driver->endScene(); driver->endScene();
...@@ -58,7 +58,7 @@ bool terrainRecalc(void) ...@@ -58,7 +58,7 @@ bool terrainRecalc(void)
// This is big enough to cause a recalc // This is big enough to cause a recalc
camera->setUpVector(vector3df(1.f, 0.f, .1f).normalize()); camera->setUpVector(vector3df(1.f, 0.f, .1f).normalize());
device->run(); device->run();
driver->beginScene(true, true, video::SColor(255,100,101,140)); driver->beginScene(true, true, video::SColor(255,100,101,140));
smgr->drawAll(); smgr->drawAll();
driver->endScene(); driver->endScene();
...@@ -72,7 +72,7 @@ bool terrainRecalc(void) ...@@ -72,7 +72,7 @@ bool terrainRecalc(void)
device->closeDevice(); device->closeDevice();
device->run(); device->run();
device->drop(); device->drop();
return result; return result;
} }
bool terrainGaps() bool terrainGaps()
...@@ -114,7 +114,7 @@ bool terrainGaps() ...@@ -114,7 +114,7 @@ bool terrainGaps()
device->closeDevice(); device->closeDevice();
device->run(); device->run();
device->drop(); device->drop();
return true; return result;
} }
} }
...@@ -124,4 +124,5 @@ bool terrainSceneNode() ...@@ -124,4 +124,5 @@ bool terrainSceneNode()
bool result = terrainRecalc(); bool result = terrainRecalc();
result &= terrainGaps(); result &= terrainGaps();
return result; return result;
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment