Refactor FaceTTF for later better usage
This commit is contained in:
parent
dd9d5c89e1
commit
867cecc01e
@ -1,5 +1,5 @@
|
||||
# Modify this file to change the last-modified date when you add/remove a file.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
# This will then trigger a new cmake run automatically.
|
||||
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
|
||||
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
|
||||
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")
|
||||
|
@ -22,7 +22,7 @@
|
||||
/** Constructor of BoldFace.
|
||||
* \param ttf \ref FaceTTF for BoldFace to use.
|
||||
*/
|
||||
BoldFace::BoldFace(FaceTTF* ttf) : FontWithFace("BoldFace", ttf)
|
||||
BoldFace::BoldFace() : FontWithFace("BoldFace")
|
||||
{
|
||||
} // BoldFace
|
||||
|
||||
|
@ -45,7 +45,7 @@ private:
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
BoldFace(FaceTTF* ttf);
|
||||
BoldFace();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void init() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -22,7 +22,7 @@
|
||||
/** Constructor of DigitFace.
|
||||
* \param ttf \ref FaceTTF for DigitFace to use.
|
||||
*/
|
||||
DigitFace::DigitFace(FaceTTF* ttf) : FontWithFace("DigitFace", ttf)
|
||||
DigitFace::DigitFace() : FontWithFace("DigitFace")
|
||||
{
|
||||
} // DigitFace
|
||||
|
||||
|
@ -40,7 +40,7 @@ private:
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
DigitFace(FaceTTF* ttf);
|
||||
DigitFace();
|
||||
// ------------------------------------------------------------------------
|
||||
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 <cassert>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
@ -31,27 +33,71 @@
|
||||
#include FT_FREETYPE_H
|
||||
#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.
|
||||
* 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
|
||||
*/
|
||||
class FaceTTF : public NoCopy
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
private:
|
||||
/** Contains all TTF files loaded. */
|
||||
std::vector<FT_Face> m_faces;
|
||||
/** Contains all FT_Face with a list of loaded glyph index with the
|
||||
* \ref FontArea. */
|
||||
std::vector<std::pair<FT_Face, std::map<unsigned, FontArea> > > m_faces;
|
||||
#endif
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
FaceTTF(const std::vector<std::string>& ttf_list);
|
||||
FaceTTF() {}
|
||||
// ------------------------------------------------------------------------
|
||||
~FaceTTF();
|
||||
~FaceTTF() {}
|
||||
// ------------------------------------------------------------------------
|
||||
void reset()
|
||||
{
|
||||
#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.
|
||||
* \param i index of TTF file in \ref m_faces.
|
||||
@ -59,11 +105,42 @@ public:
|
||||
FT_Face getFace(unsigned int i) const
|
||||
{
|
||||
assert(i < m_faces.size());
|
||||
return m_faces[i];
|
||||
return m_faces[i].first;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the total TTF files loaded. */
|
||||
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
|
||||
|
||||
}; // FaceTTF
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "font/font_manager.hpp"
|
||||
|
||||
#include "config/stk_config.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "font/bold_face.hpp"
|
||||
#include "font/digit_face.hpp"
|
||||
#include "font/face_ttf.hpp"
|
||||
@ -51,44 +52,82 @@ FontManager::~FontManager()
|
||||
delete m_fonts[i];
|
||||
m_fonts.clear();
|
||||
|
||||
delete m_normal_ttf;
|
||||
m_normal_ttf = NULL;
|
||||
delete m_digit_ttf;
|
||||
m_digit_ttf = NULL;
|
||||
|
||||
#ifndef SERVER_ONLY
|
||||
if (ProfileWorld::isNoGraphics())
|
||||
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");
|
||||
#endif
|
||||
} // ~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.
|
||||
*/
|
||||
void FontManager::loadFonts()
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
// First load the TTF files required by each font
|
||||
m_normal_ttf = new FaceTTF(stk_config->m_normal_ttf);
|
||||
m_digit_ttf = new FaceTTF(stk_config->m_digit_ttf);
|
||||
std::vector<FT_Face> normal_ttf = loadTTF(stk_config->m_normal_ttf);
|
||||
std::vector<FT_Face> digit_ttf = loadTTF(stk_config->m_digit_ttf);
|
||||
#endif
|
||||
|
||||
// Now load fonts with settings of ttf file
|
||||
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();
|
||||
m_fonts.push_back(regular);
|
||||
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();
|
||||
m_fonts.push_back(bold);
|
||||
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();
|
||||
m_fonts.push_back(digit);
|
||||
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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -115,6 +154,8 @@ void FontManager::unitTesting()
|
||||
translations = new Translations();
|
||||
Log::setLogLevel(cur_log_level);
|
||||
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)
|
||||
{
|
||||
// Skip non-printing characters
|
||||
@ -122,20 +163,13 @@ void FontManager::unitTesting()
|
||||
|
||||
unsigned int font_number = 0;
|
||||
unsigned int glyph_index = 0;
|
||||
while (font_number < m_normal_ttf->getTotalFaces())
|
||||
{
|
||||
glyph_index =
|
||||
FT_Get_Char_Index(m_normal_ttf->getFace(font_number), c);
|
||||
if (glyph_index > 0) break;
|
||||
font_number++;
|
||||
}
|
||||
if (glyph_index > 0)
|
||||
if (ttf->getFontAndGlyphFromChar(c, &font_number, &glyph_index))
|
||||
{
|
||||
Log::debug("UnitTest", "Character %s in language %s"
|
||||
" use face %s",
|
||||
StringUtils::wideToUtf8(core::stringw(&c, 1)).c_str(),
|
||||
lang.c_str(),
|
||||
m_normal_ttf->getFace(font_number)->family_name);
|
||||
ttf->getFace(font_number)->family_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include FT_FREETYPE_H
|
||||
#endif
|
||||
|
||||
class FaceTTF;
|
||||
class FontWithFace;
|
||||
|
||||
/** This class stores all font files required in STK.
|
||||
@ -52,14 +51,11 @@ private:
|
||||
#ifndef SERVER_ONLY
|
||||
/** A FreeType library, it holds the FT_Face internally inside freetype. */
|
||||
FT_Library m_ft_library;
|
||||
|
||||
/** List of ttf files loaded. */
|
||||
std::vector<FT_Face> m_faces;
|
||||
#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
|
||||
* \ref getFont. */
|
||||
std::unordered_map<std::type_index, int> m_font_type_map;
|
||||
@ -101,6 +97,8 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the \ref m_ft_library. */
|
||||
FT_Library getFTLibrary() const { return m_ft_library; }
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<FT_Face> loadTTF(const std::vector<std::string>& ttf_list);
|
||||
#endif
|
||||
// ------------------------------------------------------------------------
|
||||
void loadFonts();
|
||||
|
@ -39,7 +39,7 @@
|
||||
* \param name The name of face, used by irrlicht to distinguish spritebank.
|
||||
* \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());
|
||||
|
||||
@ -49,7 +49,7 @@ FontWithFace::FontWithFace(const std::string& name, FaceTTF* ttf)
|
||||
m_fallback_font = NULL;
|
||||
m_fallback_font_scale = 1.0f;
|
||||
m_glyph_max_height = 0;
|
||||
m_face_ttf = ttf;
|
||||
m_face_ttf = new FaceTTF();
|
||||
|
||||
} // FontWithFace
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -65,9 +65,7 @@ FontWithFace::~FontWithFace()
|
||||
m_spritebank->drop();
|
||||
m_spritebank = NULL;
|
||||
|
||||
// To be deleted by font_manager
|
||||
m_face_ttf = NULL;
|
||||
|
||||
delete m_face_ttf;
|
||||
} // ~FontWithFace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -112,7 +110,6 @@ void FontWithFace::init()
|
||||
void FontWithFace::reset()
|
||||
{
|
||||
m_new_char_holder.clear();
|
||||
m_character_area_map.clear();
|
||||
m_character_glyph_info_map.clear();
|
||||
for (unsigned int i = 0; i < m_spritebank->getTextureCount(); i++)
|
||||
{
|
||||
@ -120,6 +117,7 @@ void FontWithFace::reset()
|
||||
static_cast<STKTexture*>(m_spritebank->getTexture(i)));
|
||||
}
|
||||
m_spritebank->clear();
|
||||
m_face_ttf->reset();
|
||||
createNewGlyphPage();
|
||||
} // reset
|
||||
|
||||
@ -138,12 +136,7 @@ void FontWithFace::loadGlyphInfo(wchar_t c)
|
||||
|
||||
unsigned int font_number = 0;
|
||||
unsigned int glyph_index = 0;
|
||||
while (font_number < m_face_ttf->getTotalFaces())
|
||||
{
|
||||
glyph_index = FT_Get_Char_Index(m_face_ttf->getFace(font_number), c);
|
||||
if (glyph_index > 0) break;
|
||||
font_number++;
|
||||
}
|
||||
m_face_ttf->getFontAndGlyphFromChar(c, &font_number, &glyph_index);
|
||||
m_character_glyph_info_map[c] = GlyphInfo(font_number, glyph_index);
|
||||
#endif
|
||||
} // loadGlyphInfo
|
||||
@ -179,10 +172,9 @@ void FontWithFace::createNewGlyphPage()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** 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.
|
||||
*/
|
||||
void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
|
||||
void FontWithFace::insertGlyph(const GlyphInfo& gi)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
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_bt = -cur_offset_y;
|
||||
a.spriteno = f.rectNumber;
|
||||
m_character_area_map[c] = a;
|
||||
m_face_ttf->insertFontArea(a, gi.font_number, gi.glyph_index);
|
||||
|
||||
// Store used area
|
||||
m_used_width += texture_size.Width;
|
||||
@ -301,7 +293,7 @@ void FontWithFace::updateCharactersList()
|
||||
for (const wchar_t& c : m_new_char_holder)
|
||||
{
|
||||
const GlyphInfo& gi = getGlyphInfo(c);
|
||||
insertGlyph(c, gi);
|
||||
insertGlyph(gi);
|
||||
}
|
||||
m_new_char_holder.clear();
|
||||
|
||||
@ -373,17 +365,23 @@ void FontWithFace::setDPI()
|
||||
* \param c The character to get.
|
||||
* \param[out] fallback_font Whether fallback font is used.
|
||||
*/
|
||||
const FontWithFace::FontArea&
|
||||
FontWithFace::getAreaFromCharacter(const wchar_t c,
|
||||
bool* fallback_font) const
|
||||
const FontArea& FontWithFace::getAreaFromCharacter(const wchar_t c,
|
||||
bool* fallback_font) const
|
||||
{
|
||||
std::map<wchar_t, FontArea>::const_iterator n =
|
||||
m_character_area_map.find(c);
|
||||
if (n != m_character_area_map.end())
|
||||
std::map<wchar_t, GlyphInfo>::const_iterator n =
|
||||
m_character_glyph_info_map.find(c);
|
||||
// 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)
|
||||
*fallback_font = false;
|
||||
return n->second;
|
||||
return *area;
|
||||
}
|
||||
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
|
||||
if (fallback_font != NULL)
|
||||
*fallback_font = false;
|
||||
return m_character_area_map.begin()->second;
|
||||
#endif
|
||||
|
||||
return *(m_face_ttf->getFirstFontArea());
|
||||
} // getAreaFromCharacter
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -419,7 +418,6 @@ core::dimension2d<u32> FontWithFace::getDimension(const wchar_t* text,
|
||||
insertCharacters(text);
|
||||
updateCharactersList();
|
||||
|
||||
assert(m_character_area_map.size() > 0);
|
||||
core::dimension2d<float> dim(0.0f, 0.0f);
|
||||
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,
|
||||
FontSettings* font_settings) const
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
const float scale = font_settings ? font_settings->getScale() : 1.0f;
|
||||
float x = 0;
|
||||
int idx = 0;
|
||||
@ -482,7 +481,7 @@ int FontWithFace::getCharacterFromPos(const wchar_t* text, int pixel_x,
|
||||
|
||||
++idx;
|
||||
}
|
||||
|
||||
#endif
|
||||
return -1;
|
||||
} // getCharacterFromPos
|
||||
|
||||
@ -759,3 +758,18 @@ void FontWithFace::render(const core::stringw& text,
|
||||
}
|
||||
#endif
|
||||
} // 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 FontSettings;
|
||||
struct FontArea;
|
||||
|
||||
/** An abstract class which contains functions which convert vector fonts into
|
||||
* bitmap and render them in STK. To make STK draw characters with different
|
||||
@ -70,23 +71,6 @@ public:
|
||||
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:
|
||||
/** Used in vertical dimension calculation. */
|
||||
int m_font_max_height;
|
||||
@ -176,25 +160,11 @@ private:
|
||||
/** The dpi of this font. */
|
||||
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. */
|
||||
std::map<wchar_t, GlyphInfo> m_character_glyph_info_map;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** 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 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;
|
||||
}
|
||||
float getCharWidth(const FontArea& area, bool fallback, float scale) const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Test if a character has already been tried to be loaded.
|
||||
* \param c Character to test.
|
||||
@ -243,7 +213,7 @@ private:
|
||||
/** 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 insertGlyph(wchar_t c, const GlyphInfo& gi);
|
||||
void insertGlyph(const GlyphInfo& gi);
|
||||
// ------------------------------------------------------------------------
|
||||
void setDPI();
|
||||
// ------------------------------------------------------------------------
|
||||
@ -273,7 +243,7 @@ private:
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
FontWithFace(const std::string& name, FaceTTF* ttf);
|
||||
FontWithFace(const std::string& name);
|
||||
// ------------------------------------------------------------------------
|
||||
virtual ~FontWithFace();
|
||||
// ------------------------------------------------------------------------
|
||||
@ -305,7 +275,8 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Return the dpi of this face. */
|
||||
unsigned int getDPI() const { return m_face_dpi; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
FaceTTF* getFaceTTF() const { return m_face_ttf; }
|
||||
}; // FontWithFace
|
||||
|
||||
#endif
|
||||
|
@ -22,7 +22,7 @@
|
||||
/** Constructor of RegularFace.
|
||||
* \param ttf \ref FaceTTF for RegularFace to use.
|
||||
*/
|
||||
RegularFace::RegularFace(FaceTTF* ttf) : FontWithFace("RegularFace", ttf)
|
||||
RegularFace::RegularFace() : FontWithFace("RegularFace")
|
||||
{
|
||||
} // RegularFace
|
||||
|
||||
|
@ -38,7 +38,7 @@ private:
|
||||
public:
|
||||
LEAK_CHECK()
|
||||
// ------------------------------------------------------------------------
|
||||
RegularFace(FaceTTF* ttf);
|
||||
RegularFace();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void init() OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "guiengine/scalable_font.hpp"
|
||||
|
||||
#include "font/face_ttf.hpp"
|
||||
#include "font/font_settings.hpp"
|
||||
#include "font/font_with_face.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
@ -143,7 +144,7 @@ IGUISpriteBank* ScalableFont::getSpriteBank() const
|
||||
// ------------------------------------------------------------------------
|
||||
u32 ScalableFont::getSpriteNoFromChar(const wchar_t *c) const
|
||||
{
|
||||
const FontWithFace::FontArea& area =
|
||||
const FontArea& area =
|
||||
m_face->getAreaFromCharacter(*c, NULL/*fallback_font*/);
|
||||
return area.spriteno;
|
||||
} // getSpriteNoFromChar
|
||||
|
Loading…
Reference in New Issue
Block a user