Refactor FaceTTF for later better usage
This commit is contained in:
parent
dd9d5c89e1
commit
867cecc01e
@ -22,7 +22,7 @@
|
|||||||
/** Constructor of BoldFace.
|
/** Constructor of BoldFace.
|
||||||
* \param ttf \ref FaceTTF for BoldFace to use.
|
* \param ttf \ref FaceTTF for BoldFace to use.
|
||||||
*/
|
*/
|
||||||
BoldFace::BoldFace(FaceTTF* ttf) : FontWithFace("BoldFace", ttf)
|
BoldFace::BoldFace() : FontWithFace("BoldFace")
|
||||||
{
|
{
|
||||||
} // BoldFace
|
} // BoldFace
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
LEAK_CHECK()
|
LEAK_CHECK()
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
BoldFace(FaceTTF* ttf);
|
BoldFace();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void init() OVERRIDE;
|
virtual void init() OVERRIDE;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
/** Constructor of DigitFace.
|
/** Constructor of DigitFace.
|
||||||
* \param ttf \ref FaceTTF for DigitFace to use.
|
* \param ttf \ref FaceTTF for DigitFace to use.
|
||||||
*/
|
*/
|
||||||
DigitFace::DigitFace(FaceTTF* ttf) : FontWithFace("DigitFace", ttf)
|
DigitFace::DigitFace() : FontWithFace("DigitFace")
|
||||||
{
|
{
|
||||||
} // DigitFace
|
} // DigitFace
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
LEAK_CHECK()
|
LEAK_CHECK()
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
DigitFace(FaceTTF* ttf);
|
DigitFace();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void init() OVERRIDE;
|
virtual void init() OVERRIDE;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
//
|
|
||||||
// SuperTuxKart - a fun racing game with go-kart
|
|
||||||
// Copyright (C) 2016 SuperTuxKart-Team
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License
|
|
||||||
// as published by the Free Software Foundation; either version 3
|
|
||||||
// of the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
#include "font/face_ttf.hpp"
|
|
||||||
|
|
||||||
#include "font/font_manager.hpp"
|
|
||||||
#include "io/file_manager.hpp"
|
|
||||||
#include "modes/profile_world.hpp"
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Constructor. Load all TTFs from a list.
|
|
||||||
* \param ttf_list List of TTFs to be loaded.
|
|
||||||
*/
|
|
||||||
FaceTTF::FaceTTF(const std::vector<std::string>& ttf_list)
|
|
||||||
{
|
|
||||||
#ifndef SERVER_ONLY
|
|
||||||
if (ProfileWorld::isNoGraphics())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (const std::string& font : ttf_list)
|
|
||||||
{
|
|
||||||
FT_Face face = NULL;
|
|
||||||
const std::string loc = file_manager
|
|
||||||
->getAssetChecked(FileManager::TTF, font.c_str(), true);
|
|
||||||
font_manager->checkFTError(FT_New_Face(font_manager->getFTLibrary(),
|
|
||||||
loc.c_str(), 0, &face), loc + " is loaded");
|
|
||||||
m_faces.push_back(face);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} // FaceTTF
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
/** Destructor. Clears all TTFs.
|
|
||||||
*/
|
|
||||||
FaceTTF::~FaceTTF()
|
|
||||||
{
|
|
||||||
#ifndef SERVER_ONLY
|
|
||||||
if (ProfileWorld::isNoGraphics())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < m_faces.size(); i++)
|
|
||||||
{
|
|
||||||
font_manager->checkFTError(FT_Done_Face(m_faces[i]), "removing face");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} // ~FaceTTF
|
|
@ -23,7 +23,9 @@
|
|||||||
#include "utils/no_copy.hpp"
|
#include "utils/no_copy.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
@ -31,27 +33,71 @@
|
|||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** This class will load a list of TTF files from \ref STKConfig, and save
|
/** Glyph metrics for each glyph loaded. */
|
||||||
|
struct FontArea
|
||||||
|
{
|
||||||
|
FontArea() : advance_x(0), bearing_x(0), offset_y(0), offset_y_bt(0),
|
||||||
|
spriteno(0) {}
|
||||||
|
/** Advance width for horizontal layout. */
|
||||||
|
int advance_x;
|
||||||
|
/** Left side bearing for horizontal layout. */
|
||||||
|
int bearing_x;
|
||||||
|
/** Top side bearing for horizontal layout. */
|
||||||
|
int offset_y;
|
||||||
|
/** Top side bearing for horizontal layout used in billboard text. */
|
||||||
|
int offset_y_bt;
|
||||||
|
/** Index number in sprite bank of \ref FontWithFace. */
|
||||||
|
int spriteno;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** This class will load a list of TTF files from \ref FontManager, and save
|
||||||
* them inside \ref m_faces for \ref FontWithFace to load glyph.
|
* them inside \ref m_faces for \ref FontWithFace to load glyph.
|
||||||
* Each FaceTTF can be used more than once in each instantiation of \ref
|
|
||||||
* FontWithFace, so it can render characters differently using the same TTF
|
|
||||||
* file to save memory, for example different outline size.
|
|
||||||
* \ingroup font
|
* \ingroup font
|
||||||
*/
|
*/
|
||||||
class FaceTTF : public NoCopy
|
class FaceTTF : public NoCopy
|
||||||
{
|
{
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
private:
|
private:
|
||||||
/** Contains all TTF files loaded. */
|
/** Contains all FT_Face with a list of loaded glyph index with the
|
||||||
std::vector<FT_Face> m_faces;
|
* \ref FontArea. */
|
||||||
|
std::vector<std::pair<FT_Face, std::map<unsigned, FontArea> > > m_faces;
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
LEAK_CHECK()
|
LEAK_CHECK()
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
FaceTTF(const std::vector<std::string>& ttf_list);
|
FaceTTF() {}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
~FaceTTF();
|
~FaceTTF() {}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
|
for (unsigned int i = 0; i < m_faces.size(); i++)
|
||||||
|
m_faces[i].second.clear();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
/* Return a white-space font area, which is the first glyph in ttf. */
|
||||||
|
const FontArea* getFirstFontArea() const
|
||||||
|
{
|
||||||
|
#ifdef SERVER_ONLY
|
||||||
|
static FontArea area;
|
||||||
|
return &area;
|
||||||
|
#else
|
||||||
|
if (m_faces.empty())
|
||||||
|
return NULL;
|
||||||
|
if (m_faces.front().second.empty())
|
||||||
|
return NULL;
|
||||||
|
return &(m_faces.front().second.begin()->second);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void loadFaces(std::vector<FT_Face> faces)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < faces.size(); i++)
|
||||||
|
m_faces.emplace_back(faces[i], std::map<unsigned, FontArea>());
|
||||||
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Return a TTF in \ref m_faces.
|
/** Return a TTF in \ref m_faces.
|
||||||
* \param i index of TTF file in \ref m_faces.
|
* \param i index of TTF file in \ref m_faces.
|
||||||
@ -59,11 +105,42 @@ public:
|
|||||||
FT_Face getFace(unsigned int i) const
|
FT_Face getFace(unsigned int i) const
|
||||||
{
|
{
|
||||||
assert(i < m_faces.size());
|
assert(i < m_faces.size());
|
||||||
return m_faces[i];
|
return m_faces[i].first;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Return the total TTF files loaded. */
|
/** Return the total TTF files loaded. */
|
||||||
unsigned int getTotalFaces() const { return (unsigned int)m_faces.size(); }
|
unsigned int getTotalFaces() const { return (unsigned int)m_faces.size(); }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
void insertFontArea(const FontArea& a, unsigned font_index,
|
||||||
|
unsigned glyph_index)
|
||||||
|
{
|
||||||
|
auto& ttf = m_faces.at(font_index).second;
|
||||||
|
ttf[glyph_index] = a;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
const FontArea* getFontArea(unsigned font_index, unsigned glyph_index)
|
||||||
|
{
|
||||||
|
auto& ttf = m_faces.at(font_index).second;
|
||||||
|
auto it = ttf.find(glyph_index);
|
||||||
|
if (it != ttf.end())
|
||||||
|
return &it->second;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
bool getFontAndGlyphFromChar(uint32_t c, unsigned* font, unsigned* glyph)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < m_faces.size(); i++)
|
||||||
|
{
|
||||||
|
unsigned glyph_index = FT_Get_Char_Index(m_faces[i].first, c);
|
||||||
|
if (glyph_index > 0)
|
||||||
|
{
|
||||||
|
*font = i;
|
||||||
|
*glyph = glyph_index;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}; // FaceTTF
|
}; // FaceTTF
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "font/font_manager.hpp"
|
#include "font/font_manager.hpp"
|
||||||
|
|
||||||
#include "config/stk_config.hpp"
|
#include "config/stk_config.hpp"
|
||||||
|
#include "io/file_manager.hpp"
|
||||||
#include "font/bold_face.hpp"
|
#include "font/bold_face.hpp"
|
||||||
#include "font/digit_face.hpp"
|
#include "font/digit_face.hpp"
|
||||||
#include "font/face_ttf.hpp"
|
#include "font/face_ttf.hpp"
|
||||||
@ -51,44 +52,82 @@ FontManager::~FontManager()
|
|||||||
delete m_fonts[i];
|
delete m_fonts[i];
|
||||||
m_fonts.clear();
|
m_fonts.clear();
|
||||||
|
|
||||||
delete m_normal_ttf;
|
|
||||||
m_normal_ttf = NULL;
|
|
||||||
delete m_digit_ttf;
|
|
||||||
m_digit_ttf = NULL;
|
|
||||||
|
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
if (ProfileWorld::isNoGraphics())
|
if (ProfileWorld::isNoGraphics())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < m_faces.size(); i++)
|
||||||
|
checkFTError(FT_Done_Face(m_faces[i]), "removing faces");
|
||||||
checkFTError(FT_Done_FreeType(m_ft_library), "removing freetype library");
|
checkFTError(FT_Done_FreeType(m_ft_library), "removing freetype library");
|
||||||
#endif
|
#endif
|
||||||
} // ~FontManager
|
} // ~FontManager
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Load all TTFs from a list to m_faces.
|
||||||
|
* \param ttf_list List of TTFs to be loaded.
|
||||||
|
*/
|
||||||
|
std::vector<FT_Face>
|
||||||
|
FontManager::loadTTF(const std::vector<std::string>& ttf_list)
|
||||||
|
{
|
||||||
|
std::vector <FT_Face> ret;
|
||||||
|
if (ProfileWorld::isNoGraphics())
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (const std::string& font : ttf_list)
|
||||||
|
{
|
||||||
|
FT_Face face = NULL;
|
||||||
|
const std::string loc = file_manager
|
||||||
|
->getAssetChecked(FileManager::TTF, font.c_str(), true);
|
||||||
|
font_manager->checkFTError(FT_New_Face(
|
||||||
|
m_ft_library, loc.c_str(), 0, &face), loc + " is loaded");
|
||||||
|
ret.push_back(face);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} // loadTTF
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Initialize all \ref FaceTTF and \ref FontWithFace members.
|
/** Initialize all \ref FaceTTF and \ref FontWithFace members.
|
||||||
*/
|
*/
|
||||||
void FontManager::loadFonts()
|
void FontManager::loadFonts()
|
||||||
{
|
{
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
// First load the TTF files required by each font
|
// First load the TTF files required by each font
|
||||||
m_normal_ttf = new FaceTTF(stk_config->m_normal_ttf);
|
std::vector<FT_Face> normal_ttf = loadTTF(stk_config->m_normal_ttf);
|
||||||
m_digit_ttf = new FaceTTF(stk_config->m_digit_ttf);
|
std::vector<FT_Face> digit_ttf = loadTTF(stk_config->m_digit_ttf);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Now load fonts with settings of ttf file
|
// Now load fonts with settings of ttf file
|
||||||
unsigned int font_loaded = 0;
|
unsigned int font_loaded = 0;
|
||||||
RegularFace* regular = new RegularFace(m_normal_ttf);
|
RegularFace* regular = new RegularFace();
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
regular->getFaceTTF()->loadFaces(normal_ttf);
|
||||||
|
#endif
|
||||||
regular->init();
|
regular->init();
|
||||||
m_fonts.push_back(regular);
|
m_fonts.push_back(regular);
|
||||||
m_font_type_map[std::type_index(typeid(RegularFace))] = font_loaded++;
|
m_font_type_map[std::type_index(typeid(RegularFace))] = font_loaded++;
|
||||||
|
|
||||||
BoldFace* bold = new BoldFace(m_normal_ttf);
|
BoldFace* bold = new BoldFace();
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
bold->getFaceTTF()->loadFaces(normal_ttf);
|
||||||
|
#endif
|
||||||
bold->init();
|
bold->init();
|
||||||
m_fonts.push_back(bold);
|
m_fonts.push_back(bold);
|
||||||
m_font_type_map[std::type_index(typeid(BoldFace))] = font_loaded++;
|
m_font_type_map[std::type_index(typeid(BoldFace))] = font_loaded++;
|
||||||
|
|
||||||
DigitFace* digit = new DigitFace(m_digit_ttf);
|
DigitFace* digit = new DigitFace();
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
digit->getFaceTTF()->loadFaces(digit_ttf);
|
||||||
|
#endif
|
||||||
digit->init();
|
digit->init();
|
||||||
m_fonts.push_back(digit);
|
m_fonts.push_back(digit);
|
||||||
m_font_type_map[std::type_index(typeid(DigitFace))] = font_loaded++;
|
m_font_type_map[std::type_index(typeid(DigitFace))] = font_loaded++;
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
m_faces.insert(m_faces.end(), normal_ttf.begin(), normal_ttf.end());
|
||||||
|
m_faces.insert(m_faces.end(), digit_ttf.begin(), digit_ttf.end());
|
||||||
|
#endif
|
||||||
} // loadFonts
|
} // loadFonts
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -115,6 +154,8 @@ void FontManager::unitTesting()
|
|||||||
translations = new Translations();
|
translations = new Translations();
|
||||||
Log::setLogLevel(cur_log_level);
|
Log::setLogLevel(cur_log_level);
|
||||||
std::set<wchar_t> used_chars = translations->getCurrentAllChar();
|
std::set<wchar_t> used_chars = translations->getCurrentAllChar();
|
||||||
|
// First FontWithFace is RegularFace
|
||||||
|
FaceTTF* ttf = m_fonts.front()->getFaceTTF();
|
||||||
for (const wchar_t& c : used_chars)
|
for (const wchar_t& c : used_chars)
|
||||||
{
|
{
|
||||||
// Skip non-printing characters
|
// Skip non-printing characters
|
||||||
@ -122,20 +163,13 @@ void FontManager::unitTesting()
|
|||||||
|
|
||||||
unsigned int font_number = 0;
|
unsigned int font_number = 0;
|
||||||
unsigned int glyph_index = 0;
|
unsigned int glyph_index = 0;
|
||||||
while (font_number < m_normal_ttf->getTotalFaces())
|
if (ttf->getFontAndGlyphFromChar(c, &font_number, &glyph_index))
|
||||||
{
|
|
||||||
glyph_index =
|
|
||||||
FT_Get_Char_Index(m_normal_ttf->getFace(font_number), c);
|
|
||||||
if (glyph_index > 0) break;
|
|
||||||
font_number++;
|
|
||||||
}
|
|
||||||
if (glyph_index > 0)
|
|
||||||
{
|
{
|
||||||
Log::debug("UnitTest", "Character %s in language %s"
|
Log::debug("UnitTest", "Character %s in language %s"
|
||||||
" use face %s",
|
" use face %s",
|
||||||
StringUtils::wideToUtf8(core::stringw(&c, 1)).c_str(),
|
StringUtils::wideToUtf8(core::stringw(&c, 1)).c_str(),
|
||||||
lang.c_str(),
|
lang.c_str(),
|
||||||
m_normal_ttf->getFace(font_number)->family_name);
|
ttf->getFace(font_number)->family_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class FaceTTF;
|
|
||||||
class FontWithFace;
|
class FontWithFace;
|
||||||
|
|
||||||
/** This class stores all font files required in STK.
|
/** This class stores all font files required in STK.
|
||||||
@ -52,14 +51,11 @@ private:
|
|||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
/** A FreeType library, it holds the FT_Face internally inside freetype. */
|
/** A FreeType library, it holds the FT_Face internally inside freetype. */
|
||||||
FT_Library m_ft_library;
|
FT_Library m_ft_library;
|
||||||
|
|
||||||
|
/** List of ttf files loaded. */
|
||||||
|
std::vector<FT_Face> m_faces;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** TTF files used in \ref BoldFace and \ref RegularFace. */
|
|
||||||
FaceTTF* m_normal_ttf;
|
|
||||||
|
|
||||||
/** TTF files used in \ref DigitFace. */
|
|
||||||
FaceTTF* m_digit_ttf;
|
|
||||||
|
|
||||||
/** Map type for each \ref FontWithFace with a index, save getting time in
|
/** Map type for each \ref FontWithFace with a index, save getting time in
|
||||||
* \ref getFont. */
|
* \ref getFont. */
|
||||||
std::unordered_map<std::type_index, int> m_font_type_map;
|
std::unordered_map<std::type_index, int> m_font_type_map;
|
||||||
@ -101,6 +97,8 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Return the \ref m_ft_library. */
|
/** Return the \ref m_ft_library. */
|
||||||
FT_Library getFTLibrary() const { return m_ft_library; }
|
FT_Library getFTLibrary() const { return m_ft_library; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
std::vector<FT_Face> loadTTF(const std::vector<std::string>& ttf_list);
|
||||||
#endif
|
#endif
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void loadFonts();
|
void loadFonts();
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
* \param name The name of face, used by irrlicht to distinguish spritebank.
|
* \param name The name of face, used by irrlicht to distinguish spritebank.
|
||||||
* \param ttf \ref FaceTTF for this face to use.
|
* \param ttf \ref FaceTTF for this face to use.
|
||||||
*/
|
*/
|
||||||
FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
|
FontWithFace::FontWithFace(const std::string& name)
|
||||||
{
|
{
|
||||||
m_spritebank = irr_driver->getGUI()->addEmptySpriteBank(name.c_str());
|
m_spritebank = irr_driver->getGUI()->addEmptySpriteBank(name.c_str());
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
|
|||||||
m_fallback_font = NULL;
|
m_fallback_font = NULL;
|
||||||
m_fallback_font_scale = 1.0f;
|
m_fallback_font_scale = 1.0f;
|
||||||
m_glyph_max_height = 0;
|
m_glyph_max_height = 0;
|
||||||
m_face_ttf = ttf;
|
m_face_ttf = new FaceTTF();
|
||||||
|
|
||||||
} // FontWithFace
|
} // FontWithFace
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -65,9 +65,7 @@ FontWithFace::~FontWithFace()
|
|||||||
m_spritebank->drop();
|
m_spritebank->drop();
|
||||||
m_spritebank = NULL;
|
m_spritebank = NULL;
|
||||||
|
|
||||||
// To be deleted by font_manager
|
delete m_face_ttf;
|
||||||
m_face_ttf = NULL;
|
|
||||||
|
|
||||||
} // ~FontWithFace
|
} // ~FontWithFace
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -112,7 +110,6 @@ void FontWithFace::init()
|
|||||||
void FontWithFace::reset()
|
void FontWithFace::reset()
|
||||||
{
|
{
|
||||||
m_new_char_holder.clear();
|
m_new_char_holder.clear();
|
||||||
m_character_area_map.clear();
|
|
||||||
m_character_glyph_info_map.clear();
|
m_character_glyph_info_map.clear();
|
||||||
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
|
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
|
||||||
{
|
{
|
||||||
@ -120,6 +117,7 @@ void FontWithFace::reset()
|
|||||||
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
|
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
|
||||||
}
|
}
|
||||||
m_spritebank->clear();
|
m_spritebank->clear();
|
||||||
|
m_face_ttf->reset();
|
||||||
createNewGlyphPage();
|
createNewGlyphPage();
|
||||||
} // reset
|
} // reset
|
||||||
|
|
||||||
@ -138,12 +136,7 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
|
|||||||
|
|
||||||
unsigned int font_number = 0;
|
unsigned int font_number = 0;
|
||||||
unsigned int glyph_index = 0;
|
unsigned int glyph_index = 0;
|
||||||
while (font_number < m_face_ttf->getTotalFaces())
|
m_face_ttf->getFontAndGlyphFromChar(c, &font_number, &glyph_index);
|
||||||
{
|
|
||||||
glyph_index = FT_Get_Char_Index(m_face_ttf->getFace(font_number), c);
|
|
||||||
if (glyph_index > 0) break;
|
|
||||||
font_number++;
|
|
||||||
}
|
|
||||||
m_character_glyph_info_map[c] = GlyphInfo(font_number, glyph_index);
|
m_character_glyph_info_map[c] = GlyphInfo(font_number, glyph_index);
|
||||||
#endif
|
#endif
|
||||||
} // loadGlyphInfo
|
} // loadGlyphInfo
|
||||||
@ -179,10 +172,9 @@ void FontWithFace::createNewGlyphPage()
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Render a glyph for a character into bitmap and save it into the glyph page.
|
/** Render a glyph for a character into bitmap and save it into the glyph page.
|
||||||
* \param c The character to be loaded.
|
|
||||||
* \param c \ref GlyphInfo for the character.
|
* \param c \ref GlyphInfo for the character.
|
||||||
*/
|
*/
|
||||||
void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
void FontWithFace::insertGlyph(const GlyphInfo& gi)
|
||||||
{
|
{
|
||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
if (ProfileWorld::isNoGraphics())
|
if (ProfileWorld::isNoGraphics())
|
||||||
@ -280,7 +272,7 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
|||||||
a.offset_y = m_glyph_max_height - cur_height + cur_offset_y;
|
a.offset_y = m_glyph_max_height - cur_height + cur_offset_y;
|
||||||
a.offset_y_bt = -cur_offset_y;
|
a.offset_y_bt = -cur_offset_y;
|
||||||
a.spriteno = f.rectNumber;
|
a.spriteno = f.rectNumber;
|
||||||
m_character_area_map[c] = a;
|
m_face_ttf->insertFontArea(a, gi.font_number, gi.glyph_index);
|
||||||
|
|
||||||
// Store used area
|
// Store used area
|
||||||
m_used_width += texture_size.Width;
|
m_used_width += texture_size.Width;
|
||||||
@ -301,7 +293,7 @@ void FontWithFace::updateCharactersList()
|
|||||||
for (const wchar_t& c : m_new_char_holder)
|
for (const wchar_t& c : m_new_char_holder)
|
||||||
{
|
{
|
||||||
const GlyphInfo& gi = getGlyphInfo(c);
|
const GlyphInfo& gi = getGlyphInfo(c);
|
||||||
insertGlyph(c, gi);
|
insertGlyph(gi);
|
||||||
}
|
}
|
||||||
m_new_char_holder.clear();
|
m_new_char_holder.clear();
|
||||||
|
|
||||||
@ -373,17 +365,23 @@ void FontWithFace::setDPI()
|
|||||||
* \param c The character to get.
|
* \param c The character to get.
|
||||||
* \param[out] fallback_font Whether fallback font is used.
|
* \param[out] fallback_font Whether fallback font is used.
|
||||||
*/
|
*/
|
||||||
const FontWithFace::FontArea&
|
const FontArea& FontWithFace::getAreaFromCharacter(const wchar_t c,
|
||||||
FontWithFace::getAreaFromCharacter(const wchar_t c,
|
bool* fallback_font) const
|
||||||
bool* fallback_font) const
|
|
||||||
{
|
{
|
||||||
std::map<wchar_t, FontArea>::const_iterator n =
|
std::map<wchar_t, GlyphInfo>::const_iterator n =
|
||||||
m_character_area_map.find(c);
|
m_character_glyph_info_map.find(c);
|
||||||
if (n != m_character_area_map.end())
|
// Not found, return the first font area, which is a white-space
|
||||||
|
if (n == m_character_glyph_info_map.end())
|
||||||
|
return *(m_face_ttf->getFirstFontArea());
|
||||||
|
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
|
const FontArea* area = m_face_ttf->getFontArea(n->second.font_number,
|
||||||
|
n->second.glyph_index);
|
||||||
|
if (area != NULL)
|
||||||
{
|
{
|
||||||
if (fallback_font != NULL)
|
if (fallback_font != NULL)
|
||||||
*fallback_font = false;
|
*fallback_font = false;
|
||||||
return n->second;
|
return *area;
|
||||||
}
|
}
|
||||||
else if (m_fallback_font != NULL && fallback_font != NULL)
|
else if (m_fallback_font != NULL && fallback_font != NULL)
|
||||||
{
|
{
|
||||||
@ -394,8 +392,9 @@ const FontWithFace::FontArea&
|
|||||||
// Not found, return the first font area, which is a white-space
|
// Not found, return the first font area, which is a white-space
|
||||||
if (fallback_font != NULL)
|
if (fallback_font != NULL)
|
||||||
*fallback_font = false;
|
*fallback_font = false;
|
||||||
return m_character_area_map.begin()->second;
|
#endif
|
||||||
|
|
||||||
|
return *(m_face_ttf->getFirstFontArea());
|
||||||
} // getAreaFromCharacter
|
} // getAreaFromCharacter
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -419,7 +418,6 @@ core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
|
|||||||
insertCharacters(text);
|
insertCharacters(text);
|
||||||
updateCharactersList();
|
updateCharactersList();
|
||||||
|
|
||||||
assert(m_character_area_map.size() > 0);
|
|
||||||
core::dimension2d<float> dim(0.0f, 0.0f);
|
core::dimension2d<float> dim(0.0f, 0.0f);
|
||||||
core::dimension2d<float> this_line(0.0f, m_font_max_height * scale);
|
core::dimension2d<float> this_line(0.0f, m_font_max_height * scale);
|
||||||
|
|
||||||
@ -465,6 +463,7 @@ core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
|
|||||||
int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
|
int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
|
||||||
FontSettings* font_settings) const
|
FontSettings* font_settings) const
|
||||||
{
|
{
|
||||||
|
#ifndef SERVER_ONLY
|
||||||
const float scale = font_settings ? font_settings->getScale() : 1.0f;
|
const float scale = font_settings ? font_settings->getScale() : 1.0f;
|
||||||
float x = 0;
|
float x = 0;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@ -482,7 +481,7 @@ int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
|
|||||||
|
|
||||||
++idx;
|
++idx;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
} // getCharacterFromPos
|
} // getCharacterFromPos
|
||||||
|
|
||||||
@ -759,3 +758,18 @@ void FontWithFace::render(const core::stringw& text,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} // render
|
} // render
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Return a character width.
|
||||||
|
* \param area \ref FontArea to get glyph metrics.
|
||||||
|
* \param fallback If fallback font is used.
|
||||||
|
* \param scale The scaling of the character.
|
||||||
|
* \return The calculated width with suitable scaling. */
|
||||||
|
float FontWithFace::getCharWidth(const FontArea& area, bool fallback,
|
||||||
|
float scale) const
|
||||||
|
{
|
||||||
|
if (fallback)
|
||||||
|
return area.advance_x * m_fallback_font_scale;
|
||||||
|
else
|
||||||
|
return area.advance_x * scale;
|
||||||
|
} // getCharWidth
|
||||||
|
@ -43,6 +43,7 @@ const int BEARING = 64;
|
|||||||
|
|
||||||
class FaceTTF;
|
class FaceTTF;
|
||||||
class FontSettings;
|
class FontSettings;
|
||||||
|
struct FontArea;
|
||||||
|
|
||||||
/** An abstract class which contains functions which convert vector fonts into
|
/** An abstract class which contains functions which convert vector fonts into
|
||||||
* bitmap and render them in STK. To make STK draw characters with different
|
* bitmap and render them in STK. To make STK draw characters with different
|
||||||
@ -70,23 +71,6 @@ public:
|
|||||||
const video::SColor* const colors) = 0;
|
const video::SColor* const colors) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Glyph metrics for each glyph loaded. */
|
|
||||||
struct FontArea
|
|
||||||
{
|
|
||||||
FontArea() : advance_x(0), bearing_x(0) ,offset_y(0), offset_y_bt(0),
|
|
||||||
spriteno(0) {}
|
|
||||||
/** Advance width for horizontal layout. */
|
|
||||||
int advance_x;
|
|
||||||
/** Left side bearing for horizontal layout. */
|
|
||||||
int bearing_x;
|
|
||||||
/** Top side bearing for horizontal layout. */
|
|
||||||
int offset_y;
|
|
||||||
/** Top side bearing for horizontal layout used in billboard text. */
|
|
||||||
int offset_y_bt;
|
|
||||||
/** Index number in sprite bank. */
|
|
||||||
int spriteno;
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Used in vertical dimension calculation. */
|
/** Used in vertical dimension calculation. */
|
||||||
int m_font_max_height;
|
int m_font_max_height;
|
||||||
@ -176,25 +160,11 @@ private:
|
|||||||
/** The dpi of this font. */
|
/** The dpi of this font. */
|
||||||
unsigned int m_face_dpi;
|
unsigned int m_face_dpi;
|
||||||
|
|
||||||
/** Store a list of supported character to a \ref FontArea. */
|
|
||||||
std::map<wchar_t, FontArea> m_character_area_map;
|
|
||||||
|
|
||||||
/** Store a list of loaded and tested character to a \ref GlyphInfo. */
|
/** Store a list of loaded and tested character to a \ref GlyphInfo. */
|
||||||
std::map<wchar_t, GlyphInfo> m_character_glyph_info_map;
|
std::map<wchar_t, GlyphInfo> m_character_glyph_info_map;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Return a character width.
|
float getCharWidth(const FontArea& area, bool fallback, float scale) const;
|
||||||
* \param area \ref FontArea to get glyph metrics.
|
|
||||||
* \param fallback If fallback font is used.
|
|
||||||
* \param scale The scaling of the character.
|
|
||||||
* \return The calculated width with suitable scaling. */
|
|
||||||
float getCharWidth(const FontArea& area, bool fallback, float scale) const
|
|
||||||
{
|
|
||||||
if (fallback)
|
|
||||||
return area.advance_x * m_fallback_font_scale;
|
|
||||||
else
|
|
||||||
return area.advance_x * scale;
|
|
||||||
}
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Test if a character has already been tried to be loaded.
|
/** Test if a character has already been tried to be loaded.
|
||||||
* \param c Character to test.
|
* \param c Character to test.
|
||||||
@ -243,7 +213,7 @@ private:
|
|||||||
/** Add a character into \ref m_new_char_holder for lazy loading later. */
|
/** Add a character into \ref m_new_char_holder for lazy loading later. */
|
||||||
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
|
void addLazyLoadChar(wchar_t c) { m_new_char_holder.insert(c); }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void insertGlyph(wchar_t c, const GlyphInfo& gi);
|
void insertGlyph(const GlyphInfo& gi);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setDPI();
|
void setDPI();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -273,7 +243,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
LEAK_CHECK()
|
LEAK_CHECK()
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
FontWithFace(const std::string& name, FaceTTF* ttf);
|
FontWithFace(const std::string& name);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual ~FontWithFace();
|
virtual ~FontWithFace();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -305,7 +275,8 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
/** Return the dpi of this face. */
|
/** Return the dpi of this face. */
|
||||||
unsigned int getDPI() const { return m_face_dpi; }
|
unsigned int getDPI() const { return m_face_dpi; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
FaceTTF* getFaceTTF() const { return m_face_ttf; }
|
||||||
}; // FontWithFace
|
}; // FontWithFace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
/** Constructor of RegularFace.
|
/** Constructor of RegularFace.
|
||||||
* \param ttf \ref FaceTTF for RegularFace to use.
|
* \param ttf \ref FaceTTF for RegularFace to use.
|
||||||
*/
|
*/
|
||||||
RegularFace::RegularFace(FaceTTF* ttf) : FontWithFace("RegularFace", ttf)
|
RegularFace::RegularFace() : FontWithFace("RegularFace")
|
||||||
{
|
{
|
||||||
} // RegularFace
|
} // RegularFace
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
LEAK_CHECK()
|
LEAK_CHECK()
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
RegularFace(FaceTTF* ttf);
|
RegularFace();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
virtual void init() OVERRIDE;
|
virtual void init() OVERRIDE;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "guiengine/scalable_font.hpp"
|
#include "guiengine/scalable_font.hpp"
|
||||||
|
|
||||||
|
#include "font/face_ttf.hpp"
|
||||||
#include "font/font_settings.hpp"
|
#include "font/font_settings.hpp"
|
||||||
#include "font/font_with_face.hpp"
|
#include "font/font_with_face.hpp"
|
||||||
#include "utils/translation.hpp"
|
#include "utils/translation.hpp"
|
||||||
@ -143,7 +144,7 @@ IGUISpriteBank* ScalableFont::getSpriteBank() const
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
u32 ScalableFont::getSpriteNoFromChar(const wchar_t *c) const
|
u32 ScalableFont::getSpriteNoFromChar(const wchar_t *c) const
|
||||||
{
|
{
|
||||||
const FontWithFace::FontArea& area =
|
const FontArea& area =
|
||||||
m_face->getAreaFromCharacter(*c, NULL/*fallback_font*/);
|
m_face->getAreaFromCharacter(*c, NULL/*fallback_font*/);
|
||||||
return area.spriteno;
|
return area.spriteno;
|
||||||
} // getSpriteNoFromChar
|
} // getSpriteNoFromChar
|
||||||
|
Loading…
Reference in New Issue
Block a user