Clean up freetype code

1. Remove all ifdef of freetype

2. Require freetype in CMake

3. Clean up declaration

4. Add leak check

5. Make script language display better in title
This commit is contained in:
Benau 2015-10-30 18:08:02 +08:00
parent 66909086fd
commit b9b2b538fa
11 changed files with 105 additions and 648 deletions

View File

@ -16,7 +16,6 @@ if (NOT CMAKE_BUILD_TYPE)
endif()
option(USE_WIIUSE "Support for wiimote input devices" ON)
option(USE_FREETYPE "Use Freetype to render text" ON)
option(USE_FRIBIDI "Support for right-to-left languages" ON)
option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
option(USE_SYSTEM_ANGELSCRIPT "Use system angelscript instead of built-in angelscript. If you enable this option, make sure to use a compatible version." OFF)
@ -166,14 +165,12 @@ else()
endif()
# Freetype
if(USE_FREETYPE)
find_package(Freetype)
if(FREETYPE_FOUND)
include_directories(${FREETYPE_INCLUDE_DIRS})
else()
message(FATAL_ERROR "Freetype not found. "
"Either install freetype or disable freetype rendering support with -DUSE_FREETYPE=0 ")
endif()
find_package(Freetype)
if(FREETYPE_FOUND)
include_directories(${FREETYPE_INCLUDE_DIRS})
else()
message(FATAL_ERROR "Freetype not found. "
"Freetype is required to display characters in SuperTuxKart. ")
endif()
# Fribidi
@ -351,7 +348,7 @@ target_link_libraries(supertuxkart
${OGGVORBIS_LIBRARIES}
${OPENAL_LIBRARY}
${OPENGL_LIBRARIES}
${FREETPYE_LIBRARIES}
${FREETYPE_LIBRARIES}
)
if(UNIX AND NOT APPLE)
@ -381,11 +378,6 @@ if(USE_FRIBIDI)
add_definitions(-DENABLE_BIDI)
endif()
if(USE_FREETYPE)
target_link_libraries(supertuxkart ${FREETYPE_LIBRARIES})
add_definitions(-DENABLE_FREETYPE)
endif()
# Wiiuse
# ------
if(USE_WIIUSE)

View File

@ -67,11 +67,7 @@ scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFon
font->doDraw(text, core::rect<s32>(0, 0, size.Width, size.Height), video::SColor(255,255,255,255),
false, false, NULL, this);
#ifdef ENABLE_FREETYPE
const float scale = 0.03f; //Larger for ttf font as they are less bold
#else
const float scale = 0.018f;
#endif // ENABLE_FREETYPE
const float scale = 0.03f;
//scene::SMesh* mesh = new scene::SMesh();
std::map<video::ITexture*, scene::SMeshBuffer*> buffers;

View File

@ -688,10 +688,8 @@ namespace GUIEngine
{
IGUIEnvironment* g_env;
Skin* g_skin = NULL;
#ifdef ENABLE_FREETYPE
FTEnvironment* g_ft_env = NULL;
GlyphPageCreator* g_gp_creator = NULL;
#endif // ENABLE_FREETYPE
ScalableFont *g_font;
ScalableFont *g_outline_font;
ScalableFont *g_large_font;
@ -956,12 +954,10 @@ namespace GUIEngine
//if (g_skin != NULL) delete g_skin;
g_skin = NULL;
#ifdef ENABLE_FREETYPE
g_ft_env->~FTEnvironment();
g_ft_env = NULL;
g_gp_creator->~GlyphPageCreator();
g_gp_creator = NULL;
#endif // ENABLE_FREETYPE
for (unsigned int i=0; i<g_loaded_screens.size(); i++)
{
@ -1031,10 +1027,8 @@ namespace GUIEngine
g_focus_for_player[n] = NULL;
}
#ifdef ENABLE_FREETYPE
g_ft_env = new FTEnvironment();
g_gp_creator = new GlyphPageCreator();
#endif // ENABLE_FREETYPE
/*
To make the g_font a little bit nicer, we load an external g_font
@ -1069,10 +1063,6 @@ namespace GUIEngine
}
}
#ifdef ENABLE_FREETYPE
float normal_text_scale = 1;
float title_text_scale = 1;
ScalableFont* digit_font =new ScalableFont(g_env,T_DIGIT);
digit_font->setMonospaceDigits(true);
g_digit_font = digit_font;
@ -1081,16 +1071,16 @@ namespace GUIEngine
sfont2->setKerningWidth(0);
// Because the fallback font is much smaller than the title font:
sfont2->m_fallback_font_scale = 2.0f;
sfont2->m_fallback_kerning_width = 5;
sfont2->m_fallback_kerning_width = 0;
ScalableFont* sfont =new ScalableFont(g_env,T_NORMAL);
sfont->setKerningHeight(0);
sfont->setScale(normal_text_scale);
sfont->setScale(1);
g_font = sfont;
Private::font_height = g_font->getDimension( L"X" ).Height;
ScalableFont* sfont_larger = sfont->getHollowCopy();
sfont_larger->setScale(normal_text_scale*1.4f);
sfont_larger->setScale(1.4f);
sfont_larger->setKerningHeight(0);
g_large_font = sfont_larger;
@ -1100,7 +1090,7 @@ namespace GUIEngine
Private::large_font_height = g_large_font->getDimension( L"X" ).Height;
ScalableFont* sfont_smaller = sfont->getHollowCopy();
sfont_smaller->setScale(normal_text_scale*0.8f);
sfont_smaller->setScale(0.8f);
sfont_smaller->setKerningHeight(0);
g_small_font = sfont_smaller;
@ -1108,83 +1098,11 @@ namespace GUIEngine
g_small_font->getDimension( L"X" ).Height;
sfont2->m_fallback_font = sfont;
sfont2->setScale(title_text_scale);
sfont2->setScale(1);
sfont2->m_black_border = true;
g_title_font = sfont2;
Private::title_font_height =
g_title_font->getDimension( L"X" ).Height;
#else
// font size is resolution-dependent.
// normal text will range from 0.8, in 640x* resolutions (won't scale
// below that) to 1.0, in 1024x* resolutions, and linearly up
// normal text will range from 0.2, in 640x* resolutions (won't scale
// below that) to 0.4, in 1024x* resolutions, and linearly up
const int screen_width = irr_driver->getFrameSize().Width;
const int screen_height = irr_driver->getFrameSize().Height;
float scale = std::max(0, screen_width - 640)/564.0f;
// attempt to compensate for small screens
if (screen_width < 1200) scale = std::max(0, screen_width - 640) / 750.0f;
if (screen_width < 900 || screen_height < 700) scale = std::min(scale, 0.05f);
Log::info("GUIEngine", "scale: %f", scale);
float normal_text_scale = 0.7f + 0.2f*scale;
float title_text_scale = 0.2f + 0.2f*scale;
ScalableFont* sfont =
new ScalableFont(g_env,
file_manager->getAssetChecked(FileManager::FONT,
"StkFont.xml",true) );
sfont->setScale(normal_text_scale);
sfont->setKerningHeight(-5);
g_font = sfont;
ScalableFont* digit_font =
new ScalableFont(g_env,
file_manager->getAssetChecked(FileManager::FONT,
"BigDigitFont.xml",true));
digit_font->lazyLoadTexture(0); // make sure the texture is loaded for this one
digit_font->setMonospaceDigits(true);
g_digit_font = digit_font;
Private::font_height = g_font->getDimension( L"X" ).Height;
ScalableFont* sfont_larger = sfont->getHollowCopy();
sfont_larger->setScale(normal_text_scale*1.4f);
sfont_larger->setKerningHeight(-5);
g_large_font = sfont_larger;
g_outline_font = sfont->getHollowCopy();
g_outline_font->m_black_border = true;
Private::large_font_height = g_large_font->getDimension( L"X" ).Height;
ScalableFont* sfont_smaller = sfont->getHollowCopy();
sfont_smaller->setScale(normal_text_scale*0.8f);
sfont_smaller->setKerningHeight(-5);
g_small_font = sfont_smaller;
Private::small_font_height =
g_small_font->getDimension( L"X" ).Height;
ScalableFont* sfont2 =
new ScalableFont(g_env,
file_manager->getAssetChecked(FileManager::FONT,
"title_font.xml",
true) );
sfont2->m_fallback_font = sfont;
// Because the fallback font is much smaller than the title font:
sfont2->m_fallback_font_scale = 4.0f;
sfont2->m_fallback_kerning_width = 15;
sfont2->setScale(title_text_scale);
sfont2->setKerningWidth(-18);
sfont2->m_black_border = true;
g_title_font = sfont2;
Private::title_font_height =
g_title_font->getDimension( L"X" ).Height;
#endif // ENABLE_FREETYPE
if (g_font != NULL) g_skin->setFont(g_font);
@ -1202,15 +1120,13 @@ namespace GUIEngine
void reloadHollowCopyFont(irr::gui::ScalableFont* sfont)
{
//Base on the init function above
float normal_text_scale = 1;
sfont->setScale(normal_text_scale);
sfont->setKerningHeight(-5);
sfont->setScale(1);
sfont->setKerningHeight(0);
Private::font_height = sfont->getDimension( L"X" ).Height;
ScalableFont* sfont_larger = sfont->getHollowCopy();
sfont_larger->setScale(normal_text_scale*1.4f);
sfont_larger->setKerningHeight(-5);
sfont_larger->setScale(1.4f);
sfont_larger->setKerningHeight(0);
g_large_font = sfont_larger;
g_outline_font = sfont->getHollowCopy();
@ -1219,8 +1135,8 @@ namespace GUIEngine
Private::large_font_height = g_large_font->getDimension( L"X" ).Height;
ScalableFont* sfont_smaller = sfont->getHollowCopy();
sfont_smaller->setScale(normal_text_scale*0.8f);
sfont_smaller->setKerningHeight(-5);
sfont_smaller->setScale(0.8f);
sfont_smaller->setKerningHeight(0);
g_small_font = sfont_smaller;
Private::small_font_height = g_small_font->getDimension( L"X" ).Height;

View File

@ -39,10 +39,8 @@ namespace irr
#include "utils/constants.hpp"
#include "utils/ptr_vector.hpp"
#ifdef ENABLE_FREETYPE
#include "guiengine/ft_environment.hpp"
#include "guiengine/glyph_page_creator.hpp"
#endif // ENABLE_FREETYPE
/**
* \ingroup guiengine
@ -86,10 +84,8 @@ namespace GUIEngine
{
extern irr::gui::IGUIEnvironment* g_env;
extern Skin* g_skin;
#ifdef ENABLE_FREETYPE
extern FTEnvironment* g_ft_env;
extern GlyphPageCreator* g_gp_creator;
#endif // ENABLE_FREETYPE
extern irr::gui::ScalableFont* g_small_font;
extern irr::gui::ScalableFont* g_font;
extern irr::gui::ScalableFont* g_outline_font;
@ -181,7 +177,6 @@ namespace GUIEngine
*/
inline Skin* getSkin() { return Private::g_skin; }
#ifdef ENABLE_FREETYPE
/**
* \pre GUIEngine::init must have been called first
* \return the freetype and library with face
@ -193,7 +188,6 @@ namespace GUIEngine
* \return the glyph page creator, useful to create a glyph page from individual char
*/
inline GlyphPageCreator* getGlyphPageCreator() { return Private::g_gp_creator; }
#endif // ENABLE_FREETYPE
Screen* getScreenNamed(const char* name);
@ -271,13 +265,11 @@ namespace GUIEngine
*/
void reloadSkin();
#ifdef ENABLE_FREETYPE
/**
* \brief call when translation in user config was updated for freetype rendering STK
*/
void cleanHollowCopyFont();
void reloadHollowCopyFont(irr::gui::ScalableFont*);
#endif // ENABLE_FREETYPE
}
#endif

View File

@ -15,7 +15,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef ENABLE_FREETYPE
#include "guiengine/ft_environment.hpp"
#include "guiengine/get_font_properties.hpp"
#include "io/file_manager.hpp"
@ -98,4 +97,3 @@ FT_Library FTEnvironment::ft_lib = NULL;
FT_Error FTEnvironment::ft_err = 0;
} // guiengine
#endif // ENABLE_FREETYPE

View File

@ -19,6 +19,8 @@
#include "guiengine/get_font_properties.hpp"
#include FT_FREETYPE_H
#include "utils/leak_check.hpp"
/**
* \ingroup guiengine
*/
@ -30,6 +32,9 @@ namespace GUIEngine
class FTEnvironment
{
public:
LEAK_CHECK()
FTEnvironment();
~FTEnvironment();
FT_Face ft_face[irr::gui::F_COUNT];

View File

@ -21,7 +21,6 @@
//
// http://irrlicht.suckerfreegames.com/
#ifdef ENABLE_FREETYPE
#include <irrlicht.h>
#include "guiengine/engine.hpp"
@ -151,9 +150,4 @@ bool GlyphPageCreator::insertGlyph(FT_Bitmap bits, core::rect<s32>& rect)
return true;
}
u32 GlyphPageCreator::used_width = 0;
u32 GlyphPageCreator::used_height = 0;
u32 GlyphPageCreator::temp_height = 0;
} // guiengine
#endif // ENABLE_FREETYPE

View File

@ -21,6 +21,8 @@
#include FT_FREETYPE_H
#include <set>
#include "utils/leak_check.hpp"
using namespace irr;
/**
@ -34,6 +36,9 @@ namespace GUIEngine
class GlyphPageCreator
{
public:
LEAK_CHECK()
GlyphPageCreator();
~GlyphPageCreator();
@ -51,7 +56,7 @@ namespace GUIEngine
/** Reset position of glyph on the current glyph page.
*/
static void clearGlyphPage();
void clearGlyphPage();
/** Clear (fill it with transparent content) the current glyph page.
*/
@ -87,9 +92,9 @@ namespace GUIEngine
*/
video::IImage* page;
static u32 temp_height;
static u32 used_width;
static u32 used_height;
u32 temp_height;
u32 used_width;
u32 used_height;
};
} // guiengine

View File

@ -26,7 +26,6 @@ namespace gui
{
//! constructor
#ifdef ENABLE_FREETYPE
ScalableFont::ScalableFont(IGUIEnvironment *env, TTFLoadingType type)
: Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0),
MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0)
@ -90,51 +89,6 @@ void ScalableFont::recreateFromLanguage()
Log::fatal("ScalableFont", "Recreation of TTF font failed");
}
}
#else
ScalableFont::ScalableFont(IGUIEnvironment *env, const std::string &filename)
: Driver(0), SpriteBank(0), Environment(env), WrongCharacter(0),
MaxHeight(0), GlobalKerningWidth(0), GlobalKerningHeight(0)
{
#ifdef _DEBUG
setDebugName("ScalableFont");
#endif
m_fallback_font = NULL;
m_fallback_kerning_width = 0;
m_fallback_font_scale = 1.0f;
m_scale = 1.0f;
m_is_hollow_copy = false;
m_black_border = false;
m_shadow = false;
m_mono_space_digits = false;
m_rtl = translations->isRTLLanguage();
if (Environment)
{
// don't grab environment, to avoid circular references
Driver = Environment->getVideoDriver();
SpriteBank = Environment->addEmptySpriteBank(io::path(filename.c_str()));
if (SpriteBank)
SpriteBank->grab();
}
if (Driver)
Driver->grab();
setInvisibleCharacters ( L" " );
io::IXMLReader* reader = file_manager->createXMLReader(filename.c_str());
if (!load( reader ))
{
Log::fatal("ScalableFont", "Loading font failed");
}
reader->drop();
assert(Areas.size() > 0);
}
#endif // ENABLE_FREETYPE
//! destructor
ScalableFont::~ScalableFont()
@ -157,204 +111,6 @@ void ScalableFont::setShadow(const irr::video::SColor &col)
m_shadow_color = col;
}
#ifndef ENABLE_FREETYPE
void ScalableFont::doReadXmlFile(io::IXMLReader* xml)
{
int trim_top = 0;
int trim_bottom = 0;
while (xml->read())
{
if (io::EXN_ELEMENT == xml->getNodeType())
{
if (core::stringw(L"include") == xml->getNodeName())
{
core::stringc filename = xml->getAttributeValue(L"file");
/*
const wchar_t* iflangis = xml->getAttributeValue(L"iflanguage");
Log::info("ScalableFont", "langcode = %s", translations->getCurrentLanguageCode().c_str());
if (iflangis != NULL &&
core::stringc(iflangis) != translations->getCurrentLanguageCode().c_str())
{
continue;
}
*/
io::IXMLReader* included = file_manager->createXMLReader(
file_manager->getAsset(FileManager::FONT, filename.c_str()));
if (included != NULL)
{
doReadXmlFile(included);
included->drop();
}
}
else if (core::stringw(L"Texture") == xml->getNodeName())
{
// add a texture
core::stringc filename = xml->getAttributeValue(L"filename");
core::stringc fn = file_manager->getAsset(FileManager::FONT,
filename.c_str()).c_str();
u32 i = (u32)xml->getAttributeValueAsInt(L"index");
float scale=1.0f;
if(xml->getAttributeValue(L"scale"))
{
scale = xml->getAttributeValueAsFloat(L"scale");
//Log::info("ScalableFont", "scale = %f", scale);
}
bool excludeFromMaxHeightCalculation = false;
if (xml->getAttributeValue(L"excludeFromMaxHeightCalculation"))
excludeFromMaxHeightCalculation = (core::stringc(xml->getAttributeValue(L"excludeFromMaxHeightCalculation")) == "true");
core::stringw alpha = xml->getAttributeValue(L"hasAlpha");
//Log::info("ScalableFont", "Adding font texture %s; alpha = %s", fn.c_str(), alpha.c_str());
// make sure the sprite bank has enough textures in it
while (i+1 > SpriteBank->getTextureCount())
{
SpriteBank->addTexture(NULL);
}
TextureInfo info;
info.m_file_name = fn;
info.m_has_alpha = (alpha == core::stringw("true"));
info.m_scale = scale;
info.m_exclude_from_max_height_calculation = excludeFromMaxHeightCalculation;
#ifdef DEBUG
if (m_texture_files.find(i) != m_texture_files.end())
{
Log::warn("ScalableFont", "Font conflict, two images have texture %i.", i);
}
#endif
m_texture_files[i] = info;
}
else if (core::stringw(L"font") == xml->getNodeName())
{
trim_top = (u32)xml->getAttributeValueAsInt(L"trim_top"); // returns 0 if no such attribute
trim_bottom = (u32)xml->getAttributeValueAsInt(L"trim_bottom");
}
else if (core::stringw(L"c") == xml->getNodeName())
{
// adding a character to this font
SFontArea a;
SGUISpriteFrame f;
SGUISprite s;
core::rect<s32> rectangle;
a.underhang = xml->getAttributeValueAsInt(L"u");
a.overhang = xml->getAttributeValueAsInt(L"o");
a.spriteno = SpriteBank->getSprites().size();
s32 texno = xml->getAttributeValueAsInt(L"i");
// parse rectangle
core::stringc rectstr = xml->getAttributeValue(L"r");
wchar_t ch = xml->getAttributeValue(L"c")[0];
const c8 *c = rectstr.c_str();
s32 val;
val = 0;
while (*c >= '0' && *c <= '9')
{
val *= 10;
val += *c - '0';
c++;
}
rectangle.UpperLeftCorner.X = val;
while (*c == L' ' || *c == L',') c++;
val = 0;
while (*c >= '0' && *c <= '9')
{
val *= 10;
val += *c - '0';
c++;
}
rectangle.UpperLeftCorner.Y = val + trim_top;
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 - trim_bottom;
CharacterMap[ch] = Areas.size();
//Log::info("ScalableFont", "Inserting character '%d' with area %d", (int)ch, Areas.size());
// make frame
f.rectNumber = SpriteBank->getPositions().size();
f.textureNumber = texno;
// add frame to sprite
s.Frames.push_back(f);
s.frameTime = 0;
// add rectangle to sprite bank
SpriteBank->getPositions().push_back(rectangle);
a.width = rectangle.getWidth();
// add sprite to sprite bank
SpriteBank->getSprites().push_back(s);
// add character to font
Areas.push_back(a);
}
}
}
}
//! loads a font file from xml
bool ScalableFont::load(io::IXMLReader* xml)
{
if (!SpriteBank)
{
Log::error("ScalableFont::load", "SpriteBank is NULL!!");
return false;
}
doReadXmlFile(xml);
// set bad character
WrongCharacter = getAreaIDFromCharacter(L' ', NULL);
setMaxHeight();
for(wchar_t c='0'; c<='9'; c++)
{
SFontArea a = getAreaFromCharacter(c, NULL);
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.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;
return true;
}
#endif // ENABLE_FREETYPE
#ifdef ENABLE_FREETYPE
//! loads a font from a TTF file
bool ScalableFont::loadTTF()
{
@ -376,12 +132,12 @@ bool ScalableFont::loadTTF()
m_dpi = cur_prop.size;
std::vector <s32> offset;
std::vector <s32> bx;
std::vector <s32> bearingx;
std::vector <s32> advance;
std::vector <s32> height;
std::set<wchar_t>::iterator it;
s32 current_maxheight = 0;
s32 curr_maxheight = 0;
s32 t;
u32 texno = 0;
SpriteBank->addTexture(NULL);
@ -437,22 +193,22 @@ bool ScalableFont::loadTTF()
Log::error("ScalableFont::loadTTF", "Can't load a single glyph.");
// Store vertical offset on line.
s32 offset_on_line = (curr_face->glyph->metrics.height >> 6) - curr_face->glyph->bitmap_top;
offset.push_back(offset_on_line);
s32 curr_offset = (curr_face->glyph->metrics.height >> 6) - curr_face->glyph->bitmap_top;
offset.push_back(curr_offset);
// This is to be used later.
t = curr_face->glyph->metrics.height >> 6;
height.push_back(t);
if (t > current_maxheight)
current_maxheight = t;
if (t > curr_maxheight)
curr_maxheight = t;
// Store horizontal padding (bearingX).
s32 bX = curr_face->glyph->bitmap_left;
bx.push_back(bX);
s32 curr_bearingx = curr_face->glyph->bitmap_left;
bearingx.push_back(curr_bearingx);
// Store total width on horizontal line.
s32 width = curr_face->glyph->advance.x >> 6;
advance.push_back(width);
s32 curr_advance = curr_face->glyph->advance.x >> 6;
advance.push_back(curr_advance);
// Convert to an anti-aliased bitmap
FT_Bitmap bits = slot->bitmap;
@ -538,7 +294,7 @@ bool ScalableFont::loadTTF()
//Storing now
SFontArea a;
a.spriteno = n;
a.offsety = current_maxheight - height.at(n)
a.offsety = curr_maxheight - height.at(n)
+ offset.at(n); //Compute the correct offset as ttf texture image is cropped against the glyph fully.
a.offsety_bt = -offset.at(n); //FIXME
@ -550,7 +306,7 @@ bool ScalableFont::loadTTF()
if (!n) //Skip width-less characters
a.bearingx = 0;
else
a.bearingx = bx.at(n);
a.bearingx = bearingx.at(n);
if (!n) //Skip width-less characters
a.width = 0;
else
@ -563,10 +319,10 @@ bool ScalableFont::loadTTF()
//Reserve 10 for normal font new characters added, 40 for digit font to display separately
//Consider fallback font (bold) too
MaxHeight = (int)((current_maxheight + (m_type == T_DIGIT ? 40 : 10) +
MaxHeight = (int)((curr_maxheight + (m_type == T_DIGIT ? 40 : 10) +
(m_type == T_BOLD ? 20 : 0))*m_scale);
GlyphMaxHeight = current_maxheight;
GlyphMaxHeight = curr_maxheight;
for(wchar_t c='0'; c<='9'; c++)
{
@ -611,8 +367,8 @@ bool ScalableFont::lazyLoadChar()
GUIEngine::GlyphPageCreator* gp_creator = GUIEngine::getGlyphPageCreator();
s32 height;
s32 bX;
s32 offset_on_line;
s32 bearingx;
s32 curr_offset;
s32 width;
u32 texno = SpriteBank->getTextureCount() - 1;
std::set<wchar_t>::iterator it;
@ -653,9 +409,9 @@ bool ScalableFont::lazyLoadChar()
if (err)
Log::error("ScalableFont::loadTTF", "Can't load a single glyph.");
offset_on_line = (curr_face->glyph->metrics.height >> 6) - curr_face->glyph->bitmap_top;
curr_offset = (curr_face->glyph->metrics.height >> 6) - curr_face->glyph->bitmap_top;
height = curr_face->glyph->metrics.height >> 6;
bX = curr_face->glyph->bitmap_left;
bearingx = curr_face->glyph->bitmap_left;
width = curr_face->glyph->advance.x >> 6;
FT_Bitmap bits = slot->bitmap;
CharacterMap[*it] = SpriteBank->getSprites().size();
@ -686,9 +442,9 @@ bool ScalableFont::lazyLoadChar()
SFontArea a;
a.spriteno = SpriteBank->getSprites().size() - 1;
a.offsety = GlyphMaxHeight - height + offset_on_line;
a.offsety_bt = -offset_on_line;
a.bearingx = bX;
a.offsety = GlyphMaxHeight - height + curr_offset;
a.offsety_bt = -curr_offset;
a.bearingx = bearingx;
a.width = width;
Areas.push_back(a);
}
@ -729,42 +485,12 @@ void ScalableFont::forceNewPage()
gp_creator->createNewGlyphPage();
}
#endif // ENABLE_FREETYPE
void ScalableFont::setScale(const float scale)
{
m_scale = scale;
}
#ifndef ENABLE_FREETYPE
void ScalableFont::setMaxHeight()
{
MaxHeight = 0;
s32 t;
core::array< core::rect<s32> >& p = SpriteBank->getPositions();
core::array< SGUISprite >& sprites = SpriteBank->getSprites();
for (u32 i=0; i<p.size(); ++i)
{
t = p[i].getHeight();
// FIXME: consider fallback fonts
int texID = sprites[i].Frames[0].textureNumber;
const TextureInfo& info = (*(m_texture_files.find(texID))).second;
if (info.m_exclude_from_max_height_calculation) continue;
float char_scale = info.m_scale;
t = (int)(t*char_scale);
if (t>MaxHeight)
MaxHeight = t;
}
MaxHeight = (int)(MaxHeight*m_scale);
}
#endif // ENABLE_FREETYPE
@ -780,18 +506,6 @@ s32 ScalableFont::getKerningWidth(const wchar_t* thisLetter, const wchar_t* prev
{
s32 ret = GlobalKerningWidth;
#ifndef ENABLE_FREETYPE
if (thisLetter)
{
ret += Areas[getAreaIDFromCharacter(*thisLetter, NULL)].overhang;
if (previousLetter)
{
ret += Areas[getAreaIDFromCharacter(*previousLetter, NULL)].underhang;
}
}
#endif // ENABLE_FREETYPE
return ret;
}
@ -880,7 +594,6 @@ void ScalableFont::setInvisibleCharacters( const wchar_t *s )
//! returns the dimension of text
core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
{
#ifdef ENABLE_FREETYPE
GUIEngine::GlyphPageCreator* gp_creator = GUIEngine::getGlyphPageCreator();
if (m_type == T_NORMAL || T_BOLD) //lazy load char
@ -901,7 +614,6 @@ core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
Log::error("ScalableFont::lazyLoadChar", "Can't insert new char into glyph pages.");
}
}
#endif // ENABLE_FREETYPE
assert(Areas.size() > 0);
@ -925,10 +637,6 @@ core::dimension2d<u32> ScalableFont::getDimension(const wchar_t* text) const
bool fallback = false;
const SFontArea &area = getAreaFromCharacter(*p, &fallback);
#ifndef ENABLE_FREETYPE
thisLine.Width += area.underhang;
#endif // ENABLE_FREETYPE
thisLine.Width += getCharWidth(area, fallback);
}
@ -1015,7 +723,6 @@ void ScalableFont::doDraw(const core::stringw& text,
core::array<core::position2di> offsets(text_size);
std::vector<bool> fallback(text_size);
#ifdef ENABLE_FREETYPE
if (m_type == T_NORMAL || T_BOLD) //lazy load char, have to do this again
{ //because some text isn't drawn with getDimension
for (u32 i = 0; i<text_size; i++)
@ -1044,7 +751,6 @@ void ScalableFont::doDraw(const core::stringw& text,
Log::error("ScalableFont::lazyLoadChar", "Can't insert new char into glyph pages.");
}
}
#endif // ENABLE_FREETYPE
for (u32 i = 0; i<text_size; i++)
{
@ -1064,7 +770,6 @@ void ScalableFont::doDraw(const core::stringw& text,
bool use_fallback_font = false;
const SFontArea &area = getAreaFromCharacter(c, &use_fallback_font);
fallback[i] = use_fallback_font;
#ifdef ENABLE_FREETYPE
if (charCollector == NULL)
{
//floor is used to prevent negligible movement when m_scale changes with resolution
@ -1090,10 +795,6 @@ void ScalableFont::doDraw(const core::stringw& text,
offset.X -= Hpadding;
offset.Y -= Vpadding + floor(m_type == T_DIGIT ? 20*m_scale : 0);
}
#else
offset.X += area.underhang;
offsets.push_back(offset);
#endif // ENABLE_FREETYPE
// Invisible character. add something to the array anyway so that
// indices from the various arrays remain in sync
indices.push_back( Invisible.findFirst(c) < 0 ? area.spriteno
@ -1119,6 +820,52 @@ void ScalableFont::doDraw(const core::stringw& text,
}
const int spriteAmount = sprites.size();
if (m_black_border && charCollector == NULL)
{ //Draw black border first, to make it behind the real character
//which make script language display better
video::SColor black(color.getAlpha(),0,0,0);
for (int n=0; n<indiceAmount; n++)
{
const int spriteID = indices[n];
if (!fallback[n] && (spriteID < 0 || spriteID >= spriteAmount)) continue;
if (indices[n] == -1) continue;
const int texID = (fallback[n] ?
(*fallback_sprites)[spriteID].Frames[0].textureNumber :
sprites[spriteID].Frames[0].textureNumber);
core::rect<s32> source = (fallback[n] ?
(*fallback_positions)[(*fallback_sprites)[spriteID].Frames[0].rectNumber] :
positions[sprites[spriteID].Frames[0].rectNumber]);
core::dimension2d<s32> size = source.getSize();
float scale = (fallback[n] ? m_scale*m_fallback_font_scale : m_scale);
size.Width = (int)(size.Width * scale);
size.Height = (int)(size.Height * scale);
core::rect<s32> dest(offsets[n], size);
video::ITexture* texture = (fallback[n] ?
m_fallback_font->SpriteBank->getTexture(texID) :
SpriteBank->getTexture(texID) );
for (int x_delta=-2; x_delta<=2; x_delta++)
{
for (int y_delta=-2; y_delta<=2; y_delta++)
{
if (x_delta == 0 || y_delta == 0) continue;
draw2DImage(texture,
dest + core::position2d<s32>(x_delta, y_delta),
source,
clip,
black, true);
}
}
}
}
for (int n=0; n<indiceAmount; n++)
{
const int spriteID = indices[n];
@ -1135,30 +882,13 @@ void ScalableFont::doDraw(const core::stringw& text,
(*fallback_positions)[(*fallback_sprites)[spriteID].Frames[0].rectNumber] :
positions[sprites[spriteID].Frames[0].rectNumber]);
#ifdef ENABLE_FREETYPE
float char_scale = 1.0f;
#else
const TextureInfo& info = (fallback[n] ?
(*(m_fallback_font->m_texture_files.find(texID))).second :
(*(m_texture_files.find(texID))).second
);
float char_scale = info.m_scale;
#endif // ENABLE_FREETYPE
core::dimension2d<s32> size = source.getSize();
float scale = (fallback[n] ? m_scale*m_fallback_font_scale : m_scale);
size.Width = (int)(size.Width * scale * char_scale);
size.Height = (int)(size.Height * scale * char_scale);
size.Width = (int)(size.Width * scale);
size.Height = (int)(size.Height * scale);
// align vertically if character is smaller
#ifndef ENABLE_FREETYPE
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);
#else
core::rect<s32> dest(offsets[n], size);
#endif // ENABLE_FREETYPE
video::ITexture* texture = (fallback[n] ?
m_fallback_font->SpriteBank->getTexture(texID) :
@ -1176,54 +906,7 @@ void ScalableFont::doDraw(const core::stringw& text,
GL32_draw2DRectangle(video::SColor(255, 255,0,0), dest,clip);
#endif
#ifndef ENABLE_FREETYPE
if (texture == NULL)
{
// perform lazy loading
if (fallback[n])
{
m_fallback_font->lazyLoadTexture(texID);
texture = m_fallback_font->SpriteBank->getTexture(texID);
}
else
{
lazyLoadTexture(texID);
texture = SpriteBank->getTexture(texID);
}
if (texture == NULL)
{
Log::warn("ScalableFont", "Character not found in current font");
continue; // no such character
}
}
#endif // ENABLE_FREETYPE
if (m_black_border && charCollector == NULL)
{
// draw black border
video::SColor black(color.getAlpha(),0,0,0);
for (int x_delta=-2; x_delta<=2; x_delta++)
{
for (int y_delta=-2; y_delta<=2; y_delta++)
{
if (x_delta == 0 || y_delta == 0) continue;
draw2DImage(texture,
dest + core::position2d<s32>(x_delta, y_delta),
source,
clip,
black, true);
}
}
}
#ifdef ENABLE_FREETYPE
if (fallback[n] || m_type == T_BOLD)
#else
if (fallback[n])
#endif // ENABLE_FREETYPE
{
// TODO: don't hardcode colors?
video::SColor orange(color.getAlpha(), 255, 100, 0);
@ -1269,78 +952,10 @@ void ScalableFont::doDraw(const core::stringw& text,
}
#ifndef ENABLE_FREETYPE
void ScalableFont::lazyLoadTexture(int texID)
{
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
// load texture
assert(m_texture_files[texID].m_file_name.size() > 0);
// Font textures can not be resized (besides the impact on quality in
// this case, the indices in the xml files would become wrong).
core::dimension2du old_max_size = Driver->getDriverAttributes()
.getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
Driver->getNonConstDriverAttributes().setAttribute("MAX_TEXTURE_SIZE",
core::dimension2du(0, 0));
SpriteBank->setTexture(texID, Driver->getTexture( m_texture_files[texID].m_file_name ));
Driver->getNonConstDriverAttributes().setAttribute("MAX_TEXTURE_SIZE", old_max_size);
// set previous mip-map+filter state
//Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap);
// couldn't load texture, abort.
if (!SpriteBank->getTexture(texID))
{
Log::error("ScalableFont::lazyLoadTexture", "Unable to load all textures in the font");
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return;
}
else
{
assert(m_texture_files[texID].m_file_name.size() > 0);
// colorkey texture rather than alpha channel?
if (! m_texture_files[texID].m_has_alpha)
{
Driver->makeColorKeyTexture(SpriteBank->getTexture(texID), core::position2di(0,0));
}
}
}
#endif // ENABLE_FREETYPE
int ScalableFont::getCharWidth(const SFontArea& area, const bool fallback) const
{
#ifdef ENABLE_FREETYPE
const float char_scale = 1.0f;
#else
core::array< SGUISprite >& sprites = SpriteBank->getSprites();
core::array< SGUISprite >* fallback_sprites = (m_fallback_font != NULL ?
&m_fallback_font->SpriteBank->getSprites() :
NULL);
const int texID = (fallback ?
(*fallback_sprites)[area.spriteno].Frames[0].textureNumber :
sprites[area.spriteno].Frames[0].textureNumber);
const TextureInfo& info = (fallback ?
(*(m_fallback_font->m_texture_files.find(texID))).second :
(*(m_texture_files.find(texID))).second
);
assert(info.m_file_name.size() > 0);
const float char_scale = info.m_scale;
#endif // ENABLE_FREETYPE
//Log::info("ScalableFont", "area.spriteno = %d, char_scale = %f", area.spriteno, char_scale);
#ifdef ENABLE_FREETYPE
if (fallback) return (int)((area.width*m_fallback_font_scale + m_fallback_kerning_width) * m_scale * char_scale);
else return (int)((area.width + GlobalKerningWidth) * m_scale * char_scale);
#else
if (fallback) 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);
#endif // ENABLE_FREETYPE
if (fallback) return (int)((area.width*m_fallback_font_scale + m_fallback_kerning_width) * m_scale);
else return (int)((area.width + GlobalKerningWidth) * m_scale);
}
@ -1355,11 +970,7 @@ s32 ScalableFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const
bool use_fallback_font = false;
const SFontArea &a = getAreaFromCharacter(text[idx], &use_fallback_font);
#ifdef ENABLE_FREETYPE
x += getCharWidth(a, use_fallback_font) + GlobalKerningWidth;
#else
x += getCharWidth(a, use_fallback_font) + a.overhang + a.underhang + GlobalKerningWidth;
#endif // ENABLE_FREETYPE
if (x >= pixel_x)
return idx;

View File

@ -7,9 +7,7 @@
#include "utils/leak_check.hpp"
#ifdef ENABLE_FREETYPE
#include "guiengine/get_font_properties.hpp"
#endif // ENABLE_FREETYPE
#include "IrrCompileConfig.h"
#include "IGUIFontBitmap.h"
@ -55,26 +53,6 @@ class ScalableFont : public IGUIFontBitmap
bool m_mono_space_digits;
irr::video::SColor m_shadow_color;
#ifndef ENABLE_FREETYPE
struct TextureInfo
{
irr::core::stringc m_file_name;
bool m_has_alpha;
float m_scale;
bool m_exclude_from_max_height_calculation;
TextureInfo()
{
m_has_alpha = false;
m_scale = 1.0f;
}
};
std::map<int /* texture file ID */, TextureInfo> m_texture_files;
void doReadXmlFile(io::IXMLReader* xml);
#endif // ENABLE_FREETYPE
bool m_is_hollow_copy;
bool m_rtl;
@ -84,22 +62,16 @@ public:
bool m_black_border;
#ifdef ENABLE_FREETYPE
TTFLoadingType m_type;
FontUse m_font_use;
u32 m_dpi;
#endif // ENABLE_FREETYPE
ScalableFont* m_fallback_font;
float m_fallback_font_scale;
int m_fallback_kerning_width;
//! constructor
#ifdef ENABLE_FREETYPE
ScalableFont(IGUIEnvironment* env, TTFLoadingType type);
#else
ScalableFont(IGUIEnvironment* env, const std::string &filename);
#endif // ENABLE_FREETYPE
/** 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
@ -120,15 +92,8 @@ public:
//! destructor
virtual ~ScalableFont();
#ifdef ENABLE_FREETYPE
//! loads a font from a TTF file
bool loadTTF();
#else
//! loads a font from an XML file
bool load(io::IXMLReader* xml);
void lazyLoadTexture(int texID);
#endif // ENABLE_FREETYPE
//! draws an text and clips it to the specified rectangle if wanted
virtual void draw(const core::stringw& text, const core::rect<s32>& position,
@ -180,7 +145,6 @@ public:
void updateRTL();
#ifdef ENABLE_FREETYPE
//! re-create fonts when language is changed
void recreateFromLanguage();
@ -189,11 +153,9 @@ public:
//! force create a new texture (glyph) page in a font
void forceNewPage();
#endif // ENABLE_FREETYPE
private:
#ifdef ENABLE_FREETYPE
struct SFontArea
{
SFontArea() : width(0), spriteno(0), offsety(0), offsety_bt(0), bearingx(0) {}
@ -203,16 +165,6 @@ private:
s32 offsety_bt;
s32 bearingx;
};
#else
struct SFontArea
{
SFontArea() : underhang(0), overhang(0), width(0), spriteno(0) {}
s32 underhang;
s32 overhang;
s32 width;
u32 spriteno;
};
#endif // ENABLE_FREETYPE
int getCharWidth(const SFontArea& area, const bool fallback) const;
s32 getAreaIDFromCharacter(const wchar_t c, bool* fallback_font) const;
@ -229,10 +181,8 @@ private:
u32 WrongCharacter;
s32 MaxHeight;
s32 GlobalKerningWidth, GlobalKerningHeight;
#ifdef ENABLE_FREETYPE
s32 GlyphMaxHeight;
video::ITexture* LastNormalPage;
#endif // ENABLE_FREETYPE
core::stringw Invisible;
};

View File

@ -330,13 +330,11 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
translations = new Translations();
#ifdef ENABLE_FREETYPE
//Reload fonts for new translation when using freetype
//Reload fonts for new translation
GUIEngine::cleanHollowCopyFont();
GUIEngine::getTitleFont()->recreateFromLanguage();
GUIEngine::getFont()->recreateFromLanguage();
GUIEngine::reloadHollowCopyFont(GUIEngine::getFont());
#endif // ENABLE_FREETYPE
GUIEngine::getStateManager()->hardResetAndGoToScreen<MainMenuScreen>();